diff options
author | Hans-Kristian Arntzen <post@arntzen-software.no> | 2021-05-21 16:32:03 +0200 |
---|---|---|
committer | Hans-Kristian Arntzen <post@arntzen-software.no> | 2021-05-21 16:32:03 +0200 |
commit | bf3793dd3596b4d16be840bd2575ea4a33eace9a (patch) | |
tree | f548a27d956e0d5d0df82fa6b0655dbb2caa7b89 | |
parent | a6c951485604426bf0ae798196596b9dac656cc5 (diff) | |
download | SPIRV-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.tese | 28 | ||||
-rw-r--r-- | shaders-msl-no-opt/asm/tese/split-access-chain.asm.tese | 35 | ||||
-rw-r--r-- | spirv_msl.cpp | 18 |
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()), |