diff --git a/SPIRV/GlslangToSpv.cpp b/SPIRV/GlslangToSpv.cpp index 94e37e8f..2a3ce8ec 100755 --- a/SPIRV/GlslangToSpv.cpp +++ b/SPIRV/GlslangToSpv.cpp @@ -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 diff --git a/SPIRV/SpvBuilder.cpp b/SPIRV/SpvBuilder.cpp index 1594da31..b2cafbf2 100755 --- a/SPIRV/SpvBuilder.cpp +++ b/SPIRV/SpvBuilder.cpp @@ -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& out) const { // Header, before first instructions: diff --git a/SPIRV/SpvBuilder.h b/SPIRV/SpvBuilder.h index 00516c82..92ddac9e 100755 --- a/SPIRV/SpvBuilder.h +++ b/SPIRV/SpvBuilder.h @@ -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&) const; void createBranch(Block* block); diff --git a/Test/baseResults/spv.aggOps.frag.out b/Test/baseResults/spv.aggOps.frag.out index 124c8fb8..abac3874 100644 --- a/Test/baseResults/spv.aggOps.frag.out +++ b/Test/baseResults/spv.aggOps.frag.out @@ -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