radv: Introduce sdma_copy_buffer for GFX7+.

Helper salvaged from radeonsi (before SDMA removal).

This will be used for driver internal submissions to DMA shaders from GTT
to invisible VRAM.

Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/16271>
This commit is contained in:
Tatsuyuki Ishi 2023-02-28 22:09:18 +09:00 committed by Marge Bot
parent d4fb3db748
commit 3b258ae2d9
2 changed files with 42 additions and 0 deletions

View file

@ -3016,6 +3016,8 @@ void radv_rra_trace_finish(VkDevice vk_device, struct radv_rra_trace_data *data)
bool radv_sdma_copy_image(struct radv_device *device, struct radeon_cmdbuf *cs,
struct radv_image *image, struct radv_buffer *buffer,
const VkBufferImageCopy2 *region);
void radv_sdma_copy_buffer(struct radv_device *device, struct radeon_cmdbuf *cs, uint64_t src_va,
uint64_t dst_va, uint64_t size);
void radv_memory_trace_init(struct radv_device *device);
void radv_rmv_log_bo_allocate(struct radv_device *device, struct radeon_winsys_bo *bo,

View file

@ -142,3 +142,43 @@ radv_sdma_copy_image(struct radv_device *device, struct radeon_cmdbuf *cs, struc
assert(device->physical_device->rad_info.gfx_level >= GFX9);
return radv_sdma_v4_v5_copy_image_to_buffer(device, cs, image, buffer, region);
}
void
radv_sdma_copy_buffer(struct radv_device *device, struct radeon_cmdbuf *cs, uint64_t src_va,
uint64_t dst_va, uint64_t size)
{
if (size == 0)
return;
enum amd_gfx_level gfx_level = device->physical_device->rad_info.gfx_level;
unsigned max_size_per_packet =
gfx_level >= GFX10_3 ? GFX103_SDMA_COPY_MAX_SIZE : CIK_SDMA_COPY_MAX_SIZE;
unsigned align = ~0u;
unsigned ncopy = DIV_ROUND_UP(size, max_size_per_packet);
bool tmz = false;
assert(gfx_level >= GFX7);
/* Align copy size to dw if src/dst address are dw aligned */
if ((src_va & 0x3) == 0 && (src_va & 0x3) == 0 && size > 4 && (size & 3) != 0) {
align = ~0x3u;
ncopy++;
}
radeon_check_space(device->ws, cs, ncopy * 7);
for (unsigned i = 0; i < ncopy; i++) {
unsigned csize = size >= 4 ? MIN2(size & align, max_size_per_packet) : size;
radeon_emit(cs, CIK_SDMA_PACKET(CIK_SDMA_OPCODE_COPY, CIK_SDMA_COPY_SUB_OPCODE_LINEAR,
(tmz ? 1u : 0) << 2));
radeon_emit(cs, gfx_level >= GFX9 ? csize - 1 : csize);
radeon_emit(cs, 0); /* src/dst endian swap */
radeon_emit(cs, src_va);
radeon_emit(cs, src_va >> 32);
radeon_emit(cs, dst_va);
radeon_emit(cs, dst_va >> 32);
dst_va += csize;
src_va += csize;
size -= csize;
}
}