2 * Copyright 2010 Jerome Glisse <glisse@freedesktop.org>
3 * Copyright 2014,2015 Advanced Micro Devices, Inc.
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the "Software"),
7 * to deal in the Software without restriction, including without limitation
8 * on the rights to use, copy, modify, merge, publish, distribute, sub
9 * license, and/or sell copies of the Software, and to permit persons to whom
10 * the Software is furnished to do so, subject to the following conditions:
12 * The above copyright notice and this permission notice (including the next
13 * paragraph) shall be included in all copies or substantial portions of the
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
19 * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
20 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
21 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
22 * USE OR OTHER DEALINGS IN THE SOFTWARE.
30 #include "radeon/r600_cs.h"
32 #include "util/u_format.h"
34 static void cik_sdma_do_copy_buffer(struct si_context
*ctx
,
35 struct pipe_resource
*dst
,
36 struct pipe_resource
*src
,
41 struct radeon_winsys_cs
*cs
= ctx
->b
.dma
.cs
;
42 unsigned i
, ncopy
, csize
;
43 struct r600_resource
*rdst
= (struct r600_resource
*)dst
;
44 struct r600_resource
*rsrc
= (struct r600_resource
*)src
;
46 dst_offset
+= r600_resource(dst
)->gpu_address
;
47 src_offset
+= r600_resource(src
)->gpu_address
;
49 ncopy
= DIV_ROUND_UP(size
, CIK_SDMA_COPY_MAX_SIZE
);
50 r600_need_dma_space(&ctx
->b
, ncopy
* 7);
52 radeon_add_to_buffer_list(&ctx
->b
, &ctx
->b
.dma
, rsrc
, RADEON_USAGE_READ
,
53 RADEON_PRIO_SDMA_BUFFER
);
54 radeon_add_to_buffer_list(&ctx
->b
, &ctx
->b
.dma
, rdst
, RADEON_USAGE_WRITE
,
55 RADEON_PRIO_SDMA_BUFFER
);
57 for (i
= 0; i
< ncopy
; i
++) {
58 csize
= MIN2(size
, CIK_SDMA_COPY_MAX_SIZE
);
59 cs
->buf
[cs
->cdw
++] = CIK_SDMA_PACKET(CIK_SDMA_OPCODE_COPY
,
60 CIK_SDMA_COPY_SUB_OPCODE_LINEAR
,
62 cs
->buf
[cs
->cdw
++] = csize
;
63 cs
->buf
[cs
->cdw
++] = 0; /* src/dst endian swap */
64 cs
->buf
[cs
->cdw
++] = src_offset
;
65 cs
->buf
[cs
->cdw
++] = src_offset
>> 32;
66 cs
->buf
[cs
->cdw
++] = dst_offset
;
67 cs
->buf
[cs
->cdw
++] = dst_offset
>> 32;
74 static void cik_sdma_copy_buffer(struct si_context
*ctx
,
75 struct pipe_resource
*dst
,
76 struct pipe_resource
*src
,
81 struct r600_resource
*rdst
= (struct r600_resource
*)dst
;
83 /* Mark the buffer range of destination as valid (initialized),
84 * so that transfer_map knows it should wait for the GPU when mapping
86 util_range_add(&rdst
->valid_buffer_range
, dst_offset
,
89 cik_sdma_do_copy_buffer(ctx
, dst
, src
, dst_offset
, src_offset
, size
);
90 r600_dma_emit_wait_idle(&ctx
->b
);
93 static void cik_sdma_copy(struct pipe_context
*ctx
,
94 struct pipe_resource
*dst
,
96 unsigned dstx
, unsigned dsty
, unsigned dstz
,
97 struct pipe_resource
*src
,
99 const struct pipe_box
*src_box
)
101 struct si_context
*sctx
= (struct si_context
*)ctx
;
106 if (dst
->target
== PIPE_BUFFER
&& src
->target
== PIPE_BUFFER
) {
107 cik_sdma_copy_buffer(sctx
, dst
, src
, dstx
, src_box
->x
, src_box
->width
);
112 si_resource_copy_region(ctx
, dst
, dst_level
, dstx
, dsty
, dstz
,
113 src
, src_level
, src_box
);
116 void cik_init_sdma_functions(struct si_context
*sctx
)
118 sctx
->b
.dma_copy
= cik_sdma_copy
;