Commit a5d86164 by LoopDawg

HLSL: allow mixed user & builtin members in hull shader output structure

Hull shaders have an implicitly arrayed output. This is handled by creating an arrayed form of the provided output type, and writing to the element of it indexed by InvocationID. The implicit indirection into that array was causing some troubles when copying to a split structure. handleAssign was able to handle simple symbol lvalues, but not an lvalue composed of an indirection into an array.
parent ba6a3c29
...@@ -3555,7 +3555,7 @@ spv::Id TGlslangToSpvTraverser::handleUserFunctionCall(const glslang::TIntermAgg ...@@ -3555,7 +3555,7 @@ spv::Id TGlslangToSpvTraverser::handleUserFunctionCall(const glslang::TIntermAgg
const glslang::TIntermSequence& glslangArgs = node->getSequence(); const glslang::TIntermSequence& glslangArgs = node->getSequence();
const glslang::TQualifierList& qualifiers = node->getQualifierList(); const glslang::TQualifierList& qualifiers = node->getQualifierList();
// Encapsulate lvalue logic, used in two places below, for safety. // Encapsulate lvalue logic, used in several places below, for safety.
const auto isLValue = [](int qualifier, const glslang::TType& paramType) -> bool { const auto isLValue = [](int qualifier, const glslang::TType& paramType) -> bool {
return qualifier != glslang::EvqConstReadOnly || paramType.containsOpaque(); return qualifier != glslang::EvqConstReadOnly || paramType.containsOpaque();
}; };
......
...@@ -32,7 +32,7 @@ vertex spacing = equal_spacing ...@@ -32,7 +32,7 @@ vertex spacing = equal_spacing
0:? 'm_cpid' ( temp uint) 0:? 'm_cpid' ( temp uint)
0:? 'm_cpid' ( in uint InvocationID) 0:? 'm_cpid' ( in uint InvocationID)
0:26 move second child to first child ( temp structure{ temp 3-component vector of float cpoint}) 0:26 move second child to first child ( temp structure{ temp 3-component vector of float cpoint})
0:26 indirect index ( temp structure{ temp 3-component vector of float cpoint}) 0:26 indirect index (layout( location=0) out structure{ temp 3-component vector of float cpoint})
0:? '@entryPointOutput' (layout( location=0) out 4-element array of structure{ temp 3-component vector of float cpoint}) 0:? '@entryPointOutput' (layout( location=0) out 4-element array of structure{ temp 3-component vector of float cpoint})
0:? 'm_cpid' ( in uint InvocationID) 0:? 'm_cpid' ( in uint InvocationID)
0:26 Function Call: @main(struct-VS_OUT-vf31[4];u1; ( temp structure{ temp 3-component vector of float cpoint}) 0:26 Function Call: @main(struct-VS_OUT-vf31[4];u1; ( temp structure{ temp 3-component vector of float cpoint})
...@@ -146,7 +146,7 @@ vertex spacing = equal_spacing ...@@ -146,7 +146,7 @@ vertex spacing = equal_spacing
0:? 'm_cpid' ( temp uint) 0:? 'm_cpid' ( temp uint)
0:? 'm_cpid' ( in uint InvocationID) 0:? 'm_cpid' ( in uint InvocationID)
0:26 move second child to first child ( temp structure{ temp 3-component vector of float cpoint}) 0:26 move second child to first child ( temp structure{ temp 3-component vector of float cpoint})
0:26 indirect index ( temp structure{ temp 3-component vector of float cpoint}) 0:26 indirect index (layout( location=0) out structure{ temp 3-component vector of float cpoint})
0:? '@entryPointOutput' (layout( location=0) out 4-element array of structure{ temp 3-component vector of float cpoint}) 0:? '@entryPointOutput' (layout( location=0) out 4-element array of structure{ temp 3-component vector of float cpoint})
0:? 'm_cpid' ( in uint InvocationID) 0:? 'm_cpid' ( in uint InvocationID)
0:26 Function Call: @main(struct-VS_OUT-vf31[4];u1; ( temp structure{ temp 3-component vector of float cpoint}) 0:26 Function Call: @main(struct-VS_OUT-vf31[4];u1; ( temp structure{ temp 3-component vector of float cpoint})
......
...@@ -28,7 +28,7 @@ vertex spacing = equal_spacing ...@@ -28,7 +28,7 @@ vertex spacing = equal_spacing
0:? 'ip' ( temp 4-element array of structure{ temp 3-component vector of float cpoint}) 0:? 'ip' ( temp 4-element array of structure{ temp 3-component vector of float cpoint})
0:? 'ip' (layout( location=0) in 4-element array of structure{ temp 3-component vector of float cpoint}) 0:? 'ip' (layout( location=0) in 4-element array of structure{ temp 3-component vector of float cpoint})
0:26 move second child to first child ( temp structure{ temp 3-component vector of float cpoint}) 0:26 move second child to first child ( temp structure{ temp 3-component vector of float cpoint})
0:26 indirect index ( temp structure{ temp 3-component vector of float cpoint}) 0:26 indirect index (layout( location=0) out structure{ temp 3-component vector of float cpoint})
0:? '@entryPointOutput' (layout( location=0) out 4-element array of structure{ temp 3-component vector of float cpoint}) 0:? '@entryPointOutput' (layout( location=0) out 4-element array of structure{ temp 3-component vector of float cpoint})
0:? 'InvocationId' ( in uint InvocationID) 0:? 'InvocationId' ( in uint InvocationID)
0:26 Function Call: @main(struct-VS_OUT-vf31[4]; ( temp structure{ temp 3-component vector of float cpoint}) 0:26 Function Call: @main(struct-VS_OUT-vf31[4]; ( temp structure{ temp 3-component vector of float cpoint})
...@@ -140,7 +140,7 @@ vertex spacing = equal_spacing ...@@ -140,7 +140,7 @@ vertex spacing = equal_spacing
0:? 'ip' ( temp 4-element array of structure{ temp 3-component vector of float cpoint}) 0:? 'ip' ( temp 4-element array of structure{ temp 3-component vector of float cpoint})
0:? 'ip' (layout( location=0) in 4-element array of structure{ temp 3-component vector of float cpoint}) 0:? 'ip' (layout( location=0) in 4-element array of structure{ temp 3-component vector of float cpoint})
0:26 move second child to first child ( temp structure{ temp 3-component vector of float cpoint}) 0:26 move second child to first child ( temp structure{ temp 3-component vector of float cpoint})
0:26 indirect index ( temp structure{ temp 3-component vector of float cpoint}) 0:26 indirect index (layout( location=0) out structure{ temp 3-component vector of float cpoint})
0:? '@entryPointOutput' (layout( location=0) out 4-element array of structure{ temp 3-component vector of float cpoint}) 0:? '@entryPointOutput' (layout( location=0) out 4-element array of structure{ temp 3-component vector of float cpoint})
0:? 'InvocationId' ( in uint InvocationID) 0:? 'InvocationId' ( in uint InvocationID)
0:26 Function Call: @main(struct-VS_OUT-vf31[4]; ( temp structure{ temp 3-component vector of float cpoint}) 0:26 Function Call: @main(struct-VS_OUT-vf31[4]; ( temp structure{ temp 3-component vector of float cpoint})
......
...@@ -28,7 +28,7 @@ vertex spacing = equal_spacing ...@@ -28,7 +28,7 @@ vertex spacing = equal_spacing
0:? 'ip' ( temp 4-element array of structure{ temp 3-component vector of float cpoint}) 0:? 'ip' ( temp 4-element array of structure{ temp 3-component vector of float cpoint})
0:? 'ip' (layout( location=0) in 4-element array of structure{ temp 3-component vector of float cpoint}) 0:? 'ip' (layout( location=0) in 4-element array of structure{ temp 3-component vector of float cpoint})
0:26 move second child to first child ( temp structure{ temp 3-component vector of float cpoint}) 0:26 move second child to first child ( temp structure{ temp 3-component vector of float cpoint})
0:26 indirect index ( temp structure{ temp 3-component vector of float cpoint}) 0:26 indirect index (layout( location=0) out structure{ temp 3-component vector of float cpoint})
0:? '@entryPointOutput' (layout( location=0) out 4-element array of structure{ temp 3-component vector of float cpoint}) 0:? '@entryPointOutput' (layout( location=0) out 4-element array of structure{ temp 3-component vector of float cpoint})
0:? 'InvocationId' ( in uint InvocationID) 0:? 'InvocationId' ( in uint InvocationID)
0:26 Function Call: @main(struct-VS_OUT-vf31[4]; ( temp structure{ temp 3-component vector of float cpoint}) 0:26 Function Call: @main(struct-VS_OUT-vf31[4]; ( temp structure{ temp 3-component vector of float cpoint})
...@@ -140,7 +140,7 @@ vertex spacing = equal_spacing ...@@ -140,7 +140,7 @@ vertex spacing = equal_spacing
0:? 'ip' ( temp 4-element array of structure{ temp 3-component vector of float cpoint}) 0:? 'ip' ( temp 4-element array of structure{ temp 3-component vector of float cpoint})
0:? 'ip' (layout( location=0) in 4-element array of structure{ temp 3-component vector of float cpoint}) 0:? 'ip' (layout( location=0) in 4-element array of structure{ temp 3-component vector of float cpoint})
0:26 move second child to first child ( temp structure{ temp 3-component vector of float cpoint}) 0:26 move second child to first child ( temp structure{ temp 3-component vector of float cpoint})
0:26 indirect index ( temp structure{ temp 3-component vector of float cpoint}) 0:26 indirect index (layout( location=0) out structure{ temp 3-component vector of float cpoint})
0:? '@entryPointOutput' (layout( location=0) out 4-element array of structure{ temp 3-component vector of float cpoint}) 0:? '@entryPointOutput' (layout( location=0) out 4-element array of structure{ temp 3-component vector of float cpoint})
0:? 'InvocationId' ( in uint InvocationID) 0:? 'InvocationId' ( in uint InvocationID)
0:26 Function Call: @main(struct-VS_OUT-vf31[4]; ( temp structure{ temp 3-component vector of float cpoint}) 0:26 Function Call: @main(struct-VS_OUT-vf31[4]; ( temp structure{ temp 3-component vector of float cpoint})
......
...@@ -29,7 +29,7 @@ triangle order = cw ...@@ -29,7 +29,7 @@ triangle order = cw
0:? 'cpid' ( temp uint) 0:? 'cpid' ( temp uint)
0:? 'cpid' ( in uint InvocationID) 0:? 'cpid' ( in uint InvocationID)
0:27 move second child to first child ( temp structure{ temp 3-component vector of float val}) 0:27 move second child to first child ( temp structure{ temp 3-component vector of float val})
0:27 indirect index ( temp structure{ temp 3-component vector of float val}) 0:27 indirect index (layout( location=0) out structure{ temp 3-component vector of float val})
0:? '@entryPointOutput' (layout( location=0) out 3-element array of structure{ temp 3-component vector of float val}) 0:? '@entryPointOutput' (layout( location=0) out 3-element array of structure{ temp 3-component vector of float val})
0:? 'cpid' ( in uint InvocationID) 0:? 'cpid' ( in uint InvocationID)
0:27 Function Call: @main(struct-hs_in_t-vf31[3];u1; ( temp structure{ temp 3-component vector of float val}) 0:27 Function Call: @main(struct-hs_in_t-vf31[3];u1; ( temp structure{ temp 3-component vector of float val})
...@@ -229,7 +229,7 @@ triangle order = cw ...@@ -229,7 +229,7 @@ triangle order = cw
0:? 'cpid' ( temp uint) 0:? 'cpid' ( temp uint)
0:? 'cpid' ( in uint InvocationID) 0:? 'cpid' ( in uint InvocationID)
0:27 move second child to first child ( temp structure{ temp 3-component vector of float val}) 0:27 move second child to first child ( temp structure{ temp 3-component vector of float val})
0:27 indirect index ( temp structure{ temp 3-component vector of float val}) 0:27 indirect index (layout( location=0) out structure{ temp 3-component vector of float val})
0:? '@entryPointOutput' (layout( location=0) out 3-element array of structure{ temp 3-component vector of float val}) 0:? '@entryPointOutput' (layout( location=0) out 3-element array of structure{ temp 3-component vector of float val})
0:? 'cpid' ( in uint InvocationID) 0:? 'cpid' ( in uint InvocationID)
0:27 Function Call: @main(struct-hs_in_t-vf31[3];u1; ( temp structure{ temp 3-component vector of float val}) 0:27 Function Call: @main(struct-hs_in_t-vf31[3];u1; ( temp structure{ temp 3-component vector of float val})
......
...@@ -36,7 +36,7 @@ triangle order = cw ...@@ -36,7 +36,7 @@ triangle order = cw
0:? 'cpid' ( temp uint) 0:? 'cpid' ( temp uint)
0:? 'cpid' ( in uint InvocationID) 0:? 'cpid' ( in uint InvocationID)
0:28 move second child to first child ( temp structure{ temp 3-component vector of float val}) 0:28 move second child to first child ( temp structure{ temp 3-component vector of float val})
0:28 indirect index ( temp structure{ temp 3-component vector of float val}) 0:28 indirect index (layout( location=0) out structure{ temp 3-component vector of float val})
0:? '@entryPointOutput' (layout( location=0) out 3-element array of structure{ temp 3-component vector of float val}) 0:? '@entryPointOutput' (layout( location=0) out 3-element array of structure{ temp 3-component vector of float val})
0:? 'cpid' ( in uint InvocationID) 0:? 'cpid' ( in uint InvocationID)
0:28 Function Call: @main(struct-hs_in_t-vf31[3];u1; ( temp structure{ temp 3-component vector of float val}) 0:28 Function Call: @main(struct-hs_in_t-vf31[3];u1; ( temp structure{ temp 3-component vector of float val})
...@@ -245,7 +245,7 @@ triangle order = cw ...@@ -245,7 +245,7 @@ triangle order = cw
0:? 'cpid' ( temp uint) 0:? 'cpid' ( temp uint)
0:? 'cpid' ( in uint InvocationID) 0:? 'cpid' ( in uint InvocationID)
0:28 move second child to first child ( temp structure{ temp 3-component vector of float val}) 0:28 move second child to first child ( temp structure{ temp 3-component vector of float val})
0:28 indirect index ( temp structure{ temp 3-component vector of float val}) 0:28 indirect index (layout( location=0) out structure{ temp 3-component vector of float val})
0:? '@entryPointOutput' (layout( location=0) out 3-element array of structure{ temp 3-component vector of float val}) 0:? '@entryPointOutput' (layout( location=0) out 3-element array of structure{ temp 3-component vector of float val})
0:? 'cpid' ( in uint InvocationID) 0:? 'cpid' ( in uint InvocationID)
0:28 Function Call: @main(struct-hs_in_t-vf31[3];u1; ( temp structure{ temp 3-component vector of float val}) 0:28 Function Call: @main(struct-hs_in_t-vf31[3];u1; ( temp structure{ temp 3-component vector of float val})
......
...@@ -29,7 +29,7 @@ triangle order = ccw ...@@ -29,7 +29,7 @@ triangle order = ccw
0:? 'ip' ( temp 3-element array of structure{ temp 3-component vector of float cpoint}) 0:? 'ip' ( temp 3-element array of structure{ temp 3-component vector of float cpoint})
0:? 'ip' (layout( location=0) in 3-element array of structure{ temp 3-component vector of float cpoint}) 0:? 'ip' (layout( location=0) in 3-element array of structure{ temp 3-component vector of float cpoint})
0:26 move second child to first child ( temp structure{ temp 3-component vector of float cpoint}) 0:26 move second child to first child ( temp structure{ temp 3-component vector of float cpoint})
0:26 indirect index ( temp structure{ temp 3-component vector of float cpoint}) 0:26 indirect index (layout( location=0) out structure{ temp 3-component vector of float cpoint})
0:? '@entryPointOutput' (layout( location=0) out 3-element array of structure{ temp 3-component vector of float cpoint}) 0:? '@entryPointOutput' (layout( location=0) out 3-element array of structure{ temp 3-component vector of float cpoint})
0:? 'InvocationId' ( in uint InvocationID) 0:? 'InvocationId' ( in uint InvocationID)
0:26 Function Call: @main(struct-VS_OUT-vf31[3]; ( temp structure{ temp 3-component vector of float cpoint}) 0:26 Function Call: @main(struct-VS_OUT-vf31[3]; ( temp structure{ temp 3-component vector of float cpoint})
...@@ -85,7 +85,7 @@ triangle order = ccw ...@@ -85,7 +85,7 @@ triangle order = ccw
0:? 'ip' ( temp 3-element array of structure{ temp 3-component vector of float cpoint}) 0:? 'ip' ( temp 3-element array of structure{ temp 3-component vector of float cpoint})
0:? 'ip' (layout( location=0) in 3-element array of structure{ temp 3-component vector of float cpoint}) 0:? 'ip' (layout( location=0) in 3-element array of structure{ temp 3-component vector of float cpoint})
0:26 move second child to first child ( temp structure{ temp 3-component vector of float cpoint}) 0:26 move second child to first child ( temp structure{ temp 3-component vector of float cpoint})
0:26 indirect index ( temp structure{ temp 3-component vector of float cpoint}) 0:26 indirect index (layout( location=0) out structure{ temp 3-component vector of float cpoint})
0:? '@entryPointOutput' (layout( location=0) out 3-element array of structure{ temp 3-component vector of float cpoint}) 0:? '@entryPointOutput' (layout( location=0) out 3-element array of structure{ temp 3-component vector of float cpoint})
0:? 'InvocationId' ( in uint InvocationID) 0:? 'InvocationId' ( in uint InvocationID)
0:26 Function Call: @main(struct-VS_OUT-vf31[3]; ( temp structure{ temp 3-component vector of float cpoint}) 0:26 Function Call: @main(struct-VS_OUT-vf31[3]; ( temp structure{ temp 3-component vector of float cpoint})
......
// Test mixed output structure: user and builtin members. Hull shaders involve extra
// logic in this case, over and above e.g. pixel or vertex stages, which is related to
// the implicit array dimension.
struct HS_Output
{
float tessFactor[3] : SV_TessFactor;
float coord : TEXCOORD0;
};
[domain("tri")]
[outputcontrolpoints(3)]
HS_Output main ( )
{
HS_Output output = (HS_Output)0;
return output;
}
...@@ -164,6 +164,7 @@ INSTANTIATE_TEST_CASE_P( ...@@ -164,6 +164,7 @@ INSTANTIATE_TEST_CASE_P(
{"hlsl.hull.1.tesc", "main"}, {"hlsl.hull.1.tesc", "main"},
{"hlsl.hull.2.tesc", "main"}, {"hlsl.hull.2.tesc", "main"},
{"hlsl.hull.3.tesc", "main"}, {"hlsl.hull.3.tesc", "main"},
{"hlsl.hull.4.tesc", "main"},
{"hlsl.hull.void.tesc", "main"}, {"hlsl.hull.void.tesc", "main"},
{"hlsl.hull.ctrlpt-1.tesc", "main"}, {"hlsl.hull.ctrlpt-1.tesc", "main"},
{"hlsl.hull.ctrlpt-2.tesc", "main"}, {"hlsl.hull.ctrlpt-2.tesc", "main"},
......
...@@ -2039,7 +2039,10 @@ TIntermNode* HlslParseContext::transformEntryPoint(const TSourceLoc& loc, TFunct ...@@ -2039,7 +2039,10 @@ TIntermNode* HlslParseContext::transformEntryPoint(const TSourceLoc& loc, TFunct
TIntermTyped* element = intermediate.addIndex(EOpIndexIndirect, intermediate.addSymbol(*entryPointOutput), TIntermTyped* element = intermediate.addIndex(EOpIndexIndirect, intermediate.addSymbol(*entryPointOutput),
invocationIdSym, loc); invocationIdSym, loc);
element->setType(callReturn->getType());
// Set the type of the array element being dereferenced
const TType derefElementType(entryPointOutput->getType(), 0);
element->setType(derefElementType);
returnAssign = handleAssign(loc, EOpAssign, element, callReturn); returnAssign = handleAssign(loc, EOpAssign, element, callReturn);
} else { } else {
...@@ -2561,14 +2564,25 @@ TIntermTyped* HlslParseContext::handleAssign(const TSourceLoc& loc, TOperator op ...@@ -2561,14 +2564,25 @@ TIntermTyped* HlslParseContext::handleAssign(const TSourceLoc& loc, TOperator op
if (left->getAsOperator() && left->getAsOperator()->getOp() == EOpMatrixSwizzle) if (left->getAsOperator() && left->getAsOperator()->getOp() == EOpMatrixSwizzle)
return handleAssignToMatrixSwizzle(loc, op, left, right); return handleAssignToMatrixSwizzle(loc, op, left, right);
const bool isSplitLeft = wasSplit(left); // Return true if the given node is an index operation into a split variable.
const bool isSplitRight = wasSplit(right); const auto indexesSplit = [this](const TIntermTyped* node) -> bool {
const TIntermBinary* binaryNode = node->getAsBinaryNode();
if (binaryNode == nullptr)
return false;
return (binaryNode->getOp() == EOpIndexDirect || binaryNode->getOp() == EOpIndexIndirect) &&
wasSplit(binaryNode->getLeft());
};
const bool isSplitLeft = wasSplit(left) || indexesSplit(left);
const bool isSplitRight = wasSplit(right) || indexesSplit(right);
const bool isFlattenLeft = wasFlattened(left); const bool isFlattenLeft = wasFlattened(left);
const bool isFlattenRight = wasFlattened(right); const bool isFlattenRight = wasFlattened(right);
// OK to do a single assign if both are split, or both are unsplit. But if one is and the other // OK to do a single assign if neither side is split or flattened. Otherwise,
// isn't, we fall back to a member-wise copy. // fall through 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. // Clip and cull distance requires more processing. See comment above assignClipCullDistance.
if (isClipOrCullDistance(left->getType()) || isClipOrCullDistance(right->getType())) { if (isClipOrCullDistance(left->getType()) || isClipOrCullDistance(right->getType())) {
...@@ -2803,8 +2817,25 @@ TIntermTyped* HlslParseContext::handleAssign(const TSourceLoc& loc, TOperator op ...@@ -2803,8 +2817,25 @@ TIntermTyped* HlslParseContext::handleAssign(const TSourceLoc& loc, TOperator op
// If either left or right was a split structure, we must read or write it, but still have to // If either left or right was a split structure, we must read or write it, but still have to
// parallel-recurse through the unsplit structure to identify the built-in IO vars. // parallel-recurse through the unsplit structure to identify the built-in IO vars.
if (isSplitLeft) // The left can be either a symbol, or an index into a symbol (e.g, array reference)
splitLeft = intermediate.addSymbol(*getSplitNonIoVar(left->getAsSymbolNode()->getId()), loc); if (isSplitLeft) {
if (indexesSplit(left)) {
// Index case: Refer to the indexed symbol, if the left is an index operator.
const TIntermSymbol* symNode = left->getAsBinaryNode()->getLeft()->getAsSymbolNode();
TIntermTyped* splitLeftNonIo = intermediate.addSymbol(*getSplitNonIoVar(symNode->getId()), loc);
splitLeft = intermediate.addIndex(left->getAsBinaryNode()->getOp(), splitLeftNonIo,
left->getAsBinaryNode()->getRight(), loc);
const TType derefType(splitLeftNonIo->getType(), 0);
splitLeft->setType(derefType);
} else {
// Symbol case: otherwise, if not indexed, we have the symbol directly.
const TIntermSymbol* symNode = left->getAsSymbolNode();
splitLeft = intermediate.addSymbol(*getSplitNonIoVar(symNode->getId()), loc);
}
}
if (isSplitRight) if (isSplitRight)
splitRight = intermediate.addSymbol(*getSplitNonIoVar(right->getAsSymbolNode()->getId()), loc); splitRight = intermediate.addSymbol(*getSplitNonIoVar(right->getAsSymbolNode()->getId()), loc);
......
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