From 95ac1d06fb4b0c3e6b8a8fedcc64be91270ec38d Mon Sep 17 00:00:00 2001 From: cosmonaut Date: Thu, 15 Feb 2024 20:08:39 -0800 Subject: [PATCH 01/20] update vulkan implementation in line with new API --- src/Refresh_Driver_Vulkan.c | 1987 +++++++++++++++++------------------ 1 file changed, 964 insertions(+), 1023 deletions(-) diff --git a/src/Refresh_Driver_Vulkan.c b/src/Refresh_Driver_Vulkan.c index 72f0c10..b4f2f83 100644 --- a/src/Refresh_Driver_Vulkan.c +++ b/src/Refresh_Driver_Vulkan.c @@ -449,7 +449,6 @@ struct VulkanMemoryAllocation uint8_t availableForAllocation; VkDeviceSize freeSpace; VkDeviceSize usedSpace; - uint8_t *mapPointer; SDL_mutex *memoryLock; }; @@ -756,6 +755,7 @@ struct VulkanUniformBufferPool VulkanBuffer *buffer; VkDeviceSize nextAvailableOffset; SDL_mutex *lock; + uint8_t *mapPointer; /* uniform buffers are permanently mapped */ VulkanUniformBuffer **availableBuffers; uint32_t availableBufferCount; @@ -1522,22 +1522,6 @@ typedef struct DescriptorSetData VkDescriptorSet descriptorSet; } DescriptorSetData; -typedef struct VulkanTransferBuffer -{ - VulkanBuffer* buffer; - VkDeviceSize offset; - uint8_t fromPool; -} VulkanTransferBuffer; - -typedef struct VulkanTransferBufferPool -{ - SDL_mutex *lock; - - VulkanTransferBuffer **availableBuffers; - uint32_t availableBufferCount; - uint32_t availableBufferCapacity; -} VulkanTransferBufferPool; - typedef struct VulkanFencePool { SDL_mutex *lock; @@ -1582,10 +1566,6 @@ typedef struct VulkanCommandBuffer VkDescriptorSet bufferDescriptorSet; /* updated by BindComputeBuffers */ VkDescriptorSet imageDescriptorSet; /* updated by BindComputeTextures */ - VulkanTransferBuffer** transferBuffers; - uint32_t transferBufferCount; - uint32_t transferBufferCapacity; - VulkanUniformBuffer **boundUniformBuffers; uint32_t boundUniformBufferCount; uint32_t boundUniformBufferCapacity; @@ -1604,6 +1584,16 @@ typedef struct VulkanCommandBuffer uint32_t boundComputeTextureCount; uint32_t boundComputeTextureCapacity; + /* Keep track of copy resources for memory barriers */ + + VulkanBuffer **copiedGpuBuffers; + uint32_t copiedGpuBufferCount; + uint32_t copiedGpuBufferCapacity; + + VulkanTexture **copiedTextures; + uint32_t copiedTextureCount; + uint32_t copiedTextureCapacity; + /* Viewport/scissor state */ VkViewport currentViewport; @@ -1751,7 +1741,6 @@ typedef struct VulkanRenderer uint32_t submittedCommandBufferCount; uint32_t submittedCommandBufferCapacity; - VulkanTransferBufferPool transferBufferPool; VulkanFencePool fencePool; CommandPoolHashTable commandPoolHashTable; @@ -2578,24 +2567,6 @@ static uint8_t VULKAN_INTERNAL_AllocateMemory( return 0; } - /* persistent mapping for host memory */ - if (isHostVisible) - { - result = renderer->vkMapMemory( - renderer->logicalDevice, - allocation->memory, - 0, - VK_WHOLE_SIZE, - 0, - (void**) &allocation->mapPointer - ); - VULKAN_ERROR_CHECK(result, vkMapMemory, 0) - } - else - { - allocation->mapPointer = NULL; - } - VULKAN_INTERNAL_NewMemoryFreeRegion( renderer, allocation, @@ -3380,6 +3351,64 @@ static void VULKAN_INTERNAL_TrackFramebuffer( ); } +static void VULKAN_INTERNAL_TrackComputeBuffer( + VulkanRenderer *renderer, + VulkanCommandBuffer *commandBuffer, + VulkanBuffer *computeBuffer +) { + TRACK_RESOURCE( + computeBuffer, + VulkanBuffer*, + boundComputeBuffers, + boundComputeBufferCount, + boundComputeBufferCapacity + ); +} + +static void VULKAN_INTERNAL_TrackComputeTexture( + VulkanRenderer *renderer, + VulkanCommandBuffer *commandBuffer, + VulkanTexture *computeTexture +) { + TRACK_RESOURCE( + computeTexture, + VulkanTexture*, + boundComputeTextures, + boundComputeTextureCount, + boundComputeTextureCapacity + ); +} + +/* For tracking Textures used in a copy pass. */ +static void VULKAN_INTERNAL_TrackCopiedTexture( + VulkanRenderer *renderer, + VulkanCommandBuffer *commandBuffer, + VulkanTexture *texture +) { + TRACK_RESOURCE( + texture, + VulkanTexture*, + copiedTextures, + copiedTextureCount, + copiedTextureCapacity + ); +} + +/* For tracking GpuBuffers used in a copy pass. */ +static void VULKAN_INTERNAL_TrackCopiedBuffer( + VulkanRenderer *renderer, + VulkanCommandBuffer *commandBuffer, + VulkanBuffer *buffer +) { + TRACK_RESOURCE( + buffer, + VulkanBuffer*, + copiedGpuBuffers, + copiedGpuBufferCount, + copiedGpuBufferCapacity + ); +} + #undef TRACK_RESOURCE /* Resource Disposal */ @@ -3599,11 +3628,12 @@ static void VULKAN_INTERNAL_DestroyCommandPool( SDL_free(commandBuffer->presentDatas); SDL_free(commandBuffer->waitSemaphores); SDL_free(commandBuffer->signalSemaphores); - SDL_free(commandBuffer->transferBuffers); SDL_free(commandBuffer->boundUniformBuffers); SDL_free(commandBuffer->boundDescriptorSetDatas); SDL_free(commandBuffer->boundComputeBuffers); SDL_free(commandBuffer->boundComputeTextures); + SDL_free(commandBuffer->copiedGpuBuffers); + SDL_free(commandBuffer->copiedTextures); SDL_free(commandBuffer->usedBuffers); SDL_free(commandBuffer->usedTextures); SDL_free(commandBuffer->usedSamplers); @@ -4247,6 +4277,15 @@ static VulkanUniformBufferPool* VULKAN_INTERNAL_CreateUniformBufferPool( uniformBufferPool->descriptorPool.descriptorPoolCount = 0; uniformBufferPool->descriptorPool.descriptorPools = NULL; + renderer->vkMapMemory( + renderer->logicalDevice, + uniformBufferPool->buffer->usedRegion->allocation->memory, + 0, + VK_WHOLE_SIZE, + 0, + (void**) &uniformBufferPool->mapPointer + ); + VULKAN_INTERNAL_AddUniformDescriptorPool(renderer, &uniformBufferPool->descriptorPool); return uniformBufferPool; @@ -4479,6 +4518,11 @@ static void VULKAN_INTERNAL_DestroyUniformBufferPool( SDL_free(uniformBufferPool->availableBuffers[i]); } + renderer->vkUnmapMemory( + renderer->logicalDevice, + uniformBufferPool->buffer->usedRegion->allocation->memory + ); + VULKAN_INTERNAL_DestroyBuffer(renderer, uniformBufferPool->buffer); SDL_DestroyMutex(uniformBufferPool->lock); @@ -5202,15 +5246,6 @@ static void VULKAN_DestroyDevice( SDL_free(renderer->dummyFragmentUniformBuffer); SDL_free(renderer->dummyComputeUniformBuffer); - for (i = 0; i < renderer->transferBufferPool.availableBufferCount; i += 1) - { - VULKAN_INTERNAL_DestroyBuffer(renderer, renderer->transferBufferPool.availableBuffers[i]->buffer); - SDL_free(renderer->transferBufferPool.availableBuffers[i]); - } - - SDL_free(renderer->transferBufferPool.availableBuffers); - SDL_DestroyMutex(renderer->transferBufferPool.lock); - for (i = 0; i < renderer->fencePool.availableFenceCount; i += 1) { renderer->vkDestroyFence(renderer->logicalDevice, renderer->fencePool.availableFences[i], NULL); @@ -5553,7 +5588,7 @@ static void VULKAN_DrawPrimitives( static void VULKAN_DrawPrimitivesIndirect( Refresh_Renderer *driverData, Refresh_CommandBuffer *commandBuffer, - Refresh_Buffer *buffer, + Refresh_GpuBuffer *buffer, uint32_t offsetInBytes, uint32_t drawCount, uint32_t stride, @@ -5596,104 +5631,6 @@ static void VULKAN_DrawPrimitivesIndirect( VULKAN_INTERNAL_TrackBuffer(renderer, vulkanCommandBuffer, vulkanBuffer); } -static void VULKAN_DispatchCompute( - Refresh_Renderer *driverData, - Refresh_CommandBuffer *commandBuffer, - uint32_t groupCountX, - uint32_t groupCountY, - uint32_t groupCountZ, - uint32_t computeParamOffset -) { - VulkanRenderer* renderer = (VulkanRenderer*) driverData; - VulkanCommandBuffer *vulkanCommandBuffer = (VulkanCommandBuffer*) commandBuffer; - VulkanComputePipeline *computePipeline = vulkanCommandBuffer->currentComputePipeline; - VkDescriptorSet descriptorSets[3]; - VulkanResourceAccessType resourceAccessType = RESOURCE_ACCESS_NONE; - VulkanBuffer *currentComputeBuffer; - VulkanTexture *currentComputeTexture; - uint32_t i; - - descriptorSets[0] = vulkanCommandBuffer->bufferDescriptorSet; - descriptorSets[1] = vulkanCommandBuffer->imageDescriptorSet; - descriptorSets[2] = vulkanCommandBuffer->computeUniformBuffer->descriptorSet; - - renderer->vkCmdBindDescriptorSets( - vulkanCommandBuffer->commandBuffer, - VK_PIPELINE_BIND_POINT_COMPUTE, - computePipeline->pipelineLayout->pipelineLayout, - 0, - 3, - descriptorSets, - 1, - &computeParamOffset - ); - - renderer->vkCmdDispatch( - vulkanCommandBuffer->commandBuffer, - groupCountX, - groupCountY, - groupCountZ - ); - - /* Re-transition buffers after dispatch */ - for (i = 0; i < vulkanCommandBuffer->boundComputeBufferCount; i += 1) - { - currentComputeBuffer = vulkanCommandBuffer->boundComputeBuffers[i]; - - if (currentComputeBuffer->usage & VK_BUFFER_USAGE_VERTEX_BUFFER_BIT) - { - resourceAccessType = RESOURCE_ACCESS_VERTEX_BUFFER; - } - else if (currentComputeBuffer->usage & VK_BUFFER_USAGE_INDEX_BUFFER_BIT) - { - resourceAccessType = RESOURCE_ACCESS_INDEX_BUFFER; - } - else if (currentComputeBuffer->usage & VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT) - { - resourceAccessType = RESOURCE_ACCESS_INDIRECT_BUFFER; - } - - if (resourceAccessType != RESOURCE_ACCESS_NONE) - { - VULKAN_INTERNAL_BufferMemoryBarrier( - renderer, - vulkanCommandBuffer->commandBuffer, - resourceAccessType, - currentComputeBuffer - ); - } - } - - vulkanCommandBuffer->boundComputeBufferCount = 0; - - /* Re-transition sampler images after dispatch */ - for (i = 0; i < vulkanCommandBuffer->boundComputeTextureCount; i += 1) - { - currentComputeTexture = vulkanCommandBuffer->boundComputeTextures[i]; - - if (currentComputeTexture->usageFlags & VK_IMAGE_USAGE_SAMPLED_BIT) - { - resourceAccessType = RESOURCE_ACCESS_ANY_SHADER_READ_SAMPLED_IMAGE; - - VULKAN_INTERNAL_ImageMemoryBarrier( - renderer, - vulkanCommandBuffer->commandBuffer, - resourceAccessType, - currentComputeTexture->aspectFlags, - 0, - currentComputeTexture->layerCount, - 0, - currentComputeTexture->levelCount, - 0, - currentComputeTexture->image, - ¤tComputeTexture->resourceAccessType - ); - } - } - - vulkanCommandBuffer->boundComputeTextureCount = 0; -} - static VulkanTexture* VULKAN_INTERNAL_CreateTexture( VulkanRenderer *renderer, uint32_t width, @@ -6546,42 +6483,42 @@ static Refresh_GraphicsPipeline* VULKAN_CreateGraphicsPipeline( /* Depth Stencil State */ frontStencilState.failOp = RefreshToVK_StencilOp[ - pipelineCreateInfo->depthStencilState.frontStencilState.failOp + pipelineCreateInfo->depthStencilState.stencilState.failOp ]; frontStencilState.passOp = RefreshToVK_StencilOp[ - pipelineCreateInfo->depthStencilState.frontStencilState.passOp + pipelineCreateInfo->depthStencilState.stencilState.passOp ]; frontStencilState.depthFailOp = RefreshToVK_StencilOp[ - pipelineCreateInfo->depthStencilState.frontStencilState.depthFailOp + pipelineCreateInfo->depthStencilState.stencilState.depthFailOp ]; frontStencilState.compareOp = RefreshToVK_CompareOp[ - pipelineCreateInfo->depthStencilState.frontStencilState.compareOp + pipelineCreateInfo->depthStencilState.stencilState.compareOp ]; frontStencilState.compareMask = - pipelineCreateInfo->depthStencilState.frontStencilState.compareMask; + pipelineCreateInfo->depthStencilState.stencilState.compareMask; frontStencilState.writeMask = - pipelineCreateInfo->depthStencilState.frontStencilState.writeMask; + pipelineCreateInfo->depthStencilState.stencilState.writeMask; frontStencilState.reference = - pipelineCreateInfo->depthStencilState.frontStencilState.reference; + pipelineCreateInfo->depthStencilState.stencilState.reference; backStencilState.failOp = RefreshToVK_StencilOp[ - pipelineCreateInfo->depthStencilState.backStencilState.failOp + pipelineCreateInfo->depthStencilState.stencilState.failOp ]; backStencilState.passOp = RefreshToVK_StencilOp[ - pipelineCreateInfo->depthStencilState.backStencilState.passOp + pipelineCreateInfo->depthStencilState.stencilState.passOp ]; backStencilState.depthFailOp = RefreshToVK_StencilOp[ - pipelineCreateInfo->depthStencilState.backStencilState.depthFailOp + pipelineCreateInfo->depthStencilState.stencilState.depthFailOp ]; backStencilState.compareOp = RefreshToVK_CompareOp[ - pipelineCreateInfo->depthStencilState.backStencilState.compareOp + pipelineCreateInfo->depthStencilState.stencilState.compareOp ]; backStencilState.compareMask = - pipelineCreateInfo->depthStencilState.backStencilState.compareMask; + pipelineCreateInfo->depthStencilState.stencilState.compareMask; backStencilState.writeMask = - pipelineCreateInfo->depthStencilState.backStencilState.writeMask; + pipelineCreateInfo->depthStencilState.stencilState.writeMask; backStencilState.reference = - pipelineCreateInfo->depthStencilState.backStencilState.reference; + pipelineCreateInfo->depthStencilState.stencilState.reference; depthStencilStateCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO; @@ -7079,7 +7016,7 @@ static Refresh_Texture* VULKAN_CreateTexture( return (Refresh_Texture*) container; } -static Refresh_Buffer* VULKAN_CreateBuffer( +static Refresh_GpuBuffer* VULKAN_CreateGpuBuffer( Refresh_Renderer *driverData, Refresh_BufferUsageFlags usageFlags, uint32_t sizeInBytes @@ -7117,7 +7054,7 @@ static Refresh_Buffer* VULKAN_CreateBuffer( resourceAccessType = RESOURCE_ACCESS_INDIRECT_BUFFER; } - return (Refresh_Buffer*) VULKAN_INTERNAL_CreateBufferContainer( + return (Refresh_GpuBuffer*) VULKAN_INTERNAL_CreateBufferContainer( (VulkanRenderer*) driverData, sizeInBytes, resourceAccessType, @@ -7125,677 +7062,47 @@ static Refresh_Buffer* VULKAN_CreateBuffer( ); } -/* Setters */ - -static VulkanTransferBuffer* VULKAN_INTERNAL_AcquireTransferBuffer( - VulkanRenderer *renderer, - VulkanCommandBuffer *commandBuffer, - VkDeviceSize requiredSize, - VkDeviceSize alignment +static Refresh_CpuBuffer* VULKAN_CreateCpuBuffer( + Refresh_Renderer *driverData, + uint32_t sizeInBytes ) { - VkDeviceSize size; - VkDeviceSize offset; - uint32_t i; - VulkanTransferBuffer *transferBuffer; + VulkanRenderer *renderer = (VulkanRenderer*) driverData; + VkBufferUsageFlags vulkanUsageFlags = + VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT; - /* Search the command buffer's current transfer buffers */ - - for (i = 0; i < commandBuffer->transferBufferCount; i += 1) - { - transferBuffer = commandBuffer->transferBuffers[i]; - offset = transferBuffer->offset + alignment - (transferBuffer->offset % alignment); - - if (offset + requiredSize <= transferBuffer->buffer->size) - { - transferBuffer->offset = offset; - return transferBuffer; - } - } - - /* Nothing fits, can we get a transfer buffer from the pool? */ - - SDL_LockMutex(renderer->transferBufferPool.lock); - - for (i = 0; i < renderer->transferBufferPool.availableBufferCount; i += 1) - { - transferBuffer = renderer->transferBufferPool.availableBuffers[i]; - offset = transferBuffer->offset + alignment - (transferBuffer->offset % alignment); - - if (offset + requiredSize <= transferBuffer->buffer->size) - { - if (commandBuffer->transferBufferCount == commandBuffer->transferBufferCapacity) - { - commandBuffer->transferBufferCapacity *= 2; - commandBuffer->transferBuffers = SDL_realloc( - commandBuffer->transferBuffers, - commandBuffer->transferBufferCapacity * sizeof(VulkanTransferBuffer*) - ); - } - - commandBuffer->transferBuffers[commandBuffer->transferBufferCount] = transferBuffer; - commandBuffer->transferBufferCount += 1; - - renderer->transferBufferPool.availableBuffers[i] = renderer->transferBufferPool.availableBuffers[renderer->transferBufferPool.availableBufferCount - 1]; - renderer->transferBufferPool.availableBufferCount -= 1; - SDL_UnlockMutex(renderer->transferBufferPool.lock); - - transferBuffer->offset = offset; - return transferBuffer; - } - } - - SDL_UnlockMutex(renderer->transferBufferPool.lock); - - /* Nothing fits, so let's create a new transfer buffer */ - - size = TRANSFER_BUFFER_STARTING_SIZE; - - while (size < requiredSize) - { - size *= 2; - } - - transferBuffer = SDL_malloc(sizeof(VulkanTransferBuffer)); - transferBuffer->offset = 0; - transferBuffer->buffer = VULKAN_INTERNAL_CreateBuffer( + VulkanBuffer *vulkanBuffer = VULKAN_INTERNAL_CreateBuffer( renderer, - size, - RESOURCE_ACCESS_TRANSFER_READ_WRITE, - VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT, + sizeInBytes, + RESOURCE_ACCESS_NONE, + vulkanUsageFlags, 1, 0, 1 ); - transferBuffer->fromPool = 0; - if (transferBuffer->buffer == NULL) - { - Refresh_LogError("Failed to allocate transfer buffer!"); - SDL_free(transferBuffer); - return NULL; - } - - if (commandBuffer->transferBufferCount == commandBuffer->transferBufferCapacity) - { - commandBuffer->transferBufferCapacity *= 2; - commandBuffer->transferBuffers = SDL_realloc( - commandBuffer->transferBuffers, - commandBuffer->transferBufferCapacity * sizeof(VulkanTransferBuffer*) - ); - } - - commandBuffer->transferBuffers[commandBuffer->transferBufferCount] = transferBuffer; - commandBuffer->transferBufferCount += 1; - - return transferBuffer; + return (Refresh_CpuBuffer*) vulkanBuffer; } -static void VULKAN_SetTextureData( - Refresh_Renderer *driverData, - Refresh_CommandBuffer *commandBuffer, - Refresh_TextureSlice *textureSlice, - void *data, - uint32_t dataLengthInBytes -) { - VulkanRenderer *renderer = (VulkanRenderer*) driverData; - VulkanTexture *vulkanTexture = ((VulkanTextureContainer*) textureSlice->texture)->vulkanTexture; - VulkanCommandBuffer *vulkanCommandBuffer = (VulkanCommandBuffer*) commandBuffer; - VulkanTransferBuffer *transferBuffer; - VkBufferImageCopy imageCopy; - uint8_t *stagingBufferPointer; - uint32_t blockSize = VULKAN_INTERNAL_TextureBlockSize(vulkanTexture->format); - uint32_t bufferRowLength; - uint32_t bufferImageHeight; +/* Setters */ - transferBuffer = VULKAN_INTERNAL_AcquireTransferBuffer( - renderer, - vulkanCommandBuffer, - VULKAN_INTERNAL_BytesPerImage( - textureSlice->rectangle.w, - textureSlice->rectangle.h, - vulkanTexture->format - ), - VULKAN_INTERNAL_BytesPerPixel(vulkanTexture->format) - ); - - if (transferBuffer == NULL) - { - return; - } - - stagingBufferPointer = - transferBuffer->buffer->usedRegion->allocation->mapPointer + - transferBuffer->buffer->usedRegion->resourceOffset + - transferBuffer->offset; - - SDL_memcpy( - stagingBufferPointer, - data, - dataLengthInBytes - ); - - /* TODO: is it worth it to only transition the specific subresource? */ - VULKAN_INTERNAL_ImageMemoryBarrier( - renderer, - vulkanCommandBuffer->commandBuffer, - RESOURCE_ACCESS_TRANSFER_WRITE, - VK_IMAGE_ASPECT_COLOR_BIT, - 0, - vulkanTexture->layerCount, - 0, - vulkanTexture->levelCount, - 0, - vulkanTexture->image, - &vulkanTexture->resourceAccessType - ); - - bufferRowLength = SDL_max(blockSize, textureSlice->rectangle.w); - bufferImageHeight = SDL_max(blockSize, textureSlice->rectangle.h); - - imageCopy.imageExtent.width = textureSlice->rectangle.w; - imageCopy.imageExtent.height = textureSlice->rectangle.h; - imageCopy.imageExtent.depth = 1; - imageCopy.imageOffset.x = textureSlice->rectangle.x; - imageCopy.imageOffset.y = textureSlice->rectangle.y; - imageCopy.imageOffset.z = textureSlice->depth; - imageCopy.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; - imageCopy.imageSubresource.baseArrayLayer = textureSlice->layer; - imageCopy.imageSubresource.layerCount = 1; - imageCopy.imageSubresource.mipLevel = textureSlice->level; - imageCopy.bufferOffset = transferBuffer->offset; - imageCopy.bufferRowLength = bufferRowLength; - imageCopy.bufferImageHeight = bufferImageHeight; - - renderer->vkCmdCopyBufferToImage( - vulkanCommandBuffer->commandBuffer, - transferBuffer->buffer->buffer, - vulkanTexture->image, - AccessMap[vulkanTexture->resourceAccessType].imageLayout, - 1, - &imageCopy - ); - - transferBuffer->offset += dataLengthInBytes; - - if (vulkanTexture->usageFlags & VK_IMAGE_USAGE_SAMPLED_BIT) - { - /* TODO: is it worth it to only transition the specific subresource? */ - VULKAN_INTERNAL_ImageMemoryBarrier( - renderer, - vulkanCommandBuffer->commandBuffer, - RESOURCE_ACCESS_ANY_SHADER_READ_SAMPLED_IMAGE, - VK_IMAGE_ASPECT_COLOR_BIT, - 0, - vulkanTexture->layerCount, - 0, - vulkanTexture->levelCount, - 0, - vulkanTexture->image, - &vulkanTexture->resourceAccessType - ); - } - - VULKAN_INTERNAL_TrackTexture(renderer, vulkanCommandBuffer, vulkanTexture); -} - -static void VULKAN_SetTextureDataYUV( - Refresh_Renderer *driverData, - Refresh_CommandBuffer* commandBuffer, - Refresh_Texture *y, - Refresh_Texture *u, - Refresh_Texture *v, - uint32_t yWidth, - uint32_t yHeight, - uint32_t uvWidth, - uint32_t uvHeight, - void *yDataPtr, - void *uDataPtr, - void *vDataPtr, - uint32_t yDataLength, - uint32_t uvDataLength, - uint32_t yStride, - uint32_t uvStride -) { - VulkanRenderer *renderer = (VulkanRenderer*) driverData; - VulkanTexture *tex = ((VulkanTextureContainer*) y)->vulkanTexture; - - VulkanCommandBuffer *vulkanCommandBuffer = (VulkanCommandBuffer*)commandBuffer; - VulkanTransferBuffer *transferBuffer; - VkBufferImageCopy imageCopy; - uint8_t * stagingBufferPointer; - - transferBuffer = VULKAN_INTERNAL_AcquireTransferBuffer( - renderer, - vulkanCommandBuffer, - yDataLength + uvDataLength, - VULKAN_INTERNAL_BytesPerPixel(tex->format) - ); - - if (transferBuffer == NULL) - { - return; - } - - stagingBufferPointer = - transferBuffer->buffer->usedRegion->allocation->mapPointer + - transferBuffer->buffer->usedRegion->resourceOffset + - transferBuffer->offset; - - /* Initialize values that are the same for Y, U, and V */ - - imageCopy.imageExtent.depth = 1; - imageCopy.imageOffset.x = 0; - imageCopy.imageOffset.y = 0; - imageCopy.imageOffset.z = 0; - imageCopy.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; - imageCopy.imageSubresource.baseArrayLayer = 0; - imageCopy.imageSubresource.layerCount = 1; - imageCopy.imageSubresource.mipLevel = 0; - - /* Y */ - - SDL_memcpy( - stagingBufferPointer, - yDataPtr, - yDataLength - ); - - VULKAN_INTERNAL_ImageMemoryBarrier( - renderer, - vulkanCommandBuffer->commandBuffer, - RESOURCE_ACCESS_TRANSFER_WRITE, - VK_IMAGE_ASPECT_COLOR_BIT, - 0, - tex->layerCount, - 0, - tex->levelCount, - 0, - tex->image, - &tex->resourceAccessType - ); - - - imageCopy.imageExtent.width = yWidth; - imageCopy.imageExtent.height = yHeight; - imageCopy.bufferOffset = transferBuffer->offset; - imageCopy.bufferRowLength = yStride; - imageCopy.bufferImageHeight = yHeight; - - renderer->vkCmdCopyBufferToImage( - vulkanCommandBuffer->commandBuffer, - transferBuffer->buffer->buffer, - tex->image, - AccessMap[tex->resourceAccessType].imageLayout, - 1, - &imageCopy - ); - - if (tex->usageFlags & VK_IMAGE_USAGE_SAMPLED_BIT) - { - /* TODO: is it worth it to only transition the specific subresource? */ - VULKAN_INTERNAL_ImageMemoryBarrier( - renderer, - vulkanCommandBuffer->commandBuffer, - RESOURCE_ACCESS_ANY_SHADER_READ_SAMPLED_IMAGE, - VK_IMAGE_ASPECT_COLOR_BIT, - 0, - tex->layerCount, - 0, - tex->levelCount, - 0, - tex->image, - &tex->resourceAccessType - ); - } - - VULKAN_INTERNAL_TrackTexture(renderer, vulkanCommandBuffer, tex); - - /* These apply to both U and V */ - - imageCopy.imageExtent.width = uvWidth; - imageCopy.imageExtent.height = uvHeight; - imageCopy.bufferRowLength = uvStride; - imageCopy.bufferImageHeight = uvHeight; - - /* U */ - - imageCopy.bufferOffset = transferBuffer->offset + yDataLength; - - tex = ((VulkanTextureContainer*) u)->vulkanTexture; - - SDL_memcpy( - stagingBufferPointer + yDataLength, - uDataPtr, - uvDataLength - ); - - VULKAN_INTERNAL_ImageMemoryBarrier( - renderer, - vulkanCommandBuffer->commandBuffer, - RESOURCE_ACCESS_TRANSFER_WRITE, - VK_IMAGE_ASPECT_COLOR_BIT, - 0, - tex->layerCount, - 0, - tex->levelCount, - 0, - tex->image, - &tex->resourceAccessType - ); - - renderer->vkCmdCopyBufferToImage( - vulkanCommandBuffer->commandBuffer, - transferBuffer->buffer->buffer, - tex->image, - AccessMap[tex->resourceAccessType].imageLayout, - 1, - &imageCopy - ); - - if (tex->usageFlags & VK_IMAGE_USAGE_SAMPLED_BIT) - { - /* TODO: is it worth it to only transition the specific subresource? */ - VULKAN_INTERNAL_ImageMemoryBarrier( - renderer, - vulkanCommandBuffer->commandBuffer, - RESOURCE_ACCESS_ANY_SHADER_READ_SAMPLED_IMAGE, - VK_IMAGE_ASPECT_COLOR_BIT, - 0, - tex->layerCount, - 0, - tex->levelCount, - 0, - tex->image, - &tex->resourceAccessType - ); - } - - VULKAN_INTERNAL_TrackTexture(renderer, vulkanCommandBuffer, tex); - - /* V */ - - imageCopy.bufferOffset = transferBuffer->offset + yDataLength + uvDataLength; - - tex = ((VulkanTextureContainer*) v)->vulkanTexture; - - SDL_memcpy( - stagingBufferPointer + yDataLength + uvDataLength, - vDataPtr, - uvDataLength - ); - - VULKAN_INTERNAL_ImageMemoryBarrier( - renderer, - vulkanCommandBuffer->commandBuffer, - RESOURCE_ACCESS_TRANSFER_WRITE, - VK_IMAGE_ASPECT_COLOR_BIT, - 0, - tex->layerCount, - 0, - tex->levelCount, - 0, - tex->image, - &tex->resourceAccessType - ); - - renderer->vkCmdCopyBufferToImage( - vulkanCommandBuffer->commandBuffer, - transferBuffer->buffer->buffer, - tex->image, - AccessMap[tex->resourceAccessType].imageLayout, - 1, - &imageCopy - ); - - transferBuffer->offset += yDataLength + uvDataLength; - - if (tex->usageFlags & VK_IMAGE_USAGE_SAMPLED_BIT) - { - /* TODO: is it worth it to only transition the specific subresource? */ - VULKAN_INTERNAL_ImageMemoryBarrier( - renderer, - vulkanCommandBuffer->commandBuffer, - RESOURCE_ACCESS_ANY_SHADER_READ_SAMPLED_IMAGE, - VK_IMAGE_ASPECT_COLOR_BIT, - 0, - tex->layerCount, - 0, - tex->levelCount, - 0, - tex->image, - &tex->resourceAccessType - ); - } - - VULKAN_INTERNAL_TrackTexture(renderer, vulkanCommandBuffer, tex); -} - -static void VULKAN_INTERNAL_BlitImage( - VulkanRenderer *renderer, - VulkanCommandBuffer *commandBuffer, - Refresh_TextureSlice *sourceTextureSlice, - Refresh_TextureSlice *destinationTextureSlice, - VkFilter filter -) { - VkImageBlit blit; - VulkanTexture *sourceTexture = ((VulkanTextureContainer*) sourceTextureSlice->texture)->vulkanTexture; - VulkanTexture *destinationTexture = ((VulkanTextureContainer*) destinationTextureSlice->texture)->vulkanTexture; - - VulkanResourceAccessType originalSourceAccessType = sourceTexture->resourceAccessType; - VulkanResourceAccessType originalDestinationAccessType = destinationTexture->resourceAccessType; - - if (originalDestinationAccessType == RESOURCE_ACCESS_NONE) - { - originalDestinationAccessType = RESOURCE_ACCESS_ANY_SHADER_READ_SAMPLED_IMAGE; - } - - /* TODO: is it worth it to only transition the specific subresource? */ - VULKAN_INTERNAL_ImageMemoryBarrier( - renderer, - commandBuffer->commandBuffer, - RESOURCE_ACCESS_TRANSFER_READ, - VK_IMAGE_ASPECT_COLOR_BIT, - 0, - sourceTexture->layerCount, - 0, - sourceTexture->levelCount, - 0, - sourceTexture->image, - &sourceTexture->resourceAccessType - ); - - VULKAN_INTERNAL_ImageMemoryBarrier( - renderer, - commandBuffer->commandBuffer, - RESOURCE_ACCESS_TRANSFER_WRITE, - VK_IMAGE_ASPECT_COLOR_BIT, - 0, - destinationTexture->layerCount, - 0, - destinationTexture->levelCount, - 0, - destinationTexture->image, - &destinationTexture->resourceAccessType - ); - - blit.srcOffsets[0].x = sourceTextureSlice->rectangle.x; - blit.srcOffsets[0].y = sourceTextureSlice->rectangle.y; - blit.srcOffsets[0].z = sourceTextureSlice->depth; - blit.srcOffsets[1].x = sourceTextureSlice->rectangle.x + sourceTextureSlice->rectangle.w; - blit.srcOffsets[1].y = sourceTextureSlice->rectangle.y + sourceTextureSlice->rectangle.h; - blit.srcOffsets[1].z = 1; - - blit.srcSubresource.mipLevel = sourceTextureSlice->level; - blit.srcSubresource.baseArrayLayer = sourceTextureSlice->layer; - blit.srcSubresource.layerCount = 1; - blit.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; - - blit.dstOffsets[0].x = destinationTextureSlice->rectangle.x; - blit.dstOffsets[0].y = destinationTextureSlice->rectangle.y; - blit.dstOffsets[0].z = destinationTextureSlice->depth; - blit.dstOffsets[1].x = destinationTextureSlice->rectangle.x + destinationTextureSlice->rectangle.w; - blit.dstOffsets[1].y = destinationTextureSlice->rectangle.y + destinationTextureSlice->rectangle.h; - blit.dstOffsets[1].z = 1; - - blit.dstSubresource.mipLevel = destinationTextureSlice->level; - blit.dstSubresource.baseArrayLayer = destinationTextureSlice->layer; - blit.dstSubresource.layerCount = 1; - blit.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; - - renderer->vkCmdBlitImage( - commandBuffer->commandBuffer, - sourceTexture->image, - VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, - destinationTexture->image, - VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, - 1, - &blit, - filter - ); - - /* TODO: is it worth it to only transition the specific subresource? */ - VULKAN_INTERNAL_ImageMemoryBarrier( - renderer, - commandBuffer->commandBuffer, - originalSourceAccessType, - VK_IMAGE_ASPECT_COLOR_BIT, - 0, - sourceTexture->layerCount, - 0, - sourceTexture->levelCount, - 0, - sourceTexture->image, - &sourceTexture->resourceAccessType - ); - - VULKAN_INTERNAL_ImageMemoryBarrier( - renderer, - commandBuffer->commandBuffer, - originalDestinationAccessType, - VK_IMAGE_ASPECT_COLOR_BIT, - 0, - destinationTexture->layerCount, - 0, - destinationTexture->levelCount, - 0, - destinationTexture->image, - &destinationTexture->resourceAccessType - ); - - VULKAN_INTERNAL_TrackTexture(renderer, commandBuffer, sourceTexture); - VULKAN_INTERNAL_TrackTexture(renderer, commandBuffer, destinationTexture); -} - -REFRESHAPI void VULKAN_CopyTextureToTexture( - Refresh_Renderer *driverData, - Refresh_CommandBuffer *commandBuffer, - Refresh_TextureSlice *sourceTextureSlice, - Refresh_TextureSlice *destinationTextureSlice, - Refresh_Filter filter -) { - VulkanRenderer *renderer = (VulkanRenderer*)driverData; - VulkanCommandBuffer *vulkanCommandBuffer = (VulkanCommandBuffer*) commandBuffer; - - VULKAN_INTERNAL_BlitImage( - renderer, - vulkanCommandBuffer, - sourceTextureSlice, - destinationTextureSlice, - RefreshToVK_Filter[filter] - ); -} - -static void VULKAN_INTERNAL_SetBufferData( - VulkanBuffer* vulkanBuffer, - VkDeviceSize offsetInBytes, +static void VULKAN_INTERNAL_SetUniformBufferData( + VulkanUniformBuffer *uniformBuffer, void* data, uint32_t dataLength ) { + uint8_t *dst = + uniformBuffer->pool->mapPointer + + uniformBuffer->pool->buffer->usedRegion->resourceOffset + + uniformBuffer->poolOffset + + uniformBuffer->offset; + SDL_memcpy( - vulkanBuffer->usedRegion->allocation->mapPointer + vulkanBuffer->usedRegion->resourceOffset + offsetInBytes, + dst, data, dataLength ); } -static void VULKAN_SetBufferData( - Refresh_Renderer *driverData, - Refresh_CommandBuffer *commandBuffer, - Refresh_Buffer *buffer, - uint32_t offsetInBytes, - void* data, - uint32_t dataLength -) { - VulkanRenderer* renderer = (VulkanRenderer*) driverData; - VulkanCommandBuffer* vulkanCommandBuffer = (VulkanCommandBuffer*) commandBuffer; - VulkanBuffer* vulkanBuffer = ((VulkanBufferContainer*) buffer)->vulkanBuffer; - VulkanTransferBuffer* transferBuffer; - uint8_t* transferBufferPointer; - VkBufferCopy bufferCopy; - VulkanResourceAccessType accessType = vulkanBuffer->resourceAccessType; - - transferBuffer = VULKAN_INTERNAL_AcquireTransferBuffer( - renderer, - vulkanCommandBuffer, - dataLength, - renderer->physicalDeviceProperties.properties.limits.optimalBufferCopyOffsetAlignment - ); - - if (transferBuffer == NULL) - { - return; - } - - transferBufferPointer = - transferBuffer->buffer->usedRegion->allocation->mapPointer + - transferBuffer->buffer->usedRegion->resourceOffset + - transferBuffer->offset; - - SDL_memcpy( - transferBufferPointer, - data, - dataLength - ); - - VULKAN_INTERNAL_BufferMemoryBarrier( - renderer, - vulkanCommandBuffer->commandBuffer, - RESOURCE_ACCESS_TRANSFER_READ, - transferBuffer->buffer - ); - - VULKAN_INTERNAL_BufferMemoryBarrier( - renderer, - vulkanCommandBuffer->commandBuffer, - RESOURCE_ACCESS_TRANSFER_WRITE, - vulkanBuffer - ); - - bufferCopy.srcOffset = transferBuffer->offset; - bufferCopy.dstOffset = offsetInBytes; - bufferCopy.size = (VkDeviceSize) dataLength; - - renderer->vkCmdCopyBuffer( - vulkanCommandBuffer->commandBuffer, - transferBuffer->buffer->buffer, - vulkanBuffer->buffer, - 1, - &bufferCopy - ); - - VULKAN_INTERNAL_BufferMemoryBarrier( - renderer, - vulkanCommandBuffer->commandBuffer, - accessType, - vulkanBuffer - ); - - transferBuffer->offset += dataLength; - - VULKAN_INTERNAL_TrackBuffer(renderer, vulkanCommandBuffer, vulkanBuffer); -} - -/* FIXME: this should return uint64_t */ static uint32_t VULKAN_PushVertexShaderUniforms( Refresh_Renderer *driverData, Refresh_CommandBuffer *commandBuffer, @@ -7839,9 +7146,8 @@ static uint32_t VULKAN_PushVertexShaderUniforms( offset = vulkanCommandBuffer->vertexUniformBuffer->offset; - VULKAN_INTERNAL_SetBufferData( - vulkanCommandBuffer->vertexUniformBuffer->pool->buffer, - vulkanCommandBuffer->vertexUniformBuffer->poolOffset + vulkanCommandBuffer->vertexUniformBuffer->offset, + VULKAN_INTERNAL_SetUniformBufferData( + vulkanCommandBuffer->vertexUniformBuffer, data, dataLengthInBytes ); @@ -7851,7 +7157,6 @@ static uint32_t VULKAN_PushVertexShaderUniforms( return offset; } -/* FIXME: this should return uint64_t */ static uint32_t VULKAN_PushFragmentShaderUniforms( Refresh_Renderer *driverData, Refresh_CommandBuffer *commandBuffer, @@ -7883,9 +7188,8 @@ static uint32_t VULKAN_PushFragmentShaderUniforms( offset = vulkanCommandBuffer->fragmentUniformBuffer->offset; - VULKAN_INTERNAL_SetBufferData( - vulkanCommandBuffer->fragmentUniformBuffer->pool->buffer, - vulkanCommandBuffer->fragmentUniformBuffer->poolOffset + vulkanCommandBuffer->fragmentUniformBuffer->offset, + VULKAN_INTERNAL_SetUniformBufferData( + vulkanCommandBuffer->fragmentUniformBuffer, data, dataLengthInBytes ); @@ -7926,9 +7230,8 @@ static uint32_t VULKAN_PushComputeShaderUniforms( offset = vulkanCommandBuffer->computeUniformBuffer->offset; - VULKAN_INTERNAL_SetBufferData( - vulkanCommandBuffer->computeUniformBuffer->pool->buffer, - vulkanCommandBuffer->computeUniformBuffer->poolOffset + vulkanCommandBuffer->computeUniformBuffer->offset, + VULKAN_INTERNAL_SetUniformBufferData( + vulkanCommandBuffer->computeUniformBuffer, data, dataLengthInBytes ); @@ -8153,103 +7456,6 @@ static void VULKAN_BindFragmentSamplers( ); } -static void VULKAN_GetBufferData( - Refresh_Renderer *driverData, - Refresh_Buffer *buffer, - void *data, - uint32_t dataLengthInBytes -) { - VulkanBuffer* vulkanBuffer = ((VulkanBufferContainer*) buffer)->vulkanBuffer; - uint8_t *dataPtr = (uint8_t*) data; - uint8_t *mapPointer; - - mapPointer = - vulkanBuffer->usedRegion->allocation->mapPointer + - vulkanBuffer->usedRegion->resourceOffset; - - SDL_memcpy( - dataPtr, - mapPointer, - dataLengthInBytes - ); -} - -static void VULKAN_CopyTextureToBuffer( - Refresh_Renderer *driverData, - Refresh_CommandBuffer *commandBuffer, - Refresh_TextureSlice *textureSlice, - Refresh_Buffer *buffer -) { - VulkanRenderer *renderer = (VulkanRenderer*) driverData; - VulkanCommandBuffer *vulkanCommandBuffer = (VulkanCommandBuffer*) commandBuffer; - VulkanTexture *vulkanTexture = ((VulkanTextureContainer*) textureSlice->texture)->vulkanTexture; - VulkanBuffer* vulkanBuffer = ((VulkanBufferContainer*) buffer)->vulkanBuffer; - - VulkanResourceAccessType prevResourceAccess; - VkBufferImageCopy imageCopy; - - /* Cache this so we can restore it later */ - prevResourceAccess = vulkanTexture->resourceAccessType; - - VULKAN_INTERNAL_ImageMemoryBarrier( - renderer, - vulkanCommandBuffer->commandBuffer, - RESOURCE_ACCESS_TRANSFER_READ, - VK_IMAGE_ASPECT_COLOR_BIT, - textureSlice->layer, - 1, - textureSlice->level, - 1, - 0, - vulkanTexture->image, - &vulkanTexture->resourceAccessType - ); - - /* Save texture data to buffer */ - - imageCopy.imageExtent.width = textureSlice->rectangle.w; - imageCopy.imageExtent.height = textureSlice->rectangle.h; - imageCopy.imageExtent.depth = 1; - imageCopy.bufferRowLength = textureSlice->rectangle.w; - imageCopy.bufferImageHeight = textureSlice->rectangle.h; - imageCopy.imageOffset.x = textureSlice->rectangle.x; - imageCopy.imageOffset.y = textureSlice->rectangle.y; - imageCopy.imageOffset.z = textureSlice->depth; - imageCopy.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; - imageCopy.imageSubresource.baseArrayLayer = textureSlice->layer; - imageCopy.imageSubresource.layerCount = 1; - imageCopy.imageSubresource.mipLevel = textureSlice->level; - imageCopy.bufferOffset = 0; - - renderer->vkCmdCopyImageToBuffer( - vulkanCommandBuffer->commandBuffer, - vulkanTexture->image, - AccessMap[vulkanTexture->resourceAccessType].imageLayout, - vulkanBuffer->buffer, - 1, - &imageCopy - ); - - /* Restore the image layout */ - - VULKAN_INTERNAL_ImageMemoryBarrier( - renderer, - vulkanCommandBuffer->commandBuffer, - prevResourceAccess, - VK_IMAGE_ASPECT_COLOR_BIT, - textureSlice->layer, - 1, - textureSlice->level, - 1, - 0, - vulkanTexture->image, - &vulkanTexture->resourceAccessType - ); - - VULKAN_INTERNAL_TrackBuffer(renderer, vulkanCommandBuffer, vulkanBuffer); - VULKAN_INTERNAL_TrackTexture(renderer, vulkanCommandBuffer, vulkanTexture); -} - static void VULKAN_INTERNAL_QueueDestroyTexture( VulkanRenderer *renderer, VulkanTexture *vulkanTexture @@ -8335,9 +7541,9 @@ static void VULKAN_INTERNAL_QueueDestroyBuffer( SDL_UnlockMutex(renderer->disposeLock); } -static void VULKAN_QueueDestroyBuffer( +static void VULKAN_QueueDestroyGpuBuffer( Refresh_Renderer *driverData, - Refresh_Buffer *buffer + Refresh_GpuBuffer *buffer ) { VulkanRenderer *renderer = (VulkanRenderer*) driverData; VulkanBufferContainer *vulkanBufferContainer = (VulkanBufferContainer*) buffer; @@ -8353,6 +7559,20 @@ static void VULKAN_QueueDestroyBuffer( SDL_UnlockMutex(renderer->disposeLock); } +static void VULKAN_QueueDestroyCpuBuffer( + Refresh_Renderer *driverData, + Refresh_CpuBuffer *buffer +) { + VulkanRenderer *renderer = (VulkanRenderer*) driverData; + VulkanBuffer *vulkanBuffer = (VulkanBuffer*) buffer; + + SDL_LockMutex(renderer->disposeLock); + + VULKAN_INTERNAL_QueueDestroyBuffer(renderer, vulkanBuffer); + + SDL_UnlockMutex(renderer->disposeLock); +} + static void VULKAN_QueueDestroyShaderModule( Refresh_Renderer *driverData, Refresh_ShaderModule *shaderModule @@ -9188,7 +8408,7 @@ static void VULKAN_BindVertexBuffers( Refresh_CommandBuffer *commandBuffer, uint32_t firstBinding, uint32_t bindingCount, - Refresh_Buffer **pBuffers, + Refresh_GpuBuffer **pBuffers, uint64_t *pOffsets ) { VulkanRenderer* renderer = (VulkanRenderer*) driverData; @@ -9218,7 +8438,7 @@ static void VULKAN_BindVertexBuffers( static void VULKAN_BindIndexBuffer( Refresh_Renderer *driverData, Refresh_CommandBuffer *commandBuffer, - Refresh_Buffer *buffer, + Refresh_GpuBuffer *buffer, uint64_t offset, Refresh_IndexElementSize indexElementSize ) { @@ -9236,6 +8456,16 @@ static void VULKAN_BindIndexBuffer( ); } +static void VULKAN_BeginComputePass( + Refresh_Renderer *driverData, + Refresh_CommandBuffer *commandBuffer +) { + VulkanCommandBuffer *vulkanCommandBuffer = (VulkanCommandBuffer*) commandBuffer; + + vulkanCommandBuffer->boundComputeBufferCount = 0; + vulkanCommandBuffer->boundComputeTextureCount = 0; +} + static void VULKAN_BindComputePipeline( Refresh_Renderer *driverData, Refresh_CommandBuffer *commandBuffer, @@ -9292,7 +8522,7 @@ static void VULKAN_BindComputePipeline( static void VULKAN_BindComputeBuffers( Refresh_Renderer *driverData, Refresh_CommandBuffer *commandBuffer, - Refresh_Buffer **pBuffers + Refresh_GpuBuffer **pBuffers ) { VulkanRenderer* renderer = (VulkanRenderer*) driverData; VulkanCommandBuffer *vulkanCommandBuffer = (VulkanCommandBuffer*) commandBuffer; @@ -9323,6 +8553,7 @@ static void VULKAN_BindComputeBuffers( ); VULKAN_INTERNAL_TrackBuffer(renderer, vulkanCommandBuffer, currentVulkanBuffer); + VULKAN_INTERNAL_TrackComputeBuffer(renderer, vulkanCommandBuffer, currentVulkanBuffer); } vulkanCommandBuffer->bufferDescriptorSet = @@ -9333,24 +8564,13 @@ static void VULKAN_BindComputeBuffers( NULL, descriptorBufferInfos ); - - if (vulkanCommandBuffer->boundComputeBufferCount == vulkanCommandBuffer->boundComputeBufferCapacity) - { - vulkanCommandBuffer->boundComputeBufferCapacity *= 2; - vulkanCommandBuffer->boundComputeBuffers = SDL_realloc( - vulkanCommandBuffer->boundComputeBuffers, - vulkanCommandBuffer->boundComputeBufferCapacity * sizeof(VulkanBuffer*) - ); - } - - vulkanCommandBuffer->boundComputeBuffers[vulkanCommandBuffer->boundComputeBufferCount] = currentVulkanBuffer; - vulkanCommandBuffer->boundComputeBufferCount += 1; } static void VULKAN_BindComputeTextures( Refresh_Renderer *driverData, Refresh_CommandBuffer *commandBuffer, - Refresh_Texture **pTextures + Refresh_Texture **pTextures, + uint32_t **pLevels ) { VulkanRenderer* renderer = (VulkanRenderer*) driverData; VulkanCommandBuffer *vulkanCommandBuffer = (VulkanCommandBuffer*) commandBuffer; @@ -9387,18 +8607,7 @@ static void VULKAN_BindComputeTextures( ); VULKAN_INTERNAL_TrackTexture(renderer, vulkanCommandBuffer, currentTexture); - - if (vulkanCommandBuffer->boundComputeTextureCount == vulkanCommandBuffer->boundComputeTextureCapacity) - { - vulkanCommandBuffer->boundComputeTextureCapacity *= 2; - vulkanCommandBuffer->boundComputeTextures = SDL_realloc( - vulkanCommandBuffer->boundComputeTextures, - vulkanCommandBuffer->boundComputeTextureCapacity * sizeof(VulkanTexture *) - ); - } - - vulkanCommandBuffer->boundComputeTextures[i] = currentTexture; - vulkanCommandBuffer->boundComputeTextureCount += 1; + VULKAN_INTERNAL_TrackComputeTexture(renderer, vulkanCommandBuffer, currentTexture); } vulkanCommandBuffer->imageDescriptorSet = @@ -9411,6 +8620,794 @@ static void VULKAN_BindComputeTextures( ); } +static void VULKAN_DispatchCompute( + Refresh_Renderer *driverData, + Refresh_CommandBuffer *commandBuffer, + uint32_t groupCountX, + uint32_t groupCountY, + uint32_t groupCountZ, + uint32_t computeParamOffset +) { + VulkanRenderer* renderer = (VulkanRenderer*) driverData; + VulkanCommandBuffer *vulkanCommandBuffer = (VulkanCommandBuffer*) commandBuffer; + VulkanComputePipeline *computePipeline = vulkanCommandBuffer->currentComputePipeline; + VkDescriptorSet descriptorSets[3]; + + descriptorSets[0] = vulkanCommandBuffer->bufferDescriptorSet; + descriptorSets[1] = vulkanCommandBuffer->imageDescriptorSet; + descriptorSets[2] = vulkanCommandBuffer->computeUniformBuffer->descriptorSet; + + renderer->vkCmdBindDescriptorSets( + vulkanCommandBuffer->commandBuffer, + VK_PIPELINE_BIND_POINT_COMPUTE, + computePipeline->pipelineLayout->pipelineLayout, + 0, + 3, + descriptorSets, + 1, + &computeParamOffset + ); + + renderer->vkCmdDispatch( + vulkanCommandBuffer->commandBuffer, + groupCountX, + groupCountY, + groupCountZ + ); +} + +static void VULKAN_EndComputePass( + Refresh_Renderer *driverData, + Refresh_CommandBuffer *commandBuffer +) { + VulkanRenderer *renderer = (VulkanRenderer*) driverData; + VulkanCommandBuffer *vulkanCommandBuffer = (VulkanCommandBuffer*) commandBuffer; + VulkanBuffer *currentComputeBuffer; + VulkanTexture *currentComputeTexture; + VulkanResourceAccessType resourceAccessType = RESOURCE_ACCESS_NONE; + uint32_t i; + + /* Re-transition buffers */ + for (i = 0; i < vulkanCommandBuffer->boundComputeBufferCount; i += 1) + { + currentComputeBuffer = vulkanCommandBuffer->boundComputeBuffers[i]; + + if (currentComputeBuffer->usage & VK_BUFFER_USAGE_VERTEX_BUFFER_BIT) + { + resourceAccessType = RESOURCE_ACCESS_VERTEX_BUFFER; + } + else if (currentComputeBuffer->usage & VK_BUFFER_USAGE_INDEX_BUFFER_BIT) + { + resourceAccessType = RESOURCE_ACCESS_INDEX_BUFFER; + } + else if (currentComputeBuffer->usage & VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT) + { + resourceAccessType = RESOURCE_ACCESS_INDIRECT_BUFFER; + } + + if (resourceAccessType != RESOURCE_ACCESS_NONE) + { + VULKAN_INTERNAL_BufferMemoryBarrier( + renderer, + vulkanCommandBuffer->commandBuffer, + resourceAccessType, + currentComputeBuffer + ); + } + } + + /* Re-transition sampler images */ + for (i = 0; i < vulkanCommandBuffer->boundComputeTextureCount; i += 1) + { + currentComputeTexture = vulkanCommandBuffer->boundComputeTextures[i]; + + if (currentComputeTexture->usageFlags & VK_IMAGE_USAGE_SAMPLED_BIT) + { + resourceAccessType = RESOURCE_ACCESS_ANY_SHADER_READ_SAMPLED_IMAGE; + + VULKAN_INTERNAL_ImageMemoryBarrier( + renderer, + vulkanCommandBuffer->commandBuffer, + resourceAccessType, + currentComputeTexture->aspectFlags, + 0, + currentComputeTexture->layerCount, + 0, + currentComputeTexture->levelCount, + 0, + currentComputeTexture->image, + ¤tComputeTexture->resourceAccessType + ); + } + } +} + +static void* VULKAN_MapCpuBuffer( + Refresh_Renderer *driverData, + Refresh_CpuBuffer *buffer, + uint32_t offsetInBytes, + uint32_t sizeInBytes +) { + VulkanRenderer *renderer = (VulkanRenderer*) driverData; + VulkanBuffer *vulkanBuffer = (VulkanBuffer*) buffer; + VkResult result; + void* mapPointer; + + result = renderer->vkMapMemory( + renderer->logicalDevice, + vulkanBuffer->usedRegion->allocation->memory, + offsetInBytes, + sizeInBytes, + 0, + &mapPointer + ); + VULKAN_ERROR_CHECK(result, vkMapMemory, NULL) + + return mapPointer; +} + +static void VULKAN_UnmapCpuBuffer( + Refresh_Renderer *driverData, + Refresh_CpuBuffer *buffer +) { + VulkanRenderer *renderer = (VulkanRenderer*) driverData; + VulkanBuffer *vulkanBuffer = (VulkanBuffer*) buffer; + + renderer->vkUnmapMemory( + renderer->logicalDevice, + vulkanBuffer->usedRegion->allocation->memory + ); +} + +static void VULKAN_BeginCopyPass( + Refresh_Renderer *driverData, + Refresh_CommandBuffer *commandBuffer +) { + VulkanRenderer *renderer = (VulkanRenderer*) driverData; + VulkanCommandBuffer *vulkanCommandBuffer = (VulkanCommandBuffer*) commandBuffer; + + vulkanCommandBuffer->copiedGpuBufferCount = 0; + vulkanCommandBuffer->copiedTextureCount = 0; +} + +static void VULKAN_UploadToTexture( + Refresh_Renderer *driverData, + Refresh_CommandBuffer *commandBuffer, + Refresh_CpuBuffer *cpuBuffer, + Refresh_TextureSlice *textureSlice, + Refresh_BufferImageCopy *copyParams +) { + VulkanRenderer *renderer = (VulkanRenderer*) driverData; + VulkanCommandBuffer *vulkanCommandBuffer = (VulkanCommandBuffer*) commandBuffer; + VulkanBuffer *vulkanCpuBuffer = (VulkanBuffer*) cpuBuffer; + VulkanTexture *vulkanTexture = ((VulkanTextureContainer*) textureSlice->texture)->vulkanTexture; + VkBufferImageCopy imageCopy; + + VULKAN_INTERNAL_BufferMemoryBarrier( + renderer, + vulkanCommandBuffer->commandBuffer, + RESOURCE_ACCESS_TRANSFER_READ, + vulkanCpuBuffer + ); + + VULKAN_INTERNAL_ImageMemoryBarrier( + renderer, + vulkanCommandBuffer->commandBuffer, + RESOURCE_ACCESS_TRANSFER_WRITE, + vulkanTexture->aspectFlags, + 0, + vulkanTexture->layerCount, + 0, + vulkanTexture->levelCount, + 0, + vulkanTexture->image, + &vulkanTexture->resourceAccessType + ); + + imageCopy.imageExtent.width = textureSlice->w; + imageCopy.imageExtent.height = textureSlice->h; + imageCopy.imageExtent.depth = textureSlice->d; + imageCopy.imageOffset.x = textureSlice->x; + imageCopy.imageOffset.y = textureSlice->y; + imageCopy.imageOffset.z = textureSlice->z; + imageCopy.imageSubresource.aspectMask = vulkanTexture->aspectFlags; + imageCopy.imageSubresource.baseArrayLayer = textureSlice->baseLayer; + imageCopy.imageSubresource.layerCount = textureSlice->layerCount; + imageCopy.imageSubresource.mipLevel = textureSlice->mipLevel; + imageCopy.bufferOffset = copyParams->bufferOffset; + imageCopy.bufferRowLength = copyParams->bufferStride; + imageCopy.bufferImageHeight = copyParams->bufferImageHeight; + + renderer->vkCmdCopyBufferToImage( + vulkanCommandBuffer->commandBuffer, + vulkanCpuBuffer->buffer, + vulkanTexture->image, + AccessMap[vulkanTexture->resourceAccessType].imageLayout, + 1, + &imageCopy + ); + + VULKAN_INTERNAL_TrackBuffer(renderer, vulkanCommandBuffer, vulkanCpuBuffer); + VULKAN_INTERNAL_TrackTexture(renderer, vulkanCommandBuffer, vulkanTexture); + VULKAN_INTERNAL_TrackCopiedTexture(renderer, vulkanCommandBuffer, vulkanTexture); +} + +static void VULKAN_UploadToBuffer( + Refresh_Renderer *driverData, + Refresh_CommandBuffer *commandBuffer, + Refresh_CpuBuffer *cpuBuffer, + Refresh_GpuBuffer *gpuBuffer, + Refresh_BufferCopy *copyParams +) { + VulkanRenderer *renderer = (VulkanRenderer*) driverData; + VulkanCommandBuffer *vulkanCommandBuffer = (VulkanCommandBuffer*) commandBuffer; + VulkanBuffer *vulkanCpuBuffer = (VulkanBuffer*) cpuBuffer; + VulkanBuffer *vulkanGpuBuffer = ((VulkanBufferContainer*) gpuBuffer)->vulkanBuffer; + VkBufferCopy bufferCopy; + + VULKAN_INTERNAL_BufferMemoryBarrier( + renderer, + vulkanCommandBuffer->commandBuffer, + RESOURCE_ACCESS_TRANSFER_READ, + vulkanCpuBuffer + ); + + VULKAN_INTERNAL_BufferMemoryBarrier( + renderer, + vulkanCommandBuffer->commandBuffer, + RESOURCE_ACCESS_TRANSFER_WRITE, + vulkanGpuBuffer + ); + + bufferCopy.srcOffset = copyParams->srcOffset; + bufferCopy.dstOffset = copyParams->dstOffset; + bufferCopy.size = copyParams->size; + + renderer->vkCmdCopyBuffer( + vulkanCommandBuffer->commandBuffer, + vulkanCpuBuffer->buffer, + vulkanGpuBuffer->buffer, + 1, + &bufferCopy + ); + + VULKAN_INTERNAL_TrackBuffer(renderer, vulkanCommandBuffer, vulkanCpuBuffer); + VULKAN_INTERNAL_TrackBuffer(renderer, vulkanCommandBuffer, vulkanGpuBuffer); + VULKAN_INTERNAL_TrackCopiedBuffer(renderer, vulkanCommandBuffer, vulkanGpuBuffer); +} + +static void VULKAN_DownloadFromTexture( + Refresh_Renderer *driverData, + Refresh_CommandBuffer *commandBuffer, + Refresh_TextureSlice *textureSlice, + Refresh_CpuBuffer *cpuBuffer, + Refresh_BufferImageCopy *copyParams +) { + VulkanRenderer *renderer = (VulkanRenderer*) driverData; + VulkanCommandBuffer *vulkanCommandBuffer = (VulkanCommandBuffer*) commandBuffer; + VulkanTexture *vulkanTexture = ((VulkanTextureContainer*) textureSlice->texture)->vulkanTexture; + VulkanBuffer *vulkanCpuBuffer = (VulkanBuffer*) cpuBuffer; + VkBufferImageCopy imageCopy; + + VULKAN_INTERNAL_BufferMemoryBarrier( + renderer, + vulkanCommandBuffer->commandBuffer, + RESOURCE_ACCESS_TRANSFER_WRITE, + vulkanCpuBuffer + ); + + VULKAN_INTERNAL_ImageMemoryBarrier( + renderer, + vulkanCommandBuffer->commandBuffer, + RESOURCE_ACCESS_TRANSFER_READ, + vulkanTexture->aspectFlags, + 0, + vulkanTexture->layerCount, + 0, + vulkanTexture->levelCount, + 0, + vulkanTexture->image, + &vulkanTexture->resourceAccessType + ); + + imageCopy.imageExtent.width = textureSlice->w; + imageCopy.imageExtent.height = textureSlice->h; + imageCopy.imageExtent.depth = textureSlice->d; + imageCopy.imageOffset.x = textureSlice->x; + imageCopy.imageOffset.y = textureSlice->y; + imageCopy.imageOffset.z = textureSlice->z; + imageCopy.imageSubresource.aspectMask = vulkanTexture->aspectFlags; + imageCopy.imageSubresource.baseArrayLayer = textureSlice->baseLayer; + imageCopy.imageSubresource.layerCount = textureSlice->layerCount; + imageCopy.imageSubresource.mipLevel = textureSlice->mipLevel; + imageCopy.bufferOffset = copyParams->bufferOffset; + imageCopy.bufferRowLength = copyParams->bufferStride; + imageCopy.bufferImageHeight = copyParams->bufferImageHeight; + + renderer->vkCmdCopyImageToBuffer( + vulkanCommandBuffer->commandBuffer, + vulkanTexture->image, + AccessMap[vulkanTexture->resourceAccessType].imageLayout, + vulkanCpuBuffer->buffer, + 1, + &imageCopy + ); + + VULKAN_INTERNAL_TrackBuffer(renderer, vulkanCommandBuffer, vulkanCpuBuffer); + VULKAN_INTERNAL_TrackTexture(renderer, vulkanCommandBuffer, vulkanTexture); + VULKAN_INTERNAL_TrackCopiedTexture(renderer, vulkanCommandBuffer, vulkanTexture); +} + +static void VULKAN_DownloadFromBuffer( + Refresh_Renderer *driverData, + Refresh_CommandBuffer *commandBuffer, + Refresh_GpuBuffer *gpuBuffer, + Refresh_CpuBuffer *cpuBuffer, + Refresh_BufferCopy *copyParams +) { + VulkanRenderer *renderer = (VulkanRenderer*) driverData; + VulkanCommandBuffer *vulkanCommandBuffer = (VulkanCommandBuffer*) commandBuffer; + VulkanBuffer *vulkanCpuBuffer = (VulkanBuffer*) cpuBuffer; + VulkanBuffer *vulkanGpuBuffer = ((VulkanBufferContainer*) gpuBuffer)->vulkanBuffer; + VkBufferCopy bufferCopy; + + VULKAN_INTERNAL_BufferMemoryBarrier( + renderer, + vulkanCommandBuffer->commandBuffer, + RESOURCE_ACCESS_TRANSFER_WRITE, + vulkanCpuBuffer + ); + + VULKAN_INTERNAL_BufferMemoryBarrier( + renderer, + vulkanCommandBuffer->commandBuffer, + RESOURCE_ACCESS_TRANSFER_READ, + vulkanGpuBuffer + ); + + bufferCopy.srcOffset = copyParams->srcOffset; + bufferCopy.dstOffset = copyParams->dstOffset; + bufferCopy.size = copyParams->size; + + renderer->vkCmdCopyBuffer( + vulkanCommandBuffer->commandBuffer, + vulkanGpuBuffer->buffer, + vulkanCpuBuffer->buffer, + 1, + &bufferCopy + ); + + VULKAN_INTERNAL_TrackBuffer(renderer, vulkanCommandBuffer, vulkanCpuBuffer); + VULKAN_INTERNAL_TrackBuffer(renderer, vulkanCommandBuffer, vulkanGpuBuffer); + VULKAN_INTERNAL_TrackBuffer(renderer, vulkanCommandBuffer, vulkanGpuBuffer); +} + +static void VULKAN_CopyTextureToTexture( + Refresh_Renderer *driverData, + Refresh_CommandBuffer *commandBuffer, + Refresh_TextureSlice *source, + Refresh_TextureSlice *destination +) { + VulkanRenderer *renderer = (VulkanRenderer*) driverData; + VulkanCommandBuffer *vulkanCommandBuffer = (VulkanCommandBuffer*) commandBuffer; + VulkanTexture *srcTexture = ((VulkanTextureContainer*) source->texture)->vulkanTexture; + VulkanTexture *dstTexture = ((VulkanTextureContainer*) destination->texture)->vulkanTexture; + VkImageCopy imageCopy; + + VULKAN_INTERNAL_ImageMemoryBarrier( + renderer, + vulkanCommandBuffer->commandBuffer, + RESOURCE_ACCESS_TRANSFER_READ, + VK_IMAGE_ASPECT_COLOR_BIT, + 0, + srcTexture->layerCount, + 0, + srcTexture->levelCount, + 0, + srcTexture->image, + &srcTexture->resourceAccessType + ); + + VULKAN_INTERNAL_ImageMemoryBarrier( + renderer, + vulkanCommandBuffer->commandBuffer, + RESOURCE_ACCESS_TRANSFER_WRITE, + VK_IMAGE_ASPECT_COLOR_BIT, + 0, + dstTexture->layerCount, + 0, + dstTexture->levelCount, + 0, + dstTexture->image, + &dstTexture->resourceAccessType + ); + + imageCopy.srcOffset.x = source->x; + imageCopy.srcOffset.y = source->y; + imageCopy.srcOffset.z = source->z; + imageCopy.srcSubresource.aspectMask = srcTexture->aspectFlags; + imageCopy.srcSubresource.baseArrayLayer = source->baseLayer; + imageCopy.srcSubresource.layerCount = source->layerCount; + imageCopy.srcSubresource.mipLevel = source->mipLevel; + imageCopy.dstOffset.x = destination->x; + imageCopy.dstOffset.y = destination->y; + imageCopy.dstOffset.z = destination->z; + imageCopy.dstSubresource.aspectMask = dstTexture->aspectFlags; + imageCopy.dstSubresource.baseArrayLayer = destination->baseLayer; + imageCopy.dstSubresource.layerCount = destination->layerCount; + imageCopy.dstSubresource.mipLevel = destination->mipLevel; + imageCopy.extent.width = source->w; + imageCopy.extent.height = source->h; + imageCopy.extent.depth = source->d; + + renderer->vkCmdCopyImage( + vulkanCommandBuffer->commandBuffer, + srcTexture->image, + AccessMap[srcTexture->resourceAccessType].imageLayout, + dstTexture->image, + AccessMap[dstTexture->resourceAccessType].imageLayout, + 1, + &imageCopy + ); + + VULKAN_INTERNAL_TrackTexture(renderer, vulkanCommandBuffer, srcTexture); + VULKAN_INTERNAL_TrackTexture(renderer, vulkanCommandBuffer, dstTexture); + VULKAN_INTERNAL_TrackCopiedTexture(renderer, vulkanCommandBuffer, srcTexture); + VULKAN_INTERNAL_TrackCopiedTexture(renderer, vulkanCommandBuffer, dstTexture); +} + +static void VULKAN_CopyTextureToBuffer( + Refresh_Renderer *driverData, + Refresh_CommandBuffer *commandBuffer, + Refresh_TextureSlice *textureSlice, + Refresh_GpuBuffer *buffer, + Refresh_BufferImageCopy *copyParams +) { + VulkanRenderer *renderer = (VulkanRenderer*) driverData; + VulkanCommandBuffer *vulkanCommandBuffer = (VulkanCommandBuffer*) commandBuffer; + VulkanTexture *vulkanTexture = ((VulkanTextureContainer*) textureSlice->texture)->vulkanTexture; + VulkanBuffer *vulkanBuffer = ((VulkanBufferContainer*) buffer)->vulkanBuffer; + VkBufferImageCopy imageCopy; + + VULKAN_INTERNAL_ImageMemoryBarrier( + renderer, + vulkanCommandBuffer->commandBuffer, + RESOURCE_ACCESS_TRANSFER_READ, + vulkanTexture->aspectFlags, + 0, + vulkanTexture->layerCount, + 0, + vulkanTexture->levelCount, + 0, + vulkanTexture->image, + &vulkanTexture->resourceAccessType + ); + + VULKAN_INTERNAL_BufferMemoryBarrier( + renderer, + vulkanCommandBuffer->commandBuffer, + RESOURCE_ACCESS_TRANSFER_WRITE, + vulkanBuffer + ); + + imageCopy.imageExtent.width = textureSlice->w; + imageCopy.imageExtent.height = textureSlice->h; + imageCopy.imageExtent.depth = textureSlice->d; + imageCopy.imageOffset.x = textureSlice->x; + imageCopy.imageOffset.y = textureSlice->y; + imageCopy.imageOffset.z = textureSlice->z; + imageCopy.imageSubresource.aspectMask = vulkanTexture->aspectFlags; + imageCopy.imageSubresource.baseArrayLayer = textureSlice->baseLayer; + imageCopy.imageSubresource.layerCount = textureSlice->layerCount; + imageCopy.imageSubresource.mipLevel = textureSlice->mipLevel; + imageCopy.bufferOffset = copyParams->bufferOffset; + imageCopy.bufferRowLength = copyParams->bufferStride; + imageCopy.bufferImageHeight = copyParams->bufferImageHeight; + + renderer->vkCmdCopyImageToBuffer( + vulkanCommandBuffer->commandBuffer, + vulkanTexture->image, + AccessMap[vulkanTexture->resourceAccessType].imageLayout, + vulkanBuffer->buffer, + 1, + &imageCopy + ); + + VULKAN_INTERNAL_TrackBuffer(renderer, vulkanCommandBuffer, vulkanBuffer); + VULKAN_INTERNAL_TrackTexture(renderer, vulkanCommandBuffer, vulkanTexture); + VULKAN_INTERNAL_TrackCopiedBuffer(renderer, vulkanCommandBuffer, vulkanBuffer); + VULKAN_INTERNAL_TrackCopiedTexture(renderer, vulkanCommandBuffer, vulkanTexture); +} + +static void VULKAN_CopyBufferToTexture( + Refresh_Renderer *driverData, + Refresh_CommandBuffer *commandBuffer, + Refresh_GpuBuffer *buffer, + Refresh_TextureSlice *textureSlice, + Refresh_BufferImageCopy *copyParams +) { + VulkanRenderer *renderer = (VulkanRenderer*) driverData; + VulkanCommandBuffer *vulkanCommandBuffer = (VulkanCommandBuffer*) commandBuffer; + VulkanBuffer *vulkanBuffer = ((VulkanBufferContainer*) buffer)->vulkanBuffer; + VulkanTexture *vulkanTexture = ((VulkanTextureContainer*) textureSlice->texture)->vulkanTexture; + VkBufferImageCopy imageCopy; + + VULKAN_INTERNAL_BufferMemoryBarrier( + renderer, + vulkanCommandBuffer->commandBuffer, + RESOURCE_ACCESS_TRANSFER_READ, + vulkanBuffer + ); + + VULKAN_INTERNAL_ImageMemoryBarrier( + renderer, + vulkanCommandBuffer->commandBuffer, + RESOURCE_ACCESS_TRANSFER_WRITE, + vulkanTexture->aspectFlags, + 0, + vulkanTexture->layerCount, + 0, + vulkanTexture->levelCount, + 0, + vulkanTexture->image, + &vulkanTexture->resourceAccessType + ); + + imageCopy.imageExtent.width = textureSlice->w; + imageCopy.imageExtent.height = textureSlice->h; + imageCopy.imageExtent.depth = textureSlice->d; + imageCopy.imageOffset.x = textureSlice->x; + imageCopy.imageOffset.y = textureSlice->y; + imageCopy.imageOffset.z = textureSlice->z; + imageCopy.imageSubresource.aspectMask = vulkanTexture->aspectFlags; + imageCopy.imageSubresource.baseArrayLayer = textureSlice->baseLayer; + imageCopy.imageSubresource.layerCount = textureSlice->layerCount; + imageCopy.imageSubresource.mipLevel = textureSlice->mipLevel; + imageCopy.bufferOffset = copyParams->bufferOffset; + imageCopy.bufferRowLength = copyParams->bufferStride; + imageCopy.bufferImageHeight = copyParams->bufferImageHeight; + + renderer->vkCmdCopyBufferToImage( + vulkanCommandBuffer->commandBuffer, + vulkanBuffer->buffer, + vulkanTexture->image, + AccessMap[vulkanTexture->resourceAccessType].imageLayout, + 1, + &imageCopy + ); + + VULKAN_INTERNAL_TrackBuffer(renderer, vulkanCommandBuffer, vulkanBuffer); + VULKAN_INTERNAL_TrackTexture(renderer, vulkanCommandBuffer, vulkanTexture); + VULKAN_INTERNAL_TrackCopiedBuffer(renderer, vulkanCommandBuffer, vulkanBuffer); + VULKAN_INTERNAL_TrackCopiedTexture(renderer, vulkanCommandBuffer, vulkanTexture); +} + +static void VULKAN_CopyBufferToBuffer( + Refresh_Renderer *driverData, + Refresh_CommandBuffer *commandBuffer, + Refresh_GpuBuffer *source, + Refresh_GpuBuffer *destination, + Refresh_BufferCopy *copyParams +) { + VulkanRenderer *renderer = (VulkanRenderer*) driverData; + VulkanCommandBuffer *vulkanCommandBuffer = (VulkanCommandBuffer*) commandBuffer; + VulkanBuffer *vulkanSrcBuffer = ((VulkanBufferContainer*) source)->vulkanBuffer; + VulkanBuffer *vulkanDstBuffer = ((VulkanBufferContainer*) destination)->vulkanBuffer; + VkBufferCopy bufferCopy; + + VULKAN_INTERNAL_BufferMemoryBarrier( + renderer, + vulkanCommandBuffer->commandBuffer, + RESOURCE_ACCESS_TRANSFER_READ, + vulkanSrcBuffer + ); + + VULKAN_INTERNAL_BufferMemoryBarrier( + renderer, + vulkanCommandBuffer->commandBuffer, + RESOURCE_ACCESS_TRANSFER_WRITE, + vulkanDstBuffer + ); + + bufferCopy.srcOffset = copyParams->srcOffset; + bufferCopy.dstOffset = copyParams->dstOffset; + bufferCopy.size = copyParams->size; + + renderer->vkCmdCopyBuffer( + vulkanCommandBuffer->commandBuffer, + vulkanSrcBuffer->buffer, + vulkanDstBuffer->buffer, + 1, + &bufferCopy + ); + + VULKAN_INTERNAL_TrackBuffer(renderer, vulkanCommandBuffer, vulkanSrcBuffer); + VULKAN_INTERNAL_TrackBuffer(renderer, vulkanCommandBuffer, vulkanDstBuffer); + VULKAN_INTERNAL_TrackCopiedBuffer(renderer, vulkanCommandBuffer, vulkanSrcBuffer); + VULKAN_INTERNAL_TrackCopiedBuffer(renderer, vulkanCommandBuffer, vulkanDstBuffer); +} + +static void VULKAN_GenerateMipmaps( + Refresh_Renderer *driverData, + Refresh_CommandBuffer *commandBuffer, + Refresh_Texture *texture +) { + VulkanRenderer *renderer = (VulkanRenderer*) driverData; + VulkanCommandBuffer *vulkanCommandBuffer = (VulkanCommandBuffer*) commandBuffer; + VulkanTexture *vulkanTexture = ((VulkanTextureContainer*) texture)->vulkanTexture; + VulkanResourceAccessType *levelAccessType; + VkImageBlit blit; + uint32_t level; + + if (vulkanTexture->levelCount <= 1) { return; } + + /* Store the original image layout... */ + levelAccessType = SDL_stack_alloc( + VulkanResourceAccessType, + vulkanTexture->levelCount + ); + + for (level = 0; level < vulkanTexture->levelCount; level += 1) + { + levelAccessType[level] = vulkanTexture->resourceAccessType; + } + + /* Blit each mip sequentially. Barriers, barriers everywhere! */ + for (level = 1; level < vulkanTexture->levelCount; level += 1) + { + VULKAN_INTERNAL_ImageMemoryBarrier( + renderer, + vulkanCommandBuffer->commandBuffer, + RESOURCE_ACCESS_TRANSFER_READ, + VK_IMAGE_ASPECT_COLOR_BIT, + 0, + vulkanTexture->layerCount, + level - 1, + 1, + 0, + vulkanTexture->image, + &levelAccessType[level - 1] + ); + + VULKAN_INTERNAL_ImageMemoryBarrier( + renderer, + vulkanCommandBuffer->commandBuffer, + RESOURCE_ACCESS_TRANSFER_WRITE, + VK_IMAGE_ASPECT_COLOR_BIT, + 0, + vulkanTexture->layerCount, + level, + 1, + 1, + vulkanTexture->image, + &levelAccessType[level] + ); + + blit.srcOffsets[0].x = 0; + blit.srcOffsets[0].y = 0; + blit.srcOffsets[0].z = 0; + + blit.srcOffsets[1].x = vulkanTexture->dimensions.width >> (level - 1); + blit.srcOffsets[1].y = vulkanTexture->dimensions.height >> (level - 1); + blit.srcOffsets[1].z = 1; + + blit.dstOffsets[0].x = 0; + blit.dstOffsets[0].y = 0; + blit.dstOffsets[0].z = 0; + + blit.dstOffsets[1].x = vulkanTexture->dimensions.width >> level; + blit.dstOffsets[1].y = vulkanTexture->dimensions.height >> level; + blit.dstOffsets[1].z = 1; + + blit.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; + blit.srcSubresource.baseArrayLayer = 0; + blit.srcSubresource.layerCount = vulkanTexture->layerCount; + blit.srcSubresource.mipLevel = level - 1; + + blit.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; + blit.dstSubresource.baseArrayLayer = 0; + blit.dstSubresource.layerCount = vulkanTexture->layerCount; + blit.dstSubresource.mipLevel = level; + + renderer->vkCmdBlitImage( + vulkanCommandBuffer->commandBuffer, + vulkanTexture->image, + VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, + vulkanTexture->image, + VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, + 1, + &blit, + VK_FILTER_LINEAR + ); + } + + /* Transition final level to READ */ + VULKAN_INTERNAL_ImageMemoryBarrier( + renderer, + vulkanCommandBuffer->commandBuffer, + RESOURCE_ACCESS_TRANSFER_READ, + VK_IMAGE_ASPECT_COLOR_BIT, + 0, + vulkanTexture->layerCount, + vulkanTexture->levelCount - 1, + 1, + 1, + vulkanTexture->image, + &levelAccessType[vulkanTexture->levelCount - 1] + ); + + /* The whole texture is in READ layout now, so set the access type on the texture */ + vulkanTexture->resourceAccessType = RESOURCE_ACCESS_TRANSFER_READ; + + SDL_stack_free(levelAccessType); +} + +static void VULKAN_EndCopyPass( + Refresh_Renderer *driverData, + Refresh_CommandBuffer *commandBuffer +) { + VulkanRenderer *renderer = (VulkanRenderer*) driverData; + VulkanCommandBuffer *vulkanCommandBuffer = (VulkanCommandBuffer*) commandBuffer; + VulkanBuffer *currentBuffer; + VulkanTexture *currentTexture; + VulkanResourceAccessType resourceAccessType = RESOURCE_ACCESS_NONE; + uint32_t i; + + /* Re-transition GpuBuffers */ + for (i = 0; i < vulkanCommandBuffer->copiedGpuBufferCount; i += 1) + { + currentBuffer = vulkanCommandBuffer->copiedGpuBuffers[i]; + + if (currentBuffer->usage & VK_BUFFER_USAGE_VERTEX_BUFFER_BIT) + { + resourceAccessType = RESOURCE_ACCESS_VERTEX_BUFFER; + } + else if (currentBuffer->usage & VK_BUFFER_USAGE_INDEX_BUFFER_BIT) + { + resourceAccessType = RESOURCE_ACCESS_INDEX_BUFFER; + } + else if (currentBuffer->usage & VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT) + { + resourceAccessType = RESOURCE_ACCESS_INDIRECT_BUFFER; + } + + if (resourceAccessType != RESOURCE_ACCESS_NONE) + { + VULKAN_INTERNAL_BufferMemoryBarrier( + renderer, + vulkanCommandBuffer->commandBuffer, + resourceAccessType, + currentBuffer + ); + } + } + + /* Re-transition textures */ + for (i = 0; i < vulkanCommandBuffer->copiedTextureCount; i += 1) + { + currentTexture = vulkanCommandBuffer->copiedTextures[i]; + + if (currentTexture->usageFlags & VK_IMAGE_USAGE_SAMPLED_BIT) + { + resourceAccessType = RESOURCE_ACCESS_ANY_SHADER_READ_SAMPLED_IMAGE; + + VULKAN_INTERNAL_ImageMemoryBarrier( + renderer, + vulkanCommandBuffer->commandBuffer, + resourceAccessType, + currentTexture->aspectFlags, + 0, + currentTexture->layerCount, + 0, + currentTexture->levelCount, + 0, + currentTexture->image, + ¤tTexture->resourceAccessType + ); + } + } +} + static void VULKAN_INTERNAL_AllocateCommandBuffers( VulkanRenderer *renderer, VulkanCommandPool *vulkanCommandPool, @@ -9478,14 +9475,6 @@ static void VULKAN_INTERNAL_AllocateCommandBuffers( commandBuffer->signalSemaphoreCapacity * sizeof(VkSemaphore) ); - /* Transfer buffer tracking */ - - commandBuffer->transferBufferCapacity = 4; - commandBuffer->transferBufferCount = 0; - commandBuffer->transferBuffers = SDL_malloc( - commandBuffer->transferBufferCapacity * sizeof(VulkanTransferBuffer*) - ); - /* Bound buffer tracking */ commandBuffer->boundUniformBufferCapacity = 16; @@ -9516,6 +9505,20 @@ static void VULKAN_INTERNAL_AllocateCommandBuffers( commandBuffer->boundComputeTextureCapacity * sizeof(VulkanTexture*) ); + /* Copy resource tracking */ + + commandBuffer->copiedGpuBufferCapacity = 16; + commandBuffer->copiedGpuBufferCount = 0; + commandBuffer->copiedGpuBuffers = SDL_malloc( + commandBuffer->copiedGpuBufferCapacity * sizeof(VulkanBuffer*) + ); + + commandBuffer->copiedTextureCapacity = 16; + commandBuffer->copiedTextureCount = 0; + commandBuffer->copiedTextures = SDL_malloc( + commandBuffer->copiedTextureCapacity * sizeof(VulkanTexture*) + ); + /* Resource tracking */ commandBuffer->usedBufferCapacity = 4; @@ -10200,30 +10203,6 @@ static void VULKAN_INTERNAL_CleanCommandBuffer( commandBuffer->boundUniformBufferCount = 0; - /* Clean up transfer buffers */ - - for (i = 0; i < commandBuffer->transferBufferCount; i += 1) - { - if (commandBuffer->transferBuffers[i]->fromPool) - { - SDL_LockMutex(renderer->transferBufferPool.lock); - - commandBuffer->transferBuffers[i]->offset = 0; - renderer->transferBufferPool.availableBuffers[renderer->transferBufferPool.availableBufferCount] = commandBuffer->transferBuffers[i]; - renderer->transferBufferPool.availableBufferCount += 1; - - SDL_UnlockMutex(renderer->transferBufferPool.lock); - } - else - { - VULKAN_INTERNAL_QueueDestroyBuffer(renderer, commandBuffer->transferBuffers[i]->buffer); - SDL_free(commandBuffer->transferBuffers[i]); - commandBuffer->transferBuffers[i] = NULL; - } - } - - commandBuffer->transferBufferCount = 0; - /* Bound descriptor sets are now available */ for (i = 0; i < commandBuffer->boundDescriptorSetDataCount; i += 1) @@ -11717,9 +11696,6 @@ static Refresh_Device* VULKAN_CreateDevice( /* Variables: Image Format Detection */ VkImageFormatProperties imageFormatProperties; - /* Variables: Transfer buffer init */ - VulkanTransferBuffer *transferBuffer; - SDL_memset(renderer, '\0', sizeof(VulkanRenderer)); renderer->debugMode = debugMode; @@ -12102,41 +12078,6 @@ static Refresh_Device* VULKAN_CreateDevice( renderer->renderTargetHashArray.count = 0; renderer->renderTargetHashArray.capacity = 0; - /* Initialize transfer buffer pool */ - - renderer->transferBufferPool.lock = SDL_CreateMutex(); - - renderer->transferBufferPool.availableBufferCapacity = 4; - renderer->transferBufferPool.availableBufferCount = 0; - renderer->transferBufferPool.availableBuffers = SDL_malloc( - renderer->transferBufferPool.availableBufferCapacity * sizeof(VulkanTransferBuffer*) - ); - - for (i = 0; i < renderer->transferBufferPool.availableBufferCapacity; i += 1) - { - transferBuffer = SDL_malloc(sizeof(VulkanTransferBuffer)); - transferBuffer->offset = 0; - transferBuffer->fromPool = 1; - transferBuffer->buffer = VULKAN_INTERNAL_CreateBuffer( - renderer, - POOLED_TRANSFER_BUFFER_SIZE, - RESOURCE_ACCESS_TRANSFER_READ_WRITE, - VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT, - 1, - 0, - 1 - ); - - if (transferBuffer->buffer == NULL) - { - Refresh_LogError("Failed to allocate transfer buffer!"); - SDL_free(transferBuffer); - } - - renderer->transferBufferPool.availableBuffers[i] = transferBuffer; - renderer->transferBufferPool.availableBufferCount += 1; - } - /* Initialize fence pool */ renderer->fencePool.lock = SDL_CreateMutex(); -- 2.25.1 From 86099fb7ee178b7dbd3abe90cc03f155041edc47 Mon Sep 17 00:00:00 2001 From: cosmonaut Date: Thu, 15 Feb 2024 20:13:26 -0800 Subject: [PATCH 02/20] remove ignored memory property flags --- src/Refresh_Driver_Vulkan.c | 36 ++++++++++-------------------------- 1 file changed, 10 insertions(+), 26 deletions(-) diff --git a/src/Refresh_Driver_Vulkan.c b/src/Refresh_Driver_Vulkan.c index b4f2f83..749d564 100644 --- a/src/Refresh_Driver_Vulkan.c +++ b/src/Refresh_Driver_Vulkan.c @@ -2365,7 +2365,6 @@ static uint8_t VULKAN_INTERNAL_FindMemoryType( VulkanRenderer *renderer, uint32_t typeFilter, VkMemoryPropertyFlags requiredProperties, - VkMemoryPropertyFlags ignoredProperties, uint32_t *memoryTypeIndex ) { uint32_t i; @@ -2373,8 +2372,7 @@ static uint8_t VULKAN_INTERNAL_FindMemoryType( for (i = *memoryTypeIndex; i < renderer->memoryProperties.memoryTypeCount; i += 1) { if ( (typeFilter & (1 << i)) && - (renderer->memoryProperties.memoryTypes[i].propertyFlags & requiredProperties) == requiredProperties && - (renderer->memoryProperties.memoryTypes[i].propertyFlags & ignoredProperties) == 0 ) + (renderer->memoryProperties.memoryTypes[i].propertyFlags & requiredProperties) == requiredProperties) { *memoryTypeIndex = i; return 1; @@ -2388,7 +2386,6 @@ static uint8_t VULKAN_INTERNAL_FindBufferMemoryRequirements( VulkanRenderer *renderer, VkBuffer buffer, VkMemoryPropertyFlags requiredMemoryProperties, - VkMemoryPropertyFlags ignoredMemoryProperties, VkMemoryRequirements2KHR *pMemoryRequirements, uint32_t *pMemoryTypeIndex ) { @@ -2408,7 +2405,6 @@ static uint8_t VULKAN_INTERNAL_FindBufferMemoryRequirements( renderer, pMemoryRequirements->memoryRequirements.memoryTypeBits, requiredMemoryProperties, - ignoredMemoryProperties, pMemoryTypeIndex ); } @@ -2417,7 +2413,6 @@ static uint8_t VULKAN_INTERNAL_FindImageMemoryRequirements( VulkanRenderer *renderer, VkImage image, VkMemoryPropertyFlags requiredMemoryPropertyFlags, - VkMemoryPropertyFlags ignoredMemoryPropertyFlags, VkMemoryRequirements2KHR *pMemoryRequirements, uint32_t *pMemoryTypeIndex ) { @@ -2437,7 +2432,6 @@ static uint8_t VULKAN_INTERNAL_FindImageMemoryRequirements( renderer, pMemoryRequirements->memoryRequirements.memoryTypeBits, requiredMemoryPropertyFlags, - ignoredMemoryPropertyFlags, pMemoryTypeIndex ); } @@ -2859,22 +2853,19 @@ static uint8_t VULKAN_INTERNAL_BindMemoryForImage( uint8_t bindResult = 0; uint32_t memoryTypeIndex = 0; VkMemoryPropertyFlags requiredMemoryPropertyFlags; - VkMemoryPropertyFlags ignoredMemoryPropertyFlags; VkMemoryRequirements2KHR memoryRequirements = { VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2_KHR, NULL }; - /* Prefer GPU allocation */ + /* Prefer GPU allocation for textures */ requiredMemoryPropertyFlags = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT; - ignoredMemoryPropertyFlags = 0; while (VULKAN_INTERNAL_FindImageMemoryRequirements( renderer, image, requiredMemoryPropertyFlags, - ignoredMemoryPropertyFlags, &memoryRequirements, &memoryTypeIndex )) { @@ -2904,7 +2895,6 @@ static uint8_t VULKAN_INTERNAL_BindMemoryForImage( { memoryTypeIndex = 0; requiredMemoryPropertyFlags = 0; - ignoredMemoryPropertyFlags = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT; if (isRenderTarget) { @@ -2917,7 +2907,6 @@ static uint8_t VULKAN_INTERNAL_BindMemoryForImage( renderer, image, requiredMemoryPropertyFlags, - ignoredMemoryPropertyFlags, &memoryRequirements, &memoryTypeIndex )) { @@ -2958,7 +2947,6 @@ static uint8_t VULKAN_INTERNAL_BindMemoryForBuffer( uint8_t bindResult = 0; uint32_t memoryTypeIndex = 0; VkMemoryPropertyFlags requiredMemoryPropertyFlags = 0; - VkMemoryPropertyFlags ignoredMemoryPropertyFlags = 0; VkMemoryRequirements2KHR memoryRequirements = { VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2_KHR, @@ -2971,24 +2959,17 @@ static uint8_t VULKAN_INTERNAL_BindMemoryForBuffer( VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT; } - else - { - ignoredMemoryPropertyFlags = - VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT; - } if (preferDeviceLocal) { requiredMemoryPropertyFlags |= VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT; } - ignoredMemoryPropertyFlags = 0; while (VULKAN_INTERNAL_FindBufferMemoryRequirements( renderer, buffer, requiredMemoryPropertyFlags, - ignoredMemoryPropertyFlags, &memoryRequirements, &memoryTypeIndex )) { @@ -3013,14 +2994,18 @@ static uint8_t VULKAN_INTERNAL_BindMemoryForBuffer( } } - /* Bind failed, try again if originally preferred device local */ + /* Bind failed, try again without preferred flags */ if (bindResult != 1) { memoryTypeIndex = 0; + requiredMemoryPropertyFlags = 0; - requiredMemoryPropertyFlags = - VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | - VK_MEMORY_PROPERTY_HOST_COHERENT_BIT; + if (requireHostVisible) + { + requiredMemoryPropertyFlags = + VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | + VK_MEMORY_PROPERTY_HOST_COHERENT_BIT; + } /* Follow-up for the warning logged by FindMemoryType */ if (!renderer->unifiedMemoryWarning) @@ -3033,7 +3018,6 @@ static uint8_t VULKAN_INTERNAL_BindMemoryForBuffer( renderer, buffer, requiredMemoryPropertyFlags, - ignoredMemoryPropertyFlags, &memoryRequirements, &memoryTypeIndex )) { -- 2.25.1 From 35d90f8dcb50c407acc56311513b48c4ae4b3aa9 Mon Sep 17 00:00:00 2001 From: cosmonaut Date: Thu, 15 Feb 2024 20:19:36 -0800 Subject: [PATCH 03/20] fix autoReleaseFence race condition --- src/Refresh_Driver_Vulkan.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Refresh_Driver_Vulkan.c b/src/Refresh_Driver_Vulkan.c index 749d564..92d8032 100644 --- a/src/Refresh_Driver_Vulkan.c +++ b/src/Refresh_Driver_Vulkan.c @@ -9661,6 +9661,7 @@ static Refresh_CommandBuffer* VULKAN_AcquireCommandBuffer( commandBuffer->computeUniformBuffer = NULL; commandBuffer->renderPassColorTargetCount = 0; + commandBuffer->autoReleaseFence = 1; /* Reset the command buffer here to avoid resets being called * from a separate thread than where the command buffer was acquired @@ -10322,11 +10323,11 @@ static Refresh_Fence* VULKAN_SubmitAndAcquireFence( ) { VulkanCommandBuffer *vulkanCommandBuffer; - VULKAN_Submit(driverData, commandBuffer); - vulkanCommandBuffer = (VulkanCommandBuffer*) commandBuffer; vulkanCommandBuffer->autoReleaseFence = 0; + VULKAN_Submit(driverData, commandBuffer); + return (Refresh_Fence*) vulkanCommandBuffer->inFlightFence; } @@ -10377,7 +10378,6 @@ static void VULKAN_Submit( VULKAN_INTERNAL_EndCommandBuffer(renderer, vulkanCommandBuffer); - vulkanCommandBuffer->autoReleaseFence = 1; vulkanCommandBuffer->inFlightFence = VULKAN_INTERNAL_AcquireFenceFromPool(renderer); submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; -- 2.25.1 From 4ed50a96c9cfae1ec412057accb6a44ecd98bb08 Mon Sep 17 00:00:00 2001 From: cosmonaut Date: Fri, 16 Feb 2024 15:57:41 -0800 Subject: [PATCH 04/20] move compute reset to EndComputePass --- src/Refresh_Driver_Vulkan.c | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/src/Refresh_Driver_Vulkan.c b/src/Refresh_Driver_Vulkan.c index 92d8032..1083fb8 100644 --- a/src/Refresh_Driver_Vulkan.c +++ b/src/Refresh_Driver_Vulkan.c @@ -5178,19 +5178,6 @@ static void VULKAN_INTERNAL_EndCommandBuffer( ) { VkResult result; - /* Compute pipelines are not explicitly unbound so we have to clean up here */ - if ( commandBuffer->computeUniformBuffer != renderer->dummyComputeUniformBuffer && - commandBuffer->computeUniformBuffer != NULL - ) { - VULKAN_INTERNAL_BindUniformBuffer( - renderer, - commandBuffer, - commandBuffer->computeUniformBuffer - ); - } - commandBuffer->computeUniformBuffer = NULL; - commandBuffer->currentComputePipeline = NULL; - result = renderer->vkEndCommandBuffer( commandBuffer->commandBuffer ); @@ -8704,6 +8691,19 @@ 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; } static void* VULKAN_MapCpuBuffer( -- 2.25.1 From a3d69ace213d7b835a6c3c4e4a02fdd896a568d3 Mon Sep 17 00:00:00 2001 From: cosmonaut Date: Fri, 16 Feb 2024 17:27:33 -0800 Subject: [PATCH 05/20] rework uniform buffer implementation as a ring buffer --- src/Refresh_Driver_Vulkan.c | 700 +++++++----------------------------- 1 file changed, 125 insertions(+), 575 deletions(-) diff --git a/src/Refresh_Driver_Vulkan.c b/src/Refresh_Driver_Vulkan.c index 1083fb8..00bcd2c 100644 --- a/src/Refresh_Driver_Vulkan.c +++ b/src/Refresh_Driver_Vulkan.c @@ -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 ); -- 2.25.1 From 45f5bef3372d22a734bad8c71835ace1dacae5c1 Mon Sep 17 00:00:00 2001 From: cosmonaut Date: Fri, 16 Feb 2024 17:41:12 -0800 Subject: [PATCH 06/20] fix the UBO descriptor range to use UBO_SECTION_SIZE --- src/Refresh_Driver_Vulkan.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Refresh_Driver_Vulkan.c b/src/Refresh_Driver_Vulkan.c index 00bcd2c..7b08f95 100644 --- a/src/Refresh_Driver_Vulkan.c +++ b/src/Refresh_Driver_Vulkan.c @@ -4244,7 +4244,7 @@ static VulkanUniformBufferObject* VULKAN_INTERNAL_CreateUniformBufferObject( /* Update the descriptor set for the first and last time! */ descriptorBufferInfo.buffer = uniformBufferObject->buffer->buffer; descriptorBufferInfo.offset = 0; - descriptorBufferInfo.range = VK_WHOLE_SIZE; + descriptorBufferInfo.range = UBO_SECTION_SIZE; writeDescriptorSet.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; writeDescriptorSet.pNext = NULL; @@ -6846,7 +6846,7 @@ static uint32_t VULKAN_PushVertexShaderUniforms( SDL_LockMutex(renderer->vertexUniformBufferObject->lock); - if (renderer->vertexUniformBufferObject->currentOffset + dataLengthInBytes >= UBO_BUFFER_SIZE) + if (renderer->vertexUniformBufferObject->currentOffset + dataLengthInBytes + UBO_SECTION_SIZE >= UBO_BUFFER_SIZE) { renderer->vertexUniformBufferObject->currentOffset = 0; } @@ -6885,7 +6885,7 @@ static uint32_t VULKAN_PushFragmentShaderUniforms( SDL_LockMutex(renderer->fragmentUniformBufferObject->lock); - if (renderer->fragmentUniformBufferObject->currentOffset + dataLengthInBytes >= UBO_BUFFER_SIZE) + if (renderer->fragmentUniformBufferObject->currentOffset + dataLengthInBytes + UBO_SECTION_SIZE >= UBO_BUFFER_SIZE) { renderer->fragmentUniformBufferObject->currentOffset = 0; } @@ -6924,7 +6924,7 @@ static uint32_t VULKAN_PushComputeShaderUniforms( SDL_LockMutex(renderer->computeUniformBufferObject->lock); - if (renderer->computeUniformBufferObject->currentOffset + dataLengthInBytes >= UBO_BUFFER_SIZE) + if (renderer->computeUniformBufferObject->currentOffset + dataLengthInBytes + UBO_SECTION_SIZE >= UBO_BUFFER_SIZE) { renderer->computeUniformBufferObject->currentOffset = 0; } -- 2.25.1 From 55ce210be6e688b569cc2a66122e7ea6e35b4f12 Mon Sep 17 00:00:00 2001 From: cosmonaut Date: Fri, 16 Feb 2024 17:45:27 -0800 Subject: [PATCH 07/20] add FIXME --- src/Refresh_Driver_Vulkan.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Refresh_Driver_Vulkan.c b/src/Refresh_Driver_Vulkan.c index 7b08f95..59a724c 100644 --- a/src/Refresh_Driver_Vulkan.c +++ b/src/Refresh_Driver_Vulkan.c @@ -1548,6 +1548,7 @@ typedef struct VulkanCommandBuffer VkDescriptorSet bufferDescriptorSet; /* updated by BindComputeBuffers */ VkDescriptorSet imageDescriptorSet; /* updated by BindComputeTextures */ + /* FIXME: descriptor pools should be per-command-buffer */ DescriptorSetData *boundDescriptorSetDatas; uint32_t boundDescriptorSetDataCount; uint32_t boundDescriptorSetDataCapacity; -- 2.25.1 From 695ad15b7583e1f9c401cdac8b580d0877c73d20 Mon Sep 17 00:00:00 2001 From: cosmonaut Date: Fri, 16 Feb 2024 18:26:30 -0800 Subject: [PATCH 08/20] update PushUniforms and Draw functions --- src/Refresh_Driver_Vulkan.c | 90 +++++++++++++------------------------ 1 file changed, 30 insertions(+), 60 deletions(-) diff --git a/src/Refresh_Driver_Vulkan.c b/src/Refresh_Driver_Vulkan.c index 59a724c..7307e71 100644 --- a/src/Refresh_Driver_Vulkan.c +++ b/src/Refresh_Driver_Vulkan.c @@ -1539,6 +1539,10 @@ typedef struct VulkanCommandBuffer VulkanComputePipeline *currentComputePipeline; VulkanGraphicsPipeline *currentGraphicsPipeline; + uint32_t vertexUniformOffset; + uint32_t fragmentUniformOffset; + uint32_t computeUniformOffset; + VulkanTexture *renderPassColorTargetTextures[MAX_COLOR_TARGET_BINDINGS]; uint32_t renderPassColorTargetCount; VulkanTexture *renderPassDepthTexture; /* can be NULL */ @@ -5203,9 +5207,7 @@ static void VULKAN_DrawInstancedPrimitives( uint32_t baseVertex, uint32_t startIndex, uint32_t primitiveCount, - uint32_t instanceCount, - uint32_t vertexParamOffset, - uint32_t fragmentParamOffset + uint32_t instanceCount ) { VulkanRenderer* renderer = (VulkanRenderer*) driverData; VulkanCommandBuffer *vulkanCommandBuffer = (VulkanCommandBuffer*) commandBuffer; @@ -5218,8 +5220,8 @@ static void VULKAN_DrawInstancedPrimitives( descriptorSets[2] = renderer->vertexUniformBufferObject->descriptorSet; descriptorSets[3] = renderer->fragmentUniformBufferObject->descriptorSet; - dynamicOffsets[0] = vertexParamOffset; - dynamicOffsets[1] = fragmentParamOffset; + dynamicOffsets[0] = vulkanCommandBuffer->vertexUniformOffset; + dynamicOffsets[1] = vulkanCommandBuffer->fragmentUniformOffset; renderer->vkCmdBindDescriptorSets( vulkanCommandBuffer->commandBuffer, @@ -5250,9 +5252,7 @@ static void VULKAN_DrawIndexedPrimitives( Refresh_CommandBuffer *commandBuffer, uint32_t baseVertex, uint32_t startIndex, - uint32_t primitiveCount, - uint32_t vertexParamOffset, - uint32_t fragmentParamOffset + uint32_t primitiveCount ) { VULKAN_DrawInstancedPrimitives( driverData, @@ -5260,9 +5260,7 @@ static void VULKAN_DrawIndexedPrimitives( baseVertex, startIndex, primitiveCount, - 1, - vertexParamOffset, - fragmentParamOffset + 1 ); } @@ -5270,9 +5268,7 @@ static void VULKAN_DrawPrimitives( Refresh_Renderer *driverData, Refresh_CommandBuffer *commandBuffer, uint32_t vertexStart, - uint32_t primitiveCount, - uint32_t vertexParamOffset, - uint32_t fragmentParamOffset + uint32_t primitiveCount ) { VulkanRenderer* renderer = (VulkanRenderer*) driverData; VulkanCommandBuffer *vulkanCommandBuffer = (VulkanCommandBuffer*) commandBuffer; @@ -5285,8 +5281,8 @@ static void VULKAN_DrawPrimitives( descriptorSets[2] = renderer->vertexUniformBufferObject->descriptorSet; descriptorSets[3] = renderer->fragmentUniformBufferObject->descriptorSet; - dynamicOffsets[0] = vertexParamOffset; - dynamicOffsets[1] = fragmentParamOffset; + dynamicOffsets[0] = vulkanCommandBuffer->vertexUniformOffset; + dynamicOffsets[1] = vulkanCommandBuffer->fragmentUniformOffset; renderer->vkCmdBindDescriptorSets( vulkanCommandBuffer->commandBuffer, @@ -5317,9 +5313,7 @@ static void VULKAN_DrawPrimitivesIndirect( Refresh_GpuBuffer *buffer, uint32_t offsetInBytes, uint32_t drawCount, - uint32_t stride, - uint32_t vertexParamOffset, - uint32_t fragmentParamOffset + uint32_t stride ) { VulkanRenderer* renderer = (VulkanRenderer*) driverData; VulkanCommandBuffer *vulkanCommandBuffer = (VulkanCommandBuffer*) commandBuffer; @@ -5332,8 +5326,8 @@ static void VULKAN_DrawPrimitivesIndirect( descriptorSets[2] = renderer->vertexUniformBufferObject->descriptorSet; descriptorSets[3] = renderer->fragmentUniformBufferObject->descriptorSet; - dynamicOffsets[0] = vertexParamOffset; - dynamicOffsets[1] = fragmentParamOffset; + dynamicOffsets[0] = vulkanCommandBuffer->vertexUniformOffset; + dynamicOffsets[1] = vulkanCommandBuffer->fragmentUniformOffset; renderer->vkCmdBindDescriptorSets( vulkanCommandBuffer->commandBuffer, @@ -6828,7 +6822,7 @@ static void VULKAN_INTERNAL_SetUniformBufferData( ); } -static uint32_t VULKAN_PushVertexShaderUniforms( +static void VULKAN_PushVertexShaderUniforms( Refresh_Renderer *driverData, Refresh_CommandBuffer *commandBuffer, void *data, @@ -6837,22 +6831,15 @@ static uint32_t VULKAN_PushVertexShaderUniforms( VulkanRenderer* renderer = (VulkanRenderer*) driverData; VulkanCommandBuffer* vulkanCommandBuffer = (VulkanCommandBuffer*) commandBuffer; VulkanGraphicsPipeline* graphicsPipeline = vulkanCommandBuffer->currentGraphicsPipeline; - uint32_t offset; - - if (graphicsPipeline->vertexUniformBlockSize == 0) - { - Refresh_LogError("Bound pipeline's vertex stage does not declare uniforms!"); - return 0; - } SDL_LockMutex(renderer->vertexUniformBufferObject->lock); - if (renderer->vertexUniformBufferObject->currentOffset + dataLengthInBytes + UBO_SECTION_SIZE >= UBO_BUFFER_SIZE) + if (renderer->vertexUniformBufferObject->currentOffset + graphicsPipeline->vertexUniformBlockSize + UBO_SECTION_SIZE >= UBO_BUFFER_SIZE) { renderer->vertexUniformBufferObject->currentOffset = 0; } - offset = renderer->vertexUniformBufferObject->currentOffset; + vulkanCommandBuffer->vertexUniformOffset = renderer->vertexUniformBufferObject->currentOffset; VULKAN_INTERNAL_SetUniformBufferData( renderer->vertexUniformBufferObject, @@ -6863,11 +6850,9 @@ static uint32_t VULKAN_PushVertexShaderUniforms( renderer->vertexUniformBufferObject->currentOffset += graphicsPipeline->vertexUniformBlockSize; SDL_UnlockMutex(renderer->vertexUniformBufferObject->lock); - - return offset; } -static uint32_t VULKAN_PushFragmentShaderUniforms( +static void VULKAN_PushFragmentShaderUniforms( Refresh_Renderer *driverData, Refresh_CommandBuffer *commandBuffer, void *data, @@ -6876,22 +6861,15 @@ static uint32_t VULKAN_PushFragmentShaderUniforms( VulkanRenderer* renderer = (VulkanRenderer*) driverData; VulkanCommandBuffer* vulkanCommandBuffer = (VulkanCommandBuffer*) commandBuffer; VulkanGraphicsPipeline* graphicsPipeline = vulkanCommandBuffer->currentGraphicsPipeline; - uint32_t offset; - - if (graphicsPipeline->fragmentUniformBlockSize == 0) - { - Refresh_LogError("Bound pipeline's fragment stage does not declare uniforms!"); - return 0; - } SDL_LockMutex(renderer->fragmentUniformBufferObject->lock); - if (renderer->fragmentUniformBufferObject->currentOffset + dataLengthInBytes + UBO_SECTION_SIZE >= UBO_BUFFER_SIZE) + if (renderer->fragmentUniformBufferObject->currentOffset + graphicsPipeline->fragmentUniformBlockSize + UBO_SECTION_SIZE >= UBO_BUFFER_SIZE) { renderer->fragmentUniformBufferObject->currentOffset = 0; } - offset = renderer->fragmentUniformBufferObject->currentOffset; + vulkanCommandBuffer->fragmentUniformOffset = renderer->fragmentUniformBufferObject->currentOffset; VULKAN_INTERNAL_SetUniformBufferData( renderer->fragmentUniformBufferObject, @@ -6902,11 +6880,9 @@ static uint32_t VULKAN_PushFragmentShaderUniforms( renderer->fragmentUniformBufferObject->currentOffset += graphicsPipeline->fragmentUniformBlockSize; SDL_UnlockMutex(renderer->fragmentUniformBufferObject->lock); - - return offset; } -static uint32_t VULKAN_PushComputeShaderUniforms( +static void VULKAN_PushComputeShaderUniforms( Refresh_Renderer *driverData, Refresh_CommandBuffer *commandBuffer, void *data, @@ -6915,22 +6891,15 @@ static uint32_t VULKAN_PushComputeShaderUniforms( VulkanRenderer* renderer = (VulkanRenderer*) driverData; VulkanCommandBuffer* vulkanCommandBuffer = (VulkanCommandBuffer*) commandBuffer; VulkanComputePipeline* computePipeline = vulkanCommandBuffer->currentComputePipeline; - uint32_t offset; - - if (computePipeline->uniformBlockSize == 0) - { - Refresh_LogError("Bound pipeline's compute stage does not declare uniforms!"); - return 0; - } SDL_LockMutex(renderer->computeUniformBufferObject->lock); - if (renderer->computeUniformBufferObject->currentOffset + dataLengthInBytes + UBO_SECTION_SIZE >= UBO_BUFFER_SIZE) + if (renderer->computeUniformBufferObject->currentOffset + computePipeline->uniformBlockSize + UBO_SECTION_SIZE >= UBO_BUFFER_SIZE) { renderer->computeUniformBufferObject->currentOffset = 0; } - offset = renderer->computeUniformBufferObject->currentOffset; + vulkanCommandBuffer->computeUniformOffset = renderer->computeUniformBufferObject->currentOffset; VULKAN_INTERNAL_SetUniformBufferData( renderer->computeUniformBufferObject, @@ -6941,8 +6910,6 @@ static uint32_t VULKAN_PushComputeShaderUniforms( renderer->computeUniformBufferObject->currentOffset += computePipeline->uniformBlockSize; SDL_UnlockMutex(renderer->computeUniformBufferObject->lock); - - return offset; } /* If fetching an image descriptor, descriptorImageInfos must not be NULL. @@ -8239,8 +8206,7 @@ static void VULKAN_DispatchCompute( Refresh_CommandBuffer *commandBuffer, uint32_t groupCountX, uint32_t groupCountY, - uint32_t groupCountZ, - uint32_t computeParamOffset + uint32_t groupCountZ ) { VulkanRenderer* renderer = (VulkanRenderer*) driverData; VulkanCommandBuffer *vulkanCommandBuffer = (VulkanCommandBuffer*) commandBuffer; @@ -8259,7 +8225,7 @@ static void VULKAN_DispatchCompute( 3, descriptorSets, 1, - &computeParamOffset + &vulkanCommandBuffer->computeUniformOffset ); renderer->vkCmdDispatch( @@ -9280,6 +9246,10 @@ static Refresh_CommandBuffer* VULKAN_AcquireCommandBuffer( commandBuffer->currentComputePipeline = NULL; commandBuffer->currentGraphicsPipeline = NULL; + commandBuffer->vertexUniformOffset = 0; + commandBuffer->fragmentUniformOffset = 0; + commandBuffer->computeUniformOffset = 0; + commandBuffer->renderPassColorTargetCount = 0; commandBuffer->autoReleaseFence = 1; -- 2.25.1 From f5e25979f409bb2cfd87bec8bdab8b0a010a300b Mon Sep 17 00:00:00 2001 From: cosmonaut Date: Fri, 16 Feb 2024 18:29:05 -0800 Subject: [PATCH 09/20] use 32 bit block sizes --- src/Refresh_Driver_Vulkan.c | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/src/Refresh_Driver_Vulkan.c b/src/Refresh_Driver_Vulkan.c index 7307e71..94c4351 100644 --- a/src/Refresh_Driver_Vulkan.c +++ b/src/Refresh_Driver_Vulkan.c @@ -872,8 +872,8 @@ typedef struct VulkanGraphicsPipeline VkPipeline pipeline; VulkanGraphicsPipelineLayout *pipelineLayout; Refresh_PrimitiveType primitiveType; - VkDeviceSize vertexUniformBlockSize; - VkDeviceSize fragmentUniformBlockSize; + uint32_t vertexUniformBlockSize; + uint32_t fragmentUniformBlockSize; VulkanShaderModule *vertexShaderModule; VulkanShaderModule *fragmentShaderModule; @@ -892,7 +892,7 @@ typedef struct VulkanComputePipeline { VkPipeline pipeline; VulkanComputePipelineLayout *pipelineLayout; - VkDeviceSize uniformBlockSize; /* permanently set in Create function */ + uint32_t uniformBlockSize; /* permanently set in Create function */ VulkanShaderModule *computeShaderModule; SDL_atomic_t referenceCount; @@ -1754,7 +1754,7 @@ typedef struct VulkanRenderer VkDescriptorSetLayout fragmentUniformDescriptorSetLayout; VkDescriptorSetLayout computeUniformDescriptorSetLayout; - VkDeviceSize minUBOAlignment; + uint32_t minUBOAlignment; /* Some drivers don't support D16 for some reason. Fun! */ VkFormat D16Format; @@ -2078,6 +2078,13 @@ static inline VkDeviceSize VULKAN_INTERNAL_NextHighestAlignment( return align * ((n + align - 1) / align); } +static inline uint32_t VULKAN_INTERNAL_NextHighestAlignment32( + uint32_t n, + uint32_t align +) { + return align * ((n + align - 1) / align); +} + static void VULKAN_INTERNAL_MakeMemoryUnavailable( VulkanRenderer* renderer, VulkanMemoryAllocation *allocation @@ -6086,7 +6093,7 @@ static Refresh_GraphicsPipeline* VULKAN_CreateGraphicsPipeline( shaderStageCreateInfos[0].pSpecializationInfo = NULL; graphicsPipeline->vertexUniformBlockSize = - VULKAN_INTERNAL_NextHighestAlignment( + VULKAN_INTERNAL_NextHighestAlignment32( pipelineCreateInfo->vertexShaderInfo.uniformBufferSize, renderer->minUBOAlignment ); @@ -6103,7 +6110,7 @@ static Refresh_GraphicsPipeline* VULKAN_CreateGraphicsPipeline( shaderStageCreateInfos[1].pSpecializationInfo = NULL; graphicsPipeline->fragmentUniformBlockSize = - VULKAN_INTERNAL_NextHighestAlignment( + VULKAN_INTERNAL_NextHighestAlignment32( pipelineCreateInfo->fragmentShaderInfo.uniformBufferSize, renderer->minUBOAlignment ); @@ -6529,7 +6536,7 @@ static Refresh_ComputePipeline* VULKAN_CreateComputePipeline( ); vulkanComputePipeline->uniformBlockSize = - VULKAN_INTERNAL_NextHighestAlignment( + VULKAN_INTERNAL_NextHighestAlignment32( computeShaderInfo->uniformBufferSize, renderer->minUBOAlignment ); @@ -11334,7 +11341,7 @@ static Refresh_Device* VULKAN_CreateDevice( /* Set up UBO layouts */ - renderer->minUBOAlignment = renderer->physicalDeviceProperties.properties.limits.minUniformBufferOffsetAlignment; + renderer->minUBOAlignment = (uint32_t) renderer->physicalDeviceProperties.properties.limits.minUniformBufferOffsetAlignment; emptyVertexSamplerLayoutBinding.binding = 0; emptyVertexSamplerLayoutBinding.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; -- 2.25.1 From a0414d0a4f74a09b92db9996866d10ce51b8b530 Mon Sep 17 00:00:00 2001 From: cosmonaut Date: Fri, 16 Feb 2024 18:43:02 -0800 Subject: [PATCH 10/20] require CpuBuffers to be host-local --- src/Refresh_Driver_Vulkan.c | 34 ++++++++++++++++++++++++++++++---- 1 file changed, 30 insertions(+), 4 deletions(-) diff --git a/src/Refresh_Driver_Vulkan.c b/src/Refresh_Driver_Vulkan.c index 94c4351..6c95d11 100644 --- a/src/Refresh_Driver_Vulkan.c +++ b/src/Refresh_Driver_Vulkan.c @@ -709,6 +709,7 @@ struct VulkanBuffer uint8_t requireHostVisible; uint8_t preferDeviceLocal; + uint8_t requireHostLocal; SDL_atomic_t referenceCount; /* Tracks command buffer usage */ @@ -2350,6 +2351,7 @@ static uint8_t VULKAN_INTERNAL_FindMemoryType( VulkanRenderer *renderer, uint32_t typeFilter, VkMemoryPropertyFlags requiredProperties, + VkMemoryPropertyFlags ignoredProperties, uint32_t *memoryTypeIndex ) { uint32_t i; @@ -2357,7 +2359,8 @@ static uint8_t VULKAN_INTERNAL_FindMemoryType( for (i = *memoryTypeIndex; i < renderer->memoryProperties.memoryTypeCount; i += 1) { if ( (typeFilter & (1 << i)) && - (renderer->memoryProperties.memoryTypes[i].propertyFlags & requiredProperties) == requiredProperties) + (renderer->memoryProperties.memoryTypes[i].propertyFlags & requiredProperties) == requiredProperties && + (renderer->memoryProperties.memoryTypes[i].propertyFlags & ignoredProperties) == 0 ) { *memoryTypeIndex = i; return 1; @@ -2371,6 +2374,7 @@ static uint8_t VULKAN_INTERNAL_FindBufferMemoryRequirements( VulkanRenderer *renderer, VkBuffer buffer, VkMemoryPropertyFlags requiredMemoryProperties, + VkMemoryPropertyFlags ignoredMemoryProperties, VkMemoryRequirements2KHR *pMemoryRequirements, uint32_t *pMemoryTypeIndex ) { @@ -2390,6 +2394,7 @@ static uint8_t VULKAN_INTERNAL_FindBufferMemoryRequirements( renderer, pMemoryRequirements->memoryRequirements.memoryTypeBits, requiredMemoryProperties, + ignoredMemoryProperties, pMemoryTypeIndex ); } @@ -2417,6 +2422,7 @@ static uint8_t VULKAN_INTERNAL_FindImageMemoryRequirements( renderer, pMemoryRequirements->memoryRequirements.memoryTypeBits, requiredMemoryPropertyFlags, + 0, pMemoryTypeIndex ); } @@ -2925,6 +2931,7 @@ static uint8_t VULKAN_INTERNAL_BindMemoryForBuffer( VkBuffer buffer, VkDeviceSize size, uint8_t requireHostVisible, + uint8_t requireHostLocal, uint8_t preferDeviceLocal, uint8_t dedicatedAllocation, VulkanMemoryUsedRegion** usedRegion @@ -2932,6 +2939,7 @@ static uint8_t VULKAN_INTERNAL_BindMemoryForBuffer( uint8_t bindResult = 0; uint32_t memoryTypeIndex = 0; VkMemoryPropertyFlags requiredMemoryPropertyFlags = 0; + VkMemoryPropertyFlags ignoredMemoryPropertyFlags = 0; VkMemoryRequirements2KHR memoryRequirements = { VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2_KHR, @@ -2945,7 +2953,11 @@ static uint8_t VULKAN_INTERNAL_BindMemoryForBuffer( VK_MEMORY_PROPERTY_HOST_COHERENT_BIT; } - if (preferDeviceLocal) + if (requireHostLocal) + { + ignoredMemoryPropertyFlags = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT; + } + else if (preferDeviceLocal) { requiredMemoryPropertyFlags |= VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT; @@ -2955,6 +2967,7 @@ static uint8_t VULKAN_INTERNAL_BindMemoryForBuffer( renderer, buffer, requiredMemoryPropertyFlags, + ignoredMemoryPropertyFlags, &memoryRequirements, &memoryTypeIndex )) { @@ -2979,7 +2992,7 @@ static uint8_t VULKAN_INTERNAL_BindMemoryForBuffer( } } - /* Bind failed, try again without preferred flags */ + /* Bind failed, try again with fallback flags */ if (bindResult != 1) { memoryTypeIndex = 0; @@ -2992,6 +3005,11 @@ static uint8_t VULKAN_INTERNAL_BindMemoryForBuffer( VK_MEMORY_PROPERTY_HOST_COHERENT_BIT; } + if (requireHostLocal) + { + ignoredMemoryPropertyFlags = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT; + } + /* Follow-up for the warning logged by FindMemoryType */ if (!renderer->unifiedMemoryWarning) { @@ -3003,6 +3021,7 @@ static uint8_t VULKAN_INTERNAL_BindMemoryForBuffer( renderer, buffer, requiredMemoryPropertyFlags, + ignoredMemoryPropertyFlags, &memoryRequirements, &memoryTypeIndex )) { @@ -4106,6 +4125,7 @@ static VulkanBuffer* VULKAN_INTERNAL_CreateBuffer( VulkanResourceAccessType resourceAccessType, VkBufferUsageFlags usage, uint8_t requireHostVisible, + uint8_t requireHostLocal, uint8_t preferDeviceLocal, uint8_t dedicatedAllocation ) { @@ -4120,6 +4140,7 @@ static VulkanBuffer* VULKAN_INTERNAL_CreateBuffer( buffer->resourceAccessType = resourceAccessType; buffer->usage = usage; buffer->requireHostVisible = requireHostVisible; + buffer->requireHostLocal = requireHostLocal; buffer->preferDeviceLocal = preferDeviceLocal; bufferCreateInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO; @@ -4144,6 +4165,7 @@ static VulkanBuffer* VULKAN_INTERNAL_CreateBuffer( buffer->buffer, buffer->size, buffer->requireHostVisible, + buffer->requireHostLocal, buffer->preferDeviceLocal, dedicatedAllocation, &buffer->usedRegion @@ -4235,6 +4257,7 @@ static VulkanUniformBufferObject* VULKAN_INTERNAL_CreateUniformBufferObject( resourceAccessType, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, 1, + 0, 1, 1 ); @@ -4290,7 +4313,7 @@ static VulkanUniformBufferObject* VULKAN_INTERNAL_CreateUniformBufferObject( return uniformBufferObject; } -/* Buffer indirection so we can cleanly defrag */ +/* Buffer indirection so we can cleanly defrag GpuBuffers */ static VulkanBufferContainer* VULKAN_INTERNAL_CreateBufferContainer( VulkanRenderer *renderer, uint32_t sizeInBytes, @@ -4309,6 +4332,7 @@ static VulkanBufferContainer* VULKAN_INTERNAL_CreateBufferContainer( resourceAccessType, usageFlags, 0, + 0, 1, 0 ); @@ -6803,6 +6827,7 @@ static Refresh_CpuBuffer* VULKAN_CreateCpuBuffer( RESOURCE_ACCESS_NONE, vulkanUsageFlags, 1, + 1, 0, 1 ); @@ -10134,6 +10159,7 @@ static uint8_t VULKAN_INTERNAL_DefragmentMemory( RESOURCE_ACCESS_NONE, currentRegion->vulkanBuffer->usage, currentRegion->vulkanBuffer->requireHostVisible, + currentRegion->vulkanBuffer->requireHostLocal, currentRegion->vulkanBuffer->preferDeviceLocal, 0 ); -- 2.25.1 From 74f26e605d69a99956c6be1b4825591e5d240d55 Mon Sep 17 00:00:00 2001 From: cosmonaut Date: Fri, 16 Feb 2024 18:51:09 -0800 Subject: [PATCH 11/20] permanently map host-visible buffers --- src/Refresh_Driver_Vulkan.c | 74 ++++++++++--------------------------- 1 file changed, 20 insertions(+), 54 deletions(-) diff --git a/src/Refresh_Driver_Vulkan.c b/src/Refresh_Driver_Vulkan.c index 6c95d11..abf0f88 100644 --- a/src/Refresh_Driver_Vulkan.c +++ b/src/Refresh_Driver_Vulkan.c @@ -449,6 +449,7 @@ struct VulkanMemoryAllocation uint8_t availableForAllocation; VkDeviceSize freeSpace; VkDeviceSize usedSpace; + uint8_t *mapPointer; SDL_mutex *memoryLock; }; @@ -745,7 +746,6 @@ typedef struct VulkanUniformBufferObject VkDescriptorSet descriptorSet; VulkanBuffer *buffer; uint32_t currentOffset; - uint8_t *mapPointer; /* uniform buffers are permanently mapped */ SDL_mutex *lock; } VulkanUniformBufferObject; @@ -2552,6 +2552,24 @@ static uint8_t VULKAN_INTERNAL_AllocateMemory( return 0; } + /* Persistent mapping for host-visible memory */ + if (isHostVisible) + { + result = renderer->vkMapMemory( + renderer->logicalDevice, + allocation->memory, + 0, + VK_WHOLE_SIZE, + 0, + (void**) &allocation->mapPointer + ); + VULKAN_ERROR_CHECK(result, vkMapMemory, 0) + } + else + { + allocation->mapPointer = NULL; + } + VULKAN_INTERNAL_NewMemoryFreeRegion( renderer, allocation, @@ -4300,16 +4318,6 @@ static VulkanUniformBufferObject* VULKAN_INTERNAL_CreateUniformBufferObject( NULL ); - /* Permanently map the memory */ - renderer->vkMapMemory( - renderer->logicalDevice, - uniformBufferObject->buffer->usedRegion->allocation->memory, - 0, - VK_WHOLE_SIZE, - 0, - (void**) &uniformBufferObject->mapPointer - ); - return uniformBufferObject; } @@ -4354,11 +4362,6 @@ static void VULKAN_INTERNAL_DestroyUniformBufferObject( VulkanRenderer *renderer, VulkanUniformBufferObject *uniformBufferObject ) { - renderer->vkUnmapMemory( - renderer->logicalDevice, - uniformBufferObject->buffer->usedRegion->allocation->memory - ); - VULKAN_INTERNAL_DestroyBuffer(renderer, uniformBufferObject->buffer); SDL_DestroyMutex(uniformBufferObject->lock); @@ -6843,7 +6846,7 @@ static void VULKAN_INTERNAL_SetUniformBufferData( uint32_t dataLength ) { uint8_t *dst = - uniformBufferObject->mapPointer + + uniformBufferObject->buffer->usedRegion->allocation->mapPointer + uniformBufferObject->buffer->usedRegion->resourceOffset + uniformBufferObject->currentOffset; @@ -8336,43 +8339,6 @@ static void VULKAN_EndComputePass( vulkanCommandBuffer->currentComputePipeline = NULL; } -static void* VULKAN_MapCpuBuffer( - Refresh_Renderer *driverData, - Refresh_CpuBuffer *buffer, - uint32_t offsetInBytes, - uint32_t sizeInBytes -) { - VulkanRenderer *renderer = (VulkanRenderer*) driverData; - VulkanBuffer *vulkanBuffer = (VulkanBuffer*) buffer; - VkResult result; - void* mapPointer; - - result = renderer->vkMapMemory( - renderer->logicalDevice, - vulkanBuffer->usedRegion->allocation->memory, - offsetInBytes, - sizeInBytes, - 0, - &mapPointer - ); - VULKAN_ERROR_CHECK(result, vkMapMemory, NULL) - - return mapPointer; -} - -static void VULKAN_UnmapCpuBuffer( - Refresh_Renderer *driverData, - Refresh_CpuBuffer *buffer -) { - VulkanRenderer *renderer = (VulkanRenderer*) driverData; - VulkanBuffer *vulkanBuffer = (VulkanBuffer*) buffer; - - renderer->vkUnmapMemory( - renderer->logicalDevice, - vulkanBuffer->usedRegion->allocation->memory - ); -} - static void VULKAN_BeginCopyPass( Refresh_Renderer *driverData, Refresh_CommandBuffer *commandBuffer -- 2.25.1 From 0c095fa56d56936790c21ff50d4c597d6807a9ec Mon Sep 17 00:00:00 2001 From: cosmonaut Date: Fri, 16 Feb 2024 18:56:25 -0800 Subject: [PATCH 12/20] write pDataPtr on CreateCpuBuffer --- src/Refresh_Driver_Vulkan.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/Refresh_Driver_Vulkan.c b/src/Refresh_Driver_Vulkan.c index abf0f88..e0687bb 100644 --- a/src/Refresh_Driver_Vulkan.c +++ b/src/Refresh_Driver_Vulkan.c @@ -6818,7 +6818,8 @@ static Refresh_GpuBuffer* VULKAN_CreateGpuBuffer( static Refresh_CpuBuffer* VULKAN_CreateCpuBuffer( Refresh_Renderer *driverData, - uint32_t sizeInBytes + uint32_t sizeInBytes, + void **pDataPtr ) { VulkanRenderer *renderer = (VulkanRenderer*) driverData; VkBufferUsageFlags vulkanUsageFlags = @@ -6835,6 +6836,8 @@ static Refresh_CpuBuffer* VULKAN_CreateCpuBuffer( 1 ); + *pDataPtr = vulkanBuffer->usedRegion->allocation->mapPointer; + return (Refresh_CpuBuffer*) vulkanBuffer; } -- 2.25.1 From 6674076423f3874e5f8e1487e3daa758a49556b4 Mon Sep 17 00:00:00 2001 From: cosmonaut Date: Wed, 21 Feb 2024 23:11:15 -0800 Subject: [PATCH 13/20] implement SetData and GetData --- src/Refresh_Driver_Vulkan.c | 341 ++++++++++++++++++++++++++++-------- 1 file changed, 269 insertions(+), 72 deletions(-) diff --git a/src/Refresh_Driver_Vulkan.c b/src/Refresh_Driver_Vulkan.c index e0687bb..7a8e6eb 100644 --- a/src/Refresh_Driver_Vulkan.c +++ b/src/Refresh_Driver_Vulkan.c @@ -695,11 +695,32 @@ static const VulkanResourceAccessInfo AccessMap[RESOURCE_ACCESS_TYPES_COUNT] = /* Memory structures */ -typedef struct VulkanBufferContainer /* cast from Refresh_Buffer */ +/* We use pointer indirection so that defrag can occur without objects + * needing to be aware of the backing buffers changing. + */ +typedef struct VulkanBufferContainer { VulkanBuffer *vulkanBuffer; } VulkanBufferContainer; +/* CpuBuffers consist of multiple backing buffer containers so that data transfers + * can occur safely without the client having to explicitly manage transfer timing. + */ +typedef struct VulkanCpuBufferContainer /* cast from Refresh_CpuBuffer */ +{ + uint32_t sizeInBytes; + VulkanBufferContainer *activeBuffer; + + /* These are all the buffers that have been used by this container. + * If a buffer is bound and then updated with Discard, a new buffer + * will be added to this list. + * These can be reused after they are submitted and command processing is complete. + */ + uint32_t bufferCapacity; + uint32_t bufferCount; + VulkanBufferContainer **backingBuffers; +} VulkanCpuBufferContainer; + struct VulkanBuffer { VkBuffer buffer; @@ -711,10 +732,13 @@ struct VulkanBuffer uint8_t requireHostVisible; uint8_t preferDeviceLocal; uint8_t requireHostLocal; + uint8_t preserveContentsOnDefrag; SDL_atomic_t referenceCount; /* Tracks command buffer usage */ VulkanBufferContainer *container; + + uint8_t markedForDestroy; /* so that defrag doesn't double-free */ }; typedef enum VulkanUniformBufferType @@ -802,6 +826,8 @@ struct VulkanTexture SDL_atomic_t referenceCount; VulkanTextureContainer *container; + + uint8_t markedForDestroy; /* so that defrag doesn't double-free */ }; typedef struct VulkanRenderTarget @@ -3248,6 +3274,28 @@ static void VULKAN_INTERNAL_ImageMemoryBarrier( /* Resource tracking */ +#define ADD_TO_ARRAY_UNIQUE(resource, type, array, count, capacity) \ + uint32_t i; \ + \ + for (i = 0; i < commandBuffer->count; i += 1) \ + { \ + if (commandBuffer->array[i] == resource) \ + { \ + return; \ + } \ + } \ + \ + if (commandBuffer->count == commandBuffer->capacity) \ + { \ + commandBuffer->capacity += 1; \ + commandBuffer->array = SDL_realloc( \ + commandBuffer->array, \ + commandBuffer->capacity * sizeof(type) \ + ); \ + } \ + commandBuffer->array[commandBuffer->count] = resource; \ + commandBuffer->count += 1; + #define TRACK_RESOURCE(resource, type, array, count, capacity) \ uint32_t i; \ \ @@ -3269,10 +3317,8 @@ static void VULKAN_INTERNAL_ImageMemoryBarrier( } \ commandBuffer->array[commandBuffer->count] = resource; \ commandBuffer->count += 1; \ - \ SDL_AtomicIncRef(&resource->referenceCount); - static void VULKAN_INTERNAL_TrackBuffer( VulkanRenderer *renderer, VulkanCommandBuffer *commandBuffer, @@ -3391,7 +3437,7 @@ static void VULKAN_INTERNAL_TrackCopiedTexture( VulkanCommandBuffer *commandBuffer, VulkanTexture *texture ) { - TRACK_RESOURCE( + ADD_TO_ARRAY_UNIQUE( texture, VulkanTexture*, copiedTextures, @@ -3406,7 +3452,7 @@ static void VULKAN_INTERNAL_TrackCopiedBuffer( VulkanCommandBuffer *commandBuffer, VulkanBuffer *buffer ) { - TRACK_RESOURCE( + ADD_TO_ARRAY_UNIQUE( buffer, VulkanBuffer*, copiedGpuBuffers, @@ -4145,7 +4191,8 @@ static VulkanBuffer* VULKAN_INTERNAL_CreateBuffer( uint8_t requireHostVisible, uint8_t requireHostLocal, uint8_t preferDeviceLocal, - uint8_t dedicatedAllocation + uint8_t dedicatedAllocation, + uint8_t preserveContentsOnDefrag ) { VulkanBuffer* buffer; VkResult vulkanResult; @@ -4160,6 +4207,8 @@ static VulkanBuffer* VULKAN_INTERNAL_CreateBuffer( buffer->requireHostVisible = requireHostVisible; buffer->requireHostLocal = requireHostLocal; buffer->preferDeviceLocal = preferDeviceLocal; + buffer->preserveContentsOnDefrag = preserveContentsOnDefrag; + buffer->markedForDestroy = 0; bufferCreateInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO; bufferCreateInfo.pNext = NULL; @@ -4277,6 +4326,7 @@ static VulkanUniformBufferObject* VULKAN_INTERNAL_CreateUniformBufferObject( 1, 0, 1, + 1, 1 ); @@ -4321,12 +4371,17 @@ static VulkanUniformBufferObject* VULKAN_INTERNAL_CreateUniformBufferObject( return uniformBufferObject; } -/* Buffer indirection so we can cleanly defrag GpuBuffers */ +/* Indirection so we can cleanly defrag buffers */ static VulkanBufferContainer* VULKAN_INTERNAL_CreateBufferContainer( VulkanRenderer *renderer, uint32_t sizeInBytes, VulkanResourceAccessType resourceAccessType, - VkBufferUsageFlags usageFlags + VkBufferUsageFlags usageFlags, + uint8_t requireHostVisible, + uint8_t requireHostLocal, + uint8_t preferDeviceLocal, + uint8_t dedicatedAllocation, + uint8_t preserveContentsOnDefrag ) { VulkanBufferContainer* bufferContainer; VulkanBuffer* buffer; @@ -4339,10 +4394,11 @@ static VulkanBufferContainer* VULKAN_INTERNAL_CreateBufferContainer( sizeInBytes, resourceAccessType, usageFlags, - 0, - 0, - 1, - 0 + requireHostVisible, + requireHostLocal, + preferDeviceLocal, + dedicatedAllocation, + preserveContentsOnDefrag ); if (buffer == NULL) @@ -5413,6 +5469,7 @@ static VulkanTexture* VULKAN_INTERNAL_CreateTexture( texture->isCube = 0; texture->is3D = 0; + texture->markedForDestroy = 0; if (isCube) { @@ -6812,20 +6869,26 @@ static Refresh_GpuBuffer* VULKAN_CreateGpuBuffer( (VulkanRenderer*) driverData, sizeInBytes, resourceAccessType, - vulkanUsageFlags + vulkanUsageFlags, + 0, + 0, + 1, + 0, + 1 ); } static Refresh_CpuBuffer* VULKAN_CreateCpuBuffer( Refresh_Renderer *driverData, - uint32_t sizeInBytes, - void **pDataPtr + uint32_t sizeInBytes ) { VulkanRenderer *renderer = (VulkanRenderer*) driverData; VkBufferUsageFlags vulkanUsageFlags = VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT; + VulkanCpuBufferContainer *bufferContainer = (VulkanCpuBufferContainer*) SDL_malloc(sizeof(VulkanCpuBufferContainer)); - VulkanBuffer *vulkanBuffer = VULKAN_INTERNAL_CreateBuffer( + bufferContainer->sizeInBytes = sizeInBytes; + bufferContainer->activeBuffer = VULKAN_INTERNAL_CreateBufferContainer( renderer, sizeInBytes, RESOURCE_ACCESS_NONE, @@ -6833,12 +6896,18 @@ static Refresh_CpuBuffer* VULKAN_CreateCpuBuffer( 1, 1, 0, - 1 + 0, + 0 ); - *pDataPtr = vulkanBuffer->usedRegion->allocation->mapPointer; + bufferContainer->bufferCapacity = 1; + bufferContainer->bufferCount = 1; + bufferContainer->backingBuffers = SDL_malloc( + bufferContainer->bufferCapacity * sizeof(VulkanBufferContainer*) + ); + bufferContainer->backingBuffers[0] = bufferContainer->activeBuffer; - return (Refresh_CpuBuffer*) vulkanBuffer; + return (Refresh_CpuBuffer*) bufferContainer; } /* Setters */ @@ -7169,6 +7238,8 @@ static void VULKAN_INTERNAL_QueueDestroyTexture( VulkanRenderer *renderer, VulkanTexture *vulkanTexture ) { + if (vulkanTexture->markedForDestroy) { return; } + SDL_LockMutex(renderer->disposeLock); EXPAND_ARRAY_IF_NEEDED( @@ -7184,6 +7255,8 @@ static void VULKAN_INTERNAL_QueueDestroyTexture( ] = vulkanTexture; renderer->texturesToDestroyCount += 1; + vulkanTexture->markedForDestroy = 1; + SDL_UnlockMutex(renderer->disposeLock); } @@ -7232,6 +7305,8 @@ static void VULKAN_INTERNAL_QueueDestroyBuffer( VulkanRenderer *renderer, VulkanBuffer *vulkanBuffer ) { + if (vulkanBuffer->markedForDestroy) { return; } + SDL_LockMutex(renderer->disposeLock); EXPAND_ARRAY_IF_NEEDED( @@ -7247,6 +7322,8 @@ static void VULKAN_INTERNAL_QueueDestroyBuffer( ] = vulkanBuffer; renderer->buffersToDestroyCount += 1; + vulkanBuffer->markedForDestroy = 1; + SDL_UnlockMutex(renderer->disposeLock); } @@ -7262,7 +7339,7 @@ static void VULKAN_QueueDestroyGpuBuffer( VULKAN_INTERNAL_QueueDestroyBuffer(renderer, vulkanBuffer); - /* Containers are just client handles, so we can destroy immediately */ + /* Containers are just client handles, so we can free immediately */ SDL_free(vulkanBufferContainer); SDL_UnlockMutex(renderer->disposeLock); @@ -7273,11 +7350,20 @@ static void VULKAN_QueueDestroyCpuBuffer( Refresh_CpuBuffer *buffer ) { VulkanRenderer *renderer = (VulkanRenderer*) driverData; - VulkanBuffer *vulkanBuffer = (VulkanBuffer*) buffer; + VulkanCpuBufferContainer *bufferContainer = (VulkanCpuBufferContainer*) buffer; + uint32_t i; SDL_LockMutex(renderer->disposeLock); - VULKAN_INTERNAL_QueueDestroyBuffer(renderer, vulkanBuffer); + for (i = 0; i < bufferContainer->bufferCount; i += 1) + { + VULKAN_INTERNAL_QueueDestroyBuffer(renderer, bufferContainer->backingBuffers[i]->vulkanBuffer); + SDL_free(bufferContainer->backingBuffers[i]); + } + + /* Containers are just client handles, so we can free immediately */ + SDL_free(bufferContainer->backingBuffers); + SDL_free(bufferContainer); SDL_UnlockMutex(renderer->disposeLock); } @@ -8342,6 +8428,108 @@ static void VULKAN_EndComputePass( vulkanCommandBuffer->currentComputePipeline = NULL; } +static void VULKAN_INTERNAL_DiscardActiveCpuBuffer( + VulkanRenderer *renderer, + VulkanCpuBufferContainer *cpuBufferContainer +) { + VulkanBufferContainer *cpuBuffer; + uint32_t i; + + cpuBufferContainer->activeBuffer->vulkanBuffer->preserveContentsOnDefrag = 0; + + /* If a previously-discarded buffer is available, we can use that. */ + for (i = 0; i < cpuBufferContainer->bufferCount; i += 1) + { + cpuBuffer = cpuBufferContainer->backingBuffers[i]; + if (SDL_AtomicGet(&cpuBuffer->vulkanBuffer->referenceCount) == 0) + { + cpuBufferContainer->activeBuffer = cpuBuffer; + return; + } + } + + /* No buffer is available, generate a new one. */ + cpuBufferContainer->activeBuffer = VULKAN_INTERNAL_CreateBufferContainer( + renderer, + cpuBufferContainer->sizeInBytes, + RESOURCE_ACCESS_NONE, + VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT, + 1, + 1, + 0, + 0, + 0 + ); + + EXPAND_ARRAY_IF_NEEDED( + cpuBufferContainer->backingBuffers, + VulkanBufferContainer*, + cpuBufferContainer->bufferCount + 1, + cpuBufferContainer->bufferCapacity, + cpuBufferContainer->bufferCapacity * 2 + ); + + cpuBufferContainer->backingBuffers[ + cpuBufferContainer->bufferCount + ] = cpuBufferContainer->activeBuffer; + cpuBufferContainer->bufferCount += 1; +} + +static void VULKAN_SetData( + Refresh_Renderer *driverData, + void* data, + Refresh_CpuBuffer *cpuBuffer, + Refresh_BufferCopy *copyParams, + Refresh_SetDataOptions option +) { + VulkanRenderer *renderer = (VulkanRenderer*) driverData; + VulkanCpuBufferContainer *cpuBufferContainer = (VulkanCpuBufferContainer*) cpuBuffer; + VulkanBuffer *vulkanBuffer = cpuBufferContainer->activeBuffer->vulkanBuffer; + + if (option == REFRESH_SETDATAOPTIONS_DISCARD && SDL_AtomicGet(&vulkanBuffer->referenceCount) > 0) + { + VULKAN_INTERNAL_DiscardActiveCpuBuffer( + renderer, + cpuBufferContainer + ); + } + + uint8_t *bufferPointer = + vulkanBuffer->usedRegion->allocation->mapPointer + + vulkanBuffer->usedRegion->resourceOffset + + copyParams->dstOffset; + + SDL_memcpy( + bufferPointer, + ((uint8_t*) data) + copyParams->srcOffset, + copyParams->size + ); +} + +static void VULKAN_GetData( + Refresh_Renderer *driverData, + Refresh_CpuBuffer *cpuBuffer, + void* data, + Refresh_BufferCopy *copyParams +) { + VulkanRenderer *renderer = (VulkanRenderer*) driverData; + VulkanCpuBufferContainer *cpuBufferContainer = (VulkanCpuBufferContainer*) cpuBuffer; + VulkanBuffer *vulkanBuffer = cpuBufferContainer->activeBuffer->vulkanBuffer; + + uint8_t *bufferPointer = + vulkanBuffer->usedRegion->allocation->mapPointer + + vulkanBuffer->usedRegion->resourceOffset + + copyParams->srcOffset; + + SDL_memcpy( + ((uint8_t*) data) + copyParams->dstOffset, + bufferPointer, + copyParams->size + ); + + vulkanBuffer->preserveContentsOnDefrag = 0; +} + static void VULKAN_BeginCopyPass( Refresh_Renderer *driverData, Refresh_CommandBuffer *commandBuffer @@ -8362,7 +8550,7 @@ static void VULKAN_UploadToTexture( ) { VulkanRenderer *renderer = (VulkanRenderer*) driverData; VulkanCommandBuffer *vulkanCommandBuffer = (VulkanCommandBuffer*) commandBuffer; - VulkanBuffer *vulkanCpuBuffer = (VulkanBuffer*) cpuBuffer; + VulkanCpuBufferContainer *bufferContainer = (VulkanCpuBufferContainer*) cpuBuffer; VulkanTexture *vulkanTexture = ((VulkanTextureContainer*) textureSlice->texture)->vulkanTexture; VkBufferImageCopy imageCopy; @@ -8370,7 +8558,7 @@ static void VULKAN_UploadToTexture( renderer, vulkanCommandBuffer->commandBuffer, RESOURCE_ACCESS_TRANSFER_READ, - vulkanCpuBuffer + bufferContainer->activeBuffer->vulkanBuffer ); VULKAN_INTERNAL_ImageMemoryBarrier( @@ -8403,14 +8591,14 @@ static void VULKAN_UploadToTexture( renderer->vkCmdCopyBufferToImage( vulkanCommandBuffer->commandBuffer, - vulkanCpuBuffer->buffer, + bufferContainer->activeBuffer->vulkanBuffer->buffer, vulkanTexture->image, AccessMap[vulkanTexture->resourceAccessType].imageLayout, 1, &imageCopy ); - VULKAN_INTERNAL_TrackBuffer(renderer, vulkanCommandBuffer, vulkanCpuBuffer); + VULKAN_INTERNAL_TrackBuffer(renderer, vulkanCommandBuffer, bufferContainer->activeBuffer->vulkanBuffer); VULKAN_INTERNAL_TrackTexture(renderer, vulkanCommandBuffer, vulkanTexture); VULKAN_INTERNAL_TrackCopiedTexture(renderer, vulkanCommandBuffer, vulkanTexture); } @@ -8424,7 +8612,7 @@ static void VULKAN_UploadToBuffer( ) { VulkanRenderer *renderer = (VulkanRenderer*) driverData; VulkanCommandBuffer *vulkanCommandBuffer = (VulkanCommandBuffer*) commandBuffer; - VulkanBuffer *vulkanCpuBuffer = (VulkanBuffer*) cpuBuffer; + VulkanCpuBufferContainer *cpuBufferContainer = (VulkanCpuBufferContainer*) cpuBuffer; VulkanBuffer *vulkanGpuBuffer = ((VulkanBufferContainer*) gpuBuffer)->vulkanBuffer; VkBufferCopy bufferCopy; @@ -8432,7 +8620,7 @@ static void VULKAN_UploadToBuffer( renderer, vulkanCommandBuffer->commandBuffer, RESOURCE_ACCESS_TRANSFER_READ, - vulkanCpuBuffer + cpuBufferContainer->activeBuffer->vulkanBuffer ); VULKAN_INTERNAL_BufferMemoryBarrier( @@ -8448,13 +8636,13 @@ static void VULKAN_UploadToBuffer( renderer->vkCmdCopyBuffer( vulkanCommandBuffer->commandBuffer, - vulkanCpuBuffer->buffer, + cpuBufferContainer->activeBuffer->vulkanBuffer->buffer, vulkanGpuBuffer->buffer, 1, &bufferCopy ); - VULKAN_INTERNAL_TrackBuffer(renderer, vulkanCommandBuffer, vulkanCpuBuffer); + VULKAN_INTERNAL_TrackBuffer(renderer, vulkanCommandBuffer, cpuBufferContainer->activeBuffer->vulkanBuffer); VULKAN_INTERNAL_TrackBuffer(renderer, vulkanCommandBuffer, vulkanGpuBuffer); VULKAN_INTERNAL_TrackCopiedBuffer(renderer, vulkanCommandBuffer, vulkanGpuBuffer); } @@ -8469,14 +8657,14 @@ static void VULKAN_DownloadFromTexture( VulkanRenderer *renderer = (VulkanRenderer*) driverData; VulkanCommandBuffer *vulkanCommandBuffer = (VulkanCommandBuffer*) commandBuffer; VulkanTexture *vulkanTexture = ((VulkanTextureContainer*) textureSlice->texture)->vulkanTexture; - VulkanBuffer *vulkanCpuBuffer = (VulkanBuffer*) cpuBuffer; + VulkanCpuBufferContainer *cpuBufferContainer = (VulkanCpuBufferContainer*) cpuBuffer; VkBufferImageCopy imageCopy; VULKAN_INTERNAL_BufferMemoryBarrier( renderer, vulkanCommandBuffer->commandBuffer, RESOURCE_ACCESS_TRANSFER_WRITE, - vulkanCpuBuffer + cpuBufferContainer->activeBuffer->vulkanBuffer ); VULKAN_INTERNAL_ImageMemoryBarrier( @@ -8511,14 +8699,16 @@ static void VULKAN_DownloadFromTexture( vulkanCommandBuffer->commandBuffer, vulkanTexture->image, AccessMap[vulkanTexture->resourceAccessType].imageLayout, - vulkanCpuBuffer->buffer, + cpuBufferContainer->activeBuffer->vulkanBuffer->buffer, 1, &imageCopy ); - VULKAN_INTERNAL_TrackBuffer(renderer, vulkanCommandBuffer, vulkanCpuBuffer); + VULKAN_INTERNAL_TrackBuffer(renderer, vulkanCommandBuffer, cpuBufferContainer->activeBuffer->vulkanBuffer); VULKAN_INTERNAL_TrackTexture(renderer, vulkanCommandBuffer, vulkanTexture); VULKAN_INTERNAL_TrackCopiedTexture(renderer, vulkanCommandBuffer, vulkanTexture); + + cpuBufferContainer->activeBuffer->vulkanBuffer->preserveContentsOnDefrag = 1; } static void VULKAN_DownloadFromBuffer( @@ -8530,7 +8720,7 @@ static void VULKAN_DownloadFromBuffer( ) { VulkanRenderer *renderer = (VulkanRenderer*) driverData; VulkanCommandBuffer *vulkanCommandBuffer = (VulkanCommandBuffer*) commandBuffer; - VulkanBuffer *vulkanCpuBuffer = (VulkanBuffer*) cpuBuffer; + VulkanCpuBufferContainer *cpuBufferContainer = (VulkanCpuBufferContainer*) cpuBuffer; VulkanBuffer *vulkanGpuBuffer = ((VulkanBufferContainer*) gpuBuffer)->vulkanBuffer; VkBufferCopy bufferCopy; @@ -8538,7 +8728,7 @@ static void VULKAN_DownloadFromBuffer( renderer, vulkanCommandBuffer->commandBuffer, RESOURCE_ACCESS_TRANSFER_WRITE, - vulkanCpuBuffer + cpuBufferContainer->activeBuffer->vulkanBuffer ); VULKAN_INTERNAL_BufferMemoryBarrier( @@ -8555,14 +8745,16 @@ static void VULKAN_DownloadFromBuffer( renderer->vkCmdCopyBuffer( vulkanCommandBuffer->commandBuffer, vulkanGpuBuffer->buffer, - vulkanCpuBuffer->buffer, + cpuBufferContainer->activeBuffer->vulkanBuffer->buffer, 1, &bufferCopy ); - VULKAN_INTERNAL_TrackBuffer(renderer, vulkanCommandBuffer, vulkanCpuBuffer); + VULKAN_INTERNAL_TrackBuffer(renderer, vulkanCommandBuffer, cpuBufferContainer->activeBuffer->vulkanBuffer); VULKAN_INTERNAL_TrackBuffer(renderer, vulkanCommandBuffer, vulkanGpuBuffer); VULKAN_INTERNAL_TrackBuffer(renderer, vulkanCommandBuffer, vulkanGpuBuffer); + + cpuBufferContainer->activeBuffer->vulkanBuffer->preserveContentsOnDefrag = 1; } static void VULKAN_CopyTextureToTexture( @@ -10118,7 +10310,7 @@ static uint8_t VULKAN_INTERNAL_DefragmentMemory( currentRegion = allocation->usedRegions[i]; copyResourceAccessType = RESOURCE_ACCESS_NONE; - if (currentRegion->isBuffer) + if (currentRegion->isBuffer && !currentRegion->vulkanBuffer->markedForDestroy) { currentRegion->vulkanBuffer->usage |= VK_BUFFER_USAGE_TRANSFER_DST_BIT; @@ -10130,7 +10322,8 @@ static uint8_t VULKAN_INTERNAL_DefragmentMemory( currentRegion->vulkanBuffer->requireHostVisible, currentRegion->vulkanBuffer->requireHostLocal, currentRegion->vulkanBuffer->preferDeviceLocal, - 0 + 0, + currentRegion->vulkanBuffer->preserveContentsOnDefrag ); if (newBuffer == NULL) @@ -10139,43 +10332,47 @@ static uint8_t VULKAN_INTERNAL_DefragmentMemory( return 0; } - originalResourceAccessType = currentRegion->vulkanBuffer->resourceAccessType; + /* Copy buffer contents if necessary */ + if (currentRegion->vulkanBuffer->preserveContentsOnDefrag) + { + originalResourceAccessType = currentRegion->vulkanBuffer->resourceAccessType; - VULKAN_INTERNAL_BufferMemoryBarrier( - renderer, - commandBuffer->commandBuffer, - RESOURCE_ACCESS_TRANSFER_READ, - currentRegion->vulkanBuffer - ); + VULKAN_INTERNAL_BufferMemoryBarrier( + renderer, + commandBuffer->commandBuffer, + RESOURCE_ACCESS_TRANSFER_READ, + currentRegion->vulkanBuffer + ); - VULKAN_INTERNAL_BufferMemoryBarrier( - renderer, - commandBuffer->commandBuffer, - RESOURCE_ACCESS_TRANSFER_WRITE, - newBuffer - ); + VULKAN_INTERNAL_BufferMemoryBarrier( + renderer, + commandBuffer->commandBuffer, + RESOURCE_ACCESS_TRANSFER_WRITE, + newBuffer + ); - bufferCopy.srcOffset = 0; - bufferCopy.dstOffset = 0; - bufferCopy.size = currentRegion->resourceSize; + bufferCopy.srcOffset = 0; + bufferCopy.dstOffset = 0; + bufferCopy.size = currentRegion->resourceSize; - renderer->vkCmdCopyBuffer( - commandBuffer->commandBuffer, - currentRegion->vulkanBuffer->buffer, - newBuffer->buffer, - 1, - &bufferCopy - ); + renderer->vkCmdCopyBuffer( + commandBuffer->commandBuffer, + currentRegion->vulkanBuffer->buffer, + newBuffer->buffer, + 1, + &bufferCopy + ); - VULKAN_INTERNAL_BufferMemoryBarrier( - renderer, - commandBuffer->commandBuffer, - originalResourceAccessType, - newBuffer - ); + VULKAN_INTERNAL_BufferMemoryBarrier( + renderer, + commandBuffer->commandBuffer, + originalResourceAccessType, + newBuffer + ); - VULKAN_INTERNAL_TrackBuffer(renderer, commandBuffer, currentRegion->vulkanBuffer); - VULKAN_INTERNAL_TrackBuffer(renderer, commandBuffer, newBuffer); + VULKAN_INTERNAL_TrackBuffer(renderer, commandBuffer, currentRegion->vulkanBuffer); + VULKAN_INTERNAL_TrackBuffer(renderer, commandBuffer, newBuffer); + } /* re-point original container to new buffer */ if (currentRegion->vulkanBuffer->container != NULL) @@ -10189,7 +10386,7 @@ static uint8_t VULKAN_INTERNAL_DefragmentMemory( renderer->needDefrag = 1; } - else + else if (!currentRegion->vulkanTexture->markedForDestroy) { newTexture = VULKAN_INTERNAL_CreateTexture( renderer, -- 2.25.1 From 578ac3634d9b3f812e9c9de5e21ad5c9628dac2a Mon Sep 17 00:00:00 2001 From: cosmonaut Date: Wed, 21 Feb 2024 23:12:39 -0800 Subject: [PATCH 14/20] rename to MAX_UBO_SECTION_SIZE --- src/Refresh_Driver_Vulkan.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/Refresh_Driver_Vulkan.c b/src/Refresh_Driver_Vulkan.c index 7a8e6eb..aae3632 100644 --- a/src/Refresh_Driver_Vulkan.c +++ b/src/Refresh_Driver_Vulkan.c @@ -80,7 +80,7 @@ typedef struct VulkanExtensions #define TRANSFER_BUFFER_STARTING_SIZE 8000000 /* 8MB */ #define POOLED_TRANSFER_BUFFER_SIZE 16000000 /* 16MB */ #define UBO_BUFFER_SIZE 16777216 /* 16MB */ -#define UBO_SECTION_SIZE 4096 /* 4KB */ +#define MAX_UBO_SECTION_SIZE 4096 /* 4KB */ #define DESCRIPTOR_POOL_STARTING_SIZE 128 #define DEFRAG_TIME 200 #define WINDOW_DATA "Refresh_VulkanWindowData" @@ -4347,7 +4347,7 @@ static VulkanUniformBufferObject* VULKAN_INTERNAL_CreateUniformBufferObject( /* Update the descriptor set for the first and last time! */ descriptorBufferInfo.buffer = uniformBufferObject->buffer->buffer; descriptorBufferInfo.offset = 0; - descriptorBufferInfo.range = UBO_SECTION_SIZE; + descriptorBufferInfo.range = MAX_UBO_SECTION_SIZE; writeDescriptorSet.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; writeDescriptorSet.pNext = NULL; @@ -6941,7 +6941,7 @@ static void VULKAN_PushVertexShaderUniforms( SDL_LockMutex(renderer->vertexUniformBufferObject->lock); - if (renderer->vertexUniformBufferObject->currentOffset + graphicsPipeline->vertexUniformBlockSize + UBO_SECTION_SIZE >= UBO_BUFFER_SIZE) + if (renderer->vertexUniformBufferObject->currentOffset + graphicsPipeline->vertexUniformBlockSize + MAX_UBO_SECTION_SIZE >= UBO_BUFFER_SIZE) { renderer->vertexUniformBufferObject->currentOffset = 0; } @@ -6971,7 +6971,7 @@ static void VULKAN_PushFragmentShaderUniforms( SDL_LockMutex(renderer->fragmentUniformBufferObject->lock); - if (renderer->fragmentUniformBufferObject->currentOffset + graphicsPipeline->fragmentUniformBlockSize + UBO_SECTION_SIZE >= UBO_BUFFER_SIZE) + if (renderer->fragmentUniformBufferObject->currentOffset + graphicsPipeline->fragmentUniformBlockSize + MAX_UBO_SECTION_SIZE >= UBO_BUFFER_SIZE) { renderer->fragmentUniformBufferObject->currentOffset = 0; } @@ -7001,7 +7001,7 @@ static void VULKAN_PushComputeShaderUniforms( SDL_LockMutex(renderer->computeUniformBufferObject->lock); - if (renderer->computeUniformBufferObject->currentOffset + computePipeline->uniformBlockSize + UBO_SECTION_SIZE >= UBO_BUFFER_SIZE) + if (renderer->computeUniformBufferObject->currentOffset + computePipeline->uniformBlockSize + MAX_UBO_SECTION_SIZE >= UBO_BUFFER_SIZE) { renderer->computeUniformBufferObject->currentOffset = 0; } -- 2.25.1 From aedc575885e5a292eb4597eca1e096eec0e528eb Mon Sep 17 00:00:00 2001 From: cosmonaut Date: Wed, 21 Feb 2024 23:43:25 -0800 Subject: [PATCH 15/20] fix discard copy --- src/Refresh_Driver_Vulkan.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/Refresh_Driver_Vulkan.c b/src/Refresh_Driver_Vulkan.c index aae3632..7dea313 100644 --- a/src/Refresh_Driver_Vulkan.c +++ b/src/Refresh_Driver_Vulkan.c @@ -8484,9 +8484,8 @@ static void VULKAN_SetData( ) { VulkanRenderer *renderer = (VulkanRenderer*) driverData; VulkanCpuBufferContainer *cpuBufferContainer = (VulkanCpuBufferContainer*) cpuBuffer; - VulkanBuffer *vulkanBuffer = cpuBufferContainer->activeBuffer->vulkanBuffer; - if (option == REFRESH_SETDATAOPTIONS_DISCARD && SDL_AtomicGet(&vulkanBuffer->referenceCount) > 0) + if (option == REFRESH_SETDATAOPTIONS_DISCARD && SDL_AtomicGet(&cpuBufferContainer->activeBuffer->vulkanBuffer->referenceCount) > 0) { VULKAN_INTERNAL_DiscardActiveCpuBuffer( renderer, @@ -8495,8 +8494,8 @@ static void VULKAN_SetData( } uint8_t *bufferPointer = - vulkanBuffer->usedRegion->allocation->mapPointer + - vulkanBuffer->usedRegion->resourceOffset + + cpuBufferContainer->activeBuffer->vulkanBuffer->usedRegion->allocation->mapPointer + + cpuBufferContainer->activeBuffer->vulkanBuffer->usedRegion->resourceOffset + copyParams->dstOffset; SDL_memcpy( -- 2.25.1 From 20c369845fb30a78cee0868aabc7f549217012af Mon Sep 17 00:00:00 2001 From: cosmonaut Date: Thu, 22 Feb 2024 10:35:27 -0800 Subject: [PATCH 16/20] rename DISCARD to SAFEDISCARD --- src/Refresh_Driver_Vulkan.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Refresh_Driver_Vulkan.c b/src/Refresh_Driver_Vulkan.c index 7dea313..4e952e6 100644 --- a/src/Refresh_Driver_Vulkan.c +++ b/src/Refresh_Driver_Vulkan.c @@ -8485,7 +8485,7 @@ static void VULKAN_SetData( VulkanRenderer *renderer = (VulkanRenderer*) driverData; VulkanCpuBufferContainer *cpuBufferContainer = (VulkanCpuBufferContainer*) cpuBuffer; - if (option == REFRESH_SETDATAOPTIONS_DISCARD && SDL_AtomicGet(&cpuBufferContainer->activeBuffer->vulkanBuffer->referenceCount) > 0) + if (option == REFRESH_SETDATAOPTIONS_SAFEDISCARD && SDL_AtomicGet(&cpuBufferContainer->activeBuffer->vulkanBuffer->referenceCount) > 0) { VULKAN_INTERNAL_DiscardActiveCpuBuffer( renderer, -- 2.25.1 From e5cd3c6fcef8b9ceb8c5e61977f6045d3e4bac3f Mon Sep 17 00:00:00 2001 From: cosmonaut Date: Fri, 23 Feb 2024 09:38:08 -0800 Subject: [PATCH 17/20] remove unused ubo management functions --- src/Refresh_Driver_Vulkan.c | 41 ------------------------------------- 1 file changed, 41 deletions(-) diff --git a/src/Refresh_Driver_Vulkan.c b/src/Refresh_Driver_Vulkan.c index 4e952e6..18476c7 100644 --- a/src/Refresh_Driver_Vulkan.c +++ b/src/Refresh_Driver_Vulkan.c @@ -748,21 +748,6 @@ typedef enum VulkanUniformBufferType UNIFORM_BUFFER_COMPUTE } VulkanUniformBufferType; -/* Yes, the pool is made of multiple pools. - * For some reason it was considered a good idea to make VkDescriptorPool fixed-size. - */ -typedef struct VulkanUniformDescriptorPool -{ - VkDescriptorPool* descriptorPools; - uint32_t descriptorPoolCount; - - /* Decremented whenever a descriptor set is allocated and - * incremented whenever a descriptor pool is allocated. - * This lets us keep track of when we need a new pool. - */ - uint32_t availableDescriptorSetCount; -} VulkanUniformDescriptorPool; - /* Uniform buffers are just one buffer that we carve slices out of. */ typedef struct VulkanUniformBufferObject { @@ -4260,32 +4245,6 @@ static VulkanBuffer* VULKAN_INTERNAL_CreateBuffer( /* Uniform buffer functions */ -static uint8_t VULKAN_INTERNAL_AddUniformDescriptorPool( - VulkanRenderer *renderer, - VulkanUniformDescriptorPool *vulkanUniformDescriptorPool -) { - vulkanUniformDescriptorPool->descriptorPools = SDL_realloc( - vulkanUniformDescriptorPool->descriptorPools, - sizeof(VkDescriptorPool) * (vulkanUniformDescriptorPool->descriptorPoolCount + 1) - ); - - if (!VULKAN_INTERNAL_CreateDescriptorPool( - renderer, - VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, - DESCRIPTOR_POOL_STARTING_SIZE, - DESCRIPTOR_POOL_STARTING_SIZE, - &vulkanUniformDescriptorPool->descriptorPools[vulkanUniformDescriptorPool->descriptorPoolCount] - )) { - Refresh_LogError("Failed to create descriptor pool!"); - return 0; - } - - vulkanUniformDescriptorPool->descriptorPoolCount += 1; - vulkanUniformDescriptorPool->availableDescriptorSetCount += DESCRIPTOR_POOL_STARTING_SIZE; - - return 1; -} - static VulkanUniformBufferObject* VULKAN_INTERNAL_CreateUniformBufferObject( VulkanRenderer *renderer, VulkanUniformBufferType uniformBufferType -- 2.25.1 From 6f2e4ed6d1f385e1910e3294a645257027fda112 Mon Sep 17 00:00:00 2001 From: cosmonaut Date: Fri, 23 Feb 2024 09:47:53 -0800 Subject: [PATCH 18/20] rename CpuBuffer to TransferBuffer --- src/Refresh_Driver_Vulkan.c | 162 ++++++++++++++++++------------------ 1 file changed, 81 insertions(+), 81 deletions(-) diff --git a/src/Refresh_Driver_Vulkan.c b/src/Refresh_Driver_Vulkan.c index 18476c7..b185aa2 100644 --- a/src/Refresh_Driver_Vulkan.c +++ b/src/Refresh_Driver_Vulkan.c @@ -703,10 +703,10 @@ typedef struct VulkanBufferContainer VulkanBuffer *vulkanBuffer; } VulkanBufferContainer; -/* CpuBuffers consist of multiple backing buffer containers so that data transfers +/* TransferBuffers consist of multiple backing buffer containers so that data transfers * can occur safely without the client having to explicitly manage transfer timing. */ -typedef struct VulkanCpuBufferContainer /* cast from Refresh_CpuBuffer */ +typedef struct VulkanTransferBufferContainer /* cast from Refresh_TransferBuffer */ { uint32_t sizeInBytes; VulkanBufferContainer *activeBuffer; @@ -719,7 +719,7 @@ typedef struct VulkanCpuBufferContainer /* cast from Refresh_CpuBuffer */ uint32_t bufferCapacity; uint32_t bufferCount; VulkanBufferContainer **backingBuffers; -} VulkanCpuBufferContainer; +} VulkanTransferBufferContainer; struct VulkanBuffer { @@ -5359,14 +5359,14 @@ static void VULKAN_DrawPrimitives( static void VULKAN_DrawPrimitivesIndirect( Refresh_Renderer *driverData, Refresh_CommandBuffer *commandBuffer, - Refresh_GpuBuffer *buffer, + Refresh_GpuBuffer *gpuBuffer, uint32_t offsetInBytes, uint32_t drawCount, uint32_t stride ) { VulkanRenderer* renderer = (VulkanRenderer*) driverData; VulkanCommandBuffer *vulkanCommandBuffer = (VulkanCommandBuffer*) commandBuffer; - VulkanBuffer *vulkanBuffer = ((VulkanBufferContainer*) buffer)->vulkanBuffer; + VulkanBuffer *vulkanBuffer = ((VulkanBufferContainer*) gpuBuffer)->vulkanBuffer; VkDescriptorSet descriptorSets[4]; uint32_t dynamicOffsets[2]; @@ -6837,17 +6837,17 @@ static Refresh_GpuBuffer* VULKAN_CreateGpuBuffer( ); } -static Refresh_CpuBuffer* VULKAN_CreateCpuBuffer( +static Refresh_TransferBuffer* VULKAN_CreateTransferBuffer( Refresh_Renderer *driverData, uint32_t sizeInBytes ) { VulkanRenderer *renderer = (VulkanRenderer*) driverData; VkBufferUsageFlags vulkanUsageFlags = VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT; - VulkanCpuBufferContainer *bufferContainer = (VulkanCpuBufferContainer*) SDL_malloc(sizeof(VulkanCpuBufferContainer)); + VulkanTransferBufferContainer *transferBufferContainer = (VulkanTransferBufferContainer*) SDL_malloc(sizeof(VulkanTransferBufferContainer)); - bufferContainer->sizeInBytes = sizeInBytes; - bufferContainer->activeBuffer = VULKAN_INTERNAL_CreateBufferContainer( + transferBufferContainer->sizeInBytes = sizeInBytes; + transferBufferContainer->activeBuffer = VULKAN_INTERNAL_CreateBufferContainer( renderer, sizeInBytes, RESOURCE_ACCESS_NONE, @@ -6859,14 +6859,14 @@ static Refresh_CpuBuffer* VULKAN_CreateCpuBuffer( 0 ); - bufferContainer->bufferCapacity = 1; - bufferContainer->bufferCount = 1; - bufferContainer->backingBuffers = SDL_malloc( - bufferContainer->bufferCapacity * sizeof(VulkanBufferContainer*) + transferBufferContainer->bufferCapacity = 1; + transferBufferContainer->bufferCount = 1; + transferBufferContainer->backingBuffers = SDL_malloc( + transferBufferContainer->bufferCapacity * sizeof(VulkanBufferContainer*) ); - bufferContainer->backingBuffers[0] = bufferContainer->activeBuffer; + transferBufferContainer->backingBuffers[0] = transferBufferContainer->activeBuffer; - return (Refresh_CpuBuffer*) bufferContainer; + return (Refresh_TransferBuffer*) transferBufferContainer; } /* Setters */ @@ -7288,10 +7288,10 @@ static void VULKAN_INTERNAL_QueueDestroyBuffer( static void VULKAN_QueueDestroyGpuBuffer( Refresh_Renderer *driverData, - Refresh_GpuBuffer *buffer + Refresh_GpuBuffer *gpuBuffer ) { VulkanRenderer *renderer = (VulkanRenderer*) driverData; - VulkanBufferContainer *vulkanBufferContainer = (VulkanBufferContainer*) buffer; + VulkanBufferContainer *vulkanBufferContainer = (VulkanBufferContainer*) gpuBuffer; VulkanBuffer *vulkanBuffer = vulkanBufferContainer->vulkanBuffer; SDL_LockMutex(renderer->disposeLock); @@ -7304,25 +7304,25 @@ static void VULKAN_QueueDestroyGpuBuffer( SDL_UnlockMutex(renderer->disposeLock); } -static void VULKAN_QueueDestroyCpuBuffer( +static void VULKAN_QueueDestroyTransferBuffer( Refresh_Renderer *driverData, - Refresh_CpuBuffer *buffer + Refresh_TransferBuffer *transferBuffer ) { VulkanRenderer *renderer = (VulkanRenderer*) driverData; - VulkanCpuBufferContainer *bufferContainer = (VulkanCpuBufferContainer*) buffer; + VulkanTransferBufferContainer *transferBufferContainer = (VulkanTransferBufferContainer*) transferBuffer; uint32_t i; SDL_LockMutex(renderer->disposeLock); - for (i = 0; i < bufferContainer->bufferCount; i += 1) + for (i = 0; i < transferBufferContainer->bufferCount; i += 1) { - VULKAN_INTERNAL_QueueDestroyBuffer(renderer, bufferContainer->backingBuffers[i]->vulkanBuffer); - SDL_free(bufferContainer->backingBuffers[i]); + VULKAN_INTERNAL_QueueDestroyBuffer(renderer, transferBufferContainer->backingBuffers[i]->vulkanBuffer); + SDL_free(transferBufferContainer->backingBuffers[i]); } /* Containers are just client handles, so we can free immediately */ - SDL_free(bufferContainer->backingBuffers); - SDL_free(bufferContainer); + SDL_free(transferBufferContainer->backingBuffers); + SDL_free(transferBufferContainer); SDL_UnlockMutex(renderer->disposeLock); } @@ -8124,13 +8124,13 @@ static void VULKAN_BindVertexBuffers( static void VULKAN_BindIndexBuffer( Refresh_Renderer *driverData, Refresh_CommandBuffer *commandBuffer, - Refresh_GpuBuffer *buffer, + Refresh_GpuBuffer *gpuBuffer, uint64_t offset, Refresh_IndexElementSize indexElementSize ) { VulkanRenderer* renderer = (VulkanRenderer*) driverData; VulkanCommandBuffer *vulkanCommandBuffer = (VulkanCommandBuffer*) commandBuffer; - VulkanBuffer* vulkanBuffer = ((VulkanBufferContainer*) buffer)->vulkanBuffer; + VulkanBuffer* vulkanBuffer = ((VulkanBufferContainer*) gpuBuffer)->vulkanBuffer; VULKAN_INTERNAL_TrackBuffer(renderer, vulkanCommandBuffer, vulkanBuffer); @@ -8387,30 +8387,30 @@ static void VULKAN_EndComputePass( vulkanCommandBuffer->currentComputePipeline = NULL; } -static void VULKAN_INTERNAL_DiscardActiveCpuBuffer( +static void VULKAN_INTERNAL_DiscardActiveTransferBuffer( VulkanRenderer *renderer, - VulkanCpuBufferContainer *cpuBufferContainer + VulkanTransferBufferContainer *transferBufferContainer ) { - VulkanBufferContainer *cpuBuffer; + VulkanBufferContainer *transferBuffer; uint32_t i; - cpuBufferContainer->activeBuffer->vulkanBuffer->preserveContentsOnDefrag = 0; + transferBufferContainer->activeBuffer->vulkanBuffer->preserveContentsOnDefrag = 0; /* If a previously-discarded buffer is available, we can use that. */ - for (i = 0; i < cpuBufferContainer->bufferCount; i += 1) + for (i = 0; i < transferBufferContainer->bufferCount; i += 1) { - cpuBuffer = cpuBufferContainer->backingBuffers[i]; - if (SDL_AtomicGet(&cpuBuffer->vulkanBuffer->referenceCount) == 0) + transferBuffer = transferBufferContainer->backingBuffers[i]; + if (SDL_AtomicGet(&transferBuffer->vulkanBuffer->referenceCount) == 0) { - cpuBufferContainer->activeBuffer = cpuBuffer; + transferBufferContainer->activeBuffer = transferBuffer; return; } } /* No buffer is available, generate a new one. */ - cpuBufferContainer->activeBuffer = VULKAN_INTERNAL_CreateBufferContainer( + transferBufferContainer->activeBuffer = VULKAN_INTERNAL_CreateBufferContainer( renderer, - cpuBufferContainer->sizeInBytes, + transferBufferContainer->sizeInBytes, RESOURCE_ACCESS_NONE, VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT, 1, @@ -8421,40 +8421,40 @@ static void VULKAN_INTERNAL_DiscardActiveCpuBuffer( ); EXPAND_ARRAY_IF_NEEDED( - cpuBufferContainer->backingBuffers, + transferBufferContainer->backingBuffers, VulkanBufferContainer*, - cpuBufferContainer->bufferCount + 1, - cpuBufferContainer->bufferCapacity, - cpuBufferContainer->bufferCapacity * 2 + transferBufferContainer->bufferCount + 1, + transferBufferContainer->bufferCapacity, + transferBufferContainer->bufferCapacity * 2 ); - cpuBufferContainer->backingBuffers[ - cpuBufferContainer->bufferCount - ] = cpuBufferContainer->activeBuffer; - cpuBufferContainer->bufferCount += 1; + transferBufferContainer->backingBuffers[ + transferBufferContainer->bufferCount + ] = transferBufferContainer->activeBuffer; + transferBufferContainer->bufferCount += 1; } static void VULKAN_SetData( Refresh_Renderer *driverData, void* data, - Refresh_CpuBuffer *cpuBuffer, + Refresh_TransferBuffer *transferBuffer, Refresh_BufferCopy *copyParams, Refresh_SetDataOptions option ) { VulkanRenderer *renderer = (VulkanRenderer*) driverData; - VulkanCpuBufferContainer *cpuBufferContainer = (VulkanCpuBufferContainer*) cpuBuffer; + VulkanTransferBufferContainer *transferBufferContainer = (VulkanTransferBufferContainer*) transferBuffer; - if (option == REFRESH_SETDATAOPTIONS_SAFEDISCARD && SDL_AtomicGet(&cpuBufferContainer->activeBuffer->vulkanBuffer->referenceCount) > 0) + if (option == REFRESH_SETDATAOPTIONS_SAFEDISCARD && SDL_AtomicGet(&transferBufferContainer->activeBuffer->vulkanBuffer->referenceCount) > 0) { - VULKAN_INTERNAL_DiscardActiveCpuBuffer( + VULKAN_INTERNAL_DiscardActiveTransferBuffer( renderer, - cpuBufferContainer + transferBufferContainer ); } uint8_t *bufferPointer = - cpuBufferContainer->activeBuffer->vulkanBuffer->usedRegion->allocation->mapPointer + - cpuBufferContainer->activeBuffer->vulkanBuffer->usedRegion->resourceOffset + + transferBufferContainer->activeBuffer->vulkanBuffer->usedRegion->allocation->mapPointer + + transferBufferContainer->activeBuffer->vulkanBuffer->usedRegion->resourceOffset + copyParams->dstOffset; SDL_memcpy( @@ -8466,13 +8466,13 @@ static void VULKAN_SetData( static void VULKAN_GetData( Refresh_Renderer *driverData, - Refresh_CpuBuffer *cpuBuffer, + Refresh_TransferBuffer *transferBuffer, void* data, Refresh_BufferCopy *copyParams ) { VulkanRenderer *renderer = (VulkanRenderer*) driverData; - VulkanCpuBufferContainer *cpuBufferContainer = (VulkanCpuBufferContainer*) cpuBuffer; - VulkanBuffer *vulkanBuffer = cpuBufferContainer->activeBuffer->vulkanBuffer; + VulkanTransferBufferContainer *transferBufferContainer = (VulkanTransferBufferContainer*) transferBuffer; + VulkanBuffer *vulkanBuffer = transferBufferContainer->activeBuffer->vulkanBuffer; uint8_t *bufferPointer = vulkanBuffer->usedRegion->allocation->mapPointer + @@ -8502,13 +8502,13 @@ static void VULKAN_BeginCopyPass( static void VULKAN_UploadToTexture( Refresh_Renderer *driverData, Refresh_CommandBuffer *commandBuffer, - Refresh_CpuBuffer *cpuBuffer, + Refresh_TransferBuffer *transferBuffer, Refresh_TextureSlice *textureSlice, Refresh_BufferImageCopy *copyParams ) { VulkanRenderer *renderer = (VulkanRenderer*) driverData; VulkanCommandBuffer *vulkanCommandBuffer = (VulkanCommandBuffer*) commandBuffer; - VulkanCpuBufferContainer *bufferContainer = (VulkanCpuBufferContainer*) cpuBuffer; + VulkanTransferBufferContainer *transferBufferContainer = (VulkanTransferBufferContainer*) transferBuffer; VulkanTexture *vulkanTexture = ((VulkanTextureContainer*) textureSlice->texture)->vulkanTexture; VkBufferImageCopy imageCopy; @@ -8516,7 +8516,7 @@ static void VULKAN_UploadToTexture( renderer, vulkanCommandBuffer->commandBuffer, RESOURCE_ACCESS_TRANSFER_READ, - bufferContainer->activeBuffer->vulkanBuffer + transferBufferContainer->activeBuffer->vulkanBuffer ); VULKAN_INTERNAL_ImageMemoryBarrier( @@ -8549,14 +8549,14 @@ static void VULKAN_UploadToTexture( renderer->vkCmdCopyBufferToImage( vulkanCommandBuffer->commandBuffer, - bufferContainer->activeBuffer->vulkanBuffer->buffer, + transferBufferContainer->activeBuffer->vulkanBuffer->buffer, vulkanTexture->image, AccessMap[vulkanTexture->resourceAccessType].imageLayout, 1, &imageCopy ); - VULKAN_INTERNAL_TrackBuffer(renderer, vulkanCommandBuffer, bufferContainer->activeBuffer->vulkanBuffer); + VULKAN_INTERNAL_TrackBuffer(renderer, vulkanCommandBuffer, transferBufferContainer->activeBuffer->vulkanBuffer); VULKAN_INTERNAL_TrackTexture(renderer, vulkanCommandBuffer, vulkanTexture); VULKAN_INTERNAL_TrackCopiedTexture(renderer, vulkanCommandBuffer, vulkanTexture); } @@ -8564,13 +8564,13 @@ static void VULKAN_UploadToTexture( static void VULKAN_UploadToBuffer( Refresh_Renderer *driverData, Refresh_CommandBuffer *commandBuffer, - Refresh_CpuBuffer *cpuBuffer, + Refresh_TransferBuffer *transferBuffer, Refresh_GpuBuffer *gpuBuffer, Refresh_BufferCopy *copyParams ) { VulkanRenderer *renderer = (VulkanRenderer*) driverData; VulkanCommandBuffer *vulkanCommandBuffer = (VulkanCommandBuffer*) commandBuffer; - VulkanCpuBufferContainer *cpuBufferContainer = (VulkanCpuBufferContainer*) cpuBuffer; + VulkanTransferBufferContainer *transferBufferContainer = (VulkanTransferBufferContainer*) transferBuffer; VulkanBuffer *vulkanGpuBuffer = ((VulkanBufferContainer*) gpuBuffer)->vulkanBuffer; VkBufferCopy bufferCopy; @@ -8578,7 +8578,7 @@ static void VULKAN_UploadToBuffer( renderer, vulkanCommandBuffer->commandBuffer, RESOURCE_ACCESS_TRANSFER_READ, - cpuBufferContainer->activeBuffer->vulkanBuffer + transferBufferContainer->activeBuffer->vulkanBuffer ); VULKAN_INTERNAL_BufferMemoryBarrier( @@ -8594,13 +8594,13 @@ static void VULKAN_UploadToBuffer( renderer->vkCmdCopyBuffer( vulkanCommandBuffer->commandBuffer, - cpuBufferContainer->activeBuffer->vulkanBuffer->buffer, + transferBufferContainer->activeBuffer->vulkanBuffer->buffer, vulkanGpuBuffer->buffer, 1, &bufferCopy ); - VULKAN_INTERNAL_TrackBuffer(renderer, vulkanCommandBuffer, cpuBufferContainer->activeBuffer->vulkanBuffer); + VULKAN_INTERNAL_TrackBuffer(renderer, vulkanCommandBuffer, transferBufferContainer->activeBuffer->vulkanBuffer); VULKAN_INTERNAL_TrackBuffer(renderer, vulkanCommandBuffer, vulkanGpuBuffer); VULKAN_INTERNAL_TrackCopiedBuffer(renderer, vulkanCommandBuffer, vulkanGpuBuffer); } @@ -8609,20 +8609,20 @@ static void VULKAN_DownloadFromTexture( Refresh_Renderer *driverData, Refresh_CommandBuffer *commandBuffer, Refresh_TextureSlice *textureSlice, - Refresh_CpuBuffer *cpuBuffer, + Refresh_TransferBuffer *transferBuffer, Refresh_BufferImageCopy *copyParams ) { VulkanRenderer *renderer = (VulkanRenderer*) driverData; VulkanCommandBuffer *vulkanCommandBuffer = (VulkanCommandBuffer*) commandBuffer; VulkanTexture *vulkanTexture = ((VulkanTextureContainer*) textureSlice->texture)->vulkanTexture; - VulkanCpuBufferContainer *cpuBufferContainer = (VulkanCpuBufferContainer*) cpuBuffer; + VulkanTransferBufferContainer *transferBufferContainer = (VulkanTransferBufferContainer*) transferBuffer; VkBufferImageCopy imageCopy; VULKAN_INTERNAL_BufferMemoryBarrier( renderer, vulkanCommandBuffer->commandBuffer, RESOURCE_ACCESS_TRANSFER_WRITE, - cpuBufferContainer->activeBuffer->vulkanBuffer + transferBufferContainer->activeBuffer->vulkanBuffer ); VULKAN_INTERNAL_ImageMemoryBarrier( @@ -8657,28 +8657,28 @@ static void VULKAN_DownloadFromTexture( vulkanCommandBuffer->commandBuffer, vulkanTexture->image, AccessMap[vulkanTexture->resourceAccessType].imageLayout, - cpuBufferContainer->activeBuffer->vulkanBuffer->buffer, + transferBufferContainer->activeBuffer->vulkanBuffer->buffer, 1, &imageCopy ); - VULKAN_INTERNAL_TrackBuffer(renderer, vulkanCommandBuffer, cpuBufferContainer->activeBuffer->vulkanBuffer); + VULKAN_INTERNAL_TrackBuffer(renderer, vulkanCommandBuffer, transferBufferContainer->activeBuffer->vulkanBuffer); VULKAN_INTERNAL_TrackTexture(renderer, vulkanCommandBuffer, vulkanTexture); VULKAN_INTERNAL_TrackCopiedTexture(renderer, vulkanCommandBuffer, vulkanTexture); - cpuBufferContainer->activeBuffer->vulkanBuffer->preserveContentsOnDefrag = 1; + transferBufferContainer->activeBuffer->vulkanBuffer->preserveContentsOnDefrag = 1; } static void VULKAN_DownloadFromBuffer( Refresh_Renderer *driverData, Refresh_CommandBuffer *commandBuffer, Refresh_GpuBuffer *gpuBuffer, - Refresh_CpuBuffer *cpuBuffer, + Refresh_TransferBuffer *transferBuffer, Refresh_BufferCopy *copyParams ) { VulkanRenderer *renderer = (VulkanRenderer*) driverData; VulkanCommandBuffer *vulkanCommandBuffer = (VulkanCommandBuffer*) commandBuffer; - VulkanCpuBufferContainer *cpuBufferContainer = (VulkanCpuBufferContainer*) cpuBuffer; + VulkanTransferBufferContainer *transferBufferContainer = (VulkanTransferBufferContainer*) transferBuffer; VulkanBuffer *vulkanGpuBuffer = ((VulkanBufferContainer*) gpuBuffer)->vulkanBuffer; VkBufferCopy bufferCopy; @@ -8686,7 +8686,7 @@ static void VULKAN_DownloadFromBuffer( renderer, vulkanCommandBuffer->commandBuffer, RESOURCE_ACCESS_TRANSFER_WRITE, - cpuBufferContainer->activeBuffer->vulkanBuffer + transferBufferContainer->activeBuffer->vulkanBuffer ); VULKAN_INTERNAL_BufferMemoryBarrier( @@ -8703,16 +8703,16 @@ static void VULKAN_DownloadFromBuffer( renderer->vkCmdCopyBuffer( vulkanCommandBuffer->commandBuffer, vulkanGpuBuffer->buffer, - cpuBufferContainer->activeBuffer->vulkanBuffer->buffer, + transferBufferContainer->activeBuffer->vulkanBuffer->buffer, 1, &bufferCopy ); - VULKAN_INTERNAL_TrackBuffer(renderer, vulkanCommandBuffer, cpuBufferContainer->activeBuffer->vulkanBuffer); + VULKAN_INTERNAL_TrackBuffer(renderer, vulkanCommandBuffer, transferBufferContainer->activeBuffer->vulkanBuffer); VULKAN_INTERNAL_TrackBuffer(renderer, vulkanCommandBuffer, vulkanGpuBuffer); VULKAN_INTERNAL_TrackBuffer(renderer, vulkanCommandBuffer, vulkanGpuBuffer); - cpuBufferContainer->activeBuffer->vulkanBuffer->preserveContentsOnDefrag = 1; + transferBufferContainer->activeBuffer->vulkanBuffer->preserveContentsOnDefrag = 1; } static void VULKAN_CopyTextureToTexture( @@ -8793,13 +8793,13 @@ static void VULKAN_CopyTextureToBuffer( Refresh_Renderer *driverData, Refresh_CommandBuffer *commandBuffer, Refresh_TextureSlice *textureSlice, - Refresh_GpuBuffer *buffer, + Refresh_GpuBuffer *gpuBuffer, Refresh_BufferImageCopy *copyParams ) { VulkanRenderer *renderer = (VulkanRenderer*) driverData; VulkanCommandBuffer *vulkanCommandBuffer = (VulkanCommandBuffer*) commandBuffer; VulkanTexture *vulkanTexture = ((VulkanTextureContainer*) textureSlice->texture)->vulkanTexture; - VulkanBuffer *vulkanBuffer = ((VulkanBufferContainer*) buffer)->vulkanBuffer; + VulkanBuffer *vulkanBuffer = ((VulkanBufferContainer*) gpuBuffer)->vulkanBuffer; VkBufferImageCopy imageCopy; VULKAN_INTERNAL_ImageMemoryBarrier( @@ -8855,13 +8855,13 @@ static void VULKAN_CopyTextureToBuffer( static void VULKAN_CopyBufferToTexture( Refresh_Renderer *driverData, Refresh_CommandBuffer *commandBuffer, - Refresh_GpuBuffer *buffer, + Refresh_GpuBuffer *gpuBuffer, Refresh_TextureSlice *textureSlice, Refresh_BufferImageCopy *copyParams ) { VulkanRenderer *renderer = (VulkanRenderer*) driverData; VulkanCommandBuffer *vulkanCommandBuffer = (VulkanCommandBuffer*) commandBuffer; - VulkanBuffer *vulkanBuffer = ((VulkanBufferContainer*) buffer)->vulkanBuffer; + VulkanBuffer *vulkanBuffer = ((VulkanBufferContainer*) gpuBuffer)->vulkanBuffer; VulkanTexture *vulkanTexture = ((VulkanTextureContainer*) textureSlice->texture)->vulkanTexture; VkBufferImageCopy imageCopy; -- 2.25.1 From 733ca6f650e6122d5222f281036f02e3bc423f83 Mon Sep 17 00:00:00 2001 From: cosmonaut Date: Fri, 23 Feb 2024 10:42:52 -0800 Subject: [PATCH 19/20] fix double refcount on compute resources --- src/Refresh_Driver_Vulkan.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Refresh_Driver_Vulkan.c b/src/Refresh_Driver_Vulkan.c index b185aa2..e4efd04 100644 --- a/src/Refresh_Driver_Vulkan.c +++ b/src/Refresh_Driver_Vulkan.c @@ -3393,7 +3393,7 @@ static void VULKAN_INTERNAL_TrackComputeBuffer( VulkanCommandBuffer *commandBuffer, VulkanBuffer *computeBuffer ) { - TRACK_RESOURCE( + ADD_TO_ARRAY_UNIQUE( computeBuffer, VulkanBuffer*, boundComputeBuffers, @@ -3407,7 +3407,7 @@ static void VULKAN_INTERNAL_TrackComputeTexture( VulkanCommandBuffer *commandBuffer, VulkanTexture *computeTexture ) { - TRACK_RESOURCE( + ADD_TO_ARRAY_UNIQUE( computeTexture, VulkanTexture*, boundComputeTextures, -- 2.25.1 From bade5ac0b96b2e80bc7f1e4de7d2bd120455eaab Mon Sep 17 00:00:00 2001 From: cosmonaut Date: Fri, 23 Feb 2024 15:30:22 -0800 Subject: [PATCH 20/20] update shader compiler to use net8.0 --- shadercompiler/refreshc.csproj | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/shadercompiler/refreshc.csproj b/shadercompiler/refreshc.csproj index 309740b..70b0822 100644 --- a/shadercompiler/refreshc.csproj +++ b/shadercompiler/refreshc.csproj @@ -2,9 +2,9 @@ Exe - net7.0 + net8.0 refreshc - true + true -- 2.25.1