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