radeon: More missing stdio.h includes.
[mesa.git] / src / gallium / winsys / radeon / drm / radeon_drm_bo.c
1 /*
2 * Copyright © 2011 Marek Olšák <maraeo@gmail.com>
3 * All Rights Reserved.
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining
6 * a copy of this software and associated documentation files (the
7 * "Software"), to deal in the Software without restriction, including
8 * without limitation the rights to use, copy, modify, merge, publish,
9 * distribute, sub license, and/or sell copies of the Software, and to
10 * permit persons to whom the Software is furnished to do so, subject to
11 * the following conditions:
12 *
13 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
14 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
15 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
16 * NON-INFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS, AUTHORS
17 * AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
20 * USE OR OTHER DEALINGS IN THE SOFTWARE.
21 *
22 * The above copyright notice and this permission notice (including the
23 * next paragraph) shall be included in all copies or substantial portions
24 * of the Software.
25 */
26
27 #define _FILE_OFFSET_BITS 64
28 #include "radeon_drm_cs.h"
29
30 #include "util/u_hash_table.h"
31 #include "util/u_memory.h"
32 #include "util/u_simple_list.h"
33 #include "util/u_double_list.h"
34 #include "os/os_thread.h"
35 #include "os/os_mman.h"
36 #include "os/os_time.h"
37
38 #include "state_tracker/drm_driver.h"
39
40 #include <sys/ioctl.h>
41 #include <xf86drm.h>
42 #include <errno.h>
43 #include <fcntl.h>
44 #include <stdio.h>
45
46 /*
47 * this are copy from radeon_drm, once an updated libdrm is released
48 * we should bump configure.ac requirement for it and remove the following
49 * field
50 */
51 #define RADEON_BO_FLAGS_MACRO_TILE 1
52 #define RADEON_BO_FLAGS_MICRO_TILE 2
53 #define RADEON_BO_FLAGS_MICRO_TILE_SQUARE 0x20
54
55 #ifndef DRM_RADEON_GEM_WAIT
56 #define DRM_RADEON_GEM_WAIT 0x2b
57
58 #define RADEON_GEM_NO_WAIT 0x1
59 #define RADEON_GEM_USAGE_READ 0x2
60 #define RADEON_GEM_USAGE_WRITE 0x4
61
62 struct drm_radeon_gem_wait {
63 uint32_t handle;
64 uint32_t flags; /* one of RADEON_GEM_* */
65 };
66
67 #endif
68
69 #ifndef RADEON_VA_MAP
70
71 #define RADEON_VA_MAP 1
72 #define RADEON_VA_UNMAP 2
73
74 #define RADEON_VA_RESULT_OK 0
75 #define RADEON_VA_RESULT_ERROR 1
76 #define RADEON_VA_RESULT_VA_EXIST 2
77
78 #define RADEON_VM_PAGE_VALID (1 << 0)
79 #define RADEON_VM_PAGE_READABLE (1 << 1)
80 #define RADEON_VM_PAGE_WRITEABLE (1 << 2)
81 #define RADEON_VM_PAGE_SYSTEM (1 << 3)
82 #define RADEON_VM_PAGE_SNOOPED (1 << 4)
83
84 struct drm_radeon_gem_va {
85 uint32_t handle;
86 uint32_t operation;
87 uint32_t vm_id;
88 uint32_t flags;
89 uint64_t offset;
90 };
91
92 #define DRM_RADEON_GEM_VA 0x2b
93 #endif
94
95
96
97 extern const struct pb_vtbl radeon_bo_vtbl;
98
99
100 static INLINE struct radeon_bo *radeon_bo(struct pb_buffer *bo)
101 {
102 assert(bo->vtbl == &radeon_bo_vtbl);
103 return (struct radeon_bo *)bo;
104 }
105
106 struct radeon_bo_va_hole {
107 struct list_head list;
108 uint64_t offset;
109 uint64_t size;
110 };
111
112 struct radeon_bomgr {
113 /* Base class. */
114 struct pb_manager base;
115
116 /* Winsys. */
117 struct radeon_drm_winsys *rws;
118
119 /* List of buffer GEM names. Protected by bo_handles_mutex. */
120 struct util_hash_table *bo_names;
121 /* List of buffer handles. Protectded by bo_handles_mutex. */
122 struct util_hash_table *bo_handles;
123 pipe_mutex bo_handles_mutex;
124 pipe_mutex bo_va_mutex;
125
126 /* is virtual address supported */
127 bool va;
128 uint64_t va_offset;
129 struct list_head va_holes;
130 };
131
132 static INLINE struct radeon_bomgr *radeon_bomgr(struct pb_manager *mgr)
133 {
134 return (struct radeon_bomgr *)mgr;
135 }
136
137 static struct radeon_bo *get_radeon_bo(struct pb_buffer *_buf)
138 {
139 struct radeon_bo *bo = NULL;
140
141 if (_buf->vtbl == &radeon_bo_vtbl) {
142 bo = radeon_bo(_buf);
143 } else {
144 struct pb_buffer *base_buf;
145 pb_size offset;
146 pb_get_base_buffer(_buf, &base_buf, &offset);
147
148 if (base_buf->vtbl == &radeon_bo_vtbl)
149 bo = radeon_bo(base_buf);
150 }
151
152 return bo;
153 }
154
155 static void radeon_bo_wait(struct pb_buffer *_buf, enum radeon_bo_usage usage)
156 {
157 struct radeon_bo *bo = get_radeon_bo(_buf);
158
159 while (p_atomic_read(&bo->num_active_ioctls)) {
160 sched_yield();
161 }
162
163 /* XXX use this when it's ready */
164 /*if (bo->rws->info.drm_minor >= 12) {
165 struct drm_radeon_gem_wait args = {};
166 args.handle = bo->handle;
167 args.flags = usage;
168 while (drmCommandWriteRead(bo->rws->fd, DRM_RADEON_GEM_WAIT,
169 &args, sizeof(args)) == -EBUSY);
170 } else*/ {
171 struct drm_radeon_gem_wait_idle args;
172 memset(&args, 0, sizeof(args));
173 args.handle = bo->handle;
174 while (drmCommandWrite(bo->rws->fd, DRM_RADEON_GEM_WAIT_IDLE,
175 &args, sizeof(args)) == -EBUSY);
176 }
177 }
178
179 static boolean radeon_bo_is_busy(struct pb_buffer *_buf,
180 enum radeon_bo_usage usage)
181 {
182 struct radeon_bo *bo = get_radeon_bo(_buf);
183
184 if (p_atomic_read(&bo->num_active_ioctls)) {
185 return TRUE;
186 }
187
188 /* XXX use this when it's ready */
189 /*if (bo->rws->info.drm_minor >= 12) {
190 struct drm_radeon_gem_wait args = {};
191 args.handle = bo->handle;
192 args.flags = usage | RADEON_GEM_NO_WAIT;
193 return drmCommandWriteRead(bo->rws->fd, DRM_RADEON_GEM_WAIT,
194 &args, sizeof(args)) != 0;
195 } else*/ {
196 struct drm_radeon_gem_busy args;
197 memset(&args, 0, sizeof(args));
198 args.handle = bo->handle;
199 return drmCommandWriteRead(bo->rws->fd, DRM_RADEON_GEM_BUSY,
200 &args, sizeof(args)) != 0;
201 }
202 }
203
204 static uint64_t radeon_bomgr_find_va(struct radeon_bomgr *mgr, uint64_t size, uint64_t alignment)
205 {
206 struct radeon_bo_va_hole *hole, *n;
207 uint64_t offset = 0, waste = 0;
208
209 alignment = MAX2(alignment, 4096);
210 size = align(size, 4096);
211
212 pipe_mutex_lock(mgr->bo_va_mutex);
213 /* first look for a hole */
214 LIST_FOR_EACH_ENTRY_SAFE(hole, n, &mgr->va_holes, list) {
215 offset = hole->offset;
216 waste = offset % alignment;
217 waste = waste ? alignment - waste : 0;
218 offset += waste;
219 if (offset >= (hole->offset + hole->size)) {
220 continue;
221 }
222 if (!waste && hole->size == size) {
223 offset = hole->offset;
224 list_del(&hole->list);
225 FREE(hole);
226 pipe_mutex_unlock(mgr->bo_va_mutex);
227 return offset;
228 }
229 if ((hole->size - waste) > size) {
230 if (waste) {
231 n = CALLOC_STRUCT(radeon_bo_va_hole);
232 n->size = waste;
233 n->offset = hole->offset;
234 list_add(&n->list, &hole->list);
235 }
236 hole->size -= (size + waste);
237 hole->offset += size + waste;
238 pipe_mutex_unlock(mgr->bo_va_mutex);
239 return offset;
240 }
241 if ((hole->size - waste) == size) {
242 hole->size = waste;
243 pipe_mutex_unlock(mgr->bo_va_mutex);
244 return offset;
245 }
246 }
247
248 offset = mgr->va_offset;
249 waste = offset % alignment;
250 waste = waste ? alignment - waste : 0;
251 if (waste) {
252 n = CALLOC_STRUCT(radeon_bo_va_hole);
253 n->size = waste;
254 n->offset = offset;
255 list_add(&n->list, &mgr->va_holes);
256 }
257 offset += waste;
258 mgr->va_offset += size + waste;
259 pipe_mutex_unlock(mgr->bo_va_mutex);
260 return offset;
261 }
262
263 static void radeon_bomgr_force_va(struct radeon_bomgr *mgr, uint64_t va, uint64_t size)
264 {
265 size = align(size, 4096);
266
267 pipe_mutex_lock(mgr->bo_va_mutex);
268 if (va >= mgr->va_offset) {
269 if (va > mgr->va_offset) {
270 struct radeon_bo_va_hole *hole;
271 hole = CALLOC_STRUCT(radeon_bo_va_hole);
272 if (hole) {
273 hole->size = va - mgr->va_offset;
274 hole->offset = mgr->va_offset;
275 list_add(&hole->list, &mgr->va_holes);
276 }
277 }
278 mgr->va_offset = va + size;
279 } else {
280 struct radeon_bo_va_hole *hole, *n;
281 uint64_t hole_end, va_end;
282
283 /* Prune/free all holes that fall into the range
284 */
285 LIST_FOR_EACH_ENTRY_SAFE(hole, n, &mgr->va_holes, list) {
286 hole_end = hole->offset + hole->size;
287 va_end = va + size;
288 if (hole->offset >= va_end || hole_end <= va)
289 continue;
290 if (hole->offset >= va && hole_end <= va_end) {
291 list_del(&hole->list);
292 FREE(hole);
293 continue;
294 }
295 if (hole->offset >= va)
296 hole->offset = va_end;
297 else
298 hole_end = va;
299 hole->size = hole_end - hole->offset;
300 }
301 }
302 pipe_mutex_unlock(mgr->bo_va_mutex);
303 }
304
305 static void radeon_bomgr_free_va(struct radeon_bomgr *mgr, uint64_t va, uint64_t size)
306 {
307 struct radeon_bo_va_hole *hole;
308
309 size = align(size, 4096);
310
311 pipe_mutex_lock(mgr->bo_va_mutex);
312 if ((va + size) == mgr->va_offset) {
313 mgr->va_offset = va;
314 /* Delete uppermost hole if it reaches the new top */
315 if (!LIST_IS_EMPTY(&mgr->va_holes)) {
316 hole = container_of(mgr->va_holes.next, hole, list);
317 if ((hole->offset + hole->size) == va) {
318 mgr->va_offset = hole->offset;
319 list_del(&hole->list);
320 FREE(hole);
321 }
322 }
323 } else {
324 struct radeon_bo_va_hole *next;
325
326 hole = container_of(&mgr->va_holes, hole, list);
327 LIST_FOR_EACH_ENTRY(next, &mgr->va_holes, list) {
328 if (next->offset < va)
329 break;
330 hole = next;
331 }
332
333 if (&hole->list != &mgr->va_holes) {
334 /* Grow upper hole if it's adjacent */
335 if (hole->offset == (va + size)) {
336 hole->offset = va;
337 hole->size += size;
338 /* Merge lower hole if it's adjacent */
339 if (next != hole && &next->list != &mgr->va_holes &&
340 (next->offset + next->size) == va) {
341 next->size += hole->size;
342 list_del(&hole->list);
343 FREE(hole);
344 }
345 goto out;
346 }
347 }
348
349 /* Grow lower hole if it's adjacent */
350 if (next != hole && &next->list != &mgr->va_holes &&
351 (next->offset + next->size) == va) {
352 next->size += size;
353 goto out;
354 }
355
356 /* FIXME on allocation failure we just lose virtual address space
357 * maybe print a warning
358 */
359 next = CALLOC_STRUCT(radeon_bo_va_hole);
360 if (next) {
361 next->size = size;
362 next->offset = va;
363 list_add(&next->list, &hole->list);
364 }
365 }
366 out:
367 pipe_mutex_unlock(mgr->bo_va_mutex);
368 }
369
370 static void radeon_bo_destroy(struct pb_buffer *_buf)
371 {
372 struct radeon_bo *bo = radeon_bo(_buf);
373 struct radeon_bomgr *mgr = bo->mgr;
374 struct drm_gem_close args;
375
376 memset(&args, 0, sizeof(args));
377
378 pipe_mutex_lock(bo->mgr->bo_handles_mutex);
379 util_hash_table_remove(bo->mgr->bo_handles, (void*)(uintptr_t)bo->handle);
380 if (bo->name) {
381 util_hash_table_remove(bo->mgr->bo_names,
382 (void*)(uintptr_t)bo->name);
383 }
384 pipe_mutex_unlock(bo->mgr->bo_handles_mutex);
385
386 if (bo->ptr)
387 os_munmap(bo->ptr, bo->base.size);
388
389 /* Close object. */
390 args.handle = bo->handle;
391 drmIoctl(bo->rws->fd, DRM_IOCTL_GEM_CLOSE, &args);
392
393 if (mgr->va) {
394 radeon_bomgr_free_va(mgr, bo->va, bo->base.size);
395 }
396
397 pipe_mutex_destroy(bo->map_mutex);
398
399 if (bo->initial_domain & RADEON_DOMAIN_VRAM)
400 bo->rws->allocated_vram -= align(bo->base.size, 4096);
401 else if (bo->initial_domain & RADEON_DOMAIN_GTT)
402 bo->rws->allocated_gtt -= align(bo->base.size, 4096);
403 FREE(bo);
404 }
405
406 void *radeon_bo_do_map(struct radeon_bo *bo)
407 {
408 struct drm_radeon_gem_mmap args = {0};
409 void *ptr;
410
411 /* Return the pointer if it's already mapped. */
412 if (bo->ptr)
413 return bo->ptr;
414
415 /* Map the buffer. */
416 pipe_mutex_lock(bo->map_mutex);
417 /* Return the pointer if it's already mapped (in case of a race). */
418 if (bo->ptr) {
419 pipe_mutex_unlock(bo->map_mutex);
420 return bo->ptr;
421 }
422 args.handle = bo->handle;
423 args.offset = 0;
424 args.size = (uint64_t)bo->base.size;
425 if (drmCommandWriteRead(bo->rws->fd,
426 DRM_RADEON_GEM_MMAP,
427 &args,
428 sizeof(args))) {
429 pipe_mutex_unlock(bo->map_mutex);
430 fprintf(stderr, "radeon: gem_mmap failed: %p 0x%08X\n",
431 bo, bo->handle);
432 return NULL;
433 }
434
435 ptr = os_mmap(0, args.size, PROT_READ|PROT_WRITE, MAP_SHARED,
436 bo->rws->fd, args.addr_ptr);
437 if (ptr == MAP_FAILED) {
438 pipe_mutex_unlock(bo->map_mutex);
439 fprintf(stderr, "radeon: mmap failed, errno: %i\n", errno);
440 return NULL;
441 }
442 bo->ptr = ptr;
443 pipe_mutex_unlock(bo->map_mutex);
444
445 return bo->ptr;
446 }
447
448 static void *radeon_bo_map(struct radeon_winsys_cs_handle *buf,
449 struct radeon_winsys_cs *rcs,
450 enum pipe_transfer_usage usage)
451 {
452 struct radeon_bo *bo = (struct radeon_bo*)buf;
453 struct radeon_drm_cs *cs = (struct radeon_drm_cs*)rcs;
454
455 /* If it's not unsynchronized bo_map, flush CS if needed and then wait. */
456 if (!(usage & PIPE_TRANSFER_UNSYNCHRONIZED)) {
457 /* DONTBLOCK doesn't make sense with UNSYNCHRONIZED. */
458 if (usage & PIPE_TRANSFER_DONTBLOCK) {
459 if (!(usage & PIPE_TRANSFER_WRITE)) {
460 /* Mapping for read.
461 *
462 * Since we are mapping for read, we don't need to wait
463 * if the GPU is using the buffer for read too
464 * (neither one is changing it).
465 *
466 * Only check whether the buffer is being used for write. */
467 if (cs && radeon_bo_is_referenced_by_cs_for_write(cs, bo)) {
468 cs->flush_cs(cs->flush_data, RADEON_FLUSH_ASYNC);
469 return NULL;
470 }
471
472 if (radeon_bo_is_busy((struct pb_buffer*)bo,
473 RADEON_USAGE_WRITE)) {
474 return NULL;
475 }
476 } else {
477 if (cs && radeon_bo_is_referenced_by_cs(cs, bo)) {
478 cs->flush_cs(cs->flush_data, RADEON_FLUSH_ASYNC);
479 return NULL;
480 }
481
482 if (radeon_bo_is_busy((struct pb_buffer*)bo,
483 RADEON_USAGE_READWRITE)) {
484 return NULL;
485 }
486 }
487 } else {
488 uint64_t time = os_time_get_nano();
489
490 if (!(usage & PIPE_TRANSFER_WRITE)) {
491 /* Mapping for read.
492 *
493 * Since we are mapping for read, we don't need to wait
494 * if the GPU is using the buffer for read too
495 * (neither one is changing it).
496 *
497 * Only check whether the buffer is being used for write. */
498 if (cs && radeon_bo_is_referenced_by_cs_for_write(cs, bo)) {
499 cs->flush_cs(cs->flush_data, 0);
500 }
501 radeon_bo_wait((struct pb_buffer*)bo,
502 RADEON_USAGE_WRITE);
503 } else {
504 /* Mapping for write. */
505 if (cs) {
506 if (radeon_bo_is_referenced_by_cs(cs, bo)) {
507 cs->flush_cs(cs->flush_data, 0);
508 } else {
509 /* Try to avoid busy-waiting in radeon_bo_wait. */
510 if (p_atomic_read(&bo->num_active_ioctls))
511 radeon_drm_cs_sync_flush(rcs);
512 }
513 }
514
515 radeon_bo_wait((struct pb_buffer*)bo, RADEON_USAGE_READWRITE);
516 }
517
518 bo->mgr->rws->buffer_wait_time += os_time_get_nano() - time;
519 }
520 }
521
522 return radeon_bo_do_map(bo);
523 }
524
525 static void radeon_bo_unmap(struct radeon_winsys_cs_handle *_buf)
526 {
527 /* NOP */
528 }
529
530 static void radeon_bo_get_base_buffer(struct pb_buffer *buf,
531 struct pb_buffer **base_buf,
532 unsigned *offset)
533 {
534 *base_buf = buf;
535 *offset = 0;
536 }
537
538 static enum pipe_error radeon_bo_validate(struct pb_buffer *_buf,
539 struct pb_validate *vl,
540 unsigned flags)
541 {
542 /* Always pinned */
543 return PIPE_OK;
544 }
545
546 static void radeon_bo_fence(struct pb_buffer *buf,
547 struct pipe_fence_handle *fence)
548 {
549 }
550
551 const struct pb_vtbl radeon_bo_vtbl = {
552 radeon_bo_destroy,
553 NULL, /* never called */
554 NULL, /* never called */
555 radeon_bo_validate,
556 radeon_bo_fence,
557 radeon_bo_get_base_buffer,
558 };
559
560 static struct pb_buffer *radeon_bomgr_create_bo(struct pb_manager *_mgr,
561 pb_size size,
562 const struct pb_desc *desc)
563 {
564 struct radeon_bomgr *mgr = radeon_bomgr(_mgr);
565 struct radeon_drm_winsys *rws = mgr->rws;
566 struct radeon_bo *bo;
567 struct drm_radeon_gem_create args;
568 struct radeon_bo_desc *rdesc = (struct radeon_bo_desc*)desc;
569 int r;
570
571 memset(&args, 0, sizeof(args));
572
573 assert(rdesc->initial_domains);
574 assert((rdesc->initial_domains &
575 ~(RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM)) == 0);
576
577 args.size = size;
578 args.alignment = desc->alignment;
579 args.initial_domain = rdesc->initial_domains;
580
581 if (drmCommandWriteRead(rws->fd, DRM_RADEON_GEM_CREATE,
582 &args, sizeof(args))) {
583 fprintf(stderr, "radeon: Failed to allocate a buffer:\n");
584 fprintf(stderr, "radeon: size : %d bytes\n", size);
585 fprintf(stderr, "radeon: alignment : %d bytes\n", desc->alignment);
586 fprintf(stderr, "radeon: domains : %d\n", args.initial_domain);
587 return NULL;
588 }
589
590 bo = CALLOC_STRUCT(radeon_bo);
591 if (!bo)
592 return NULL;
593
594 pipe_reference_init(&bo->base.reference, 1);
595 bo->base.alignment = desc->alignment;
596 bo->base.usage = desc->usage;
597 bo->base.size = size;
598 bo->base.vtbl = &radeon_bo_vtbl;
599 bo->mgr = mgr;
600 bo->rws = mgr->rws;
601 bo->handle = args.handle;
602 bo->va = 0;
603 bo->initial_domain = rdesc->initial_domains;
604 pipe_mutex_init(bo->map_mutex);
605
606 if (mgr->va) {
607 struct drm_radeon_gem_va va;
608
609 bo->va = radeon_bomgr_find_va(mgr, size, desc->alignment);
610
611 va.handle = bo->handle;
612 va.vm_id = 0;
613 va.operation = RADEON_VA_MAP;
614 va.flags = RADEON_VM_PAGE_READABLE |
615 RADEON_VM_PAGE_WRITEABLE |
616 RADEON_VM_PAGE_SNOOPED;
617 va.offset = bo->va;
618 r = drmCommandWriteRead(rws->fd, DRM_RADEON_GEM_VA, &va, sizeof(va));
619 if (r && va.operation == RADEON_VA_RESULT_ERROR) {
620 fprintf(stderr, "radeon: Failed to allocate virtual address for buffer:\n");
621 fprintf(stderr, "radeon: size : %d bytes\n", size);
622 fprintf(stderr, "radeon: alignment : %d bytes\n", desc->alignment);
623 fprintf(stderr, "radeon: domains : %d\n", args.initial_domain);
624 fprintf(stderr, "radeon: va : 0x%016llx\n", (unsigned long long)bo->va);
625 radeon_bo_destroy(&bo->base);
626 return NULL;
627 }
628 if (va.operation == RADEON_VA_RESULT_VA_EXIST) {
629 radeon_bomgr_free_va(mgr, bo->va, size);
630 bo->va = va.offset;
631 radeon_bomgr_force_va(mgr, bo->va, size);
632 }
633 }
634
635 if (rdesc->initial_domains & RADEON_DOMAIN_VRAM)
636 rws->allocated_vram += align(size, 4096);
637 else if (rdesc->initial_domains & RADEON_DOMAIN_GTT)
638 rws->allocated_gtt += align(size, 4096);
639
640 return &bo->base;
641 }
642
643 static void radeon_bomgr_flush(struct pb_manager *mgr)
644 {
645 /* NOP */
646 }
647
648 /* This is for the cache bufmgr. */
649 static boolean radeon_bomgr_is_buffer_busy(struct pb_manager *_mgr,
650 struct pb_buffer *_buf)
651 {
652 struct radeon_bo *bo = radeon_bo(_buf);
653
654 if (radeon_bo_is_referenced_by_any_cs(bo)) {
655 return TRUE;
656 }
657
658 if (radeon_bo_is_busy((struct pb_buffer*)bo, RADEON_USAGE_READWRITE)) {
659 return TRUE;
660 }
661
662 return FALSE;
663 }
664
665 static void radeon_bomgr_destroy(struct pb_manager *_mgr)
666 {
667 struct radeon_bomgr *mgr = radeon_bomgr(_mgr);
668 util_hash_table_destroy(mgr->bo_names);
669 util_hash_table_destroy(mgr->bo_handles);
670 pipe_mutex_destroy(mgr->bo_handles_mutex);
671 pipe_mutex_destroy(mgr->bo_va_mutex);
672 FREE(mgr);
673 }
674
675 #define PTR_TO_UINT(x) ((unsigned)((intptr_t)(x)))
676
677 static unsigned handle_hash(void *key)
678 {
679 return PTR_TO_UINT(key);
680 }
681
682 static int handle_compare(void *key1, void *key2)
683 {
684 return PTR_TO_UINT(key1) != PTR_TO_UINT(key2);
685 }
686
687 struct pb_manager *radeon_bomgr_create(struct radeon_drm_winsys *rws)
688 {
689 struct radeon_bomgr *mgr;
690
691 mgr = CALLOC_STRUCT(radeon_bomgr);
692 if (!mgr)
693 return NULL;
694
695 mgr->base.destroy = radeon_bomgr_destroy;
696 mgr->base.create_buffer = radeon_bomgr_create_bo;
697 mgr->base.flush = radeon_bomgr_flush;
698 mgr->base.is_buffer_busy = radeon_bomgr_is_buffer_busy;
699
700 mgr->rws = rws;
701 mgr->bo_names = util_hash_table_create(handle_hash, handle_compare);
702 mgr->bo_handles = util_hash_table_create(handle_hash, handle_compare);
703 pipe_mutex_init(mgr->bo_handles_mutex);
704 pipe_mutex_init(mgr->bo_va_mutex);
705
706 mgr->va = rws->info.r600_virtual_address;
707 mgr->va_offset = rws->info.r600_va_start;
708 list_inithead(&mgr->va_holes);
709
710 return &mgr->base;
711 }
712
713 static unsigned eg_tile_split(unsigned tile_split)
714 {
715 switch (tile_split) {
716 case 0: tile_split = 64; break;
717 case 1: tile_split = 128; break;
718 case 2: tile_split = 256; break;
719 case 3: tile_split = 512; break;
720 default:
721 case 4: tile_split = 1024; break;
722 case 5: tile_split = 2048; break;
723 case 6: tile_split = 4096; break;
724 }
725 return tile_split;
726 }
727
728 static unsigned eg_tile_split_rev(unsigned eg_tile_split)
729 {
730 switch (eg_tile_split) {
731 case 64: return 0;
732 case 128: return 1;
733 case 256: return 2;
734 case 512: return 3;
735 default:
736 case 1024: return 4;
737 case 2048: return 5;
738 case 4096: return 6;
739 }
740 }
741
742 static void radeon_bo_get_tiling(struct pb_buffer *_buf,
743 enum radeon_bo_layout *microtiled,
744 enum radeon_bo_layout *macrotiled,
745 unsigned *bankw, unsigned *bankh,
746 unsigned *tile_split,
747 unsigned *stencil_tile_split,
748 unsigned *mtilea,
749 bool *scanout)
750 {
751 struct radeon_bo *bo = get_radeon_bo(_buf);
752 struct drm_radeon_gem_set_tiling args;
753
754 memset(&args, 0, sizeof(args));
755
756 args.handle = bo->handle;
757
758 drmCommandWriteRead(bo->rws->fd,
759 DRM_RADEON_GEM_GET_TILING,
760 &args,
761 sizeof(args));
762
763 *microtiled = RADEON_LAYOUT_LINEAR;
764 *macrotiled = RADEON_LAYOUT_LINEAR;
765 if (args.tiling_flags & RADEON_BO_FLAGS_MICRO_TILE)
766 *microtiled = RADEON_LAYOUT_TILED;
767
768 if (args.tiling_flags & RADEON_BO_FLAGS_MACRO_TILE)
769 *macrotiled = RADEON_LAYOUT_TILED;
770 if (bankw && tile_split && stencil_tile_split && mtilea && tile_split) {
771 *bankw = (args.tiling_flags >> RADEON_TILING_EG_BANKW_SHIFT) & RADEON_TILING_EG_BANKW_MASK;
772 *bankh = (args.tiling_flags >> RADEON_TILING_EG_BANKH_SHIFT) & RADEON_TILING_EG_BANKH_MASK;
773 *tile_split = (args.tiling_flags >> RADEON_TILING_EG_TILE_SPLIT_SHIFT) & RADEON_TILING_EG_TILE_SPLIT_MASK;
774 *stencil_tile_split = (args.tiling_flags >> RADEON_TILING_EG_STENCIL_TILE_SPLIT_SHIFT) & RADEON_TILING_EG_STENCIL_TILE_SPLIT_MASK;
775 *mtilea = (args.tiling_flags >> RADEON_TILING_EG_MACRO_TILE_ASPECT_SHIFT) & RADEON_TILING_EG_MACRO_TILE_ASPECT_MASK;
776 *tile_split = eg_tile_split(*tile_split);
777 }
778 if (scanout)
779 *scanout = bo->rws->gen >= DRV_SI && !(args.tiling_flags & RADEON_TILING_R600_NO_SCANOUT);
780 }
781
782 static void radeon_bo_set_tiling(struct pb_buffer *_buf,
783 struct radeon_winsys_cs *rcs,
784 enum radeon_bo_layout microtiled,
785 enum radeon_bo_layout macrotiled,
786 unsigned bankw, unsigned bankh,
787 unsigned tile_split,
788 unsigned stencil_tile_split,
789 unsigned mtilea,
790 uint32_t pitch,
791 bool scanout)
792 {
793 struct radeon_bo *bo = get_radeon_bo(_buf);
794 struct radeon_drm_cs *cs = radeon_drm_cs(rcs);
795 struct drm_radeon_gem_set_tiling args;
796
797 memset(&args, 0, sizeof(args));
798
799 /* Tiling determines how DRM treats the buffer data.
800 * We must flush CS when changing it if the buffer is referenced. */
801 if (cs && radeon_bo_is_referenced_by_cs(cs, bo)) {
802 cs->flush_cs(cs->flush_data, 0);
803 }
804
805 while (p_atomic_read(&bo->num_active_ioctls)) {
806 sched_yield();
807 }
808
809 if (microtiled == RADEON_LAYOUT_TILED)
810 args.tiling_flags |= RADEON_BO_FLAGS_MICRO_TILE;
811 else if (microtiled == RADEON_LAYOUT_SQUARETILED)
812 args.tiling_flags |= RADEON_BO_FLAGS_MICRO_TILE_SQUARE;
813
814 if (macrotiled == RADEON_LAYOUT_TILED)
815 args.tiling_flags |= RADEON_BO_FLAGS_MACRO_TILE;
816
817 args.tiling_flags |= (bankw & RADEON_TILING_EG_BANKW_MASK) <<
818 RADEON_TILING_EG_BANKW_SHIFT;
819 args.tiling_flags |= (bankh & RADEON_TILING_EG_BANKH_MASK) <<
820 RADEON_TILING_EG_BANKH_SHIFT;
821 if (tile_split) {
822 args.tiling_flags |= (eg_tile_split_rev(tile_split) &
823 RADEON_TILING_EG_TILE_SPLIT_MASK) <<
824 RADEON_TILING_EG_TILE_SPLIT_SHIFT;
825 }
826 args.tiling_flags |= (stencil_tile_split &
827 RADEON_TILING_EG_STENCIL_TILE_SPLIT_MASK) <<
828 RADEON_TILING_EG_STENCIL_TILE_SPLIT_SHIFT;
829 args.tiling_flags |= (mtilea & RADEON_TILING_EG_MACRO_TILE_ASPECT_MASK) <<
830 RADEON_TILING_EG_MACRO_TILE_ASPECT_SHIFT;
831
832 if (bo->rws->gen >= DRV_SI && !scanout)
833 args.tiling_flags |= RADEON_TILING_R600_NO_SCANOUT;
834
835 args.handle = bo->handle;
836 args.pitch = pitch;
837
838 drmCommandWriteRead(bo->rws->fd,
839 DRM_RADEON_GEM_SET_TILING,
840 &args,
841 sizeof(args));
842 }
843
844 static struct radeon_winsys_cs_handle *radeon_drm_get_cs_handle(struct pb_buffer *_buf)
845 {
846 /* return radeon_bo. */
847 return (struct radeon_winsys_cs_handle*)get_radeon_bo(_buf);
848 }
849
850 static struct pb_buffer *
851 radeon_winsys_bo_create(struct radeon_winsys *rws,
852 unsigned size,
853 unsigned alignment,
854 boolean use_reusable_pool,
855 enum radeon_bo_domain domain)
856 {
857 struct radeon_drm_winsys *ws = radeon_drm_winsys(rws);
858 struct radeon_bomgr *mgr = radeon_bomgr(ws->kman);
859 struct radeon_bo_desc desc;
860 struct pb_manager *provider;
861 struct pb_buffer *buffer;
862
863 memset(&desc, 0, sizeof(desc));
864 desc.base.alignment = alignment;
865
866 /* Additional criteria for the cache manager. */
867 desc.base.usage = domain;
868 desc.initial_domains = domain;
869
870 /* Assign a buffer manager. */
871 if (use_reusable_pool)
872 provider = ws->cman;
873 else
874 provider = ws->kman;
875
876 buffer = provider->create_buffer(provider, size, &desc.base);
877 if (!buffer)
878 return NULL;
879
880 pipe_mutex_lock(mgr->bo_handles_mutex);
881 util_hash_table_set(mgr->bo_handles, (void*)(uintptr_t)get_radeon_bo(buffer)->handle, buffer);
882 pipe_mutex_unlock(mgr->bo_handles_mutex);
883
884 return (struct pb_buffer*)buffer;
885 }
886
887 static struct pb_buffer *radeon_winsys_bo_from_handle(struct radeon_winsys *rws,
888 struct winsys_handle *whandle,
889 unsigned *stride)
890 {
891 struct radeon_drm_winsys *ws = radeon_drm_winsys(rws);
892 struct radeon_bo *bo;
893 struct radeon_bomgr *mgr = radeon_bomgr(ws->kman);
894 struct drm_radeon_gem_busy args;
895 int r;
896 unsigned handle;
897 uint64_t size;
898
899 /* We must maintain a list of pairs <handle, bo>, so that we always return
900 * the same BO for one particular handle. If we didn't do that and created
901 * more than one BO for the same handle and then relocated them in a CS,
902 * we would hit a deadlock in the kernel.
903 *
904 * The list of pairs is guarded by a mutex, of course. */
905 pipe_mutex_lock(mgr->bo_handles_mutex);
906
907 if (whandle->type == DRM_API_HANDLE_TYPE_SHARED) {
908 /* First check if there already is an existing bo for the handle. */
909 bo = util_hash_table_get(mgr->bo_names, (void*)(uintptr_t)whandle->handle);
910 } else if (whandle->type == DRM_API_HANDLE_TYPE_FD) {
911 /* We must first get the GEM handle, as fds are unreliable keys */
912 r = drmPrimeFDToHandle(ws->fd, whandle->handle, &handle);
913 if (r)
914 goto fail;
915 bo = util_hash_table_get(mgr->bo_handles, (void*)(uintptr_t)handle);
916 } else {
917 /* Unknown handle type */
918 goto fail;
919 }
920
921 if (bo) {
922 /* Increase the refcount. */
923 struct pb_buffer *b = NULL;
924 pb_reference(&b, &bo->base);
925 goto done;
926 }
927
928 /* There isn't, create a new one. */
929 bo = CALLOC_STRUCT(radeon_bo);
930 if (!bo) {
931 goto fail;
932 }
933
934 if (whandle->type == DRM_API_HANDLE_TYPE_SHARED) {
935 struct drm_gem_open open_arg = {};
936 memset(&open_arg, 0, sizeof(open_arg));
937 /* Open the BO. */
938 open_arg.name = whandle->handle;
939 if (drmIoctl(ws->fd, DRM_IOCTL_GEM_OPEN, &open_arg)) {
940 FREE(bo);
941 goto fail;
942 }
943 handle = open_arg.handle;
944 size = open_arg.size;
945 bo->name = whandle->handle;
946 } else if (whandle->type == DRM_API_HANDLE_TYPE_FD) {
947 size = lseek(whandle->handle, 0, SEEK_END);
948 /*
949 * Could check errno to determine whether the kernel is new enough, but
950 * it doesn't really matter why this failed, just that it failed.
951 */
952 if (size == (off_t)-1) {
953 FREE(bo);
954 goto fail;
955 }
956 lseek(whandle->handle, 0, SEEK_SET);
957 }
958
959 bo->handle = handle;
960
961 /* Initialize it. */
962 pipe_reference_init(&bo->base.reference, 1);
963 bo->base.alignment = 0;
964 bo->base.usage = PB_USAGE_GPU_WRITE | PB_USAGE_GPU_READ;
965 bo->base.size = (unsigned) size;
966 bo->base.vtbl = &radeon_bo_vtbl;
967 bo->mgr = mgr;
968 bo->rws = mgr->rws;
969 bo->va = 0;
970 pipe_mutex_init(bo->map_mutex);
971
972 if (bo->name)
973 util_hash_table_set(mgr->bo_names, (void*)(uintptr_t)bo->name, bo);
974
975 util_hash_table_set(mgr->bo_handles, (void*)(uintptr_t)bo->handle, bo);
976
977 done:
978 pipe_mutex_unlock(mgr->bo_handles_mutex);
979
980 if (stride)
981 *stride = whandle->stride;
982
983 if (mgr->va && !bo->va) {
984 struct drm_radeon_gem_va va;
985
986 bo->va = radeon_bomgr_find_va(mgr, bo->base.size, 1 << 20);
987
988 va.handle = bo->handle;
989 va.operation = RADEON_VA_MAP;
990 va.vm_id = 0;
991 va.offset = bo->va;
992 va.flags = RADEON_VM_PAGE_READABLE |
993 RADEON_VM_PAGE_WRITEABLE |
994 RADEON_VM_PAGE_SNOOPED;
995 va.offset = bo->va;
996 r = drmCommandWriteRead(ws->fd, DRM_RADEON_GEM_VA, &va, sizeof(va));
997 if (r && va.operation == RADEON_VA_RESULT_ERROR) {
998 fprintf(stderr, "radeon: Failed to assign virtual address space\n");
999 radeon_bo_destroy(&bo->base);
1000 return NULL;
1001 }
1002 if (va.operation == RADEON_VA_RESULT_VA_EXIST) {
1003 radeon_bomgr_free_va(mgr, bo->va, bo->base.size);
1004 bo->va = va.offset;
1005 radeon_bomgr_force_va(mgr, bo->va, bo->base.size);
1006 }
1007 }
1008
1009 memset(&args, 0, sizeof(args));
1010
1011 args.handle = bo->handle;
1012 r = drmCommandWriteRead(bo->rws->fd, DRM_RADEON_GEM_BUSY, &args, sizeof(args));
1013 /* We don't mind if the bo is busy; we're just after the memory domain */
1014 if (r && r != -EBUSY) {
1015 fprintf(stderr, "radeon: Failed to find initial domain for imported bo\n");
1016 radeon_bo_destroy(&bo->base);
1017 return NULL;
1018 }
1019 bo->initial_domain = args.domain;
1020
1021 switch (bo->initial_domain) {
1022 case RADEON_DOMAIN_GTT:
1023 ws->allocated_gtt += align(size, 4096);
1024 break;
1025 case RADEON_DOMAIN_VRAM:
1026 ws->allocated_vram += align(size, 4096);
1027 break;
1028 }
1029
1030
1031 return (struct pb_buffer*)bo;
1032
1033 fail:
1034 pipe_mutex_unlock(mgr->bo_handles_mutex);
1035 return NULL;
1036 }
1037
1038 static boolean radeon_winsys_bo_get_handle(struct pb_buffer *buffer,
1039 unsigned stride,
1040 struct winsys_handle *whandle)
1041 {
1042 struct drm_gem_flink flink;
1043 struct radeon_bo *bo = get_radeon_bo(buffer);
1044
1045 memset(&flink, 0, sizeof(flink));
1046
1047 if (whandle->type == DRM_API_HANDLE_TYPE_SHARED) {
1048 if (!bo->flinked) {
1049 flink.handle = bo->handle;
1050
1051 if (ioctl(bo->rws->fd, DRM_IOCTL_GEM_FLINK, &flink)) {
1052 return FALSE;
1053 }
1054
1055 bo->flinked = TRUE;
1056 bo->flink = flink.name;
1057
1058 pipe_mutex_lock(bo->mgr->bo_handles_mutex);
1059 util_hash_table_set(bo->mgr->bo_names, (void*)(uintptr_t)bo->flink, bo);
1060 pipe_mutex_unlock(bo->mgr->bo_handles_mutex);
1061 }
1062 whandle->handle = bo->flink;
1063 } else if (whandle->type == DRM_API_HANDLE_TYPE_KMS) {
1064 whandle->handle = bo->handle;
1065 } else if (whandle->type == DRM_API_HANDLE_TYPE_FD) {
1066 if (drmPrimeHandleToFD(bo->rws->fd, bo->handle, DRM_CLOEXEC, (int*)&whandle->handle))
1067 return FALSE;
1068 }
1069
1070 whandle->stride = stride;
1071 return TRUE;
1072 }
1073
1074 static uint64_t radeon_winsys_bo_va(struct radeon_winsys_cs_handle *buf)
1075 {
1076 return ((struct radeon_bo*)buf)->va;
1077 }
1078
1079 void radeon_bomgr_init_functions(struct radeon_drm_winsys *ws)
1080 {
1081 ws->base.buffer_get_cs_handle = radeon_drm_get_cs_handle;
1082 ws->base.buffer_set_tiling = radeon_bo_set_tiling;
1083 ws->base.buffer_get_tiling = radeon_bo_get_tiling;
1084 ws->base.buffer_map = radeon_bo_map;
1085 ws->base.buffer_unmap = radeon_bo_unmap;
1086 ws->base.buffer_wait = radeon_bo_wait;
1087 ws->base.buffer_is_busy = radeon_bo_is_busy;
1088 ws->base.buffer_create = radeon_winsys_bo_create;
1089 ws->base.buffer_from_handle = radeon_winsys_bo_from_handle;
1090 ws->base.buffer_get_handle = radeon_winsys_bo_get_handle;
1091 ws->base.buffer_get_virtual_address = radeon_winsys_bo_va;
1092 }