Browse Source

vulkan: modify descriptor set allocation
Setting the size of each descriptor pool to one
was a hack introduced to make the code work on android.
Changing the code to now allocate all descriptor sets at once
should fix the previous crash.
Not tested yet.

niki 2 years ago
parent
commit
9025631231
2 changed files with 30 additions and 22 deletions
  1. 28 21
      src/modules/graphics/vulkan/Shader.cpp
  2. 2 1
      src/modules/graphics/vulkan/Shader.h

+ 28 - 21
src/modules/graphics/vulkan/Shader.cpp

@@ -118,7 +118,7 @@ static const TBuiltInResource defaultTBuiltInResource = {
 };
 };
 
 
 static const uint32_t STREAMBUFFER_DEFAULT_SIZE = 16;
 static const uint32_t STREAMBUFFER_DEFAULT_SIZE = 16;
-static const uint32_t DESCRIPTOR_POOL_SIZE = 1;
+static const uint32_t DESCRIPTOR_POOL_SIZE = 16;
 
 
 static VkShaderStageFlagBits getStageBit(ShaderStageType type) {
 static VkShaderStageFlagBits getStageBit(ShaderStageType type) {
 	switch (type) {
 	switch (type) {
@@ -174,7 +174,6 @@ bool Shader::loadVolatile() {
 	currentFrame = 0;
 	currentFrame = 0;
 	currentUsedUniformStreamBuffersCount = 0;
 	currentUsedUniformStreamBuffersCount = 0;
 	currentUsedDescriptorSetsCount = 0;
 	currentUsedDescriptorSetsCount = 0;
-	currentAllocatedDescriptorSets = DESCRIPTOR_POOL_SIZE;
 
 
 	return true;
 	return true;
 }
 }
@@ -197,11 +196,14 @@ void Shader::unloadVolatile() {
 		if (computePipeline != VK_NULL_HANDLE)
 		if (computePipeline != VK_NULL_HANDLE)
 			vkDestroyPipeline(device, computePipeline, nullptr);
 			vkDestroyPipeline(device, computePipeline, nullptr);
 	});
 	});
-	for (const auto &streamBufferVector : streamBuffers) {
-		for (const auto streamBuffer : streamBufferVector) {
+
+	while (!freeDescriptorSets.empty())
+		freeDescriptorSets.pop();
+
+	for (const auto &streamBufferVector : streamBuffers)
+		for (const auto streamBuffer : streamBufferVector)
 			delete streamBuffer;
 			delete streamBuffer;
-		}
-	}
+
 	shaderModules.clear();
 	shaderModules.clear();
 	shaderStages.clear();
 	shaderStages.clear();
 	streamBuffers.clear();
 	streamBuffers.clear();
@@ -877,7 +879,7 @@ void Shader::setMainTex(graphics::Texture* texture) {
 }
 }
 
 
 VkDescriptorSet Shader::allocateDescriptorSet() {
 VkDescriptorSet Shader::allocateDescriptorSet() {
-	if (currentAllocatedDescriptorSets >= DESCRIPTOR_POOL_SIZE) {
+	if (freeDescriptorSets.empty()) {
 		// fixme: we can optimize this, since sizes should never change for a given shader.
 		// fixme: we can optimize this, since sizes should never change for a given shader.
 		std::vector<VkDescriptorPoolSize> sizes;
 		std::vector<VkDescriptorPoolSize> sizes;
 
 
@@ -910,24 +912,29 @@ VkDescriptorSet Shader::allocateDescriptorSet() {
 		}
 		}
 		descriptorPools.push_back(pool);
 		descriptorPools.push_back(pool);
 
 
-		currentAllocatedDescriptorSets = 0;
-	}
+		std::vector<VkDescriptorSetLayout> layouts(DESCRIPTOR_POOL_SIZE, descriptorSetLayout);
 
 
-	VkDescriptorSetAllocateInfo allocInfo{};
-	allocInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
-	allocInfo.descriptorPool = descriptorPools.back();
-	allocInfo.descriptorSetCount = 1;
-	allocInfo.pSetLayouts = &descriptorSetLayout;
+		VkDescriptorSetAllocateInfo allocInfo{};
+		allocInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
+		allocInfo.descriptorPool = descriptorPools.back();
+		allocInfo.descriptorSetCount = DESCRIPTOR_POOL_SIZE;
+		allocInfo.pSetLayouts = layouts.data();
 
 
-	VkDescriptorSet descriptorSet;
-	VkResult result = vkAllocateDescriptorSets(device, &allocInfo, &descriptorSet);
-	if (result != VK_SUCCESS) {
-		throw love::Exception("failed to allocate descriptor set");
-	}
+		std::vector<VkDescriptorSet> descriptorSet;
+		descriptorSet.resize(DESCRIPTOR_POOL_SIZE);
+		VkResult result = vkAllocateDescriptorSets(device, &allocInfo, descriptorSet.data());
+		if (result != VK_SUCCESS) {
+			throw love::Exception("failed to allocate descriptor set");
+		}
 
 
-	currentAllocatedDescriptorSets++;
+		for (const auto ds : descriptorSet) {
+			freeDescriptorSets.push(ds);
+		}
+	}
 
 
-	return descriptorSet;
+	auto ds = freeDescriptorSets.front();
+	freeDescriptorSets.pop();
+	return ds;
 }
 }
 } // vulkan
 } // vulkan
 } // graphics
 } // graphics

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

@@ -12,6 +12,7 @@
 #include <memory>
 #include <memory>
 #include <iostream>
 #include <iostream>
 #include <unordered_map>
 #include <unordered_map>
+#include <queue>
 
 
 
 
 namespace love {
 namespace love {
@@ -88,7 +89,7 @@ private:
 	// that gets dynamically increased if more memory is needed
 	// that gets dynamically increased if more memory is needed
 	std::vector<std::vector<StreamBuffer*>> streamBuffers;
 	std::vector<std::vector<StreamBuffer*>> streamBuffers;
 	std::vector<VkDescriptorPool> descriptorPools;
 	std::vector<VkDescriptorPool> descriptorPools;
-	uint32_t currentAllocatedDescriptorSets;
+	std::queue<VkDescriptorSet> freeDescriptorSets;
 	std::vector<std::vector<VkDescriptorSet>> descriptorSetsVector;
 	std::vector<std::vector<VkDescriptorSet>> descriptorSetsVector;
 
 
 	std::vector<VkPipelineShaderStageCreateInfo> shaderStages;
 	std::vector<VkPipelineShaderStageCreateInfo> shaderStages;