• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright © 2016 Red Hat.
3  * Copyright © 2016 Bas Nieuwenhuizen
4  *
5  * based on si_state.c
6  * Copyright © 2015 Advanced Micro Devices, Inc.
7  *
8  * SPDX-License-Identifier: MIT
9  */
10 
11 #include "radv_cp_dma.h"
12 #include "radv_buffer.h"
13 #include "radv_cs.h"
14 #include "radv_debug.h"
15 #include "radv_shader.h"
16 #include "radv_sqtt.h"
17 #include "sid.h"
18 
19 /* Set this if you want the 3D engine to wait until CP DMA is done.
20  * It should be set on the last CP DMA packet. */
21 #define CP_DMA_SYNC (1 << 0)
22 
23 /* Set this if the source data was used as a destination in a previous CP DMA
24  * packet. It's for preventing a read-after-write (RAW) hazard between two
25  * CP DMA packets. */
26 #define CP_DMA_RAW_WAIT (1 << 1)
27 #define CP_DMA_USE_L2   (1 << 2)
28 #define CP_DMA_CLEAR    (1 << 3)
29 
30 /* Alignment for optimal performance. */
31 #define SI_CPDMA_ALIGNMENT 32
32 
33 /* The max number of bytes that can be copied per packet. */
34 static inline unsigned
cp_dma_max_byte_count(enum amd_gfx_level gfx_level)35 cp_dma_max_byte_count(enum amd_gfx_level gfx_level)
36 {
37    unsigned max = gfx_level >= GFX11  ? 32767
38                   : gfx_level >= GFX9 ? S_415_BYTE_COUNT_GFX9(~0u)
39                                       : S_415_BYTE_COUNT_GFX6(~0u);
40 
41    /* make it aligned for optimal performance */
42    return max & ~(SI_CPDMA_ALIGNMENT - 1);
43 }
44 
45 /* Emit a CP DMA packet to do a copy from one buffer to another, or to clear
46  * a buffer. The size must fit in bits [20:0]. If CP_DMA_CLEAR is set, src_va is a 32-bit
47  * clear value.
48  */
49 static void
radv_cs_emit_cp_dma(struct radv_device * device,struct radeon_cmdbuf * cs,bool predicating,uint64_t dst_va,uint64_t src_va,unsigned size,unsigned flags)50 radv_cs_emit_cp_dma(struct radv_device *device, struct radeon_cmdbuf *cs, bool predicating, uint64_t dst_va,
51                     uint64_t src_va, unsigned size, unsigned flags)
52 {
53    const struct radv_physical_device *pdev = radv_device_physical(device);
54    const bool cp_dma_use_L2 = (flags & CP_DMA_USE_L2) && pdev->info.cp_dma_use_L2;
55    uint32_t header = 0, command = 0;
56 
57    assert(size <= cp_dma_max_byte_count(pdev->info.gfx_level));
58 
59    radeon_check_space(device->ws, cs, 9);
60    if (pdev->info.gfx_level >= GFX9)
61       command |= S_415_BYTE_COUNT_GFX9(size);
62    else
63       command |= S_415_BYTE_COUNT_GFX6(size);
64 
65    /* Sync flags. */
66    if (flags & CP_DMA_SYNC)
67       header |= S_411_CP_SYNC(1);
68 
69    if (flags & CP_DMA_RAW_WAIT)
70       command |= S_415_RAW_WAIT(1);
71 
72    /* Src and dst flags. */
73    if (pdev->info.gfx_level >= GFX9 && !(flags & CP_DMA_CLEAR) && src_va == dst_va)
74       header |= S_411_DST_SEL(V_411_NOWHERE); /* prefetch only */
75    else if (cp_dma_use_L2)
76       header |= S_411_DST_SEL(V_411_DST_ADDR_TC_L2);
77 
78    if (flags & CP_DMA_CLEAR)
79       header |= S_411_SRC_SEL(V_411_DATA);
80    else if (cp_dma_use_L2)
81       header |= S_411_SRC_SEL(V_411_SRC_ADDR_TC_L2);
82 
83    if (pdev->info.gfx_level >= GFX7) {
84       radeon_emit(cs, PKT3(PKT3_DMA_DATA, 5, predicating));
85       radeon_emit(cs, header);
86       radeon_emit(cs, src_va);       /* SRC_ADDR_LO [31:0] */
87       radeon_emit(cs, src_va >> 32); /* SRC_ADDR_HI [31:0] */
88       radeon_emit(cs, dst_va);       /* DST_ADDR_LO [31:0] */
89       radeon_emit(cs, dst_va >> 32); /* DST_ADDR_HI [31:0] */
90       radeon_emit(cs, command);
91    } else {
92       assert(!cp_dma_use_L2);
93       header |= S_411_SRC_ADDR_HI(src_va >> 32);
94       radeon_emit(cs, PKT3(PKT3_CP_DMA, 4, predicating));
95       radeon_emit(cs, src_va);                  /* SRC_ADDR_LO [31:0] */
96       radeon_emit(cs, header);                  /* SRC_ADDR_HI [15:0] + flags. */
97       radeon_emit(cs, dst_va);                  /* DST_ADDR_LO [31:0] */
98       radeon_emit(cs, (dst_va >> 32) & 0xffff); /* DST_ADDR_HI [15:0] */
99       radeon_emit(cs, command);
100    }
101 }
102 
103 static void
radv_emit_cp_dma(struct radv_cmd_buffer * cmd_buffer,uint64_t dst_va,uint64_t src_va,unsigned size,unsigned flags)104 radv_emit_cp_dma(struct radv_cmd_buffer *cmd_buffer, uint64_t dst_va, uint64_t src_va, unsigned size, unsigned flags)
105 {
106    struct radv_device *device = radv_cmd_buffer_device(cmd_buffer);
107    struct radeon_cmdbuf *cs = cmd_buffer->cs;
108    bool predicating = cmd_buffer->state.predicating;
109 
110    radv_cs_emit_cp_dma(device, cs, predicating, dst_va, src_va, size, flags);
111 
112    /* CP DMA is executed in ME, but index buffers are read by PFP.
113     * This ensures that ME (CP DMA) is idle before PFP starts fetching
114     * indices. If we wanted to execute CP DMA in PFP, this packet
115     * should precede it.
116     */
117    if (flags & CP_DMA_SYNC) {
118       if (cmd_buffer->qf == RADV_QUEUE_GENERAL) {
119          radeon_emit(cs, PKT3(PKT3_PFP_SYNC_ME, 0, cmd_buffer->state.predicating));
120          radeon_emit(cs, 0);
121       }
122 
123       /* CP will see the sync flag and wait for all DMAs to complete. */
124       cmd_buffer->state.dma_is_busy = false;
125    }
126 
127    if (radv_device_fault_detection_enabled(device))
128       radv_cmd_buffer_trace_emit(cmd_buffer);
129 }
130 
131 void
radv_cs_cp_dma_prefetch(const struct radv_device * device,struct radeon_cmdbuf * cs,uint64_t va,unsigned size,bool predicating)132 radv_cs_cp_dma_prefetch(const struct radv_device *device, struct radeon_cmdbuf *cs, uint64_t va, unsigned size,
133                         bool predicating)
134 {
135    const struct radv_physical_device *pdev = radv_device_physical(device);
136    struct radeon_winsys *ws = device->ws;
137    enum amd_gfx_level gfx_level = pdev->info.gfx_level;
138    uint32_t header = 0, command = 0;
139 
140    if (gfx_level >= GFX11)
141       size = MIN2(size, 32768 - SI_CPDMA_ALIGNMENT);
142 
143    assert(size <= cp_dma_max_byte_count(gfx_level));
144 
145    radeon_check_space(ws, cs, 9);
146 
147    uint64_t aligned_va = va & ~(SI_CPDMA_ALIGNMENT - 1);
148    uint64_t aligned_size = ((va + size + SI_CPDMA_ALIGNMENT - 1) & ~(SI_CPDMA_ALIGNMENT - 1)) - aligned_va;
149 
150    if (gfx_level >= GFX9) {
151       command |= S_415_BYTE_COUNT_GFX9(aligned_size) | S_415_DISABLE_WR_CONFIRM_GFX9(1);
152       header |= S_411_DST_SEL(V_411_NOWHERE);
153    } else {
154       command |= S_415_BYTE_COUNT_GFX6(aligned_size) | S_415_DISABLE_WR_CONFIRM_GFX6(1);
155       header |= S_411_DST_SEL(V_411_DST_ADDR_TC_L2);
156    }
157 
158    header |= S_411_SRC_SEL(V_411_SRC_ADDR_TC_L2);
159 
160    radeon_emit(cs, PKT3(PKT3_DMA_DATA, 5, predicating));
161    radeon_emit(cs, header);
162    radeon_emit(cs, aligned_va);       /* SRC_ADDR_LO [31:0] */
163    radeon_emit(cs, aligned_va >> 32); /* SRC_ADDR_HI [31:0] */
164    radeon_emit(cs, aligned_va);       /* DST_ADDR_LO [31:0] */
165    radeon_emit(cs, aligned_va >> 32); /* DST_ADDR_HI [31:0] */
166    radeon_emit(cs, command);
167 }
168 
169 void
radv_cp_dma_prefetch(struct radv_cmd_buffer * cmd_buffer,uint64_t va,unsigned size)170 radv_cp_dma_prefetch(struct radv_cmd_buffer *cmd_buffer, uint64_t va, unsigned size)
171 {
172    struct radv_device *device = radv_cmd_buffer_device(cmd_buffer);
173 
174    radv_cs_cp_dma_prefetch(device, cmd_buffer->cs, va, size, cmd_buffer->state.predicating);
175 
176    if (radv_device_fault_detection_enabled(device))
177       radv_cmd_buffer_trace_emit(cmd_buffer);
178 }
179 
180 static void
radv_cp_dma_prepare(struct radv_cmd_buffer * cmd_buffer,uint64_t byte_count,uint64_t remaining_size,unsigned * flags)181 radv_cp_dma_prepare(struct radv_cmd_buffer *cmd_buffer, uint64_t byte_count, uint64_t remaining_size, unsigned *flags)
182 {
183 
184    /* Flush the caches for the first copy only.
185     * Also wait for the previous CP DMA operations.
186     */
187    if (cmd_buffer->state.flush_bits) {
188       radv_emit_cache_flush(cmd_buffer);
189       *flags |= CP_DMA_RAW_WAIT;
190    }
191 
192    /* Do the synchronization after the last dma, so that all data
193     * is written to memory.
194     */
195    if (byte_count == remaining_size)
196       *flags |= CP_DMA_SYNC;
197 }
198 
199 static void
radv_cp_dma_realign_engine(struct radv_cmd_buffer * cmd_buffer,unsigned size)200 radv_cp_dma_realign_engine(struct radv_cmd_buffer *cmd_buffer, unsigned size)
201 {
202    uint64_t va;
203    uint32_t offset;
204    unsigned dma_flags = 0;
205    unsigned buf_size = SI_CPDMA_ALIGNMENT * 2;
206    void *ptr;
207 
208    assert(size < SI_CPDMA_ALIGNMENT);
209 
210    radv_cmd_buffer_upload_alloc(cmd_buffer, buf_size, &offset, &ptr);
211 
212    va = radv_buffer_get_va(cmd_buffer->upload.upload_bo);
213    va += offset;
214 
215    radv_cp_dma_prepare(cmd_buffer, size, size, &dma_flags);
216 
217    radv_emit_cp_dma(cmd_buffer, va, va + SI_CPDMA_ALIGNMENT, size, dma_flags);
218 }
219 
220 void
radv_cp_dma_buffer_copy(struct radv_cmd_buffer * cmd_buffer,uint64_t src_va,uint64_t dest_va,uint64_t size)221 radv_cp_dma_buffer_copy(struct radv_cmd_buffer *cmd_buffer, uint64_t src_va, uint64_t dest_va, uint64_t size)
222 {
223    struct radv_device *device = radv_cmd_buffer_device(cmd_buffer);
224    const struct radv_physical_device *pdev = radv_device_physical(device);
225    enum amd_gfx_level gfx_level = pdev->info.gfx_level;
226    uint64_t main_src_va, main_dest_va;
227    uint64_t skipped_size = 0, realign_size = 0;
228 
229    /* Assume that we are not going to sync after the last DMA operation. */
230    cmd_buffer->state.dma_is_busy = true;
231 
232    if (pdev->info.family <= CHIP_CARRIZO || pdev->info.family == CHIP_STONEY) {
233       /* If the size is not aligned, we must add a dummy copy at the end
234        * just to align the internal counter. Otherwise, the DMA engine
235        * would slow down by an order of magnitude for following copies.
236        */
237       if (size % SI_CPDMA_ALIGNMENT)
238          realign_size = SI_CPDMA_ALIGNMENT - (size % SI_CPDMA_ALIGNMENT);
239 
240       /* If the copy begins unaligned, we must start copying from the next
241        * aligned block and the skipped part should be copied after everything
242        * else has been copied. Only the src alignment matters, not dst.
243        */
244       if (src_va % SI_CPDMA_ALIGNMENT) {
245          skipped_size = SI_CPDMA_ALIGNMENT - (src_va % SI_CPDMA_ALIGNMENT);
246          /* The main part will be skipped if the size is too small. */
247          skipped_size = MIN2(skipped_size, size);
248          size -= skipped_size;
249       }
250    }
251    main_src_va = src_va + skipped_size;
252    main_dest_va = dest_va + skipped_size;
253 
254    while (size) {
255       unsigned dma_flags = 0;
256       unsigned byte_count = MIN2(size, cp_dma_max_byte_count(gfx_level));
257 
258       if (pdev->info.gfx_level >= GFX9) {
259          /* DMA operations via L2 are coherent and faster.
260           * TODO: GFX7-GFX8 should also support this but it
261           * requires tests/benchmarks.
262           *
263           * Also enable on GFX9 so we can use L2 at rest on GFX9+. On Raven
264           * this didn't seem to be worse.
265           *
266           * Note that we only use CP DMA for sizes < RADV_BUFFER_OPS_CS_THRESHOLD,
267           * which is 4k at the moment, so this is really unlikely to cause
268           * significant thrashing.
269           */
270          dma_flags |= CP_DMA_USE_L2;
271       }
272 
273       radv_cp_dma_prepare(cmd_buffer, byte_count, size + skipped_size + realign_size, &dma_flags);
274 
275       dma_flags &= ~CP_DMA_SYNC;
276 
277       radv_emit_cp_dma(cmd_buffer, main_dest_va, main_src_va, byte_count, dma_flags);
278 
279       size -= byte_count;
280       main_src_va += byte_count;
281       main_dest_va += byte_count;
282    }
283 
284    if (skipped_size) {
285       unsigned dma_flags = 0;
286 
287       radv_cp_dma_prepare(cmd_buffer, skipped_size, size + skipped_size + realign_size, &dma_flags);
288 
289       radv_emit_cp_dma(cmd_buffer, dest_va, src_va, skipped_size, dma_flags);
290    }
291    if (realign_size)
292       radv_cp_dma_realign_engine(cmd_buffer, realign_size);
293 
294    if (pdev->info.cp_sdma_ge_use_system_memory_scope)
295       cmd_buffer->state.flush_bits |= RADV_CMD_FLAG_INV_L2;
296 }
297 
298 void
radv_cp_dma_clear_buffer(struct radv_cmd_buffer * cmd_buffer,uint64_t va,uint64_t size,unsigned value)299 radv_cp_dma_clear_buffer(struct radv_cmd_buffer *cmd_buffer, uint64_t va, uint64_t size, unsigned value)
300 {
301    struct radv_device *device = radv_cmd_buffer_device(cmd_buffer);
302    const struct radv_physical_device *pdev = radv_device_physical(device);
303 
304    if (!size)
305       return;
306 
307    assert(va % 4 == 0 && size % 4 == 0);
308 
309    enum amd_gfx_level gfx_level = pdev->info.gfx_level;
310 
311    /* Assume that we are not going to sync after the last DMA operation. */
312    cmd_buffer->state.dma_is_busy = true;
313 
314    while (size) {
315       unsigned byte_count = MIN2(size, cp_dma_max_byte_count(gfx_level));
316       unsigned dma_flags = CP_DMA_CLEAR;
317 
318       if (pdev->info.gfx_level >= GFX9) {
319          /* DMA operations via L2 are coherent and faster.
320           * TODO: GFX7-GFX8 should also support this but it
321           * requires tests/benchmarks.
322           *
323           * Also enable on GFX9 so we can use L2 at rest on GFX9+.
324           */
325          dma_flags |= CP_DMA_USE_L2;
326       }
327 
328       radv_cp_dma_prepare(cmd_buffer, byte_count, size, &dma_flags);
329 
330       /* Emit the clear packet. */
331       radv_emit_cp_dma(cmd_buffer, va, value, byte_count, dma_flags);
332 
333       size -= byte_count;
334       va += byte_count;
335    }
336 
337    if (pdev->info.cp_sdma_ge_use_system_memory_scope)
338       cmd_buffer->state.flush_bits |= RADV_CMD_FLAG_INV_L2;
339 }
340 
341 void
radv_cp_dma_wait_for_idle(struct radv_cmd_buffer * cmd_buffer)342 radv_cp_dma_wait_for_idle(struct radv_cmd_buffer *cmd_buffer)
343 {
344    struct radv_device *device = radv_cmd_buffer_device(cmd_buffer);
345    const struct radv_physical_device *pdev = radv_device_physical(device);
346 
347    if (pdev->info.gfx_level < GFX7)
348       return;
349 
350    if (!cmd_buffer->state.dma_is_busy)
351       return;
352 
353    /* Issue a dummy DMA that copies zero bytes.
354     *
355     * The DMA engine will see that there's no work to do and skip this
356     * DMA request, however, the CP will see the sync flag and still wait
357     * for all DMAs to complete.
358     */
359    radv_emit_cp_dma(cmd_buffer, 0, 0, 0, CP_DMA_SYNC);
360 
361    cmd_buffer->state.dma_is_busy = false;
362 }
363