From 317a3fe49b206db1a1075be6a1b56d206e908f04 Mon Sep 17 00:00:00 2001 From: Jarred Davies Date: Thu, 19 Jan 2023 10:46:16 +0000 Subject: [PATCH] pvr: Select a single aspect format for the texture state of DS image views This change also means the texture state words will be based off of the image view's format instead of the image's format. Signed-off-by: Jarred Davies Reviewed-by: Frank Binns Part-of: --- src/imagination/vulkan/pvr_formats.c | 39 ++++++++++++++++++++++++-- src/imagination/vulkan/pvr_formats.h | 2 ++ src/imagination/vulkan/pvr_image.c | 6 ++-- src/imagination/vulkan/pvr_tex_state.c | 8 +++++- src/imagination/vulkan/pvr_tex_state.h | 1 + 5 files changed, 48 insertions(+), 8 deletions(-) diff --git a/src/imagination/vulkan/pvr_formats.c b/src/imagination/vulkan/pvr_formats.c index 9ef8710100c..9364de7b6f0 100644 --- a/src/imagination/vulkan/pvr_formats.c +++ b/src/imagination/vulkan/pvr_formats.c @@ -47,6 +47,8 @@ [VK_FORMAT_##vk] = { \ .vk_format = VK_FORMAT_##vk, \ .tex_format = ROGUE_TEXSTATE_FORMAT_##tex_fmt, \ + .depth_tex_format = ROGUE_TEXSTATE_FORMAT_INVALID, \ + .stencil_tex_format = ROGUE_TEXSTATE_FORMAT_INVALID, \ .pbe_packmode = ROGUE_PBESTATE_PACKMODE_##pack_mode, \ .pbe_accum_format = PVR_PBE_ACCUM_FORMAT_##accum_format, \ .supported = true, \ @@ -56,14 +58,29 @@ [VK_FORMAT_##vk] = { \ .vk_format = VK_FORMAT_##vk, \ .tex_format = ROGUE_TEXSTATE_FORMAT_COMPRESSED_##tex_fmt, \ + .depth_tex_format = ROGUE_TEXSTATE_FORMAT_INVALID, \ + .stencil_tex_format = ROGUE_TEXSTATE_FORMAT_INVALID, \ .pbe_packmode = ROGUE_PBESTATE_PACKMODE_INVALID, \ .pbe_accum_format = PVR_PBE_ACCUM_FORMAT_INVALID, \ .supported = true, \ } +#define FORMAT_DEPTH_STENCIL(vk, combined_fmt, d_fmt, s_fmt) \ + [VK_FORMAT_##vk] = { \ + .vk_format = VK_FORMAT_##vk, \ + .tex_format = ROGUE_TEXSTATE_FORMAT_##combined_fmt, \ + .depth_tex_format = ROGUE_TEXSTATE_FORMAT_##d_fmt, \ + .stencil_tex_format = ROGUE_TEXSTATE_FORMAT_##s_fmt, \ + .pbe_packmode = ROGUE_PBESTATE_PACKMODE_INVALID, \ + .pbe_accum_format = PVR_PBE_ACCUM_FORMAT_INVALID, \ + .supported = true, \ + } + struct pvr_format { VkFormat vk_format; uint32_t tex_format; + uint32_t depth_tex_format; + uint32_t stencil_tex_format; uint32_t pbe_packmode; enum pvr_pbe_accum_format pbe_accum_format; bool supported; @@ -179,11 +196,11 @@ static const struct pvr_format pvr_format_table[] = { /* VK_FORMAT_E5B9G9R9_UFLOAT_PACK32 = 123. */ FORMAT(E5B9G9R9_UFLOAT_PACK32, SE9995, SE9995, INVALID), /* VK_FORMAT_D16_UNORM = 124. */ - FORMAT(D16_UNORM, U16, U16, F16), + FORMAT_DEPTH_STENCIL(D16_UNORM, U16, U16, INVALID), /* VK_FORMAT_D32_SFLOAT = 126. */ - FORMAT(D32_SFLOAT, F32, F32, F16), + FORMAT_DEPTH_STENCIL(D32_SFLOAT, F32, F32, INVALID), /* VK_FORMAT_D24_UNORM_S8_UINT = 129. */ - FORMAT(D24_UNORM_S8_UINT, ST8U24, ST8U24, F16), + FORMAT_DEPTH_STENCIL(D24_UNORM_S8_UINT, ST8U24, X8U24, U8X24), /* VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK = 147. */ FORMAT_COMPRESSED(ETC2_R8G8B8_UNORM_BLOCK, ETC2_RGB), /* VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK = 148. */ @@ -232,6 +249,22 @@ uint32_t pvr_get_tex_format(VkFormat vk_format) return ROGUE_TEXSTATE_FORMAT_INVALID; } +uint32_t pvr_get_tex_format_aspect(VkFormat vk_format, + VkImageAspectFlags aspect_mask) +{ + const struct pvr_format *pvr_format = pvr_get_format(vk_format); + if (pvr_format) { + if (aspect_mask == VK_IMAGE_ASPECT_DEPTH_BIT) + return pvr_format->depth_tex_format; + else if (aspect_mask == VK_IMAGE_ASPECT_STENCIL_BIT) + return pvr_format->stencil_tex_format; + + return pvr_format->tex_format; + } + + return PVRX(TEXSTATE_FORMAT_INVALID); +} + uint32_t pvr_get_pbe_packmode(VkFormat vk_format) { const struct pvr_format *pvr_format = pvr_get_format(vk_format); diff --git a/src/imagination/vulkan/pvr_formats.h b/src/imagination/vulkan/pvr_formats.h index ba6e490f196..f7d011bb3e1 100644 --- a/src/imagination/vulkan/pvr_formats.h +++ b/src/imagination/vulkan/pvr_formats.h @@ -59,6 +59,8 @@ enum pvr_pbe_accum_format { const uint8_t *pvr_get_format_swizzle(VkFormat vk_format); uint32_t pvr_get_tex_format(VkFormat vk_format); +uint32_t pvr_get_tex_format_aspect(VkFormat vk_format, + VkImageAspectFlags aspect_mask); uint32_t pvr_get_pbe_packmode(VkFormat vk_format); uint32_t pvr_get_pbe_accum_format(VkFormat vk_format); uint32_t pvr_get_pbe_accum_format_size_in_bytes(VkFormat vk_format); diff --git a/src/imagination/vulkan/pvr_image.c b/src/imagination/vulkan/pvr_image.c index 8f43682d0f0..19d5240b2ad 100644 --- a/src/imagination/vulkan/pvr_image.c +++ b/src/imagination/vulkan/pvr_image.c @@ -286,6 +286,7 @@ VkResult pvr_CreateImageView(VkDevice _device, info.base_level = iview->vk.base_mip_level; info.mip_levels = iview->vk.level_count; info.extent = image->vk.extent; + info.aspect_mask = image->vk.aspects; info.is_cube = (info.type == VK_IMAGE_VIEW_TYPE_CUBE || info.type == VK_IMAGE_VIEW_TYPE_CUBE_ARRAY); info.array_size = iview->vk.layer_count; @@ -299,10 +300,7 @@ VkResult pvr_CreateImageView(VkDevice _device, info.sample_count = image->vk.samples; info.addr = image->dev_addr; - /* TODO: if ERN_46863 is supported, Depth and stencil are sampled separately - * from images with combined depth+stencil. Add logic here to handle it. - */ - info.format = iview->vk.format; + info.format = pCreateInfo->format; vk_component_mapping_to_pipe_swizzle(iview->vk.swizzle, input_swizzle); format_swizzle = pvr_get_format_swizzle(info.format); diff --git a/src/imagination/vulkan/pvr_tex_state.c b/src/imagination/vulkan/pvr_tex_state.c index c2a2f7601d7..4ef771a3363 100644 --- a/src/imagination/vulkan/pvr_tex_state.c +++ b/src/imagination/vulkan/pvr_tex_state.c @@ -130,7 +130,13 @@ pvr_pack_tex_state(struct pvr_device *device, unreachable("Unknown memory layout"); } - word0.texformat = pvr_get_tex_format(info->format); + /* When sampling from a combined D/S image, the TPU will default to only + * the depth aspect. + * The driver must select the correct single aspect format when sampling + * to avoid this. + */ + word0.texformat = + pvr_get_tex_format_aspect(info->format, info->aspect_mask); word0.smpcnt = util_logbase2(info->sample_count); word0.swiz0 = pvr_get_hw_swizzle(VK_COMPONENT_SWIZZLE_R, info->swizzle[0]); diff --git a/src/imagination/vulkan/pvr_tex_state.h b/src/imagination/vulkan/pvr_tex_state.h index 24e199b1014..6cd617ce877 100644 --- a/src/imagination/vulkan/pvr_tex_state.h +++ b/src/imagination/vulkan/pvr_tex_state.h @@ -52,6 +52,7 @@ struct pvr_texture_state_info { enum pvr_memlayout mem_layout; uint32_t flags; VkImageViewType type; + VkImageAspectFlags aspect_mask; bool is_cube; enum pvr_texture_state tex_state_type; VkExtent3D extent;