SPV: Reduce spurious type generation by removing intermediate types in the middle...
authorJohn Kessenich <cepheus@frii.com>
Sun, 13 Sep 2015 20:46:30 +0000 (14:46 -0600)
committerJohn Kessenich <cepheus@frii.com>
Sun, 13 Sep 2015 20:46:30 +0000 (14:46 -0600)
This generally simplifies access chain generation, with far fewer  type conversions.
It is particularly important to future SPIR-V changes where there is less aggregate
type uniqueness due to carrying different layout information with the type.

SPIRV/GlslangToSpv.cpp
SPIRV/SpvBuilder.cpp
SPIRV/SpvBuilder.h
Test/baseResults/spv.310.comp.out
Test/baseResults/spv.Operations.frag.out
Test/baseResults/spv.accessChain.frag.out
Test/baseResults/spv.double.comp.out
Test/baseResults/spv.forLoop.frag.out

index 4c7c17c..0240dea 100755 (executable)
@@ -530,12 +530,12 @@ bool TGlslangToSpvTraverser::visitBinary(glslang::TVisit /* visit */, glslang::T
             // evaluate the right
             builder.clearAccessChain();
             node->getRight()->traverse(this);
-            spv::Id rValue = builder.accessChainLoad(TranslatePrecisionDecoration(node->getRight()->getType()));
+            spv::Id rValue = builder.accessChainLoad(convertGlslangToSpvType(node->getRight()->getType()));
 
             if (node->getOp() != glslang::EOpAssign) {
                 // the left is also an r-value
                 builder.setAccessChain(lValue);
-                spv::Id leftRValue = builder.accessChainLoad(TranslatePrecisionDecoration(node->getLeft()->getType()));
+                spv::Id leftRValue = builder.accessChainLoad(convertGlslangToSpvType(node->getLeft()->getType()));
 
                 // do the operation
                 rValue = createBinaryOperation(node->getOp(), TranslatePrecisionDecoration(node->getType()), 
@@ -587,10 +587,10 @@ bool TGlslangToSpvTraverser::visitBinary(glslang::TVisit /* visit */, glslang::T
                 // so short circuit the access-chain stuff with a swizzle.
                 std::vector<unsigned> swizzle;
                 swizzle.push_back(node->getRight()->getAsConstantUnion()->getConstArray()[0].getIConst());
-                builder.accessChainPushSwizzle(swizzle);
+                builder.accessChainPushSwizzle(swizzle, convertGlslangToSpvType(node->getLeft()->getType()));
             } else {
                 // normal case for indexing array or structure or block
-                builder.accessChainPush(builder.makeIntConstant(index), convertGlslangToSpvType(node->getType()));
+                builder.accessChainPush(builder.makeIntConstant(index));
             }
         }
         return false;
@@ -611,15 +611,15 @@ bool TGlslangToSpvTraverser::visitBinary(glslang::TVisit /* visit */, glslang::T
             // compute the next index in the chain
             builder.clearAccessChain();
             node->getRight()->traverse(this);
-            spv::Id index = builder.accessChainLoad(TranslatePrecisionDecoration(node->getRight()->getType()));
+            spv::Id index = builder.accessChainLoad(convertGlslangToSpvType(node->getRight()->getType()));
 
             // restore the saved access chain
             builder.setAccessChain(partial);
 
             if (! node->getLeft()->getType().isArray() && node->getLeft()->getType().isVector())
-                builder.accessChainPushComponent(index);
+                builder.accessChainPushComponent(index, convertGlslangToSpvType(node->getLeft()->getType()));
             else
-                builder.accessChainPush(index, convertGlslangToSpvType(node->getType()));
+                builder.accessChainPush(index);
         }
         return false;
     case glslang::EOpVectorSwizzle:
@@ -629,7 +629,7 @@ bool TGlslangToSpvTraverser::visitBinary(glslang::TVisit /* visit */, glslang::T
             std::vector<unsigned> swizzle;
             for (int i = 0; i < (int)swizzleSequence.size(); ++i)
                 swizzle.push_back(swizzleSequence[i]->getAsConstantUnion()->getConstArray()[0].getIConst());
-            builder.accessChainPushSwizzle(swizzle);
+            builder.accessChainPushSwizzle(swizzle, convertGlslangToSpvType(node->getLeft()->getType()));
         }
         return false;
     default:
@@ -641,11 +641,11 @@ bool TGlslangToSpvTraverser::visitBinary(glslang::TVisit /* visit */, glslang::T
     // Get the operands
     builder.clearAccessChain();
     node->getLeft()->traverse(this);
-    spv::Id left = builder.accessChainLoad(TranslatePrecisionDecoration(node->getLeft()->getType()));
+    spv::Id left = builder.accessChainLoad(convertGlslangToSpvType(node->getLeft()->getType()));
 
     builder.clearAccessChain();
     node->getRight()->traverse(this);
-    spv::Id right = builder.accessChainLoad(TranslatePrecisionDecoration(node->getRight()->getType()));
+    spv::Id right = builder.accessChainLoad(convertGlslangToSpvType(node->getRight()->getType()));
 
     spv::Id result;
     spv::Decoration precision = TranslatePrecisionDecoration(node->getType());
@@ -702,7 +702,7 @@ bool TGlslangToSpvTraverser::visitUnary(glslang::TVisit /* visit */, glslang::TI
 
     builder.clearAccessChain();
     node->getOperand()->traverse(this);
-    spv::Id operand = builder.accessChainLoad(TranslatePrecisionDecoration(node->getOperand()->getType()));
+    spv::Id operand = builder.accessChainLoad(convertGlslangToSpvType(node->getOperand()->getType()));
 
     spv::Decoration precision = TranslatePrecisionDecoration(node->getType());
 
@@ -1038,11 +1038,11 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt
 
         builder.clearAccessChain();
         left->traverse(this);
-        spv::Id leftId = builder.accessChainLoad(TranslatePrecisionDecoration(left->getType()));
+        spv::Id leftId = builder.accessChainLoad(convertGlslangToSpvType(left->getType()));
 
         builder.clearAccessChain();
         right->traverse(this);
-        spv::Id rightId = builder.accessChainLoad(TranslatePrecisionDecoration(right->getType()));
+        spv::Id rightId = builder.accessChainLoad(convertGlslangToSpvType(right->getType()));
 
         result = createBinaryOperation(binOp, precision, 
                                        convertGlslangToSpvType(node->getType()), leftId, rightId, 
@@ -1084,7 +1084,7 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt
         if (lvalue)
             operands.push_back(builder.accessChainGetLValue());
         else
-            operands.push_back(builder.accessChainLoad(TranslatePrecisionDecoration(glslangOperands[arg]->getAsTyped()->getType())));
+            operands.push_back(builder.accessChainLoad(convertGlslangToSpvType(glslangOperands[arg]->getAsTyped()->getType())));
     }
 
     if (atomic) {
@@ -1134,13 +1134,13 @@ bool TGlslangToSpvTraverser::visitSelection(glslang::TVisit /* visit */, glslang
     node->getCondition()->traverse(this);
 
     // make an "if" based on the value created by the condition
-    spv::Builder::If ifBuilder(builder.accessChainLoad(spv::NoPrecision), builder);
+    spv::Builder::If ifBuilder(builder.accessChainLoad(convertGlslangToSpvType(node->getCondition()->getType())), builder);
 
     if (node->getTrueBlock()) {
         // emit the "then" statement
         node->getTrueBlock()->traverse(this);
         if (result)
-            builder.createStore(builder.accessChainLoad(TranslatePrecisionDecoration(node->getTrueBlock()->getAsTyped()->getType())), result);
+            builder.createStore(builder.accessChainLoad(convertGlslangToSpvType(node->getTrueBlock()->getAsTyped()->getType())), result);
     }
 
     if (node->getFalseBlock()) {
@@ -1148,7 +1148,7 @@ bool TGlslangToSpvTraverser::visitSelection(glslang::TVisit /* visit */, glslang
         // emit the "else" statement
         node->getFalseBlock()->traverse(this);
         if (result)
-            builder.createStore(builder.accessChainLoad(TranslatePrecisionDecoration(node->getFalseBlock()->getAsTyped()->getType())), result);
+            builder.createStore(builder.accessChainLoad(convertGlslangToSpvType(node->getFalseBlock()->getAsTyped()->getType())), result);
     }
 
     ifBuilder.makeEndIf();
@@ -1169,7 +1169,7 @@ bool TGlslangToSpvTraverser::visitSwitch(glslang::TVisit /* visit */, glslang::T
 {
     // emit and get the condition before doing anything with switch
     node->getCondition()->traverse(this);
-    spv::Id selector = builder.accessChainLoad(TranslatePrecisionDecoration(node->getCondition()->getAsTyped()->getType()));
+    spv::Id selector = builder.accessChainLoad(convertGlslangToSpvType(node->getCondition()->getAsTyped()->getType()));
 
     // browse the children to sort out code segments
     int defaultSegment = -1;
@@ -1233,7 +1233,7 @@ bool TGlslangToSpvTraverser::visitLoop(glslang::TVisit /* visit */, glslang::TIn
     if (node->getTest()) {
         node->getTest()->traverse(this);
         // the AST only contained the test computation, not the branch, we have to add it
-        spv::Id condition = builder.accessChainLoad(TranslatePrecisionDecoration(node->getTest()->getType()));
+        spv::Id condition = builder.accessChainLoad(convertGlslangToSpvType(node->getTest()->getType()));
         builder.createLoopTestBranch(condition);
     } else {
         builder.createBranchToBody();
@@ -1279,7 +1279,7 @@ bool TGlslangToSpvTraverser::visitBranch(glslang::TVisit /* visit */, glslang::T
         if (inMain)
             builder.makeMainReturn();
         else if (node->getExpression())
-            builder.makeReturn(false, builder.accessChainLoad(TranslatePrecisionDecoration(node->getExpression()->getType())));
+            builder.makeReturn(false, builder.accessChainLoad(convertGlslangToSpvType(node->getExpression()->getType())));
         else
             builder.makeReturn();
 
@@ -1664,7 +1664,7 @@ void TGlslangToSpvTraverser::translateArguments(const glslang::TIntermSequence&
     for (int i = 0; i < (int)glslangArguments.size(); ++i) {
         builder.clearAccessChain();
         glslangArguments[i]->traverse(this);
-        arguments.push_back(builder.accessChainLoad(TranslatePrecisionDecoration(glslangArguments[i]->getAsTyped()->getType())));
+        arguments.push_back(builder.accessChainLoad(convertGlslangToSpvType(glslangArguments[i]->getAsTyped()->getType())));
     }
 }
 
@@ -1672,7 +1672,7 @@ void TGlslangToSpvTraverser::translateArguments(glslang::TIntermUnary& node, std
 {
     builder.clearAccessChain();
     node.getOperand()->traverse(this);
-    arguments.push_back(builder.accessChainLoad(TranslatePrecisionDecoration(node.getAsTyped()->getType())));
+    arguments.push_back(builder.accessChainLoad(convertGlslangToSpvType(node.getOperand()->getType())));
 }
 
 spv::Id TGlslangToSpvTraverser::createImageTextureFunctionCall(glslang::TIntermOperator* node)
@@ -1806,17 +1806,19 @@ spv::Id TGlslangToSpvTraverser::handleUserFunctionCall(const glslang::TIntermAgg
     // 1. Evaluate the arguments
     std::vector<spv::Builder::AccessChain> lValues;
     std::vector<spv::Id> rValues;
+    std::vector<spv::Id> argTypes;
     for (int a = 0; a < (int)glslangArgs.size(); ++a) {
         // build l-value
         builder.clearAccessChain();
         glslangArgs[a]->traverse(this);
+        argTypes.push_back(convertGlslangToSpvType(glslangArgs[a]->getAsTyped()->getType()));
         // keep outputs as l-values, evaluate input-only as r-values
         if (qualifiers[a] != glslang::EvqConstReadOnly) {
             // save l-value
             lValues.push_back(builder.getAccessChain());
         } else {
             // process r-value
-            rValues.push_back(builder.accessChainLoad(TranslatePrecisionDecoration(glslangArgs[a]->getAsTyped()->getType())));
+            rValues.push_back(builder.accessChainLoad(argTypes.back()));
         }
     }
 
@@ -1836,7 +1838,7 @@ spv::Id TGlslangToSpvTraverser::handleUserFunctionCall(const glslang::TIntermAgg
             if (qualifiers[a] == glslang::EvqIn || qualifiers[a] == glslang::EvqInOut) {
                 // need to copy the input into output space
                 builder.setAccessChain(lValues[lValueCount]);
-                spv::Id copy = builder.accessChainLoad(spv::NoPrecision);  // TODO: get precision
+                spv::Id copy = builder.accessChainLoad(argTypes[a]);
                 builder.createStore(copy, arg);
             }
             ++lValueCount;
index 953b604..9913b0b 100755 (executable)
@@ -1957,18 +1957,23 @@ void Builder::createBranchToLoopHeaderFromInside(const Loop& loop)
 
 void Builder::clearAccessChain()
 {
-    accessChain.base = 0;
+    accessChain.base = NoResult;
     accessChain.indexChain.clear();
-    accessChain.instr = 0;
+    accessChain.instr = NoResult;
     accessChain.swizzle.clear();
-    accessChain.component = 0;
-    accessChain.resultType = NoType;
+    accessChain.component = NoResult;
+    accessChain.preSwizzleBaseType = NoType;
     accessChain.isRValue = false;
 }
 
 // Comments in header
-void Builder::accessChainPushSwizzle(std::vector<unsigned>& swizzle)
+void Builder::accessChainPushSwizzle(std::vector<unsigned>& swizzle, Id preSwizzleBaseType)
 {
+    // swizzles can be stacked in GLSL, but simplified to a single
+    // one here; the base type doesn't change
+    if (accessChain.preSwizzleBaseType == NoType)
+        accessChain.preSwizzleBaseType = preSwizzleBaseType;
+
     // if needed, propagate the swizzle for the current access chain
     if (accessChain.swizzle.size()) {
         std::vector<unsigned> oldSwizzle = accessChain.swizzle;
@@ -1990,7 +1995,7 @@ void Builder::accessChainStore(Id rvalue)
 
     Id base = collapseAccessChain();
 
-    if (accessChain.swizzle.size() && accessChain.component)
+    if (accessChain.swizzle.size() && accessChain.component != NoResult)
         MissingFunctionality("simultaneous l-value swizzle and dynamic component selection");
 
     // If swizzle exists, it is out-of-order or not full, we must load the target vector,
@@ -2002,7 +2007,7 @@ void Builder::accessChainStore(Id rvalue)
     }
 
     // dynamic component selection
-    if (accessChain.component) {
+    if (accessChain.component != NoResult) {
         Id tempBaseId = (source == NoResult) ? createLoad(base) : source;
         source = createVectorInsertDynamic(tempBaseId, getTypeId(tempBaseId), rvalue, accessChain.component);
     }
@@ -2014,13 +2019,15 @@ void Builder::accessChainStore(Id rvalue)
 }
 
 // Comments in header
-Id Builder::accessChainLoad(Decoration /*precision*/)
+Id Builder::accessChainLoad(Id resultType)
 {
     Id id;
 
     if (accessChain.isRValue) {
         if (accessChain.indexChain.size() > 0) {
             mergeAccessChainSwizzle();  // TODO: optimization: look at applying this optimization more widely
+            Id swizzleBase = accessChain.preSwizzleBaseType != NoType ? accessChain.preSwizzleBaseType : resultType;
+        
             // if all the accesses are constants, we can use OpCompositeExtract
             std::vector<unsigned> indexes;
             bool constant = true;
@@ -2034,7 +2041,7 @@ Id Builder::accessChainLoad(Decoration /*precision*/)
             }
 
             if (constant)
-                id = createCompositeExtract(accessChain.base, accessChain.resultType, indexes);
+                id = createCompositeExtract(accessChain.base, swizzleBase, indexes);
             else {
                 // make a new function variable for this r-value
                 Id lValue = createVariable(StorageClassFunction, getTypeId(accessChain.base), "indexable");
@@ -2057,24 +2064,22 @@ Id Builder::accessChainLoad(Decoration /*precision*/)
     }
 
     // Done, unless there are swizzles to do
-    if (accessChain.swizzle.size() == 0 && accessChain.component == 0)
+    if (accessChain.swizzle.size() == 0 && accessChain.component == NoResult)
         return id;
 
-    Id componentType = getScalarTypeId(accessChain.resultType);
-
     // Do remaining swizzling
     // First, static swizzling
     if (accessChain.swizzle.size()) {
         // static swizzle
-        Id resultType = componentType;
+        Id swizzledType = getScalarTypeId(getTypeId(id));
         if (accessChain.swizzle.size() > 1)
-            resultType = makeVectorType(componentType, (int)accessChain.swizzle.size());
-        id = createRvalueSwizzle(resultType, id, accessChain.swizzle);
+            swizzledType = makeVectorType(swizzledType, (int)accessChain.swizzle.size());
+        id = createRvalueSwizzle(swizzledType, id, accessChain.swizzle);
     }
 
     // dynamic single-component selection
-    if (accessChain.component)
-        id = createVectorExtractDynamic(id, componentType, accessChain.component);
+    if (accessChain.component != NoResult)
+        id = createVectorExtractDynamic(id, resultType, accessChain.component);
 
     return id;
 }
@@ -2089,7 +2094,7 @@ Id Builder::accessChainGetLValue()
     // extract and insert elements to perform writeMask and/or swizzle.  This does not
     // go with getting a direct l-value pointer.
     assert(accessChain.swizzle.size() == 0);
-    assert(accessChain.component == spv::NoResult);
+    assert(accessChain.component == NoResult);
 
     return lvalue;
 }
@@ -2170,7 +2175,7 @@ void Builder::simplifyAccessChainSwizzle()
 {
     // If the swizzle has fewer components than the vector, it is subsetting, and must stay
     // to preserve that fact.
-    if (getNumTypeComponents(accessChain.resultType) > (int)accessChain.swizzle.size())
+    if (getNumTypeComponents(accessChain.preSwizzleBaseType) > (int)accessChain.swizzle.size())
         return;
 
     // if components are out of order, it is a swizzle
@@ -2181,6 +2186,8 @@ void Builder::simplifyAccessChainSwizzle()
 
     // otherwise, there is no need to track this swizzle
     accessChain.swizzle.clear();
+    if (accessChain.component == NoResult)
+        accessChain.preSwizzleBaseType = NoType;
 }
 
 // clear out swizzle if it can become part of the indexes
@@ -2188,12 +2195,12 @@ void Builder::mergeAccessChainSwizzle()
 {
     // is there even a chance of doing something?  Need a single-component swizzle
     if ((accessChain.swizzle.size() > 1) ||
-        (accessChain.swizzle.size() == 0 && accessChain.component == 0))
+        (accessChain.swizzle.size() == 0 && accessChain.component == NoResult))
         return;
 
     // TODO: optimization: remove this, but for now confine this to non-dynamic accesses
     // (the above test is correct when this is removed.)
-    if (accessChain.component)
+    if (accessChain.component != NoResult)
         return;
 
     // move the swizzle over to the indexes
@@ -2201,10 +2208,10 @@ void Builder::mergeAccessChainSwizzle()
         accessChain.indexChain.push_back(makeUintConstant(accessChain.swizzle.front()));
     else
         accessChain.indexChain.push_back(accessChain.component);
-    accessChain.resultType = getScalarTypeId(accessChain.resultType);
 
     // now there is no need to track this swizzle
     accessChain.component = NoResult;
+    accessChain.preSwizzleBaseType = NoType;
     accessChain.swizzle.clear();
 }
 
index 1ceb9c6..f81f9ed 100755 (executable)
@@ -431,7 +431,7 @@ public:
         Id instr;                    // the instruction that generates this access chain
         std::vector<unsigned> swizzle;
         Id component;                // a dynamic component index, can coexist with a swizzle, done after the swizzle
-        Id resultType;               // dereferenced type, to be exclusive of swizzles
+        Id preSwizzleBaseType;       // dereferenced type, before swizzle or component is applied; NoType unless a swizzle or component is present
         bool isRValue;
     };
 
@@ -452,7 +452,6 @@ public:
     {
         assert(isPointer(lValue));
         accessChain.base = lValue;
-        accessChain.resultType = getContainedTypeId(getTypeId(lValue));
     }
 
     // set new base value as an r-value
@@ -460,27 +459,30 @@ public:
     {
         accessChain.isRValue = true;
         accessChain.base = rValue;
-        accessChain.resultType = getTypeId(rValue);
     }
 
     // push offset onto the end of the chain
-    void accessChainPush(Id offset, Id newType)
+    void accessChainPush(Id offset)
     {
         accessChain.indexChain.push_back(offset);
-        accessChain.resultType = newType;
     }
 
     // push new swizzle onto the end of any existing swizzle, merging into a single swizzle
-    void accessChainPushSwizzle(std::vector<unsigned>& swizzle);
+    void accessChainPushSwizzle(std::vector<unsigned>& swizzle, Id preSwizzleBaseType);
 
     // push a variable component selection onto the access chain; supporting only one, so unsided
-    void accessChainPushComponent(Id component) { accessChain.component = component; }
+    void accessChainPushComponent(Id component, Id preSwizzleBaseType)
+    {
+        accessChain.component = component;
+        if (accessChain.preSwizzleBaseType == NoType)
+            accessChain.preSwizzleBaseType = preSwizzleBaseType;
+    }
 
     // use accessChain and swizzle to store value
     void accessChainStore(Id rvalue);
 
     // use accessChain and swizzle to load an r-value
-    Id accessChainLoad(Decoration precision);
+    Id accessChainLoad(Id ResultType);
 
     // get the direct pointer for an l-value
     Id accessChainGetLValue();
index 9fbb2d5..b8c7b88 100644 (file)
@@ -7,7 +7,7 @@ Linked compute stage:
 \r
 // Module Version 99\r
 // Generated by (magic number): 51a00bb\r
-// Id's are bound by 72\r
+// Id's are bound by 68\r
 \r
                               Source ESSL 310\r
                               Capability Shader\r
@@ -26,21 +26,21 @@ Linked compute stage:
                               MemberName 25(outbna) 0  "k"\r
                               MemberName 25(outbna) 1  "na"\r
                               Name 27  "outbnamena"\r
-                              Name 47  "i"\r
-                              Name 53  "outs"\r
-                              MemberName 53(outs) 0  "s"\r
-                              MemberName 53(outs) 1  "va"\r
-                              Name 55  "outnames"\r
-                              Name 59  "gl_LocalInvocationID"\r
+                              Name 44  "i"\r
+                              Name 50  "outs"\r
+                              MemberName 50(outs) 0  "s"\r
+                              MemberName 50(outs) 1  "va"\r
+                              Name 52  "outnames"\r
+                              Name 55  "gl_LocalInvocationID"\r
                               Decorate 14(outb) GLSLShared\r
                               Decorate 14(outb) BufferBlock\r
                               Decorate 25(outbna) GLSLShared\r
                               Decorate 25(outbna) BufferBlock\r
-                              Decorate 53(outs) GLSLShared\r
-                              Decorate 53(outs) BufferBlock\r
-                              Decorate 59(gl_LocalInvocationID) BuiltIn LocalInvocationId\r
-                              Decorate 71 BuiltIn WorkgroupSize\r
-                              Decorate 71 NoStaticUse\r
+                              Decorate 50(outs) GLSLShared\r
+                              Decorate 50(outs) BufferBlock\r
+                              Decorate 55(gl_LocalInvocationID) BuiltIn LocalInvocationId\r
+                              Decorate 67 BuiltIn WorkgroupSize\r
+                              Decorate 67 NoStaticUse\r
                2:             TypeVoid\r
                3:             TypeFunction 2\r
                7:             TypeInt 32 0\r
@@ -64,30 +64,26 @@ Linked compute stage:
   27(outbnamena):     26(ptr) Variable Uniform\r
               28:     17(int) Constant 1\r
               31:             TypePointer Uniform 24(fvec4)\r
-              33:             TypeRuntimeArray 12(fvec3)\r
-              34:     17(int) Constant 3\r
-              35:     17(int) Constant 18\r
-              36:             TypePointer Uniform 12(fvec3)\r
-              40:             TypeRuntimeArray 12(fvec3)\r
-              41:     17(int) Constant 17\r
-              42:   11(float) Constant 1077936128\r
-              43:   12(fvec3) ConstantComposite 42 42 42\r
-              45:             TypeRuntimeArray 12(fvec3)\r
-              46:             TypePointer WorkgroupLocal 17(int)\r
-           47(i):     46(ptr) Variable WorkgroupLocal\r
-              52:             TypeRuntimeArray 24(fvec4)\r
-        53(outs):             TypeStruct 17(int) 52\r
-              54:             TypePointer Uniform 53(outs)\r
-    55(outnames):     54(ptr) Variable Uniform\r
-              56:             TypeRuntimeArray 24(fvec4)\r
-              57:             TypeVector 7(int) 3\r
-              58:             TypePointer Input 57(ivec3)\r
-59(gl_LocalInvocationID):     58(ptr) Variable Input\r
-              66:             TypePointer Uniform 17(int)\r
-              68:      7(int) Constant 16\r
-              69:      7(int) Constant 32\r
-              70:      7(int) Constant 4\r
-              71:   57(ivec3) ConstantComposite 68 69 70\r
+              33:     17(int) Constant 3\r
+              34:     17(int) Constant 18\r
+              35:             TypePointer Uniform 12(fvec3)\r
+              39:     17(int) Constant 17\r
+              40:   11(float) Constant 1077936128\r
+              41:   12(fvec3) ConstantComposite 40 40 40\r
+              43:             TypePointer WorkgroupLocal 17(int)\r
+           44(i):     43(ptr) Variable WorkgroupLocal\r
+              49:             TypeRuntimeArray 24(fvec4)\r
+        50(outs):             TypeStruct 17(int) 49\r
+              51:             TypePointer Uniform 50(outs)\r
+    52(outnames):     51(ptr) Variable Uniform\r
+              53:             TypeVector 7(int) 3\r
+              54:             TypePointer Input 53(ivec3)\r
+55(gl_LocalInvocationID):     54(ptr) Variable Input\r
+              62:             TypePointer Uniform 17(int)\r
+              64:      7(int) Constant 16\r
+              65:      7(int) Constant 32\r
+              66:      7(int) Constant 4\r
+              67:   53(ivec3) ConstantComposite 64 65 66\r
          4(main):           2 Function None 3\r
                5:             Label\r
                               MemoryBarrier 8 9\r
@@ -99,26 +95,26 @@ Linked compute stage:
               30:   24(fvec4) CompositeConstruct 29 29 29 29\r
               32:     31(ptr) AccessChain 27(outbnamena) 28\r
                               Store 32 30\r
-              37:     36(ptr) AccessChain 16(outbname) 34 35\r
-              38:   12(fvec3) Load 37\r
-              39:   11(float) CompositeExtract 38 0\r
-                              Store 20(s) 39\r
-              44:     36(ptr) AccessChain 16(outbname) 34 41\r
-                              Store 44 43\r
-              48:     17(int) Load 47(i)\r
-              49:   11(float) Load 20(s)\r
-              50:   12(fvec3) CompositeConstruct 49 49 49\r
-              51:     36(ptr) AccessChain 16(outbname) 34 48\r
-                              Store 51 50\r
-              60:   57(ivec3) Load 59(gl_LocalInvocationID)\r
-              61:      7(int) CompositeExtract 60 0\r
-              62:   11(float) Load 20(s)\r
-              63:   24(fvec4) CompositeConstruct 62 62 62 62\r
-              64:     31(ptr) AccessChain 55(outnames) 28 61\r
-                              Store 64 63\r
-              65:     17(int) ArrayLength 16(outbname)\r
-              67:     66(ptr) AccessChain 55(outnames) 18\r
-                              Store 67 65\r
+              36:     35(ptr) AccessChain 16(outbname) 33 34\r
+              37:   12(fvec3) Load 36\r
+              38:   11(float) CompositeExtract 37 0\r
+                              Store 20(s) 38\r
+              42:     35(ptr) AccessChain 16(outbname) 33 39\r
+                              Store 42 41\r
+              45:     17(int) Load 44(i)\r
+              46:   11(float) Load 20(s)\r
+              47:   12(fvec3) CompositeConstruct 46 46 46\r
+              48:     35(ptr) AccessChain 16(outbname) 33 45\r
+                              Store 48 47\r
+              56:   53(ivec3) Load 55(gl_LocalInvocationID)\r
+              57:      7(int) CompositeExtract 56 0\r
+              58:   11(float) Load 20(s)\r
+              59:   24(fvec4) CompositeConstruct 58 58 58 58\r
+              60:     31(ptr) AccessChain 52(outnames) 28 57\r
+                              Store 60 59\r
+              61:     17(int) ArrayLength 16(outbname)\r
+              63:     62(ptr) AccessChain 52(outnames) 18\r
+                              Store 63 61\r
                               Branch 6\r
                6:             Label\r
                               Return\r
index 9858f85..909bb23 100755 (executable)
@@ -51,7 +51,7 @@ Linked fragment stage:
              292:     19(int) Constant 2\r
              299:     19(int) Constant 1\r
              301:             TypePointer Function 7(float)\r
-             332:             TypeVector 7(float) 3\r
+             331:             TypeVector 7(float) 3\r
              347:    7(float) Constant 1073741824\r
              354:    7(float) Constant 1065353216\r
              359:     19(int) Constant 66\r
@@ -434,11 +434,11 @@ Linked fragment stage:
              329:    7(float) Load 302(f)\r
              330:    7(float) FAdd 329 328\r
                               Store 302(f) 330\r
-             331:    8(fvec4) Load 10(v)\r
-             333:  332(fvec3) VectorShuffle 331 331 0 1 2\r
+             332:    8(fvec4) Load 10(v)\r
+             333:  331(fvec3) VectorShuffle 332 332 0 1 2\r
              334:    8(fvec4) Load 10(v)\r
-             335:  332(fvec3) VectorShuffle 334 334 0 1 2\r
-             336:  332(fvec3) ExtInst 1(GLSL.std.450) 67(Cross) 333 335\r
+             335:  331(fvec3) VectorShuffle 334 334 0 1 2\r
+             336:  331(fvec3) ExtInst 1(GLSL.std.450) 67(Cross) 333 335\r
              337:    7(float) CompositeExtract 336 0\r
              338:    7(float) Load 302(f)\r
              339:    7(float) FAdd 338 337\r
index f45cc34..c280bff 100755 (executable)
@@ -86,7 +86,7 @@ Linked fragment stage:
               67:     14(int) Constant 0\r
               68:             TypeInt 32 0\r
               69:     68(int) Constant 0\r
-              97:             TypeVector 7(float) 2\r
+              96:             TypeVector 7(float) 2\r
              110:     68(int) Constant 2\r
              142:    7(float) Constant 0\r
              143:    8(fvec3) ConstantComposite 142 142 142\r
@@ -227,8 +227,8 @@ Linked fragment stage:
         34(comp):     15(ptr) FunctionParameter\r
               36:             Label\r
               95:     14(int) Load 34(comp)\r
-              96:    8(fvec3) CompositeExtract 33(i) 0\r
-              98:   97(fvec2) VectorShuffle 96 96 1 0\r
+              97:    8(fvec3) CompositeExtract 33(i) 0\r
+              98:   96(fvec2) VectorShuffle 97 97 1 0\r
               99:    7(float) VectorExtractDynamic 98 95\r
              100:    8(fvec3) Load 66(OutColor)\r
              101:    8(fvec3) CompositeConstruct 99 99 99\r
@@ -241,10 +241,10 @@ Linked fragment stage:
         38(comp):     15(ptr) FunctionParameter\r
               40:             Label\r
              103:    8(fvec3) CompositeExtract 37(i) 0\r
-             104:   97(fvec2) VectorShuffle 103 103 0 1\r
+             104:   96(fvec2) VectorShuffle 103 103 0 1\r
              105:    8(fvec3) Load 66(OutColor)\r
-             106:   97(fvec2) VectorShuffle 105 105 0 1\r
-             107:   97(fvec2) FAdd 106 104\r
+             106:   96(fvec2) VectorShuffle 105 105 0 1\r
+             107:   96(fvec2) FAdd 106 104\r
              108:    8(fvec3) Load 66(OutColor)\r
              109:    8(fvec3) VectorShuffle 108 107 3 4 2\r
                               Store 66(OutColor) 109\r
@@ -279,10 +279,10 @@ Linked fragment stage:
         50(comp):     15(ptr) FunctionParameter\r
               52:             Label\r
              121:    8(fvec3) CompositeExtract 49(i) 0\r
-             122:   97(fvec2) VectorShuffle 121 121 0 1\r
+             122:   96(fvec2) VectorShuffle 121 121 0 1\r
              123:    8(fvec3) Load 66(OutColor)\r
-             124:   97(fvec2) VectorShuffle 123 123 2 1\r
-             125:   97(fvec2) FAdd 124 122\r
+             124:   96(fvec2) VectorShuffle 123 123 2 1\r
+             125:   96(fvec2) FAdd 124 122\r
              126:    8(fvec3) Load 66(OutColor)\r
              127:    8(fvec3) VectorShuffle 126 125 0 4 3\r
                               Store 66(OutColor) 127\r
@@ -293,10 +293,10 @@ Linked fragment stage:
         54(comp):     15(ptr) FunctionParameter\r
               56:             Label\r
              128:    8(fvec3) CompositeExtract 53(i) 0\r
-             129:   97(fvec2) VectorShuffle 128 128 0 1\r
+             129:   96(fvec2) VectorShuffle 128 128 0 1\r
              130:    8(fvec3) Load 66(OutColor)\r
-             131:   97(fvec2) VectorShuffle 130 130 0 2\r
-             132:   97(fvec2) FAdd 131 129\r
+             131:   96(fvec2) VectorShuffle 130 130 0 2\r
+             132:   96(fvec2) FAdd 131 129\r
              133:    8(fvec3) Load 66(OutColor)\r
              134:    8(fvec3) VectorShuffle 133 132 3 1 4\r
                               Store 66(OutColor) 134\r
index 3f2ca15..d77bc0c 100755 (executable)
@@ -57,7 +57,7 @@ Linked compute stage:
               25:             TypeVector 24(int) 3\r
               26:             TypePointer Input 25(ivec3)\r
 27(gl_GlobalInvocationID):     26(ptr) Variable Input\r
-              29:             TypeVector 24(int) 2\r
+              28:             TypeVector 24(int) 2\r
               32:             TypePointer Function 8(float)\r
 34(gl_LocalInvocationID):     26(ptr) Variable Input\r
               38:     12(int) Constant 8\r
@@ -86,12 +86,12 @@ Linked compute stage:
                               Store 16 14\r
               20:     19(ptr) AccessChain 11(bufInst) 17\r
                               Store 20 18\r
-              28:   25(ivec3) Load 27(gl_GlobalInvocationID)\r
-              30:   29(ivec2) VectorShuffle 28 28 0 1\r
+              29:   25(ivec3) Load 27(gl_GlobalInvocationID)\r
+              30:   28(ivec2) VectorShuffle 29 29 0 1\r
               31:   21(ivec2) Bitcast 30\r
                               Store 23(storePos) 31\r
               35:   25(ivec3) Load 34(gl_LocalInvocationID)\r
-              36:   29(ivec2) VectorShuffle 35 35 0 1\r
+              36:   28(ivec2) VectorShuffle 35 35 0 1\r
               37:   21(ivec2) Bitcast 36\r
               39:   21(ivec2) CompositeConstruct 38 38\r
               40:   21(ivec2) ISub 37 39\r
index 972ecea..75949a0 100755 (executable)
@@ -58,7 +58,7 @@ Linked fragment stage:
               50:             TypePointer UniformConstant 49(ivec4)\r
           51(v4):     50(ptr) Variable UniformConstant\r
               71:     48(int) Constant 4\r
-              86:             TypeVector 7(float) 3\r
+              85:             TypeVector 7(float) 3\r
               97:             TypePointer Input 7(float)\r
            98(f):     97(ptr) Variable Input\r
              116:     14(int) Constant 16\r
@@ -145,8 +145,8 @@ Linked fragment stage:
               82:    8(fvec4) Load 36(gl_FragColor)\r
               83:    8(fvec4) FAdd 82 81\r
                               Store 36(gl_FragColor) 83\r
-              85:    8(fvec4) Load 12(BaseColor)\r
-              87:   86(fvec3) VectorShuffle 85 85 0 1 2\r
+              86:    8(fvec4) Load 12(BaseColor)\r
+              87:   85(fvec3) VectorShuffle 86 86 0 1 2\r
               88:    8(fvec4) Load 84(r)\r
               89:    8(fvec4) VectorShuffle 88 87 4 5 6 3\r
                               Store 84(r) 89\r
@@ -169,10 +169,10 @@ Linked fragment stage:
                                 Branch 91\r
               92:             Label\r
              104:    8(fvec4) Load 84(r)\r
-             105:   86(fvec3) VectorShuffle 104 104 0 1 2\r
+             105:   85(fvec3) VectorShuffle 104 104 0 1 2\r
              106:    8(fvec4) Load 36(gl_FragColor)\r
-             107:   86(fvec3) VectorShuffle 106 106 0 1 2\r
-             108:   86(fvec3) FAdd 107 105\r
+             107:   85(fvec3) VectorShuffle 106 106 0 1 2\r
+             108:   85(fvec3) FAdd 107 105\r
              109:    8(fvec4) Load 36(gl_FragColor)\r
              110:    8(fvec4) VectorShuffle 109 108 4 5 6 3\r
                               Store 36(gl_FragColor) 110\r