layers: Rename and add spirv parameter helper
diff --git a/layers/generated/spirv_grammar_helper.cpp b/layers/generated/spirv_grammar_helper.cpp
index 2b376be..3570794 100644
--- a/layers/generated/spirv_grammar_helper.cpp
+++ b/layers/generated/spirv_grammar_helper.cpp
@@ -156,8 +156,8 @@
 }
 
 
-// Return paramater position of memory scope ID or zero if there is none
-uint32_t MemoryScopeParam(uint32_t opcode) {
+// Return parameter position of memory scope ID or zero if there is none
+uint32_t MemoryScopeParamPosition(uint32_t opcode) {
     uint32_t position = 0;
     switch (opcode) {
         case spv::OpMemoryBarrier:
@@ -190,8 +190,8 @@
     return position;
 }
 
-// Return paramater position of execution scope ID or zero if there is none
-uint32_t ExecutionScopeParam(uint32_t opcode) {
+// Return parameter position of execution scope ID or zero if there is none
+uint32_t ExecutionScopeParamPosition(uint32_t opcode) {
     uint32_t position = 0;
     switch (opcode) {
         case spv::OpControlBarrier:
@@ -259,8 +259,8 @@
     return position;
 }
 
-// Return paramater position of Image Operands or zero if there is none
-uint32_t ImageOperandsParam(uint32_t opcode) {
+// Return parameter position of Image Operands or zero if there is none
+uint32_t ImageOperandsParamPosition(uint32_t opcode) {
     uint32_t position = 0;
     switch (opcode) {
         case spv::OpImageWrite:
@@ -300,5 +300,34 @@
     return position;
 }
 
+// Return number of optional parameter from ImageOperands
+uint32_t ImageOperandsParamCount(uint32_t image_operand) {
+    uint32_t count = 0;
+    switch (image_operand) {
+        case spv::ImageOperandsMaskNone:
+        case spv::ImageOperandsNonPrivateTexelMask:
+        case spv::ImageOperandsVolatileTexelMask:
+        case spv::ImageOperandsSignExtendMask:
+        case spv::ImageOperandsZeroExtendMask:
+            return 0;
+        case spv::ImageOperandsBiasMask:
+        case spv::ImageOperandsLodMask:
+        case spv::ImageOperandsConstOffsetMask:
+        case spv::ImageOperandsOffsetMask:
+        case spv::ImageOperandsConstOffsetsMask:
+        case spv::ImageOperandsSampleMask:
+        case spv::ImageOperandsMinLodMask:
+        case spv::ImageOperandsMakeTexelAvailableMask:
+        case spv::ImageOperandsMakeTexelVisibleMask:
+            return 1;
+        case spv::ImageOperandsGradMask:
+            return 2;
+            break;
+        default:
+            break;
+    }
+    return count;
+}
+
 
 
diff --git a/layers/generated/spirv_grammar_helper.h b/layers/generated/spirv_grammar_helper.h
index 0e27682..ffbab99 100644
--- a/layers/generated/spirv_grammar_helper.h
+++ b/layers/generated/spirv_grammar_helper.h
@@ -37,9 +37,10 @@
 bool ImageFetchOperation(uint32_t opcode);
 bool ImageSampleOperation(uint32_t opcode);
 
-uint32_t MemoryScopeParam(uint32_t opcode);
-uint32_t ExecutionScopeParam(uint32_t opcode);
-uint32_t ImageOperandsParam(uint32_t opcode);
+uint32_t MemoryScopeParamPosition(uint32_t opcode);
+uint32_t ExecutionScopeParamPosition(uint32_t opcode);
+uint32_t ImageOperandsParamPosition(uint32_t opcode);
+uint32_t ImageOperandsParamCount(uint32_t opcode);
 
 static inline const char* string_SpvOpcode(uint32_t opcode) {
     switch ((spv::Op)opcode) {
diff --git a/layers/shader_module.cpp b/layers/shader_module.cpp
index 4a5e892..c493601 100644
--- a/layers/shader_module.cpp
+++ b/layers/shader_module.cpp
@@ -1911,36 +1911,6 @@
     return 0;
 }
 
-uint32_t SHADER_MODULE_STATE::ImageOperandsCount(uint32_t i) const {
-    uint32_t count = 0;
-    switch (i) {
-        case spv::ImageOperandsMaskNone:
-        case spv::ImageOperandsMakeTexelAvailableMask:  // ImageOperandsMakeTexelAvailableKHRMask
-        case spv::ImageOperandsMakeTexelVisibleMask:    // ImageOperandsMakeTexelVisibleKHRMask
-        case spv::ImageOperandsNonPrivateTexelMask:     // ImageOperandsNonPrivateTexelKHRMask
-        case spv::ImageOperandsVolatileTexelMask:       // ImageOperandsVolatileTexelKHRMask
-        case spv::ImageOperandsSignExtendMask:
-        case spv::ImageOperandsZeroExtendMask:
-            count = 0;
-            break;
-        case spv::ImageOperandsBiasMask:
-        case spv::ImageOperandsLodMask:
-        case spv::ImageOperandsConstOffsetMask:
-        case spv::ImageOperandsOffsetMask:
-        case spv::ImageOperandsConstOffsetsMask:
-        case spv::ImageOperandsSampleMask:
-        case spv::ImageOperandsMinLodMask:
-            count = 1;
-            break;
-        case spv::ImageOperandsGradMask:
-            count = 2;
-            break;
-        default:
-            break;
-    }
-    return count;
-}
-
 // Assumes itr points to an OpConstant instruction
 uint32_t GetConstantValue(const spirv_inst_iter &itr) { return itr.word(3); }
 
diff --git a/layers/shader_module.h b/layers/shader_module.h
index b7e5ab3..b91761f 100644
--- a/layers/shader_module.h
+++ b/layers/shader_module.h
@@ -381,7 +381,6 @@
     uint32_t GetBaseType(const spirv_inst_iter &iter) const;
     uint32_t CalcComputeSharedMemory(VkShaderStageFlagBits stage,
                                      const spirv_inst_iter &insn) const;
-    uint32_t ImageOperandsCount(uint32_t i) const;
 
   private:
     // Functions used for initialization only
diff --git a/layers/shader_validation.cpp b/layers/shader_validation.cpp
index 56f5ba7..af249d3 100644
--- a/layers/shader_validation.cpp
+++ b/layers/shader_validation.cpp
@@ -672,7 +672,7 @@
 bool CoreChecks::ValidateMemoryScope(SHADER_MODULE_STATE const *src, const spirv_inst_iter &insn) const {
     bool skip = false;
 
-    const auto &entry = MemoryScopeParam(insn.opcode());
+    const auto &entry = MemoryScopeParamPosition(insn.opcode());
     if (entry > 0) {
         const uint32_t scope_id = insn.word(entry);
         if (enabled_features.core12.vulkanMemoryModel && !enabled_features.core12.vulkanMemoryModelDeviceScope) {
@@ -2178,7 +2178,7 @@
 
     const uint32_t opcode = insn.opcode();
     if (ImageGatherOperation(opcode) || ImageSampleOperation(opcode) || ImageFetchOperation(opcode)) {
-        uint32_t image_operand_position = ImageOperandsParam(opcode);
+        uint32_t image_operand_position = ImageOperandsParamPosition(opcode);
         // Image operands can be optional
         if (image_operand_position != 0 && insn.len() > image_operand_position) {
             auto image_operand = insn.word(image_operand_position);
@@ -2249,7 +2249,7 @@
                                 }
                             }
                         }
-                        index += src->ImageOperandsCount(i);
+                        index += ImageOperandsParamCount(i);
                     }
                 }
             }
diff --git a/scripts/spirv_grammar_generator.py b/scripts/spirv_grammar_generator.py
index e9a3634..afac268 100644
--- a/scripts/spirv_grammar_generator.py
+++ b/scripts/spirv_grammar_generator.py
@@ -100,6 +100,7 @@
         self.memoryScopeParam = [[] for i in range(5)]
         self.executionScopeParam = [[] for i in range(5)]
         self.imageOperandsParam = [[] for i in range(8)]
+        self.imageOperandsParamCount = [[] for i in range(3)]
 
         # Lots of switch statements share same ending
         self.commonBoolSwitch = '''            found = true;
@@ -110,13 +111,15 @@
     return found;
 }\n
 '''
-        self.commonParamSwitch = '''            break;
+
+    def commonParamSwitch(self, variableName):
+        return '''            break;
         default:
             break;
-    }
-    return position;
-}\n
-'''
+    }}
+    return {};
+}}\n
+'''.format(variableName)
 
     #
     # Called at beginning of processing as file is opened
@@ -174,7 +177,7 @@
         write(self.atomicOperation(), file=self.outFile)
         write(self.groupOperation(), file=self.outFile)
         write(self.imageOperation(), file=self.outFile)
-        write(self.scopeHelper(), file=self.outFile)
+        write(self.parameterHelper(), file=self.outFile)
         write(self.stringHelper(), file=self.outFile)
         # Finish processing in superclass
         OutputGenerator.endFile(self)
@@ -207,6 +210,13 @@
                     for enum in operandKind['enumerants']:
                         if 'capabilities' in enum and len(enum['capabilities']) == 1 and enum['capabilities'][0] == 'Kernel':
                             kernelCapability.append(enum['enumerant'])
+                if operandKind['kind'] == 'ImageOperands':
+                    values = [] # prevent alias from being duplicatd
+                    for enum in operandKind['enumerants']:
+                        count = 0  if 'parameters' not in enum else len(enum['parameters'])
+                        if enum['value'] not in values:
+                            self.imageOperandsParamCount[count].append(enum['enumerant'])
+                            values.append(enum['value'])
 
             for instruction in instructions:
                 opname = instruction['opname']
@@ -314,16 +324,17 @@
 
         return output;
     #
-    # Generate functions for scope id
-    def scopeHelper(self):
+    # Generate functions for operand parameter switch cases
+    def parameterHelper(self):
         output = ''
         if self.headerFile:
-            output += 'uint32_t MemoryScopeParam(uint32_t opcode);\n'
-            output += 'uint32_t ExecutionScopeParam(uint32_t opcode);\n'
-            output += 'uint32_t ImageOperandsParam(uint32_t opcode);\n'
+            output += 'uint32_t MemoryScopeParamPosition(uint32_t opcode);\n'
+            output += 'uint32_t ExecutionScopeParamPosition(uint32_t opcode);\n'
+            output += 'uint32_t ImageOperandsParamPosition(uint32_t opcode);\n'
+            output += 'uint32_t ImageOperandsParamCount(uint32_t opcode);\n'
         elif self.sourceFile:
-            output += '// Return paramater position of memory scope ID or zero if there is none\n'
-            output += 'uint32_t MemoryScopeParam(uint32_t opcode) {\n'
+            output += '// Return parameter position of memory scope ID or zero if there is none\n'
+            output += 'uint32_t MemoryScopeParamPosition(uint32_t opcode) {\n'
             output += '    uint32_t position = 0;\n'
             output += '    switch (opcode) {\n'
             for index, operands in enumerate(self.memoryScopeParam):
@@ -331,10 +342,10 @@
                     output += '        case spv::{}:\n'.format(operand)
                 if len(operands) != 0:
                     output += '            return {};\n'.format(index)
-            output += self.commonParamSwitch
+            output += self.commonParamSwitch('position')
 
-            output += '// Return paramater position of execution scope ID or zero if there is none\n'
-            output += 'uint32_t ExecutionScopeParam(uint32_t opcode) {\n'
+            output += '// Return parameter position of execution scope ID or zero if there is none\n'
+            output += 'uint32_t ExecutionScopeParamPosition(uint32_t opcode) {\n'
             output += '    uint32_t position = 0;\n'
             output += '    switch (opcode) {\n'
             for index, operands in enumerate(self.executionScopeParam):
@@ -342,11 +353,11 @@
                     output += '        case spv::{}:\n'.format(operand)
                 if len(operands) != 0:
                     output += '            return {};\n'.format(index)
-            output += self.commonParamSwitch
+            output += self.commonParamSwitch('position')
 
 
-            output += '// Return paramater position of Image Operands or zero if there is none\n'
-            output += 'uint32_t ImageOperandsParam(uint32_t opcode) {\n'
+            output += '// Return parameter position of Image Operands or zero if there is none\n'
+            output += 'uint32_t ImageOperandsParamPosition(uint32_t opcode) {\n'
             output += '    uint32_t position = 0;\n'
             output += '    switch (opcode) {\n'
             for index, operands in enumerate(self.imageOperandsParam):
@@ -354,7 +365,21 @@
                     output += '        case spv::{}:\n'.format(operand)
                 if len(operands) != 0:
                     output += '            return {};\n'.format(index)
-            output += self.commonParamSwitch
+            output += self.commonParamSwitch('position')
+
+            output += '// Return number of optional parameter from ImageOperands\n'
+            output += 'uint32_t ImageOperandsParamCount(uint32_t image_operand) {\n'
+            output += '    uint32_t count = 0;\n'
+            output += '    switch (image_operand) {\n'
+            for index, operands in enumerate(self.imageOperandsParamCount):
+                for operand in operands:
+                    if operand == 'None': # not sure why header is not consistent with this
+                        output += '        case spv::ImageOperandsMask{}:\n'.format(operand)
+                    else:
+                        output += '        case spv::ImageOperands{}Mask:\n'.format(operand)
+                if len(operands) != 0:
+                    output += '            return {};\n'.format(index)
+            output += self.commonParamSwitch('count')
 
         return output;
     #