Fix loading bool arrays from interface blocks

SPIR-V disallows bool in interface blocks, which is emulated with uint.
When loading a bool variable (through accessChainLoad()), it's converted
from uint to bool if it came from an interface block.

This was handled for bool and bvecN, but not for bool arrays.  This
change implements the conversion for bool arrays.

Closes #2694
This commit is contained in:
Shahbaz Youssefi 2021-07-15 22:00:51 -04:00
parent 4b7b86d568
commit 097215f618
6 changed files with 304 additions and 13 deletions

View File

@ -179,6 +179,7 @@ protected:
spv::Id accessChainLoad(const glslang::TType& type);
void accessChainStore(const glslang::TType& type, spv::Id rvalue);
void multiTypeStore(const glslang::TType&, spv::Id rValue);
spv::Id convertLoadedBoolInUniformToUint(const glslang::TType& type, spv::Id nominalTypeId, spv::Id loadedId);
glslang::TLayoutPacking getExplicitLayout(const glslang::TType& type) const;
int getArrayStride(const glslang::TType& arrayType, glslang::TLayoutPacking, glslang::TLayoutMatrix);
int getMatrixStride(const glslang::TType& matrixType, glslang::TLayoutPacking, glslang::TLayoutMatrix);
@ -2231,6 +2232,49 @@ bool TGlslangToSpvTraverser::visitBinary(glslang::TVisit /* visit */, glslang::T
}
}
spv::Id TGlslangToSpvTraverser::convertLoadedBoolInUniformToUint(const glslang::TType& type,
spv::Id nominalTypeId,
spv::Id loadedId)
{
if (builder.isScalarType(nominalTypeId)) {
// Conversion for bool
spv::Id boolType = builder.makeBoolType();
if (nominalTypeId != boolType)
return builder.createBinOp(spv::OpINotEqual, boolType, loadedId, builder.makeUintConstant(0));
} else if (builder.isVectorType(nominalTypeId)) {
// Conversion for bvec
int vecSize = builder.getNumTypeComponents(nominalTypeId);
spv::Id bvecType = builder.makeVectorType(builder.makeBoolType(), vecSize);
if (nominalTypeId != bvecType)
loadedId = builder.createBinOp(spv::OpINotEqual, bvecType, loadedId,
makeSmearedConstant(builder.makeUintConstant(0), vecSize));
} else if (builder.isArrayType(nominalTypeId)) {
// Conversion for bool array
spv::Id boolArrayTypeId = convertGlslangToSpvType(type);
if (nominalTypeId != boolArrayTypeId)
{
// Use OpCopyLogical from SPIR-V 1.4 if available.
if (glslangIntermediate->getSpv().spv >= glslang::EShTargetSpv_1_4)
return builder.createUnaryOp(spv::OpCopyLogical, boolArrayTypeId, loadedId);
glslang::TType glslangElementType(type, 0);
spv::Id elementNominalTypeId = builder.getContainedTypeId(nominalTypeId);
std::vector<spv::Id> constituents;
for (int index = 0; index < type.getOuterArraySize(); ++index) {
// get the element
spv::Id elementValue = builder.createCompositeExtract(loadedId, elementNominalTypeId, index);
// recursively convert it
spv::Id elementConvertedValue = convertLoadedBoolInUniformToUint(glslangElementType, elementNominalTypeId, elementValue);
constituents.push_back(elementConvertedValue);
}
return builder.createCompositeConstruct(boolArrayTypeId, constituents);
}
}
return loadedId;
}
// Figure out what, if any, type changes are needed when accessing a specific built-in.
// Returns <the type SPIR-V requires for declarion, the type to translate to on use>.
// Also see comment for 'forceType', regarding tracking SPIR-V-required types.
@ -4560,19 +4604,7 @@ spv::Id TGlslangToSpvTraverser::accessChainLoad(const glslang::TType& type)
// Need to convert to abstract types when necessary
if (type.getBasicType() == glslang::EbtBool) {
if (builder.isScalarType(nominalTypeId)) {
// Conversion for bool
spv::Id boolType = builder.makeBoolType();
if (nominalTypeId != boolType)
loadedId = builder.createBinOp(spv::OpINotEqual, boolType, loadedId, builder.makeUintConstant(0));
} else if (builder.isVectorType(nominalTypeId)) {
// Conversion for bvec
int vecSize = builder.getNumTypeComponents(nominalTypeId);
spv::Id bvecType = builder.makeVectorType(builder.makeBoolType(), vecSize);
if (nominalTypeId != bvecType)
loadedId = builder.createBinOp(spv::OpINotEqual, bvecType, loadedId,
makeSmearedConstant(builder.makeUintConstant(0), vecSize));
}
loadedId = convertLoadedBoolInUniformToUint(type, nominalTypeId, loadedId);
}
return loadedId;

View File

@ -0,0 +1,104 @@
spv.1.4.load.bool.array.interface.block.frag
Validation failed
// Module Version 10400
// Generated by (magic number): 8000a
// Id's are bound by 64
Capability Shader
1: ExtInstImport "GLSL.std.450"
MemoryModel Logical GLSL450
EntryPoint Fragment 4 "main" 13 20 61
ExecutionMode 4 OriginUpperLeft
Source GLSL 450
Name 4 "main"
Name 11 "ssbo"
MemberName 11(ssbo) 0 "bo"
Name 13 ""
Name 18 "ub"
MemberName 18(ub) 0 "bi"
Name 20 ""
Name 61 "color"
Decorate 8 ArrayStride 4
Decorate 10 ArrayStride 12
MemberDecorate 11(ssbo) 0 Offset 0
Decorate 11(ssbo) Block
Decorate 13 DescriptorSet 0
Decorate 13 Binding 1
Decorate 16 ArrayStride 16
Decorate 17 ArrayStride 48
MemberDecorate 18(ub) 0 Offset 0
Decorate 18(ub) Block
Decorate 20 DescriptorSet 0
Decorate 20 Binding 0
Decorate 61(color) Location 0
2: TypeVoid
3: TypeFunction 2
6: TypeInt 32 0
7: 6(int) Constant 3
8: TypeArray 6(int) 7
9: 6(int) Constant 2
10: TypeArray 8 9
11(ssbo): TypeStruct 10
12: TypePointer StorageBuffer 11(ssbo)
13: 12(ptr) Variable StorageBuffer
14: TypeInt 32 1
15: 14(int) Constant 0
16: TypeArray 6(int) 7
17: TypeArray 16 9
18(ub): TypeStruct 17
19: TypePointer Uniform 18(ub)
20: 19(ptr) Variable Uniform
21: TypePointer Uniform 17
24: TypeBool
25: TypeArray 24(bool) 7
26: TypeArray 25 9
28: TypePointer StorageBuffer 10
31: TypePointer StorageBuffer 8
34: 6(int) Constant 1
35: 6(int) Constant 0
37: TypePointer StorageBuffer 6(int)
40: 14(int) Constant 1
44: 14(int) Constant 2
58: TypeFloat 32
59: TypeVector 58(float) 4
60: TypePointer Output 59(fvec4)
61(color): 60(ptr) Variable Output
62: 58(float) Constant 0
63: 59(fvec4) ConstantComposite 62 62 62 62
4(main): 2 Function None 3
5: Label
22: 21(ptr) AccessChain 20 15
23: 17 Load 22
27: 26 CopyLogical 23
29: 28(ptr) AccessChain 13 15
30: 25 CompositeExtract 27 0
32: 31(ptr) AccessChain 29 15
33: 24(bool) CompositeExtract 30 0
36: 6(int) Select 33 34 35
38: 37(ptr) AccessChain 32 15
Store 38 36
39: 24(bool) CompositeExtract 30 1
41: 6(int) Select 39 34 35
42: 37(ptr) AccessChain 32 40
Store 42 41
43: 24(bool) CompositeExtract 30 2
45: 6(int) Select 43 34 35
46: 37(ptr) AccessChain 32 44
Store 46 45
47: 25 CompositeExtract 27 1
48: 31(ptr) AccessChain 29 40
49: 24(bool) CompositeExtract 47 0
50: 6(int) Select 49 34 35
51: 37(ptr) AccessChain 48 15
Store 51 50
52: 24(bool) CompositeExtract 47 1
53: 6(int) Select 52 34 35
54: 37(ptr) AccessChain 48 40
Store 54 53
55: 24(bool) CompositeExtract 47 2
56: 6(int) Select 55 34 35
57: 37(ptr) AccessChain 48 44
Store 57 56
Store 61(color) 63
Return
FunctionEnd

View File

@ -0,0 +1,119 @@
spv.load.bool.array.interface.block.frag
// Module Version 10000
// Generated by (magic number): 8000a
// Id's are bound by 80
Capability Shader
1: ExtInstImport "GLSL.std.450"
MemoryModel Logical GLSL450
EntryPoint Fragment 4 "main" 77
ExecutionMode 4 OriginUpperLeft
Source GLSL 450
Name 4 "main"
Name 11 "ssbo"
MemberName 11(ssbo) 0 "bo"
Name 13 ""
Name 18 "ub"
MemberName 18(ub) 0 "bi"
Name 20 ""
Name 77 "color"
Decorate 8 ArrayStride 4
Decorate 10 ArrayStride 12
MemberDecorate 11(ssbo) 0 Offset 0
Decorate 11(ssbo) BufferBlock
Decorate 13 DescriptorSet 0
Decorate 13 Binding 1
Decorate 16 ArrayStride 16
Decorate 17 ArrayStride 48
MemberDecorate 18(ub) 0 Offset 0
Decorate 18(ub) Block
Decorate 20 DescriptorSet 0
Decorate 20 Binding 0
Decorate 77(color) Location 0
2: TypeVoid
3: TypeFunction 2
6: TypeInt 32 0
7: 6(int) Constant 3
8: TypeArray 6(int) 7
9: 6(int) Constant 2
10: TypeArray 8 9
11(ssbo): TypeStruct 10
12: TypePointer Uniform 11(ssbo)
13: 12(ptr) Variable Uniform
14: TypeInt 32 1
15: 14(int) Constant 0
16: TypeArray 6(int) 7
17: TypeArray 16 9
18(ub): TypeStruct 17
19: TypePointer Uniform 18(ub)
20: 19(ptr) Variable Uniform
21: TypePointer Uniform 17
24: TypeBool
25: TypeArray 24(bool) 7
26: TypeArray 25 9
29: 6(int) Constant 0
45: TypePointer Uniform 10
48: TypePointer Uniform 8
51: 6(int) Constant 1
53: TypePointer Uniform 6(int)
56: 14(int) Constant 1
60: 14(int) Constant 2
74: TypeFloat 32
75: TypeVector 74(float) 4
76: TypePointer Output 75(fvec4)
77(color): 76(ptr) Variable Output
78: 74(float) Constant 0
79: 75(fvec4) ConstantComposite 78 78 78 78
4(main): 2 Function None 3
5: Label
22: 21(ptr) AccessChain 20 15
23: 17 Load 22
27: 16 CompositeExtract 23 0
28: 6(int) CompositeExtract 27 0
30: 24(bool) INotEqual 28 29
31: 6(int) CompositeExtract 27 1
32: 24(bool) INotEqual 31 29
33: 6(int) CompositeExtract 27 2
34: 24(bool) INotEqual 33 29
35: 25 CompositeConstruct 30 32 34
36: 16 CompositeExtract 23 1
37: 6(int) CompositeExtract 36 0
38: 24(bool) INotEqual 37 29
39: 6(int) CompositeExtract 36 1
40: 24(bool) INotEqual 39 29
41: 6(int) CompositeExtract 36 2
42: 24(bool) INotEqual 41 29
43: 25 CompositeConstruct 38 40 42
44: 26 CompositeConstruct 35 43
46: 45(ptr) AccessChain 13 15
47: 25 CompositeExtract 44 0
49: 48(ptr) AccessChain 46 15
50: 24(bool) CompositeExtract 47 0
52: 6(int) Select 50 51 29
54: 53(ptr) AccessChain 49 15
Store 54 52
55: 24(bool) CompositeExtract 47 1
57: 6(int) Select 55 51 29
58: 53(ptr) AccessChain 49 56
Store 58 57
59: 24(bool) CompositeExtract 47 2
61: 6(int) Select 59 51 29
62: 53(ptr) AccessChain 49 60
Store 62 61
63: 25 CompositeExtract 44 1
64: 48(ptr) AccessChain 46 56
65: 24(bool) CompositeExtract 63 0
66: 6(int) Select 65 51 29
67: 53(ptr) AccessChain 64 15
Store 67 66
68: 24(bool) CompositeExtract 63 1
69: 6(int) Select 68 51 29
70: 53(ptr) AccessChain 64 56
Store 70 69
71: 24(bool) CompositeExtract 63 2
72: 6(int) Select 71 51 29
73: 53(ptr) AccessChain 64 60
Store 73 72
Store 77(color) 79
Return
FunctionEnd

View File

@ -0,0 +1,17 @@
#version 450 core
layout(std140, set=0, binding=0) uniform ub {
bool bi[2][3];
};
layout(std430, set=0, binding=1) buffer ssbo {
bool bo[2][3];
};
layout(location=0) out vec4 color;
void main()
{
bo = bi;
color = vec4(0);
}

View File

@ -0,0 +1,17 @@
#version 450 core
layout(std140, set=0, binding=0) uniform ub {
bool bi[2][3];
};
layout(std430, set=0, binding=1) buffer ssbo {
bool bo[2][3];
};
layout(location=0) out vec4 color;
void main()
{
bo = bi;
color = vec4(0);
}

View File

@ -352,6 +352,7 @@ INSTANTIATE_TEST_SUITE_P(
"spv.functionParameterTypes.frag",
"spv.GeometryShaderPassthrough.geom",
"spv.funcall.array.frag",
"spv.load.bool.array.interface.block.frag",
"spv.interpOps.frag",
"spv.int64.frag",
"spv.intcoopmat.comp",
@ -565,6 +566,7 @@ INSTANTIATE_TEST_SUITE_P(
"spv.1.4.OpCopyLogicalBool.comp",
"spv.1.4.OpCopyLogical.funcall.frag",
"spv.1.4.funcall.array.frag",
"spv.1.4.load.bool.array.interface.block.frag",
"spv.1.4.image.frag",
"spv.1.4.sparseTexture.frag",
"spv.1.4.texture.frag",