layers: Update fs checks for component qualifiers

The shader validation for checking fs outputs against renderpass
attachments did not allow for component qualifiers in location
definitions, causing incorrect warnings. Updated test to cover
behavior that was incorrectly handled.

Change-Id: Iec27d55283a3aab6c406e1d78b4a128a7d5cdb6f
diff --git a/layers/shader_validation.cpp b/layers/shader_validation.cpp
index 68c2129..7b2f411 100644
--- a/layers/shader_validation.cpp
+++ b/layers/shader_validation.cpp
@@ -777,6 +777,7 @@
         bool b_at_end = inputs.size() == 0 || it_b == inputs.end();
         auto a_first = a_at_end ? 0 : it_a->first;
         auto b_first = b_at_end ? 0 : it_b->first.first;
+
         if (!a_at_end && (b_at_end || a_first < b_first)) {
             if (!used &&
                 log_msg(report_data, VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_SHADER_MODULE_EXT,
@@ -834,6 +835,7 @@
 
     auto it_a = outputs.begin();
     auto it_b = color_attachments.begin();
+    bool used = false;
 
     // Walk attachment list and outputs together
 
@@ -849,11 +851,14 @@
         } else if (!b_at_end && (a_at_end || it_a->first.first > it_b->first)) {
             // Only complain if there are unmasked channels for this attachment. If the writemask is 0, it's acceptable for the
             // shader to not produce a matching output.
-            if (pipeline->attachments[it_b->first].colorWriteMask != 0) {
-                skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_SHADER_MODULE_EXT,
-                                HandleToUint64(fs->vk_shader_module), kVUID_Core_Shader_InputNotProduced,
-                                "Attachment %d not written by fragment shader", it_b->first);
+            if (!used) {
+                if (pipeline->attachments[it_b->first].colorWriteMask != 0) {
+                    skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_SHADER_MODULE_EXT,
+                                    HandleToUint64(fs->vk_shader_module), kVUID_Core_Shader_InputNotProduced,
+                                    "Attachment %d not written by fragment shader", it_b->first);
+                }
             }
+            used = false;
             it_b++;
         } else {
             unsigned output_type = GetFundamentalType(fs, it_a->second.type_id);
@@ -869,7 +874,7 @@
 
             // OK!
             it_a++;
-            it_b++;
+            used = true;
         }
     }
 
diff --git a/tests/layer_validation_tests.cpp b/tests/layer_validation_tests.cpp
index 999b2b9..213d9fe 100644
--- a/tests/layer_validation_tests.cpp
+++ b/tests/layer_validation_tests.cpp
@@ -28506,8 +28506,9 @@
 TEST_F(VkPositiveLayerTest, CreatePipelineAttribComponents) {
     TEST_DESCRIPTION(
         "Test that pipeline validation accepts consuming a vertex attribute through multiple vertex shader inputs, each consuming "
-        "a different subset of the components.");
-    m_errorMonitor->ExpectSuccess();
+        "a different subset of the components, and that fragment shader-attachment validation tolerates multiple duplicate "
+        "location outputs");
+    m_errorMonitor->ExpectSuccess(VK_DEBUG_REPORT_ERROR_BIT_EXT | VK_DEBUG_REPORT_WARNING_BIT_EXT);
 
     ASSERT_NO_FATAL_FAILURE(Init());
     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
@@ -28536,9 +28537,12 @@
     char const *fsSource =
         "#version 450\n"
         "\n"
-        "layout(location=0) out vec4 color;\n"
+        "layout(location=0, component=0) out float color0;\n"
+        "layout(location=0, component=1) out float color1;\n"
+        "layout(location=0, component=2) out float color2;\n"
+        "layout(location=0, component=3) out float color3;\n"
         "void main(){\n"
-        "   color = vec4(1);\n"
+        "   color0 = float(1);\n"
         "}\n";
 
     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);