rework uniform buffer implementation as a ring buffer
							parent
							
								
									4ed50a96c9
								
							
						
					
					
						commit
						a3d69ace21
					
				| 
						 | 
				
			
			@ -715,16 +715,6 @@ struct VulkanBuffer
 | 
			
		|||
	VulkanBufferContainer *container;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
typedef struct VulkanUniformBufferPool VulkanUniformBufferPool;
 | 
			
		||||
 | 
			
		||||
typedef struct VulkanUniformBuffer
 | 
			
		||||
{
 | 
			
		||||
	VulkanUniformBufferPool *pool;
 | 
			
		||||
	VkDeviceSize poolOffset; /* memory offset relative to the pool buffer */
 | 
			
		||||
	VkDeviceSize offset; /* based on uniform pushes */
 | 
			
		||||
	VkDescriptorSet descriptorSet;
 | 
			
		||||
} VulkanUniformBuffer;
 | 
			
		||||
 | 
			
		||||
typedef enum VulkanUniformBufferType
 | 
			
		||||
{
 | 
			
		||||
	UNIFORM_BUFFER_VERTEX,
 | 
			
		||||
| 
						 | 
				
			
			@ -747,20 +737,16 @@ typedef struct VulkanUniformDescriptorPool
 | 
			
		|||
	uint32_t availableDescriptorSetCount;
 | 
			
		||||
} VulkanUniformDescriptorPool;
 | 
			
		||||
 | 
			
		||||
/* This is actually just one buffer that we carve slices out of. */
 | 
			
		||||
struct VulkanUniformBufferPool
 | 
			
		||||
/* Uniform buffers are just one buffer that we carve slices out of. */
 | 
			
		||||
typedef struct VulkanUniformBufferObject
 | 
			
		||||
{
 | 
			
		||||
	VulkanUniformBufferType type;
 | 
			
		||||
	VulkanUniformDescriptorPool descriptorPool;
 | 
			
		||||
	VkDescriptorSet descriptorSet;
 | 
			
		||||
	VulkanBuffer *buffer;
 | 
			
		||||
	VkDeviceSize nextAvailableOffset;
 | 
			
		||||
	SDL_mutex *lock;
 | 
			
		||||
	uint32_t currentOffset;
 | 
			
		||||
	uint8_t *mapPointer; /* uniform buffers are permanently mapped */
 | 
			
		||||
 | 
			
		||||
	VulkanUniformBuffer **availableBuffers;
 | 
			
		||||
	uint32_t availableBufferCount;
 | 
			
		||||
	uint32_t availableBufferCapacity;
 | 
			
		||||
};
 | 
			
		||||
	SDL_mutex *lock;
 | 
			
		||||
} VulkanUniformBufferObject;
 | 
			
		||||
 | 
			
		||||
/* Renderer Structure */
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1557,19 +1543,11 @@ typedef struct VulkanCommandBuffer
 | 
			
		|||
	uint32_t renderPassColorTargetCount;
 | 
			
		||||
	VulkanTexture *renderPassDepthTexture; /* can be NULL */
 | 
			
		||||
 | 
			
		||||
	VulkanUniformBuffer *vertexUniformBuffer;
 | 
			
		||||
	VulkanUniformBuffer *fragmentUniformBuffer;
 | 
			
		||||
	VulkanUniformBuffer *computeUniformBuffer;
 | 
			
		||||
 | 
			
		||||
	VkDescriptorSet vertexSamplerDescriptorSet; /* updated by BindVertexSamplers */
 | 
			
		||||
	VkDescriptorSet fragmentSamplerDescriptorSet; /* updated by BindFragmentSamplers */
 | 
			
		||||
	VkDescriptorSet bufferDescriptorSet; /* updated by BindComputeBuffers */
 | 
			
		||||
	VkDescriptorSet imageDescriptorSet; /* updated by BindComputeTextures */
 | 
			
		||||
 | 
			
		||||
	VulkanUniformBuffer **boundUniformBuffers;
 | 
			
		||||
	uint32_t boundUniformBufferCount;
 | 
			
		||||
	uint32_t boundUniformBufferCapacity;
 | 
			
		||||
 | 
			
		||||
	DescriptorSetData *boundDescriptorSetDatas;
 | 
			
		||||
	uint32_t boundDescriptorSetDataCount;
 | 
			
		||||
	uint32_t boundDescriptorSetDataCapacity;
 | 
			
		||||
| 
						 | 
				
			
			@ -1763,19 +1741,14 @@ typedef struct VulkanRenderer
 | 
			
		|||
	VkDescriptorSet emptyComputeBufferDescriptorSet;
 | 
			
		||||
	VkDescriptorSet emptyComputeImageDescriptorSet;
 | 
			
		||||
 | 
			
		||||
	VulkanUniformBufferPool *vertexUniformBufferPool;
 | 
			
		||||
	VulkanUniformBufferPool *fragmentUniformBufferPool;
 | 
			
		||||
	VulkanUniformBufferPool *computeUniformBufferPool;
 | 
			
		||||
	VulkanUniformBufferObject *vertexUniformBufferObject;
 | 
			
		||||
	VulkanUniformBufferObject *fragmentUniformBufferObject;
 | 
			
		||||
	VulkanUniformBufferObject *computeUniformBufferObject;
 | 
			
		||||
 | 
			
		||||
	VkDescriptorSetLayout vertexUniformDescriptorSetLayout;
 | 
			
		||||
	VkDescriptorSetLayout fragmentUniformDescriptorSetLayout;
 | 
			
		||||
	VkDescriptorSetLayout computeUniformDescriptorSetLayout;
 | 
			
		||||
 | 
			
		||||
	VulkanBuffer *dummyBuffer;
 | 
			
		||||
	VulkanUniformBuffer *dummyVertexUniformBuffer;
 | 
			
		||||
	VulkanUniformBuffer *dummyFragmentUniformBuffer;
 | 
			
		||||
	VulkanUniformBuffer *dummyComputeUniformBuffer;
 | 
			
		||||
 | 
			
		||||
	VkDeviceSize minUBOAlignment;
 | 
			
		||||
 | 
			
		||||
	/* Some drivers don't support D16 for some reason. Fun! */
 | 
			
		||||
| 
						 | 
				
			
			@ -3612,7 +3585,6 @@ static void VULKAN_INTERNAL_DestroyCommandPool(
 | 
			
		|||
		SDL_free(commandBuffer->presentDatas);
 | 
			
		||||
		SDL_free(commandBuffer->waitSemaphores);
 | 
			
		||||
		SDL_free(commandBuffer->signalSemaphores);
 | 
			
		||||
		SDL_free(commandBuffer->boundUniformBuffers);
 | 
			
		||||
		SDL_free(commandBuffer->boundDescriptorSetDatas);
 | 
			
		||||
		SDL_free(commandBuffer->boundComputeBuffers);
 | 
			
		||||
		SDL_free(commandBuffer->boundComputeTextures);
 | 
			
		||||
| 
						 | 
				
			
			@ -4213,24 +4185,30 @@ static uint8_t VULKAN_INTERNAL_AddUniformDescriptorPool(
 | 
			
		|||
	return 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static VulkanUniformBufferPool* VULKAN_INTERNAL_CreateUniformBufferPool(
 | 
			
		||||
static VulkanUniformBufferObject* VULKAN_INTERNAL_CreateUniformBufferObject(
 | 
			
		||||
	VulkanRenderer *renderer,
 | 
			
		||||
	VulkanUniformBufferType uniformBufferType
 | 
			
		||||
) {
 | 
			
		||||
	VulkanUniformBufferPool* uniformBufferPool = SDL_malloc(sizeof(VulkanUniformBufferPool));
 | 
			
		||||
	VulkanUniformBufferObject* uniformBufferObject = SDL_malloc(sizeof(VulkanUniformBufferObject));
 | 
			
		||||
	VulkanResourceAccessType resourceAccessType;
 | 
			
		||||
	VkDescriptorSetLayout descriptorSetLayout;
 | 
			
		||||
	VkWriteDescriptorSet writeDescriptorSet;
 | 
			
		||||
	VkDescriptorBufferInfo descriptorBufferInfo;
 | 
			
		||||
 | 
			
		||||
	if (uniformBufferType == UNIFORM_BUFFER_VERTEX)
 | 
			
		||||
	{
 | 
			
		||||
		resourceAccessType = RESOURCE_ACCESS_VERTEX_SHADER_READ_UNIFORM_BUFFER;
 | 
			
		||||
		descriptorSetLayout = renderer->vertexUniformDescriptorSetLayout;
 | 
			
		||||
	}
 | 
			
		||||
	else if (uniformBufferType == UNIFORM_BUFFER_FRAGMENT)
 | 
			
		||||
	{
 | 
			
		||||
		resourceAccessType = RESOURCE_ACCESS_FRAGMENT_SHADER_READ_UNIFORM_BUFFER;
 | 
			
		||||
		descriptorSetLayout = renderer->fragmentUniformDescriptorSetLayout;
 | 
			
		||||
	}
 | 
			
		||||
	else if (uniformBufferType == UNIFORM_BUFFER_COMPUTE)
 | 
			
		||||
	{
 | 
			
		||||
		resourceAccessType = RESOURCE_ACCESS_COMPUTE_SHADER_READ_UNIFORM_BUFFER;
 | 
			
		||||
		descriptorSetLayout = renderer->computeUniformDescriptorSetLayout;
 | 
			
		||||
	}
 | 
			
		||||
	else
 | 
			
		||||
	{
 | 
			
		||||
| 
						 | 
				
			
			@ -4238,59 +4216,66 @@ static VulkanUniformBufferPool* VULKAN_INTERNAL_CreateUniformBufferPool(
 | 
			
		|||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	uniformBufferPool->buffer = VULKAN_INTERNAL_CreateBuffer(
 | 
			
		||||
	/* Allocate backing buffer */
 | 
			
		||||
	uniformBufferObject->buffer = VULKAN_INTERNAL_CreateBuffer(
 | 
			
		||||
		renderer,
 | 
			
		||||
		UBO_BUFFER_SIZE,
 | 
			
		||||
		resourceAccessType,
 | 
			
		||||
		VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT,
 | 
			
		||||
		1,
 | 
			
		||||
		0,
 | 
			
		||||
		1,
 | 
			
		||||
		1
 | 
			
		||||
	);
 | 
			
		||||
 | 
			
		||||
	uniformBufferPool->nextAvailableOffset = 0;
 | 
			
		||||
	uniformBufferObject->lock = SDL_CreateMutex();
 | 
			
		||||
 | 
			
		||||
	uniformBufferPool->type = uniformBufferType;
 | 
			
		||||
	uniformBufferPool->lock = SDL_CreateMutex();
 | 
			
		||||
	uniformBufferObject->currentOffset = 0;
 | 
			
		||||
	uniformBufferObject->type = uniformBufferType;
 | 
			
		||||
 | 
			
		||||
	uniformBufferPool->availableBufferCapacity = 16;
 | 
			
		||||
	uniformBufferPool->availableBufferCount = 0;
 | 
			
		||||
	uniformBufferPool->availableBuffers = SDL_malloc(uniformBufferPool->availableBufferCapacity * sizeof(VulkanUniformBuffer*));
 | 
			
		||||
	/* Allocate a descriptor set for the uniform buffer */
 | 
			
		||||
	VULKAN_INTERNAL_AllocateDescriptorSets(
 | 
			
		||||
		renderer,
 | 
			
		||||
		renderer->defaultDescriptorPool,
 | 
			
		||||
		descriptorSetLayout,
 | 
			
		||||
		1,
 | 
			
		||||
		&uniformBufferObject->descriptorSet
 | 
			
		||||
	);
 | 
			
		||||
 | 
			
		||||
	uniformBufferPool->descriptorPool.availableDescriptorSetCount = 0;
 | 
			
		||||
	uniformBufferPool->descriptorPool.descriptorPoolCount = 0;
 | 
			
		||||
	uniformBufferPool->descriptorPool.descriptorPools = NULL;
 | 
			
		||||
	/* Update the descriptor set for the first and last time! */
 | 
			
		||||
	descriptorBufferInfo.buffer = uniformBufferObject->buffer->buffer;
 | 
			
		||||
	descriptorBufferInfo.offset = 0;
 | 
			
		||||
	descriptorBufferInfo.range = VK_WHOLE_SIZE;
 | 
			
		||||
 | 
			
		||||
	writeDescriptorSet.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
 | 
			
		||||
	writeDescriptorSet.pNext = NULL;
 | 
			
		||||
	writeDescriptorSet.descriptorCount = 1;
 | 
			
		||||
	writeDescriptorSet.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC;
 | 
			
		||||
	writeDescriptorSet.dstArrayElement = 0;
 | 
			
		||||
	writeDescriptorSet.dstBinding = 0;
 | 
			
		||||
	writeDescriptorSet.dstSet = uniformBufferObject->descriptorSet;
 | 
			
		||||
	writeDescriptorSet.pBufferInfo = &descriptorBufferInfo;
 | 
			
		||||
	writeDescriptorSet.pImageInfo = NULL;
 | 
			
		||||
	writeDescriptorSet.pTexelBufferView = NULL;
 | 
			
		||||
 | 
			
		||||
	renderer->vkUpdateDescriptorSets(
 | 
			
		||||
		renderer->logicalDevice,
 | 
			
		||||
		1,
 | 
			
		||||
		&writeDescriptorSet,
 | 
			
		||||
		0,
 | 
			
		||||
		NULL
 | 
			
		||||
	);
 | 
			
		||||
 | 
			
		||||
	/* Permanently map the memory */
 | 
			
		||||
	renderer->vkMapMemory(
 | 
			
		||||
		renderer->logicalDevice,
 | 
			
		||||
		uniformBufferPool->buffer->usedRegion->allocation->memory,
 | 
			
		||||
		uniformBufferObject->buffer->usedRegion->allocation->memory,
 | 
			
		||||
		0,
 | 
			
		||||
		VK_WHOLE_SIZE,
 | 
			
		||||
		0,
 | 
			
		||||
		(void**) &uniformBufferPool->mapPointer
 | 
			
		||||
		(void**) &uniformBufferObject->mapPointer
 | 
			
		||||
	);
 | 
			
		||||
 | 
			
		||||
	VULKAN_INTERNAL_AddUniformDescriptorPool(renderer, &uniformBufferPool->descriptorPool);
 | 
			
		||||
 | 
			
		||||
	return uniformBufferPool;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void VULKAN_INTERNAL_BindUniformBuffer(
 | 
			
		||||
	VulkanRenderer *renderer,
 | 
			
		||||
	VulkanCommandBuffer *commandBuffer,
 | 
			
		||||
	VulkanUniformBuffer *uniformBuffer
 | 
			
		||||
) {
 | 
			
		||||
	if (commandBuffer->boundUniformBufferCount >= commandBuffer->boundUniformBufferCapacity)
 | 
			
		||||
	{
 | 
			
		||||
		commandBuffer->boundUniformBufferCapacity *= 2;
 | 
			
		||||
		commandBuffer->boundUniformBuffers = SDL_realloc(
 | 
			
		||||
			commandBuffer->boundUniformBuffers,
 | 
			
		||||
			sizeof(VulkanUniformBuffer*) * commandBuffer->boundUniformBufferCapacity
 | 
			
		||||
		);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	commandBuffer->boundUniformBuffers[commandBuffer->boundUniformBufferCount] = uniformBuffer;
 | 
			
		||||
	commandBuffer->boundUniformBufferCount += 1;
 | 
			
		||||
	return uniformBufferObject;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Buffer indirection so we can cleanly defrag */
 | 
			
		||||
| 
						 | 
				
			
			@ -4329,244 +4314,19 @@ static VulkanBufferContainer* VULKAN_INTERNAL_CreateBufferContainer(
 | 
			
		|||
	return (VulkanBufferContainer*) bufferContainer;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static uint8_t VULKAN_INTERNAL_CreateUniformBuffer(
 | 
			
		||||
static void VULKAN_INTERNAL_DestroyUniformBufferObject(
 | 
			
		||||
	VulkanRenderer *renderer,
 | 
			
		||||
	VulkanUniformBufferPool *bufferPool
 | 
			
		||||
	VulkanUniformBufferObject *uniformBufferObject
 | 
			
		||||
) {
 | 
			
		||||
	VkDescriptorSetLayout descriptorSetLayout;
 | 
			
		||||
 | 
			
		||||
	if (bufferPool->type == UNIFORM_BUFFER_VERTEX)
 | 
			
		||||
	{
 | 
			
		||||
		descriptorSetLayout = renderer->vertexUniformDescriptorSetLayout;
 | 
			
		||||
	}
 | 
			
		||||
	else if (bufferPool->type == UNIFORM_BUFFER_FRAGMENT)
 | 
			
		||||
	{
 | 
			
		||||
		descriptorSetLayout = renderer->fragmentUniformDescriptorSetLayout;
 | 
			
		||||
	}
 | 
			
		||||
	else if (bufferPool->type == UNIFORM_BUFFER_COMPUTE)
 | 
			
		||||
	{
 | 
			
		||||
		descriptorSetLayout = renderer->computeUniformDescriptorSetLayout;
 | 
			
		||||
	}
 | 
			
		||||
	else
 | 
			
		||||
	{
 | 
			
		||||
		Refresh_LogError("Unrecognized uniform buffer type!");
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	VulkanUniformBuffer *uniformBuffer = SDL_malloc(sizeof(VulkanUniformBuffer));
 | 
			
		||||
	uniformBuffer->pool = bufferPool;
 | 
			
		||||
	uniformBuffer->poolOffset = bufferPool->nextAvailableOffset;
 | 
			
		||||
	uniformBuffer->offset = 0;
 | 
			
		||||
 | 
			
		||||
	bufferPool->nextAvailableOffset += VULKAN_INTERNAL_NextHighestAlignment(UBO_SECTION_SIZE, renderer->minUBOAlignment);
 | 
			
		||||
 | 
			
		||||
	if (bufferPool->nextAvailableOffset >= UBO_BUFFER_SIZE)
 | 
			
		||||
	{
 | 
			
		||||
		Refresh_LogError("Uniform buffer overflow!");
 | 
			
		||||
		SDL_free(uniformBuffer);
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* Allocate a descriptor set for the uniform buffer */
 | 
			
		||||
 | 
			
		||||
	if (bufferPool->descriptorPool.availableDescriptorSetCount == 0)
 | 
			
		||||
	{
 | 
			
		||||
		if (!VULKAN_INTERNAL_AddUniformDescriptorPool(
 | 
			
		||||
			renderer,
 | 
			
		||||
			&bufferPool->descriptorPool
 | 
			
		||||
		)) {
 | 
			
		||||
			Refresh_LogError("Failed to add uniform descriptor pool!");
 | 
			
		||||
			SDL_free(uniformBuffer);
 | 
			
		||||
			return 0;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (!VULKAN_INTERNAL_AllocateDescriptorSets(
 | 
			
		||||
		renderer,
 | 
			
		||||
		bufferPool->descriptorPool.descriptorPools[bufferPool->descriptorPool.descriptorPoolCount - 1],
 | 
			
		||||
		descriptorSetLayout,
 | 
			
		||||
		1,
 | 
			
		||||
		&uniformBuffer->descriptorSet
 | 
			
		||||
	)) {
 | 
			
		||||
		Refresh_LogError("Failed to allocate uniform descriptor set!");
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	bufferPool->descriptorPool.availableDescriptorSetCount -= 1;
 | 
			
		||||
 | 
			
		||||
	if (bufferPool->availableBufferCount >= bufferPool->availableBufferCapacity)
 | 
			
		||||
	{
 | 
			
		||||
		bufferPool->availableBufferCapacity *= 2;
 | 
			
		||||
 | 
			
		||||
		bufferPool->availableBuffers = SDL_realloc(
 | 
			
		||||
			bufferPool->availableBuffers,
 | 
			
		||||
			sizeof(VulkanUniformBuffer*) * bufferPool->availableBufferCapacity
 | 
			
		||||
		);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	bufferPool->availableBuffers[bufferPool->availableBufferCount] = uniformBuffer;
 | 
			
		||||
	bufferPool->availableBufferCount += 1;
 | 
			
		||||
 | 
			
		||||
	return 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static VulkanUniformBuffer* VULKAN_INTERNAL_CreateDummyUniformBuffer(
 | 
			
		||||
	VulkanRenderer *renderer,
 | 
			
		||||
	VulkanUniformBufferType uniformBufferType
 | 
			
		||||
) {
 | 
			
		||||
	VkDescriptorSetLayout descriptorSetLayout;
 | 
			
		||||
	VkWriteDescriptorSet writeDescriptorSet;
 | 
			
		||||
	VkDescriptorBufferInfo descriptorBufferInfo;
 | 
			
		||||
 | 
			
		||||
	if (uniformBufferType == UNIFORM_BUFFER_VERTEX)
 | 
			
		||||
	{
 | 
			
		||||
		descriptorSetLayout = renderer->vertexUniformDescriptorSetLayout;
 | 
			
		||||
	}
 | 
			
		||||
	else if (uniformBufferType == UNIFORM_BUFFER_FRAGMENT)
 | 
			
		||||
	{
 | 
			
		||||
		descriptorSetLayout = renderer->fragmentUniformDescriptorSetLayout;
 | 
			
		||||
	}
 | 
			
		||||
	else if (uniformBufferType == UNIFORM_BUFFER_COMPUTE)
 | 
			
		||||
	{
 | 
			
		||||
		descriptorSetLayout = renderer->computeUniformDescriptorSetLayout;
 | 
			
		||||
	}
 | 
			
		||||
	else
 | 
			
		||||
	{
 | 
			
		||||
		Refresh_LogError("Unrecognized uniform buffer type!");
 | 
			
		||||
		return NULL;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	VulkanUniformBuffer *uniformBuffer = SDL_malloc(sizeof(VulkanUniformBuffer));
 | 
			
		||||
	uniformBuffer->poolOffset = 0;
 | 
			
		||||
	uniformBuffer->offset = 0;
 | 
			
		||||
 | 
			
		||||
	/* Allocate a descriptor set for the uniform buffer */
 | 
			
		||||
 | 
			
		||||
	VULKAN_INTERNAL_AllocateDescriptorSets(
 | 
			
		||||
		renderer,
 | 
			
		||||
		renderer->defaultDescriptorPool,
 | 
			
		||||
		descriptorSetLayout,
 | 
			
		||||
		1,
 | 
			
		||||
		&uniformBuffer->descriptorSet
 | 
			
		||||
	);
 | 
			
		||||
 | 
			
		||||
	/* Update the descriptor set for the first and last time! */
 | 
			
		||||
 | 
			
		||||
	descriptorBufferInfo.buffer = renderer->dummyBuffer->buffer;
 | 
			
		||||
	descriptorBufferInfo.offset = 0;
 | 
			
		||||
	descriptorBufferInfo.range = VK_WHOLE_SIZE;
 | 
			
		||||
 | 
			
		||||
	writeDescriptorSet.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
 | 
			
		||||
	writeDescriptorSet.pNext = NULL;
 | 
			
		||||
	writeDescriptorSet.descriptorCount = 1;
 | 
			
		||||
	writeDescriptorSet.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC;
 | 
			
		||||
	writeDescriptorSet.dstArrayElement = 0;
 | 
			
		||||
	writeDescriptorSet.dstBinding = 0;
 | 
			
		||||
	writeDescriptorSet.dstSet = uniformBuffer->descriptorSet;
 | 
			
		||||
	writeDescriptorSet.pBufferInfo = &descriptorBufferInfo;
 | 
			
		||||
	writeDescriptorSet.pImageInfo = NULL;
 | 
			
		||||
	writeDescriptorSet.pTexelBufferView = NULL;
 | 
			
		||||
 | 
			
		||||
	renderer->vkUpdateDescriptorSets(
 | 
			
		||||
		renderer->logicalDevice,
 | 
			
		||||
		1,
 | 
			
		||||
		&writeDescriptorSet,
 | 
			
		||||
		0,
 | 
			
		||||
		NULL
 | 
			
		||||
	);
 | 
			
		||||
 | 
			
		||||
	uniformBuffer->pool = NULL; /* No pool because this is a dummy */
 | 
			
		||||
 | 
			
		||||
	return uniformBuffer;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void VULKAN_INTERNAL_DestroyUniformBufferPool(
 | 
			
		||||
	VulkanRenderer *renderer,
 | 
			
		||||
	VulkanUniformBufferPool *uniformBufferPool
 | 
			
		||||
) {
 | 
			
		||||
	uint32_t i;
 | 
			
		||||
 | 
			
		||||
	for (i = 0; i < uniformBufferPool->descriptorPool.descriptorPoolCount; i += 1)
 | 
			
		||||
	{
 | 
			
		||||
		renderer->vkDestroyDescriptorPool(
 | 
			
		||||
			renderer->logicalDevice,
 | 
			
		||||
			uniformBufferPool->descriptorPool.descriptorPools[i],
 | 
			
		||||
			NULL
 | 
			
		||||
		);
 | 
			
		||||
	}
 | 
			
		||||
	SDL_free(uniformBufferPool->descriptorPool.descriptorPools);
 | 
			
		||||
 | 
			
		||||
	/* This is always destroyed after submissions, so all buffers are available */
 | 
			
		||||
	for (i = 0; i < uniformBufferPool->availableBufferCount; i += 1)
 | 
			
		||||
	{
 | 
			
		||||
		SDL_free(uniformBufferPool->availableBuffers[i]);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	renderer->vkUnmapMemory(
 | 
			
		||||
		renderer->logicalDevice,
 | 
			
		||||
		uniformBufferPool->buffer->usedRegion->allocation->memory
 | 
			
		||||
		uniformBufferObject->buffer->usedRegion->allocation->memory
 | 
			
		||||
	);
 | 
			
		||||
 | 
			
		||||
	VULKAN_INTERNAL_DestroyBuffer(renderer, uniformBufferPool->buffer);
 | 
			
		||||
	VULKAN_INTERNAL_DestroyBuffer(renderer, uniformBufferObject->buffer);
 | 
			
		||||
 | 
			
		||||
	SDL_DestroyMutex(uniformBufferPool->lock);
 | 
			
		||||
	SDL_free(uniformBufferPool->availableBuffers);
 | 
			
		||||
	SDL_free(uniformBufferPool);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static VulkanUniformBuffer* VULKAN_INTERNAL_AcquireUniformBufferFromPool(
 | 
			
		||||
	VulkanRenderer *renderer,
 | 
			
		||||
	VulkanUniformBufferPool *bufferPool,
 | 
			
		||||
	VkDeviceSize blockSize
 | 
			
		||||
) {
 | 
			
		||||
	VkWriteDescriptorSet writeDescriptorSet;
 | 
			
		||||
	VkDescriptorBufferInfo descriptorBufferInfo;
 | 
			
		||||
 | 
			
		||||
	SDL_LockMutex(bufferPool->lock);
 | 
			
		||||
 | 
			
		||||
	if (bufferPool->availableBufferCount == 0)
 | 
			
		||||
	{
 | 
			
		||||
		if (!VULKAN_INTERNAL_CreateUniformBuffer(renderer, bufferPool))
 | 
			
		||||
		{
 | 
			
		||||
			SDL_UnlockMutex(bufferPool->lock);
 | 
			
		||||
			Refresh_LogError("Failed to create uniform buffer!");
 | 
			
		||||
			return NULL;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	VulkanUniformBuffer *uniformBuffer = bufferPool->availableBuffers[bufferPool->availableBufferCount - 1];
 | 
			
		||||
	bufferPool->availableBufferCount -= 1;
 | 
			
		||||
 | 
			
		||||
	SDL_UnlockMutex(bufferPool->lock);
 | 
			
		||||
 | 
			
		||||
	uniformBuffer->offset = 0;
 | 
			
		||||
 | 
			
		||||
	/* Update the descriptor set with the correct range */
 | 
			
		||||
 | 
			
		||||
	descriptorBufferInfo.buffer = uniformBuffer->pool->buffer->buffer;
 | 
			
		||||
	descriptorBufferInfo.offset = uniformBuffer->poolOffset;
 | 
			
		||||
	descriptorBufferInfo.range = blockSize;
 | 
			
		||||
 | 
			
		||||
	writeDescriptorSet.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
 | 
			
		||||
	writeDescriptorSet.pNext = NULL;
 | 
			
		||||
	writeDescriptorSet.descriptorCount = 1;
 | 
			
		||||
	writeDescriptorSet.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC;
 | 
			
		||||
	writeDescriptorSet.dstArrayElement = 0;
 | 
			
		||||
	writeDescriptorSet.dstBinding = 0;
 | 
			
		||||
	writeDescriptorSet.dstSet = uniformBuffer->descriptorSet;
 | 
			
		||||
	writeDescriptorSet.pBufferInfo = &descriptorBufferInfo;
 | 
			
		||||
	writeDescriptorSet.pImageInfo = NULL;
 | 
			
		||||
	writeDescriptorSet.pTexelBufferView = NULL;
 | 
			
		||||
 | 
			
		||||
	renderer->vkUpdateDescriptorSets(
 | 
			
		||||
		renderer->logicalDevice,
 | 
			
		||||
		1,
 | 
			
		||||
		&writeDescriptorSet,
 | 
			
		||||
		0,
 | 
			
		||||
		NULL
 | 
			
		||||
	);
 | 
			
		||||
 | 
			
		||||
	return uniformBuffer;
 | 
			
		||||
	SDL_DestroyMutex(uniformBufferObject->lock);
 | 
			
		||||
	SDL_free(uniformBufferObject);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Swapchain */
 | 
			
		||||
| 
						 | 
				
			
			@ -5211,12 +4971,6 @@ static void VULKAN_DestroyDevice(
 | 
			
		|||
 | 
			
		||||
	SDL_free(renderer->submittedCommandBuffers);
 | 
			
		||||
 | 
			
		||||
	VULKAN_INTERNAL_DestroyBuffer(renderer, renderer->dummyBuffer);
 | 
			
		||||
 | 
			
		||||
	SDL_free(renderer->dummyVertexUniformBuffer);
 | 
			
		||||
	SDL_free(renderer->dummyFragmentUniformBuffer);
 | 
			
		||||
	SDL_free(renderer->dummyComputeUniformBuffer);
 | 
			
		||||
 | 
			
		||||
	for (i = 0; i < renderer->fencePool.availableFenceCount; i += 1)
 | 
			
		||||
	{
 | 
			
		||||
		renderer->vkDestroyFence(renderer->logicalDevice, renderer->fencePool.availableFences[i], NULL);
 | 
			
		||||
| 
						 | 
				
			
			@ -5361,9 +5115,9 @@ static void VULKAN_DestroyDevice(
 | 
			
		|||
		NULL
 | 
			
		||||
	);
 | 
			
		||||
 | 
			
		||||
	VULKAN_INTERNAL_DestroyUniformBufferPool(renderer, renderer->vertexUniformBufferPool);
 | 
			
		||||
	VULKAN_INTERNAL_DestroyUniformBufferPool(renderer, renderer->fragmentUniformBufferPool);
 | 
			
		||||
	VULKAN_INTERNAL_DestroyUniformBufferPool(renderer, renderer->computeUniformBufferPool);
 | 
			
		||||
	VULKAN_INTERNAL_DestroyUniformBufferObject(renderer, renderer->vertexUniformBufferObject);
 | 
			
		||||
	VULKAN_INTERNAL_DestroyUniformBufferObject(renderer, renderer->fragmentUniformBufferObject);
 | 
			
		||||
	VULKAN_INTERNAL_DestroyUniformBufferObject(renderer, renderer->computeUniformBufferObject);
 | 
			
		||||
 | 
			
		||||
	for (i = 0; i < renderer->framebufferHashArray.count; i += 1)
 | 
			
		||||
	{
 | 
			
		||||
| 
						 | 
				
			
			@ -5460,8 +5214,8 @@ static void VULKAN_DrawInstancedPrimitives(
 | 
			
		|||
 | 
			
		||||
	descriptorSets[0] = vulkanCommandBuffer->vertexSamplerDescriptorSet;
 | 
			
		||||
	descriptorSets[1] = vulkanCommandBuffer->fragmentSamplerDescriptorSet;
 | 
			
		||||
	descriptorSets[2] = vulkanCommandBuffer->vertexUniformBuffer->descriptorSet;
 | 
			
		||||
	descriptorSets[3] = vulkanCommandBuffer->fragmentUniformBuffer->descriptorSet;
 | 
			
		||||
	descriptorSets[2] = renderer->vertexUniformBufferObject->descriptorSet;
 | 
			
		||||
	descriptorSets[3] = renderer->fragmentUniformBufferObject->descriptorSet;
 | 
			
		||||
 | 
			
		||||
	dynamicOffsets[0] = vertexParamOffset;
 | 
			
		||||
	dynamicOffsets[1] = fragmentParamOffset;
 | 
			
		||||
| 
						 | 
				
			
			@ -5527,8 +5281,8 @@ static void VULKAN_DrawPrimitives(
 | 
			
		|||
 | 
			
		||||
	descriptorSets[0] = vulkanCommandBuffer->vertexSamplerDescriptorSet;
 | 
			
		||||
	descriptorSets[1] = vulkanCommandBuffer->fragmentSamplerDescriptorSet;
 | 
			
		||||
	descriptorSets[2] = vulkanCommandBuffer->vertexUniformBuffer->descriptorSet;
 | 
			
		||||
	descriptorSets[3] = vulkanCommandBuffer->fragmentUniformBuffer->descriptorSet;
 | 
			
		||||
	descriptorSets[2] = renderer->vertexUniformBufferObject->descriptorSet;
 | 
			
		||||
	descriptorSets[3] = renderer->fragmentUniformBufferObject->descriptorSet;
 | 
			
		||||
 | 
			
		||||
	dynamicOffsets[0] = vertexParamOffset;
 | 
			
		||||
	dynamicOffsets[1] = fragmentParamOffset;
 | 
			
		||||
| 
						 | 
				
			
			@ -5574,8 +5328,8 @@ static void VULKAN_DrawPrimitivesIndirect(
 | 
			
		|||
 | 
			
		||||
	descriptorSets[0] = vulkanCommandBuffer->vertexSamplerDescriptorSet;
 | 
			
		||||
	descriptorSets[1] = vulkanCommandBuffer->fragmentSamplerDescriptorSet;
 | 
			
		||||
	descriptorSets[2] = vulkanCommandBuffer->vertexUniformBuffer->descriptorSet;
 | 
			
		||||
	descriptorSets[3] = vulkanCommandBuffer->fragmentUniformBuffer->descriptorSet;
 | 
			
		||||
	descriptorSets[2] = renderer->vertexUniformBufferObject->descriptorSet;
 | 
			
		||||
	descriptorSets[3] = renderer->fragmentUniformBufferObject->descriptorSet;
 | 
			
		||||
 | 
			
		||||
	dynamicOffsets[0] = vertexParamOffset;
 | 
			
		||||
	dynamicOffsets[1] = fragmentParamOffset;
 | 
			
		||||
| 
						 | 
				
			
			@ -7057,15 +6811,14 @@ static Refresh_CpuBuffer* VULKAN_CreateCpuBuffer(
 | 
			
		|||
/* Setters */
 | 
			
		||||
 | 
			
		||||
static void VULKAN_INTERNAL_SetUniformBufferData(
 | 
			
		||||
	VulkanUniformBuffer *uniformBuffer,
 | 
			
		||||
	VulkanUniformBufferObject *uniformBufferObject,
 | 
			
		||||
	void* data,
 | 
			
		||||
	uint32_t dataLength
 | 
			
		||||
) {
 | 
			
		||||
	uint8_t *dst =
 | 
			
		||||
		uniformBuffer->pool->mapPointer +
 | 
			
		||||
		uniformBuffer->pool->buffer->usedRegion->resourceOffset +
 | 
			
		||||
		uniformBuffer->poolOffset +
 | 
			
		||||
		uniformBuffer->offset;
 | 
			
		||||
		uniformBufferObject->mapPointer +
 | 
			
		||||
		uniformBufferObject->buffer->usedRegion->resourceOffset +
 | 
			
		||||
		uniformBufferObject->currentOffset;
 | 
			
		||||
 | 
			
		||||
	SDL_memcpy(
 | 
			
		||||
		dst,
 | 
			
		||||
| 
						 | 
				
			
			@ -7085,45 +6838,30 @@ static uint32_t VULKAN_PushVertexShaderUniforms(
 | 
			
		|||
	VulkanGraphicsPipeline* graphicsPipeline = vulkanCommandBuffer->currentGraphicsPipeline;
 | 
			
		||||
	uint32_t offset;
 | 
			
		||||
 | 
			
		||||
	if (graphicsPipeline == NULL)
 | 
			
		||||
	{
 | 
			
		||||
		Refresh_LogError("Cannot push uniforms if a pipeline is not bound!");
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (graphicsPipeline->vertexUniformBlockSize == 0)
 | 
			
		||||
	{
 | 
			
		||||
		Refresh_LogError("Bound pipeline's vertex stage does not declare uniforms!");
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (
 | 
			
		||||
		vulkanCommandBuffer->vertexUniformBuffer->offset +
 | 
			
		||||
		graphicsPipeline->vertexUniformBlockSize >=
 | 
			
		||||
		UBO_SECTION_SIZE
 | 
			
		||||
	) {
 | 
			
		||||
		/* We're out of space in this buffer, bind the old one and acquire a new one */
 | 
			
		||||
		VULKAN_INTERNAL_BindUniformBuffer(
 | 
			
		||||
			renderer,
 | 
			
		||||
			vulkanCommandBuffer,
 | 
			
		||||
			vulkanCommandBuffer->vertexUniformBuffer
 | 
			
		||||
		);
 | 
			
		||||
		vulkanCommandBuffer->vertexUniformBuffer = VULKAN_INTERNAL_AcquireUniformBufferFromPool(
 | 
			
		||||
			renderer,
 | 
			
		||||
			renderer->vertexUniformBufferPool,
 | 
			
		||||
			graphicsPipeline->vertexUniformBlockSize
 | 
			
		||||
		);
 | 
			
		||||
	SDL_LockMutex(renderer->vertexUniformBufferObject->lock);
 | 
			
		||||
 | 
			
		||||
	if (renderer->vertexUniformBufferObject->currentOffset + dataLengthInBytes >= UBO_BUFFER_SIZE)
 | 
			
		||||
	{
 | 
			
		||||
		renderer->vertexUniformBufferObject->currentOffset = 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	offset = vulkanCommandBuffer->vertexUniformBuffer->offset;
 | 
			
		||||
	offset = renderer->vertexUniformBufferObject->currentOffset;
 | 
			
		||||
 | 
			
		||||
	VULKAN_INTERNAL_SetUniformBufferData(
 | 
			
		||||
		vulkanCommandBuffer->vertexUniformBuffer,
 | 
			
		||||
		renderer->vertexUniformBufferObject,
 | 
			
		||||
		data,
 | 
			
		||||
		dataLengthInBytes
 | 
			
		||||
	);
 | 
			
		||||
 | 
			
		||||
	vulkanCommandBuffer->vertexUniformBuffer->offset += graphicsPipeline->vertexUniformBlockSize;
 | 
			
		||||
	renderer->vertexUniformBufferObject->currentOffset += graphicsPipeline->vertexUniformBlockSize;
 | 
			
		||||
 | 
			
		||||
	SDL_UnlockMutex(renderer->vertexUniformBufferObject->lock);
 | 
			
		||||
 | 
			
		||||
	return offset;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -7139,33 +6877,30 @@ static uint32_t VULKAN_PushFragmentShaderUniforms(
 | 
			
		|||
	VulkanGraphicsPipeline* graphicsPipeline = vulkanCommandBuffer->currentGraphicsPipeline;
 | 
			
		||||
	uint32_t offset;
 | 
			
		||||
 | 
			
		||||
	if (
 | 
			
		||||
		vulkanCommandBuffer->fragmentUniformBuffer->offset +
 | 
			
		||||
		graphicsPipeline->fragmentUniformBlockSize >=
 | 
			
		||||
		UBO_SECTION_SIZE
 | 
			
		||||
	) {
 | 
			
		||||
		/* We're out of space in this buffer, bind the old one and acquire a new one */
 | 
			
		||||
		VULKAN_INTERNAL_BindUniformBuffer(
 | 
			
		||||
			renderer,
 | 
			
		||||
			vulkanCommandBuffer,
 | 
			
		||||
			vulkanCommandBuffer->fragmentUniformBuffer
 | 
			
		||||
		);
 | 
			
		||||
		vulkanCommandBuffer->fragmentUniformBuffer = VULKAN_INTERNAL_AcquireUniformBufferFromPool(
 | 
			
		||||
			renderer,
 | 
			
		||||
			renderer->fragmentUniformBufferPool,
 | 
			
		||||
			graphicsPipeline->fragmentUniformBlockSize
 | 
			
		||||
		);
 | 
			
		||||
	if (graphicsPipeline->fragmentUniformBlockSize == 0)
 | 
			
		||||
	{
 | 
			
		||||
		Refresh_LogError("Bound pipeline's fragment stage does not declare uniforms!");
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	offset = vulkanCommandBuffer->fragmentUniformBuffer->offset;
 | 
			
		||||
	SDL_LockMutex(renderer->fragmentUniformBufferObject->lock);
 | 
			
		||||
 | 
			
		||||
	if (renderer->fragmentUniformBufferObject->currentOffset + dataLengthInBytes >= UBO_BUFFER_SIZE)
 | 
			
		||||
	{
 | 
			
		||||
		renderer->fragmentUniformBufferObject->currentOffset = 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	offset = renderer->fragmentUniformBufferObject->currentOffset;
 | 
			
		||||
 | 
			
		||||
	VULKAN_INTERNAL_SetUniformBufferData(
 | 
			
		||||
		vulkanCommandBuffer->fragmentUniformBuffer,
 | 
			
		||||
		renderer->fragmentUniformBufferObject,
 | 
			
		||||
		data,
 | 
			
		||||
		dataLengthInBytes
 | 
			
		||||
	);
 | 
			
		||||
 | 
			
		||||
	vulkanCommandBuffer->fragmentUniformBuffer->offset += graphicsPipeline->fragmentUniformBlockSize;
 | 
			
		||||
	renderer->fragmentUniformBufferObject->currentOffset += graphicsPipeline->fragmentUniformBlockSize;
 | 
			
		||||
 | 
			
		||||
	SDL_UnlockMutex(renderer->fragmentUniformBufferObject->lock);
 | 
			
		||||
 | 
			
		||||
	return offset;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -7181,33 +6916,30 @@ static uint32_t VULKAN_PushComputeShaderUniforms(
 | 
			
		|||
	VulkanComputePipeline* computePipeline = vulkanCommandBuffer->currentComputePipeline;
 | 
			
		||||
	uint32_t offset;
 | 
			
		||||
 | 
			
		||||
	if (
 | 
			
		||||
		vulkanCommandBuffer->computeUniformBuffer->offset +
 | 
			
		||||
		computePipeline->uniformBlockSize >=
 | 
			
		||||
		UBO_SECTION_SIZE
 | 
			
		||||
	) {
 | 
			
		||||
		/* We're out of space in this buffer, bind the old one and acquire a new one */
 | 
			
		||||
		VULKAN_INTERNAL_BindUniformBuffer(
 | 
			
		||||
			renderer,
 | 
			
		||||
			vulkanCommandBuffer,
 | 
			
		||||
			vulkanCommandBuffer->computeUniformBuffer
 | 
			
		||||
		);
 | 
			
		||||
		vulkanCommandBuffer->computeUniformBuffer = VULKAN_INTERNAL_AcquireUniformBufferFromPool(
 | 
			
		||||
			renderer,
 | 
			
		||||
			renderer->computeUniformBufferPool,
 | 
			
		||||
			computePipeline->uniformBlockSize
 | 
			
		||||
		);
 | 
			
		||||
	if (computePipeline->uniformBlockSize == 0)
 | 
			
		||||
	{
 | 
			
		||||
		Refresh_LogError("Bound pipeline's compute stage does not declare uniforms!");
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	offset = vulkanCommandBuffer->computeUniformBuffer->offset;
 | 
			
		||||
	SDL_LockMutex(renderer->computeUniformBufferObject->lock);
 | 
			
		||||
 | 
			
		||||
	if (renderer->computeUniformBufferObject->currentOffset + dataLengthInBytes >= UBO_BUFFER_SIZE)
 | 
			
		||||
	{
 | 
			
		||||
		renderer->computeUniformBufferObject->currentOffset = 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	offset = renderer->computeUniformBufferObject->currentOffset;
 | 
			
		||||
 | 
			
		||||
	VULKAN_INTERNAL_SetUniformBufferData(
 | 
			
		||||
		vulkanCommandBuffer->computeUniformBuffer,
 | 
			
		||||
		renderer->computeUniformBufferObject,
 | 
			
		||||
		data,
 | 
			
		||||
		dataLengthInBytes
 | 
			
		||||
	);
 | 
			
		||||
 | 
			
		||||
	vulkanCommandBuffer->computeUniformBuffer->offset += computePipeline->uniformBlockSize;
 | 
			
		||||
	renderer->computeUniformBufferObject->currentOffset += computePipeline->uniformBlockSize;
 | 
			
		||||
 | 
			
		||||
	SDL_UnlockMutex(renderer->computeUniformBufferObject->lock);
 | 
			
		||||
 | 
			
		||||
	return offset;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -8195,28 +7927,6 @@ static void VULKAN_EndRenderPass(
 | 
			
		|||
		vulkanCommandBuffer->commandBuffer
 | 
			
		||||
	);
 | 
			
		||||
 | 
			
		||||
	if (	vulkanCommandBuffer->vertexUniformBuffer != renderer->dummyVertexUniformBuffer &&
 | 
			
		||||
		vulkanCommandBuffer->vertexUniformBuffer != NULL
 | 
			
		||||
	) {
 | 
			
		||||
		VULKAN_INTERNAL_BindUniformBuffer(
 | 
			
		||||
			renderer,
 | 
			
		||||
			vulkanCommandBuffer,
 | 
			
		||||
			vulkanCommandBuffer->vertexUniformBuffer
 | 
			
		||||
		);
 | 
			
		||||
	}
 | 
			
		||||
	vulkanCommandBuffer->vertexUniformBuffer = NULL;
 | 
			
		||||
 | 
			
		||||
	if (	vulkanCommandBuffer->fragmentUniformBuffer != renderer->dummyFragmentUniformBuffer &&
 | 
			
		||||
		vulkanCommandBuffer->fragmentUniformBuffer != NULL
 | 
			
		||||
	) {
 | 
			
		||||
		VULKAN_INTERNAL_BindUniformBuffer(
 | 
			
		||||
			renderer,
 | 
			
		||||
			vulkanCommandBuffer,
 | 
			
		||||
			vulkanCommandBuffer->fragmentUniformBuffer
 | 
			
		||||
		);
 | 
			
		||||
	}
 | 
			
		||||
	vulkanCommandBuffer->fragmentUniformBuffer = NULL;
 | 
			
		||||
 | 
			
		||||
	/* If the render targets can be sampled, transition them to sample layout */
 | 
			
		||||
	for (i = 0; i < vulkanCommandBuffer->renderPassColorTargetCount; i += 1)
 | 
			
		||||
	{
 | 
			
		||||
| 
						 | 
				
			
			@ -8292,52 +8002,6 @@ static void VULKAN_BindGraphicsPipeline(
 | 
			
		|||
	VulkanCommandBuffer *vulkanCommandBuffer = (VulkanCommandBuffer*) commandBuffer;
 | 
			
		||||
	VulkanGraphicsPipeline* pipeline = (VulkanGraphicsPipeline*) graphicsPipeline;
 | 
			
		||||
 | 
			
		||||
	if (	vulkanCommandBuffer->vertexUniformBuffer != renderer->dummyVertexUniformBuffer &&
 | 
			
		||||
		vulkanCommandBuffer->vertexUniformBuffer != NULL
 | 
			
		||||
	) {
 | 
			
		||||
		VULKAN_INTERNAL_BindUniformBuffer(
 | 
			
		||||
			renderer,
 | 
			
		||||
			vulkanCommandBuffer,
 | 
			
		||||
			vulkanCommandBuffer->vertexUniformBuffer
 | 
			
		||||
		);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (pipeline->vertexUniformBlockSize == 0)
 | 
			
		||||
	{
 | 
			
		||||
		vulkanCommandBuffer->vertexUniformBuffer = renderer->dummyVertexUniformBuffer;
 | 
			
		||||
	}
 | 
			
		||||
	else
 | 
			
		||||
	{
 | 
			
		||||
		vulkanCommandBuffer->vertexUniformBuffer = VULKAN_INTERNAL_AcquireUniformBufferFromPool(
 | 
			
		||||
			renderer,
 | 
			
		||||
			renderer->vertexUniformBufferPool,
 | 
			
		||||
			pipeline->vertexUniformBlockSize
 | 
			
		||||
		);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (	vulkanCommandBuffer->fragmentUniformBuffer != renderer->dummyFragmentUniformBuffer &&
 | 
			
		||||
		vulkanCommandBuffer->fragmentUniformBuffer != NULL
 | 
			
		||||
	) {
 | 
			
		||||
		VULKAN_INTERNAL_BindUniformBuffer(
 | 
			
		||||
			renderer,
 | 
			
		||||
			vulkanCommandBuffer,
 | 
			
		||||
			vulkanCommandBuffer->fragmentUniformBuffer
 | 
			
		||||
		);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (pipeline->fragmentUniformBlockSize == 0)
 | 
			
		||||
	{
 | 
			
		||||
		vulkanCommandBuffer->fragmentUniformBuffer = renderer->dummyFragmentUniformBuffer;
 | 
			
		||||
	}
 | 
			
		||||
	else
 | 
			
		||||
	{
 | 
			
		||||
		vulkanCommandBuffer->fragmentUniformBuffer = VULKAN_INTERNAL_AcquireUniformBufferFromPool(
 | 
			
		||||
			renderer,
 | 
			
		||||
			renderer->fragmentUniformBufferPool,
 | 
			
		||||
			pipeline->fragmentUniformBlockSize
 | 
			
		||||
		);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* bind dummy sets if necessary */
 | 
			
		||||
	if (pipeline->pipelineLayout->vertexSamplerDescriptorSetCache == NULL)
 | 
			
		||||
	{
 | 
			
		||||
| 
						 | 
				
			
			@ -8446,7 +8110,7 @@ static void VULKAN_BindComputePipeline(
 | 
			
		|||
	VulkanCommandBuffer *vulkanCommandBuffer = (VulkanCommandBuffer*) commandBuffer;
 | 
			
		||||
	VulkanComputePipeline *vulkanComputePipeline = (VulkanComputePipeline*) computePipeline;
 | 
			
		||||
 | 
			
		||||
	/* bind dummy sets */
 | 
			
		||||
	/* bind dummy sets if necessary */
 | 
			
		||||
	if (vulkanComputePipeline->pipelineLayout->bufferDescriptorSetCache == NULL)
 | 
			
		||||
	{
 | 
			
		||||
		vulkanCommandBuffer->bufferDescriptorSet = renderer->emptyComputeBufferDescriptorSet;
 | 
			
		||||
| 
						 | 
				
			
			@ -8457,15 +8121,6 @@ static void VULKAN_BindComputePipeline(
 | 
			
		|||
		vulkanCommandBuffer->imageDescriptorSet = renderer->emptyComputeImageDescriptorSet;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (	vulkanCommandBuffer->computeUniformBuffer != renderer->dummyComputeUniformBuffer &&
 | 
			
		||||
		vulkanCommandBuffer->computeUniformBuffer != NULL
 | 
			
		||||
	) {
 | 
			
		||||
		VULKAN_INTERNAL_BindUniformBuffer(
 | 
			
		||||
			renderer,
 | 
			
		||||
			vulkanCommandBuffer,
 | 
			
		||||
			vulkanCommandBuffer->computeUniformBuffer
 | 
			
		||||
		);
 | 
			
		||||
	}
 | 
			
		||||
	renderer->vkCmdBindPipeline(
 | 
			
		||||
		vulkanCommandBuffer->commandBuffer,
 | 
			
		||||
		VK_PIPELINE_BIND_POINT_COMPUTE,
 | 
			
		||||
| 
						 | 
				
			
			@ -8474,19 +8129,6 @@ static void VULKAN_BindComputePipeline(
 | 
			
		|||
 | 
			
		||||
	vulkanCommandBuffer->currentComputePipeline = vulkanComputePipeline;
 | 
			
		||||
 | 
			
		||||
	if (vulkanComputePipeline->uniformBlockSize == 0)
 | 
			
		||||
	{
 | 
			
		||||
		vulkanCommandBuffer->computeUniformBuffer = renderer->dummyComputeUniformBuffer;
 | 
			
		||||
	}
 | 
			
		||||
	else
 | 
			
		||||
	{
 | 
			
		||||
		vulkanCommandBuffer->computeUniformBuffer = VULKAN_INTERNAL_AcquireUniformBufferFromPool(
 | 
			
		||||
			renderer,
 | 
			
		||||
			renderer->computeUniformBufferPool,
 | 
			
		||||
			vulkanComputePipeline->uniformBlockSize
 | 
			
		||||
		);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	VULKAN_INTERNAL_TrackComputePipeline(renderer, vulkanCommandBuffer, vulkanComputePipeline);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -8606,7 +8248,7 @@ static void VULKAN_DispatchCompute(
 | 
			
		|||
 | 
			
		||||
	descriptorSets[0] = vulkanCommandBuffer->bufferDescriptorSet;
 | 
			
		||||
	descriptorSets[1] = vulkanCommandBuffer->imageDescriptorSet;
 | 
			
		||||
	descriptorSets[2] = vulkanCommandBuffer->computeUniformBuffer->descriptorSet;
 | 
			
		||||
	descriptorSets[2] = renderer->computeUniformBufferObject->descriptorSet;
 | 
			
		||||
 | 
			
		||||
	renderer->vkCmdBindDescriptorSets(
 | 
			
		||||
		vulkanCommandBuffer->commandBuffer,
 | 
			
		||||
| 
						 | 
				
			
			@ -8692,17 +8334,6 @@ static void VULKAN_EndComputePass(
 | 
			
		|||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (	vulkanCommandBuffer->computeUniformBuffer != renderer->dummyComputeUniformBuffer &&
 | 
			
		||||
		vulkanCommandBuffer->computeUniformBuffer != NULL)
 | 
			
		||||
	{
 | 
			
		||||
		VULKAN_INTERNAL_BindUniformBuffer(
 | 
			
		||||
			renderer,
 | 
			
		||||
			vulkanCommandBuffer,
 | 
			
		||||
			vulkanCommandBuffer->computeUniformBuffer
 | 
			
		||||
		);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	vulkanCommandBuffer->computeUniformBuffer = NULL;
 | 
			
		||||
	vulkanCommandBuffer->currentComputePipeline = NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -9459,14 +9090,6 @@ static void VULKAN_INTERNAL_AllocateCommandBuffers(
 | 
			
		|||
			commandBuffer->signalSemaphoreCapacity * sizeof(VkSemaphore)
 | 
			
		||||
		);
 | 
			
		||||
 | 
			
		||||
		/* Bound buffer tracking */
 | 
			
		||||
 | 
			
		||||
		commandBuffer->boundUniformBufferCapacity = 16;
 | 
			
		||||
		commandBuffer->boundUniformBufferCount = 0;
 | 
			
		||||
		commandBuffer->boundUniformBuffers = SDL_malloc(
 | 
			
		||||
			commandBuffer->boundUniformBufferCapacity * sizeof(VulkanUniformBuffer*)
 | 
			
		||||
		);
 | 
			
		||||
 | 
			
		||||
		/* Descriptor set tracking */
 | 
			
		||||
 | 
			
		||||
		commandBuffer->boundDescriptorSetDataCapacity = 16;
 | 
			
		||||
| 
						 | 
				
			
			@ -9656,10 +9279,6 @@ static Refresh_CommandBuffer* VULKAN_AcquireCommandBuffer(
 | 
			
		|||
	commandBuffer->currentComputePipeline = NULL;
 | 
			
		||||
	commandBuffer->currentGraphicsPipeline = NULL;
 | 
			
		||||
 | 
			
		||||
	commandBuffer->vertexUniformBuffer = NULL;
 | 
			
		||||
	commandBuffer->fragmentUniformBuffer = NULL;
 | 
			
		||||
	commandBuffer->computeUniformBuffer = NULL;
 | 
			
		||||
 | 
			
		||||
	commandBuffer->renderPassColorTargetCount = 0;
 | 
			
		||||
	commandBuffer->autoReleaseFence = 1;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -10152,7 +9771,6 @@ static void VULKAN_INTERNAL_CleanCommandBuffer(
 | 
			
		|||
	VulkanCommandBuffer *commandBuffer
 | 
			
		||||
) {
 | 
			
		||||
	uint32_t i;
 | 
			
		||||
	VulkanUniformBuffer *uniformBuffer;
 | 
			
		||||
	DescriptorSetData *descriptorSetData;
 | 
			
		||||
 | 
			
		||||
	if (commandBuffer->autoReleaseFence)
 | 
			
		||||
| 
						 | 
				
			
			@ -10165,29 +9783,6 @@ static void VULKAN_INTERNAL_CleanCommandBuffer(
 | 
			
		|||
		commandBuffer->inFlightFence = VK_NULL_HANDLE;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* Bound uniform buffers are now available */
 | 
			
		||||
 | 
			
		||||
	for (i = 0; i < commandBuffer->boundUniformBufferCount; i += 1)
 | 
			
		||||
	{
 | 
			
		||||
		uniformBuffer = commandBuffer->boundUniformBuffers[i];
 | 
			
		||||
 | 
			
		||||
		SDL_LockMutex(uniformBuffer->pool->lock);
 | 
			
		||||
		if (uniformBuffer->pool->availableBufferCount == uniformBuffer->pool->availableBufferCapacity)
 | 
			
		||||
		{
 | 
			
		||||
			uniformBuffer->pool->availableBufferCapacity *= 2;
 | 
			
		||||
			uniformBuffer->pool->availableBuffers = SDL_realloc(
 | 
			
		||||
				uniformBuffer->pool->availableBuffers,
 | 
			
		||||
				uniformBuffer->pool->availableBufferCapacity * sizeof(VulkanUniformBuffer*)
 | 
			
		||||
			);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		uniformBuffer->pool->availableBuffers[uniformBuffer->pool->availableBufferCount] = uniformBuffer;
 | 
			
		||||
		uniformBuffer->pool->availableBufferCount += 1;
 | 
			
		||||
		SDL_UnlockMutex(uniformBuffer->pool->lock);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	commandBuffer->boundUniformBufferCount = 0;
 | 
			
		||||
 | 
			
		||||
	/* Bound descriptor sets are now available */
 | 
			
		||||
 | 
			
		||||
	for (i = 0; i < commandBuffer->boundDescriptorSetDataCount; i += 1)
 | 
			
		||||
| 
						 | 
				
			
			@ -11958,64 +11553,19 @@ static Refresh_Device* VULKAN_CreateDevice(
 | 
			
		|||
		&renderer->emptyComputeImageDescriptorSet
 | 
			
		||||
	);
 | 
			
		||||
 | 
			
		||||
	/* Dummy Uniform Buffers */
 | 
			
		||||
	/* Initialize uniform buffer objects */
 | 
			
		||||
 | 
			
		||||
	renderer->dummyBuffer = VULKAN_INTERNAL_CreateBuffer(
 | 
			
		||||
		renderer,
 | 
			
		||||
		16,
 | 
			
		||||
		RESOURCE_ACCESS_GENERAL,
 | 
			
		||||
		VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT,
 | 
			
		||||
		0,
 | 
			
		||||
		0,
 | 
			
		||||
		1
 | 
			
		||||
	);
 | 
			
		||||
 | 
			
		||||
	renderer->dummyVertexUniformBuffer = VULKAN_INTERNAL_CreateDummyUniformBuffer(
 | 
			
		||||
	renderer->vertexUniformBufferObject = VULKAN_INTERNAL_CreateUniformBufferObject(
 | 
			
		||||
		renderer,
 | 
			
		||||
		UNIFORM_BUFFER_VERTEX
 | 
			
		||||
	);
 | 
			
		||||
 | 
			
		||||
	if (renderer->dummyVertexUniformBuffer == NULL)
 | 
			
		||||
	{
 | 
			
		||||
		Refresh_LogError("Failed to create dummy vertex uniform buffer!");
 | 
			
		||||
		return NULL;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	renderer->dummyFragmentUniformBuffer = VULKAN_INTERNAL_CreateDummyUniformBuffer(
 | 
			
		||||
	renderer->fragmentUniformBufferObject = VULKAN_INTERNAL_CreateUniformBufferObject(
 | 
			
		||||
		renderer,
 | 
			
		||||
		UNIFORM_BUFFER_FRAGMENT
 | 
			
		||||
	);
 | 
			
		||||
 | 
			
		||||
	if (renderer->dummyFragmentUniformBuffer == NULL)
 | 
			
		||||
	{
 | 
			
		||||
		Refresh_LogError("Failed to create dummy fragment uniform buffer!");
 | 
			
		||||
		return NULL;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	renderer->dummyComputeUniformBuffer = VULKAN_INTERNAL_CreateDummyUniformBuffer(
 | 
			
		||||
		renderer,
 | 
			
		||||
		UNIFORM_BUFFER_COMPUTE
 | 
			
		||||
	);
 | 
			
		||||
 | 
			
		||||
	if (renderer->dummyComputeUniformBuffer == NULL)
 | 
			
		||||
	{
 | 
			
		||||
		Refresh_LogError("Failed to create dummy compute uniform buffer!");
 | 
			
		||||
		return NULL;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* Initialize uniform buffer pools */
 | 
			
		||||
 | 
			
		||||
	renderer->vertexUniformBufferPool = VULKAN_INTERNAL_CreateUniformBufferPool(
 | 
			
		||||
		renderer,
 | 
			
		||||
		UNIFORM_BUFFER_VERTEX
 | 
			
		||||
	);
 | 
			
		||||
 | 
			
		||||
	renderer->fragmentUniformBufferPool = VULKAN_INTERNAL_CreateUniformBufferPool(
 | 
			
		||||
		renderer,
 | 
			
		||||
		UNIFORM_BUFFER_FRAGMENT
 | 
			
		||||
	);
 | 
			
		||||
 | 
			
		||||
	renderer->computeUniformBufferPool = VULKAN_INTERNAL_CreateUniformBufferPool(
 | 
			
		||||
	renderer->computeUniformBufferObject = VULKAN_INTERNAL_CreateUniformBufferObject(
 | 
			
		||||
		renderer,
 | 
			
		||||
		UNIFORM_BUFFER_COMPUTE
 | 
			
		||||
	);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue