Browse Source

vulkan: shader binding mapper works with arrays of resources

Sasha Szpakowski 1 year ago
parent
commit
be377601f7
2 changed files with 19 additions and 17 deletions
  1. 1 1
      src/common/Range.h
  2. 18 16
      src/modules/graphics/vulkan/Shader.cpp

+ 1 - 1
src/common/Range.h

@@ -61,7 +61,7 @@ struct Range
 		return first <= other.first && last >= other.last;
 	}
 
-	bool intersects(const Range &other)
+	bool intersects(const Range &other) const
 	{
 		return !(first > other.last || last < other.first);
 	}

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

@@ -21,6 +21,7 @@
 #include "graphics/vertex.h"
 #include "Shader.h"
 #include "Graphics.h"
+#include "common/Range.h"
 
 #include "libraries/glslang/glslang/Public/ShaderLang.h"
 #include "libraries/glslang/glslang/Public/ResourceLimits.h"
@@ -41,21 +42,21 @@ static const uint32_t DESCRIPTOR_POOL_SIZE = 1000;
 class BindingMapper
 {
 public:
-	uint32_t operator()(spirv_cross::CompilerGLSL &comp, std::vector<uint32_t> &spirv, const std::string &name, const spirv_cross::ID &id)
+	uint32_t operator()(spirv_cross::CompilerGLSL &comp, std::vector<uint32_t> &spirv, const std::string &name, int count, const spirv_cross::ID &id)
 	{
 		auto it = bindingMappings.find(name);
 		if (it == bindingMappings.end())
 		{
 			auto binding = comp.get_decoration(id, spv::DecorationBinding);
 
-			if (isFreeBinding(binding))
+			if (isFreeBinding(binding, count))
 			{
-				bindingMappings[name] = binding;
+				bindingMappings[name] = Range(binding, count);
 				return binding;
 			}
 			else
 			{
-				uint32_t freeBinding = getFreeBinding();
+				uint32_t freeBinding = getFreeBinding(count);
 
 				uint32_t binaryBindingOffset;
 				if (!comp.get_binary_offset_for_decoration(id, spv::DecorationBinding, binaryBindingOffset))
@@ -63,37 +64,38 @@ public:
 
 				spirv[binaryBindingOffset] = freeBinding;
 
-				bindingMappings[name] = freeBinding;
+				bindingMappings[name] = Range(freeBinding, count);
 
 				return freeBinding;
 			}
 		}
 		else
-			return it->second;
+			return (uint32_t)it->second.getOffset();
 	};
 
 
 private:
-	uint32_t getFreeBinding()
+	uint32_t getFreeBinding(int count)
 	{
 		for (uint32_t i = 0;; i++)
 		{
-			if (isFreeBinding(i))
+			if (isFreeBinding(i, count))
 				return i;
 		}
 	}
 
-	bool isFreeBinding(uint32_t binding)
+	bool isFreeBinding(uint32_t binding, int count)
 	{
+		Range r(binding, count);
 		for (const auto &entry : bindingMappings)
 		{
-			if (entry.second == binding)
+			if (entry.second.intersects(r))
 				return false;
 		}
 		return true;
 	}
 
-	std::map<std::string, uint32_t> bindingMappings;
+	std::map<std::string, Range> bindingMappings;
 
 };
 
@@ -641,7 +643,7 @@ void Shader::compileShaders()
 
 				localUniformStagingData.resize(defaultUniformBlockSize);
 				localUniformData.resize(defaultUniformBlockSize);
-				localUniformLocation = bindingMapper(comp, spirv, resource.name, resource.id);
+				localUniformLocation = bindingMapper(comp, spirv, resource.name, 1, resource.id);
 
 				memset(localUniformStagingData.data(), 0, defaultUniformBlockSize);
 				memset(localUniformData.data(), 0, defaultUniformBlockSize);
@@ -667,7 +669,7 @@ void Shader::compileShaders()
 
 			UniformInfo &u = *(uniformit->second);
 			u.active = true;
-			u.location = bindingMapper(comp, spirv, name, r.id);
+			u.location = bindingMapper(comp, spirv, name, u.count, r.id);
 
 			BuiltinUniform builtin;
 			if (getConstant(name.c_str(), builtin))
@@ -686,7 +688,7 @@ void Shader::compileShaders()
 
 			UniformInfo &u = uniformit->second;
 			u.active = true;
-			u.location = bindingMapper(comp, spirv, name, r.id);
+			u.location = bindingMapper(comp, spirv, name, u.count, r.id);
 		}
 
 		for (const auto &r : shaderResources.storage_images)
@@ -701,7 +703,7 @@ void Shader::compileShaders()
 
 			UniformInfo &u = uniformit->second;
 			u.active = true;
-			u.location = bindingMapper(comp, spirv, name, r.id);
+			u.location = bindingMapper(comp, spirv, name, u.count, r.id);
 		}
 
 		if (shaderStage == SHADERSTAGE_VERTEX)
@@ -771,7 +773,7 @@ void Shader::compileShaders()
 
 	for (const auto kvp : reflection.allUniforms)
 	{
-		if (kvp.second->location < 0)
+		if (!kvp.second->active)
 			continue;
 
 		switch (kvp.second->baseType)