layers: block members do not express extra array level in member type

Fixes GH #377.

Signed-off-by: Chris Forbes <chrisforbes@google.com>
diff --git a/layers/core_validation.cpp b/layers/core_validation.cpp
index a2a04da..320db8f 100644
--- a/layers/core_validation.cpp
+++ b/layers/core_validation.cpp
@@ -1264,6 +1264,7 @@
     uint32_t type_id;
     uint32_t offset;
     bool is_patch;
+    bool is_block_member;
     /* TODO: collect the name, too? Isn't required to be present. */
 };
 
@@ -1341,6 +1342,7 @@
                     v.type_id = member_type_id;
                     v.offset = offset;
                     v.is_patch = is_patch;
+                    v.is_block_member = true;
                     out[std::make_pair(location + offset, component)] = v;
                 }
             }
@@ -1430,6 +1432,7 @@
                     v.type_id = type;
                     v.offset = offset;
                     v.is_patch = is_patch;
+                    v.is_block_member = false;
                     out[std::make_pair(location + offset, component)] = v;
                 }
             } else if (builtin == -1) {
@@ -1486,6 +1489,7 @@
             v.type_id = insn.word(1);
             v.offset = 0;
             v.is_patch = false;
+            v.is_block_member = false;
             out[std::make_pair(set, binding)] = v;
         }
     }
@@ -1530,9 +1534,13 @@
             }
             b_it++;
         } else {
+            // subtleties of arrayed interfaces:
+            // - if is_patch, then the member is not arrayed, even though the interface may be.
+            // - if is_block_member, then the extra array level of an arrayed interface is not
+            //   expressed in the member type -- it's expressed in the block type.
             if (!types_match(producer, consumer, a_it->second.type_id, b_it->second.type_id,
-                             producer_stage->arrayed_output && !a_it->second.is_patch,
-                             consumer_stage->arrayed_input && !b_it->second.is_patch,
+                             producer_stage->arrayed_output && !a_it->second.is_patch && !a_it->second.is_block_member,
+                             consumer_stage->arrayed_input && !b_it->second.is_patch && !b_it->second.is_block_member,
                              true)) {
                 if (log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VkDebugReportObjectTypeEXT(0), 0,
                             __LINE__, SHADER_CHECKER_INTERFACE_TYPE_MISMATCH, "SC", "Type mismatch on location %u.%u: '%s' vs '%s'",
diff --git a/tests/layer_validation_tests.cpp b/tests/layer_validation_tests.cpp
index 0bad845..1b45b82 100644
--- a/tests/layer_validation_tests.cpp
+++ b/tests/layer_validation_tests.cpp
@@ -5658,6 +5658,60 @@
     m_errorMonitor->VerifyNotFound();
 }
 
+TEST_F(VkLayerTest, CreatePipelineGeometryInputBlockPositive)
+{
+    m_errorMonitor->ExpectSuccess();
+
+    ASSERT_NO_FATAL_FAILURE(InitState());
+    ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
+
+    if (!m_device->phy().features().geometryShader) {
+        printf("Device does not support geometry shaders; skipped.\n");
+        return;
+    }
+
+    char const *vsSource =
+        "#version 450\n"
+        "layout(location=0) out VertexData { vec4 x; } vs_out;\n"
+        "void main(){\n"
+        "   vs_out.x = vec4(1);\n"
+        "}\n";
+    char const *gsSource =
+        "#version 450\n"
+        "layout(triangles) in;\n"
+        "layout(triangle_strip, max_vertices=3) out;\n"
+        "layout(location=0) in VertexData { vec4 x; } gs_in[];\n"
+        "out gl_PerVertex { vec4 gl_Position; };\n"
+        "void main() {\n"
+        "   gl_Position = gs_in[0].x;\n"
+        "   EmitVertex();\n"
+        "}\n";
+    char const *fsSource =
+        "#version 450\n"
+        "layout(location=0) out vec4 color;\n"
+        "void main(){\n"
+        "   color = vec4(1);\n"
+        "}\n";
+
+    VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
+    VkShaderObj gs(m_device, gsSource, VK_SHADER_STAGE_GEOMETRY_BIT, this);
+    VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
+
+    VkPipelineObj pipe(m_device);
+    pipe.AddColorAttachment();
+    pipe.AddShader(&vs);
+    pipe.AddShader(&gs);
+    pipe.AddShader(&fs);
+
+    VkDescriptorSetObj descriptorSet(m_device);
+    descriptorSet.AppendDummy();
+    descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
+
+    pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
+
+    m_errorMonitor->VerifyNotFound();
+}
+
 TEST_F(VkLayerTest, CreatePipelineTessPatchDecorationMismatch)
 {
     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,