Compare commits

..

3 Commits

Author SHA1 Message Date
cosmonaut 53c439ef04 fix multiple copy sync hazard
continuous-integration/drone/push Build is passing Details
continuous-integration/drone/pr Build is passing Details
2024-01-12 17:36:28 -08:00
cosmonaut ae98ae2345 fix some sync hazards 2024-01-12 17:36:28 -08:00
Evan Hemsley 425694ede5 try moving layout transition into render pass 2024-01-12 17:36:28 -08:00
1 changed files with 50 additions and 72 deletions

View File

@ -79,8 +79,7 @@ typedef struct VulkanExtensions
#define ALLOCATION_INCREMENT 16000000 /* 16MB */ #define ALLOCATION_INCREMENT 16000000 /* 16MB */
#define TRANSFER_BUFFER_STARTING_SIZE 8000000 /* 8MB */ #define TRANSFER_BUFFER_STARTING_SIZE 8000000 /* 8MB */
#define POOLED_TRANSFER_BUFFER_SIZE 16000000 /* 16MB */ #define POOLED_TRANSFER_BUFFER_SIZE 16000000 /* 16MB */
#define UBO_BUFFER_SIZE 16000000 /* 16MB */ #define UBO_BUFFER_SIZE 16000 /* 16KB */
#define UBO_SECTION_SIZE 4000 /* 4KB */
#define DESCRIPTOR_POOL_STARTING_SIZE 128 #define DESCRIPTOR_POOL_STARTING_SIZE 128
#define DEFRAG_TIME 200 #define DEFRAG_TIME 200
#define WINDOW_DATA "Refresh_VulkanWindowData" #define WINDOW_DATA "Refresh_VulkanWindowData"
@ -720,8 +719,8 @@ typedef struct VulkanUniformBufferPool VulkanUniformBufferPool;
typedef struct VulkanUniformBuffer typedef struct VulkanUniformBuffer
{ {
VulkanUniformBufferPool *pool; VulkanUniformBufferPool *pool;
VkDeviceSize poolOffset; /* memory offset relative to the pool buffer */ VulkanBufferContainer *vulkanBufferContainer; /* use container to avoid defrag issues */
VkDeviceSize offset; /* based on uniform pushes */ VkDeviceSize offset;
VkDescriptorSet descriptorSet; VkDescriptorSet descriptorSet;
} VulkanUniformBuffer; } VulkanUniformBuffer;
@ -747,13 +746,10 @@ typedef struct VulkanUniformDescriptorPool
uint32_t availableDescriptorSetCount; uint32_t availableDescriptorSetCount;
} VulkanUniformDescriptorPool; } VulkanUniformDescriptorPool;
/* This is actually just one buffer that we carve slices out of. */
struct VulkanUniformBufferPool struct VulkanUniformBufferPool
{ {
VulkanUniformBufferType type; VulkanUniformBufferType type;
VulkanUniformDescriptorPool descriptorPool; VulkanUniformDescriptorPool descriptorPool;
VulkanBuffer *buffer;
VkDeviceSize nextAvailableOffset;
SDL_mutex *lock; SDL_mutex *lock;
VulkanUniformBuffer **availableBuffers; VulkanUniformBuffer **availableBuffers;
@ -1786,8 +1782,6 @@ typedef struct VulkanRenderer
VkDescriptorSetLayout vertexUniformDescriptorSetLayout; VkDescriptorSetLayout vertexUniformDescriptorSetLayout;
VkDescriptorSetLayout fragmentUniformDescriptorSetLayout; VkDescriptorSetLayout fragmentUniformDescriptorSetLayout;
VkDescriptorSetLayout computeUniformDescriptorSetLayout; VkDescriptorSetLayout computeUniformDescriptorSetLayout;
VulkanBuffer *dummyBuffer;
VulkanUniformBuffer *dummyVertexUniformBuffer; VulkanUniformBuffer *dummyVertexUniformBuffer;
VulkanUniformBuffer *dummyFragmentUniformBuffer; VulkanUniformBuffer *dummyFragmentUniformBuffer;
VulkanUniformBuffer *dummyComputeUniformBuffer; VulkanUniformBuffer *dummyComputeUniformBuffer;
@ -4209,36 +4203,6 @@ static VulkanUniformBufferPool* VULKAN_INTERNAL_CreateUniformBufferPool(
VulkanUniformBufferType uniformBufferType VulkanUniformBufferType uniformBufferType
) { ) {
VulkanUniformBufferPool* uniformBufferPool = SDL_malloc(sizeof(VulkanUniformBufferPool)); VulkanUniformBufferPool* uniformBufferPool = SDL_malloc(sizeof(VulkanUniformBufferPool));
VulkanResourceAccessType resourceAccessType;
if (uniformBufferType == UNIFORM_BUFFER_VERTEX)
{
resourceAccessType = RESOURCE_ACCESS_VERTEX_SHADER_READ_UNIFORM_BUFFER;
}
else if (uniformBufferType == UNIFORM_BUFFER_FRAGMENT)
{
resourceAccessType = RESOURCE_ACCESS_FRAGMENT_SHADER_READ_UNIFORM_BUFFER;
}
else if (uniformBufferType == UNIFORM_BUFFER_COMPUTE)
{
resourceAccessType = RESOURCE_ACCESS_COMPUTE_SHADER_READ_UNIFORM_BUFFER;
}
else
{
Refresh_LogError("Unrecognized uniform buffer type!");
return 0;
}
uniformBufferPool->buffer = VULKAN_INTERNAL_CreateBuffer(
renderer,
UBO_BUFFER_SIZE,
resourceAccessType,
VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT,
0,
1
);
uniformBufferPool->nextAvailableOffset = 0;
uniformBufferPool->type = uniformBufferType; uniformBufferPool->type = uniformBufferType;
uniformBufferPool->lock = SDL_CreateMutex(); uniformBufferPool->lock = SDL_CreateMutex();
@ -4272,6 +4236,12 @@ static void VULKAN_INTERNAL_BindUniformBuffer(
commandBuffer->boundUniformBuffers[commandBuffer->boundUniformBufferCount] = uniformBuffer; commandBuffer->boundUniformBuffers[commandBuffer->boundUniformBufferCount] = uniformBuffer;
commandBuffer->boundUniformBufferCount += 1; commandBuffer->boundUniformBufferCount += 1;
VULKAN_INTERNAL_TrackBuffer(
renderer,
commandBuffer,
uniformBuffer->vulkanBufferContainer->vulkanBuffer
);
} }
/* Buffer indirection so we can cleanly defrag */ /* Buffer indirection so we can cleanly defrag */
@ -4340,18 +4310,22 @@ static uint8_t VULKAN_INTERNAL_CreateUniformBuffer(
VulkanUniformBuffer *uniformBuffer = SDL_malloc(sizeof(VulkanUniformBuffer)); VulkanUniformBuffer *uniformBuffer = SDL_malloc(sizeof(VulkanUniformBuffer));
uniformBuffer->pool = bufferPool; uniformBuffer->pool = bufferPool;
uniformBuffer->poolOffset = bufferPool->nextAvailableOffset; uniformBuffer->vulkanBufferContainer = VULKAN_INTERNAL_CreateBufferContainer(
uniformBuffer->offset = 0; renderer,
UBO_BUFFER_SIZE,
resourceAccessType,
VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT,
0
);
bufferPool->nextAvailableOffset += UBO_SECTION_SIZE; if (uniformBuffer->vulkanBufferContainer == NULL)
if (bufferPool->nextAvailableOffset >= UBO_BUFFER_SIZE)
{ {
Refresh_LogError("Uniform buffer overflow!"); Refresh_LogError("Failed to create buffer for uniform buffer!");
SDL_free(uniformBuffer);
return 0; return 0;
} }
uniformBuffer->offset = 0;
/* Allocate a descriptor set for the uniform buffer */ /* Allocate a descriptor set for the uniform buffer */
if (bufferPool->descriptorPool.availableDescriptorSetCount == 0) if (bufferPool->descriptorPool.availableDescriptorSetCount == 0)
@ -4361,7 +4335,6 @@ static uint8_t VULKAN_INTERNAL_CreateUniformBuffer(
&bufferPool->descriptorPool &bufferPool->descriptorPool
)) { )) {
Refresh_LogError("Failed to add uniform descriptor pool!"); Refresh_LogError("Failed to add uniform descriptor pool!");
SDL_free(uniformBuffer);
return 0; return 0;
} }
} }
@ -4426,7 +4399,15 @@ static VulkanUniformBuffer* VULKAN_INTERNAL_CreateDummyUniformBuffer(
} }
VulkanUniformBuffer *uniformBuffer = SDL_malloc(sizeof(VulkanUniformBuffer)); VulkanUniformBuffer *uniformBuffer = SDL_malloc(sizeof(VulkanUniformBuffer));
uniformBuffer->poolOffset = 0; uniformBuffer->pool = NULL;
uniformBuffer->vulkanBufferContainer = VULKAN_INTERNAL_CreateBufferContainer(
renderer,
1,
resourceAccessType,
VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT,
1
);
uniformBuffer->offset = 0; uniformBuffer->offset = 0;
/* Allocate a descriptor set for the uniform buffer */ /* Allocate a descriptor set for the uniform buffer */
@ -4441,7 +4422,7 @@ static VulkanUniformBuffer* VULKAN_INTERNAL_CreateDummyUniformBuffer(
/* Update the descriptor set for the first and last time! */ /* Update the descriptor set for the first and last time! */
descriptorBufferInfo.buffer = renderer->dummyBuffer->buffer; descriptorBufferInfo.buffer = uniformBuffer->vulkanBufferContainer->vulkanBuffer->buffer;
descriptorBufferInfo.offset = 0; descriptorBufferInfo.offset = 0;
descriptorBufferInfo.range = VK_WHOLE_SIZE; descriptorBufferInfo.range = VK_WHOLE_SIZE;
@ -4488,11 +4469,11 @@ static void VULKAN_INTERNAL_DestroyUniformBufferPool(
/* This is always destroyed after submissions, so all buffers are available */ /* This is always destroyed after submissions, so all buffers are available */
for (i = 0; i < uniformBufferPool->availableBufferCount; i += 1) for (i = 0; i < uniformBufferPool->availableBufferCount; i += 1)
{ {
VULKAN_INTERNAL_DestroyBuffer(renderer, uniformBufferPool->availableBuffers[i]->vulkanBufferContainer->vulkanBuffer);
SDL_free(uniformBufferPool->availableBuffers[i]->vulkanBufferContainer);
SDL_free(uniformBufferPool->availableBuffers[i]); SDL_free(uniformBufferPool->availableBuffers[i]);
} }
VULKAN_INTERNAL_DestroyBuffer(renderer, uniformBufferPool->buffer);
SDL_DestroyMutex(uniformBufferPool->lock); SDL_DestroyMutex(uniformBufferPool->lock);
SDL_free(uniformBufferPool->availableBuffers); SDL_free(uniformBufferPool->availableBuffers);
SDL_free(uniformBufferPool); SDL_free(uniformBufferPool);
@ -4527,8 +4508,8 @@ static VulkanUniformBuffer* VULKAN_INTERNAL_AcquireUniformBufferFromPool(
/* Update the descriptor set with the correct range */ /* Update the descriptor set with the correct range */
descriptorBufferInfo.buffer = uniformBuffer->pool->buffer->buffer; descriptorBufferInfo.buffer = uniformBuffer->vulkanBufferContainer->vulkanBuffer->buffer;
descriptorBufferInfo.offset = uniformBuffer->poolOffset; descriptorBufferInfo.offset = 0;
descriptorBufferInfo.range = blockSize; descriptorBufferInfo.range = blockSize;
writeDescriptorSet.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; writeDescriptorSet.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
@ -5208,7 +5189,13 @@ static void VULKAN_DestroyDevice(
SDL_free(renderer->submittedCommandBuffers); SDL_free(renderer->submittedCommandBuffers);
VULKAN_INTERNAL_DestroyBuffer(renderer, renderer->dummyBuffer); VULKAN_INTERNAL_DestroyBuffer(renderer, renderer->dummyVertexUniformBuffer->vulkanBufferContainer->vulkanBuffer);
VULKAN_INTERNAL_DestroyBuffer(renderer, renderer->dummyFragmentUniformBuffer->vulkanBufferContainer->vulkanBuffer);
VULKAN_INTERNAL_DestroyBuffer(renderer, renderer->dummyComputeUniformBuffer->vulkanBufferContainer->vulkanBuffer);
SDL_free(renderer->dummyVertexUniformBuffer->vulkanBufferContainer);
SDL_free(renderer->dummyFragmentUniformBuffer->vulkanBufferContainer);
SDL_free(renderer->dummyComputeUniformBuffer->vulkanBufferContainer);
SDL_free(renderer->dummyVertexUniformBuffer); SDL_free(renderer->dummyVertexUniformBuffer);
SDL_free(renderer->dummyFragmentUniformBuffer); SDL_free(renderer->dummyFragmentUniformBuffer);
@ -7941,7 +7928,7 @@ static uint32_t VULKAN_PushVertexShaderUniforms(
if ( if (
vulkanCommandBuffer->vertexUniformBuffer->offset + vulkanCommandBuffer->vertexUniformBuffer->offset +
graphicsPipeline->vertexUniformBlockSize >= graphicsPipeline->vertexUniformBlockSize >=
UBO_SECTION_SIZE UBO_BUFFER_SIZE
) { ) {
/* We're out of space in this buffer, bind the old one and acquire a new one */ /* We're out of space in this buffer, bind the old one and acquire a new one */
VULKAN_INTERNAL_BindUniformBuffer( VULKAN_INTERNAL_BindUniformBuffer(
@ -7959,8 +7946,8 @@ static uint32_t VULKAN_PushVertexShaderUniforms(
offset = vulkanCommandBuffer->vertexUniformBuffer->offset; offset = vulkanCommandBuffer->vertexUniformBuffer->offset;
VULKAN_INTERNAL_SetBufferData( VULKAN_INTERNAL_SetBufferData(
vulkanCommandBuffer->vertexUniformBuffer->pool->buffer, vulkanCommandBuffer->vertexUniformBuffer->vulkanBufferContainer->vulkanBuffer,
vulkanCommandBuffer->vertexUniformBuffer->poolOffset + vulkanCommandBuffer->vertexUniformBuffer->offset, vulkanCommandBuffer->vertexUniformBuffer->offset,
data, data,
dataLengthInBytes dataLengthInBytes
); );
@ -7985,7 +7972,7 @@ static uint32_t VULKAN_PushFragmentShaderUniforms(
if ( if (
vulkanCommandBuffer->fragmentUniformBuffer->offset + vulkanCommandBuffer->fragmentUniformBuffer->offset +
graphicsPipeline->fragmentUniformBlockSize >= graphicsPipeline->fragmentUniformBlockSize >=
UBO_SECTION_SIZE UBO_BUFFER_SIZE
) { ) {
/* We're out of space in this buffer, bind the old one and acquire a new one */ /* We're out of space in this buffer, bind the old one and acquire a new one */
VULKAN_INTERNAL_BindUniformBuffer( VULKAN_INTERNAL_BindUniformBuffer(
@ -8003,8 +7990,8 @@ static uint32_t VULKAN_PushFragmentShaderUniforms(
offset = vulkanCommandBuffer->fragmentUniformBuffer->offset; offset = vulkanCommandBuffer->fragmentUniformBuffer->offset;
VULKAN_INTERNAL_SetBufferData( VULKAN_INTERNAL_SetBufferData(
vulkanCommandBuffer->fragmentUniformBuffer->pool->buffer, vulkanCommandBuffer->fragmentUniformBuffer->vulkanBufferContainer->vulkanBuffer,
vulkanCommandBuffer->fragmentUniformBuffer->poolOffset + vulkanCommandBuffer->fragmentUniformBuffer->offset, vulkanCommandBuffer->fragmentUniformBuffer->offset,
data, data,
dataLengthInBytes dataLengthInBytes
); );
@ -8028,7 +8015,7 @@ static uint32_t VULKAN_PushComputeShaderUniforms(
if ( if (
vulkanCommandBuffer->computeUniformBuffer->offset + vulkanCommandBuffer->computeUniformBuffer->offset +
computePipeline->uniformBlockSize >= computePipeline->uniformBlockSize >=
UBO_SECTION_SIZE UBO_BUFFER_SIZE
) { ) {
/* We're out of space in this buffer, bind the old one and acquire a new one */ /* We're out of space in this buffer, bind the old one and acquire a new one */
VULKAN_INTERNAL_BindUniformBuffer( VULKAN_INTERNAL_BindUniformBuffer(
@ -8046,8 +8033,8 @@ static uint32_t VULKAN_PushComputeShaderUniforms(
offset = vulkanCommandBuffer->computeUniformBuffer->offset; offset = vulkanCommandBuffer->computeUniformBuffer->offset;
VULKAN_INTERNAL_SetBufferData( VULKAN_INTERNAL_SetBufferData(
vulkanCommandBuffer->computeUniformBuffer->pool->buffer, vulkanCommandBuffer->computeUniformBuffer->vulkanBufferContainer->vulkanBuffer,
vulkanCommandBuffer->computeUniformBuffer->poolOffset + vulkanCommandBuffer->computeUniformBuffer->offset, vulkanCommandBuffer->computeUniformBuffer->offset,
data, data,
dataLengthInBytes dataLengthInBytes
); );
@ -12084,15 +12071,6 @@ static Refresh_Device* VULKAN_CreateDevice(
/* Dummy Uniform Buffers */ /* Dummy Uniform Buffers */
renderer->dummyBuffer = VULKAN_INTERNAL_CreateBuffer(
renderer,
1,
RESOURCE_ACCESS_GENERAL,
VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT,
0,
1
);
renderer->dummyVertexUniformBuffer = VULKAN_INTERNAL_CreateDummyUniformBuffer( renderer->dummyVertexUniformBuffer = VULKAN_INTERNAL_CreateDummyUniformBuffer(
renderer, renderer,
UNIFORM_BUFFER_VERTEX UNIFORM_BUFFER_VERTEX