diff --git a/include/Refresh.h b/include/Refresh.h index 682e3da..aa2de3f 100644 --- a/include/Refresh.h +++ b/include/Refresh.h @@ -658,6 +658,7 @@ REFRESHAPI void REFRESH_DestroyDevice(REFRESH_Device *device); */ REFRESHAPI void REFRESH_Clear( REFRESH_Device *device, + REFRESH_CommandBuffer *commandBuffer, REFRESH_Rect *clearRect, REFRESH_ClearOptions options, REFRESH_Color *colors, @@ -681,6 +682,7 @@ REFRESHAPI void REFRESH_Clear( */ REFRESHAPI void REFRESH_DrawInstancedPrimitives( REFRESH_Device *device, + REFRESH_CommandBuffer *commandBuffer, uint32_t baseVertex, uint32_t minVertexIndex, uint32_t numVertices, @@ -707,6 +709,7 @@ REFRESHAPI void REFRESH_DrawInstancedPrimitives( */ REFRESHAPI void REFRESH_DrawIndexedPrimitives( REFRESH_Device *device, + REFRESH_CommandBuffer *commandBuffer, uint32_t baseVertex, uint32_t minVertexIndex, uint32_t numVertices, @@ -727,6 +730,7 @@ REFRESHAPI void REFRESH_DrawIndexedPrimitives( */ REFRESHAPI void REFRESH_DrawPrimitives( REFRESH_Device *device, + REFRESH_CommandBuffer *commandBuffer, uint32_t vertexStart, uint32_t primitiveCount, uint32_t vertexParamOffset, @@ -742,6 +746,7 @@ REFRESHAPI void REFRESH_DrawPrimitives( */ REFRESHAPI void REFRESH_DispatchCompute( REFRESH_Device *device, + REFRESH_CommandBuffer *commandBuffer, uint32_t groupCountX, uint32_t groupCountY, uint32_t groupCountZ, @@ -895,7 +900,7 @@ REFRESHAPI REFRESH_Buffer* REFRESH_CreateBuffer( * dataLength: The size of the image data in bytes. */ REFRESHAPI void REFRESH_SetTextureData2D( - REFRESH_Device *device, + REFRESH_Device *driverData, REFRESH_Texture *texture, uint32_t x, uint32_t y, @@ -920,7 +925,7 @@ REFRESHAPI void REFRESH_SetTextureData2D( * dataLength: The size of the image data in bytes. */ REFRESHAPI void REFRESH_SetTextureData3D( - REFRESH_Device *device, + REFRESH_Device *driverData, REFRESH_Texture *texture, uint32_t x, uint32_t y, @@ -946,7 +951,7 @@ REFRESHAPI void REFRESH_SetTextureData3D( * dataLength: The size of the image data in bytes. */ REFRESHAPI void REFRESH_SetTextureDataCube( - REFRESH_Device *device, + REFRESH_Device *driverData, REFRESH_Texture *texture, uint32_t x, uint32_t y, @@ -971,7 +976,7 @@ REFRESHAPI void REFRESH_SetTextureDataCube( * dataLength: The size of the image data in bytes. */ REFRESHAPI void REFRESH_SetTextureDataYUV( - REFRESH_Device *device, + REFRESH_Device *driverData, REFRESH_Texture *y, REFRESH_Texture *u, REFRESH_Texture *v, @@ -1014,6 +1019,7 @@ REFRESHAPI void REFRESH_SetBufferData( */ REFRESHAPI uint32_t REFRESH_PushVertexShaderParams( REFRESH_Device *device, + REFRESH_CommandBuffer *commandBuffer, void *data, uint32_t paramBlockCount ); @@ -1030,6 +1036,7 @@ REFRESHAPI uint32_t REFRESH_PushVertexShaderParams( */ REFRESHAPI uint32_t REFRESH_PushFragmentShaderParams( REFRESH_Device *device, + REFRESH_CommandBuffer *commandBuffer, void *data, uint32_t paramBlockCount ); @@ -1046,6 +1053,7 @@ REFRESHAPI uint32_t REFRESH_PushFragmentShaderParams( */ REFRESHAPI uint32_t REFRESH_PushComputeShaderParams( REFRESH_Device *device, + REFRESH_CommandBuffer *commandBuffer, void *data, uint32_t paramBlockCount ); @@ -1061,6 +1069,7 @@ REFRESHAPI uint32_t REFRESH_PushComputeShaderParams( */ REFRESHAPI void REFRESH_SetVertexSamplers( REFRESH_Device *device, + REFRESH_CommandBuffer *commandBuffer, REFRESH_Texture **pTextures, REFRESH_Sampler **pSamplers ); @@ -1076,6 +1085,7 @@ REFRESHAPI void REFRESH_SetVertexSamplers( */ REFRESHAPI void REFRESH_SetFragmentSamplers( REFRESH_Device *device, + REFRESH_CommandBuffer *commandBuffer, REFRESH_Texture **pTextures, REFRESH_Sampler **pSamplers ); @@ -1284,6 +1294,7 @@ REFRESHAPI void REFRESH_AddDisposeGraphicsPipeline( */ REFRESHAPI void REFRESH_BeginRenderPass( REFRESH_Device *device, + REFRESH_CommandBuffer *commandBuffer, REFRESH_RenderPass *renderPass, REFRESH_Framebuffer *framebuffer, REFRESH_Rect renderArea, @@ -1294,18 +1305,21 @@ REFRESHAPI void REFRESH_BeginRenderPass( /* Ends the current render pass. */ REFRESHAPI void REFRESH_EndRenderPass( - REFRESH_Device *device + REFRESH_Device *device, + REFRESH_CommandBuffer *commandBuffer ); /* Binds a graphics pipeline to the graphics bind point. */ REFRESHAPI void REFRESH_BindGraphicsPipeline( REFRESH_Device *device, + REFRESH_CommandBuffer *commandBuffer, REFRESH_GraphicsPipeline *graphicsPipeline ); /* Binds vertex buffers for use with subsequent draw calls. */ REFRESHAPI void REFRESH_BindVertexBuffers( REFRESH_Device *device, + REFRESH_CommandBuffer *commandBuffer, uint32_t firstBinding, uint32_t bindingCount, REFRESH_Buffer **pBuffers, @@ -1315,6 +1329,7 @@ REFRESHAPI void REFRESH_BindVertexBuffers( /* Binds an index buffer for use with subsequent draw calls. */ REFRESHAPI void REFRESH_BindIndexBuffer( REFRESH_Device *device, + REFRESH_CommandBuffer *commandBuffer, REFRESH_Buffer *buffer, uint64_t offset, REFRESH_IndexElementSize indexElementSize @@ -1323,6 +1338,7 @@ REFRESHAPI void REFRESH_BindIndexBuffer( /* Binds a compute pipeline to the compute bind point. */ REFRESHAPI void REFRESH_BindComputePipeline( REFRESH_Device *device, + REFRESH_CommandBuffer *commandBuffer, REFRESH_ComputePipeline *computePipeline ); @@ -1334,6 +1350,7 @@ REFRESHAPI void REFRESH_BindComputePipeline( */ REFRESHAPI void REFRESH_BindComputeBuffers( REFRESH_Device *device, + REFRESH_CommandBuffer *commandBuffer, REFRESH_Buffer **pBuffers ); @@ -1345,6 +1362,7 @@ REFRESHAPI void REFRESH_BindComputeBuffers( */ REFRESHAPI void REFRESH_BindComputeTextures( REFRESH_Device *device, + REFRESH_CommandBuffer *commandBuffer, REFRESH_Texture **pTextures ); @@ -1379,6 +1397,7 @@ REFRESHAPI REFRESH_CommandBuffer* REFRESH_AcquireCommandBuffer( */ REFRESHAPI void REFRESH_QueuePresent( REFRESH_Device *device, + REFRESH_CommandBuffer *commandBuffer, REFRESH_TextureSlice *textureSlice, REFRESH_Rect *sourceRectangle, REFRESH_Rect *destinationRectangle @@ -1386,7 +1405,9 @@ REFRESHAPI void REFRESH_QueuePresent( /* Submits all of the enqueued commands. */ REFRESHAPI void REFRESH_Submit( - REFRESH_Device* device + REFRESH_Device* device, + REFRESH_CommandBuffer **pCommandBuffers, + uint32_t commandBufferCount ); #ifdef __cplusplus diff --git a/src/Refresh.c b/src/Refresh.c index b439bff..6505d8b 100644 --- a/src/Refresh.c +++ b/src/Refresh.c @@ -148,7 +148,8 @@ void REFRESH_DestroyDevice(REFRESH_Device *device) } void REFRESH_Clear( - REFRESH_Device *device, + REFRESH_Device *device, + REFRESH_CommandBuffer *commandBuffer, REFRESH_Rect *clearRect, REFRESH_ClearOptions options, REFRESH_Color *colors, @@ -159,6 +160,7 @@ void REFRESH_Clear( NULL_RETURN(device); device->Clear( device->driverData, + commandBuffer, clearRect, options, colors, @@ -170,6 +172,7 @@ void REFRESH_Clear( void REFRESH_DrawIndexedPrimitives( REFRESH_Device *device, + REFRESH_CommandBuffer *commandBuffer, uint32_t baseVertex, uint32_t minVertexIndex, uint32_t numVertices, @@ -183,6 +186,7 @@ void REFRESH_DrawIndexedPrimitives( NULL_RETURN(device); device->DrawIndexedPrimitives( device->driverData, + commandBuffer, baseVertex, minVertexIndex, numVertices, @@ -197,6 +201,7 @@ void REFRESH_DrawIndexedPrimitives( void REFRESH_DrawInstancedPrimitives( REFRESH_Device *device, + REFRESH_CommandBuffer *commandBuffer, uint32_t baseVertex, uint32_t minVertexIndex, uint32_t numVertices, @@ -211,6 +216,7 @@ void REFRESH_DrawInstancedPrimitives( NULL_RETURN(device); device->DrawInstancedPrimitives( device->driverData, + commandBuffer, baseVertex, minVertexIndex, numVertices, @@ -226,6 +232,7 @@ void REFRESH_DrawInstancedPrimitives( void REFRESH_DrawPrimitives( REFRESH_Device *device, + REFRESH_CommandBuffer *commandBuffer, uint32_t vertexStart, uint32_t primitiveCount, uint32_t vertexParamOffset, @@ -234,6 +241,7 @@ void REFRESH_DrawPrimitives( NULL_RETURN(device); device->DrawPrimitives( device->driverData, + commandBuffer, vertexStart, primitiveCount, vertexParamOffset, @@ -243,6 +251,7 @@ void REFRESH_DrawPrimitives( void REFRESH_DispatchCompute( REFRESH_Device *device, + REFRESH_CommandBuffer *commandBuffer, uint32_t groupCountX, uint32_t groupCountY, uint32_t groupCountZ, @@ -251,6 +260,7 @@ void REFRESH_DispatchCompute( NULL_RETURN(device); device->DispatchCompute( device->driverData, + commandBuffer, groupCountX, groupCountY, groupCountZ, @@ -549,12 +559,14 @@ void REFRESH_SetBufferData( uint32_t REFRESH_PushVertexShaderParams( REFRESH_Device *device, + REFRESH_CommandBuffer *commandBuffer, void *data, uint32_t elementCount ) { if (device == NULL) { return 0; } return device->PushVertexShaderParams( device->driverData, + commandBuffer, data, elementCount ); @@ -562,12 +574,14 @@ uint32_t REFRESH_PushVertexShaderParams( uint32_t REFRESH_PushFragmentShaderParams( REFRESH_Device *device, + REFRESH_CommandBuffer *commandBuffer, void *data, uint32_t elementCount ) { if (device == NULL) { return 0; } return device->PushFragmentShaderParams( device->driverData, + commandBuffer, data, elementCount ); @@ -575,12 +589,14 @@ uint32_t REFRESH_PushFragmentShaderParams( uint32_t REFRESH_PushComputeShaderParams( REFRESH_Device *device, + REFRESH_CommandBuffer *commandBuffer, void *data, uint32_t elementCount ) { if (device == NULL) { return 0; } return device->PushComputeShaderParams( device->driverData, + commandBuffer, data, elementCount ); @@ -588,12 +604,14 @@ uint32_t REFRESH_PushComputeShaderParams( void REFRESH_SetVertexSamplers( REFRESH_Device *device, + REFRESH_CommandBuffer *commandBuffer, REFRESH_Texture **pTextures, REFRESH_Sampler **pSamplers ) { NULL_RETURN(device); device->SetVertexSamplers( device->driverData, + commandBuffer, pTextures, pSamplers ); @@ -601,12 +619,14 @@ void REFRESH_SetVertexSamplers( void REFRESH_SetFragmentSamplers( REFRESH_Device *device, + REFRESH_CommandBuffer *commandBuffer, REFRESH_Texture **pTextures, REFRESH_Sampler **pSamplers ) { NULL_RETURN(device); device->SetFragmentSamplers( device->driverData, + commandBuffer, pTextures, pSamplers ); @@ -783,6 +803,7 @@ void REFRESH_AddDisposeGraphicsPipeline( void REFRESH_BeginRenderPass( REFRESH_Device *device, + REFRESH_CommandBuffer *commandBuffer, REFRESH_RenderPass *renderPass, REFRESH_Framebuffer *framebuffer, REFRESH_Rect renderArea, @@ -793,6 +814,7 @@ void REFRESH_BeginRenderPass( NULL_RETURN(device); device->BeginRenderPass( device->driverData, + commandBuffer, renderPass, framebuffer, renderArea, @@ -803,25 +825,32 @@ void REFRESH_BeginRenderPass( } void REFRESH_EndRenderPass( - REFRESH_Device *device + REFRESH_Device *device, + REFRESH_CommandBuffer *commandBuffer ) { NULL_RETURN(device); - device->EndRenderPass(device->driverData); + device->EndRenderPass( + device->driverData, + commandBuffer + ); } void REFRESH_BindGraphicsPipeline( REFRESH_Device *device, + REFRESH_CommandBuffer *commandBuffer, REFRESH_GraphicsPipeline *graphicsPipeline ) { NULL_RETURN(device); device->BindGraphicsPipeline( device->driverData, + commandBuffer, graphicsPipeline ); } void REFRESH_BindVertexBuffers( REFRESH_Device *device, + REFRESH_CommandBuffer *commandBuffer, uint32_t firstBinding, uint32_t bindingCount, REFRESH_Buffer **pBuffers, @@ -830,6 +859,7 @@ void REFRESH_BindVertexBuffers( NULL_RETURN(device); device->BindVertexBuffers( device->driverData, + commandBuffer, firstBinding, bindingCount, pBuffers, @@ -839,6 +869,7 @@ void REFRESH_BindVertexBuffers( void REFRESH_BindIndexBuffer( REFRESH_Device *device, + REFRESH_CommandBuffer *commandBuffer, REFRESH_Buffer *buffer, uint64_t offset, REFRESH_IndexElementSize indexElementSize @@ -846,6 +877,7 @@ void REFRESH_BindIndexBuffer( NULL_RETURN(device); device->BindIndexBuffer( device->driverData, + commandBuffer, buffer, offset, indexElementSize @@ -854,33 +886,39 @@ void REFRESH_BindIndexBuffer( void REFRESH_BindComputePipeline( REFRESH_Device *device, + REFRESH_CommandBuffer *commandBuffer, REFRESH_ComputePipeline *computePipeline ) { NULL_RETURN(device); device->BindComputePipeline( device->driverData, + commandBuffer, computePipeline ); } void REFRESH_BindComputeBuffers( REFRESH_Device *device, + REFRESH_CommandBuffer *commandBuffer, REFRESH_Buffer **pBuffers ) { NULL_RETURN(device); device->BindComputeBuffers( device->driverData, + commandBuffer, pBuffers ); } void REFRESH_BindComputeTextures( REFRESH_Device *device, + REFRESH_CommandBuffer *commandBuffer, REFRESH_Texture **pTextures ) { NULL_RETURN(device); device->BindComputeTextures( device->driverData, + commandBuffer, pTextures ); } @@ -898,6 +936,7 @@ REFRESH_CommandBuffer* REFRESH_AcquireCommandBuffer( void REFRESH_QueuePresent( REFRESH_Device *device, + REFRESH_CommandBuffer *commandBuffer, REFRESH_TextureSlice* textureSlice, REFRESH_Rect *sourceRectangle, REFRESH_Rect *destinationRectangle @@ -905,6 +944,7 @@ void REFRESH_QueuePresent( NULL_RETURN(device); device->QueuePresent( device->driverData, + commandBuffer, textureSlice, sourceRectangle, destinationRectangle @@ -912,11 +952,15 @@ void REFRESH_QueuePresent( } void REFRESH_Submit( - REFRESH_Device *device + REFRESH_Device *device, + REFRESH_CommandBuffer **pCommandBuffers, + uint32_t commandBufferCount ) { NULL_RETURN(device); device->Submit( - device->driverData + device->driverData, + pCommandBuffers, + commandBufferCount ); } diff --git a/src/Refresh_Driver.h b/src/Refresh_Driver.h index bea283b..1334aac 100644 --- a/src/Refresh_Driver.h +++ b/src/Refresh_Driver.h @@ -169,6 +169,7 @@ struct REFRESH_Device void (*Clear)( REFRESH_Renderer *driverData, + REFRESH_CommandBuffer *commandBuffer, REFRESH_Rect *clearRect, REFRESH_ClearOptions options, REFRESH_Color *colors, @@ -179,6 +180,7 @@ struct REFRESH_Device void (*DrawInstancedPrimitives)( REFRESH_Renderer *driverData, + REFRESH_CommandBuffer *commandBuffer, uint32_t baseVertex, uint32_t minVertexIndex, uint32_t numVertices, @@ -193,6 +195,7 @@ struct REFRESH_Device void (*DrawIndexedPrimitives)( REFRESH_Renderer *driverData, + REFRESH_CommandBuffer *commandBuffer, uint32_t baseVertex, uint32_t minVertexIndex, uint32_t numVertices, @@ -206,6 +209,7 @@ struct REFRESH_Device void (*DrawPrimitives)( REFRESH_Renderer *driverData, + REFRESH_CommandBuffer *commandBuffer, uint32_t vertexStart, uint32_t primitiveCount, uint32_t vertexParamOffset, @@ -214,6 +218,7 @@ struct REFRESH_Device void (*DispatchCompute)( REFRESH_Renderer *device, + REFRESH_CommandBuffer *commandBuffer, uint32_t groupCountX, uint32_t groupCountY, uint32_t groupCountZ, @@ -362,30 +367,35 @@ struct REFRESH_Device uint32_t(*PushVertexShaderParams)( REFRESH_Renderer *driverData, + REFRESH_CommandBuffer *commandBuffer, void *data, uint32_t elementCount ); uint32_t(*PushFragmentShaderParams)( REFRESH_Renderer *driverData, + REFRESH_CommandBuffer *commandBuffer, void *data, uint32_t elementCount ); uint32_t (*PushComputeShaderParams)( REFRESH_Renderer *driverData, + REFRESH_CommandBuffer *commandBuffer, void *data, uint32_t elementCount ); void(*SetVertexSamplers)( REFRESH_Renderer *driverData, + REFRESH_CommandBuffer *commandBuffer, REFRESH_Texture **pTextures, REFRESH_Sampler **pSamplers ); void(*SetFragmentSamplers)( REFRESH_Renderer *driverData, + REFRESH_CommandBuffer *commandBuffer, REFRESH_Texture **pTextures, REFRESH_Sampler **pSamplers ); @@ -476,6 +486,7 @@ struct REFRESH_Device void(*BeginRenderPass)( REFRESH_Renderer *driverData, + REFRESH_CommandBuffer *commandBuffer, REFRESH_RenderPass *renderPass, REFRESH_Framebuffer *framebuffer, REFRESH_Rect renderArea, @@ -485,16 +496,19 @@ struct REFRESH_Device ); void(*EndRenderPass)( - REFRESH_Renderer *driverData + REFRESH_Renderer *driverData, + REFRESH_CommandBuffer *commandBuffer ); void(*BindGraphicsPipeline)( REFRESH_Renderer *driverData, + REFRESH_CommandBuffer *commandBuffer, REFRESH_GraphicsPipeline *graphicsPipeline ); void(*BindVertexBuffers)( REFRESH_Renderer *driverData, + REFRESH_CommandBuffer *commandBuffer, uint32_t firstBinding, uint32_t bindingCount, REFRESH_Buffer **pBuffers, @@ -503,6 +517,7 @@ struct REFRESH_Device void(*BindIndexBuffer)( REFRESH_Renderer *driverData, + REFRESH_CommandBuffer *commandBuffer, REFRESH_Buffer *buffer, uint64_t offset, REFRESH_IndexElementSize indexElementSize @@ -510,16 +525,19 @@ struct REFRESH_Device void(*BindComputePipeline)( REFRESH_Renderer *driverData, + REFRESH_CommandBuffer *commandBuffer, REFRESH_ComputePipeline *computePipeline ); void(*BindComputeBuffers)( REFRESH_Renderer *driverData, + REFRESH_CommandBuffer *commandBuffer, REFRESH_Buffer **pBuffers ); void(*BindComputeTextures)( REFRESH_Renderer *driverData, + REFRESH_CommandBuffer *commandBuffer, REFRESH_Texture **pTextures ); @@ -530,13 +548,16 @@ struct REFRESH_Device void(*QueuePresent)( REFRESH_Renderer *driverData, + REFRESH_CommandBuffer *commandBuffer, REFRESH_TextureSlice *textureSlice, REFRESH_Rect *sourceRectangle, REFRESH_Rect *destinationRectangle ); void(*Submit)( - REFRESH_Renderer *driverData + REFRESH_Renderer *driverData, + REFRESH_CommandBuffer **pCommandBuffers, + uint32_t commandBufferCount ); /* Opaque pointer for the Driver */ diff --git a/src/Refresh_Driver_Vulkan.c b/src/Refresh_Driver_Vulkan.c index 01ed4a6..5bb9639 100644 --- a/src/Refresh_Driver_Vulkan.c +++ b/src/Refresh_Driver_Vulkan.c @@ -682,6 +682,7 @@ typedef struct QueueFamilyIndices { uint32_t graphicsFamily; uint32_t presentFamily; + uint32_t transferFamily; } QueueFamilyIndices; typedef struct SwapChainSupportDetails @@ -750,6 +751,7 @@ typedef struct VulkanTexture VkFormat format; REFRESH_SurfaceFormat refreshFormat; VulkanResourceAccessType resourceAccessType; + uint32_t queueFamilyIndex; REFRESH_TextureUsageFlags usageFlags; REFRESHNAMELESS union { @@ -1152,9 +1154,6 @@ typedef struct VulkanCommandBuffer VulkanCommandPool *commandPool; - /* FIXME: do we even use this? */ - uint32_t numActiveCommands; - VulkanComputePipeline *currentComputePipeline; VulkanGraphicsPipeline *currentGraphicsPipeline; VulkanFramebuffer *currentFramebuffer; @@ -1211,11 +1210,17 @@ typedef struct VulkanRenderer QueueFamilyIndices queueFamilyIndices; VkQueue graphicsQueue; VkQueue presentQueue; + VkQueue transferQueue; VkFence inFlightFence; + VkSemaphore transferFinishedSemaphore; VkSemaphore imageAvailableSemaphore; VkSemaphore renderFinishedSemaphore; + VkCommandPool transferCommandPool; + VkCommandBuffer transferCommandBuffers[2]; /* frame count */ + uint8_t pendingTransfer; + VulkanCommandBuffer **submittedCommandBuffers; uint32_t submittedCommandBufferCount; uint32_t submittedCommandBufferCapacity; @@ -1370,7 +1375,7 @@ typedef struct VulkanRenderer static void VULKAN_INTERNAL_BeginCommandBuffer(VulkanRenderer *renderer, VulkanCommandBuffer *commandBuffer); static void VULKAN_Submit(REFRESH_Renderer *driverData, REFRESH_CommandBuffer **pCommandBuffers, uint32_t commandBufferCount); -static void VULKAN_SubmitAndSync(REFRESH_Renderer *driverData, REFRESH_CommandBuffer *commandBuffer); +static void VULKAN_INTERNAL_SubmitTransfer(REFRESH_Renderer *driverData); /* Error Handling */ @@ -1901,7 +1906,7 @@ static uint8_t VULKAN_INTERNAL_FindAvailableMemory( static void VULKAN_INTERNAL_BufferMemoryBarrier( VulkanRenderer *renderer, - VulkanCommandBuffer *commandBuffer, + VkCommandBuffer commandBuffer, VulkanResourceAccessType nextResourceAccessType, VulkanBuffer *buffer, VulkanSubBuffer *subBuffer @@ -1957,7 +1962,7 @@ static void VULKAN_INTERNAL_BufferMemoryBarrier( } renderer->vkCmdPipelineBarrier( - commandBuffer->commandBuffer, + commandBuffer, srcStages, dstStages, 0, @@ -1968,14 +1973,13 @@ static void VULKAN_INTERNAL_BufferMemoryBarrier( 0, NULL ); - commandBuffer->numActiveCommands += 1; buffer->resourceAccessType = nextResourceAccessType; } static void VULKAN_INTERNAL_ImageMemoryBarrier( VulkanRenderer *renderer, - VulkanCommandBuffer *commandBuffer, + VkCommandBuffer commandBuffer, VulkanResourceAccessType nextAccess, VkImageAspectFlags aspectMask, uint32_t baseLayer, @@ -1984,6 +1988,8 @@ static void VULKAN_INTERNAL_ImageMemoryBarrier( uint32_t levelCount, uint8_t discardContents, VkImage image, + uint32_t dstQueueFamilyIndex, + uint32_t *srcQueueFamilyIndex, /* can be NULL */ VulkanResourceAccessType *resourceAccessType ) { VkPipelineStageFlags srcStages = 0; @@ -2003,8 +2009,15 @@ static void VULKAN_INTERNAL_ImageMemoryBarrier( memoryBarrier.dstAccessMask = 0; memoryBarrier.oldLayout = VK_IMAGE_LAYOUT_UNDEFINED; memoryBarrier.newLayout = VK_IMAGE_LAYOUT_UNDEFINED; - memoryBarrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; - memoryBarrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; + memoryBarrier.dstQueueFamilyIndex = dstQueueFamilyIndex; + if (dstQueueFamilyIndex == VK_QUEUE_FAMILY_IGNORED) + { + memoryBarrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; + } + else + { + memoryBarrier.srcQueueFamilyIndex = *srcQueueFamilyIndex; + } memoryBarrier.image = image; memoryBarrier.subresourceRange.aspectMask = aspectMask; memoryBarrier.subresourceRange.baseArrayLayer = baseLayer; @@ -2048,7 +2061,7 @@ static void VULKAN_INTERNAL_ImageMemoryBarrier( } renderer->vkCmdPipelineBarrier( - commandBuffer->commandBuffer, + commandBuffer, srcStages, dstStages, 0, @@ -2059,7 +2072,11 @@ static void VULKAN_INTERNAL_ImageMemoryBarrier( 1, &memoryBarrier ); - commandBuffer->numActiveCommands += 1; + + if (dstQueueFamilyIndex != VK_QUEUE_FAMILY_IGNORED) + { + *srcQueueFamilyIndex = dstQueueFamilyIndex; + } *resourceAccessType = nextAccess; } @@ -3311,7 +3328,6 @@ static void VULKAN_INTERNAL_EndCommandBuffer( commandBuffer->currentComputePipeline = NULL; commandBuffer->boundComputeBufferCount = 0; - commandBuffer->numActiveCommands = 0; } /* Public API */ @@ -3346,6 +3362,12 @@ static void VULKAN_DestroyDevice( VULKAN_INTERNAL_DestroyTextureStagingBuffer(renderer); + renderer->vkDestroySemaphore( + renderer->logicalDevice, + renderer->transferFinishedSemaphore, + NULL + ); + renderer->vkDestroySemaphore( renderer->logicalDevice, renderer->imageAvailableSemaphore, @@ -3545,7 +3567,7 @@ static void VULKAN_Clear( float depth, int32_t stencil ) { - VulkanRenderer *renderer = (VulkanRenderer*) driverData; + VulkanRenderer* renderer = (VulkanRenderer*) driverData; VulkanCommandBuffer *vulkanCommandBuffer = (VulkanCommandBuffer*) commandBuffer; uint32_t attachmentCount, i; @@ -3646,7 +3668,6 @@ static void VULKAN_Clear( 1, &vulkanClearRect ); - vulkanCommandBuffer->numActiveCommands += 1; } static void VULKAN_DrawInstancedPrimitives( @@ -3663,7 +3684,7 @@ static void VULKAN_DrawInstancedPrimitives( uint32_t vertexParamOffset, uint32_t fragmentParamOffset ) { - VulkanRenderer *renderer = (VulkanRenderer*) driverData; + VulkanRenderer* renderer = (VulkanRenderer*) driverData; VulkanCommandBuffer *vulkanCommandBuffer = (VulkanCommandBuffer*) commandBuffer; VkDescriptorSet descriptorSets[4]; @@ -3687,7 +3708,6 @@ static void VULKAN_DrawInstancedPrimitives( 2, dynamicOffsets ); - vulkanCommandBuffer->numActiveCommands += 1; renderer->vkCmdDrawIndexed( vulkanCommandBuffer->commandBuffer, @@ -3700,7 +3720,6 @@ static void VULKAN_DrawInstancedPrimitives( baseVertex, 0 ); - vulkanCommandBuffer->numActiveCommands += 1; } static void VULKAN_DrawIndexedPrimitives( @@ -3740,8 +3759,9 @@ static void VULKAN_DrawPrimitives( uint32_t vertexParamOffset, uint32_t fragmentParamOffset ) { - VulkanRenderer *renderer = (VulkanRenderer*) driverData; + VulkanRenderer* renderer = (VulkanRenderer*) driverData; VulkanCommandBuffer *vulkanCommandBuffer = (VulkanCommandBuffer*) commandBuffer; + VkDescriptorSet descriptorSets[4]; uint32_t dynamicOffsets[2]; @@ -3763,7 +3783,6 @@ static void VULKAN_DrawPrimitives( 2, dynamicOffsets ); - vulkanCommandBuffer->numActiveCommands += 1; renderer->vkCmdDraw( vulkanCommandBuffer->commandBuffer, @@ -3775,7 +3794,6 @@ static void VULKAN_DrawPrimitives( vertexStart, 0 ); - vulkanCommandBuffer->numActiveCommands += 1; } static void VULKAN_DispatchCompute( @@ -3786,9 +3804,10 @@ static void VULKAN_DispatchCompute( uint32_t groupCountZ, uint32_t computeParamOffset ) { - VulkanRenderer *renderer = (VulkanRenderer*) driverData; + VulkanRenderer* renderer = (VulkanRenderer*) driverData; VulkanCommandBuffer *vulkanCommandBuffer = (VulkanCommandBuffer*) commandBuffer; VulkanComputePipeline *computePipeline = vulkanCommandBuffer->currentComputePipeline; + VulkanBuffer *currentBuffer; VkDescriptorSet descriptorSets[3]; uint32_t i; @@ -3798,7 +3817,7 @@ static void VULKAN_DispatchCompute( currentBuffer = vulkanCommandBuffer->boundComputeBuffers[i]; VULKAN_INTERNAL_BufferMemoryBarrier( renderer, - vulkanCommandBuffer, + vulkanCommandBuffer->commandBuffer, RESOURCE_ACCESS_COMPUTE_SHADER_READ_OTHER, currentBuffer, currentBuffer->subBuffers[currentBuffer->currentSubBufferIndex] @@ -3819,7 +3838,6 @@ static void VULKAN_DispatchCompute( 1, &computeParamOffset ); - vulkanCommandBuffer->numActiveCommands += 1; renderer->vkCmdDispatch( vulkanCommandBuffer->commandBuffer, @@ -3827,7 +3845,6 @@ static void VULKAN_DispatchCompute( groupCountY, groupCountZ ); - vulkanCommandBuffer->numActiveCommands += 1; for (i = 0; i < vulkanCommandBuffer->boundComputeBufferCount; i += 1) { @@ -3836,7 +3853,7 @@ static void VULKAN_DispatchCompute( { VULKAN_INTERNAL_BufferMemoryBarrier( renderer, - vulkanCommandBuffer, + vulkanCommandBuffer->commandBuffer, RESOURCE_ACCESS_VERTEX_BUFFER, currentBuffer, currentBuffer->subBuffers[currentBuffer->currentSubBufferIndex] @@ -3846,7 +3863,7 @@ static void VULKAN_DispatchCompute( { VULKAN_INTERNAL_BufferMemoryBarrier( renderer, - vulkanCommandBuffer, + vulkanCommandBuffer->commandBuffer, RESOURCE_ACCESS_INDEX_BUFFER, currentBuffer, currentBuffer->subBuffers[currentBuffer->currentSubBufferIndex] @@ -5420,6 +5437,7 @@ static uint8_t VULKAN_INTERNAL_CreateTexture( texture->levelCount = levelCount; texture->layerCount = layerCount; texture->resourceAccessType = RESOURCE_ACCESS_NONE; + texture->queueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; texture->usageFlags = textureUsageFlags; return 1; @@ -5754,7 +5772,6 @@ static void VULKAN_INTERNAL_MaybeExpandStagingBuffer( static void VULKAN_SetTextureData2D( REFRESH_Renderer *driverData, - REFRESH_CommandBuffer *commandBuffer, REFRESH_Texture *texture, uint32_t x, uint32_t y, @@ -5764,9 +5781,10 @@ static void VULKAN_SetTextureData2D( void *data, uint32_t dataLengthInBytes ) { - VkResult vulkanResult; VulkanRenderer *renderer = (VulkanRenderer*) driverData; - VulkanCommandBuffer *vulkanCommandBuffer = (VulkanCommandBuffer*) commandBuffer; + + VkCommandBuffer commandBuffer = renderer->transferCommandBuffers[renderer->frameIndex]; + VkResult vulkanResult; VulkanTexture *vulkanTexture = (VulkanTexture*) texture; VkBufferImageCopy imageCopy; uint8_t *mapPointer; @@ -5797,7 +5815,7 @@ static void VULKAN_SetTextureData2D( VULKAN_INTERNAL_ImageMemoryBarrier( renderer, - vulkanCommandBuffer, + renderer->transferCommandBuffers[renderer->frameIndex], RESOURCE_ACCESS_TRANSFER_WRITE, VK_IMAGE_ASPECT_COLOR_BIT, 0, @@ -5806,6 +5824,8 @@ static void VULKAN_SetTextureData2D( vulkanTexture->levelCount, 0, vulkanTexture->image, + renderer->queueFamilyIndices.transferFamily, + &vulkanTexture->queueFamilyIndex, &vulkanTexture->resourceAccessType ); @@ -5824,20 +5844,19 @@ static void VULKAN_SetTextureData2D( imageCopy.bufferImageHeight = 0; renderer->vkCmdCopyBufferToImage( - vulkanCommandBuffer->commandBuffer, + commandBuffer, renderer->textureStagingBuffer->subBuffers[0]->buffer, vulkanTexture->image, AccessMap[vulkanTexture->resourceAccessType].imageLayout, 1, &imageCopy ); - vulkanCommandBuffer->numActiveCommands += 1; if (vulkanTexture->usageFlags & REFRESH_TEXTUREUSAGE_SAMPLER_BIT) { VULKAN_INTERNAL_ImageMemoryBarrier( renderer, - vulkanCommandBuffer, + commandBuffer, RESOURCE_ACCESS_ANY_SHADER_READ_SAMPLED_IMAGE, VK_IMAGE_ASPECT_COLOR_BIT, 0, @@ -5846,17 +5865,19 @@ static void VULKAN_SetTextureData2D( vulkanTexture->levelCount, 0, vulkanTexture->image, + renderer->queueFamilyIndices.graphicsFamily, + &vulkanTexture->queueFamilyIndex, &vulkanTexture->resourceAccessType ); } - /* Hard sync point */ - VULKAN_SubmitAndSync(driverData, commandBuffer); + renderer->pendingTransfer = 1; + + VULKAN_INTERNAL_SubmitTransfer(driverData); } static void VULKAN_SetTextureData3D( REFRESH_Renderer *driverData, - REFRESH_CommandBuffer *commandBuffer, REFRESH_Texture *texture, uint32_t x, uint32_t y, @@ -5868,10 +5889,11 @@ static void VULKAN_SetTextureData3D( void* data, uint32_t dataLength ) { - VkResult vulkanResult; VulkanRenderer *renderer = (VulkanRenderer*) driverData; - VulkanCommandBuffer *vulkanCommandBuffer = (VulkanCommandBuffer*) commandBuffer; VulkanTexture *vulkanTexture = (VulkanTexture*) texture; + + VkCommandBuffer commandBuffer = renderer->transferCommandBuffers[renderer->frameIndex]; + VkResult vulkanResult; VkBufferImageCopy imageCopy; uint8_t *mapPointer; @@ -5901,7 +5923,7 @@ static void VULKAN_SetTextureData3D( VULKAN_INTERNAL_ImageMemoryBarrier( renderer, - vulkanCommandBuffer, + commandBuffer, RESOURCE_ACCESS_TRANSFER_WRITE, VK_IMAGE_ASPECT_COLOR_BIT, 0, @@ -5910,6 +5932,8 @@ static void VULKAN_SetTextureData3D( vulkanTexture->levelCount, 0, vulkanTexture->image, + renderer->queueFamilyIndices.transferFamily, + &vulkanTexture->queueFamilyIndex, &vulkanTexture->resourceAccessType ); @@ -5928,20 +5952,19 @@ static void VULKAN_SetTextureData3D( imageCopy.bufferImageHeight = 0; renderer->vkCmdCopyBufferToImage( - vulkanCommandBuffer->commandBuffer, + commandBuffer, renderer->textureStagingBuffer->subBuffers[0]->buffer, vulkanTexture->image, AccessMap[vulkanTexture->resourceAccessType].imageLayout, 1, &imageCopy ); - vulkanCommandBuffer->numActiveCommands += 1; if (vulkanTexture->usageFlags & REFRESH_TEXTUREUSAGE_SAMPLER_BIT) { VULKAN_INTERNAL_ImageMemoryBarrier( renderer, - vulkanCommandBuffer, + commandBuffer, RESOURCE_ACCESS_ANY_SHADER_READ_SAMPLED_IMAGE, VK_IMAGE_ASPECT_COLOR_BIT, 0, @@ -5950,17 +5973,19 @@ static void VULKAN_SetTextureData3D( vulkanTexture->levelCount, 0, vulkanTexture->image, + renderer->queueFamilyIndices.graphicsFamily, + &vulkanTexture->queueFamilyIndex, &vulkanTexture->resourceAccessType ); } - /* Hard sync point */ - VULKAN_SubmitAndSync(driverData, commandBuffer); + renderer->pendingTransfer = 1; + + VULKAN_INTERNAL_SubmitTransfer(driverData); } static void VULKAN_SetTextureDataCube( REFRESH_Renderer *driverData, - REFRESH_CommandBuffer *commandBuffer, REFRESH_Texture *texture, uint32_t x, uint32_t y, @@ -5971,10 +5996,11 @@ static void VULKAN_SetTextureDataCube( void* data, uint32_t dataLength ) { - VkResult vulkanResult; VulkanRenderer *renderer = (VulkanRenderer*) driverData; - VulkanCommandBuffer *vulkanCommandBuffer = (VulkanCommandBuffer*) commandBuffer; VulkanTexture *vulkanTexture = (VulkanTexture*) texture; + + VkCommandBuffer commandBuffer = renderer->transferCommandBuffers[renderer->frameIndex]; + VkResult vulkanResult; VkBufferImageCopy imageCopy; uint8_t *mapPointer; @@ -6004,7 +6030,7 @@ static void VULKAN_SetTextureDataCube( VULKAN_INTERNAL_ImageMemoryBarrier( renderer, - vulkanCommandBuffer, + commandBuffer, RESOURCE_ACCESS_TRANSFER_WRITE, VK_IMAGE_ASPECT_COLOR_BIT, 0, @@ -6013,6 +6039,8 @@ static void VULKAN_SetTextureDataCube( vulkanTexture->levelCount, 0, vulkanTexture->image, + renderer->queueFamilyIndices.transferFamily, + &vulkanTexture->queueFamilyIndex, &vulkanTexture->resourceAccessType ); @@ -6031,20 +6059,19 @@ static void VULKAN_SetTextureDataCube( imageCopy.bufferImageHeight = 0; /* assumes tightly packed data */ renderer->vkCmdCopyBufferToImage( - vulkanCommandBuffer->commandBuffer, + commandBuffer, renderer->textureStagingBuffer->subBuffers[0]->buffer, vulkanTexture->image, AccessMap[vulkanTexture->resourceAccessType].imageLayout, 1, &imageCopy ); - vulkanCommandBuffer->numActiveCommands += 1; if (vulkanTexture->usageFlags & REFRESH_TEXTUREUSAGE_SAMPLER_BIT) { VULKAN_INTERNAL_ImageMemoryBarrier( renderer, - vulkanCommandBuffer, + commandBuffer, RESOURCE_ACCESS_ANY_SHADER_READ_SAMPLED_IMAGE, VK_IMAGE_ASPECT_COLOR_BIT, 0, @@ -6053,17 +6080,19 @@ static void VULKAN_SetTextureDataCube( vulkanTexture->levelCount, 0, vulkanTexture->image, + renderer->queueFamilyIndices.graphicsFamily, + &vulkanTexture->queueFamilyIndex, &vulkanTexture->resourceAccessType ); } - /* Hard sync point */ - VULKAN_SubmitAndSync(driverData, commandBuffer); + renderer->pendingTransfer = 1; + + VULKAN_INTERNAL_SubmitTransfer(driverData); } static void VULKAN_SetTextureDataYUV( REFRESH_Renderer *driverData, - REFRESH_CommandBuffer *commandBuffer, REFRESH_Texture *y, REFRESH_Texture *u, REFRESH_Texture *v, @@ -6075,8 +6104,9 @@ static void VULKAN_SetTextureDataYUV( uint32_t dataLength ) { VulkanRenderer *renderer = (VulkanRenderer*) driverData; - VulkanCommandBuffer *vulkanCommandBuffer = (VulkanCommandBuffer*) commandBuffer; VulkanTexture *tex; + + VkCommandBuffer commandBuffer = renderer->transferCommandBuffers[renderer->frameIndex]; uint8_t *dataPtr = (uint8_t*) data; int32_t yDataLength = BytesPerImage(yWidth, yHeight, REFRESH_SURFACEFORMAT_R8); int32_t uvDataLength = BytesPerImage(uvWidth, uvHeight, REFRESH_SURFACEFORMAT_R8); @@ -6125,7 +6155,7 @@ static void VULKAN_SetTextureDataYUV( VULKAN_INTERNAL_ImageMemoryBarrier( renderer, - vulkanCommandBuffer, + commandBuffer, RESOURCE_ACCESS_TRANSFER_WRITE, VK_IMAGE_ASPECT_COLOR_BIT, 0, @@ -6134,6 +6164,8 @@ static void VULKAN_SetTextureDataYUV( tex->levelCount, 0, tex->image, + renderer->queueFamilyIndices.transferFamily, + &tex->queueFamilyIndex, &tex->resourceAccessType ); @@ -6143,14 +6175,13 @@ static void VULKAN_SetTextureDataYUV( imageCopy.bufferImageHeight = yHeight; renderer->vkCmdCopyBufferToImage( - vulkanCommandBuffer->commandBuffer, + commandBuffer, renderer->textureStagingBuffer->subBuffers[0]->buffer, tex->image, AccessMap[tex->resourceAccessType].imageLayout, 1, &imageCopy ); - vulkanCommandBuffer->numActiveCommands += 1; /* These apply to both U and V */ @@ -6173,7 +6204,7 @@ static void VULKAN_SetTextureDataYUV( VULKAN_INTERNAL_ImageMemoryBarrier( renderer, - vulkanCommandBuffer, + commandBuffer, RESOURCE_ACCESS_TRANSFER_WRITE, VK_IMAGE_ASPECT_COLOR_BIT, 0, @@ -6182,18 +6213,19 @@ static void VULKAN_SetTextureDataYUV( tex->levelCount, 0, tex->image, + renderer->queueFamilyIndices.transferFamily, + &tex->queueFamilyIndex, &tex->resourceAccessType ); renderer->vkCmdCopyBufferToImage( - vulkanCommandBuffer->commandBuffer, + commandBuffer, renderer->textureStagingBuffer->subBuffers[0]->buffer, tex->image, AccessMap[tex->resourceAccessType].imageLayout, 1, &imageCopy ); - vulkanCommandBuffer->numActiveCommands += 1; /* V */ @@ -6214,7 +6246,7 @@ static void VULKAN_SetTextureDataYUV( VULKAN_INTERNAL_ImageMemoryBarrier( renderer, - vulkanCommandBuffer, + commandBuffer, RESOURCE_ACCESS_TRANSFER_WRITE, VK_IMAGE_ASPECT_COLOR_BIT, 0, @@ -6223,24 +6255,25 @@ static void VULKAN_SetTextureDataYUV( tex->levelCount, 0, tex->image, + renderer->queueFamilyIndices.transferFamily, + &tex->queueFamilyIndex, &tex->resourceAccessType ); renderer->vkCmdCopyBufferToImage( - vulkanCommandBuffer->commandBuffer, + commandBuffer, renderer->textureStagingBuffer->subBuffers[0]->buffer, tex->image, AccessMap[tex->resourceAccessType].imageLayout, 1, &imageCopy ); - vulkanCommandBuffer->numActiveCommands += 1; if (tex->usageFlags & REFRESH_TEXTUREUSAGE_SAMPLER_BIT) { VULKAN_INTERNAL_ImageMemoryBarrier( renderer, - vulkanCommandBuffer, + commandBuffer, RESOURCE_ACCESS_ANY_SHADER_READ_SAMPLED_IMAGE, VK_IMAGE_ASPECT_COLOR_BIT, 0, @@ -6249,12 +6282,16 @@ static void VULKAN_SetTextureDataYUV( tex->levelCount, 0, tex->image, + renderer->queueFamilyIndices.graphicsFamily, + &tex->queueFamilyIndex, &tex->resourceAccessType ); } + renderer->pendingTransfer = 1; + /* Hard sync point */ - VULKAN_SubmitAndSync(driverData, commandBuffer); + VULKAN_INTERNAL_SubmitTransfer(driverData); } static void VULKAN_SetBufferData( @@ -6329,7 +6366,7 @@ static uint32_t VULKAN_PushVertexShaderParams( void *data, uint32_t elementCount ) { - VulkanRenderer* renderer = (VulkanRenderer*)driverData; + VulkanRenderer* renderer = (VulkanRenderer*) driverData; VulkanCommandBuffer *vulkanCommandBuffer = (VulkanCommandBuffer*) commandBuffer; SDL_LockMutex(renderer->uniformBufferLock); @@ -6347,7 +6384,7 @@ static uint32_t VULKAN_PushVertexShaderParams( } VULKAN_SetBufferData( - driverData, + (REFRESH_Renderer*) renderer, (REFRESH_Buffer*) renderer->vertexUBO, renderer->vertexUBOOffset, data, @@ -6365,7 +6402,7 @@ static uint32_t VULKAN_PushFragmentShaderParams( void *data, uint32_t elementCount ) { - VulkanRenderer* renderer = (VulkanRenderer*)driverData; + VulkanRenderer* renderer = (VulkanRenderer*) driverData; VulkanCommandBuffer *vulkanCommandBuffer = (VulkanCommandBuffer*) commandBuffer; SDL_LockMutex(renderer->uniformBufferLock); @@ -6383,7 +6420,7 @@ static uint32_t VULKAN_PushFragmentShaderParams( } VULKAN_SetBufferData( - driverData, + (REFRESH_Renderer*) renderer, (REFRESH_Buffer*) renderer->fragmentUBO, renderer->fragmentUBOOffset, data, @@ -6401,7 +6438,7 @@ static uint32_t VULKAN_PushComputeShaderParams( void *data, uint32_t elementCount ) { - VulkanRenderer* renderer = (VulkanRenderer*)driverData; + VulkanRenderer* renderer = (VulkanRenderer*) driverData; VulkanCommandBuffer *vulkanCommandBuffer = (VulkanCommandBuffer*) commandBuffer; SDL_LockMutex(renderer->uniformBufferLock); @@ -6419,7 +6456,7 @@ static uint32_t VULKAN_PushComputeShaderParams( } VULKAN_SetBufferData( - driverData, + (REFRESH_Renderer*) renderer, (REFRESH_Buffer*) renderer->computeUBO, renderer->computeUBOOffset, data, @@ -6736,12 +6773,12 @@ static void VULKAN_SetVertexSamplers( REFRESH_Texture **pTextures, REFRESH_Sampler **pSamplers ) { - VulkanTexture *currentTexture; - uint32_t i, samplerCount; - VulkanRenderer* renderer = (VulkanRenderer*) driverData; VulkanCommandBuffer *vulkanCommandBuffer = (VulkanCommandBuffer*) commandBuffer; VulkanGraphicsPipeline *graphicsPipeline = vulkanCommandBuffer->currentGraphicsPipeline; + + VulkanTexture *currentTexture; + uint32_t i, samplerCount; ImageDescriptorSetData vertexSamplerDescriptorSetData; if (graphicsPipeline->pipelineLayout->vertexSamplerDescriptorSetCache == NULL) @@ -6772,12 +6809,12 @@ static void VULKAN_SetFragmentSamplers( REFRESH_Texture **pTextures, REFRESH_Sampler **pSamplers ) { - VulkanTexture *currentTexture; - uint32_t i, samplerCount; - VulkanRenderer* renderer = (VulkanRenderer*) driverData; VulkanCommandBuffer *vulkanCommandBuffer = (VulkanCommandBuffer*) commandBuffer; VulkanGraphicsPipeline *graphicsPipeline = vulkanCommandBuffer->currentGraphicsPipeline; + VulkanTexture *currentTexture; + + uint32_t i, samplerCount; ImageDescriptorSetData fragmentSamplerDescriptorSetData; if (graphicsPipeline->pipelineLayout->fragmentSamplerDescriptorSetCache == NULL) @@ -6804,7 +6841,6 @@ static void VULKAN_SetFragmentSamplers( static void VULKAN_INTERNAL_GetTextureData( REFRESH_Renderer *driverData, - REFRESH_CommandBuffer *commandBuffer, REFRESH_Texture *texture, int32_t x, int32_t y, @@ -6815,8 +6851,9 @@ static void VULKAN_INTERNAL_GetTextureData( void* data ) { VulkanRenderer *renderer = (VulkanRenderer*) driverData; - VulkanCommandBuffer *vulkanCommandBuffer = (VulkanCommandBuffer*) commandBuffer; VulkanTexture *vulkanTexture = (VulkanTexture*) texture; + + VkCommandBuffer commandBuffer = renderer->transferCommandBuffers[renderer->frameIndex]; VulkanResourceAccessType prevResourceAccess; VkBufferImageCopy imageCopy; uint8_t *dataPtr = (uint8_t*) data; @@ -6831,7 +6868,7 @@ static void VULKAN_INTERNAL_GetTextureData( VULKAN_INTERNAL_ImageMemoryBarrier( renderer, - vulkanCommandBuffer, + commandBuffer, RESOURCE_ACCESS_TRANSFER_READ, VK_IMAGE_ASPECT_COLOR_BIT, 0, @@ -6840,6 +6877,8 @@ static void VULKAN_INTERNAL_GetTextureData( vulkanTexture->levelCount, 0, vulkanTexture->image, + renderer->queueFamilyIndices.transferFamily, + &vulkanTexture->queueFamilyIndex, &vulkanTexture->resourceAccessType ); @@ -6860,20 +6899,19 @@ static void VULKAN_INTERNAL_GetTextureData( imageCopy.bufferOffset = 0; renderer->vkCmdCopyImageToBuffer( - vulkanCommandBuffer->commandBuffer, + commandBuffer, vulkanTexture->image, AccessMap[vulkanTexture->resourceAccessType].imageLayout, renderer->textureStagingBuffer->subBuffers[0]->buffer, 1, &imageCopy ); - vulkanCommandBuffer->numActiveCommands += 1; /* Restore the image layout and wait for completion of the render pass */ VULKAN_INTERNAL_ImageMemoryBarrier( renderer, - vulkanCommandBuffer, + commandBuffer, prevResourceAccess, VK_IMAGE_ASPECT_COLOR_BIT, 0, @@ -6882,11 +6920,15 @@ static void VULKAN_INTERNAL_GetTextureData( vulkanTexture->levelCount, 0, vulkanTexture->image, + renderer->queueFamilyIndices.graphicsFamily, + &vulkanTexture->queueFamilyIndex, &vulkanTexture->resourceAccessType ); + renderer->pendingTransfer = 1; + /* Hard sync point */ - VULKAN_SubmitAndSync(driverData, commandBuffer); + VULKAN_INTERNAL_SubmitTransfer(driverData); /* Read from staging buffer */ @@ -6919,7 +6961,6 @@ static void VULKAN_INTERNAL_GetTextureData( static void VULKAN_GetTextureData2D( REFRESH_Renderer *driverData, - REFRESH_CommandBuffer *commandBuffer, REFRESH_Texture *texture, uint32_t x, uint32_t y, @@ -6930,7 +6971,6 @@ static void VULKAN_GetTextureData2D( ) { VULKAN_INTERNAL_GetTextureData( driverData, - commandBuffer, texture, x, y, @@ -6944,7 +6984,6 @@ static void VULKAN_GetTextureData2D( static void VULKAN_GetTextureDataCube( REFRESH_Renderer *driverData, - REFRESH_CommandBuffer *commandBuffer, REFRESH_Texture *texture, uint32_t x, uint32_t y, @@ -6956,7 +6995,6 @@ static void VULKAN_GetTextureDataCube( ) { VULKAN_INTERNAL_GetTextureData( driverData, - commandBuffer, texture, x, y, @@ -7199,9 +7237,10 @@ static void VULKAN_BeginRenderPass( uint32_t colorClearCount, REFRESH_DepthStencilValue *depthStencilClearValue ) { - VulkanRenderer *renderer = (VulkanRenderer*) driverData; + VulkanRenderer* renderer = (VulkanRenderer*) driverData; VulkanCommandBuffer *vulkanCommandBuffer = (VulkanCommandBuffer*) commandBuffer; VulkanFramebuffer *vulkanFramebuffer = (VulkanFramebuffer*) framebuffer; + VkClearValue *clearValues; uint32_t i; uint32_t clearCount = colorClearCount; @@ -7213,7 +7252,7 @@ static void VULKAN_BeginRenderPass( { VULKAN_INTERNAL_ImageMemoryBarrier( renderer, - vulkanCommandBuffer, + vulkanCommandBuffer->commandBuffer, RESOURCE_ACCESS_COLOR_ATTACHMENT_READ_WRITE, VK_IMAGE_ASPECT_COLOR_BIT, vulkanFramebuffer->colorTargets[i]->layer, @@ -7222,6 +7261,8 @@ static void VULKAN_BeginRenderPass( 1, 0, vulkanFramebuffer->colorTargets[i]->texture->image, + VK_QUEUE_FAMILY_IGNORED, + NULL, &vulkanFramebuffer->colorTargets[i]->texture->resourceAccessType ); } @@ -7237,7 +7278,7 @@ static void VULKAN_BeginRenderPass( VULKAN_INTERNAL_ImageMemoryBarrier( renderer, - vulkanCommandBuffer, + vulkanCommandBuffer->commandBuffer, RESOURCE_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_WRITE, depthAspectFlags, 0, @@ -7246,6 +7287,8 @@ static void VULKAN_BeginRenderPass( 1, 0, vulkanFramebuffer->depthStencilTarget->texture->image, + VK_QUEUE_FAMILY_IGNORED, + NULL, &vulkanFramebuffer->depthStencilTarget->texture->resourceAccessType ); @@ -7289,7 +7332,6 @@ static void VULKAN_BeginRenderPass( &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE ); - vulkanCommandBuffer->numActiveCommands += 1; vulkanCommandBuffer->currentFramebuffer = vulkanFramebuffer; @@ -7300,15 +7342,14 @@ static void VULKAN_EndRenderPass( REFRESH_Renderer *driverData, REFRESH_CommandBuffer *commandBuffer ) { - uint32_t i; - VulkanRenderer *renderer = (VulkanRenderer*) driverData; + VulkanRenderer* renderer = (VulkanRenderer*) driverData; VulkanCommandBuffer *vulkanCommandBuffer = (VulkanCommandBuffer*) commandBuffer; VulkanTexture *currentTexture; + uint32_t i; renderer->vkCmdEndRenderPass( vulkanCommandBuffer->commandBuffer ); - vulkanCommandBuffer->numActiveCommands += 1; for (i = 0; i < vulkanCommandBuffer->currentFramebuffer->colorTargetCount; i += 1) { @@ -7317,7 +7358,7 @@ static void VULKAN_EndRenderPass( { VULKAN_INTERNAL_ImageMemoryBarrier( renderer, - vulkanCommandBuffer, + vulkanCommandBuffer->commandBuffer, RESOURCE_ACCESS_ANY_SHADER_READ_SAMPLED_IMAGE, VK_IMAGE_ASPECT_COLOR_BIT, 0, @@ -7326,6 +7367,8 @@ static void VULKAN_EndRenderPass( currentTexture->levelCount, 0, currentTexture->image, + VK_QUEUE_FAMILY_IGNORED, + NULL, ¤tTexture->resourceAccessType ); } @@ -7360,7 +7403,6 @@ static void VULKAN_BindGraphicsPipeline( VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline->pipeline ); - vulkanCommandBuffer->numActiveCommands += 1; vulkanCommandBuffer->currentGraphicsPipeline = pipeline; } @@ -7402,10 +7444,11 @@ static void VULKAN_BindVertexBuffers( REFRESH_Buffer **pBuffers, uint64_t *pOffsets ) { - VkBuffer *buffers = SDL_stack_alloc(VkBuffer, bindingCount); - VulkanCommandBuffer *vulkanCommandBuffer = (VulkanCommandBuffer*) commandBuffer; - VulkanBuffer* currentBuffer; VulkanRenderer* renderer = (VulkanRenderer*) driverData; + VulkanCommandBuffer *vulkanCommandBuffer = (VulkanCommandBuffer*) commandBuffer; + + VkBuffer *buffers = SDL_stack_alloc(VkBuffer, bindingCount); + VulkanBuffer* currentBuffer; uint32_t i; for (i = 0; i < bindingCount; i += 1) @@ -7422,7 +7465,6 @@ static void VULKAN_BindVertexBuffers( buffers, pOffsets ); - vulkanCommandBuffer->numActiveCommands += 1; SDL_stack_free(buffers); } @@ -7446,7 +7488,6 @@ static void VULKAN_BindIndexBuffer( offset, RefreshToVK_IndexType[indexElementSize] ); - vulkanCommandBuffer->numActiveCommands += 1; } static void VULKAN_BindComputePipeline( @@ -7454,7 +7495,7 @@ static void VULKAN_BindComputePipeline( REFRESH_CommandBuffer *commandBuffer, REFRESH_ComputePipeline *computePipeline ) { - VulkanRenderer *renderer = (VulkanRenderer*) driverData; + VulkanRenderer* renderer = (VulkanRenderer*) driverData; VulkanCommandBuffer *vulkanCommandBuffer = (VulkanCommandBuffer*) commandBuffer; VulkanComputePipeline *vulkanComputePipeline = (VulkanComputePipeline*) computePipeline; @@ -7474,7 +7515,6 @@ static void VULKAN_BindComputePipeline( VK_PIPELINE_BIND_POINT_COMPUTE, vulkanComputePipeline->pipeline ); - vulkanCommandBuffer->numActiveCommands += 1; vulkanCommandBuffer->currentComputePipeline = vulkanComputePipeline; } @@ -7484,9 +7524,10 @@ static void VULKAN_BindComputeBuffers( REFRESH_CommandBuffer *commandBuffer, REFRESH_Buffer **pBuffers ) { - VulkanRenderer *renderer = (VulkanRenderer*) driverData; + VulkanRenderer* renderer = (VulkanRenderer*) driverData; VulkanCommandBuffer *vulkanCommandBuffer = (VulkanCommandBuffer*) commandBuffer; VulkanComputePipeline *computePipeline = vulkanCommandBuffer->currentComputePipeline; + VulkanBuffer *currentBuffer; BufferDescriptorSetData bufferDescriptorSetData; uint32_t i; @@ -7523,9 +7564,10 @@ static void VULKAN_BindComputeTextures( REFRESH_CommandBuffer *commandBuffer, REFRESH_Texture **pTextures ) { - VulkanRenderer *renderer = (VulkanRenderer*) driverData; + VulkanRenderer* renderer = (VulkanRenderer*) driverData; VulkanCommandBuffer *vulkanCommandBuffer = (VulkanCommandBuffer*) commandBuffer; VulkanComputePipeline *computePipeline = vulkanCommandBuffer->currentComputePipeline; + VulkanTexture *currentTexture; ImageDescriptorSetData imageDescriptorSetData; uint32_t i; @@ -7622,7 +7664,6 @@ static REFRESH_CommandBuffer* VULKAN_AcquireCommandBuffer( } commandBuffer->boundComputeBufferCount = 0; - commandBuffer->numActiveCommands = 0; commandBuffer->fixed = fixed; commandBuffer->submitted = 0; @@ -7632,7 +7673,7 @@ static REFRESH_CommandBuffer* VULKAN_AcquireCommandBuffer( } static void VULKAN_QueuePresent( - REFRESH_Renderer* driverData, + REFRESH_Renderer *driverData, REFRESH_CommandBuffer *commandBuffer, REFRESH_TextureSlice* textureSlice, REFRESH_Rect* sourceRectangle, @@ -7703,7 +7744,7 @@ static void VULKAN_QueuePresent( VULKAN_INTERNAL_ImageMemoryBarrier( renderer, - vulkanCommandBuffer, + vulkanCommandBuffer->commandBuffer, RESOURCE_ACCESS_TRANSFER_READ, VK_IMAGE_ASPECT_COLOR_BIT, 0, @@ -7712,12 +7753,14 @@ static void VULKAN_QueuePresent( 1, 0, vulkanTexture->image, + VK_QUEUE_FAMILY_IGNORED, + NULL, &vulkanTexture->resourceAccessType ); VULKAN_INTERNAL_ImageMemoryBarrier( renderer, - vulkanCommandBuffer, + vulkanCommandBuffer->commandBuffer, RESOURCE_ACCESS_TRANSFER_WRITE, VK_IMAGE_ASPECT_COLOR_BIT, 0, @@ -7726,6 +7769,8 @@ static void VULKAN_QueuePresent( 1, 0, renderer->swapChainImages[swapChainImageIndex], + VK_QUEUE_FAMILY_IGNORED, + NULL, &renderer->swapChainResourceAccessTypes[swapChainImageIndex] ); @@ -7763,11 +7808,10 @@ static void VULKAN_QueuePresent( &blit, VK_FILTER_LINEAR ); - vulkanCommandBuffer->numActiveCommands += 1; VULKAN_INTERNAL_ImageMemoryBarrier( renderer, - vulkanCommandBuffer, + vulkanCommandBuffer->commandBuffer, RESOURCE_ACCESS_PRESENT, VK_IMAGE_ASPECT_COLOR_BIT, 0, @@ -7776,12 +7820,14 @@ static void VULKAN_QueuePresent( 1, 0, renderer->swapChainImages[swapChainImageIndex], + VK_QUEUE_FAMILY_IGNORED, + NULL, &renderer->swapChainResourceAccessTypes[swapChainImageIndex] ); VULKAN_INTERNAL_ImageMemoryBarrier( renderer, - vulkanCommandBuffer, + vulkanCommandBuffer->commandBuffer, RESOURCE_ACCESS_COLOR_ATTACHMENT_READ_WRITE, VK_IMAGE_ASPECT_COLOR_BIT, 0, @@ -7790,6 +7836,8 @@ static void VULKAN_QueuePresent( 1, 0, vulkanTexture->image, + VK_QUEUE_FAMILY_IGNORED, + NULL, &vulkanTexture->resourceAccessType ); } @@ -7964,7 +8012,7 @@ static void VULKAN_INTERNAL_ResetCommandBuffer( VulkanCommandPool *commandPool = commandBuffer->commandPool; vulkanResult = renderer->vkResetCommandBuffer( - commandBuffer, + commandBuffer->commandBuffer, VK_COMMAND_BUFFER_RESET_RELEASE_RESOURCES_BIT ); @@ -7981,13 +8029,13 @@ static void VULKAN_INTERNAL_ResetCommandBuffer( commandPool->inactiveCommandBufferCount += 1; } -static void VULKAN_SubmitAndSync( - REFRESH_Renderer *driverData, - REFRESH_CommandBuffer *commandBuffer +/* This function triggers a hard sync point */ +static void VULKAN_INTERNAL_SubmitTransfer( + REFRESH_Renderer *driverData ) { VulkanRenderer* renderer = (VulkanRenderer*)driverData; - VULKAN_Submit(driverData, &commandBuffer, 1); + VULKAN_Submit(driverData, NULL, 0); renderer->vkWaitForFences( renderer->logicalDevice, @@ -8004,7 +8052,7 @@ static void VULKAN_Submit( uint32_t commandBufferCount ) { VulkanRenderer* renderer = (VulkanRenderer*)driverData; - VkSubmitInfo submitInfo; + VkSubmitInfo transferSubmitInfo, submitInfo; VkResult vulkanResult, presentResult = VK_SUCCESS; VulkanCommandBuffer *currentCommandBuffer; VkCommandBuffer *commandBuffers; @@ -8014,6 +8062,19 @@ static void VULKAN_Submit( VkPipelineStageFlags waitStages = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; VkPresentInfoKHR presentInfo; + if (renderer->pendingTransfer) + { + transferSubmitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; + transferSubmitInfo.pNext = NULL; + transferSubmitInfo.commandBufferCount = 1; + transferSubmitInfo.pCommandBuffers = &renderer->transferCommandBuffers[renderer->frameIndex]; + transferSubmitInfo.pWaitDstStageMask = NULL; + transferSubmitInfo.pWaitSemaphores = NULL; + transferSubmitInfo.waitSemaphoreCount = 0; + transferSubmitInfo.pSignalSemaphores = &renderer->transferFinishedSemaphore; + transferSubmitInfo.signalSemaphoreCount = 1; + } + present = !renderer->headless && renderer->shouldPresent; commandBuffers = SDL_stack_alloc(VkCommandBuffer, commandBufferCount); @@ -8027,8 +8088,8 @@ static void VULKAN_Submit( submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; submitInfo.pNext = NULL; - submitInfo.commandBufferCount = commandBuffers; - submitInfo.pCommandBuffers = commandBufferCount; + submitInfo.commandBufferCount = commandBufferCount; + submitInfo.pCommandBuffers = commandBuffers; if (present) { @@ -8084,6 +8145,23 @@ static void VULKAN_Submit( &renderer->inFlightFence ); + if (renderer->pendingTransfer) + { + /* Submit any pending transfers */ + vulkanResult = renderer->vkQueueSubmit( + renderer->transferQueue, + 1, + &transferSubmitInfo, + renderer->inFlightFence + ); + + if (vulkanResult != VK_SUCCESS) + { + LogVulkanResult("vkQueueSubmit", vulkanResult); + return; + } + } + /* Submit the commands, finally. */ vulkanResult = renderer->vkQueueSubmit( renderer->graphicsQueue, @@ -8112,7 +8190,7 @@ static void VULKAN_Submit( for (i = 0; i < commandBufferCount; i += 1) { ((VulkanCommandBuffer*)pCommandBuffers[i])->submitted = 1; - renderer->submittedCommandBuffers[renderer->submittedCommandBufferCount] = pCommandBuffers[i]; + renderer->submittedCommandBuffers[renderer->submittedCommandBufferCount] = (VulkanCommandBuffer*) pCommandBuffers[i]; } renderer->submittedCommandBufferCount = commandBufferCount; @@ -8442,11 +8520,12 @@ static uint8_t VULKAN_INTERNAL_IsDeviceSuitable( SwapChainSupportDetails swapChainSupportDetails; VkQueueFamilyProperties *queueProps; VkBool32 supportsPresent; - uint8_t querySuccess, foundSuitableDevice = 0; + uint8_t querySuccess, foundGraphicsPresentFamily, foundTransferFamily, foundSuitableDevice = 0; VkPhysicalDeviceProperties deviceProperties; queueFamilyIndices->graphicsFamily = UINT32_MAX; queueFamilyIndices->presentFamily = UINT32_MAX; + queueFamilyIndices->transferFamily = UINT32_MAX; *isIdeal = 0; /* Note: If no dedicated device exists, @@ -8502,11 +8581,29 @@ static uint8_t VULKAN_INTERNAL_IsDeviceSuitable( surface, &supportsPresent ); - if ( supportsPresent && - (queueProps[i].queueFlags & VK_QUEUE_GRAPHICS_BIT) != 0 ) + if (!foundGraphicsPresentFamily) + { + if ( supportsPresent && + (queueProps[i].queueFlags & VK_QUEUE_GRAPHICS_BIT) != 0 ) + { + queueFamilyIndices->graphicsFamily = i; + queueFamilyIndices->presentFamily = i; + foundGraphicsPresentFamily = 1; + } + } + + if (!foundTransferFamily) + { + if ( queueProps[i].queueFlags & VK_QUEUE_TRANSFER_BIT && + !(queueProps[i].queueFlags & VK_QUEUE_GRAPHICS_BIT) ) + { + queueFamilyIndices->transferFamily = i; + foundTransferFamily = 1; + } + } + + if (foundGraphicsPresentFamily && foundTransferFamily) { - queueFamilyIndices->graphicsFamily = i; - queueFamilyIndices->presentFamily = i; foundSuitableDevice = 1; break; } @@ -8647,14 +8744,12 @@ static uint8_t VULKAN_INTERNAL_CreateLogicalDevice( VkDeviceCreateInfo deviceCreateInfo; VkPhysicalDeviceFeatures deviceFeatures; - VkDeviceQueueCreateInfo *queueCreateInfos = SDL_stack_alloc( - VkDeviceQueueCreateInfo, - 2 - ); + VkDeviceQueueCreateInfo queueCreateInfos[3]; VkDeviceQueueCreateInfo queueCreateInfoGraphics; VkDeviceQueueCreateInfo queueCreateInfoPresent; + VkDeviceQueueCreateInfo queueCreateInfoTransfer; - int32_t queueInfoCount = 1; + int32_t queueInfoCount = 2; float queuePriority = 1.0f; queueCreateInfoGraphics.sType = @@ -8668,6 +8763,17 @@ static uint8_t VULKAN_INTERNAL_CreateLogicalDevice( queueCreateInfos[0] = queueCreateInfoGraphics; + queueCreateInfoTransfer.sType = + VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO; + queueCreateInfoTransfer.pNext = NULL; + queueCreateInfoTransfer.flags = 0; + queueCreateInfoTransfer.queueFamilyIndex = + renderer->queueFamilyIndices.transferFamily; + queueCreateInfoTransfer.queueCount = 1; + queueCreateInfoTransfer.pQueuePriorities = &queuePriority; + + queueCreateInfos[1] = queueCreateInfoTransfer; + if (renderer->queueFamilyIndices.presentFamily != renderer->queueFamilyIndices.graphicsFamily) { queueCreateInfoPresent.sType = @@ -8679,7 +8785,7 @@ static uint8_t VULKAN_INTERNAL_CreateLogicalDevice( queueCreateInfoPresent.queueCount = 1; queueCreateInfoPresent.pQueuePriorities = &queuePriority; - queueCreateInfos[1] = queueCreateInfoPresent; + queueCreateInfos[queueInfoCount] = queueCreateInfoPresent; queueInfoCount += 1; } @@ -8741,7 +8847,13 @@ static uint8_t VULKAN_INTERNAL_CreateLogicalDevice( &renderer->presentQueue ); - SDL_stack_free(queueCreateInfos); + renderer->vkGetDeviceQueue( + renderer->logicalDevice, + renderer->queueFamilyIndices.transferFamily, + 0, + &renderer->transferQueue + ); + return 1; } @@ -8759,6 +8871,10 @@ static REFRESH_Device* VULKAN_CreateDevice( VkFenceCreateInfo fenceInfo; VkSemaphoreCreateInfo semaphoreInfo; + /* Variables: Transfer command buffer */ + VkCommandPoolCreateInfo transferCommandPoolCreateInfo; + VkCommandBufferAllocateInfo transferCommandBufferAllocateInfo; + /* Variables: Descriptor set layouts */ VkDescriptorSetLayoutCreateInfo setLayoutCreateInfo; VkDescriptorSetLayoutBinding vertexParamLayoutBinding; @@ -8926,6 +9042,19 @@ static REFRESH_Device* VULKAN_CreateDevice( semaphoreInfo.pNext = NULL; semaphoreInfo.flags = 0; + vulkanResult = renderer->vkCreateSemaphore( + renderer->logicalDevice, + &semaphoreInfo, + NULL, + &renderer->transferFinishedSemaphore + ); + + if (vulkanResult != VK_SUCCESS) + { + LogVulkanResult("vkCreateSemaphore", vulkanResult); + return NULL; + } + vulkanResult = renderer->vkCreateSemaphore( renderer->logicalDevice, &semaphoreInfo, @@ -8935,7 +9064,7 @@ static REFRESH_Device* VULKAN_CreateDevice( if (vulkanResult != VK_SUCCESS) { - LogVulkanResult("vkCreateFence", vulkanResult); + LogVulkanResult("vkCreateSemaphore", vulkanResult); return NULL; } @@ -8961,7 +9090,7 @@ static REFRESH_Device* VULKAN_CreateDevice( if (vulkanResult != VK_SUCCESS) { - LogVulkanResult("vkCreateSemaphore", vulkanResult); + LogVulkanResult("vkCreateFence", vulkanResult); return NULL; } @@ -8973,6 +9102,46 @@ static REFRESH_Device* VULKAN_CreateDevice( renderer->descriptorSetLock = SDL_CreateMutex(); renderer->boundBufferLock = SDL_CreateMutex(); + /* Transfer buffer */ + + transferCommandPoolCreateInfo.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO; + transferCommandPoolCreateInfo.pNext = NULL; + transferCommandPoolCreateInfo.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT; + transferCommandPoolCreateInfo.queueFamilyIndex = renderer->queueFamilyIndices.transferFamily; + + vulkanResult = renderer->vkCreateCommandPool( + renderer->logicalDevice, + &transferCommandPoolCreateInfo, + NULL, + &renderer->transferCommandPool + ); + + if (vulkanResult != VK_SUCCESS) + { + LogVulkanResult("vkCreateCommandPool", vulkanResult); + return NULL; + } + + transferCommandBufferAllocateInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO; + transferCommandBufferAllocateInfo.pNext = NULL; + transferCommandBufferAllocateInfo.commandBufferCount = 2; + transferCommandBufferAllocateInfo.commandPool = renderer->transferCommandPool; + transferCommandBufferAllocateInfo.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY; + + vulkanResult = renderer->vkAllocateCommandBuffers( + renderer->logicalDevice, + &transferCommandBufferAllocateInfo, + renderer->transferCommandBuffers + ); + + if (vulkanResult != VK_SUCCESS) + { + LogVulkanResult("vkAllocateCommandBuffers", vulkanResult); + return NULL; + } + + renderer->pendingTransfer = 0; + /* * Create submitted command buffer list */