diff --git a/src/amd/vulkan/radv_sdma.c b/src/amd/vulkan/radv_sdma.c index 4a75bb84e93..e99c0fda029 100644 --- a/src/amd/vulkan/radv_sdma.c +++ b/src/amd/vulkan/radv_sdma.c @@ -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); diff --git a/src/amd/vulkan/radv_sdma.h b/src/amd/vulkan/radv_sdma.h index e1dd06c962e..b0de4a1a6b5 100644 --- a/src/amd/vulkan/radv_sdma.h +++ b/src/amd/vulkan/radv_sdma.h @@ -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. */