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
;
128 struct drm_gem_close args
;
131 return (struct radeon_bo
*)boi
;
133 if (bo_gem
->priv_ptr
) {
134 drm_munmap(bo_gem
->priv_ptr
, boi
->size
);
137 /* Zero out args to make valgrind happy */
138 memset(&args
, 0, sizeof(args
));
141 args
.handle
= boi
->handle
;
142 drmIoctl(boi
->bom
->fd
, DRM_IOCTL_GEM_CLOSE
, &args
);
143 memset(bo_gem
, 0, sizeof(struct radeon_bo_gem
));
148 static int bo_map(struct radeon_bo_int
*boi
, int write
)
150 struct radeon_bo_gem
*bo_gem
= (struct radeon_bo_gem
*)boi
;
151 struct drm_radeon_gem_mmap args
;
155 if (bo_gem
->map_count
++ != 0) {
158 if (bo_gem
->priv_ptr
) {
164 /* Zero out args to make valgrind happy */
165 memset(&args
, 0, sizeof(args
));
166 args
.handle
= boi
->handle
;
168 args
.size
= (uint64_t)boi
->size
;
169 r
= drmCommandWriteRead(boi
->bom
->fd
,
174 fprintf(stderr
, "error mapping %p 0x%08X (error = %d)\n",
175 boi
, boi
->handle
, r
);
178 ptr
= drm_mmap(0, args
.size
, PROT_READ
|PROT_WRITE
, MAP_SHARED
, boi
->bom
->fd
, args
.addr_ptr
);
179 if (ptr
== MAP_FAILED
)
181 bo_gem
->priv_ptr
= ptr
;
183 boi
->ptr
= bo_gem
->priv_ptr
;
190 static int bo_unmap(struct radeon_bo_int
*boi
)
192 struct radeon_bo_gem
*bo_gem
= (struct radeon_bo_gem
*)boi
;
194 if (--bo_gem
->map_count
> 0) {
197 //drm_munmap(bo->ptr, bo->size);
202 static int bo_wait(struct radeon_bo_int
*boi
)
204 struct drm_radeon_gem_wait_idle args
;
207 /* Zero out args to make valgrind happy */
208 memset(&args
, 0, sizeof(args
));
209 args
.handle
= boi
->handle
;
211 ret
= drmCommandWrite(boi
->bom
->fd
, DRM_RADEON_GEM_WAIT_IDLE
,
212 &args
, sizeof(args
));
213 } while (ret
== -EBUSY
);
217 static int bo_is_busy(struct radeon_bo_int
*boi
, uint32_t *domain
)
219 struct drm_radeon_gem_busy args
;
222 args
.handle
= boi
->handle
;
225 ret
= drmCommandWriteRead(boi
->bom
->fd
, DRM_RADEON_GEM_BUSY
,
226 &args
, sizeof(args
));
228 *domain
= args
.domain
;
232 static int bo_set_tiling(struct radeon_bo_int
*boi
, uint32_t tiling_flags
,
235 struct drm_radeon_gem_set_tiling args
;
238 args
.handle
= boi
->handle
;
239 args
.tiling_flags
= tiling_flags
;
242 r
= drmCommandWriteRead(boi
->bom
->fd
,
243 DRM_RADEON_GEM_SET_TILING
,
249 static int bo_get_tiling(struct radeon_bo_int
*boi
, uint32_t *tiling_flags
,
252 struct drm_radeon_gem_set_tiling args
= {};
255 args
.handle
= boi
->handle
;
257 r
= drmCommandWriteRead(boi
->bom
->fd
,
258 DRM_RADEON_GEM_GET_TILING
,
265 *tiling_flags
= args
.tiling_flags
;
270 static const struct radeon_bo_funcs bo_gem_funcs
= {
273 .bo_unref
= bo_unref
,
275 .bo_unmap
= bo_unmap
,
277 .bo_is_static
= NULL
,
278 .bo_set_tiling
= bo_set_tiling
,
279 .bo_get_tiling
= bo_get_tiling
,
280 .bo_is_busy
= bo_is_busy
,
281 .bo_is_referenced_by_cs
= NULL
,
284 drm_public
struct radeon_bo_manager
*radeon_bo_manager_gem_ctor(int fd
)
286 struct bo_manager_gem
*bomg
;
288 bomg
= (struct bo_manager_gem
*)calloc(1, sizeof(struct bo_manager_gem
));
292 bomg
->base
.funcs
= &bo_gem_funcs
;
294 return (struct radeon_bo_manager
*)bomg
;
297 drm_public
void radeon_bo_manager_gem_dtor(struct radeon_bo_manager
*bom
)
299 struct bo_manager_gem
*bomg
= (struct bo_manager_gem
*)bom
;
308 radeon_gem_name_bo(struct radeon_bo
*bo
)
310 struct radeon_bo_gem
*bo_gem
= (struct radeon_bo_gem
*)bo
;
315 radeon_gem_get_reloc_in_cs(struct radeon_bo
*bo
)
317 struct radeon_bo_gem
*bo_gem
= (struct radeon_bo_gem
*)bo
;
318 return &bo_gem
->reloc_in_cs
;
322 radeon_gem_get_kernel_name(struct radeon_bo
*bo
, uint32_t *name
)
324 struct radeon_bo_gem
*bo_gem
= (struct radeon_bo_gem
*)bo
;
325 struct radeon_bo_int
*boi
= (struct radeon_bo_int
*)bo
;
326 struct drm_gem_flink flink
;
330 *name
= bo_gem
->name
;
333 flink
.handle
= bo
->handle
;
334 r
= drmIoctl(boi
->bom
->fd
, DRM_IOCTL_GEM_FLINK
, &flink
);
338 bo_gem
->name
= flink
.name
;
344 radeon_gem_set_domain(struct radeon_bo
*bo
, uint32_t read_domains
, uint32_t write_domain
)
346 struct radeon_bo_int
*boi
= (struct radeon_bo_int
*)bo
;
347 struct drm_radeon_gem_set_domain args
;
350 args
.handle
= bo
->handle
;
351 args
.read_domains
= read_domains
;
352 args
.write_domain
= write_domain
;
354 r
= drmCommandWriteRead(boi
->bom
->fd
,
355 DRM_RADEON_GEM_SET_DOMAIN
,
361 drm_public
int radeon_gem_prime_share_bo(struct radeon_bo
*bo
, int *handle
)
363 struct radeon_bo_gem
*bo_gem
= (struct radeon_bo_gem
*)bo
;
366 ret
= drmPrimeHandleToFD(bo_gem
->base
.bom
->fd
, bo
->handle
, DRM_CLOEXEC
, handle
);
370 drm_public
struct radeon_bo
*
371 radeon_gem_bo_open_prime(struct radeon_bo_manager
*bom
, int fd_handle
, uint32_t size
)
373 struct radeon_bo_gem
*bo
;
377 bo
= (struct radeon_bo_gem
*)calloc(1, sizeof(struct radeon_bo_gem
));
384 bo
->base
.size
= size
;
385 bo
->base
.alignment
= 0;
386 bo
->base
.domains
= RADEON_GEM_DOMAIN_GTT
;
389 atomic_set(&bo
->reloc_in_cs
, 0);
392 r
= drmPrimeFDToHandle(bom
->fd
, fd_handle
, &handle
);
398 bo
->base
.handle
= handle
;
401 radeon_bo_ref((struct radeon_bo
*)bo
);
402 return (struct radeon_bo
*)bo
;