2 * Copyright © 2008 Dave Airlie
3 * Copyright © 2008 Jérôme Glisse
6 * Permission is hereby granted, free of charge, to any person obtaining
7 * a copy of this software and associated documentation files (the
8 * "Software"), to deal in the Software without restriction, including
9 * without limitation the rights to use, copy, modify, merge, publish,
10 * distribute, sub license, and/or sell copies of the Software, and to
11 * permit persons to whom the Software is furnished to do so, subject to
12 * the following conditions:
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
16 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17 * NON-INFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS, AUTHORS
18 * AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
20 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
21 * USE OR OTHER DEALINGS IN THE SOFTWARE.
23 * The above copyright notice and this permission notice (including the
24 * next paragraph) shall be included in all copies or substantial portions
30 * Jérôme Glisse <glisse@freedesktop.org>
37 #include "libdrm_macros.h"
39 #include "xf86atomic.h"
41 #include "radeon_drm.h"
42 #include "radeon_bo.h"
43 #include "radeon_bo_int.h"
44 #include "radeon_bo_gem.h"
46 struct radeon_bo_gem
{
47 struct radeon_bo_int base
;
54 struct bo_manager_gem
{
55 struct radeon_bo_manager base
;
58 static int bo_wait(struct radeon_bo_int
*boi
);
60 static struct radeon_bo
*bo_open(struct radeon_bo_manager
*bom
,
67 struct radeon_bo_gem
*bo
;
70 bo
= (struct radeon_bo_gem
*)calloc(1, sizeof(struct radeon_bo_gem
));
78 bo
->base
.alignment
= alignment
;
79 bo
->base
.domains
= domains
;
80 bo
->base
.flags
= flags
;
82 atomic_set(&bo
->reloc_in_cs
, 0);
85 struct drm_gem_open open_arg
;
87 memset(&open_arg
, 0, sizeof(open_arg
));
88 open_arg
.name
= handle
;
89 r
= drmIoctl(bom
->fd
, DRM_IOCTL_GEM_OPEN
, &open_arg
);
94 bo
->base
.handle
= open_arg
.handle
;
95 bo
->base
.size
= open_arg
.size
;
98 struct drm_radeon_gem_create args
;
101 args
.alignment
= alignment
;
102 args
.initial_domain
= bo
->base
.domains
;
105 r
= drmCommandWriteRead(bom
->fd
, DRM_RADEON_GEM_CREATE
,
106 &args
, sizeof(args
));
107 bo
->base
.handle
= args
.handle
;
109 fprintf(stderr
, "Failed to allocate :\n");
110 fprintf(stderr
, " size : %d bytes\n", size
);
111 fprintf(stderr
, " alignment : %d bytes\n", alignment
);
112 fprintf(stderr
, " domains : %d\n", bo
->base
.domains
);
117 radeon_bo_ref((struct radeon_bo
*)bo
);
118 return (struct radeon_bo
*)bo
;
121 static void bo_ref(struct radeon_bo_int
*boi
)
125 static struct radeon_bo
*bo_unref(struct radeon_bo_int
*boi
)
127 struct radeon_bo_gem
*bo_gem
= (struct radeon_bo_gem
*)boi
;
130 return (struct radeon_bo
*)boi
;
132 if (bo_gem
->priv_ptr
) {
133 drm_munmap(bo_gem
->priv_ptr
, boi
->size
);
137 drmCloseBufferHandle(boi
->bom
->fd
, boi
->handle
);
138 memset(bo_gem
, 0, sizeof(struct radeon_bo_gem
));
143 static int bo_map(struct radeon_bo_int
*boi
, int write
)
145 struct radeon_bo_gem
*bo_gem
= (struct radeon_bo_gem
*)boi
;
146 struct drm_radeon_gem_mmap args
;
150 if (bo_gem
->map_count
++ != 0) {
153 if (bo_gem
->priv_ptr
) {
159 /* Zero out args to make valgrind happy */
160 memset(&args
, 0, sizeof(args
));
161 args
.handle
= boi
->handle
;
163 args
.size
= (uint64_t)boi
->size
;
164 r
= drmCommandWriteRead(boi
->bom
->fd
,
169 fprintf(stderr
, "error mapping %p 0x%08X (error = %d)\n",
170 boi
, boi
->handle
, r
);
173 ptr
= drm_mmap(0, args
.size
, PROT_READ
|PROT_WRITE
, MAP_SHARED
, boi
->bom
->fd
, args
.addr_ptr
);
174 if (ptr
== MAP_FAILED
)
176 bo_gem
->priv_ptr
= ptr
;
178 boi
->ptr
= bo_gem
->priv_ptr
;
185 static int bo_unmap(struct radeon_bo_int
*boi
)
187 struct radeon_bo_gem
*bo_gem
= (struct radeon_bo_gem
*)boi
;
189 if (--bo_gem
->map_count
> 0) {
192 //drm_munmap(bo->ptr, bo->size);
197 static int bo_wait(struct radeon_bo_int
*boi
)
199 struct drm_radeon_gem_wait_idle args
;
202 /* Zero out args to make valgrind happy */
203 memset(&args
, 0, sizeof(args
));
204 args
.handle
= boi
->handle
;
206 ret
= drmCommandWrite(boi
->bom
->fd
, DRM_RADEON_GEM_WAIT_IDLE
,
207 &args
, sizeof(args
));
208 } while (ret
== -EBUSY
);
212 static int bo_is_busy(struct radeon_bo_int
*boi
, uint32_t *domain
)
214 struct drm_radeon_gem_busy args
;
217 args
.handle
= boi
->handle
;
220 ret
= drmCommandWriteRead(boi
->bom
->fd
, DRM_RADEON_GEM_BUSY
,
221 &args
, sizeof(args
));
223 *domain
= args
.domain
;
227 static int bo_set_tiling(struct radeon_bo_int
*boi
, uint32_t tiling_flags
,
230 struct drm_radeon_gem_set_tiling args
;
233 args
.handle
= boi
->handle
;
234 args
.tiling_flags
= tiling_flags
;
237 r
= drmCommandWriteRead(boi
->bom
->fd
,
238 DRM_RADEON_GEM_SET_TILING
,
244 static int bo_get_tiling(struct radeon_bo_int
*boi
, uint32_t *tiling_flags
,
247 struct drm_radeon_gem_set_tiling args
= {};
250 args
.handle
= boi
->handle
;
252 r
= drmCommandWriteRead(boi
->bom
->fd
,
253 DRM_RADEON_GEM_GET_TILING
,
260 *tiling_flags
= args
.tiling_flags
;
265 static const struct radeon_bo_funcs bo_gem_funcs
= {
268 .bo_unref
= bo_unref
,
270 .bo_unmap
= bo_unmap
,
272 .bo_is_static
= NULL
,
273 .bo_set_tiling
= bo_set_tiling
,
274 .bo_get_tiling
= bo_get_tiling
,
275 .bo_is_busy
= bo_is_busy
,
276 .bo_is_referenced_by_cs
= NULL
,
279 drm_public
struct radeon_bo_manager
*radeon_bo_manager_gem_ctor(int fd
)
281 struct bo_manager_gem
*bomg
;
283 bomg
= (struct bo_manager_gem
*)calloc(1, sizeof(struct bo_manager_gem
));
287 bomg
->base
.funcs
= &bo_gem_funcs
;
289 return (struct radeon_bo_manager
*)bomg
;
292 drm_public
void radeon_bo_manager_gem_dtor(struct radeon_bo_manager
*bom
)
294 struct bo_manager_gem
*bomg
= (struct bo_manager_gem
*)bom
;
303 radeon_gem_name_bo(struct radeon_bo
*bo
)
305 struct radeon_bo_gem
*bo_gem
= (struct radeon_bo_gem
*)bo
;
310 radeon_gem_get_reloc_in_cs(struct radeon_bo
*bo
)
312 struct radeon_bo_gem
*bo_gem
= (struct radeon_bo_gem
*)bo
;
313 return &bo_gem
->reloc_in_cs
;
317 radeon_gem_get_kernel_name(struct radeon_bo
*bo
, uint32_t *name
)
319 struct radeon_bo_gem
*bo_gem
= (struct radeon_bo_gem
*)bo
;
320 struct radeon_bo_int
*boi
= (struct radeon_bo_int
*)bo
;
321 struct drm_gem_flink flink
;
325 *name
= bo_gem
->name
;
328 flink
.handle
= bo
->handle
;
329 r
= drmIoctl(boi
->bom
->fd
, DRM_IOCTL_GEM_FLINK
, &flink
);
333 bo_gem
->name
= flink
.name
;
339 radeon_gem_set_domain(struct radeon_bo
*bo
, uint32_t read_domains
, uint32_t write_domain
)
341 struct radeon_bo_int
*boi
= (struct radeon_bo_int
*)bo
;
342 struct drm_radeon_gem_set_domain args
;
345 args
.handle
= bo
->handle
;
346 args
.read_domains
= read_domains
;
347 args
.write_domain
= write_domain
;
349 r
= drmCommandWriteRead(boi
->bom
->fd
,
350 DRM_RADEON_GEM_SET_DOMAIN
,
356 drm_public
int radeon_gem_prime_share_bo(struct radeon_bo
*bo
, int *handle
)
358 struct radeon_bo_gem
*bo_gem
= (struct radeon_bo_gem
*)bo
;
361 ret
= drmPrimeHandleToFD(bo_gem
->base
.bom
->fd
, bo
->handle
, DRM_CLOEXEC
, handle
);
365 drm_public
struct radeon_bo
*
366 radeon_gem_bo_open_prime(struct radeon_bo_manager
*bom
, int fd_handle
, uint32_t size
)
368 struct radeon_bo_gem
*bo
;
372 bo
= (struct radeon_bo_gem
*)calloc(1, sizeof(struct radeon_bo_gem
));
379 bo
->base
.size
= size
;
380 bo
->base
.alignment
= 0;
381 bo
->base
.domains
= RADEON_GEM_DOMAIN_GTT
;
384 atomic_set(&bo
->reloc_in_cs
, 0);
387 r
= drmPrimeFDToHandle(bom
->fd
, fd_handle
, &handle
);
393 bo
->base
.handle
= handle
;
396 radeon_bo_ref((struct radeon_bo
*)bo
);
397 return (struct radeon_bo
*)bo
;