0:7 Function Definition: PixelShaderFunction(vf4;vf4;struct-OutParam-vf2-vi21; (global 4-component vector of float)
0:7 Function Parameters:
0:7 'input' (layout(location=0 ) in 4-component vector of float)
-0:7 'out1' (out 4-component vector of float)
-0:7 'out2' (out structure{temp 2-component vector of float v, temp 2-component vector of int i})
+0:7 'out1' (layout(location=1 ) out 4-component vector of float)
+0:7 'out2' (layout(location=2 ) out structure{temp 2-component vector of float v, temp 2-component vector of int i})
0:? Sequence
0:8 move second child to first child (temp 4-component vector of float)
-0:8 'out1' (out 4-component vector of float)
+0:8 'out1' (layout(location=1 ) out 4-component vector of float)
0:8 'input' (layout(location=0 ) in 4-component vector of float)
0:9 move second child to first child (temp 2-component vector of float)
-0:9 v: direct index for structure (temp 2-component vector of float)
-0:9 'out2' (out structure{temp 2-component vector of float v, temp 2-component vector of int i})
-0:9 Constant:
-0:9 0 (const int)
+0:? 'v' (layout(location=2 ) out 2-component vector of float)
0:9 Constant:
0:9 2.000000
0:9 2.000000
0:10 move second child to first child (temp 2-component vector of int)
-0:10 i: direct index for structure (temp 2-component vector of int)
-0:10 'out2' (out structure{temp 2-component vector of float v, temp 2-component vector of int i})
-0:10 Constant:
-0:10 1 (const int)
+0:? 'i' (layout(location=3 ) out 2-component vector of int)
0:10 Constant:
0:10 3 (const int)
0:10 3 (const int)
0:11 Sequence
0:11 move second child to first child (temp 4-component vector of float)
0:? '@entryPointOutput' (layout(location=0 ) out 4-component vector of float)
-0:11 'out1' (out 4-component vector of float)
+0:11 'out1' (layout(location=1 ) out 4-component vector of float)
0:11 Branch: Return
0:? Linker Objects
0:7 Function Definition: PixelShaderFunction(vf4;vf4;struct-OutParam-vf2-vi21; (global 4-component vector of float)
0:7 Function Parameters:
0:7 'input' (layout(location=0 ) in 4-component vector of float)
-0:7 'out1' (out 4-component vector of float)
-0:7 'out2' (out structure{temp 2-component vector of float v, temp 2-component vector of int i})
+0:7 'out1' (layout(location=1 ) out 4-component vector of float)
+0:7 'out2' (layout(location=2 ) out structure{temp 2-component vector of float v, temp 2-component vector of int i})
0:? Sequence
0:8 move second child to first child (temp 4-component vector of float)
-0:8 'out1' (out 4-component vector of float)
+0:8 'out1' (layout(location=1 ) out 4-component vector of float)
0:8 'input' (layout(location=0 ) in 4-component vector of float)
0:9 move second child to first child (temp 2-component vector of float)
-0:9 v: direct index for structure (temp 2-component vector of float)
-0:9 'out2' (out structure{temp 2-component vector of float v, temp 2-component vector of int i})
-0:9 Constant:
-0:9 0 (const int)
+0:? 'v' (layout(location=2 ) out 2-component vector of float)
0:9 Constant:
0:9 2.000000
0:9 2.000000
0:10 move second child to first child (temp 2-component vector of int)
-0:10 i: direct index for structure (temp 2-component vector of int)
-0:10 'out2' (out structure{temp 2-component vector of float v, temp 2-component vector of int i})
-0:10 Constant:
-0:10 1 (const int)
+0:? 'i' (layout(location=3 ) out 2-component vector of int)
0:10 Constant:
0:10 3 (const int)
0:10 3 (const int)
0:11 Sequence
0:11 move second child to first child (temp 4-component vector of float)
0:? '@entryPointOutput' (layout(location=0 ) out 4-component vector of float)
-0:11 'out1' (out 4-component vector of float)
+0:11 'out1' (layout(location=1 ) out 4-component vector of float)
0:11 Branch: Return
0:? Linker Objects
// Module Version 10000
// Generated by (magic number): 80001
-// Id's are bound by 32
+// Id's are bound by 27
Capability Shader
1: ExtInstImport "GLSL.std.450"
MemoryModel Logical GLSL450
- EntryPoint Fragment 4 "PixelShaderFunction" 9 11 18 29
+ EntryPoint Fragment 4 "PixelShaderFunction" 9 11 15 21 24
ExecutionMode 4 OriginUpperLeft
Name 4 "PixelShaderFunction"
Name 9 "out1"
Name 11 "input"
- Name 16 "OutParam"
- MemberName 16(OutParam) 0 "v"
- MemberName 16(OutParam) 1 "i"
- Name 18 "out2"
- Name 29 "@entryPointOutput"
+ Name 15 "v"
+ Name 21 "i"
+ Name 24 "@entryPointOutput"
+ Decorate 9(out1) Location 1
Decorate 11(input) Location 0
- Decorate 29(@entryPointOutput) Location 0
+ Decorate 15(v) Location 2
+ Decorate 21(i) Location 3
+ Decorate 24(@entryPointOutput) Location 0
2: TypeVoid
3: TypeFunction 2
6: TypeFloat 32
10: TypePointer Input 7(fvec4)
11(input): 10(ptr) Variable Input
13: TypeVector 6(float) 2
- 14: TypeInt 32 1
- 15: TypeVector 14(int) 2
- 16(OutParam): TypeStruct 13(fvec2) 15(ivec2)
- 17: TypePointer Output 16(OutParam)
- 18(out2): 17(ptr) Variable Output
- 19: 14(int) Constant 0
- 20: 6(float) Constant 1073741824
- 21: 13(fvec2) ConstantComposite 20 20
- 22: TypePointer Output 13(fvec2)
- 24: 14(int) Constant 1
- 25: 14(int) Constant 3
- 26: 15(ivec2) ConstantComposite 25 25
- 27: TypePointer Output 15(ivec2)
-29(@entryPointOutput): 8(ptr) Variable Output
+ 14: TypePointer Output 13(fvec2)
+ 15(v): 14(ptr) Variable Output
+ 16: 6(float) Constant 1073741824
+ 17: 13(fvec2) ConstantComposite 16 16
+ 18: TypeInt 32 1
+ 19: TypeVector 18(int) 2
+ 20: TypePointer Output 19(ivec2)
+ 21(i): 20(ptr) Variable Output
+ 22: 18(int) Constant 3
+ 23: 19(ivec2) ConstantComposite 22 22
+24(@entryPointOutput): 8(ptr) Variable Output
4(PixelShaderFunction): 2 Function None 3
5: Label
12: 7(fvec4) Load 11(input)
Store 9(out1) 12
- 23: 22(ptr) AccessChain 18(out2) 19
- Store 23 21
- 28: 27(ptr) AccessChain 18(out2) 24
- Store 28 26
- 30: 7(fvec4) Load 9(out1)
- Store 29(@entryPointOutput) 30
+ Store 15(v) 17
+ Store 21(i) 23
+ 25: 7(fvec4) Load 9(out1)
+ Store 24(@entryPointOutput) 25
Return
FunctionEnd
--- /dev/null
+hlsl.structin.vert
+Shader version: 450
+0:? Sequence
+0:7 Function Definition: main(vf4;struct-VI-vf4[2]-vu21;vf4; (global 4-component vector of float Position)
+0:7 Function Parameters:
+0:7 'd' (layout(location=0 ) in 4-component vector of float)
+0:7 'vi' (layout(location=1 ) in structure{temp 2-element array of 4-component vector of float m, temp 2-component vector of uint coord})
+0:7 'e' (layout(location=4 ) in 4-component vector of float)
+0:? Sequence
+0:8 Sequence
+0:8 move second child to first child (temp 4-component vector of float)
+0:? '@entryPointOutput' (out 4-component vector of float Position)
+0:8 add (temp 4-component vector of float)
+0:8 add (temp 4-component vector of float)
+0:8 add (temp 4-component vector of float)
+0:8 add (temp 4-component vector of float)
+0:8 direct index (layout(location=1 ) temp 4-component vector of float)
+0:? 'm' (layout(location=1 ) in 2-element array of 4-component vector of float)
+0:8 Constant:
+0:8 1 (const int)
+0:8 direct index (layout(location=1 ) temp 4-component vector of float)
+0:? 'm' (layout(location=1 ) in 2-element array of 4-component vector of float)
+0:8 Constant:
+0:8 0 (const int)
+0:8 Construct vec4 (temp 4-component vector of float)
+0:8 Convert uint to float (temp float)
+0:8 direct index (temp uint)
+0:? 'coord' (layout(location=3 ) in 2-component vector of uint)
+0:8 Constant:
+0:8 0 (const int)
+0:8 'd' (layout(location=0 ) in 4-component vector of float)
+0:8 'e' (layout(location=4 ) in 4-component vector of float)
+0:8 Branch: Return
+0:? Linker Objects
+
+
+Linked vertex stage:
+
+
+Shader version: 450
+0:? Sequence
+0:7 Function Definition: main(vf4;struct-VI-vf4[2]-vu21;vf4; (global 4-component vector of float Position)
+0:7 Function Parameters:
+0:7 'd' (layout(location=0 ) in 4-component vector of float)
+0:7 'vi' (layout(location=1 ) in structure{temp 2-element array of 4-component vector of float m, temp 2-component vector of uint coord})
+0:7 'e' (layout(location=4 ) in 4-component vector of float)
+0:? Sequence
+0:8 Sequence
+0:8 move second child to first child (temp 4-component vector of float)
+0:? '@entryPointOutput' (out 4-component vector of float Position)
+0:8 add (temp 4-component vector of float)
+0:8 add (temp 4-component vector of float)
+0:8 add (temp 4-component vector of float)
+0:8 add (temp 4-component vector of float)
+0:8 direct index (layout(location=1 ) temp 4-component vector of float)
+0:? 'm' (layout(location=1 ) in 2-element array of 4-component vector of float)
+0:8 Constant:
+0:8 1 (const int)
+0:8 direct index (layout(location=1 ) temp 4-component vector of float)
+0:? 'm' (layout(location=1 ) in 2-element array of 4-component vector of float)
+0:8 Constant:
+0:8 0 (const int)
+0:8 Construct vec4 (temp 4-component vector of float)
+0:8 Convert uint to float (temp float)
+0:8 direct index (temp uint)
+0:? 'coord' (layout(location=3 ) in 2-component vector of uint)
+0:8 Constant:
+0:8 0 (const int)
+0:8 'd' (layout(location=0 ) in 4-component vector of float)
+0:8 'e' (layout(location=4 ) in 4-component vector of float)
+0:8 Branch: Return
+0:? Linker Objects
+
+// 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 Vertex 4 "main" 9 14 26 34 37
+ Name 4 "main"
+ Name 9 "@entryPointOutput"
+ Name 14 "m"
+ Name 26 "coord"
+ Name 34 "d"
+ Name 37 "e"
+ Decorate 9(@entryPointOutput) BuiltIn Position
+ Decorate 14(m) Location 1
+ Decorate 26(coord) Location 3
+ Decorate 34(d) Location 0
+ Decorate 37(e) Location 4
+ 2: TypeVoid
+ 3: TypeFunction 2
+ 6: TypeFloat 32
+ 7: TypeVector 6(float) 4
+ 8: TypePointer Output 7(fvec4)
+9(@entryPointOutput): 8(ptr) Variable Output
+ 10: TypeInt 32 0
+ 11: 10(int) Constant 2
+ 12: TypeArray 7(fvec4) 11
+ 13: TypePointer Input 12
+ 14(m): 13(ptr) Variable Input
+ 15: TypeInt 32 1
+ 16: 15(int) Constant 1
+ 17: TypePointer Input 7(fvec4)
+ 20: 15(int) Constant 0
+ 24: TypeVector 10(int) 2
+ 25: TypePointer Input 24(ivec2)
+ 26(coord): 25(ptr) Variable Input
+ 27: 10(int) Constant 0
+ 28: TypePointer Input 10(int)
+ 34(d): 17(ptr) Variable Input
+ 37(e): 17(ptr) Variable Input
+ 4(main): 2 Function None 3
+ 5: Label
+ 18: 17(ptr) AccessChain 14(m) 16
+ 19: 7(fvec4) Load 18
+ 21: 17(ptr) AccessChain 14(m) 20
+ 22: 7(fvec4) Load 21
+ 23: 7(fvec4) FAdd 19 22
+ 29: 28(ptr) AccessChain 26(coord) 27
+ 30: 10(int) Load 29
+ 31: 6(float) ConvertUToF 30
+ 32: 7(fvec4) CompositeConstruct 31 31 31 31
+ 33: 7(fvec4) FAdd 23 32
+ 35: 7(fvec4) Load 34(d)
+ 36: 7(fvec4) FAdd 33 35
+ 38: 7(fvec4) Load 37(e)
+ 39: 7(fvec4) FAdd 36 38
+ Store 9(@entryPointOutput) 39
+ Return
+ FunctionEnd
--- /dev/null
+struct VI {
+ float4 m[2];
+ uint2 coord;
+};
+
+float4 main(float4 d, VI vi, float4 e) : SV_POSITION
+{
+ return vi.m[1] + vi.m[0] + float4(vi.coord.x) + d + e;
+}
\ No newline at end of file
// 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.1477"
-#define GLSLANG_DATE "09-Sep-2016"
+#define GLSLANG_REVISION "Overload400-PrecQual.1481"
+#define GLSLANG_DATE "10-Sep-2016"
{"hlsl.semicolons.frag", "main"},
{"hlsl.shapeConv.frag", "main"},
{"hlsl.stringtoken.frag", "main"},
+ {"hlsl.structin.vert", "main"},
{"hlsl.intrinsics.vert", "VertexShaderFunction"},
{"hlsl.matType.frag", "PixelShaderFunction"},
{"hlsl.max.frag", "PixelShaderFunction"},
}
}
if (fieldFound) {
- if (base->getType().getQualifier().storage == EvqConst)
- result = intermediate.foldDereference(base, member, loc);
+ if (base->getAsSymbolNode() && shouldFlatten(base->getType()))
+ result = flattenAccess(base, member);
else {
- TIntermTyped* index = intermediate.addConstantUnion(member, loc);
- result = intermediate.addIndex(EOpIndexDirectStruct, base, index, loc);
- result->setType(*(*fields)[member].type);
+ if (base->getType().getQualifier().storage == EvqConst)
+ result = intermediate.foldDereference(base, member, loc);
+ else {
+ TIntermTyped* index = intermediate.addConstantUnion(member, loc);
+ result = intermediate.addIndex(EOpIndexDirectStruct, base, index, loc);
+ result->setType(*(*fields)[member].type);
+ }
}
} else
error(loc, "no such field in structure", field.c_str(), "");
return result;
}
+// Is this a structure that can't be passed down the stack?
+// E.g., pipeline inputs to the vertex stage and outputs from the fragment stage.
+bool HlslParseContext::shouldFlatten(const TType& type)
+{
+ const TStorageQualifier qualifier = type.getQualifier().storage;
+
+ return type.isStruct() &&
+ ((language == EShLangVertex && qualifier == EvqVaryingIn) ||
+ (language == EShLangFragment && qualifier == EvqVaryingOut));
+}
+
+// Figure out mapping between a structures top members and an
+// equivalent set of individual variables.
+//
+// Assumes shouldFlatten() or equivalent was called first.
+//
+// TODO: generalize this to arbitrary nesting?
+void HlslParseContext::flattenStruct(const TVariable& variable)
+{
+ TVector<TVariable*> memberVariables;
+
+ auto members = *variable.getType().getStruct();
+ int location = variable.getType().getQualifier().layoutLocation;
+ for (int member = 0; member < (int)members.size(); ++member) {
+ TVariable* memberVariable = makeInternalVariable(members[member].type->getFieldName().c_str(), *members[member].type);
+ memberVariable->getWritableType().getQualifier() = variable.getType().getQualifier();
+ memberVariable->getWritableType().getQualifier().layoutLocation = location;
+ location += intermediate.computeTypeLocationSize(memberVariable->getType());
+ memberVariables.push_back(memberVariable);
+ }
+
+ flattenMap[variable.getUniqueId()] = memberVariables;
+}
+
+// Turn an access into structure that was flattened to instead be
+// an access to the individual variable the member was flattened to.
+// Assumes shouldFlatten() or equivalent was called first.
+TIntermTyped* HlslParseContext::flattenAccess(TIntermTyped* base, int member)
+{
+ const TIntermSymbol& symbolNode = *base->getAsSymbolNode();
+
+ if (flattenMap.find(symbolNode.getId()) == flattenMap.end())
+ return base;
+
+ const TVariable* memberVariable = flattenMap[symbolNode.getId()][member];
+ return intermediate.addSymbol(*memberVariable);
+}
+
//
// Handle seeing a function declarator in the grammar. This is the precursor
// to recognizing a function prototype or function definition.
paramNodes = intermediate.growAggregate(paramNodes,
intermediate.addSymbol(*variable, loc),
loc);
+
+ if (shouldFlatten(*param.type))
+ flattenStruct(*variable);
}
} else
paramNodes = intermediate.growAggregate(paramNodes, intermediate.addSymbol(*param.type, loc), loc);
// parameters are actually shader-scoped inputs and outputs (in or out)
for (int i = 0; i < function.getParamCount(); i++) {
- if (function[i].type->getQualifier().isParamInput()) {
- function[i].type->getQualifier().storage = EvqVaryingIn;
- if (function[i].type->getQualifier().builtIn == EbvNone) {
- function[i].type->getQualifier().layoutLocation = inCount;
+ TType& paramType = *function[i].type;
+ if (paramType.getQualifier().isParamInput()) {
+ paramType.getQualifier().storage = EvqVaryingIn;
+ if (paramType.getQualifier().builtIn == EbvNone) {
+ paramType.getQualifier().layoutLocation = inCount;
inCount += intermediate.computeTypeLocationSize(*function[i].type);
}
} else {
- function[i].type->getQualifier().storage = EvqVaryingOut;
- if (function[i].type->getQualifier().builtIn == EbvNone && language != EShLangFragment) {
- function[i].type->getQualifier().layoutLocation = outCount;
+ paramType.getQualifier().storage = EvqVaryingOut;
+ if (paramType.getQualifier().builtIn == EbvNone) {
+ paramType.getQualifier().layoutLocation = outCount;
outCount += intermediate.computeTypeLocationSize(*function[i].type);
}
}
- remapBuiltInType(*function[i].type);
+ remapBuiltInType(paramType);
}
}
TIntermTyped* handleBinaryMath(const TSourceLoc&, const char* str, TOperator op, TIntermTyped* left, TIntermTyped* right);
TIntermTyped* handleUnaryMath(const TSourceLoc&, const char* str, TOperator op, TIntermTyped* childNode);
TIntermTyped* handleDotDereference(const TSourceLoc&, TIntermTyped* base, const TString& field);
+ bool shouldFlatten(const TType&);
+ void flattenStruct(const TVariable& variable);
+ TIntermTyped* flattenAccess(TIntermTyped* base, int member);
TFunction& handleFunctionDeclarator(const TSourceLoc&, TFunction& function, bool prototype);
TIntermAggregate* handleFunctionDefinition(const TSourceLoc&, TFunction&);
void handleFunctionBody(const TSourceLoc&, TFunction&, TIntermNode* functionBody, TIntermNode*& node);
// array-sizing declarations
//
TVector<TSymbol*> ioArraySymbolResizeList;
+
+ TMap<int, TVector<TVariable*>> flattenMap;
};
} // end namespace glslang