1 #include "radeon_priv.h"
3 #include "util/u_inlines.h"
4 #include "util/u_memory.h"
5 #include "util/u_double_list.h"
6 #include "pipebuffer/pb_buffer.h"
7 #include "pipebuffer/pb_bufmgr.h"
13 struct radeon_bo_pbmgr
*mgr
;
14 struct list_head maplist
;
17 extern const struct pb_vtbl radeon_bo_pb_vtbl
;
19 static INLINE
struct radeon_bo_pb
*radeon_bo_pb(struct pb_buffer
*buf
)
22 assert(buf
->vtbl
== &radeon_bo_pb_vtbl
);
23 return (struct radeon_bo_pb
*)buf
;
26 struct radeon_bo_pbmgr
{
28 struct radeon
*radeon
;
29 struct list_head buffer_map_list
;
32 static INLINE
struct radeon_bo_pbmgr
*radeon_bo_pbmgr(struct pb_manager
*mgr
)
35 return (struct radeon_bo_pbmgr
*)mgr
;
38 static void radeon_bo_pb_destroy(struct pb_buffer
*_buf
)
40 struct radeon_bo_pb
*buf
= radeon_bo_pb(_buf
);
42 LIST_DEL(&buf
->maplist
);
44 if (buf
->bo
->data
!= NULL
) {
45 radeon_bo_unmap(buf
->mgr
->radeon
, buf
->bo
);
47 radeon_bo_reference(buf
->mgr
->radeon
, &buf
->bo
, NULL
);
52 radeon_bo_pb_map_internal(struct pb_buffer
*_buf
,
53 unsigned flags
, void *ctx
)
55 struct radeon_bo_pb
*buf
= radeon_bo_pb(_buf
);
57 if (flags
& PB_USAGE_UNSYNCHRONIZED
) {
58 if (!buf
->bo
->data
&& radeon_bo_map(buf
->mgr
->radeon
, buf
->bo
)) {
61 LIST_DELINIT(&buf
->maplist
);
65 if (p_atomic_read(&buf
->bo
->reference
.count
) > 1) {
66 if (flags
& PB_USAGE_DONTBLOCK
) {
74 if (flags
& PB_USAGE_DONTBLOCK
) {
76 if (radeon_bo_busy(buf
->mgr
->radeon
, buf
->bo
, &domain
))
80 if (buf
->bo
->data
!= NULL
) {
81 if (radeon_bo_wait(buf
->mgr
->radeon
, buf
->bo
)) {
85 if (radeon_bo_map(buf
->mgr
->radeon
, buf
->bo
)) {
88 if (radeon_bo_wait(buf
->mgr
->radeon
, buf
->bo
)) {
89 radeon_bo_unmap(buf
->mgr
->radeon
, buf
->bo
);
94 LIST_DELINIT(&buf
->maplist
);
98 static void radeon_bo_pb_unmap_internal(struct pb_buffer
*_buf
)
100 struct radeon_bo_pb
*buf
= radeon_bo_pb(_buf
);
101 LIST_ADDTAIL(&buf
->maplist
, &buf
->mgr
->buffer_map_list
);
105 radeon_bo_pb_get_base_buffer(struct pb_buffer
*buf
,
106 struct pb_buffer
**base_buf
,
113 static enum pipe_error
114 radeon_bo_pb_validate(struct pb_buffer
*_buf
,
115 struct pb_validate
*vl
,
123 radeon_bo_pb_fence(struct pb_buffer
*buf
,
124 struct pipe_fence_handle
*fence
)
128 const struct pb_vtbl radeon_bo_pb_vtbl
= {
129 radeon_bo_pb_destroy
,
130 radeon_bo_pb_map_internal
,
131 radeon_bo_pb_unmap_internal
,
132 radeon_bo_pb_validate
,
134 radeon_bo_pb_get_base_buffer
,
138 radeon_bo_pb_create_buffer_from_handle(struct pb_manager
*_mgr
,
141 struct radeon_bo_pbmgr
*mgr
= radeon_bo_pbmgr(_mgr
);
142 struct radeon
*radeon
= mgr
->radeon
;
143 struct radeon_bo_pb
*bo
;
144 struct radeon_bo
*hw_bo
;
146 hw_bo
= radeon_bo(radeon
, handle
, 0, 0, NULL
);
150 bo
= CALLOC_STRUCT(radeon_bo_pb
);
152 radeon_bo_reference(radeon
, &hw_bo
, NULL
);
156 LIST_INITHEAD(&bo
->maplist
);
157 pipe_reference_init(&bo
->b
.base
.reference
, 1);
158 bo
->b
.base
.alignment
= 0;
159 bo
->b
.base
.usage
= PB_USAGE_GPU_WRITE
| PB_USAGE_GPU_READ
;
160 bo
->b
.base
.size
= hw_bo
->size
;
161 bo
->b
.vtbl
= &radeon_bo_pb_vtbl
;
169 static struct pb_buffer
*
170 radeon_bo_pb_create_buffer(struct pb_manager
*_mgr
,
172 const struct pb_desc
*desc
)
174 struct radeon_bo_pbmgr
*mgr
= radeon_bo_pbmgr(_mgr
);
175 struct radeon
*radeon
= mgr
->radeon
;
176 struct radeon_bo_pb
*bo
;
179 bo
= CALLOC_STRUCT(radeon_bo_pb
);
183 pipe_reference_init(&bo
->b
.base
.reference
, 1);
184 bo
->b
.base
.alignment
= desc
->alignment
;
185 bo
->b
.base
.usage
= desc
->usage
;
186 bo
->b
.base
.size
= size
;
187 bo
->b
.vtbl
= &radeon_bo_pb_vtbl
;
190 LIST_INITHEAD(&bo
->maplist
);
192 bo
->bo
= radeon_bo(radeon
, 0, size
,
193 desc
->alignment
, NULL
);
205 radeon_bo_pbmgr_flush(struct pb_manager
*mgr
)
211 radeon_bo_pbmgr_destroy(struct pb_manager
*_mgr
)
213 struct radeon_bo_pbmgr
*mgr
= radeon_bo_pbmgr(_mgr
);
217 struct pb_manager
*radeon_bo_pbmgr_create(struct radeon
*radeon
)
219 struct radeon_bo_pbmgr
*mgr
;
221 mgr
= CALLOC_STRUCT(radeon_bo_pbmgr
);
225 mgr
->b
.destroy
= radeon_bo_pbmgr_destroy
;
226 mgr
->b
.create_buffer
= radeon_bo_pb_create_buffer
;
227 mgr
->b
.flush
= radeon_bo_pbmgr_flush
;
229 mgr
->radeon
= radeon
;
230 LIST_INITHEAD(&mgr
->buffer_map_list
);
234 void radeon_bo_pbmgr_flush_maps(struct pb_manager
*_mgr
)
236 struct radeon_bo_pbmgr
*mgr
= radeon_bo_pbmgr(_mgr
);
237 struct radeon_bo_pb
*rpb
= NULL
;
238 struct radeon_bo_pb
*t_rpb
;
240 LIST_FOR_EACH_ENTRY_SAFE(rpb
, t_rpb
, &mgr
->buffer_map_list
, maplist
) {
241 radeon_bo_unmap(mgr
->radeon
, rpb
->bo
);
242 LIST_DELINIT(&rpb
->maplist
);
245 LIST_INITHEAD(&mgr
->buffer_map_list
);
248 struct radeon_bo
*radeon_bo_pb_get_bo(struct pb_buffer
*_buf
)
250 struct radeon_bo_pb
*buf
;
251 if (_buf
->vtbl
== &radeon_bo_pb_vtbl
) {
252 buf
= radeon_bo_pb(_buf
);
255 struct pb_buffer
*base_buf
;
257 pb_get_base_buffer(_buf
, &base_buf
, &offset
);
258 if (base_buf
->vtbl
== &radeon_bo_pb_vtbl
) {
259 buf
= radeon_bo_pb(base_buf
);