diff --git a/SPIRV/GlslangToSpv.cpp b/SPIRV/GlslangToSpv.cpp index c767ab61..d0bebaea 100644 --- a/SPIRV/GlslangToSpv.cpp +++ b/SPIRV/GlslangToSpv.cpp @@ -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 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 . // 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; diff --git a/Test/baseResults/spv.1.4.load.bool.array.interface.block.frag.out b/Test/baseResults/spv.1.4.load.bool.array.interface.block.frag.out new file mode 100644 index 00000000..9f698db8 --- /dev/null +++ b/Test/baseResults/spv.1.4.load.bool.array.interface.block.frag.out @@ -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 diff --git a/Test/baseResults/spv.load.bool.array.interface.block.frag.out b/Test/baseResults/spv.load.bool.array.interface.block.frag.out new file mode 100644 index 00000000..f45736cb --- /dev/null +++ b/Test/baseResults/spv.load.bool.array.interface.block.frag.out @@ -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 diff --git a/Test/spv.1.4.load.bool.array.interface.block.frag b/Test/spv.1.4.load.bool.array.interface.block.frag new file mode 100644 index 00000000..22037415 --- /dev/null +++ b/Test/spv.1.4.load.bool.array.interface.block.frag @@ -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); +} + diff --git a/Test/spv.load.bool.array.interface.block.frag b/Test/spv.load.bool.array.interface.block.frag new file mode 100644 index 00000000..22037415 --- /dev/null +++ b/Test/spv.load.bool.array.interface.block.frag @@ -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); +} + diff --git a/gtests/Spv.FromFile.cpp b/gtests/Spv.FromFile.cpp index 20683a68..80ce0b18 100644 --- a/gtests/Spv.FromFile.cpp +++ b/gtests/Spv.FromFile.cpp @@ -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",