Built-in values declared as specialization constant

Support declaring built-in values as spec constants.

Refine the code in createSpvConstant().
This commit is contained in:
qining 2016-04-03 23:55:17 -04:00
parent a42533eca1
commit 4f4bb81cd9
4 changed files with 140 additions and 110 deletions

View File

@ -3735,6 +3735,7 @@ spv::Id TGlslangToSpvTraverser::createSpvConstant(const glslang::TIntermTyped& n
{ {
assert(node.getQualifier().isConstant()); assert(node.getQualifier().isConstant());
// Handle front-end constants first (non-specialization constants).
if (! node.getQualifier().specConstant) { if (! node.getQualifier().specConstant) {
// hand off to the non-spec-constant path // hand off to the non-spec-constant path
assert(node.getAsConstantUnion() != nullptr || node.getAsSymbolNode() != nullptr); assert(node.getAsConstantUnion() != nullptr || node.getAsSymbolNode() != nullptr);
@ -3745,31 +3746,35 @@ spv::Id TGlslangToSpvTraverser::createSpvConstant(const glslang::TIntermTyped& n
// We now know we have a specialization constant to build // We now know we have a specialization constant to build
if (node.getAsSymbolNode() && node.getQualifier().hasSpecConstantId()) { // gl_WorkgroupSize is a special case until the front-end handles hierarchical specialization constants,
// this is a direct literal assigned to a layout(constant_id=) declaration // even then, it's specialization ids are handled by special case syntax in GLSL: layout(local_size_x = ...
int nextConst = 0; if (node.getType().getQualifier().builtIn == glslang::EbvWorkGroupSize) {
return createSpvConstantFromConstUnionArray(node.getType(), node.getAsConstantUnion() ? node.getAsConstantUnion()->getConstArray() : node.getAsSymbolNode()->getConstArray(), std::vector<spv::Id> dimConstId;
nextConst, true); for (int dim = 0; dim < 3; ++dim) {
} else { bool specConst = (glslangIntermediate->getLocalSizeSpecId(dim) != glslang::TQualifier::layoutNotSet);
// gl_WorkgroupSize is a special case until the front-end handles hierarchical specialization constants, dimConstId.push_back(builder.makeUintConstant(glslangIntermediate->getLocalSize(dim), specConst));
// even then, it's specialization ids are handled by special case syntax in GLSL: layout(local_size_x = ... if (specConst)
if (node.getType().getQualifier().builtIn == glslang::EbvWorkGroupSize) { addDecoration(dimConstId.back(), spv::DecorationSpecId, glslangIntermediate->getLocalSizeSpecId(dim));
std::vector<spv::Id> dimConstId; }
for (int dim = 0; dim < 3; ++dim) { return builder.makeCompositeConstant(builder.makeVectorType(builder.makeUintType(32), 3), dimConstId, true);
bool specConst = (glslangIntermediate->getLocalSizeSpecId(dim) != glslang::TQualifier::layoutNotSet); }
dimConstId.push_back(builder.makeUintConstant(glslangIntermediate->getLocalSize(dim), specConst));
if (specConst) // An AST node labelled as specialization constant should be a symbol node.
addDecoration(dimConstId.back(), spv::DecorationSpecId, glslangIntermediate->getLocalSizeSpecId(dim)); // Its initializer should either be a sub tree with constant nodes, or a constant union array.
} if (auto* sn = node.getAsSymbolNode()) {
return builder.makeCompositeConstant(builder.makeVectorType(builder.makeUintType(32), 3), dimConstId, true); if (auto* sub_tree = sn->getConstSubtree()) {
} else if (auto* sn = node.getAsSymbolNode()){ return createSpvConstantFromConstSubTree(sub_tree);
return createSpvConstantFromConstSubTree(sn->getConstSubtree()); } else if (auto* const_union_array = &sn->getConstArray()){
} else { int nextConst = 0;
spv::MissingFunctionality("Neither a front-end constant nor a spec constant."); return createSpvConstantFromConstUnionArray(sn->getType(), *const_union_array, nextConst, true);
exit(1);
return spv::NoResult;
} }
} }
// Neither a front-end constant node, nor a specialization constant node with constant union array or
// constant sub tree as initializer.
spv::MissingFunctionality("Neither a front-end constant nor a spec constant.");
exit(1);
return spv::NoResult;
} }
// Use 'consts' as the flattened glslang source of scalar constants to recursively // Use 'consts' as the flattened glslang source of scalar constants to recursively

View File

@ -7,32 +7,35 @@ Linked vertex stage:
// Module Version 10000 // Module Version 10000
// Generated by (magic number): 80001 // Generated by (magic number): 80001
// Id's are bound by 72 // Id's are bound by 81
Capability Shader Capability Shader
Capability Float64 Capability Float64
1: ExtInstImport "GLSL.std.450" 1: ExtInstImport "GLSL.std.450"
MemoryModel Logical GLSL450 MemoryModel Logical GLSL450
EntryPoint Vertex 4 "main" 17 19 25 50 EntryPoint Vertex 4 "main" 20 22 28 53
Source GLSL 400 Source GLSL 400
Name 4 "main" Name 4 "main"
Name 14 "foo(vf4[s1498];" Name 14 "foo(vf4[s1498];"
Name 13 "p" Name 13 "p"
Name 17 "color" Name 17 "builtin_spec_constant("
Name 19 "ucol" Name 20 "color"
Name 25 "size" Name 22 "ucol"
Name 44 "param" Name 28 "size"
Name 50 "dupUcol" Name 47 "param"
Name 53 "dupUcol"
Name 76 "result"
Decorate 9 SpecId 16 Decorate 9 SpecId 16
Decorate 27 SpecId 17 Decorate 30 SpecId 17
Decorate 31 SpecId 22 Decorate 34 SpecId 22
Decorate 36 SpecId 19 Decorate 39 SpecId 19
Decorate 37 SpecId 18 Decorate 40 SpecId 18
Decorate 47 SpecId 116 Decorate 50 SpecId 116
Decorate 57 SpecId 117 Decorate 60 SpecId 117
Decorate 60 SpecId 122 Decorate 63 SpecId 122
Decorate 64 SpecId 119 Decorate 67 SpecId 119
Decorate 65 SpecId 118 Decorate 68 SpecId 118
Decorate 77 SpecId 24
2: TypeVoid 2: TypeVoid
3: TypeFunction 2 3: TypeFunction 2
6: TypeFloat 32 6: TypeFloat 32
@ -42,83 +45,93 @@ Linked vertex stage:
10: TypeArray 7(fvec4) 9 10: TypeArray 7(fvec4) 9
11: TypePointer Function 10 11: TypePointer Function 10
12: TypeFunction 2 11(ptr) 12: TypeFunction 2 11(ptr)
16: TypePointer Output 7(fvec4) 16: TypeFunction 8(int)
17(color): 16(ptr) Variable Output 19: TypePointer Output 7(fvec4)
18: TypePointer Input 10 20(color): 19(ptr) Variable Output
19(ucol): 18(ptr) Variable Input 21: TypePointer Input 10
20: 8(int) Constant 2 22(ucol): 21(ptr) Variable Input
21: TypePointer Input 7(fvec4) 23: 8(int) Constant 2
24: TypePointer Output 8(int) 24: TypePointer Input 7(fvec4)
25(size): 24(ptr) Variable Output 27: TypePointer Output 8(int)
26: TypeBool 28(size): 27(ptr) Variable Output
27: 26(bool) SpecConstantTrue 29: TypeBool
30: TypeInt 32 0 30: 29(bool) SpecConstantTrue
31: 30(int) SpecConstant 2 33: TypeInt 32 0
35: TypeFloat 64 34: 33(int) SpecConstant 2
36: 35(float) SpecConstant 1413754136 1074340347 38: TypeFloat 64
37: 6(float) SpecConstant 1078523331 39: 38(float) SpecConstant 1413754136 1074340347
47: 8(int) SpecConstant 12 40: 6(float) SpecConstant 1078523331
48: TypeArray 7(fvec4) 47 50: 8(int) SpecConstant 12
49: TypePointer Input 48 51: TypeArray 7(fvec4) 50
50(dupUcol): 49(ptr) Variable Input 52: TypePointer Input 51
57: 26(bool) SpecConstantTrue 53(dupUcol): 52(ptr) Variable Input
60: 30(int) SpecConstant 2 60: 29(bool) SpecConstantTrue
64: 35(float) SpecConstant 1413754136 1074340347 63: 33(int) SpecConstant 2
65: 6(float) SpecConstant 1078523331 67: 38(float) SpecConstant 1413754136 1074340347
68: 6(float) SpecConstant 1078523331
75: TypePointer Function 8(int)
77: 8(int) SpecConstant 8
4(main): 2 Function None 3 4(main): 2 Function None 3
5: Label 5: Label
44(param): 11(ptr) Variable Function 47(param): 11(ptr) Variable Function
22: 21(ptr) AccessChain 19(ucol) 20 25: 24(ptr) AccessChain 22(ucol) 23
23: 7(fvec4) Load 22 26: 7(fvec4) Load 25
Store 17(color) 23 Store 20(color) 26
Store 25(size) 9 Store 28(size) 9
SelectionMerge 29 None SelectionMerge 32 None
BranchConditional 27 28 29 BranchConditional 30 31 32
28: Label 31: Label
32: 6(float) ConvertUToF 31 35: 6(float) ConvertUToF 34
33: 7(fvec4) Load 17(color) 36: 7(fvec4) Load 20(color)
34: 7(fvec4) VectorTimesScalar 33 32 37: 7(fvec4) VectorTimesScalar 36 35
Store 17(color) 34 Store 20(color) 37
Branch 29 Branch 32
29: Label 32: Label
38: 35(float) FConvert 37 41: 38(float) FConvert 40
39: 35(float) FDiv 36 38 42: 38(float) FDiv 39 41
40: 6(float) FConvert 39 43: 6(float) FConvert 42
41: 7(fvec4) Load 17(color) 44: 7(fvec4) Load 20(color)
42: 7(fvec4) CompositeConstruct 40 40 40 40 45: 7(fvec4) CompositeConstruct 43 43 43 43
43: 7(fvec4) FAdd 41 42 46: 7(fvec4) FAdd 44 45
Store 17(color) 43 Store 20(color) 46
45: 10 Load 19(ucol) 48: 10 Load 22(ucol)
Store 44(param) 45 Store 47(param) 48
46: 2 FunctionCall 14(foo(vf4[s1498];) 44(param) 49: 2 FunctionCall 14(foo(vf4[s1498];) 47(param)
Return Return
FunctionEnd FunctionEnd
14(foo(vf4[s1498];): 2 Function None 12 14(foo(vf4[s1498];): 2 Function None 12
13(p): 11(ptr) FunctionParameter 13(p): 11(ptr) FunctionParameter
15: Label 15: Label
51: 21(ptr) AccessChain 50(dupUcol) 20 54: 24(ptr) AccessChain 53(dupUcol) 23
52: 7(fvec4) Load 51 55: 7(fvec4) Load 54
53: 7(fvec4) Load 17(color) 56: 7(fvec4) Load 20(color)
54: 7(fvec4) FAdd 53 52 57: 7(fvec4) FAdd 56 55
Store 17(color) 54 Store 20(color) 57
55: 8(int) Load 25(size) 58: 8(int) Load 28(size)
56: 8(int) IAdd 55 47 59: 8(int) IAdd 58 50
Store 25(size) 56 Store 28(size) 59
SelectionMerge 59 None SelectionMerge 62 None
BranchConditional 57 58 59 BranchConditional 60 61 62
58: Label 61: Label
61: 6(float) ConvertUToF 60 64: 6(float) ConvertUToF 63
62: 7(fvec4) Load 17(color) 65: 7(fvec4) Load 20(color)
63: 7(fvec4) VectorTimesScalar 62 61 66: 7(fvec4) VectorTimesScalar 65 64
Store 17(color) 63 Store 20(color) 66
Branch 59 Branch 62
59: Label 62: Label
66: 35(float) FConvert 65 69: 38(float) FConvert 68
67: 35(float) FDiv 64 66 70: 38(float) FDiv 67 69
68: 6(float) FConvert 67 71: 6(float) FConvert 70
69: 7(fvec4) Load 17(color) 72: 7(fvec4) Load 20(color)
70: 7(fvec4) CompositeConstruct 68 68 68 68 73: 7(fvec4) CompositeConstruct 71 71 71 71
71: 7(fvec4) FAdd 69 70 74: 7(fvec4) FAdd 72 73
Store 17(color) 71 Store 20(color) 74
Return Return
FunctionEnd FunctionEnd
17(builtin_spec_constant(): 8(int) Function None 16
18: Label
76(result): 75(ptr) Variable Function
Store 76(result) 77
78: 8(int) Load 76(result)
ReturnValue 78
FunctionEnd

View File

@ -8,6 +8,8 @@ layout(constant_id = 18) const float spFloat = 3.14;
layout(constant_id = 19) const double spDouble = 3.1415926535897932384626433832795; layout(constant_id = 19) const double spDouble = 3.1415926535897932384626433832795;
layout(constant_id = 22) const uint scale = 2; layout(constant_id = 22) const uint scale = 2;
layout(constant_id = 24) gl_MaxImageUnits;
out vec4 color; out vec4 color;
out int size; out int size;
@ -41,3 +43,9 @@ void foo(vec4 p[arraySize])
color *= dupScale; color *= dupScale;
color += float(spDupDouble / spDupFloat); color += float(spDupDouble / spDupFloat);
} }
int builtin_spec_constant()
{
int result = gl_MaxImageUnits;
return result;
}

View File

@ -5713,6 +5713,10 @@ void TParseContext::addQualifierToExisting(const TSourceLoc& loc, TQualifier qua
error(loc, "cannot change qualification after use", "invariant", ""); error(loc, "cannot change qualification after use", "invariant", "");
symbol->getWritableType().getQualifier().invariant = true; symbol->getWritableType().getQualifier().invariant = true;
invariantCheck(loc, symbol->getType().getQualifier()); invariantCheck(loc, symbol->getType().getQualifier());
} else if (qualifier.specConstant) {
symbol->getWritableType().getQualifier().makeSpecConstant();
if (qualifier.hasSpecConstantId())
symbol->getWritableType().getQualifier().layoutSpecConstantId = qualifier.layoutSpecConstantId;
} else } else
warn(loc, "unknown requalification", "", ""); warn(loc, "unknown requalification", "", "");
} }