Mesa (main): panvk: Support clearing ZS attachments

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Mon Oct 4 13:33:38 UTC 2021


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

Author: Boris Brezillon <boris.brezillon at collabora.com>
Date:   Thu Sep 30 12:54:40 2021 +0200

panvk: Support clearing ZS attachments

Signed-off-by: Boris Brezillon <boris.brezillon at collabora.com>
Reviewed-by: Tomeu Vizoso <tomeu.vizoso at collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/13137>

---

 src/panfrost/vulkan/panvk_private.h       |   8 +-
 src/panfrost/vulkan/panvk_vX_meta_clear.c | 236 +++++++++++++++++++++++-------
 2 files changed, 190 insertions(+), 54 deletions(-)

diff --git a/src/panfrost/vulkan/panvk_private.h b/src/panfrost/vulkan/panvk_private.h
index bf95df07136..e8a8984b1d8 100644
--- a/src/panfrost/vulkan/panvk_private.h
+++ b/src/panfrost/vulkan/panvk_private.h
@@ -159,9 +159,11 @@ struct panvk_meta {
    } blitter;
 
    struct {
-      mali_ptr shader;
-      struct pan_shader_info shader_info;
-   } clear_attachment[MAX_RTS][3]; /* 3 base types */
+      struct {
+         mali_ptr shader;
+         struct pan_shader_info shader_info;
+      } color[MAX_RTS][3], zs, z, s; /* 3 base types */
+   } clear_attachment;
 
    struct {
       struct {
diff --git a/src/panfrost/vulkan/panvk_vX_meta_clear.c b/src/panfrost/vulkan/panvk_vX_meta_clear.c
index c3dca80abb4..764f1455ddc 100644
--- a/src/panfrost/vulkan/panvk_vX_meta_clear.c
+++ b/src/panfrost/vulkan/panvk_vX_meta_clear.c
@@ -32,17 +32,16 @@
 #include "vk_format.h"
 
 static mali_ptr
-panvk_meta_clear_attachments_shader(struct panfrost_device *pdev,
-                                    struct pan_pool *bin_pool,
-                                    unsigned rt,
-                                    enum glsl_base_type base_type,
-                                    struct pan_shader_info *shader_info)
+panvk_meta_clear_color_attachment_shader(struct panfrost_device *pdev,
+                                         struct pan_pool *bin_pool,
+                                         unsigned rt,
+                                         enum glsl_base_type base_type,
+                                         struct pan_shader_info *shader_info)
 {
    nir_builder b = nir_builder_init_simple_shader(MESA_SHADER_FRAGMENT,
                                      GENX(pan_shader_get_compiler_options)(),
-                                     "panvk_meta_clear_attachment(base_type=%d,rt=%d)",
-                                     base_type,
-                                     rt);
+                                     "panvk_meta_clear_rt%d_attachment(base_type=%d)",
+                                     rt, base_type);
 
    b.shader->info.internal = true;
    b.shader->info.num_ubos = 1;
@@ -84,11 +83,79 @@ panvk_meta_clear_attachments_shader(struct panfrost_device *pdev,
    return shader;
 }
 
+static mali_ptr
+panvk_meta_clear_zs_attachment_shader(struct panfrost_device *pdev,
+                                      struct pan_pool *bin_pool,
+                                      bool clear_z, bool clear_s,
+                                      enum glsl_base_type base_type,
+                                      struct pan_shader_info *shader_info)
+{
+   nir_builder b = nir_builder_init_simple_shader(MESA_SHADER_FRAGMENT,
+                                     GENX(pan_shader_get_compiler_options)(),
+                                     "panvk_meta_clear_%s%s_attachment()",
+                                     clear_z ? "z" : "", clear_s ? "s" : "");
+
+   b.shader->info.internal = true;
+   b.shader->info.num_ubos = 1;
+
+   unsigned drv_loc = 0;
+   nir_variable *z_out =
+      clear_z ?
+      nir_variable_create(b.shader, nir_var_shader_out, glsl_float_type(), "depth") :
+      NULL;
+   nir_variable *s_out =
+      clear_s ?
+      nir_variable_create(b.shader, nir_var_shader_out, glsl_float_type(), "stencil") :
+      NULL;
+
+   nir_ssa_def *clear_values = nir_load_ubo(&b, 2, 32, nir_imm_int(&b, 0),
+                                            nir_imm_int(&b, 0),
+                                            .align_mul = 4,
+                                            .align_offset = 0,
+                                            .range_base = 0,
+                                            .range = ~0);
+
+   if (z_out) {
+      z_out->data.location = FRAG_RESULT_DEPTH;
+      z_out->data.driver_location = drv_loc++;
+      nir_store_var(&b, z_out, nir_channel(&b, clear_values, 0), 1);
+   }
+
+   if (s_out) {
+      s_out->data.location = FRAG_RESULT_STENCIL;
+      s_out->data.driver_location = drv_loc++;
+      nir_store_var(&b, s_out, nir_channel(&b, clear_values, 1), 1);
+   }
+
+   struct panfrost_compile_inputs inputs = {
+      .gpu_id = pdev->gpu_id,
+      .is_blit = true,
+   };
+
+   struct util_dynarray binary;
+
+   util_dynarray_init(&binary, NULL);
+   GENX(pan_shader_compile)(b.shader, &inputs, &binary, shader_info);
+
+   /* Make sure UBO words have been upgraded to push constants */
+   assert(shader_info->ubo_count == 1);
+   assert(shader_info->push.count == 2);
+
+   mali_ptr shader =
+      pan_pool_upload_aligned(bin_pool, binary.data, binary.size,
+                              PAN_ARCH >= 6 ? 128 : 64);
+
+   util_dynarray_fini(&binary);
+   ralloc_free(b.shader);
+
+   return shader;
+}
+
 static mali_ptr
 panvk_meta_clear_attachments_emit_rsd(struct panfrost_device *pdev,
                                       struct pan_pool *desc_pool,
                                       enum pipe_format format,
-                                      unsigned rt,
+                                      unsigned rt, bool z, bool s,
                                       struct pan_shader_info *shader_info,
                                       mali_ptr shader)
 {
@@ -96,12 +163,19 @@ panvk_meta_clear_attachments_emit_rsd(struct panfrost_device *pdev,
       pan_pool_alloc_desc_aggregate(desc_pool,
                                     PAN_DESC(RENDERER_STATE),
                                     PAN_DESC_ARRAY(rt + 1, BLEND));
+   bool zs = z | s;
 
    pan_pack(rsd_ptr.cpu, RENDERER_STATE, cfg) {
       pan_shader_prepare_rsd(shader_info, shader, &cfg);
-      cfg.properties.depth_source = MALI_DEPTH_SOURCE_FIXED_FUNCTION;
+      cfg.properties.depth_source =
+         z ?
+	 MALI_DEPTH_SOURCE_SHADER :
+	 MALI_DEPTH_SOURCE_FIXED_FUNCTION;
+      cfg.multisample_misc.depth_write_mask = z;
       cfg.multisample_misc.sample_mask = UINT16_MAX;
       cfg.multisample_misc.depth_function = MALI_FUNC_ALWAYS;
+      cfg.stencil_mask_misc.stencil_enable = s;
+      cfg.properties.stencil_from_shader = s;
       cfg.stencil_mask_misc.stencil_mask_front = 0xFF;
       cfg.stencil_mask_misc.stencil_mask_back = 0xFF;
       cfg.stencil_front.compare_function = MALI_FUNC_ALWAYS;
@@ -112,16 +186,23 @@ panvk_meta_clear_attachments_emit_rsd(struct panfrost_device *pdev,
       cfg.stencil_back = cfg.stencil_front;
 
 #if PAN_ARCH >= 6
-      cfg.properties.allow_forward_pixel_to_be_killed = true;
-      cfg.properties.allow_forward_pixel_to_kill = true;
-      cfg.properties.zs_update_operation =
-         MALI_PIXEL_KILL_STRONG_EARLY;
-      cfg.properties.pixel_kill_operation =
-         MALI_PIXEL_KILL_FORCE_EARLY;
+      cfg.properties.allow_forward_pixel_to_be_killed = PAN_ARCH >= 7 || !zs;
+      cfg.properties.allow_forward_pixel_to_kill = !zs;
+      if (zs) {
+         cfg.properties.zs_update_operation =
+            MALI_PIXEL_KILL_FORCE_LATE;
+         cfg.properties.pixel_kill_operation =
+            MALI_PIXEL_KILL_FORCE_LATE;
+      } else {
+         cfg.properties.zs_update_operation =
+            MALI_PIXEL_KILL_STRONG_EARLY;
+         cfg.properties.pixel_kill_operation =
+            MALI_PIXEL_KILL_FORCE_EARLY;
+      }
 #else
       cfg.properties.shader_reads_tilebuffer = false;
       cfg.properties.work_register_count = shader_info->work_reg_count;
-      cfg.properties.force_early_z = true;
+      cfg.properties.force_early_z = !zs;
       cfg.stencil_mask_misc.alpha_test_compare_function = MALI_FUNC_ALWAYS;
 #endif
    }
@@ -140,27 +221,37 @@ panvk_meta_clear_attachments_emit_rsd(struct panfrost_device *pdev,
       bd += pan_size(BLEND);
    }
 
-   pan_pack(bd, BLEND, cfg) {
-      cfg.round_to_fb_precision = true;
-      cfg.load_destination = false;
-      cfg.equation.rgb.a = MALI_BLEND_OPERAND_A_SRC;
-      cfg.equation.rgb.b = MALI_BLEND_OPERAND_B_SRC;
-      cfg.equation.rgb.c = MALI_BLEND_OPERAND_C_ZERO;
-      cfg.equation.alpha.a = MALI_BLEND_OPERAND_A_SRC;
-      cfg.equation.alpha.b = MALI_BLEND_OPERAND_B_SRC;
-      cfg.equation.alpha.c = MALI_BLEND_OPERAND_C_ZERO;
+   if (zs) {
+      /* We write the depth/stencil, disable blending on RT0. */
+      pan_pack(bd, BLEND, cfg) {
+         cfg.enable = false;
+#if PAN_ARCH >= 6
+         cfg.internal.mode = MALI_BLEND_MODE_OFF;
+#endif
+      }
+   } else {
+      pan_pack(bd, BLEND, cfg) {
+         cfg.round_to_fb_precision = true;
+         cfg.load_destination = false;
+         cfg.equation.rgb.a = MALI_BLEND_OPERAND_A_SRC;
+         cfg.equation.rgb.b = MALI_BLEND_OPERAND_B_SRC;
+         cfg.equation.rgb.c = MALI_BLEND_OPERAND_C_ZERO;
+         cfg.equation.alpha.a = MALI_BLEND_OPERAND_A_SRC;
+         cfg.equation.alpha.b = MALI_BLEND_OPERAND_B_SRC;
+         cfg.equation.alpha.c = MALI_BLEND_OPERAND_C_ZERO;
 #if PAN_ARCH >= 6
-      cfg.internal.mode = MALI_BLEND_MODE_OPAQUE;
-      cfg.equation.color_mask = 0xf;
-      cfg.internal.fixed_function.num_comps = 4;
-      cfg.internal.fixed_function.conversion.memory_format =
-         panfrost_format_to_bifrost_blend(pdev, format, false);
-      cfg.internal.fixed_function.conversion.register_format =
-         shader_info->bifrost.blend[rt].format;
+         cfg.internal.mode = MALI_BLEND_MODE_OPAQUE;
+         cfg.equation.color_mask = 0xf;
+         cfg.internal.fixed_function.num_comps = 4;
+         cfg.internal.fixed_function.conversion.memory_format =
+            panfrost_format_to_bifrost_blend(pdev, format, false);
+         cfg.internal.fixed_function.conversion.register_format =
+            shader_info->bifrost.blend[rt].format;
 #else
-      cfg.equation.color_mask =
-         (1 << util_format_get_nr_components(format)) - 1;
+         cfg.equation.color_mask =
+            (1 << util_format_get_nr_components(format)) - 1;
 #endif
+      }
    }
 
    return rsd_ptr.gpu;
@@ -314,9 +405,6 @@ panvk_meta_clear_attachment(struct panvk_cmd_buffer *cmdbuf,
    unsigned maxx = MAX2(clear_rect->rect.offset.x + clear_rect->rect.extent.width - 1, 0);
    unsigned maxy = MAX2(clear_rect->rect.offset.y + clear_rect->rect.extent.height - 1, 0);
 
-   /* TODO: Support depth/stencil */
-   assert(mask == VK_IMAGE_ASPECT_COLOR_BIT);
-
    panvk_per_arch(cmd_alloc_fb_desc)(cmdbuf);
    panvk_per_arch(cmd_alloc_tls_desc)(cmdbuf, true);
    panvk_per_arch(cmd_prepare_tiler_context)(cmdbuf);
@@ -335,14 +423,38 @@ panvk_meta_clear_attachment(struct panvk_cmd_buffer *cmdbuf,
                                                   rect, sizeof(rect), 64);
 
    enum glsl_base_type base_type = panvk_meta_get_format_type(att->format);
-   mali_ptr shader = meta->clear_attachment[rt][base_type].shader;
-   struct pan_shader_info *shader_info =
-      &meta->clear_attachment[rt][base_type].shader_info;
+   struct pan_shader_info *shader_info;
+   bool clear_z = false, clear_s = false;
+   mali_ptr shader;
+
+   switch (mask) {
+   case VK_IMAGE_ASPECT_COLOR_BIT:
+      shader = meta->clear_attachment.color[rt][base_type].shader;
+      shader_info = &meta->clear_attachment.color[rt][base_type].shader_info;
+      break;
+   case VK_IMAGE_ASPECT_DEPTH_BIT:
+      shader = meta->clear_attachment.z.shader;
+      shader_info = &meta->clear_attachment.z.shader_info;
+      clear_z = true;
+      break;
+   case VK_IMAGE_ASPECT_STENCIL_BIT:
+      shader = meta->clear_attachment.s.shader;
+      shader_info = &meta->clear_attachment.s.shader_info;
+      clear_s = true;
+      break;
+   case VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT:
+      shader = meta->clear_attachment.zs.shader;
+      shader_info = &meta->clear_attachment.zs.shader_info;
+      clear_s = clear_z = true;
+      break;
+   default:
+      unreachable("Invalid aspect mask\n");
+   }
 
    mali_ptr rsd =
       panvk_meta_clear_attachments_emit_rsd(pdev,
                                             &cmdbuf->desc_pool.base,
-                                            att->format, rt,
+                                            att->format, rt, clear_z, clear_s,
                                             shader_info,
                                             shader);
 
@@ -547,30 +659,52 @@ static void
 panvk_meta_clear_attachment_init(struct panvk_physical_device *dev)
 {
    for (unsigned rt = 0; rt < MAX_RTS; rt++) {
-      dev->meta.clear_attachment[rt][GLSL_TYPE_UINT].shader =
-         panvk_meta_clear_attachments_shader(
+      dev->meta.clear_attachment.color[rt][GLSL_TYPE_UINT].shader =
+         panvk_meta_clear_color_attachment_shader(
                &dev->pdev,
                &dev->meta.bin_pool.base,
                rt,
                GLSL_TYPE_UINT,
-               &dev->meta.clear_attachment[rt][GLSL_TYPE_UINT].shader_info);
+               &dev->meta.clear_attachment.color[rt][GLSL_TYPE_UINT].shader_info);
 
-      dev->meta.clear_attachment[rt][GLSL_TYPE_INT].shader =
-         panvk_meta_clear_attachments_shader(
+      dev->meta.clear_attachment.color[rt][GLSL_TYPE_INT].shader =
+         panvk_meta_clear_color_attachment_shader(
                &dev->pdev,
                &dev->meta.bin_pool.base,
                rt,
                GLSL_TYPE_INT,
-               &dev->meta.clear_attachment[rt][GLSL_TYPE_INT].shader_info);
+               &dev->meta.clear_attachment.color[rt][GLSL_TYPE_INT].shader_info);
 
-      dev->meta.clear_attachment[rt][GLSL_TYPE_FLOAT].shader =
-         panvk_meta_clear_attachments_shader(
+      dev->meta.clear_attachment.color[rt][GLSL_TYPE_FLOAT].shader =
+         panvk_meta_clear_color_attachment_shader(
                &dev->pdev,
                &dev->meta.bin_pool.base,
                rt,
                GLSL_TYPE_FLOAT,
-               &dev->meta.clear_attachment[rt][GLSL_TYPE_FLOAT].shader_info);
+               &dev->meta.clear_attachment.color[rt][GLSL_TYPE_FLOAT].shader_info);
    }
+
+   dev->meta.clear_attachment.z.shader =
+         panvk_meta_clear_zs_attachment_shader(
+               &dev->pdev,
+               &dev->meta.bin_pool.base,
+               true, false,
+               GLSL_TYPE_FLOAT,
+               &dev->meta.clear_attachment.z.shader_info);
+   dev->meta.clear_attachment.s.shader =
+         panvk_meta_clear_zs_attachment_shader(
+               &dev->pdev,
+               &dev->meta.bin_pool.base,
+               false, true,
+               GLSL_TYPE_FLOAT,
+               &dev->meta.clear_attachment.s.shader_info);
+   dev->meta.clear_attachment.zs.shader =
+         panvk_meta_clear_zs_attachment_shader(
+               &dev->pdev,
+               &dev->meta.bin_pool.base,
+               true, true,
+               GLSL_TYPE_FLOAT,
+               &dev->meta.clear_attachment.zs.shader_info);
 }
 
 void



More information about the mesa-commit mailing list