From 3188c1b5c74c4e5894be7b7878dc0d11a9121c67 Mon Sep 17 00:00:00 2001 From: Mark Collins Date: Tue, 9 Jan 2024 13:42:28 +0000 Subject: [PATCH] tu: Use `Z24_UNORM_S8_UINT_AS_R8G8B8A8` for A7XX GMEM D24S8 blits/clear A7XX has corruption when 2D blits are performed on D24S8 images from GMEM when the source format is FMT6_8_8_8_8_UNORM, this is fixed by using FMT6_Z24_UNORM_S8_UINT_AS_R8G8B8A8. Fixes VK-CTS: dEQP-VK.pipeline.monolithic.multisample.misc.* Signed-off-by: Mark Collins Part-of: --- src/freedreno/vulkan/tu_clear_blit.cc | 50 ++++++++++++++++++--------- 1 file changed, 33 insertions(+), 17 deletions(-) diff --git a/src/freedreno/vulkan/tu_clear_blit.cc b/src/freedreno/vulkan/tu_clear_blit.cc index 70a8b0faa51..711fc6913bd 100644 --- a/src/freedreno/vulkan/tu_clear_blit.cc +++ b/src/freedreno/vulkan/tu_clear_blit.cc @@ -67,8 +67,9 @@ format_to_ifmt(enum pipe_format format) } } +template static struct tu_native_format -blit_format_texture(enum pipe_format format, enum a6xx_tile_mode tile_mode) +blit_format_texture(enum pipe_format format, enum a6xx_tile_mode tile_mode, bool gmem) { struct tu_native_format fmt = tu6_format_texture(format, tile_mode); @@ -79,8 +80,12 @@ blit_format_texture(enum pipe_format format, enum a6xx_tile_mode tile_mode) * FMT6_Z24_UNORM_S8_UINT_AS_R8G8B8A8 or FMT6_8_8_8_8_UNORM for blit * src. Since this is called when there is no image and thus no ubwc, * we can always use FMT6_8_8_8_8_UNORM. + * + * Note (A7XX): Since it's erroneous to use FMT6_8_8_8_8_UNORM for a GMEM + * image (see blit_base_format), we use FMT6_Z24_UNORM_S8_UINT_AS_R8G8B8A8 + * instead. */ - fmt.fmt = FMT6_8_8_8_8_UNORM; + fmt.fmt = CHIP >= A7XX && gmem ? FMT6_Z24_UNORM_S8_UINT_AS_R8G8B8A8 : FMT6_8_8_8_8_UNORM; break; default: break; @@ -107,9 +112,18 @@ blit_format_color(enum pipe_format format, enum a6xx_tile_mode tile_mode) return fmt; } +template static enum a6xx_format -blit_base_format(enum pipe_format format, bool ubwc) +blit_base_format(enum pipe_format format, bool ubwc, bool gmem) { + if (CHIP >= A7XX && gmem) + /* A7XX requires D24S8 in GMEM to always be treated as + * FMT6_Z24_UNORM_S8_UINT_AS_R8G8B8A8 regardless of if the image + * is UBWC-compatible. Using FMT6_8_8_8_8_UNORM instead will result + * in misrendering around the edges of the destination image. + */ + ubwc = true; + if (ubwc) { switch (format) { case PIPE_FORMAT_Z24X8_UNORM: @@ -320,7 +334,7 @@ r2d_src_buffer(struct tu_cmd_buffer *cmd, uint32_t width, uint32_t height, enum pipe_format dst_format) { - struct tu_native_format fmt = blit_format_texture(format, TILE6_LINEAR); + struct tu_native_format fmt = blit_format_texture(format, TILE6_LINEAR, false); enum a6xx_format color_format = fmt.fmt; fixup_src_format(&format, dst_format, &color_format); @@ -412,7 +426,7 @@ r2d_setup_common(struct tu_cmd_buffer *cmd, tu_cs_emit_call(cs, cmd->device->dbg_renderpass_stomp_cs); } - enum a6xx_format fmt = blit_base_format(dst_format, ubwc); + enum a6xx_format fmt = blit_base_format(dst_format, ubwc, false); fixup_dst_format(src_format, &dst_format, &fmt); enum a6xx_2d_ifmt ifmt = format_to_ifmt(dst_format); @@ -1119,6 +1133,7 @@ r3d_src(struct tu_cmd_buffer *cmd, filter); } +template static void r3d_src_buffer(struct tu_cmd_buffer *cmd, struct tu_cs *cs, @@ -1129,7 +1144,7 @@ r3d_src_buffer(struct tu_cmd_buffer *cmd, { uint32_t desc[A6XX_TEX_CONST_DWORDS]; - struct tu_native_format fmt = blit_format_texture(format, TILE6_LINEAR); + struct tu_native_format fmt = blit_format_texture(format, TILE6_LINEAR, false); enum a6xx_format color_format = fmt.fmt; fixup_src_format(&format, dst_format, &color_format); @@ -1261,6 +1276,7 @@ r3d_src_gmem_load(struct tu_cmd_buffer *cmd, VK_FILTER_NEAREST); } +template static void r3d_src_gmem(struct tu_cmd_buffer *cmd, struct tu_cs *cs, @@ -1273,7 +1289,7 @@ r3d_src_gmem(struct tu_cmd_buffer *cmd, uint32_t desc[A6XX_TEX_CONST_DWORDS]; memcpy(desc, iview->view.descriptor, sizeof(desc)); - enum a6xx_format fmt = blit_format_texture(format, TILE6_LINEAR).fmt; + enum a6xx_format fmt = blit_format_texture(format, TILE6_LINEAR, true).fmt; fixup_src_format(&format, dst_format, &fmt); /* patch the format so that depth/stencil get the right format and swizzle */ @@ -1455,7 +1471,7 @@ r3d_setup(struct tu_cmd_buffer *cmd, tu_cs_emit_call(cs, cmd->device->dbg_renderpass_stomp_cs); } - enum a6xx_format fmt = blit_base_format(dst_format, ubwc); + enum a6xx_format fmt = blit_base_format(dst_format, ubwc, false); fixup_dst_format(src_format, &dst_format, &fmt); if (!cmd->state.pass) { @@ -1640,7 +1656,7 @@ static const struct blit_ops r3d_ops = { .coords = r3d_coords, .clear_value = r3d_clear_value, .src = r3d_src, - .src_buffer = r3d_src_buffer, + .src_buffer = r3d_src_buffer, .dst = r3d_dst, .dst_depth = r3d_dst_depth, .dst_stencil = r3d_dst_stencil, @@ -2217,11 +2233,12 @@ TU_GENX(tu_CmdCopyImageToBuffer2); * format, i.e. only when the other image is linear. */ +template static bool is_swapped_format(enum pipe_format format) { - struct tu_native_format linear = blit_format_texture(format, TILE6_LINEAR); - struct tu_native_format tiled = blit_format_texture(format, TILE6_3); + struct tu_native_format linear = blit_format_texture(format, TILE6_LINEAR, false); + struct tu_native_format tiled = blit_format_texture(format, TILE6_3, false); return linear.fmt != tiled.fmt || linear.swap != tiled.swap; } @@ -2308,8 +2325,8 @@ tu_copy_image_to_image(struct tu_cmd_buffer *cmd, * due to the different tile layout. */ use_staging_blit = true; - } else if (is_swapped_format(src_format) || - is_swapped_format(dst_format)) { + } else if (is_swapped_format(src_format) || + is_swapped_format(dst_format)) { /* If either format has a non-identity swap, then we can't copy * to/from it. */ @@ -3098,7 +3115,7 @@ clear_gmem_attachment(struct tu_cmd_buffer *cmd, { tu_cs_emit_pkt4(cs, REG_A6XX_RB_BLIT_DST_INFO, 1); tu_cs_emit(cs, A6XX_RB_BLIT_DST_INFO_COLOR_FORMAT( - blit_base_format(format, false))); + blit_base_format(format, false, true))); tu_cs_emit_regs(cs, A6XX_RB_BLIT_INFO(.gmem = 1, .clear_mask = clear_mask)); @@ -3706,7 +3723,7 @@ store_cp_blit(struct tu_cmd_buffer *cmd, r2d_dst(cs, &iview->view, layer, src_format); } - enum a6xx_format fmt = blit_format_texture(src_format, TILE6_2).fmt; + enum a6xx_format fmt = blit_format_texture(src_format, TILE6_2, true).fmt; fixup_src_format(&src_format, dst_format, &fmt); tu_cs_emit_regs(cs, @@ -3785,7 +3802,7 @@ store_3d_blit(struct tu_cmd_buffer *cmd, r3d_dst(cs, &iview->view, layer, src_format); } - r3d_src_gmem(cmd, cs, iview, src_format, dst_format, gmem_offset, cpp); + r3d_src_gmem(cmd, cs, iview, src_format, dst_format, gmem_offset, cpp); /* sync GMEM writes with CACHE. */ tu_emit_event_write(cmd, cs, FD_CACHE_INVALIDATE); @@ -4025,7 +4042,6 @@ tu_store_gmem_attachment(struct tu_cmd_buffer *cmd, } } } else { - /* A7XX TODO: Fix D24S8 MSAA resolves using the 2D blits */ if (!cmd->state.pass->has_fdm) { r2d_coords(cmd, cs, render_area->offset, render_area->offset, render_area->extent);