Browse Source

shaderpipeline: Support binding descriptor sets in SPIR-V

rdb 5 years ago
parent
commit
615e797767

+ 28 - 0
panda/src/shaderpipeline/shaderModuleSpirV.cxx

@@ -593,6 +593,34 @@ assign_locations(Stage stage) {
   }
 }
 
+/**
+ * Assign descriptor bindings for a descriptor set based on the given locations.
+ * Assumes there are already binding and set decorations.
+ * To create gaps in the descriptor set, entries in locations may be -1.
+ */
+void ShaderModuleSpirV::InstructionWriter::
+bind_descriptor_set(uint32_t set, const vector_int &locations) {
+  for (InstructionIterator it = _instructions.begin_annotations();
+       it != _instructions.end() && (*it).is_annotation();
+       ++it) {
+    Instruction op = *it;
+
+    if (op.opcode == spv::OpDecorate && op.nargs >= 3) {
+      Definition &def = _defs[op.args[0]];
+
+      auto lit = std::find(locations.begin(), locations.end(), def._location);
+      if (lit != locations.end() && def._location >= 0) {
+        if (op.args[1] == spv::DecorationBinding) {
+          op.args[2] = std::distance(locations.begin(), lit);
+        }
+        else if (op.args[1] == spv::DecorationDescriptorSet) {
+          op.args[2] = set;
+        }
+      }
+    }
+  }
+}
+
 /**
  * Converts the members of the struct type with the given ID to regular
  * variables.  Useful for unwrapping uniform blocks.

+ 1 - 0
panda/src/shaderpipeline/shaderModuleSpirV.h

@@ -176,6 +176,7 @@ public:
     Definition &modify_definition(uint32_t id);
 
     void assign_locations(Stage stage);
+    void bind_descriptor_set(uint32_t set, const vector_int &locations);
 
     void flatten_struct(uint32_t type_id);
     uint32_t make_block(const ShaderType::Struct *block_type, const pvector<int> &locations,