Mesa (master): tu: Force sysmem with mipmapped non-aligned linear stores
GitLab Mirror
gitlab-mirror at kemper.freedesktop.org
Thu Feb 13 03:04:34 UTC 2020
Module: Mesa
Branch: master
Commit: da64c35ff920df58b872619bb6f54ae978cb47c9
URL: http://cgit.freedesktop.org/mesa/mesa/commit/?id=da64c35ff920df58b872619bb6f54ae978cb47c9
Author: Connor Abbott <cwabbott0 at gmail.com>
Date: Fri Jan 31 17:47:48 2020 +0100
tu: Force sysmem with mipmapped non-aligned linear stores
Fixes hangs with
dEQP-VK.api.image_clearing.core.clear_color_image.1d.linear.single_layer.r8g8b8a8_unorm
and many others on a640, and presumably silent corruption with a630.
Tested-by: Marge Bot <https://gitlab.freedesktop.org/mesa/mesa/merge_requests/3713>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/merge_requests/3713>
---
src/freedreno/vulkan/tu_cmd_buffer.c | 63 +++++++++++++++++++++++++++++++++++-
src/freedreno/vulkan/tu_private.h | 3 ++
2 files changed, 65 insertions(+), 1 deletion(-)
diff --git a/src/freedreno/vulkan/tu_cmd_buffer.c b/src/freedreno/vulkan/tu_cmd_buffer.c
index cc6c0a8b553..d54891971eb 100644
--- a/src/freedreno/vulkan/tu_cmd_buffer.c
+++ b/src/freedreno/vulkan/tu_cmd_buffer.c
@@ -111,6 +111,66 @@ tu_bo_list_merge(struct tu_bo_list *list, const struct tu_bo_list *other)
return VK_SUCCESS;
}
+static bool
+is_linear_mipmapped(const struct tu_image_view *iview)
+{
+ return iview->image->layout.tile_mode == TILE6_LINEAR &&
+ iview->base_mip != iview->image->level_count - 1;
+}
+
+static bool
+force_sysmem(const struct tu_cmd_buffer *cmd,
+ const struct VkRect2D *render_area)
+{
+ const struct tu_framebuffer *fb = cmd->state.framebuffer;
+ const struct tu_physical_device *device = cmd->device->physical_device;
+ bool has_linear_mipmapped_store = false;
+ const struct tu_render_pass *pass = cmd->state.pass;
+
+ /* Iterate over all the places we call tu6_emit_store_attachment() */
+ for (unsigned i = 0; i < pass->subpass_count; i++) {
+ const struct tu_subpass *subpass = &pass->subpasses[i];
+ if (subpass->resolve_attachments) {
+ for (unsigned i = 0; i < subpass->color_count; i++) {
+ uint32_t a = subpass->resolve_attachments[i].attachment;
+ if (a != VK_ATTACHMENT_UNUSED &&
+ cmd->state.pass->attachments[a].store_op == VK_ATTACHMENT_STORE_OP_STORE) {
+ const struct tu_image_view *iview = fb->attachments[a].attachment;
+ if (is_linear_mipmapped(iview)) {
+ has_linear_mipmapped_store = true;
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ for (unsigned i = 0; i < pass->attachment_count; i++) {
+ if (pass->attachments[i].gmem_offset >= 0 &&
+ cmd->state.pass->attachments[i].store_op == VK_ATTACHMENT_STORE_OP_STORE) {
+ const struct tu_image_view *iview = fb->attachments[i].attachment;
+ if (is_linear_mipmapped(iview)) {
+ has_linear_mipmapped_store = true;
+ break;
+ }
+ }
+ }
+
+ /* Linear textures cannot have any padding between mipmap levels and their
+ * height isn't padded, while at the same time the GMEM->MEM resolve does
+ * not have per-pixel granularity, so if the image height isn't aligned to
+ * the resolve granularity and the render area is tall enough, we may wind
+ * up writing past the bottom of the image into the next miplevel or even
+ * past the end of the image. For the last miplevel, the layout code should
+ * insert enough padding so that the overdraw writes to the padding. To
+ * work around this, we force-enable sysmem rendering.
+ */
+ const uint32_t y2 = render_area->offset.y + render_area->extent.height;
+ const uint32_t aligned_y2 = ALIGN_POT(y2, device->tile_align_h);
+
+ return has_linear_mipmapped_store && aligned_y2 > fb->height;
+}
+
static void
tu_tiling_config_update_tile_layout(struct tu_tiling_config *tiling,
const struct tu_device *dev,
@@ -703,7 +763,7 @@ use_sysmem_rendering(struct tu_cmd_buffer *cmd)
if (unlikely(cmd->device->physical_device->instance->debug_flags & TU_DEBUG_SYSMEM))
return true;
- return false;
+ return cmd->state.tiling_config.force_sysmem;
}
static void
@@ -1755,6 +1815,7 @@ tu_cmd_update_tiling_config(struct tu_cmd_buffer *cmd,
struct tu_tiling_config *tiling = &cmd->state.tiling_config;
tiling->render_area = *render_area;
+ tiling->force_sysmem = force_sysmem(cmd, render_area);
tu_tiling_config_update_tile_layout(tiling, dev, cmd->state.pass->gmem_pixels);
tu_tiling_config_update_pipe_layout(tiling, dev);
diff --git a/src/freedreno/vulkan/tu_private.h b/src/freedreno/vulkan/tu_private.h
index 7c53e509d8e..30931b0e321 100644
--- a/src/freedreno/vulkan/tu_private.h
+++ b/src/freedreno/vulkan/tu_private.h
@@ -822,6 +822,9 @@ struct tu_tiling_config
/* pipe register values */
uint32_t pipe_config[MAX_VSC_PIPES];
uint32_t pipe_sizes[MAX_VSC_PIPES];
+
+ /* Whether sysmem rendering must be used */
+ bool force_sysmem;
};
enum tu_cmd_dirty_bits
More information about the mesa-commit
mailing list