From d40b78be7607a23178c62e4b00d2c5ede9082702 Mon Sep 17 00:00:00 2001 From: Sasha Szpakowski Date: Mon, 8 Apr 2024 17:59:06 -0300 Subject: [PATCH] vulkan: fix shader cross-stage io (varying) location mapping. --- src/modules/graphics/vulkan/Shader.cpp | 31 +++++++++++++++++++++++--- 1 file changed, 28 insertions(+), 3 deletions(-) diff --git a/src/modules/graphics/vulkan/Shader.cpp b/src/modules/graphics/vulkan/Shader.cpp index 293899503..2f1da6625 100644 --- a/src/modules/graphics/vulkan/Shader.cpp +++ b/src/modules/graphics/vulkan/Shader.cpp @@ -41,6 +41,11 @@ static const uint32_t DESCRIPTOR_POOL_SIZE = 1000; class BindingMapper { public: + + BindingMapper(spv::Decoration decoration) + : decoration(decoration) + {} + uint32_t operator()(spirv_cross::CompilerGLSL &comp, std::vector &spirv, const std::string &name, int count, const spirv_cross::ID &id) { auto it = bindingMappings.find(name); @@ -58,7 +63,7 @@ public: uint32_t freeBinding = getFreeBinding(count); uint32_t binaryBindingOffset; - if (!comp.get_binary_offset_for_decoration(id, spv::DecorationBinding, binaryBindingOffset)) + if (!comp.get_binary_offset_for_decoration(id, decoration, binaryBindingOffset)) throw love::Exception("could not get binary offset for uniform %s binding", name.c_str()); spirv[binaryBindingOffset] = freeBinding; @@ -73,7 +78,7 @@ public: auto binding = (uint32_t)it->second.getOffset(); uint32_t binaryBindingOffset; - if (!comp.get_binary_offset_for_decoration(id, spv::DecorationBinding, binaryBindingOffset)) + if (!comp.get_binary_offset_for_decoration(id, decoration, binaryBindingOffset)) throw love::Exception("could not get binary offset for uniform %s binding", name.c_str()); spirv[binaryBindingOffset] = binding; @@ -104,6 +109,7 @@ private: return true; } + spv::Decoration decoration; std::map bindingMappings; }; @@ -570,7 +576,8 @@ void Shader::compileShaders() if (!program->mapIO()) throw love::Exception("mapIO failed"); - BindingMapper bindingMapper; + BindingMapper bindingMapper(spv::DecorationBinding); + BindingMapper ioLocationMapper(spv::DecorationLocation); for (int i = 0; i < SHADERSTAGE_MAX_ENUM; i++) { @@ -711,6 +718,24 @@ void Shader::compileShaders() attributes[r.name] = index; } + + for (const auto &r : shaderResources.stage_outputs) + { + const auto &type = comp.get_type(r.type_id); + int count = type.array.empty() ? 1 : type.array[0]; + + ioLocationMapper(comp, spirv, r.name, count, r.id); + } + } + else if (shaderStage == SHADERSTAGE_PIXEL) + { + for (const auto &r : shaderResources.stage_inputs) + { + const auto &type = comp.get_type(r.type_id); + int count = type.array.empty() ? 1 : type.array[0]; + + ioLocationMapper(comp, spirv, r.name, count, r.id); + } } VkShaderModuleCreateInfo createInfo{};