SPV: Fix an issue caused by bool-to-uint32 conversion.
This issue is related with the commit
103bef9d74d768f0690ed53f52681baead384d1e.
diff --git a/SPIRV/GlslangToSpv.cpp b/SPIRV/GlslangToSpv.cpp
index 21a04b0..81f7cc1 100755
--- a/SPIRV/GlslangToSpv.cpp
+++ b/SPIRV/GlslangToSpv.cpp
@@ -98,6 +98,7 @@
spv::Id convertGlslangToSpvType(const glslang::TType& type, glslang::TLayoutPacking, const glslang::TQualifier&);
spv::Id makeArraySizeId(const glslang::TArraySizes&, int dim);
spv::Id accessChainLoad(const glslang::TType& type);
+ void accessChainStore(const glslang::TType& type, spv::Id rvalue);
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);
@@ -805,7 +806,7 @@
// store the result
builder.setAccessChain(lValue);
- builder.accessChainStore(rValue);
+ accessChainStore(node->getType(), rValue);
// assignments are expressions having an rValue after they are evaluated...
builder.clearAccessChain();
@@ -1904,12 +1905,55 @@
spv::Id loadedId = builder.accessChainLoad(TranslatePrecisionDecoration(type), nominalTypeId);
// Need to convert to abstract types when necessary
- if (builder.isScalarType(nominalTypeId) && type.getBasicType() == glslang::EbtBool && nominalTypeId != builder.makeBoolType())
- loadedId = builder.createBinOp(spv::OpINotEqual, builder.makeBoolType(), loadedId, builder.makeUintConstant(0));
+ 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));
+ }
+ }
return loadedId;
}
+// Wrap the builder's accessChainStore to:
+// - do conversion of concrete to abstract type
+void TGlslangToSpvTraverser::accessChainStore(const glslang::TType& type, spv::Id rvalue)
+{
+ // Need to convert to abstract types when necessary
+ if (type.getBasicType() == glslang::EbtBool) {
+ spv::Id nominalTypeId = builder.accessChainGetInferredType();
+
+ if (builder.isScalarType(nominalTypeId)) {
+ // Conversion for bool
+ spv::Id boolType = builder.makeBoolType();
+ if (nominalTypeId != boolType) {
+ spv::Id zero = builder.makeUintConstant(0);
+ spv::Id one = builder.makeUintConstant(1);
+ rvalue = builder.createTriOp(spv::OpSelect, nominalTypeId, rvalue, one, zero);
+ }
+ } else if (builder.isVectorType(nominalTypeId)) {
+ // Conversion for bvec
+ int vecSize = builder.getNumTypeComponents(nominalTypeId);
+ spv::Id bvecType = builder.makeVectorType(builder.makeBoolType(), vecSize);
+ if (nominalTypeId != bvecType) {
+ spv::Id zero = makeSmearedConstant(builder.makeUintConstant(0), vecSize);
+ spv::Id one = makeSmearedConstant(builder.makeUintConstant(1), vecSize);
+ rvalue = builder.createTriOp(spv::OpSelect, nominalTypeId, rvalue, one, zero);
+ }
+ }
+ }
+
+ builder.accessChainStore(rvalue);
+}
+
// Decide whether or not this type should be
// decorated with offsets and strides, and if so
// whether std140 or std430 rules should be applied.
@@ -2470,7 +2514,7 @@
if (qualifiers[a] == glslang::EvqOut || qualifiers[a] == glslang::EvqInOut) {
spv::Id copy = builder.createLoad(spvArgs[a]);
builder.setAccessChain(lValues[lValueCount]);
- builder.accessChainStore(copy);
+ accessChainStore(glslangArgs[a]->getAsTyped()->getType(), copy);
}
++lValueCount;
}