diff --git a/Test/baseResults/hlsl.entry-in.frag.out b/Test/baseResults/hlsl.entry-in.frag.out new file mode 100755 index 00000000..e1a55bc3 --- /dev/null +++ b/Test/baseResults/hlsl.entry-in.frag.out @@ -0,0 +1,149 @@ +hlsl.entry-in.frag +Shader version: 450 +gl_FragCoord origin is upper left +0:? Sequence +0:8 Function Definition: PixelShaderFunction(struct-InParam-vf2-vf4-vi21; (global 4-component vector of float) +0:8 Function Parameters: +0:8 'i' (in structure{temp 2-component vector of float v, temp 4-component vector of float FragCoord fragCoord, temp 2-component vector of int i2}) +0:? Sequence +0:? Sequence +0:10 move second child to first child (temp 2-component vector of float) +0:10 v: direct index for structure (temp 2-component vector of float) +0:10 'local' (temp structure{temp 2-component vector of float v, temp 4-component vector of float FragCoord fragCoord, temp 2-component vector of int i2}) +0:10 Constant: +0:10 0 (const int) +0:? 'v' (layout(location=0 ) in 2-component vector of float) +0:10 move second child to first child (temp 4-component vector of float) +0:10 fragCoord: direct index for structure (temp 4-component vector of float FragCoord) +0:10 'local' (temp structure{temp 2-component vector of float v, temp 4-component vector of float FragCoord fragCoord, temp 2-component vector of int i2}) +0:10 Constant: +0:10 1 (const int) +0:? 'fragCoord' (in 4-component vector of float FragCoord) +0:10 move second child to first child (temp 2-component vector of int) +0:10 i2: direct index for structure (temp 2-component vector of int) +0:10 'local' (temp structure{temp 2-component vector of float v, temp 4-component vector of float FragCoord fragCoord, temp 2-component vector of int i2}) +0:10 Constant: +0:10 2 (const int) +0:? 'i2' (layout(location=1 ) in 2-component vector of int) +0:12 Sequence +0:12 move second child to first child (temp 4-component vector of float) +0:? '@entryPointOutput' (layout(location=0 ) out 4-component vector of float) +0:12 fragCoord: direct index for structure (temp 4-component vector of float FragCoord) +0:12 'local' (temp structure{temp 2-component vector of float v, temp 4-component vector of float FragCoord fragCoord, temp 2-component vector of int i2}) +0:12 Constant: +0:12 1 (const int) +0:12 Branch: Return +0:? Linker Objects +0:? '@entryPointOutput' (layout(location=0 ) out 4-component vector of float) +0:? 'v' (layout(location=0 ) in 2-component vector of float) +0:? 'fragCoord' (in 4-component vector of float FragCoord) +0:? 'i2' (layout(location=1 ) in 2-component vector of int) + + +Linked fragment stage: + + +Shader version: 450 +gl_FragCoord origin is upper left +0:? Sequence +0:8 Function Definition: PixelShaderFunction(struct-InParam-vf2-vf4-vi21; (global 4-component vector of float) +0:8 Function Parameters: +0:8 'i' (in structure{temp 2-component vector of float v, temp 4-component vector of float FragCoord fragCoord, temp 2-component vector of int i2}) +0:? Sequence +0:? Sequence +0:10 move second child to first child (temp 2-component vector of float) +0:10 v: direct index for structure (temp 2-component vector of float) +0:10 'local' (temp structure{temp 2-component vector of float v, temp 4-component vector of float FragCoord fragCoord, temp 2-component vector of int i2}) +0:10 Constant: +0:10 0 (const int) +0:? 'v' (layout(location=0 ) in 2-component vector of float) +0:10 move second child to first child (temp 4-component vector of float) +0:10 fragCoord: direct index for structure (temp 4-component vector of float FragCoord) +0:10 'local' (temp structure{temp 2-component vector of float v, temp 4-component vector of float FragCoord fragCoord, temp 2-component vector of int i2}) +0:10 Constant: +0:10 1 (const int) +0:? 'fragCoord' (in 4-component vector of float FragCoord) +0:10 move second child to first child (temp 2-component vector of int) +0:10 i2: direct index for structure (temp 2-component vector of int) +0:10 'local' (temp structure{temp 2-component vector of float v, temp 4-component vector of float FragCoord fragCoord, temp 2-component vector of int i2}) +0:10 Constant: +0:10 2 (const int) +0:? 'i2' (layout(location=1 ) in 2-component vector of int) +0:12 Sequence +0:12 move second child to first child (temp 4-component vector of float) +0:? '@entryPointOutput' (layout(location=0 ) out 4-component vector of float) +0:12 fragCoord: direct index for structure (temp 4-component vector of float FragCoord) +0:12 'local' (temp structure{temp 2-component vector of float v, temp 4-component vector of float FragCoord fragCoord, temp 2-component vector of int i2}) +0:12 Constant: +0:12 1 (const int) +0:12 Branch: Return +0:? Linker Objects +0:? '@entryPointOutput' (layout(location=0 ) out 4-component vector of float) +0:? 'v' (layout(location=0 ) in 2-component vector of float) +0:? 'fragCoord' (in 4-component vector of float FragCoord) +0:? 'i2' (layout(location=1 ) in 2-component vector of int) + +// Module Version 10000 +// Generated by (magic number): 80001 +// Id's are bound by 37 + + Capability Shader + 1: ExtInstImport "GLSL.std.450" + MemoryModel Logical GLSL450 + EntryPoint Fragment 4 "PixelShaderFunction" 16 22 28 33 + ExecutionMode 4 OriginUpperLeft + Name 4 "PixelShaderFunction" + Name 11 "InParam" + MemberName 11(InParam) 0 "v" + MemberName 11(InParam) 1 "fragCoord" + MemberName 11(InParam) 2 "i2" + Name 13 "local" + Name 16 "v" + Name 22 "fragCoord" + Name 28 "i2" + Name 33 "@entryPointOutput" + MemberDecorate 11(InParam) 1 BuiltIn FragCoord + Decorate 16(v) Location 0 + Decorate 22(fragCoord) BuiltIn FragCoord + Decorate 28(i2) Location 1 + Decorate 33(@entryPointOutput) Location 0 + 2: TypeVoid + 3: TypeFunction 2 + 6: TypeFloat 32 + 7: TypeVector 6(float) 2 + 8: TypeVector 6(float) 4 + 9: TypeInt 32 1 + 10: TypeVector 9(int) 2 + 11(InParam): TypeStruct 7(fvec2) 8(fvec4) 10(ivec2) + 12: TypePointer Function 11(InParam) + 14: 9(int) Constant 0 + 15: TypePointer Input 7(fvec2) + 16(v): 15(ptr) Variable Input + 18: TypePointer Function 7(fvec2) + 20: 9(int) Constant 1 + 21: TypePointer Input 8(fvec4) + 22(fragCoord): 21(ptr) Variable Input + 24: TypePointer Function 8(fvec4) + 26: 9(int) Constant 2 + 27: TypePointer Input 10(ivec2) + 28(i2): 27(ptr) Variable Input + 30: TypePointer Function 10(ivec2) + 32: TypePointer Output 8(fvec4) +33(@entryPointOutput): 32(ptr) Variable Output +4(PixelShaderFunction): 2 Function None 3 + 5: Label + 13(local): 12(ptr) Variable Function + 17: 7(fvec2) Load 16(v) + 19: 18(ptr) AccessChain 13(local) 14 + Store 19 17 + 23: 8(fvec4) Load 22(fragCoord) + 25: 24(ptr) AccessChain 13(local) 20 + Store 25 23 + 29: 10(ivec2) Load 28(i2) + 31: 30(ptr) AccessChain 13(local) 26 + Store 31 29 + 34: 24(ptr) AccessChain 13(local) 20 + 35: 8(fvec4) Load 34 + Store 33(@entryPointOutput) 35 + Return + FunctionEnd diff --git a/Test/hlsl.entry-in.frag b/Test/hlsl.entry-in.frag new file mode 100644 index 00000000..4d4ba50b --- /dev/null +++ b/Test/hlsl.entry-in.frag @@ -0,0 +1,13 @@ +struct InParam { + float2 v; + float4 fragCoord : SV_POSITION; + int2 i2; +}; + +float4 PixelShaderFunction(InParam i) : COLOR0 +{ + InParam local; + local = i; + + return local.fragCoord; +} diff --git a/glslang/Include/revision.h b/glslang/Include/revision.h index b1618c5c..0eb19923 100644 --- a/glslang/Include/revision.h +++ b/glslang/Include/revision.h @@ -2,5 +2,5 @@ // For the version, it uses the latest git tag followed by the number of commits. // For the date, it uses the current date (when then script is run). -#define GLSLANG_REVISION "Overload400-PrecQual.1490" +#define GLSLANG_REVISION "Overload400-PrecQual.1491" #define GLSLANG_DATE "16-Sep-2016" diff --git a/gtests/Hlsl.FromFile.cpp b/gtests/Hlsl.FromFile.cpp index d4206af2..06660c73 100644 --- a/gtests/Hlsl.FromFile.cpp +++ b/gtests/Hlsl.FromFile.cpp @@ -85,6 +85,7 @@ INSTANTIATE_TEST_CASE_P( {"hlsl.depthLess.frag", "PixelShaderFunction"}, {"hlsl.discard.frag", "PixelShaderFunction"}, {"hlsl.doLoop.frag", "PixelShaderFunction"}, + {"hlsl.entry-in.frag", "PixelShaderFunction"}, {"hlsl.entry-out.frag", "PixelShaderFunction"}, {"hlsl.float1.frag", "PixelShaderFunction"}, {"hlsl.float4.frag", "PixelShaderFunction"}, diff --git a/hlsl/hlslParseHelper.cpp b/hlsl/hlslParseHelper.cpp index 1b0cb345..b274653f 100755 --- a/hlsl/hlslParseHelper.cpp +++ b/hlsl/hlslParseHelper.cpp @@ -1037,20 +1037,39 @@ void HlslParseContext::handleFunctionArgument(TFunction* function, TIntermTyped* // to intermediate.addAssign(). TIntermTyped* HlslParseContext::handleAssign(const TSourceLoc& loc, TOperator op, TIntermTyped* left, TIntermTyped* right) { - if (! shouldFlatten(left->getType()) || - ! left->getAsSymbolNode() || - flattenMap.find(left->getAsSymbolNode()->getId()) == flattenMap.end()) + const auto mustFlatten = [&](const TIntermTyped& node) { + return shouldFlatten(node.getType()) && node.getAsSymbolNode() && + flattenMap.find(node.getAsSymbolNode()->getId()) != flattenMap.end(); + }; + + bool flattenLeft = mustFlatten(*left); + bool flattenRight = mustFlatten(*right); + if (! flattenLeft && ! flattenRight) return intermediate.addAssign(op, left, right, loc); - // If we get here, we are assigning a whole struct to a flattened l-value, so have to - // do member-by-member assignment: + // If we get here, we are assigning to or from a whole struct that must be + // flattened, so have to do member-by-member assignment: const auto& members = *left->getType().getStruct(); - const auto& memberVariables = flattenMap[left->getAsSymbolNode()->getId()]; + const auto getMember = [&](bool flatten, TIntermTyped* node, + const TVector& memberVariables, int member) { + TIntermTyped* subTree; + if (flatten) + subTree = intermediate.addSymbol(*memberVariables[member]); + else { + subTree = intermediate.addIndex(EOpIndexDirectStruct, node, + intermediate.addConstantUnion(member, loc), loc); + subTree->setType(*members[member].type); + } + + return subTree; + }; + + const auto& leftVariables = flattenMap[left->getAsSymbolNode()->getId()]; + const auto& rightVariables = flattenMap[right->getAsSymbolNode()->getId()]; TIntermAggregate* assignList = nullptr; - for (int member = 0; member < (int)memberVariables.size(); ++member) { - TIntermTyped* subRight = intermediate.addIndex(EOpIndexDirectStruct, right, intermediate.addConstantUnion(member, loc), loc); - subRight->setType(*members[member].type); - TIntermTyped* subLeft = intermediate.addSymbol(*memberVariables[member]); + for (int member = 0; member < (int)members.size(); ++member) { + TIntermTyped* subRight = getMember(flattenRight, right, rightVariables, member); + TIntermTyped* subLeft = getMember(flattenLeft, left, leftVariables, member); assignList = intermediate.growAggregate(assignList, intermediate.addAssign(op, subLeft, subRight, loc)); } assignList->setOperator(EOpSequence);