From 44d510892c60e6ee23f973bbc52b0dd95d715a61 Mon Sep 17 00:00:00 2001 From: cosmonaut Date: Wed, 23 Feb 2022 23:48:22 -0800 Subject: [PATCH 1/8] start rewriting render pass API --- include/Refresh.h | 124 ++---- src/Refresh.c | 66 +--- src/Refresh_Driver.h | 38 +- src/Refresh_Driver_Template.txt | 42 +- src/Refresh_Driver_Vulkan.c | 658 +++++++++++++++++--------------- 5 files changed, 413 insertions(+), 515 deletions(-) diff --git a/include/Refresh.h b/include/Refresh.h index bfb8d29..27c61b0 100644 --- a/include/Refresh.h +++ b/include/Refresh.h @@ -59,9 +59,7 @@ typedef struct Refresh_Buffer Refresh_Buffer; typedef struct Refresh_Texture Refresh_Texture; typedef struct Refresh_Sampler Refresh_Sampler; typedef struct Refresh_RenderTarget Refresh_RenderTarget; -typedef struct Refresh_Framebuffer Refresh_Framebuffer; typedef struct Refresh_ShaderModule Refresh_ShaderModule; -typedef struct Refresh_RenderPass Refresh_RenderPass; typedef struct Refresh_ComputePipeline Refresh_ComputePipeline; typedef struct Refresh_GraphicsPipeline Refresh_GraphicsPipeline; typedef struct Refresh_CommandBuffer Refresh_CommandBuffer; @@ -473,30 +471,6 @@ typedef struct Refresh_GraphicsPipelineLayoutCreateInfo uint32_t fragmentSamplerBindingCount; } Refresh_GraphicsPipelineLayoutCreateInfo; -typedef struct Refresh_ColorTargetDescription -{ - Refresh_TextureFormat format; - Refresh_SampleCount multisampleCount; - Refresh_LoadOp loadOp; - Refresh_StoreOp storeOp; -} Refresh_ColorTargetDescription; - -typedef struct Refresh_DepthStencilTargetDescription -{ - Refresh_TextureFormat depthStencilFormat; - Refresh_LoadOp loadOp; - Refresh_StoreOp storeOp; - Refresh_LoadOp stencilLoadOp; - Refresh_StoreOp stencilStoreOp; -} Refresh_DepthStencilTargetDescription; - -typedef struct Refresh_RenderPassCreateInfo -{ - const Refresh_ColorTargetDescription *colorTargetDescriptions; - uint32_t colorTargetCount; - const Refresh_DepthStencilTargetDescription *depthTargetDescription; /* can be NULL */ -} Refresh_RenderPassCreateInfo; - typedef struct Refresh_ShaderModuleCreateInfo { size_t codeSize; @@ -579,6 +553,19 @@ typedef struct Refresh_ComputePipelineCreateInfo Refresh_ComputePipelineLayoutCreateInfo pipelineLayoutCreateInfo; } Refresh_ComputePipelineCreateInfo; +typedef struct Refresh_AttachmentDescription +{ + Refresh_TextureFormat format; + Refresh_SampleCount sampleCount; +} Refresh_AttachmentDescription; + +typedef struct Refresh_GraphicsPipelineAttachmentInfo +{ + Refresh_AttachmentDescription colorAttachmentDescriptions[4]; + uint32_t colorAttachmentCount; + Refresh_AttachmentDescription *depthStencilAttachmentDescription; /* Can be NULL */ +} Refresh_GraphicsPipelineAttachmentInfo; + typedef struct Refresh_GraphicsPipelineCreateInfo { Refresh_ShaderStageState vertexShaderState; @@ -591,18 +578,28 @@ typedef struct Refresh_GraphicsPipelineCreateInfo Refresh_DepthStencilState depthStencilState; Refresh_ColorBlendState colorBlendState; Refresh_GraphicsPipelineLayoutCreateInfo pipelineLayoutCreateInfo; - Refresh_RenderPass *renderPass; + Refresh_GraphicsPipelineAttachmentInfo attachmentInfo; } Refresh_GraphicsPipelineCreateInfo; -typedef struct Refresh_FramebufferCreateInfo +/* Render pass structures */ + +typedef struct Refresh_ColorAttachmentInfo +{ + Refresh_RenderTarget *pRenderTarget; + Refresh_Vec4 clearColor; /* Can be ignored by RenderPass */ + Refresh_LoadOp loadOp; + Refresh_StoreOp storeOp; +} Refresh_ColorAttachmentInfo; + +typedef struct Refresh_DepthStencilAttachmentInfo { - Refresh_RenderPass *renderPass; - Refresh_RenderTarget **pColorTargets; - uint32_t colorTargetCount; Refresh_RenderTarget *pDepthStencilTarget; - uint32_t width; - uint32_t height; -} Refresh_FramebufferCreateInfo; + Refresh_DepthStencilValue depthStencilValue; /* Can be ignored by RenderPass */ + Refresh_LoadOp loadOp; + Refresh_StoreOp storeOp; + Refresh_LoadOp stencilLoadOp; + Refresh_StoreOp stencilStoreOp; +} Refresh_DepthStencilAttachmentInfo; /* Interop Structs */ @@ -802,12 +799,6 @@ REFRESHAPI void Refresh_DispatchCompute( /* State Creation */ -/* Returns an allocated RenderPass* object. */ -REFRESHAPI Refresh_RenderPass* Refresh_CreateRenderPass( - Refresh_Device *device, - Refresh_RenderPassCreateInfo *renderPassCreateInfo -); - /* Returns an allocated ComputePipeline* object. */ REFRESHAPI Refresh_ComputePipeline* Refresh_CreateComputePipeline( Refresh_Device *device, @@ -826,12 +817,6 @@ REFRESHAPI Refresh_Sampler* Refresh_CreateSampler( Refresh_SamplerStateCreateInfo *samplerStateCreateInfo ); -/* Returns an allocated Framebuffer* object. */ -REFRESHAPI Refresh_Framebuffer* Refresh_CreateFramebuffer( - Refresh_Device *device, - Refresh_FramebufferCreateInfo *framebufferCreateInfo -); - /* Returns an allocated ShaderModule* object. */ REFRESHAPI Refresh_ShaderModule* Refresh_CreateShaderModule( Refresh_Device *device, @@ -1081,19 +1066,6 @@ REFRESHAPI void Refresh_QueueDestroyRenderTarget( Refresh_RenderTarget *renderTarget ); -/* Sends a framebuffer to be destroyed by the renderer. Note that we call it - * "QueueDestroy" because it may not be immediately destroyed by the renderer if - * this is not called from the main thread (for example, if a garbage collector - * deletes the resource instead of the programmer). - * - * framebuffer: The Refresh_Framebuffer to be destroyed. - */ -REFRESHAPI void Refresh_QueueDestroyFramebuffer( - Refresh_Device *device, - Refresh_CommandBuffer *commandBuffer, - Refresh_Framebuffer *frameBuffer -); - /* Sends a shader module to be destroyed by the renderer. Note that we call it * "QueueDestroy" because it may not be immediately destroyed by the renderer if * this is not called from the main thread (for example, if a garbage collector @@ -1107,19 +1079,6 @@ REFRESHAPI void Refresh_QueueDestroyShaderModule( Refresh_ShaderModule *shaderModule ); -/* Sends a render pass to be destroyed by the renderer. Note that we call it - * "QueueDestroy" because it may not be immediately destroyed by the renderer if - * this is not called from the main thread (for example, if a garbage collector - * deletes the resource instead of the programmer). - * - * renderPass: The Refresh_RenderPass to be destroyed. - */ -REFRESHAPI void Refresh_QueueDestroyRenderPass( - Refresh_Device *device, - Refresh_CommandBuffer *commandBuffer, - Refresh_RenderPass *renderPass -); - /* Sends a compute pipeline to be destroyed by the renderer. Note that we call it * "QueueDestroy" because it may not be immediately destroyed by the renderer if * this is not called from the main thread (for example, if a garbage collector @@ -1150,28 +1109,23 @@ REFRESHAPI void Refresh_QueueDestroyGraphicsPipeline( /* Begins a render pass. * - * renderPass: The renderpass to begin. - * framebuffer: The framebuffer to bind for the render pass. * renderArea: * The area affected by the render pass. * All load, store and resolve operations are restricted * to the given rectangle. - * clearValues: - * A pointer to an array of Refresh_Color structures - * that contains clear values for each color target in the - * framebuffer. May be NULL. - * clearCount: The amount of color structs in the above array. - * depthStencilClearValue: The depth/stencil clear value. May be NULL. + * pColorAttachmentInfos: + * A pointer to an array of Refresh_ColorAttachmentInfo structures + * that contains render targets and clear values. May be NULL. + * colorAttachmentCount: The amount of structs in the above array. + * depthStencilAttachmentInfo: The depth/stencil render target and clear value. May be NULL. */ REFRESHAPI void Refresh_BeginRenderPass( Refresh_Device *device, Refresh_CommandBuffer *commandBuffer, - Refresh_RenderPass *renderPass, - Refresh_Framebuffer *framebuffer, Refresh_Rect *renderArea, - Refresh_Vec4 *pColorClearValues, - uint32_t colorClearCount, - Refresh_DepthStencilValue *depthStencilClearValue + Refresh_ColorAttachmentInfo *pColorAttachmentInfos, + uint32_t colorAttachmentCount, + Refresh_DepthStencilAttachmentInfo *depthStencilAttachmentInfo ); /* Ends the current render pass. */ diff --git a/src/Refresh.c b/src/Refresh.c index 369aad9..3c68cb7 100644 --- a/src/Refresh.c +++ b/src/Refresh.c @@ -250,17 +250,6 @@ void Refresh_DispatchCompute( ); } -Refresh_RenderPass* Refresh_CreateRenderPass( - Refresh_Device *device, - Refresh_RenderPassCreateInfo *renderPassCreateInfo -) { - NULL_RETURN_NULL(device); - return device->CreateRenderPass( - device->driverData, - renderPassCreateInfo - ); -} - Refresh_ComputePipeline* Refresh_CreateComputePipeline( Refresh_Device *device, Refresh_ComputePipelineCreateInfo *pipelineCreateInfo @@ -294,17 +283,6 @@ Refresh_Sampler* Refresh_CreateSampler( ); } -Refresh_Framebuffer* Refresh_CreateFramebuffer( - Refresh_Device *device, - Refresh_FramebufferCreateInfo *framebufferCreateInfo -) { - NULL_RETURN_NULL(device); - return device->CreateFramebuffer( - device->driverData, - framebufferCreateInfo - ); -} - Refresh_ShaderModule* Refresh_CreateShaderModule( Refresh_Device *device, Refresh_ShaderModuleCreateInfo *shaderModuleCreateInfo @@ -592,19 +570,6 @@ void Refresh_QueueDestroyRenderTarget( ); } -void Refresh_QueueDestroyFramebuffer( - Refresh_Device *device, - Refresh_CommandBuffer *commandBuffer, - Refresh_Framebuffer *frameBuffer -) { - NULL_RETURN(device); - device->QueueDestroyFramebuffer( - device->driverData, - commandBuffer, - frameBuffer - ); -} - void Refresh_QueueDestroyShaderModule( Refresh_Device *device, Refresh_CommandBuffer *commandBuffer, @@ -618,19 +583,6 @@ void Refresh_QueueDestroyShaderModule( ); } -void Refresh_QueueDestroyRenderPass( - Refresh_Device *device, - Refresh_CommandBuffer *commandBuffer, - Refresh_RenderPass *renderPass -) { - NULL_RETURN(device); - device->QueueDestroyRenderPass( - device->driverData, - commandBuffer, - renderPass - ); -} - void Refresh_QueueDestroyComputePipeline( Refresh_Device *device, Refresh_CommandBuffer *commandBuffer, @@ -659,24 +611,20 @@ void Refresh_QueueDestroyGraphicsPipeline( void Refresh_BeginRenderPass( Refresh_Device *device, - Refresh_CommandBuffer *commandBuffer, - Refresh_RenderPass *renderPass, - Refresh_Framebuffer *framebuffer, + Refresh_CommandBuffer *commandBuffer, Refresh_Rect *renderArea, - Refresh_Vec4 *pColorClearValues, - uint32_t colorClearCount, - Refresh_DepthStencilValue *depthStencilClearValue + Refresh_ColorAttachmentInfo *pColorAttachmentInfos, + uint32_t colorAttachmentCount, + Refresh_DepthStencilAttachmentInfo *depthStencilAttachmentInfo ) { NULL_RETURN(device); device->BeginRenderPass( device->driverData, commandBuffer, - renderPass, - framebuffer, renderArea, - pColorClearValues, - colorClearCount, - depthStencilClearValue + pColorAttachmentInfos, + colorAttachmentCount, + depthStencilAttachmentInfo ); } diff --git a/src/Refresh_Driver.h b/src/Refresh_Driver.h index 948b76a..438ec11 100644 --- a/src/Refresh_Driver.h +++ b/src/Refresh_Driver.h @@ -218,11 +218,6 @@ struct Refresh_Device /* State Creation */ - Refresh_RenderPass* (*CreateRenderPass)( - Refresh_Renderer *driverData, - Refresh_RenderPassCreateInfo *renderPassCreateInfo - ); - Refresh_ComputePipeline* (*CreateComputePipeline)( Refresh_Renderer *driverData, Refresh_ComputePipelineCreateInfo *pipelineCreateInfo @@ -238,11 +233,6 @@ struct Refresh_Device Refresh_SamplerStateCreateInfo *samplerStateCreateInfo ); - Refresh_Framebuffer* (*CreateFramebuffer)( - Refresh_Renderer *driverData, - Refresh_FramebufferCreateInfo *framebufferCreateInfo - ); - Refresh_ShaderModule* (*CreateShaderModule)( Refresh_Renderer *driverData, Refresh_ShaderModuleCreateInfo *shaderModuleCreateInfo @@ -383,24 +373,12 @@ struct Refresh_Device Refresh_RenderTarget *renderTarget ); - void(*QueueDestroyFramebuffer)( - Refresh_Renderer *driverData, - Refresh_CommandBuffer *commandBuffer, - Refresh_Framebuffer *frameBuffer - ); - void(*QueueDestroyShaderModule)( Refresh_Renderer *driverData, Refresh_CommandBuffer *commandBuffer, Refresh_ShaderModule *shaderModule ); - void(*QueueDestroyRenderPass)( - Refresh_Renderer *driverData, - Refresh_CommandBuffer *commandBuffer, - Refresh_RenderPass *renderPass - ); - void(*QueueDestroyComputePipeline)( Refresh_Renderer *driverData, Refresh_CommandBuffer *commandBuffer, @@ -417,13 +395,11 @@ struct Refresh_Device void(*BeginRenderPass)( Refresh_Renderer *driverData, - Refresh_CommandBuffer *commandBuffer, - Refresh_RenderPass *renderPass, - Refresh_Framebuffer *framebuffer, - Refresh_Rect *renderArea, - Refresh_Vec4 *pColorClearValues, - uint32_t colorClearCount, - Refresh_DepthStencilValue *depthStencilClearValue + Refresh_CommandBuffer *commandBuffer, + Refresh_Rect *renderArea, + Refresh_ColorAttachmentInfo *pColorAttachmentInfos, + uint32_t colorAttachmentCount, + Refresh_DepthStencilAttachmentInfo *depthStencilAttachmentInfo ); void(*EndRenderPass)( @@ -509,11 +485,9 @@ struct Refresh_Device ASSIGN_DRIVER_FUNC(DrawInstancedPrimitives, name) \ ASSIGN_DRIVER_FUNC(DrawPrimitives, name) \ ASSIGN_DRIVER_FUNC(DispatchCompute, name) \ - ASSIGN_DRIVER_FUNC(CreateRenderPass, name) \ ASSIGN_DRIVER_FUNC(CreateComputePipeline, name) \ ASSIGN_DRIVER_FUNC(CreateGraphicsPipeline, name) \ ASSIGN_DRIVER_FUNC(CreateSampler, name) \ - ASSIGN_DRIVER_FUNC(CreateFramebuffer, name) \ ASSIGN_DRIVER_FUNC(CreateShaderModule, name) \ ASSIGN_DRIVER_FUNC(CreateTexture, name) \ ASSIGN_DRIVER_FUNC(CreateRenderTarget, name) \ @@ -533,9 +507,7 @@ struct Refresh_Device ASSIGN_DRIVER_FUNC(QueueDestroySampler, name) \ ASSIGN_DRIVER_FUNC(QueueDestroyBuffer, name) \ ASSIGN_DRIVER_FUNC(QueueDestroyRenderTarget, name) \ - ASSIGN_DRIVER_FUNC(QueueDestroyFramebuffer, name) \ ASSIGN_DRIVER_FUNC(QueueDestroyShaderModule, name) \ - ASSIGN_DRIVER_FUNC(QueueDestroyRenderPass, name) \ ASSIGN_DRIVER_FUNC(QueueDestroyComputePipeline, name) \ ASSIGN_DRIVER_FUNC(QueueDestroyGraphicsPipeline, name) \ ASSIGN_DRIVER_FUNC(BeginRenderPass, name) \ diff --git a/src/Refresh_Driver_Template.txt b/src/Refresh_Driver_Template.txt index f530f92..6f71659 100644 --- a/src/Refresh_Driver_Template.txt +++ b/src/Refresh_Driver_Template.txt @@ -321,12 +321,6 @@ static void TEMPLATE_DispatchCompute( /* State Creation */ -static Refresh_RenderPass* TEMPLATE_CreateRenderPass( - Refresh_Renderer *driverData, - Refresh_RenderPassCreateInfo *renderPassCreateInfo -) { - NOT_IMPLEMENTED -} static Refresh_ComputePipeline* TEMPLATE_CreateComputePipeline( Refresh_Renderer *driverData, @@ -349,13 +343,6 @@ static Refresh_Sampler* TEMPLATE_CreateSampler( NOT_IMPLEMENTED } -static Refresh_Framebuffer* TEMPLATE_CreateFramebuffer( - Refresh_Renderer *driverData, - Refresh_FramebufferCreateInfo *framebufferCreateInfo -) { - NOT_IMPLEMENTED -} - static Refresh_ShaderModule* TEMPLATE_CreateShaderModule( Refresh_Renderer *driverData, Refresh_ShaderModuleCreateInfo *shaderModuleCreateInfo @@ -504,6 +491,7 @@ static void TEMPLATE_GetBufferData( static void TEMPLATE_QueueDestroyTexture( Refresh_Renderer *driverData, + Refresh_CommandBuffer *commandBuffer, Refresh_Texture *texture ) { NOT_IMPLEMENTED @@ -511,6 +499,7 @@ static void TEMPLATE_QueueDestroyTexture( static void TEMPLATE_QueueDestroySampler( Refresh_Renderer *driverData, + Refresh_CommandBuffer *commandBuffer, Refresh_Sampler *sampler ) { NOT_IMPLEMENTED @@ -518,6 +507,7 @@ static void TEMPLATE_QueueDestroySampler( static void TEMPLATE_QueueDestroyBuffer( Refresh_Renderer *driverData, + Refresh_CommandBuffer *commandBuffer, Refresh_Buffer *buffer ) { NOT_IMPLEMENTED @@ -525,34 +515,25 @@ static void TEMPLATE_QueueDestroyBuffer( static void TEMPLATE_QueueDestroyRenderTarget( Refresh_Renderer *driverData, + Refresh_CommandBuffer *commandBuffer, Refresh_RenderTarget *renderTarget ) { NOT_IMPLEMENTED } -static void TEMPLATE_QueueDestroyFramebuffer( - Refresh_Renderer *driverData, - Refresh_Framebuffer *frameBuffer -) { - NOT_IMPLEMENTED -} - static void TEMPLATE_QueueDestroyShaderModule( Refresh_Renderer *driverData, + Refresh_CommandBuffer *commandBuffer, + Refresh_ShaderModule *shaderModule ) { NOT_IMPLEMENTED } -static void TEMPLATE_QueueDestroyRenderPass( - Refresh_Renderer *driverData, - Refresh_RenderPass *renderPass -) { - NOT_IMPLEMENTED -} static void TEMPLATE_QueueDestroyComputePipeline( Refresh_Renderer *driverData, + Refresh_CommandBuffer *commandBuffer, Refresh_ComputePipeline *computePipeline ) { NOT_IMPLEMENTED @@ -560,6 +541,7 @@ static void TEMPLATE_QueueDestroyComputePipeline( static void TEMPLATE_QueueDestroyGraphicsPipeline( Refresh_Renderer *driverData, + Refresh_CommandBuffer *commandBuffer, Refresh_GraphicsPipeline *graphicsPipeline ) { NOT_IMPLEMENTED @@ -570,12 +552,10 @@ static void TEMPLATE_QueueDestroyGraphicsPipeline( static void TEMPLATE_BeginRenderPass( Refresh_Renderer *driverData, Refresh_CommandBuffer *commandBuffer, - Refresh_RenderPass *renderPass, - Refresh_Framebuffer *framebuffer, Refresh_Rect *renderArea, - Refresh_Vec4 *pColorClearValues, - uint32_t colorClearCount, - Refresh_DepthStencilValue *depthStencilClearValue + Refresh_ColorAttachmentInfo *pColorAttachmentInfos, + uint32_t colorAttachmentCount, + Refresh_DepthStencilAttachmentInfo *depthStencilAttachmentInfo ) { NOT_IMPLEMENTED } diff --git a/src/Refresh_Driver_Vulkan.c b/src/Refresh_Driver_Vulkan.c index ea7c6d5..51e61c9 100644 --- a/src/Refresh_Driver_Vulkan.c +++ b/src/Refresh_Driver_Vulkan.c @@ -141,6 +141,7 @@ typedef enum VulkanResourceAccessType RESOURCE_ACCESS_FRAGMENT_SHADER_READ_COLOR_ATTACHMENT, RESOURCE_ACCESS_FRAGMENT_SHADER_READ_DEPTH_STENCIL_ATTACHMENT, RESOURCE_ACCESS_COMPUTE_SHADER_READ_UNIFORM_BUFFER, + RESOURCE_ACCESS_COMPUTE_SHADER_READ_SAMPLED_IMAGE_OR_UNIFORM_TEXEL_BUFFER, RESOURCE_ACCESS_COMPUTE_SHADER_READ_OTHER, RESOURCE_ACCESS_ANY_SHADER_READ_SAMPLED_IMAGE, RESOURCE_ACCESS_COLOR_ATTACHMENT_READ, @@ -526,6 +527,12 @@ static const VulkanResourceAccessInfo AccessMap[RESOURCE_ACCESS_TYPES_COUNT] = VK_IMAGE_LAYOUT_UNDEFINED }, + /* RESOURCE_ACCESS_COMPUTE_SHADER_READ_SAMPLED_IMAGE_OR_UNIFORM_TEXEL_BUFFER */ + { VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, + VK_ACCESS_SHADER_READ_BIT, + VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL + }, + /* RESOURCE_ACCESS_COMPUTE_SHADER_READ_OTHER */ { VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, @@ -816,16 +823,6 @@ typedef struct VulkanRenderTarget VkSampleCountFlags multisampleCount; } VulkanRenderTarget; -typedef struct VulkanFramebuffer -{ - VkFramebuffer framebuffer; - VulkanRenderTarget *colorTargets[MAX_COLOR_TARGET_BINDINGS]; - uint32_t colorTargetCount; - VulkanRenderTarget *depthStencilTarget; - uint32_t width; - uint32_t height; -} VulkanFramebuffer; - /* Cache structures */ /* Descriptor Set Layout Caches*/ @@ -907,6 +904,131 @@ static inline void DescriptorSetLayoutHashTable_Insert( arr->count += 1; } +typedef struct RenderPassColorTargetDescription +{ + Refresh_Vec4 clearColor; + Refresh_LoadOp loadOp; + Refresh_StoreOp storeOp; +} RenderPassColorTargetDescription; + +typedef struct RenderPassDepthStencilTargetDescription +{ + Refresh_LoadOp loadOp; + Refresh_StoreOp storeOp; + Refresh_LoadOp stencilLoadOp; + Refresh_StoreOp stencilStoreOp; +} RenderPassDepthStencilTargetDescription; + +typedef struct RenderPassHash +{ + RenderPassColorTargetDescription colorTargetDescriptions[MAX_COLOR_TARGET_BINDINGS]; + uint32_t colorAttachmentCount; + RenderPassDepthStencilTargetDescription depthStencilTargetDescription; +} RenderPassHash; + +typedef struct RenderPassHashMap +{ + RenderPassHash key; + VkRenderPass value; +} RenderPassHashMap; + +typedef struct RenderPassHashArray +{ + RenderPassHashMap *elements; + int32_t count; + int32_t capacity; +} RenderPassHashArray; + +static inline uint8_t RenderPassHash_Compare( + RenderPassHash *a, + RenderPassHash *b +) { + uint32_t i; + + if (a->colorAttachmentCount != b->colorAttachmentCount) + { + return 0; + } + + for (i = 0; i < a->colorAttachmentCount; i += 1) + { + if ( a->colorTargetDescriptions[i].clearColor.x != b->colorTargetDescriptions[i].clearColor.x || + a->colorTargetDescriptions[i].clearColor.y != b->colorTargetDescriptions[i].clearColor.y || + a->colorTargetDescriptions[i].clearColor.z != b->colorTargetDescriptions[i].clearColor.z || + a->colorTargetDescriptions[i].clearColor.w != b->colorTargetDescriptions[i].clearColor.w ) + { + return 0; + } + + if (a->colorTargetDescriptions[i].loadOp != b->colorTargetDescriptions[i].loadOp) + { + return 0; + } + + if (a->colorTargetDescriptions[i].storeOp != b->colorTargetDescriptions[i].storeOp) + { + return 0; + } + } + + if (a->depthStencilTargetDescription.loadOp != b->depthStencilTargetDescription.loadOp) + { + return 0; + } + + if (a->depthStencilTargetDescription.storeOp != b->depthStencilTargetDescription.storeOp) + { + return 0; + } + + if (a->depthStencilTargetDescription.stencilLoadOp != b->depthStencilTargetDescription.stencilLoadOp) + { + return 0; + } + + if (a->depthStencilTargetDescription.stencilStoreOp != b->depthStencilTargetDescription.stencilStoreOp) + { + return 0; + } + + return 1; +} + +static inline VkRenderPass RenderPassHashArray_Fetch( + RenderPassHashArray *arr, + RenderPassHash *key +) { + int32_t i, j; + + for (i = 0; i < arr->count; i += 1) + { + const RenderPassHash *e = &arr->elements[i].key; + + if (RenderPassHash_Compare(e, key)) + { + return arr->elements[i].value; + } + } + + return VK_NULL_HANDLE; +} + +static inline void RenderPassHashArray_Insert( + RenderPassHashArray *arr, + RenderPassHash key, + VkRenderPass value +) { + RenderPassHashMap map; + + map.key = key; + map.value = value; + + EXPAND_ELEMENTS_IF_NEEDED(arr, 4, RenderPassHashMap) + + arr->elements[arr->count] = map; + arr->count += 1; +} + /* Descriptor Set Caches */ struct DescriptorSetCache @@ -1123,15 +1245,11 @@ typedef struct VulkanCommandBuffer VulkanComputePipeline *currentComputePipeline; VulkanGraphicsPipeline *currentGraphicsPipeline; - VulkanFramebuffer *currentFramebuffer; VulkanUniformBuffer *vertexUniformBuffer; VulkanUniformBuffer *fragmentUniformBuffer; VulkanUniformBuffer *computeUniformBuffer; - VulkanBuffer *boundComputeBuffers[MAX_BUFFER_BINDINGS]; - uint32_t boundComputeBufferCount; - VkDescriptorSet vertexSamplerDescriptorSet; /* updated by BindVertexSamplers */ VkDescriptorSet fragmentSamplerDescriptorSet; /* updated by BindFragmentSamplers */ VkDescriptorSet bufferDescriptorSet; /* updated by BindComputeBuffers */ @@ -1179,14 +1297,6 @@ typedef struct VulkanCommandBuffer uint32_t samplersToDestroyCount; uint32_t samplersToDestroyCapacity; - VulkanFramebuffer **framebuffersToDestroy; - uint32_t framebuffersToDestroyCount; - uint32_t framebuffersToDestroyCapacity; - - VkRenderPass *renderPassesToDestroy; - uint32_t renderPassesToDestroyCount; - uint32_t renderPassesToDestroyCapacity; - VkFence inFlightFence; /* borrowed from VulkanRenderer */ } VulkanCommandBuffer; @@ -1313,6 +1423,7 @@ typedef struct VulkanRenderer DescriptorSetLayoutHashTable descriptorSetLayoutHashTable; GraphicsPipelineLayoutHashTable graphicsPipelineLayoutHashTable; ComputePipelineLayoutHashTable computePipelineLayoutHashTable; + RenderPassHashArray renderPassHashArray; VkDescriptorPool defaultDescriptorPool; @@ -2396,8 +2507,6 @@ static void VULKAN_INTERNAL_DestroyCommandPool( SDL_free(commandBuffer->computePipelinesToDestroy); SDL_free(commandBuffer->shaderModulesToDestroy); SDL_free(commandBuffer->samplersToDestroy); - SDL_free(commandBuffer->framebuffersToDestroy); - SDL_free(commandBuffer->renderPassesToDestroy); SDL_free(commandBuffer); } @@ -2454,18 +2563,6 @@ static void VULKAN_INTERNAL_DestroySampler( ); } -/* The framebuffer doesn't own any targets so we don't have to do much. */ -static void VULKAN_INTERNAL_DestroyFramebuffer( - VulkanRenderer *renderer, - VulkanFramebuffer *framebuffer -) { - renderer->vkDestroyFramebuffer( - renderer->logicalDevice, - framebuffer->framebuffer, - NULL - ); -} - static void VULKAN_INTERNAL_DestroyRenderPass( VulkanRenderer *renderer, VkRenderPass renderPass @@ -3956,7 +4053,6 @@ static void VULKAN_INTERNAL_EndCommandBuffer( } commandBuffer->computeUniformBuffer = NULL; commandBuffer->currentComputePipeline = NULL; - commandBuffer->boundComputeBufferCount = 0; result = renderer->vkEndCommandBuffer( commandBuffer->commandBuffer @@ -4220,8 +4316,7 @@ static void VULKAN_Clear( uint8_t shouldClearStencil = options & REFRESH_CLEAROPTIONS_STENCIL; uint8_t shouldClearDepthStencil = ( - (shouldClearDepth || shouldClearStencil) && - vulkanCommandBuffer->currentFramebuffer->depthStencilTarget != NULL + (shouldClearDepth || shouldClearStencil) ); if (!shouldClearColor && !shouldClearDepthStencil) @@ -4440,17 +4535,6 @@ static void VULKAN_DispatchCompute( VkDescriptorSet descriptorSets[3]; uint32_t i; - for (i = 0; i < vulkanCommandBuffer->boundComputeBufferCount; i += 1) - { - currentBuffer = vulkanCommandBuffer->boundComputeBuffers[i]; - VULKAN_INTERNAL_BufferMemoryBarrier( - renderer, - vulkanCommandBuffer->commandBuffer, - RESOURCE_ACCESS_COMPUTE_SHADER_READ_OTHER, - currentBuffer - ); - } - descriptorSets[0] = vulkanCommandBuffer->bufferDescriptorSet; descriptorSets[1] = vulkanCommandBuffer->imageDescriptorSet; descriptorSets[2] = vulkanCommandBuffer->computeUniformBuffer->descriptorSet; @@ -4472,37 +4556,14 @@ static void VULKAN_DispatchCompute( groupCountY, groupCountZ ); - - for (i = 0; i < vulkanCommandBuffer->boundComputeBufferCount; i += 1) - { - currentBuffer = vulkanCommandBuffer->boundComputeBuffers[i]; - if (currentBuffer->usage & VK_BUFFER_USAGE_VERTEX_BUFFER_BIT) - { - VULKAN_INTERNAL_BufferMemoryBarrier( - renderer, - vulkanCommandBuffer->commandBuffer, - RESOURCE_ACCESS_VERTEX_BUFFER, - currentBuffer - ); - } - else if (currentBuffer->usage & VK_BUFFER_USAGE_INDEX_BUFFER_BIT) - { - VULKAN_INTERNAL_BufferMemoryBarrier( - renderer, - vulkanCommandBuffer->commandBuffer, - RESOURCE_ACCESS_INDEX_BUFFER, - currentBuffer - ); - } - } } -static Refresh_RenderPass* VULKAN_CreateRenderPass( - Refresh_Renderer *driverData, - Refresh_RenderPassCreateInfo *renderPassCreateInfo +static VkRenderPass VULKAN_INTERNAL_CreateRenderPass( + VulkanRenderer *renderer, + Refresh_ColorAttachmentInfo *pColorAttachmentInfos, + uint32_t colorAttachmentCount, + Refresh_DepthStencilAttachmentInfo *depthStencilAttachmentInfo ) { - VulkanRenderer *renderer = (VulkanRenderer*) driverData; - VkResult vulkanResult; VkAttachmentDescription attachmentDescriptions[2 * MAX_COLOR_TARGET_BINDINGS + 1]; VkAttachmentReference colorAttachmentReferences[MAX_COLOR_TARGET_BINDINGS]; @@ -4518,25 +4579,28 @@ static Refresh_RenderPass* VULKAN_CreateRenderPass( uint32_t colorAttachmentReferenceCount = 0; uint32_t resolveReferenceCount = 0; - for (i = 0; i < renderPassCreateInfo->colorTargetCount; i += 1) + VulkanRenderTarget *colorTarget; + VulkanRenderTarget *depthStencilTarget; + + for (i = 0; i < colorAttachmentCount; i += 1) { - if (renderPassCreateInfo->colorTargetDescriptions[attachmentDescriptionCount].multisampleCount > REFRESH_SAMPLECOUNT_1) + colorTarget = (VulkanRenderTarget*) pColorAttachmentInfos[attachmentDescriptionCount].pRenderTarget; + + if (colorTarget->multisampleCount > VK_SAMPLE_COUNT_1_BIT) { multisampling = 1; /* Resolve attachment and multisample attachment */ attachmentDescriptions[attachmentDescriptionCount].flags = 0; - attachmentDescriptions[attachmentDescriptionCount].format = RefreshToVK_SurfaceFormat[ - renderPassCreateInfo->colorTargetDescriptions[i].format - ]; + attachmentDescriptions[attachmentDescriptionCount].format = colorTarget->texture->format; attachmentDescriptions[attachmentDescriptionCount].samples = VK_SAMPLE_COUNT_1_BIT; attachmentDescriptions[attachmentDescriptionCount].loadOp = RefreshToVK_LoadOp[ - renderPassCreateInfo->colorTargetDescriptions[i].loadOp + pColorAttachmentInfos[i].loadOp ]; attachmentDescriptions[attachmentDescriptionCount].storeOp = RefreshToVK_StoreOp[ - renderPassCreateInfo->colorTargetDescriptions[i].storeOp + pColorAttachmentInfos[i].storeOp ]; attachmentDescriptions[attachmentDescriptionCount].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; @@ -4556,17 +4620,13 @@ static Refresh_RenderPass* VULKAN_CreateRenderPass( resolveReferenceCount += 1; attachmentDescriptions[attachmentDescriptionCount].flags = 0; - attachmentDescriptions[attachmentDescriptionCount].format = RefreshToVK_SurfaceFormat[ - renderPassCreateInfo->colorTargetDescriptions[i].format - ]; - attachmentDescriptions[attachmentDescriptionCount].samples = RefreshToVK_SampleCount[ - renderPassCreateInfo->colorTargetDescriptions[i].multisampleCount - ]; + attachmentDescriptions[attachmentDescriptionCount].format = colorTarget->texture->format; + attachmentDescriptions[attachmentDescriptionCount].samples = colorTarget->multisampleCount; attachmentDescriptions[attachmentDescriptionCount].loadOp = RefreshToVK_LoadOp[ - renderPassCreateInfo->colorTargetDescriptions[i].loadOp + pColorAttachmentInfos[i].loadOp ]; attachmentDescriptions[attachmentDescriptionCount].storeOp = RefreshToVK_StoreOp[ - renderPassCreateInfo->colorTargetDescriptions[i].storeOp + pColorAttachmentInfos[i].storeOp ]; attachmentDescriptions[attachmentDescriptionCount].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; @@ -4588,16 +4648,14 @@ static Refresh_RenderPass* VULKAN_CreateRenderPass( else { attachmentDescriptions[attachmentDescriptionCount].flags = 0; - attachmentDescriptions[attachmentDescriptionCount].format = RefreshToVK_SurfaceFormat[ - renderPassCreateInfo->colorTargetDescriptions[i].format - ]; + attachmentDescriptions[attachmentDescriptionCount].format = colorTarget->texture->format; attachmentDescriptions[attachmentDescriptionCount].samples = VK_SAMPLE_COUNT_1_BIT; attachmentDescriptions[attachmentDescriptionCount].loadOp = RefreshToVK_LoadOp[ - renderPassCreateInfo->colorTargetDescriptions[i].loadOp + pColorAttachmentInfos[i].loadOp ]; attachmentDescriptions[attachmentDescriptionCount].storeOp = RefreshToVK_StoreOp[ - renderPassCreateInfo->colorTargetDescriptions[i].storeOp + pColorAttachmentInfos[i].storeOp ]; attachmentDescriptions[attachmentDescriptionCount].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; @@ -4622,34 +4680,33 @@ static Refresh_RenderPass* VULKAN_CreateRenderPass( subpass.flags = 0; subpass.inputAttachmentCount = 0; subpass.pInputAttachments = NULL; - subpass.colorAttachmentCount = renderPassCreateInfo->colorTargetCount; + subpass.colorAttachmentCount = colorAttachmentCount; subpass.pColorAttachments = colorAttachmentReferences; subpass.preserveAttachmentCount = 0; subpass.pPreserveAttachments = NULL; - if (renderPassCreateInfo->depthTargetDescription == NULL) + if (depthStencilAttachmentInfo == NULL) { subpass.pDepthStencilAttachment = NULL; } else { + depthStencilTarget = (VulkanRenderTarget*) depthStencilAttachmentInfo->pDepthStencilTarget; attachmentDescriptions[attachmentDescriptionCount].flags = 0; - attachmentDescriptions[attachmentDescriptionCount].format = RefreshToVK_SurfaceFormat[ - renderPassCreateInfo->depthTargetDescription->depthStencilFormat - ]; + attachmentDescriptions[attachmentDescriptionCount].format = depthStencilTarget->texture->format; attachmentDescriptions[attachmentDescriptionCount].samples = VK_SAMPLE_COUNT_1_BIT; /* FIXME: do these take multisamples? */ attachmentDescriptions[attachmentDescriptionCount].loadOp = RefreshToVK_LoadOp[ - renderPassCreateInfo->depthTargetDescription->loadOp + depthStencilAttachmentInfo->loadOp ]; attachmentDescriptions[attachmentDescriptionCount].storeOp = RefreshToVK_StoreOp[ - renderPassCreateInfo->depthTargetDescription->storeOp + depthStencilAttachmentInfo->storeOp ]; attachmentDescriptions[attachmentDescriptionCount].stencilLoadOp = RefreshToVK_LoadOp[ - renderPassCreateInfo->depthTargetDescription->stencilLoadOp + depthStencilAttachmentInfo->stencilLoadOp ]; attachmentDescriptions[attachmentDescriptionCount].stencilStoreOp = RefreshToVK_StoreOp[ - renderPassCreateInfo->depthTargetDescription->stencilStoreOp + depthStencilAttachmentInfo->stencilStoreOp ]; attachmentDescriptions[attachmentDescriptionCount].initialLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; @@ -4696,10 +4753,10 @@ static Refresh_RenderPass* VULKAN_CreateRenderPass( if (vulkanResult != VK_SUCCESS) { LogVulkanResultAsError("vkCreateRenderPass", vulkanResult); - return NULL_RENDER_PASS; + return VK_NULL_HANDLE; } - return (Refresh_RenderPass*) renderPass; + return renderPass; } static Refresh_GraphicsPipeline* VULKAN_CreateGraphicsPipeline( @@ -5268,22 +5325,27 @@ static Refresh_Sampler* VULKAN_CreateSampler( return (Refresh_Sampler*) sampler; } -static Refresh_Framebuffer* VULKAN_CreateFramebuffer( +static VkFramebuffer VULKAN_INTERNAL_CreateFramebuffer( Refresh_Renderer *driverData, - Refresh_FramebufferCreateInfo *framebufferCreateInfo + VkRenderPass renderPass, + uint32_t width, + uint32_t height, + VulkanRenderTarget **colorTargets, + uint32_t colorTargetCount, + VulkanRenderTarget *depthStencilTarget /* Can be NULL */ ) { VkResult vulkanResult; + VkFramebuffer framebuffer; VkFramebufferCreateInfo vkFramebufferCreateInfo; VkImageView *imageViews; - uint32_t colorAttachmentCount = framebufferCreateInfo->colorTargetCount; + uint32_t colorAttachmentCount = colorTargetCount; uint32_t attachmentCount = colorAttachmentCount; uint32_t i; VulkanRenderer *renderer = (VulkanRenderer*) driverData; - VulkanFramebuffer *vulkanFramebuffer = (VulkanFramebuffer*) SDL_malloc(sizeof(VulkanFramebuffer)); - if (framebufferCreateInfo->pDepthStencilTarget != NULL) + if (depthStencilTarget != NULL) { attachmentCount += 1; } @@ -5292,53 +5354,40 @@ static Refresh_Framebuffer* VULKAN_CreateFramebuffer( for (i = 0; i < colorAttachmentCount; i += 1) { - imageViews[i] = ((VulkanRenderTarget*)framebufferCreateInfo->pColorTargets[i])->view; + imageViews[i] = ((VulkanRenderTarget*)colorTargets[i])->view; } - if (framebufferCreateInfo->pDepthStencilTarget != NULL) + if (depthStencilTarget != NULL) { - imageViews[colorAttachmentCount] = ((VulkanRenderTarget*)framebufferCreateInfo->pDepthStencilTarget)->view; + imageViews[colorAttachmentCount] = ((VulkanRenderTarget*)depthStencilTarget)->view; } vkFramebufferCreateInfo.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO; vkFramebufferCreateInfo.pNext = NULL; vkFramebufferCreateInfo.flags = 0; - vkFramebufferCreateInfo.renderPass = (VkRenderPass) framebufferCreateInfo->renderPass; + vkFramebufferCreateInfo.renderPass = renderPass; vkFramebufferCreateInfo.attachmentCount = attachmentCount; vkFramebufferCreateInfo.pAttachments = imageViews; - vkFramebufferCreateInfo.width = framebufferCreateInfo->width; - vkFramebufferCreateInfo.height = framebufferCreateInfo->height; + vkFramebufferCreateInfo.width = width; + vkFramebufferCreateInfo.height = height; vkFramebufferCreateInfo.layers = 1; vulkanResult = renderer->vkCreateFramebuffer( renderer->logicalDevice, &vkFramebufferCreateInfo, NULL, - &vulkanFramebuffer->framebuffer + &framebuffer ); + SDL_stack_free(imageViews); + if (vulkanResult != VK_SUCCESS) { LogVulkanResultAsError("vkCreateFramebuffer", vulkanResult); - SDL_stack_free(imageViews); - return NULL; + return VK_NULL_HANDLE; } - for (i = 0; i < colorAttachmentCount; i += 1) - { - vulkanFramebuffer->colorTargets[i] = - (VulkanRenderTarget*) framebufferCreateInfo->pColorTargets[i]; - } - - vulkanFramebuffer->colorTargetCount = colorAttachmentCount; - vulkanFramebuffer->depthStencilTarget = - (VulkanRenderTarget*) framebufferCreateInfo->pDepthStencilTarget; - - vulkanFramebuffer->width = framebufferCreateInfo->width; - vulkanFramebuffer->height = framebufferCreateInfo->height; - - SDL_stack_free(imageViews); - return (Refresh_Framebuffer*) vulkanFramebuffer; + return framebuffer; } static Refresh_ShaderModule* VULKAN_CreateShaderModule( @@ -6706,6 +6755,20 @@ static void VULKAN_BindVertexSamplers( descriptorImageInfos[i].imageView = currentTexture->view; descriptorImageInfos[i].sampler = (VkSampler) pSamplers[i]; descriptorImageInfos[i].imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; + + VULKAN_INTERNAL_ImageMemoryBarrier( + renderer, + vulkanCommandBuffer->commandBuffer, + RESOURCE_ACCESS_VERTEX_SHADER_READ_SAMPLED_IMAGE, + VK_IMAGE_ASPECT_COLOR_BIT, + 0, + currentTexture->layerCount, + 0, + currentTexture->levelCount, + 0, + currentTexture->image, + ¤tTexture->resourceAccessType + ); } vulkanCommandBuffer->vertexSamplerDescriptorSet = VULKAN_INTERNAL_FetchDescriptorSet( @@ -6744,6 +6807,20 @@ static void VULKAN_BindFragmentSamplers( descriptorImageInfos[i].imageView = currentTexture->view; descriptorImageInfos[i].sampler = (VkSampler) pSamplers[i]; descriptorImageInfos[i].imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; + + VULKAN_INTERNAL_ImageMemoryBarrier( + renderer, + vulkanCommandBuffer->commandBuffer, + RESOURCE_ACCESS_FRAGMENT_SHADER_READ_SAMPLED_IMAGE, + VK_IMAGE_ASPECT_COLOR_BIT, + 0, + currentTexture->layerCount, + 0, + currentTexture->levelCount, + 0, + currentTexture->image, + ¤tTexture->resourceAccessType + ); } vulkanCommandBuffer->fragmentSamplerDescriptorSet = VULKAN_INTERNAL_FetchDescriptorSet( @@ -6931,26 +7008,6 @@ static void VULKAN_QueueDestroyRenderTarget( vulkanCommandBuffer->renderTargetsToDestroyCount += 1; } -static void VULKAN_QueueDestroyFramebuffer( - Refresh_Renderer *driverData, - Refresh_CommandBuffer *commandBuffer, - Refresh_Framebuffer *framebuffer -) { - VulkanCommandBuffer* vulkanCommandBuffer = (VulkanCommandBuffer*)commandBuffer; - VulkanFramebuffer *vulkanFramebuffer = (VulkanFramebuffer*) framebuffer; - - EXPAND_ARRAY_IF_NEEDED( - vulkanCommandBuffer->framebuffersToDestroy, - VulkanFramebuffer*, - vulkanCommandBuffer->framebuffersToDestroyCount + 1, - vulkanCommandBuffer->framebuffersToDestroyCapacity, - vulkanCommandBuffer->framebuffersToDestroyCapacity * 2 - ) - - vulkanCommandBuffer->framebuffersToDestroy[vulkanCommandBuffer->framebuffersToDestroyCount] = vulkanFramebuffer; - vulkanCommandBuffer->framebuffersToDestroyCount += 1; -} - static void VULKAN_QueueDestroyShaderModule( Refresh_Renderer *driverData, Refresh_CommandBuffer *commandBuffer, @@ -6971,26 +7028,6 @@ static void VULKAN_QueueDestroyShaderModule( vulkanCommandBuffer->shaderModulesToDestroyCount += 1; } -static void VULKAN_QueueDestroyRenderPass( - Refresh_Renderer *driverData, - Refresh_CommandBuffer *commandBuffer, - Refresh_RenderPass *renderPass -) { - VulkanCommandBuffer* vulkanCommandBuffer = (VulkanCommandBuffer*)commandBuffer; - VkRenderPass vulkanRenderPass = (VkRenderPass) renderPass; - - EXPAND_ARRAY_IF_NEEDED( - vulkanCommandBuffer->renderPassesToDestroy, - VkRenderPass, - vulkanCommandBuffer->renderPassesToDestroyCount + 1, - vulkanCommandBuffer->renderPassesToDestroyCapacity, - vulkanCommandBuffer->renderPassesToDestroyCapacity * 2 - ) - - vulkanCommandBuffer->renderPassesToDestroy[vulkanCommandBuffer->renderPassesToDestroyCount] = vulkanRenderPass; - vulkanCommandBuffer->renderPassesToDestroyCount += 1; -} - static void VULKAN_QueueDestroyComputePipeline( Refresh_Renderer *driverData, Refresh_CommandBuffer *commandBuffer, @@ -7033,50 +7070,121 @@ static void VULKAN_QueueDestroyGraphicsPipeline( /* Command Buffer render state */ +static VkRenderPass VULKAN_INTERNAL_FetchRenderPass( + VulkanRenderer *renderer, + Refresh_ColorAttachmentInfo *pColorAttachmentInfos, + uint32_t colorAttachmentCount, + Refresh_DepthStencilAttachmentInfo *depthStencilAttachmentInfo +) { + VkRenderPass renderPass; + RenderPassHash hash; + uint32_t i; + + for (i = 0; i < colorAttachmentCount; i += 1) + { + hash.colorTargetDescriptions[i].clearColor = pColorAttachmentInfos[i].clearColor; + hash.colorTargetDescriptions[i].loadOp = pColorAttachmentInfos[i].loadOp; + hash.colorTargetDescriptions[i].storeOp = pColorAttachmentInfos[i].storeOp; + } + + if (depthStencilAttachmentInfo == NULL) + { + hash.depthStencilTargetDescription.loadOp = REFRESH_LOADOP_DONT_CARE; + hash.depthStencilTargetDescription.storeOp = REFRESH_STOREOP_DONT_CARE; + hash.depthStencilTargetDescription.stencilLoadOp = REFRESH_LOADOP_DONT_CARE; + hash.depthStencilTargetDescription.stencilStoreOp = REFRESH_STOREOP_DONT_CARE; + } + else + { + hash.depthStencilTargetDescription.loadOp = depthStencilAttachmentInfo->loadOp; + hash.depthStencilTargetDescription.storeOp = depthStencilAttachmentInfo->storeOp; + hash.depthStencilTargetDescription.stencilLoadOp = depthStencilAttachmentInfo->stencilLoadOp; + hash.depthStencilTargetDescription.stencilStoreOp = depthStencilAttachmentInfo->stencilStoreOp; + } + + renderPass = RenderPassHashArray_Fetch( + &renderer->renderPassHashArray, + &hash + ); + + if (renderPass != VK_NULL_HANDLE) + { + return renderPass; + } + + renderPass = VULKAN_INTERNAL_CreateRenderPass( + renderer, + pColorAttachmentInfos, + colorAttachmentCount, + depthStencilAttachmentInfo + ); + + RenderPassHashArray_Insert( + &renderer->renderPassHashArray, + hash, + renderPass + ); + + return renderPass; +} + static void VULKAN_BeginRenderPass( Refresh_Renderer *driverData, Refresh_CommandBuffer *commandBuffer, - Refresh_RenderPass *renderPass, - Refresh_Framebuffer *framebuffer, Refresh_Rect *renderArea, - Refresh_Vec4 *pColorClearValues, - uint32_t colorClearCount, - Refresh_DepthStencilValue *depthStencilClearValue + Refresh_ColorAttachmentInfo *pColorAttachmentInfos, + uint32_t colorAttachmentCount, + Refresh_DepthStencilAttachmentInfo *depthStencilAttachmentInfo ) { VulkanRenderer* renderer = (VulkanRenderer*) driverData; VulkanCommandBuffer *vulkanCommandBuffer = (VulkanCommandBuffer*) commandBuffer; - VulkanFramebuffer *vulkanFramebuffer = (VulkanFramebuffer*) framebuffer; + VkRenderPass renderPass; + VkFramebuffer framebuffer; + VulkanRenderTarget *colorTarget; + VulkanRenderTarget *depthStencilTarget; VkClearValue *clearValues; + uint32_t clearCount = colorAttachmentCount; uint32_t i; - uint32_t clearCount = colorClearCount; VkImageAspectFlags depthAspectFlags; + renderPass = VULKAN_INTERNAL_FetchRenderPass( + renderer, + pColorAttachmentInfos, + colorAttachmentCount, + depthStencilAttachmentInfo + ); + + framebuffer = VULKAN_INTERNAL_FetchFramebuffer(renderer); + /* Layout transitions */ - for (i = 0; i < vulkanFramebuffer->colorTargetCount; i += 1) + for (i = 0; i < colorAttachmentCount; i += 1) { + VulkanRenderTarget *colorTarget = (VulkanRenderTarget*) pColorAttachmentInfos->pRenderTarget; + VULKAN_INTERNAL_ImageMemoryBarrier( renderer, vulkanCommandBuffer->commandBuffer, RESOURCE_ACCESS_COLOR_ATTACHMENT_READ_WRITE, VK_IMAGE_ASPECT_COLOR_BIT, 0, - vulkanFramebuffer->colorTargets[i]->texture->layerCount, + colorTarget->texture->layerCount, 0, - vulkanFramebuffer->colorTargets[i]->texture->levelCount, + colorTarget->texture->levelCount, 0, - vulkanFramebuffer->colorTargets[i]->texture->image, - &vulkanFramebuffer->colorTargets[i]->texture->resourceAccessType + colorTarget->texture->image, + &colorTarget->texture->resourceAccessType ); } - if (vulkanFramebuffer->depthStencilTarget != NULL) + if (depthStencilAttachmentInfo != NULL) { + depthStencilTarget = (VulkanRenderTarget*) depthStencilAttachmentInfo->pDepthStencilTarget; depthAspectFlags = VK_IMAGE_ASPECT_DEPTH_BIT; if (IsStencilFormat( - vulkanFramebuffer->depthStencilTarget->texture->format + depthStencilTarget->texture->format )) { depthAspectFlags |= VK_IMAGE_ASPECT_STENCIL_BIT; } @@ -7087,12 +7195,12 @@ static void VULKAN_BeginRenderPass( RESOURCE_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_WRITE, depthAspectFlags, 0, - vulkanFramebuffer->depthStencilTarget->texture->layerCount, + depthStencilTarget->texture->layerCount, 0, - vulkanFramebuffer->depthStencilTarget->texture->levelCount, + depthStencilTarget->texture->levelCount, 0, - vulkanFramebuffer->depthStencilTarget->texture->image, - &vulkanFramebuffer->depthStencilTarget->texture->resourceAccessType + depthStencilTarget->texture->image, + &depthStencilTarget->texture->resourceAccessType ); clearCount += 1; @@ -7102,27 +7210,27 @@ static void VULKAN_BeginRenderPass( clearValues = SDL_stack_alloc(VkClearValue, clearCount); - for (i = 0; i < colorClearCount; i += 1) + for (i = 0; i < colorAttachmentCount; i += 1) { - clearValues[i].color.float32[0] = pColorClearValues[i].x; - clearValues[i].color.float32[1] = pColorClearValues[i].y; - clearValues[i].color.float32[2] = pColorClearValues[i].z; - clearValues[i].color.float32[3] = pColorClearValues[i].w; + clearValues[i].color.float32[0] = pColorAttachmentInfos[i].clearColor.x; + clearValues[i].color.float32[1] = pColorAttachmentInfos[i].clearColor.y; + clearValues[i].color.float32[2] = pColorAttachmentInfos[i].clearColor.z; + clearValues[i].color.float32[3] = pColorAttachmentInfos[i].clearColor.w; } - if (depthStencilClearValue != NULL) + if (depthStencilAttachmentInfo != NULL) { - clearValues[colorClearCount].depthStencil.depth = - depthStencilClearValue->depth; - clearValues[colorClearCount].depthStencil.stencil = - depthStencilClearValue->stencil; + clearValues[colorAttachmentCount].depthStencil.depth = + depthStencilAttachmentInfo->depthStencilValue.depth; + clearValues[colorAttachmentCount].depthStencil.stencil = + depthStencilAttachmentInfo->depthStencilValue.stencil; } VkRenderPassBeginInfo renderPassBeginInfo; renderPassBeginInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO; renderPassBeginInfo.pNext = NULL; renderPassBeginInfo.renderPass = (VkRenderPass) renderPass; - renderPassBeginInfo.framebuffer = vulkanFramebuffer->framebuffer; + renderPassBeginInfo.framebuffer = framebuffer; renderPassBeginInfo.renderArea.extent.width = renderArea->w; renderPassBeginInfo.renderArea.extent.height = renderArea->h; renderPassBeginInfo.renderArea.offset.x = renderArea->x; @@ -7136,7 +7244,6 @@ static void VULKAN_BeginRenderPass( VK_SUBPASS_CONTENTS_INLINE ); - vulkanCommandBuffer->currentFramebuffer = vulkanFramebuffer; vulkanCommandBuffer->renderPassInProgress = 1; SDL_stack_free(clearValues); @@ -7174,62 +7281,9 @@ static void VULKAN_EndRenderPass( vulkanCommandBuffer->fragmentUniformBuffer ); } + vulkanCommandBuffer->fragmentUniformBuffer = NULL; - - for (i = 0; i < vulkanCommandBuffer->currentFramebuffer->colorTargetCount; i += 1) - { - currentTexture = vulkanCommandBuffer->currentFramebuffer->colorTargets[i]->texture; - - if (currentTexture->usageFlags & VK_IMAGE_USAGE_SAMPLED_BIT) - { - VULKAN_INTERNAL_ImageMemoryBarrier( - renderer, - vulkanCommandBuffer->commandBuffer, - RESOURCE_ACCESS_ANY_SHADER_READ_SAMPLED_IMAGE, - VK_IMAGE_ASPECT_COLOR_BIT, - 0, - currentTexture->layerCount, - 0, - currentTexture->levelCount, - 0, - currentTexture->image, - ¤tTexture->resourceAccessType - ); - } - } - - if (vulkanCommandBuffer->currentFramebuffer->depthStencilTarget != NULL) - { - currentTexture = vulkanCommandBuffer->currentFramebuffer->depthStencilTarget->texture; - - if (currentTexture->usageFlags & VK_IMAGE_USAGE_SAMPLED_BIT) - { - depthAspectFlags = VK_IMAGE_ASPECT_DEPTH_BIT; - - if (IsStencilFormat( - currentTexture->format - )) { - depthAspectFlags |= VK_IMAGE_ASPECT_STENCIL_BIT; - } - - VULKAN_INTERNAL_ImageMemoryBarrier( - renderer, - vulkanCommandBuffer->commandBuffer, - RESOURCE_ACCESS_ANY_SHADER_READ_SAMPLED_IMAGE, - depthAspectFlags, - 0, - currentTexture->layerCount, - 0, - currentTexture->levelCount, - 0, - currentTexture->image, - ¤tTexture->resourceAccessType - ); - } - } - vulkanCommandBuffer->currentGraphicsPipeline = NULL; - vulkanCommandBuffer->currentFramebuffer = NULL; vulkanCommandBuffer->renderPassInProgress = 0; } @@ -7324,6 +7378,13 @@ static void VULKAN_BindVertexBuffers( { currentVulkanBuffer = (VulkanBuffer*) pBuffers[i]; buffers[i] = currentVulkanBuffer->buffer; + + VULKAN_INTERNAL_BufferMemoryBarrier( + renderer, + vulkanCommandBuffer->commandBuffer, + RESOURCE_ACCESS_VERTEX_BUFFER, + currentVulkanBuffer + ); } renderer->vkCmdBindVertexBuffers( @@ -7348,6 +7409,13 @@ static void VULKAN_BindIndexBuffer( VulkanCommandBuffer *vulkanCommandBuffer = (VulkanCommandBuffer*) commandBuffer; VulkanBuffer* vulkanBuffer = (VulkanBuffer*) buffer; + VULKAN_INTERNAL_BufferMemoryBarrier( + renderer, + vulkanCommandBuffer->commandBuffer, + RESOURCE_ACCESS_INDEX_BUFFER, + vulkanBuffer + ); + renderer->vkCmdBindIndexBuffer( vulkanCommandBuffer->commandBuffer, vulkanBuffer->buffer, @@ -7430,11 +7498,14 @@ static void VULKAN_BindComputeBuffers( descriptorBufferInfos[i].offset = 0; descriptorBufferInfos[i].range = currentVulkanBuffer->size; - vulkanCommandBuffer->boundComputeBuffers[i] = currentVulkanBuffer; + VULKAN_INTERNAL_BufferMemoryBarrier( + renderer, + vulkanCommandBuffer->commandBuffer, + RESOURCE_ACCESS_COMPUTE_SHADER_READ_OTHER, + currentVulkanBuffer + ); } - vulkanCommandBuffer->boundComputeBufferCount = computePipeline->pipelineLayout->bufferDescriptorSetCache->bindingCount; - vulkanCommandBuffer->bufferDescriptorSet = VULKAN_INTERNAL_FetchDescriptorSet( renderer, @@ -7469,6 +7540,20 @@ static void VULKAN_BindComputeTextures( descriptorImageInfos[i].imageView = currentTexture->view; descriptorImageInfos[i].sampler = VK_NULL_HANDLE; descriptorImageInfos[i].imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; + + VULKAN_INTERNAL_ImageMemoryBarrier( + renderer, + vulkanCommandBuffer->commandBuffer, + RESOURCE_ACCESS_COMPUTE_SHADER_READ_SAMPLED_IMAGE_OR_UNIFORM_TEXEL_BUFFER, + VK_IMAGE_ASPECT_COLOR_BIT, + 0, + currentTexture->layerCount, + 0, + currentTexture->levelCount, + 0, + currentTexture->image, + ¤tTexture->resourceAccessType + ); } vulkanCommandBuffer->imageDescriptorSet = @@ -7524,7 +7609,6 @@ static void VULKAN_INTERNAL_AllocateCommandBuffers( commandBuffer = SDL_malloc(sizeof(VulkanCommandBuffer)); commandBuffer->commandPool = vulkanCommandPool; commandBuffer->commandBuffer = commandBuffers[i]; - commandBuffer->boundComputeBufferCount = 0; commandBuffer->present = 0; commandBuffer->presentWindowHandle = NULL; @@ -7613,22 +7697,6 @@ static void VULKAN_INTERNAL_AllocateCommandBuffers( commandBuffer->samplersToDestroyCapacity ); - commandBuffer->framebuffersToDestroyCapacity = 16; - commandBuffer->framebuffersToDestroyCount = 0; - - commandBuffer->framebuffersToDestroy = (VulkanFramebuffer**) SDL_malloc( - sizeof(VulkanFramebuffer*) * - commandBuffer->framebuffersToDestroyCapacity - ); - - commandBuffer->renderPassesToDestroyCapacity = 16; - commandBuffer->renderPassesToDestroyCount = 0; - - commandBuffer->renderPassesToDestroy = (VkRenderPass*) SDL_malloc( - sizeof(VkRenderPass) * - commandBuffer->renderPassesToDestroyCapacity - ); - vulkanCommandPool->inactiveCommandBuffers[ vulkanCommandPool->inactiveCommandBufferCount ] = commandBuffer; @@ -7744,7 +7812,7 @@ static Refresh_CommandBuffer* VULKAN_AcquireCommandBuffer( commandBuffer->currentComputePipeline = NULL; commandBuffer->currentGraphicsPipeline = NULL; - commandBuffer->currentFramebuffer = NULL; + commandBuffer->vertexUniformBuffer = NULL; commandBuffer->fragmentUniformBuffer = NULL; commandBuffer->computeUniformBuffer = NULL; @@ -7754,12 +7822,6 @@ static Refresh_CommandBuffer* VULKAN_AcquireCommandBuffer( commandBuffer->present = 0; commandBuffer->renderPassInProgress = 0; - for (i = 0; i < MAX_BUFFER_BINDINGS; i += 1) - { - commandBuffer->boundComputeBuffers[i] = NULL; - } - commandBuffer->boundComputeBufferCount = 0; - VULKAN_INTERNAL_BeginCommandBuffer(renderer, commandBuffer); return (Refresh_CommandBuffer*) commandBuffer; @@ -8084,24 +8146,6 @@ static void VULKAN_INTERNAL_CleanCommandBuffer( } commandBuffer->samplersToDestroyCount = 0; - for (i = 0; i < commandBuffer->framebuffersToDestroyCount; i += 1) - { - VULKAN_INTERNAL_DestroyFramebuffer( - renderer, - commandBuffer->framebuffersToDestroy[i] - ); - } - commandBuffer->framebuffersToDestroyCount = 0; - - for (i = 0; i < commandBuffer->renderPassesToDestroyCount; i += 1) - { - VULKAN_INTERNAL_DestroyRenderPass( - renderer, - commandBuffer->renderPassesToDestroy[i] - ); - } - commandBuffer->renderPassesToDestroyCount = 0; - SDL_LockMutex(renderer->acquireCommandBufferLock); if (commandBuffer->commandPool->inactiveCommandBufferCount == commandBuffer->commandPool->inactiveCommandBufferCapacity) -- 2.25.1 From 8d41e2a64a350f6dbf373a605c06850ebb173cff Mon Sep 17 00:00:00 2001 From: cosmonaut Date: Thu, 24 Feb 2022 12:01:35 -0800 Subject: [PATCH 2/8] continue rewrite --- include/Refresh.h | 13 +- src/Refresh.c | 4 +- src/Refresh_Driver.h | 2 +- src/Refresh_Driver_Template.txt | 2 +- src/Refresh_Driver_Vulkan.c | 678 ++++++++++++++++++++++++++------ 5 files changed, 558 insertions(+), 141 deletions(-) diff --git a/include/Refresh.h b/include/Refresh.h index 27c61b0..f046988 100644 --- a/include/Refresh.h +++ b/include/Refresh.h @@ -553,17 +553,18 @@ typedef struct Refresh_ComputePipelineCreateInfo Refresh_ComputePipelineLayoutCreateInfo pipelineLayoutCreateInfo; } Refresh_ComputePipelineCreateInfo; -typedef struct Refresh_AttachmentDescription +typedef struct Refresh_ColorAttachmentDescription { Refresh_TextureFormat format; Refresh_SampleCount sampleCount; -} Refresh_AttachmentDescription; +} Refresh_ColorAttachmentDescription; typedef struct Refresh_GraphicsPipelineAttachmentInfo { - Refresh_AttachmentDescription colorAttachmentDescriptions[4]; + Refresh_ColorAttachmentDescription colorAttachmentDescriptions[4]; uint32_t colorAttachmentCount; - Refresh_AttachmentDescription *depthStencilAttachmentDescription; /* Can be NULL */ + uint8_t hasDepthStencilAttachment; + Refresh_TextureFormat depthStencilFormat; } Refresh_GraphicsPipelineAttachmentInfo; typedef struct Refresh_GraphicsPipelineCreateInfo @@ -1113,7 +1114,7 @@ REFRESHAPI void Refresh_QueueDestroyGraphicsPipeline( * The area affected by the render pass. * All load, store and resolve operations are restricted * to the given rectangle. - * pColorAttachmentInfos: + * colorAttachmentInfos: * A pointer to an array of Refresh_ColorAttachmentInfo structures * that contains render targets and clear values. May be NULL. * colorAttachmentCount: The amount of structs in the above array. @@ -1123,7 +1124,7 @@ REFRESHAPI void Refresh_BeginRenderPass( Refresh_Device *device, Refresh_CommandBuffer *commandBuffer, Refresh_Rect *renderArea, - Refresh_ColorAttachmentInfo *pColorAttachmentInfos, + Refresh_ColorAttachmentInfo *colorAttachmentInfos, uint32_t colorAttachmentCount, Refresh_DepthStencilAttachmentInfo *depthStencilAttachmentInfo ); diff --git a/src/Refresh.c b/src/Refresh.c index 3c68cb7..7936df7 100644 --- a/src/Refresh.c +++ b/src/Refresh.c @@ -613,7 +613,7 @@ void Refresh_BeginRenderPass( Refresh_Device *device, Refresh_CommandBuffer *commandBuffer, Refresh_Rect *renderArea, - Refresh_ColorAttachmentInfo *pColorAttachmentInfos, + Refresh_ColorAttachmentInfo *colorAttachmentInfos, uint32_t colorAttachmentCount, Refresh_DepthStencilAttachmentInfo *depthStencilAttachmentInfo ) { @@ -622,7 +622,7 @@ void Refresh_BeginRenderPass( device->driverData, commandBuffer, renderArea, - pColorAttachmentInfos, + colorAttachmentInfos, colorAttachmentCount, depthStencilAttachmentInfo ); diff --git a/src/Refresh_Driver.h b/src/Refresh_Driver.h index 438ec11..fb917e3 100644 --- a/src/Refresh_Driver.h +++ b/src/Refresh_Driver.h @@ -397,7 +397,7 @@ struct Refresh_Device Refresh_Renderer *driverData, Refresh_CommandBuffer *commandBuffer, Refresh_Rect *renderArea, - Refresh_ColorAttachmentInfo *pColorAttachmentInfos, + Refresh_ColorAttachmentInfo *colorAttachmentInfos, uint32_t colorAttachmentCount, Refresh_DepthStencilAttachmentInfo *depthStencilAttachmentInfo ); diff --git a/src/Refresh_Driver_Template.txt b/src/Refresh_Driver_Template.txt index 6f71659..0a01725 100644 --- a/src/Refresh_Driver_Template.txt +++ b/src/Refresh_Driver_Template.txt @@ -553,7 +553,7 @@ static void TEMPLATE_BeginRenderPass( Refresh_Renderer *driverData, Refresh_CommandBuffer *commandBuffer, Refresh_Rect *renderArea, - Refresh_ColorAttachmentInfo *pColorAttachmentInfos, + Refresh_ColorAttachmentInfo *colorAttachmentInfos, uint32_t colorAttachmentCount, Refresh_DepthStencilAttachmentInfo *depthStencilAttachmentInfo ) { diff --git a/src/Refresh_Driver_Vulkan.c b/src/Refresh_Driver_Vulkan.c index 51e61c9..08124ee 100644 --- a/src/Refresh_Driver_Vulkan.c +++ b/src/Refresh_Driver_Vulkan.c @@ -998,11 +998,11 @@ static inline VkRenderPass RenderPassHashArray_Fetch( RenderPassHashArray *arr, RenderPassHash *key ) { - int32_t i, j; + int32_t i; for (i = 0; i < arr->count; i += 1) { - const RenderPassHash *e = &arr->elements[i].key; + RenderPassHash *e = &arr->elements[i].key; if (RenderPassHash_Compare(e, key)) { @@ -1029,6 +1029,116 @@ static inline void RenderPassHashArray_Insert( arr->count += 1; } +typedef struct FramebufferHash +{ + VkImageView colorAttachmentViews[MAX_COLOR_TARGET_BINDINGS]; + VkImageView colorMultiSampleAttachmentViews[MAX_COLOR_TARGET_BINDINGS]; + uint32_t colorAttachmentCount; + VkImageView depthStencilAttachmentView; + uint32_t width; + uint32_t height; +} FramebufferHash; + +typedef struct FramebufferHashMap +{ + FramebufferHash key; + VkFramebuffer value; +} FramebufferHashMap; + +typedef struct FramebufferHashArray +{ + FramebufferHashMap *elements; + int32_t count; + int32_t capacity; +} FramebufferHashArray; + +static inline uint8_t FramebufferHash_Compare( + FramebufferHash *a, + FramebufferHash *b +) { + uint32_t i; + + if (a->colorAttachmentCount != b->colorAttachmentCount) + { + return 0; + } + + for (i = 0; i < a->colorAttachmentCount; i += 1) + { + if (a->colorAttachmentViews[i] != b->colorAttachmentViews[i]) + { + return 0; + } + + if (a->colorMultiSampleAttachmentViews[i] != b->colorMultiSampleAttachmentViews[i]) + { + return 0; + } + } + + if (a->depthStencilAttachmentView != b->depthStencilAttachmentView) + { + return 0; + } + + if (a->width != b->width) + { + return 0; + } + + if (a->height != b->height) + { + return 0; + } + + return 1; +} + +static inline VkFramebuffer FramebufferHashArray_Fetch( + FramebufferHashArray *arr, + FramebufferHash *key +) { + int32_t i; + + for (i = 0; i < arr->count; i += 1) + { + FramebufferHash *e = &arr->elements[i].key; + if (FramebufferHash_Compare(e, key)) + { + return arr->elements[i].value; + } + } + + return VK_NULL_HANDLE; +} + +static inline void FramebufferHashArray_Insert( + FramebufferHashArray *arr, + FramebufferHash key, + VkFramebuffer value +) { + FramebufferHashMap map; + map.key = key; + map.value = value; + + EXPAND_ELEMENTS_IF_NEEDED(arr, 4, FramebufferHashMap) + + arr->elements[arr->count] = map; + arr->count += 1; +} + +static inline void FramebufferHashArray_Remove( + FramebufferHashArray *arr, + uint32_t index +) { + if (index != arr->count - 1) + { + arr->elements[index] = arr->elements[arr->count - 1]; + } + + arr->count -= 1; +} + /* Descriptor Set Caches */ struct DescriptorSetCache @@ -1424,6 +1534,7 @@ typedef struct VulkanRenderer GraphicsPipelineLayoutHashTable graphicsPipelineLayoutHashTable; ComputePipelineLayoutHashTable computePipelineLayoutHashTable; RenderPassHashArray renderPassHashArray; + FramebufferHashArray framebufferHashArray; VkDescriptorPool defaultDescriptorPool; @@ -1454,6 +1565,8 @@ typedef struct VulkanRenderer SDL_mutex *submitLock; SDL_mutex *acquireFenceLock; SDL_mutex *acquireCommandBufferLock; + SDL_mutex *renderPassFetchLock; + SDL_mutex *framebufferFetchLock; #define VULKAN_INSTANCE_FUNCTION(ext, ret, func, params) \ vkfntype_##func func; @@ -2419,11 +2532,43 @@ static void VULKAN_INTERNAL_DestroyTexture( static void VULKAN_INTERNAL_DestroyRenderTarget( VulkanRenderer *renderer, - VulkanRenderTarget *renderTargetTarget + VulkanRenderTarget *renderTarget ) { + int32_t i, j; + FramebufferHash *hash; + + SDL_LockMutex(renderer->framebufferFetchLock); + + /* Remove all associated framebuffers */ + for (i = renderer->framebufferHashArray.count; i >= 0; i -= 1) + { + hash = &renderer->framebufferHashArray.elements[i].key; + + for (j = 0; j < hash->colorAttachmentCount; j += 1) + { + if (hash->colorAttachmentViews[i] == renderTarget->view) + { + renderer->vkDestroyFramebuffer( + renderer->logicalDevice, + renderer->framebufferHashArray.elements[i].value, + NULL + ); + + FramebufferHashArray_Remove( + &renderer->framebufferHashArray, + i + ); + + break; + } + } + } + + SDL_UnlockMutex(renderer->framebufferFetchLock); + renderer->vkDestroyImageView( renderer->logicalDevice, - renderTargetTarget->view, + renderTarget->view, NULL ); @@ -2431,15 +2576,15 @@ static void VULKAN_INTERNAL_DestroyRenderTarget( * so we don't free it here * But the multisampleTexture is! */ - if (renderTargetTarget->multisampleTexture != NULL) + if (renderTarget->multisampleTexture != NULL) { VULKAN_INTERNAL_DestroyTexture( renderer, - renderTargetTarget->multisampleTexture + renderTarget->multisampleTexture ); } - SDL_free(renderTargetTarget); + SDL_free(renderTarget); } static void VULKAN_INTERNAL_DestroyBuffer( @@ -2563,17 +2708,6 @@ static void VULKAN_INTERNAL_DestroySampler( ); } -static void VULKAN_INTERNAL_DestroyRenderPass( - VulkanRenderer *renderer, - VkRenderPass renderPass -) { - renderer->vkDestroyRenderPass( - renderer->logicalDevice, - renderPass, - NULL - ); -} - static void VULKAN_INTERNAL_DestroySwapchain( VulkanRenderer* renderer, void *windowHandle @@ -4286,6 +4420,8 @@ static void VULKAN_DestroyDevice( SDL_DestroyMutex(renderer->submitLock); SDL_DestroyMutex(renderer->acquireFenceLock); SDL_DestroyMutex(renderer->acquireCommandBufferLock); + SDL_DestroyMutex(renderer->renderPassFetchLock); + SDL_DestroyMutex(renderer->framebufferFetchLock); renderer->vkDestroyDevice(renderer->logicalDevice, NULL); renderer->vkDestroyInstance(renderer->instance, NULL); @@ -4531,9 +4667,7 @@ static void VULKAN_DispatchCompute( VulkanCommandBuffer *vulkanCommandBuffer = (VulkanCommandBuffer*) commandBuffer; VulkanComputePipeline *computePipeline = vulkanCommandBuffer->currentComputePipeline; - VulkanBuffer *currentBuffer; VkDescriptorSet descriptorSets[3]; - uint32_t i; descriptorSets[0] = vulkanCommandBuffer->bufferDescriptorSet; descriptorSets[1] = vulkanCommandBuffer->imageDescriptorSet; @@ -4560,7 +4694,7 @@ static void VULKAN_DispatchCompute( static VkRenderPass VULKAN_INTERNAL_CreateRenderPass( VulkanRenderer *renderer, - Refresh_ColorAttachmentInfo *pColorAttachmentInfos, + Refresh_ColorAttachmentInfo *colorAttachmentInfos, uint32_t colorAttachmentCount, Refresh_DepthStencilAttachmentInfo *depthStencilAttachmentInfo ) { @@ -4569,7 +4703,7 @@ static VkRenderPass VULKAN_INTERNAL_CreateRenderPass( VkAttachmentReference colorAttachmentReferences[MAX_COLOR_TARGET_BINDINGS]; VkAttachmentReference resolveReferences[MAX_COLOR_TARGET_BINDINGS + 1]; VkAttachmentReference depthStencilAttachmentReference; - VkRenderPassCreateInfo vkRenderPassCreateInfo; + VkRenderPassCreateInfo renderPassCreateInfo; VkSubpassDescription subpass; VkRenderPass renderPass; uint32_t i; @@ -4584,7 +4718,7 @@ static VkRenderPass VULKAN_INTERNAL_CreateRenderPass( for (i = 0; i < colorAttachmentCount; i += 1) { - colorTarget = (VulkanRenderTarget*) pColorAttachmentInfos[attachmentDescriptionCount].pRenderTarget; + colorTarget = (VulkanRenderTarget*) colorAttachmentInfos[attachmentDescriptionCount].pRenderTarget; if (colorTarget->multisampleCount > VK_SAMPLE_COUNT_1_BIT) { @@ -4597,10 +4731,10 @@ static VkRenderPass VULKAN_INTERNAL_CreateRenderPass( attachmentDescriptions[attachmentDescriptionCount].samples = VK_SAMPLE_COUNT_1_BIT; attachmentDescriptions[attachmentDescriptionCount].loadOp = RefreshToVK_LoadOp[ - pColorAttachmentInfos[i].loadOp + colorAttachmentInfos[i].loadOp ]; attachmentDescriptions[attachmentDescriptionCount].storeOp = RefreshToVK_StoreOp[ - pColorAttachmentInfos[i].storeOp + colorAttachmentInfos[i].storeOp ]; attachmentDescriptions[attachmentDescriptionCount].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; @@ -4623,10 +4757,10 @@ static VkRenderPass VULKAN_INTERNAL_CreateRenderPass( attachmentDescriptions[attachmentDescriptionCount].format = colorTarget->texture->format; attachmentDescriptions[attachmentDescriptionCount].samples = colorTarget->multisampleCount; attachmentDescriptions[attachmentDescriptionCount].loadOp = RefreshToVK_LoadOp[ - pColorAttachmentInfos[i].loadOp + colorAttachmentInfos[i].loadOp ]; attachmentDescriptions[attachmentDescriptionCount].storeOp = RefreshToVK_StoreOp[ - pColorAttachmentInfos[i].storeOp + colorAttachmentInfos[i].storeOp ]; attachmentDescriptions[attachmentDescriptionCount].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; @@ -4652,10 +4786,10 @@ static VkRenderPass VULKAN_INTERNAL_CreateRenderPass( attachmentDescriptions[attachmentDescriptionCount].samples = VK_SAMPLE_COUNT_1_BIT; attachmentDescriptions[attachmentDescriptionCount].loadOp = RefreshToVK_LoadOp[ - pColorAttachmentInfos[i].loadOp + colorAttachmentInfos[i].loadOp ]; attachmentDescriptions[attachmentDescriptionCount].storeOp = RefreshToVK_StoreOp[ - pColorAttachmentInfos[i].storeOp + colorAttachmentInfos[i].storeOp ]; attachmentDescriptions[attachmentDescriptionCount].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; @@ -4666,12 +4800,12 @@ static VkRenderPass VULKAN_INTERNAL_CreateRenderPass( attachmentDescriptions[attachmentDescriptionCount].finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; - attachmentDescriptionCount += 1; - colorAttachmentReferences[colorAttachmentReferenceCount].attachment = i; + colorAttachmentReferences[colorAttachmentReferenceCount].attachment = attachmentDescriptionCount; colorAttachmentReferences[colorAttachmentReferenceCount].layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; + attachmentDescriptionCount += 1; colorAttachmentReferenceCount += 1; } } @@ -4733,32 +4867,207 @@ static VkRenderPass VULKAN_INTERNAL_CreateRenderPass( subpass.pResolveAttachments = NULL; } - vkRenderPassCreateInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO; - vkRenderPassCreateInfo.pNext = NULL; - vkRenderPassCreateInfo.flags = 0; - vkRenderPassCreateInfo.pAttachments = attachmentDescriptions; - vkRenderPassCreateInfo.attachmentCount = attachmentDescriptionCount; - vkRenderPassCreateInfo.subpassCount = 1; - vkRenderPassCreateInfo.pSubpasses = &subpass; - vkRenderPassCreateInfo.dependencyCount = 0; - vkRenderPassCreateInfo.pDependencies = NULL; + renderPassCreateInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO; + renderPassCreateInfo.pNext = NULL; + renderPassCreateInfo.flags = 0; + renderPassCreateInfo.pAttachments = attachmentDescriptions; + renderPassCreateInfo.attachmentCount = attachmentDescriptionCount; + renderPassCreateInfo.subpassCount = 1; + renderPassCreateInfo.pSubpasses = &subpass; + renderPassCreateInfo.dependencyCount = 0; + renderPassCreateInfo.pDependencies = NULL; vulkanResult = renderer->vkCreateRenderPass( renderer->logicalDevice, - &vkRenderPassCreateInfo, + &renderPassCreateInfo, NULL, &renderPass ); if (vulkanResult != VK_SUCCESS) { + renderPass = VK_NULL_HANDLE; LogVulkanResultAsError("vkCreateRenderPass", vulkanResult); - return VK_NULL_HANDLE; } return renderPass; } +static VkRenderPass VULKAN_INTERNAL_CreateTransientRenderPass( + VulkanRenderer *renderer, + Refresh_GraphicsPipelineAttachmentInfo attachmentInfo +) { + VkAttachmentDescription attachmentDescriptions[2 * MAX_COLOR_TARGET_BINDINGS + 1]; + VkAttachmentReference colorAttachmentReferences[MAX_COLOR_TARGET_BINDINGS]; + VkAttachmentReference resolveReferences[MAX_COLOR_TARGET_BINDINGS + 1]; + VkAttachmentReference depthStencilAttachmentReference; + Refresh_ColorAttachmentDescription attachmentDescription; + VkSubpassDescription subpass; + VkRenderPassCreateInfo renderPassCreateInfo; + VkRenderPass renderPass; + VkResult result; + + uint32_t multisampling = 0; + uint32_t attachmentDescriptionCount = 0; + uint32_t colorAttachmentReferenceCount = 0; + uint32_t resolveReferenceCount = 0; + uint32_t i; + + for (i = 0; i < attachmentInfo.colorAttachmentCount; i += 1) + { + attachmentDescription = attachmentInfo.colorAttachmentDescriptions[i]; + + if (attachmentDescription.sampleCount > REFRESH_SAMPLECOUNT_1) + { + multisampling = 1; + + /* Resolve attachment and multisample attachment */ + + attachmentDescriptions[attachmentDescriptionCount].flags = 0; + attachmentDescriptions[attachmentDescriptionCount].format = RefreshToVK_SurfaceFormat[ + attachmentDescription.format + ]; + attachmentDescriptions[attachmentDescriptionCount].samples = VK_SAMPLE_COUNT_1_BIT; + attachmentDescriptions[attachmentDescriptionCount].loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; + attachmentDescriptions[attachmentDescriptionCount].storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; + attachmentDescriptions[attachmentDescriptionCount].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; + attachmentDescriptions[attachmentDescriptionCount].stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; + attachmentDescriptions[attachmentDescriptionCount].initialLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; + attachmentDescriptions[attachmentDescriptionCount].finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; + + resolveReferences[resolveReferenceCount].attachment = attachmentDescriptionCount; + resolveReferences[resolveReferenceCount].layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; + + attachmentDescriptionCount += 1; + resolveReferenceCount += 1; + + attachmentDescriptions[attachmentDescriptionCount].flags = 0; + attachmentDescriptions[attachmentDescriptionCount].format = RefreshToVK_SurfaceFormat[ + attachmentDescription.format + ]; + attachmentDescriptions[attachmentDescriptionCount].samples = VK_SAMPLE_COUNT_1_BIT; + attachmentDescriptions[attachmentDescriptionCount].loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; + attachmentDescriptions[attachmentDescriptionCount].storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; + attachmentDescriptions[attachmentDescriptionCount].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; + attachmentDescriptions[attachmentDescriptionCount].stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; + attachmentDescriptions[attachmentDescriptionCount].initialLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; + attachmentDescriptions[attachmentDescriptionCount].finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; + + colorAttachmentReferences[colorAttachmentReferenceCount].attachment = + attachmentDescriptionCount; + colorAttachmentReferences[colorAttachmentReferenceCount].layout = + VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; + + attachmentDescriptionCount += 1; + colorAttachmentReferenceCount += 1; + } + else + { + attachmentDescriptions[attachmentDescriptionCount].flags = 0; + attachmentDescriptions[attachmentDescriptionCount].format = RefreshToVK_SurfaceFormat[ + attachmentDescription.format + ]; + attachmentDescriptions[attachmentDescriptionCount].samples = + VK_SAMPLE_COUNT_1_BIT; + attachmentDescriptions[attachmentDescriptionCount].loadOp = + VK_ATTACHMENT_LOAD_OP_DONT_CARE; + attachmentDescriptions[attachmentDescriptionCount].storeOp = + VK_ATTACHMENT_STORE_OP_DONT_CARE; + attachmentDescriptions[attachmentDescriptionCount].stencilLoadOp = + VK_ATTACHMENT_LOAD_OP_DONT_CARE; + attachmentDescriptions[attachmentDescriptionCount].stencilStoreOp = + VK_ATTACHMENT_STORE_OP_DONT_CARE; + attachmentDescriptions[attachmentDescriptionCount].initialLayout = + VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; + attachmentDescriptions[attachmentDescriptionCount].finalLayout = + VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; + + + colorAttachmentReferences[colorAttachmentReferenceCount].attachment = attachmentDescriptionCount; + colorAttachmentReferences[colorAttachmentReferenceCount].layout = + VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; + + attachmentDescriptionCount += 1; + colorAttachmentReferenceCount += 1; + } + } + + subpass.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS; + subpass.flags = 0; + subpass.inputAttachmentCount = 0; + subpass.pInputAttachments = NULL; + subpass.colorAttachmentCount = attachmentInfo.colorAttachmentCount; + subpass.pColorAttachments = colorAttachmentReferences; + subpass.preserveAttachmentCount = 0; + subpass.pPreserveAttachments = NULL; + + if (attachmentInfo.hasDepthStencilAttachment) + { + attachmentDescriptions[attachmentDescriptionCount].flags = 0; + attachmentDescriptions[attachmentDescriptionCount].format = RefreshToVK_SurfaceFormat[ + attachmentInfo.depthStencilFormat + ]; + attachmentDescriptions[attachmentDescriptionCount].samples = + VK_SAMPLE_COUNT_1_BIT; /* FIXME: do these take multisamples? */ + attachmentDescriptions[attachmentDescriptionCount].loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; + attachmentDescriptions[attachmentDescriptionCount].storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; + attachmentDescriptions[attachmentDescriptionCount].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; + attachmentDescriptions[attachmentDescriptionCount].stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; + attachmentDescriptions[attachmentDescriptionCount].initialLayout = + VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; + attachmentDescriptions[attachmentDescriptionCount].finalLayout = + VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; + + depthStencilAttachmentReference.attachment = + attachmentDescriptionCount; + depthStencilAttachmentReference.layout = + VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; + + subpass.pDepthStencilAttachment = + &depthStencilAttachmentReference; + + attachmentDescriptionCount += 1; + } + else + { + subpass.pDepthStencilAttachment = NULL; + } + + if (multisampling) + { + subpass.pResolveAttachments = resolveReferences; + } + else + { + subpass.pResolveAttachments = NULL; + } + + renderPassCreateInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO; + renderPassCreateInfo.pNext = NULL; + renderPassCreateInfo.flags = 0; + renderPassCreateInfo.pAttachments = attachmentDescriptions; + renderPassCreateInfo.attachmentCount = attachmentDescriptionCount; + renderPassCreateInfo.subpassCount = 1; + renderPassCreateInfo.pSubpasses = &subpass; + renderPassCreateInfo.dependencyCount = 0; + renderPassCreateInfo.pDependencies = NULL; + + result = renderer->vkCreateRenderPass( + renderer->logicalDevice, + &renderPassCreateInfo, + NULL, + &renderPass + ); + + if (result != VK_SUCCESS) + { + renderPass = VK_NULL_HANDLE; + LogVulkanResultAsError("vkCreateRenderPass", result); + } + + return renderPass; +} + static Refresh_GraphicsPipeline* VULKAN_CreateGraphicsPipeline( Refresh_Renderer *driverData, Refresh_GraphicsPipelineCreateInfo *pipelineCreateInfo @@ -4797,6 +5106,13 @@ static Refresh_GraphicsPipeline* VULKAN_CreateGraphicsPipeline( VulkanRenderer *renderer = (VulkanRenderer*) driverData; + /* Create a "compatible" render pass */ + + VkRenderPass transientRenderPass = VULKAN_INTERNAL_CreateTransientRenderPass( + renderer, + pipelineCreateInfo->attachmentInfo + ); + /* Shader stages */ shaderStageCreateInfos[0].sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; @@ -5074,7 +5390,7 @@ static Refresh_GraphicsPipeline* VULKAN_CreateGraphicsPipeline( vkPipelineCreateInfo.pColorBlendState = &colorBlendStateCreateInfo; vkPipelineCreateInfo.pDynamicState = VK_NULL_HANDLE; vkPipelineCreateInfo.layout = graphicsPipeline->pipelineLayout->pipelineLayout; - vkPipelineCreateInfo.renderPass = (VkRenderPass) pipelineCreateInfo->renderPass; + vkPipelineCreateInfo.renderPass = transientRenderPass; vkPipelineCreateInfo.subpass = 0; vkPipelineCreateInfo.basePipelineHandle = VK_NULL_HANDLE; vkPipelineCreateInfo.basePipelineIndex = 0; @@ -5095,6 +5411,12 @@ static Refresh_GraphicsPipeline* VULKAN_CreateGraphicsPipeline( SDL_stack_free(scissors); SDL_stack_free(colorBlendAttachmentStates); + renderer->vkDestroyRenderPass( + renderer->logicalDevice, + transientRenderPass, + NULL + ); + if (vulkanResult != VK_SUCCESS) { LogVulkanResultAsError("vkCreateGraphicsPipelines", vulkanResult); @@ -5325,71 +5647,6 @@ static Refresh_Sampler* VULKAN_CreateSampler( return (Refresh_Sampler*) sampler; } -static VkFramebuffer VULKAN_INTERNAL_CreateFramebuffer( - Refresh_Renderer *driverData, - VkRenderPass renderPass, - uint32_t width, - uint32_t height, - VulkanRenderTarget **colorTargets, - uint32_t colorTargetCount, - VulkanRenderTarget *depthStencilTarget /* Can be NULL */ -) { - VkResult vulkanResult; - VkFramebuffer framebuffer; - VkFramebufferCreateInfo vkFramebufferCreateInfo; - - VkImageView *imageViews; - uint32_t colorAttachmentCount = colorTargetCount; - uint32_t attachmentCount = colorAttachmentCount; - uint32_t i; - - VulkanRenderer *renderer = (VulkanRenderer*) driverData; - - if (depthStencilTarget != NULL) - { - attachmentCount += 1; - } - - imageViews = SDL_stack_alloc(VkImageView, attachmentCount); - - for (i = 0; i < colorAttachmentCount; i += 1) - { - imageViews[i] = ((VulkanRenderTarget*)colorTargets[i])->view; - } - - if (depthStencilTarget != NULL) - { - imageViews[colorAttachmentCount] = ((VulkanRenderTarget*)depthStencilTarget)->view; - } - - vkFramebufferCreateInfo.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO; - vkFramebufferCreateInfo.pNext = NULL; - vkFramebufferCreateInfo.flags = 0; - vkFramebufferCreateInfo.renderPass = renderPass; - vkFramebufferCreateInfo.attachmentCount = attachmentCount; - vkFramebufferCreateInfo.pAttachments = imageViews; - vkFramebufferCreateInfo.width = width; - vkFramebufferCreateInfo.height = height; - vkFramebufferCreateInfo.layers = 1; - - vulkanResult = renderer->vkCreateFramebuffer( - renderer->logicalDevice, - &vkFramebufferCreateInfo, - NULL, - &framebuffer - ); - - SDL_stack_free(imageViews); - - if (vulkanResult != VK_SUCCESS) - { - LogVulkanResultAsError("vkCreateFramebuffer", vulkanResult); - return VK_NULL_HANDLE; - } - - return framebuffer; -} - static Refresh_ShaderModule* VULKAN_CreateShaderModule( Refresh_Renderer *driverData, Refresh_ShaderModuleCreateInfo *shaderModuleCreateInfo @@ -7072,7 +7329,7 @@ static void VULKAN_QueueDestroyGraphicsPipeline( static VkRenderPass VULKAN_INTERNAL_FetchRenderPass( VulkanRenderer *renderer, - Refresh_ColorAttachmentInfo *pColorAttachmentInfos, + Refresh_ColorAttachmentInfo *colorAttachmentInfos, uint32_t colorAttachmentCount, Refresh_DepthStencilAttachmentInfo *depthStencilAttachmentInfo ) { @@ -7080,11 +7337,13 @@ static VkRenderPass VULKAN_INTERNAL_FetchRenderPass( RenderPassHash hash; uint32_t i; + SDL_LockMutex(renderer->renderPassFetchLock); + for (i = 0; i < colorAttachmentCount; i += 1) { - hash.colorTargetDescriptions[i].clearColor = pColorAttachmentInfos[i].clearColor; - hash.colorTargetDescriptions[i].loadOp = pColorAttachmentInfos[i].loadOp; - hash.colorTargetDescriptions[i].storeOp = pColorAttachmentInfos[i].storeOp; + hash.colorTargetDescriptions[i].clearColor = colorAttachmentInfos[i].clearColor; + hash.colorTargetDescriptions[i].loadOp = colorAttachmentInfos[i].loadOp; + hash.colorTargetDescriptions[i].storeOp = colorAttachmentInfos[i].storeOp; } if (depthStencilAttachmentInfo == NULL) @@ -7109,30 +7368,170 @@ static VkRenderPass VULKAN_INTERNAL_FetchRenderPass( if (renderPass != VK_NULL_HANDLE) { + SDL_UnlockMutex(renderer->renderPassFetchLock); return renderPass; } renderPass = VULKAN_INTERNAL_CreateRenderPass( renderer, - pColorAttachmentInfos, + colorAttachmentInfos, colorAttachmentCount, depthStencilAttachmentInfo ); - RenderPassHashArray_Insert( - &renderer->renderPassHashArray, - hash, - renderPass + if (renderPass != VK_NULL_HANDLE) + { + RenderPassHashArray_Insert( + &renderer->renderPassHashArray, + hash, + renderPass + ); + } + + SDL_UnlockMutex(renderer->renderPassFetchLock); + return renderPass; +} + +static VkFramebuffer VULKAN_INTERNAL_FetchFramebuffer( + VulkanRenderer *renderer, + VkRenderPass renderPass, + Refresh_ColorAttachmentInfo *colorAttachmentInfos, + uint32_t colorAttachmentCount, + Refresh_DepthStencilAttachmentInfo *depthStencilAttachmentInfo +) { + VkFramebuffer framebuffer; + VkFramebufferCreateInfo framebufferInfo; + VkResult result; + VkImageView imageViewAttachments[2 * MAX_COLOR_TARGET_BINDINGS + 1]; + FramebufferHash hash; + VulkanRenderTarget *renderTarget; + uint32_t attachmentCount = 0; + uint32_t i; + + SDL_LockMutex(renderer->framebufferFetchLock); + + for (i = 0; i < MAX_COLOR_TARGET_BINDINGS; i += 1) + { + hash.colorAttachmentViews[i] = VK_NULL_HANDLE; + hash.colorMultiSampleAttachmentViews[i] = VK_NULL_HANDLE; + } + + hash.colorAttachmentCount = colorAttachmentCount; + + for (i = 0; i < colorAttachmentCount; i += 1) + { + renderTarget = (VulkanRenderTarget*) colorAttachmentInfos[i].pRenderTarget; + + hash.colorAttachmentViews[i] = ( + renderTarget->view + ); + + hash.colorMultiSampleAttachmentViews[i] = ( + renderTarget->multisampleTexture->view + ); + } + + if (depthStencilAttachmentInfo == NULL) + { + hash.depthStencilAttachmentView = VK_NULL_HANDLE; + } + else + { + hash.depthStencilAttachmentView = ((VulkanRenderTarget*)depthStencilAttachmentInfo->pDepthStencilTarget)->view; + } + + if (colorAttachmentCount > 0) + { + renderTarget = (VulkanRenderTarget*) colorAttachmentInfos[0].pRenderTarget; + } + else + { + renderTarget = (VulkanRenderTarget*) depthStencilAttachmentInfo->pDepthStencilTarget; + } + + hash.width = renderTarget->texture->dimensions.width; + hash.height = renderTarget->texture->dimensions.height; + + framebuffer = FramebufferHashArray_Fetch( + &renderer->framebufferHashArray, + &hash ); - return renderPass; + if (framebuffer != VK_NULL_HANDLE) + { + SDL_UnlockMutex(renderer->framebufferFetchLock); + return framebuffer; + } + + /* Create a new framebuffer */ + + for (i = 0; i < colorAttachmentCount; i += 1) + { + renderTarget = (VulkanRenderTarget*) colorAttachmentInfos[i].pRenderTarget; + + imageViewAttachments[attachmentCount] = + renderTarget->view; + + attachmentCount += 1; + + if (renderTarget->multisampleCount > VK_SAMPLE_COUNT_1_BIT) + { + imageViewAttachments[attachmentCount] = + renderTarget->multisampleTexture->view; + + attachmentCount += 1; + } + } + + if (depthStencilAttachmentInfo != NULL) + { + renderTarget = (VulkanRenderTarget*) depthStencilAttachmentInfo->pDepthStencilTarget; + + imageViewAttachments[attachmentCount] = renderTarget->view; + + attachmentCount += 1; + } + + framebufferInfo.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO; + framebufferInfo.pNext = NULL; + framebufferInfo.flags = 0; + framebufferInfo.renderPass = renderPass; + framebufferInfo.attachmentCount = attachmentCount; + framebufferInfo.pAttachments = imageViewAttachments; + framebufferInfo.width = hash.width; + framebufferInfo.height = hash.height; + framebufferInfo.layers = 1; + + result = renderer->vkCreateFramebuffer( + renderer->logicalDevice, + &framebufferInfo, + NULL, + &framebuffer + ); + + if (result == VK_SUCCESS) + { + FramebufferHashArray_Insert( + &renderer->framebufferHashArray, + hash, + framebuffer + ); + } + else + { + LogVulkanResultAsError("vkCreateFramebuffer", result); + framebuffer = VK_NULL_HANDLE; + } + + SDL_UnlockMutex(renderer->framebufferFetchLock); + return framebuffer; } static void VULKAN_BeginRenderPass( Refresh_Renderer *driverData, Refresh_CommandBuffer *commandBuffer, Refresh_Rect *renderArea, - Refresh_ColorAttachmentInfo *pColorAttachmentInfos, + Refresh_ColorAttachmentInfo *colorAttachmentInfos, uint32_t colorAttachmentCount, Refresh_DepthStencilAttachmentInfo *depthStencilAttachmentInfo ) { @@ -7141,27 +7540,38 @@ static void VULKAN_BeginRenderPass( VkRenderPass renderPass; VkFramebuffer framebuffer; - VulkanRenderTarget *colorTarget; VulkanRenderTarget *depthStencilTarget; VkClearValue *clearValues; uint32_t clearCount = colorAttachmentCount; uint32_t i; VkImageAspectFlags depthAspectFlags; + if (colorAttachmentCount == 0 && depthStencilAttachmentInfo == NULL) + { + Refresh_LogError("Render pass must have at least one render target!"); + return; + } + renderPass = VULKAN_INTERNAL_FetchRenderPass( renderer, - pColorAttachmentInfos, + colorAttachmentInfos, colorAttachmentCount, depthStencilAttachmentInfo ); - framebuffer = VULKAN_INTERNAL_FetchFramebuffer(renderer); + framebuffer = VULKAN_INTERNAL_FetchFramebuffer( + renderer, + renderPass, + colorAttachmentInfos, + colorAttachmentCount, + depthStencilAttachmentInfo + ); /* Layout transitions */ for (i = 0; i < colorAttachmentCount; i += 1) { - VulkanRenderTarget *colorTarget = (VulkanRenderTarget*) pColorAttachmentInfos->pRenderTarget; + VulkanRenderTarget *colorTarget = (VulkanRenderTarget*) colorAttachmentInfos->pRenderTarget; VULKAN_INTERNAL_ImageMemoryBarrier( renderer, @@ -7212,10 +7622,10 @@ static void VULKAN_BeginRenderPass( for (i = 0; i < colorAttachmentCount; i += 1) { - clearValues[i].color.float32[0] = pColorAttachmentInfos[i].clearColor.x; - clearValues[i].color.float32[1] = pColorAttachmentInfos[i].clearColor.y; - clearValues[i].color.float32[2] = pColorAttachmentInfos[i].clearColor.z; - clearValues[i].color.float32[3] = pColorAttachmentInfos[i].clearColor.w; + clearValues[i].color.float32[0] = colorAttachmentInfos[i].clearColor.x; + clearValues[i].color.float32[1] = colorAttachmentInfos[i].clearColor.y; + clearValues[i].color.float32[2] = colorAttachmentInfos[i].clearColor.z; + clearValues[i].color.float32[3] = colorAttachmentInfos[i].clearColor.w; } if (depthStencilAttachmentInfo != NULL) @@ -7255,9 +7665,6 @@ static void VULKAN_EndRenderPass( ) { VulkanRenderer* renderer = (VulkanRenderer*) driverData; VulkanCommandBuffer *vulkanCommandBuffer = (VulkanCommandBuffer*) commandBuffer; - VulkanTexture *currentTexture; - VkImageAspectFlags depthAspectFlags; - uint32_t i; renderer->vkCmdEndRenderPass( vulkanCommandBuffer->commandBuffer @@ -7797,7 +8204,6 @@ static Refresh_CommandBuffer* VULKAN_AcquireCommandBuffer( uint8_t fixed ) { VulkanRenderer *renderer = (VulkanRenderer*) driverData; - uint32_t i; SDL_threadID threadID = SDL_ThreadID(); @@ -9245,6 +9651,8 @@ static Refresh_Device* VULKAN_CreateDevice( renderer->submitLock = SDL_CreateMutex(); renderer->acquireFenceLock = SDL_CreateMutex(); renderer->acquireCommandBufferLock = SDL_CreateMutex(); + renderer->renderPassFetchLock = SDL_CreateMutex(); + renderer->framebufferFetchLock = SDL_CreateMutex(); /* Create fence lists */ @@ -9552,6 +9960,14 @@ static Refresh_Device* VULKAN_CreateDevice( renderer->descriptorSetLayoutHashTable.buckets[i].capacity = 0; } + renderer->renderPassHashArray.elements = NULL; + renderer->renderPassHashArray.count = 0; + renderer->renderPassHashArray.capacity = 0; + + renderer->framebufferHashArray.elements = NULL; + renderer->framebufferHashArray.count = 0; + renderer->framebufferHashArray.capacity = 0; + /* Initialize transfer buffer pool */ renderer->transferBufferPool.lock = SDL_CreateMutex(); -- 2.25.1 From 3fcc9405861db8861c22465ac3a04ccb32a96e7f Mon Sep 17 00:00:00 2001 From: cosmonaut Date: Thu, 24 Feb 2022 12:04:41 -0800 Subject: [PATCH 3/8] destroy render passes and framebuffers on exit --- src/Refresh_Driver_Vulkan.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/src/Refresh_Driver_Vulkan.c b/src/Refresh_Driver_Vulkan.c index 08124ee..139720f 100644 --- a/src/Refresh_Driver_Vulkan.c +++ b/src/Refresh_Driver_Vulkan.c @@ -4376,6 +4376,28 @@ static void VULKAN_DestroyDevice( NULL ); + for (i = 0; i < renderer->framebufferHashArray.count; i += 1) + { + renderer->vkDestroyFramebuffer( + renderer->logicalDevice, + renderer->framebufferHashArray.elements[i].value, + NULL + ); + } + + SDL_free(renderer->framebufferHashArray.elements); + + for (i = 0; i < renderer->renderPassHashArray.count; i += 1) + { + renderer->vkDestroyRenderPass( + renderer->logicalDevice, + renderer->renderPassHashArray.elements[i].value, + NULL + ); + } + + SDL_free(renderer->renderPassHashArray.elements); + VULKAN_INTERNAL_DestroyUniformBufferPool(renderer, renderer->vertexUniformBufferPool); VULKAN_INTERNAL_DestroyUniformBufferPool(renderer, renderer->fragmentUniformBufferPool); VULKAN_INTERNAL_DestroyUniformBufferPool(renderer, renderer->computeUniformBufferPool); -- 2.25.1 From 2db60e5ab009f11b3b63616d88c2fc54c1f28b1c Mon Sep 17 00:00:00 2001 From: cosmonaut Date: Thu, 24 Feb 2022 12:38:18 -0800 Subject: [PATCH 4/8] fix null reference --- src/Refresh_Driver_Vulkan.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/Refresh_Driver_Vulkan.c b/src/Refresh_Driver_Vulkan.c index 139720f..8c95633 100644 --- a/src/Refresh_Driver_Vulkan.c +++ b/src/Refresh_Driver_Vulkan.c @@ -7448,9 +7448,12 @@ static VkFramebuffer VULKAN_INTERNAL_FetchFramebuffer( renderTarget->view ); - hash.colorMultiSampleAttachmentViews[i] = ( - renderTarget->multisampleTexture->view - ); + if (renderTarget->multisampleTexture != NULL) + { + hash.colorMultiSampleAttachmentViews[i] = ( + renderTarget->multisampleTexture->view + ); + } } if (depthStencilAttachmentInfo == NULL) @@ -7496,7 +7499,7 @@ static VkFramebuffer VULKAN_INTERNAL_FetchFramebuffer( attachmentCount += 1; - if (renderTarget->multisampleCount > VK_SAMPLE_COUNT_1_BIT) + if (renderTarget->multisampleTexture != NULL) { imageViewAttachments[attachmentCount] = renderTarget->multisampleTexture->view; -- 2.25.1 From 3741a95cb3d03a914a541ec7e2431b353b8ec9dd Mon Sep 17 00:00:00 2001 From: cosmonaut Date: Thu, 24 Feb 2022 13:02:05 -0800 Subject: [PATCH 5/8] partially revert memory barrier change --- src/Refresh_Driver_Vulkan.c | 68 +++++++++++++++++++++---------------- 1 file changed, 39 insertions(+), 29 deletions(-) diff --git a/src/Refresh_Driver_Vulkan.c b/src/Refresh_Driver_Vulkan.c index 8c95633..c78d6f5 100644 --- a/src/Refresh_Driver_Vulkan.c +++ b/src/Refresh_Driver_Vulkan.c @@ -1356,6 +1356,9 @@ typedef struct VulkanCommandBuffer VulkanComputePipeline *currentComputePipeline; VulkanGraphicsPipeline *currentGraphicsPipeline; + VulkanRenderTarget *renderPassColorTargets[MAX_COLOR_TARGET_BINDINGS]; + uint32_t renderPassColorTargetCount; + VulkanUniformBuffer *vertexUniformBuffer; VulkanUniformBuffer *fragmentUniformBuffer; VulkanUniformBuffer *computeUniformBuffer; @@ -7034,20 +7037,6 @@ static void VULKAN_BindVertexSamplers( descriptorImageInfos[i].imageView = currentTexture->view; descriptorImageInfos[i].sampler = (VkSampler) pSamplers[i]; descriptorImageInfos[i].imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; - - VULKAN_INTERNAL_ImageMemoryBarrier( - renderer, - vulkanCommandBuffer->commandBuffer, - RESOURCE_ACCESS_VERTEX_SHADER_READ_SAMPLED_IMAGE, - VK_IMAGE_ASPECT_COLOR_BIT, - 0, - currentTexture->layerCount, - 0, - currentTexture->levelCount, - 0, - currentTexture->image, - ¤tTexture->resourceAccessType - ); } vulkanCommandBuffer->vertexSamplerDescriptorSet = VULKAN_INTERNAL_FetchDescriptorSet( @@ -7086,20 +7075,6 @@ static void VULKAN_BindFragmentSamplers( descriptorImageInfos[i].imageView = currentTexture->view; descriptorImageInfos[i].sampler = (VkSampler) pSamplers[i]; descriptorImageInfos[i].imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; - - VULKAN_INTERNAL_ImageMemoryBarrier( - renderer, - vulkanCommandBuffer->commandBuffer, - RESOURCE_ACCESS_FRAGMENT_SHADER_READ_SAMPLED_IMAGE, - VK_IMAGE_ASPECT_COLOR_BIT, - 0, - currentTexture->layerCount, - 0, - currentTexture->levelCount, - 0, - currentTexture->image, - ¤tTexture->resourceAccessType - ); } vulkanCommandBuffer->fragmentSamplerDescriptorSet = VULKAN_INTERNAL_FetchDescriptorSet( @@ -7682,6 +7657,13 @@ static void VULKAN_BeginRenderPass( vulkanCommandBuffer->renderPassInProgress = 1; SDL_stack_free(clearValues); + + for (i = 0; i < colorAttachmentCount; i += 1) + { + vulkanCommandBuffer->renderPassColorTargets[i] = + (VulkanRenderTarget*) colorAttachmentInfos[i].pRenderTarget; + } + vulkanCommandBuffer->renderPassColorTargetCount = colorAttachmentCount; } static void VULKAN_EndRenderPass( @@ -7690,6 +7672,8 @@ static void VULKAN_EndRenderPass( ) { VulkanRenderer* renderer = (VulkanRenderer*) driverData; VulkanCommandBuffer *vulkanCommandBuffer = (VulkanCommandBuffer*) commandBuffer; + VulkanTexture *currentTexture; + uint32_t i; renderer->vkCmdEndRenderPass( vulkanCommandBuffer->commandBuffer @@ -7713,8 +7697,32 @@ static void VULKAN_EndRenderPass( 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) + { + currentTexture = vulkanCommandBuffer->renderPassColorTargets[i]->texture; + + if (currentTexture->usageFlags & VK_IMAGE_USAGE_SAMPLED_BIT) + { + VULKAN_INTERNAL_ImageMemoryBarrier( + renderer, + vulkanCommandBuffer->commandBuffer, + RESOURCE_ACCESS_ANY_SHADER_READ_SAMPLED_IMAGE, + VK_IMAGE_ASPECT_COLOR_BIT, + 0, + currentTexture->layerCount, + 0, + currentTexture->levelCount, + 0, + currentTexture->image, + ¤tTexture->resourceAccessType + ); + } + } + vulkanCommandBuffer->renderPassColorTargetCount = 0; + vulkanCommandBuffer->currentGraphicsPipeline = NULL; vulkanCommandBuffer->renderPassInProgress = 0; } @@ -8251,7 +8259,9 @@ static Refresh_CommandBuffer* VULKAN_AcquireCommandBuffer( commandBuffer->fixed = fixed; commandBuffer->submitted = 0; commandBuffer->present = 0; + commandBuffer->renderPassInProgress = 0; + commandBuffer->renderPassColorTargetCount = 0; VULKAN_INTERNAL_BeginCommandBuffer(renderer, commandBuffer); -- 2.25.1 From e9e9e37d1549fe167e1456aab4c720a75a6fad3f Mon Sep 17 00:00:00 2001 From: cosmonaut Date: Thu, 24 Feb 2022 13:05:45 -0800 Subject: [PATCH 6/8] another barrier revert --- src/Refresh_Driver_Vulkan.c | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/src/Refresh_Driver_Vulkan.c b/src/Refresh_Driver_Vulkan.c index c78d6f5..9a62c4a 100644 --- a/src/Refresh_Driver_Vulkan.c +++ b/src/Refresh_Driver_Vulkan.c @@ -7818,13 +7818,6 @@ static void VULKAN_BindVertexBuffers( { currentVulkanBuffer = (VulkanBuffer*) pBuffers[i]; buffers[i] = currentVulkanBuffer->buffer; - - VULKAN_INTERNAL_BufferMemoryBarrier( - renderer, - vulkanCommandBuffer->commandBuffer, - RESOURCE_ACCESS_VERTEX_BUFFER, - currentVulkanBuffer - ); } renderer->vkCmdBindVertexBuffers( @@ -7849,13 +7842,6 @@ static void VULKAN_BindIndexBuffer( VulkanCommandBuffer *vulkanCommandBuffer = (VulkanCommandBuffer*) commandBuffer; VulkanBuffer* vulkanBuffer = (VulkanBuffer*) buffer; - VULKAN_INTERNAL_BufferMemoryBarrier( - renderer, - vulkanCommandBuffer->commandBuffer, - RESOURCE_ACCESS_INDEX_BUFFER, - vulkanBuffer - ); - renderer->vkCmdBindIndexBuffer( vulkanCommandBuffer->commandBuffer, vulkanBuffer->buffer, -- 2.25.1 From a39b49ee9b30c2c95cb2675e7a4b3070ff67de71 Mon Sep 17 00:00:00 2001 From: cosmonaut Date: Thu, 24 Feb 2022 13:45:02 -0800 Subject: [PATCH 7/8] decouple buffer size from memory size --- src/Refresh_Driver_Vulkan.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/Refresh_Driver_Vulkan.c b/src/Refresh_Driver_Vulkan.c index 9a62c4a..ccfcfbe 100644 --- a/src/Refresh_Driver_Vulkan.c +++ b/src/Refresh_Driver_Vulkan.c @@ -667,6 +667,7 @@ typedef struct VulkanBuffer /* cast from Refresh_Buffer */ VkBuffer buffer; VkDeviceSize size; VkDeviceSize offset; /* move this to UsedMemoryRegion system */ + VkDeviceSize memorySize; /* move this to UsedMemoryRegion system */ VulkanMemoryAllocation *allocation; /* see above */ VulkanResourceAccessType resourceAccessType; VkBufferUsageFlags usage; @@ -2613,7 +2614,7 @@ static void VULKAN_INTERNAL_DestroyBuffer( VULKAN_INTERNAL_NewMemoryFreeRegion( buffer->allocation, buffer->offset, - buffer->size + buffer->memorySize ); SDL_UnlockMutex(renderer->allocatorLock); @@ -3184,7 +3185,7 @@ static VulkanBuffer* VULKAN_INTERNAL_CreateBuffer( buffer->buffer, &buffer->allocation, &buffer->offset, - &buffer->size + &buffer->memorySize ); /* We're out of available memory */ @@ -6080,13 +6081,13 @@ static Refresh_Buffer* VULKAN_CreateBuffer( buffer = VULKAN_INTERNAL_CreateBuffer( (VulkanRenderer*)driverData, sizeInBytes, - RESOURCE_ACCESS_VERTEX_BUFFER, + RESOURCE_ACCESS_MEMORY_TRANSFER_READ_WRITE, vulkanUsageFlags ); if (buffer == NULL) { - Refresh_LogError("Failed to create vertex buffer!"); + Refresh_LogError("Failed to create buffer!"); return NULL; } -- 2.25.1 From 76217adc40fb198ab71425b10e78bae087fae257 Mon Sep 17 00:00:00 2001 From: cosmonaut Date: Thu, 24 Feb 2022 13:48:52 -0800 Subject: [PATCH 8/8] simplify VULKAN_INTERNAL_CreateTexture --- src/Refresh_Driver_Vulkan.c | 48 ++++++++++++++++--------------------- 1 file changed, 20 insertions(+), 28 deletions(-) diff --git a/src/Refresh_Driver_Vulkan.c b/src/Refresh_Driver_Vulkan.c index ccfcfbe..1431907 100644 --- a/src/Refresh_Driver_Vulkan.c +++ b/src/Refresh_Driver_Vulkan.c @@ -5705,8 +5705,7 @@ static Refresh_ShaderModule* VULKAN_CreateShaderModule( return (Refresh_ShaderModule*) shaderModule; } -/* texture should be an alloc'd but uninitialized VulkanTexture */ -static uint8_t VULKAN_INTERNAL_CreateTexture( +static VulkanTexture* VULKAN_INTERNAL_CreateTexture( VulkanRenderer *renderer, uint32_t width, uint32_t height, @@ -5717,8 +5716,7 @@ static uint8_t VULKAN_INTERNAL_CreateTexture( VkFormat format, VkImageAspectFlags aspectMask, VkImageType imageType, - VkImageUsageFlags imageUsageFlags, - VulkanTexture *texture + VkImageUsageFlags imageUsageFlags ) { VkResult vulkanResult; VkImageCreateInfo imageCreateInfo; @@ -5732,6 +5730,8 @@ static uint8_t VULKAN_INTERNAL_CreateTexture( ((imageUsageFlags & VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) != 0); VkComponentMapping swizzle = IDENTITY_SWIZZLE; + VulkanTexture *texture = SDL_malloc(sizeof(VulkanTexture)); + texture->isCube = 0; texture->is3D = 0; @@ -5891,7 +5891,7 @@ static uint8_t VULKAN_INTERNAL_CreateTexture( texture->queueFamilyIndex = renderer->queueFamilyIndices.graphicsFamily; texture->usageFlags = imageUsageFlags; - return 1; + return texture; } static Refresh_Texture* VULKAN_CreateTexture( @@ -5899,7 +5899,6 @@ static Refresh_Texture* VULKAN_CreateTexture( Refresh_TextureCreateInfo *textureCreateInfo ) { VulkanRenderer *renderer = (VulkanRenderer*) driverData; - VulkanTexture *result; VkImageUsageFlags imageUsageFlags = ( VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT @@ -5936,9 +5935,7 @@ static Refresh_Texture* VULKAN_CreateTexture( imageAspectFlags = VK_IMAGE_ASPECT_COLOR_BIT; } - result = (VulkanTexture*) SDL_malloc(sizeof(VulkanTexture)); - - VULKAN_INTERNAL_CreateTexture( + return (Refresh_Texture*) VULKAN_INTERNAL_CreateTexture( renderer, textureCreateInfo->width, textureCreateInfo->height, @@ -5949,11 +5946,8 @@ static Refresh_Texture* VULKAN_CreateTexture( format, imageAspectFlags, VK_IMAGE_TYPE_2D, - imageUsageFlags, - result + imageUsageFlags ); - - return (Refresh_Texture*) result; } static Refresh_RenderTarget* VULKAN_CreateRenderTarget( @@ -5992,22 +5986,20 @@ static Refresh_RenderTarget* VULKAN_CreateRenderTarget( if (multisampleCount > REFRESH_SAMPLECOUNT_1) { renderTarget->multisampleTexture = - (VulkanTexture*) SDL_malloc(sizeof(VulkanTexture)); + VULKAN_INTERNAL_CreateTexture( + renderer, + renderTarget->texture->dimensions.width, + renderTarget->texture->dimensions.height, + 1, + 0, + RefreshToVK_SampleCount[multisampleCount], + 1, + renderTarget->texture->format, + aspectFlags, + VK_IMAGE_TYPE_2D, + VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT + ); - VULKAN_INTERNAL_CreateTexture( - renderer, - renderTarget->texture->dimensions.width, - renderTarget->texture->dimensions.height, - 1, - 0, - RefreshToVK_SampleCount[multisampleCount], - 1, - renderTarget->texture->format, - aspectFlags, - VK_IMAGE_TYPE_2D, - VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT, - renderTarget->multisampleTexture - ); renderTarget->multisampleCount = multisampleCount; } -- 2.25.1