radv: disable TC-compat HTILE in GENERAL for Detroit: Become Human
The game has invalid usage of render loops and enabling TC-compat
HTILE in GENERAL introduces rendering issues.
Gitlab: https://gitlab.freedesktop.org/mesa/mesa/-/issues/3063
Cc: mesa-stable
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/8412>
diff --git a/src/amd/vulkan/radv_cmd_buffer.c b/src/amd/vulkan/radv_cmd_buffer.c
index 5555f7c..8488190 100644
--- a/src/amd/vulkan/radv_cmd_buffer.c
+++ b/src/amd/vulkan/radv_cmd_buffer.c
@@ -1694,7 +1694,7 @@
!radv_image_is_tc_compat_htile(image))
return;
- if (!radv_layout_is_htile_compressed(image, layout, in_render_loop,
+ if (!radv_layout_is_htile_compressed(cmd_buffer->device, image, layout, in_render_loop,
radv_image_queue_family_mask(image,
cmd_buffer->queue_family_index,
cmd_buffer->queue_family_index))) {
@@ -1737,7 +1737,7 @@
uint32_t db_z_info = ds->db_z_info;
uint32_t db_stencil_info = ds->db_stencil_info;
- if (!radv_layout_is_htile_compressed(image, layout, in_render_loop,
+ if (!radv_layout_is_htile_compressed(cmd_buffer->device, image, layout, in_render_loop,
radv_image_queue_family_mask(image,
cmd_buffer->queue_family_index,
cmd_buffer->queue_family_index))) {
@@ -5950,11 +5950,11 @@
if (src_layout == VK_IMAGE_LAYOUT_UNDEFINED) {
radv_initialize_htile(cmd_buffer, image, range);
- } else if (!radv_layout_is_htile_compressed(image, src_layout, src_render_loop, src_queue_mask) &&
- radv_layout_is_htile_compressed(image, dst_layout, dst_render_loop, dst_queue_mask)) {
+ } else if (!radv_layout_is_htile_compressed(cmd_buffer->device, image, src_layout, src_render_loop, src_queue_mask) &&
+ radv_layout_is_htile_compressed(cmd_buffer->device, image, dst_layout, dst_render_loop, dst_queue_mask)) {
radv_initialize_htile(cmd_buffer, image, range);
- } else if (radv_layout_is_htile_compressed(image, src_layout, src_render_loop, src_queue_mask) &&
- !radv_layout_is_htile_compressed(image, dst_layout, dst_render_loop, dst_queue_mask)) {
+ } else if (radv_layout_is_htile_compressed(cmd_buffer->device, image, src_layout, src_render_loop, src_queue_mask) &&
+ !radv_layout_is_htile_compressed(cmd_buffer->device, image, dst_layout, dst_render_loop, dst_queue_mask)) {
cmd_buffer->state.flush_bits |= RADV_CMD_FLAG_FLUSH_AND_INV_DB |
RADV_CMD_FLAG_FLUSH_AND_INV_DB_META;
diff --git a/src/amd/vulkan/radv_device.c b/src/amd/vulkan/radv_device.c
index c606423..80c622b 100644
--- a/src/amd/vulkan/radv_device.c
+++ b/src/amd/vulkan/radv_device.c
@@ -620,6 +620,14 @@
/* Fix various artifacts in Detroit: Become Human */
instance->debug_flags |= RADV_DEBUG_ZERO_VRAM |
RADV_DEBUG_DISCARD_TO_DEMOTE;
+
+ /* Fix rendering issues in Detroit: Become Human
+ * because the game uses render loops (it
+ * samples/renders from/to the same depth/stencil
+ * texture inside the same draw) without input
+ * attachments and that is invalid Vulkan usage.
+ */
+ instance->disable_tc_compat_htile_in_general = true;
}
}
diff --git a/src/amd/vulkan/radv_image.c b/src/amd/vulkan/radv_image.c
index 2bad566..edf7cf6 100644
--- a/src/amd/vulkan/radv_image.c
+++ b/src/amd/vulkan/radv_image.c
@@ -1738,7 +1738,8 @@
}
}
-bool radv_layout_is_htile_compressed(const struct radv_image *image,
+bool radv_layout_is_htile_compressed(const struct radv_device *device,
+ const struct radv_image *image,
VkImageLayout layout,
bool in_render_loop,
unsigned queue_mask)
@@ -1746,6 +1747,7 @@
if (radv_image_is_tc_compat_htile(image)) {
if (layout == VK_IMAGE_LAYOUT_GENERAL &&
!in_render_loop &&
+ !device->instance->disable_tc_compat_htile_in_general &&
!(image->usage & VK_IMAGE_USAGE_STORAGE_BIT)) {
/* It should be safe to enable TC-compat HTILE with
* VK_IMAGE_LAYOUT_GENERAL if we are not in a render
diff --git a/src/amd/vulkan/radv_meta_clear.c b/src/amd/vulkan/radv_meta_clear.c
index 4484895..0261a4d 100644
--- a/src/amd/vulkan/radv_meta_clear.c
+++ b/src/amd/vulkan/radv_meta_clear.c
@@ -733,7 +733,7 @@
iview->base_mip == 0 &&
iview->base_layer == 0 &&
iview->layer_count == iview->image->info.array_size &&
- radv_layout_is_htile_compressed(iview->image, layout, in_render_loop, queue_mask) &&
+ radv_layout_is_htile_compressed(cmd_buffer->device, iview->image, layout, in_render_loop, queue_mask) &&
radv_image_extent_compare(iview->image, &iview->extent))
return true;
return false;
@@ -1090,7 +1090,7 @@
if (!radv_image_view_can_fast_clear(cmd_buffer->device, iview))
return false;
- if (!radv_layout_is_htile_compressed(iview->image, image_layout, in_render_loop,
+ if (!radv_layout_is_htile_compressed(cmd_buffer->device, iview->image, image_layout, in_render_loop,
radv_image_queue_family_mask(iview->image,
cmd_buffer->queue_family_index,
cmd_buffer->queue_family_index)))
diff --git a/src/amd/vulkan/radv_private.h b/src/amd/vulkan/radv_private.h
index 6c3a166..cb2b638 100644
--- a/src/amd/vulkan/radv_private.h
+++ b/src/amd/vulkan/radv_private.h
@@ -358,6 +358,7 @@
* Workarounds for game bugs.
*/
bool enable_mrt_output_nan_fixup;
+ bool disable_tc_compat_htile_in_general;
};
VkResult radv_init_wsi(struct radv_physical_device *physical_device);
@@ -1901,7 +1902,8 @@
* If this is false reads that don't use the htile should be able to return
* correct results.
*/
-bool radv_layout_is_htile_compressed(const struct radv_image *image,
+bool radv_layout_is_htile_compressed(const struct radv_device *device,
+ const struct radv_image *image,
VkImageLayout layout,
bool in_render_loop,
unsigned queue_mask);