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

Author: Karmjit Mahil <[email protected]>
Date:   Thu Jul 28 15:05:27 2022 +0100

pvr: Add depth_bias_array handling on dbenable.

On dbenable depth bias is enabled so we need to write the depth
bias data into the depth_bias_array (which gets uploaded to the
device) and also setup the depth bias index (used in the control
stream).

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

---

 src/imagination/vulkan/pvr_cmd_buffer.c | 116 ++++++++++++++++++++++++++++++--
 src/imagination/vulkan/pvr_pipeline.c   |  11 ++-
 src/imagination/vulkan/pvr_private.h    |   7 +-
 3 files changed, 122 insertions(+), 12 deletions(-)

diff --git a/src/imagination/vulkan/pvr_cmd_buffer.c 
b/src/imagination/vulkan/pvr_cmd_buffer.c
index 984d24fab51..93e5a385d1b 100644
--- a/src/imagination/vulkan/pvr_cmd_buffer.c
+++ b/src/imagination/vulkan/pvr_cmd_buffer.c
@@ -1997,8 +1997,8 @@ void pvr_CmdSetDepthBias(VkCommandBuffer commandBuffer,
    struct pvr_cmd_buffer_state *const state = &cmd_buffer->state;
 
    state->dynamic.common.depth_bias.constant_factor = depthBiasConstantFactor;
-   state->dynamic.common.depth_bias.clamp = depthBiasClamp;
    state->dynamic.common.depth_bias.slope_factor = depthBiasSlopeFactor;
+   state->dynamic.common.depth_bias.clamp = depthBiasClamp;
    state->dirty.depth_bias = true;
 }
 
@@ -3546,6 +3546,97 @@ pvr_setup_isp_faces_and_control(struct pvr_cmd_buffer 
*const cmd_buffer,
    ppp_state->isp.back_b = back_b;
 }
 
+static float
+pvr_calculate_final_depth_bias_contant_factor(struct pvr_device_info *dev_info,
+                                              VkFormat format,
+                                              float depth_bias)
+{
+   /* Information for future modifiers of these depth bias calculations.
+    * ==================================================================
+    * Specified depth bias equations scale the specified constant factor by a
+    * value 'r' that is guaranteed to cause a resolvable difference in depth
+    * across the entire range of depth values.
+    * For floating point depth formats 'r' is calculated by taking the maximum
+    * exponent across the triangle.
+    * For UNORM formats 'r' is constant.
+    * Here 'n' is the number of mantissa bits stored in the floating point
+    * representation (23 for F32).
+    *
+    *    UNORM Format -> z += dbcf * r + slope
+    *    FLOAT Format -> z += dbcf * 2^(e-n) + slope
+    *
+    * HW Variations.
+    * ==============
+    * The HW either always performs the F32 depth bias equation (exponent based
+    * r), or in the case of HW that correctly supports the integer depth bias
+    * equation for UNORM depth formats, we can select between both equations
+    * using the ROGUE_CR_ISP_CTL.dbias_is_int flag - this is required to
+    * correctly perform Vulkan UNORM depth bias (constant r).
+    *
+    *    if ern42307:
+    *       if DBIAS_IS_INT_EN:
+    *          z += dbcf + slope
+    *       else:
+    *          z += dbcf * 2^(e-n) + slope
+    *    else:
+    *       z += dbcf * 2^(e-n) + slope
+    *
+    */
+
+   float nudge_factor;
+
+   if (PVR_HAS_ERN(dev_info, 42307)) {
+      switch (format) {
+      case VK_FORMAT_D16_UNORM:
+         return depth_bias / (1 << 15);
+
+      case VK_FORMAT_D24_UNORM_S8_UINT:
+      case VK_FORMAT_X8_D24_UNORM_PACK32:
+         return depth_bias / (1 << 23);
+
+      default:
+         return depth_bias;
+      }
+   }
+
+   /* The reasoning behind clamping/nudging the value here is because UNORM
+    * depth formats can have higher precision over our underlying D32F
+    * representation for some depth ranges.
+    *
+    * When the HW scales the depth bias value by 2^(e-n) [The 'r' term'] a 
depth
+    * bias of 1 can result in a value smaller than one F32 ULP, which will get
+    * quantized to 0 - resulting in no bias.
+    *
+    * Biasing small values away from zero will ensure that small depth biases 
of
+    * 1 still yield a result and overcome Z-fighting.
+    */
+   switch (format) {
+   case VK_FORMAT_D16_UNORM:
+      depth_bias *= 512.0f;
+      nudge_factor = 1.0f;
+      break;
+
+   case VK_FORMAT_D24_UNORM_S8_UINT:
+   case VK_FORMAT_X8_D24_UNORM_PACK32:
+      depth_bias *= 2.0f;
+      nudge_factor = 2.0f;
+      break;
+
+   default:
+      nudge_factor = 0.0f;
+      break;
+   }
+
+   if (nudge_factor != 0.0f) {
+      if (depth_bias < 0.0f && depth_bias > -nudge_factor)
+         depth_bias -= nudge_factor;
+      else if (depth_bias > 0.0f && depth_bias < nudge_factor)
+         depth_bias += nudge_factor;
+   }
+
+   return depth_bias;
+}
+
 static void pvr_get_viewport_scissor_overlap(const VkViewport *const viewport,
                                              const VkRect2D *const scissor,
                                              VkRect2D *const rect_out)
@@ -3612,7 +3703,6 @@ pvr_get_geom_region_clip_align_size(struct 
pvr_device_info *const dev_info)
    return 16U + 16U * (!PVR_HAS_FEATURE(dev_info, tile_size_16x16));
 }
 
-/* FIXME: Remove device param when PVR_HAS_FEATURE() accepts const dev_info */
 static void
 pvr_setup_isp_depth_bias_scissor_state(struct pvr_cmd_buffer *const cmd_buffer)
 {
@@ -3625,8 +3715,26 @@ pvr_setup_isp_depth_bias_scissor_state(struct 
pvr_cmd_buffer *const cmd_buffer)
    struct pvr_device_info *const dev_info =
       &cmd_buffer->device->pdevice->dev_info;
 
-   if (ispctl->dbenable)
-      assert(!"Unimplemented");
+   if (ispctl->dbenable && (cmd_buffer->state.dirty.depth_bias ||
+                            cmd_buffer->depth_bias_array.size == 0)) {
+      struct pvr_depth_bias_state depth_bias = dynamic_state->depth_bias;
+
+      depth_bias.constant_factor =
+         pvr_calculate_final_depth_bias_contant_factor(
+            dev_info,
+            cmd_buffer->state.depth_format,
+            depth_bias.constant_factor);
+
+      ppp_state->depthbias_scissor_indices.depthbias_index =
+         util_dynarray_num_elements(&cmd_buffer->depth_bias_array,
+                                    __typeof__(depth_bias));
+
+      util_dynarray_append(&cmd_buffer->depth_bias_array,
+                           __typeof__(depth_bias),
+                           depth_bias);
+
+      emit_state->isp_dbsc = true;
+   }
 
    if (ispctl->scenable) {
       const uint32_t region_clip_align_size =
diff --git a/src/imagination/vulkan/pvr_pipeline.c 
b/src/imagination/vulkan/pvr_pipeline.c
index dbabeb424fb..ad06ed2a77b 100644
--- a/src/imagination/vulkan/pvr_pipeline.c
+++ b/src/imagination/vulkan/pvr_pipeline.c
@@ -1778,12 +1778,11 @@ static void pvr_graphics_pipeline_init_dynamic_state(
 
       /* TODO: Do we need the depthBiasEnable check? */
       if (!(dynamic_states & PVR_DYNAMIC_STATE_BIT_DEPTH_BIAS)) {
-         internal_dynamic_state->depth_bias.constant_factor =
-            rasterization_state->depthBiasConstantFactor;
-         internal_dynamic_state->depth_bias.clamp =
-            rasterization_state->depthBiasClamp;
-         internal_dynamic_state->depth_bias.slope_factor =
-            rasterization_state->depthBiasSlopeFactor;
+         internal_dynamic_state->depth_bias = (struct pvr_depth_bias_state){
+            .constant_factor = rasterization_state->depthBiasConstantFactor,
+            .slope_factor = rasterization_state->depthBiasSlopeFactor,
+            .clamp = rasterization_state->depthBiasClamp,
+         };
       }
    }
 
diff --git a/src/imagination/vulkan/pvr_private.h 
b/src/imagination/vulkan/pvr_private.h
index e35c96606ca..aa0e00264ef 100644
--- a/src/imagination/vulkan/pvr_private.h
+++ b/src/imagination/vulkan/pvr_private.h
@@ -761,11 +761,14 @@ struct pvr_dynamic_state {
    /* Saved information from pCreateInfo. */
    float line_width;
 
-   struct {
+   /* Do not change this. This is the format used for the depth_bias_array
+    * elements uploaded to the device.
+    */
+   struct pvr_depth_bias_state {
       /* Saved information from pCreateInfo. */
       float constant_factor;
-      float clamp;
       float slope_factor;
+      float clamp;
    } depth_bias;
    float blend_constants[4];
    struct {

Reply via email to