i965/drm: Unwrap the unnecessary drm_bacon_reloc_target_info struct.
[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 /**
94 * upper_32_bits - return bits 32-63 of a number
95 * @n: the number we're accessing
96 *
97 * A basic shift-right of a 64- or 32-bit quantity. Use this to suppress
98 * the "right shift count >= width of type" warning when that quantity is
99 * 32-bits.
100 */
101 #define upper_32_bits(n) ((__u32)(((n) >> 16) >> 16))
102
103 /**
104 * lower_32_bits - return bits 0-31 of a number
105 * @n: the number we're accessing
106 */
107 #define lower_32_bits(n) ((__u32)(n))
108
109 struct _drm_bacon_context {
110 unsigned int ctx_id;
111 struct _drm_bacon_bufmgr *bufmgr;
112 };
113
114 typedef struct _drm_bacon_bo_gem drm_bacon_bo_gem;
115
116 struct drm_bacon_gem_bo_bucket {
117 struct list_head head;
118 unsigned long size;
119 };
120
121 typedef struct _drm_bacon_bufmgr {
122 int refcount;
123
124 int fd;
125
126 int max_relocs;
127
128 pthread_mutex_t lock;
129
130 struct drm_i915_gem_exec_object2 *exec2_objects;
131 drm_bacon_bo **exec_bos;
132 int exec_size;
133 int exec_count;
134
135 /** Array of lists of cached gem objects of power-of-two sizes */
136 struct drm_bacon_gem_bo_bucket cache_bucket[14 * 4];
137 int num_buckets;
138 time_t time;
139
140 struct list_head managers;
141
142 struct hash_table *name_table;
143 struct hash_table *handle_table;
144
145 struct list_head vma_cache;
146 int vma_count, vma_open, vma_max;
147
148 uint64_t gtt_size;
149 unsigned int has_llc : 1;
150 unsigned int bo_reuse : 1;
151 unsigned int no_exec : 1;
152 } drm_bacon_bufmgr;
153
154 struct _drm_bacon_bo_gem {
155 drm_bacon_bo bo;
156
157 int refcount;
158 uint32_t gem_handle;
159 const char *name;
160
161 /**
162 * Kenel-assigned global name for this object
163 *
164 * List contains both flink named and prime fd'd objects
165 */
166 unsigned int global_name;
167
168 /**
169 * Index of the buffer within the validation list while preparing a
170 * batchbuffer execution.
171 */
172 int validate_index;
173
174 /**
175 * Current tiling mode
176 */
177 uint32_t tiling_mode;
178 uint32_t swizzle_mode;
179 unsigned long stride;
180
181 time_t free_time;
182
183 /** Array passed to the DRM containing relocation information. */
184 struct drm_i915_gem_relocation_entry *relocs;
185 /**
186 * Array of info structs corresponding to relocs[i].target_handle etc
187 */
188 drm_bacon_bo **reloc_bos;
189 /** Number of entries in relocs */
190 int reloc_count;
191 /** Mapped address for the buffer, saved across map/unmap cycles */
192 void *mem_virtual;
193 /** GTT virtual address for the buffer, saved across map/unmap cycles */
194 void *gtt_virtual;
195 /** WC CPU address for the buffer, saved across map/unmap cycles */
196 void *wc_virtual;
197 int map_count;
198 struct list_head vma_list;
199
200 /** BO cache list */
201 struct list_head head;
202
203 /**
204 * Boolean of whether this BO and its children have been included in
205 * the current drm_bacon_bufmgr_check_aperture_space() total.
206 */
207 bool included_in_check_aperture;
208
209 /**
210 * Boolean of whether this buffer has been used as a relocation
211 * target and had its size accounted for, and thus can't have any
212 * further relocations added to it.
213 */
214 bool used_as_reloc_target;
215
216 /**
217 * Boolean of whether we have encountered an error whilst building the relocation tree.
218 */
219 bool has_error;
220
221 /**
222 * Boolean of whether this buffer can be re-used
223 */
224 bool reusable;
225
226 /**
227 * Boolean of whether the GPU is definitely not accessing the buffer.
228 *
229 * This is only valid when reusable, since non-reusable
230 * buffers are those that have been shared with other
231 * processes, so we don't know their state.
232 */
233 bool idle;
234
235 /**
236 * Size in bytes of this buffer and its relocation descendents.
237 *
238 * Used to avoid costly tree walking in
239 * drm_bacon_bufmgr_check_aperture in the common case.
240 */
241 int reloc_tree_size;
242
243 /** Flags that we may need to do the SW_FINISH ioctl on unmap. */
244 bool mapped_cpu_write;
245 };
246
247 static unsigned int
248 drm_bacon_gem_estimate_batch_space(drm_bacon_bo ** bo_array, int count);
249
250 static unsigned int
251 drm_bacon_gem_compute_batch_space(drm_bacon_bo ** bo_array, int count);
252
253 static int
254 drm_bacon_gem_bo_set_tiling_internal(drm_bacon_bo *bo,
255 uint32_t tiling_mode,
256 uint32_t stride);
257
258 static void drm_bacon_gem_bo_unreference_locked_timed(drm_bacon_bo *bo,
259 time_t time);
260
261 static void drm_bacon_gem_bo_free(drm_bacon_bo *bo);
262
263 static inline drm_bacon_bo_gem *to_bo_gem(drm_bacon_bo *bo)
264 {
265 return (drm_bacon_bo_gem *)bo;
266 }
267
268 static uint32_t
269 key_hash_uint(const void *key)
270 {
271 return _mesa_hash_data(key, 4);
272 }
273
274 static bool
275 key_uint_equal(const void *a, const void *b)
276 {
277 return *((unsigned *) a) == *((unsigned *) b);
278 }
279
280 static drm_bacon_bo_gem *
281 hash_find_bo(struct hash_table *ht, unsigned int key)
282 {
283 struct hash_entry *entry = _mesa_hash_table_search(ht, &key);
284 return entry ? (drm_bacon_bo_gem *) entry->data : NULL;
285 }
286
287 static unsigned long
288 drm_bacon_gem_bo_tile_size(drm_bacon_bufmgr *bufmgr, unsigned long size,
289 uint32_t *tiling_mode)
290 {
291 if (*tiling_mode == I915_TILING_NONE)
292 return size;
293
294 /* 965+ just need multiples of page size for tiling */
295 return ALIGN(size, 4096);
296 }
297
298 /*
299 * Round a given pitch up to the minimum required for X tiling on a
300 * given chip. We use 512 as the minimum to allow for a later tiling
301 * change.
302 */
303 static unsigned long
304 drm_bacon_gem_bo_tile_pitch(drm_bacon_bufmgr *bufmgr,
305 unsigned long pitch, uint32_t *tiling_mode)
306 {
307 unsigned long tile_width;
308
309 /* If untiled, then just align it so that we can do rendering
310 * to it with the 3D engine.
311 */
312 if (*tiling_mode == I915_TILING_NONE)
313 return ALIGN(pitch, 64);
314
315 if (*tiling_mode == I915_TILING_X)
316 tile_width = 512;
317 else
318 tile_width = 128;
319
320 /* 965 is flexible */
321 return ALIGN(pitch, tile_width);
322 }
323
324 static struct drm_bacon_gem_bo_bucket *
325 drm_bacon_gem_bo_bucket_for_size(drm_bacon_bufmgr *bufmgr,
326 unsigned long size)
327 {
328 int i;
329
330 for (i = 0; i < bufmgr->num_buckets; i++) {
331 struct drm_bacon_gem_bo_bucket *bucket =
332 &bufmgr->cache_bucket[i];
333 if (bucket->size >= size) {
334 return bucket;
335 }
336 }
337
338 return NULL;
339 }
340
341 static void
342 drm_bacon_gem_dump_validation_list(drm_bacon_bufmgr *bufmgr)
343 {
344 int i, j;
345
346 for (i = 0; i < bufmgr->exec_count; i++) {
347 drm_bacon_bo *bo = bufmgr->exec_bos[i];
348 drm_bacon_bo_gem *bo_gem = (drm_bacon_bo_gem *) bo;
349
350 if (bo_gem->relocs == NULL) {
351 DBG("%2d: %d (%s)\n", i, bo_gem->gem_handle,
352 bo_gem->name);
353 continue;
354 }
355
356 for (j = 0; j < bo_gem->reloc_count; j++) {
357 drm_bacon_bo *target_bo = bo_gem->reloc_bos[j];
358 drm_bacon_bo_gem *target_gem =
359 (drm_bacon_bo_gem *) target_bo;
360
361 DBG("%2d: %d (%s)@0x%08x %08x -> "
362 "%d (%s)@0x%08x %08x + 0x%08x\n",
363 i,
364 bo_gem->gem_handle,
365 bo_gem->name,
366 upper_32_bits(bo_gem->relocs[j].offset),
367 lower_32_bits(bo_gem->relocs[j].offset),
368 target_gem->gem_handle,
369 target_gem->name,
370 upper_32_bits(target_bo->offset64),
371 lower_32_bits(target_bo->offset64),
372 bo_gem->relocs[j].delta);
373 }
374 }
375 }
376
377 inline void
378 drm_bacon_bo_reference(drm_bacon_bo *bo)
379 {
380 drm_bacon_bo_gem *bo_gem = (drm_bacon_bo_gem *) bo;
381
382 p_atomic_inc(&bo_gem->refcount);
383 }
384
385 static void
386 drm_bacon_add_validate_buffer2(drm_bacon_bo *bo)
387 {
388 drm_bacon_bufmgr *bufmgr = bo->bufmgr;
389 drm_bacon_bo_gem *bo_gem = (drm_bacon_bo_gem *)bo;
390 int index;
391
392 if (bo_gem->validate_index != -1)
393 return;
394
395 /* Extend the array of validation entries as necessary. */
396 if (bufmgr->exec_count == bufmgr->exec_size) {
397 int new_size = bufmgr->exec_size * 2;
398
399 if (new_size == 0)
400 new_size = 5;
401
402 bufmgr->exec2_objects =
403 realloc(bufmgr->exec2_objects,
404 sizeof(*bufmgr->exec2_objects) * new_size);
405 bufmgr->exec_bos =
406 realloc(bufmgr->exec_bos,
407 sizeof(*bufmgr->exec_bos) * new_size);
408 bufmgr->exec_size = new_size;
409 }
410
411 index = bufmgr->exec_count;
412 bo_gem->validate_index = index;
413 /* Fill in array entry */
414 bufmgr->exec2_objects[index].handle = bo_gem->gem_handle;
415 bufmgr->exec2_objects[index].relocation_count = bo_gem->reloc_count;
416 bufmgr->exec2_objects[index].relocs_ptr = (uintptr_t)bo_gem->relocs;
417 bufmgr->exec2_objects[index].alignment = bo->align;
418 bufmgr->exec2_objects[index].offset = bo->offset64;
419 bufmgr->exec2_objects[index].flags = 0;
420 bufmgr->exec2_objects[index].rsvd1 = 0;
421 bufmgr->exec2_objects[index].rsvd2 = 0;
422 bufmgr->exec_bos[index] = bo;
423 bufmgr->exec_count++;
424 }
425
426 static void
427 drm_bacon_bo_gem_set_in_aperture_size(drm_bacon_bufmgr *bufmgr,
428 drm_bacon_bo_gem *bo_gem,
429 unsigned int alignment)
430 {
431 unsigned int size;
432
433 assert(!bo_gem->used_as_reloc_target);
434
435 /* The older chipsets are far-less flexible in terms of tiling,
436 * and require tiled buffer to be size aligned in the aperture.
437 * This means that in the worst possible case we will need a hole
438 * twice as large as the object in order for it to fit into the
439 * aperture. Optimal packing is for wimps.
440 */
441 size = bo_gem->bo.size;
442
443 bo_gem->reloc_tree_size = size + alignment;
444 }
445
446 static int
447 drm_bacon_setup_reloc_list(drm_bacon_bo *bo)
448 {
449 drm_bacon_bo_gem *bo_gem = (drm_bacon_bo_gem *) bo;
450 drm_bacon_bufmgr *bufmgr = bo->bufmgr;
451 unsigned int max_relocs = bufmgr->max_relocs;
452
453 if (bo->size / 4 < max_relocs)
454 max_relocs = bo->size / 4;
455
456 bo_gem->relocs = malloc(max_relocs *
457 sizeof(struct drm_i915_gem_relocation_entry));
458 bo_gem->reloc_bos = malloc(max_relocs * sizeof(drm_bacon_bo *));
459 if (bo_gem->relocs == NULL || bo_gem->reloc_bos == NULL) {
460 bo_gem->has_error = true;
461
462 free (bo_gem->relocs);
463 bo_gem->relocs = NULL;
464
465 free (bo_gem->reloc_bos);
466 bo_gem->reloc_bos = NULL;
467
468 return 1;
469 }
470
471 return 0;
472 }
473
474 int
475 drm_bacon_bo_busy(drm_bacon_bo *bo)
476 {
477 drm_bacon_bufmgr *bufmgr = bo->bufmgr;
478 drm_bacon_bo_gem *bo_gem = (drm_bacon_bo_gem *) bo;
479 struct drm_i915_gem_busy busy;
480 int ret;
481
482 if (bo_gem->reusable && bo_gem->idle)
483 return false;
484
485 memclear(busy);
486 busy.handle = bo_gem->gem_handle;
487
488 ret = drmIoctl(bufmgr->fd, DRM_IOCTL_I915_GEM_BUSY, &busy);
489 if (ret == 0) {
490 bo_gem->idle = !busy.busy;
491 return busy.busy;
492 } else {
493 return false;
494 }
495 return (ret == 0 && busy.busy);
496 }
497
498 static int
499 drm_bacon_gem_bo_madvise_internal(drm_bacon_bufmgr *bufmgr,
500 drm_bacon_bo_gem *bo_gem, int state)
501 {
502 struct drm_i915_gem_madvise madv;
503
504 memclear(madv);
505 madv.handle = bo_gem->gem_handle;
506 madv.madv = state;
507 madv.retained = 1;
508 drmIoctl(bufmgr->fd, DRM_IOCTL_I915_GEM_MADVISE, &madv);
509
510 return madv.retained;
511 }
512
513 int
514 drm_bacon_bo_madvise(drm_bacon_bo *bo, int madv)
515 {
516 return drm_bacon_gem_bo_madvise_internal(bo->bufmgr,
517 (drm_bacon_bo_gem *) bo,
518 madv);
519 }
520
521 /* drop the oldest entries that have been purged by the kernel */
522 static void
523 drm_bacon_gem_bo_cache_purge_bucket(drm_bacon_bufmgr *bufmgr,
524 struct drm_bacon_gem_bo_bucket *bucket)
525 {
526 while (!list_empty(&bucket->head)) {
527 drm_bacon_bo_gem *bo_gem;
528
529 bo_gem = LIST_ENTRY(drm_bacon_bo_gem,
530 bucket->head.next, head);
531 if (drm_bacon_gem_bo_madvise_internal
532 (bufmgr, bo_gem, I915_MADV_DONTNEED))
533 break;
534
535 list_del(&bo_gem->head);
536 drm_bacon_gem_bo_free(&bo_gem->bo);
537 }
538 }
539
540 static drm_bacon_bo *
541 drm_bacon_gem_bo_alloc_internal(drm_bacon_bufmgr *bufmgr,
542 const char *name,
543 unsigned long size,
544 unsigned long flags,
545 uint32_t tiling_mode,
546 unsigned long stride,
547 unsigned int alignment)
548 {
549 drm_bacon_bo_gem *bo_gem;
550 unsigned int page_size = getpagesize();
551 int ret;
552 struct drm_bacon_gem_bo_bucket *bucket;
553 bool alloc_from_cache;
554 unsigned long bo_size;
555 bool for_render = false;
556
557 if (flags & BO_ALLOC_FOR_RENDER)
558 for_render = true;
559
560 /* Round the allocated size up to a power of two number of pages. */
561 bucket = drm_bacon_gem_bo_bucket_for_size(bufmgr, size);
562
563 /* If we don't have caching at this size, don't actually round the
564 * allocation up.
565 */
566 if (bucket == NULL) {
567 bo_size = size;
568 if (bo_size < page_size)
569 bo_size = page_size;
570 } else {
571 bo_size = bucket->size;
572 }
573
574 pthread_mutex_lock(&bufmgr->lock);
575 /* Get a buffer out of the cache if available */
576 retry:
577 alloc_from_cache = false;
578 if (bucket != NULL && !list_empty(&bucket->head)) {
579 if (for_render) {
580 /* Allocate new render-target BOs from the tail (MRU)
581 * of the list, as it will likely be hot in the GPU
582 * cache and in the aperture for us.
583 */
584 bo_gem = LIST_ENTRY(drm_bacon_bo_gem,
585 bucket->head.prev, head);
586 list_del(&bo_gem->head);
587 alloc_from_cache = true;
588 bo_gem->bo.align = alignment;
589 } else {
590 assert(alignment == 0);
591 /* For non-render-target BOs (where we're probably
592 * going to map it first thing in order to fill it
593 * with data), check if the last BO in the cache is
594 * unbusy, and only reuse in that case. Otherwise,
595 * allocating a new buffer is probably faster than
596 * waiting for the GPU to finish.
597 */
598 bo_gem = LIST_ENTRY(drm_bacon_bo_gem,
599 bucket->head.next, head);
600 if (!drm_bacon_bo_busy(&bo_gem->bo)) {
601 alloc_from_cache = true;
602 list_del(&bo_gem->head);
603 }
604 }
605
606 if (alloc_from_cache) {
607 if (!drm_bacon_gem_bo_madvise_internal
608 (bufmgr, bo_gem, I915_MADV_WILLNEED)) {
609 drm_bacon_gem_bo_free(&bo_gem->bo);
610 drm_bacon_gem_bo_cache_purge_bucket(bufmgr,
611 bucket);
612 goto retry;
613 }
614
615 if (drm_bacon_gem_bo_set_tiling_internal(&bo_gem->bo,
616 tiling_mode,
617 stride)) {
618 drm_bacon_gem_bo_free(&bo_gem->bo);
619 goto retry;
620 }
621 }
622 }
623
624 if (!alloc_from_cache) {
625 struct drm_i915_gem_create create;
626
627 bo_gem = calloc(1, sizeof(*bo_gem));
628 if (!bo_gem)
629 goto err;
630
631 /* drm_bacon_gem_bo_free calls list_del() for an uninitialized
632 list (vma_list), so better set the list head here */
633 list_inithead(&bo_gem->vma_list);
634
635 bo_gem->bo.size = bo_size;
636
637 memclear(create);
638 create.size = bo_size;
639
640 ret = drmIoctl(bufmgr->fd,
641 DRM_IOCTL_I915_GEM_CREATE,
642 &create);
643 if (ret != 0) {
644 free(bo_gem);
645 goto err;
646 }
647
648 bo_gem->gem_handle = create.handle;
649 _mesa_hash_table_insert(bufmgr->handle_table,
650 &bo_gem->gem_handle, bo_gem);
651
652 bo_gem->bo.handle = bo_gem->gem_handle;
653 bo_gem->bo.bufmgr = bufmgr;
654 bo_gem->bo.align = alignment;
655
656 bo_gem->tiling_mode = I915_TILING_NONE;
657 bo_gem->swizzle_mode = I915_BIT_6_SWIZZLE_NONE;
658 bo_gem->stride = 0;
659
660 if (drm_bacon_gem_bo_set_tiling_internal(&bo_gem->bo,
661 tiling_mode,
662 stride))
663 goto err_free;
664 }
665
666 bo_gem->name = name;
667 p_atomic_set(&bo_gem->refcount, 1);
668 bo_gem->validate_index = -1;
669 bo_gem->used_as_reloc_target = false;
670 bo_gem->has_error = false;
671 bo_gem->reusable = true;
672
673 drm_bacon_bo_gem_set_in_aperture_size(bufmgr, bo_gem, alignment);
674 pthread_mutex_unlock(&bufmgr->lock);
675
676 DBG("bo_create: buf %d (%s) %ldb\n",
677 bo_gem->gem_handle, bo_gem->name, size);
678
679 return &bo_gem->bo;
680
681 err_free:
682 drm_bacon_gem_bo_free(&bo_gem->bo);
683 err:
684 pthread_mutex_unlock(&bufmgr->lock);
685 return NULL;
686 }
687
688 drm_bacon_bo *
689 drm_bacon_bo_alloc_for_render(drm_bacon_bufmgr *bufmgr,
690 const char *name,
691 unsigned long size,
692 unsigned int alignment)
693 {
694 return drm_bacon_gem_bo_alloc_internal(bufmgr, name, size,
695 BO_ALLOC_FOR_RENDER,
696 I915_TILING_NONE, 0,
697 alignment);
698 }
699
700 drm_bacon_bo *
701 drm_bacon_bo_alloc(drm_bacon_bufmgr *bufmgr,
702 const char *name,
703 unsigned long size,
704 unsigned int alignment)
705 {
706 return drm_bacon_gem_bo_alloc_internal(bufmgr, name, size, 0,
707 I915_TILING_NONE, 0, 0);
708 }
709
710 drm_bacon_bo *
711 drm_bacon_bo_alloc_tiled(drm_bacon_bufmgr *bufmgr, const char *name,
712 int x, int y, int cpp, uint32_t *tiling_mode,
713 unsigned long *pitch, unsigned long flags)
714 {
715 unsigned long size, stride;
716 uint32_t tiling;
717
718 do {
719 unsigned long aligned_y, height_alignment;
720
721 tiling = *tiling_mode;
722
723 /* If we're tiled, our allocations are in 8 or 32-row blocks,
724 * so failure to align our height means that we won't allocate
725 * enough pages.
726 *
727 * If we're untiled, we still have to align to 2 rows high
728 * because the data port accesses 2x2 blocks even if the
729 * bottom row isn't to be rendered, so failure to align means
730 * we could walk off the end of the GTT and fault. This is
731 * documented on 965, and may be the case on older chipsets
732 * too so we try to be careful.
733 */
734 aligned_y = y;
735 height_alignment = 2;
736
737 if (tiling == I915_TILING_X)
738 height_alignment = 8;
739 else if (tiling == I915_TILING_Y)
740 height_alignment = 32;
741 aligned_y = ALIGN(y, height_alignment);
742
743 stride = x * cpp;
744 stride = drm_bacon_gem_bo_tile_pitch(bufmgr, stride, tiling_mode);
745 size = stride * aligned_y;
746 size = drm_bacon_gem_bo_tile_size(bufmgr, size, tiling_mode);
747 } while (*tiling_mode != tiling);
748 *pitch = stride;
749
750 if (tiling == I915_TILING_NONE)
751 stride = 0;
752
753 return drm_bacon_gem_bo_alloc_internal(bufmgr, name, size, flags,
754 tiling, stride, 0);
755 }
756
757 /**
758 * Returns a drm_bacon_bo wrapping the given buffer object handle.
759 *
760 * This can be used when one application needs to pass a buffer object
761 * to another.
762 */
763 drm_bacon_bo *
764 drm_bacon_bo_gem_create_from_name(drm_bacon_bufmgr *bufmgr,
765 const char *name,
766 unsigned int handle)
767 {
768 drm_bacon_bo_gem *bo_gem;
769 int ret;
770 struct drm_gem_open open_arg;
771 struct drm_i915_gem_get_tiling get_tiling;
772
773 /* At the moment most applications only have a few named bo.
774 * For instance, in a DRI client only the render buffers passed
775 * between X and the client are named. And since X returns the
776 * alternating names for the front/back buffer a linear search
777 * provides a sufficiently fast match.
778 */
779 pthread_mutex_lock(&bufmgr->lock);
780 bo_gem = hash_find_bo(bufmgr->name_table, handle);
781 if (bo_gem) {
782 drm_bacon_bo_reference(&bo_gem->bo);
783 goto out;
784 }
785
786 memclear(open_arg);
787 open_arg.name = handle;
788 ret = drmIoctl(bufmgr->fd,
789 DRM_IOCTL_GEM_OPEN,
790 &open_arg);
791 if (ret != 0) {
792 DBG("Couldn't reference %s handle 0x%08x: %s\n",
793 name, handle, strerror(errno));
794 bo_gem = NULL;
795 goto out;
796 }
797 /* Now see if someone has used a prime handle to get this
798 * object from the kernel before by looking through the list
799 * again for a matching gem_handle
800 */
801 bo_gem = hash_find_bo(bufmgr->handle_table, open_arg.handle);
802 if (bo_gem) {
803 drm_bacon_bo_reference(&bo_gem->bo);
804 goto out;
805 }
806
807 bo_gem = calloc(1, sizeof(*bo_gem));
808 if (!bo_gem)
809 goto out;
810
811 p_atomic_set(&bo_gem->refcount, 1);
812 list_inithead(&bo_gem->vma_list);
813
814 bo_gem->bo.size = open_arg.size;
815 bo_gem->bo.offset64 = 0;
816 bo_gem->bo.virtual = NULL;
817 bo_gem->bo.bufmgr = bufmgr;
818 bo_gem->name = name;
819 bo_gem->validate_index = -1;
820 bo_gem->gem_handle = open_arg.handle;
821 bo_gem->bo.handle = open_arg.handle;
822 bo_gem->global_name = handle;
823 bo_gem->reusable = false;
824
825 _mesa_hash_table_insert(bufmgr->handle_table,
826 &bo_gem->gem_handle, bo_gem);
827 _mesa_hash_table_insert(bufmgr->name_table,
828 &bo_gem->global_name, bo_gem);
829
830 memclear(get_tiling);
831 get_tiling.handle = bo_gem->gem_handle;
832 ret = drmIoctl(bufmgr->fd,
833 DRM_IOCTL_I915_GEM_GET_TILING,
834 &get_tiling);
835 if (ret != 0)
836 goto err_unref;
837
838 bo_gem->tiling_mode = get_tiling.tiling_mode;
839 bo_gem->swizzle_mode = get_tiling.swizzle_mode;
840 /* XXX stride is unknown */
841 drm_bacon_bo_gem_set_in_aperture_size(bufmgr, bo_gem, 0);
842 DBG("bo_create_from_handle: %d (%s)\n", handle, bo_gem->name);
843
844 out:
845 pthread_mutex_unlock(&bufmgr->lock);
846 return &bo_gem->bo;
847
848 err_unref:
849 drm_bacon_gem_bo_free(&bo_gem->bo);
850 pthread_mutex_unlock(&bufmgr->lock);
851 return NULL;
852 }
853
854 static void
855 drm_bacon_gem_bo_free(drm_bacon_bo *bo)
856 {
857 drm_bacon_bufmgr *bufmgr = bo->bufmgr;
858 drm_bacon_bo_gem *bo_gem = (drm_bacon_bo_gem *) bo;
859 struct drm_gem_close close;
860 struct hash_entry *entry;
861 int ret;
862
863 list_del(&bo_gem->vma_list);
864 if (bo_gem->mem_virtual) {
865 VG(VALGRIND_FREELIKE_BLOCK(bo_gem->mem_virtual, 0));
866 drm_munmap(bo_gem->mem_virtual, bo_gem->bo.size);
867 bufmgr->vma_count--;
868 }
869 if (bo_gem->wc_virtual) {
870 VG(VALGRIND_FREELIKE_BLOCK(bo_gem->wc_virtual, 0));
871 drm_munmap(bo_gem->wc_virtual, bo_gem->bo.size);
872 bufmgr->vma_count--;
873 }
874 if (bo_gem->gtt_virtual) {
875 drm_munmap(bo_gem->gtt_virtual, bo_gem->bo.size);
876 bufmgr->vma_count--;
877 }
878
879 if (bo_gem->global_name) {
880 entry = _mesa_hash_table_search(bufmgr->name_table,
881 &bo_gem->global_name);
882 _mesa_hash_table_remove(bufmgr->name_table, entry);
883 }
884 entry = _mesa_hash_table_search(bufmgr->handle_table,
885 &bo_gem->gem_handle);
886 _mesa_hash_table_remove(bufmgr->handle_table, entry);
887
888 /* Close this object */
889 memclear(close);
890 close.handle = bo_gem->gem_handle;
891 ret = drmIoctl(bufmgr->fd, DRM_IOCTL_GEM_CLOSE, &close);
892 if (ret != 0) {
893 DBG("DRM_IOCTL_GEM_CLOSE %d failed (%s): %s\n",
894 bo_gem->gem_handle, bo_gem->name, strerror(errno));
895 }
896 free(bo);
897 }
898
899 static void
900 drm_bacon_gem_bo_mark_mmaps_incoherent(drm_bacon_bo *bo)
901 {
902 #if HAVE_VALGRIND
903 drm_bacon_bo_gem *bo_gem = (drm_bacon_bo_gem *) bo;
904
905 if (bo_gem->mem_virtual)
906 VALGRIND_MAKE_MEM_NOACCESS(bo_gem->mem_virtual, bo->size);
907
908 if (bo_gem->wc_virtual)
909 VALGRIND_MAKE_MEM_NOACCESS(bo_gem->wc_virtual, bo->size);
910
911 if (bo_gem->gtt_virtual)
912 VALGRIND_MAKE_MEM_NOACCESS(bo_gem->gtt_virtual, bo->size);
913 #endif
914 }
915
916 /** Frees all cached buffers significantly older than @time. */
917 static void
918 drm_bacon_gem_cleanup_bo_cache(drm_bacon_bufmgr *bufmgr, time_t time)
919 {
920 int i;
921
922 if (bufmgr->time == time)
923 return;
924
925 for (i = 0; i < bufmgr->num_buckets; i++) {
926 struct drm_bacon_gem_bo_bucket *bucket =
927 &bufmgr->cache_bucket[i];
928
929 while (!list_empty(&bucket->head)) {
930 drm_bacon_bo_gem *bo_gem;
931
932 bo_gem = LIST_ENTRY(drm_bacon_bo_gem,
933 bucket->head.next, head);
934 if (time - bo_gem->free_time <= 1)
935 break;
936
937 list_del(&bo_gem->head);
938
939 drm_bacon_gem_bo_free(&bo_gem->bo);
940 }
941 }
942
943 bufmgr->time = time;
944 }
945
946 static void drm_bacon_gem_bo_purge_vma_cache(drm_bacon_bufmgr *bufmgr)
947 {
948 int limit;
949
950 DBG("%s: cached=%d, open=%d, limit=%d\n", __FUNCTION__,
951 bufmgr->vma_count, bufmgr->vma_open, bufmgr->vma_max);
952
953 if (bufmgr->vma_max < 0)
954 return;
955
956 /* We may need to evict a few entries in order to create new mmaps */
957 limit = bufmgr->vma_max - 2*bufmgr->vma_open;
958 if (limit < 0)
959 limit = 0;
960
961 while (bufmgr->vma_count > limit) {
962 drm_bacon_bo_gem *bo_gem;
963
964 bo_gem = LIST_ENTRY(drm_bacon_bo_gem,
965 bufmgr->vma_cache.next,
966 vma_list);
967 assert(bo_gem->map_count == 0);
968 list_delinit(&bo_gem->vma_list);
969
970 if (bo_gem->mem_virtual) {
971 drm_munmap(bo_gem->mem_virtual, bo_gem->bo.size);
972 bo_gem->mem_virtual = NULL;
973 bufmgr->vma_count--;
974 }
975 if (bo_gem->wc_virtual) {
976 drm_munmap(bo_gem->wc_virtual, bo_gem->bo.size);
977 bo_gem->wc_virtual = NULL;
978 bufmgr->vma_count--;
979 }
980 if (bo_gem->gtt_virtual) {
981 drm_munmap(bo_gem->gtt_virtual, bo_gem->bo.size);
982 bo_gem->gtt_virtual = NULL;
983 bufmgr->vma_count--;
984 }
985 }
986 }
987
988 static void drm_bacon_gem_bo_close_vma(drm_bacon_bufmgr *bufmgr,
989 drm_bacon_bo_gem *bo_gem)
990 {
991 bufmgr->vma_open--;
992 list_addtail(&bo_gem->vma_list, &bufmgr->vma_cache);
993 if (bo_gem->mem_virtual)
994 bufmgr->vma_count++;
995 if (bo_gem->wc_virtual)
996 bufmgr->vma_count++;
997 if (bo_gem->gtt_virtual)
998 bufmgr->vma_count++;
999 drm_bacon_gem_bo_purge_vma_cache(bufmgr);
1000 }
1001
1002 static void drm_bacon_gem_bo_open_vma(drm_bacon_bufmgr *bufmgr,
1003 drm_bacon_bo_gem *bo_gem)
1004 {
1005 bufmgr->vma_open++;
1006 list_del(&bo_gem->vma_list);
1007 if (bo_gem->mem_virtual)
1008 bufmgr->vma_count--;
1009 if (bo_gem->wc_virtual)
1010 bufmgr->vma_count--;
1011 if (bo_gem->gtt_virtual)
1012 bufmgr->vma_count--;
1013 drm_bacon_gem_bo_purge_vma_cache(bufmgr);
1014 }
1015
1016 static void
1017 drm_bacon_gem_bo_unreference_final(drm_bacon_bo *bo, time_t time)
1018 {
1019 drm_bacon_bufmgr *bufmgr = bo->bufmgr;
1020 drm_bacon_bo_gem *bo_gem = (drm_bacon_bo_gem *) bo;
1021 struct drm_bacon_gem_bo_bucket *bucket;
1022 int i;
1023
1024 /* Unreference all the target buffers */
1025 for (i = 0; i < bo_gem->reloc_count; i++) {
1026 if (bo_gem->reloc_bos[i] != bo) {
1027 drm_bacon_gem_bo_unreference_locked_timed(bo_gem->
1028 reloc_bos[i],
1029 time);
1030 }
1031 }
1032 bo_gem->reloc_count = 0;
1033 bo_gem->used_as_reloc_target = false;
1034
1035 DBG("bo_unreference final: %d (%s)\n",
1036 bo_gem->gem_handle, bo_gem->name);
1037
1038 /* release memory associated with this object */
1039 if (bo_gem->reloc_bos) {
1040 free(bo_gem->reloc_bos);
1041 bo_gem->reloc_bos = NULL;
1042 }
1043 if (bo_gem->relocs) {
1044 free(bo_gem->relocs);
1045 bo_gem->relocs = NULL;
1046 }
1047
1048 /* Clear any left-over mappings */
1049 if (bo_gem->map_count) {
1050 DBG("bo freed with non-zero map-count %d\n", bo_gem->map_count);
1051 bo_gem->map_count = 0;
1052 drm_bacon_gem_bo_close_vma(bufmgr, bo_gem);
1053 drm_bacon_gem_bo_mark_mmaps_incoherent(bo);
1054 }
1055
1056 bucket = drm_bacon_gem_bo_bucket_for_size(bufmgr, bo->size);
1057 /* Put the buffer into our internal cache for reuse if we can. */
1058 if (bufmgr->bo_reuse && bo_gem->reusable && bucket != NULL &&
1059 drm_bacon_gem_bo_madvise_internal(bufmgr, bo_gem,
1060 I915_MADV_DONTNEED)) {
1061 bo_gem->free_time = time;
1062
1063 bo_gem->name = NULL;
1064 bo_gem->validate_index = -1;
1065
1066 list_addtail(&bo_gem->head, &bucket->head);
1067 } else {
1068 drm_bacon_gem_bo_free(bo);
1069 }
1070 }
1071
1072 static void drm_bacon_gem_bo_unreference_locked_timed(drm_bacon_bo *bo,
1073 time_t time)
1074 {
1075 drm_bacon_bo_gem *bo_gem = (drm_bacon_bo_gem *) bo;
1076
1077 assert(p_atomic_read(&bo_gem->refcount) > 0);
1078 if (p_atomic_dec_zero(&bo_gem->refcount))
1079 drm_bacon_gem_bo_unreference_final(bo, time);
1080 }
1081
1082 void
1083 drm_bacon_bo_unreference(drm_bacon_bo *bo)
1084 {
1085 drm_bacon_bo_gem *bo_gem = (drm_bacon_bo_gem *) bo;
1086
1087 if (bo == NULL)
1088 return;
1089
1090 assert(p_atomic_read(&bo_gem->refcount) > 0);
1091
1092 if (atomic_add_unless(&bo_gem->refcount, -1, 1)) {
1093 drm_bacon_bufmgr *bufmgr = bo->bufmgr;
1094 struct timespec time;
1095
1096 clock_gettime(CLOCK_MONOTONIC, &time);
1097
1098 pthread_mutex_lock(&bufmgr->lock);
1099
1100 if (p_atomic_dec_zero(&bo_gem->refcount)) {
1101 drm_bacon_gem_bo_unreference_final(bo, time.tv_sec);
1102 drm_bacon_gem_cleanup_bo_cache(bufmgr, time.tv_sec);
1103 }
1104
1105 pthread_mutex_unlock(&bufmgr->lock);
1106 }
1107 }
1108
1109 int
1110 drm_bacon_bo_map(drm_bacon_bo *bo, int write_enable)
1111 {
1112 drm_bacon_bufmgr *bufmgr = bo->bufmgr;
1113 drm_bacon_bo_gem *bo_gem = (drm_bacon_bo_gem *) bo;
1114 struct drm_i915_gem_set_domain set_domain;
1115 int ret;
1116
1117 pthread_mutex_lock(&bufmgr->lock);
1118
1119 if (bo_gem->map_count++ == 0)
1120 drm_bacon_gem_bo_open_vma(bufmgr, bo_gem);
1121
1122 if (!bo_gem->mem_virtual) {
1123 struct drm_i915_gem_mmap mmap_arg;
1124
1125 DBG("bo_map: %d (%s), map_count=%d\n",
1126 bo_gem->gem_handle, bo_gem->name, bo_gem->map_count);
1127
1128 memclear(mmap_arg);
1129 mmap_arg.handle = bo_gem->gem_handle;
1130 mmap_arg.size = bo->size;
1131 ret = drmIoctl(bufmgr->fd,
1132 DRM_IOCTL_I915_GEM_MMAP,
1133 &mmap_arg);
1134 if (ret != 0) {
1135 ret = -errno;
1136 DBG("%s:%d: Error mapping buffer %d (%s): %s .\n",
1137 __FILE__, __LINE__, bo_gem->gem_handle,
1138 bo_gem->name, strerror(errno));
1139 if (--bo_gem->map_count == 0)
1140 drm_bacon_gem_bo_close_vma(bufmgr, bo_gem);
1141 pthread_mutex_unlock(&bufmgr->lock);
1142 return ret;
1143 }
1144 VG(VALGRIND_MALLOCLIKE_BLOCK(mmap_arg.addr_ptr, mmap_arg.size, 0, 1));
1145 bo_gem->mem_virtual = (void *)(uintptr_t) mmap_arg.addr_ptr;
1146 }
1147 DBG("bo_map: %d (%s) -> %p\n", bo_gem->gem_handle, bo_gem->name,
1148 bo_gem->mem_virtual);
1149 bo->virtual = bo_gem->mem_virtual;
1150
1151 memclear(set_domain);
1152 set_domain.handle = bo_gem->gem_handle;
1153 set_domain.read_domains = I915_GEM_DOMAIN_CPU;
1154 if (write_enable)
1155 set_domain.write_domain = I915_GEM_DOMAIN_CPU;
1156 else
1157 set_domain.write_domain = 0;
1158 ret = drmIoctl(bufmgr->fd,
1159 DRM_IOCTL_I915_GEM_SET_DOMAIN,
1160 &set_domain);
1161 if (ret != 0) {
1162 DBG("%s:%d: Error setting to CPU domain %d: %s\n",
1163 __FILE__, __LINE__, bo_gem->gem_handle,
1164 strerror(errno));
1165 }
1166
1167 if (write_enable)
1168 bo_gem->mapped_cpu_write = true;
1169
1170 drm_bacon_gem_bo_mark_mmaps_incoherent(bo);
1171 VG(VALGRIND_MAKE_MEM_DEFINED(bo_gem->mem_virtual, bo->size));
1172 pthread_mutex_unlock(&bufmgr->lock);
1173
1174 return 0;
1175 }
1176
1177 static int
1178 map_gtt(drm_bacon_bo *bo)
1179 {
1180 drm_bacon_bufmgr *bufmgr = bo->bufmgr;
1181 drm_bacon_bo_gem *bo_gem = (drm_bacon_bo_gem *) bo;
1182 int ret;
1183
1184 if (bo_gem->map_count++ == 0)
1185 drm_bacon_gem_bo_open_vma(bufmgr, bo_gem);
1186
1187 /* Get a mapping of the buffer if we haven't before. */
1188 if (bo_gem->gtt_virtual == NULL) {
1189 struct drm_i915_gem_mmap_gtt mmap_arg;
1190
1191 DBG("bo_map_gtt: mmap %d (%s), map_count=%d\n",
1192 bo_gem->gem_handle, bo_gem->name, bo_gem->map_count);
1193
1194 memclear(mmap_arg);
1195 mmap_arg.handle = bo_gem->gem_handle;
1196
1197 /* Get the fake offset back... */
1198 ret = drmIoctl(bufmgr->fd,
1199 DRM_IOCTL_I915_GEM_MMAP_GTT,
1200 &mmap_arg);
1201 if (ret != 0) {
1202 ret = -errno;
1203 DBG("%s:%d: Error preparing buffer map %d (%s): %s .\n",
1204 __FILE__, __LINE__,
1205 bo_gem->gem_handle, bo_gem->name,
1206 strerror(errno));
1207 if (--bo_gem->map_count == 0)
1208 drm_bacon_gem_bo_close_vma(bufmgr, bo_gem);
1209 return ret;
1210 }
1211
1212 /* and mmap it */
1213 bo_gem->gtt_virtual = drm_mmap(0, bo->size, PROT_READ | PROT_WRITE,
1214 MAP_SHARED, bufmgr->fd,
1215 mmap_arg.offset);
1216 if (bo_gem->gtt_virtual == MAP_FAILED) {
1217 bo_gem->gtt_virtual = NULL;
1218 ret = -errno;
1219 DBG("%s:%d: Error mapping buffer %d (%s): %s .\n",
1220 __FILE__, __LINE__,
1221 bo_gem->gem_handle, bo_gem->name,
1222 strerror(errno));
1223 if (--bo_gem->map_count == 0)
1224 drm_bacon_gem_bo_close_vma(bufmgr, bo_gem);
1225 return ret;
1226 }
1227 }
1228
1229 bo->virtual = bo_gem->gtt_virtual;
1230
1231 DBG("bo_map_gtt: %d (%s) -> %p\n", bo_gem->gem_handle, bo_gem->name,
1232 bo_gem->gtt_virtual);
1233
1234 return 0;
1235 }
1236
1237 int
1238 drm_bacon_gem_bo_map_gtt(drm_bacon_bo *bo)
1239 {
1240 drm_bacon_bufmgr *bufmgr = bo->bufmgr;
1241 drm_bacon_bo_gem *bo_gem = (drm_bacon_bo_gem *) bo;
1242 struct drm_i915_gem_set_domain set_domain;
1243 int ret;
1244
1245 pthread_mutex_lock(&bufmgr->lock);
1246
1247 ret = map_gtt(bo);
1248 if (ret) {
1249 pthread_mutex_unlock(&bufmgr->lock);
1250 return ret;
1251 }
1252
1253 /* Now move it to the GTT domain so that the GPU and CPU
1254 * caches are flushed and the GPU isn't actively using the
1255 * buffer.
1256 *
1257 * The pagefault handler does this domain change for us when
1258 * it has unbound the BO from the GTT, but it's up to us to
1259 * tell it when we're about to use things if we had done
1260 * rendering and it still happens to be bound to the GTT.
1261 */
1262 memclear(set_domain);
1263 set_domain.handle = bo_gem->gem_handle;
1264 set_domain.read_domains = I915_GEM_DOMAIN_GTT;
1265 set_domain.write_domain = I915_GEM_DOMAIN_GTT;
1266 ret = drmIoctl(bufmgr->fd,
1267 DRM_IOCTL_I915_GEM_SET_DOMAIN,
1268 &set_domain);
1269 if (ret != 0) {
1270 DBG("%s:%d: Error setting domain %d: %s\n",
1271 __FILE__, __LINE__, bo_gem->gem_handle,
1272 strerror(errno));
1273 }
1274
1275 drm_bacon_gem_bo_mark_mmaps_incoherent(bo);
1276 VG(VALGRIND_MAKE_MEM_DEFINED(bo_gem->gtt_virtual, bo->size));
1277 pthread_mutex_unlock(&bufmgr->lock);
1278
1279 return 0;
1280 }
1281
1282 /**
1283 * Performs a mapping of the buffer object like the normal GTT
1284 * mapping, but avoids waiting for the GPU to be done reading from or
1285 * rendering to the buffer.
1286 *
1287 * This is used in the implementation of GL_ARB_map_buffer_range: The
1288 * user asks to create a buffer, then does a mapping, fills some
1289 * space, runs a drawing command, then asks to map it again without
1290 * synchronizing because it guarantees that it won't write over the
1291 * data that the GPU is busy using (or, more specifically, that if it
1292 * does write over the data, it acknowledges that rendering is
1293 * undefined).
1294 */
1295
1296 int
1297 drm_bacon_gem_bo_map_unsynchronized(drm_bacon_bo *bo)
1298 {
1299 drm_bacon_bufmgr *bufmgr = bo->bufmgr;
1300 #ifdef HAVE_VALGRIND
1301 drm_bacon_bo_gem *bo_gem = (drm_bacon_bo_gem *) bo;
1302 #endif
1303 int ret;
1304
1305 /* If the CPU cache isn't coherent with the GTT, then use a
1306 * regular synchronized mapping. The problem is that we don't
1307 * track where the buffer was last used on the CPU side in
1308 * terms of drm_bacon_bo_map vs drm_bacon_gem_bo_map_gtt, so
1309 * we would potentially corrupt the buffer even when the user
1310 * does reasonable things.
1311 */
1312 if (!bufmgr->has_llc)
1313 return drm_bacon_gem_bo_map_gtt(bo);
1314
1315 pthread_mutex_lock(&bufmgr->lock);
1316
1317 ret = map_gtt(bo);
1318 if (ret == 0) {
1319 drm_bacon_gem_bo_mark_mmaps_incoherent(bo);
1320 VG(VALGRIND_MAKE_MEM_DEFINED(bo_gem->gtt_virtual, bo->size));
1321 }
1322
1323 pthread_mutex_unlock(&bufmgr->lock);
1324
1325 return ret;
1326 }
1327
1328 int
1329 drm_bacon_bo_unmap(drm_bacon_bo *bo)
1330 {
1331 drm_bacon_bufmgr *bufmgr = bo->bufmgr;
1332 drm_bacon_bo_gem *bo_gem = (drm_bacon_bo_gem *) bo;
1333 int ret = 0;
1334
1335 if (bo == NULL)
1336 return 0;
1337
1338 pthread_mutex_lock(&bufmgr->lock);
1339
1340 if (bo_gem->map_count <= 0) {
1341 DBG("attempted to unmap an unmapped bo\n");
1342 pthread_mutex_unlock(&bufmgr->lock);
1343 /* Preserve the old behaviour of just treating this as a
1344 * no-op rather than reporting the error.
1345 */
1346 return 0;
1347 }
1348
1349 if (bo_gem->mapped_cpu_write) {
1350 struct drm_i915_gem_sw_finish sw_finish;
1351
1352 /* Cause a flush to happen if the buffer's pinned for
1353 * scanout, so the results show up in a timely manner.
1354 * Unlike GTT set domains, this only does work if the
1355 * buffer should be scanout-related.
1356 */
1357 memclear(sw_finish);
1358 sw_finish.handle = bo_gem->gem_handle;
1359 ret = drmIoctl(bufmgr->fd,
1360 DRM_IOCTL_I915_GEM_SW_FINISH,
1361 &sw_finish);
1362 ret = ret == -1 ? -errno : 0;
1363
1364 bo_gem->mapped_cpu_write = false;
1365 }
1366
1367 /* We need to unmap after every innovation as we cannot track
1368 * an open vma for every bo as that will exhaust the system
1369 * limits and cause later failures.
1370 */
1371 if (--bo_gem->map_count == 0) {
1372 drm_bacon_gem_bo_close_vma(bufmgr, bo_gem);
1373 drm_bacon_gem_bo_mark_mmaps_incoherent(bo);
1374 bo->virtual = NULL;
1375 }
1376 pthread_mutex_unlock(&bufmgr->lock);
1377
1378 return ret;
1379 }
1380
1381 int
1382 drm_bacon_bo_subdata(drm_bacon_bo *bo, unsigned long offset,
1383 unsigned long size, const void *data)
1384 {
1385 drm_bacon_bufmgr *bufmgr = bo->bufmgr;
1386 drm_bacon_bo_gem *bo_gem = (drm_bacon_bo_gem *) bo;
1387 struct drm_i915_gem_pwrite pwrite;
1388 int ret;
1389
1390 memclear(pwrite);
1391 pwrite.handle = bo_gem->gem_handle;
1392 pwrite.offset = offset;
1393 pwrite.size = size;
1394 pwrite.data_ptr = (uint64_t) (uintptr_t) data;
1395 ret = drmIoctl(bufmgr->fd,
1396 DRM_IOCTL_I915_GEM_PWRITE,
1397 &pwrite);
1398 if (ret != 0) {
1399 ret = -errno;
1400 DBG("%s:%d: Error writing data to buffer %d: (%d %d) %s .\n",
1401 __FILE__, __LINE__, bo_gem->gem_handle, (int)offset,
1402 (int)size, strerror(errno));
1403 }
1404
1405 return ret;
1406 }
1407
1408 int
1409 drm_bacon_bo_get_subdata(drm_bacon_bo *bo, unsigned long offset,
1410 unsigned long size, void *data)
1411 {
1412 drm_bacon_bufmgr *bufmgr = bo->bufmgr;
1413 drm_bacon_bo_gem *bo_gem = (drm_bacon_bo_gem *) bo;
1414 struct drm_i915_gem_pread pread;
1415 int ret;
1416
1417 memclear(pread);
1418 pread.handle = bo_gem->gem_handle;
1419 pread.offset = offset;
1420 pread.size = size;
1421 pread.data_ptr = (uint64_t) (uintptr_t) data;
1422 ret = drmIoctl(bufmgr->fd,
1423 DRM_IOCTL_I915_GEM_PREAD,
1424 &pread);
1425 if (ret != 0) {
1426 ret = -errno;
1427 DBG("%s:%d: Error reading data from buffer %d: (%d %d) %s .\n",
1428 __FILE__, __LINE__, bo_gem->gem_handle, (int)offset,
1429 (int)size, strerror(errno));
1430 }
1431
1432 return ret;
1433 }
1434
1435 /** Waits for all GPU rendering with the object to have completed. */
1436 void
1437 drm_bacon_bo_wait_rendering(drm_bacon_bo *bo)
1438 {
1439 drm_bacon_gem_bo_start_gtt_access(bo, 1);
1440 }
1441
1442 /**
1443 * Waits on a BO for the given amount of time.
1444 *
1445 * @bo: buffer object to wait for
1446 * @timeout_ns: amount of time to wait in nanoseconds.
1447 * If value is less than 0, an infinite wait will occur.
1448 *
1449 * Returns 0 if the wait was successful ie. the last batch referencing the
1450 * object has completed within the allotted time. Otherwise some negative return
1451 * value describes the error. Of particular interest is -ETIME when the wait has
1452 * failed to yield the desired result.
1453 *
1454 * Similar to drm_bacon_gem_bo_wait_rendering except a timeout parameter allows
1455 * the operation to give up after a certain amount of time. Another subtle
1456 * difference is the internal locking semantics are different (this variant does
1457 * not hold the lock for the duration of the wait). This makes the wait subject
1458 * to a larger userspace race window.
1459 *
1460 * The implementation shall wait until the object is no longer actively
1461 * referenced within a batch buffer at the time of the call. The wait will
1462 * not guarantee that the buffer is re-issued via another thread, or an flinked
1463 * handle. Userspace must make sure this race does not occur if such precision
1464 * is important.
1465 *
1466 * Note that some kernels have broken the inifite wait for negative values
1467 * promise, upgrade to latest stable kernels if this is the case.
1468 */
1469 int
1470 drm_bacon_gem_bo_wait(drm_bacon_bo *bo, int64_t timeout_ns)
1471 {
1472 drm_bacon_bufmgr *bufmgr = bo->bufmgr;
1473 drm_bacon_bo_gem *bo_gem = (drm_bacon_bo_gem *) bo;
1474 struct drm_i915_gem_wait wait;
1475 int ret;
1476
1477 memclear(wait);
1478 wait.bo_handle = bo_gem->gem_handle;
1479 wait.timeout_ns = timeout_ns;
1480 ret = drmIoctl(bufmgr->fd, DRM_IOCTL_I915_GEM_WAIT, &wait);
1481 if (ret == -1)
1482 return -errno;
1483
1484 return ret;
1485 }
1486
1487 /**
1488 * Sets the object to the GTT read and possibly write domain, used by the X
1489 * 2D driver in the absence of kernel support to do drm_bacon_gem_bo_map_gtt().
1490 *
1491 * In combination with drm_bacon_gem_bo_pin() and manual fence management, we
1492 * can do tiled pixmaps this way.
1493 */
1494 void
1495 drm_bacon_gem_bo_start_gtt_access(drm_bacon_bo *bo, int write_enable)
1496 {
1497 drm_bacon_bufmgr *bufmgr = bo->bufmgr;
1498 drm_bacon_bo_gem *bo_gem = (drm_bacon_bo_gem *) bo;
1499 struct drm_i915_gem_set_domain set_domain;
1500 int ret;
1501
1502 memclear(set_domain);
1503 set_domain.handle = bo_gem->gem_handle;
1504 set_domain.read_domains = I915_GEM_DOMAIN_GTT;
1505 set_domain.write_domain = write_enable ? I915_GEM_DOMAIN_GTT : 0;
1506 ret = drmIoctl(bufmgr->fd,
1507 DRM_IOCTL_I915_GEM_SET_DOMAIN,
1508 &set_domain);
1509 if (ret != 0) {
1510 DBG("%s:%d: Error setting memory domains %d (%08x %08x): %s .\n",
1511 __FILE__, __LINE__, bo_gem->gem_handle,
1512 set_domain.read_domains, set_domain.write_domain,
1513 strerror(errno));
1514 }
1515 }
1516
1517 static void
1518 drm_bacon_bufmgr_gem_destroy(drm_bacon_bufmgr *bufmgr)
1519 {
1520 free(bufmgr->exec2_objects);
1521 free(bufmgr->exec_bos);
1522
1523 pthread_mutex_destroy(&bufmgr->lock);
1524
1525 /* Free any cached buffer objects we were going to reuse */
1526 for (int i = 0; i < bufmgr->num_buckets; i++) {
1527 struct drm_bacon_gem_bo_bucket *bucket =
1528 &bufmgr->cache_bucket[i];
1529 drm_bacon_bo_gem *bo_gem;
1530
1531 while (!list_empty(&bucket->head)) {
1532 bo_gem = LIST_ENTRY(drm_bacon_bo_gem,
1533 bucket->head.next, head);
1534 list_del(&bo_gem->head);
1535
1536 drm_bacon_gem_bo_free(&bo_gem->bo);
1537 }
1538 }
1539
1540 _mesa_hash_table_destroy(bufmgr->name_table, NULL);
1541 _mesa_hash_table_destroy(bufmgr->handle_table, NULL);
1542
1543 free(bufmgr);
1544 }
1545
1546 /**
1547 * Adds the target buffer to the validation list and adds the relocation
1548 * to the reloc_buffer's relocation list.
1549 *
1550 * The relocation entry at the given offset must already contain the
1551 * precomputed relocation value, because the kernel will optimize out
1552 * the relocation entry write when the buffer hasn't moved from the
1553 * last known offset in target_bo.
1554 */
1555 int
1556 drm_bacon_bo_emit_reloc(drm_bacon_bo *bo, uint32_t offset,
1557 drm_bacon_bo *target_bo, uint32_t target_offset,
1558 uint32_t read_domains, uint32_t write_domain)
1559 {
1560 drm_bacon_bufmgr *bufmgr = bo->bufmgr;
1561 drm_bacon_bo_gem *bo_gem = (drm_bacon_bo_gem *) bo;
1562 drm_bacon_bo_gem *target_bo_gem = (drm_bacon_bo_gem *) target_bo;
1563
1564 if (bo_gem->has_error)
1565 return -ENOMEM;
1566
1567 if (target_bo_gem->has_error) {
1568 bo_gem->has_error = true;
1569 return -ENOMEM;
1570 }
1571
1572 /* Create a new relocation list if needed */
1573 if (bo_gem->relocs == NULL && drm_bacon_setup_reloc_list(bo))
1574 return -ENOMEM;
1575
1576 /* Check overflow */
1577 assert(bo_gem->reloc_count < bufmgr->max_relocs);
1578
1579 /* Check args */
1580 assert(offset <= bo->size - 4);
1581 assert((write_domain & (write_domain - 1)) == 0);
1582
1583 /* Make sure that we're not adding a reloc to something whose size has
1584 * already been accounted for.
1585 */
1586 assert(!bo_gem->used_as_reloc_target);
1587 if (target_bo_gem != bo_gem) {
1588 target_bo_gem->used_as_reloc_target = true;
1589 bo_gem->reloc_tree_size += target_bo_gem->reloc_tree_size;
1590 }
1591
1592 bo_gem->reloc_bos[bo_gem->reloc_count] = target_bo;
1593 if (target_bo != bo)
1594 drm_bacon_bo_reference(target_bo);
1595
1596 bo_gem->relocs[bo_gem->reloc_count].offset = offset;
1597 bo_gem->relocs[bo_gem->reloc_count].delta = target_offset;
1598 bo_gem->relocs[bo_gem->reloc_count].target_handle =
1599 target_bo_gem->gem_handle;
1600 bo_gem->relocs[bo_gem->reloc_count].read_domains = read_domains;
1601 bo_gem->relocs[bo_gem->reloc_count].write_domain = write_domain;
1602 bo_gem->relocs[bo_gem->reloc_count].presumed_offset = target_bo->offset64;
1603 bo_gem->reloc_count++;
1604
1605 return 0;
1606 }
1607
1608 int
1609 drm_bacon_gem_bo_get_reloc_count(drm_bacon_bo *bo)
1610 {
1611 drm_bacon_bo_gem *bo_gem = (drm_bacon_bo_gem *) bo;
1612
1613 return bo_gem->reloc_count;
1614 }
1615
1616 /**
1617 * Removes existing relocation entries in the BO after "start".
1618 *
1619 * This allows a user to avoid a two-step process for state setup with
1620 * counting up all the buffer objects and doing a
1621 * drm_bacon_bufmgr_check_aperture_space() before emitting any of the
1622 * relocations for the state setup. Instead, save the state of the
1623 * batchbuffer including drm_bacon_gem_get_reloc_count(), emit all the
1624 * state, and then check if it still fits in the aperture.
1625 *
1626 * Any further drm_bacon_bufmgr_check_aperture_space() queries
1627 * involving this buffer in the tree are undefined after this call.
1628 */
1629 void
1630 drm_bacon_gem_bo_clear_relocs(drm_bacon_bo *bo, int start)
1631 {
1632 drm_bacon_bufmgr *bufmgr = bo->bufmgr;
1633 drm_bacon_bo_gem *bo_gem = (drm_bacon_bo_gem *) bo;
1634 int i;
1635 struct timespec time;
1636
1637 clock_gettime(CLOCK_MONOTONIC, &time);
1638
1639 assert(bo_gem->reloc_count >= start);
1640
1641 /* Unreference the cleared target buffers */
1642 pthread_mutex_lock(&bufmgr->lock);
1643
1644 for (i = start; i < bo_gem->reloc_count; i++) {
1645 drm_bacon_bo_gem *target_bo_gem = (drm_bacon_bo_gem *) bo_gem->reloc_bos[i];
1646 if (&target_bo_gem->bo != bo) {
1647 drm_bacon_gem_bo_unreference_locked_timed(&target_bo_gem->bo,
1648 time.tv_sec);
1649 }
1650 }
1651 bo_gem->reloc_count = start;
1652
1653 pthread_mutex_unlock(&bufmgr->lock);
1654
1655 }
1656
1657 static void
1658 drm_bacon_gem_bo_process_reloc2(drm_bacon_bo *bo)
1659 {
1660 drm_bacon_bo_gem *bo_gem = (drm_bacon_bo_gem *)bo;
1661 int i;
1662
1663 if (bo_gem->relocs == NULL)
1664 return;
1665
1666 for (i = 0; i < bo_gem->reloc_count; i++) {
1667 drm_bacon_bo *target_bo = bo_gem->reloc_bos[i];
1668
1669 if (target_bo == bo)
1670 continue;
1671
1672 drm_bacon_gem_bo_mark_mmaps_incoherent(bo);
1673
1674 /* Continue walking the tree depth-first. */
1675 drm_bacon_gem_bo_process_reloc2(target_bo);
1676
1677 /* Add the target to the validate list */
1678 drm_bacon_add_validate_buffer2(target_bo);
1679 }
1680 }
1681
1682 static void
1683 drm_bacon_update_buffer_offsets2 (drm_bacon_bufmgr *bufmgr)
1684 {
1685 int i;
1686
1687 for (i = 0; i < bufmgr->exec_count; i++) {
1688 drm_bacon_bo *bo = bufmgr->exec_bos[i];
1689 drm_bacon_bo_gem *bo_gem = (drm_bacon_bo_gem *)bo;
1690
1691 /* Update the buffer offset */
1692 if (bufmgr->exec2_objects[i].offset != bo->offset64) {
1693 DBG("BO %d (%s) migrated: 0x%08x %08x -> 0x%08x %08x\n",
1694 bo_gem->gem_handle, bo_gem->name,
1695 upper_32_bits(bo->offset64),
1696 lower_32_bits(bo->offset64),
1697 upper_32_bits(bufmgr->exec2_objects[i].offset),
1698 lower_32_bits(bufmgr->exec2_objects[i].offset));
1699 bo->offset64 = bufmgr->exec2_objects[i].offset;
1700 }
1701 }
1702 }
1703
1704 static int
1705 do_exec2(drm_bacon_bo *bo, int used, drm_bacon_context *ctx,
1706 int in_fence, int *out_fence,
1707 unsigned int flags)
1708 {
1709 drm_bacon_bufmgr *bufmgr = bo->bufmgr;
1710 struct drm_i915_gem_execbuffer2 execbuf;
1711 int ret = 0;
1712 int i;
1713
1714 if (to_bo_gem(bo)->has_error)
1715 return -ENOMEM;
1716
1717 pthread_mutex_lock(&bufmgr->lock);
1718 /* Update indices and set up the validate list. */
1719 drm_bacon_gem_bo_process_reloc2(bo);
1720
1721 /* Add the batch buffer to the validation list. There are no relocations
1722 * pointing to it.
1723 */
1724 drm_bacon_add_validate_buffer2(bo);
1725
1726 memclear(execbuf);
1727 execbuf.buffers_ptr = (uintptr_t)bufmgr->exec2_objects;
1728 execbuf.buffer_count = bufmgr->exec_count;
1729 execbuf.batch_start_offset = 0;
1730 execbuf.batch_len = used;
1731 execbuf.cliprects_ptr = 0;
1732 execbuf.num_cliprects = 0;
1733 execbuf.DR1 = 0;
1734 execbuf.DR4 = 0;
1735 execbuf.flags = flags;
1736 if (ctx == NULL)
1737 i915_execbuffer2_set_context_id(execbuf, 0);
1738 else
1739 i915_execbuffer2_set_context_id(execbuf, ctx->ctx_id);
1740 execbuf.rsvd2 = 0;
1741 if (in_fence != -1) {
1742 execbuf.rsvd2 = in_fence;
1743 execbuf.flags |= I915_EXEC_FENCE_IN;
1744 }
1745 if (out_fence != NULL) {
1746 *out_fence = -1;
1747 execbuf.flags |= I915_EXEC_FENCE_OUT;
1748 }
1749
1750 if (bufmgr->no_exec)
1751 goto skip_execution;
1752
1753 ret = drmIoctl(bufmgr->fd,
1754 DRM_IOCTL_I915_GEM_EXECBUFFER2_WR,
1755 &execbuf);
1756 if (ret != 0) {
1757 ret = -errno;
1758 if (ret == -ENOSPC) {
1759 DBG("Execbuffer fails to pin. "
1760 "Estimate: %u. Actual: %u. Available: %u\n",
1761 drm_bacon_gem_estimate_batch_space(bufmgr->exec_bos,
1762 bufmgr->exec_count),
1763 drm_bacon_gem_compute_batch_space(bufmgr->exec_bos,
1764 bufmgr->exec_count),
1765 (unsigned int) bufmgr->gtt_size);
1766 }
1767 }
1768 drm_bacon_update_buffer_offsets2(bufmgr);
1769
1770 if (ret == 0 && out_fence != NULL)
1771 *out_fence = execbuf.rsvd2 >> 32;
1772
1773 skip_execution:
1774 if (INTEL_DEBUG & DEBUG_BUFMGR)
1775 drm_bacon_gem_dump_validation_list(bufmgr);
1776
1777 for (i = 0; i < bufmgr->exec_count; i++) {
1778 drm_bacon_bo_gem *bo_gem = to_bo_gem(bufmgr->exec_bos[i]);
1779
1780 bo_gem->idle = false;
1781
1782 /* Disconnect the buffer from the validate list */
1783 bo_gem->validate_index = -1;
1784 bufmgr->exec_bos[i] = NULL;
1785 }
1786 bufmgr->exec_count = 0;
1787 pthread_mutex_unlock(&bufmgr->lock);
1788
1789 return ret;
1790 }
1791
1792 int
1793 drm_bacon_bo_exec(drm_bacon_bo *bo, int used)
1794 {
1795 return do_exec2(bo, used, NULL, -1, NULL, I915_EXEC_RENDER);
1796 }
1797
1798 int
1799 drm_bacon_bo_mrb_exec(drm_bacon_bo *bo, int used, unsigned int flags)
1800 {
1801 return do_exec2(bo, used, NULL, -1, NULL, flags);
1802 }
1803
1804 int
1805 drm_bacon_gem_bo_context_exec(drm_bacon_bo *bo, drm_bacon_context *ctx,
1806 int used, unsigned int flags)
1807 {
1808 return do_exec2(bo, used, ctx, -1, NULL, flags);
1809 }
1810
1811 int
1812 drm_bacon_gem_bo_fence_exec(drm_bacon_bo *bo,
1813 drm_bacon_context *ctx,
1814 int used,
1815 int in_fence,
1816 int *out_fence,
1817 unsigned int flags)
1818 {
1819 return do_exec2(bo, used, ctx, in_fence, out_fence, flags);
1820 }
1821
1822 static int
1823 drm_bacon_gem_bo_set_tiling_internal(drm_bacon_bo *bo,
1824 uint32_t tiling_mode,
1825 uint32_t stride)
1826 {
1827 drm_bacon_bufmgr *bufmgr = bo->bufmgr;
1828 drm_bacon_bo_gem *bo_gem = (drm_bacon_bo_gem *) bo;
1829 struct drm_i915_gem_set_tiling set_tiling;
1830 int ret;
1831
1832 if (bo_gem->global_name == 0 &&
1833 tiling_mode == bo_gem->tiling_mode &&
1834 stride == bo_gem->stride)
1835 return 0;
1836
1837 memset(&set_tiling, 0, sizeof(set_tiling));
1838 do {
1839 /* set_tiling is slightly broken and overwrites the
1840 * input on the error path, so we have to open code
1841 * rmIoctl.
1842 */
1843 set_tiling.handle = bo_gem->gem_handle;
1844 set_tiling.tiling_mode = tiling_mode;
1845 set_tiling.stride = stride;
1846
1847 ret = ioctl(bufmgr->fd,
1848 DRM_IOCTL_I915_GEM_SET_TILING,
1849 &set_tiling);
1850 } while (ret == -1 && (errno == EINTR || errno == EAGAIN));
1851 if (ret == -1)
1852 return -errno;
1853
1854 bo_gem->tiling_mode = set_tiling.tiling_mode;
1855 bo_gem->swizzle_mode = set_tiling.swizzle_mode;
1856 bo_gem->stride = set_tiling.stride;
1857 return 0;
1858 }
1859
1860 int
1861 drm_bacon_bo_set_tiling(drm_bacon_bo *bo, uint32_t * tiling_mode,
1862 uint32_t stride)
1863 {
1864 drm_bacon_bufmgr *bufmgr = bo->bufmgr;
1865 drm_bacon_bo_gem *bo_gem = (drm_bacon_bo_gem *) bo;
1866 int ret;
1867
1868 /* Linear buffers have no stride. By ensuring that we only ever use
1869 * stride 0 with linear buffers, we simplify our code.
1870 */
1871 if (*tiling_mode == I915_TILING_NONE)
1872 stride = 0;
1873
1874 ret = drm_bacon_gem_bo_set_tiling_internal(bo, *tiling_mode, stride);
1875 if (ret == 0)
1876 drm_bacon_bo_gem_set_in_aperture_size(bufmgr, bo_gem, 0);
1877
1878 *tiling_mode = bo_gem->tiling_mode;
1879 return ret;
1880 }
1881
1882 int
1883 drm_bacon_bo_get_tiling(drm_bacon_bo *bo, uint32_t * tiling_mode,
1884 uint32_t *swizzle_mode)
1885 {
1886 drm_bacon_bo_gem *bo_gem = (drm_bacon_bo_gem *) bo;
1887
1888 *tiling_mode = bo_gem->tiling_mode;
1889 *swizzle_mode = bo_gem->swizzle_mode;
1890 return 0;
1891 }
1892
1893 drm_bacon_bo *
1894 drm_bacon_bo_gem_create_from_prime(drm_bacon_bufmgr *bufmgr, int prime_fd, int size)
1895 {
1896 int ret;
1897 uint32_t handle;
1898 drm_bacon_bo_gem *bo_gem;
1899 struct drm_i915_gem_get_tiling get_tiling;
1900
1901 pthread_mutex_lock(&bufmgr->lock);
1902 ret = drmPrimeFDToHandle(bufmgr->fd, prime_fd, &handle);
1903 if (ret) {
1904 DBG("create_from_prime: failed to obtain handle from fd: %s\n", strerror(errno));
1905 pthread_mutex_unlock(&bufmgr->lock);
1906 return NULL;
1907 }
1908
1909 /*
1910 * See if the kernel has already returned this buffer to us. Just as
1911 * for named buffers, we must not create two bo's pointing at the same
1912 * kernel object
1913 */
1914 bo_gem = hash_find_bo(bufmgr->handle_table, handle);
1915 if (bo_gem) {
1916 drm_bacon_bo_reference(&bo_gem->bo);
1917 goto out;
1918 }
1919
1920 bo_gem = calloc(1, sizeof(*bo_gem));
1921 if (!bo_gem)
1922 goto out;
1923
1924 p_atomic_set(&bo_gem->refcount, 1);
1925 list_inithead(&bo_gem->vma_list);
1926
1927 /* Determine size of bo. The fd-to-handle ioctl really should
1928 * return the size, but it doesn't. If we have kernel 3.12 or
1929 * later, we can lseek on the prime fd to get the size. Older
1930 * kernels will just fail, in which case we fall back to the
1931 * provided (estimated or guess size). */
1932 ret = lseek(prime_fd, 0, SEEK_END);
1933 if (ret != -1)
1934 bo_gem->bo.size = ret;
1935 else
1936 bo_gem->bo.size = size;
1937
1938 bo_gem->bo.handle = handle;
1939 bo_gem->bo.bufmgr = bufmgr;
1940
1941 bo_gem->gem_handle = handle;
1942 _mesa_hash_table_insert(bufmgr->handle_table,
1943 &bo_gem->gem_handle, bo_gem);
1944
1945 bo_gem->name = "prime";
1946 bo_gem->validate_index = -1;
1947 bo_gem->used_as_reloc_target = false;
1948 bo_gem->has_error = false;
1949 bo_gem->reusable = false;
1950
1951 memclear(get_tiling);
1952 get_tiling.handle = bo_gem->gem_handle;
1953 if (drmIoctl(bufmgr->fd,
1954 DRM_IOCTL_I915_GEM_GET_TILING,
1955 &get_tiling))
1956 goto err;
1957
1958 bo_gem->tiling_mode = get_tiling.tiling_mode;
1959 bo_gem->swizzle_mode = get_tiling.swizzle_mode;
1960 /* XXX stride is unknown */
1961 drm_bacon_bo_gem_set_in_aperture_size(bufmgr, bo_gem, 0);
1962
1963 out:
1964 pthread_mutex_unlock(&bufmgr->lock);
1965 return &bo_gem->bo;
1966
1967 err:
1968 drm_bacon_gem_bo_free(&bo_gem->bo);
1969 pthread_mutex_unlock(&bufmgr->lock);
1970 return NULL;
1971 }
1972
1973 int
1974 drm_bacon_bo_gem_export_to_prime(drm_bacon_bo *bo, int *prime_fd)
1975 {
1976 drm_bacon_bufmgr *bufmgr = bo->bufmgr;
1977 drm_bacon_bo_gem *bo_gem = (drm_bacon_bo_gem *) bo;
1978
1979 if (drmPrimeHandleToFD(bufmgr->fd, bo_gem->gem_handle,
1980 DRM_CLOEXEC, prime_fd) != 0)
1981 return -errno;
1982
1983 bo_gem->reusable = false;
1984
1985 return 0;
1986 }
1987
1988 int
1989 drm_bacon_bo_flink(drm_bacon_bo *bo, uint32_t *name)
1990 {
1991 drm_bacon_bufmgr *bufmgr = bo->bufmgr;
1992 drm_bacon_bo_gem *bo_gem = (drm_bacon_bo_gem *) bo;
1993
1994 if (!bo_gem->global_name) {
1995 struct drm_gem_flink flink;
1996
1997 memclear(flink);
1998 flink.handle = bo_gem->gem_handle;
1999 if (drmIoctl(bufmgr->fd, DRM_IOCTL_GEM_FLINK, &flink))
2000 return -errno;
2001
2002 pthread_mutex_lock(&bufmgr->lock);
2003 if (!bo_gem->global_name) {
2004 bo_gem->global_name = flink.name;
2005 bo_gem->reusable = false;
2006
2007 _mesa_hash_table_insert(bufmgr->name_table,
2008 &bo_gem->global_name, bo_gem);
2009 }
2010 pthread_mutex_unlock(&bufmgr->lock);
2011 }
2012
2013 *name = bo_gem->global_name;
2014 return 0;
2015 }
2016
2017 /**
2018 * Enables unlimited caching of buffer objects for reuse.
2019 *
2020 * This is potentially very memory expensive, as the cache at each bucket
2021 * size is only bounded by how many buffers of that size we've managed to have
2022 * in flight at once.
2023 */
2024 void
2025 drm_bacon_bufmgr_gem_enable_reuse(drm_bacon_bufmgr *bufmgr)
2026 {
2027 bufmgr->bo_reuse = true;
2028 }
2029
2030 /**
2031 * Return the additional aperture space required by the tree of buffer objects
2032 * rooted at bo.
2033 */
2034 static int
2035 drm_bacon_gem_bo_get_aperture_space(drm_bacon_bo *bo)
2036 {
2037 drm_bacon_bo_gem *bo_gem = (drm_bacon_bo_gem *) bo;
2038 int i;
2039 int total = 0;
2040
2041 if (bo == NULL || bo_gem->included_in_check_aperture)
2042 return 0;
2043
2044 total += bo->size;
2045 bo_gem->included_in_check_aperture = true;
2046
2047 for (i = 0; i < bo_gem->reloc_count; i++)
2048 total +=
2049 drm_bacon_gem_bo_get_aperture_space(bo_gem->reloc_bos[i]);
2050
2051 return total;
2052 }
2053
2054 /**
2055 * Clear the flag set by drm_bacon_gem_bo_get_aperture_space() so we're ready
2056 * for the next drm_bacon_bufmgr_check_aperture_space() call.
2057 */
2058 static void
2059 drm_bacon_gem_bo_clear_aperture_space_flag(drm_bacon_bo *bo)
2060 {
2061 drm_bacon_bo_gem *bo_gem = (drm_bacon_bo_gem *) bo;
2062 int i;
2063
2064 if (bo == NULL || !bo_gem->included_in_check_aperture)
2065 return;
2066
2067 bo_gem->included_in_check_aperture = false;
2068
2069 for (i = 0; i < bo_gem->reloc_count; i++)
2070 drm_bacon_gem_bo_clear_aperture_space_flag(bo_gem->reloc_bos[i]);
2071 }
2072
2073 /**
2074 * Return a conservative estimate for the amount of aperture required
2075 * for a collection of buffers. This may double-count some buffers.
2076 */
2077 static unsigned int
2078 drm_bacon_gem_estimate_batch_space(drm_bacon_bo **bo_array, int count)
2079 {
2080 int i;
2081 unsigned int total = 0;
2082
2083 for (i = 0; i < count; i++) {
2084 drm_bacon_bo_gem *bo_gem = (drm_bacon_bo_gem *) bo_array[i];
2085 if (bo_gem != NULL)
2086 total += bo_gem->reloc_tree_size;
2087 }
2088 return total;
2089 }
2090
2091 /**
2092 * Return the amount of aperture needed for a collection of buffers.
2093 * This avoids double counting any buffers, at the cost of looking
2094 * at every buffer in the set.
2095 */
2096 static unsigned int
2097 drm_bacon_gem_compute_batch_space(drm_bacon_bo **bo_array, int count)
2098 {
2099 int i;
2100 unsigned int total = 0;
2101
2102 for (i = 0; i < count; i++) {
2103 total += drm_bacon_gem_bo_get_aperture_space(bo_array[i]);
2104 /* For the first buffer object in the array, we get an
2105 * accurate count back for its reloc_tree size (since nothing
2106 * had been flagged as being counted yet). We can save that
2107 * value out as a more conservative reloc_tree_size that
2108 * avoids double-counting target buffers. Since the first
2109 * buffer happens to usually be the batch buffer in our
2110 * callers, this can pull us back from doing the tree
2111 * walk on every new batch emit.
2112 */
2113 if (i == 0) {
2114 drm_bacon_bo_gem *bo_gem =
2115 (drm_bacon_bo_gem *) bo_array[i];
2116 bo_gem->reloc_tree_size = total;
2117 }
2118 }
2119
2120 for (i = 0; i < count; i++)
2121 drm_bacon_gem_bo_clear_aperture_space_flag(bo_array[i]);
2122 return total;
2123 }
2124
2125 /**
2126 * Return -1 if the batchbuffer should be flushed before attempting to
2127 * emit rendering referencing the buffers pointed to by bo_array.
2128 *
2129 * This is required because if we try to emit a batchbuffer with relocations
2130 * to a tree of buffers that won't simultaneously fit in the aperture,
2131 * the rendering will return an error at a point where the software is not
2132 * prepared to recover from it.
2133 *
2134 * However, we also want to emit the batchbuffer significantly before we reach
2135 * the limit, as a series of batchbuffers each of which references buffers
2136 * covering almost all of the aperture means that at each emit we end up
2137 * waiting to evict a buffer from the last rendering, and we get synchronous
2138 * performance. By emitting smaller batchbuffers, we eat some CPU overhead to
2139 * get better parallelism.
2140 */
2141 int
2142 drm_bacon_bufmgr_check_aperture_space(drm_bacon_bo **bo_array, int count)
2143 {
2144 drm_bacon_bufmgr *bufmgr = bo_array[0]->bufmgr;
2145 unsigned int total = 0;
2146 unsigned int threshold = bufmgr->gtt_size * 3 / 4;
2147
2148 total = drm_bacon_gem_estimate_batch_space(bo_array, count);
2149
2150 if (total > threshold)
2151 total = drm_bacon_gem_compute_batch_space(bo_array, count);
2152
2153 if (total > threshold) {
2154 DBG("check_space: overflowed available aperture, "
2155 "%dkb vs %dkb\n",
2156 total / 1024, (int)bufmgr->gtt_size / 1024);
2157 return -ENOSPC;
2158 } else {
2159 DBG("drm_check_space: total %dkb vs bufgr %dkb\n", total / 1024,
2160 (int)bufmgr->gtt_size / 1024);
2161 return 0;
2162 }
2163 }
2164
2165 /*
2166 * Disable buffer reuse for objects which are shared with the kernel
2167 * as scanout buffers
2168 */
2169 int
2170 drm_bacon_bo_disable_reuse(drm_bacon_bo *bo)
2171 {
2172 drm_bacon_bo_gem *bo_gem = (drm_bacon_bo_gem *) bo;
2173
2174 bo_gem->reusable = false;
2175 return 0;
2176 }
2177
2178 int
2179 drm_bacon_bo_is_reusable(drm_bacon_bo *bo)
2180 {
2181 drm_bacon_bo_gem *bo_gem = (drm_bacon_bo_gem *) bo;
2182
2183 return bo_gem->reusable;
2184 }
2185
2186 static int
2187 _drm_bacon_gem_bo_references(drm_bacon_bo *bo, drm_bacon_bo *target_bo)
2188 {
2189 drm_bacon_bo_gem *bo_gem = (drm_bacon_bo_gem *) bo;
2190 int i;
2191
2192 for (i = 0; i < bo_gem->reloc_count; i++) {
2193 if (bo_gem->reloc_bos[i] == target_bo)
2194 return 1;
2195 if (bo == bo_gem->reloc_bos[i])
2196 continue;
2197 if (_drm_bacon_gem_bo_references(bo_gem->reloc_bos[i],
2198 target_bo))
2199 return 1;
2200 }
2201
2202 return 0;
2203 }
2204
2205 /** Return true if target_bo is referenced by bo's relocation tree. */
2206 int
2207 drm_bacon_bo_references(drm_bacon_bo *bo, drm_bacon_bo *target_bo)
2208 {
2209 drm_bacon_bo_gem *target_bo_gem = (drm_bacon_bo_gem *) target_bo;
2210
2211 if (bo == NULL || target_bo == NULL)
2212 return 0;
2213 if (target_bo_gem->used_as_reloc_target)
2214 return _drm_bacon_gem_bo_references(bo, target_bo);
2215 return 0;
2216 }
2217
2218 static void
2219 add_bucket(drm_bacon_bufmgr *bufmgr, int size)
2220 {
2221 unsigned int i = bufmgr->num_buckets;
2222
2223 assert(i < ARRAY_SIZE(bufmgr->cache_bucket));
2224
2225 list_inithead(&bufmgr->cache_bucket[i].head);
2226 bufmgr->cache_bucket[i].size = size;
2227 bufmgr->num_buckets++;
2228 }
2229
2230 static void
2231 init_cache_buckets(drm_bacon_bufmgr *bufmgr)
2232 {
2233 unsigned long size, cache_max_size = 64 * 1024 * 1024;
2234
2235 /* OK, so power of two buckets was too wasteful of memory.
2236 * Give 3 other sizes between each power of two, to hopefully
2237 * cover things accurately enough. (The alternative is
2238 * probably to just go for exact matching of sizes, and assume
2239 * that for things like composited window resize the tiled
2240 * width/height alignment and rounding of sizes to pages will
2241 * get us useful cache hit rates anyway)
2242 */
2243 add_bucket(bufmgr, 4096);
2244 add_bucket(bufmgr, 4096 * 2);
2245 add_bucket(bufmgr, 4096 * 3);
2246
2247 /* Initialize the linked lists for BO reuse cache. */
2248 for (size = 4 * 4096; size <= cache_max_size; size *= 2) {
2249 add_bucket(bufmgr, size);
2250
2251 add_bucket(bufmgr, size + size * 1 / 4);
2252 add_bucket(bufmgr, size + size * 2 / 4);
2253 add_bucket(bufmgr, size + size * 3 / 4);
2254 }
2255 }
2256
2257 void
2258 drm_bacon_bufmgr_gem_set_vma_cache_size(drm_bacon_bufmgr *bufmgr, int limit)
2259 {
2260 bufmgr->vma_max = limit;
2261
2262 drm_bacon_gem_bo_purge_vma_cache(bufmgr);
2263 }
2264
2265 drm_bacon_context *
2266 drm_bacon_gem_context_create(drm_bacon_bufmgr *bufmgr)
2267 {
2268 struct drm_i915_gem_context_create create;
2269 drm_bacon_context *context = NULL;
2270 int ret;
2271
2272 context = calloc(1, sizeof(*context));
2273 if (!context)
2274 return NULL;
2275
2276 memclear(create);
2277 ret = drmIoctl(bufmgr->fd, DRM_IOCTL_I915_GEM_CONTEXT_CREATE, &create);
2278 if (ret != 0) {
2279 DBG("DRM_IOCTL_I915_GEM_CONTEXT_CREATE failed: %s\n",
2280 strerror(errno));
2281 free(context);
2282 return NULL;
2283 }
2284
2285 context->ctx_id = create.ctx_id;
2286 context->bufmgr = bufmgr;
2287
2288 return context;
2289 }
2290
2291 int
2292 drm_bacon_gem_context_get_id(drm_bacon_context *ctx, uint32_t *ctx_id)
2293 {
2294 if (ctx == NULL)
2295 return -EINVAL;
2296
2297 *ctx_id = ctx->ctx_id;
2298
2299 return 0;
2300 }
2301
2302 void
2303 drm_bacon_gem_context_destroy(drm_bacon_context *ctx)
2304 {
2305 struct drm_i915_gem_context_destroy destroy;
2306 int ret;
2307
2308 if (ctx == NULL)
2309 return;
2310
2311 memclear(destroy);
2312
2313 destroy.ctx_id = ctx->ctx_id;
2314 ret = drmIoctl(ctx->bufmgr->fd, DRM_IOCTL_I915_GEM_CONTEXT_DESTROY,
2315 &destroy);
2316 if (ret != 0)
2317 fprintf(stderr, "DRM_IOCTL_I915_GEM_CONTEXT_DESTROY failed: %s\n",
2318 strerror(errno));
2319
2320 free(ctx);
2321 }
2322
2323 int
2324 drm_bacon_get_reset_stats(drm_bacon_context *ctx,
2325 uint32_t *reset_count,
2326 uint32_t *active,
2327 uint32_t *pending)
2328 {
2329 struct drm_i915_reset_stats stats;
2330 int ret;
2331
2332 if (ctx == NULL)
2333 return -EINVAL;
2334
2335 memclear(stats);
2336
2337 stats.ctx_id = ctx->ctx_id;
2338 ret = drmIoctl(ctx->bufmgr->fd,
2339 DRM_IOCTL_I915_GET_RESET_STATS,
2340 &stats);
2341 if (ret == 0) {
2342 if (reset_count != NULL)
2343 *reset_count = stats.reset_count;
2344
2345 if (active != NULL)
2346 *active = stats.batch_active;
2347
2348 if (pending != NULL)
2349 *pending = stats.batch_pending;
2350 }
2351
2352 return ret;
2353 }
2354
2355 int
2356 drm_bacon_reg_read(drm_bacon_bufmgr *bufmgr,
2357 uint32_t offset,
2358 uint64_t *result)
2359 {
2360 struct drm_i915_reg_read reg_read;
2361 int ret;
2362
2363 memclear(reg_read);
2364 reg_read.offset = offset;
2365
2366 ret = drmIoctl(bufmgr->fd, DRM_IOCTL_I915_REG_READ, &reg_read);
2367
2368 *result = reg_read.val;
2369 return ret;
2370 }
2371
2372 static pthread_mutex_t bufmgr_list_mutex = PTHREAD_MUTEX_INITIALIZER;
2373 static struct list_head bufmgr_list = { &bufmgr_list, &bufmgr_list };
2374
2375 static drm_bacon_bufmgr *
2376 drm_bacon_bufmgr_gem_find(int fd)
2377 {
2378 list_for_each_entry(drm_bacon_bufmgr,
2379 bufmgr, &bufmgr_list, managers) {
2380 if (bufmgr->fd == fd) {
2381 p_atomic_inc(&bufmgr->refcount);
2382 return bufmgr;
2383 }
2384 }
2385
2386 return NULL;
2387 }
2388
2389 void
2390 drm_bacon_bufmgr_destroy(drm_bacon_bufmgr *bufmgr)
2391 {
2392 if (atomic_add_unless(&bufmgr->refcount, -1, 1)) {
2393 pthread_mutex_lock(&bufmgr_list_mutex);
2394
2395 if (p_atomic_dec_zero(&bufmgr->refcount)) {
2396 list_del(&bufmgr->managers);
2397 drm_bacon_bufmgr_gem_destroy(bufmgr);
2398 }
2399
2400 pthread_mutex_unlock(&bufmgr_list_mutex);
2401 }
2402 }
2403
2404 void *drm_bacon_gem_bo_map__gtt(drm_bacon_bo *bo)
2405 {
2406 drm_bacon_bufmgr *bufmgr = bo->bufmgr;
2407 drm_bacon_bo_gem *bo_gem = (drm_bacon_bo_gem *) bo;
2408
2409 if (bo_gem->gtt_virtual)
2410 return bo_gem->gtt_virtual;
2411
2412 pthread_mutex_lock(&bufmgr->lock);
2413 if (bo_gem->gtt_virtual == NULL) {
2414 struct drm_i915_gem_mmap_gtt mmap_arg;
2415 void *ptr;
2416
2417 DBG("bo_map_gtt: mmap %d (%s), map_count=%d\n",
2418 bo_gem->gem_handle, bo_gem->name, bo_gem->map_count);
2419
2420 if (bo_gem->map_count++ == 0)
2421 drm_bacon_gem_bo_open_vma(bufmgr, bo_gem);
2422
2423 memclear(mmap_arg);
2424 mmap_arg.handle = bo_gem->gem_handle;
2425
2426 /* Get the fake offset back... */
2427 ptr = MAP_FAILED;
2428 if (drmIoctl(bufmgr->fd,
2429 DRM_IOCTL_I915_GEM_MMAP_GTT,
2430 &mmap_arg) == 0) {
2431 /* and mmap it */
2432 ptr = drm_mmap(0, bo->size, PROT_READ | PROT_WRITE,
2433 MAP_SHARED, bufmgr->fd,
2434 mmap_arg.offset);
2435 }
2436 if (ptr == MAP_FAILED) {
2437 if (--bo_gem->map_count == 0)
2438 drm_bacon_gem_bo_close_vma(bufmgr, bo_gem);
2439 ptr = NULL;
2440 }
2441
2442 bo_gem->gtt_virtual = ptr;
2443 }
2444 pthread_mutex_unlock(&bufmgr->lock);
2445
2446 return bo_gem->gtt_virtual;
2447 }
2448
2449 void *drm_bacon_gem_bo_map__cpu(drm_bacon_bo *bo)
2450 {
2451 drm_bacon_bufmgr *bufmgr = bo->bufmgr;
2452 drm_bacon_bo_gem *bo_gem = (drm_bacon_bo_gem *) bo;
2453
2454 if (bo_gem->mem_virtual)
2455 return bo_gem->mem_virtual;
2456
2457 pthread_mutex_lock(&bufmgr->lock);
2458 if (!bo_gem->mem_virtual) {
2459 struct drm_i915_gem_mmap mmap_arg;
2460
2461 if (bo_gem->map_count++ == 0)
2462 drm_bacon_gem_bo_open_vma(bufmgr, bo_gem);
2463
2464 DBG("bo_map: %d (%s), map_count=%d\n",
2465 bo_gem->gem_handle, bo_gem->name, bo_gem->map_count);
2466
2467 memclear(mmap_arg);
2468 mmap_arg.handle = bo_gem->gem_handle;
2469 mmap_arg.size = bo->size;
2470 if (drmIoctl(bufmgr->fd,
2471 DRM_IOCTL_I915_GEM_MMAP,
2472 &mmap_arg)) {
2473 DBG("%s:%d: Error mapping buffer %d (%s): %s .\n",
2474 __FILE__, __LINE__, bo_gem->gem_handle,
2475 bo_gem->name, strerror(errno));
2476 if (--bo_gem->map_count == 0)
2477 drm_bacon_gem_bo_close_vma(bufmgr, bo_gem);
2478 } else {
2479 VG(VALGRIND_MALLOCLIKE_BLOCK(mmap_arg.addr_ptr, mmap_arg.size, 0, 1));
2480 bo_gem->mem_virtual = (void *)(uintptr_t) mmap_arg.addr_ptr;
2481 }
2482 }
2483 pthread_mutex_unlock(&bufmgr->lock);
2484
2485 return bo_gem->mem_virtual;
2486 }
2487
2488 void *drm_bacon_gem_bo_map__wc(drm_bacon_bo *bo)
2489 {
2490 drm_bacon_bufmgr *bufmgr = bo->bufmgr;
2491 drm_bacon_bo_gem *bo_gem = (drm_bacon_bo_gem *) bo;
2492
2493 if (bo_gem->wc_virtual)
2494 return bo_gem->wc_virtual;
2495
2496 pthread_mutex_lock(&bufmgr->lock);
2497 if (!bo_gem->wc_virtual) {
2498 struct drm_i915_gem_mmap mmap_arg;
2499
2500 if (bo_gem->map_count++ == 0)
2501 drm_bacon_gem_bo_open_vma(bufmgr, bo_gem);
2502
2503 DBG("bo_map: %d (%s), map_count=%d\n",
2504 bo_gem->gem_handle, bo_gem->name, bo_gem->map_count);
2505
2506 memclear(mmap_arg);
2507 mmap_arg.handle = bo_gem->gem_handle;
2508 mmap_arg.size = bo->size;
2509 mmap_arg.flags = I915_MMAP_WC;
2510 if (drmIoctl(bufmgr->fd,
2511 DRM_IOCTL_I915_GEM_MMAP,
2512 &mmap_arg)) {
2513 DBG("%s:%d: Error mapping buffer %d (%s): %s .\n",
2514 __FILE__, __LINE__, bo_gem->gem_handle,
2515 bo_gem->name, strerror(errno));
2516 if (--bo_gem->map_count == 0)
2517 drm_bacon_gem_bo_close_vma(bufmgr, bo_gem);
2518 } else {
2519 VG(VALGRIND_MALLOCLIKE_BLOCK(mmap_arg.addr_ptr, mmap_arg.size, 0, 1));
2520 bo_gem->wc_virtual = (void *)(uintptr_t) mmap_arg.addr_ptr;
2521 }
2522 }
2523 pthread_mutex_unlock(&bufmgr->lock);
2524
2525 return bo_gem->wc_virtual;
2526 }
2527
2528 /**
2529 * Initializes the GEM buffer manager, which uses the kernel to allocate, map,
2530 * and manage map buffer objections.
2531 *
2532 * \param fd File descriptor of the opened DRM device.
2533 */
2534 drm_bacon_bufmgr *
2535 drm_bacon_bufmgr_gem_init(struct gen_device_info *devinfo,
2536 int fd, int batch_size)
2537 {
2538 drm_bacon_bufmgr *bufmgr;
2539 struct drm_i915_gem_get_aperture aperture;
2540
2541 pthread_mutex_lock(&bufmgr_list_mutex);
2542
2543 bufmgr = drm_bacon_bufmgr_gem_find(fd);
2544 if (bufmgr)
2545 goto exit;
2546
2547 bufmgr = calloc(1, sizeof(*bufmgr));
2548 if (bufmgr == NULL)
2549 goto exit;
2550
2551 bufmgr->fd = fd;
2552 p_atomic_set(&bufmgr->refcount, 1);
2553
2554 if (pthread_mutex_init(&bufmgr->lock, NULL) != 0) {
2555 free(bufmgr);
2556 bufmgr = NULL;
2557 goto exit;
2558 }
2559
2560 memclear(aperture);
2561 drmIoctl(bufmgr->fd, DRM_IOCTL_I915_GEM_GET_APERTURE, &aperture);
2562 bufmgr->gtt_size = aperture.aper_available_size;
2563
2564 bufmgr->has_llc = devinfo->has_llc;
2565
2566 /* Let's go with one relocation per every 2 dwords (but round down a bit
2567 * since a power of two will mean an extra page allocation for the reloc
2568 * buffer).
2569 *
2570 * Every 4 was too few for the blender benchmark.
2571 */
2572 bufmgr->max_relocs = batch_size / sizeof(uint32_t) / 2 - 2;
2573
2574 init_cache_buckets(bufmgr);
2575
2576 list_inithead(&bufmgr->vma_cache);
2577 bufmgr->vma_max = -1; /* unlimited by default */
2578
2579 list_add(&bufmgr->managers, &bufmgr_list);
2580
2581 bufmgr->name_table =
2582 _mesa_hash_table_create(NULL, key_hash_uint, key_uint_equal);
2583 bufmgr->handle_table =
2584 _mesa_hash_table_create(NULL, key_hash_uint, key_uint_equal);
2585
2586 exit:
2587 pthread_mutex_unlock(&bufmgr_list_mutex);
2588
2589 return bufmgr;
2590 }