mirror of
https://github.com/KhronosGroup/glslang
synced 2024-11-08 11:30:06 +00:00
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:
parent
4b7b86d568
commit
097215f618
@ -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;
|
||||
|
@ -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
|
119
Test/baseResults/spv.load.bool.array.interface.block.frag.out
Normal file
119
Test/baseResults/spv.load.bool.array.interface.block.frag.out
Normal 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
|
17
Test/spv.1.4.load.bool.array.interface.block.frag
Normal file
17
Test/spv.1.4.load.bool.array.interface.block.frag
Normal 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);
|
||||
}
|
||||
|
17
Test/spv.load.bool.array.interface.block.frag
Normal file
17
Test/spv.load.bool.array.interface.block.frag
Normal 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);
|
||||
}
|
||||
|
@ -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",
|
||||
|
Loading…
Reference in New Issue
Block a user