From 191bf7aba645798554659acf4f3dafb09764e5cc Mon Sep 17 00:00:00 2001 From: Samuel Pitoiset Date: Thu, 13 Nov 2025 18:13:57 +0100 Subject: [PATCH] ac,radv: add ac_emit_sdma_constant_fill() Signed-off-by: Samuel Pitoiset Part-of: --- src/amd/common/ac_cmdbuf_sdma.c | 22 ++++++++++++++++++++ src/amd/common/ac_cmdbuf_sdma.h | 4 ++++ src/amd/vulkan/radv_sdma.c | 37 +++++++-------------------------- 3 files changed, 33 insertions(+), 30 deletions(-) diff --git a/src/amd/common/ac_cmdbuf_sdma.c b/src/amd/common/ac_cmdbuf_sdma.c index fe21a2f2985..0ac1379c3bd 100644 --- a/src/amd/common/ac_cmdbuf_sdma.c +++ b/src/amd/common/ac_cmdbuf_sdma.c @@ -64,3 +64,25 @@ ac_emit_sdma_write_data_head(struct ac_cmdbuf *cs, uint64_t va, uint32_t count) ac_cmdbuf_emit(count - 1); ac_cmdbuf_end(); } + +uint64_t +ac_emit_sdma_constant_fill(struct ac_cmdbuf *cs, enum sdma_version sdma_ip_version, + uint64_t va, uint64_t size, uint32_t value) +{ + const uint32_t fill_size = 2; /* This means that count is in DWORDS. */ + + assert(sdma_ip_version >= SDMA_2_4); + + const uint64_t max_fill_size = BITFIELD64_MASK(sdma_ip_version >= SDMA_6_0 ? 30 : 22) & ~0x3; + const uint64_t bytes_written = MIN2(size, max_fill_size); + + ac_cmdbuf_begin(cs); + ac_cmdbuf_emit(SDMA_PACKET(SDMA_OPCODE_CONSTANT_FILL, 0, 0) | (fill_size << 30)); + ac_cmdbuf_emit(va); + ac_cmdbuf_emit(va >> 32); + ac_cmdbuf_emit(value); + ac_cmdbuf_emit(bytes_written - 1); /* Must be programmed in bytes, even if the fill is done in dwords. */ + ac_cmdbuf_end(); + + return bytes_written; +} diff --git a/src/amd/common/ac_cmdbuf_sdma.h b/src/amd/common/ac_cmdbuf_sdma.h index b23b4676aee..a8381bed566 100644 --- a/src/amd/common/ac_cmdbuf_sdma.h +++ b/src/amd/common/ac_cmdbuf_sdma.h @@ -24,6 +24,10 @@ void ac_emit_sdma_wait_mem(struct ac_cmdbuf *cs, uint32_t op, uint64_t va, uint3 void ac_emit_sdma_write_data_head(struct ac_cmdbuf *cs, uint64_t va, uint32_t count); +uint64_t +ac_emit_sdma_constant_fill(struct ac_cmdbuf *cs, enum sdma_version sdma_ip_version, + uint64_t va, uint64_t size, uint32_t value); + #ifdef __cplusplus } #endif diff --git a/src/amd/vulkan/radv_sdma.c b/src/amd/vulkan/radv_sdma.c index dbab3356661..dc64a5b4a69 100644 --- a/src/amd/vulkan/radv_sdma.c +++ b/src/amd/vulkan/radv_sdma.c @@ -404,41 +404,18 @@ radv_sdma_copy_memory(const struct radv_device *device, struct radv_cmd_stream * } void -radv_sdma_fill_memory(const struct radv_device *device, struct radv_cmd_stream *cs, const uint64_t va, - const uint64_t size, const uint32_t value) +radv_sdma_fill_memory(const struct radv_device *device, struct radv_cmd_stream *cs, uint64_t va, uint64_t size, + const uint32_t value) { const struct radv_physical_device *pdev = radv_device_physical(device); - const uint32_t fill_size = 2; /* This means that the count is in dwords. */ - const uint32_t constant_fill_header = SDMA_PACKET(SDMA_OPCODE_CONSTANT_FILL, 0, 0) | (fill_size & 0x3) << 30; + while (size > 0) { + radeon_check_space(device->ws, cs->b, 5); + uint64_t bytes_written = ac_emit_sdma_constant_fill(cs->b, pdev->info.sdma_ip_version, va, size, value); - /* This packet is the same since SDMA v2.4, haven't bothered to check older versions. */ - const enum sdma_version ver = pdev->info.sdma_ip_version; - assert(ver >= SDMA_2_4); - - /* Maximum allowed fill size depends on the GPU. - * Emit as many packets as necessary to fill all the bytes we need. - */ - const uint64_t max_fill_bytes = BITFIELD64_MASK(ver >= SDMA_6_0 ? 30 : 22) & ~0x3; - const unsigned num_packets = DIV_ROUND_UP(size, max_fill_bytes); - ASSERTED unsigned cdw_max = radeon_check_space(device->ws, cs->b, num_packets * 5); - - radeon_begin(cs); - - for (unsigned i = 0; i < num_packets; ++i) { - const uint64_t offset = i * max_fill_bytes; - const uint64_t fill_bytes = MIN2(size - offset, max_fill_bytes); - const uint64_t fill_va = va + offset; - - radeon_emit(constant_fill_header); - radeon_emit(fill_va); - radeon_emit(fill_va >> 32); - radeon_emit(value); - radeon_emit(fill_bytes - 1); /* Must be programmed in bytes, even if the fill is done in dwords. */ + size -= bytes_written; + va += bytes_written; } - - radeon_end(); - assert(cs->b->cdw <= cdw_max); } static void