panvk: Consolidate image copy format selection

Non-UNORM/non-RGBA8 formats forces blend shaders to be used when the
graphics pipeline is involved. We also have a few formats that can't
be used with AFBC, so let's consolidate the formats we pick when using
a graphics pipeline independently of the image modifier.

Signed-off-by: Boris Brezillon <boris.brezillon@collabora.com>
Reviewed-by: Eric R. Smith <eric.smith@collabora.com>
Reviewed-by: Christoph Pillmayer <christoph.pillmayer@arm.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/37158>
This commit is contained in:
Boris Brezillon 2025-09-04 15:28:31 +02:00 committed by Marge Bot
parent 3643a4115b
commit b4b874ef24
2 changed files with 77 additions and 51 deletions

View file

@ -29,11 +29,11 @@ panvk_meta_get_uint_format_for_blk_size(unsigned blk_sz)
case 1:
return VK_FORMAT_R8_UINT;
case 2:
return VK_FORMAT_R16_UINT;
return VK_FORMAT_R8G8_UINT;
case 3:
return VK_FORMAT_R8G8B8_UINT;
case 4:
return VK_FORMAT_R32_UINT;
return VK_FORMAT_R8G8B8A8_UINT;
case 6:
return VK_FORMAT_R16G16B16_UINT;
case 8:
@ -47,8 +47,31 @@ panvk_meta_get_uint_format_for_blk_size(unsigned blk_sz)
}
}
static inline VkFormat
panvk_meta_get_unorm_format_for_blk_size(unsigned blk_sz)
{
/* We expect _UINT formats to be used if the blocksize is greater than
* 32-bit.
*/
assert(blk_sz <= 4);
switch (blk_sz) {
case 1:
return VK_FORMAT_R8_UNORM;
case 2:
return VK_FORMAT_R8G8_UNORM;
case 3:
return VK_FORMAT_R8G8B8_UNORM;
case 4:
return VK_FORMAT_R8G8B8A8_UNORM;
default:
return VK_FORMAT_UNDEFINED;
}
}
static inline struct vk_meta_copy_image_properties
panvk_meta_copy_get_image_properties(struct panvk_image *img)
panvk_meta_copy_get_image_properties(struct panvk_image *img,
bool use_gfx_pipeline, bool is_destination)
{
uint64_t mod = img->vk.drm_format_mod;
enum pipe_format pfmt = vk_format_to_pipe_format(img->vk.format);
@ -56,63 +79,52 @@ panvk_meta_copy_get_image_properties(struct panvk_image *img)
memset(&props, 0, sizeof(props));
const struct vk_format_ycbcr_info *ycbcr_info =
vk_format_get_ycbcr_info(img->vk.format);
const bool is_afbc = drm_is_afbc(img->vk.drm_format_mod);
/* Format re-interpretation is not an option on Bifrost */
const bool preserve_img_fmt = is_afbc && PAN_ARCH <= 7;
/* We want UNORM when the image is the destination of a copy and a graphics
* pipeline is used to avoid blend shaders. On Bifrost, only UNORM/sRGB
* is allowed, so we use UNORM formats when creating depth/stencil views too.
*/
const bool use_unorm =
(use_gfx_pipeline && is_destination) || preserve_img_fmt;
if (drm_is_afbc(mod)) {
if (ycbcr_info) {
for (uint32_t p = 0; p < ycbcr_info->n_planes; p++)
props.plane[p].view_format = ycbcr_info->planes[p].format;
} else if (!vk_format_is_depth_or_stencil(img->vk.format)) {
props.color.view_format = img->vk.format;
} else {
switch (img->vk.format) {
case VK_FORMAT_D24_UNORM_S8_UINT:
props.depth.view_format = VK_FORMAT_R8G8B8A8_UNORM;
props.depth.component_mask = BITFIELD_MASK(3);
props.stencil.view_format = VK_FORMAT_R8G8B8A8_UNORM;
props.stencil.component_mask = BITFIELD_BIT(3);
break;
case VK_FORMAT_X8_D24_UNORM_PACK32:
props.depth.view_format = VK_FORMAT_R8G8B8A8_UNORM;
props.depth.component_mask = BITFIELD_MASK(3);
break;
case VK_FORMAT_D16_UNORM:
props.depth.view_format = VK_FORMAT_R8G8_UNORM;
props.depth.component_mask = BITFIELD_MASK(2);
break;
default:
assert(!"Invalid ZS format");
break;
}
}
} else if (vk_format_is_depth_or_stencil(img->vk.format)) {
if (vk_format_is_depth_or_stencil(img->vk.format)) {
switch (img->vk.format) {
case VK_FORMAT_S8_UINT:
props.stencil.view_format = VK_FORMAT_R8_UINT;
props.stencil.view_format =
use_unorm ? VK_FORMAT_R8_UNORM : VK_FORMAT_R8_UINT;
props.stencil.component_mask = BITFIELD_MASK(1);
break;
case VK_FORMAT_D24_UNORM_S8_UINT:
props.depth.view_format = VK_FORMAT_R8G8B8A8_UINT;
props.depth.view_format =
use_unorm ? VK_FORMAT_R8G8B8A8_UNORM : VK_FORMAT_R8G8B8A8_UINT;
props.depth.component_mask = BITFIELD_MASK(3);
props.stencil.view_format = VK_FORMAT_R8G8B8A8_UINT;
props.stencil.view_format = props.depth.view_format;
props.stencil.component_mask = BITFIELD_BIT(3);
break;
case VK_FORMAT_X8_D24_UNORM_PACK32:
props.depth.view_format = VK_FORMAT_R8G8B8A8_UINT;
props.depth.view_format =
use_unorm ? VK_FORMAT_R8G8B8A8_UNORM : VK_FORMAT_R8G8B8A8_UINT;
props.depth.component_mask = BITFIELD_MASK(3);
break;
case VK_FORMAT_D32_SFLOAT_S8_UINT:
props.depth.view_format = VK_FORMAT_R32_UINT;
props.depth.component_mask = BITFIELD_BIT(0);
props.stencil.view_format = VK_FORMAT_R8_UINT;
props.depth.view_format = use_unorm ? VK_FORMAT_R8G8B8A8_UNORM
: VK_FORMAT_R8G8B8A8_UINT;
props.depth.component_mask = BITFIELD_MASK(4);
props.stencil.view_format =
use_unorm ? VK_FORMAT_R8_UNORM : 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;
props.depth.component_mask = BITFIELD_BIT(0);
props.depth.view_format =
use_unorm ? VK_FORMAT_R8G8_UNORM : VK_FORMAT_R8G8_UINT;
props.depth.component_mask = BITFIELD_MASK(2);
break;
case VK_FORMAT_D32_SFLOAT:
props.depth.view_format = VK_FORMAT_R32_UINT;
props.depth.component_mask = BITFIELD_BIT(0);
props.depth.view_format = use_unorm ? VK_FORMAT_R8G8B8A8_UNORM
: VK_FORMAT_R8G8B8A8_UINT;
props.depth.component_mask = BITFIELD_MASK(4);
break;
default:
assert(!"Invalid ZS format");
@ -124,12 +136,22 @@ panvk_meta_copy_get_image_properties(struct panvk_image *img)
vk_format_get_blocksize(ycbcr_info->planes[p].format);
props.plane[p].view_format =
use_unorm ?
panvk_meta_get_unorm_format_for_blk_size(blk_sz) :
panvk_meta_get_uint_format_for_blk_size(blk_sz);
}
} else {
unsigned blk_sz = util_format_get_blocksize(pfmt);
props.color.view_format = panvk_meta_get_uint_format_for_blk_size(blk_sz);
if (preserve_img_fmt) {
props.color.view_format = img->vk.format;
} else if (use_unorm) {
props.color.view_format =
panvk_meta_get_unorm_format_for_blk_size(blk_sz);
} else {
props.color.view_format =
panvk_meta_get_uint_format_for_blk_size(blk_sz);
}
}
if (mod == DRM_FORMAT_MOD_ARM_16X16_BLOCK_U_INTERLEAVED ||

View file

@ -23,7 +23,9 @@ copy_to_image_use_gfx_pipeline(struct panvk_device *dev,
struct panvk_instance *instance =
to_panvk_instance(dev->vk.physical->instance);
if (instance->debug_flags & PANVK_DEBUG_COPY_GFX)
/* Don't force gfx-based copies if the format is bigger than 32-bit. */
if ((instance->debug_flags & PANVK_DEBUG_COPY_GFX) &&
vk_format_get_blocksize(dst_img->vk.format) <= 4)
return true;
/* Writes to AFBC images must go through the graphics pipeline. */
@ -391,14 +393,15 @@ panvk_per_arch(CmdCopyBufferToImage2)(
VK_FROM_HANDLE(panvk_cmd_buffer, cmdbuf, commandBuffer);
struct panvk_device *dev = to_panvk_device(cmdbuf->vk.base.device);
VK_FROM_HANDLE(panvk_image, img, pCopyBufferToImageInfo->dstImage);
struct vk_meta_copy_image_properties img_props =
panvk_meta_copy_get_image_properties(img);
/* Early out if this operation was lowered. */
if (lower_copy_buffer_to_image(commandBuffer, pCopyBufferToImageInfo))
return;
bool use_gfx_pipeline = copy_to_image_use_gfx_pipeline(dev, img);
struct vk_meta_copy_image_properties img_props =
panvk_meta_copy_get_image_properties(img, use_gfx_pipeline, true);
if (use_gfx_pipeline) {
struct panvk_cmd_meta_graphics_save_ctx save = {0};
@ -427,7 +430,7 @@ panvk_per_arch(CmdCopyImageToBuffer2)(
struct panvk_device *dev = to_panvk_device(cmdbuf->vk.base.device);
VK_FROM_HANDLE(panvk_image, img, pCopyImageToBufferInfo->srcImage);
struct vk_meta_copy_image_properties img_props =
panvk_meta_copy_get_image_properties(img);
panvk_meta_copy_get_image_properties(img, false, false);
struct panvk_cmd_meta_compute_save_ctx save = {0};
panvk_per_arch(cmd_meta_compute_start)(cmdbuf, &save);
@ -547,16 +550,17 @@ panvk_per_arch(CmdCopyImage2)(VkCommandBuffer commandBuffer,
struct panvk_device *dev = to_panvk_device(cmdbuf->vk.base.device);
VK_FROM_HANDLE(panvk_image, src_img, pCopyImageInfo->srcImage);
VK_FROM_HANDLE(panvk_image, dst_img, pCopyImageInfo->dstImage);
struct vk_meta_copy_image_properties src_img_props =
panvk_meta_copy_get_image_properties(src_img);
struct vk_meta_copy_image_properties dst_img_props =
panvk_meta_copy_get_image_properties(dst_img);
/* Early out if this operation was lowered. */
if (lower_copy_image(commandBuffer, pCopyImageInfo))
return;
bool use_gfx_pipeline = copy_to_image_use_gfx_pipeline(dev, dst_img);
struct vk_meta_copy_image_properties dst_img_props =
panvk_meta_copy_get_image_properties(dst_img, use_gfx_pipeline, true);
struct vk_meta_copy_image_properties src_img_props =
panvk_meta_copy_get_image_properties(src_img, use_gfx_pipeline, false);
if (use_gfx_pipeline) {
struct panvk_cmd_meta_graphics_save_ctx save = {0};