Browse Source

vulkan: fix shaders with int vertex attributes when nothing using that attribute is drawn.

Sasha Szpakowski 1 year ago
parent
commit
111bbde32d

+ 20 - 8
src/modules/graphics/vulkan/Graphics.cpp

@@ -2260,7 +2260,7 @@ void Graphics::createVulkanVertexFormat(
 
 
 	for (const auto &pair : shader->getVertexAttributeIndices())
 	for (const auto &pair : shader->getVertexAttributeIndices())
 	{
 	{
-		int i = pair.second;
+		int i = pair.second.index;
 		uint32 bit = 1u << i;
 		uint32 bit = 1u << i;
 
 
 		VkVertexInputAttributeDescription attribdesc{};
 		VkVertexInputAttributeDescription attribdesc{};
@@ -2295,13 +2295,25 @@ void Graphics::createVulkanVertexFormat(
 			attribdesc.binding = DEFAULT_VERTEX_BUFFER_BINDING;
 			attribdesc.binding = DEFAULT_VERTEX_BUFFER_BINDING;
 
 
 			// Indices should match the creation parameters for defaultVertexBuffer.
 			// 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())
 			if (usedBuffers.find(DEFAULT_VERTEX_BUFFER_BINDING) == usedBuffers.end())
 			{
 			{

+ 16 - 2
src/modules/graphics/vulkan/Shader.cpp

@@ -373,7 +373,7 @@ void Shader::attach()
 int Shader::getVertexAttributeIndex(const std::string &name)
 int Shader::getVertexAttributeIndex(const std::string &name)
 {
 {
 	auto it = attributes.find(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
 const Shader::UniformInfo *Shader::getUniformInfo(BuiltinUniform builtin) const
@@ -716,7 +716,21 @@ void Shader::compileShaders()
 
 
 				spirv[locationOffset] = (uint32_t)index;
 				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)
 			for (const auto &r : shaderResources.stage_outputs)

+ 9 - 2
src/modules/graphics/vulkan/Shader.h

@@ -52,6 +52,13 @@ class Shader final
 	, public Volatile
 	, public Volatile
 {
 {
 public:
 public:
+
+	struct AttributeInfo
+	{
+		int index;
+		DataBaseType baseType;
+	};
+
 	Shader(StrongRef<love::graphics::ShaderStage> stages[], const CompileOptions &options);
 	Shader(StrongRef<love::graphics::ShaderStage> stages[], const CompileOptions &options);
 	virtual ~Shader();
 	virtual ~Shader();
 
 
@@ -75,7 +82,7 @@ public:
 	std::string getWarnings() const override { return ""; }
 	std::string getWarnings() const override { return ""; }
 
 
 	int getVertexAttributeIndex(const std::string &name) override;
 	int getVertexAttributeIndex(const std::string &name) override;
-	const std::unordered_map<std::string, int> getVertexAttributeIndices() const { return attributes; }
+	const std::unordered_map<std::string, AttributeInfo> getVertexAttributeIndices() const { return attributes; }
 
 
 	const UniformInfo *getUniformInfo(BuiltinUniform builtin) const override;
 	const UniformInfo *getUniformInfo(BuiltinUniform builtin) const override;
 
 
@@ -126,7 +133,7 @@ private:
 	uint32_t localUniformLocation;
 	uint32_t localUniformLocation;
 	OptionalInt builtinUniformDataOffset;
 	OptionalInt builtinUniformDataOffset;
 
 
-	std::unordered_map<std::string, int> attributes;
+	std::unordered_map<std::string, AttributeInfo> attributes;
 
 
 	uint32_t currentFrame;
 	uint32_t currentFrame;
 	uint32_t currentDescriptorPool;
 	uint32_t currentDescriptorPool;