-
Notifications
You must be signed in to change notification settings - Fork 853
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Support specialization composite constants #211
Merged
johnkslang
merged 1 commit into
KhronosGroup:master
from
Qining:spec-constants-composite
Mar 25, 2016
Merged
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -128,8 +128,9 @@ class TGlslangToSpvTraverser : public glslang::TIntermTraverser { | |
void addDecoration(spv::Id id, spv::Decoration dec, unsigned value); | ||
void addMemberDecoration(spv::Id id, int member, spv::Decoration dec); | ||
void addMemberDecoration(spv::Id id, int member, spv::Decoration dec, unsigned value); | ||
spv::Id createSpvSpecConstant(const glslang::TIntermTyped&); | ||
spv::Id createSpvConstant(const glslang::TType& type, const glslang::TConstUnionArray&, int& nextConst, bool specConstant); | ||
spv::Id createSpvConstant(const glslang::TIntermTyped&); | ||
spv::Id createSpvConstantFromConstUnionArray(const glslang::TType& type, const glslang::TConstUnionArray&, int& nextConst, bool specConstant); | ||
spv::Id createSpvConstantFromConstSubTree(const glslang::TIntermTyped* subTree); | ||
bool isTrivialLeaf(const glslang::TIntermTyped* node); | ||
bool isTrivial(const glslang::TIntermTyped* node); | ||
spv::Id createShortCircuit(glslang::TOperator, glslang::TIntermTyped& left, glslang::TIntermTyped& right); | ||
|
@@ -1520,7 +1521,7 @@ bool TGlslangToSpvTraverser::visitSwitch(glslang::TVisit /* visit */, glslang::T | |
void TGlslangToSpvTraverser::visitConstantUnion(glslang::TIntermConstantUnion* node) | ||
{ | ||
int nextConst = 0; | ||
spv::Id constant = createSpvConstant(node->getType(), node->getConstArray(), nextConst, false); | ||
spv::Id constant = createSpvConstantFromConstUnionArray(node->getType(), node->getConstArray(), nextConst, false); | ||
|
||
builder.clearAccessChain(); | ||
builder.setAccessChainRValue(constant); | ||
|
@@ -1630,7 +1631,7 @@ spv::Id TGlslangToSpvTraverser::createSpvVariable(const glslang::TIntermSymbol* | |
// can still have a mapping to a SPIR-V Id. | ||
// This includes specialization constants. | ||
if (node->getQualifier().isConstant()) { | ||
return createSpvSpecConstant(*node); | ||
return createSpvConstant(*node); | ||
} | ||
|
||
// Now, handle actual variables | ||
|
@@ -3730,15 +3731,15 @@ void TGlslangToSpvTraverser::addMemberDecoration(spv::Id id, int member, spv::De | |
// recursively walks. So, this function walks the "top" of the tree: | ||
// - emit specialization constant-building instructions for specConstant | ||
// - when running into a non-spec-constant, switch to createSpvConstant() | ||
spv::Id TGlslangToSpvTraverser::createSpvSpecConstant(const glslang::TIntermTyped& node) | ||
spv::Id TGlslangToSpvTraverser::createSpvConstant(const glslang::TIntermTyped& node) | ||
{ | ||
assert(node.getQualifier().isConstant()); | ||
|
||
if (! node.getQualifier().specConstant) { | ||
// hand off to the non-spec-constant path | ||
assert(node.getAsConstantUnion() != nullptr || node.getAsSymbolNode() != nullptr); | ||
int nextConst = 0; | ||
return createSpvConstant(node.getType(), node.getAsConstantUnion() ? node.getAsConstantUnion()->getConstArray() : node.getAsSymbolNode()->getConstArray(), | ||
return createSpvConstantFromConstUnionArray(node.getType(), node.getAsConstantUnion() ? node.getAsConstantUnion()->getConstArray() : node.getAsSymbolNode()->getConstArray(), | ||
nextConst, false); | ||
} | ||
|
||
|
@@ -3747,7 +3748,7 @@ spv::Id TGlslangToSpvTraverser::createSpvSpecConstant(const glslang::TIntermType | |
if (node.getAsSymbolNode() && node.getQualifier().hasSpecConstantId()) { | ||
// this is a direct literal assigned to a layout(constant_id=) declaration | ||
int nextConst = 0; | ||
return createSpvConstant(node.getType(), node.getAsConstantUnion() ? node.getAsConstantUnion()->getConstArray() : node.getAsSymbolNode()->getConstArray(), | ||
return createSpvConstantFromConstUnionArray(node.getType(), node.getAsConstantUnion() ? node.getAsConstantUnion()->getConstArray() : node.getAsSymbolNode()->getConstArray(), | ||
nextConst, true); | ||
} else { | ||
// gl_WorkgroupSize is a special case until the front-end handles hierarchical specialization constants, | ||
|
@@ -3761,8 +3762,10 @@ spv::Id TGlslangToSpvTraverser::createSpvSpecConstant(const glslang::TIntermType | |
addDecoration(dimConstId.back(), spv::DecorationSpecId, glslangIntermediate->getLocalSizeSpecId(dim)); | ||
} | ||
return builder.makeCompositeConstant(builder.makeVectorType(builder.makeUintType(32), 3), dimConstId, true); | ||
} else if (auto* sn = node.getAsSymbolNode()){ | ||
return createSpvConstantFromConstSubTree(sn->getConstSubtree()); | ||
} else { | ||
spv::MissingFunctionality("specialization-constant expression trees"); | ||
spv::MissingFunctionality("Neither a front-end constant nor a spec constant."); | ||
exit(1); | ||
return spv::NoResult; | ||
} | ||
|
@@ -3775,7 +3778,7 @@ spv::Id TGlslangToSpvTraverser::createSpvSpecConstant(const glslang::TIntermType | |
// If there are not enough elements present in 'consts', 0 will be substituted; | ||
// an empty 'consts' can be used to create a fully zeroed SPIR-V constant. | ||
// | ||
spv::Id TGlslangToSpvTraverser::createSpvConstant(const glslang::TType& glslangType, const glslang::TConstUnionArray& consts, int& nextConst, bool specConstant) | ||
spv::Id TGlslangToSpvTraverser::createSpvConstantFromConstUnionArray(const glslang::TType& glslangType, const glslang::TConstUnionArray& consts, int& nextConst, bool specConstant) | ||
{ | ||
// vector of constants for SPIR-V | ||
std::vector<spv::Id> spvConsts; | ||
|
@@ -3786,15 +3789,15 @@ spv::Id TGlslangToSpvTraverser::createSpvConstant(const glslang::TType& glslangT | |
if (glslangType.isArray()) { | ||
glslang::TType elementType(glslangType, 0); | ||
for (int i = 0; i < glslangType.getOuterArraySize(); ++i) | ||
spvConsts.push_back(createSpvConstant(elementType, consts, nextConst, false)); | ||
spvConsts.push_back(createSpvConstantFromConstUnionArray(elementType, consts, nextConst, false)); | ||
} else if (glslangType.isMatrix()) { | ||
glslang::TType vectorType(glslangType, 0); | ||
for (int col = 0; col < glslangType.getMatrixCols(); ++col) | ||
spvConsts.push_back(createSpvConstant(vectorType, consts, nextConst, false)); | ||
spvConsts.push_back(createSpvConstantFromConstUnionArray(vectorType, consts, nextConst, false)); | ||
} else if (glslangType.getStruct()) { | ||
glslang::TVector<glslang::TTypeLoc>::const_iterator iter; | ||
for (iter = glslangType.getStruct()->begin(); iter != glslangType.getStruct()->end(); ++iter) | ||
spvConsts.push_back(createSpvConstant(*iter->type, consts, nextConst, false)); | ||
spvConsts.push_back(createSpvConstantFromConstUnionArray(*iter->type, consts, nextConst, false)); | ||
} else if (glslangType.isVector()) { | ||
for (unsigned int i = 0; i < (unsigned int)glslangType.getVectorSize(); ++i) { | ||
bool zero = nextConst >= consts.size(); | ||
|
@@ -3851,6 +3854,66 @@ spv::Id TGlslangToSpvTraverser::createSpvConstant(const glslang::TType& glslangT | |
return builder.makeCompositeConstant(typeId, spvConsts); | ||
} | ||
|
||
// Create constant ID from const initializer sub tree. | ||
spv::Id TGlslangToSpvTraverser::createSpvConstantFromConstSubTree( | ||
const glslang::TIntermTyped* subTree) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Have function open '{' start a new line. |
||
const glslang::TType& glslangType = subTree->getType(); | ||
spv::Id typeId = convertGlslangToSpvType(glslangType); | ||
bool is_spec_const = subTree->getType().getQualifier().isSpecConstant(); | ||
if (const glslang::TIntermAggregate* an = subTree->getAsAggregate()) { | ||
// Aggregate node, we should generate OpConstantComposite or | ||
// OpSpecConstantComposite instruction. | ||
std::vector<spv::Id> const_constituents; | ||
for (auto NI = an->getSequence().begin(); NI != an->getSequence().end(); | ||
NI++) { | ||
const_constituents.push_back( | ||
createSpvConstantFromConstSubTree((*NI)->getAsTyped())); | ||
} | ||
// Note that constructors are aggregate nodes, so expressions like: | ||
// float x = float(y) will become an aggregate node. If 'x' is declared | ||
// as a constant, the aggregate node representing 'float(y)' will be | ||
// processed here. | ||
if (builder.isVectorType(typeId) || builder.isMatrixType(typeId) || | ||
builder.isAggregateType(typeId)) { | ||
return builder.makeCompositeConstant(typeId, const_constituents, is_spec_const); | ||
} else { | ||
assert(builder.isScalarType(typeId) && const_constituents.size() == 1); | ||
return const_constituents.front(); | ||
} | ||
|
||
} else if (const glslang::TIntermBinary* bn = subTree->getAsBinaryNode()) { | ||
// Binary operation node, we should generate OpSpecConstantOp <binary op> | ||
// This case should only happen when Specialization Constants are involved. | ||
spv::MissingFunctionality("OpSpecConstantOp <binary op> not implemented"); | ||
return spv::NoResult; | ||
|
||
} else if (const glslang::TIntermUnary* un = subTree->getAsUnaryNode()) { | ||
// Unary operation node, similar to binary operation node, should only | ||
// happen when specialization constants are involved. | ||
spv::MissingFunctionality("OpSpecConstantOp <unary op> not implemented"); | ||
return spv::NoResult; | ||
|
||
} else if (const glslang::TIntermConstantUnion* cn = subTree->getAsConstantUnion()) { | ||
// ConstantUnion node, should redirect to | ||
// createSpvConstantFromConstUnionArray | ||
int nextConst = 0; | ||
return createSpvConstantFromConstUnionArray( | ||
glslangType, cn->getConstArray(), nextConst, is_spec_const); | ||
|
||
} else if (const glslang::TIntermSymbol* sn = subTree->getAsSymbolNode()) { | ||
// Symbol node. Call getSymbolId(). This should cover both cases 1) the | ||
// symbol has already been assigned an ID, 2) need a new ID for this | ||
// symbol. | ||
return getSymbolId(sn); | ||
|
||
} else { | ||
spv::MissingFunctionality( | ||
"createSpvConstantFromConstSubTree() not covered TIntermTyped* const " | ||
"initializer subtree."); | ||
return spv::NoResult; | ||
} | ||
} | ||
|
||
// Return true if the node is a constant or symbol whose reading has no | ||
// non-trivial observable cost or effect. | ||
bool TGlslangToSpvTraverser::isTrivialLeaf(const glslang::TIntermTyped* node) | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,172 @@ | ||
spv.specConstantComposite.vert | ||
Warning, version 450 is not yet complete; most version-specific features are present, but some are missing. | ||
|
||
|
||
Linked vertex stage: | ||
|
||
|
||
// Module Version 10000 | ||
// Generated by (magic number): 80001 | ||
// Id's are bound by 106 | ||
|
||
Capability Shader | ||
Capability Float64 | ||
1: ExtInstImport "GLSL.std.450" | ||
MemoryModel Logical GLSL450 | ||
EntryPoint Vertex 4 "main" 27 105 | ||
Source GLSL 450 | ||
Name 4 "main" | ||
Name 6 "refer_primary_spec_const(" | ||
Name 8 "refer_composite_spec_const(" | ||
Name 10 "refer_copmosite_dot_dereference(" | ||
Name 12 "refer_composite_bracket_dereference(" | ||
Name 16 "refer_spec_const_array_length(" | ||
Name 18 "declare_spec_const_in_func(" | ||
Name 27 "color" | ||
Name 41 "flat_struct" | ||
MemberName 41(flat_struct) 0 "i" | ||
MemberName 41(flat_struct) 1 "f" | ||
MemberName 41(flat_struct) 2 "d" | ||
MemberName 41(flat_struct) 3 "b" | ||
Name 42 "nesting_struct" | ||
MemberName 42(nesting_struct) 0 "nested" | ||
MemberName 42(nesting_struct) 1 "v" | ||
MemberName 42(nesting_struct) 2 "i" | ||
Name 72 "indexable" | ||
Name 76 "indexable" | ||
Name 83 "len" | ||
Name 105 "global_vec4_array_with_spec_length" | ||
Decorate 21 SpecId 203 | ||
Decorate 28 SpecId 200 | ||
Decorate 32 SpecId 201 | ||
Decorate 43 SpecId 202 | ||
2: TypeVoid | ||
3: TypeFunction 2 | ||
14: TypeInt 32 1 | ||
15: TypeFunction 14(int) | ||
20: TypeBool | ||
21: 20(bool) SpecConstantTrue | ||
24: TypeFloat 32 | ||
25: TypeVector 24(float) 4 | ||
26: TypePointer Output 25(fvec4) | ||
27(color): 26(ptr) Variable Output | ||
28: 14(int) SpecConstant 3 | ||
32: 24(float) SpecConstant 1078523331 | ||
33: 25(fvec4) SpecConstantComposite 32 32 32 32 | ||
36: 24(float) Constant 1133908460 | ||
37: 25(fvec4) SpecConstantComposite 32 32 36 36 | ||
40: TypeFloat 64 | ||
41(flat_struct): TypeStruct 14(int) 24(float) 40(float) 20(bool) | ||
42(nesting_struct): TypeStruct 41(flat_struct) 25(fvec4) 14(int) | ||
43: 40(float) SpecConstant 1413754136 1074340347 | ||
44:41(flat_struct) SpecConstantComposite 28 32 43 21 | ||
45:42(nesting_struct) SpecConstantComposite 44 33 28 | ||
46: 14(int) Constant 2 | ||
51: TypeInt 32 0 | ||
52: 51(int) Constant 0 | ||
57: 51(int) Constant 5 | ||
58: TypeArray 24(float) 57 | ||
59: 24(float) Constant 1065353216 | ||
60: 24(float) Constant 1073741824 | ||
61: 24(float) Constant 1077936128 | ||
62: 58 SpecConstantComposite 32 32 59 60 61 | ||
63: 14(int) Constant 1 | ||
68: TypeArray 14(int) 57 | ||
69: 14(int) Constant 30 | ||
70: 68 SpecConstantComposite 28 28 63 46 69 | ||
71: TypePointer Function 68 | ||
73: TypePointer Function 14(int) | ||
87: 24(float) Constant 1106321080 | ||
88:41(flat_struct) SpecConstantComposite 69 87 43 21 | ||
89: 14(int) Constant 10 | ||
90:42(nesting_struct) SpecConstantComposite 88 37 89 | ||
96: 20(bool) ConstantFalse | ||
97:41(flat_struct) SpecConstantComposite 28 32 43 96 | ||
98: 24(float) Constant 1036831949 | ||
99: 25(fvec4) ConstantComposite 98 98 98 98 | ||
100:42(nesting_struct) SpecConstantComposite 97 99 28 | ||
101: 14(int) Constant 3000 | ||
102:42(nesting_struct) SpecConstantComposite 88 37 101 | ||
103: TypeArray 25(fvec4) 28 | ||
104: TypePointer Input 103 | ||
105(global_vec4_array_with_spec_length): 104(ptr) Variable Input | ||
4(main): 2 Function None 3 | ||
5: Label | ||
Return | ||
FunctionEnd | ||
6(refer_primary_spec_const(): 2 Function None 3 | ||
7: Label | ||
SelectionMerge 23 None | ||
BranchConditional 21 22 23 | ||
22: Label | ||
29: 24(float) ConvertSToF 28 | ||
30: 25(fvec4) Load 27(color) | ||
31: 25(fvec4) VectorTimesScalar 30 29 | ||
Store 27(color) 31 | ||
Branch 23 | ||
23: Label | ||
Return | ||
FunctionEnd | ||
8(refer_composite_spec_const(): 2 Function None 3 | ||
9: Label | ||
34: 25(fvec4) Load 27(color) | ||
35: 25(fvec4) FAdd 34 33 | ||
Store 27(color) 35 | ||
38: 25(fvec4) Load 27(color) | ||
39: 25(fvec4) FSub 38 37 | ||
Store 27(color) 39 | ||
Return | ||
FunctionEnd | ||
10(refer_copmosite_dot_dereference(): 2 Function None 3 | ||
11: Label | ||
47: 14(int) CompositeExtract 45 2 | ||
48: 24(float) ConvertSToF 47 | ||
49: 25(fvec4) Load 27(color) | ||
50: 25(fvec4) VectorTimesScalar 49 48 | ||
Store 27(color) 50 | ||
53: 24(float) CompositeExtract 33 0 | ||
54: 25(fvec4) Load 27(color) | ||
55: 25(fvec4) CompositeConstruct 53 53 53 53 | ||
56: 25(fvec4) FAdd 54 55 | ||
Store 27(color) 56 | ||
Return | ||
FunctionEnd | ||
12(refer_composite_bracket_dereference(): 2 Function None 3 | ||
13: Label | ||
72(indexable): 71(ptr) Variable Function | ||
76(indexable): 71(ptr) Variable Function | ||
64: 24(float) CompositeExtract 62 1 | ||
65: 25(fvec4) Load 27(color) | ||
66: 25(fvec4) CompositeConstruct 64 64 64 64 | ||
67: 25(fvec4) FSub 65 66 | ||
Store 27(color) 67 | ||
Store 72(indexable) 70 | ||
74: 73(ptr) AccessChain 72(indexable) 28 | ||
75: 14(int) Load 74 | ||
Store 76(indexable) 70 | ||
77: 73(ptr) AccessChain 76(indexable) 75 | ||
78: 14(int) Load 77 | ||
79: 24(float) ConvertSToF 78 | ||
80: 25(fvec4) Load 27(color) | ||
81: 25(fvec4) CompositeConstruct 79 79 79 79 | ||
82: 25(fvec4) FDiv 80 81 | ||
Store 27(color) 82 | ||
Return | ||
FunctionEnd | ||
16(refer_spec_const_array_length(): 14(int) Function None 15 | ||
17: Label | ||
83(len): 73(ptr) Variable Function | ||
Store 83(len) 28 | ||
84: 14(int) Load 83(len) | ||
ReturnValue 84 | ||
FunctionEnd | ||
18(declare_spec_const_in_func(): 2 Function None 3 | ||
19: Label | ||
91: 14(int) CompositeExtract 90 2 | ||
92: 24(float) ConvertSToF 91 | ||
93: 25(fvec4) Load 27(color) | ||
94: 25(fvec4) CompositeConstruct 92 92 92 92 | ||
95: 25(fvec4) FDiv 93 94 | ||
Store 27(color) 95 | ||
Return | ||
FunctionEnd |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Need 4 space indentation.