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)