SPV: Handle GLSL bool loads from a uniform buffer as a conversion from int -> bool.
SPIR-V bool is abstract; it has no bit pattern for storage with transparent memory.
OpenGL's convention is a bool in a uniform buffer is 32-bit int with non-0 being 'true'.
diff --git a/SPIRV/GlslangToSpv.cpp b/SPIRV/GlslangToSpv.cpp
index 94e37e8..2a3ce8e 100755
--- a/SPIRV/GlslangToSpv.cpp
+++ b/SPIRV/GlslangToSpv.cpp
@@ -1570,7 +1570,12 @@
spvType = builder.makeFloatType(64);
break;
case glslang::EbtBool:
- spvType = builder.makeBoolType();
+ // "transparent" bool doesn't exist in SPIR-V. The GLSL convention is
+ // a 32-bit int where non-0 means true.
+ if (explicitLayout != glslang::ElpNone)
+ spvType = builder.makeUintType(32);
+ else
+ spvType = builder.makeBoolType();
break;
case glslang::EbtInt:
spvType = builder.makeIntType(32);
@@ -1764,9 +1769,21 @@
return spvType;
}
+// Wrap the builder's accessChainLoad to:
+// - localize handling of RelaxedPrecision
+// - use the SPIR-V inferred type instead of another conversion of the glslang type
+// (avoids unnecessary work and possible type punning for structures)
+// - do conversion of concrete to abstract type
spv::Id TGlslangToSpvTraverser::accessChainLoad(const glslang::TType& type)
{
- return builder.accessChainLoad(TranslatePrecisionDecoration(type), convertGlslangToSpvType(type));
+ spv::Id nominalTypeId = builder.accessChainGetInferredType();
+ 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));
+
+ return loadedId;
}
// Decide whether or not this type should be
diff --git a/SPIRV/SpvBuilder.cpp b/SPIRV/SpvBuilder.cpp
index 1594da3..b2cafbf 100755
--- a/SPIRV/SpvBuilder.cpp
+++ b/SPIRV/SpvBuilder.cpp
@@ -1990,6 +1990,39 @@
return lvalue;
}
+// comment in header
+Id Builder::accessChainGetInferredType()
+{
+ // anything to operate on?
+ if (accessChain.base == NoResult)
+ return NoType;
+ Id type = getTypeId(accessChain.base);
+
+ // do initial dereference
+ if (! accessChain.isRValue)
+ type = getContainedTypeId(type);
+
+ // dereference each index
+ for (auto deref : accessChain.indexChain) {
+ if (isStructType(type))
+ type = getContainedTypeId(type, getConstantScalar(deref));
+ else
+ type = getContainedTypeId(type);
+ }
+
+ // dereference swizzle
+ if (accessChain.swizzle.size() == 1)
+ type = getContainedTypeId(type);
+ else if (accessChain.swizzle.size() > 1)
+ type = makeVectorType(getContainedTypeId(type), accessChain.swizzle.size());
+
+ // dereference component selection
+ if (accessChain.component)
+ type = getContainedTypeId(type);
+
+ return type;
+}
+
void Builder::dump(std::vector<unsigned int>& out) const
{
// Header, before first instructions:
diff --git a/SPIRV/SpvBuilder.h b/SPIRV/SpvBuilder.h
index 00516c8..92ddac9 100755
--- a/SPIRV/SpvBuilder.h
+++ b/SPIRV/SpvBuilder.h
@@ -506,6 +506,10 @@
// get the direct pointer for an l-value
Id accessChainGetLValue();
+ // Get the inferred SPIR-V type of the result of the current access chain,
+ // based on the type of the base and the chain of dereferences.
+ Id accessChainGetInferredType();
+
void dump(std::vector<unsigned int>&) const;
void createBranch(Block* block);
diff --git a/Test/baseResults/spv.aggOps.frag.out b/Test/baseResults/spv.aggOps.frag.out
index 124c8fb..abac387 100644
--- a/Test/baseResults/spv.aggOps.frag.out
+++ b/Test/baseResults/spv.aggOps.frag.out
@@ -7,12 +7,12 @@
// Module Version 10000
// Generated by (magic number): 80001
-// Id's are bound by 380
+// Id's are bound by 378
Capability Shader
1: ExtInstImport "GLSL.std.450"
MemoryModel Logical GLSL450
- EntryPoint Fragment 4 "main" 16 41 90 376
+ EntryPoint Fragment 4 "main" 16 41 90 374
ExecutionMode 4 OriginLowerLeft
Source GLSL 450
Name 4 "main"
@@ -42,15 +42,8 @@
Name 343 "bn"
MemberName 343(bn) 0 "foo2a"
Name 345 "bi"
- Name 347 "s1"
- MemberName 347(s1) 0 "i"
- MemberName 347(s1) 1 "f"
- Name 348 "s2"
- MemberName 348(s2) 0 "i"
- MemberName 348(s2) 1 "f"
- MemberName 348(s2) 2 "s1_1"
- Name 376 "color"
- Name 379 "foo1"
+ Name 374 "color"
+ Name 377 "foo1"
MemberDecorate 341(s1) 0 Offset 0
MemberDecorate 341(s1) 1 Offset 4
MemberDecorate 342(s2) 0 Offset 0
@@ -108,14 +101,12 @@
344: TypePointer Uniform 343(bn)
345(bi): 344(ptr) Variable Uniform
346: 6(int) Constant 0
- 347(s1): TypeStruct 6(int) 7(float)
- 348(s2): TypeStruct 6(int) 7(float) 347(s1)
- 349: TypePointer Uniform 342(s2)
- 372: 7(float) Constant 1090519040
- 375: TypePointer Output 14(fvec4)
- 376(color): 375(ptr) Variable Output
- 378: TypePointer UniformConstant 8(s1)
- 379(foo1): 378(ptr) Variable UniformConstant
+ 347: TypePointer Uniform 342(s2)
+ 370: 7(float) Constant 1090519040
+ 373: TypePointer Output 14(fvec4)
+ 374(color): 373(ptr) Variable Output
+ 376: TypePointer UniformConstant 8(s1)
+ 377(foo1): 376(ptr) Variable UniformConstant
4(main): 2 Function None 3
5: Label
13(a): 12(ptr) Variable Function
@@ -439,35 +430,35 @@
Store 82(v) 340
Branch 337
337: Label
- 350: 349(ptr) AccessChain 345(bi) 346
- 351: 342(s2) Load 350
- 352: 55(s2) Load 57(foo2a)
- 353: 6(int) CompositeExtract 351 0
- 354: 6(int) CompositeExtract 352 0
- 355: 61(bool) INotEqual 353 354
- 356: 7(float) CompositeExtract 351 1
- 357: 7(float) CompositeExtract 352 1
- 358: 61(bool) FOrdNotEqual 356 357
- 359: 61(bool) LogicalOr 355 358
- 360: 341(s1) CompositeExtract 351 2
- 361: 8(s1) CompositeExtract 352 2
- 362: 6(int) CompositeExtract 360 0
- 363: 6(int) CompositeExtract 361 0
- 364: 61(bool) INotEqual 362 363
- 365: 7(float) CompositeExtract 360 1
- 366: 7(float) CompositeExtract 361 1
- 367: 61(bool) FOrdNotEqual 365 366
- 368: 61(bool) LogicalOr 364 367
- 369: 61(bool) LogicalOr 359 368
- SelectionMerge 371 None
- BranchConditional 369 370 371
- 370: Label
- 373: 14(fvec4) Load 82(v)
- 374: 14(fvec4) VectorTimesScalar 373 372
- Store 82(v) 374
- Branch 371
- 371: Label
- 377: 14(fvec4) Load 82(v)
- Store 376(color) 377
+ 348: 347(ptr) AccessChain 345(bi) 346
+ 349: 342(s2) Load 348
+ 350: 55(s2) Load 57(foo2a)
+ 351: 6(int) CompositeExtract 349 0
+ 352: 6(int) CompositeExtract 350 0
+ 353: 61(bool) INotEqual 351 352
+ 354: 7(float) CompositeExtract 349 1
+ 355: 7(float) CompositeExtract 350 1
+ 356: 61(bool) FOrdNotEqual 354 355
+ 357: 61(bool) LogicalOr 353 356
+ 358: 341(s1) CompositeExtract 349 2
+ 359: 8(s1) CompositeExtract 350 2
+ 360: 6(int) CompositeExtract 358 0
+ 361: 6(int) CompositeExtract 359 0
+ 362: 61(bool) INotEqual 360 361
+ 363: 7(float) CompositeExtract 358 1
+ 364: 7(float) CompositeExtract 359 1
+ 365: 61(bool) FOrdNotEqual 363 364
+ 366: 61(bool) LogicalOr 362 365
+ 367: 61(bool) LogicalOr 357 366
+ SelectionMerge 369 None
+ BranchConditional 367 368 369
+ 368: Label
+ 371: 14(fvec4) Load 82(v)
+ 372: 14(fvec4) VectorTimesScalar 371 370
+ Store 82(v) 372
+ Branch 369
+ 369: Label
+ 375: 14(fvec4) Load 82(v)
+ Store 374(color) 375
Return
FunctionEnd