Lines Matching refs:bo

173 static int bo_set_tiling_internal(struct crocus_bo *bo, uint32_t tiling_mode,
176 static void bo_free(struct crocus_bo *bo);
194 struct crocus_bo *bo = entry ? entry->data : NULL;
196 if (bo) {
197 assert(bo->external);
198 assert(!bo->reusable);
205 if (bo->head.prev || bo->head.next)
206 list_del(&bo->head);
208 crocus_bo_reference(bo);
211 return bo;
256 crocus_bo_busy(struct crocus_bo *bo)
258 struct crocus_bufmgr *bufmgr = bo->bufmgr;
259 struct drm_i915_gem_busy busy = { .handle = bo->gem_handle };
263 bo->idle = !busy.busy;
270 crocus_bo_madvise(struct crocus_bo *bo, int state)
273 .handle = bo->gem_handle,
278 intel_ioctl(bo->bufmgr->fd, DRM_IOCTL_I915_GEM_MADVISE, &madv);
286 struct crocus_bo *bo = calloc(1, sizeof(*bo));
287 if (!bo)
290 list_inithead(&bo->exports);
291 bo->hash = _mesa_hash_pointer(bo);
292 return bo;
304 struct crocus_bo *bo = NULL;
318 bo = cur;
326 if (!bo)
333 void *map = crocus_bo_map(NULL, bo, MAP_WRITE | MAP_RAW);
335 memset(map, 0, bo->size);
337 bo_free(bo);
342 return bo;
348 struct crocus_bo *bo = bo_calloc();
349 if (!bo)
358 free(bo);
362 bo->gem_handle = create.handle;
363 bo->bufmgr = bufmgr;
364 bo->size = bo_size;
365 bo->idle = true;
366 bo->tiling_mode = I915_TILING_NONE;
367 bo->swizzle_mode = I915_BIT_6_SWIZZLE_NONE;
368 bo->stride = 0;
375 .handle = bo->gem_handle,
380 if (intel_ioctl(bo->bufmgr->fd, DRM_IOCTL_I915_GEM_SET_DOMAIN, &sd) != 0) {
381 bo_free(bo);
385 return bo;
397 struct crocus_bo *bo;
412 bo = alloc_bo_from_cache(bufmgr, bucket, alignment, flags);
416 if (!bo) {
417 bo = alloc_fresh_bo(bufmgr, bo_size);
418 if (!bo)
422 if (bo_set_tiling_internal(bo, tiling_mode, stride))
425 bo->name = name;
426 p_atomic_set(&bo->refcount, 1);
427 bo->reusable = bucket && bufmgr->bo_reuse;
428 bo->cache_coherent = bufmgr->has_llc;
429 bo->index = -1;
430 bo->kflags = 0;
433 bo->scanout = 1;
435 if ((flags & BO_ALLOC_COHERENT) && !bo->cache_coherent) {
437 .handle = bo->gem_handle,
441 bo->cache_coherent = true;
442 bo->reusable = false;
446 DBG("bo_create: buf %d (%s) %llub\n", bo->gem_handle,
447 bo->name, (unsigned long long) size);
449 return bo;
452 bo_free(bo);
478 struct crocus_bo *bo;
480 bo = bo_calloc();
481 if (!bo)
490 bo->gem_handle = arg.handle;
494 .handle = bo->gem_handle,
500 bo->name = name;
501 bo->size = size;
502 bo->map_cpu = ptr;
504 bo->bufmgr = bufmgr;
505 bo->kflags = 0;
507 p_atomic_set(&bo->refcount, 1);
508 bo->userptr = true;
509 bo->cache_coherent = true;
510 bo->index = -1;
511 bo->idle = true;
513 return bo;
516 intel_ioctl(bufmgr->fd, DRM_IOCTL_GEM_CLOSE, &bo->gem_handle);
518 free(bo);
532 struct crocus_bo *bo;
534 /* At the moment most applications only have a few named bo.
541 bo = find_and_ref_external_bo(bufmgr->name_table, handle);
542 if (bo)
550 bo = NULL;
557 bo = find_and_ref_external_bo(bufmgr->handle_table, open_arg.handle);
558 if (bo)
561 bo = bo_calloc();
562 if (!bo)
565 p_atomic_set(&bo->refcount, 1);
567 bo->size = open_arg.size;
568 bo->gtt_offset = 0;
569 bo->bufmgr = bufmgr;
570 bo->gem_handle = open_arg.handle;
571 bo->name = name;
572 bo->global_name = handle;
573 bo->reusable = false;
574 bo->external = true;
575 bo->kflags = 0;
577 _mesa_hash_table_insert(bufmgr->handle_table, &bo->gem_handle, bo);
578 _mesa_hash_table_insert(bufmgr->name_table, &bo->global_name, bo);
580 struct drm_i915_gem_get_tiling get_tiling = { .handle = bo->gem_handle };
585 bo->tiling_mode = get_tiling.tiling_mode;
586 bo->swizzle_mode = get_tiling.swizzle_mode;
588 DBG("bo_create_from_handle: %d (%s)\n", handle, bo->name);
592 return bo;
595 bo_free(bo);
601 bo_close(struct crocus_bo *bo)
603 struct crocus_bufmgr *bufmgr = bo->bufmgr;
605 if (bo->external) {
608 if (bo->global_name) {
609 entry = _mesa_hash_table_search(bufmgr->name_table, &bo->global_name);
613 entry = _mesa_hash_table_search(bufmgr->handle_table, &bo->gem_handle);
616 list_for_each_entry_safe(struct bo_export, export, &bo->exports, link) {
624 assert(list_is_empty(&bo->exports));
628 struct drm_gem_close close = { .handle = bo->gem_handle };
632 bo->gem_handle, bo->name, strerror(errno));
635 free(bo);
639 bo_free(struct crocus_bo *bo)
641 struct crocus_bufmgr *bufmgr = bo->bufmgr;
643 if (bo->map_cpu && !bo->userptr) {
644 VG_NOACCESS(bo->map_cpu, bo->size);
645 munmap(bo->map_cpu, bo->size);
647 if (bo->map_wc) {
648 VG_NOACCESS(bo->map_wc, bo->size);
649 munmap(bo->map_wc, bo->size);
651 if (bo->map_gtt) {
652 VG_NOACCESS(bo->map_gtt, bo->size);
653 munmap(bo->map_gtt, bo->size);
656 if (bo->idle) {
657 bo_close(bo);
662 list_addtail(&bo->head, &bufmgr->zombie_list);
678 list_for_each_entry_safe(struct crocus_bo, bo, &bucket->head, head) {
679 if (time - bo->free_time <= 1)
682 list_del(&bo->head);
684 bo_free(bo);
688 list_for_each_entry_safe(struct crocus_bo, bo, &bufmgr->zombie_list, head) {
692 if (!bo->idle && crocus_bo_busy(bo))
695 list_del(&bo->head);
696 bo_close(bo);
703 bo_unreference_final(struct crocus_bo *bo, time_t time)
705 struct crocus_bufmgr *bufmgr = bo->bufmgr;
708 DBG("bo_unreference final: %d (%s)\n", bo->gem_handle, bo->name);
711 if (bo->reusable)
712 bucket = bucket_for_size(bufmgr, bo->size);
714 if (bucket && crocus_bo_madvise(bo, I915_MADV_DONTNEED)) {
715 bo->free_time = time;
716 bo->name = NULL;
718 list_addtail(&bo->head, &bucket->head);
720 bo_free(bo);
725 __crocus_bo_unreference(struct crocus_bo *bo)
727 struct crocus_bufmgr *bufmgr = bo->bufmgr;
734 if (p_atomic_dec_zero(&bo->refcount)) {
735 bo_unreference_final(bo, time.tv_sec);
744 struct crocus_bo *bo,
747 bool busy = dbg && !bo->idle;
750 crocus_bo_wait_rendering(bo);
756 action, bo->name, elapsed * 1000);
781 struct crocus_bo *bo, bool wc)
783 struct crocus_bufmgr *bufmgr = bo->bufmgr;
786 .handle = bo->gem_handle,
787 .size = bo->size,
794 __FILE__, __LINE__, bo->gem_handle, bo->name, strerror(errno));
803 crocus_bo_gem_mmap_offset(struct util_debug_callback *dbg, struct crocus_bo *bo,
806 struct crocus_bufmgr *bufmgr = bo->bufmgr;
809 .handle = bo->gem_handle,
817 __FILE__, __LINE__, bo->gem_handle, bo->name, strerror(errno));
822 void *map = mmap(0, bo->size, PROT_READ | PROT_WRITE, MAP_SHARED,
826 __FILE__, __LINE__, bo->gem_handle, bo->name, strerror(errno));
834 crocus_bo_gem_mmap(struct util_debug_callback *dbg, struct crocus_bo *bo, bool wc)
836 struct crocus_bufmgr *bufmgr = bo->bufmgr;
839 return crocus_bo_gem_mmap_offset(dbg, bo, wc);
841 return crocus_bo_gem_mmap_legacy(dbg, bo, wc);
846 struct crocus_bo *bo, unsigned flags)
852 assert(bo->cache_coherent || !(flags & MAP_WRITE));
854 if (!bo->map_cpu) {
855 DBG("crocus_bo_map_cpu: %d (%s)\n", bo->gem_handle, bo->name);
857 void *map = crocus_bo_gem_mmap(dbg, bo, false);
862 VG_DEFINED(map, bo->size);
864 if (p_atomic_cmpxchg(&bo->map_cpu, NULL, map)) {
865 VG_NOACCESS(map, bo->size);
866 munmap(map, bo->size);
869 assert(bo->map_cpu);
871 DBG("crocus_bo_map_cpu: %d (%s) -> %p, ", bo->gem_handle, bo->name,
872 bo->map_cpu);
876 bo_wait_with_stall_warning(dbg, bo, "CPU mapping");
879 if (!bo->cache_coherent && !bo->bufmgr->has_llc) {
896 intel_invalidate_range(bo->map_cpu, bo->size);
899 return bo->map_cpu;
904 struct crocus_bo *bo, unsigned flags)
906 if (!bo->map_wc) {
907 DBG("crocus_bo_map_wc: %d (%s)\n", bo->gem_handle, bo->name);
909 void *map = crocus_bo_gem_mmap(dbg, bo, true);
914 VG_DEFINED(map, bo->size);
916 if (p_atomic_cmpxchg(&bo->map_wc, NULL, map)) {
917 VG_NOACCESS(map, bo->size);
918 munmap(map, bo->size);
921 assert(bo->map_wc);
923 DBG("crocus_bo_map_wc: %d (%s) -> %p\n", bo->gem_handle, bo->name, bo->map_wc);
927 bo_wait_with_stall_warning(dbg, bo, "WC mapping");
930 return bo->map_wc;
957 struct crocus_bo *bo, unsigned flags)
959 struct crocus_bufmgr *bufmgr = bo->bufmgr;
967 if (bo->map_gtt == NULL) {
968 DBG("bo_map_gtt: mmap %d (%s)\n", bo->gem_handle, bo->name);
970 struct drm_i915_gem_mmap_gtt mmap_arg = { .handle = bo->gem_handle };
976 __FILE__, __LINE__, bo->gem_handle, bo->name, strerror(errno));
981 void *map = mmap(0, bo->size, PROT_READ | PROT_WRITE,
985 __FILE__, __LINE__, bo->gem_handle, bo->name, strerror(errno));
994 VG_DEFINED(map, bo->size);
996 if (p_atomic_cmpxchg(&bo->map_gtt, NULL, map)) {
997 VG_NOACCESS(map, bo->size);
998 munmap(map, bo->size);
1001 assert(bo->map_gtt);
1003 DBG("bo_map_gtt: %d (%s) -> %p, ", bo->gem_handle, bo->name, bo->map_gtt);
1007 bo_wait_with_stall_warning(dbg, bo, "GTT mapping");
1010 return bo->map_gtt;
1014 can_map_cpu(struct crocus_bo *bo, unsigned flags)
1016 if (bo->scanout)
1019 if (bo->cache_coherent)
1027 if (!(flags & MAP_WRITE) && bo->bufmgr->has_llc)
1032 * bo, invalidating continued access to the CPU mmap on non-LLC device.
1052 struct crocus_bo *bo, unsigned flags)
1054 if (bo->tiling_mode != I915_TILING_NONE && !(flags & MAP_RAW))
1055 return crocus_bo_map_gtt(dbg, bo, flags);
1059 if (can_map_cpu(bo, flags))
1060 map = crocus_bo_map_cpu(dbg, bo, flags);
1062 map = crocus_bo_map_wc(dbg, bo, flags);
1077 bo->name, flags);
1078 map = crocus_bo_map_gtt(dbg, bo, flags);
1086 crocus_bo_wait_rendering(struct crocus_bo *bo)
1091 crocus_bo_wait(bo, -1);
1097 * @bo: buffer object to wait for
1122 crocus_bo_wait(struct crocus_bo *bo, int64_t timeout_ns)
1124 struct crocus_bufmgr *bufmgr = bo->bufmgr;
1127 if (bo->idle && !bo->external)
1131 .bo_handle = bo->gem_handle,
1138 bo->idle = true;
1152 list_for_each_entry_safe(struct crocus_bo, bo, &bucket->head, head) {
1153 list_del(&bo->head);
1155 bo_free(bo);
1160 list_for_each_entry_safe(struct crocus_bo, bo, &bufmgr->zombie_list, head) {
1161 list_del(&bo->head);
1162 bo_close(bo);
1174 bo_set_tiling_internal(struct crocus_bo *bo, uint32_t tiling_mode,
1177 struct crocus_bufmgr *bufmgr = bo->bufmgr;
1181 if (bo->global_name == 0 &&
1182 tiling_mode == bo->tiling_mode && stride == bo->stride)
1191 set_tiling.handle = bo->gem_handle;
1200 bo->tiling_mode = set_tiling.tiling_mode;
1201 bo->swizzle_mode = set_tiling.swizzle_mode;
1202 bo->stride = set_tiling.stride;
1207 crocus_bo_get_tiling(struct crocus_bo *bo, uint32_t *tiling_mode,
1210 *tiling_mode = bo->tiling_mode;
1211 *swizzle_mode = bo->swizzle_mode;
1220 struct crocus_bo *bo;
1233 * for named buffers, we must not create two bo's pointing at the same
1236 bo = find_and_ref_external_bo(bufmgr->handle_table, handle);
1237 if (bo)
1240 bo = bo_calloc();
1241 if (!bo)
1244 p_atomic_set(&bo->refcount, 1);
1246 /* Determine size of bo. The fd-to-handle ioctl really should
1253 bo->size = ret;
1255 bo->bufmgr = bufmgr;
1256 bo->name = "prime";
1257 bo->reusable = false;
1258 bo->external = true;
1259 bo->kflags = 0;
1260 bo->gem_handle = handle;
1261 _mesa_hash_table_insert(bufmgr->handle_table, &bo->gem_handle, bo);
1266 bo->tiling_mode = isl_tiling_to_i915_tiling(mod_info->tiling);
1268 struct drm_i915_gem_get_tiling get_tiling = { .handle = bo->gem_handle };
1272 bo->tiling_mode = get_tiling.tiling_mode;
1274 bo->tiling_mode = I915_TILING_NONE;
1279 return bo;
1282 bo_free(bo);
1292 struct crocus_bo *bo;
1305 * for named buffers, we must not create two bo's pointing at the same
1308 bo = find_and_ref_external_bo(bufmgr->handle_table, handle);
1309 if (bo)
1312 bo = bo_calloc();
1313 if (!bo)
1316 p_atomic_set(&bo->refcount, 1);
1318 /* Determine size of bo. The fd-to-handle ioctl really should
1325 bo->size = ret;
1327 bo->bufmgr = bufmgr;
1328 bo->name = "prime";
1329 bo->reusable = false;
1330 bo->external = true;
1331 bo->kflags = 0;
1332 bo->gem_handle = handle;
1333 _mesa_hash_table_insert(bufmgr->handle_table, &bo->gem_handle, bo);
1337 return bo;
1341 crocus_bo_make_external_locked(struct crocus_bo *bo)
1343 if (!bo->external) {
1344 _mesa_hash_table_insert(bo->bufmgr->handle_table, &bo->gem_handle, bo);
1345 bo->external = true;
1346 bo->reusable = false;
1351 crocus_bo_make_external(struct crocus_bo *bo)
1353 struct crocus_bufmgr *bufmgr = bo->bufmgr;
1355 if (bo->external) {
1356 assert(!bo->reusable);
1361 crocus_bo_make_external_locked(bo);
1366 crocus_bo_export_dmabuf(struct crocus_bo *bo, int *prime_fd)
1368 struct crocus_bufmgr *bufmgr = bo->bufmgr;
1370 crocus_bo_make_external(bo);
1372 if (drmPrimeHandleToFD(bufmgr->fd, bo->gem_handle,
1380 crocus_bo_export_gem_handle(struct crocus_bo *bo)
1382 crocus_bo_make_external(bo);
1384 return bo->gem_handle;
1388 crocus_bo_flink(struct crocus_bo *bo, uint32_t *name)
1390 struct crocus_bufmgr *bufmgr = bo->bufmgr;
1392 if (!bo->global_name) {
1393 struct drm_gem_flink flink = { .handle = bo->gem_handle };
1399 if (!bo->global_name) {
1400 crocus_bo_make_external_locked(bo);
1401 bo->global_name = flink.name;
1402 _mesa_hash_table_insert(bufmgr->name_table, &bo->global_name, bo);
1407 *name = bo->global_name;
1412 crocus_bo_export_gem_handle_for_device(struct crocus_bo *bo, int drm_fd,
1419 struct crocus_bufmgr *bufmgr = bo->bufmgr;
1425 *out_handle = crocus_bo_export_gem_handle(bo);
1436 int err = crocus_bo_export_dmabuf(bo, &dmabuf_fd);
1452 list_for_each_entry(struct bo_export, iter, &bo->exports, link) {
1465 list_addtail(&export->link, &bo->exports);