Fix various gaps in OpRuntimeArray support in SC

Fixes #289
diff --git a/layers/shader_validation.cpp b/layers/shader_validation.cpp
index 3100127..86a25ce 100644
--- a/layers/shader_validation.cpp
+++ b/layers/shader_validation.cpp
@@ -218,6 +218,10 @@
             ss << "arr[" << GetConstantValue(src, insn.word(3)) << "] of ";
             DescribeTypeInner(ss, src, insn.word(2));
             break;
+        case spv::OpTypeRuntimeArray:
+            ss << "runtime arr[] of ";
+            DescribeTypeInner(ss, src, insn.word(2));
+            break;
         case spv::OpTypePointer:
             ss << "ptr to " << StorageClassName(insn.word(2)) << " ";
             DescribeTypeInner(ss, src, insn.word(3));
@@ -269,6 +273,8 @@
     assert(a_insn != a->end());
     assert(b_insn != b->end());
 
+    // Ignore runtime-sized arrays-- they cannot appear in these interfaces.
+
     if (a_arrayed && a_insn.opcode() == spv::OpTypeArray) {
         return TypesMatch(a, b, a_insn.word(2), b_type, false, b_arrayed, relaxed);
     }
@@ -409,6 +415,7 @@
 }
 
 // characterizes a SPIR-V type appearing in an interface to a FF stage, for comparison to a VkFormat's characterization above.
+// also used for input attachments, as we statically know their format.
 static unsigned GetFundamentalType(shader_module const *src, unsigned type) {
     auto insn = src->get_def(type);
     assert(insn != src->end());
@@ -419,15 +426,13 @@
         case spv::OpTypeFloat:
             return FORMAT_TYPE_FLOAT;
         case spv::OpTypeVector:
-            return GetFundamentalType(src, insn.word(2));
         case spv::OpTypeMatrix:
-            return GetFundamentalType(src, insn.word(2));
         case spv::OpTypeArray:
+        case spv::OpTypeRuntimeArray:
+        case spv::OpTypeImage:
             return GetFundamentalType(src, insn.word(2));
         case spv::OpTypePointer:
             return GetFundamentalType(src, insn.word(3));
-        case spv::OpTypeImage:
-            return GetFundamentalType(src, insn.word(2));
 
         default:
             return 0;
@@ -647,8 +652,9 @@
     auto type = module->get_def(type_id);
 
     // Strip off any array or ptrs. Where we remove array levels, adjust the  descriptor count for each dimension.
-    while (type.opcode() == spv::OpTypeArray || type.opcode() == spv::OpTypePointer) {
-        if (type.opcode() == spv::OpTypeArray) {
+    while (type.opcode() == spv::OpTypeArray || type.opcode() == spv::OpTypePointer || type.opcode() == spv::OpTypeRuntimeArray) {
+        if (type.opcode() == spv::OpTypeArray || type.opcode() == spv::OpTypeRuntimeArray) {
+            // Element type
             type = module->get_def(type.word(2));
         } else {
             if (type.word(2) == spv::StorageClassStorageBuffer) {
@@ -1375,6 +1381,7 @@
     while (true) {
         switch (type.opcode()) {
             case spv::OpTypeArray:
+            case spv::OpTypeRuntimeArray:
             case spv::OpTypeSampledImage:
                 type = module->get_def(type.word(2));
                 break;