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