Module: Mesa
Branch: main
Commit: 3457f8083a656524ffe7ce572a7d09b0c7279cf3
URL:    
http://cgit.freedesktop.org/mesa/mesa/commit/?id=3457f8083a656524ffe7ce572a7d09b0c7279cf3

Author: Karmjit Mahil <[email protected]>
Date:   Tue Nov 29 15:48:13 2022 +0000

pvr: Acquire scratch buffer on framebuffer creation.

Signed-off-by: Karmjit Mahil <[email protected]>
Reviewed-by: Frank Binns <[email protected]>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/21102>

---

 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 3477a77f6d7..8eb345f12ce 100644
--- a/src/imagination/csbgen/rogue_cr.xml
+++ b/src/imagination/csbgen/rogue_cr.xml
@@ -583,7 +583,9 @@ SOFTWARE.
     <field name="downscale" start="56" end="56" type="bool"/>
     <field name="size_z" start="52" end="55" type="SIZE"/>
     <field name="rotation" start="50" end="51" type="ROTATION_TYPE"/>
-    <field name="linestride" start="34" end="49" type="uint"/>
+    <field name="linestride" start="34" end="49" type="uint">
+      <define name="ALIGNMENT" value="2"/>
+    </field>
     <field name="memlayout" start="32" end="33" type="MEMLAYOUT"/>
     <field name="swiz_chan3" start="29" end="31" type="SWIZ"/>
     <field name="swiz_chan2" start="26" end="28" type="SWIZ"/>
diff --git a/src/imagination/vulkan/pvr_device.c 
b/src/imagination/vulkan/pvr_device.c
index ab88b2ed448..98f10af0c02 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 592b92906a2..e8fd902b2e0 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 2bc6aeab14f..3fd26d94ccd 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 fe0854f33e3..a3475d9c3f6 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,

Reply via email to