summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHans-Kristian Arntzen <post@arntzen-software.no>2021-05-21 16:32:03 +0200
committerHans-Kristian Arntzen <post@arntzen-software.no>2021-05-21 16:32:03 +0200
commitbf3793dd3596b4d16be840bd2575ea4a33eace9a (patch)
treef548a27d956e0d5d0df82fa6b0655dbb2caa7b89
parenta6c951485604426bf0ae798196596b9dac656cc5 (diff)
downloadSPIRV-Cross-bf3793dd3596b4d16be840bd2575ea4a33eace9a.tar.gz
SPIRV-Cross-bf3793dd3596b4d16be840bd2575ea4a33eace9a.tar.bz2
SPIRV-Cross-bf3793dd3596b4d16be840bd2575ea4a33eace9a.zip
MSL: Improve handling of split tessellation access chains.
-rw-r--r--reference/shaders-msl-no-opt/asm/tese/split-access-chain.asm.tese28
-rw-r--r--shaders-msl-no-opt/asm/tese/split-access-chain.asm.tese35
-rw-r--r--spirv_msl.cpp18
3 files changed, 79 insertions, 2 deletions
diff --git a/reference/shaders-msl-no-opt/asm/tese/split-access-chain.asm.tese b/reference/shaders-msl-no-opt/asm/tese/split-access-chain.asm.tese
new file mode 100644
index 00000000..05a81133
--- /dev/null
+++ b/reference/shaders-msl-no-opt/asm/tese/split-access-chain.asm.tese
@@ -0,0 +1,28 @@
+#include <metal_stdlib>
+#include <simd/simd.h>
+
+using namespace metal;
+
+struct main0_out
+{
+ float o0 [[user(locn0)]];
+ float4 gl_Position [[position]];
+};
+
+struct main0_in
+{
+ float4 in0 [[attribute(0)]];
+};
+
+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.o0 = patchIn.gl_in[0u].in0.z;
+ return out;
+}
+
diff --git a/shaders-msl-no-opt/asm/tese/split-access-chain.asm.tese b/shaders-msl-no-opt/asm/tese/split-access-chain.asm.tese
new file mode 100644
index 00000000..e13064f9
--- /dev/null
+++ b/shaders-msl-no-opt/asm/tese/split-access-chain.asm.tese
@@ -0,0 +1,35 @@
+ OpCapability Tessellation
+ %94 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint TessellationEvaluation %main "main" %in0 %o0
+ OpExecutionMode %main Quads
+ OpName %main "main"
+ OpName %in0 "in0"
+ OpName %o0 "o0"
+ OpDecorate %in0 Location 0
+ OpDecorate %o0 Location 0
+ %void = OpTypeVoid
+ %3 = OpTypeFunction %void
+ %float = OpTypeFloat 32
+ %v4float = OpTypeVector %float 4
+ %uint = OpTypeInt 32 0
+ %uint_0 = OpConstant %uint 0
+ %uint_1 = OpConstant %uint 1
+ %uint_2 = OpConstant %uint 2
+%_arr_v4float_uint_1 = OpTypeArray %v4float %uint_1
+%_ptr_Output_float = OpTypePointer Output %float
+%_ptr_Input__arr_v4float_uint_1 = OpTypePointer Input %_arr_v4float_uint_1
+ %in0 = OpVariable %_ptr_Input__arr_v4float_uint_1 Input
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+ %o0 = OpVariable %_ptr_Output_float Output
+%_ptr_Function_float = OpTypePointer Function %float
+%_ptr_Input_v4float = OpTypePointer Input %v4float
+%_ptr_Input_float = OpTypePointer Input %float
+ %main = OpFunction %void None %3
+ %4 = OpLabel
+ %ac = OpAccessChain %_ptr_Input_v4float %in0 %uint_0
+ %bac = OpInBoundsAccessChain %_ptr_Input_float %ac %uint_2
+ %loaded = OpLoad %float %bac
+ OpStore %o0 %loaded
+ OpReturn
+ OpFunctionEnd
diff --git a/spirv_msl.cpp b/spirv_msl.cpp
index 8a5a22f8..aee52f7d 100644
--- a/spirv_msl.cpp
+++ b/spirv_msl.cpp
@@ -7145,7 +7145,17 @@ bool CompilerMSL::emit_tessellation_access_chain(const uint32_t *ops, uint32_t l
uint32_t const_mbr_id = next_id++;
uint32_t index = get_extended_decoration(ops[2], SPIRVCrossDecorationInterfaceMemberIndex);
- if (flatten_composites || is_block)
+ // If we have a pointer chain expression, and we are no longer pointing to a composite
+ // object, we are in the clear. There is no longer a need to flatten anything.
+ bool further_access_chain_is_trivial = false;
+ if (ptr_is_chain && flatten_composites)
+ {
+ auto &ptr_type = expression_type(ptr);
+ if (!is_array(ptr_type) && !is_matrix(ptr_type) && ptr_type.basetype != SPIRType::Struct)
+ further_access_chain_is_trivial = true;
+ }
+
+ if (!further_access_chain_is_trivial && (flatten_composites || is_block))
{
uint32_t i = first_non_array_index;
auto *type = &get_variable_element_type(*var);
@@ -7261,7 +7271,11 @@ bool CompilerMSL::emit_tessellation_access_chain(const uint32_t *ops, uint32_t l
// First one is the gl_in/gl_out struct itself, then an index into that array.
// If we have traversed further, we use a normal access chain formulation.
auto *ptr_expr = maybe_get<SPIRExpression>(ptr);
- if (flatten_composites && ptr_expr && ptr_expr->implied_read_expressions.size() == 2)
+ bool split_access_chain_formulation = flatten_composites && ptr_expr &&
+ ptr_expr->implied_read_expressions.size() == 2 &&
+ !further_access_chain_is_trivial;
+
+ if (split_access_chain_formulation)
{
e = join(to_expression(ptr),
access_chain_internal(stage_var_id, indices.data(), uint32_t(indices.size()),