Commit c44b95fd by LoopDawg

WIP: HLSL: handle clip/cull distance array semantic matching

In HLSL, there are three (TODO: ??) dimensions of clip and cull distance values: * The semantic's value N, ala SV_ClipDistanceN. * The array demension, if the value is an array. * The vector element, if the value is a vector or array of vectors. In SPIR-V, clip and cull distance are arrays of scalar floats, always. This PR currently ignores the semantic N axis, and handles the other two axes by sequentially copying each vector element of each array member into sequential floats in the output array. Fixes: #946
parent 4329d555
hlsl.clipdistance-1.vert
Shader version: 500
0:? Sequence
0:4 Function Definition: @main(vf4;f1;f1; ( temp void)
0:4 Function Parameters:
0:4 'pos' ( out 4-component vector of float)
0:4 'clip' ( out float)
0:4 'cull' ( out float)
0:? Sequence
0:5 move second child to first child ( temp 4-component vector of float)
0:5 'pos' ( out 4-component vector of float)
0:5 Constant:
0:5 1.000000
0:5 1.000000
0:5 1.000000
0:5 1.000000
0:6 move second child to first child ( temp float)
0:6 'clip' ( out float)
0:6 Constant:
0:6 0.500000
0:7 move second child to first child ( temp float)
0:7 'cull' ( out float)
0:7 Constant:
0:7 0.510000
0:4 Function Definition: main( ( temp void)
0:4 Function Parameters:
0:? Sequence
0:4 Function Call: @main(vf4;f1;f1; ( temp void)
0:? 'pos' ( temp 4-component vector of float)
0:? 'clip' ( temp float)
0:? 'cull' ( temp float)
0:4 move second child to first child ( temp 4-component vector of float)
0:? 'pos' ( out 4-component vector of float Position)
0:? 'pos' ( temp 4-component vector of float)
0:? Sequence
0:4 move second child to first child ( temp float)
0:4 direct index ( temp float)
0:? 'clip' ( out 1-element array of float ClipDistance)
0:4 Constant:
0:4 0 (const int)
0:? 'clip' ( temp float)
0:? Sequence
0:4 move second child to first child ( temp float)
0:4 direct index ( temp float)
0:? 'cull' ( out 1-element array of float CullDistance)
0:4 Constant:
0:4 0 (const int)
0:? 'cull' ( temp float)
0:? Linker Objects
0:? 'pos' ( out 4-component vector of float Position)
0:? 'clip' ( out 1-element array of float ClipDistance)
0:? 'cull' ( out 1-element array of float CullDistance)
Linked vertex stage:
Shader version: 500
0:? Sequence
0:4 Function Definition: @main(vf4;f1;f1; ( temp void)
0:4 Function Parameters:
0:4 'pos' ( out 4-component vector of float)
0:4 'clip' ( out float)
0:4 'cull' ( out float)
0:? Sequence
0:5 move second child to first child ( temp 4-component vector of float)
0:5 'pos' ( out 4-component vector of float)
0:5 Constant:
0:5 1.000000
0:5 1.000000
0:5 1.000000
0:5 1.000000
0:6 move second child to first child ( temp float)
0:6 'clip' ( out float)
0:6 Constant:
0:6 0.500000
0:7 move second child to first child ( temp float)
0:7 'cull' ( out float)
0:7 Constant:
0:7 0.510000
0:4 Function Definition: main( ( temp void)
0:4 Function Parameters:
0:? Sequence
0:4 Function Call: @main(vf4;f1;f1; ( temp void)
0:? 'pos' ( temp 4-component vector of float)
0:? 'clip' ( temp float)
0:? 'cull' ( temp float)
0:4 move second child to first child ( temp 4-component vector of float)
0:? 'pos' ( out 4-component vector of float Position)
0:? 'pos' ( temp 4-component vector of float)
0:? Sequence
0:4 move second child to first child ( temp float)
0:4 direct index ( temp float)
0:? 'clip' ( out 1-element array of float ClipDistance)
0:4 Constant:
0:4 0 (const int)
0:? 'clip' ( temp float)
0:? Sequence
0:4 move second child to first child ( temp float)
0:4 direct index ( temp float)
0:? 'cull' ( out 1-element array of float CullDistance)
0:4 Constant:
0:4 0 (const int)
0:? 'cull' ( temp float)
0:? Linker Objects
0:? 'pos' ( out 4-component vector of float Position)
0:? 'clip' ( out 1-element array of float ClipDistance)
0:? 'cull' ( out 1-element array of float CullDistance)
// Module Version 10000
// Generated by (magic number): 80001
// Id's are bound by 46
Capability Shader
Capability ClipDistance
Capability CullDistance
1: ExtInstImport "GLSL.std.450"
MemoryModel Logical GLSL450
EntryPoint Vertex 4 "main" 31 37 43
Source HLSL 500
Name 4 "main"
Name 14 "@main(vf4;f1;f1;"
Name 11 "pos"
Name 12 "clip"
Name 13 "cull"
Name 20 "pos"
Name 21 "clip"
Name 22 "cull"
Name 23 "param"
Name 24 "param"
Name 25 "param"
Name 31 "pos"
Name 37 "clip"
Name 43 "cull"
Decorate 31(pos) BuiltIn Position
Decorate 37(clip) BuiltIn ClipDistance
Decorate 43(cull) BuiltIn CullDistance
2: TypeVoid
3: TypeFunction 2
6: TypeFloat 32
7: TypeVector 6(float) 4
8: TypePointer Function 7(fvec4)
9: TypePointer Function 6(float)
10: TypeFunction 2 8(ptr) 9(ptr) 9(ptr)
16: 6(float) Constant 1065353216
17: 7(fvec4) ConstantComposite 16 16 16 16
18: 6(float) Constant 1056964608
19: 6(float) Constant 1057132380
30: TypePointer Output 7(fvec4)
31(pos): 30(ptr) Variable Output
33: TypeInt 32 0
34: 33(int) Constant 1
35: TypeArray 6(float) 34
36: TypePointer Output 35
37(clip): 36(ptr) Variable Output
38: TypeInt 32 1
39: 38(int) Constant 0
41: TypePointer Output 6(float)
43(cull): 36(ptr) Variable Output
4(main): 2 Function None 3
5: Label
20(pos): 8(ptr) Variable Function
21(clip): 9(ptr) Variable Function
22(cull): 9(ptr) Variable Function
23(param): 8(ptr) Variable Function
24(param): 9(ptr) Variable Function
25(param): 9(ptr) Variable Function
26: 2 FunctionCall 14(@main(vf4;f1;f1;) 23(param) 24(param) 25(param)
27: 7(fvec4) Load 23(param)
Store 20(pos) 27
28: 6(float) Load 24(param)
Store 21(clip) 28
29: 6(float) Load 25(param)
Store 22(cull) 29
32: 7(fvec4) Load 20(pos)
Store 31(pos) 32
40: 6(float) Load 21(clip)
42: 41(ptr) AccessChain 37(clip) 39
Store 42 40
44: 6(float) Load 22(cull)
45: 41(ptr) AccessChain 43(cull) 39
Store 45 44
Return
FunctionEnd
14(@main(vf4;f1;f1;): 2 Function None 10
11(pos): 8(ptr) FunctionParameter
12(clip): 9(ptr) FunctionParameter
13(cull): 9(ptr) FunctionParameter
15: Label
Store 11(pos) 17
Store 12(clip) 18
Store 13(cull) 19
Return
FunctionEnd
hlsl.clipdistance-3.vert
Shader version: 500
0:? Sequence
0:4 Function Definition: @main(vf4;f1[2];f1[2]; ( temp void)
0:4 Function Parameters:
0:4 'pos' ( out 4-component vector of float)
0:4 'clip' ( out 2-element array of float)
0:4 'cull' ( out 2-element array of float)
0:? Sequence
0:5 move second child to first child ( temp 4-component vector of float)
0:5 'pos' ( out 4-component vector of float)
0:5 Constant:
0:5 1.000000
0:5 1.000000
0:5 1.000000
0:5 1.000000
0:6 move second child to first child ( temp float)
0:6 direct index ( temp float)
0:6 'clip' ( out 2-element array of float)
0:6 Constant:
0:6 0 (const int)
0:6 Constant:
0:6 0.500000
0:7 move second child to first child ( temp float)
0:7 direct index ( temp float)
0:7 'clip' ( out 2-element array of float)
0:7 Constant:
0:7 1 (const int)
0:7 Constant:
0:7 0.600000
0:9 move second child to first child ( temp float)
0:9 direct index ( temp float)
0:9 'cull' ( out 2-element array of float)
0:9 Constant:
0:9 0 (const int)
0:9 Constant:
0:9 0.525000
0:10 move second child to first child ( temp float)
0:10 direct index ( temp float)
0:10 'cull' ( out 2-element array of float)
0:10 Constant:
0:10 1 (const int)
0:10 Constant:
0:10 0.625000
0:4 Function Definition: main( ( temp void)
0:4 Function Parameters:
0:? Sequence
0:4 Function Call: @main(vf4;f1[2];f1[2]; ( temp void)
0:? 'pos' ( temp 4-component vector of float)
0:? 'clip' ( temp 2-element array of float)
0:? 'cull' ( temp 2-element array of float)
0:4 move second child to first child ( temp 4-component vector of float)
0:? 'pos' ( out 4-component vector of float Position)
0:? 'pos' ( temp 4-component vector of float)
0:? Sequence
0:4 move second child to first child ( temp 2-element array of float)
0:? 'clip' ( out 2-element array of float ClipDistance)
0:? 'clip' ( temp 2-element array of float)
0:? Sequence
0:4 move second child to first child ( temp 2-element array of float)
0:? 'cull' ( out 2-element array of float CullDistance)
0:? 'cull' ( temp 2-element array of float)
0:? Linker Objects
0:? 'pos' ( out 4-component vector of float Position)
0:? 'clip' ( out 2-element array of float ClipDistance)
0:? 'cull' ( out 2-element array of float CullDistance)
Linked vertex stage:
Shader version: 500
0:? Sequence
0:4 Function Definition: @main(vf4;f1[2];f1[2]; ( temp void)
0:4 Function Parameters:
0:4 'pos' ( out 4-component vector of float)
0:4 'clip' ( out 2-element array of float)
0:4 'cull' ( out 2-element array of float)
0:? Sequence
0:5 move second child to first child ( temp 4-component vector of float)
0:5 'pos' ( out 4-component vector of float)
0:5 Constant:
0:5 1.000000
0:5 1.000000
0:5 1.000000
0:5 1.000000
0:6 move second child to first child ( temp float)
0:6 direct index ( temp float)
0:6 'clip' ( out 2-element array of float)
0:6 Constant:
0:6 0 (const int)
0:6 Constant:
0:6 0.500000
0:7 move second child to first child ( temp float)
0:7 direct index ( temp float)
0:7 'clip' ( out 2-element array of float)
0:7 Constant:
0:7 1 (const int)
0:7 Constant:
0:7 0.600000
0:9 move second child to first child ( temp float)
0:9 direct index ( temp float)
0:9 'cull' ( out 2-element array of float)
0:9 Constant:
0:9 0 (const int)
0:9 Constant:
0:9 0.525000
0:10 move second child to first child ( temp float)
0:10 direct index ( temp float)
0:10 'cull' ( out 2-element array of float)
0:10 Constant:
0:10 1 (const int)
0:10 Constant:
0:10 0.625000
0:4 Function Definition: main( ( temp void)
0:4 Function Parameters:
0:? Sequence
0:4 Function Call: @main(vf4;f1[2];f1[2]; ( temp void)
0:? 'pos' ( temp 4-component vector of float)
0:? 'clip' ( temp 2-element array of float)
0:? 'cull' ( temp 2-element array of float)
0:4 move second child to first child ( temp 4-component vector of float)
0:? 'pos' ( out 4-component vector of float Position)
0:? 'pos' ( temp 4-component vector of float)
0:? Sequence
0:4 move second child to first child ( temp 2-element array of float)
0:? 'clip' ( out 2-element array of float ClipDistance)
0:? 'clip' ( temp 2-element array of float)
0:? Sequence
0:4 move second child to first child ( temp 2-element array of float)
0:? 'cull' ( out 2-element array of float CullDistance)
0:? 'cull' ( temp 2-element array of float)
0:? Linker Objects
0:? 'pos' ( out 4-component vector of float Position)
0:? 'clip' ( out 2-element array of float ClipDistance)
0:? 'cull' ( out 2-element array of float CullDistance)
// Module Version 10000
// Generated by (magic number): 80001
// Id's are bound by 51
Capability Shader
Capability ClipDistance
Capability CullDistance
1: ExtInstImport "GLSL.std.450"
MemoryModel Logical GLSL450
EntryPoint Vertex 4 "main" 44 47 49
Source HLSL 500
Name 4 "main"
Name 17 "@main(vf4;f1[2];f1[2];"
Name 14 "pos"
Name 15 "clip"
Name 16 "cull"
Name 33 "pos"
Name 34 "clip"
Name 35 "cull"
Name 36 "param"
Name 37 "param"
Name 38 "param"
Name 44 "pos"
Name 47 "clip"
Name 49 "cull"
Decorate 44(pos) BuiltIn Position
Decorate 47(clip) BuiltIn ClipDistance
Decorate 49(cull) BuiltIn CullDistance
2: TypeVoid
3: TypeFunction 2
6: TypeFloat 32
7: TypeVector 6(float) 4
8: TypePointer Function 7(fvec4)
9: TypeInt 32 0
10: 9(int) Constant 2
11: TypeArray 6(float) 10
12: TypePointer Function 11
13: TypeFunction 2 8(ptr) 12(ptr) 12(ptr)
19: 6(float) Constant 1065353216
20: 7(fvec4) ConstantComposite 19 19 19 19
21: TypeInt 32 1
22: 21(int) Constant 0
23: 6(float) Constant 1056964608
24: TypePointer Function 6(float)
26: 21(int) Constant 1
27: 6(float) Constant 1058642330
29: 6(float) Constant 1057384038
31: 6(float) Constant 1059061760
43: TypePointer Output 7(fvec4)
44(pos): 43(ptr) Variable Output
46: TypePointer Output 11
47(clip): 46(ptr) Variable Output
49(cull): 46(ptr) Variable Output
4(main): 2 Function None 3
5: Label
33(pos): 8(ptr) Variable Function
34(clip): 12(ptr) Variable Function
35(cull): 12(ptr) Variable Function
36(param): 8(ptr) Variable Function
37(param): 12(ptr) Variable Function
38(param): 12(ptr) Variable Function
39: 2 FunctionCall 17(@main(vf4;f1[2];f1[2];) 36(param) 37(param) 38(param)
40: 7(fvec4) Load 36(param)
Store 33(pos) 40
41: 11 Load 37(param)
Store 34(clip) 41
42: 11 Load 38(param)
Store 35(cull) 42
45: 7(fvec4) Load 33(pos)
Store 44(pos) 45
48: 11 Load 34(clip)
Store 47(clip) 48
50: 11 Load 35(cull)
Store 49(cull) 50
Return
FunctionEnd
17(@main(vf4;f1[2];f1[2];): 2 Function None 13
14(pos): 8(ptr) FunctionParameter
15(clip): 12(ptr) FunctionParameter
16(cull): 12(ptr) FunctionParameter
18: Label
Store 14(pos) 20
25: 24(ptr) AccessChain 15(clip) 22
Store 25 23
28: 24(ptr) AccessChain 15(clip) 26
Store 28 27
30: 24(ptr) AccessChain 16(cull) 22
Store 30 29
32: 24(ptr) AccessChain 16(cull) 26
Store 32 31
Return
FunctionEnd
void main(out float4 pos : SV_Position,
out float clip : SV_ClipDistance, // scalar float
out float cull : SV_CullDistance) // scalar float
{
pos = 1.0f.xxxx;
clip = 0.5f;
cull = 0.51f;
}
void main(out float4 pos : SV_Position,
out float2 clip[2] : SV_ClipDistance, // array of vector float
out float2 cull[2] : SV_CullDistance) // array of vector float
{
pos = 1.0f.xxxx;
clip[0].x = 0.5f;
clip[0].y = 0.6f;
clip[1].x = 0.7f;
clip[1].y = 0.8f;
cull[0].x = 0.525f;
cull[0].y = 0.625f;
cull[1].x = 0.725f;
cull[1].y = 0.825f;
}
void main(out float4 pos : SV_Position,
out float clip[2] : SV_ClipDistance, // array of scalar float
out float cull[2] : SV_CullDistance) // array of scalar float
{
pos = 1.0f.xxxx;
clip[0] = 0.5f;
clip[1] = 0.6f;
cull[0] = 0.525f;
cull[1] = 0.625f;
}
struct VS_INPUT {
float4 Position : POSITION;
};
struct VS_OUTPUT {
float4 Position : SV_Position;
float4 ClipRect : SV_ClipDistance0; // vector in split struct
};
VS_OUTPUT main(const VS_INPUT v)
{
VS_OUTPUT Output;
Output.Position = 0;
Output.ClipRect.x = 1;
Output.ClipRect.y = 2;
Output.ClipRect.z = 3;
Output.ClipRect.w = 4;
return Output;
}
struct VS_INPUT {
float4 Position : POSITION;
};
struct VS_OUTPUT {
float4 Position : SV_Position;
float2 ClipRect[2] : SV_ClipDistance0; // array of float2 in split struct
};
VS_OUTPUT main(const VS_INPUT v)
{
VS_OUTPUT Output;
Output.Position = 0;
Output.ClipRect[0].x = 1;
Output.ClipRect[0].y = 2;
Output.ClipRect[1].x = 3;
Output.ClipRect[1].y = 4;
return Output;
}
......@@ -97,6 +97,11 @@ INSTANTIATE_TEST_CASE_P(
{"hlsl.cast.frag", "PixelShaderFunction"},
{"hlsl.charLit.vert", "main"},
{"hlsl.clip.frag", "main"},
{"hlsl.clipdistance-1.vert", "main"},
{"hlsl.clipdistance-2.vert", "main"},
{"hlsl.clipdistance-3.vert", "main"},
{"hlsl.clipdistance-4.vert", "main"},
{"hlsl.clipdistance-5.vert", "main"},
{"hlsl.comparison.vec.frag", "main"},
{"hlsl.conditional.frag", "PixelShaderFunction"},
{"hlsl.constantbuffer.frag", "main"},
......
......@@ -1492,9 +1492,25 @@ void HlslParseContext::fixBuiltInIoType(TType& type)
switch (type.getQualifier().builtIn) {
case EbvTessLevelOuter: requiredArraySize = 4; break;
case EbvTessLevelInner: requiredArraySize = 2; break;
case EbvClipDistance: // TODO: ...
case EbvCullDistance: // TODO: ...
return;
case EbvClipDistance:
case EbvCullDistance:
{
// ClipDistance and CullDistance are handled specially in the entry point output
// copy algorithm, because they may need to be unpacked from components of vectors
// (or a scalar) into a float array. Here, we make the array the right size and type,
// which is the number of components per vector times the array size (or 1 if not
// an array). The copy itself is handled in assignClipCullDistance().
requiredArraySize = type.getVectorSize() * (type.isArray() ? type.getOuterArraySize() : 1);
TType clipCullType(EbtFloat, type.getQualifier().storage, 1);
clipCullType.getQualifier() = type.getQualifier();
type.shallowCopy(clipCullType);
break;
}
case EbvTessCoord:
{
// tesscoord is always a vec3 for the IO variable, no matter the shader's
......@@ -2290,6 +2306,88 @@ void HlslParseContext::handleFunctionArgument(TFunction* function,
arguments = newArg;
}
// Clip and cull distance require special handling due to a semantic mismatch. In HLSL,
// these can be float scalar, float vector, or arrays of float scalar or float vector.
// In SPIR-V, they are arrays of scalar floats in all cases. We must copy individual components
// (e.g, both x and y components of a float2) out into the destination float array.
//
// The values are assigned to sequential members of the output array. The inner dimension
// is vector components. The outer dimension is array elements.
TIntermAggregate* HlslParseContext::assignClipCullDistance(const TSourceLoc& loc, TOperator op,
TIntermTyped* left, TIntermTyped* right)
{
// ***
// TODO: this does not yet handle the index coming from the semantic's ID, as in SV_ClipDistance[012345...]
// ***
// left has got to be an array of scalar floats, per SPIR-V semantics.
// fixBuiltInIoType() should have handled that upstream.
assert(left->getType().isArray());
assert(left->getType().getVectorSize() == 1);
assert(left->getType().getBasicType() == EbtFloat);
// array sizes, or 1 if it's not an array:
const int lhsArraySize = (left->getType().isArray() ? left->getType().getOuterArraySize() : 1);
const int rhsArraySize = (right->getType().isArray() ? right->getType().getOuterArraySize() : 1);
// vector sizes:
const int lhsVectorSize = left->getType().getVectorSize();
const int rhsVectorSize = right->getType().getVectorSize();
// We may be creating multiple sub-assignments. This is an aggregate to hold them.
// TODO: it would be possible to be clever sometimes and avoid the sequence node if not needed.
TIntermAggregate* assignList = nullptr;
// If the types are homomorphic, use a simple assign. No need to mess about with
// individual components.
if (left->getType().isArray() == right->getType().isArray() &&
lhsArraySize == rhsArraySize &&
lhsVectorSize == rhsVectorSize) {
assignList = intermediate.growAggregate(assignList, intermediate.addAssign(op, left, right, loc));
assignList->setOperator(EOpSequence);
return assignList;
}
// We are going to copy each component of the right (per array element if indicated) to sequential
// array elements of the left. This tracks the lhs element we're writing to as we go along.
int lhsArrayPos = 0;
// Loop through every component of every element of the RHS, and copy to LHS elements in turn.
for (int rhsArrayPos = 0; rhsArrayPos < rhsArraySize; ++rhsArrayPos) {
for (int rhsComponent = 0; rhsComponent < rhsVectorSize; ++rhsComponent) {
// LHS array member to write to:
TIntermTyped* lhsMember = intermediate.addIndex(EOpIndexDirect, left,
intermediate.addConstantUnion(lhsArrayPos++, loc), loc);
TIntermTyped* rhsMember = right;
// If right is an array, extract the element of interest
if (right->getType().isArray()) {
const TType derefType(rhsMember->getType(), 0);
rhsMember = intermediate.addIndex(EOpIndexDirect, rhsMember,
intermediate.addConstantUnion(rhsArrayPos, loc), loc);
rhsMember->setType(derefType);
}
// If right is a vector, extract the component of interest.
if (right->getType().isVector()) {
const TType derefType(rhsMember->getType(), 0);
rhsMember = intermediate.addIndex(EOpIndexDirect, rhsMember,
intermediate.addConstantUnion(rhsComponent, loc), loc);
rhsMember->setType(derefType);
}
// Assign: to the proper lhs member.
assignList = intermediate.growAggregate(assignList,
intermediate.addAssign(op, lhsMember, rhsMember, loc));
}
}
assert(assignList != nullptr);
assignList->setOperator(EOpSequence);
return assignList;
}
// Some simple source assignments need to be flattened to a sequence
// of AST assignments. Catch these and flatten, otherwise, pass through
// to intermediate.addAssign().
......@@ -2312,8 +2410,14 @@ TIntermTyped* HlslParseContext::handleAssign(const TSourceLoc& loc, TOperator op
// OK to do a single assign if both are split, or both are unsplit. But if one is and the other
// isn't, we fall back to a member-wise copy.
if (! isFlattenLeft && ! isFlattenRight && !isSplitLeft && !isSplitRight)
if (! isFlattenLeft && ! isFlattenRight && !isSplitLeft && !isSplitRight) {
// Clip and cull distance requires more processing. See comment above assignClipCullDistance.
const TBuiltInVariable leftBuiltIn = left->getType().getQualifier().builtIn;
if (leftBuiltIn == EbvClipDistance || leftBuiltIn == EbvCullDistance)
return assignClipCullDistance(loc, op, left, right);
return intermediate.addAssign(op, left, right, loc);
}
TIntermAggregate* assignList = nullptr;
const TVector<TVariable*>* leftVariables = nullptr;
......@@ -2474,13 +2578,21 @@ TIntermTyped* HlslParseContext::handleAssign(const TSourceLoc& loc, TOperator op
TIntermTyped* subSplitLeft = isSplitLeft ? getMember(true, left, member, splitLeft, memberL) : subLeft;
TIntermTyped* subSplitRight = isSplitRight ? getMember(false, right, member, splitRight, memberR) : subRight;
// If this is the final flattening (no nested types below to flatten) we'll copy the member, else
// recurse into the type hierarchy. However, if splitting the struct, that means we can copy a whole
// subtree here IFF it does not itself contain any interstage built-in IO variables, so we only have to
// recurse into it if there's something for splitting to do. That can save a lot of AST verbosity for
// a bunch of memberwise copies.
if ((!isFlattenLeft && !isFlattenRight &&
!typeL.containsBuiltInInterstageIO(language) && !typeR.containsBuiltInInterstageIO(language))) {
const TBuiltInVariable leftBuiltIn = subSplitLeft->getType().getQualifier().builtIn;
if (leftBuiltIn == EbvClipDistance || leftBuiltIn == EbvCullDistance) {
// Clip and cull distance builtin assignment is complex in its own right, and is handled in
// a separate function dedicated to that task. See comment above assignClipCullDistance;
assignList = intermediate.growAggregate(assignList, assignClipCullDistance(loc, op, subSplitLeft, subSplitRight), loc);
} else if ((!isFlattenLeft && !isFlattenRight &&
!typeL.containsBuiltInInterstageIO(language) && !typeR.containsBuiltInInterstageIO(language))) {
// If this is the final flattening (no nested types below to flatten) we'll copy the member, else
// recurse into the type hierarchy. However, if splitting the struct, that means we can copy a whole
// subtree here IFF it does not itself contain any interstage built-in IO variables, so we only have to
// recurse into it if there's something for splitting to do. That can save a lot of AST verbosity for
// a bunch of memberwise copies.
assignList = intermediate.growAggregate(assignList, intermediate.addAssign(op, subSplitLeft, subSplitRight, loc), loc);
} else {
traverse(subLeft, subRight, subSplitLeft, subSplitRight);
......
......@@ -90,6 +90,7 @@ public:
TIntermTyped* handleAssign(const TSourceLoc&, TOperator, TIntermTyped* left, TIntermTyped* right);
TIntermTyped* handleAssignToMatrixSwizzle(const TSourceLoc&, TOperator, TIntermTyped* left, TIntermTyped* right);
TIntermTyped* handleFunctionCall(const TSourceLoc&, TFunction*, TIntermTyped*);
TIntermAggregate* assignClipCullDistance(const TSourceLoc&, TOperator, TIntermTyped* left, TIntermTyped* right);
void decomposeIntrinsic(const TSourceLoc&, TIntermTyped*& node, TIntermNode* arguments);
void decomposeSampleMethods(const TSourceLoc&, TIntermTyped*& node, TIntermNode* arguments);
void decomposeStructBufferMethods(const TSourceLoc&, TIntermTyped*& node, TIntermNode* arguments);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment