From 111bbde32d967a6bbd6d0893341f8635feac6d26 Mon Sep 17 00:00:00 2001 From: Sasha Szpakowski Date: Thu, 11 Apr 2024 22:35:43 -0300 Subject: [PATCH] vulkan: fix shaders with int vertex attributes when nothing using that attribute is drawn. --- src/modules/graphics/vulkan/Graphics.cpp | 28 +++++++++++++++++------- src/modules/graphics/vulkan/Shader.cpp | 18 +++++++++++++-- src/modules/graphics/vulkan/Shader.h | 11 ++++++++-- 3 files changed, 45 insertions(+), 12 deletions(-) diff --git a/src/modules/graphics/vulkan/Graphics.cpp b/src/modules/graphics/vulkan/Graphics.cpp index ea8d23c88..896b940df 100644 --- a/src/modules/graphics/vulkan/Graphics.cpp +++ b/src/modules/graphics/vulkan/Graphics.cpp @@ -2260,7 +2260,7 @@ void Graphics::createVulkanVertexFormat( for (const auto &pair : shader->getVertexAttributeIndices()) { - int i = pair.second; + int i = pair.second.index; uint32 bit = 1u << i; VkVertexInputAttributeDescription attribdesc{}; @@ -2295,13 +2295,25 @@ void Graphics::createVulkanVertexFormat( attribdesc.binding = DEFAULT_VERTEX_BUFFER_BINDING; // Indices should match the creation parameters for defaultVertexBuffer. - // TODO: handle int/uint attributes? - if (i == ATTRIB_COLOR) - attribdesc.offset = defaultVertexBuffer->getDataMember(2).offset; - else - attribdesc.offset = defaultVertexBuffer->getDataMember(0).offset; - - attribdesc.format = Vulkan::getVulkanVertexFormat(DATAFORMAT_FLOAT_VEC4); + switch (pair.second.baseType) + { + case DATA_BASETYPE_INT: + attribdesc.offset = defaultVertexBuffer->getDataMember(1).offset; + attribdesc.format = Vulkan::getVulkanVertexFormat(DATAFORMAT_INT32_VEC4); + break; + case DATA_BASETYPE_UINT: + attribdesc.offset = defaultVertexBuffer->getDataMember(1).offset; + attribdesc.format = Vulkan::getVulkanVertexFormat(DATAFORMAT_UINT32_VEC4); + break; + case DATA_BASETYPE_FLOAT: + default: + if (i == ATTRIB_COLOR) + attribdesc.offset = defaultVertexBuffer->getDataMember(2).offset; + else + attribdesc.offset = defaultVertexBuffer->getDataMember(0).offset; + attribdesc.format = Vulkan::getVulkanVertexFormat(DATAFORMAT_FLOAT_VEC4); + break; + } if (usedBuffers.find(DEFAULT_VERTEX_BUFFER_BINDING) == usedBuffers.end()) { diff --git a/src/modules/graphics/vulkan/Shader.cpp b/src/modules/graphics/vulkan/Shader.cpp index 2f1da6625..5f3c4f213 100644 --- a/src/modules/graphics/vulkan/Shader.cpp +++ b/src/modules/graphics/vulkan/Shader.cpp @@ -373,7 +373,7 @@ void Shader::attach() int Shader::getVertexAttributeIndex(const std::string &name) { auto it = attributes.find(name); - return it == attributes.end() ? -1 : it->second; + return it == attributes.end() ? -1 : it->second.index; } const Shader::UniformInfo *Shader::getUniformInfo(BuiltinUniform builtin) const @@ -716,7 +716,21 @@ void Shader::compileShaders() spirv[locationOffset] = (uint32_t)index; - attributes[r.name] = index; + DataBaseType basetype = DATA_BASETYPE_FLOAT; + + switch (comp.get_type(r.base_type_id).basetype) + { + case spirv_cross::SPIRType::Int: + basetype = DATA_BASETYPE_INT; + break; + case spirv_cross::SPIRType::UInt: + basetype = DATA_BASETYPE_UINT; + break; + default: + break; + } + + attributes[r.name] = { index, basetype }; } for (const auto &r : shaderResources.stage_outputs) diff --git a/src/modules/graphics/vulkan/Shader.h b/src/modules/graphics/vulkan/Shader.h index 98b2b7f77..e1f676f6e 100644 --- a/src/modules/graphics/vulkan/Shader.h +++ b/src/modules/graphics/vulkan/Shader.h @@ -52,6 +52,13 @@ class Shader final , public Volatile { public: + + struct AttributeInfo + { + int index; + DataBaseType baseType; + }; + Shader(StrongRef stages[], const CompileOptions &options); virtual ~Shader(); @@ -75,7 +82,7 @@ class Shader final std::string getWarnings() const override { return ""; } int getVertexAttributeIndex(const std::string &name) override; - const std::unordered_map getVertexAttributeIndices() const { return attributes; } + const std::unordered_map getVertexAttributeIndices() const { return attributes; } const UniformInfo *getUniformInfo(BuiltinUniform builtin) const override; @@ -126,7 +133,7 @@ class Shader final uint32_t localUniformLocation; OptionalInt builtinUniformDataOffset; - std::unordered_map attributes; + std::unordered_map attributes; uint32_t currentFrame; uint32_t currentDescriptorPool;