From 65cdff9a5401fabd4b0fdccd196cf8c878e13ea6 Mon Sep 17 00:00:00 2001 From: steve-lunarg Date: Thu, 19 Jan 2017 15:18:00 -0700 Subject: [PATCH] HLSL: fix dereferencing when copying split structures with arrays When copying split types with mixtures of user variables and buitins, where the builtins are extracted, there is a parallel structures traversal. The traversal was not obtaining the derefenced types in the array case. --- .../hlsl.struct.split.assign.frag.out | 196 ++++++++++++++++++ Test/hlsl.struct.split.assign.frag | 12 ++ gtests/Hlsl.FromFile.cpp | 1 + hlsl/hlslParseHelper.cpp | 9 +- 4 files changed, 213 insertions(+), 5 deletions(-) create mode 100644 Test/baseResults/hlsl.struct.split.assign.frag.out create mode 100644 Test/hlsl.struct.split.assign.frag diff --git a/Test/baseResults/hlsl.struct.split.assign.frag.out b/Test/baseResults/hlsl.struct.split.assign.frag.out new file mode 100644 index 00000000..e214c512 --- /dev/null +++ b/Test/baseResults/hlsl.struct.split.assign.frag.out @@ -0,0 +1,196 @@ +hlsl.struct.split.assign.frag +Shader version: 450 +gl_FragCoord origin is upper left +0:? Sequence +0:7 Function Definition: main(i1;struct-S-f1-vf41[3]; (temp 4-component vector of float) +0:7 Function Parameters: +0:7 'i' (layout(location=0 ) in int) +0:7 'input' (in 3-element array of structure{temp float f, temp 4-component vector of float FragCoord pos}) +0:? Sequence +0:9 Sequence +0:9 move second child to first child (temp float) +0:9 f: direct index for structure (temp float) +0:9 direct index (layout(location=1 ) in structure{temp float f}) +0:9 'input' (layout(location=1 ) in 3-element array of structure{temp float f}) +0:9 Constant: +0:9 0 (const int) +0:9 Constant: +0:9 0 (const int) +0:9 f: direct index for structure (temp float) +0:9 direct index (temp structure{temp float f, temp 4-component vector of float pos}) +0:9 'a' (temp 3-element array of structure{temp float f, temp 4-component vector of float pos}) +0:9 Constant: +0:9 0 (const int) +0:9 Constant: +0:9 0 (const int) +0:9 move second child to first child (temp float) +0:9 f: direct index for structure (temp float) +0:9 direct index (layout(location=1 ) in structure{temp float f}) +0:9 'input' (layout(location=1 ) in 3-element array of structure{temp float f}) +0:9 Constant: +0:9 1 (const int) +0:9 Constant: +0:9 0 (const int) +0:9 f: direct index for structure (temp float) +0:9 direct index (temp structure{temp float f, temp 4-component vector of float pos}) +0:9 'a' (temp 3-element array of structure{temp float f, temp 4-component vector of float pos}) +0:9 Constant: +0:9 1 (const int) +0:9 Constant: +0:9 0 (const int) +0:9 move second child to first child (temp float) +0:9 f: direct index for structure (temp float) +0:9 direct index (layout(location=1 ) in structure{temp float f}) +0:9 'input' (layout(location=1 ) in 3-element array of structure{temp float f}) +0:9 Constant: +0:9 2 (const int) +0:9 Constant: +0:9 0 (const int) +0:9 f: direct index for structure (temp float) +0:9 direct index (temp structure{temp float f, temp 4-component vector of float pos}) +0:9 'a' (temp 3-element array of structure{temp float f, temp 4-component vector of float pos}) +0:9 Constant: +0:9 2 (const int) +0:9 Constant: +0:9 0 (const int) +0:11 Sequence +0:11 Branch: Return +0:? Linker Objects +0:? '@entryPointOutput' (layout(location=0 ) out 4-component vector of float) +0:? 'i' (layout(location=0 ) in int) +0:? 'input' (layout(location=1 ) in 3-element array of structure{temp float f}) +0:? 'input_pos' (in 3-element array of 4-component vector of float FragCoord) + + +Linked fragment stage: + + +Shader version: 450 +gl_FragCoord origin is upper left +0:? Sequence +0:7 Function Definition: main(i1;struct-S-f1-vf41[3]; (temp 4-component vector of float) +0:7 Function Parameters: +0:7 'i' (layout(location=0 ) in int) +0:7 'input' (in 3-element array of structure{temp float f, temp 4-component vector of float FragCoord pos}) +0:? Sequence +0:9 Sequence +0:9 move second child to first child (temp float) +0:9 f: direct index for structure (temp float) +0:9 direct index (layout(location=1 ) in structure{temp float f}) +0:9 'input' (layout(location=1 ) in 3-element array of structure{temp float f}) +0:9 Constant: +0:9 0 (const int) +0:9 Constant: +0:9 0 (const int) +0:9 f: direct index for structure (temp float) +0:9 direct index (temp structure{temp float f, temp 4-component vector of float pos}) +0:9 'a' (temp 3-element array of structure{temp float f, temp 4-component vector of float pos}) +0:9 Constant: +0:9 0 (const int) +0:9 Constant: +0:9 0 (const int) +0:9 move second child to first child (temp float) +0:9 f: direct index for structure (temp float) +0:9 direct index (layout(location=1 ) in structure{temp float f}) +0:9 'input' (layout(location=1 ) in 3-element array of structure{temp float f}) +0:9 Constant: +0:9 1 (const int) +0:9 Constant: +0:9 0 (const int) +0:9 f: direct index for structure (temp float) +0:9 direct index (temp structure{temp float f, temp 4-component vector of float pos}) +0:9 'a' (temp 3-element array of structure{temp float f, temp 4-component vector of float pos}) +0:9 Constant: +0:9 1 (const int) +0:9 Constant: +0:9 0 (const int) +0:9 move second child to first child (temp float) +0:9 f: direct index for structure (temp float) +0:9 direct index (layout(location=1 ) in structure{temp float f}) +0:9 'input' (layout(location=1 ) in 3-element array of structure{temp float f}) +0:9 Constant: +0:9 2 (const int) +0:9 Constant: +0:9 0 (const int) +0:9 f: direct index for structure (temp float) +0:9 direct index (temp structure{temp float f, temp 4-component vector of float pos}) +0:9 'a' (temp 3-element array of structure{temp float f, temp 4-component vector of float pos}) +0:9 Constant: +0:9 2 (const int) +0:9 Constant: +0:9 0 (const int) +0:11 Sequence +0:11 Branch: Return +0:? Linker Objects +0:? '@entryPointOutput' (layout(location=0 ) out 4-component vector of float) +0:? 'i' (layout(location=0 ) in int) +0:? 'input' (layout(location=1 ) in 3-element array of structure{temp float f}) +0:? 'input_pos' (in 3-element array of 4-component vector of float FragCoord) + +// Module Version 10000 +// Generated by (magic number): 80001 +// Id's are bound by 41 + + Capability Shader + 1: ExtInstImport "GLSL.std.450" + MemoryModel Logical GLSL450 + EntryPoint Fragment 4 "main" 12 35 37 40 + ExecutionMode 4 OriginUpperLeft + Name 4 "main" + Name 7 "S" + MemberName 7(S) 0 "f" + Name 12 "input" + Name 16 "S" + MemberName 16(S) 0 "f" + MemberName 16(S) 1 "pos" + Name 19 "a" + Name 35 "@entryPointOutput" + Name 37 "i" + Name 40 "input_pos" + Decorate 12(input) Location 1 + Decorate 35(@entryPointOutput) Location 0 + Decorate 37(i) Location 0 + Decorate 40(input_pos) BuiltIn FragCoord + 2: TypeVoid + 3: TypeFunction 2 + 6: TypeFloat 32 + 7(S): TypeStruct 6(float) + 8: TypeInt 32 0 + 9: 8(int) Constant 3 + 10: TypeArray 7(S) 9 + 11: TypePointer Input 10 + 12(input): 11(ptr) Variable Input + 13: TypeInt 32 1 + 14: 13(int) Constant 0 + 15: TypeVector 6(float) 4 + 16(S): TypeStruct 6(float) 15(fvec4) + 17: TypeArray 16(S) 9 + 18: TypePointer Function 17 + 20: TypePointer Function 6(float) + 23: TypePointer Input 6(float) + 25: 13(int) Constant 1 + 29: 13(int) Constant 2 + 34: TypePointer Output 15(fvec4) +35(@entryPointOutput): 34(ptr) Variable Output + 36: TypePointer Input 13(int) + 37(i): 36(ptr) Variable Input + 38: TypeArray 15(fvec4) 9 + 39: TypePointer Input 38 + 40(input_pos): 39(ptr) Variable Input + 4(main): 2 Function None 3 + 5: Label + 19(a): 18(ptr) Variable Function + 21: 20(ptr) AccessChain 19(a) 14 14 + 22: 6(float) Load 21 + 24: 23(ptr) AccessChain 12(input) 14 14 + Store 24 22 + 26: 20(ptr) AccessChain 19(a) 25 14 + 27: 6(float) Load 26 + 28: 23(ptr) AccessChain 12(input) 25 14 + Store 28 27 + 30: 20(ptr) AccessChain 19(a) 29 14 + 31: 6(float) Load 30 + 32: 23(ptr) AccessChain 12(input) 29 14 + Store 32 31 + Return + FunctionEnd diff --git a/Test/hlsl.struct.split.assign.frag b/Test/hlsl.struct.split.assign.frag new file mode 100644 index 00000000..e7fe0288 --- /dev/null +++ b/Test/hlsl.struct.split.assign.frag @@ -0,0 +1,12 @@ +struct S { + float f; + float4 pos : SV_Position; +}; + +float4 main(int i, S input[3]) : COLOR0 +{ + S a[3]; + input = a; + + return float3(1.0); +} diff --git a/gtests/Hlsl.FromFile.cpp b/gtests/Hlsl.FromFile.cpp index b6dde702..b703398c 100644 --- a/gtests/Hlsl.FromFile.cpp +++ b/gtests/Hlsl.FromFile.cpp @@ -211,6 +211,7 @@ INSTANTIATE_TEST_CASE_P( {"hlsl.string.frag", "main"}, {"hlsl.struct.split-1.vert", "main"}, {"hlsl.struct.split.array.geom", "main"}, + {"hlsl.struct.split.assign.frag", "main"}, {"hlsl.struct.split.call.vert", "main"}, {"hlsl.struct.split.nested.geom", "main"}, {"hlsl.struct.split.trivial.geom", "main"}, diff --git a/hlsl/hlslParseHelper.cpp b/hlsl/hlslParseHelper.cpp index 2e5b7331..1257e2d0 100755 --- a/hlsl/hlslParseHelper.cpp +++ b/hlsl/hlslParseHelper.cpp @@ -1827,10 +1827,6 @@ TIntermTyped* HlslParseContext::handleAssign(const TSourceLoc& loc, TOperator op // If the RHS is a simple symbol node, we'll copy it for each member. TIntermSymbol* cloneSymNode = nullptr; - // Array structs are not yet handled in flattening. (Compilation error upstream, so - // this should never fire). - assert(!(left->getType().isStruct() && left->getType().isArray())); - int memberCount = 0; // Track how many items there are to copy. @@ -1921,10 +1917,13 @@ TIntermTyped* HlslParseContext::handleAssign(const TSourceLoc& loc, TOperator op TIntermTyped* subLeft = getMember(true, left, element, left, element); TIntermTyped* subRight = getMember(false, right, element, right, element); + TIntermTyped* subSplitLeft = isSplitLeft ? getMember(true, left, element, splitLeft, element) : subLeft; + TIntermTyped* subSplitRight = isSplitRight ? getMember(false, right, element, splitRight, element) : subRight; + if (isFinalFlattening(dereferencedType)) assignList = intermediate.growAggregate(assignList, intermediate.addAssign(op, subLeft, subRight, loc), loc); else - traverse(subLeft, subRight, splitLeft, splitRight); + traverse(subLeft, subRight, subSplitLeft, subSplitRight); } } else if (left->getType().isStruct()) { // struct case