瀏覽代碼

vulkan: Strip location decorations from uniform variables

This fixes a validation error
rdb 2 年之前
父節點
當前提交
45bd76d4d7

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

@@ -1187,6 +1187,28 @@ remove_unused_variables() {
   }
   }
 }
 }
 
 
+/**
+ * Removes location decorations from uniforms.
+ */
+void ShaderModuleSpirV::InstructionWriter::
+strip_uniform_locations() {
+  InstructionIterator it = _instructions.begin();
+  while (it != _instructions.end()) {
+    Instruction op = *it;
+
+    if (op.opcode == spv::OpDecorate && op.args[1] == spv::DecorationLocation) {
+      Definition &def = modify_definition(op.args[0]);
+      if (def._storage_class == spv::StorageClassUniformConstant) {
+        it = _instructions.erase(it);
+        def._location = -1;
+        continue;
+      }
+    }
+
+    ++it;
+  }
+}
+
 /**
 /**
  * Converts the members of the struct type with the given ID to regular
  * Converts the members of the struct type with the given ID to regular
  * variables.  Useful for unwrapping uniform blocks.
  * variables.  Useful for unwrapping uniform blocks.

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

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

+ 4 - 0
panda/src/vulkandisplay/vulkanShaderContext.cxx

@@ -164,6 +164,10 @@ create_modules(VkDevice device, const ShaderType::Struct *push_constant_block_ty
       writer.bind_descriptor_set(VulkanGraphicsStateGuardian::DS_shader_attrib, tex_input_set_locations);
       writer.bind_descriptor_set(VulkanGraphicsStateGuardian::DS_shader_attrib, tex_input_set_locations);
     }
     }
 
 
+    // These are not used in Vulkan, no longer needed by the code above, and
+    // the validation layers trip over them.
+    writer.strip_uniform_locations();
+
     // Change OpenGL conventions to Vulkan conventions.
     // Change OpenGL conventions to Vulkan conventions.
     for (ShaderModuleSpirV::Instruction op : instructions) {
     for (ShaderModuleSpirV::Instruction op : instructions) {
       if (op.opcode == spv::OpExecutionMode) {
       if (op.opcode == spv::OpExecutionMode) {