radv: Use SDMA surface structs for determining unaligned buffer copies.

This removes a bunch of redundant calculations, thus making the code
less error-prone.

Also move the row pitch calculation to a separate function.

Signed-off-by: Timur Kristóf <timur.kristof@gmail.com>
Reviewed-by: Tatsuyuki Ishi <ishitatsuyuki@gmail.com>
Reviewed-by: Samuel Pitoiset <samuel.pitoiset@gmail.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/26353>
This commit is contained in:
Timur Kristóf 2023-12-07 21:17:31 +01:00 committed by Marge Bot
parent dab4863396
commit 7fe899a3b6
3 changed files with 19 additions and 30 deletions

View file

@ -103,7 +103,7 @@ transfer_copy_buffer_image(struct radv_cmd_buffer *cmd_buffer, struct radv_buffe
const struct radv_sdma_surf img = radv_sdma_get_surf(device, image, region->imageSubresource, region->imageOffset);
const VkExtent3D extent = radv_sdma_get_copy_extent(image, region->imageSubresource, region->imageExtent);
if (radv_sdma_use_unaligned_buffer_image_copy(device, image, buffer, region)) {
if (radv_sdma_use_unaligned_buffer_image_copy(device, &buf, &img, extent)) {
if (!alloc_transfer_temp_bo(cmd_buffer))
return;

View file

@ -41,6 +41,15 @@ struct radv_sdma_chunked_copy_info {
unsigned num_rows_per_copy;
};
ALWAYS_INLINE static unsigned
radv_sdma_pitch_alignment(const struct radv_device *device, const unsigned bpp)
{
if (device->physical_device->rad_info.sdma_ip_version >= SDMA_5_0)
return MAX2(1, 4 / bpp);
return 4;
}
ALWAYS_INLINE static void
radv_sdma_check_pitches(const unsigned pitch, const unsigned slice_pitch, const unsigned bpp, const bool uses_depth)
{
@ -81,16 +90,6 @@ radv_sdma_surface_type_from_aspect_mask(const VkImageAspectFlags aspectMask)
return 0;
}
ALWAYS_INLINE static VkOffset3D
radv_sdma_get_image_offset(const struct radv_image *const image, const VkImageSubresourceLayers subresource,
VkOffset3D offset)
{
if (image->vk.image_type != VK_IMAGE_TYPE_3D)
offset.z = subresource.baseArrayLayer;
return offset;
}
ALWAYS_INLINE static VkExtent3D
radv_sdma_pixel_extent_to_blocks(const VkExtent3D extent, const unsigned blk_w, const unsigned blk_h)
{
@ -494,26 +493,16 @@ radv_sdma_copy_buffer_image(const struct radv_device *device, struct radeon_cmdb
}
bool
radv_sdma_use_unaligned_buffer_image_copy(const struct radv_device *device, const struct radv_image *image,
const struct radv_buffer *buffer, const VkBufferImageCopy2 *region)
radv_sdma_use_unaligned_buffer_image_copy(const struct radv_device *device, const struct radv_sdma_surf *buf,
const struct radv_sdma_surf *img, const VkExtent3D ext)
{
const struct radeon_surf *const surf = &image->planes[0].surface;
const enum sdma_version ver = device->physical_device->rad_info.sdma_ip_version;
const unsigned pitch_alignment = ver >= SDMA_5_0 ? MAX2(1, 4 / surf->bpe) : 4;
const unsigned pitch = (region->bufferRowLength ? region->bufferRowLength : region->imageExtent.width);
const unsigned pitch_blocks = radv_sdma_pixels_to_blocks(pitch, surf->blk_w);
if (!radv_is_aligned(pitch_blocks, pitch_alignment))
const unsigned pitch_blocks = radv_sdma_pixels_to_blocks(buf->pitch, img->blk_w);
if (!radv_is_aligned(pitch_blocks, radv_sdma_pitch_alignment(device, img->bpp)))
return true;
const VkOffset3D off = radv_sdma_get_image_offset(image, region->imageSubresource, region->imageOffset);
const VkExtent3D ext = radv_sdma_get_copy_extent(image, region->imageSubresource, region->imageExtent);
const bool uses_depth = off.z != 0 || ext.depth != 1;
if (!surf->is_linear && uses_depth) {
const unsigned slice_pitch =
(region->bufferImageHeight ? region->bufferImageHeight : region->imageExtent.height) * pitch;
const unsigned slice_pitch_blocks = radv_sdma_pixel_area_to_blocks(slice_pitch, surf->blk_w, surf->blk_h);
const bool uses_depth = img->offset.z != 0 || ext.depth != 1;
if (!img->is_linear && uses_depth) {
const unsigned slice_pitch_blocks = radv_sdma_pixel_area_to_blocks(buf->slice_pitch, img->blk_w, img->blk_h);
if (!radv_is_aligned(slice_pitch_blocks, 4))
return true;
}

View file

@ -73,8 +73,8 @@ struct radv_sdma_surf radv_sdma_get_surf(const struct radv_device *const device,
void radv_sdma_copy_buffer_image(const struct radv_device *device, struct radeon_cmdbuf *cs,
const struct radv_sdma_surf *buf, const struct radv_sdma_surf *img,
const VkExtent3D extent, bool to_image);
bool radv_sdma_use_unaligned_buffer_image_copy(const struct radv_device *device, const struct radv_image *image,
const struct radv_buffer *buffer, const VkBufferImageCopy2 *region);
bool radv_sdma_use_unaligned_buffer_image_copy(const struct radv_device *device, const struct radv_sdma_surf *buf,
const struct radv_sdma_surf *img, const VkExtent3D ext);
void radv_sdma_copy_buffer_image_unaligned(const struct radv_device *device, struct radeon_cmdbuf *cs,
const struct radv_sdma_surf *buf, const struct radv_sdma_surf *img_in,
const VkExtent3D copy_extent, struct radeon_winsys_bo *temp_bo,