SPV: More corrections of <id> versus "immediate" operands.
diff --git a/SPIRV/GlslangToSpv.cpp b/SPIRV/GlslangToSpv.cpp
index 81f7f08..d8369d2 100755
--- a/SPIRV/GlslangToSpv.cpp
+++ b/SPIRV/GlslangToSpv.cpp
@@ -3630,9 +3630,10 @@
 
     // Check for image functions other than queries
     if (node->isImage()) {
-        std::vector<spv::Id> operands;
+        std::vector<spv::IdImmediate> operands;
         auto opIt = arguments.begin();
-        operands.push_back(*(opIt++));
+        spv::IdImmediate image = { true, *(opIt++) };
+        operands.push_back(image);
 
         // Handle subpass operations
         // TODO: GLSL should change to have the "MS" only on the type rather than the
@@ -3643,38 +3644,47 @@
             std::vector<spv::Id> comps;
             comps.push_back(zero);
             comps.push_back(zero);
-            operands.push_back(builder.makeCompositeConstant(builder.makeVectorType(builder.makeIntType(32), 2), comps));
+            spv::IdImmediate coord = { true,
+                builder.makeCompositeConstant(builder.makeVectorType(builder.makeIntType(32), 2), comps) };
+            operands.push_back(coord);
             if (sampler.ms) {
-                operands.push_back(spv::ImageOperandsSampleMask);
-                operands.push_back(*(opIt++));
+                spv::IdImmediate imageOperands = { false, spv::ImageOperandsSampleMask };
+                operands.push_back(imageOperands);
+                spv::IdImmediate imageOperand = { true, *(opIt++) };
+                operands.push_back(imageOperand);
             }
             spv::Id result = builder.createOp(spv::OpImageRead, resultType(), operands);
             builder.setPrecision(result, precision);
             return result;
         }
 
-        operands.push_back(*(opIt++));
+        spv::IdImmediate coord = { true, *(opIt++) };
+        operands.push_back(coord);
 #ifdef AMD_EXTENSIONS
         if (node->getOp() == glslang::EOpImageLoad || node->getOp() == glslang::EOpImageLoadLod) {
 #else
         if (node->getOp() == glslang::EOpImageLoad) {
 #endif
             if (sampler.ms) {
-                operands.push_back(spv::ImageOperandsSampleMask);
-                operands.push_back(*opIt);
+                spv::IdImmediate imageOperands = { false, spv::ImageOperandsSampleMask };
+                operands.push_back(imageOperands);
+                spv::IdImmediate imageOperand = { true, *opIt };
+                operands.push_back(imageOperand);
 #ifdef AMD_EXTENSIONS
             } else if (cracked.lod) {
                 builder.addExtension(spv::E_SPV_AMD_shader_image_load_store_lod);
                 builder.addCapability(spv::CapabilityImageReadWriteLodAMD);
 
-                operands.push_back(spv::ImageOperandsLodMask);
-                operands.push_back(*opIt);
+                spv::IdImmediate imageOperands = { false, spv::ImageOperandsLodMask };
+                operands.push_back(imageOperands);
+                spv::IdImmediate imageOperand = { true, *opIt };
+                operands.push_back(imageOperand);
 #endif
             }
-            if (builder.getImageTypeFormat(builder.getImageType(operands.front())) == spv::ImageFormatUnknown)
+            if (builder.getImageTypeFormat(builder.getImageType(operands.front().word)) == spv::ImageFormatUnknown)
                 builder.addCapability(spv::CapabilityStorageImageReadWithoutFormat);
 
-            std::vector<spv::Id> result( 1, builder.createOp(spv::OpImageRead, resultType(), operands) );
+            std::vector<spv::Id> result(1, builder.createOp(spv::OpImageRead, resultType(), operands));
             builder.setPrecision(result[0], precision);
 
             // If needed, add a conversion constructor to the proper size.
@@ -3688,22 +3698,30 @@
         } else if (node->getOp() == glslang::EOpImageStore) {
 #endif
             if (sampler.ms) {
-                operands.push_back(*(opIt + 1));
-                operands.push_back(spv::ImageOperandsSampleMask);
-                operands.push_back(*opIt);
+                spv::IdImmediate texel = { true, *(opIt + 1) };
+                operands.push_back(texel);
+                spv::IdImmediate imageOperands = { false, spv::ImageOperandsSampleMask };
+                operands.push_back(imageOperands);
+                spv::IdImmediate imageOperand = { true, *opIt };
+                operands.push_back(imageOperand);
 #ifdef AMD_EXTENSIONS
             } else if (cracked.lod) {
                 builder.addExtension(spv::E_SPV_AMD_shader_image_load_store_lod);
                 builder.addCapability(spv::CapabilityImageReadWriteLodAMD);
 
-                operands.push_back(*(opIt + 1));
-                operands.push_back(spv::ImageOperandsLodMask);
-                operands.push_back(*opIt);
+                spv::IdImmediate texel = { true, *(opIt + 1) };
+                operands.push_back(texel);
+                spv::IdImmediate imageOperands = { false, spv::ImageOperandsLodMask };
+                operands.push_back(imageOperands);
+                spv::IdImmediate imageOperand = { true, *opIt };
+                operands.push_back(imageOperand);
 #endif
-            } else
-                operands.push_back(*opIt);
+            } else {
+                spv::IdImmediate texel = { true, *opIt };
+                operands.push_back(texel);
+            }
             builder.createNoResultOp(spv::OpImageWrite, operands);
-            if (builder.getImageTypeFormat(builder.getImageType(operands.front())) == spv::ImageFormatUnknown)
+            if (builder.getImageTypeFormat(builder.getImageType(operands.front().word)) == spv::ImageFormatUnknown)
                 builder.addCapability(spv::CapabilityStorageImageWriteWithoutFormat);
             return spv::NoResult;
 #ifdef AMD_EXTENSIONS
@@ -3712,19 +3730,23 @@
         } else if (node->getOp() == glslang::EOpSparseImageLoad) {
 #endif
             builder.addCapability(spv::CapabilitySparseResidency);
-            if (builder.getImageTypeFormat(builder.getImageType(operands.front())) == spv::ImageFormatUnknown)
+            if (builder.getImageTypeFormat(builder.getImageType(operands.front().word)) == spv::ImageFormatUnknown)
                 builder.addCapability(spv::CapabilityStorageImageReadWithoutFormat);
 
             if (sampler.ms) {
-                operands.push_back(spv::ImageOperandsSampleMask);
-                operands.push_back(*opIt++);
+                spv::IdImmediate imageOperands = { false, spv::ImageOperandsSampleMask };
+                operands.push_back(imageOperands);
+                spv::IdImmediate imageOperand = { true, *opIt++ };
+                operands.push_back(imageOperand);
 #ifdef AMD_EXTENSIONS
             } else if (cracked.lod) {
                 builder.addExtension(spv::E_SPV_AMD_shader_image_load_store_lod);
                 builder.addCapability(spv::CapabilityImageReadWriteLodAMD);
 
-                operands.push_back(spv::ImageOperandsLodMask);
-                operands.push_back(*opIt++);
+                spv::IdImmediate imageOperands = { false, spv::ImageOperandsLodMask };
+                operands.push_back(imageOperands);
+                spv::IdImmediate imageOperand = { true, *opIt++ };
+                operands.push_back(imageOperand);
 #endif
             }
 
@@ -3744,7 +3766,9 @@
 
             // GLSL "IMAGE_PARAMS" will involve in constructing an image texel pointer and this pointer,
             // as the first source operand, is required by SPIR-V atomic operations.
-            operands.push_back(sampler.ms ? *(opIt++) : builder.makeUintConstant(0)); // For non-MS, the value should be 0
+            // For non-MS, the sample value should be 0
+            spv::IdImmediate sample = { true, sampler.ms ? *(opIt++) : builder.makeUintConstant(0) };
+            operands.push_back(sample);
 
             spv::Id resultTypeId = builder.makePointer(spv::StorageClassImage, resultType());
             spv::Id pointer = builder.createOp(spv::OpImageTexelPointer, resultTypeId, operands);
@@ -5383,7 +5407,7 @@
 #endif
 
     spv::Op opCode = spv::OpNop;
-    std::vector<spv::Id> spvGroupOperands;
+    std::vector<spv::IdImmediate> spvGroupOperands;
     spv::GroupOperation groupOperation = spv::GroupOperationMax;
 
     if (op == glslang::EOpBallot || op == glslang::EOpReadFirstInvocation ||
@@ -5410,7 +5434,6 @@
             builder.addExtension(spv::E_SPV_AMD_shader_ballot);
 #endif
 
-        spvGroupOperands.push_back(builder.makeUintConstant(spv::ScopeSubgroup));
 #ifdef AMD_EXTENSIONS
         switch (op) {
         case glslang::EOpMinInvocations:
@@ -5420,7 +5443,6 @@
         case glslang::EOpMaxInvocationsNonUniform:
         case glslang::EOpAddInvocationsNonUniform:
             groupOperation = spv::GroupOperationReduce;
-            spvGroupOperands.push_back(groupOperation);
             break;
         case glslang::EOpMinInvocationsInclusiveScan:
         case glslang::EOpMaxInvocationsInclusiveScan:
@@ -5429,7 +5451,6 @@
         case glslang::EOpMaxInvocationsInclusiveScanNonUniform:
         case glslang::EOpAddInvocationsInclusiveScanNonUniform:
             groupOperation = spv::GroupOperationInclusiveScan;
-            spvGroupOperands.push_back(groupOperation);
             break;
         case glslang::EOpMinInvocationsExclusiveScan:
         case glslang::EOpMaxInvocationsExclusiveScan:
@@ -5438,16 +5459,23 @@
         case glslang::EOpMaxInvocationsExclusiveScanNonUniform:
         case glslang::EOpAddInvocationsExclusiveScanNonUniform:
             groupOperation = spv::GroupOperationExclusiveScan;
-            spvGroupOperands.push_back(groupOperation);
             break;
         default:
             break;
         }
+        spv::IdImmediate scope = { true, builder.makeUintConstant(spv::ScopeSubgroup) };
+        spvGroupOperands.push_back(scope);
+        if (groupOperation != spv::GroupOperationMax) {
+            spv::IdImmediate groupOp = { false, groupOperation };
+            spvGroupOperands.push_back(groupOp);
+        }
 #endif
     }
 
-    for (auto opIt = operands.begin(); opIt != operands.end(); ++opIt)
-        spvGroupOperands.push_back(*opIt);
+    for (auto opIt = operands.begin(); opIt != operands.end(); ++opIt) {
+        spv::IdImmediate op = { true, *opIt };
+        spvGroupOperands.push_back(op);
+    }
 
     switch (op) {
     case glslang::EOpAnyInvocation:
@@ -5586,7 +5614,8 @@
 }
 
 // Create group invocation operations on a vector
-spv::Id TGlslangToSpvTraverser::CreateInvocationsVectorOperation(spv::Op op, spv::GroupOperation groupOperation, spv::Id typeId, std::vector<spv::Id>& operands)
+spv::Id TGlslangToSpvTraverser::CreateInvocationsVectorOperation(spv::Op op, spv::GroupOperation groupOperation,
+    spv::Id typeId, std::vector<spv::Id>& operands)
 {
 #ifdef AMD_EXTENSIONS
     assert(op == spv::OpGroupFMin || op == spv::OpGroupUMin || op == spv::OpGroupSMin ||
@@ -5619,18 +5648,23 @@
     for (int comp = 0; comp < numComponents; ++comp) {
         std::vector<unsigned int> indexes;
         indexes.push_back(comp);
-        spv::Id scalar = builder.createCompositeExtract(operands[0], scalarType, indexes);
-        std::vector<spv::Id> spvGroupOperands;
+        spv::IdImmediate scalar = { true, builder.createCompositeExtract(operands[0], scalarType, indexes) };
+        std::vector<spv::IdImmediate> spvGroupOperands;
         if (op == spv::OpSubgroupReadInvocationKHR) {
             spvGroupOperands.push_back(scalar);
-            spvGroupOperands.push_back(operands[1]);
+            spv::IdImmediate operand = { true, operands[1] };
+            spvGroupOperands.push_back(operand);
         } else if (op == spv::OpGroupBroadcast) {
-            spvGroupOperands.push_back(builder.makeUintConstant(spv::ScopeSubgroup));
+            spv::IdImmediate scope = { true, builder.makeUintConstant(spv::ScopeSubgroup) };
+            spvGroupOperands.push_back(scope);
             spvGroupOperands.push_back(scalar);
-            spvGroupOperands.push_back(operands[1]);
+            spv::IdImmediate operand = { true, operands[1] };
+            spvGroupOperands.push_back(operand);
         } else {
-            spvGroupOperands.push_back(builder.makeUintConstant(spv::ScopeSubgroup));
-            spvGroupOperands.push_back(groupOperation);
+            spv::IdImmediate scope = { true, builder.makeUintConstant(spv::ScopeSubgroup) };
+            spvGroupOperands.push_back(scope);
+            spv::IdImmediate groupOp = { false, groupOperation };
+            spvGroupOperands.push_back(groupOp);
             spvGroupOperands.push_back(scalar);
         }
 
@@ -5642,7 +5676,8 @@
 }
 
 // Create subgroup invocation operations.
-spv::Id TGlslangToSpvTraverser::createSubgroupOperation(glslang::TOperator op, spv::Id typeId, std::vector<spv::Id>& operands, glslang::TBasicType typeProxy)
+spv::Id TGlslangToSpvTraverser::createSubgroupOperation(glslang::TOperator op, spv::Id typeId,
+    std::vector<spv::Id>& operands, glslang::TBasicType typeProxy)
 {
     // Add the required capabilities.
     switch (op) {
@@ -5890,14 +5925,11 @@
     default: assert(0 && "Unhandled subgroup operation!");
     }
 
-    std::vector<spv::Id> spvGroupOperands;
-
-    // Every operation begins with the Execution Scope operand.
-    spvGroupOperands.push_back(builder.makeUintConstant(spv::ScopeSubgroup));
-
-    // Next, for all operations that use a Group Operation, push that as an operand.
+    // get the right Group Operation
+    spv::GroupOperation groupOperation = spv::GroupOperationMax;
     switch (op) {
-    default: break;
+    default:
+        break;
     case glslang::EOpSubgroupBallotBitCount:
     case glslang::EOpSubgroupAdd:
     case glslang::EOpSubgroupMul:
@@ -5906,7 +5938,7 @@
     case glslang::EOpSubgroupAnd:
     case glslang::EOpSubgroupOr:
     case glslang::EOpSubgroupXor:
-        spvGroupOperands.push_back(spv::GroupOperationReduce);
+        groupOperation = spv::GroupOperationReduce;
         break;
     case glslang::EOpSubgroupBallotInclusiveBitCount:
     case glslang::EOpSubgroupInclusiveAdd:
@@ -5916,7 +5948,7 @@
     case glslang::EOpSubgroupInclusiveAnd:
     case glslang::EOpSubgroupInclusiveOr:
     case glslang::EOpSubgroupInclusiveXor:
-        spvGroupOperands.push_back(spv::GroupOperationInclusiveScan);
+        groupOperation = spv::GroupOperationInclusiveScan;
         break;
     case glslang::EOpSubgroupBallotExclusiveBitCount:
     case glslang::EOpSubgroupExclusiveAdd:
@@ -5926,7 +5958,7 @@
     case glslang::EOpSubgroupExclusiveAnd:
     case glslang::EOpSubgroupExclusiveOr:
     case glslang::EOpSubgroupExclusiveXor:
-        spvGroupOperands.push_back(spv::GroupOperationExclusiveScan);
+        groupOperation = spv::GroupOperationExclusiveScan;
         break;
     case glslang::EOpSubgroupClusteredAdd:
     case glslang::EOpSubgroupClusteredMul:
@@ -5935,7 +5967,7 @@
     case glslang::EOpSubgroupClusteredAnd:
     case glslang::EOpSubgroupClusteredOr:
     case glslang::EOpSubgroupClusteredXor:
-        spvGroupOperands.push_back(spv::GroupOperationClusteredReduce);
+        groupOperation = spv::GroupOperationClusteredReduce;
         break;
 #ifdef NV_EXTENSIONS
     case glslang::EOpSubgroupPartitionedAdd:
@@ -5945,7 +5977,7 @@
     case glslang::EOpSubgroupPartitionedAnd:
     case glslang::EOpSubgroupPartitionedOr:
     case glslang::EOpSubgroupPartitionedXor:
-        spvGroupOperands.push_back(spv::GroupOperationPartitionedReduceNV);
+        groupOperation = spv::GroupOperationPartitionedReduceNV;
         break;
     case glslang::EOpSubgroupPartitionedInclusiveAdd:
     case glslang::EOpSubgroupPartitionedInclusiveMul:
@@ -5954,7 +5986,7 @@
     case glslang::EOpSubgroupPartitionedInclusiveAnd:
     case glslang::EOpSubgroupPartitionedInclusiveOr:
     case glslang::EOpSubgroupPartitionedInclusiveXor:
-        spvGroupOperands.push_back(spv::GroupOperationPartitionedInclusiveScanNV);
+        groupOperation = spv::GroupOperationPartitionedInclusiveScanNV;
         break;
     case glslang::EOpSubgroupPartitionedExclusiveAdd:
     case glslang::EOpSubgroupPartitionedExclusiveMul:
@@ -5963,22 +5995,41 @@
     case glslang::EOpSubgroupPartitionedExclusiveAnd:
     case glslang::EOpSubgroupPartitionedExclusiveOr:
     case glslang::EOpSubgroupPartitionedExclusiveXor:
-        spvGroupOperands.push_back(spv::GroupOperationPartitionedExclusiveScanNV);
+        groupOperation = spv::GroupOperationPartitionedExclusiveScanNV;
         break;
 #endif
     }
 
+    // build the instruction
+    std::vector<spv::IdImmediate> spvGroupOperands;
+
+    // Every operation begins with the Execution Scope operand.
+    spv::IdImmediate executionScope = { true, builder.makeUintConstant(spv::ScopeSubgroup) };
+    spvGroupOperands.push_back(executionScope);
+
+    // Next, for all operations that use a Group Operation, push that as an operand.
+    if (groupOperation != spv::GroupOperationMax) {
+        spv::IdImmediate groupOperand = { false, groupOperation };
+        spvGroupOperands.push_back(groupOperand);
+    }
+
     // Push back the operands next.
-    for (auto opIt : operands) {
-        spvGroupOperands.push_back(opIt);
+    for (auto opIt = operands.cbegin(); opIt != operands.cend(); ++opIt) {
+        spv::IdImmediate operand = { true, *opIt };
+        spvGroupOperands.push_back(operand);
     }
 
     // Some opcodes have additional operands.
+    spv::Id directionId = spv::NoResult;
     switch (op) {
     default: break;
-    case glslang::EOpSubgroupQuadSwapHorizontal: spvGroupOperands.push_back(builder.makeUintConstant(0)); break;
-    case glslang::EOpSubgroupQuadSwapVertical:   spvGroupOperands.push_back(builder.makeUintConstant(1)); break;
-    case glslang::EOpSubgroupQuadSwapDiagonal:   spvGroupOperands.push_back(builder.makeUintConstant(2)); break;
+    case glslang::EOpSubgroupQuadSwapHorizontal: directionId = builder.makeUintConstant(0); break;
+    case glslang::EOpSubgroupQuadSwapVertical:   directionId = builder.makeUintConstant(1); break;
+    case glslang::EOpSubgroupQuadSwapDiagonal:   directionId = builder.makeUintConstant(2); break;
+    }
+    if (directionId != spv::NoResult) {
+        spv::IdImmediate direction = { true, directionId };
+        spvGroupOperands.push_back(direction);
     }
 
     return builder.createOp(opCode, typeId, spvGroupOperands);