v3dv: implement support for depth testing
authorIago Toral Quiroga <itoral@igalia.com>
Tue, 28 Jan 2020 12:03:41 +0000 (13:03 +0100)
committerMarge Bot <eric+marge@anholt.net>
Tue, 13 Oct 2020 21:21:26 +0000 (21:21 +0000)
This ignores stencil for now and focuses on depth testing without
support for early depth testing.

To implement this we need to start considering how many of our
framebuffer attachments are color attachments, since some of the
computations we use to determine tile sizes and binning configuration
depend on this.

Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/6766>

src/broadcom/vulkan/v3dv_cmd_buffer.c
src/broadcom/vulkan/v3dv_device.c
src/broadcom/vulkan/v3dv_formats.c
src/broadcom/vulkan/v3dv_image.c
src/broadcom/vulkan/v3dv_meta_copy.c
src/broadcom/vulkan/v3dv_pipeline.c
src/broadcom/vulkan/v3dv_private.h

index 615a7ae..ca74520 100644 (file)
@@ -24,6 +24,7 @@
 #include "v3dv_private.h"
 #include "broadcom/cle/v3dx_pack.h"
 #include "util/u_pack_color.h"
+#include "vk_format_info.h"
 
 const struct v3dv_dynamic_state default_dynamic_state = {
    .viewport = {
@@ -238,7 +239,9 @@ cmd_buffer_can_merge_subpass(struct v3dv_cmd_buffer *cmd_buffer)
 
    /* FIXME: resolve attachments */
 
-   /* FIXME: also check depth/stencil attachment */
+   if (subpass->ds_attachment.attachment !=
+       prev_subpass->ds_attachment.attachment)
+      return false;
 
    return true;
 }
@@ -295,7 +298,8 @@ v3dv_cmd_buffer_start_frame(struct v3dv_cmd_buffer *cmd_buffer,
    cl_emit(&job->bcl, TILE_BINNING_MODE_CFG, config) {
       config.width_in_pixels = framebuffer->width;
       config.height_in_pixels = framebuffer->height;
-      config.number_of_render_targets = MAX2(framebuffer->attachment_count, 1);
+      config.number_of_render_targets =
+         MAX2(framebuffer->color_attachment_count, 1);
       config.multisample_mode_4x = false; /* FIXME */
       config.maximum_bpp_of_all_render_targets = framebuffer->internal_bpp;
    }
@@ -563,6 +567,23 @@ cmd_buffer_state_set_attachment_clear_color(struct v3dv_cmd_buffer *cmd_buffer,
 }
 
 static void
+cmd_buffer_state_set_attachment_clear_depth_stencil(
+   struct v3dv_cmd_buffer *cmd_buffer,
+   uint32_t attachment_idx,
+   bool clear_depth, bool clear_stencil,
+   const VkClearDepthStencilValue *ds)
+{
+   struct v3dv_cmd_buffer_attachment_state *attachment_state =
+      &cmd_buffer->state.attachments[attachment_idx];
+
+   if (clear_depth)
+      attachment_state->clear_value.z = ds->depth;
+
+   if (clear_stencil)
+      attachment_state->clear_value.s = ds->stencil;
+}
+
+static void
 cmd_buffer_state_set_clear_values(struct v3dv_cmd_buffer *cmd_buffer,
                                   uint32_t count, const VkClearValue *values)
 {
@@ -577,9 +598,18 @@ cmd_buffer_state_set_clear_values(struct v3dv_cmd_buffer *cmd_buffer,
       if (attachment->desc.loadOp != VK_ATTACHMENT_LOAD_OP_CLEAR)
          continue;
 
-      /* FIXME: support depth/stencil */
-      cmd_buffer_state_set_attachment_clear_color(cmd_buffer, i,
-                                                  &values[i].color);
+      VkImageAspectFlags aspects = vk_format_aspects(attachment->desc.format);
+      if (aspects & VK_IMAGE_ASPECT_COLOR_BIT) {
+         cmd_buffer_state_set_attachment_clear_color(cmd_buffer, i,
+                                                     &values[i].color);
+      } else if (aspects & (VK_IMAGE_ASPECT_DEPTH_BIT |
+                            VK_IMAGE_ASPECT_STENCIL_BIT)) {
+         cmd_buffer_state_set_attachment_clear_depth_stencil(
+            cmd_buffer, i,
+            aspects & VK_IMAGE_ASPECT_DEPTH_BIT,
+            aspects & VK_IMAGE_ASPECT_STENCIL_BIT,
+            &values[i].depthStencil);
+      }
    }
 }
 
@@ -701,6 +731,7 @@ setup_render_target(struct v3dv_cmd_buffer *cmd_buffer, int rt,
    const struct v3dv_framebuffer *framebuffer = state->framebuffer;
    assert(attachment_idx < framebuffer->attachment_count);
    struct v3dv_image_view *iview = framebuffer->attachments[attachment_idx];
+   assert(iview->aspects & VK_IMAGE_ASPECT_COLOR_BIT);
 
    *rt_bpp = iview->internal_bpp;
    *rt_type = iview->internal_type;
@@ -788,6 +819,25 @@ cmd_buffer_render_pass_emit_loads(struct v3dv_cmd_buffer *cmd_buffer,
       }
    }
 
+   uint32_t ds_attachment_idx = subpass->ds_attachment.attachment;
+   if (ds_attachment_idx != VK_ATTACHMENT_UNUSED) {
+      const struct v3dv_render_pass_attachment *ds_attachment =
+         &state->pass->attachments[ds_attachment_idx];
+      const struct v3dv_cmd_buffer_attachment_state *ds_attachment_state =
+         &state->attachments[ds_attachment_idx];
+
+      assert(state->job->first_subpass >= ds_attachment_state->first_subpass);
+      bool needs_load =
+         state->job->first_subpass > ds_attachment_state->first_subpass ||
+         ds_attachment->desc.loadOp == VK_ATTACHMENT_LOAD_OP_LOAD;
+
+      if (needs_load) {
+         struct v3dv_image_view *iview =
+            framebuffer->attachments[ds_attachment_idx];
+         cmd_buffer_render_pass_emit_load(cmd_buffer, cl, iview, layer, Z);
+      }
+   }
+
    cl_emit(cl, END_OF_LOADS, end);
 }
 
@@ -869,7 +919,7 @@ cmd_buffer_render_pass_emit_stores(struct v3dv_cmd_buffer *cmd_buffer,
       has_stores = true;
    }
 
-   /* FIXME: depth/stencil store
+   /* FIXME: separate stencil
     *
     * GFXH-1461/GFXH-1689: The per-buffer store command's clear
     * buffer bit is broken for depth/stencil.  In addition, the
@@ -882,6 +932,25 @@ cmd_buffer_render_pass_emit_stores(struct v3dv_cmd_buffer *cmd_buffer,
     * not want to do that. We might want to consider emitting clears for
     * all RTs needing clearing just once ahead of the first subpass.
     */
+   bool needs_ds_clear = false;
+   uint32_t ds_attachment_idx = subpass->ds_attachment.attachment;
+   if (ds_attachment_idx != VK_ATTACHMENT_UNUSED) {
+      const struct v3dv_render_pass_attachment *ds_attachment =
+         &state->pass->attachments[ds_attachment_idx];
+      const struct v3dv_cmd_buffer_attachment_state *ds_attachment_state =
+         &state->attachments[ds_attachment_idx];
+
+      /* Only clear once on the first subpass that uses the attachment */
+      assert(state->job->first_subpass >= ds_attachment_state->first_subpass);
+      needs_ds_clear =
+         state->job->first_subpass == ds_attachment_state->first_subpass &&
+         ds_attachment->desc.loadOp == VK_ATTACHMENT_LOAD_OP_CLEAR;
+
+      cmd_buffer_render_pass_emit_store(cmd_buffer, cl,
+                                        ds_attachment_idx, layer,
+                                        Z, needs_ds_clear);
+      has_stores = true;
+   }
 
    /* We always need to emit at least one dummy store */
    if (!has_stores) {
@@ -889,6 +958,14 @@ cmd_buffer_render_pass_emit_stores(struct v3dv_cmd_buffer *cmd_buffer,
          store.buffer_to_store = NONE;
       }
    }
+
+   /* FIXME: see fixme remark for depth/stencil above */
+   if (needs_ds_clear) {
+      cl_emit(cl, CLEAR_TILE_BUFFERS, clear) {
+         clear.clear_z_stencil_buffer = true;
+         clear.clear_all_render_targets = true;
+      }
+   }
 }
 
 static void
@@ -1054,13 +1131,23 @@ cmd_buffer_emit_render_pass_rcl(struct v3dv_cmd_buffer *cmd_buffer)
     * Z_STENCIL_CLEAR_VALUES must be last. The ones in between are optional
     * updates to the previous HW state.
     */
+   const uint32_t ds_attachment_idx = subpass->ds_attachment.attachment;
+
    cl_emit(rcl, TILE_RENDERING_MODE_CFG_COMMON, config) {
-      config.early_z_disable = true; /* FIXME */
       config.image_width_pixels = framebuffer->width;
       config.image_height_pixels = framebuffer->height;
       config.number_of_render_targets = MAX2(subpass->color_count, 1);
       config.multisample_mode_4x = false; /* FIXME */
       config.maximum_bpp_of_all_render_targets = framebuffer->internal_bpp;
+
+      if (ds_attachment_idx != VK_ATTACHMENT_UNUSED) {
+         const struct v3dv_image_view *iview =
+            framebuffer->attachments[ds_attachment_idx];
+         config.internal_depth_type = iview->internal_type;
+         config.early_z_disable = true; /* FIXME */
+      } else {
+         config.early_z_disable = true;
+      }
    }
 
    for (uint32_t i = 0; i < subpass->color_count; i++) {
@@ -1143,10 +1230,19 @@ cmd_buffer_emit_render_pass_rcl(struct v3dv_cmd_buffer *cmd_buffer)
    }
 
    /* Ends rendering mode config. */
-   cl_emit(rcl, TILE_RENDERING_MODE_CFG_ZS_CLEAR_VALUES, clear) {
-      clear.z_clear_value = 0; /* FIXME */
-      clear.stencil_clear_value = 0; /* FIXME */
-   };
+   if (ds_attachment_idx != VK_ATTACHMENT_UNUSED) {
+      cl_emit(rcl, TILE_RENDERING_MODE_CFG_ZS_CLEAR_VALUES, clear) {
+         clear.z_clear_value =
+            state->attachments[ds_attachment_idx].clear_value.z;
+         clear.stencil_clear_value =
+            state->attachments[ds_attachment_idx].clear_value.s;
+      };
+   } else {
+      cl_emit(rcl, TILE_RENDERING_MODE_CFG_ZS_CLEAR_VALUES, clear) {
+         clear.z_clear_value = 1.0f;
+         clear.stencil_clear_value = 0;
+      };
+   }
 
    /* Always set initial block size before the first branch, which needs
     * to match the value from binning mode config.
index 34e504b..417f121 100644 (file)
@@ -1659,7 +1659,9 @@ compute_internal_bpp_from_attachments(struct v3dv_framebuffer *framebuffer)
    uint8_t max_bpp = RENDER_TARGET_MAXIMUM_32BPP;
    for (uint32_t i = 0; i < framebuffer->attachment_count; i++) {
       const struct v3dv_image_view *att = framebuffer->attachments[i];
-      if (att)
+      assert(att);
+
+      if (att->aspects & VK_IMAGE_ASPECT_COLOR_BIT)
          max_bpp = MAX2(max_bpp, att->internal_bpp);
    }
    framebuffer->internal_bpp = max_bpp;
@@ -1680,9 +1682,9 @@ v3dv_framebuffer_compute_tiling_params(struct v3dv_framebuffer *framebuffer)
 
    /* FIXME: MSAA */
 
-   if (framebuffer->attachment_count > 2)
+   if (framebuffer->color_attachment_count > 2)
       tile_size_index += 2;
-   else if (framebuffer->attachment_count > 1)
+   else if (framebuffer->color_attachment_count > 1)
       tile_size_index += 1;
 
    tile_size_index += framebuffer->internal_bpp;
@@ -1739,9 +1741,12 @@ v3dv_CreateFramebuffer(VkDevice _device,
    framebuffer->height = pCreateInfo->height;
    framebuffer->layers = pCreateInfo->layers;
    framebuffer->attachment_count = pCreateInfo->attachmentCount;
+   framebuffer->color_attachment_count = 0;
    for (uint32_t i = 0; i < pCreateInfo->attachmentCount; i++) {
       framebuffer->attachments[i] =
          v3dv_image_view_from_handle(pCreateInfo->pAttachments[i]);
+      if (framebuffer->attachments[i]->aspects & VK_IMAGE_ASPECT_COLOR_BIT)
+         framebuffer->color_attachment_count++;
    }
 
    compute_internal_bpp_from_attachments(framebuffer);
index 803544e..ad1da91 100644 (file)
 #define SWIZ_000X      SWIZ(0, 0, 0, X)
 
 static const struct v3dv_format format_table[] = {
-   FORMAT(R8G8B8A8_SRGB,           SRGB8_ALPHA8, RGBA8,       SWIZ_XYZW, 16),
-   FORMAT(B8G8R8A8_SRGB,           SRGB8_ALPHA8, RGBA8,       SWIZ_ZYXW, 16),
-   FORMAT(R8G8B8A8_UNORM,          RGBA8,        RGBA8,       SWIZ_XYZW, 16),
-   FORMAT(B8G8R8A8_UNORM,          RGBA8,        RGBA8,       SWIZ_ZYXW, 16),
-   FORMAT(R32G32B32A32_SFLOAT,     RGBA32F,      RGBA32F,     SWIZ_XYZW, 32),
+   /* Color */
+   FORMAT(R8G8B8A8_SRGB,           SRGB8_ALPHA8, RGBA8,         SWIZ_XYZW, 16),
+   FORMAT(B8G8R8A8_SRGB,           SRGB8_ALPHA8, RGBA8,         SWIZ_ZYXW, 16),
+   FORMAT(R8G8B8A8_UNORM,          RGBA8,        RGBA8,         SWIZ_XYZW, 16),
+   FORMAT(B8G8R8A8_UNORM,          RGBA8,        RGBA8,         SWIZ_ZYXW, 16),
+   FORMAT(R32G32B32A32_SFLOAT,     RGBA32F,      RGBA32F,       SWIZ_XYZW, 32),
+   FORMAT(R32G32B32A32_SFLOAT,     RGBA32F,      RGBA32F,       SWIZ_XYZW, 32),
+
+   /* Depth */
+   FORMAT(D16_UNORM,               D16,          DEPTH_COMP16,  SWIZ_XXXX, 32),
+   FORMAT(D32_SFLOAT,              D32F,         DEPTH_COMP32F, SWIZ_XXXX, 32),
+   FORMAT(X8_D24_UNORM_PACK32,     D24S8,        DEPTH24_X8,    SWIZ_XXXX, 32),
 };
 
 const struct v3dv_format *
@@ -228,7 +235,9 @@ image_format_features(VkFormat vk_format,
 
    const VkImageAspectFlags aspects = vk_format_aspects(vk_format);
 
-   if (aspects != VK_IMAGE_ASPECT_COLOR_BIT)
+   const uint32_t supported_aspects =
+      VK_IMAGE_ASPECT_COLOR_BIT | VK_IMAGE_ASPECT_DEPTH_BIT;
+   if ((aspects & supported_aspects) != aspects)
       return 0;
 
    VkFormatFeatureFlags flags =
@@ -239,9 +248,13 @@ image_format_features(VkFormat vk_format,
       VK_FORMAT_FEATURE_TRANSFER_DST_BIT;
 
    if (v3dv_format->rt_type != V3D_OUTPUT_IMAGE_FORMAT_NO) {
-      flags |= VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT |
-               VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT |
-               VK_FORMAT_FEATURE_BLIT_DST_BIT;
+      flags |= VK_FORMAT_FEATURE_BLIT_DST_BIT;
+      if (aspects & VK_IMAGE_ASPECT_COLOR_BIT) {
+         flags |= VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT |
+                  VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT;
+      } else if (aspects & VK_IMAGE_ASPECT_DEPTH_BIT) {
+         flags |= VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT;
+      }
    }
 
    return flags;
index 80516c6..1ac33d1 100644 (file)
@@ -411,10 +411,6 @@ v3dv_CreateImageView(VkDevice _device,
    assert(range->layerCount > 0);
    assert(range->baseMipLevel < image->levels);
 
-   /* FIXME: we don't handle depth/stencil yet */
-   assert((range->aspectMask &
-           (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT)) == 0);
-
 #ifdef DEBUG
    switch (image->type) {
    case VK_IMAGE_TYPE_1D:
index a7bb115..9a58b7b 100644 (file)
@@ -285,6 +285,7 @@ setup_framebuffer_params(struct v3dv_framebuffer *fb,
     * only the framebuffer size and the internal bpp.
     */
    fb->attachment_count = 0;
+   fb->color_attachment_count = 0;
 
    v3dv_framebuffer_compute_tiling_params(fb);
 }
index fd13a94..b3bb7ef 100644 (file)
@@ -963,10 +963,10 @@ pack_cfg_bits(struct v3dv_pipeline *pipeline,
       /* Note: ez state may update based on the compiled FS, along with zsa
        * (FIXME: not done)
        */
-      config.early_z_updates_enable = true;
+      config.early_z_updates_enable = false;
       if (ds_info && ds_info->depthTestEnable) {
-         config.z_updates_enable = false;
-         config.early_z_enable = config.early_z_enable;
+         config.z_updates_enable = true;
+         config.early_z_enable = false;
          config.depth_test_function = ds_info->depthCompareOp;
       } else {
          config.depth_test_function = VK_COMPARE_OP_ALWAYS;
index f3fb8f8..7ab3ca0 100644 (file)
@@ -386,6 +386,7 @@ struct v3dv_framebuffer {
    uint32_t frame_height_in_supertiles;
 
    uint32_t attachment_count;
+   uint32_t color_attachment_count;
    struct v3dv_image_view *attachments[0];
 };