HLSL: Handle flatten for reads from flatten structs and parameter passing.

This commit is contained in:
John Kessenich 2016-09-16 19:44:00 -06:00
parent 34e7ee79bb
commit d2ce838a58
5 changed files with 193 additions and 11 deletions

View File

@ -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

13
Test/hlsl.entry-in.frag Normal file
View File

@ -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;
}

View File

@ -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"

View File

@ -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"},

View File

@ -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<TVariable*>& 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);