radv/gfx10: implement a GE bug workaround
[mesa.git] / src / amd / vulkan / radv_image.c
index 6245873a4edcf94ccab95bf91e430220353fb5d6..f3237dd5985fc442845d6d06b4894f74ab24b698 100644 (file)
@@ -83,9 +83,12 @@ radv_use_tc_compat_htile_for_image(struct radv_device *device,
                return false;
 
        /* FIXME: for some reason TC compat with 2/4/8 samples breaks some cts
-        * tests - disable for now */
+        * tests - disable for now. On GFX10 D32_SFLOAT is affected as well.
+        */
        if (pCreateInfo->samples >= 2 &&
-           pCreateInfo->format == VK_FORMAT_D32_SFLOAT_S8_UINT)
+           (pCreateInfo->format == VK_FORMAT_D32_SFLOAT_S8_UINT ||
+            (pCreateInfo->format == VK_FORMAT_D32_SFLOAT &&
+             device->physical_device->rad_info.chip_class == GFX10)))
                return false;
 
        /* GFX9 supports both 32-bit and 16-bit depth surfaces, while GFX8 only
@@ -519,7 +522,7 @@ si_set_mutable_tex_desc_fields(struct radv_device *device,
                }
 
                state[7] = meta_va >> 16;
-       } else if (chip_class >= GFX9) {
+       } else if (chip_class == GFX9) {
                state[3] &= C_008F1C_SW_MODE;
                state[4] &= C_008F20_PITCH;
 
@@ -614,6 +617,15 @@ static unsigned gfx9_border_color_swizzle(const enum vk_swizzle swizzle[4])
        return bc_swizzle;
 }
 
+static bool vi_alpha_is_on_msb(struct radv_device *device, VkFormat format)
+{
+       const struct vk_format_description *desc = vk_format_description(format);
+
+       if (device->physical_device->rad_info.chip_class >= GFX10 && desc->nr_channels == 1)
+               return desc->swizzle[3] == VK_SWIZZLE_X;
+
+       return radv_translate_colorswap(format, false) <= 1;
+}
 /**
  * Build the sampler view descriptor for a texture (GFX10).
  */
@@ -646,7 +658,7 @@ gfx10_make_texture_descriptor(struct radv_device *device,
        }
 
        type = radv_tex_dim(image->type, view_type, image->info.array_size, image->info.samples,
-                           is_storage_image, device->physical_device->rad_info.chip_class >= GFX9);
+                           is_storage_image, device->physical_device->rad_info.chip_class == GFX9);
        if (type == V_008F1C_SQ_RSRC_IMG_1D_ARRAY) {
                height = 1;
                depth = image->info.array_size;
@@ -688,11 +700,9 @@ gfx10_make_texture_descriptor(struct radv_device *device,
        state[7] = 0;
 
        if (radv_dcc_enabled(image, first_level)) {
-               unsigned swap = radv_translate_colorswap(vk_format, FALSE);
-
                state[6] |= S_00A018_MAX_UNCOMPRESSED_BLOCK_SIZE(V_028C78_MAX_BLOCK_SIZE_256B) |
                            S_00A018_MAX_COMPRESSED_BLOCK_SIZE(V_028C78_MAX_BLOCK_SIZE_128B) |
-                           S_00A018_ALPHA_IS_ON_MSB(swap <= 1);
+                           S_00A018_ALPHA_IS_ON_MSB(vi_alpha_is_on_msb(device, vk_format));
        }
 
        /* Initialize the sampler view for FMASK. */
@@ -784,7 +794,7 @@ si_make_texture_descriptor(struct radv_device *device,
        }
 
        /* S8 with either Z16 or Z32 HTILE need a special format. */
-       if (device->physical_device->rad_info.chip_class >= GFX9 &&
+       if (device->physical_device->rad_info.chip_class == GFX9 &&
            vk_format == VK_FORMAT_S8_UINT &&
            radv_image_is_tc_compat_htile(image)) {
                if (image->vk_format == VK_FORMAT_D32_SFLOAT_S8_UINT)
@@ -793,7 +803,7 @@ si_make_texture_descriptor(struct radv_device *device,
                        data_format = V_008F14_IMG_DATA_FORMAT_S8_16;
        }
        type = radv_tex_dim(image->type, view_type, image->info.array_size, image->info.samples,
-                           is_storage_image, device->physical_device->rad_info.chip_class >= GFX9);
+                           is_storage_image, device->physical_device->rad_info.chip_class == GFX9);
        if (type == V_008F1C_SQ_RSRC_IMG_1D_ARRAY) {
                height = 1;
                depth = image->info.array_size;
@@ -825,7 +835,7 @@ si_make_texture_descriptor(struct radv_device *device,
        state[6] = 0;
        state[7] = 0;
 
-       if (device->physical_device->rad_info.chip_class >= GFX9) {
+       if (device->physical_device->rad_info.chip_class == GFX9) {
                unsigned bc_swizzle = gfx9_border_color_swizzle(swizzle);
 
                /* Depth is the last accessible layer on Gfx9.
@@ -846,9 +856,7 @@ si_make_texture_descriptor(struct radv_device *device,
                state[5] |= S_008F24_LAST_ARRAY(last_layer);
        }
        if (image->dcc_offset) {
-               unsigned swap = radv_translate_colorswap(vk_format, FALSE);
-
-               state[6] = S_008F28_ALPHA_IS_ON_MSB(swap <= 1);
+               state[6] = S_008F28_ALPHA_IS_ON_MSB(vi_alpha_is_on_msb(device, vk_format));
        } else {
                /* The last dword is unused by hw. The shader uses it to clear
                 * bits in the first dword of sampler state.
@@ -871,7 +879,7 @@ si_make_texture_descriptor(struct radv_device *device,
 
                va = gpu_address + image->offset + image->fmask.offset;
 
-               if (device->physical_device->rad_info.chip_class >= GFX9) {
+               if (device->physical_device->rad_info.chip_class == GFX9) {
                        fmask_format = V_008F14_IMG_DATA_FORMAT_FMASK;
                        switch (image->info.samples) {
                        case 2:
@@ -921,7 +929,7 @@ si_make_texture_descriptor(struct radv_device *device,
                fmask_state[6] = 0;
                fmask_state[7] = 0;
 
-               if (device->physical_device->rad_info.chip_class >= GFX9) {
+               if (device->physical_device->rad_info.chip_class == GFX9) {
                        fmask_state[3] |= S_008F1C_SW_MODE(image->planes[0].surface.u.gfx9.fmask.swizzle_mode);
                        fmask_state[4] |= S_008F20_DEPTH(last_layer) |
                                          S_008F20_PITCH(image->planes[0].surface.u.gfx9.fmask.epitch);
@@ -1031,7 +1039,8 @@ radv_query_opaque_metadata(struct radv_device *device,
                for (i = 0; i <= image->info.levels - 1; i++)
                        md->metadata[10+i] = image->planes[0].surface.u.legacy.level[i].offset >> 8;
                md->size_metadata = (11 + image->info.levels - 1) * 4;
-       }
+       } else
+               md->size_metadata = 10 * 4;
 }
 
 void
@@ -1183,14 +1192,15 @@ radv_image_alloc_dcc(struct radv_image *image)
 }
 
 static void
-radv_image_alloc_htile(struct radv_image *image)
+radv_image_alloc_htile(struct radv_device *device, struct radv_image *image)
 {
        image->htile_offset = align64(image->size, image->planes[0].surface.htile_alignment);
 
        /* + 8 for storing the clear values */
        image->clear_value_offset = image->htile_offset + image->planes[0].surface.htile_size;
        image->size = image->clear_value_offset + 8;
-       if (radv_image_is_tc_compat_htile(image)) {
+       if (radv_image_is_tc_compat_htile(image) &&
+           device->physical_device->has_tc_compat_zrange_bug) {
                /* Metadata for the TC-compatible HTILE hardware bug which
                 * have to be fixed by updating ZRANGE_PRECISION when doing
                 * fast depth clears to 0.0f.
@@ -1399,7 +1409,7 @@ radv_image_create(VkDevice _device,
                        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(image);
+                               radv_image_alloc_htile(device, image);
                        } else {
                                radv_image_disable_htile(image);
                        }