소스 검색

shaderpipeline: bind_descriptor_set adds new decorations if they don't yet exist

rdb 1 년 전
부모
커밋
bf0dea32fe
1개의 변경된 파일20개의 추가작업 그리고 2개의 파일을 삭제
  1. 20 2
      panda/src/shaderpipeline/spirVTransformer.cxx

+ 20 - 2
panda/src/shaderpipeline/spirVTransformer.cxx

@@ -281,7 +281,6 @@ assign_locations(pmap<uint32_t, int> remap) {
 
 /**
  * Assign descriptor bindings for a descriptor set based on the given ids.
- * Assumes there are already binding and set decorations.
  * To create gaps in the descriptor set, entries in ids may be 0.
  */
 void SpirVTransformer::
@@ -289,6 +288,9 @@ bind_descriptor_set(uint32_t set, const pvector<uint32_t> &ids) {
   InstructionIterator it(_annotations.data());
   InstructionIterator end(_annotations.data() + _annotations.size());
 
+  BitArray assigned_sets;
+  BitArray assigned_bindings;
+
   while (it != end) {
     Instruction op = *it;
 
@@ -297,15 +299,31 @@ bind_descriptor_set(uint32_t set, const pvector<uint32_t> &ids) {
          op.args[1] == spv::DecorationDescriptorSet)) {
       auto iit = std::find(ids.begin(), ids.end(), op.args[0]);
       if (iit != ids.end()) {
+        uint32_t binding = std::distance(ids.begin(), iit);
         if (op.args[1] == spv::DecorationBinding) {
-          op.args[2] = std::distance(ids.begin(), iit);
+          op.args[2] = binding;
+          assigned_bindings.set_bit(binding);
         }
         else if (op.args[1] == spv::DecorationDescriptorSet) {
           op.args[2] = set;
+          assigned_sets.set_bit(binding);
         }
       }
     }
 
     ++it;
   }
+
+  // Anything left?
+  for (uint32_t binding = 0; binding < ids.size(); ++binding) {
+    uint32_t id = ids[binding];
+    if (id > 0) {
+      if (!assigned_sets.get_bit(binding)) {
+        _annotations.insert(_annotations.end(), {spv::OpDecorate | (4 << spv::WordCountShift), id, spv::DecorationDescriptorSet, set});
+      }
+      if (!assigned_bindings.get_bit(binding)) {
+        _annotations.insert(_annotations.end(), {spv::OpDecorate | (4 << spv::WordCountShift), id, spv::DecorationBinding, binding});
+      }
+    }
+  }
 }