radv: Rely on ac_surface for avoiding cmask for linear images.
[mesa.git] / src / amd / vulkan / radv_image.c
index d52924d300f7a47707af770ac4d4b30ce78dc1ab..a4a622a0d815e931f991320150de479cddd9c178 100644 (file)
 #include "sid.h"
 #include "util/debug.h"
 #include "util/u_atomic.h"
-
-struct gfx10_format {
-    unsigned img_format:9;
-
-    /* Various formats are only supported with workarounds for vertex fetch,
-     * and some 32_32_32 formats are supported natively, but only for buffers
-     * (possibly with some image support, actually, but no filtering). */
-    bool buffers_only:1;
-};
+#include "vulkan/util/vk_format.h"
 
 #include "gfx10_format_table.h"
 
@@ -238,6 +230,13 @@ radv_use_dcc_for_image(struct radv_device *device,
        return true;
 }
 
+static inline bool
+radv_use_fmask_for_image(const struct radv_image *image)
+{
+       return image->info.samples > 1 &&
+              image->usage & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
+}
+
 static bool
 radv_use_tc_compat_cmask_for_image(struct radv_device *device,
                                   struct radv_image *image)
@@ -448,6 +447,9 @@ radv_init_surface(struct radv_device *device,
                unreachable("unhandled image type");
        }
 
+       /* Required for clearing/initializing a specific layer on GFX8. */
+       surface->flags |= RADEON_SURF_CONTIGUOUS_DCC_LAYERS;
+
        if (is_depth) {
                surface->flags |= RADEON_SURF_ZBUFFER;
                if (radv_use_tc_compat_htile_for_image(device, pCreateInfo, image_format))
@@ -466,6 +468,9 @@ radv_init_surface(struct radv_device *device,
        if (!radv_use_dcc_for_image(device, image, pCreateInfo, image_format))
                surface->flags |= RADEON_SURF_DISABLE_DCC;
 
+       if (!radv_use_fmask_for_image(image))
+               surface->flags |= RADEON_SURF_NO_FMASK;
+
        return 0;
 }
 
@@ -530,7 +535,7 @@ radv_make_buffer_descriptor(struct radv_device *device,
                   S_008F0C_DST_SEL_W(radv_map_swizzle(desc->swizzle[3]));
 
        if (device->physical_device->rad_info.chip_class >= GFX10) {
-               const struct gfx10_format *fmt = gfx10_format_description(vk_format);
+               const struct gfx10_format *fmt = &gfx10_format_table[vk_format_to_pipe_format(vk_format)];
 
                /* OOB_SELECT chooses the out-of-bounds check:
                 *  - 0: (index >= NUM_RECORDS) || (offset >= STRIDE)
@@ -760,7 +765,7 @@ gfx10_make_texture_descriptor(struct radv_device *device,
        unsigned type;
 
        desc = vk_format_description(vk_format);
-       img_format = gfx10_format_description(vk_format)->img_format;
+       img_format = gfx10_format_table[vk_format_to_pipe_format(vk_format)].img_format;
 
        if (desc->colorspace == VK_FORMAT_COLORSPACE_ZS) {
                const unsigned char swizzle_xxxx[4] = {0, 0, 0, 0};
@@ -1286,21 +1291,6 @@ radv_image_can_enable_dcc(struct radv_device *device, struct radv_image *image)
            !radv_image_has_dcc(image))
                return false;
 
-       /* On GFX8, DCC layers can be interleaved and it's currently only
-        * enabled if slice size is equal to the per slice fast clear size
-        * because the driver assumes that portions of multiple layers are
-        * contiguous during fast clears.
-        */
-       if (image->info.array_size > 1) {
-               const struct legacy_surf_level *surf_level =
-                       &image->planes[0].surface.u.legacy.level[0];
-
-               assert(device->physical_device->rad_info.chip_class == GFX8);
-
-               if (image->planes[0].surface.dcc_slice_size != surf_level->dcc_fast_clear_size)
-                       return false;
-       }
-
        return true;
 }
 
@@ -1317,15 +1307,7 @@ radv_image_can_enable_cmask(struct radv_image *image)
 
        return radv_image_can_enable_dcc_or_cmask(image) &&
               image->info.levels == 1 &&
-              image->info.depth == 1 &&
-              !image->planes[0].surface.is_linear;
-}
-
-static inline bool
-radv_image_can_enable_fmask(struct radv_image *image)
-{
-       return image->info.samples > 1 &&
-              image->usage & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
+              image->info.depth == 1;
 }
 
 static inline bool
@@ -1379,6 +1361,12 @@ radv_image_create_layout(struct radv_device *device,
                        info.height /= desc->height_divisor;
                }
 
+               if (create_info.no_metadata_planes || image->plane_count > 1) {
+                       image->planes[plane].surface.flags |= RADEON_SURF_DISABLE_DCC |
+                                                             RADEON_SURF_NO_FMASK |
+                                                             RADEON_SURF_NO_HTILE;
+               }
+
                device->ws->surface_init(device->ws, &info, &image->planes[plane].surface);
 
                image->planes[plane].offset = align(image->size, image->planes[plane].surface.surf_alignment);
@@ -1388,44 +1376,39 @@ radv_image_create_layout(struct radv_device *device,
                image->planes[plane].format = vk_format_get_plane_format(image->vk_format, plane);
        }
 
-       if (!create_info.no_metadata_planes) {
-               /* Try to enable DCC first. */
-               if (radv_image_can_enable_dcc(device, image)) {
-                       radv_image_alloc_dcc(image);
-                       if (image->info.samples > 1) {
-                               /* CMASK should be enabled because DCC fast
-                                * clear with MSAA needs it.
-                                */
-                               assert(radv_image_can_enable_cmask(image));
-                               radv_image_alloc_cmask(device, image);
-                       }
-               } else {
-                       /* When DCC cannot be enabled, try CMASK. */
-                       radv_image_disable_dcc(image);
-                       if (radv_image_can_enable_cmask(image)) {
-                               radv_image_alloc_cmask(device, image);
-                       }
+       /* Try to enable DCC first. */
+       if (radv_image_can_enable_dcc(device, image)) {
+               radv_image_alloc_dcc(image);
+               if (image->info.samples > 1) {
+                       /* CMASK should be enabled because DCC fast
+                        * clear with MSAA needs it.
+                        */
+                       assert(radv_image_can_enable_cmask(image));
+                       radv_image_alloc_cmask(device, image);
                }
+       } else {
+               /* When DCC cannot be enabled, try CMASK. */
+               radv_image_disable_dcc(image);
+               if (radv_image_can_enable_cmask(image)) {
+                       radv_image_alloc_cmask(device, image);
+               }
+       }
 
-               /* Try to enable FMASK for multisampled images. */
-               if (radv_image_can_enable_fmask(image)) {
-                       radv_image_alloc_fmask(device, image);
+       /* Try to enable FMASK for multisampled images. */
+       if (image->planes[0].surface.fmask_size) {
+               radv_image_alloc_fmask(device, image);
 
-                       if (radv_use_tc_compat_cmask_for_image(device, image))
-                               image->tc_compatible_cmask = true;
+               if (radv_use_tc_compat_cmask_for_image(device, image))
+                       image->tc_compatible_cmask = true;
+       } else {
+               /* Otherwise, try to enable HTILE for depth surfaces. */
+               if (radv_image_can_enable_htile(image) &&
+                   !(device->instance->debug_flags & RADV_DEBUG_NO_HIZ)) {
+                       image->tc_compatible_htile = image->planes[0].surface.flags & RADEON_SURF_TC_COMPATIBLE_HTILE;
+                       radv_image_alloc_htile(device, image);
                } else {
-                       /* Otherwise, try to enable HTILE for depth surfaces. */
-                       if (radv_image_can_enable_htile(image) &&
-                           !(device->instance->debug_flags & RADV_DEBUG_NO_HIZ)) {
-                               image->tc_compatible_htile = image->planes[0].surface.flags & RADEON_SURF_TC_COMPATIBLE_HTILE;
-                               radv_image_alloc_htile(device, image);
-                       } else {
-                               radv_image_disable_htile(image);
-                       }
+                       radv_image_disable_htile(image);
                }
-       } else {
-               radv_image_disable_dcc(image);
-               radv_image_disable_htile(image);
        }
 
        assert(image->planes[0].surface.surf_size);