Mesa (main): radv: disable viewport depth clamping only when necessary

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Tue Jul 19 09:25:59 UTC 2022


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

Author: Samuel Pitoiset <samuel.pitoiset at gmail.com>
Date:   Thu May  5 16:53:13 2022 +0200

radv: disable viewport depth clamping only when necessary

When the application uses depth values outside of the [0.0,1.0] range
with VK_EXT_depth_range_unrestricted, or when explicitly disabled.
Otherwise, the driver can clamp to [0.0,1.0] internally for optimal
performance.

>From the Vulkan spec "in 28.10.1. Depth Clamping and Range Adjustment":

    "If depth clamping is not enabled and zf is not in the range [0, 1]
    and either VK_EXT_depth_range_unrestricted is not enabled, or the
    depth attachment has a fixed-point format, then zf is undefined
    following this step."

Signed-off-by: Samuel Pitoiset <samuel.pitoiset at gmail.com>
Reviewed-by: Timur Kristóf <timur.kristof at gmail.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/16349>

---

 src/amd/vulkan/radv_cmd_buffer.c | 16 ++++++++++++----
 src/amd/vulkan/radv_pipeline.c   | 32 +++++++++++++++++---------------
 src/amd/vulkan/radv_private.h    |  7 +++++++
 3 files changed, 36 insertions(+), 19 deletions(-)

diff --git a/src/amd/vulkan/radv_cmd_buffer.c b/src/amd/vulkan/radv_cmd_buffer.c
index 8f39dacbec3..7c1c90d72f6 100644
--- a/src/amd/vulkan/radv_cmd_buffer.c
+++ b/src/amd/vulkan/radv_cmd_buffer.c
@@ -1426,7 +1426,7 @@ radv_emit_graphics_pipeline(struct radv_cmd_buffer *cmd_buffer)
 static void
 radv_emit_viewport(struct radv_cmd_buffer *cmd_buffer)
 {
-   bool negative_one_to_one = cmd_buffer->state.graphics_pipeline->negative_one_to_one;
+   const struct radv_graphics_pipeline *pipeline = cmd_buffer->state.graphics_pipeline;
    const struct radv_viewport_state *viewport = &cmd_buffer->state.dynamic.viewport;
    int i;
    const unsigned count = viewport->count;
@@ -1441,7 +1441,7 @@ radv_emit_viewport(struct radv_cmd_buffer *cmd_buffer)
       radeon_emit(cmd_buffer->cs, fui(viewport->xform[i].translate[1]));
 
       double scale_z, translate_z;
-      if (negative_one_to_one) {
+      if (pipeline->negative_one_to_one) {
          scale_z = viewport->xform[i].scale[2] * 0.5f;
          translate_z = (viewport->xform[i].translate[2] + viewport->viewports[i].maxDepth) * 0.5f;
       } else {
@@ -1455,8 +1455,16 @@ radv_emit_viewport(struct radv_cmd_buffer *cmd_buffer)
 
    radeon_set_context_reg_seq(cmd_buffer->cs, R_0282D0_PA_SC_VPORT_ZMIN_0, count * 2);
    for (i = 0; i < count; i++) {
-      float zmin = MIN2(viewport->viewports[i].minDepth, viewport->viewports[i].maxDepth);
-      float zmax = MAX2(viewport->viewports[i].minDepth, viewport->viewports[i].maxDepth);
+      float zmin, zmax;
+
+      if (pipeline->depth_clamp_mode == RADV_DEPTH_CLAMP_MODE_ZERO_TO_ONE) {
+         zmin = 0.0f;
+         zmax = 1.0f;
+      } else {
+         zmin = MIN2(viewport->viewports[i].minDepth, viewport->viewports[i].maxDepth);
+         zmax = MAX2(viewport->viewports[i].minDepth, viewport->viewports[i].maxDepth);
+      }
+
       radeon_emit(cmd_buffer->cs, fui(zmin));
       radeon_emit(cmd_buffer->cs, fui(zmax));
    }
diff --git a/src/amd/vulkan/radv_pipeline.c b/src/amd/vulkan/radv_pipeline.c
index 2fe53407d2f..c9a2cd88f58 100644
--- a/src/amd/vulkan/radv_pipeline.c
+++ b/src/amd/vulkan/radv_pipeline.c
@@ -2145,7 +2145,7 @@ static void
 radv_pipeline_init_raster_state(struct radv_graphics_pipeline *pipeline,
                                 const struct radv_graphics_pipeline_info *info)
 {
-   const struct radv_physical_device *pdevice = pipeline->base.device->physical_device;
+   const struct radv_device *device = pipeline->base.device;
 
    pipeline->pa_su_sc_mode_cntl =
       S_028814_FACE(info->rs.front_face) |
@@ -2159,7 +2159,7 @@ radv_pipeline_init_raster_state(struct radv_graphics_pipeline *pipeline,
       S_028814_POLY_OFFSET_PARA_ENABLE(info->rs.depth_bias_enable) |
       S_028814_PROVOKING_VTX_LAST(info->rs.provoking_vtx_last);
 
-   if (pdevice->rad_info.gfx_level >= GFX10) {
+   if (device->physical_device->rad_info.gfx_level >= GFX10) {
       /* It should also be set if PERPENDICULAR_ENDCAP_ENA is set. */
       pipeline->pa_su_sc_mode_cntl |=
          S_028814_KEEP_TOGETHER_ENABLE(info->rs.polygon_mode != V_028814_X_DRAW_TRIANGLES);
@@ -2174,6 +2174,20 @@ radv_pipeline_init_raster_state(struct radv_graphics_pipeline *pipeline,
 
    pipeline->uses_conservative_overestimate =
       info->rs.conservative_mode == VK_CONSERVATIVE_RASTERIZATION_MODE_OVERESTIMATE_EXT;
+
+   pipeline->depth_clamp_mode = RADV_DEPTH_CLAMP_MODE_VIEWPORT;
+   if (!info->rs.depth_clamp_enable) {
+      /* For optimal performance, depth clamping should always be enabled except if the
+       * application disables clamping explicitly or uses depth values outside of the [0.0, 1.0]
+       * range.
+       */
+      if (info->rs.depth_clip_disable ||
+          device->vk.enabled_extensions.EXT_depth_range_unrestricted) {
+         pipeline->depth_clamp_mode = RADV_DEPTH_CLAMP_MODE_DISABLED;
+      } else {
+         pipeline->depth_clamp_mode = RADV_DEPTH_CLAMP_MODE_ZERO_TO_ONE;
+      }
+   }
 }
 
 static struct radv_depth_stencil_state
@@ -2181,7 +2195,6 @@ radv_pipeline_init_depth_stencil_state(struct radv_graphics_pipeline *pipeline,
                                        const struct radv_graphics_pipeline_info *info)
 {
    const struct radv_physical_device *pdevice = pipeline->base.device->physical_device;
-   struct radv_shader *ps = pipeline->base.shaders[MESA_SHADER_FRAGMENT];
    struct radv_depth_stencil_state ds_state = {0};
    uint32_t db_depth_control = 0;
 
@@ -2210,19 +2223,8 @@ radv_pipeline_init_depth_stencil_state(struct radv_graphics_pipeline *pipeline,
    ds_state.db_render_override |= S_02800C_FORCE_HIS_ENABLE0(V_02800C_FORCE_DISABLE) |
                                   S_02800C_FORCE_HIS_ENABLE1(V_02800C_FORCE_DISABLE);
 
-   if (!info->rs.depth_clamp_enable && ps->info.ps.writes_z) {
-      /* From VK_EXT_depth_range_unrestricted spec:
-       *
-       * "The behavior described in Primitive Clipping still applies.
-       *  If depth clamping is disabled the depth values are still
-       *  clipped to 0 ≤ zc ≤ wc before the viewport transform. If
-       *  depth clamping is enabled the above equation is ignored and
-       *  the depth values are instead clamped to the VkViewport
-       *  minDepth and maxDepth values, which in the case of this
-       *  extension can be outside of the 0.0 to 1.0 range."
-       */
+   if (pipeline->depth_clamp_mode == RADV_DEPTH_CLAMP_MODE_DISABLED)
       ds_state.db_render_override |= S_02800C_DISABLE_VIEWPORT_CLAMP(1);
-   }
 
    if (pdevice->rad_info.gfx_level >= GFX11) {
       unsigned max_allowed_tiles_in_wave = 0;
diff --git a/src/amd/vulkan/radv_private.h b/src/amd/vulkan/radv_private.h
index 10f54a6f2b2..a6a5c645728 100644
--- a/src/amd/vulkan/radv_private.h
+++ b/src/amd/vulkan/radv_private.h
@@ -2078,6 +2078,12 @@ struct radv_graphics_pipeline_info {
    uint8_t ds_att_samples;
 };
 
+enum radv_depth_clamp_mode {
+   RADV_DEPTH_CLAMP_MODE_VIEWPORT = 0,       /* Clamp to the viewport min/max depth bounds */
+   RADV_DEPTH_CLAMP_MODE_ZERO_TO_ONE = 1,    /* Clamp between 0.0f and 1.0f */
+   RADV_DEPTH_CLAMP_MODE_DISABLED = 2,       /* Disable depth clamping */
+};
+
 struct radv_pipeline {
    struct vk_object_base base;
    enum radv_pipeline_type type;
@@ -2153,6 +2159,7 @@ struct radv_graphics_pipeline {
    bool uses_dynamic_stride;
    bool uses_conservative_overestimate;
    bool negative_one_to_one;
+   enum radv_depth_clamp_mode depth_clamp_mode;
    bool use_per_attribute_vb_descs;
    bool can_use_simple_input;
    bool uses_user_sample_locations;



More information about the mesa-commit mailing list