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

View File

@ -3,6 +3,12 @@ struct OutParam {
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
{
out1 = input;
@ -11,7 +17,7 @@ float4 PixelShaderFunction(float4 input, out float4 out1, out OutParam out2, out
OutParam local;
local.v = 12.0;
local.i = 13;
out3 = local;
fun(out3);
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 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"

View File

@ -2246,21 +2246,9 @@ TIntermTyped* HlslParseContext::handleFunctionCall(const TSourceLoc& loc, TFunct
if (builtIn && fnCandidate->getNumExtensions())
requireExtensions(loc, fnCandidate->getNumExtensions(), fnCandidate->getExtensions(), fnCandidate->getName().c_str());
if (arguments) {
// Make sure qualifications work for these arguments.
//TIntermAggregate* aggregate = arguments->getAsAggregate();
//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
}
// Convert 'in' arguments
if (arguments)
addInputArgumentConversions(*fnCandidate, arguments);
op = fnCandidate->getBuiltInOp();
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'
// is the single argument itself or its children are the arguments. Only 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()) {
// In-qualified arguments just need an extra node added above the argument to
// convert to the correct type.
@ -2401,9 +2391,9 @@ void HlslParseContext::addInputArgumentConversions(const TFunction& function, TI
if (shouldFlatten(arg->getType())) {
// Will make a two-level subtree.
// 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.
TSourceLoc dummyLoc;
TSourceLoc dummyLoc; // ?? fix these everywhere to be arguments[i]->getLoc()?
dummyLoc.init();
TVariable* internalAggregate = makeInternalVariable("aggShadow", *function[i].type);
internalAggregate->getWritableType().getQualifier().makeTemporary();
@ -2433,11 +2423,16 @@ void HlslParseContext::addInputArgumentConversions(const TFunction& function, TI
TIntermTyped* HlslParseContext::addOutputArgumentConversions(const TFunction& function, TIntermAggregate& intermNode) const
{
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?
bool outputConversions = false;
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;
break;
}
@ -2468,18 +2463,21 @@ TIntermTyped* HlslParseContext::addOutputArgumentConversions(const TFunction& fu
// Process each argument's conversion
for (int i = 0; i < function.getParamCount(); ++i) {
if (*function[i].type != arguments[i]->getAsTyped()->getType()) {
if (function[i].type->getQualifier().isParamOutput()) {
// Out-qualified arguments need to use the topology set up above.
// do the " ...(tempArg, ...), arg = tempArg" bit from above
TVariable* tempArg = makeInternalVariable("tempArg", *function[i].type);
tempArg->getWritableType().getQualifier().makeTemporary();
TIntermSymbol* tempArgNode = intermediate.addSymbol(*tempArg, intermNode.getLoc());
TIntermTyped* tempAssign = intermediate.addAssign(EOpAssign, arguments[i]->getAsTyped(), tempArgNode, arguments[i]->getLoc());
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());
}
if (needsConversion(i)) {
// Out-qualified arguments needing conversion need to use the topology setup above.
// Do the " ...(tempArg, ...), arg = tempArg" bit from above.
// Make a temporary for what the function expects the argument to look like.
TVariable* tempArg = makeInternalVariable("tempArg", *function[i].type);
tempArg->getWritableType().getQualifier().makeTemporary();
TIntermSymbol* tempArgNode = intermediate.addSymbol(*tempArg, intermNode.getLoc());
// This makes the deepest level, the member-wise copy
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());
}
}