layers: Use entrypoint interface specification to collect variables
authorChris Forbes <chrisforbes@google.com>
Mon, 1 Feb 2016 01:29:51 +0000 (14:29 +1300)
committerTobin Ehlis <tobine@google.com>
Fri, 12 Feb 2016 14:45:52 +0000 (07:45 -0700)
The module may contain many others -- only the variables listed in
the OpEntryPoint are part of the interface.

Note that the shader resource interface is NOT listed in OpEntryPoint. For now we
continue to conservatively assume every OpVariable in the module with a suitable
storage class is in every entrypoint's shader resource interface -- that is, we're
not walking the static call tree from each entrypoint to determine what is and is
not used by it.

Signed-off-by: Chris Forbes <chrisforbes@google.com>
layers/draw_state.cpp

index 81b9bb6..fb8fafd 100644 (file)
@@ -394,6 +394,11 @@ build_def_index(shader_module *module)
             module->def_index[insn.word(2)] = insn.offset();
             break;
 
+        /* Variables */
+        case spv::OpVariable:
+            module->def_index[insn.word(2)] = insn.offset();
+            break;
+
         default:
             /* We don't care about any other defs for now. */
             break;
@@ -730,12 +735,27 @@ collect_interface_by_location(layer_data *my_data, VkDevice dev,
                 blocks[insn.word(1)] = 1;
             }
         }
+    }
 
         /* TODO: handle grouped decorations */
         /* TODO: handle index=1 dual source outputs from FS -- two vars will
          * have the same location, and we DONT want to clobber. */
 
-        else if (insn.opcode() == spv::OpVariable && insn.word(3) == sinterface) {
+    /* find the end of the entrypoint's name string. additional zero bytes follow the actual null
+       terminator, to fill out the rest of the word - so we only need to look at the last byte in
+       the word to determine which word contains the terminator. */
+    auto word = 3;
+    while (entrypoint.word(word) & 0xff000000u) {
+        ++word;
+    }
+    ++word;
+
+    for (; word < entrypoint.len(); word++) {
+        auto insn = src->get_def(entrypoint.word(word));
+        assert(insn != src->end());
+        assert(insn.opcode() == spv::OpVariable);
+
+        if (insn.word(3) == sinterface) {
             unsigned id = insn.word(2);
             unsigned type = insn.word(1);