layers: Reduce looping for builtins
diff --git a/layers/shader_validation.cpp b/layers/shader_validation.cpp
index 4126016..06eea8f 100644
--- a/layers/shader_validation.cpp
+++ b/layers/shader_validation.cpp
@@ -184,6 +184,10 @@
                 auto target_id = insn.word(1);
                 decorations[target_id].add(insn.word(2), insn.len() > 3u ? insn.word(3) : 0u);
                 decoration_inst.push_back(insn);
+                if (insn.word(2) == spv::DecorationBuiltIn) {
+                    builtin_decoration_list.emplace_back(insn.offset(), static_cast<spv::BuiltIn>(insn.word(3)));
+                }
+
             } break;
             case spv::OpGroupDecorate: {
                 auto const &src = decorations[insn.word(1)];
@@ -191,6 +195,9 @@
             } break;
             case spv::OpMemberDecorate: {
                 member_decoration_inst.push_back(insn);
+                if (insn.word(3) == spv::DecorationBuiltIn) {
+                    builtin_decoration_list.emplace_back(insn.offset(), static_cast<spv::BuiltIn>(insn.word(4)));
+                }
             } break;
 
                 // Entry points ... add to the entrypoint table
@@ -812,9 +819,9 @@
         switch (insn.word(2)) {
             case spv::DecorationBlock: {
                 uint32_t block_id = insn.word(1);
-                for (auto built_in_block_id : builtin_struct_members) {
+                for (auto builtin_block_id : builtin_struct_members) {
                     // Check if one of the members of the block are built-in -> the block is built-in
-                    if (block_id == built_in_block_id) {
+                    if (block_id == builtin_block_id) {
                         builtin_decorations.push_back(block_id);
                         break;
                     }
@@ -848,14 +855,14 @@
 
         // Now find all members belonging to the struct defining the IO block
         if (def.opcode() == spv::OpTypeStruct) {
-            for (auto built_in_id : builtin_decorations) {
-                if (built_in_id == def.word(1)) {
+            for (auto builtin_id : builtin_decorations) {
+                if (builtin_id == def.word(1)) {
                     for (int i = 2; i < static_cast<int>(def.len()); i++) {
                         builtin_block_members.push_back(spv::BuiltInMax);  // Start with undefined builtin for each struct member.
                     }
                     // These shouldn't be left after replacing.
                     for (auto insn : src->member_decoration_inst) {
-                        if (insn.word(1) == built_in_id && insn.word(3) == spv::DecorationBuiltIn) {
+                        if (insn.word(1) == builtin_id && insn.word(3) == spv::DecorationBuiltIn) {
                             auto struct_index = insn.word(2);
                             assert(struct_index < builtin_block_members.size());
                             builtin_block_members[struct_index] = insn.word(4);
@@ -3280,24 +3287,14 @@
     bool skip = false;
 
     // Search for PointSize built-in decorations
-    std::vector<uint32_t> pointsize_builtin_offsets;
-    spirv_inst_iter insn = entrypoint;
-    while (!pointsize_written && (insn.opcode() != spv::OpFunction)) {
-        if (insn.opcode() == spv::OpMemberDecorate) {
-            if (insn.word(3) == spv::DecorationBuiltIn) {
-                if (insn.word(4) == spv::BuiltInPointSize) {
-                    pointsize_written = IsBuiltInWritten(src, insn, entrypoint);
-                }
-            }
-        } else if (insn.opcode() == spv::OpDecorate) {
-            if (insn.word(2) == spv::DecorationBuiltIn) {
-                if (insn.word(3) == spv::BuiltInPointSize) {
-                    pointsize_written = IsBuiltInWritten(src, insn, entrypoint);
-                }
+    for (auto set : src->builtin_decoration_list) {
+        auto insn = src->at(set.offset);
+        if (set.builtin == spv::BuiltInPointSize) {
+            pointsize_written = IsBuiltInWritten(src, insn, entrypoint);
+            if (pointsize_written) {
+                break;
             }
         }
-
-        insn++;
     }
 
     if ((stage == VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT || stage == VK_SHADER_STAGE_GEOMETRY_BIT) &&
@@ -3324,31 +3321,18 @@
     bool skip = false;
 
     // Check if the primitive shading rate is written
-    spirv_inst_iter insn = entrypoint;
-    while (!(primitiverate_written && viewportindex_written && viewportmask_written) && insn.opcode() != spv::OpFunction) {
-        if (insn.opcode() == spv::OpMemberDecorate) {
-            if (insn.word(3) == spv::DecorationBuiltIn) {
-                if (insn.word(4) == spv::BuiltInPrimitiveShadingRateKHR) {
-                    primitiverate_written = IsBuiltInWritten(src, insn, entrypoint);
-                } else if (insn.word(4) == spv::BuiltInViewportIndex) {
-                    viewportindex_written = IsBuiltInWritten(src, insn, entrypoint);
-                } else if (insn.word(4) == spv::BuiltInViewportMaskNV) {
-                    viewportmask_written = IsBuiltInWritten(src, insn, entrypoint);
-                }
-            }
-        } else if (insn.opcode() == spv::OpDecorate) {
-            if (insn.word(2) == spv::DecorationBuiltIn) {
-                if (insn.word(3) == spv::BuiltInPrimitiveShadingRateKHR) {
-                    primitiverate_written = IsBuiltInWritten(src, insn, entrypoint);
-                } else if (insn.word(3) == spv::BuiltInViewportIndex) {
-                    viewportindex_written = IsBuiltInWritten(src, insn, entrypoint);
-                } else if (insn.word(3) == spv::BuiltInViewportMaskNV) {
-                    viewportmask_written = IsBuiltInWritten(src, insn, entrypoint);
-                }
-            }
+    for (auto set : src->builtin_decoration_list) {
+        auto insn = src->at(set.offset);
+        if (set.builtin == spv::BuiltInPrimitiveShadingRateKHR) {
+            primitiverate_written = IsBuiltInWritten(src, insn, entrypoint);
+        } else if (set.builtin == spv::BuiltInViewportIndex) {
+            viewportindex_written = IsBuiltInWritten(src, insn, entrypoint);
+        } else if (set.builtin == spv::BuiltInViewportMaskNV) {
+            viewportmask_written = IsBuiltInWritten(src, insn, entrypoint);
         }
-
-        insn++;
+        if (primitiverate_written && viewportindex_written && viewportmask_written) {
+            break;
+        }
     }
 
     if (!phys_dev_ext_props.fragment_shading_rate_props.primitiveFragmentShadingRateWithMultipleViewports &&
@@ -3778,26 +3762,18 @@
 
         if (stage->stage == VK_SHADER_STAGE_VERTEX_BIT || stage->stage == VK_SHADER_STAGE_GEOMETRY_BIT ||
             stage->stage == VK_SHADER_STAGE_MESH_BIT_NV) {
-            spirv_inst_iter insn = entrypoints[stage_id];
             bool primitiverate_written = false;
 
-            while (!primitiverate_written && (insn.opcode() != spv::OpFunction)) {
-                if (insn.opcode() == spv::OpMemberDecorate) {
-                    if (insn.word(3) == spv::DecorationBuiltIn) {
-                        if (insn.word(4) == spv::BuiltInPrimitiveShadingRateKHR) {
-                            primitiverate_written = IsBuiltInWritten(shaders[stage_id], insn, entrypoints[stage_id]);
-                        }
-                    }
-                } else if (insn.opcode() == spv::OpDecorate) {
-                    if (insn.word(2) == spv::DecorationBuiltIn) {
-                        if (insn.word(3) == spv::BuiltInPrimitiveShadingRateKHR) {
-                            primitiverate_written = IsBuiltInWritten(shaders[stage_id], insn, entrypoints[stage_id]);
-                        }
-                    }
+            for (auto set : shaders[stage_id]->builtin_decoration_list) {
+                auto insn = shaders[stage_id]->at(set.offset);
+                if (set.builtin == spv::BuiltInPrimitiveShadingRateKHR) {
+                    primitiverate_written = IsBuiltInWritten(shaders[stage_id], insn, entrypoints[stage_id]);
                 }
-
-                insn++;
+                if (primitiverate_written) {
+                    break;
+                }
             }
+
             if (primitiverate_written) {
                 pipeline_state->wrote_primitive_shading_rate.insert(stage->stage);
             }