Module: Mesa Branch: main Commit: e255305e8483c005abd2671f3c2c2d25a55d1d8e URL: http://cgit.freedesktop.org/mesa/mesa/commit/?id=e255305e8483c005abd2671f3c2c2d25a55d1d8e
Author: Danylo Piliaiev <[email protected]> Date: Wed Mar 23 16:35:09 2022 +0200 turnip: Ignore aspectMask for D32S8 framebuffer attachment Vulkan spec says: "When an image view of a depth/stencil image is used as a depth/stencil framebuffer attachment, the aspectMask is ignored and both depth and stencil image subresources are used." Since we use two planes for D32S8 format we have to add a special case for depth in addition to already existing case for stencil. Fixes hang in CTS: dEQP-VK.renderpass.depth_stencil_write_conditions.stencil_kill_write_d32sf_s8ui Signed-off-by: Danylo Piliaiev <[email protected]> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/15532> --- src/freedreno/vulkan/tu_clear_blit.c | 127 ++++++++++++++++++++++++++++------- src/freedreno/vulkan/tu_cmd_buffer.c | 5 +- src/freedreno/vulkan/tu_image.c | 16 ++++- src/freedreno/vulkan/tu_private.h | 11 +++ 4 files changed, 133 insertions(+), 26 deletions(-) diff --git a/src/freedreno/vulkan/tu_clear_blit.c b/src/freedreno/vulkan/tu_clear_blit.c index 3e732decd1a..111a3b09f84 100644 --- a/src/freedreno/vulkan/tu_clear_blit.c +++ b/src/freedreno/vulkan/tu_clear_blit.c @@ -161,6 +161,24 @@ r2d_src(struct tu_cmd_buffer *cmd, tu_cs_image_flag_ref(cs, iview, layer); } +static void +r2d_src_depth(struct tu_cmd_buffer *cmd, + struct tu_cs *cs, + const struct tu_image_view *iview, + uint32_t layer, + VkFilter filter) +{ + tu_cs_emit_pkt4(cs, REG_A6XX_SP_PS_2D_SRC_INFO, 5); + tu_cs_emit(cs, tu_image_view_depth(iview, SP_PS_2D_SRC_INFO)); + tu_cs_emit(cs, iview->view.SP_PS_2D_SRC_SIZE); + tu_cs_emit_qw(cs, iview->depth_base_addr + iview->depth_layer_size * layer); + /* SP_PS_2D_SRC_PITCH has shifted pitch field */ + tu_cs_emit(cs, iview->depth_PITCH << 9); + + tu_cs_emit_pkt4(cs, REG_A6XX_SP_PS_2D_SRC_FLAGS, 3); + tu_cs_image_flag_ref(cs, &iview->view, layer); +} + static void r2d_src_stencil(struct tu_cmd_buffer *cmd, struct tu_cs *cs, @@ -208,6 +226,18 @@ r2d_dst(struct tu_cs *cs, const struct fdl6_view *iview, uint32_t layer) tu_cs_image_flag_ref(cs, iview, layer); } +static void +r2d_dst_depth(struct tu_cs *cs, const struct tu_image_view *iview, uint32_t layer) +{ + tu_cs_emit_pkt4(cs, REG_A6XX_RB_2D_DST_INFO, 4); + tu_cs_emit(cs, tu_image_view_depth(iview, RB_2D_DST_INFO)); + tu_cs_emit_qw(cs, iview->depth_base_addr + iview->depth_layer_size * layer); + tu_cs_emit(cs, iview->depth_PITCH); + + tu_cs_emit_pkt4(cs, REG_A6XX_RB_2D_DST_FLAGS, 3); + tu_cs_image_flag_ref(cs, &iview->view, layer); +} + static void r2d_dst_stencil(struct tu_cs *cs, const struct tu_image_view *iview, uint32_t layer) { @@ -950,6 +980,20 @@ r3d_dst(struct tu_cs *cs, const struct fdl6_view *iview, uint32_t layer) tu_cs_emit_regs(cs, A6XX_RB_RENDER_CNTL(.flag_mrts = iview->ubwc_enabled)); } +static void +r3d_dst_depth(struct tu_cs *cs, const struct tu_image_view *iview, uint32_t layer) +{ + tu_cs_emit_pkt4(cs, REG_A6XX_RB_MRT_BUF_INFO(0), 6); + tu_cs_emit(cs, tu_image_view_depth(iview, RB_MRT_BUF_INFO)); + tu_cs_image_depth_ref(cs, iview, layer); + tu_cs_emit(cs, 0); + + tu_cs_emit_pkt4(cs, REG_A6XX_RB_MRT_FLAG_BUFFER(0), 3); + tu_cs_image_flag_ref(cs, &iview->view, layer); + + tu_cs_emit_regs(cs, A6XX_RB_RENDER_CNTL(.flag_mrts = iview->view.ubwc_enabled)); +} + static void r3d_dst_stencil(struct tu_cs *cs, const struct tu_image_view *iview, uint32_t layer) { @@ -1105,6 +1149,8 @@ struct blit_ops { uint64_t va, uint32_t pitch, uint32_t width, uint32_t height); void (*dst)(struct tu_cs *cs, const struct fdl6_view *iview, uint32_t layer); + void (*dst_depth)(struct tu_cs *cs, const struct tu_image_view *iview, uint32_t layer); + void (*dst_stencil)(struct tu_cs *cs, const struct tu_image_view *iview, uint32_t layer); void (*dst_buffer)(struct tu_cs *cs, enum pipe_format format, uint64_t va, uint32_t pitch); void (*setup)(struct tu_cmd_buffer *cmd, struct tu_cs *cs, @@ -1125,6 +1171,8 @@ static const struct blit_ops r2d_ops = { .src = r2d_src, .src_buffer = r2d_src_buffer, .dst = r2d_dst, + .dst_depth = r2d_dst_depth, + .dst_stencil = r2d_dst_stencil, .dst_buffer = r2d_dst_buffer, .setup = r2d_setup, .run = r2d_run, @@ -1137,6 +1185,8 @@ static const struct blit_ops r3d_ops = { .src = r3d_src, .src_buffer = r3d_src_buffer, .dst = r3d_dst, + .dst_depth = r3d_dst_depth, + .dst_stencil = r3d_dst_stencil, .dst_buffer = r3d_dst_buffer, .setup = r3d_setup, .run = r3d_run, @@ -2031,7 +2081,7 @@ resolve_sysmem(struct tu_cmd_buffer *cmd, uint32_t layer_mask, uint32_t layers, const VkRect2D *rect, - bool separate_stencil) + bool separate_ds) { const struct blit_ops *ops = &r2d_ops; @@ -2043,9 +2093,14 @@ resolve_sysmem(struct tu_cmd_buffer *cmd, ops->coords(cs, &rect->offset, &rect->offset, &rect->extent); for_each_layer(i, layer_mask, layers) { - if (separate_stencil) { - r2d_src_stencil(cmd, cs, src, i, VK_FILTER_NEAREST); - r2d_dst_stencil(cs, dst, i); + if (separate_ds) { + if (format == VK_FORMAT_D32_SFLOAT) { + r2d_src_depth(cmd, cs, src, i, VK_FILTER_NEAREST); + ops->dst_depth(cs, dst, i); + } else { + r2d_src_stencil(cmd, cs, src, i, VK_FILTER_NEAREST); + ops->dst_stencil(cs, dst, i); + } } else { ops->src(cmd, cs, &src->view, i, VK_FILTER_NEAREST); ops->dst(cs, &dst->view, i); @@ -2071,7 +2126,7 @@ tu_resolve_sysmem(struct tu_cmd_buffer *cmd, if (dst->image->vk_format == VK_FORMAT_D32_SFLOAT_S8_UINT) { resolve_sysmem(cmd, cs, VK_FORMAT_D32_SFLOAT, - src, dst, layer_mask, layers, rect, false); + src, dst, layer_mask, layers, rect, true); resolve_sysmem(cmd, cs, VK_FORMAT_S8_UINT, src, dst, layer_mask, layers, rect, true); } else { @@ -2556,7 +2611,7 @@ clear_sysmem_attachment(struct tu_cmd_buffer *cmd, VkImageAspectFlags clear_mask, const VkRenderPassBeginInfo *info, uint32_t a, - bool separate_stencil) + bool separate_ds) { enum pipe_format format = tu_vk_format_to_pipe_format(vk_format); const struct tu_framebuffer *fb = cmd->state.framebuffer; @@ -2574,11 +2629,12 @@ clear_sysmem_attachment(struct tu_cmd_buffer *cmd, ops->clear_value(cs, format, &info->pClearValues[a]); for_each_layer(i, clear_views, fb->layers) { - if (separate_stencil) { - if (ops == &r3d_ops) - r3d_dst_stencil(cs, iview, i); - else - r2d_dst_stencil(cs, iview, i); + if (separate_ds) { + if (vk_format == VK_FORMAT_D32_SFLOAT) { + ops->dst_depth(cs, iview, i); + } else { + ops->dst_stencil(cs, iview, i); + } } else { ops->dst(cs, &iview->view, i); } @@ -2607,7 +2663,7 @@ tu_clear_sysmem_attachment(struct tu_cmd_buffer *cmd, if (attachment->format == VK_FORMAT_D32_SFLOAT_S8_UINT) { if (attachment->clear_mask & VK_IMAGE_ASPECT_DEPTH_BIT) { clear_sysmem_attachment(cmd, cs, VK_FORMAT_D32_SFLOAT, VK_IMAGE_ASPECT_COLOR_BIT, - info, a, false); + info, a, true); } if (attachment->clear_mask & VK_IMAGE_ASPECT_STENCIL_BIT) { clear_sysmem_attachment(cmd, cs, VK_FORMAT_S8_UINT, VK_IMAGE_ASPECT_COLOR_BIT, @@ -2675,13 +2731,25 @@ tu_emit_blit(struct tu_cmd_buffer *cmd, vk_format_is_depth_or_stencil(attachment->format))); tu_cs_emit_pkt4(cs, REG_A6XX_RB_BLIT_DST_INFO, 4); - if (separate_stencil) { - tu_cs_emit(cs, tu_image_view_stencil(iview, RB_BLIT_DST_INFO) & ~A6XX_RB_BLIT_DST_INFO_FLAGS); - tu_cs_emit_qw(cs, iview->stencil_base_addr); - tu_cs_emit(cs, iview->stencil_PITCH); + if (attachment->format == VK_FORMAT_D32_SFLOAT_S8_UINT) { + if (!separate_stencil) { + tu_cs_emit(cs, tu_image_view_depth(iview, RB_BLIT_DST_INFO)); + tu_cs_emit_qw(cs, iview->depth_base_addr); + tu_cs_emit(cs, iview->depth_PITCH); - tu_cs_emit_regs(cs, - A6XX_RB_BLIT_BASE_GMEM(attachment->gmem_offset_stencil)); + tu_cs_emit_pkt4(cs, REG_A6XX_RB_BLIT_FLAG_DST, 3); + tu_cs_image_flag_ref(cs, &iview->view, 0); + + tu_cs_emit_regs(cs, + A6XX_RB_BLIT_BASE_GMEM(attachment->gmem_offset)); + } else { + tu_cs_emit(cs, tu_image_view_stencil(iview, RB_BLIT_DST_INFO) & ~A6XX_RB_BLIT_DST_INFO_FLAGS); + tu_cs_emit_qw(cs, iview->stencil_base_addr); + tu_cs_emit(cs, iview->stencil_PITCH); + + tu_cs_emit_regs(cs, + A6XX_RB_BLIT_BASE_GMEM(attachment->gmem_offset_stencil)); + } } else { tu_cs_emit(cs, iview->view.RB_BLIT_DST_INFO); tu_cs_image_ref_2d(cs, &iview->view, 0, false); @@ -2764,10 +2832,16 @@ store_cp_blit(struct tu_cmd_buffer *cmd, { r2d_setup_common(cmd, cs, format, VK_IMAGE_ASPECT_COLOR_BIT, 0, false, iview->view.ubwc_enabled, true); - if (separate_stencil) - r2d_dst_stencil(cs, iview, 0); - else + + if (iview->image->vk_format == VK_FORMAT_D32_SFLOAT_S8_UINT) { + if (!separate_stencil) { + r2d_dst_depth(cs, iview, 0); + } else { + r2d_dst_stencil(cs, iview, 0); + } + } else { r2d_dst(cs, &iview->view, 0); + } tu_cs_emit_regs(cs, A6XX_SP_PS_2D_SRC_INFO( @@ -2816,10 +2890,15 @@ store_3d_blit(struct tu_cmd_buffer *cmd, r3d_coords(cs, &render_area->offset, &render_area->offset, &render_area->extent); - if (separate_stencil) - r3d_dst_stencil(cs, iview, 0); - else + if (iview->image->vk_format == VK_FORMAT_D32_SFLOAT_S8_UINT) { + if (!separate_stencil) { + r3d_dst_depth(cs, iview, 0); + } else { + r3d_dst_stencil(cs, iview, 0); + } + } else { r3d_dst(cs, &iview->view, 0); + } r3d_src_gmem(cmd, cs, iview, format, gmem_offset, cpp); diff --git a/src/freedreno/vulkan/tu_cmd_buffer.c b/src/freedreno/vulkan/tu_cmd_buffer.c index a1e47a5007f..15107caca80 100644 --- a/src/freedreno/vulkan/tu_cmd_buffer.c +++ b/src/freedreno/vulkan/tu_cmd_buffer.c @@ -233,7 +233,10 @@ tu6_emit_zs(struct tu_cmd_buffer *cmd, tu_cs_emit_pkt4(cs, REG_A6XX_RB_DEPTH_BUFFER_INFO, 6); tu_cs_emit(cs, A6XX_RB_DEPTH_BUFFER_INFO(.depth_format = fmt).value); - tu_cs_image_ref(cs, &iview->view, 0); + if (attachment->format == VK_FORMAT_D32_SFLOAT_S8_UINT) + tu_cs_image_depth_ref(cs, iview, 0); + else + tu_cs_image_ref(cs, &iview->view, 0); tu_cs_emit(cs, attachment->gmem_offset); tu_cs_emit_regs(cs, diff --git a/src/freedreno/vulkan/tu_image.c b/src/freedreno/vulkan/tu_image.c index 1f12d28e455..b8aaca704b1 100644 --- a/src/freedreno/vulkan/tu_image.c +++ b/src/freedreno/vulkan/tu_image.c @@ -135,6 +135,14 @@ tu_cs_image_stencil_ref(struct tu_cs *cs, const struct tu_image_view *iview, uin tu_cs_emit_qw(cs, iview->stencil_base_addr + iview->stencil_layer_size * layer); } +void +tu_cs_image_depth_ref(struct tu_cs *cs, const struct tu_image_view *iview, uint32_t layer) +{ + tu_cs_emit(cs, iview->depth_PITCH); + tu_cs_emit(cs, iview->depth_layer_size >> 6); + tu_cs_emit_qw(cs, iview->depth_base_addr + iview->depth_layer_size * layer); +} + void tu_cs_image_ref_2d(struct tu_cs *cs, const struct fdl6_view *iview, uint32_t layer, bool src) { @@ -243,7 +251,13 @@ tu_image_view_init(struct tu_image_view *iview, fdl6_view_init(&iview->view, layouts, &args, has_z24uint_s8uint); if (image->vk_format == VK_FORMAT_D32_SFLOAT_S8_UINT) { - struct fdl_layout *layout = &image->layout[1]; + struct fdl_layout *layout = &image->layout[0]; + iview->depth_base_addr = image->iova + + fdl_surface_offset(layout, range->baseMipLevel, range->baseArrayLayer); + iview->depth_layer_size = fdl_layer_stride(layout, range->baseMipLevel); + iview->depth_PITCH = A6XX_RB_DEPTH_BUFFER_PITCH(fdl_pitch(layout, range->baseMipLevel)).value; + + layout = &image->layout[1]; iview->stencil_base_addr = image->iova + fdl_surface_offset(layout, range->baseMipLevel, range->baseArrayLayer); iview->stencil_layer_size = fdl_layer_stride(layout, range->baseMipLevel); diff --git a/src/freedreno/vulkan/tu_private.h b/src/freedreno/vulkan/tu_private.h index 1a591246a63..facf8acdfcd 100644 --- a/src/freedreno/vulkan/tu_private.h +++ b/src/freedreno/vulkan/tu_private.h @@ -1585,6 +1585,11 @@ struct tu_image_view struct fdl6_view view; + /* for d32s8 separate depth */ + uint64_t depth_base_addr; + uint32_t depth_layer_size; + uint32_t depth_PITCH; + /* for d32s8 separate stencil */ uint64_t stencil_base_addr; uint32_t stencil_layer_size; @@ -1621,9 +1626,15 @@ tu_cs_image_flag_ref(struct tu_cs *cs, const struct fdl6_view *iview, uint32_t l void tu_cs_image_stencil_ref(struct tu_cs *cs, const struct tu_image_view *iview, uint32_t layer); +void +tu_cs_image_depth_ref(struct tu_cs *cs, const struct tu_image_view *iview, uint32_t layer); + #define tu_image_view_stencil(iview, x) \ ((iview->view.x & ~A6XX_##x##_COLOR_FORMAT__MASK) | A6XX_##x##_COLOR_FORMAT(FMT6_8_UINT)) +#define tu_image_view_depth(iview, x) \ + ((iview->view.x & ~A6XX_##x##_COLOR_FORMAT__MASK) | A6XX_##x##_COLOR_FORMAT(FMT6_32_FLOAT)) + VkResult tu_gralloc_info(struct tu_device *device, const VkNativeBufferANDROID *gralloc_info,
