From 07b8ce43514d5ac8d9fe61c1b80257a860327bf7 Mon Sep 17 00:00:00 2001 From: Rebecca Mckeever Date: Tue, 26 Nov 2024 18:25:23 +0100 Subject: [PATCH] panvk: Support D32_S8 as a multiplanar format This format was already supported on Bifrost as a single plane format. Valhall doesn't support this interleaved D32_S8, so we add support for multiplanar D32_S8 and move Bifrost to this layout too, as it's more memory efficient than the interleaved layout. Signed-off-by: Rebecca Mckeever Reviewed-by: Boris Brezillon Reviewed-by: Lars-Ivar Hesselberg Simonsen Part-of: --- src/panfrost/ci/panfrost-g610-fails.txt | 19 +++++ src/panfrost/vulkan/panvk_cmd_draw.h | 1 + src/panfrost/vulkan/panvk_image.c | 17 +++- src/panfrost/vulkan/panvk_image.h | 2 + src/panfrost/vulkan/panvk_meta.h | 6 +- src/panfrost/vulkan/panvk_physical_device.c | 12 --- src/panfrost/vulkan/panvk_vX_cmd_draw.c | 82 +++++++++--------- src/panfrost/vulkan/panvk_vX_cmd_fb_preload.c | 7 +- src/panfrost/vulkan/panvk_vX_image_view.c | 85 +++++++++++-------- 9 files changed, 139 insertions(+), 92 deletions(-) diff --git a/src/panfrost/ci/panfrost-g610-fails.txt b/src/panfrost/ci/panfrost-g610-fails.txt index 794efc4d3c3..45ce3ecb2c0 100644 --- a/src/panfrost/ci/panfrost-g610-fails.txt +++ b/src/panfrost/ci/panfrost-g610-fails.txt @@ -268,6 +268,7 @@ spec@ext_image_dma_buf_import@ext_image_dma_buf_import-refcount-multithread,Cras # Filtering of 3D depth-stencil textures fails unless we set SAMPLER:round_to_nearest_even=false dEQP-VK.texture.filtering.3d.formats.d24_unorm_s8_uint_stencil.d24_unorm_s8_uint_stencil_nearest,Fail +dEQP-VK.texture.filtering.3d.formats.d32_sfloat_s8_uint_stencil.d32_sfloat_s8_uint_stencil_nearest,Fail # CTS bug, see https://gitlab.khronos.org/Tracker/vk-gl-cts/-/issues/5296 dEQP-VK.api.device_init.create_device_unsupported_features.shader_draw_parameters_features,Fail @@ -300,23 +301,41 @@ dEQP-VK.memory.pipeline_barrier.transfer_dst_uniform_buffer.1048576,Crash dEQP-VK.memory.pipeline_barrier.transfer_dst_uniform_texel_buffer.1048576,Crash dEQP-VK.renderpass.suballocation.subpass_dependencies.late_fragment_tests.render_size_128_128.subpass_count_2.d24_unorm_s8_uint,Fail +dEQP-VK.renderpass.suballocation.subpass_dependencies.late_fragment_tests.render_size_128_128.subpass_count_2.d32_sfloat_s8_uint,Fail dEQP-VK.renderpass.suballocation.subpass_dependencies.late_fragment_tests.render_size_128_128.subpass_count_3.d24_unorm_s8_uint,Fail +dEQP-VK.renderpass.suballocation.subpass_dependencies.late_fragment_tests.render_size_128_128.subpass_count_3.d32_sfloat_s8_uint,Fail dEQP-VK.renderpass.suballocation.subpass_dependencies.late_fragment_tests.render_size_128_128.subpass_count_5.d24_unorm_s8_uint,Fail +dEQP-VK.renderpass.suballocation.subpass_dependencies.late_fragment_tests.render_size_128_128.subpass_count_5.d32_sfloat_s8_uint,Fail dEQP-VK.renderpass.suballocation.subpass_dependencies.late_fragment_tests.render_size_32_32.subpass_count_2.d24_unorm_s8_uint,Fail +dEQP-VK.renderpass.suballocation.subpass_dependencies.late_fragment_tests.render_size_32_32.subpass_count_2.d32_sfloat_s8_uint,Fail dEQP-VK.renderpass.suballocation.subpass_dependencies.late_fragment_tests.render_size_32_32.subpass_count_3.d24_unorm_s8_uint,Fail +dEQP-VK.renderpass.suballocation.subpass_dependencies.late_fragment_tests.render_size_32_32.subpass_count_3.d32_sfloat_s8_uint,Fail dEQP-VK.renderpass.suballocation.subpass_dependencies.late_fragment_tests.render_size_32_32.subpass_count_5.d24_unorm_s8_uint,Fail +dEQP-VK.renderpass.suballocation.subpass_dependencies.late_fragment_tests.render_size_32_32.subpass_count_5.d32_sfloat_s8_uint,Fail dEQP-VK.renderpass.suballocation.subpass_dependencies.late_fragment_tests.render_size_64_64.subpass_count_2.d24_unorm_s8_uint,Fail +dEQP-VK.renderpass.suballocation.subpass_dependencies.late_fragment_tests.render_size_64_64.subpass_count_2.d32_sfloat_s8_uint,Fail dEQP-VK.renderpass.suballocation.subpass_dependencies.late_fragment_tests.render_size_64_64.subpass_count_3.d24_unorm_s8_uint,Fail +dEQP-VK.renderpass.suballocation.subpass_dependencies.late_fragment_tests.render_size_64_64.subpass_count_3.d32_sfloat_s8_uint,Fail dEQP-VK.renderpass.suballocation.subpass_dependencies.late_fragment_tests.render_size_64_64.subpass_count_5.d24_unorm_s8_uint,Fail +dEQP-VK.renderpass.suballocation.subpass_dependencies.late_fragment_tests.render_size_64_64.subpass_count_5.d32_sfloat_s8_uint,Fail dEQP-VK.renderpass2.suballocation.subpass_dependencies.late_fragment_tests.render_size_128_128.subpass_count_2.d24_unorm_s8_uint,Fail +dEQP-VK.renderpass2.suballocation.subpass_dependencies.late_fragment_tests.render_size_128_128.subpass_count_2.d32_sfloat_s8_uint,Fail dEQP-VK.renderpass2.suballocation.subpass_dependencies.late_fragment_tests.render_size_128_128.subpass_count_3.d24_unorm_s8_uint,Fail +dEQP-VK.renderpass2.suballocation.subpass_dependencies.late_fragment_tests.render_size_128_128.subpass_count_3.d32_sfloat_s8_uint,Fail dEQP-VK.renderpass2.suballocation.subpass_dependencies.late_fragment_tests.render_size_128_128.subpass_count_5.d24_unorm_s8_uint,Fail +dEQP-VK.renderpass2.suballocation.subpass_dependencies.late_fragment_tests.render_size_128_128.subpass_count_5.d32_sfloat_s8_uint,Fail dEQP-VK.renderpass2.suballocation.subpass_dependencies.late_fragment_tests.render_size_32_32.subpass_count_2.d24_unorm_s8_uint,Fail +dEQP-VK.renderpass2.suballocation.subpass_dependencies.late_fragment_tests.render_size_32_32.subpass_count_2.d32_sfloat_s8_uint,Fail dEQP-VK.renderpass2.suballocation.subpass_dependencies.late_fragment_tests.render_size_32_32.subpass_count_3.d24_unorm_s8_uint,Fail +dEQP-VK.renderpass2.suballocation.subpass_dependencies.late_fragment_tests.render_size_32_32.subpass_count_3.d32_sfloat_s8_uint,Fail dEQP-VK.renderpass2.suballocation.subpass_dependencies.late_fragment_tests.render_size_32_32.subpass_count_5.d24_unorm_s8_uint,Fail +dEQP-VK.renderpass2.suballocation.subpass_dependencies.late_fragment_tests.render_size_32_32.subpass_count_5.d32_sfloat_s8_uint,Fail dEQP-VK.renderpass2.suballocation.subpass_dependencies.late_fragment_tests.render_size_64_64.subpass_count_2.d24_unorm_s8_uint,Fail +dEQP-VK.renderpass2.suballocation.subpass_dependencies.late_fragment_tests.render_size_64_64.subpass_count_2.d32_sfloat_s8_uint,Fail dEQP-VK.renderpass2.suballocation.subpass_dependencies.late_fragment_tests.render_size_64_64.subpass_count_3.d24_unorm_s8_uint,Fail +dEQP-VK.renderpass2.suballocation.subpass_dependencies.late_fragment_tests.render_size_64_64.subpass_count_3.d32_sfloat_s8_uint,Fail dEQP-VK.renderpass2.suballocation.subpass_dependencies.late_fragment_tests.render_size_64_64.subpass_count_5.d24_unorm_s8_uint,Fail +dEQP-VK.renderpass2.suballocation.subpass_dependencies.late_fragment_tests.render_size_64_64.subpass_count_5.d32_sfloat_s8_uint,Fail dEQP-VK.spirv_assembly.instruction.graphics.cross_stage.basic_type.no_perspective,Fail dEQP-VK.spirv_assembly.instruction.graphics.cross_stage.interface_blocks.no_perspective,Fail diff --git a/src/panfrost/vulkan/panvk_cmd_draw.h b/src/panfrost/vulkan/panvk_cmd_draw.h index eab6ce107da..73f751f34da 100644 --- a/src/panfrost/vulkan/panvk_cmd_draw.h +++ b/src/panfrost/vulkan/panvk_cmd_draw.h @@ -50,6 +50,7 @@ struct panvk_rendering_state { } color_attachments; struct pan_image_view zs_pview; + struct pan_image_view s_pview; struct { struct panvk_image_view *iview; diff --git a/src/panfrost/vulkan/panvk_image.c b/src/panfrost/vulkan/panvk_image.c index b3f5490e431..98323ab0a5c 100644 --- a/src/panfrost/vulkan/panvk_image.c +++ b/src/panfrost/vulkan/panvk_image.c @@ -207,7 +207,19 @@ panvk_image_init_layouts(struct panvk_image *image, image->plane_count = vk_format_get_plane_count(pCreateInfo->format); + /* Z32_S8X24 is not supported on v9+, and we don't want to use it + * on v7- anyway, because it's less efficient than the multiplanar + * alternative. + */ + if (image->vk.format == VK_FORMAT_D32_SFLOAT_S8_UINT) + image->plane_count = 2; + for (uint8_t plane = 0; plane < image->plane_count; plane++) { + VkFormat format = + (image->vk.format == VK_FORMAT_D32_SFLOAT_S8_UINT) ? + ((plane == 0) ? VK_FORMAT_D32_SFLOAT : VK_FORMAT_S8_UINT) : + image->vk.format; + struct pan_image_explicit_layout plane_layout; if (explicit_info) plane_layout = (struct pan_image_explicit_layout){ @@ -216,7 +228,7 @@ panvk_image_init_layouts(struct panvk_image *image, }; image->planes[plane].layout = (struct pan_image_layout){ - .format = vk_format_to_pipe_format(image->vk.format), + .format = vk_format_to_pipe_format(format), .dim = panvk_image_type_to_mali_tex_dim(image->vk.image_type), .width = image->vk.extent.width, .height = image->vk.extent.height, @@ -299,7 +311,8 @@ panvk_image_get_total_size(const struct panvk_image *image) static bool is_disjoint(struct panvk_image *image) { - assert(image->plane_count > 1 || + assert((image->plane_count > 1 && + image->vk.format != VK_FORMAT_D32_SFLOAT_S8_UINT) || !(image->vk.create_flags & VK_IMAGE_CREATE_DISJOINT_BIT)); return image->vk.create_flags & VK_IMAGE_CREATE_DISJOINT_BIT; } diff --git a/src/panfrost/vulkan/panvk_image.h b/src/panfrost/vulkan/panvk_image.h index b7af2629490..27be14d5983 100644 --- a/src/panfrost/vulkan/panvk_image.h +++ b/src/panfrost/vulkan/panvk_image.h @@ -37,6 +37,8 @@ panvk_plane_index(VkFormat format, VkImageAspectFlags aspect_mask) return 1; case VK_IMAGE_ASPECT_PLANE_2_BIT: return 2; + case VK_IMAGE_ASPECT_STENCIL_BIT: + return format == VK_FORMAT_D32_SFLOAT_S8_UINT; } } diff --git a/src/panfrost/vulkan/panvk_meta.h b/src/panfrost/vulkan/panvk_meta.h index f7498a23bb6..3649905c557 100644 --- a/src/panfrost/vulkan/panvk_meta.h +++ b/src/panfrost/vulkan/panvk_meta.h @@ -94,10 +94,10 @@ panvk_meta_copy_get_image_properties(struct panvk_image *img) props.depth.component_mask = BITFIELD_MASK(3); break; case VK_FORMAT_D32_SFLOAT_S8_UINT: - props.depth.view_format = VK_FORMAT_R32G32_UINT; + props.depth.view_format = VK_FORMAT_R32_UINT; props.depth.component_mask = BITFIELD_BIT(0); - props.stencil.view_format = VK_FORMAT_R32G32_UINT; - props.stencil.component_mask = BITFIELD_BIT(1); + props.stencil.view_format = VK_FORMAT_R8_UINT; + props.stencil.component_mask = BITFIELD_BIT(0); break; case VK_FORMAT_D16_UNORM: props.depth.view_format = VK_FORMAT_R16_UINT; diff --git a/src/panfrost/vulkan/panvk_physical_device.c b/src/panfrost/vulkan/panvk_physical_device.c index a2429e0da32..3e17b40450d 100644 --- a/src/panfrost/vulkan/panvk_physical_device.c +++ b/src/panfrost/vulkan/panvk_physical_device.c @@ -1089,18 +1089,6 @@ get_format_properties(struct panvk_physical_device *physical_device, { VkFormatFeatureFlags tex = 0, buffer = 0; enum pipe_format pfmt = vk_format_to_pipe_format(format); - unsigned arch = pan_arch(physical_device->kmod.props.gpu_prod_id); - - /* FIXME: Valhall doesn't support interleaved D32_S8X24. Implement it as - * a multi-plane format, and we probably want to switch Bifrost to this - * layout too, since: - * - it's more cache-friendly (you load more samples on a cache-line if you don't - * have those 24 dummy bits) - * - it takes less memory (you don't lose those 24bits per texel) - * - we can use AFBC - */ - if (arch >= 9 && format == VK_FORMAT_D32_SFLOAT_S8_UINT) - goto end; if (pfmt == PIPE_FORMAT_NONE) goto end; diff --git a/src/panfrost/vulkan/panvk_vX_cmd_draw.c b/src/panfrost/vulkan/panvk_vX_cmd_draw.c index eff9acef8ad..606142bb1d8 100644 --- a/src/panfrost/vulkan/panvk_vX_cmd_draw.c +++ b/src/panfrost/vulkan/panvk_vX_cmd_draw.c @@ -77,13 +77,28 @@ render_state_set_z_attachment(struct panvk_cmd_buffer *cmdbuf, state->render.z_attachment.fmt = iview->vk.format; state->render.bound_attachments |= MESA_VK_RP_ATTACHMENT_DEPTH_BIT; - fbinfo->zs.view.zs = &iview->pview; + + state->render.zs_pview = iview->pview; + fbinfo->zs.view.zs = &state->render.zs_pview; + + /* D32_S8 is a multiplanar format, so we need to adjust the format of the + * depth-only view to match the one of the depth plane. + */ + if (iview->pview.format == PIPE_FORMAT_Z32_FLOAT_S8X24_UINT) + state->render.zs_pview.format = PIPE_FORMAT_Z32_FLOAT; fbinfo->nr_samples = MAX2(fbinfo->nr_samples, pan_image_view_get_nr_samples(&iview->pview)); state->render.z_attachment.iview = iview; - if (vk_format_has_stencil(img->vk.format)) + /* D24S8 is a single plane format where the depth/stencil are interleaved. + * If we touch the depth component, we need to make sure the stencil + * component is preserved, hence the preload, and the view format adjusment. + */ + if (img->vk.format == VK_FORMAT_D24_UNORM_S8_UINT) { fbinfo->zs.preload.s = true; + cmdbuf->state.gfx.render.zs_pview.format = + PIPE_FORMAT_Z24_UNORM_S8_UINT; + } if (att->loadOp == VK_ATTACHMENT_LOAD_OP_CLEAR) { fbinfo->zs.clear.z = true; @@ -119,28 +134,39 @@ render_state_set_s_attachment(struct panvk_cmd_buffer *cmdbuf, state->render.s_attachment.fmt = iview->vk.format; state->render.bound_attachments |= MESA_VK_RP_ATTACHMENT_STENCIL_BIT; - if (drm_is_afbc(img->vk.drm_format_mod)) { - assert(fbinfo->zs.view.zs == &iview->pview || !fbinfo->zs.view.zs); - fbinfo->zs.view.zs = &iview->pview; - } else { - fbinfo->zs.view.s = - &iview->pview != fbinfo->zs.view.zs ? &iview->pview : NULL; - } + state->render.s_pview = iview->pview; + fbinfo->zs.view.s = &state->render.s_pview; - fbinfo->zs.view.s = - &iview->pview != fbinfo->zs.view.zs ? &iview->pview : NULL; + /* D32_S8 is a multiplanar format, so we need to adjust the format of the + * stencil-only view to match the one of the stencil plane. + */ + if (iview->pview.format == PIPE_FORMAT_Z32_FLOAT_S8X24_UINT) + state->render.s_pview.format = PIPE_FORMAT_S8_UINT; fbinfo->nr_samples = MAX2(fbinfo->nr_samples, pan_image_view_get_nr_samples(&iview->pview)); state->render.s_attachment.iview = iview; - if (vk_format_has_depth(img->vk.format)) { - assert(fbinfo->zs.view.zs == NULL || &iview->pview == fbinfo->zs.view.zs); - fbinfo->zs.view.zs = &iview->pview; - + /* If the depth and stencil attachments point to the same image, + * and the format is D24S8, we can combine them in a single view + * addressing both components. + */ + if (img->vk.format == VK_FORMAT_D24_UNORM_S8_UINT && + state->render.z_attachment.iview && + state->render.z_attachment.iview->vk.image == iview->vk.image) { + state->render.zs_pview.format = PIPE_FORMAT_Z24_UNORM_S8_UINT; fbinfo->zs.preload.s = false; - fbinfo->zs.clear.s = false; - if (!fbinfo->zs.clear.z) - fbinfo->zs.preload.z = true; + fbinfo->zs.view.s = NULL; + + /* If there was no depth attachment, and the image format is D24S8, + * we use the depth+stencil slot, so we can benefit from AFBC, which + * is not supported on the stencil-only slot on Bifrost. + */ + } else if (img->vk.format == VK_FORMAT_D24_UNORM_S8_UINT && + fbinfo->zs.view.zs == NULL) { + fbinfo->zs.view.zs = &state->render.s_pview; + state->render.s_pview.format = PIPE_FORMAT_Z24_UNORM_S8_UINT; + fbinfo->zs.preload.z = true; + fbinfo->zs.view.s = NULL; } if (att->loadOp == VK_ATTACHMENT_LOAD_OP_CLEAR) { @@ -232,26 +258,6 @@ panvk_per_arch(cmd_init_render_state)(struct panvk_cmd_buffer *cmdbuf, } } - if (fbinfo->zs.view.zs) { - const struct util_format_description *fdesc = - util_format_description(fbinfo->zs.view.zs->format); - bool needs_depth = fbinfo->zs.clear.z | fbinfo->zs.preload.z | - util_format_has_depth(fdesc); - bool needs_stencil = fbinfo->zs.clear.s | fbinfo->zs.preload.s | - util_format_has_stencil(fdesc); - enum pipe_format new_fmt = - util_format_get_blocksize(fbinfo->zs.view.zs->format) == 4 - ? PIPE_FORMAT_Z24_UNORM_S8_UINT - : PIPE_FORMAT_Z32_FLOAT_S8X24_UINT; - - if (needs_depth && needs_stencil && - fbinfo->zs.view.zs->format != new_fmt) { - state->render.zs_pview = *fbinfo->zs.view.zs; - state->render.zs_pview.format = new_fmt; - fbinfo->zs.view.zs = &state->render.zs_pview; - } - } - fbinfo->extent.minx = pRenderingInfo->renderArea.offset.x; fbinfo->extent.maxx = pRenderingInfo->renderArea.offset.x + pRenderingInfo->renderArea.extent.width - 1; diff --git a/src/panfrost/vulkan/panvk_vX_cmd_fb_preload.c b/src/panfrost/vulkan/panvk_vX_cmd_fb_preload.c index a2e8d863a09..e8aaee7393a 100644 --- a/src/panfrost/vulkan/panvk_vX_cmd_fb_preload.c +++ b/src/panfrost/vulkan/panvk_vX_cmd_fb_preload.c @@ -487,9 +487,10 @@ cmd_emit_dcd(struct panvk_cmd_buffer *cmdbuf, struct pan_fb_info *fbinfo, fbinfo->bifrost.pre_post.modes[dcd_idx] = MALI_PRE_POST_FRAME_SHADER_MODE_INTERSECT; } else { - enum pipe_format fmt = fbinfo->zs.view.zs - ? fbinfo->zs.view.zs->planes[0]->layout.format - : fbinfo->zs.view.s->planes[0]->layout.format; + const struct pan_image *plane = + fbinfo->zs.view.zs ? pan_image_view_get_zs_plane(fbinfo->zs.view.zs) + : pan_image_view_get_s_plane(fbinfo->zs.view.s); + enum pipe_format fmt = plane->layout.format; bool always = false; /* If we're dealing with a combined ZS resource and only one diff --git a/src/panfrost/vulkan/panvk_vX_image_view.c b/src/panfrost/vulkan/panvk_vX_image_view.c index 3a5a4463661..b2ea3ac96d6 100644 --- a/src/panfrost/vulkan/panvk_vX_image_view.c +++ b/src/panfrost/vulkan/panvk_vX_image_view.c @@ -105,25 +105,20 @@ panvk_per_arch(CreateImageView)(VkDevice _device, view->pview.planes[image_plane] = &image->planes[image_plane]; } + /* Depth/stencil are viewed as color for copies. */ + if (view->vk.aspects == VK_IMAGE_ASPECT_COLOR_BIT && + image->vk.format == VK_FORMAT_D32_SFLOAT_S8_UINT && + vk_format_get_blocksize(view->vk.view_format) == 1) { + view->pview.planes[0] = &image->planes[1]; + } + /* We need to patch the view format when the image contains both * depth and stencil but the view only contains one of these components, so * we can ignore the component we don't use. */ - if (vk_format_is_depth_or_stencil(view->vk.view_format)) { - if (image->vk.format == VK_FORMAT_D32_SFLOAT_S8_UINT && - view->vk.view_format != VK_FORMAT_D32_SFLOAT_S8_UINT) - view->pview.format = view->vk.view_format == VK_FORMAT_D32_SFLOAT - ? PIPE_FORMAT_Z32_FLOAT_S8X24_UINT - : PIPE_FORMAT_X32_S8X24_UINT; - - if (image->vk.format == VK_FORMAT_D24_UNORM_S8_UINT && - view->vk.view_format == VK_FORMAT_S8_UINT) - view->pview.format = PIPE_FORMAT_X24S8_UINT; - - if (image->vk.format == VK_FORMAT_D32_SFLOAT_S8_UINT && - view->vk.view_format == VK_FORMAT_S8_UINT) - view->pview.format = PIPE_FORMAT_X32_S8X24_UINT; - } + if (view->vk.view_format == VK_FORMAT_S8_UINT && + image->vk.format == VK_FORMAT_D24_UNORM_S8_UINT) + view->pview.format = PIPE_FORMAT_X24S8_UINT; /* Attachments need a texture for the FB preload logic. */ VkImageUsageFlags tex_usage_mask = @@ -143,8 +138,10 @@ panvk_per_arch(CreateImageView)(VkDevice _device, struct pan_image_view pview = view->pview; bool can_preload_other_aspect = (view->vk.usage & VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) && - (image->vk.format == VK_FORMAT_D32_SFLOAT_S8_UINT || - image->vk.format == VK_FORMAT_D24_UNORM_S8_UINT); + (image->vk.format == VK_FORMAT_D24_UNORM_S8_UINT || + (image->vk.format == VK_FORMAT_D32_SFLOAT_S8_UINT && + view->vk.aspects == + (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT))); if (util_format_is_depth_or_stencil(view->pview.format)) { /* Vulkan wants R001, where the depth/stencil is stored in the red @@ -161,6 +158,12 @@ panvk_per_arch(CreateImageView)(VkDevice _device, util_format_compose_swizzles(r001, view->pview.swizzle, pview.swizzle); } + /* If the view contains both stencil and depth, we need to keep only the + * depth. We'll create another texture with only the stencil. + */ + if (pview.format == PIPE_FORMAT_Z32_FLOAT_S8X24_UINT) + pview.format = PIPE_FORMAT_Z32_FLOAT; + struct panvk_pool_alloc_info alloc_info = { #if PAN_ARCH == 6 .alignment = pan_alignment(SURFACE_WITH_STRIDE), @@ -189,13 +192,6 @@ panvk_per_arch(CreateImageView)(VkDevice _device, if (can_preload_other_aspect) { switch (pview.format) { - case PIPE_FORMAT_Z32_FLOAT: - case PIPE_FORMAT_Z32_FLOAT_S8X24_UINT: - pview.format = PIPE_FORMAT_X32_S8X24_UINT; - break; - case PIPE_FORMAT_X32_S8X24_UINT: - pview.format = PIPE_FORMAT_Z32_FLOAT_S8X24_UINT; - break; case PIPE_FORMAT_Z24X8_UNORM: case PIPE_FORMAT_Z24_UNORM_S8_UINT: pview.format = PIPE_FORMAT_X24S8_UINT; @@ -203,6 +199,12 @@ panvk_per_arch(CreateImageView)(VkDevice _device, case PIPE_FORMAT_X24S8_UINT: pview.format = PIPE_FORMAT_Z24X8_UNORM; break; + case PIPE_FORMAT_Z32_FLOAT: + pview.format = PIPE_FORMAT_S8_UINT; + break; + case PIPE_FORMAT_S8_UINT: + pview.format = PIPE_FORMAT_Z32_FLOAT; + break; default: assert(!"Invalid format"); } @@ -217,12 +219,26 @@ panvk_per_arch(CreateImageView)(VkDevice _device, #if PAN_ARCH <= 7 if (view->vk.usage & VK_IMAGE_USAGE_STORAGE_BIT) { - bool is_3d = image->planes[0].layout.dim == MALI_TEXTURE_DIMENSION_3D; - unsigned offset = image->planes[0].data.offset; - offset += - panfrost_texture_offset(&image->planes[0].layout, view->pview.first_level, - is_3d ? 0 : view->pview.first_layer, - is_3d ? view->pview.first_layer : 0); + unsigned plane_idx = 0; + + /* Stencil is on plane 1 in a D32_S8 image. The special color case is for + * vk_meta copies which create color views of depth/stencil images. In + * that case, we base the stencil vs depth detection on the format block + * size. + */ + if (image->vk.format == VK_FORMAT_D32_SFLOAT_S8_UINT && + (view->vk.aspects == VK_IMAGE_ASPECT_STENCIL_BIT || + (view->vk.aspects == VK_IMAGE_ASPECT_COLOR_BIT && + vk_format_get_blocksize(view->vk.view_format) == 1))) + plane_idx = 1; + + bool is_3d = + image->planes[plane_idx].layout.dim == MALI_TEXTURE_DIMENSION_3D; + unsigned offset = image->planes[plane_idx].data.offset; + offset += panfrost_texture_offset(&image->planes[plane_idx].layout, + view->pview.first_level, + is_3d ? 0 : view->pview.first_layer, + is_3d ? view->pview.first_layer : 0); pan_pack(view->descs.img_attrib_buf[0].opaque, ATTRIBUTE_BUFFER, cfg) { /* The format is the only thing we lack to emit attribute descriptors @@ -241,7 +257,7 @@ panvk_per_arch(CreateImageView)(VkDevice _device, cfg.type = image->vk.drm_format_mod == DRM_FORMAT_MOD_LINEAR ? MALI_ATTRIBUTE_TYPE_3D_LINEAR : MALI_ATTRIBUTE_TYPE_3D_INTERLEAVED; - cfg.pointer = image->planes[0].data.base + offset; + cfg.pointer = image->planes[plane_idx].data.base + offset; cfg.stride = fmt_blksize | (hw_fmt << 10); cfg.size = pan_kmod_bo_size(image->bo) - offset; } @@ -257,10 +273,11 @@ panvk_per_arch(CreateImageView)(VkDevice _device, view->pview.dim == MALI_TEXTURE_DIMENSION_3D ? extent.depth : (view->pview.last_layer - view->pview.first_layer + 1); - cfg.row_stride = image->planes[0].layout.slices[level].row_stride; + cfg.row_stride = + image->planes[plane_idx].layout.slices[level].row_stride; if (cfg.r_dimension > 1) { - cfg.slice_stride = - panfrost_get_layer_stride(&image->planes[0].layout, level); + cfg.slice_stride = panfrost_get_layer_stride( + &image->planes[plane_idx].layout, level); } } }