ac,radv: add ac_emit_sdma_copy_t2t_sub_window()

Signed-off-by: Samuel Pitoiset <samuel.pitoiset@gmail.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/38448>
This commit is contained in:
Samuel Pitoiset
2025-11-14 12:56:04 +01:00
committed by Marge Bot
parent f5ecc5ffd5
commit a4e4f13c78
3 changed files with 138 additions and 62 deletions
+82
View File
@@ -351,3 +351,85 @@ ac_emit_sdma_copy_tiled_sub_window(struct ac_cmdbuf *cs, const struct radeon_inf
ac_cmdbuf_end();
}
void
ac_emit_sdma_copy_t2t_sub_window(struct ac_cmdbuf *cs, const struct radeon_info *info,
const struct ac_sdma_surf_tiled *src,
const struct ac_sdma_surf_tiled *dst,
uint32_t width, uint32_t height, uint32_t depth)
{
const uint32_t src_header_dword =
ac_sdma_get_tiled_header_dword(info->sdma_ip_version, src);
const uint32_t src_info_dword = ac_sdma_get_tiled_info_dword(info, src);
const uint32_t dst_info_dword = ac_sdma_get_tiled_info_dword(info, dst);
/* Sanity checks. */
assert(info->sdma_ip_version >= SDMA_4_0);
/* On GFX10+ this supports DCC, but cannot copy a compressed surface to another compressed surface. */
assert(!src->is_compressed || !dst->is_compressed);
if (info->sdma_ip_version >= SDMA_4_0 && info->sdma_ip_version < SDMA_5_0) {
/* SDMA v4 doesn't support mip_id selection in the T2T copy packet. */
assert(src_header_dword >> 24 == 0);
/* SDMA v4 doesn't support any image metadata. */
assert(!src->is_compressed);
assert(!dst->is_compressed);
}
assert(util_is_power_of_two_nonzero(src->bpp));
assert(util_is_power_of_two_nonzero(dst->bpp));
/* Despite the name, this can indicate DCC or HTILE metadata. */
const uint32_t dcc = src->is_compressed || dst->is_compressed;
/* 0 = compress (src is uncompressed), 1 = decompress (src is compressed). */
const uint32_t dcc_dir = src->is_compressed && !dst->is_compressed;
ac_cmdbuf_begin(cs);
ac_cmdbuf_emit(SDMA_PACKET(SDMA_OPCODE_COPY, SDMA_COPY_SUB_OPCODE_T2T_SUB_WINDOW, 0) |
dcc << 19 | dcc_dir << 31 | src_header_dword);
ac_cmdbuf_emit(src->va);
ac_cmdbuf_emit(src->va >> 32);
ac_cmdbuf_emit(src->offset.x | src->offset.y << 16);
ac_cmdbuf_emit(src->offset.z | (src->extent.width - 1) << 16);
ac_cmdbuf_emit((src->extent.height - 1) | (src->extent.depth - 1) << 16);
ac_cmdbuf_emit(src_info_dword);
ac_cmdbuf_emit(dst->va);
ac_cmdbuf_emit(dst->va >> 32);
ac_cmdbuf_emit(dst->offset.x | dst->offset.y << 16);
ac_cmdbuf_emit(dst->offset.z | (dst->extent.width - 1) << 16);
ac_cmdbuf_emit((dst->extent.height - 1) | (dst->extent.depth - 1) << 16);
ac_cmdbuf_emit(dst_info_dword);
ac_cmdbuf_emit((width - 1) | (height - 1) << 16);
ac_cmdbuf_emit((depth - 1));
if (info->sdma_ip_version >= SDMA_7_0) {
/* Compress only when dst has DCC. If src has DCC, it automatically
* decompresses according to PTE.D (page table bit) even if we don't
* enable DCC in the packet.
*/
if (dst->is_compressed) {
const uint32_t dst_meta_config =
ac_sdma_get_tiled_metadata_config(info, dst, false, false);
ac_cmdbuf_emit(dst_meta_config);
}
} else {
if (dst->is_compressed) {
const uint32_t dst_meta_config =
ac_sdma_get_tiled_metadata_config(info, dst, false, false);
ac_cmdbuf_emit(dst->meta_va);
ac_cmdbuf_emit(dst->meta_va >> 32);
ac_cmdbuf_emit(dst_meta_config);
} else if (src->is_compressed) {
const uint32_t src_meta_config =
ac_sdma_get_tiled_metadata_config(info, src, true, false);
ac_cmdbuf_emit(src->meta_va);
ac_cmdbuf_emit(src->meta_va >> 32);
ac_cmdbuf_emit(src_meta_config);
}
}
ac_cmdbuf_end();
}
+6
View File
@@ -90,6 +90,12 @@ ac_emit_sdma_copy_tiled_sub_window(struct ac_cmdbuf *cs, const struct radeon_inf
bool detile, uint32_t width, uint32_t height,
uint32_t depth, bool tmz);
void
ac_emit_sdma_copy_t2t_sub_window(struct ac_cmdbuf *cs, const struct radeon_info *info,
const struct ac_sdma_surf_tiled *src,
const struct ac_sdma_surf_tiled *dst,
uint32_t width, uint32_t height, uint32_t depth);
#ifdef __cplusplus
}
#endif
+50 -62
View File
@@ -491,76 +491,64 @@ radv_sdma_emit_copy_t2t_sub_window(const struct radv_device *device, struct radv
const VkExtent3D px_extent)
{
const struct radv_physical_device *pdev = radv_device_physical(device);
/* We currently only support the SDMA v4+ versions of this packet. */
assert(pdev->info.sdma_ip_version >= SDMA_4_0);
/* On GFX10+ this supports DCC, but cannot copy a compressed surface to another compressed surface. */
assert(!src->is_compressed || !dst->is_compressed);
if (pdev->info.sdma_ip_version >= SDMA_4_0 && pdev->info.sdma_ip_version < SDMA_5_0) {
/* SDMA v4 doesn't support mip_id selection in the T2T copy packet. */
assert(src->header_dword >> 24 == 0);
assert(dst->header_dword >> 24 == 0);
/* SDMA v4 doesn't support any image metadata. */
assert(!src->is_compressed);
assert(!dst->is_compressed);
}
/* Despite the name, this can indicate DCC or HTILE metadata. */
const uint32_t dcc = src->is_compressed || dst->is_compressed;
/* 0 = compress (src is uncompressed), 1 = decompress (src is compressed). */
const uint32_t dcc_dir = src->is_compressed && !dst->is_compressed;
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 src_ext = radv_sdma_pixel_extent_to_blocks(src->extent, src->blk_w, src->blk_h);
const VkExtent3D dst_ext = radv_sdma_pixel_extent_to_blocks(dst->extent, dst->blk_w, dst->blk_h);
const VkExtent3D ext = radv_sdma_pixel_extent_to_blocks(px_extent, src->blk_w, src->blk_h);
assert(util_is_power_of_two_nonzero(src->bpp));
assert(util_is_power_of_two_nonzero(dst->bpp));
const struct ac_sdma_surf_tiled surf_src = {
.surf = src->surf,
.va = src->va,
.format = radv_format_to_pipe_format(src->aspect_format),
.bpp = src->bpp,
.offset =
{
.x = src_off.x,
.y = src_off.y,
.z = src_off.z,
},
.extent =
{
.width = src_ext.width,
.height = src_ext.height,
.depth = src_ext.depth,
},
.first_level = src->first_level,
.num_levels = src->mip_levels,
.is_compressed = src->is_compressed,
.surf_type = src->surface_type,
.meta_va = src->meta_va,
.htile_enabled = src->htile_enabled,
};
ASSERTED unsigned cdw_end = radeon_check_space(device->ws, cs->b, 15 + (dcc ? 3 : 0));
const struct ac_sdma_surf_tiled surf_dst = {
.surf = dst->surf,
.va = dst->va,
.format = radv_format_to_pipe_format(dst->aspect_format),
.bpp = dst->bpp,
.offset =
{
.x = dst_off.x,
.y = dst_off.y,
.z = dst_off.z,
},
.extent =
{
.width = dst_ext.width,
.height = dst_ext.height,
.depth = dst_ext.depth,
},
.first_level = dst->first_level,
.num_levels = dst->mip_levels,
.is_compressed = dst->is_compressed,
.surf_type = dst->surface_type,
.meta_va = dst->meta_va,
.htile_enabled = dst->htile_enabled,
};
radeon_begin(cs);
radeon_emit(SDMA_PACKET(SDMA_OPCODE_COPY, SDMA_COPY_SUB_OPCODE_T2T_SUB_WINDOW, 0) | dcc << 19 | dcc_dir << 31 |
src->header_dword);
radeon_emit(src->va);
radeon_emit(src->va >> 32);
radeon_emit(src_off.x | src_off.y << 16);
radeon_emit(src_off.z | (src_ext.width - 1) << 16);
radeon_emit((src_ext.height - 1) | (src_ext.depth - 1) << 16);
radeon_emit(src->info_dword);
radeon_emit(dst->va);
radeon_emit(dst->va >> 32);
radeon_emit(dst_off.x | dst_off.y << 16);
radeon_emit(dst_off.z | (dst_ext.width - 1) << 16);
radeon_emit((dst_ext.height - 1) | (dst_ext.depth - 1) << 16);
radeon_emit(dst->info_dword);
radeon_emit((ext.width - 1) | (ext.height - 1) << 16);
radeon_emit((ext.depth - 1));
if (pdev->info.sdma_ip_version >= SDMA_7_0) {
/* Compress only when dst has DCC. If src has DCC, it automatically decompresses according to
* PTE.D (page table bit) even if we don't enable DCC in the packet.
*/
if (dst->is_compressed)
radeon_emit(dst->meta_config | SDMA7_DCC_WRITE_CM(1));
} else {
if (dst->is_compressed) {
radeon_emit(dst->meta_va);
radeon_emit(dst->meta_va >> 32);
radeon_emit(dst->meta_config | SDMA5_DCC_WRITE_COMPRESS(1));
} else if (src->is_compressed) {
radeon_emit(src->meta_va);
radeon_emit(src->meta_va >> 32);
radeon_emit(src->meta_config);
}
}
radeon_end();
assert(cs->b->cdw <= cdw_end);
radeon_check_space(device->ws, cs->b, 18);
ac_emit_sdma_copy_t2t_sub_window(cs->b, &pdev->info, &surf_src, &surf_dst, ext.width, ext.height, ext.depth);
}
void