radv: fix potential HTILE issues for TC-compat images on GFX8
authorSamuel Pitoiset <samuel.pitoiset@gmail.com>
Wed, 9 Dec 2020 16:48:56 +0000 (17:48 +0100)
committerMarge Bot <eric+marge@anholt.net>
Tue, 5 Jan 2021 12:10:11 +0000 (12:10 +0000)
We can only use the entire HTILE buffer if TILE_STENCIL_DISABLE is
TRUE. On GFX8+, this is only true if the depth image has no stencil
and if it's not TC-compatible because of the ZRANGE_PRECISION issue.

Signed-off-by: Samuel Pitoiset <samuel.pitoiset@gmail.com>
Reviewed-by: Bas Nieuwenhuizen <bas@basnieuwenhuizen.nl>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/8039>

src/amd/vulkan/radv_cmd_buffer.c
src/amd/vulkan/radv_device.c
src/amd/vulkan/radv_meta_clear.c
src/amd/vulkan/radv_private.h

index 3d61a91..3f8c01f 100644 (file)
@@ -6000,7 +6000,7 @@ static void radv_initialize_htile(struct radv_cmd_buffer *cmd_buffer,
        assert(range->levelCount == 1 || range->levelCount == VK_REMAINING_ARRAY_LAYERS);
        VkImageAspectFlags aspects = VK_IMAGE_ASPECT_DEPTH_BIT;
        struct radv_cmd_state *state = &cmd_buffer->state;
-       uint32_t htile_value = vk_format_is_stencil(image->vk_format) ? 0xfffff3ff : 0xfffc000f;
+       uint32_t htile_value = radv_image_tile_stencil_disabled(cmd_buffer->device, image) ? 0xfffc000f : 0xfffff3ff;
        VkClearDepthStencilValue value = {0};
        struct radv_barrier_data barrier = {0};
 
index 0c84d04..b8a6fb0 100644 (file)
@@ -7103,9 +7103,10 @@ radv_initialise_ds_surface(struct radv_device *device,
                                }
                        }
 
-                       if (!surf->has_stencil)
-                               /* Use all of the htile_buffer for depth if there's no stencil. */
+                       if (radv_image_tile_stencil_disabled(device, iview->image)) {
                                ds->db_stencil_info |= S_02803C_TILE_STENCIL_DISABLE(1);
+                       }
+
                        va = radv_buffer_get_va(iview->bo) + iview->image->offset +
                                surf->htile_offset;
                        ds->db_htile_data_base = va >> 8;
@@ -7169,10 +7170,9 @@ radv_initialise_ds_surface(struct radv_device *device,
                if (radv_htile_enabled(iview->image, level)) {
                        ds->db_z_info |= S_028040_TILE_SURFACE_ENABLE(1);
 
-                       if (!surf->has_stencil &&
-                           !radv_image_is_tc_compat_htile(iview->image))
-                               /* Use all of the htile_buffer for depth if there's no stencil. */
+                       if (radv_image_tile_stencil_disabled(device, iview->image)) {
                                ds->db_stencil_info |= S_028044_TILE_STENCIL_DISABLE(1);
+                       }
 
                        va = radv_buffer_get_va(iview->bo) + iview->image->offset +
                                surf->htile_offset;
index 8b95fdb..2f09ec9 100644 (file)
@@ -945,12 +945,13 @@ clear_htile_mask(struct radv_cmd_buffer *cmd_buffer,
 }
 
 static uint32_t
-radv_get_htile_fast_clear_value(const struct radv_image *image,
+radv_get_htile_fast_clear_value(const struct radv_device *device,
+                               const struct radv_image *image,
                                VkClearDepthStencilValue value)
 {
        uint32_t clear_value;
 
-       if (!image->planes[0].surface.has_stencil) {
+       if (radv_image_tile_stencil_disabled(device, image)) {
                clear_value = value.depth ? 0xfffffff0 : 0;
        } else {
                clear_value = value.depth ? 0xfffc00f0 : 0xf0;
@@ -960,11 +961,12 @@ radv_get_htile_fast_clear_value(const struct radv_image *image,
 }
 
 static uint32_t
-radv_get_htile_mask(const struct radv_image *image, VkImageAspectFlags aspects)
+radv_get_htile_mask(const struct radv_device *device,
+                   const struct radv_image *image, VkImageAspectFlags aspects)
 {
        uint32_t mask = 0;
 
-       if (!image->planes[0].surface.has_stencil) {
+       if (radv_image_tile_stencil_disabled(device, image)) {
                /* All the HTILE buffer is used when there is no stencil. */
                mask = UINT32_MAX;
        } else {
@@ -1099,7 +1101,7 @@ radv_fast_clear_depth(struct radv_cmd_buffer *cmd_buffer,
        VkImageAspectFlags aspects = clear_att->aspectMask;
        uint32_t clear_word, flush_bits;
 
-       clear_word = radv_get_htile_fast_clear_value(iview->image, clear_value);
+       clear_word = radv_get_htile_fast_clear_value(cmd_buffer->device, iview->image, clear_value);
 
        if (pre_flush) {
                cmd_buffer->state.flush_bits |= (RADV_CMD_FLAG_FLUSH_AND_INV_DB |
@@ -1505,7 +1507,7 @@ radv_clear_htile(struct radv_cmd_buffer *cmd_buffer,
                          image->planes[0].surface.htile_slice_size * range->baseArrayLayer;
        uint32_t htile_mask, flush_bits;
 
-       htile_mask = radv_get_htile_mask(image, range->aspectMask);
+       htile_mask = radv_get_htile_mask(cmd_buffer->device, image, range->aspectMask);
 
        if (htile_mask == UINT_MAX) {
                /* Clear the whole HTILE buffer. */
index 54a00ca..cfc517c 100644 (file)
@@ -54,6 +54,7 @@
 #include "vk_alloc.h"
 #include "vk_debug_report.h"
 #include "vk_object.h"
+#include "vk_format.h"
 
 #include "radv_radeon_winsys.h"
 #include "ac_binary.h"
@@ -2023,6 +2024,25 @@ radv_image_is_tc_compat_htile(const struct radv_image *image)
        return radv_image_has_htile(image) && image->tc_compatible_htile;
 }
 
+/**
+ * Return whether the entire HTILE buffer can be used for depth in order to
+ * improve HiZ Z-Range precision.
+ */
+static inline bool
+radv_image_tile_stencil_disabled(const struct radv_device *device,
+                                const struct radv_image *image)
+{
+       if (device->physical_device->rad_info.chip_class >= GFX9) {
+               return !vk_format_is_stencil(image->vk_format);
+       } else {
+               /* Due to a hw bug, TILE_STENCIL_DISABLE must be set to 0 for
+                * the TC-compat ZRANGE issue even if no stencil is used.
+                */
+               return !vk_format_is_stencil(image->vk_format) &&
+                      !radv_image_is_tc_compat_htile(image);
+       }
+}
+
 static inline uint64_t
 radv_image_get_fast_clear_va(const struct radv_image *image,
                             uint32_t base_level)