diff --git a/SPIRV/GlslangToSpv.cpp b/SPIRV/GlslangToSpv.cpp index 625dcd7b..40f7508e 100755 --- a/SPIRV/GlslangToSpv.cpp +++ b/SPIRV/GlslangToSpv.cpp @@ -3555,7 +3555,7 @@ spv::Id TGlslangToSpvTraverser::handleUserFunctionCall(const glslang::TIntermAgg const glslang::TIntermSequence& glslangArgs = node->getSequence(); const glslang::TQualifierList& qualifiers = node->getQualifierList(); - // Encapsulate lvalue logic, used in two places below, for safety. + // Encapsulate lvalue logic, used in several places below, for safety. const auto isLValue = [](int qualifier, const glslang::TType& paramType) -> bool { return qualifier != glslang::EvqConstReadOnly || paramType.containsOpaque(); }; diff --git a/Test/baseResults/hlsl.hull.1.tesc.out b/Test/baseResults/hlsl.hull.1.tesc.out index 151a0b39..ebfaf599 100644 --- a/Test/baseResults/hlsl.hull.1.tesc.out +++ b/Test/baseResults/hlsl.hull.1.tesc.out @@ -32,7 +32,7 @@ vertex spacing = equal_spacing 0:? 'm_cpid' ( temp uint) 0:? 'm_cpid' ( in uint InvocationID) 0:26 move second child to first child ( temp structure{ temp 3-component vector of float cpoint}) -0:26 indirect index ( temp structure{ temp 3-component vector of float cpoint}) +0:26 indirect index (layout( location=0) out structure{ temp 3-component vector of float cpoint}) 0:? '@entryPointOutput' (layout( location=0) out 4-element array of structure{ temp 3-component vector of float cpoint}) 0:? 'm_cpid' ( in uint InvocationID) 0:26 Function Call: @main(struct-VS_OUT-vf31[4];u1; ( temp structure{ temp 3-component vector of float cpoint}) @@ -146,7 +146,7 @@ vertex spacing = equal_spacing 0:? 'm_cpid' ( temp uint) 0:? 'm_cpid' ( in uint InvocationID) 0:26 move second child to first child ( temp structure{ temp 3-component vector of float cpoint}) -0:26 indirect index ( temp structure{ temp 3-component vector of float cpoint}) +0:26 indirect index (layout( location=0) out structure{ temp 3-component vector of float cpoint}) 0:? '@entryPointOutput' (layout( location=0) out 4-element array of structure{ temp 3-component vector of float cpoint}) 0:? 'm_cpid' ( in uint InvocationID) 0:26 Function Call: @main(struct-VS_OUT-vf31[4];u1; ( temp structure{ temp 3-component vector of float cpoint}) diff --git a/Test/baseResults/hlsl.hull.2.tesc.out b/Test/baseResults/hlsl.hull.2.tesc.out index 11342eac..d4d75b35 100644 --- a/Test/baseResults/hlsl.hull.2.tesc.out +++ b/Test/baseResults/hlsl.hull.2.tesc.out @@ -28,7 +28,7 @@ vertex spacing = equal_spacing 0:? 'ip' ( temp 4-element array of structure{ temp 3-component vector of float cpoint}) 0:? 'ip' (layout( location=0) in 4-element array of structure{ temp 3-component vector of float cpoint}) 0:26 move second child to first child ( temp structure{ temp 3-component vector of float cpoint}) -0:26 indirect index ( temp structure{ temp 3-component vector of float cpoint}) +0:26 indirect index (layout( location=0) out structure{ temp 3-component vector of float cpoint}) 0:? '@entryPointOutput' (layout( location=0) out 4-element array of structure{ temp 3-component vector of float cpoint}) 0:? 'InvocationId' ( in uint InvocationID) 0:26 Function Call: @main(struct-VS_OUT-vf31[4]; ( temp structure{ temp 3-component vector of float cpoint}) @@ -140,7 +140,7 @@ vertex spacing = equal_spacing 0:? 'ip' ( temp 4-element array of structure{ temp 3-component vector of float cpoint}) 0:? 'ip' (layout( location=0) in 4-element array of structure{ temp 3-component vector of float cpoint}) 0:26 move second child to first child ( temp structure{ temp 3-component vector of float cpoint}) -0:26 indirect index ( temp structure{ temp 3-component vector of float cpoint}) +0:26 indirect index (layout( location=0) out structure{ temp 3-component vector of float cpoint}) 0:? '@entryPointOutput' (layout( location=0) out 4-element array of structure{ temp 3-component vector of float cpoint}) 0:? 'InvocationId' ( in uint InvocationID) 0:26 Function Call: @main(struct-VS_OUT-vf31[4]; ( temp structure{ temp 3-component vector of float cpoint}) diff --git a/Test/baseResults/hlsl.hull.3.tesc.out b/Test/baseResults/hlsl.hull.3.tesc.out index 39d92368..eecb6c81 100755 --- a/Test/baseResults/hlsl.hull.3.tesc.out +++ b/Test/baseResults/hlsl.hull.3.tesc.out @@ -28,7 +28,7 @@ vertex spacing = equal_spacing 0:? 'ip' ( temp 4-element array of structure{ temp 3-component vector of float cpoint}) 0:? 'ip' (layout( location=0) in 4-element array of structure{ temp 3-component vector of float cpoint}) 0:26 move second child to first child ( temp structure{ temp 3-component vector of float cpoint}) -0:26 indirect index ( temp structure{ temp 3-component vector of float cpoint}) +0:26 indirect index (layout( location=0) out structure{ temp 3-component vector of float cpoint}) 0:? '@entryPointOutput' (layout( location=0) out 4-element array of structure{ temp 3-component vector of float cpoint}) 0:? 'InvocationId' ( in uint InvocationID) 0:26 Function Call: @main(struct-VS_OUT-vf31[4]; ( temp structure{ temp 3-component vector of float cpoint}) @@ -140,7 +140,7 @@ vertex spacing = equal_spacing 0:? 'ip' ( temp 4-element array of structure{ temp 3-component vector of float cpoint}) 0:? 'ip' (layout( location=0) in 4-element array of structure{ temp 3-component vector of float cpoint}) 0:26 move second child to first child ( temp structure{ temp 3-component vector of float cpoint}) -0:26 indirect index ( temp structure{ temp 3-component vector of float cpoint}) +0:26 indirect index (layout( location=0) out structure{ temp 3-component vector of float cpoint}) 0:? '@entryPointOutput' (layout( location=0) out 4-element array of structure{ temp 3-component vector of float cpoint}) 0:? 'InvocationId' ( in uint InvocationID) 0:26 Function Call: @main(struct-VS_OUT-vf31[4]; ( temp structure{ temp 3-component vector of float cpoint}) diff --git a/Test/baseResults/hlsl.hull.4.tesc.out b/Test/baseResults/hlsl.hull.4.tesc.out new file mode 100644 index 00000000..9bce2518 --- /dev/null +++ b/Test/baseResults/hlsl.hull.4.tesc.out @@ -0,0 +1,241 @@ +hlsl.hull.4.tesc +Shader version: 500 +vertices = 3 +0:? Sequence +0:14 Function Definition: @main( ( temp structure{ temp 3-element array of float tessFactor, temp float coord}) +0:14 Function Parameters: +0:? Sequence +0:15 Sequence +0:15 move second child to first child ( temp structure{ temp 3-element array of float tessFactor, temp float coord}) +0:15 'output' ( temp structure{ temp 3-element array of float tessFactor, temp float coord}) +0:15 Constant: +0:15 0.000000 +0:15 0.000000 +0:15 0.000000 +0:15 0.000000 +0:16 Branch: Return with expression +0:16 'output' ( temp structure{ temp 3-element array of float tessFactor, temp float coord}) +0:14 Function Definition: main( ( temp void) +0:14 Function Parameters: +0:? Sequence +0:14 Sequence +0:14 move second child to first child ( temp structure{ temp 3-element array of float tessFactor, temp float coord}) +0:14 'flattenTemp' ( temp structure{ temp 3-element array of float tessFactor, temp float coord}) +0:14 Function Call: @main( ( temp structure{ temp 3-element array of float tessFactor, temp float coord}) +0:14 move second child to first child ( temp float) +0:14 direct index ( patch out float TessLevelOuter) +0:? '@entryPointOutput.tessFactor' ( patch out 4-element array of float TessLevelOuter) +0:14 Constant: +0:14 0 (const int) +0:14 direct index ( temp float) +0:14 tessFactor: direct index for structure ( temp 3-element array of float) +0:14 'flattenTemp' ( temp structure{ temp 3-element array of float tessFactor, temp float coord}) +0:14 Constant: +0:14 0 (const int) +0:14 Constant: +0:14 0 (const int) +0:14 move second child to first child ( temp float) +0:14 direct index ( patch out float TessLevelOuter) +0:? '@entryPointOutput.tessFactor' ( patch out 4-element array of float TessLevelOuter) +0:14 Constant: +0:14 1 (const int) +0:14 direct index ( temp float) +0:14 tessFactor: direct index for structure ( temp 3-element array of float) +0:14 'flattenTemp' ( temp structure{ temp 3-element array of float tessFactor, temp float coord}) +0:14 Constant: +0:14 0 (const int) +0:14 Constant: +0:14 1 (const int) +0:14 move second child to first child ( temp float) +0:14 direct index ( patch out float TessLevelOuter) +0:? '@entryPointOutput.tessFactor' ( patch out 4-element array of float TessLevelOuter) +0:14 Constant: +0:14 2 (const int) +0:14 direct index ( temp float) +0:14 tessFactor: direct index for structure ( temp 3-element array of float) +0:14 'flattenTemp' ( temp structure{ temp 3-element array of float tessFactor, temp float coord}) +0:14 Constant: +0:14 0 (const int) +0:14 Constant: +0:14 2 (const int) +0:14 move second child to first child ( temp float) +0:14 coord: direct index for structure ( temp float) +0:14 indirect index (layout( location=0) out structure{ temp float coord}) +0:14 '@entryPointOutput' (layout( location=0) out 3-element array of structure{ temp float coord}) +0:? 'InvocationId' ( in uint InvocationID) +0:14 Constant: +0:14 0 (const int) +0:14 coord: direct index for structure ( temp float) +0:14 'flattenTemp' ( temp structure{ temp 3-element array of float tessFactor, temp float coord}) +0:14 Constant: +0:14 1 (const int) +0:? Linker Objects +0:? '@entryPointOutput.tessFactor' ( patch out 4-element array of float TessLevelOuter) +0:? '@entryPointOutput' (layout( location=0) out 3-element array of structure{ temp float coord}) +0:? 'InvocationId' ( in uint InvocationID) + + +Linked tessellation control stage: + + +Shader version: 500 +vertices = 3 +0:? Sequence +0:14 Function Definition: @main( ( temp structure{ temp 3-element array of float tessFactor, temp float coord}) +0:14 Function Parameters: +0:? Sequence +0:15 Sequence +0:15 move second child to first child ( temp structure{ temp 3-element array of float tessFactor, temp float coord}) +0:15 'output' ( temp structure{ temp 3-element array of float tessFactor, temp float coord}) +0:15 Constant: +0:15 0.000000 +0:15 0.000000 +0:15 0.000000 +0:15 0.000000 +0:16 Branch: Return with expression +0:16 'output' ( temp structure{ temp 3-element array of float tessFactor, temp float coord}) +0:14 Function Definition: main( ( temp void) +0:14 Function Parameters: +0:? Sequence +0:14 Sequence +0:14 move second child to first child ( temp structure{ temp 3-element array of float tessFactor, temp float coord}) +0:14 'flattenTemp' ( temp structure{ temp 3-element array of float tessFactor, temp float coord}) +0:14 Function Call: @main( ( temp structure{ temp 3-element array of float tessFactor, temp float coord}) +0:14 move second child to first child ( temp float) +0:14 direct index ( patch out float TessLevelOuter) +0:? '@entryPointOutput.tessFactor' ( patch out 4-element array of float TessLevelOuter) +0:14 Constant: +0:14 0 (const int) +0:14 direct index ( temp float) +0:14 tessFactor: direct index for structure ( temp 3-element array of float) +0:14 'flattenTemp' ( temp structure{ temp 3-element array of float tessFactor, temp float coord}) +0:14 Constant: +0:14 0 (const int) +0:14 Constant: +0:14 0 (const int) +0:14 move second child to first child ( temp float) +0:14 direct index ( patch out float TessLevelOuter) +0:? '@entryPointOutput.tessFactor' ( patch out 4-element array of float TessLevelOuter) +0:14 Constant: +0:14 1 (const int) +0:14 direct index ( temp float) +0:14 tessFactor: direct index for structure ( temp 3-element array of float) +0:14 'flattenTemp' ( temp structure{ temp 3-element array of float tessFactor, temp float coord}) +0:14 Constant: +0:14 0 (const int) +0:14 Constant: +0:14 1 (const int) +0:14 move second child to first child ( temp float) +0:14 direct index ( patch out float TessLevelOuter) +0:? '@entryPointOutput.tessFactor' ( patch out 4-element array of float TessLevelOuter) +0:14 Constant: +0:14 2 (const int) +0:14 direct index ( temp float) +0:14 tessFactor: direct index for structure ( temp 3-element array of float) +0:14 'flattenTemp' ( temp structure{ temp 3-element array of float tessFactor, temp float coord}) +0:14 Constant: +0:14 0 (const int) +0:14 Constant: +0:14 2 (const int) +0:14 move second child to first child ( temp float) +0:14 coord: direct index for structure ( temp float) +0:14 indirect index (layout( location=0) out structure{ temp float coord}) +0:14 '@entryPointOutput' (layout( location=0) out 3-element array of structure{ temp float coord}) +0:? 'InvocationId' ( in uint InvocationID) +0:14 Constant: +0:14 0 (const int) +0:14 coord: direct index for structure ( temp float) +0:14 'flattenTemp' ( temp structure{ temp 3-element array of float tessFactor, temp float coord}) +0:14 Constant: +0:14 1 (const int) +0:? Linker Objects +0:? '@entryPointOutput.tessFactor' ( patch out 4-element array of float TessLevelOuter) +0:? '@entryPointOutput' (layout( location=0) out 3-element array of structure{ temp float coord}) +0:? 'InvocationId' ( in uint InvocationID) + +// Module Version 10000 +// Generated by (magic number): 80001 +// Id's are bound by 53 + + Capability Tessellation + 1: ExtInstImport "GLSL.std.450" + MemoryModel Logical GLSL450 + EntryPoint TessellationControl 4 "main" 27 46 48 + ExecutionMode 4 OutputVertices 3 + ExecutionMode 4 Triangles + Source HLSL 500 + Name 4 "main" + Name 10 "HS_Output" + MemberName 10(HS_Output) 0 "tessFactor" + MemberName 10(HS_Output) 1 "coord" + Name 12 "@main(" + Name 15 "output" + Name 22 "flattenTemp" + Name 27 "@entryPointOutput.tessFactor" + Name 43 "HS_Output" + MemberName 43(HS_Output) 0 "coord" + Name 46 "@entryPointOutput" + Name 48 "InvocationId" + Decorate 27(@entryPointOutput.tessFactor) Patch + Decorate 27(@entryPointOutput.tessFactor) BuiltIn TessLevelOuter + Decorate 46(@entryPointOutput) Location 0 + Decorate 48(InvocationId) BuiltIn InvocationId + 2: TypeVoid + 3: TypeFunction 2 + 6: TypeFloat 32 + 7: TypeInt 32 0 + 8: 7(int) Constant 3 + 9: TypeArray 6(float) 8 + 10(HS_Output): TypeStruct 9 6(float) + 11: TypeFunction 10(HS_Output) + 14: TypePointer Function 10(HS_Output) + 16: 6(float) Constant 0 + 17: 9 ConstantComposite 16 16 16 + 18:10(HS_Output) ConstantComposite 17 16 + 24: 7(int) Constant 4 + 25: TypeArray 6(float) 24 + 26: TypePointer Output 25 +27(@entryPointOutput.tessFactor): 26(ptr) Variable Output + 28: TypeInt 32 1 + 29: 28(int) Constant 0 + 30: TypePointer Function 6(float) + 33: TypePointer Output 6(float) + 35: 28(int) Constant 1 + 39: 28(int) Constant 2 + 43(HS_Output): TypeStruct 6(float) + 44: TypeArray 43(HS_Output) 8 + 45: TypePointer Output 44 +46(@entryPointOutput): 45(ptr) Variable Output + 47: TypePointer Input 7(int) +48(InvocationId): 47(ptr) Variable Input + 4(main): 2 Function None 3 + 5: Label + 22(flattenTemp): 14(ptr) Variable Function + 23:10(HS_Output) FunctionCall 12(@main() + Store 22(flattenTemp) 23 + 31: 30(ptr) AccessChain 22(flattenTemp) 29 29 + 32: 6(float) Load 31 + 34: 33(ptr) AccessChain 27(@entryPointOutput.tessFactor) 29 + Store 34 32 + 36: 30(ptr) AccessChain 22(flattenTemp) 29 35 + 37: 6(float) Load 36 + 38: 33(ptr) AccessChain 27(@entryPointOutput.tessFactor) 35 + Store 38 37 + 40: 30(ptr) AccessChain 22(flattenTemp) 29 39 + 41: 6(float) Load 40 + 42: 33(ptr) AccessChain 27(@entryPointOutput.tessFactor) 39 + Store 42 41 + 49: 7(int) Load 48(InvocationId) + 50: 30(ptr) AccessChain 22(flattenTemp) 35 + 51: 6(float) Load 50 + 52: 33(ptr) AccessChain 46(@entryPointOutput) 49 29 + Store 52 51 + Return + FunctionEnd + 12(@main():10(HS_Output) Function None 11 + 13: Label + 15(output): 14(ptr) Variable Function + Store 15(output) 18 + 19:10(HS_Output) Load 15(output) + ReturnValue 19 + FunctionEnd diff --git a/Test/baseResults/hlsl.hull.ctrlpt-1.tesc.out b/Test/baseResults/hlsl.hull.ctrlpt-1.tesc.out index 7fbe0cb5..9ccd7e3d 100644 --- a/Test/baseResults/hlsl.hull.ctrlpt-1.tesc.out +++ b/Test/baseResults/hlsl.hull.ctrlpt-1.tesc.out @@ -29,7 +29,7 @@ triangle order = cw 0:? 'cpid' ( temp uint) 0:? 'cpid' ( in uint InvocationID) 0:27 move second child to first child ( temp structure{ temp 3-component vector of float val}) -0:27 indirect index ( temp structure{ temp 3-component vector of float val}) +0:27 indirect index (layout( location=0) out structure{ temp 3-component vector of float val}) 0:? '@entryPointOutput' (layout( location=0) out 3-element array of structure{ temp 3-component vector of float val}) 0:? 'cpid' ( in uint InvocationID) 0:27 Function Call: @main(struct-hs_in_t-vf31[3];u1; ( temp structure{ temp 3-component vector of float val}) @@ -229,7 +229,7 @@ triangle order = cw 0:? 'cpid' ( temp uint) 0:? 'cpid' ( in uint InvocationID) 0:27 move second child to first child ( temp structure{ temp 3-component vector of float val}) -0:27 indirect index ( temp structure{ temp 3-component vector of float val}) +0:27 indirect index (layout( location=0) out structure{ temp 3-component vector of float val}) 0:? '@entryPointOutput' (layout( location=0) out 3-element array of structure{ temp 3-component vector of float val}) 0:? 'cpid' ( in uint InvocationID) 0:27 Function Call: @main(struct-hs_in_t-vf31[3];u1; ( temp structure{ temp 3-component vector of float val}) diff --git a/Test/baseResults/hlsl.hull.ctrlpt-2.tesc.out b/Test/baseResults/hlsl.hull.ctrlpt-2.tesc.out index 32764f30..b8e1562a 100644 --- a/Test/baseResults/hlsl.hull.ctrlpt-2.tesc.out +++ b/Test/baseResults/hlsl.hull.ctrlpt-2.tesc.out @@ -36,7 +36,7 @@ triangle order = cw 0:? 'cpid' ( temp uint) 0:? 'cpid' ( in uint InvocationID) 0:28 move second child to first child ( temp structure{ temp 3-component vector of float val}) -0:28 indirect index ( temp structure{ temp 3-component vector of float val}) +0:28 indirect index (layout( location=0) out structure{ temp 3-component vector of float val}) 0:? '@entryPointOutput' (layout( location=0) out 3-element array of structure{ temp 3-component vector of float val}) 0:? 'cpid' ( in uint InvocationID) 0:28 Function Call: @main(struct-hs_in_t-vf31[3];u1; ( temp structure{ temp 3-component vector of float val}) @@ -245,7 +245,7 @@ triangle order = cw 0:? 'cpid' ( temp uint) 0:? 'cpid' ( in uint InvocationID) 0:28 move second child to first child ( temp structure{ temp 3-component vector of float val}) -0:28 indirect index ( temp structure{ temp 3-component vector of float val}) +0:28 indirect index (layout( location=0) out structure{ temp 3-component vector of float val}) 0:? '@entryPointOutput' (layout( location=0) out 3-element array of structure{ temp 3-component vector of float val}) 0:? 'cpid' ( in uint InvocationID) 0:28 Function Call: @main(struct-hs_in_t-vf31[3];u1; ( temp structure{ temp 3-component vector of float val}) diff --git a/Test/baseResults/hlsl.hull.void.tesc.out b/Test/baseResults/hlsl.hull.void.tesc.out index 8dc38fcd..41292359 100644 --- a/Test/baseResults/hlsl.hull.void.tesc.out +++ b/Test/baseResults/hlsl.hull.void.tesc.out @@ -29,7 +29,7 @@ triangle order = ccw 0:? 'ip' ( temp 3-element array of structure{ temp 3-component vector of float cpoint}) 0:? 'ip' (layout( location=0) in 3-element array of structure{ temp 3-component vector of float cpoint}) 0:26 move second child to first child ( temp structure{ temp 3-component vector of float cpoint}) -0:26 indirect index ( temp structure{ temp 3-component vector of float cpoint}) +0:26 indirect index (layout( location=0) out structure{ temp 3-component vector of float cpoint}) 0:? '@entryPointOutput' (layout( location=0) out 3-element array of structure{ temp 3-component vector of float cpoint}) 0:? 'InvocationId' ( in uint InvocationID) 0:26 Function Call: @main(struct-VS_OUT-vf31[3]; ( temp structure{ temp 3-component vector of float cpoint}) @@ -85,7 +85,7 @@ triangle order = ccw 0:? 'ip' ( temp 3-element array of structure{ temp 3-component vector of float cpoint}) 0:? 'ip' (layout( location=0) in 3-element array of structure{ temp 3-component vector of float cpoint}) 0:26 move second child to first child ( temp structure{ temp 3-component vector of float cpoint}) -0:26 indirect index ( temp structure{ temp 3-component vector of float cpoint}) +0:26 indirect index (layout( location=0) out structure{ temp 3-component vector of float cpoint}) 0:? '@entryPointOutput' (layout( location=0) out 3-element array of structure{ temp 3-component vector of float cpoint}) 0:? 'InvocationId' ( in uint InvocationID) 0:26 Function Call: @main(struct-VS_OUT-vf31[3]; ( temp structure{ temp 3-component vector of float cpoint}) diff --git a/Test/hlsl.hull.4.tesc b/Test/hlsl.hull.4.tesc new file mode 100644 index 00000000..93b7e715 --- /dev/null +++ b/Test/hlsl.hull.4.tesc @@ -0,0 +1,17 @@ + +// Test mixed output structure: user and builtin members. Hull shaders involve extra +// logic in this case, over and above e.g. pixel or vertex stages, which is related to +// the implicit array dimension. +struct HS_Output +{ + float tessFactor[3] : SV_TessFactor; + float coord : TEXCOORD0; +}; + +[domain("tri")] +[outputcontrolpoints(3)] +HS_Output main ( ) +{ + HS_Output output = (HS_Output)0; + return output; +} diff --git a/gtests/Hlsl.FromFile.cpp b/gtests/Hlsl.FromFile.cpp index 4dfe7d79..c07e2624 100644 --- a/gtests/Hlsl.FromFile.cpp +++ b/gtests/Hlsl.FromFile.cpp @@ -164,6 +164,7 @@ INSTANTIATE_TEST_CASE_P( {"hlsl.hull.1.tesc", "main"}, {"hlsl.hull.2.tesc", "main"}, {"hlsl.hull.3.tesc", "main"}, + {"hlsl.hull.4.tesc", "main"}, {"hlsl.hull.void.tesc", "main"}, {"hlsl.hull.ctrlpt-1.tesc", "main"}, {"hlsl.hull.ctrlpt-2.tesc", "main"}, diff --git a/hlsl/hlslParseHelper.cpp b/hlsl/hlslParseHelper.cpp index 2ed252cd..2aac482d 100755 --- a/hlsl/hlslParseHelper.cpp +++ b/hlsl/hlslParseHelper.cpp @@ -2039,7 +2039,10 @@ TIntermNode* HlslParseContext::transformEntryPoint(const TSourceLoc& loc, TFunct TIntermTyped* element = intermediate.addIndex(EOpIndexIndirect, intermediate.addSymbol(*entryPointOutput), invocationIdSym, loc); - element->setType(callReturn->getType()); + + // Set the type of the array element being dereferenced + const TType derefElementType(entryPointOutput->getType(), 0); + element->setType(derefElementType); returnAssign = handleAssign(loc, EOpAssign, element, callReturn); } else { @@ -2561,14 +2564,25 @@ TIntermTyped* HlslParseContext::handleAssign(const TSourceLoc& loc, TOperator op if (left->getAsOperator() && left->getAsOperator()->getOp() == EOpMatrixSwizzle) return handleAssignToMatrixSwizzle(loc, op, left, right); - const bool isSplitLeft = wasSplit(left); - const bool isSplitRight = wasSplit(right); + // Return true if the given node is an index operation into a split variable. + const auto indexesSplit = [this](const TIntermTyped* node) -> bool { + const TIntermBinary* binaryNode = node->getAsBinaryNode(); + + if (binaryNode == nullptr) + return false; + + return (binaryNode->getOp() == EOpIndexDirect || binaryNode->getOp() == EOpIndexIndirect) && + wasSplit(binaryNode->getLeft()); + }; + + const bool isSplitLeft = wasSplit(left) || indexesSplit(left); + const bool isSplitRight = wasSplit(right) || indexesSplit(right); const bool isFlattenLeft = wasFlattened(left); const bool isFlattenRight = wasFlattened(right); - // OK to do a single assign if both are split, or both are unsplit. But if one is and the other - // isn't, we fall back to a member-wise copy. + // OK to do a single assign if neither side is split or flattened. Otherwise, + // fall through to a member-wise copy. if (!isFlattenLeft && !isFlattenRight && !isSplitLeft && !isSplitRight) { // Clip and cull distance requires more processing. See comment above assignClipCullDistance. if (isClipOrCullDistance(left->getType()) || isClipOrCullDistance(right->getType())) { @@ -2803,8 +2817,25 @@ TIntermTyped* HlslParseContext::handleAssign(const TSourceLoc& loc, TOperator op // If either left or right was a split structure, we must read or write it, but still have to // parallel-recurse through the unsplit structure to identify the built-in IO vars. - if (isSplitLeft) - splitLeft = intermediate.addSymbol(*getSplitNonIoVar(left->getAsSymbolNode()->getId()), loc); + // The left can be either a symbol, or an index into a symbol (e.g, array reference) + if (isSplitLeft) { + if (indexesSplit(left)) { + // Index case: Refer to the indexed symbol, if the left is an index operator. + const TIntermSymbol* symNode = left->getAsBinaryNode()->getLeft()->getAsSymbolNode(); + + TIntermTyped* splitLeftNonIo = intermediate.addSymbol(*getSplitNonIoVar(symNode->getId()), loc); + + splitLeft = intermediate.addIndex(left->getAsBinaryNode()->getOp(), splitLeftNonIo, + left->getAsBinaryNode()->getRight(), loc); + + const TType derefType(splitLeftNonIo->getType(), 0); + splitLeft->setType(derefType); + } else { + // Symbol case: otherwise, if not indexed, we have the symbol directly. + const TIntermSymbol* symNode = left->getAsSymbolNode(); + splitLeft = intermediate.addSymbol(*getSplitNonIoVar(symNode->getId()), loc); + } + } if (isSplitRight) splitRight = intermediate.addSymbol(*getSplitNonIoVar(right->getAsSymbolNode()->getId()), loc);