i965/drm: Merge drm_bacon_bo_gem into drm_bacon_bo.
[mesa.git] / src / mesa / drivers / dri / i965 / intel_bufmgr_gem.c
1 /**************************************************************************
2 *
3 * Copyright © 2007 Red Hat Inc.
4 * Copyright © 2007-2012 Intel Corporation
5 * Copyright 2006 Tungsten Graphics, Inc., Bismarck, ND., USA
6 * All Rights Reserved.
7 *
8 * Permission is hereby granted, free of charge, to any person obtaining a
9 * copy of this software and associated documentation files (the
10 * "Software"), to deal in the Software without restriction, including
11 * without limitation the rights to use, copy, modify, merge, publish,
12 * distribute, sub license, and/or sell copies of the Software, and to
13 * permit persons to whom the Software is furnished to do so, subject to
14 * the following conditions:
15 *
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 COPYRIGHT HOLDERS, AUTHORS AND/OR ITS 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.
23 *
24 * The above copyright notice and this permission notice (including the
25 * next paragraph) shall be included in all copies or substantial portions
26 * of the Software.
27 *
28 *
29 **************************************************************************/
30 /*
31 * Authors: Thomas Hellström <thomas-at-tungstengraphics-dot-com>
32 * Keith Whitwell <keithw-at-tungstengraphics-dot-com>
33 * Eric Anholt <eric@anholt.net>
34 * Dave Airlie <airlied@linux.ie>
35 */
36
37 #ifdef HAVE_CONFIG_H
38 #include "config.h"
39 #endif
40
41 #include <xf86drm.h>
42 #include <util/u_atomic.h>
43 #include <fcntl.h>
44 #include <stdio.h>
45 #include <stdlib.h>
46 #include <string.h>
47 #include <unistd.h>
48 #include <assert.h>
49 #include <pthread.h>
50 #include <sys/ioctl.h>
51 #include <sys/stat.h>
52 #include <sys/types.h>
53 #include <stdbool.h>
54
55 #include "errno.h"
56 #ifndef ETIME
57 #define ETIME ETIMEDOUT
58 #endif
59 #include "common/gen_debug.h"
60 #include "common/gen_device_info.h"
61 #include "libdrm_macros.h"
62 #include "main/macros.h"
63 #include "util/macros.h"
64 #include "util/hash_table.h"
65 #include "util/list.h"
66 #include "brw_bufmgr.h"
67 #include "string.h"
68
69 #include "i915_drm.h"
70
71 #ifdef HAVE_VALGRIND
72 #include <valgrind.h>
73 #include <memcheck.h>
74 #define VG(x) x
75 #else
76 #define VG(x)
77 #endif
78
79 #define memclear(s) memset(&s, 0, sizeof(s))
80
81 #define FILE_DEBUG_FLAG DEBUG_BUFMGR
82
83 static inline int
84 atomic_add_unless(int *v, int add, int unless)
85 {
86 int c, old;
87 c = p_atomic_read(v);
88 while (c != unless && (old = p_atomic_cmpxchg(v, c, c + add)) != c)
89 c = old;
90 return c == unless;
91 }
92
93 struct _drm_bacon_context {
94 unsigned int ctx_id;
95 struct _drm_bacon_bufmgr *bufmgr;
96 };
97
98 struct drm_bacon_gem_bo_bucket {
99 struct list_head head;
100 unsigned long size;
101 };
102
103 typedef struct _drm_bacon_bufmgr {
104 int fd;
105
106 pthread_mutex_t lock;
107
108 /** Array of lists of cached gem objects of power-of-two sizes */
109 struct drm_bacon_gem_bo_bucket cache_bucket[14 * 4];
110 int num_buckets;
111 time_t time;
112
113 struct hash_table *name_table;
114 struct hash_table *handle_table;
115
116 struct list_head vma_cache;
117 int vma_count, vma_open, vma_max;
118
119 unsigned int has_llc : 1;
120 unsigned int bo_reuse : 1;
121 } drm_bacon_bufmgr;
122
123 static int
124 drm_bacon_gem_bo_set_tiling_internal(drm_bacon_bo *bo,
125 uint32_t tiling_mode,
126 uint32_t stride);
127
128 static void drm_bacon_gem_bo_free(drm_bacon_bo *bo);
129
130 static uint32_t
131 key_hash_uint(const void *key)
132 {
133 return _mesa_hash_data(key, 4);
134 }
135
136 static bool
137 key_uint_equal(const void *a, const void *b)
138 {
139 return *((unsigned *) a) == *((unsigned *) b);
140 }
141
142 static drm_bacon_bo *
143 hash_find_bo(struct hash_table *ht, unsigned int key)
144 {
145 struct hash_entry *entry = _mesa_hash_table_search(ht, &key);
146 return entry ? (drm_bacon_bo *) entry->data : NULL;
147 }
148
149 static unsigned long
150 drm_bacon_gem_bo_tile_size(drm_bacon_bufmgr *bufmgr, unsigned long size,
151 uint32_t *tiling_mode)
152 {
153 if (*tiling_mode == I915_TILING_NONE)
154 return size;
155
156 /* 965+ just need multiples of page size for tiling */
157 return ALIGN(size, 4096);
158 }
159
160 /*
161 * Round a given pitch up to the minimum required for X tiling on a
162 * given chip. We use 512 as the minimum to allow for a later tiling
163 * change.
164 */
165 static unsigned long
166 drm_bacon_gem_bo_tile_pitch(drm_bacon_bufmgr *bufmgr,
167 unsigned long pitch, uint32_t *tiling_mode)
168 {
169 unsigned long tile_width;
170
171 /* If untiled, then just align it so that we can do rendering
172 * to it with the 3D engine.
173 */
174 if (*tiling_mode == I915_TILING_NONE)
175 return ALIGN(pitch, 64);
176
177 if (*tiling_mode == I915_TILING_X)
178 tile_width = 512;
179 else
180 tile_width = 128;
181
182 /* 965 is flexible */
183 return ALIGN(pitch, tile_width);
184 }
185
186 static struct drm_bacon_gem_bo_bucket *
187 drm_bacon_gem_bo_bucket_for_size(drm_bacon_bufmgr *bufmgr,
188 unsigned long size)
189 {
190 int i;
191
192 for (i = 0; i < bufmgr->num_buckets; i++) {
193 struct drm_bacon_gem_bo_bucket *bucket =
194 &bufmgr->cache_bucket[i];
195 if (bucket->size >= size) {
196 return bucket;
197 }
198 }
199
200 return NULL;
201 }
202
203 inline void
204 drm_bacon_bo_reference(drm_bacon_bo *bo)
205 {
206 p_atomic_inc(&bo->refcount);
207 }
208
209 int
210 drm_bacon_bo_busy(drm_bacon_bo *bo)
211 {
212 drm_bacon_bufmgr *bufmgr = bo->bufmgr;
213 struct drm_i915_gem_busy busy;
214 int ret;
215
216 memclear(busy);
217 busy.handle = bo->gem_handle;
218
219 ret = drmIoctl(bufmgr->fd, DRM_IOCTL_I915_GEM_BUSY, &busy);
220 if (ret == 0) {
221 bo->idle = !busy.busy;
222 return busy.busy;
223 } else {
224 return false;
225 }
226 return (ret == 0 && busy.busy);
227 }
228
229 static int
230 drm_bacon_gem_bo_madvise_internal(drm_bacon_bufmgr *bufmgr,
231 drm_bacon_bo *bo, int state)
232 {
233 struct drm_i915_gem_madvise madv;
234
235 memclear(madv);
236 madv.handle = bo->gem_handle;
237 madv.madv = state;
238 madv.retained = 1;
239 drmIoctl(bufmgr->fd, DRM_IOCTL_I915_GEM_MADVISE, &madv);
240
241 return madv.retained;
242 }
243
244 int
245 drm_bacon_bo_madvise(drm_bacon_bo *bo, int madv)
246 {
247 return drm_bacon_gem_bo_madvise_internal(bo->bufmgr, bo, madv);
248 }
249
250 /* drop the oldest entries that have been purged by the kernel */
251 static void
252 drm_bacon_gem_bo_cache_purge_bucket(drm_bacon_bufmgr *bufmgr,
253 struct drm_bacon_gem_bo_bucket *bucket)
254 {
255 while (!list_empty(&bucket->head)) {
256 drm_bacon_bo *bo;
257
258 bo = LIST_ENTRY(drm_bacon_bo, bucket->head.next, head);
259 if (drm_bacon_gem_bo_madvise_internal
260 (bufmgr, bo, I915_MADV_DONTNEED))
261 break;
262
263 list_del(&bo->head);
264 drm_bacon_gem_bo_free(bo);
265 }
266 }
267
268 static drm_bacon_bo *
269 drm_bacon_gem_bo_alloc_internal(drm_bacon_bufmgr *bufmgr,
270 const char *name,
271 unsigned long size,
272 unsigned long flags,
273 uint32_t tiling_mode,
274 unsigned long stride,
275 unsigned int alignment)
276 {
277 drm_bacon_bo *bo;
278 unsigned int page_size = getpagesize();
279 int ret;
280 struct drm_bacon_gem_bo_bucket *bucket;
281 bool alloc_from_cache;
282 unsigned long bo_size;
283 bool for_render = false;
284
285 if (flags & BO_ALLOC_FOR_RENDER)
286 for_render = true;
287
288 /* Round the allocated size up to a power of two number of pages. */
289 bucket = drm_bacon_gem_bo_bucket_for_size(bufmgr, size);
290
291 /* If we don't have caching at this size, don't actually round the
292 * allocation up.
293 */
294 if (bucket == NULL) {
295 bo_size = size;
296 if (bo_size < page_size)
297 bo_size = page_size;
298 } else {
299 bo_size = bucket->size;
300 }
301
302 pthread_mutex_lock(&bufmgr->lock);
303 /* Get a buffer out of the cache if available */
304 retry:
305 alloc_from_cache = false;
306 if (bucket != NULL && !list_empty(&bucket->head)) {
307 if (for_render) {
308 /* Allocate new render-target BOs from the tail (MRU)
309 * of the list, as it will likely be hot in the GPU
310 * cache and in the aperture for us.
311 */
312 bo = LIST_ENTRY(drm_bacon_bo, bucket->head.prev, head);
313 list_del(&bo->head);
314 alloc_from_cache = true;
315 bo->align = alignment;
316 } else {
317 assert(alignment == 0);
318 /* For non-render-target BOs (where we're probably
319 * going to map it first thing in order to fill it
320 * with data), check if the last BO in the cache is
321 * unbusy, and only reuse in that case. Otherwise,
322 * allocating a new buffer is probably faster than
323 * waiting for the GPU to finish.
324 */
325 bo = LIST_ENTRY(drm_bacon_bo, bucket->head.next, head);
326 if (!drm_bacon_bo_busy(bo)) {
327 alloc_from_cache = true;
328 list_del(&bo->head);
329 }
330 }
331
332 if (alloc_from_cache) {
333 if (!drm_bacon_gem_bo_madvise_internal
334 (bufmgr, bo, I915_MADV_WILLNEED)) {
335 drm_bacon_gem_bo_free(bo);
336 drm_bacon_gem_bo_cache_purge_bucket(bufmgr,
337 bucket);
338 goto retry;
339 }
340
341 if (drm_bacon_gem_bo_set_tiling_internal(bo,
342 tiling_mode,
343 stride)) {
344 drm_bacon_gem_bo_free(bo);
345 goto retry;
346 }
347 }
348 }
349
350 if (!alloc_from_cache) {
351 struct drm_i915_gem_create create;
352
353 bo = calloc(1, sizeof(*bo));
354 if (!bo)
355 goto err;
356
357 /* drm_bacon_gem_bo_free calls list_del() for an uninitialized
358 list (vma_list), so better set the list head here */
359 list_inithead(&bo->vma_list);
360
361 bo->size = bo_size;
362
363 memclear(create);
364 create.size = bo_size;
365
366 ret = drmIoctl(bufmgr->fd,
367 DRM_IOCTL_I915_GEM_CREATE,
368 &create);
369 if (ret != 0) {
370 free(bo);
371 goto err;
372 }
373
374 bo->gem_handle = create.handle;
375 _mesa_hash_table_insert(bufmgr->handle_table,
376 &bo->gem_handle, bo);
377
378 bo->bufmgr = bufmgr;
379 bo->align = alignment;
380
381 bo->tiling_mode = I915_TILING_NONE;
382 bo->swizzle_mode = I915_BIT_6_SWIZZLE_NONE;
383 bo->stride = 0;
384
385 if (drm_bacon_gem_bo_set_tiling_internal(bo,
386 tiling_mode,
387 stride))
388 goto err_free;
389 }
390
391 bo->name = name;
392 p_atomic_set(&bo->refcount, 1);
393 bo->reusable = true;
394
395 pthread_mutex_unlock(&bufmgr->lock);
396
397 DBG("bo_create: buf %d (%s) %ldb\n",
398 bo->gem_handle, bo->name, size);
399
400 return bo;
401
402 err_free:
403 drm_bacon_gem_bo_free(bo);
404 err:
405 pthread_mutex_unlock(&bufmgr->lock);
406 return NULL;
407 }
408
409 drm_bacon_bo *
410 drm_bacon_bo_alloc_for_render(drm_bacon_bufmgr *bufmgr,
411 const char *name,
412 unsigned long size,
413 unsigned int alignment)
414 {
415 return drm_bacon_gem_bo_alloc_internal(bufmgr, name, size,
416 BO_ALLOC_FOR_RENDER,
417 I915_TILING_NONE, 0,
418 alignment);
419 }
420
421 drm_bacon_bo *
422 drm_bacon_bo_alloc(drm_bacon_bufmgr *bufmgr,
423 const char *name,
424 unsigned long size,
425 unsigned int alignment)
426 {
427 return drm_bacon_gem_bo_alloc_internal(bufmgr, name, size, 0,
428 I915_TILING_NONE, 0, 0);
429 }
430
431 drm_bacon_bo *
432 drm_bacon_bo_alloc_tiled(drm_bacon_bufmgr *bufmgr, const char *name,
433 int x, int y, int cpp, uint32_t *tiling_mode,
434 unsigned long *pitch, unsigned long flags)
435 {
436 unsigned long size, stride;
437 uint32_t tiling;
438
439 do {
440 unsigned long aligned_y, height_alignment;
441
442 tiling = *tiling_mode;
443
444 /* If we're tiled, our allocations are in 8 or 32-row blocks,
445 * so failure to align our height means that we won't allocate
446 * enough pages.
447 *
448 * If we're untiled, we still have to align to 2 rows high
449 * because the data port accesses 2x2 blocks even if the
450 * bottom row isn't to be rendered, so failure to align means
451 * we could walk off the end of the GTT and fault. This is
452 * documented on 965, and may be the case on older chipsets
453 * too so we try to be careful.
454 */
455 aligned_y = y;
456 height_alignment = 2;
457
458 if (tiling == I915_TILING_X)
459 height_alignment = 8;
460 else if (tiling == I915_TILING_Y)
461 height_alignment = 32;
462 aligned_y = ALIGN(y, height_alignment);
463
464 stride = x * cpp;
465 stride = drm_bacon_gem_bo_tile_pitch(bufmgr, stride, tiling_mode);
466 size = stride * aligned_y;
467 size = drm_bacon_gem_bo_tile_size(bufmgr, size, tiling_mode);
468 } while (*tiling_mode != tiling);
469 *pitch = stride;
470
471 if (tiling == I915_TILING_NONE)
472 stride = 0;
473
474 return drm_bacon_gem_bo_alloc_internal(bufmgr, name, size, flags,
475 tiling, stride, 0);
476 }
477
478 /**
479 * Returns a drm_bacon_bo wrapping the given buffer object handle.
480 *
481 * This can be used when one application needs to pass a buffer object
482 * to another.
483 */
484 drm_bacon_bo *
485 drm_bacon_bo_gem_create_from_name(drm_bacon_bufmgr *bufmgr,
486 const char *name,
487 unsigned int handle)
488 {
489 drm_bacon_bo *bo;
490 int ret;
491 struct drm_gem_open open_arg;
492 struct drm_i915_gem_get_tiling get_tiling;
493
494 /* At the moment most applications only have a few named bo.
495 * For instance, in a DRI client only the render buffers passed
496 * between X and the client are named. And since X returns the
497 * alternating names for the front/back buffer a linear search
498 * provides a sufficiently fast match.
499 */
500 pthread_mutex_lock(&bufmgr->lock);
501 bo = hash_find_bo(bufmgr->name_table, handle);
502 if (bo) {
503 drm_bacon_bo_reference(bo);
504 goto out;
505 }
506
507 memclear(open_arg);
508 open_arg.name = handle;
509 ret = drmIoctl(bufmgr->fd,
510 DRM_IOCTL_GEM_OPEN,
511 &open_arg);
512 if (ret != 0) {
513 DBG("Couldn't reference %s handle 0x%08x: %s\n",
514 name, handle, strerror(errno));
515 bo = NULL;
516 goto out;
517 }
518 /* Now see if someone has used a prime handle to get this
519 * object from the kernel before by looking through the list
520 * again for a matching gem_handle
521 */
522 bo = hash_find_bo(bufmgr->handle_table, open_arg.handle);
523 if (bo) {
524 drm_bacon_bo_reference(bo);
525 goto out;
526 }
527
528 bo = calloc(1, sizeof(*bo));
529 if (!bo)
530 goto out;
531
532 p_atomic_set(&bo->refcount, 1);
533 list_inithead(&bo->vma_list);
534
535 bo->size = open_arg.size;
536 bo->offset64 = 0;
537 bo->virtual = NULL;
538 bo->bufmgr = bufmgr;
539 bo->gem_handle = open_arg.handle;
540 bo->name = name;
541 bo->global_name = handle;
542 bo->reusable = false;
543
544 _mesa_hash_table_insert(bufmgr->handle_table, &bo->gem_handle, bo);
545 _mesa_hash_table_insert(bufmgr->name_table, &bo->global_name, bo);
546
547 memclear(get_tiling);
548 get_tiling.handle = bo->gem_handle;
549 ret = drmIoctl(bufmgr->fd,
550 DRM_IOCTL_I915_GEM_GET_TILING,
551 &get_tiling);
552 if (ret != 0)
553 goto err_unref;
554
555 bo->tiling_mode = get_tiling.tiling_mode;
556 bo->swizzle_mode = get_tiling.swizzle_mode;
557 /* XXX stride is unknown */
558 DBG("bo_create_from_handle: %d (%s)\n", handle, bo->name);
559
560 out:
561 pthread_mutex_unlock(&bufmgr->lock);
562 return bo;
563
564 err_unref:
565 drm_bacon_gem_bo_free(bo);
566 pthread_mutex_unlock(&bufmgr->lock);
567 return NULL;
568 }
569
570 static void
571 drm_bacon_gem_bo_free(drm_bacon_bo *bo)
572 {
573 drm_bacon_bufmgr *bufmgr = bo->bufmgr;
574 struct drm_gem_close close;
575 struct hash_entry *entry;
576 int ret;
577
578 list_del(&bo->vma_list);
579 if (bo->mem_virtual) {
580 VG(VALGRIND_FREELIKE_BLOCK(bo->mem_virtual, 0));
581 drm_munmap(bo->mem_virtual, bo->size);
582 bufmgr->vma_count--;
583 }
584 if (bo->wc_virtual) {
585 VG(VALGRIND_FREELIKE_BLOCK(bo->wc_virtual, 0));
586 drm_munmap(bo->wc_virtual, bo->size);
587 bufmgr->vma_count--;
588 }
589 if (bo->gtt_virtual) {
590 drm_munmap(bo->gtt_virtual, bo->size);
591 bufmgr->vma_count--;
592 }
593
594 if (bo->global_name) {
595 entry = _mesa_hash_table_search(bufmgr->name_table,
596 &bo->global_name);
597 _mesa_hash_table_remove(bufmgr->name_table, entry);
598 }
599 entry = _mesa_hash_table_search(bufmgr->handle_table,
600 &bo->gem_handle);
601 _mesa_hash_table_remove(bufmgr->handle_table, entry);
602
603 /* Close this object */
604 memclear(close);
605 close.handle = bo->gem_handle;
606 ret = drmIoctl(bufmgr->fd, DRM_IOCTL_GEM_CLOSE, &close);
607 if (ret != 0) {
608 DBG("DRM_IOCTL_GEM_CLOSE %d failed (%s): %s\n",
609 bo->gem_handle, bo->name, strerror(errno));
610 }
611 free(bo);
612 }
613
614 static void
615 drm_bacon_gem_bo_mark_mmaps_incoherent(drm_bacon_bo *bo)
616 {
617 #if HAVE_VALGRIND
618 if (bo->mem_virtual)
619 VALGRIND_MAKE_MEM_NOACCESS(bo->mem_virtual, bo->size);
620
621 if (bo->wc_virtual)
622 VALGRIND_MAKE_MEM_NOACCESS(bo->wc_virtual, bo->size);
623
624 if (bo->gtt_virtual)
625 VALGRIND_MAKE_MEM_NOACCESS(bo->gtt_virtual, bo->size);
626 #endif
627 }
628
629 /** Frees all cached buffers significantly older than @time. */
630 static void
631 drm_bacon_gem_cleanup_bo_cache(drm_bacon_bufmgr *bufmgr, time_t time)
632 {
633 int i;
634
635 if (bufmgr->time == time)
636 return;
637
638 for (i = 0; i < bufmgr->num_buckets; i++) {
639 struct drm_bacon_gem_bo_bucket *bucket =
640 &bufmgr->cache_bucket[i];
641
642 while (!list_empty(&bucket->head)) {
643 drm_bacon_bo *bo;
644
645 bo = LIST_ENTRY(drm_bacon_bo, bucket->head.next, head);
646 if (time - bo->free_time <= 1)
647 break;
648
649 list_del(&bo->head);
650
651 drm_bacon_gem_bo_free(bo);
652 }
653 }
654
655 bufmgr->time = time;
656 }
657
658 static void drm_bacon_gem_bo_purge_vma_cache(drm_bacon_bufmgr *bufmgr)
659 {
660 int limit;
661
662 DBG("%s: cached=%d, open=%d, limit=%d\n", __FUNCTION__,
663 bufmgr->vma_count, bufmgr->vma_open, bufmgr->vma_max);
664
665 if (bufmgr->vma_max < 0)
666 return;
667
668 /* We may need to evict a few entries in order to create new mmaps */
669 limit = bufmgr->vma_max - 2*bufmgr->vma_open;
670 if (limit < 0)
671 limit = 0;
672
673 while (bufmgr->vma_count > limit) {
674 drm_bacon_bo *bo;
675
676 bo = LIST_ENTRY(drm_bacon_bo, bufmgr->vma_cache.next, vma_list);
677 assert(bo->map_count == 0);
678 list_delinit(&bo->vma_list);
679
680 if (bo->mem_virtual) {
681 drm_munmap(bo->mem_virtual, bo->size);
682 bo->mem_virtual = NULL;
683 bufmgr->vma_count--;
684 }
685 if (bo->wc_virtual) {
686 drm_munmap(bo->wc_virtual, bo->size);
687 bo->wc_virtual = NULL;
688 bufmgr->vma_count--;
689 }
690 if (bo->gtt_virtual) {
691 drm_munmap(bo->gtt_virtual, bo->size);
692 bo->gtt_virtual = NULL;
693 bufmgr->vma_count--;
694 }
695 }
696 }
697
698 static void drm_bacon_gem_bo_close_vma(drm_bacon_bufmgr *bufmgr,
699 drm_bacon_bo *bo)
700 {
701 bufmgr->vma_open--;
702 list_addtail(&bo->vma_list, &bufmgr->vma_cache);
703 if (bo->mem_virtual)
704 bufmgr->vma_count++;
705 if (bo->wc_virtual)
706 bufmgr->vma_count++;
707 if (bo->gtt_virtual)
708 bufmgr->vma_count++;
709 drm_bacon_gem_bo_purge_vma_cache(bufmgr);
710 }
711
712 static void drm_bacon_gem_bo_open_vma(drm_bacon_bufmgr *bufmgr,
713 drm_bacon_bo *bo)
714 {
715 bufmgr->vma_open++;
716 list_del(&bo->vma_list);
717 if (bo->mem_virtual)
718 bufmgr->vma_count--;
719 if (bo->wc_virtual)
720 bufmgr->vma_count--;
721 if (bo->gtt_virtual)
722 bufmgr->vma_count--;
723 drm_bacon_gem_bo_purge_vma_cache(bufmgr);
724 }
725
726 static void
727 drm_bacon_gem_bo_unreference_final(drm_bacon_bo *bo, time_t time)
728 {
729 drm_bacon_bufmgr *bufmgr = bo->bufmgr;
730 struct drm_bacon_gem_bo_bucket *bucket;
731
732 DBG("bo_unreference final: %d (%s)\n",
733 bo->gem_handle, bo->name);
734
735 /* Clear any left-over mappings */
736 if (bo->map_count) {
737 DBG("bo freed with non-zero map-count %d\n", bo->map_count);
738 bo->map_count = 0;
739 drm_bacon_gem_bo_close_vma(bufmgr, bo);
740 drm_bacon_gem_bo_mark_mmaps_incoherent(bo);
741 }
742
743 bucket = drm_bacon_gem_bo_bucket_for_size(bufmgr, bo->size);
744 /* Put the buffer into our internal cache for reuse if we can. */
745 if (bufmgr->bo_reuse && bo->reusable && bucket != NULL &&
746 drm_bacon_gem_bo_madvise_internal(bufmgr, bo,
747 I915_MADV_DONTNEED)) {
748 bo->free_time = time;
749
750 bo->name = NULL;
751
752 list_addtail(&bo->head, &bucket->head);
753 } else {
754 drm_bacon_gem_bo_free(bo);
755 }
756 }
757
758 void
759 drm_bacon_bo_unreference(drm_bacon_bo *bo)
760 {
761 if (bo == NULL)
762 return;
763
764 assert(p_atomic_read(&bo->refcount) > 0);
765
766 if (atomic_add_unless(&bo->refcount, -1, 1)) {
767 drm_bacon_bufmgr *bufmgr = bo->bufmgr;
768 struct timespec time;
769
770 clock_gettime(CLOCK_MONOTONIC, &time);
771
772 pthread_mutex_lock(&bufmgr->lock);
773
774 if (p_atomic_dec_zero(&bo->refcount)) {
775 drm_bacon_gem_bo_unreference_final(bo, time.tv_sec);
776 drm_bacon_gem_cleanup_bo_cache(bufmgr, time.tv_sec);
777 }
778
779 pthread_mutex_unlock(&bufmgr->lock);
780 }
781 }
782
783 int
784 drm_bacon_bo_map(drm_bacon_bo *bo, int write_enable)
785 {
786 drm_bacon_bufmgr *bufmgr = bo->bufmgr;
787 struct drm_i915_gem_set_domain set_domain;
788 int ret;
789
790 pthread_mutex_lock(&bufmgr->lock);
791
792 if (bo->map_count++ == 0)
793 drm_bacon_gem_bo_open_vma(bufmgr, bo);
794
795 if (!bo->mem_virtual) {
796 struct drm_i915_gem_mmap mmap_arg;
797
798 DBG("bo_map: %d (%s), map_count=%d\n",
799 bo->gem_handle, bo->name, bo->map_count);
800
801 memclear(mmap_arg);
802 mmap_arg.handle = bo->gem_handle;
803 mmap_arg.size = bo->size;
804 ret = drmIoctl(bufmgr->fd,
805 DRM_IOCTL_I915_GEM_MMAP,
806 &mmap_arg);
807 if (ret != 0) {
808 ret = -errno;
809 DBG("%s:%d: Error mapping buffer %d (%s): %s .\n",
810 __FILE__, __LINE__, bo->gem_handle,
811 bo->name, strerror(errno));
812 if (--bo->map_count == 0)
813 drm_bacon_gem_bo_close_vma(bufmgr, bo);
814 pthread_mutex_unlock(&bufmgr->lock);
815 return ret;
816 }
817 VG(VALGRIND_MALLOCLIKE_BLOCK(mmap_arg.addr_ptr, mmap_arg.size, 0, 1));
818 bo->mem_virtual = (void *)(uintptr_t) mmap_arg.addr_ptr;
819 }
820 DBG("bo_map: %d (%s) -> %p\n", bo->gem_handle, bo->name,
821 bo->mem_virtual);
822 bo->virtual = bo->mem_virtual;
823
824 memclear(set_domain);
825 set_domain.handle = bo->gem_handle;
826 set_domain.read_domains = I915_GEM_DOMAIN_CPU;
827 if (write_enable)
828 set_domain.write_domain = I915_GEM_DOMAIN_CPU;
829 else
830 set_domain.write_domain = 0;
831 ret = drmIoctl(bufmgr->fd,
832 DRM_IOCTL_I915_GEM_SET_DOMAIN,
833 &set_domain);
834 if (ret != 0) {
835 DBG("%s:%d: Error setting to CPU domain %d: %s\n",
836 __FILE__, __LINE__, bo->gem_handle,
837 strerror(errno));
838 }
839
840 drm_bacon_gem_bo_mark_mmaps_incoherent(bo);
841 VG(VALGRIND_MAKE_MEM_DEFINED(bo->mem_virtual, bo->size));
842 pthread_mutex_unlock(&bufmgr->lock);
843
844 return 0;
845 }
846
847 static int
848 map_gtt(drm_bacon_bo *bo)
849 {
850 drm_bacon_bufmgr *bufmgr = bo->bufmgr;
851 int ret;
852
853 if (bo->map_count++ == 0)
854 drm_bacon_gem_bo_open_vma(bufmgr, bo);
855
856 /* Get a mapping of the buffer if we haven't before. */
857 if (bo->gtt_virtual == NULL) {
858 struct drm_i915_gem_mmap_gtt mmap_arg;
859
860 DBG("bo_map_gtt: mmap %d (%s), map_count=%d\n",
861 bo->gem_handle, bo->name, bo->map_count);
862
863 memclear(mmap_arg);
864 mmap_arg.handle = bo->gem_handle;
865
866 /* Get the fake offset back... */
867 ret = drmIoctl(bufmgr->fd,
868 DRM_IOCTL_I915_GEM_MMAP_GTT,
869 &mmap_arg);
870 if (ret != 0) {
871 ret = -errno;
872 DBG("%s:%d: Error preparing buffer map %d (%s): %s .\n",
873 __FILE__, __LINE__,
874 bo->gem_handle, bo->name,
875 strerror(errno));
876 if (--bo->map_count == 0)
877 drm_bacon_gem_bo_close_vma(bufmgr, bo);
878 return ret;
879 }
880
881 /* and mmap it */
882 bo->gtt_virtual = drm_mmap(0, bo->size, PROT_READ | PROT_WRITE,
883 MAP_SHARED, bufmgr->fd,
884 mmap_arg.offset);
885 if (bo->gtt_virtual == MAP_FAILED) {
886 bo->gtt_virtual = NULL;
887 ret = -errno;
888 DBG("%s:%d: Error mapping buffer %d (%s): %s .\n",
889 __FILE__, __LINE__,
890 bo->gem_handle, bo->name,
891 strerror(errno));
892 if (--bo->map_count == 0)
893 drm_bacon_gem_bo_close_vma(bufmgr, bo);
894 return ret;
895 }
896 }
897
898 bo->virtual = bo->gtt_virtual;
899
900 DBG("bo_map_gtt: %d (%s) -> %p\n", bo->gem_handle, bo->name,
901 bo->gtt_virtual);
902
903 return 0;
904 }
905
906 int
907 drm_bacon_gem_bo_map_gtt(drm_bacon_bo *bo)
908 {
909 drm_bacon_bufmgr *bufmgr = bo->bufmgr;
910 struct drm_i915_gem_set_domain set_domain;
911 int ret;
912
913 pthread_mutex_lock(&bufmgr->lock);
914
915 ret = map_gtt(bo);
916 if (ret) {
917 pthread_mutex_unlock(&bufmgr->lock);
918 return ret;
919 }
920
921 /* Now move it to the GTT domain so that the GPU and CPU
922 * caches are flushed and the GPU isn't actively using the
923 * buffer.
924 *
925 * The pagefault handler does this domain change for us when
926 * it has unbound the BO from the GTT, but it's up to us to
927 * tell it when we're about to use things if we had done
928 * rendering and it still happens to be bound to the GTT.
929 */
930 memclear(set_domain);
931 set_domain.handle = bo->gem_handle;
932 set_domain.read_domains = I915_GEM_DOMAIN_GTT;
933 set_domain.write_domain = I915_GEM_DOMAIN_GTT;
934 ret = drmIoctl(bufmgr->fd,
935 DRM_IOCTL_I915_GEM_SET_DOMAIN,
936 &set_domain);
937 if (ret != 0) {
938 DBG("%s:%d: Error setting domain %d: %s\n",
939 __FILE__, __LINE__, bo->gem_handle,
940 strerror(errno));
941 }
942
943 drm_bacon_gem_bo_mark_mmaps_incoherent(bo);
944 VG(VALGRIND_MAKE_MEM_DEFINED(bo->gtt_virtual, bo->size));
945 pthread_mutex_unlock(&bufmgr->lock);
946
947 return 0;
948 }
949
950 /**
951 * Performs a mapping of the buffer object like the normal GTT
952 * mapping, but avoids waiting for the GPU to be done reading from or
953 * rendering to the buffer.
954 *
955 * This is used in the implementation of GL_ARB_map_buffer_range: The
956 * user asks to create a buffer, then does a mapping, fills some
957 * space, runs a drawing command, then asks to map it again without
958 * synchronizing because it guarantees that it won't write over the
959 * data that the GPU is busy using (or, more specifically, that if it
960 * does write over the data, it acknowledges that rendering is
961 * undefined).
962 */
963
964 int
965 drm_bacon_gem_bo_map_unsynchronized(drm_bacon_bo *bo)
966 {
967 drm_bacon_bufmgr *bufmgr = bo->bufmgr;
968 int ret;
969
970 /* If the CPU cache isn't coherent with the GTT, then use a
971 * regular synchronized mapping. The problem is that we don't
972 * track where the buffer was last used on the CPU side in
973 * terms of drm_bacon_bo_map vs drm_bacon_gem_bo_map_gtt, so
974 * we would potentially corrupt the buffer even when the user
975 * does reasonable things.
976 */
977 if (!bufmgr->has_llc)
978 return drm_bacon_gem_bo_map_gtt(bo);
979
980 pthread_mutex_lock(&bufmgr->lock);
981
982 ret = map_gtt(bo);
983 if (ret == 0) {
984 drm_bacon_gem_bo_mark_mmaps_incoherent(bo);
985 VG(VALGRIND_MAKE_MEM_DEFINED(bo->gtt_virtual, bo->size));
986 }
987
988 pthread_mutex_unlock(&bufmgr->lock);
989
990 return ret;
991 }
992
993 int
994 drm_bacon_bo_unmap(drm_bacon_bo *bo)
995 {
996 drm_bacon_bufmgr *bufmgr = bo->bufmgr;
997 int ret = 0;
998
999 if (bo == NULL)
1000 return 0;
1001
1002 pthread_mutex_lock(&bufmgr->lock);
1003
1004 if (bo->map_count <= 0) {
1005 DBG("attempted to unmap an unmapped bo\n");
1006 pthread_mutex_unlock(&bufmgr->lock);
1007 /* Preserve the old behaviour of just treating this as a
1008 * no-op rather than reporting the error.
1009 */
1010 return 0;
1011 }
1012
1013 /* We need to unmap after every innovation as we cannot track
1014 * an open vma for every bo as that will exhaust the system
1015 * limits and cause later failures.
1016 */
1017 if (--bo->map_count == 0) {
1018 drm_bacon_gem_bo_close_vma(bufmgr, bo);
1019 drm_bacon_gem_bo_mark_mmaps_incoherent(bo);
1020 bo->virtual = NULL;
1021 }
1022 pthread_mutex_unlock(&bufmgr->lock);
1023
1024 return ret;
1025 }
1026
1027 int
1028 drm_bacon_bo_subdata(drm_bacon_bo *bo, unsigned long offset,
1029 unsigned long size, const void *data)
1030 {
1031 drm_bacon_bufmgr *bufmgr = bo->bufmgr;
1032 struct drm_i915_gem_pwrite pwrite;
1033 int ret;
1034
1035 memclear(pwrite);
1036 pwrite.handle = bo->gem_handle;
1037 pwrite.offset = offset;
1038 pwrite.size = size;
1039 pwrite.data_ptr = (uint64_t) (uintptr_t) data;
1040 ret = drmIoctl(bufmgr->fd,
1041 DRM_IOCTL_I915_GEM_PWRITE,
1042 &pwrite);
1043 if (ret != 0) {
1044 ret = -errno;
1045 DBG("%s:%d: Error writing data to buffer %d: (%d %d) %s .\n",
1046 __FILE__, __LINE__, bo->gem_handle, (int)offset,
1047 (int)size, strerror(errno));
1048 }
1049
1050 return ret;
1051 }
1052
1053 int
1054 drm_bacon_bo_get_subdata(drm_bacon_bo *bo, unsigned long offset,
1055 unsigned long size, void *data)
1056 {
1057 drm_bacon_bufmgr *bufmgr = bo->bufmgr;
1058 struct drm_i915_gem_pread pread;
1059 int ret;
1060
1061 memclear(pread);
1062 pread.handle = bo->gem_handle;
1063 pread.offset = offset;
1064 pread.size = size;
1065 pread.data_ptr = (uint64_t) (uintptr_t) data;
1066 ret = drmIoctl(bufmgr->fd,
1067 DRM_IOCTL_I915_GEM_PREAD,
1068 &pread);
1069 if (ret != 0) {
1070 ret = -errno;
1071 DBG("%s:%d: Error reading data from buffer %d: (%d %d) %s .\n",
1072 __FILE__, __LINE__, bo->gem_handle, (int)offset,
1073 (int)size, strerror(errno));
1074 }
1075
1076 return ret;
1077 }
1078
1079 /** Waits for all GPU rendering with the object to have completed. */
1080 void
1081 drm_bacon_bo_wait_rendering(drm_bacon_bo *bo)
1082 {
1083 drm_bacon_gem_bo_start_gtt_access(bo, 1);
1084 }
1085
1086 /**
1087 * Waits on a BO for the given amount of time.
1088 *
1089 * @bo: buffer object to wait for
1090 * @timeout_ns: amount of time to wait in nanoseconds.
1091 * If value is less than 0, an infinite wait will occur.
1092 *
1093 * Returns 0 if the wait was successful ie. the last batch referencing the
1094 * object has completed within the allotted time. Otherwise some negative return
1095 * value describes the error. Of particular interest is -ETIME when the wait has
1096 * failed to yield the desired result.
1097 *
1098 * Similar to drm_bacon_gem_bo_wait_rendering except a timeout parameter allows
1099 * the operation to give up after a certain amount of time. Another subtle
1100 * difference is the internal locking semantics are different (this variant does
1101 * not hold the lock for the duration of the wait). This makes the wait subject
1102 * to a larger userspace race window.
1103 *
1104 * The implementation shall wait until the object is no longer actively
1105 * referenced within a batch buffer at the time of the call. The wait will
1106 * not guarantee that the buffer is re-issued via another thread, or an flinked
1107 * handle. Userspace must make sure this race does not occur if such precision
1108 * is important.
1109 *
1110 * Note that some kernels have broken the inifite wait for negative values
1111 * promise, upgrade to latest stable kernels if this is the case.
1112 */
1113 int
1114 drm_bacon_gem_bo_wait(drm_bacon_bo *bo, int64_t timeout_ns)
1115 {
1116 drm_bacon_bufmgr *bufmgr = bo->bufmgr;
1117 struct drm_i915_gem_wait wait;
1118 int ret;
1119
1120 memclear(wait);
1121 wait.bo_handle = bo->gem_handle;
1122 wait.timeout_ns = timeout_ns;
1123 ret = drmIoctl(bufmgr->fd, DRM_IOCTL_I915_GEM_WAIT, &wait);
1124 if (ret == -1)
1125 return -errno;
1126
1127 return ret;
1128 }
1129
1130 /**
1131 * Sets the object to the GTT read and possibly write domain, used by the X
1132 * 2D driver in the absence of kernel support to do drm_bacon_gem_bo_map_gtt().
1133 *
1134 * In combination with drm_bacon_gem_bo_pin() and manual fence management, we
1135 * can do tiled pixmaps this way.
1136 */
1137 void
1138 drm_bacon_gem_bo_start_gtt_access(drm_bacon_bo *bo, int write_enable)
1139 {
1140 drm_bacon_bufmgr *bufmgr = bo->bufmgr;
1141 struct drm_i915_gem_set_domain set_domain;
1142 int ret;
1143
1144 memclear(set_domain);
1145 set_domain.handle = bo->gem_handle;
1146 set_domain.read_domains = I915_GEM_DOMAIN_GTT;
1147 set_domain.write_domain = write_enable ? I915_GEM_DOMAIN_GTT : 0;
1148 ret = drmIoctl(bufmgr->fd,
1149 DRM_IOCTL_I915_GEM_SET_DOMAIN,
1150 &set_domain);
1151 if (ret != 0) {
1152 DBG("%s:%d: Error setting memory domains %d (%08x %08x): %s .\n",
1153 __FILE__, __LINE__, bo->gem_handle,
1154 set_domain.read_domains, set_domain.write_domain,
1155 strerror(errno));
1156 }
1157 }
1158
1159 void
1160 drm_bacon_bufmgr_destroy(drm_bacon_bufmgr *bufmgr)
1161 {
1162 pthread_mutex_destroy(&bufmgr->lock);
1163
1164 /* Free any cached buffer objects we were going to reuse */
1165 for (int i = 0; i < bufmgr->num_buckets; i++) {
1166 struct drm_bacon_gem_bo_bucket *bucket =
1167 &bufmgr->cache_bucket[i];
1168 drm_bacon_bo *bo;
1169
1170 while (!list_empty(&bucket->head)) {
1171 bo = LIST_ENTRY(drm_bacon_bo, bucket->head.next, head);
1172 list_del(&bo->head);
1173
1174 drm_bacon_gem_bo_free(bo);
1175 }
1176 }
1177
1178 _mesa_hash_table_destroy(bufmgr->name_table, NULL);
1179 _mesa_hash_table_destroy(bufmgr->handle_table, NULL);
1180
1181 free(bufmgr);
1182 }
1183
1184 static int
1185 drm_bacon_gem_bo_set_tiling_internal(drm_bacon_bo *bo,
1186 uint32_t tiling_mode,
1187 uint32_t stride)
1188 {
1189 drm_bacon_bufmgr *bufmgr = bo->bufmgr;
1190 struct drm_i915_gem_set_tiling set_tiling;
1191 int ret;
1192
1193 if (bo->global_name == 0 &&
1194 tiling_mode == bo->tiling_mode &&
1195 stride == bo->stride)
1196 return 0;
1197
1198 memset(&set_tiling, 0, sizeof(set_tiling));
1199 do {
1200 /* set_tiling is slightly broken and overwrites the
1201 * input on the error path, so we have to open code
1202 * rmIoctl.
1203 */
1204 set_tiling.handle = bo->gem_handle;
1205 set_tiling.tiling_mode = tiling_mode;
1206 set_tiling.stride = stride;
1207
1208 ret = ioctl(bufmgr->fd,
1209 DRM_IOCTL_I915_GEM_SET_TILING,
1210 &set_tiling);
1211 } while (ret == -1 && (errno == EINTR || errno == EAGAIN));
1212 if (ret == -1)
1213 return -errno;
1214
1215 bo->tiling_mode = set_tiling.tiling_mode;
1216 bo->swizzle_mode = set_tiling.swizzle_mode;
1217 bo->stride = set_tiling.stride;
1218 return 0;
1219 }
1220
1221 int
1222 drm_bacon_bo_set_tiling(drm_bacon_bo *bo, uint32_t * tiling_mode,
1223 uint32_t stride)
1224 {
1225 int ret;
1226
1227 /* Linear buffers have no stride. By ensuring that we only ever use
1228 * stride 0 with linear buffers, we simplify our code.
1229 */
1230 if (*tiling_mode == I915_TILING_NONE)
1231 stride = 0;
1232
1233 ret = drm_bacon_gem_bo_set_tiling_internal(bo, *tiling_mode, stride);
1234
1235 *tiling_mode = bo->tiling_mode;
1236 return ret;
1237 }
1238
1239 int
1240 drm_bacon_bo_get_tiling(drm_bacon_bo *bo, uint32_t * tiling_mode,
1241 uint32_t *swizzle_mode)
1242 {
1243 *tiling_mode = bo->tiling_mode;
1244 *swizzle_mode = bo->swizzle_mode;
1245 return 0;
1246 }
1247
1248 drm_bacon_bo *
1249 drm_bacon_bo_gem_create_from_prime(drm_bacon_bufmgr *bufmgr, int prime_fd, int size)
1250 {
1251 int ret;
1252 uint32_t handle;
1253 drm_bacon_bo *bo;
1254 struct drm_i915_gem_get_tiling get_tiling;
1255
1256 pthread_mutex_lock(&bufmgr->lock);
1257 ret = drmPrimeFDToHandle(bufmgr->fd, prime_fd, &handle);
1258 if (ret) {
1259 DBG("create_from_prime: failed to obtain handle from fd: %s\n", strerror(errno));
1260 pthread_mutex_unlock(&bufmgr->lock);
1261 return NULL;
1262 }
1263
1264 /*
1265 * See if the kernel has already returned this buffer to us. Just as
1266 * for named buffers, we must not create two bo's pointing at the same
1267 * kernel object
1268 */
1269 bo = hash_find_bo(bufmgr->handle_table, handle);
1270 if (bo) {
1271 drm_bacon_bo_reference(bo);
1272 goto out;
1273 }
1274
1275 bo = calloc(1, sizeof(*bo));
1276 if (!bo)
1277 goto out;
1278
1279 p_atomic_set(&bo->refcount, 1);
1280 list_inithead(&bo->vma_list);
1281
1282 /* Determine size of bo. The fd-to-handle ioctl really should
1283 * return the size, but it doesn't. If we have kernel 3.12 or
1284 * later, we can lseek on the prime fd to get the size. Older
1285 * kernels will just fail, in which case we fall back to the
1286 * provided (estimated or guess size). */
1287 ret = lseek(prime_fd, 0, SEEK_END);
1288 if (ret != -1)
1289 bo->size = ret;
1290 else
1291 bo->size = size;
1292
1293 bo->bufmgr = bufmgr;
1294
1295 bo->gem_handle = handle;
1296 _mesa_hash_table_insert(bufmgr->handle_table,
1297 &bo->gem_handle, bo);
1298
1299 bo->name = "prime";
1300 bo->reusable = false;
1301
1302 memclear(get_tiling);
1303 get_tiling.handle = bo->gem_handle;
1304 if (drmIoctl(bufmgr->fd,
1305 DRM_IOCTL_I915_GEM_GET_TILING,
1306 &get_tiling))
1307 goto err;
1308
1309 bo->tiling_mode = get_tiling.tiling_mode;
1310 bo->swizzle_mode = get_tiling.swizzle_mode;
1311 /* XXX stride is unknown */
1312
1313 out:
1314 pthread_mutex_unlock(&bufmgr->lock);
1315 return bo;
1316
1317 err:
1318 drm_bacon_gem_bo_free(bo);
1319 pthread_mutex_unlock(&bufmgr->lock);
1320 return NULL;
1321 }
1322
1323 int
1324 drm_bacon_bo_gem_export_to_prime(drm_bacon_bo *bo, int *prime_fd)
1325 {
1326 drm_bacon_bufmgr *bufmgr = bo->bufmgr;
1327
1328 if (drmPrimeHandleToFD(bufmgr->fd, bo->gem_handle,
1329 DRM_CLOEXEC, prime_fd) != 0)
1330 return -errno;
1331
1332 bo->reusable = false;
1333
1334 return 0;
1335 }
1336
1337 int
1338 drm_bacon_bo_flink(drm_bacon_bo *bo, uint32_t *name)
1339 {
1340 drm_bacon_bufmgr *bufmgr = bo->bufmgr;
1341
1342 if (!bo->global_name) {
1343 struct drm_gem_flink flink;
1344
1345 memclear(flink);
1346 flink.handle = bo->gem_handle;
1347 if (drmIoctl(bufmgr->fd, DRM_IOCTL_GEM_FLINK, &flink))
1348 return -errno;
1349
1350 pthread_mutex_lock(&bufmgr->lock);
1351 if (!bo->global_name) {
1352 bo->global_name = flink.name;
1353 bo->reusable = false;
1354
1355 _mesa_hash_table_insert(bufmgr->name_table,
1356 &bo->global_name, bo);
1357 }
1358 pthread_mutex_unlock(&bufmgr->lock);
1359 }
1360
1361 *name = bo->global_name;
1362 return 0;
1363 }
1364
1365 /**
1366 * Enables unlimited caching of buffer objects for reuse.
1367 *
1368 * This is potentially very memory expensive, as the cache at each bucket
1369 * size is only bounded by how many buffers of that size we've managed to have
1370 * in flight at once.
1371 */
1372 void
1373 drm_bacon_bufmgr_gem_enable_reuse(drm_bacon_bufmgr *bufmgr)
1374 {
1375 bufmgr->bo_reuse = true;
1376 }
1377
1378 /*
1379 * Disable buffer reuse for objects which are shared with the kernel
1380 * as scanout buffers
1381 */
1382 int
1383 drm_bacon_bo_disable_reuse(drm_bacon_bo *bo)
1384 {
1385 bo->reusable = false;
1386 return 0;
1387 }
1388
1389 int
1390 drm_bacon_bo_is_reusable(drm_bacon_bo *bo)
1391 {
1392 return bo->reusable;
1393 }
1394
1395 static void
1396 add_bucket(drm_bacon_bufmgr *bufmgr, int size)
1397 {
1398 unsigned int i = bufmgr->num_buckets;
1399
1400 assert(i < ARRAY_SIZE(bufmgr->cache_bucket));
1401
1402 list_inithead(&bufmgr->cache_bucket[i].head);
1403 bufmgr->cache_bucket[i].size = size;
1404 bufmgr->num_buckets++;
1405 }
1406
1407 static void
1408 init_cache_buckets(drm_bacon_bufmgr *bufmgr)
1409 {
1410 unsigned long size, cache_max_size = 64 * 1024 * 1024;
1411
1412 /* OK, so power of two buckets was too wasteful of memory.
1413 * Give 3 other sizes between each power of two, to hopefully
1414 * cover things accurately enough. (The alternative is
1415 * probably to just go for exact matching of sizes, and assume
1416 * that for things like composited window resize the tiled
1417 * width/height alignment and rounding of sizes to pages will
1418 * get us useful cache hit rates anyway)
1419 */
1420 add_bucket(bufmgr, 4096);
1421 add_bucket(bufmgr, 4096 * 2);
1422 add_bucket(bufmgr, 4096 * 3);
1423
1424 /* Initialize the linked lists for BO reuse cache. */
1425 for (size = 4 * 4096; size <= cache_max_size; size *= 2) {
1426 add_bucket(bufmgr, size);
1427
1428 add_bucket(bufmgr, size + size * 1 / 4);
1429 add_bucket(bufmgr, size + size * 2 / 4);
1430 add_bucket(bufmgr, size + size * 3 / 4);
1431 }
1432 }
1433
1434 void
1435 drm_bacon_bufmgr_gem_set_vma_cache_size(drm_bacon_bufmgr *bufmgr, int limit)
1436 {
1437 bufmgr->vma_max = limit;
1438
1439 drm_bacon_gem_bo_purge_vma_cache(bufmgr);
1440 }
1441
1442 drm_bacon_context *
1443 drm_bacon_gem_context_create(drm_bacon_bufmgr *bufmgr)
1444 {
1445 struct drm_i915_gem_context_create create;
1446 drm_bacon_context *context = NULL;
1447 int ret;
1448
1449 context = calloc(1, sizeof(*context));
1450 if (!context)
1451 return NULL;
1452
1453 memclear(create);
1454 ret = drmIoctl(bufmgr->fd, DRM_IOCTL_I915_GEM_CONTEXT_CREATE, &create);
1455 if (ret != 0) {
1456 DBG("DRM_IOCTL_I915_GEM_CONTEXT_CREATE failed: %s\n",
1457 strerror(errno));
1458 free(context);
1459 return NULL;
1460 }
1461
1462 context->ctx_id = create.ctx_id;
1463 context->bufmgr = bufmgr;
1464
1465 return context;
1466 }
1467
1468 int
1469 drm_bacon_gem_context_get_id(drm_bacon_context *ctx, uint32_t *ctx_id)
1470 {
1471 if (ctx == NULL)
1472 return -EINVAL;
1473
1474 *ctx_id = ctx->ctx_id;
1475
1476 return 0;
1477 }
1478
1479 void
1480 drm_bacon_gem_context_destroy(drm_bacon_context *ctx)
1481 {
1482 struct drm_i915_gem_context_destroy destroy;
1483 int ret;
1484
1485 if (ctx == NULL)
1486 return;
1487
1488 memclear(destroy);
1489
1490 destroy.ctx_id = ctx->ctx_id;
1491 ret = drmIoctl(ctx->bufmgr->fd, DRM_IOCTL_I915_GEM_CONTEXT_DESTROY,
1492 &destroy);
1493 if (ret != 0)
1494 fprintf(stderr, "DRM_IOCTL_I915_GEM_CONTEXT_DESTROY failed: %s\n",
1495 strerror(errno));
1496
1497 free(ctx);
1498 }
1499
1500 int
1501 drm_bacon_get_reset_stats(drm_bacon_context *ctx,
1502 uint32_t *reset_count,
1503 uint32_t *active,
1504 uint32_t *pending)
1505 {
1506 struct drm_i915_reset_stats stats;
1507 int ret;
1508
1509 if (ctx == NULL)
1510 return -EINVAL;
1511
1512 memclear(stats);
1513
1514 stats.ctx_id = ctx->ctx_id;
1515 ret = drmIoctl(ctx->bufmgr->fd,
1516 DRM_IOCTL_I915_GET_RESET_STATS,
1517 &stats);
1518 if (ret == 0) {
1519 if (reset_count != NULL)
1520 *reset_count = stats.reset_count;
1521
1522 if (active != NULL)
1523 *active = stats.batch_active;
1524
1525 if (pending != NULL)
1526 *pending = stats.batch_pending;
1527 }
1528
1529 return ret;
1530 }
1531
1532 int
1533 drm_bacon_reg_read(drm_bacon_bufmgr *bufmgr,
1534 uint32_t offset,
1535 uint64_t *result)
1536 {
1537 struct drm_i915_reg_read reg_read;
1538 int ret;
1539
1540 memclear(reg_read);
1541 reg_read.offset = offset;
1542
1543 ret = drmIoctl(bufmgr->fd, DRM_IOCTL_I915_REG_READ, &reg_read);
1544
1545 *result = reg_read.val;
1546 return ret;
1547 }
1548
1549 void *drm_bacon_gem_bo_map__gtt(drm_bacon_bo *bo)
1550 {
1551 drm_bacon_bufmgr *bufmgr = bo->bufmgr;
1552
1553 if (bo->gtt_virtual)
1554 return bo->gtt_virtual;
1555
1556 pthread_mutex_lock(&bufmgr->lock);
1557 if (bo->gtt_virtual == NULL) {
1558 struct drm_i915_gem_mmap_gtt mmap_arg;
1559 void *ptr;
1560
1561 DBG("bo_map_gtt: mmap %d (%s), map_count=%d\n",
1562 bo->gem_handle, bo->name, bo->map_count);
1563
1564 if (bo->map_count++ == 0)
1565 drm_bacon_gem_bo_open_vma(bufmgr, bo);
1566
1567 memclear(mmap_arg);
1568 mmap_arg.handle = bo->gem_handle;
1569
1570 /* Get the fake offset back... */
1571 ptr = MAP_FAILED;
1572 if (drmIoctl(bufmgr->fd,
1573 DRM_IOCTL_I915_GEM_MMAP_GTT,
1574 &mmap_arg) == 0) {
1575 /* and mmap it */
1576 ptr = drm_mmap(0, bo->size, PROT_READ | PROT_WRITE,
1577 MAP_SHARED, bufmgr->fd,
1578 mmap_arg.offset);
1579 }
1580 if (ptr == MAP_FAILED) {
1581 if (--bo->map_count == 0)
1582 drm_bacon_gem_bo_close_vma(bufmgr, bo);
1583 ptr = NULL;
1584 }
1585
1586 bo->gtt_virtual = ptr;
1587 }
1588 pthread_mutex_unlock(&bufmgr->lock);
1589
1590 return bo->gtt_virtual;
1591 }
1592
1593 void *drm_bacon_gem_bo_map__cpu(drm_bacon_bo *bo)
1594 {
1595 drm_bacon_bufmgr *bufmgr = bo->bufmgr;
1596
1597 if (bo->mem_virtual)
1598 return bo->mem_virtual;
1599
1600 pthread_mutex_lock(&bufmgr->lock);
1601 if (!bo->mem_virtual) {
1602 struct drm_i915_gem_mmap mmap_arg;
1603
1604 if (bo->map_count++ == 0)
1605 drm_bacon_gem_bo_open_vma(bufmgr, bo);
1606
1607 DBG("bo_map: %d (%s), map_count=%d\n",
1608 bo->gem_handle, bo->name, bo->map_count);
1609
1610 memclear(mmap_arg);
1611 mmap_arg.handle = bo->gem_handle;
1612 mmap_arg.size = bo->size;
1613 if (drmIoctl(bufmgr->fd,
1614 DRM_IOCTL_I915_GEM_MMAP,
1615 &mmap_arg)) {
1616 DBG("%s:%d: Error mapping buffer %d (%s): %s .\n",
1617 __FILE__, __LINE__, bo->gem_handle,
1618 bo->name, strerror(errno));
1619 if (--bo->map_count == 0)
1620 drm_bacon_gem_bo_close_vma(bufmgr, bo);
1621 } else {
1622 VG(VALGRIND_MALLOCLIKE_BLOCK(mmap_arg.addr_ptr, mmap_arg.size, 0, 1));
1623 bo->mem_virtual = (void *)(uintptr_t) mmap_arg.addr_ptr;
1624 }
1625 }
1626 pthread_mutex_unlock(&bufmgr->lock);
1627
1628 return bo->mem_virtual;
1629 }
1630
1631 void *drm_bacon_gem_bo_map__wc(drm_bacon_bo *bo)
1632 {
1633 drm_bacon_bufmgr *bufmgr = bo->bufmgr;
1634
1635 if (bo->wc_virtual)
1636 return bo->wc_virtual;
1637
1638 pthread_mutex_lock(&bufmgr->lock);
1639 if (!bo->wc_virtual) {
1640 struct drm_i915_gem_mmap mmap_arg;
1641
1642 if (bo->map_count++ == 0)
1643 drm_bacon_gem_bo_open_vma(bufmgr, bo);
1644
1645 DBG("bo_map: %d (%s), map_count=%d\n",
1646 bo->gem_handle, bo->name, bo->map_count);
1647
1648 memclear(mmap_arg);
1649 mmap_arg.handle = bo->gem_handle;
1650 mmap_arg.size = bo->size;
1651 mmap_arg.flags = I915_MMAP_WC;
1652 if (drmIoctl(bufmgr->fd,
1653 DRM_IOCTL_I915_GEM_MMAP,
1654 &mmap_arg)) {
1655 DBG("%s:%d: Error mapping buffer %d (%s): %s .\n",
1656 __FILE__, __LINE__, bo->gem_handle,
1657 bo->name, strerror(errno));
1658 if (--bo->map_count == 0)
1659 drm_bacon_gem_bo_close_vma(bufmgr, bo);
1660 } else {
1661 VG(VALGRIND_MALLOCLIKE_BLOCK(mmap_arg.addr_ptr, mmap_arg.size, 0, 1));
1662 bo->wc_virtual = (void *)(uintptr_t) mmap_arg.addr_ptr;
1663 }
1664 }
1665 pthread_mutex_unlock(&bufmgr->lock);
1666
1667 return bo->wc_virtual;
1668 }
1669
1670 /**
1671 * Initializes the GEM buffer manager, which uses the kernel to allocate, map,
1672 * and manage map buffer objections.
1673 *
1674 * \param fd File descriptor of the opened DRM device.
1675 */
1676 drm_bacon_bufmgr *
1677 drm_bacon_bufmgr_gem_init(struct gen_device_info *devinfo,
1678 int fd, int batch_size)
1679 {
1680 drm_bacon_bufmgr *bufmgr;
1681
1682 bufmgr = calloc(1, sizeof(*bufmgr));
1683 if (bufmgr == NULL)
1684 return NULL;
1685
1686 /* Handles to buffer objects belong to the device fd and are not
1687 * reference counted by the kernel. If the same fd is used by
1688 * multiple parties (threads sharing the same screen bufmgr, or
1689 * even worse the same device fd passed to multiple libraries)
1690 * ownership of those handles is shared by those independent parties.
1691 *
1692 * Don't do this! Ensure that each library/bufmgr has its own device
1693 * fd so that its namespace does not clash with another.
1694 */
1695 bufmgr->fd = fd;
1696
1697 if (pthread_mutex_init(&bufmgr->lock, NULL) != 0) {
1698 free(bufmgr);
1699 return NULL;
1700 }
1701
1702 bufmgr->has_llc = devinfo->has_llc;
1703
1704 init_cache_buckets(bufmgr);
1705
1706 list_inithead(&bufmgr->vma_cache);
1707 bufmgr->vma_max = -1; /* unlimited by default */
1708
1709 bufmgr->name_table =
1710 _mesa_hash_table_create(NULL, key_hash_uint, key_uint_equal);
1711 bufmgr->handle_table =
1712 _mesa_hash_table_create(NULL, key_hash_uint, key_uint_equal);
1713
1714 return bufmgr;
1715 }