Improved fix for buffer reference constants
This is an alternate fix for the issue described in commit be63facd, whose solution didn't work if there were non-trivial operations involved in computing a constant initializer which caused the 'constant unfolding' code to kick in (addConstantReferenceConversion). Instead, this change does the 'unfolding' later in createSpvConstantFromConstUnionArray. If a reference-type constant has survived that long, then folding is already done, this must be a 'real' (inside a function) use of the constant, and it should be safe to unfold and apply the bitcast.
This commit is contained in:
parent
79d25ea0ce
commit
3fd1232665
@ -7705,6 +7705,10 @@ spv::Id TGlslangToSpvTraverser::createSpvConstantFromConstUnionArray(const glsla
|
|||||||
case glslang::EbtBool:
|
case glslang::EbtBool:
|
||||||
scalar = builder.makeBoolConstant(zero ? false : consts[nextConst].getBConst(), specConstant);
|
scalar = builder.makeBoolConstant(zero ? false : consts[nextConst].getBConst(), specConstant);
|
||||||
break;
|
break;
|
||||||
|
case glslang::EbtReference:
|
||||||
|
scalar = builder.makeUint64Constant(zero ? 0 : consts[nextConst].getU64Const(), specConstant);
|
||||||
|
scalar = builder.createUnaryOp(spv::OpBitcast, typeId, scalar);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
assert(0);
|
assert(0);
|
||||||
break;
|
break;
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
spv.bufferhandle16.frag
|
spv.bufferhandle16.frag
|
||||||
// Module Version 10000
|
// Module Version 10000
|
||||||
// Generated by (magic number): 80007
|
// Generated by (magic number): 80007
|
||||||
// Id's are bound by 37
|
// Id's are bound by 48
|
||||||
|
|
||||||
Capability Shader
|
Capability Shader
|
||||||
Capability Int64
|
Capability Int64
|
||||||
@ -16,61 +16,77 @@ spv.bufferhandle16.frag
|
|||||||
SourceExtension "GL_EXT_scalar_block_layout"
|
SourceExtension "GL_EXT_scalar_block_layout"
|
||||||
SourceExtension "GL_EXT_shader_explicit_arithmetic_types_int64"
|
SourceExtension "GL_EXT_shader_explicit_arithmetic_types_int64"
|
||||||
Name 4 "main"
|
Name 4 "main"
|
||||||
Name 8 "T1"
|
Name 9 "T1"
|
||||||
MemberName 8(T1) 0 "x"
|
MemberName 9(T1) 0 "x"
|
||||||
Name 10 "a"
|
MemberName 9(T1) 1 "y"
|
||||||
Name 14 "b"
|
Name 11 "a"
|
||||||
Name 17 "c"
|
Name 15 "b"
|
||||||
Name 23 "d"
|
Name 18 "c"
|
||||||
Name 25 "e"
|
Name 24 "d"
|
||||||
Name 36 "x"
|
Name 26 "e"
|
||||||
MemberDecorate 8(T1) 0 Offset 0
|
Name 29 "f"
|
||||||
Decorate 8(T1) Block
|
Name 46 "x"
|
||||||
Decorate 10(a) DecorationAliasedPointerEXT
|
MemberDecorate 9(T1) 0 Offset 0
|
||||||
Decorate 14(b) DecorationAliasedPointerEXT
|
MemberDecorate 9(T1) 1 Offset 4
|
||||||
Decorate 17(c) DecorationAliasedPointerEXT
|
Decorate 9(T1) Block
|
||||||
Decorate 23(d) DecorationAliasedPointerEXT
|
Decorate 11(a) DecorationAliasedPointerEXT
|
||||||
Decorate 25(e) DecorationAliasedPointerEXT
|
Decorate 15(b) DecorationAliasedPointerEXT
|
||||||
|
Decorate 18(c) DecorationAliasedPointerEXT
|
||||||
|
Decorate 24(d) DecorationAliasedPointerEXT
|
||||||
|
Decorate 26(e) DecorationAliasedPointerEXT
|
||||||
|
Decorate 29(f) DecorationAliasedPointerEXT
|
||||||
2: TypeVoid
|
2: TypeVoid
|
||||||
3: TypeFunction 2
|
3: TypeFunction 2
|
||||||
TypeForwardPointer 6 PhysicalStorageBufferEXT
|
TypeForwardPointer 6 PhysicalStorageBufferEXT
|
||||||
7: TypeInt 32 1
|
7: TypeInt 32 1
|
||||||
8(T1): TypeStruct 7(int)
|
8: TypeInt 32 0
|
||||||
6: TypePointer PhysicalStorageBufferEXT 8(T1)
|
9(T1): TypeStruct 7(int) 8(int)
|
||||||
9: TypePointer Function 6(ptr)
|
6: TypePointer PhysicalStorageBufferEXT 9(T1)
|
||||||
11: TypeInt 64 0
|
10: TypePointer Function 6(ptr)
|
||||||
12: 11(int64_t) Constant 4 0
|
12: TypeInt 64 0
|
||||||
15: 11(int64_t) Constant 5 0
|
13: 12(int64_t) Constant 4 0
|
||||||
18: TypeBool
|
16: 12(int64_t) Constant 5 0
|
||||||
19: 18(bool) ConstantTrue
|
19: TypeBool
|
||||||
26: 11(int64_t) Constant 6 0
|
20: 19(bool) ConstantTrue
|
||||||
28: 11(int64_t) Constant 7 0
|
27: 12(int64_t) Constant 6 0
|
||||||
31: 7(int) Constant 3
|
31: 7(int) Constant 1
|
||||||
32: TypeInt 32 0
|
32: TypePointer PhysicalStorageBufferEXT 8(int)
|
||||||
33: 32(int) Constant 3
|
35: 8(int) Constant 0
|
||||||
34: TypeArray 7(int) 33
|
37: 12(int64_t) Constant 8 0
|
||||||
35: TypePointer Private 34
|
39: 12(int64_t) Constant 9 0
|
||||||
36(x): 35(ptr) Variable Private
|
42: 7(int) Constant 3
|
||||||
|
43: 8(int) Constant 3
|
||||||
|
44: TypeArray 7(int) 43
|
||||||
|
45: TypePointer Private 44
|
||||||
|
46(x): 45(ptr) Variable Private
|
||||||
|
47: 12(int64_t) Constant 10 0
|
||||||
4(main): 2 Function None 3
|
4(main): 2 Function None 3
|
||||||
5: Label
|
5: Label
|
||||||
10(a): 9(ptr) Variable Function
|
11(a): 10(ptr) Variable Function
|
||||||
14(b): 9(ptr) Variable Function
|
15(b): 10(ptr) Variable Function
|
||||||
17(c): 9(ptr) Variable Function
|
18(c): 10(ptr) Variable Function
|
||||||
23(d): 9(ptr) Variable Function
|
24(d): 10(ptr) Variable Function
|
||||||
25(e): 9(ptr) Variable Function
|
26(e): 10(ptr) Variable Function
|
||||||
13: 6(ptr) Bitcast 12
|
29(f): 10(ptr) Variable Function
|
||||||
Store 10(a) 13
|
14: 6(ptr) Bitcast 13
|
||||||
16: 6(ptr) Bitcast 15
|
Store 11(a) 14
|
||||||
Store 14(b) 16
|
17: 6(ptr) Bitcast 16
|
||||||
20: 6(ptr) Load 10(a)
|
Store 15(b) 17
|
||||||
21: 6(ptr) Load 14(b)
|
21: 6(ptr) Load 11(a)
|
||||||
22: 6(ptr) Select 19 20 21
|
22: 6(ptr) Load 15(b)
|
||||||
Store 17(c) 22
|
23: 6(ptr) Select 20 21 22
|
||||||
24: 6(ptr) Load 14(b)
|
Store 18(c) 23
|
||||||
Store 23(d) 24
|
25: 6(ptr) Load 15(b)
|
||||||
27: 6(ptr) Bitcast 26
|
Store 24(d) 25
|
||||||
29: 6(ptr) Bitcast 28
|
28: 6(ptr) Bitcast 27
|
||||||
30: 6(ptr) Select 19 27 29
|
Store 26(e) 28
|
||||||
Store 25(e) 30
|
30: 6(ptr) Load 11(a)
|
||||||
|
33: 32(ptr) AccessChain 30 31
|
||||||
|
34: 8(int) Load 33 Aligned 4
|
||||||
|
36: 19(bool) INotEqual 34 35
|
||||||
|
38: 6(ptr) Bitcast 37
|
||||||
|
40: 6(ptr) Bitcast 39
|
||||||
|
41: 6(ptr) Select 36 38 40
|
||||||
|
Store 29(f) 41
|
||||||
Return
|
Return
|
||||||
FunctionEnd
|
FunctionEnd
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
|
|
||||||
layout(buffer_reference) buffer T1 {
|
layout(buffer_reference) buffer T1 {
|
||||||
int x;
|
int x;
|
||||||
|
bool y;
|
||||||
};
|
};
|
||||||
layout(buffer_reference) buffer T2 {
|
layout(buffer_reference) buffer T2 {
|
||||||
int x;
|
int x;
|
||||||
@ -13,6 +14,7 @@ layout(buffer_reference) buffer T2 {
|
|||||||
|
|
||||||
const int s = int(uint64_t(T1(T2(uint64_t(3)))));
|
const int s = int(uint64_t(T1(T2(uint64_t(3)))));
|
||||||
int x[s];
|
int x[s];
|
||||||
|
const uint64_t t = uint64_t(true ? T2(uint64_t(10)) : T2(uint64_t(11)));
|
||||||
|
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
@ -20,4 +22,5 @@ void main()
|
|||||||
T1 c = true ? a : b;
|
T1 c = true ? a : b;
|
||||||
T1 d = (a,b);
|
T1 d = (a,b);
|
||||||
T1 e = true ? T1(uint64_t(6)) : T1(uint64_t(7));
|
T1 e = true ? T1(uint64_t(6)) : T1(uint64_t(7));
|
||||||
|
T1 f = a.y ? T1(uint64_t(8)) : T1(uint64_t(9));
|
||||||
}
|
}
|
||||||
|
@ -725,19 +725,6 @@ TIntermTyped* TIntermediate::createConversion(TBasicType convertTo, TIntermTyped
|
|||||||
return newNode;
|
return newNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Convert a constant that is a reference type to a uint64_t constant plus a
|
|
||||||
// constructor instruction. This is needed because SPIR-V doesn't support
|
|
||||||
// OpConstant on pointer types.
|
|
||||||
TIntermTyped* TIntermediate::addConstantReferenceConversion(TIntermTyped* node)
|
|
||||||
{
|
|
||||||
if (node->getType().getBasicType() == EbtReference && node->getAsConstantUnion()) {
|
|
||||||
const TType &type = node->getType();
|
|
||||||
node = addBuiltInFunctionCall(node->getLoc(), EOpConvPtrToUint64, true, node, TType(EbtUint64));
|
|
||||||
node = addUnaryNode(EOpConstructReference, node, node->getLoc(), type);
|
|
||||||
}
|
|
||||||
return node;
|
|
||||||
}
|
|
||||||
|
|
||||||
TIntermTyped* TIntermediate::addConversion(TBasicType convertTo, TIntermTyped* node) const
|
TIntermTyped* TIntermediate::addConversion(TBasicType convertTo, TIntermTyped* node) const
|
||||||
{
|
{
|
||||||
return createConversion(convertTo, node);
|
return createConversion(convertTo, node);
|
||||||
@ -775,9 +762,6 @@ TIntermediate::addConversion(TOperator op, TIntermTyped* node0, TIntermTyped* no
|
|||||||
return std::make_tuple(node0, node1);
|
return std::make_tuple(node0, node1);
|
||||||
}
|
}
|
||||||
|
|
||||||
node0 = addConstantReferenceConversion(node0);
|
|
||||||
node1 = addConstantReferenceConversion(node1);
|
|
||||||
|
|
||||||
auto promoteTo = std::make_tuple(EbtNumTypes, EbtNumTypes);
|
auto promoteTo = std::make_tuple(EbtNumTypes, EbtNumTypes);
|
||||||
|
|
||||||
switch (op) {
|
switch (op) {
|
||||||
@ -897,8 +881,6 @@ TIntermTyped* TIntermediate::addConversion(TOperator op, const TType& type, TInt
|
|||||||
if (!isConversionAllowed(op, node))
|
if (!isConversionAllowed(op, node))
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
node = addConstantReferenceConversion(node);
|
|
||||||
|
|
||||||
// Otherwise, if types are identical, no problem
|
// Otherwise, if types are identical, no problem
|
||||||
if (type == node->getType())
|
if (type == node->getType())
|
||||||
return node;
|
return node;
|
||||||
|
@ -6527,11 +6527,7 @@ TIntermNode* TParseContext::executeInitializer(const TSourceLoc& loc, TIntermTyp
|
|||||||
// We either have a folded constant in getAsConstantUnion, or we have to use
|
// We either have a folded constant in getAsConstantUnion, or we have to use
|
||||||
// the initializer's subtree in the AST to represent the computation of a
|
// the initializer's subtree in the AST to represent the computation of a
|
||||||
// specialization constant.
|
// specialization constant.
|
||||||
// A third case arises when a reference type is made non-constant due to
|
assert(initializer->getAsConstantUnion() || initializer->getType().getQualifier().isSpecConstant());
|
||||||
// addConstantReferenceConversion, but reference types can't be const, so
|
|
||||||
// this is an error.
|
|
||||||
assert(initializer->getAsConstantUnion() || initializer->getType().getQualifier().isSpecConstant() ||
|
|
||||||
initializer->getType().getBasicType() == EbtReference);
|
|
||||||
if (initializer->getAsConstantUnion())
|
if (initializer->getAsConstantUnion())
|
||||||
variable->setConstArray(initializer->getAsConstantUnion()->getConstArray());
|
variable->setConstArray(initializer->getAsConstantUnion()->getConstArray());
|
||||||
else {
|
else {
|
||||||
|
@ -501,7 +501,6 @@ public:
|
|||||||
TIntermTyped* addConversion(TBasicType convertTo, TIntermTyped* node) const;
|
TIntermTyped* addConversion(TBasicType convertTo, TIntermTyped* node) const;
|
||||||
void addBiShapeConversion(TOperator, TIntermTyped*& lhsNode, TIntermTyped*& rhsNode);
|
void addBiShapeConversion(TOperator, TIntermTyped*& lhsNode, TIntermTyped*& rhsNode);
|
||||||
TIntermTyped* addShapeConversion(const TType&, TIntermTyped*);
|
TIntermTyped* addShapeConversion(const TType&, TIntermTyped*);
|
||||||
TIntermTyped* addConstantReferenceConversion(TIntermTyped* node);
|
|
||||||
TIntermTyped* addBinaryMath(TOperator, TIntermTyped* left, TIntermTyped* right, TSourceLoc);
|
TIntermTyped* addBinaryMath(TOperator, TIntermTyped* left, TIntermTyped* right, TSourceLoc);
|
||||||
TIntermTyped* addAssign(TOperator op, TIntermTyped* left, TIntermTyped* right, TSourceLoc);
|
TIntermTyped* addAssign(TOperator op, TIntermTyped* left, TIntermTyped* right, TSourceLoc);
|
||||||
TIntermTyped* addIndex(TOperator op, TIntermTyped* base, TIntermTyped* index, TSourceLoc);
|
TIntermTyped* addIndex(TOperator op, TIntermTyped* base, TIntermTyped* index, TSourceLoc);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user