radv: fix SDMA copies for linear 96-bits formats
Some checks are pending
macOS-CI / macOS-CI (dri) (push) Waiting to run
macOS-CI / macOS-CI (xlib) (push) Waiting to run

The hardware requires a power of two bpe. To do that, the driver
needs to adjust the pitch/offset/extent based on a texel scale factor
which only applies to 96-bits formats.

This fixes new VKCTS coverage.

Cc: mesa-stable
Signed-off-by: Samuel Pitoiset <samuel.pitoiset@gmail.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/34927>
This commit is contained in:
Samuel Pitoiset 2025-05-12 12:42:07 +02:00 committed by Marge Bot
parent a1ee6d6730
commit 4b73d7e817
2 changed files with 34 additions and 5 deletions

View file

@ -160,7 +160,26 @@ radv_sdma_get_bpe(const struct radv_image *const image, VkImageAspectFlags aspec
const struct radeon_surf *surf = &image->planes[plane_idx].surface;
const bool is_stencil_only = aspect_mask == VK_IMAGE_ASPECT_STENCIL_BIT;
return is_stencil_only ? 1 : surf->bpe;
if (is_stencil_only) {
return 1;
} else if (image->vk.format == VK_FORMAT_R32G32B32_UINT || image->vk.format == VK_FORMAT_R32G32B32_SINT ||
image->vk.format == VK_FORMAT_R32G32B32_SFLOAT) {
/* Adjust the bpp for 96-bits formats because SDMA expects a power of two. */
return 4;
} else {
return surf->bpe;
}
}
static uint32_t
radv_sdma_get_texel_scale(const struct radv_image *const image)
{
if (image->vk.format == VK_FORMAT_R32G32B32_UINT || image->vk.format == VK_FORMAT_R32G32B32_SINT ||
image->vk.format == VK_FORMAT_R32G32B32_SFLOAT) {
return 3;
} else {
return 1;
}
}
struct radv_sdma_surf
@ -168,7 +187,8 @@ radv_sdma_get_buf_surf(uint64_t buffer_va, const struct radv_image *const image,
{
assert(util_bitcount(region->imageSubresource.aspectMask) == 1);
const unsigned pitch = (region->bufferRowLength ? region->bufferRowLength : region->imageExtent.width);
const uint32_t texel_scale = radv_sdma_get_texel_scale(image);
const unsigned pitch = (region->bufferRowLength ? region->bufferRowLength : region->imageExtent.width) * texel_scale;
const unsigned slice_pitch =
(region->bufferImageHeight ? region->bufferImageHeight : region->imageExtent.height) * pitch;
@ -183,6 +203,7 @@ radv_sdma_get_buf_surf(uint64_t buffer_va, const struct radv_image *const image,
.bpp = bpe,
.blk_w = surf->blk_w,
.blk_h = surf->blk_h,
.texel_scale = texel_scale,
.is_linear = true,
};
@ -289,6 +310,7 @@ radv_sdma_get_surf(const struct radv_device *const device, const struct radv_ima
.blk_h = surf->blk_h,
.mip_levels = image->vk.mip_levels,
.micro_tile_mode = surf->micro_tile_mode,
.texel_scale = radv_sdma_get_texel_scale(image),
.is_linear = surf->is_linear,
.is_3d = surf->u.gfx9.resource_type == RADEON_RESOURCE_3D,
};
@ -483,9 +505,9 @@ radv_sdma_emit_copy_linear_sub_window(const struct radv_device *device, struct r
*/
const struct radv_physical_device *pdev = radv_device_physical(device);
const VkOffset3D src_off = radv_sdma_pixel_offset_to_blocks(src->offset, src->blk_w, src->blk_h);
const VkOffset3D dst_off = radv_sdma_pixel_offset_to_blocks(dst->offset, dst->blk_w, dst->blk_h);
const VkExtent3D ext = radv_sdma_pixel_extent_to_blocks(pix_extent, src->blk_w, src->blk_h);
VkOffset3D src_off = radv_sdma_pixel_offset_to_blocks(src->offset, src->blk_w, src->blk_h);
VkOffset3D dst_off = radv_sdma_pixel_offset_to_blocks(dst->offset, dst->blk_w, dst->blk_h);
VkExtent3D ext = radv_sdma_pixel_extent_to_blocks(pix_extent, src->blk_w, src->blk_h);
const unsigned src_pitch = radv_sdma_pixels_to_blocks(src->pitch, src->blk_w);
const unsigned dst_pitch = radv_sdma_pixels_to_blocks(dst->pitch, dst->blk_w);
const unsigned src_slice_pitch = radv_sdma_pixel_area_to_blocks(src->slice_pitch, src->blk_w, src->blk_h);
@ -497,6 +519,12 @@ radv_sdma_emit_copy_linear_sub_window(const struct radv_device *device, struct r
radv_sdma_check_pitches(src->pitch, src->slice_pitch, src->bpp, false);
radv_sdma_check_pitches(dst->pitch, dst->slice_pitch, dst->bpp, false);
/* Adjust offset/extent for 96-bits formats because SDMA expects a power of two bpp. */
const uint32_t texel_scale = src->texel_scale == 1 ? dst->texel_scale : src->texel_scale;
src_off.x *= texel_scale;
dst_off.x *= texel_scale;
ext.width *= texel_scale;
ASSERTED unsigned cdw_end = radeon_check_space(device->ws, cs, 13);
radeon_begin(cs);

View file

@ -22,6 +22,7 @@ struct radv_sdma_surf {
unsigned blk_h; /* Image format block height in pixels. */
unsigned mip_levels; /* Mip levels in the image. */
uint8_t micro_tile_mode; /* Micro tile mode of the image. */
uint8_t texel_scale; /* Texel scale for 96-bit formats */
bool is_linear; /* Whether the image is linear. */
bool is_3d; /* Whether the image is 3-dimensional. */