From 3457f8083a656524ffe7ce572a7d09b0c7279cf3 Mon Sep 17 00:00:00 2001 From: Karmjit Mahil Date: Tue, 29 Nov 2022 15:48:13 +0000 Subject: [PATCH] pvr: Acquire scratch buffer on framebuffer creation. Signed-off-by: Karmjit Mahil Reviewed-by: Frank Binns Part-of: --- src/imagination/csbgen/rogue_cr.xml | 4 +++- src/imagination/vulkan/pvr_device.c | 19 ++++++++++++++++++- src/imagination/vulkan/pvr_private.h | 2 ++ src/imagination/vulkan/pvr_spm.c | 32 ++++++++++++++++++++++++++++++++ src/imagination/vulkan/pvr_spm.h | 5 +++++ 5 files changed, 60 insertions(+), 2 deletions(-) diff --git a/src/imagination/csbgen/rogue_cr.xml b/src/imagination/csbgen/rogue_cr.xml index 3477a77..8eb345f 100644 --- a/src/imagination/csbgen/rogue_cr.xml +++ b/src/imagination/csbgen/rogue_cr.xml @@ -583,7 +583,9 @@ SOFTWARE. - + + + diff --git a/src/imagination/vulkan/pvr_device.c b/src/imagination/vulkan/pvr_device.c index ab88b2e..98f10af 100644 --- a/src/imagination/vulkan/pvr_device.c +++ b/src/imagination/vulkan/pvr_device.c @@ -2621,11 +2621,13 @@ VkResult pvr_CreateFramebuffer(VkDevice _device, const VkAllocationCallbacks *pAllocator, VkFramebuffer *pFramebuffer) { + PVR_FROM_HANDLE(pvr_render_pass, pass, pCreateInfo->renderPass); PVR_FROM_HANDLE(pvr_device, device, _device); struct pvr_render_target *render_targets; struct pvr_framebuffer *framebuffer; struct pvr_image_view **attachments; uint32_t render_targets_count; + uint64_t scratch_buffer_size; VkResult result; assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO); @@ -2677,10 +2679,24 @@ VkResult pvr_CreateFramebuffer(VkDevice _device, goto err_free_ppp_state_bo; } + scratch_buffer_size = + pvr_spm_scratch_buffer_calc_required_size(pass, + framebuffer->width, + framebuffer->height); + + result = pvr_spm_scratch_buffer_get_buffer(device, + scratch_buffer_size, + &framebuffer->scratch_buffer); + if (result != VK_SUCCESS) + goto err_finish_render_targets; + *pFramebuffer = pvr_framebuffer_to_handle(framebuffer); return VK_SUCCESS; +err_finish_render_targets: + pvr_render_targets_fini(framebuffer->render_targets, render_targets_count); + err_free_ppp_state_bo: pvr_bo_free(device, framebuffer->ppp_state_bo); @@ -2695,12 +2711,13 @@ void pvr_DestroyFramebuffer(VkDevice _device, VkFramebuffer _fb, const VkAllocationCallbacks *pAllocator) { - PVR_FROM_HANDLE(pvr_device, device, _device); PVR_FROM_HANDLE(pvr_framebuffer, framebuffer, _fb); + PVR_FROM_HANDLE(pvr_device, device, _device); if (!framebuffer) return; + pvr_spm_scratch_buffer_release(device, framebuffer->scratch_buffer); pvr_render_targets_fini(framebuffer->render_targets, framebuffer->render_targets_count); pvr_bo_free(device, framebuffer->ppp_state_bo); diff --git a/src/imagination/vulkan/pvr_private.h b/src/imagination/vulkan/pvr_private.h index 592b929..e8fd902 100644 --- a/src/imagination/vulkan/pvr_private.h +++ b/src/imagination/vulkan/pvr_private.h @@ -1294,6 +1294,8 @@ struct pvr_framebuffer { uint32_t render_targets_count; struct pvr_render_target *render_targets; + + struct pvr_spm_scratch_buffer *scratch_buffer; }; struct pvr_render_pass_attachment { diff --git a/src/imagination/vulkan/pvr_spm.c b/src/imagination/vulkan/pvr_spm.c index 2bc6aea..3fd26d9 100644 --- a/src/imagination/vulkan/pvr_spm.c +++ b/src/imagination/vulkan/pvr_spm.c @@ -69,6 +69,38 @@ void pvr_spm_finish_scratch_buffer_store(struct pvr_device *device) } } +uint64_t +pvr_spm_scratch_buffer_calc_required_size(const struct pvr_render_pass *pass, + uint32_t framebuffer_width, + uint32_t framebuffer_height) +{ + uint64_t dwords_per_pixel; + uint64_t buffer_size; + + /* If we're allocating an SPM scratch buffer we'll have a minimum of 1 output + * reg and/or tile_buffer. + */ + uint32_t nr_tile_buffers = 1; + uint32_t nr_output_regs = 1; + + for (uint32_t i = 0; i < pass->hw_setup->render_count; i++) { + const struct pvr_renderpass_hwsetup_render *hw_render = + &pass->hw_setup->renders[i]; + + nr_tile_buffers = MAX2(nr_tile_buffers, hw_render->tile_buffers_count); + nr_output_regs = MAX2(nr_output_regs, hw_render->output_regs_count); + } + + dwords_per_pixel = + (uint64_t)pass->max_sample_count * nr_output_regs * nr_tile_buffers; + + buffer_size = ALIGN_POT((uint64_t)framebuffer_width, + PVRX(CR_PBE_WORD0_MRT0_LINESTRIDE_ALIGNMENT)); + buffer_size *= (uint64_t)framebuffer_height * dwords_per_pixel * 4; + + return buffer_size; +} + static VkResult pvr_spm_scratch_buffer_alloc(struct pvr_device *device, uint64_t size, diff --git a/src/imagination/vulkan/pvr_spm.h b/src/imagination/vulkan/pvr_spm.h index fe0854f..a3475d9 100644 --- a/src/imagination/vulkan/pvr_spm.h +++ b/src/imagination/vulkan/pvr_spm.h @@ -45,6 +45,7 @@ #include "util/simple_mtx.h" struct pvr_device; +struct pvr_render_pass; struct pvr_spm_scratch_buffer; struct pvr_spm_scratch_buffer_store { @@ -63,6 +64,10 @@ void pvr_spm_finish_scratch_buffer_store(struct pvr_device *device); * VK_ATTACHMENT_STORE_OP_NONE, not currently supported) or lazily allocated * attachments with no backing. */ +uint64_t +pvr_spm_scratch_buffer_calc_required_size(const struct pvr_render_pass *pass, + uint32_t framebuffer_width, + uint32_t framebuffer_height); VkResult pvr_spm_scratch_buffer_get_buffer( struct pvr_device *device, uint64_t size, -- 2.7.4