diff --git a/src/panfrost/vulkan/panvk_meta.h b/src/panfrost/vulkan/panvk_meta.h index 18636455205..04371162a53 100644 --- a/src/panfrost/vulkan/panvk_meta.h +++ b/src/panfrost/vulkan/panvk_meta.h @@ -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 || diff --git a/src/panfrost/vulkan/panvk_vX_cmd_meta.c b/src/panfrost/vulkan/panvk_vX_cmd_meta.c index 48af11f8bdd..4c34f6544bd 100644 --- a/src/panfrost/vulkan/panvk_vX_cmd_meta.c +++ b/src/panfrost/vulkan/panvk_vX_cmd_meta.c @@ -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};