mirror of
https://github.com/KhronosGroup/glslang
synced 2024-11-08 11:30:06 +00:00
SPV: Implement specialization constants for ?:.
This commit is contained in:
parent
433e9ff896
commit
8e6c6cef6a
@ -1775,7 +1775,7 @@ bool TGlslangToSpvTraverser::visitSelection(glslang::TVisit /* visit */, glslang
|
||||
|
||||
// return true if a single operand to ? : is okay for OpSelect
|
||||
const auto operandOkay = [](glslang::TIntermTyped* node) {
|
||||
return node->getAsSymbolNode() || node->getAsConstantUnion();
|
||||
return node->getAsSymbolNode() || node->getType().getQualifier().isConstant();
|
||||
};
|
||||
|
||||
return operandOkay(node->getTrueBlock() ->getAsTyped()) &&
|
||||
@ -1799,6 +1799,10 @@ bool TGlslangToSpvTraverser::visitSelection(glslang::TVisit /* visit */, glslang
|
||||
// Try for OpSelect
|
||||
|
||||
if (selectPolicy()) {
|
||||
SpecConstantOpModeGuard spec_constant_op_mode_setter(&builder);
|
||||
if (node->getType().getQualifier().isSpecConstant())
|
||||
spec_constant_op_mode_setter.turnOnSpecConstantOpMode();
|
||||
|
||||
handleAsOpSelect();
|
||||
return false;
|
||||
}
|
||||
|
@ -3,7 +3,7 @@ Warning, version 450 is not yet complete; most version-specific features are pre
|
||||
|
||||
// Module Version 10000
|
||||
// Generated by (magic number): 80001
|
||||
// Id's are bound by 135
|
||||
// Id's are bound by 160
|
||||
|
||||
Capability Shader
|
||||
Capability Float64
|
||||
@ -20,11 +20,18 @@ Warning, version 450 is not yet complete; most version-specific features are pre
|
||||
Name 42 "sp_uint"
|
||||
Name 43 "sp_sint"
|
||||
Name 45 "sp_double"
|
||||
Name 135 "a"
|
||||
Name 136 "b"
|
||||
Name 137 "c"
|
||||
Name 142 "ternayArray1"
|
||||
Decorate 19(sp_int) SpecId 201
|
||||
Decorate 40(sp_float) SpecId 200
|
||||
Decorate 42(sp_uint) SpecId 202
|
||||
Decorate 43(sp_sint) SpecId 203
|
||||
Decorate 45(sp_double) SpecId 204
|
||||
Decorate 135(a) SpecId 210
|
||||
Decorate 136(b) SpecId 211
|
||||
Decorate 137(c) SpecId 212
|
||||
2: TypeVoid
|
||||
3: TypeFunction 2
|
||||
6: TypeInt 32 1
|
||||
@ -137,6 +144,31 @@ Warning, version 450 is not yet complete; most version-specific features are pre
|
||||
132: TypeVector 6(int) 3
|
||||
133: 132(ivec3) SpecConstantOp 79 91 91 2 1(GLSL.std.450) 0
|
||||
134: 90(ivec4) SpecConstantOp 79 91 91 1(GLSL.std.450) 2 0 3
|
||||
135(a): 6(int) SpecConstant 4
|
||||
136(b): 6(int) SpecConstant 6
|
||||
137(c): 22(bool) SpecConstantTrue
|
||||
138: 22(bool) SpecConstantOp 173 135(a) 136(b)
|
||||
139: 6(int) SpecConstantOp 169 138 135(a) 136(b)
|
||||
140: TypeArray 6(int) 139
|
||||
141: TypePointer Private 140
|
||||
142(ternayArray1): 141(ptr) Variable Private
|
||||
143: 6(int) Constant 13
|
||||
144: 6(int) Constant 17
|
||||
145: 6(int) SpecConstantOp 169 137(c) 143 144
|
||||
146: 6(int) SpecConstantOp 169 137(c) 135(a) 144
|
||||
147: 22(bool) ConstantTrue
|
||||
148: 6(int) SpecConstantOp 169 147 135(a) 144
|
||||
149: 22(bool) SpecConstantOp 173 135(a) 136(b)
|
||||
150: 6(int) SpecConstantOp 128 143 135(a)
|
||||
151: 6(int) SpecConstantOp 132 144 136(b)
|
||||
152: 6(int) SpecConstantOp 169 149 150 151
|
||||
153: 22(bool) SpecConstantOp 168 137(c)
|
||||
154: TypeVector 39(float) 2
|
||||
155: 39(float) Constant 1065353216
|
||||
156: 154(fvec2) ConstantComposite 155 155
|
||||
157: 39(float) Constant 1073741824
|
||||
158: 154(fvec2) ConstantComposite 157 157
|
||||
159: 154(fvec2) SpecConstantOp 169 153 156 158
|
||||
4(main): 2 Function None 3
|
||||
5: Label
|
||||
Return
|
||||
|
@ -110,5 +110,15 @@ int non_const_array_size_from_spec_const() {
|
||||
return array[sp_int + 1];
|
||||
}
|
||||
|
||||
void main() {}
|
||||
// ternary
|
||||
layout(constant_id = 210) const int a = 4;
|
||||
layout(constant_id = 211) const int b = 6;
|
||||
layout(constant_id = 212) const bool c = true;
|
||||
int ternayArray1[a > b ? a : b];
|
||||
const int t1 = c ? 13 : 17;
|
||||
const int t2 = c ? a : 17;
|
||||
const int t3 = true ? a : 17;
|
||||
const int t4 = a > b ? 13 + a : 17 * b;
|
||||
const vec2 v2 = !c ? vec2(1.0) : vec2(2.0);
|
||||
|
||||
void main() {}
|
||||
|
@ -155,13 +155,9 @@ TIntermTyped* TIntermediate::addBinaryMath(TOperator op, TIntermTyped* left, TIn
|
||||
return folded;
|
||||
}
|
||||
|
||||
// If either is a specialization constant, while the other is
|
||||
// a constant (or specialization constant), the result is still
|
||||
// a specialization constant, if the operation is an allowed
|
||||
// specialization-constant operation.
|
||||
if (( left->getType().getQualifier().isSpecConstant() && right->getType().getQualifier().isConstant()) ||
|
||||
(right->getType().getQualifier().isSpecConstant() && left->getType().getQualifier().isConstant()))
|
||||
if (isSpecializationOperation(*node))
|
||||
// If can propagate spec-constantness and if the operation is an allowed
|
||||
// specialization-constant operation, make a spec-constant.
|
||||
if (specConstantPropagates(*left, *right) && isSpecializationOperation(*node))
|
||||
node->getWritableType().getQualifier().makeSpecConstant();
|
||||
|
||||
return node;
|
||||
@ -1277,6 +1273,9 @@ TIntermTyped* TIntermediate::addMethod(TIntermTyped* object, const TType& type,
|
||||
// a true path, and a false path. The two paths are specified
|
||||
// as separate parameters.
|
||||
//
|
||||
// Specialization constant operations include
|
||||
// - The ternary operator ( ? : )
|
||||
//
|
||||
// Returns the selection node created, or nullptr if one could not be.
|
||||
//
|
||||
TIntermTyped* TIntermediate::addSelection(TIntermTyped* cond, TIntermTyped* trueBlock, TIntermTyped* falseBlock, const TSourceLoc& loc)
|
||||
@ -1320,10 +1319,16 @@ TIntermTyped* TIntermediate::addSelection(TIntermTyped* cond, TIntermTyped* true
|
||||
// Make a selection node.
|
||||
//
|
||||
TIntermSelection* node = new TIntermSelection(cond, trueBlock, falseBlock, trueBlock->getType());
|
||||
node->getQualifier().makeTemporary();
|
||||
node->setLoc(loc);
|
||||
node->getQualifier().precision = std::max(trueBlock->getQualifier().precision, falseBlock->getQualifier().precision);
|
||||
|
||||
if ((cond->getQualifier().isConstant() && specConstantPropagates(*trueBlock, *falseBlock)) ||
|
||||
(cond->getQualifier().isSpecConstant() && trueBlock->getQualifier().isConstant() &&
|
||||
falseBlock->getQualifier().isConstant()))
|
||||
node->getQualifier().makeSpecConstant();
|
||||
else
|
||||
node->getQualifier().makeTemporary();
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
@ -2645,4 +2650,13 @@ void TIntermAggregate::addToPragmaTable(const TPragmaTable& pTable)
|
||||
*pragmaTable = pTable;
|
||||
}
|
||||
|
||||
// If either node is a specialization constant, while the other is
|
||||
// a constant (or specialization constant), the result is still
|
||||
// a specialization constant.
|
||||
bool TIntermediate::specConstantPropagates(const TIntermTyped& node1, const TIntermTyped& node2)
|
||||
{
|
||||
return (node1.getType().getQualifier().isSpecConstant() && node2.getType().getQualifier().isConstant()) ||
|
||||
(node2.getType().getQualifier().isSpecConstant() && node1.getType().getQualifier().isConstant());
|
||||
}
|
||||
|
||||
} // end namespace glslang
|
||||
|
@ -440,6 +440,7 @@ protected:
|
||||
bool promoteAggregate(TIntermAggregate&);
|
||||
void pushSelector(TIntermSequence&, const TVectorSelector&, const TSourceLoc&);
|
||||
void pushSelector(TIntermSequence&, const TMatrixSelector&, const TSourceLoc&);
|
||||
bool specConstantPropagates(const TIntermTyped&, const TIntermTyped&);
|
||||
|
||||
const EShLanguage language; // stage, known at construction time
|
||||
EShSource source; // source language, known a bit later
|
||||
|
Loading…
Reference in New Issue
Block a user