Mesa (main): v3dv: improve TLB layered image clears

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Fri Jul 16 09:51:41 UTC 2021


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

Author: Iago Toral Quiroga <itoral at igalia.com>
Date:   Thu Jul 15 11:05:20 2021 +0200

v3dv: improve TLB layered image clears

Our meta image clearing code was emitting a job per layer to clear,
but we can emit a single job that packs multiple layer clears for
better performance. For this we just need to make sure we pass
the maximum layer we can emit to v3dv_job_start_frame so we
allocate sufficent tile state memory.

Actually, since this operation is TLB based and doesn't make use of
layered rendering, we could do with allocating less tile state
memory too. We will improve this for this and many others TLB meta
implementations in follow up patches.

Reviewed-by: Alejandro Piñeiro <apinheiro at igalia.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/11923>

---

 src/broadcom/vulkan/v3dv_meta_clear.c   | 47 ++++++++++++++++-----------------
 src/broadcom/vulkan/v3dvx_meta_common.c | 36 ++++++++++++++-----------
 src/broadcom/vulkan/v3dvx_private.h     |  3 ++-
 3 files changed, 46 insertions(+), 40 deletions(-)

diff --git a/src/broadcom/vulkan/v3dv_meta_clear.c b/src/broadcom/vulkan/v3dv_meta_clear.c
index 469aa7a4ebd..60a7843d1d6 100644
--- a/src/broadcom/vulkan/v3dv_meta_clear.c
+++ b/src/broadcom/vulkan/v3dv_meta_clear.c
@@ -114,38 +114,37 @@ clear_image_tlb(struct v3dv_cmd_buffer *cmd_buffer,
    for (uint32_t level = min_level; level < max_level; level++) {
       if (image->type == VK_IMAGE_TYPE_3D)
          max_layer = u_minify(image->extent.depth, level);
-      for (uint32_t layer = min_layer; layer < max_layer; layer++) {
-         uint32_t width = u_minify(image->extent.width, level);
-         uint32_t height = u_minify(image->extent.height, level);
 
-         struct v3dv_job *job =
-            v3dv_cmd_buffer_start_job(cmd_buffer, -1, V3DV_JOB_TYPE_GPU_CL);
+      uint32_t width = u_minify(image->extent.width, level);
+      uint32_t height = u_minify(image->extent.height, level);
 
-         if (!job)
-            return true;
+      struct v3dv_job *job =
+         v3dv_cmd_buffer_start_job(cmd_buffer, -1, V3DV_JOB_TYPE_GPU_CL);
 
-         /* We start a a new job for each layer so the frame "depth" is 1 */
-         v3dv_job_start_frame(job, width, height, 1, 1, internal_bpp,
-                              image->samples > VK_SAMPLE_COUNT_1_BIT);
+      if (!job)
+         return true;
 
-         struct v3dv_meta_framebuffer framebuffer;
-         v3dv_X(job->device, meta_framebuffer_init)(&framebuffer, fb_format,
-                                                    internal_type,
-                                                    &job->frame_tiling);
+      v3dv_job_start_frame(job, width, height, max_layer,
+                           1, internal_bpp,
+                           image->samples > VK_SAMPLE_COUNT_1_BIT);
 
-         v3dv_X(job->device, job_emit_binning_flush)(job);
+      struct v3dv_meta_framebuffer framebuffer;
+      v3dv_X(job->device, meta_framebuffer_init)(&framebuffer, fb_format,
+                                                 internal_type,
+                                                 &job->frame_tiling);
 
-         /* If this triggers it is an application bug: the spec requires
-          * that any aspects to clear are present in the image.
-          */
-         assert(range->aspectMask & image->aspects);
+      v3dv_X(job->device, job_emit_binning_flush)(job);
 
-         v3dv_X(job->device, meta_emit_clear_image_rcl)
-            (job, image, &framebuffer, &hw_clear_value,
-             range->aspectMask, layer, level);
+      /* If this triggers it is an application bug: the spec requires
+       * that any aspects to clear are present in the image.
+       */
+      assert(range->aspectMask & image->aspects);
 
-         v3dv_cmd_buffer_finish_job(cmd_buffer);
-      }
+      v3dv_X(job->device, meta_emit_clear_image_rcl)
+         (job, image, &framebuffer, &hw_clear_value,
+          range->aspectMask, min_layer, max_layer, level);
+
+      v3dv_cmd_buffer_finish_job(cmd_buffer);
    }
 
    return true;
diff --git a/src/broadcom/vulkan/v3dvx_meta_common.c b/src/broadcom/vulkan/v3dvx_meta_common.c
index 092771d0a08..51130d0a83f 100644
--- a/src/broadcom/vulkan/v3dvx_meta_common.c
+++ b/src/broadcom/vulkan/v3dvx_meta_common.c
@@ -129,7 +129,7 @@ emit_rcl_prologue(struct v3dv_job *job,
 
 static void
 emit_frame_setup(struct v3dv_job *job,
-                 uint32_t layer,
+                 uint32_t min_layer,
                  const union v3dv_clear_value *clear_value)
 {
    v3dv_return_if_oom(NULL, job);
@@ -139,7 +139,7 @@ emit_frame_setup(struct v3dv_job *job,
    struct v3dv_cl *rcl = &job->rcl;
 
    const uint32_t tile_alloc_offset =
-      64 * layer * tiling->draw_tiles_x * tiling->draw_tiles_y;
+      64 * min_layer * tiling->draw_tiles_x * tiling->draw_tiles_y;
    cl_emit(rcl, MULTICORE_RENDERING_TILE_LIST_SET_BASE, list) {
       list.address = v3dv_cl_address(job->tile_alloc, tile_alloc_offset);
    }
@@ -893,12 +893,12 @@ v3dX(meta_emit_tfu_job)(struct v3dv_cmd_buffer *cmd_buffer,
 }
 
 static void
-emit_clear_image_per_tile_list(struct v3dv_job *job,
-                               struct v3dv_meta_framebuffer *framebuffer,
-                               struct v3dv_image *image,
-                               VkImageAspectFlags aspects,
-                               uint32_t layer,
-                               uint32_t level)
+emit_clear_image_layer_per_tile_list(struct v3dv_job *job,
+                                     struct v3dv_meta_framebuffer *framebuffer,
+                                     struct v3dv_image *image,
+                                     VkImageAspectFlags aspects,
+                                     uint32_t layer,
+                                     uint32_t level)
 {
    struct v3dv_cl *cl = &job->indirect;
    v3dv_cl_ensure_space(cl, 200, 1);
@@ -926,15 +926,19 @@ emit_clear_image_per_tile_list(struct v3dv_job *job,
 }
 
 static void
-emit_clear_image(struct v3dv_job *job,
+emit_clear_image_layers(struct v3dv_job *job,
                  struct v3dv_image *image,
                  struct v3dv_meta_framebuffer *framebuffer,
                  VkImageAspectFlags aspects,
-                 uint32_t layer,
+                 uint32_t min_layer,
+                 uint32_t max_layer,
                  uint32_t level)
 {
-   emit_clear_image_per_tile_list(job, framebuffer, image, aspects, layer, level);
-   emit_supertile_coordinates(job, framebuffer);
+   for (uint32_t layer = min_layer; layer < max_layer; layer++) {
+      emit_clear_image_layer_per_tile_list(job, framebuffer, image, aspects,
+                                           layer, level);
+      emit_supertile_coordinates(job, framebuffer);
+   }
 }
 
 void
@@ -943,7 +947,8 @@ v3dX(meta_emit_clear_image_rcl)(struct v3dv_job *job,
                                 struct v3dv_meta_framebuffer *framebuffer,
                                 const union v3dv_clear_value *clear_value,
                                 VkImageAspectFlags aspects,
-                                uint32_t layer,
+                                uint32_t min_layer,
+                                uint32_t max_layer,
                                 uint32_t level)
 {
    const struct rcl_clear_info clear_info = {
@@ -956,8 +961,9 @@ v3dX(meta_emit_clear_image_rcl)(struct v3dv_job *job,
    struct v3dv_cl *rcl = emit_rcl_prologue(job, framebuffer, &clear_info);
    v3dv_return_if_oom(NULL, job);
 
-   emit_frame_setup(job, 0, clear_value);
-   emit_clear_image(job, image, framebuffer, aspects, layer, level);
+   emit_frame_setup(job, min_layer, clear_value);
+   emit_clear_image_layers(job, image, framebuffer, aspects,
+                           min_layer, max_layer, level);
    cl_emit(rcl, END_OF_RENDERING, end);
 }
 
diff --git a/src/broadcom/vulkan/v3dvx_private.h b/src/broadcom/vulkan/v3dvx_private.h
index 7584e7af430..edebf251833 100644
--- a/src/broadcom/vulkan/v3dvx_private.h
+++ b/src/broadcom/vulkan/v3dvx_private.h
@@ -239,7 +239,8 @@ v3dX(meta_emit_clear_image_rcl)(struct v3dv_job *job,
                                 struct v3dv_meta_framebuffer *framebuffer,
                                 const union v3dv_clear_value *clear_value,
                                 VkImageAspectFlags aspects,
-                                uint32_t layer,
+                                uint32_t min_layer,
+                                uint32_t max_layer,
                                 uint32_t level);
 
 void



More information about the mesa-commit mailing list