MSL: Handle loading Clip/CullDistance in TESE.

Need to allow the flattened space to go through in some edge cases where
we cannot reasonably unflatten.
This commit is contained in:
Hans-Kristian Arntzen 2021-04-14 15:10:02 +02:00
parent a159334895
commit 75ed73818c
6 changed files with 80 additions and 1 deletions

View File

@ -0,0 +1,37 @@
#include <metal_stdlib>
#include <simd/simd.h>
using namespace metal;
struct main0_out
{
float4 gl_Position [[position]];
};
struct main0_in
{
float4 gl_Position [[attribute(0)]];
float gl_ClipDistance_0 [[attribute(1)]];
float gl_ClipDistance_1 [[attribute(2)]];
float gl_CullDistance_0 [[attribute(3)]];
float gl_CullDistance_1 [[attribute(4)]];
float gl_CullDistance_2 [[attribute(5)]];
};
struct main0_patchIn
{
patch_control_point<main0_in> gl_in;
};
[[ patch(quad, 0) ]] vertex main0_out main0(main0_patchIn patchIn [[stage_in]])
{
main0_out out = {};
out.gl_Position.x = patchIn.gl_in[0].gl_ClipDistance_0;
out.gl_Position.y = patchIn.gl_in[1].gl_CullDistance_0;
out.gl_Position.z = patchIn.gl_in[0].gl_ClipDistance_1;
out.gl_Position.w = patchIn.gl_in[1].gl_CullDistance_1;
out.gl_Position += patchIn.gl_in[0].gl_Position;
out.gl_Position += patchIn.gl_in[1].gl_Position;
return out;
}

View File

@ -0,0 +1,19 @@
#version 450
layout(quads) in;
in gl_PerVertex
{
float gl_ClipDistance[2];
float gl_CullDistance[3];
vec4 gl_Position;
} gl_in[];
void main()
{
gl_Position.x = gl_in[0].gl_ClipDistance[0];
gl_Position.y = gl_in[1].gl_CullDistance[0];
gl_Position.z = gl_in[0].gl_ClipDistance[1];
gl_Position.w = gl_in[1].gl_CullDistance[1];
gl_Position += gl_in[0].gl_Position;
gl_Position += gl_in[1].gl_Position;
}

View File

@ -8375,6 +8375,11 @@ void CompilerGLSL::access_chain_internal_append_index(std::string &expr, uint32_
expr += "]";
}
bool CompilerGLSL::access_chain_needs_stage_io_builtin_translation(uint32_t)
{
return true;
}
string CompilerGLSL::access_chain_internal(uint32_t base, const uint32_t *indices, uint32_t count,
AccessChainFlags flags, AccessChainMeta *meta)
{
@ -8584,7 +8589,7 @@ string CompilerGLSL::access_chain_internal(uint32_t base, const uint32_t *indice
SPIRV_CROSS_THROW("Member index is out of bounds!");
BuiltIn builtin;
if (is_member_builtin(*type, index, &builtin))
if (is_member_builtin(*type, index, &builtin) && access_chain_needs_stage_io_builtin_translation(base))
{
if (access_chain_is_arrayed)
{

View File

@ -673,6 +673,8 @@ protected:
std::string access_chain_internal(uint32_t base, const uint32_t *indices, uint32_t count, AccessChainFlags flags,
AccessChainMeta *meta);
virtual bool access_chain_needs_stage_io_builtin_translation(uint32_t base);
virtual void prepare_access_chain_for_scalar_access(std::string &expr, const SPIRType &type,
spv::StorageClass storage, bool &is_packed);

View File

@ -7354,6 +7354,21 @@ void CompilerMSL::prepare_access_chain_for_scalar_access(std::string &expr, cons
}
}
bool CompilerMSL::access_chain_needs_stage_io_builtin_translation(uint32_t base)
{
auto *var = maybe_get_backing_variable(base);
if (!var || !is_tessellation_shader())
return true;
// We only need to rewrite builtin access chains when accessing flattened builtins like gl_ClipDistance_N.
// Avoid overriding it back to just gl_ClipDistance.
// This can only happen in scenarios where we cannot flatten/unflatten access chains, so, the only case
// where this triggers is evaluation shader inputs.
bool redirect_builtin = get_execution_model() == ExecutionModelTessellationEvaluation ?
var->storage == StorageClassOutput : false;
return redirect_builtin;
}
// Sets the interface member index for an access chain to a pull-model interpolant.
void CompilerMSL::fix_up_interpolant_access_chain(const uint32_t *ops, uint32_t length)
{

View File

@ -951,6 +951,7 @@ protected:
void analyze_sampled_image_usage();
bool access_chain_needs_stage_io_builtin_translation(uint32_t base) override;
void prepare_access_chain_for_scalar_access(std::string &expr, const SPIRType &type, spv::StorageClass storage,
bool &is_packed) override;
void fix_up_interpolant_access_chain(const uint32_t *ops, uint32_t length);