HLSL: Handle flattened I/O structs passed to function *out* parameters.

This commit is contained in:
John Kessenich 2016-10-01 17:11:21 -06:00
parent c86d38bb2b
commit d8fe2ca8e5
4 changed files with 270 additions and 197 deletions

View File

@ -2,60 +2,83 @@ hlsl.entry-out.frag
Shader version: 450 Shader version: 450
gl_FragCoord origin is upper left gl_FragCoord origin is upper left
0:? Sequence 0:? Sequence
0:7 Function Definition: PixelShaderFunction(vf4;vf4;struct-OutParam-vf2-vi21;struct-OutParam-vf2-vi21; (temp 4-component vector of float) 0:7 Function Definition: fun(struct-OutParam-vf2-vi21; (temp void)
0:7 Function Parameters: 0:7 Function Parameters:
0:7 'input' (layout(location=0 ) in 4-component vector of float) 0:7 'op' (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' (out structure{temp 2-component vector of float v, temp 2-component vector of int i})
0:7 'out3' (out structure{temp 2-component vector of float v, temp 2-component vector of int i})
0:? Sequence 0:? Sequence
0:8 move second child to first child (temp 4-component vector of float) 0:8 move second child to first child (temp 2-component vector of float)
0:8 'out1' (layout(location=1 ) out 4-component vector of float) 0:8 v: direct index for structure (temp 2-component vector of float)
0:8 'input' (layout(location=0 ) in 4-component vector of float) 0:8 'op' (out structure{temp 2-component vector of float v, temp 2-component vector of int i})
0:9 move second child to first child (temp 2-component vector of float) 0:8 Constant:
0:? 'v' (layout(location=2 ) out 2-component vector of float) 0:8 0 (const int)
0:8 Constant:
0:8 0.400000
0:8 0.400000
0:9 move second child to first child (temp 2-component vector of int)
0:9 i: direct index for structure (temp 2-component vector of int)
0:9 'op' (out structure{temp 2-component vector of float v, temp 2-component vector of int i})
0:9 Constant:
0:9 1 (const int)
0:9 Constant: 0:9 Constant:
0:9 2.000000 0:9 7 (const int)
0:9 2.000000 0:9 7 (const int)
0:10 move second child to first child (temp 2-component vector of int) 0:13 Function Definition: PixelShaderFunction(vf4;vf4;struct-OutParam-vf2-vi21;struct-OutParam-vf2-vi21; (temp 4-component vector of float)
0:13 Function Parameters:
0:13 'input' (layout(location=0 ) in 4-component vector of float)
0:13 'out1' (layout(location=1 ) out 4-component vector of float)
0:13 'out2' (out structure{temp 2-component vector of float v, temp 2-component vector of int i})
0:13 'out3' (out structure{temp 2-component vector of float v, temp 2-component vector of int i})
0:? Sequence
0:14 move second child to first child (temp 4-component vector of float)
0:14 'out1' (layout(location=1 ) out 4-component vector of float)
0:14 'input' (layout(location=0 ) in 4-component vector of float)
0:15 move second child to first child (temp 2-component vector of float)
0:? 'v' (layout(location=2 ) out 2-component vector of float)
0:15 Constant:
0:15 2.000000
0:15 2.000000
0:16 move second child to first child (temp 2-component vector of int)
0:? 'i' (layout(location=3 ) out 2-component vector of int) 0:? 'i' (layout(location=3 ) out 2-component vector of int)
0:10 Constant: 0:16 Constant:
0:10 3 (const int) 0:16 3 (const int)
0:10 3 (const int) 0:16 3 (const int)
0:12 move second child to first child (temp 2-component vector of float) 0:18 move second child to first child (temp 2-component vector of float)
0:12 v: direct index for structure (temp 2-component vector of float) 0:18 v: direct index for structure (temp 2-component vector of float)
0:12 'local' (temp structure{temp 2-component vector of float v, temp 2-component vector of int i}) 0:18 'local' (temp structure{temp 2-component vector of float v, temp 2-component vector of int i})
0:12 Constant: 0:18 Constant:
0:12 0 (const int) 0:18 0 (const int)
0:12 Constant: 0:18 Constant:
0:12 12.000000 0:18 12.000000
0:12 12.000000 0:18 12.000000
0:13 move second child to first child (temp 2-component vector of int) 0:19 move second child to first child (temp 2-component vector of int)
0:13 i: direct index for structure (temp 2-component vector of int) 0:19 i: direct index for structure (temp 2-component vector of int)
0:13 'local' (temp structure{temp 2-component vector of float v, temp 2-component vector of int i}) 0:19 'local' (temp structure{temp 2-component vector of float v, temp 2-component vector of int i})
0:13 Constant: 0:19 Constant:
0:13 1 (const int) 0:19 1 (const int)
0:13 Constant: 0:19 Constant:
0:13 13 (const int) 0:19 13 (const int)
0:13 13 (const int) 0:19 13 (const int)
0:? Sequence 0:20 Comma (temp void)
0:14 move second child to first child (temp 2-component vector of float) 0:20 Function Call: fun(struct-OutParam-vf2-vi21; (temp void)
0:? 'v' (layout(location=4 ) out 2-component vector of float) 0:20 'tempArg' (temp structure{temp 2-component vector of float v, temp 2-component vector of int i})
0:14 v: direct index for structure (temp 2-component vector of float) 0:? Sequence
0:14 'local' (temp structure{temp 2-component vector of float v, temp 2-component vector of int i}) 0:20 move second child to first child (temp 2-component vector of float)
0:14 Constant: 0:? 'v' (layout(location=4 ) out 2-component vector of float)
0:14 0 (const int) 0:20 v: direct index for structure (temp 2-component vector of float)
0:14 move second child to first child (temp 2-component vector of int) 0:20 'tempArg' (temp structure{temp 2-component vector of float v, temp 2-component vector of int i})
0:? 'i' (layout(location=5 ) out 2-component vector of int) 0:20 Constant:
0:14 i: direct index for structure (temp 2-component vector of int) 0:20 0 (const int)
0:14 'local' (temp structure{temp 2-component vector of float v, temp 2-component vector of int i}) 0:20 move second child to first child (temp 2-component vector of int)
0:14 Constant: 0:? 'i' (layout(location=5 ) out 2-component vector of int)
0:14 1 (const int) 0:20 i: direct index for structure (temp 2-component vector of int)
0:16 Sequence 0:20 'tempArg' (temp structure{temp 2-component vector of float v, temp 2-component vector of int i})
0:16 move second child to first child (temp 4-component vector of float) 0:20 Constant:
0:20 1 (const int)
0:22 Sequence
0:22 move second child to first child (temp 4-component vector of float)
0:? '@entryPointOutput' (layout(location=0 ) out 4-component vector of float) 0:? '@entryPointOutput' (layout(location=0 ) out 4-component vector of float)
0:16 'out1' (layout(location=1 ) out 4-component vector of float) 0:22 'out1' (layout(location=1 ) out 4-component vector of float)
0:16 Branch: Return 0:22 Branch: Return
0:? Linker Objects 0:? Linker Objects
0:? '@entryPointOutput' (layout(location=0 ) out 4-component vector of float) 0:? '@entryPointOutput' (layout(location=0 ) out 4-component vector of float)
0:? 'input' (layout(location=0 ) in 4-component vector of float) 0:? 'input' (layout(location=0 ) in 4-component vector of float)
@ -72,60 +95,83 @@ Linked fragment stage:
Shader version: 450 Shader version: 450
gl_FragCoord origin is upper left gl_FragCoord origin is upper left
0:? Sequence 0:? Sequence
0:7 Function Definition: PixelShaderFunction(vf4;vf4;struct-OutParam-vf2-vi21;struct-OutParam-vf2-vi21; (temp 4-component vector of float) 0:7 Function Definition: fun(struct-OutParam-vf2-vi21; (temp void)
0:7 Function Parameters: 0:7 Function Parameters:
0:7 'input' (layout(location=0 ) in 4-component vector of float) 0:7 'op' (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' (out structure{temp 2-component vector of float v, temp 2-component vector of int i})
0:7 'out3' (out structure{temp 2-component vector of float v, temp 2-component vector of int i})
0:? Sequence 0:? Sequence
0:8 move second child to first child (temp 4-component vector of float) 0:8 move second child to first child (temp 2-component vector of float)
0:8 'out1' (layout(location=1 ) out 4-component vector of float) 0:8 v: direct index for structure (temp 2-component vector of float)
0:8 'input' (layout(location=0 ) in 4-component vector of float) 0:8 'op' (out structure{temp 2-component vector of float v, temp 2-component vector of int i})
0:9 move second child to first child (temp 2-component vector of float) 0:8 Constant:
0:? 'v' (layout(location=2 ) out 2-component vector of float) 0:8 0 (const int)
0:8 Constant:
0:8 0.400000
0:8 0.400000
0:9 move second child to first child (temp 2-component vector of int)
0:9 i: direct index for structure (temp 2-component vector of int)
0:9 'op' (out structure{temp 2-component vector of float v, temp 2-component vector of int i})
0:9 Constant:
0:9 1 (const int)
0:9 Constant: 0:9 Constant:
0:9 2.000000 0:9 7 (const int)
0:9 2.000000 0:9 7 (const int)
0:10 move second child to first child (temp 2-component vector of int) 0:13 Function Definition: PixelShaderFunction(vf4;vf4;struct-OutParam-vf2-vi21;struct-OutParam-vf2-vi21; (temp 4-component vector of float)
0:13 Function Parameters:
0:13 'input' (layout(location=0 ) in 4-component vector of float)
0:13 'out1' (layout(location=1 ) out 4-component vector of float)
0:13 'out2' (out structure{temp 2-component vector of float v, temp 2-component vector of int i})
0:13 'out3' (out structure{temp 2-component vector of float v, temp 2-component vector of int i})
0:? Sequence
0:14 move second child to first child (temp 4-component vector of float)
0:14 'out1' (layout(location=1 ) out 4-component vector of float)
0:14 'input' (layout(location=0 ) in 4-component vector of float)
0:15 move second child to first child (temp 2-component vector of float)
0:? 'v' (layout(location=2 ) out 2-component vector of float)
0:15 Constant:
0:15 2.000000
0:15 2.000000
0:16 move second child to first child (temp 2-component vector of int)
0:? 'i' (layout(location=3 ) out 2-component vector of int) 0:? 'i' (layout(location=3 ) out 2-component vector of int)
0:10 Constant: 0:16 Constant:
0:10 3 (const int) 0:16 3 (const int)
0:10 3 (const int) 0:16 3 (const int)
0:12 move second child to first child (temp 2-component vector of float) 0:18 move second child to first child (temp 2-component vector of float)
0:12 v: direct index for structure (temp 2-component vector of float) 0:18 v: direct index for structure (temp 2-component vector of float)
0:12 'local' (temp structure{temp 2-component vector of float v, temp 2-component vector of int i}) 0:18 'local' (temp structure{temp 2-component vector of float v, temp 2-component vector of int i})
0:12 Constant: 0:18 Constant:
0:12 0 (const int) 0:18 0 (const int)
0:12 Constant: 0:18 Constant:
0:12 12.000000 0:18 12.000000
0:12 12.000000 0:18 12.000000
0:13 move second child to first child (temp 2-component vector of int) 0:19 move second child to first child (temp 2-component vector of int)
0:13 i: direct index for structure (temp 2-component vector of int) 0:19 i: direct index for structure (temp 2-component vector of int)
0:13 'local' (temp structure{temp 2-component vector of float v, temp 2-component vector of int i}) 0:19 'local' (temp structure{temp 2-component vector of float v, temp 2-component vector of int i})
0:13 Constant: 0:19 Constant:
0:13 1 (const int) 0:19 1 (const int)
0:13 Constant: 0:19 Constant:
0:13 13 (const int) 0:19 13 (const int)
0:13 13 (const int) 0:19 13 (const int)
0:? Sequence 0:20 Comma (temp void)
0:14 move second child to first child (temp 2-component vector of float) 0:20 Function Call: fun(struct-OutParam-vf2-vi21; (temp void)
0:? 'v' (layout(location=4 ) out 2-component vector of float) 0:20 'tempArg' (temp structure{temp 2-component vector of float v, temp 2-component vector of int i})
0:14 v: direct index for structure (temp 2-component vector of float) 0:? Sequence
0:14 'local' (temp structure{temp 2-component vector of float v, temp 2-component vector of int i}) 0:20 move second child to first child (temp 2-component vector of float)
0:14 Constant: 0:? 'v' (layout(location=4 ) out 2-component vector of float)
0:14 0 (const int) 0:20 v: direct index for structure (temp 2-component vector of float)
0:14 move second child to first child (temp 2-component vector of int) 0:20 'tempArg' (temp structure{temp 2-component vector of float v, temp 2-component vector of int i})
0:? 'i' (layout(location=5 ) out 2-component vector of int) 0:20 Constant:
0:14 i: direct index for structure (temp 2-component vector of int) 0:20 0 (const int)
0:14 'local' (temp structure{temp 2-component vector of float v, temp 2-component vector of int i}) 0:20 move second child to first child (temp 2-component vector of int)
0:14 Constant: 0:? 'i' (layout(location=5 ) out 2-component vector of int)
0:14 1 (const int) 0:20 i: direct index for structure (temp 2-component vector of int)
0:16 Sequence 0:20 'tempArg' (temp structure{temp 2-component vector of float v, temp 2-component vector of int i})
0:16 move second child to first child (temp 4-component vector of float) 0:20 Constant:
0:20 1 (const int)
0:22 Sequence
0:22 move second child to first child (temp 4-component vector of float)
0:? '@entryPointOutput' (layout(location=0 ) out 4-component vector of float) 0:? '@entryPointOutput' (layout(location=0 ) out 4-component vector of float)
0:16 'out1' (layout(location=1 ) out 4-component vector of float) 0:22 'out1' (layout(location=1 ) out 4-component vector of float)
0:16 Branch: Return 0:22 Branch: Return
0:? Linker Objects 0:? Linker Objects
0:? '@entryPointOutput' (layout(location=0 ) out 4-component vector of float) 0:? '@entryPointOutput' (layout(location=0 ) out 4-component vector of float)
0:? 'input' (layout(location=0 ) in 4-component vector of float) 0:? 'input' (layout(location=0 ) in 4-component vector of float)
@ -137,82 +183,105 @@ gl_FragCoord origin is upper left
// Module Version 10000 // Module Version 10000
// Generated by (magic number): 80001 // Generated by (magic number): 80001
// Id's are bound by 46 // Id's are bound by 60
Capability Shader Capability Shader
1: ExtInstImport "GLSL.std.450" 1: ExtInstImport "GLSL.std.450"
MemoryModel Logical GLSL450 MemoryModel Logical GLSL450
EntryPoint Fragment 4 "PixelShaderFunction" 9 11 15 21 37 40 43 EntryPoint Fragment 4 "PixelShaderFunction" 28 30 33 37 51 54 57
ExecutionMode 4 OriginUpperLeft ExecutionMode 4 OriginUpperLeft
Name 4 "PixelShaderFunction" Name 4 "PixelShaderFunction"
Name 9 "out1" Name 10 "OutParam"
Name 11 "input" MemberName 10(OutParam) 0 "v"
Name 15 "v" MemberName 10(OutParam) 1 "i"
Name 21 "i" Name 14 "fun(struct-OutParam-vf2-vi21;"
Name 24 "OutParam" Name 13 "op"
MemberName 24(OutParam) 0 "v" Name 28 "out1"
MemberName 24(OutParam) 1 "i" Name 30 "input"
Name 26 "local" Name 33 "v"
Name 37 "v" Name 37 "i"
Name 40 "i" Name 40 "local"
Name 43 "@entryPointOutput" Name 47 "tempArg"
Decorate 9(out1) Location 1 Name 48 "param"
Decorate 11(input) Location 0 Name 51 "v"
Decorate 15(v) Location 2 Name 54 "i"
Decorate 21(i) Location 3 Name 57 "@entryPointOutput"
Decorate 37(v) Location 4 Decorate 28(out1) Location 1
Decorate 40(i) Location 5 Decorate 30(input) Location 0
Decorate 43(@entryPointOutput) Location 0 Decorate 33(v) Location 2
Decorate 37(i) Location 3
Decorate 51(v) Location 4
Decorate 54(i) Location 5
Decorate 57(@entryPointOutput) Location 0
2: TypeVoid 2: TypeVoid
3: TypeFunction 2 3: TypeFunction 2
6: TypeFloat 32 6: TypeFloat 32
7: TypeVector 6(float) 4 7: TypeVector 6(float) 2
8: TypePointer Output 7(fvec4) 8: TypeInt 32 1
9(out1): 8(ptr) Variable Output 9: TypeVector 8(int) 2
10: TypePointer Input 7(fvec4) 10(OutParam): TypeStruct 7(fvec2) 9(ivec2)
11(input): 10(ptr) Variable Input 11: TypePointer Function 10(OutParam)
13: TypeVector 6(float) 2 12: TypeFunction 2 11(ptr)
14: TypePointer Output 13(fvec2) 16: 8(int) Constant 0
15(v): 14(ptr) Variable Output 17: 6(float) Constant 1053609165
16: 6(float) Constant 1073741824 18: 7(fvec2) ConstantComposite 17 17
17: 13(fvec2) ConstantComposite 16 16 19: TypePointer Function 7(fvec2)
18: TypeInt 32 1 21: 8(int) Constant 1
19: TypeVector 18(int) 2 22: 8(int) Constant 7
20: TypePointer Output 19(ivec2) 23: 9(ivec2) ConstantComposite 22 22
21(i): 20(ptr) Variable Output 24: TypePointer Function 9(ivec2)
22: 18(int) Constant 3 26: TypeVector 6(float) 4
23: 19(ivec2) ConstantComposite 22 22 27: TypePointer Output 26(fvec4)
24(OutParam): TypeStruct 13(fvec2) 19(ivec2) 28(out1): 27(ptr) Variable Output
25: TypePointer Function 24(OutParam) 29: TypePointer Input 26(fvec4)
27: 18(int) Constant 0 30(input): 29(ptr) Variable Input
28: 6(float) Constant 1094713344 32: TypePointer Output 7(fvec2)
29: 13(fvec2) ConstantComposite 28 28 33(v): 32(ptr) Variable Output
30: TypePointer Function 13(fvec2) 34: 6(float) Constant 1073741824
32: 18(int) Constant 1 35: 7(fvec2) ConstantComposite 34 34
33: 18(int) Constant 13 36: TypePointer Output 9(ivec2)
34: 19(ivec2) ConstantComposite 33 33 37(i): 36(ptr) Variable Output
35: TypePointer Function 19(ivec2) 38: 8(int) Constant 3
37(v): 14(ptr) Variable Output 39: 9(ivec2) ConstantComposite 38 38
40(i): 20(ptr) Variable Output 41: 6(float) Constant 1094713344
43(@entryPointOutput): 8(ptr) Variable Output 42: 7(fvec2) ConstantComposite 41 41
44: 8(int) Constant 13
45: 9(ivec2) ConstantComposite 44 44
51(v): 32(ptr) Variable Output
54(i): 36(ptr) Variable Output
57(@entryPointOutput): 27(ptr) Variable Output
4(PixelShaderFunction): 2 Function None 3 4(PixelShaderFunction): 2 Function None 3
5: Label 5: Label
26(local): 25(ptr) Variable Function 40(local): 11(ptr) Variable Function
12: 7(fvec4) Load 11(input) 47(tempArg): 11(ptr) Variable Function
Store 9(out1) 12 48(param): 11(ptr) Variable Function
Store 15(v) 17 31: 26(fvec4) Load 30(input)
Store 21(i) 23 Store 28(out1) 31
31: 30(ptr) AccessChain 26(local) 27 Store 33(v) 35
Store 31 29 Store 37(i) 39
36: 35(ptr) AccessChain 26(local) 32 43: 19(ptr) AccessChain 40(local) 16
Store 36 34 Store 43 42
38: 30(ptr) AccessChain 26(local) 27 46: 24(ptr) AccessChain 40(local) 21
39: 13(fvec2) Load 38 Store 46 45
Store 37(v) 39 49: 2 FunctionCall 14(fun(struct-OutParam-vf2-vi21;) 48(param)
41: 35(ptr) AccessChain 26(local) 32 50:10(OutParam) Load 48(param)
42: 19(ivec2) Load 41 Store 47(tempArg) 50
Store 40(i) 42 52: 19(ptr) AccessChain 47(tempArg) 16
44: 7(fvec4) Load 9(out1) 53: 7(fvec2) Load 52
Store 43(@entryPointOutput) 44 Store 51(v) 53
55: 24(ptr) AccessChain 47(tempArg) 21
56: 9(ivec2) Load 55
Store 54(i) 56
58: 26(fvec4) Load 28(out1)
Store 57(@entryPointOutput) 58
Return
FunctionEnd
14(fun(struct-OutParam-vf2-vi21;): 2 Function None 12
13(op): 11(ptr) FunctionParameter
15: Label
20: 19(ptr) AccessChain 13(op) 16
Store 20 18
25: 24(ptr) AccessChain 13(op) 21
Store 25 23
Return Return
FunctionEnd FunctionEnd

View File

@ -3,6 +3,12 @@ struct OutParam {
int2 i; int2 i;
}; };
void fun(out OutParam op)
{
op.v = float2(0.4);
op.i = int2(7);
}
float4 PixelShaderFunction(float4 input, out float4 out1, out OutParam out2, out OutParam out3) : COLOR0 float4 PixelShaderFunction(float4 input, out float4 out1, out OutParam out2, out OutParam out3) : COLOR0
{ {
out1 = input; out1 = input;
@ -11,7 +17,7 @@ float4 PixelShaderFunction(float4 input, out float4 out1, out OutParam out2, out
OutParam local; OutParam local;
local.v = 12.0; local.v = 12.0;
local.i = 13; local.i = 13;
out3 = local; fun(out3);
return out1; return out1;
} }

View File

@ -2,5 +2,5 @@
// For the version, it uses the latest git tag followed by the number of commits. // 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). // For the date, it uses the current date (when then script is run).
#define GLSLANG_REVISION "Overload400-PrecQual.1543" #define GLSLANG_REVISION "Overload400-PrecQual.1544"
#define GLSLANG_DATE "01-Oct-2016" #define GLSLANG_DATE "01-Oct-2016"

View File

@ -2246,21 +2246,9 @@ TIntermTyped* HlslParseContext::handleFunctionCall(const TSourceLoc& loc, TFunct
if (builtIn && fnCandidate->getNumExtensions()) if (builtIn && fnCandidate->getNumExtensions())
requireExtensions(loc, fnCandidate->getNumExtensions(), fnCandidate->getExtensions(), fnCandidate->getName().c_str()); requireExtensions(loc, fnCandidate->getNumExtensions(), fnCandidate->getExtensions(), fnCandidate->getName().c_str());
if (arguments) { // Convert 'in' arguments
// Make sure qualifications work for these arguments. if (arguments)
//TIntermAggregate* aggregate = arguments->getAsAggregate(); addInputArgumentConversions(*fnCandidate, arguments);
//for (int i = 0; i < fnCandidate->getParamCount(); ++i) {
// // At this early point there is a slight ambiguity between whether an aggregate 'arguments'
// // is the single argument itself or its children are the arguments. Only one argument
// // means take 'arguments' itself as the one argument.
// TIntermNode* arg = fnCandidate->getParamCount() == 1 ? arguments : (aggregate ? aggregate->getSequence()[i] : arguments);
// TQualifier& formalQualifier = (*fnCandidate)[i].type->getQualifier();
// TQualifier& argQualifier = arg->getAsTyped()->getQualifier();
//}
// Convert 'in' arguments
addInputArgumentConversions(*fnCandidate, arguments); // arguments may be modified if it's just a single argument node
}
op = fnCandidate->getBuiltInOp(); op = fnCandidate->getBuiltInOp();
if (builtIn && op != EOpNull) { if (builtIn && op != EOpNull) {
@ -2390,7 +2378,9 @@ void HlslParseContext::addInputArgumentConversions(const TFunction& function, TI
// At this early point there is a slight ambiguity between whether an aggregate 'arguments' // At this early point there is a slight ambiguity between whether an aggregate 'arguments'
// is the single argument itself or its children are the arguments. Only one argument // is the single argument itself or its children are the arguments. Only one argument
// means take 'arguments' itself as the one argument. // means take 'arguments' itself as the one argument.
TIntermTyped* arg = function.getParamCount() == 1 ? arguments->getAsTyped() : (aggregate ? aggregate->getSequence()[i]->getAsTyped() : arguments->getAsTyped()); TIntermTyped* arg = function.getParamCount() == 1
? arguments->getAsTyped()
: (aggregate ? aggregate->getSequence()[i]->getAsTyped() : arguments->getAsTyped());
if (*function[i].type != arg->getType()) { if (*function[i].type != arg->getType()) {
// In-qualified arguments just need an extra node added above the argument to // In-qualified arguments just need an extra node added above the argument to
// convert to the correct type. // convert to the correct type.
@ -2401,9 +2391,9 @@ void HlslParseContext::addInputArgumentConversions(const TFunction& function, TI
if (shouldFlatten(arg->getType())) { if (shouldFlatten(arg->getType())) {
// Will make a two-level subtree. // Will make a two-level subtree.
// The deepest will copy member-by-member to build the structure to pass. // The deepest will copy member-by-member to build the structure to pass.
// The level above that will be an two-operand EOpComma sequence that follows the copy by the // The level above that will be a two-operand EOpComma sequence that follows the copy by the
// object itself. // object itself.
TSourceLoc dummyLoc; TSourceLoc dummyLoc; // ?? fix these everywhere to be arguments[i]->getLoc()?
dummyLoc.init(); dummyLoc.init();
TVariable* internalAggregate = makeInternalVariable("aggShadow", *function[i].type); TVariable* internalAggregate = makeInternalVariable("aggShadow", *function[i].type);
internalAggregate->getWritableType().getQualifier().makeTemporary(); internalAggregate->getWritableType().getQualifier().makeTemporary();
@ -2433,11 +2423,16 @@ void HlslParseContext::addInputArgumentConversions(const TFunction& function, TI
TIntermTyped* HlslParseContext::addOutputArgumentConversions(const TFunction& function, TIntermAggregate& intermNode) const TIntermTyped* HlslParseContext::addOutputArgumentConversions(const TFunction& function, TIntermAggregate& intermNode) const
{ {
TIntermSequence& arguments = intermNode.getSequence(); TIntermSequence& arguments = intermNode.getSequence();
const auto needsConversion = [&](int argNum) {
return function[argNum].type->getQualifier().isParamOutput() &&
(*function[argNum].type != arguments[argNum]->getAsTyped()->getType() ||
shouldFlatten(arguments[argNum]->getAsTyped()->getType()));
};
// Will there be any output conversions? // Will there be any output conversions?
bool outputConversions = false; bool outputConversions = false;
for (int i = 0; i < function.getParamCount(); ++i) { for (int i = 0; i < function.getParamCount(); ++i) {
if (*function[i].type != arguments[i]->getAsTyped()->getType() && function[i].type->getQualifier().isParamOutput()) { if (needsConversion(i)) {
outputConversions = true; outputConversions = true;
break; break;
} }
@ -2468,18 +2463,21 @@ TIntermTyped* HlslParseContext::addOutputArgumentConversions(const TFunction& fu
// Process each argument's conversion // Process each argument's conversion
for (int i = 0; i < function.getParamCount(); ++i) { for (int i = 0; i < function.getParamCount(); ++i) {
if (*function[i].type != arguments[i]->getAsTyped()->getType()) { if (needsConversion(i)) {
if (function[i].type->getQualifier().isParamOutput()) { // Out-qualified arguments needing conversion need to use the topology setup above.
// Out-qualified arguments need to use the topology set up above. // Do the " ...(tempArg, ...), arg = tempArg" bit from above.
// do the " ...(tempArg, ...), arg = tempArg" bit from above
TVariable* tempArg = makeInternalVariable("tempArg", *function[i].type); // Make a temporary for what the function expects the argument to look like.
tempArg->getWritableType().getQualifier().makeTemporary(); TVariable* tempArg = makeInternalVariable("tempArg", *function[i].type);
TIntermSymbol* tempArgNode = intermediate.addSymbol(*tempArg, intermNode.getLoc()); tempArg->getWritableType().getQualifier().makeTemporary();
TIntermTyped* tempAssign = intermediate.addAssign(EOpAssign, arguments[i]->getAsTyped(), tempArgNode, arguments[i]->getLoc()); TIntermSymbol* tempArgNode = intermediate.addSymbol(*tempArg, intermNode.getLoc());
conversionTree = intermediate.growAggregate(conversionTree, tempAssign, arguments[i]->getLoc());
// replace the argument with another node for the same tempArg variable // This makes the deepest level, the member-wise copy
arguments[i] = intermediate.addSymbol(*tempArg, intermNode.getLoc()); TIntermTyped* tempAssign = handleAssign(arguments[i]->getLoc(), EOpAssign, arguments[i]->getAsTyped(), tempArgNode)->getAsAggregate();
} conversionTree = intermediate.growAggregate(conversionTree, tempAssign, arguments[i]->getLoc());
// replace the argument with another node for the same tempArg variable
arguments[i] = intermediate.addSymbol(*tempArg, intermNode.getLoc());
} }
} }