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