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'.
This commit is contained in:
John Kessenich 2016-02-08 21:38:15 -07:00
parent 10110596a3
commit 103bef9d74
4 changed files with 96 additions and 51 deletions

View File

@ -1570,7 +1570,12 @@ spv::Id TGlslangToSpvTraverser::convertGlslangToSpvType(const glslang::TType& ty
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 @@ spv::Id TGlslangToSpvTraverser::convertGlslangToSpvType(const glslang::TType& ty
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

View File

@ -1990,6 +1990,39 @@ Id Builder::accessChainGetLValue()
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:

View File

@ -506,6 +506,10 @@ public:
// 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);

View File

@ -7,12 +7,12 @@ Linked fragment stage:
// 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 @@ Linked fragment stage:
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 @@ Linked fragment stage:
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 @@ Linked fragment stage:
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