Lines Matching refs:kgem
58 search_linear_cache(struct kgem *kgem, unsigned int num_pages, unsigned flags);
61 search_snoop_cache(struct kgem *kgem, unsigned int num_pages, unsigned flags);
249 static void debug_alloc(struct kgem *kgem, size_t size)
251 kgem->debug_memory.bo_allocs++;
252 kgem->debug_memory.bo_bytes += size;
254 static void debug_alloc__bo(struct kgem *kgem, struct kgem_bo *bo)
256 debug_alloc(kgem, bytes(bo));
263 static void assert_tiling(struct kgem *kgem, struct kgem_bo *bo)
272 (void)do_ioctl(kgem->fd, DRM_IOCTL_I915_GEM_GET_TILING, &tiling);
276 static void assert_cacheing(struct kgem *kgem, struct kgem_bo *bo)
279 int expect = kgem->has_llc ? SNOOPED : UNCACHED;
285 (void)do_ioctl(kgem->fd, LOCAL_IOCTL_I915_GEM_GET_CACHING, &arg);
300 #define assert_tiling(kgem, bo)
301 #define assert_cacheing(kgem, bo)
306 __kgem_set_wedged(struct kgem *kgem)
308 kgem->wedged = true;
309 sna_render_mark_wedged(container_of(kgem, struct sna, kgem));
312 static void kgem_sna_reset(struct kgem *kgem)
314 struct sna *sna = container_of(kgem, struct sna, kgem);
320 static void kgem_sna_flush(struct kgem *kgem)
322 struct sna *sna = container_of(kgem, struct sna, kgem);
393 static bool __kgem_throttle(struct kgem *kgem, bool harder)
400 if (ioctl(kgem->fd, DRM_IOCTL_I915_GEM_THROTTLE) == 0) {
401 kgem->need_throttle = 0;
412 static bool __kgem_throttle_retire(struct kgem *kgem, unsigned flags)
414 if (flags & CREATE_NO_RETIRE || !kgem->need_retire) {
419 if (kgem_retire(kgem))
422 if (flags & CREATE_NO_THROTTLE || !kgem->need_throttle) {
427 __kgem_throttle(kgem, false);
428 return kgem_retire(kgem);
431 static void *__kgem_bo_map__gtt(struct kgem *kgem, struct kgem_bo *bo)
443 if ((err = do_ioctl(kgem->fd, DRM_IOCTL_I915_GEM_MMAP_GTT, >t))) {
446 (void)__kgem_throttle_retire(kgem, 0);
447 if (kgem_expire_cache(kgem))
450 if (kgem_cleanup_cache(kgem))
460 kgem->fd, gtt.offset);
465 if (__kgem_throttle_retire(kgem, 0))
468 if (kgem_cleanup_cache(kgem))
484 static void *__kgem_bo_map__wc(struct kgem *kgem, struct kgem_bo *bo)
491 assert(kgem->has_wc_mmap);
500 if ((err = do_ioctl(kgem->fd, LOCAL_IOCTL_I915_GEM_MMAP_v2, &wc))) {
503 if (__kgem_throttle_retire(kgem, 0))
506 if (kgem_cleanup_cache(kgem))
520 static void *__kgem_bo_map__cpu(struct kgem *kgem, struct kgem_bo *bo)
531 if ((err = do_ioctl(kgem->fd, DRM_IOCTL_I915_GEM_MMAP, &mmap_arg))) {
534 if (__kgem_throttle_retire(kgem, 0))
537 if (kgem_cleanup_cache(kgem))
616 bool __kgem_busy(struct kgem *kgem, int handle)
622 busy.busy = !kgem->wedged;
623 (void)do_ioctl(kgem->fd, DRM_IOCTL_I915_GEM_BUSY, &busy);
625 __FUNCTION__, handle, busy.busy, kgem->wedged));
630 static void kgem_bo_retire(struct kgem *kgem, struct kgem_bo *bo)
634 __kgem_busy(kgem, bo->handle)));
640 kgem_retire(kgem);
646 ASSERT_IDLE(kgem, bo->handle);
650 static void kgem_bo_maybe_retire(struct kgem *kgem, struct kgem_bo *bo)
654 __kgem_busy(kgem, bo->handle)));
659 if (!__kgem_busy(kgem, bo->handle)) {
661 kgem_retire(kgem);
665 ASSERT_IDLE(kgem, bo->handle);
669 bool kgem_bo_write(struct kgem *kgem, struct kgem_bo *bo,
677 ASSERT_IDLE(kgem, bo->handle);
682 if (bo->domain == DOMAIN_CPU || (kgem->has_llc && !bo->scanout)) {
685 ptr = __kgem_bo_map__cpu(kgem, bo);
686 } else if (kgem->has_wc_mmap) {
689 ptr = __kgem_bo_map__wc(kgem, bo);
697 if ((err = gem_write(kgem->fd, bo->handle, 0, length, data))) {
700 (void)__kgem_throttle_retire(kgem, 0);
701 if (kgem_expire_cache(kgem))
704 if (kgem_cleanup_cache(kgem))
714 kgem_bo_maybe_retire(kgem, bo);
733 kgem_bo_set_purgeable(struct kgem *kgem, struct kgem_bo *bo)
746 if (do_ioctl(kgem->fd, DRM_IOCTL_I915_GEM_MADVISE, &madv) == 0) {
748 kgem->need_purge |= !madv.retained && bo->domain == DOMAIN_GPU;
757 kgem_bo_is_retained(struct kgem *kgem, struct kgem_bo *bo)
770 if (do_ioctl(kgem->fd, DRM_IOCTL_I915_GEM_MADVISE, &madv) == 0)
778 kgem_bo_clear_purgeable(struct kgem *kgem, struct kgem_bo *bo)
790 if (do_ioctl(kgem->fd, DRM_IOCTL_I915_GEM_MADVISE, &madv) == 0) {
792 kgem->need_purge |= !madv.retained && bo->domain == DOMAIN_GPU;
869 static struct kgem_request *__kgem_request_alloc(struct kgem *kgem)
879 rq = &kgem->static_request;
900 static struct list *inactive(struct kgem *kgem, int num_pages)
904 return &kgem->inactive[cache_bucket(num_pages)];
907 static struct list *active(struct kgem *kgem, int num_pages, int tiling)
911 return &kgem->active[cache_bucket(num_pages)][tiling];
1016 static int gem_param(struct kgem *kgem, int name)
1024 if (do_ioctl(kgem->fd, DRM_IOCTL_I915_GETPARAM, &gp))
1031 static bool test_has_execbuffer2(struct kgem *kgem)
1038 return do_ioctl(kgem->fd,
1043 static bool test_has_no_reloc(struct kgem *kgem)
1048 return gem_param(kgem, LOCAL_I915_PARAM_HAS_NO_RELOC) > 0;
1051 static bool test_has_handle_lut(struct kgem *kgem)
1056 return gem_param(kgem, LOCAL_I915_PARAM_HAS_HANDLE_LUT) > 0;
1059 static bool test_has_wt(struct kgem *kgem)
1064 return gem_param(kgem, LOCAL_I915_PARAM_HAS_WT) > 0;
1067 static bool test_has_semaphores_enabled(struct kgem *kgem)
1076 ret = gem_param(kgem, LOCAL_I915_PARAM_HAS_SEMAPHORES);
1091 static bool is_hw_supported(struct kgem *kgem,
1097 if (!test_has_execbuffer2(kgem))
1100 if (kgem->gen == (unsigned)-1) /* unknown chipset, assume future gen */
1101 return kgem->has_blt;
1108 if (kgem->gen == 060 && dev && dev->revision < 8) {
1113 if (kgem->gen >= 060) /* Only if the kernel supports the BLT ring */
1114 return kgem->has_blt;
1119 static bool test_has_relaxed_fencing(struct kgem *kgem)
1121 if (kgem->gen < 040) {
1125 return gem_param(kgem, LOCAL_I915_PARAM_HAS_RELAXED_FENCING) > 0;
1130 static bool test_has_llc(struct kgem *kgem)
1137 has_llc = gem_param(kgem, LOCAL_I915_PARAM_HAS_LLC);
1140 has_llc = kgem->gen >= 060;
1146 static bool test_has_wc_mmap(struct kgem *kgem)
1154 if (gem_param(kgem, LOCAL_I915_PARAM_MMAP_VERSION) < 1)
1158 wc.handle = gem_create(kgem->fd, 1);
1162 ret = do_ioctl(kgem->fd, LOCAL_IOCTL_I915_GEM_MMAP_v2, &wc) == 0;
1163 gem_close(kgem->fd, wc.handle);
1168 static bool test_has_caching(struct kgem *kgem)
1177 if (kgem->gen == 040)
1180 handle = gem_create(kgem->fd, 1);
1184 ret = gem_set_caching(kgem->fd, handle, UNCACHED);
1185 gem_close(kgem->fd, handle);
1189 static bool test_has_userptr(struct kgem *kgem)
1198 if (kgem->gen == 040)
1204 handle = gem_userptr(kgem->fd, ptr, PAGE_SIZE, false);
1205 gem_close(kgem->fd, handle);
1211 static bool test_has_create2(struct kgem *kgem)
1222 if (do_ioctl(kgem->fd, LOCAL_IOCTL_I915_GEM_CREATE2, &args) == 0)
1223 gem_close(kgem->fd, args.handle);
1231 static bool test_has_secure_batches(struct kgem *kgem)
1236 return gem_param(kgem, LOCAL_I915_PARAM_HAS_SECURE_BATCHES) > 0;
1239 static bool test_has_pinned_batches(struct kgem *kgem)
1244 return gem_param(kgem, LOCAL_I915_PARAM_HAS_PINNED_BATCHES) > 0;
1247 static int kgem_get_screen_index(struct kgem *kgem)
1249 struct sna *sna = container_of(kgem, struct sna, kgem);
1253 static int __find_debugfs(struct kgem *kgem)
1272 static int kgem_get_minor(struct kgem *kgem)
1276 if (fstat(kgem->fd, &st))
1277 return __find_debugfs(kgem);
1280 return __find_debugfs(kgem);
1285 static bool kgem_init_pinned_batches(struct kgem *kgem)
1291 if (kgem->wedged)
1301 pin.handle = gem_create(kgem->fd, size[n]);
1310 gem_close(kgem->fd, pin.handle);
1315 if (do_ioctl(kgem->fd, DRM_IOCTL_I915_GEM_PIN, &pin)) {
1316 gem_close(kgem->fd, pin.handle);
1321 debug_alloc__bo(kgem, bo);
1322 list_add(&bo->list, &kgem->pinned_batches[n]);
1329 for (n = 0; n < ARRAY_SIZE(kgem->pinned_batches); n++) {
1330 while (!list_is_empty(&kgem->pinned_batches[n])) {
1331 kgem_bo_destroy(kgem,
1332 list_first_entry(&kgem->pinned_batches[n],
1342 handle = gem_create(kgem->fd, size[n]);
1348 gem_close(kgem->fd, handle);
1352 debug_alloc__bo(kgem, bo);
1353 list_add(&bo->list, &kgem->pinned_batches[n]);
1358 static void kgem_init_swizzling(struct kgem *kgem)
1369 tiling.handle = gem_create(kgem->fd, 1);
1373 if (!gem_set_tiling(kgem->fd, tiling.handle, I915_TILING_X, 512))
1376 if (do_ioctl(kgem->fd, LOCAL_IOCTL_I915_GEM_GET_TILING, &tiling))
1379 if (kgem->gen < 50 && tiling.phys_swizzle_mode != tiling.swizzle_mode)
1382 choose_memcpy_tiled_x(kgem, tiling.swizzle_mode);
1384 gem_close(kgem->fd, tiling.handle);
1387 static void kgem_fixup_relocs(struct kgem *kgem, struct kgem_bo *bo, int shrink)
1391 bo->target_handle = kgem->has_handle_lut ? kgem->nexec : bo->handle;
1393 assert(kgem->nreloc__self <= 256);
1394 if (kgem->nreloc__self == 0)
1398 __FUNCTION__, kgem->nreloc__self,
1399 kgem->nreloc__self == 256 ? "+" : "",
1401 for (n = 0; n < kgem->nreloc__self; n++) {
1402 int i = kgem->reloc__self[n];
1404 assert(kgem->reloc[i].target_handle == ~0U);
1405 kgem->reloc[i].target_handle = bo->target_handle;
1406 kgem->reloc[i].presumed_offset = bo->presumed_offset;
1408 if (kgem->reloc[i].read_domains == I915_GEM_DOMAIN_INSTRUCTION) {
1411 kgem->reloc[i].delta,
1412 kgem->reloc[i].delta - shrink));
1414 kgem->reloc[i].delta -= shrink;
1416 kgem->batch[kgem->reloc[i].offset/sizeof(uint32_t)] =
1417 kgem->reloc[i].delta + bo->presumed_offset;
1421 for (n = kgem->reloc__self[255]; n < kgem->nreloc; n++) {
1422 if (kgem->reloc[n].target_handle == ~0U) {
1423 kgem->reloc[n].target_handle = bo->target_handle;
1424 kgem->reloc[n].presumed_offset = bo->presumed_offset;
1426 if (kgem->reloc[n].read_domains == I915_GEM_DOMAIN_INSTRUCTION) {
1429 kgem->reloc[n].delta,
1430 kgem->reloc[n].delta - shrink));
1431 kgem->reloc[n].delta -= shrink;
1433 kgem->batch[kgem->reloc[n].offset/sizeof(uint32_t)] =
1434 kgem->reloc[n].delta + bo->presumed_offset;
1441 for (n = 0; n < kgem->nreloc; n++) {
1442 if (kgem->reloc[n].offset >= sizeof(uint32_t)*kgem->nbatch)
1443 kgem->reloc[n].offset -= shrink;
1448 static struct kgem_bo *kgem_new_batch(struct kgem *kgem)
1453 last = kgem->batch_bo;
1455 kgem_fixup_relocs(kgem, last, 0);
1456 kgem->batch = NULL;
1459 if (kgem->batch) {
1465 if (!kgem->has_llc)
1468 kgem->batch_bo = kgem_create_linear(kgem,
1469 sizeof(uint32_t)*kgem->batch_size,
1471 if (kgem->batch_bo)
1472 kgem->batch = kgem_bo_map__cpu(kgem, kgem->batch_bo);
1473 if (kgem->batch == NULL) {
1476 sizeof(uint32_t)*kgem->batch_size));
1477 if (kgem->batch_bo) {
1478 kgem_bo_destroy(kgem, kgem->batch_bo);
1479 kgem->batch_bo = NULL;
1482 if (posix_memalign((void **)&kgem->batch, PAGE_SIZE,
1483 ALIGN(sizeof(uint32_t) * kgem->batch_size, PAGE_SIZE))) {
1485 __kgem_set_wedged(kgem);
1489 __FUNCTION__, kgem->batch_bo->handle,
1490 sizeof(uint32_t)*kgem->batch_size));
1491 kgem_bo_sync__cpu(kgem, kgem->batch_bo);
1499 void kgem_init(struct kgem *kgem, int fd, struct pci_device *dev, unsigned gen)
1508 kgem->fd = fd;
1509 kgem->gen = gen;
1511 list_init(&kgem->requests[0]);
1512 list_init(&kgem->requests[1]);
1513 list_init(&kgem->batch_buffers);
1514 list_init(&kgem->active_buffers);
1515 list_init(&kgem->flushing);
1516 list_init(&kgem->large);
1517 list_init(&kgem->large_inactive);
1518 list_init(&kgem->snoop);
1519 list_init(&kgem->scanout);
1520 for (i = 0; i < ARRAY_SIZE(kgem->pinned_batches); i++)
1521 list_init(&kgem->pinned_batches[i]);
1522 for (i = 0; i < ARRAY_SIZE(kgem->inactive); i++)
1523 list_init(&kgem->inactive[i]);
1524 for (i = 0; i < ARRAY_SIZE(kgem->active); i++) {
1525 for (j = 0; j < ARRAY_SIZE(kgem->active[i]); j++)
1526 list_init(&kgem->active[i][j]);
1528 for (i = 0; i < ARRAY_SIZE(kgem->vma); i++) {
1529 for (j = 0; j < ARRAY_SIZE(kgem->vma[i].inactive); j++)
1530 list_init(&kgem->vma[i].inactive[j]);
1532 kgem->vma[MAP_GTT].count = -MAX_GTT_VMA_CACHE;
1533 kgem->vma[MAP_CPU].count = -MAX_CPU_VMA_CACHE;
1535 kgem->has_blt = gem_param(kgem, LOCAL_I915_PARAM_HAS_BLT) > 0;
1537 kgem->has_blt));
1539 kgem->has_relaxed_delta =
1540 gem_param(kgem, LOCAL_I915_PARAM_HAS_RELAXED_DELTA) > 0;
1542 kgem->has_relaxed_delta));
1544 kgem->has_relaxed_fencing = test_has_relaxed_fencing(kgem);
1546 kgem->has_relaxed_fencing));
1548 kgem->has_llc = test_has_llc(kgem);
1550 kgem->has_llc));
1552 kgem->has_wt = test_has_wt(kgem);
1554 kgem->has_wt));
1556 kgem->has_wc_mmap = test_has_wc_mmap(kgem);
1558 kgem->has_wc_mmap));
1560 kgem->has_caching = test_has_caching(kgem);
1562 kgem->has_caching));
1564 kgem->has_userptr = test_has_userptr(kgem);
1566 kgem->has_userptr));
1568 kgem->has_create2 = test_has_create2(kgem);
1570 kgem->has_create2));
1572 kgem->has_no_reloc = test_has_no_reloc(kgem);
1574 kgem->has_no_reloc));
1576 kgem->has_handle_lut = test_has_handle_lut(kgem);
1578 kgem->has_handle_lut));
1580 kgem->has_semaphores = false;
1581 if (kgem->has_blt && test_has_semaphores_enabled(kgem))
1582 kgem->has_semaphores = true;
1584 kgem->has_semaphores));
1586 kgem->can_blt_cpu = gen >= 030;
1588 kgem->can_blt_cpu));
1590 kgem->can_render_y = gen != 021 && (gen >> 3) != 4;
1592 kgem->can_render_y));
1594 kgem->has_secure_batches = test_has_secure_batches(kgem);
1596 kgem->has_secure_batches));
1598 kgem->has_pinned_batches = test_has_pinned_batches(kgem);
1600 kgem->has_pinned_batches));
1602 if (!is_hw_supported(kgem, dev)) {
1603 xf86DrvMsg(kgem_get_screen_index(kgem), X_WARNING,
1605 __kgem_set_wedged(kgem);
1606 } else if (__kgem_throttle(kgem, false)) {
1607 xf86DrvMsg(kgem_get_screen_index(kgem), X_WARNING,
1609 __kgem_set_wedged(kgem);
1612 kgem->batch_size = UINT16_MAX & ~7;
1613 if (gen == 020 && !kgem->has_pinned_batches)
1615 kgem->batch_size = 4*1024;
1618 kgem->batch_size = PAGE_SIZE / sizeof(uint32_t);
1620 kgem->batch_size = 16*1024;
1621 if (!kgem->has_relaxed_delta && kgem->batch_size > 4*1024)
1622 kgem->batch_size = 4*1024;
1624 if (!kgem_init_pinned_batches(kgem) && gen == 020) {
1625 xf86DrvMsg(kgem_get_screen_index(kgem), X_WARNING,
1627 __kgem_set_wedged(kgem);
1631 kgem->batch_size));
1632 kgem_new_batch(kgem);
1634 kgem->half_cpu_cache_pages = cpu_cache_size() >> 13;
1636 __FUNCTION__, cpu_cache_size(), kgem->half_cpu_cache_pages));
1638 kgem->next_request = __kgem_request_alloc(kgem);
1641 !DBG_NO_CPU && (kgem->has_llc | kgem->has_userptr | kgem->has_caching),
1642 kgem->has_llc, kgem->has_caching, kgem->has_userptr));
1655 kgem->aperture_total = aperture.aper_size;
1656 kgem->aperture_high = aperture.aper_size * 3/4;
1657 kgem->aperture_low = aperture.aper_size * 1/3;
1660 kgem->aperture_high /= 2;
1661 kgem->aperture_low /= 2;
1664 kgem->aperture_low, kgem->aperture_low / (1024*1024),
1665 kgem->aperture_high, kgem->aperture_high / (1024*1024)));
1667 kgem->aperture_mappable = 256 * 1024 * 1024;
1669 kgem->aperture_mappable = agp_aperture_size(dev, gen);
1670 if (kgem->aperture_mappable == 0 ||
1671 kgem->aperture_mappable > aperture.aper_size)
1672 kgem->aperture_mappable = aperture.aper_size;
1674 kgem->aperture_mappable, kgem->aperture_mappable / (1024*1024)));
1676 kgem->aperture_fenceable = MIN(256*1024*1024, kgem->aperture_mappable);
1678 kgem->aperture_fenceable, kgem->aperture_fenceable / (1024*1024)));
1680 kgem->buffer_size = 64 * 1024;
1681 while (kgem->buffer_size < kgem->aperture_mappable >> 10)
1682 kgem->buffer_size *= 2;
1683 if (kgem->buffer_size >> 12 > kgem->half_cpu_cache_pages)
1684 kgem->buffer_size = kgem->half_cpu_cache_pages << 12;
1685 kgem->buffer_size = 1 << __fls(kgem->buffer_size);
1687 kgem->buffer_size, kgem->buffer_size / 1024));
1688 assert(kgem->buffer_size);
1690 kgem->max_object_size = 3 * (kgem->aperture_high >> 12) << 10;
1691 kgem->max_gpu_size = kgem->max_object_size;
1692 if (!kgem->has_llc && kgem->max_gpu_size > MAX_CACHE_SIZE)
1693 kgem->max_gpu_size = MAX_CACHE_SIZE;
1699 totalram = kgem->aperture_total;
1702 if (kgem->max_object_size > totalram / 2)
1703 kgem->max_object_size = totalram / 2;
1704 if (kgem->max_gpu_size > totalram / 4)
1705 kgem->max_gpu_size = totalram / 4;
1707 if (kgem->aperture_high > totalram / 2) {
1708 kgem->aperture_high = totalram / 2;
1709 kgem->aperture_low = kgem->aperture_high / 4;
1711 kgem->aperture_low, kgem->aperture_low / (1024*1024),
1712 kgem->aperture_high, kgem->aperture_high / (1024*1024)));
1715 kgem->max_cpu_size = kgem->max_object_size;
1717 half_gpu_max = kgem->max_gpu_size / 2;
1718 kgem->max_copy_tile_size = (MAX_CACHE_SIZE + 1)/2;
1719 if (kgem->max_copy_tile_size > half_gpu_max)
1720 kgem->max_copy_tile_size = half_gpu_max;
1722 if (kgem->has_llc)
1723 kgem->max_upload_tile_size = kgem->max_copy_tile_size;
1725 kgem->max_upload_tile_size = kgem->aperture_fenceable / 4;
1726 if (kgem->max_upload_tile_size > half_gpu_max)
1727 kgem->max_upload_tile_size = half_gpu_max;
1728 if (kgem->max_upload_tile_size > kgem->aperture_high/2)
1729 kgem->max_upload_tile_size = kgem->aperture_high/2;
1730 if (kgem->max_upload_tile_size > kgem->aperture_low)
1731 kgem->max_upload_tile_size = kgem->aperture_low;
1732 if (kgem->max_upload_tile_size < 16*PAGE_SIZE)
1733 kgem->max_upload_tile_size = 16*PAGE_SIZE;
1735 kgem->large_object_size = MAX_CACHE_SIZE;
1736 if (kgem->large_object_size > half_gpu_max)
1737 kgem->large_object_size = half_gpu_max;
1738 if (kgem->max_copy_tile_size > kgem->aperture_high/2)
1739 kgem->max_copy_tile_size = kgem->aperture_high/2;
1740 if (kgem->max_copy_tile_size > kgem->aperture_low)
1741 kgem->max_copy_tile_size = kgem->aperture_low;
1742 if (kgem->max_copy_tile_size < 16*PAGE_SIZE)
1743 kgem->max_copy_tile_size = 16*PAGE_SIZE;
1745 if (kgem->has_llc | kgem->has_caching | kgem->has_userptr) {
1746 if (kgem->large_object_size > kgem->max_cpu_size)
1747 kgem->large_object_size = kgem->max_cpu_size;
1749 kgem->max_cpu_size = 0;
1751 kgem->max_cpu_size = 0;
1754 __FUNCTION__, kgem->max_object_size));
1756 __FUNCTION__, kgem->large_object_size));
1759 kgem->max_gpu_size, kgem->max_cpu_size,
1760 kgem->max_upload_tile_size, kgem->max_copy_tile_size));
1763 kgem->aperture_mappable /= PAGE_SIZE;
1764 kgem->aperture_fenceable /= PAGE_SIZE;
1765 kgem->aperture_low /= PAGE_SIZE;
1766 kgem->aperture_high /= PAGE_SIZE;
1767 kgem->aperture_total /= PAGE_SIZE;
1769 kgem->fence_max = gem_param(kgem, I915_PARAM_NUM_FENCES_AVAIL) - 2;
1770 if ((int)kgem->fence_max < 0)
1771 kgem->fence_max = 5; /* minimum safe value for all hw */
1772 DBG(("%s: max fences=%d\n", __FUNCTION__, kgem->fence_max));
1774 kgem->batch_flags_base = 0;
1775 if (kgem->has_no_reloc)
1776 kgem->batch_flags_base |= LOCAL_I915_EXEC_NO_RELOC;
1777 if (kgem->has_handle_lut)
1778 kgem->batch_flags_base |= LOCAL_I915_EXEC_HANDLE_LUT;
1779 if (kgem->has_pinned_batches)
1780 kgem->batch_flags_base |= LOCAL_I915_EXEC_IS_PINNED;
1782 kgem_init_swizzling(kgem);
1786 static uint32_t kgem_get_unique_id(struct kgem *kgem)
1789 id = ++kgem->unique_id;
1791 id = ++kgem->unique_id;
1795 inline static uint32_t kgem_pitch_alignment(struct kgem *kgem, unsigned flags)
1801 if (kgem->gen >= 0100)
1806 void kgem_get_tile_size(struct kgem *kgem, int tiling, int pitch,
1809 if (kgem->gen <= 030) {
1811 if (kgem->gen < 030) {
1845 if (tiling && kgem->gen < 033)
1849 static uint32_t kgem_surface_size(struct kgem *kgem,
1865 if (kgem->gen <= 030) {
1867 if (kgem->gen < 030) {
1877 kgem_pitch_alignment(kgem, flags));
1885 kgem_pitch_alignment(kgem, flags));
1899 if (!kgem->has_relaxed_fencing)
1907 if (kgem->gen >= 040)
1934 if (kgem->gen < 030)
1943 bool kgem_check_surface_size(struct kgem *kgem,
1960 min_size = kgem_surface_size(kgem, kgem->has_relaxed_fencing, 0,
1972 kgem_get_tile_size(kgem, tiling, min_pitch,
1984 static uint32_t kgem_aligned_height(struct kgem *kgem,
1989 if (kgem->gen <= 030) {
1990 tile_height = tiling ? kgem->gen < 030 ? 16 : 8 : 1;
2006 if (!kgem->has_relaxed_fencing)
2013 kgem_add_handle(struct kgem *kgem, struct kgem_bo *bo)
2018 __FUNCTION__, bo->handle, kgem->nexec));
2020 assert(kgem->nexec < ARRAY_SIZE(kgem->exec));
2021 bo->target_handle = kgem->has_handle_lut ? kgem->nexec : bo->handle;
2022 exec = memset(&kgem->exec[kgem->nexec++], 0, sizeof(*exec));
2026 kgem->aperture += num_pages(bo);
2031 static void kgem_add_bo(struct kgem *kgem, struct kgem_bo *bo)
2036 bo->exec = kgem_add_handle(kgem, bo);
2037 bo->rq = MAKE_REQUEST(kgem->next_request, kgem->ring);
2039 list_move_tail(&bo->request, &kgem->next_request->buffers);
2041 list_move(&bo->list, &kgem->batch_buffers);
2044 kgem->flush |= bo->flush;
2047 static uint32_t kgem_end_batch(struct kgem *kgem)
2049 kgem->batch[kgem->nbatch++] = MI_BATCH_BUFFER_END;
2050 if (kgem->nbatch & 1)
2051 kgem->batch[kgem->nbatch++] = MI_NOOP;
2053 return kgem->nbatch;
2056 static void kgem_bo_binding_free(struct kgem *kgem, struct kgem_bo *bo)
2068 static void kgem_bo_rmfb(struct kgem *kgem, struct kgem_bo *bo)
2074 do_ioctl(kgem->fd, DRM_IOCTL_MODE_RMFB, &bo->delta);
2079 static void kgem_bo_free(struct kgem *kgem, struct kgem_bo *bo)
2088 kgem->debug_memory.bo_allocs--;
2089 kgem->debug_memory.bo_bytes -= bytes(bo);
2092 kgem_bo_binding_free(kgem, bo);
2093 kgem_bo_rmfb(kgem, bo);
2097 assert(!__kgem_busy(kgem, bo->handle));
2109 bo->handle, list_is_empty(&bo->vma) ? 0 : kgem->vma[bo->map__gtt == NULL && bo->map__wc == NULL].count));
2113 kgem->vma[bo->map__gtt == NULL && bo->map__wc == NULL].count--;
2129 gem_close(kgem->fd, bo->handle);
2138 inline static void kgem_bo_move_to_inactive(struct kgem *kgem,
2155 assert_tiling(kgem, bo);
2156 assert_cacheing(kgem, bo);
2157 ASSERT_IDLE(kgem, bo->handle);
2165 list_move(&bo->list, &kgem->large_inactive);
2169 list_move(&bo->list, &kgem->inactive[bucket(bo)]);
2170 if (bo->map__gtt && !kgem_bo_can_map(kgem, bo)) {
2175 list_add(&bo->vma, &kgem->vma[0].inactive[bucket(bo)]);
2176 kgem->vma[0].count++;
2179 list_add(&bo->vma, &kgem->vma[1].inactive[bucket(bo)]);
2180 kgem->vma[1].count++;
2184 kgem->need_expire = true;
2217 inline static void kgem_bo_remove_from_inactive(struct kgem *kgem,
2228 kgem->vma[bo->map__gtt == NULL && bo->map__wc == NULL].count--;
2232 inline static void kgem_bo_remove_from_active(struct kgem *kgem,
2239 if (RQ(bo->rq) == (void *)kgem) {
2246 static void _kgem_bo_delete_buffer(struct kgem *kgem, struct kgem_bo *bo)
2257 static bool check_scanout_size(struct kgem *kgem,
2268 if (do_ioctl(kgem->fd, DRM_IOCTL_MODE_GETFB, &info))
2271 gem_close(kgem->fd, info.handle);
2284 static void kgem_bo_move_to_scanout(struct kgem *kgem, struct kgem_bo *bo)
2296 kgem_bo_free(kgem, bo);
2304 list_move_tail(&bo->list, &kgem->scanout);
2306 list_move(&bo->list, &kgem->scanout);
2308 kgem->need_expire = true;
2312 static void kgem_bo_move_to_snoop(struct kgem *kgem, struct kgem_bo *bo)
2322 kgem_bo_free(kgem, bo);
2326 if (num_pages(bo) > kgem->max_cpu_size >> 13) {
2328 __FUNCTION__, bo->handle, num_pages(bo), kgem->max_cpu_size >> 13));
2329 kgem_bo_free(kgem, bo);
2337 list_add(&bo->list, &kgem->snoop);
2338 kgem->need_expire = true;
2341 static bool kgem_bo_move_to_cache(struct kgem *kgem, struct kgem_bo *bo)
2350 kgem_bo_free(kgem, bo);
2352 kgem_bo_move_to_snoop(kgem, bo);
2354 kgem_bo_move_to_scanout(kgem, bo);
2356 kgem_bo_set_purgeable(kgem, bo)) {
2357 kgem_bo_move_to_inactive(kgem, bo);
2360 kgem_bo_free(kgem, bo);
2366 search_snoop_cache(struct kgem *kgem, unsigned int num_pages, unsigned flags)
2372 if ((kgem->has_caching | kgem->has_userptr) == 0)
2375 if (list_is_empty(&kgem->snoop)) {
2377 if (!__kgem_throttle_retire(kgem, flags)) {
2383 list_for_each_entry(bo, &kgem->snoop, list) {
2424 void kgem_bo_undo(struct kgem *kgem, struct kgem_bo *bo)
2426 if (kgem->nexec != 1 || bo->exec == NULL)
2433 assert(bo->exec == &kgem->exec[0]);
2434 assert(kgem->exec[0].handle == bo->handle);
2435 assert(RQ(bo->rq) == kgem->next_request);
2438 kgem_reset(kgem);
2441 assert(kgem->nreloc == 0);
2442 assert(kgem->nexec == 0);
2446 void kgem_bo_pair_undo(struct kgem *kgem, struct kgem_bo *a, struct kgem_bo *b)
2448 if (kgem->nexec > 2)
2451 if (kgem->nexec == 1) {
2453 kgem_bo_undo(kgem, a);
2455 kgem_bo_undo(kgem, b);
2467 assert(a->exec == &kgem->exec[0] || a->exec == &kgem->exec[1]);
2468 assert(a->handle == kgem->exec[0].handle || a->handle == kgem->exec[1].handle);
2469 assert(RQ(a->rq) == kgem->next_request);
2470 assert(b->exec == &kgem->exec[0] || b->exec == &kgem->exec[1]);
2471 assert(b->handle == kgem->exec[0].handle || b->handle == kgem->exec[1].handle);
2472 assert(RQ(b->rq) == kgem->next_request);
2476 kgem_reset(kgem);
2480 assert(kgem->nreloc == 0);
2481 assert(kgem->nexec == 0);
2486 static void __kgem_bo_destroy(struct kgem *kgem, struct kgem_bo *bo)
2494 assert_tiling(kgem, bo);
2508 if (bo->exec == NULL && bo->rq && !__kgem_busy(kgem, bo->handle))
2511 kgem_bo_move_to_snoop(kgem, bo);
2518 kgem_bo_move_to_scanout(kgem, bo);
2536 assert_cacheing(kgem, bo);
2538 kgem_bo_undo(kgem, bo);
2541 if (bo->rq && bo->exec == NULL && !__kgem_busy(kgem, bo->handle))
2549 cache = &kgem->active[bucket(bo)][bo->tiling];
2551 cache = &kgem->large;
2560 if (!kgem_bo_set_purgeable(kgem, bo))
2563 if (!kgem->has_llc && bo->domain == DOMAIN_CPU)
2570 kgem_bo_move_to_inactive(kgem, bo);
2575 kgem_bo_free(kgem, bo);
2578 static void kgem_bo_unref(struct kgem *kgem, struct kgem_bo *bo)
2582 __kgem_bo_destroy(kgem, bo);
2585 static void kgem_buffer_release(struct kgem *kgem, struct kgem_buffer *bo)
2600 kgem_bo_destroy(kgem, cached);
2604 void kgem_retire__buffers(struct kgem *kgem)
2606 while (!list_is_empty(&kgem->active_buffers)) {
2608 list_last_entry(&kgem->active_buffers,
2615 assert(bo->base.exec == NULL || RQ(bo->base.rq) == kgem->next_request);
2622 kgem_buffer_release(kgem, bo);
2623 kgem_bo_unref(kgem, &bo->base);
2627 static bool kgem_retire__flushing(struct kgem *kgem)
2632 list_for_each_entry_safe(bo, next, &kgem->flushing, request) {
2633 assert(RQ(bo->rq) == (void *)kgem);
2636 if (__kgem_busy(kgem, bo->handle))
2644 retired |= kgem_bo_move_to_cache(kgem, bo);
2649 list_for_each_entry(bo, &kgem->flushing, request)
2655 kgem->need_retire |= !list_is_empty(&kgem->flushing);
2660 static bool __kgem_retire_rq(struct kgem *kgem, struct kgem_request *rq)
2668 if (rq == kgem->fence[rq->ring])
2669 kgem->fence[rq->ring] = NULL;
2685 bo->needs_flush = __kgem_busy(kgem, bo->handle);
2689 list_add(&bo->request, &kgem->flushing);
2690 bo->rq = MAKE_REQUEST(kgem, RQ_RING(bo->rq));
2691 kgem->need_retire = true;
2701 retired |= kgem_bo_move_to_cache(kgem, bo);
2710 if (kgem_bo_set_purgeable(kgem, rq->bo)) {
2711 kgem_bo_move_to_inactive(kgem, rq->bo);
2716 kgem_bo_free(kgem, rq->bo);
2724 static bool kgem_retire__requests_ring(struct kgem *kgem, int ring)
2728 while (!list_is_empty(&kgem->requests[ring])) {
2731 rq = list_first_entry(&kgem->requests[ring],
2735 if (__kgem_busy(kgem, rq->bo->handle))
2738 retired |= __kgem_retire_rq(kgem, rq);
2746 list_for_each_entry(bo, &kgem->requests[ring], request)
2750 if (!list_is_empty(&kgem->requests[ring]))
2751 bo = list_first_entry(&kgem->requests[ring],
2763 static bool kgem_retire__requests(struct kgem *kgem)
2768 for (n = 0; n < ARRAY_SIZE(kgem->requests); n++) {
2769 retired |= kgem_retire__requests_ring(kgem, n);
2770 kgem->need_retire |= !list_is_empty(&kgem->requests[n]);
2776 bool kgem_retire(struct kgem *kgem)
2780 DBG(("%s, need_retire?=%d\n", __FUNCTION__, kgem->need_retire));
2782 kgem->need_retire = false;
2784 retired |= kgem_retire__flushing(kgem);
2785 retired |= kgem_retire__requests(kgem);
2788 __FUNCTION__, retired, kgem->need_retire));
2790 kgem->retire(kgem);
2795 bool __kgem_ring_is_idle(struct kgem *kgem, int ring)
2799 assert(ring < ARRAY_SIZE(kgem->requests));
2800 assert(!list_is_empty(&kgem->requests[ring]));
2802 rq = kgem->fence[ring];
2806 if (__kgem_busy(kgem, rq->bo->handle)) {
2813 tmp = list_first_entry(&kgem->requests[ring],
2817 __kgem_retire_rq(kgem, tmp);
2820 assert(kgem->fence[ring] == NULL);
2821 if (list_is_empty(&kgem->requests[ring]))
2825 rq = list_last_entry(&kgem->requests[ring],
2828 if (__kgem_busy(kgem, rq->bo->handle)) {
2831 kgem->fence[ring] = rq;
2838 while (!list_is_empty(&kgem->requests[ring])) {
2839 rq = list_first_entry(&kgem->requests[ring],
2843 __kgem_retire_rq(kgem, rq);
2849 void __kgem_retire_requests_upto(struct kgem *kgem, struct kgem_bo *bo)
2852 struct list *requests = &kgem->requests[RQ_RING(rq) == I915_EXEC_BLT];
2855 assert(rq != &kgem->static_request);
2856 if (rq == (struct kgem_request *)kgem) {
2864 __kgem_retire_rq(kgem, tmp);
2869 static void kgem_commit__check_reloc(struct kgem *kgem)
2871 struct kgem_request *rq = kgem->next_request;
2873 bool has_64bit = kgem->gen >= 0100;
2876 for (i = 0; i < kgem->nreloc; i++) {
2878 if (bo->target_handle == kgem->reloc[i].target_handle) {
2880 gem_read(kgem->fd, rq->bo->handle, &value, kgem->reloc[i].offset, has_64bit ? 8 : 4);
2881 assert(bo->exec->offset == -1 || value == bo->exec->offset + (int)kgem->reloc[i].delta);
2888 #define kgem_commit__check_reloc(kgem)
2892 static void kgem_commit__check_buffers(struct kgem *kgem)
2896 list_for_each_entry(bo, &kgem->active_buffers, base.list)
2900 #define kgem_commit__check_buffers(kgem)
2903 static void kgem_commit(struct kgem *kgem)
2905 struct kgem_request *rq = kgem->next_request;
2908 kgem_commit__check_reloc(kgem);
2929 kgem_bo_free(kgem, bo);
2942 kgem->scanout_busy |= bo->scanout && bo->needs_flush;
2945 if (rq == &kgem->static_request) {
2954 if (do_ioctl(kgem->fd, DRM_IOCTL_I915_GEM_SET_DOMAIN, &set_domain)) {
2956 kgem_throttle(kgem);
2959 kgem_retire(kgem);
2965 gem_close(kgem->fd, rq->bo->handle);
2966 kgem_cleanup_cache(kgem);
2968 assert(rq->ring < ARRAY_SIZE(kgem->requests));
2969 list_add_tail(&rq->list, &kgem->requests[rq->ring]);
2970 kgem->need_throttle = kgem->need_retire = 1;
2972 if (kgem->fence[rq->ring] == NULL &&
2973 __kgem_busy(kgem, rq->bo->handle))
2974 kgem->fence[rq->ring] = rq;
2977 kgem->next_request = NULL;
2979 kgem_commit__check_buffers(kgem);
2982 static void kgem_close_list(struct kgem *kgem, struct list *head)
2985 kgem_bo_free(kgem, list_first_entry(head, struct kgem_bo, list));
2988 static void kgem_close_inactive(struct kgem *kgem)
2992 for (i = 0; i < ARRAY_SIZE(kgem->inactive); i++)
2993 kgem_close_list(kgem, &kgem->inactive[i]);
2996 static void kgem_finish_buffers(struct kgem *kgem)
3000 list_for_each_entry_safe(bo, next, &kgem->batch_buffers, base.list) {
3029 (kgem->has_llc || bo->mmapped == MMAPPED_GTT || bo->base.snoop)) {
3034 &kgem->active_buffers);
3035 kgem->need_retire = true;
3053 assert(bo->base.rq == MAKE_REQUEST(kgem->next_request, kgem->ring));
3062 shrink = search_snoop_cache(kgem, alloc,
3074 map = kgem_bo_map__cpu(kgem, shrink);
3076 kgem_bo_sync__cpu(kgem, shrink);
3080 kgem->has_handle_lut ? bo->base.target_handle : shrink->handle;
3081 for (n = 0; n < kgem->nreloc; n++) {
3082 if (kgem->reloc[n].target_handle == bo->base.target_handle) {
3083 kgem->reloc[n].target_handle = shrink->target_handle;
3084 kgem->reloc[n].presumed_offset = shrink->presumed_offset;
3085 kgem->batch[kgem->reloc[n].offset/sizeof(kgem->batch[0])] =
3086 kgem->reloc[n].delta + shrink->presumed_offset;
3108 __kgem_bo_destroy(kgem, shrink);
3111 shrink = search_linear_cache(kgem, alloc,
3122 if (gem_write__cachealigned(kgem->fd, shrink->handle,
3125 kgem->has_handle_lut ? bo->base.target_handle : shrink->handle;
3126 for (n = 0; n < kgem->nreloc; n++) {
3127 if (kgem->reloc[n].target_handle == bo->base.target_handle) {
3128 kgem->reloc[n].target_handle = shrink->target_handle;
3129 kgem->reloc[n].presumed_offset = shrink->presumed_offset;
3130 kgem->batch[kgem->reloc[n].offset/sizeof(kgem->batch[0])] =
3131 kgem->reloc[n].delta + shrink->presumed_offset;
3153 __kgem_bo_destroy(kgem, shrink);
3159 ASSERT_IDLE(kgem, bo->base.handle);
3161 gem_write__cachealigned(kgem->fd, bo->base.handle,
3169 kgem_bo_unref(kgem, &bo->base);
3173 static void kgem_cleanup(struct kgem *kgem)
3177 for (n = 0; n < ARRAY_SIZE(kgem->requests); n++) {
3178 while (!list_is_empty(&kgem->requests[n])) {
3181 rq = list_first_entry(&kgem->requests[n],
3196 kgem_bo_free(kgem, bo);
3203 kgem_close_inactive(kgem);
3207 kgem_batch_write(struct kgem *kgem,
3214 ASSERT_IDLE(kgem, bo->handle);
3219 return gem_write(kgem->fd, bo->handle, 0, sizeof(batch), batch);
3226 if (bo->domain == DOMAIN_CPU || kgem->has_llc) {
3229 ptr = __kgem_bo_map__cpu(kgem, bo);
3230 } else if (kgem->has_wc_mmap) {
3233 ptr = __kgem_bo_map__wc(kgem, bo);
3236 memcpy(ptr, kgem->batch, sizeof(uint32_t)*kgem->nbatch);
3237 if (kgem->surface != kgem->batch_size) {
3238 ret = PAGE_ALIGN(sizeof(uint32_t) * kgem->batch_size);
3239 ret -= sizeof(uint32_t) * kgem->surface;
3241 memcpy(ptr, kgem->batch + kgem->surface,
3242 (kgem->batch_size - kgem->surface)*sizeof(uint32_t));
3248 if (kgem->surface == kgem->batch_size) {
3249 if ((ret = gem_write__cachealigned(kgem->fd, bo->handle,
3250 0, sizeof(uint32_t)*kgem->nbatch,
3251 kgem->batch)) == 0)
3258 if (kgem->surface < kgem->nbatch + PAGE_SIZE/sizeof(uint32_t)) {
3259 assert(size == PAGE_ALIGN(kgem->batch_size*sizeof(uint32_t)));
3260 if ((ret = gem_write__cachealigned(kgem->fd, bo->handle,
3261 0, kgem->batch_size*sizeof(uint32_t),
3262 kgem->batch)) == 0)
3269 if ((ret = gem_write__cachealigned(kgem->fd, bo->handle,
3270 0, sizeof(uint32_t)*kgem->nbatch,
3271 kgem->batch)))
3274 ret = PAGE_ALIGN(sizeof(uint32_t) * kgem->batch_size);
3275 ret -= sizeof(uint32_t) * kgem->surface;
3276 assert(size-ret >= kgem->nbatch*sizeof(uint32_t));
3277 if (gem_write(kgem->fd, bo->handle,
3278 size - ret, (kgem->batch_size - kgem->surface)*sizeof(uint32_t),
3279 kgem->batch + kgem->surface))
3287 (void)__kgem_throttle_retire(kgem, 0);
3288 if (kgem_expire_cache(kgem))
3291 if (kgem_cleanup_cache(kgem))
3299 void kgem_reset(struct kgem *kgem)
3301 if (kgem->next_request) {
3302 struct kgem_request *rq = kgem->next_request;
3318 if (bo->needs_flush && __kgem_busy(kgem, bo->handle)) {
3320 list_add(&bo->request, &kgem->flushing);
3321 bo->rq = (void *)kgem;
3322 kgem->need_retire = true;
3329 kgem_bo_move_to_cache(kgem, bo);
3332 if (rq != &kgem->static_request) {
3338 kgem->nfence = 0;
3339 kgem->nexec = 0;
3340 kgem->nreloc = 0;
3341 kgem->nreloc__self = 0;
3342 kgem->aperture = 0;
3343 kgem->aperture_fenced = 0;
3344 kgem->aperture_max_fence = 0;
3345 kgem->nbatch = 0;
3346 kgem->surface = kgem->batch_size;
3347 kgem->mode = KGEM_NONE;
3348 kgem->needs_semaphore = false;
3349 kgem->needs_reservation = false;
3350 kgem->flush = 0;
3351 kgem->batch_flags = kgem->batch_flags_base;
3352 assert(kgem->batch);
3354 kgem->next_request = __kgem_request_alloc(kgem);
3356 kgem_sna_reset(kgem);
3359 static int compact_batch_surface(struct kgem *kgem, int *shrink)
3363 if (!kgem->has_relaxed_delta)
3364 return kgem->batch_size * sizeof(uint32_t);
3367 n = ALIGN(kgem->batch_size, 1024);
3368 size = n - kgem->surface + kgem->nbatch;
3376 kgem_create_batch(struct kgem *kgem)
3384 if (kgem->surface != kgem->batch_size)
3385 size = compact_batch_surface(kgem, &shrink);
3387 size = kgem->nbatch * sizeof(uint32_t);
3390 bo = list_first_entry(&kgem->pinned_batches[0],
3396 list_move_tail(&bo->list, &kgem->pinned_batches[0]);
3401 if (!__kgem_busy(kgem, bo->handle)) {
3403 __kgem_retire_rq(kgem, RQ(bo->rq));
3409 bo = list_first_entry(&kgem->pinned_batches[1],
3415 list_move_tail(&bo->list, &kgem->pinned_batches[1]);
3420 if (!__kgem_busy(kgem, bo->handle)) {
3421 __kgem_retire_rq(kgem, RQ(bo->rq));
3426 if (kgem->gen == 020) {
3427 bo = kgem_create_linear(kgem, size, CREATE_CACHED | CREATE_TEMPORARY);
3432 if (kgem->has_pinned_batches) {
3433 bo = kgem_create_linear(kgem, size, CREATE_CACHED | CREATE_TEMPORARY);
3435 kgem->batch_flags &= ~LOCAL_I915_EXEC_IS_PINNED;
3441 bo = list_first_entry(&kgem->pinned_batches[size > 4096],
3444 list_move_tail(&bo->list, &kgem->pinned_batches[size > 4096]);
3452 if (do_ioctl(kgem->fd, DRM_IOCTL_I915_GEM_SET_DOMAIN, &set_domain)) {
3454 kgem_throttle(kgem);
3458 kgem_retire(kgem);
3466 if (!kgem->has_llc) {
3467 bo = kgem_create_linear(kgem, size, CREATE_NO_THROTTLE);
3470 kgem_fixup_relocs(kgem, bo, shrink);
3471 if (kgem_batch_write(kgem, bo, size)) {
3472 kgem_bo_destroy(kgem, bo);
3478 bo = kgem_new_batch(kgem);
3481 return kgem_new_batch(kgem);
3504 static void dump_debugfs(struct kgem *kgem, const char *name)
3507 int minor = kgem_get_minor(kgem);
3521 static void dump_gtt_info(struct kgem *kgem)
3523 dump_debugfs(kgem, "i915_gem_gtt");
3526 static void dump_fence_regs(struct kgem *kgem)
3528 dump_debugfs(kgem, "i915_gem_fence_regs");
3532 static int do_execbuf(struct kgem *kgem, struct drm_i915_gem_execbuffer2 *execbuf)
3537 ret = do_ioctl(kgem->fd, DRM_IOCTL_I915_GEM_EXECBUFFER2, execbuf);
3542 (void)__kgem_throttle_retire(kgem, 0);
3543 if (kgem_expire_cache(kgem))
3546 if (kgem_cleanup_cache(kgem))
3550 ret = do_ioctl(kgem->fd, DRM_IOCTL_I915_GEM_EXECBUFFER2, execbuf);
3554 xf86DrvMsg(kgem_get_screen_index(kgem), X_WARNING,
3562 if (sna_mode_disable(container_of(kgem, struct sna, kgem))) {
3563 kgem_cleanup_cache(kgem);
3564 ret = do_ioctl(kgem->fd,
3568 sna_mode_enable(container_of(kgem, struct sna, kgem));
3575 void _kgem_submit(struct kgem *kgem)
3581 assert(!kgem->wedged);
3583 assert(kgem->nbatch);
3584 assert(kgem->nbatch <= KGEM_BATCH_SIZE(kgem));
3585 assert(kgem->nbatch <= kgem->surface);
3587 batch_end = kgem_end_batch(kgem);
3588 kgem_sna_flush(kgem);
3591 kgem->mode, kgem->ring, kgem->batch_flags,
3592 batch_end, kgem->nbatch, kgem->surface, kgem->batch_size,
3593 kgem->nreloc, kgem->nexec, kgem->nfence, kgem->aperture, kgem->aperture_fenced));
3595 assert(kgem->nbatch <= kgem->batch_size);
3596 assert(kgem->nbatch <= kgem->surface);
3597 assert(kgem->nreloc <= ARRAY_SIZE(kgem->reloc));
3598 assert(kgem->nexec < ARRAY_SIZE(kgem->exec));
3599 assert(kgem->nfence <= kgem->fence_max);
3601 kgem_finish_buffers(kgem);
3604 __kgem_batch_debug(kgem, batch_end);
3607 rq = kgem->next_request;
3610 rq->bo = kgem_create_batch(kgem);
3617 i = kgem->nexec++;
3618 kgem->exec[i].handle = rq->bo->handle;
3619 kgem->exec[i].relocation_count = kgem->nreloc;
3620 kgem->exec[i].relocs_ptr = (uintptr_t)kgem->reloc;
3621 kgem->exec[i].alignment = 0;
3622 kgem->exec[i].offset = rq->bo->presumed_offset;
3623 kgem->exec[i].flags = 0;
3624 kgem->exec[i].rsvd1 = 0;
3625 kgem->exec[i].rsvd2 = 0;
3627 rq->bo->exec = &kgem->exec[i];
3628 rq->bo->rq = MAKE_REQUEST(rq, kgem->ring); /* useful sanity check */
3630 rq->ring = kgem->ring == KGEM_BLT;
3633 execbuf.buffers_ptr = (uintptr_t)kgem->exec;
3634 execbuf.buffer_count = kgem->nexec;
3636 execbuf.flags = kgem->ring | kgem->batch_flags;
3643 ret = write(fd, kgem->batch, batch_end*sizeof(uint32_t));
3648 ret = do_execbuf(kgem, &execbuf);
3657 ret = do_ioctl(kgem->fd, DRM_IOCTL_I915_GEM_SET_DOMAIN, &set_domain);
3660 kgem_throttle(kgem);
3661 if (!kgem->wedged) {
3662 xf86DrvMsg(kgem_get_screen_index(kgem), X_ERROR,
3664 __kgem_set_wedged(kgem);
3669 kgem->mode, kgem->ring, batch_end, kgem->nbatch, kgem->surface,
3670 kgem->nreloc, kgem->nexec, kgem->nfence, kgem->aperture, kgem->aperture_fenced, kgem->aperture_high, kgem->aperture_total, -ret);
3672 for (i = 0; i < kgem->nexec; i++) {
3675 list_for_each_entry(bo, &kgem->next_request->buffers, request) {
3676 if (bo->handle == kgem->exec[i].handle) {
3683 kgem->exec[i].handle,
3684 (int)kgem->exec[i].offset,
3687 (int)(kgem->exec[i].flags & EXEC_OBJECT_NEEDS_FENCE),
3691 for (i = 0; i < kgem->nreloc; i++) {
3694 (int)kgem->reloc[i].offset,
3695 kgem->reloc[i].target_handle,
3696 kgem->reloc[i].delta,
3697 kgem->reloc[i].read_domains,
3698 kgem->reloc[i].write_domain,
3699 (int)kgem->reloc[i].presumed_offset);
3704 if (do_ioctl(kgem->fd, DRM_IOCTL_I915_GEM_GET_APERTURE, &aperture) == 0)
3711 dump_gtt_info(kgem);
3713 dump_fence_regs(kgem);
3718 int ignored = write(fd, kgem->batch, batch_end*sizeof(uint32_t));
3729 if (gem_read(kgem->fd, rq->bo->handle, kgem->batch, 0, batch_end*sizeof(uint32_t)) == 0)
3730 __kgem_batch_debug(kgem, batch_end);
3732 kgem_commit(kgem);
3733 if (kgem->wedged)
3734 kgem_cleanup(kgem);
3736 kgem_reset(kgem);
3738 assert(kgem->next_request != NULL);
3741 static bool find_hang_state(struct kgem *kgem, char *path, int maxlen)
3743 int minor = kgem_get_minor(kgem);
3766 void kgem_throttle(struct kgem *kgem)
3768 if (kgem->wedged)
3771 if (__kgem_throttle(kgem, true)) {
3775 xf86DrvMsg(kgem_get_screen_index(kgem), X_ERROR,
3777 if (!once && find_hang_state(kgem, path, sizeof(path))) {
3778 xf86DrvMsg(kgem_get_screen_index(kgem), X_ERROR,
3784 __kgem_set_wedged(kgem);
3785 kgem->need_throttle = false;
3789 int kgem_is_wedged(struct kgem *kgem)
3791 return __kgem_throttle(kgem, true);
3794 static void kgem_purge_cache(struct kgem *kgem)
3799 for (i = 0; i < ARRAY_SIZE(kgem->inactive); i++) {
3800 list_for_each_entry_safe(bo, next, &kgem->inactive[i], list) {
3801 if (!kgem_bo_is_retained(kgem, bo)) {
3804 kgem_bo_free(kgem, bo);
3809 kgem->need_purge = false;
3812 void kgem_clean_scanout_cache(struct kgem *kgem)
3814 while (!list_is_empty(&kgem->scanout)) {
3817 bo = list_first_entry(&kgem->scanout, struct kgem_bo, list);
3824 if (bo->exec || __kgem_busy(kgem, bo->handle))
3831 kgem_bo_rmfb(kgem, bo);
3836 if (kgem->has_llc &&
3837 !gem_set_caching(kgem->fd, bo->handle, SNOOPED))
3842 __kgem_bo_destroy(kgem, bo);
3846 void kgem_clean_large_cache(struct kgem *kgem)
3848 while (!list_is_empty(&kgem->large_inactive)) {
3849 kgem_bo_free(kgem,
3850 list_first_entry(&kgem->large_inactive,
3856 bool kgem_expire_cache(struct kgem *kgem)
3878 kgem_clean_large_cache(kgem);
3879 if (container_of(kgem, struct sna, kgem)->scrn->vtSema)
3880 kgem_clean_scanout_cache(kgem);
3883 list_for_each_entry(bo, &kgem->snoop, list) {
3892 while (!list_is_empty(&kgem->snoop)) {
3893 bo = list_last_entry(&kgem->snoop, struct kgem_bo, list);
3898 kgem_bo_free(kgem, bo);
3905 list_for_each_entry(bo, &kgem->snoop, list)
3912 kgem_retire(kgem);
3913 if (kgem->wedged)
3914 kgem_cleanup(kgem);
3916 kgem->expire(kgem);
3918 if (kgem->need_purge)
3919 kgem_purge_cache(kgem);
3921 if (kgem->need_retire)
3922 kgem_retire(kgem);
3926 for (i = 0; i < ARRAY_SIZE(kgem->inactive); i++) {
3927 idle &= list_is_empty(&kgem->inactive[i]);
3928 list_for_each_entry(bo, &kgem->inactive[i], list) {
3939 kgem->need_expire = !idle;
3944 for (i = 0; i < ARRAY_SIZE(kgem->inactive); i++) {
3948 while (!list_is_empty(&kgem->inactive[i])) {
3949 bo = list_last_entry(&kgem->inactive[i],
3963 kgem_bo_free(kgem, bo);
3969 preserve.prev->next = kgem->inactive[i].next;
3970 kgem->inactive[i].next->prev = preserve.prev;
3971 kgem->inactive[i].next = preserve.next;
3972 preserve.next->prev = &kgem->inactive[i];
3980 for (i = 0; i < ARRAY_SIZE(kgem->inactive); i++)
3981 list_for_each_entry(bo, &kgem->inactive[i], list)
3991 kgem->need_expire = !idle;
3997 bool kgem_cleanup_cache(struct kgem *kgem)
4003 for (n = 0; n < ARRAY_SIZE(kgem->requests); n++) {
4004 if (!list_is_empty(&kgem->requests[n])) {
4008 rq = list_first_entry(&kgem->requests[n],
4018 (void)do_ioctl(kgem->fd,
4024 kgem_retire(kgem);
4025 kgem_cleanup(kgem);
4027 if (!kgem->need_expire)
4030 for (i = 0; i < ARRAY_SIZE(kgem->inactive); i++) {
4031 while (!list_is_empty(&kgem->inactive[i]))
4032 kgem_bo_free(kgem,
4033 list_last_entry(&kgem->inactive[i],
4037 kgem_clean_large_cache(kgem);
4038 kgem_clean_scanout_cache(kgem);
4040 while (!list_is_empty(&kgem->snoop))
4041 kgem_bo_free(kgem,
4042 list_last_entry(&kgem->snoop,
4051 kgem->need_purge = false;
4052 kgem->need_expire = false;
4057 search_linear_cache(struct kgem *kgem, unsigned int num_pages, unsigned flags)
4073 cache = use_active ? &kgem->large : &kgem->large_inactive;
4086 if (!gem_set_tiling(kgem->fd, bo->handle,
4094 if (bo->purged && !kgem_bo_clear_purgeable(kgem, bo))
4098 if (RQ(bo->rq) == (void *)kgem) {
4104 assert_tiling(kgem, bo);
4109 kgem_bo_free(kgem, bo);
4117 if (__kgem_throttle_retire(kgem, flags))
4123 if (!use_active && list_is_empty(inactive(kgem, num_pages))) {
4132 if (list_is_empty(active(kgem, num_pages, I915_TILING_NONE))) {
4137 if (!__kgem_throttle_retire(kgem, flags)) {
4142 if (list_is_empty(inactive(kgem, num_pages))) {
4153 cache = &kgem->vma[for_cpu].inactive[cache_bucket(num_pages)];
4168 if (bo->purged && !kgem_bo_clear_purgeable(kgem, bo)) {
4169 kgem_bo_free(kgem, bo);
4174 !gem_set_tiling(kgem->fd, bo->handle,
4178 kgem_bo_remove_from_inactive(kgem, bo);
4189 assert_tiling(kgem, bo);
4190 ASSERT_MAYBE_IDLE(kgem, bo->handle, !use_active);
4197 if (flags & CREATE_CPU_MAP && !kgem->has_llc)
4201 cache = use_active ? active(kgem, num_pages, I915_TILING_NONE) : inactive(kgem, num_pages);
4213 kgem->gen <= 040 &&
4217 if (bo->purged && !kgem_bo_clear_purgeable(kgem, bo)) {
4218 kgem_bo_free(kgem, bo);
4229 if (!gem_set_tiling(kgem->fd, bo->handle,
4255 if (flags & CREATE_GTT_MAP && !kgem_bo_can_map(kgem, bo))
4268 kgem_bo_remove_from_active(kgem, bo);
4270 kgem_bo_remove_from_inactive(kgem, bo);
4282 assert_tiling(kgem, bo);
4283 ASSERT_MAYBE_IDLE(kgem, bo->handle, !use_active);
4291 kgem_bo_remove_from_active(kgem, first);
4293 kgem_bo_remove_from_inactive(kgem, first);
4304 ASSERT_MAYBE_IDLE(kgem, first->handle, !use_active);
4311 struct kgem_bo *kgem_create_for_name(struct kgem *kgem, uint32_t name)
4321 if (do_ioctl(kgem->fd, DRM_IOCTL_GEM_OPEN, &open_arg))
4328 if (do_ioctl(kgem->fd, DRM_IOCTL_I915_GEM_GET_TILING, &tiling)) {
4330 gem_close(kgem->fd, open_arg.handle);
4338 gem_close(kgem->fd, open_arg.handle);
4342 bo->unique_id = kgem_get_unique_id(kgem);
4348 debug_alloc__bo(kgem, bo);
4352 struct kgem_bo *kgem_create_for_prime(struct kgem *kgem, int name, uint32_t size)
4366 if (do_ioctl(kgem->fd, DRM_IOCTL_PRIME_FD_TO_HANDLE, &args)) {
4373 if (do_ioctl(kgem->fd, DRM_IOCTL_I915_GEM_GET_TILING, &tiling)) {
4375 gem_close(kgem->fd, args.handle);
4386 gem_close(kgem->fd, args.handle);
4396 gem_close(kgem->fd, args.handle);
4400 bo->unique_id = kgem_get_unique_id(kgem);
4410 caching.caching = kgem->has_llc;
4411 (void)drmIoctl(kgem->fd, LOCAL_IOCTL_I915_GEM_GET_CACHING, &caching);
4415 if (kgem->has_llc) {
4422 if (!kgem->has_llc) {
4428 kgem_bo_free(kgem, bo);
4440 debug_alloc__bo(kgem, bo);
4447 int kgem_bo_export_to_prime(struct kgem *kgem, struct kgem_bo *bo)
4456 if (do_ioctl(kgem->fd, DRM_IOCTL_PRIME_HANDLE_TO_FD, &args))
4466 struct kgem_bo *kgem_create_linear(struct kgem *kgem, int size, unsigned flags)
4474 if (flags & CREATE_GTT_MAP && kgem->has_llc) {
4481 bo = search_linear_cache(kgem, size, CREATE_INACTIVE | flags);
4484 ASSERT_IDLE(kgem, bo->handle);
4493 handle = gem_create(kgem->fd, size);
4500 gem_close(kgem->fd, handle);
4504 debug_alloc__bo(kgem, bo);
4508 int kgem_choose_tiling(struct kgem *kgem, int tiling, int width, int height, int bpp)
4513 if (kgem->gen < 040) {
4541 if (tiling == I915_TILING_Y && !kgem->can_render_y)
4616 unsigned kgem_can_create_2d(struct kgem *kgem,
4638 size = kgem_surface_size(kgem, false, 0,
4643 if (size <= kgem->max_cpu_size)
4645 if (size > 4096 && size <= kgem->max_gpu_size)
4647 if (size <= PAGE_SIZE*kgem->aperture_mappable/4 || kgem->has_wc_mmap)
4649 if (size > kgem->large_object_size)
4651 if (size > kgem->max_object_size) {
4653 __FUNCTION__, size, kgem->max_object_size));
4658 tiling = kgem_choose_tiling(kgem, I915_TILING_X,
4661 size = kgem_surface_size(kgem, false, 0,
4665 if (size > 0 && size <= kgem->max_gpu_size)
4667 if (size > 0 && size <= PAGE_SIZE*kgem->aperture_mappable/4)
4669 if (size > PAGE_SIZE*kgem->aperture_mappable/4)
4671 if (size > kgem->large_object_size)
4673 if (size > kgem->max_object_size) {
4675 __FUNCTION__, size, kgem->max_object_size));
4678 if (kgem->gen < 040) {
4682 if (fence_size > kgem->max_gpu_size)
4684 if (fence_size > PAGE_SIZE*kgem->aperture_fenceable/4)
4692 inline int kgem_bo_fenced_size(struct kgem *kgem, struct kgem_bo *bo)
4697 assert_tiling(kgem, bo);
4698 assert(kgem->gen < 040);
4700 if (kgem->gen < 030)
4711 __kgem_bo_create_as_display(struct kgem *kgem, int size, int tiling, int pitch)
4716 if (!kgem->has_create2)
4726 if (do_ioctl(kgem->fd, LOCAL_IOCTL_I915_GEM_CREATE2, &args)) {
4728 if (do_ioctl(kgem->fd, LOCAL_IOCTL_I915_GEM_CREATE2, &args))
4734 gem_close(kgem->fd, args.handle);
4738 bo->unique_id = kgem_get_unique_id(kgem);
4747 if (__kgem_busy(kgem, bo->handle)) {
4749 list_add(&bo->request, &kgem->flushing);
4750 bo->rq = (void *)kgem;
4751 kgem->need_retire = true;
4754 assert_tiling(kgem, bo);
4755 debug_alloc__bo(kgem, bo);
4760 static void __kgem_bo_make_scanout(struct kgem *kgem,
4765 container_of(kgem, struct sna, kgem)->scrn;
4785 if (kgem->has_llc) {
4786 if (!gem_set_caching(kgem->fd, bo->handle, DISPLAY) &&
4787 !gem_set_caching(kgem->fd, bo->handle, UNCACHED))
4797 bo->map__gtt = __kgem_bo_map__gtt(kgem, bo);
4806 if (do_ioctl(kgem->fd, DRM_IOCTL_MODE_ADDFB, &arg) == 0) {
4813 struct kgem_bo *kgem_create_2d(struct kgem *kgem,
4839 size = kgem_surface_size(kgem, kgem->has_relaxed_fencing, flags,
4852 list_for_each_entry_reverse(bo, &kgem->scanout, list) {
4856 assert_tiling(kgem, bo);
4865 if (bo->delta && !check_scanout_size(kgem, bo, width, height))
4875 bo->unique_id = kgem_get_unique_id(kgem);
4878 assert(bo->pitch*kgem_aligned_height(kgem, height, bo->tiling) <= kgem_bo_size(bo));
4879 assert_tiling(kgem, bo);
4887 last->unique_id = kgem_get_unique_id(kgem);
4890 assert(last->pitch*kgem_aligned_height(kgem, height, last->tiling) <= kgem_bo_size(last));
4891 assert_tiling(kgem, last);
4896 if (container_of(kgem, struct sna, kgem)->scrn->vtSema) {
4897 ScrnInfoPtr scrn = container_of(kgem, struct sna, kgem)->scrn;
4899 list_for_each_entry_reverse(bo, &kgem->scanout, list) {
4915 kgem_bo_rmfb(kgem, bo);
4919 if (gem_set_tiling(kgem->fd, bo->handle,
4924 kgem_bo_free(kgem, bo);
4937 if (do_ioctl(kgem->fd, DRM_IOCTL_MODE_ADDFB, &arg)) {
4938 kgem_bo_free(kgem, bo);
4943 bo->unique_id = kgem_get_unique_id(kgem);
4947 assert(bo->pitch*kgem_aligned_height(kgem, height, bo->tiling) <= kgem_bo_size(bo));
4948 assert_tiling(kgem, bo);
4954 bo = __kgem_bo_create_as_display(kgem, size, tiling, pitch);
4968 tiled_height = kgem_aligned_height(kgem, height, tiling);
4970 list_for_each_entry(bo, &kgem->large, list) {
4975 assert_tiling(kgem, bo);
4977 if (kgem->gen < 040) {
4992 if (!gem_set_tiling(kgem->fd, bo->handle,
5001 kgem_bo_remove_from_active(kgem, bo);
5003 bo->unique_id = kgem_get_unique_id(kgem);
5007 assert(bo->pitch*kgem_aligned_height(kgem, height, bo->tiling) <= kgem_bo_size(bo));
5008 assert_tiling(kgem, bo);
5014 __kgem_throttle_retire(kgem, flags);
5015 list_for_each_entry(bo, &kgem->large_inactive, list) {
5019 assert_tiling(kgem, bo);
5026 if (!gem_set_tiling(kgem->fd, bo->handle,
5034 if (bo->purged && !kgem_bo_clear_purgeable(kgem, bo)) {
5035 kgem_bo_free(kgem, bo);
5042 bo->unique_id = kgem_get_unique_id(kgem);
5047 assert(bo->pitch*kgem_aligned_height(kgem, height, bo->tiling) <= kgem_bo_size(bo));
5048 assert_tiling(kgem, bo);
5052 __kgem_bo_make_scanout(kgem, bo, width, height);
5062 if (kgem->has_llc && tiling == I915_TILING_NONE)
5067 cache = &kgem->vma[for_cpu].inactive[bucket];
5078 assert_tiling(kgem, bo);
5086 if (flags & UNCACHED && !kgem->has_llc && bo->domain != DOMAIN_CPU)
5092 !gem_set_tiling(kgem->fd, bo->handle,
5102 if (bo->purged && !kgem_bo_clear_purgeable(kgem, bo)) {
5103 kgem_bo_free(kgem, bo);
5110 bo->unique_id = kgem_get_unique_id(kgem);
5112 kgem_bo_remove_from_inactive(kgem, bo);
5120 ASSERT_IDLE(kgem, bo->handle);
5121 assert(bo->pitch*kgem_aligned_height(kgem, height, bo->tiling) <= kgem_bo_size(bo));
5122 assert_tiling(kgem, bo);
5127 __kgem_throttle_retire(kgem, flags));
5129 if (flags & CREATE_CPU_MAP && !kgem->has_llc) {
5130 if (list_is_empty(&kgem->active[bucket][tiling]) &&
5131 list_is_empty(&kgem->inactive[bucket]))
5147 cache = &kgem->active[bucket][tiling];
5149 tiled_height = kgem_aligned_height(kgem, height, tiling);
5158 assert_tiling(kgem, bo);
5160 if (kgem->gen < 040) {
5175 if (!gem_set_tiling(kgem->fd,
5184 kgem_bo_remove_from_active(kgem, bo);
5186 bo->unique_id = kgem_get_unique_id(kgem);
5190 assert(bo->pitch*kgem_aligned_height(kgem, height, bo->tiling) <= kgem_bo_size(bo));
5191 assert_tiling(kgem, bo);
5204 assert_tiling(kgem, bo);
5209 kgem_bo_remove_from_active(kgem, bo);
5212 bo->unique_id = kgem_get_unique_id(kgem);
5216 assert(bo->pitch*kgem_aligned_height(kgem, height, bo->tiling) <= kgem_bo_size(bo));
5217 assert_tiling(kgem, bo);
5223 if (kgem->gen >= 040) {
5225 cache = &kgem->active[bucket][i];
5232 assert_tiling(kgem, bo);
5239 if (!gem_set_tiling(kgem->fd,
5245 kgem_bo_remove_from_active(kgem, bo);
5247 bo->unique_id = kgem_get_unique_id(kgem);
5253 assert(bo->pitch*kgem_aligned_height(kgem, height, bo->tiling) <= kgem_bo_size(bo));
5254 assert_tiling(kgem, bo);
5261 tiled_height = kgem_surface_size(kgem, kgem->has_relaxed_fencing, flags,
5263 cache = active(kgem, tiled_height / PAGE_SIZE, i);
5264 tiled_height = kgem_aligned_height(kgem, height, i);
5271 assert_tiling(kgem, bo);
5286 kgem_bo_remove_from_active(kgem, bo);
5288 bo->unique_id = kgem_get_unique_id(kgem);
5292 assert(bo->pitch*kgem_aligned_height(kgem, height, bo->tiling) <= kgem_bo_size(bo));
5293 assert_tiling(kgem, bo);
5313 cache = &kgem->inactive[bucket];
5319 assert_tiling(kgem, bo);
5329 if (!gem_set_tiling(kgem->fd, bo->handle,
5334 if (bo->purged && !kgem_bo_clear_purgeable(kgem, bo)) {
5335 kgem_bo_free(kgem, bo);
5339 kgem_bo_remove_from_inactive(kgem, bo);
5347 bo->unique_id = kgem_get_unique_id(kgem);
5354 ASSERT_MAYBE_IDLE(kgem, bo->handle, flags & CREATE_INACTIVE);
5355 assert(bo->pitch*kgem_aligned_height(kgem, height, bo->tiling) <= kgem_bo_size(bo));
5356 assert_tiling(kgem, bo);
5360 __kgem_bo_make_scanout(kgem, bo, width, height);
5366 list_for_each_entry_reverse(bo, &kgem->active[bucket][tiling], list) {
5373 if (__kgem_busy(kgem, bo->handle)) {
5378 if (!kgem->need_throttle) {
5383 __kgem_throttle(kgem, false);
5384 } while (__kgem_busy(kgem, bo->handle));
5389 kgem_bo_remove_from_active(kgem, bo);
5393 if (!gem_set_tiling(kgem->fd, bo->handle, tiling, pitch)) {
5394 kgem_bo_free(kgem, bo);
5400 bo->unique_id = kgem_get_unique_id(kgem);
5404 assert(bo->pitch*kgem_aligned_height(kgem, height, bo->tiling) <= kgem_bo_size(bo));
5405 assert_tiling(kgem, bo);
5409 __kgem_bo_make_scanout(kgem, bo, width, height);
5430 handle = gem_create(kgem->fd, size);
5439 gem_close(kgem->fd, handle);
5443 bo->unique_id = kgem_get_unique_id(kgem);
5445 gem_set_tiling(kgem->fd, handle, tiling, pitch)) {
5449 __kgem_bo_make_scanout(kgem, bo, width, height);
5453 gem_close(kgem->fd, handle);
5459 assert(bytes(bo) >= bo->pitch * kgem_aligned_height(kgem, height, bo->tiling));
5460 assert_tiling(kgem, bo);
5462 debug_alloc__bo(kgem, bo);
5470 struct kgem_bo *kgem_create_cpu_2d(struct kgem *kgem,
5484 if (kgem->has_llc) {
5485 bo = kgem_create_2d(kgem, width, height, bpp,
5491 assert_tiling(kgem, bo);
5493 if (kgem_bo_map__cpu(kgem, bo) == NULL) {
5494 kgem_bo_destroy(kgem, bo);
5510 bo = search_snoop_cache(kgem, NUM_PAGES(size), 0);
5513 assert_tiling(kgem, bo);
5517 bo->unique_id = kgem_get_unique_id(kgem);
5521 if (kgem->has_caching) {
5522 bo = kgem_create_linear(kgem, size, flags);
5527 assert_tiling(kgem, bo);
5529 assert(!__kgem_busy(kgem, bo->handle));
5530 if (!gem_set_caching(kgem->fd, bo->handle, SNOOPED)) {
5531 kgem_bo_destroy(kgem, bo);
5536 if (kgem_bo_map__cpu(kgem, bo) == NULL) {
5537 kgem_bo_destroy(kgem, bo);
5542 bo->unique_id = kgem_get_unique_id(kgem);
5546 if (kgem->has_userptr) {
5554 bo = kgem_create_map(kgem, ptr, size, false);
5561 bo->unique_id = kgem_get_unique_id(kgem);
5568 void _kgem_bo_destroy(struct kgem *kgem, struct kgem_bo *bo)
5575 kgem_bo_binding_free(kgem, bo);
5582 _kgem_bo_delete_buffer(kgem, bo);
5584 kgem_bo_unref(kgem, bo->proxy);
5593 __kgem_bo_destroy(kgem, bo);
5596 static void __kgem_flush(struct kgem *kgem, struct kgem_bo *bo)
5603 if (!__kgem_busy(kgem, bo->handle))
5610 void kgem_scanout_flush(struct kgem *kgem, struct kgem_bo *bo)
5615 kgem_bo_submit(kgem, bo);
5623 __kgem_flush(kgem, bo);
5633 inline static bool nearly_idle(struct kgem *kgem)
5635 int ring = kgem->ring == KGEM_BLT;
5637 if (list_is_singular(&kgem->requests[ring]))
5640 return __kgem_ring_is_idle(kgem, ring);
5643 inline static bool needs_semaphore(struct kgem *kgem, struct kgem_bo *bo)
5645 if (kgem->needs_semaphore)
5648 if (bo->rq == NULL || RQ_RING(bo->rq) == kgem->ring)
5651 kgem->needs_semaphore = true;
5655 inline static bool needs_reservation(struct kgem *kgem, struct kgem_bo *bo)
5657 if (kgem->needs_reservation)
5663 kgem->needs_reservation = true;
5664 return nearly_idle(kgem);
5667 inline static bool needs_batch_flush(struct kgem *kgem, struct kgem_bo *bo)
5671 if (needs_semaphore(kgem, bo)) {
5676 if (needs_reservation(kgem, bo)) {
5681 return kgem->nreloc ? flush : false;
5684 static bool aperture_check(struct kgem *kgem, unsigned num_pages)
5689 if (kgem->aperture)
5693 reserve = kgem->aperture_mappable / 2;
5694 if (kgem->gen < 033 && reserve < kgem->aperture_max_fence)
5695 reserve = kgem->aperture_max_fence;
5696 if (!kgem->has_llc)
5697 reserve += kgem->nexec * PAGE_SIZE * 2;
5700 __FUNCTION__, num_pages, reserve, kgem->aperture_total));
5704 aperture.aper_available_size = kgem->aperture_total;
5706 (void)do_ioctl(kgem->fd, DRM_IOCTL_I915_GEM_GET_APERTURE, &aperture);
5716 static inline bool kgem_flush(struct kgem *kgem, bool flush)
5718 if (unlikely(kgem->wedged))
5721 if (kgem->nreloc == 0)
5724 if (container_of(kgem, struct sna, kgem)->flags & SNA_POWERSAVE)
5727 if (kgem->flush == flush && kgem->aperture < kgem->aperture_low)
5731 __FUNCTION__, kgem->flush, flush, kgem->aperture, kgem->aperture_low, kgem_ring_is_idle(kgem, kgem->ring)));
5732 return !kgem_ring_is_idle(kgem, kgem->ring);
5735 bool kgem_check_bo(struct kgem *kgem, ...)
5744 va_start(ap, kgem);
5751 if (needs_batch_flush(kgem, bo)) {
5770 if (kgem->nexec + num_exec >= KGEM_EXEC_SIZE(kgem)) {
5772 kgem->nexec, num_exec, KGEM_EXEC_SIZE(kgem)));
5776 if (num_pages + kgem->aperture > kgem->aperture_high) {
5778 __FUNCTION__, kgem->aperture, num_pages, kgem->aperture_high));
5779 return aperture_check(kgem, num_pages);
5785 return kgem_flush(kgem, flush);
5788 bool kgem_check_bo_fenced(struct kgem *kgem, struct kgem_bo *bo)
5796 if (kgem->gen < 040 &&
5803 if (kgem->nfence >= kgem->fence_max)
5806 if (kgem->aperture_fenced) {
5807 size = 3*kgem->aperture_fenced;
5808 if (kgem->aperture_total == kgem->aperture_mappable)
5809 size += kgem->aperture;
5810 if (size > kgem->aperture_fenceable &&
5811 kgem_ring_is_idle(kgem, kgem->ring)) {
5817 size = kgem_bo_fenced_size(kgem, bo);
5818 if (size > kgem->aperture_max_fence)
5819 kgem->aperture_max_fence = size;
5820 size += kgem->aperture_fenced;
5821 if (kgem->gen < 033 && size < 2 * kgem->aperture_max_fence)
5822 size = 2 * kgem->aperture_max_fence;
5823 if (kgem->aperture_total == kgem->aperture_mappable)
5824 size += kgem->aperture;
5825 if (size > kgem->aperture_fenceable) {
5827 __FUNCTION__, size, kgem->aperture_fenced, kgem->aperture_max_fence, kgem->aperture, kgem->aperture_fenceable));
5835 if (kgem->nexec >= KGEM_EXEC_SIZE(kgem) - 1)
5838 if (needs_batch_flush(kgem, bo))
5841 assert_tiling(kgem, bo);
5842 if (kgem->gen < 040 && bo->tiling != I915_TILING_NONE) {
5847 if (kgem->nfence >= kgem->fence_max)
5850 if (kgem->aperture_fenced) {
5851 size = 3*kgem->aperture_fenced;
5852 if (kgem->aperture_total == kgem->aperture_mappable)
5853 size += kgem->aperture;
5854 if (size > kgem->aperture_fenceable &&
5855 kgem_ring_is_idle(kgem, kgem->ring)) {
5861 size = kgem_bo_fenced_size(kgem, bo);
5862 if (size > kgem->aperture_max_fence)
5863 kgem->aperture_max_fence = size;
5864 size += kgem->aperture_fenced;
5865 if (kgem->gen < 033 && size < 2 * kgem->aperture_max_fence)
5866 size = 2 * kgem->aperture_max_fence;
5867 if (kgem->aperture_total == kgem->aperture_mappable)
5868 size += kgem->aperture;
5869 if (size > kgem->aperture_fenceable) {
5871 __FUNCTION__, size, kgem->aperture_fenced, kgem->aperture_max_fence, kgem->aperture, kgem->aperture_fenceable));
5876 if (kgem->aperture + kgem->aperture_fenced + num_pages(bo) > kgem->aperture_high) {
5878 __FUNCTION__, kgem->aperture, num_pages(bo), kgem->aperture_high));
5879 return aperture_check(kgem, num_pages(bo));
5885 return kgem_flush(kgem, bo->flush);
5888 bool kgem_check_many_bo_fenced(struct kgem *kgem, ...)
5899 va_start(ap, kgem);
5906 if (kgem->gen >= 040 || bo->tiling == I915_TILING_NONE)
5910 fenced_size += kgem_bo_fenced_size(kgem, bo);
5917 if (needs_batch_flush(kgem, bo)) {
5922 assert_tiling(kgem, bo);
5925 if (kgem->gen < 040 && bo->tiling) {
5926 uint32_t size = kgem_bo_fenced_size(kgem, bo);
5927 if (size > kgem->aperture_max_fence)
5928 kgem->aperture_max_fence = size;
5941 if (kgem->nfence + num_fence > kgem->fence_max)
5944 if (kgem->aperture_fenced) {
5945 size = 3*kgem->aperture_fenced;
5946 if (kgem->aperture_total == kgem->aperture_mappable)
5947 size += kgem->aperture;
5948 if (size > kgem->aperture_fenceable &&
5949 kgem_ring_is_idle(kgem, kgem->ring)) {
5955 size = kgem->aperture_fenced;
5957 if (kgem->gen < 033 && size < 2 * kgem->aperture_max_fence)
5958 size = 2 * kgem->aperture_max_fence;
5959 if (kgem->aperture_total == kgem->aperture_mappable)
5960 size += kgem->aperture;
5961 if (size > kgem->aperture_fenceable) {
5963 __FUNCTION__, size, kgem->aperture_fenced, kgem->aperture_max_fence, kgem->aperture, kgem->aperture_fenceable));
5971 if (kgem->nexec + num_exec >= KGEM_EXEC_SIZE(kgem))
5974 if (num_pages + kgem->aperture > kgem->aperture_high - kgem->aperture_fenced) {
5976 __FUNCTION__, kgem->aperture, kgem->aperture_fenced, num_pages, kgem->aperture_high));
5977 return aperture_check(kgem, num_pages);
5983 return kgem_flush(kgem, flush);
5986 uint32_t kgem_add_reloc(struct kgem *kgem,
5997 assert(kgem->gen < 0100);
6000 index = kgem->nreloc++;
6001 assert(index < ARRAY_SIZE(kgem->reloc));
6002 kgem->reloc[index].offset = pos * sizeof(kgem->batch[0]);
6004 assert(kgem->mode != KGEM_NONE);
6014 &kgem->next_request->buffers);
6015 bo->rq = MAKE_REQUEST(kgem->next_request,
6016 kgem->ring);
6030 kgem_add_bo(kgem, bo);
6031 assert(bo->rq == MAKE_REQUEST(kgem->next_request, kgem->ring));
6032 assert(RQ_RING(bo->rq) == kgem->ring);
6034 if (kgem->gen < 040 && read_write_domain & KGEM_RELOC_FENCED) {
6038 assert(kgem->nfence < kgem->fence_max);
6039 kgem->aperture_fenced +=
6040 kgem_bo_fenced_size(kgem, bo);
6041 kgem->nfence++;
6046 kgem->reloc[index].delta = delta;
6047 kgem->reloc[index].target_handle = bo->target_handle;
6048 kgem->reloc[index].presumed_offset = bo->presumed_offset;
6051 assert(!bo->snoop || kgem->can_blt_cpu);
6057 kgem->reloc[index].delta = delta;
6058 kgem->reloc[index].target_handle = ~0U;
6059 kgem->reloc[index].presumed_offset = 0;
6060 if (kgem->nreloc__self < 256)
6061 kgem->reloc__self[kgem->nreloc__self++] = index;
6063 kgem->reloc[index].read_domains = read_write_domain >> 16;
6064 kgem->reloc[index].write_domain = read_write_domain & 0x7fff;
6069 uint64_t kgem_add_reloc64(struct kgem *kgem,
6080 assert(kgem->gen >= 0100);
6083 index = kgem->nreloc++;
6084 assert(index < ARRAY_SIZE(kgem->reloc));
6085 kgem->reloc[index].offset = pos * sizeof(kgem->batch[0]);
6087 assert(kgem->mode != KGEM_NONE);
6097 &kgem->next_request->buffers);
6098 bo->rq = MAKE_REQUEST(kgem->next_request,
6099 kgem->ring);
6113 kgem_add_bo(kgem, bo);
6114 assert(bo->rq == MAKE_REQUEST(kgem->next_request, kgem->ring));
6115 assert(RQ_RING(bo->rq) == kgem->ring);
6119 kgem->reloc[index].delta = delta;
6120 kgem->reloc[index].target_handle = bo->target_handle;
6121 kgem->reloc[index].presumed_offset = bo->presumed_offset;
6124 assert(!bo->snoop || kgem->can_blt_cpu);
6132 kgem->reloc[index].delta = delta;
6133 kgem->reloc[index].target_handle = ~0U;
6134 kgem->reloc[index].presumed_offset = 0;
6135 if (kgem->nreloc__self < 256)
6136 kgem->reloc__self[kgem->nreloc__self++] = index;
6138 kgem->reloc[index].read_domains = read_write_domain >> 16;
6139 kgem->reloc[index].write_domain = read_write_domain & 0x7fff;
6144 static void kgem_trim_vma_cache(struct kgem *kgem, int type, int bucket)
6149 __FUNCTION__, type, kgem->vma[type].count, bucket));
6150 if (kgem->vma[type].count <= 0)
6153 if (kgem->need_purge)
6154 kgem_purge_cache(kgem);
6164 while (kgem->vma[type].count > 0) {
6168 bo == NULL && j < ARRAY_SIZE(kgem->vma[type].inactive);
6170 struct list *head = &kgem->vma[type].inactive[i++%ARRAY_SIZE(kgem->vma[type].inactive)];
6198 kgem->vma[type].count--;
6200 if (!bo->purged && !kgem_bo_set_purgeable(kgem, bo)) {
6203 kgem_bo_free(kgem, bo);
6208 static void *__kgem_bo_map__gtt_or_wc(struct kgem *kgem, struct kgem_bo *bo)
6217 kgem_trim_vma_cache(kgem, MAP_GTT, bucket(bo));
6219 if (bo->tiling || !kgem->has_wc_mmap) {
6220 assert(num_pages(bo) <= kgem->aperture_mappable / 2);
6221 assert(kgem->gen != 021 || bo->tiling != I915_TILING_Y);
6225 ptr = __kgem_bo_map__gtt(kgem, bo);
6229 ptr = __kgem_bo_map__wc(kgem, bo);
6235 void *kgem_bo_map__async(struct kgem *kgem, struct kgem_bo *bo)
6242 assert_tiling(kgem, bo);
6245 if (bo->tiling == I915_TILING_NONE && !bo->scanout && kgem->has_llc) {
6248 return kgem_bo_map__cpu(kgem, bo);
6251 return __kgem_bo_map__gtt_or_wc(kgem, bo);
6254 void *kgem_bo_map(struct kgem *kgem, struct kgem_bo *bo)
6264 assert_tiling(kgem, bo);
6268 (kgem->has_llc || bo->domain == DOMAIN_CPU)) {
6271 ptr = kgem_bo_map__cpu(kgem, bo);
6273 kgem_bo_sync__cpu(kgem, bo);
6277 ptr = __kgem_bo_map__gtt_or_wc(kgem, bo);
6283 bo->needs_flush, bo->domain, __kgem_busy(kgem, bo->handle)));
6291 if (do_ioctl(kgem->fd, DRM_IOCTL_I915_GEM_SET_DOMAIN, &set_domain)) {
6293 kgem_throttle(kgem);
6295 kgem_bo_retire(kgem, bo);
6303 void *kgem_bo_map__gtt(struct kgem *kgem, struct kgem_bo *bo)
6311 assert_tiling(kgem, bo);
6314 return __kgem_bo_map__gtt_or_wc(kgem, bo);
6317 void *kgem_bo_map__wc(struct kgem *kgem, struct kgem_bo *bo)
6325 assert_tiling(kgem, bo);
6331 return __kgem_bo_map__wc(kgem, bo);
6334 void *kgem_bo_map__cpu(struct kgem *kgem, struct kgem_bo *bo)
6341 assert_tiling(kgem, bo);
6346 kgem_trim_vma_cache(kgem, MAP_CPU, bucket(bo));
6348 return __kgem_bo_map__cpu(kgem, bo);
6351 void *kgem_bo_map__debug(struct kgem *kgem, struct kgem_bo *bo)
6355 if (bo->tiling == I915_TILING_NONE && kgem->has_llc) {
6358 ptr = __kgem_bo_map__cpu(kgem, bo);
6359 } else if (bo->tiling || !kgem->has_wc_mmap) {
6362 ptr = __kgem_bo_map__gtt(kgem, bo);
6366 ptr = __kgem_bo_map__wc(kgem, bo);
6373 uint32_t kgem_bo_flink(struct kgem *kgem, struct kgem_bo *bo)
6379 if (do_ioctl(kgem->fd, DRM_IOCTL_GEM_FLINK, &flink))
6392 kgem_bo_unclean(kgem, bo);
6397 struct kgem_bo *kgem_create_map(struct kgem *kgem,
6408 ptr, size, read_only, kgem->has_userptr));
6409 if (!kgem->has_userptr)
6419 handle = gem_userptr(kgem->fd,
6429 gem_close(kgem->fd, handle);
6433 bo->unique_id = kgem_get_unique_id(kgem);
6434 bo->snoop = !kgem->has_llc;
6435 debug_alloc__bo(kgem, bo);
6440 proxy = kgem_create_proxy(kgem, bo,
6442 kgem_bo_destroy(kgem, bo);
6456 void kgem_bo_sync__cpu(struct kgem *kgem, struct kgem_bo *bo)
6460 assert_tiling(kgem, bo);
6462 kgem_bo_submit(kgem, bo);
6476 __kgem_busy(kgem, bo->handle)));
6483 if (do_ioctl(kgem->fd, DRM_IOCTL_I915_GEM_SET_DOMAIN, &set_domain)) {
6485 kgem_throttle(kgem);
6487 kgem_bo_retire(kgem, bo);
6492 void kgem_bo_sync__cpu_full(struct kgem *kgem, struct kgem_bo *bo, bool write)
6496 assert_tiling(kgem, bo);
6499 kgem_bo_submit(kgem, bo);
6515 __kgem_busy(kgem, bo->handle)));
6522 if (do_ioctl(kgem->fd, DRM_IOCTL_I915_GEM_SET_DOMAIN, &set_domain)) {
6524 kgem_throttle(kgem);
6527 kgem_bo_retire(kgem, bo);
6531 kgem_bo_maybe_retire(kgem, bo);
6537 void kgem_bo_sync__gtt(struct kgem *kgem, struct kgem_bo *bo)
6542 assert_tiling(kgem, bo);
6544 kgem_bo_submit(kgem, bo);
6552 __kgem_busy(kgem, bo->handle)));
6559 if (do_ioctl(kgem->fd, DRM_IOCTL_I915_GEM_SET_DOMAIN, &set_domain)) {
6561 kgem_throttle(kgem);
6563 kgem_bo_retire(kgem, bo);
6569 void kgem_clear_dirty(struct kgem *kgem)
6571 struct list * const buffers = &kgem->next_request->buffers;
6582 struct kgem_bo *kgem_create_proxy(struct kgem *kgem,
6596 bo->unique_id = kgem_get_unique_id(kgem);
6613 assert(RQ(target->rq) == kgem->next_request);
6614 list_move_tail(&bo->request, &kgem->next_request->buffers);
6653 use_snoopable_buffer(struct kgem *kgem, uint32_t flags)
6656 return kgem->gen >= 030;
6685 search_snoopable_buffer(struct kgem *kgem, unsigned alloc)
6690 old = search_snoop_cache(kgem, alloc, 0);
6712 bo->mem = kgem_bo_map__cpu(kgem, &bo->base);
6715 kgem_bo_free(kgem, &bo->base);
6726 create_snoopable_buffer(struct kgem *kgem, unsigned alloc)
6731 if (kgem->has_llc) {
6738 old = search_linear_cache(kgem, alloc,
6743 handle = gem_create(kgem->fd, alloc);
6750 debug_alloc__bo(kgem, &bo->base);
6759 bo->mem = kgem_bo_map__cpu(kgem, &bo->base);
6764 kgem_bo_free(kgem, &bo->base);
6767 if (kgem->has_caching) {
6774 old = search_linear_cache(kgem, alloc,
6779 handle = gem_create(kgem->fd, alloc);
6786 debug_alloc__bo(kgem, &bo->base);
6794 assert(!__kgem_busy(kgem, bo->base.handle));
6796 if (!gem_set_caching(kgem->fd, bo->base.handle, SNOOPED))
6801 bo->mem = kgem_bo_map__cpu(kgem, &bo->base);
6809 kgem_bo_free(kgem, &bo->base);
6812 if (kgem->has_userptr) {
6823 handle = gem_userptr(kgem->fd, bo->mem, alloc * PAGE_SIZE, false);
6831 debug_alloc__bo(kgem, &bo->base);
6848 struct kgem_bo *kgem_create_buffer(struct kgem *kgem,
6863 assert(size <= kgem->max_object_size);
6866 list_for_each_entry(bo, &kgem->batch_buffers, base.list) {
6878 gem_write__cachealigned(kgem->fd, bo->base.handle,
6915 list_for_each_entry(bo, &kgem->active_buffers, base.list) {
6920 assert(bo->mmapped == MMAPPED_GTT || kgem->has_llc || bo->base.snoop);
6933 list_move(&bo->base.list, &kgem->batch_buffers);
6940 !__kgem_busy(kgem, bo->base.handle))) {
6948 kgem_bo_sync__cpu(kgem, &bo->base);
6951 kgem_bo_sync__gtt(kgem, &bo->base);
6957 list_move(&bo->base.list, &kgem->batch_buffers);
6966 alloc = ALIGN(2*size, kgem->buffer_size);
6968 alloc = ALIGN(size, kgem->buffer_size);
6974 if (alloc > kgem->aperture_mappable / 4 && !kgem->has_wc_mmap)
6977 if (kgem->has_llc &&
6985 old = search_linear_cache(kgem, alloc, CREATE_CPU_MAP);
6987 old = search_linear_cache(kgem, alloc, CREATE_INACTIVE | CREATE_CPU_MAP);
6989 old = search_linear_cache(kgem, NUM_PAGES(size), CREATE_INACTIVE | CREATE_CPU_MAP);
6996 uint32_t handle = gem_create(kgem->fd, alloc);
7002 debug_alloc__bo(kgem, &bo->base);
7010 bo->mem = kgem_bo_map__cpu(kgem, &bo->base);
7013 kgem_bo_sync__cpu(kgem, &bo->base);
7018 kgem_bo_free(kgem, &bo->base);
7034 old = search_linear_cache(kgem, alloc,
7044 if (do_ioctl(kgem->fd,
7049 kgem_bo_move_to_inactive(kgem, old);
7056 old = search_linear_cache(kgem, NUM_PAGES(size),
7059 old = search_linear_cache(kgem, alloc, CREATE_INACTIVE);
7060 if (old && !kgem_bo_can_map(kgem, old)) {
7061 _kgem_bo_destroy(kgem, old);
7068 assert(kgem_bo_can_map(kgem, old));
7082 bo->mem = kgem_bo_map(kgem, &bo->base);
7091 kgem_bo_free(kgem, &bo->base);
7102 if (use_snoopable_buffer(kgem, flags)) {
7103 bo = search_snoopable_buffer(kgem, alloc);
7106 kgem_bo_sync__cpu(kgem, &bo->base);
7112 bo = create_snoopable_buffer(kgem, alloc);
7122 old = search_linear_cache(kgem, alloc, 0);
7124 old = search_linear_cache(kgem, alloc, CREATE_INACTIVE);
7137 if (use_snoopable_buffer(kgem, flags)) {
7138 bo = create_snoopable_buffer(kgem, alloc);
7150 old = search_linear_cache(kgem, alloc, hint);
7157 uint32_t handle = gem_create(kgem->fd, alloc);
7167 debug_alloc__bo(kgem, &bo->base);
7175 bo->mem = kgem_bo_map__cpu(kgem, &bo->base);
7177 kgem_bo_sync__cpu(kgem, &bo->base);
7187 kgem_bo_free(kgem, old);
7214 list_add(&bo->base.list, &kgem->batch_buffers);
7224 return kgem_create_proxy(kgem, &bo->base, offset, size);
7233 struct kgem_bo *kgem_create_buffer_2d(struct kgem *kgem,
7244 stride = ALIGN(stride, kgem->gen >= 0100 ? 32 : 4);
7249 bo = kgem_create_buffer(kgem, stride * ALIGN(height, 2), flags, ret);
7280 bo->unique_id = kgem_get_unique_id(kgem);
7284 struct kgem_bo *kgem_upload_source_image(struct kgem *kgem,
7294 if (!kgem_can_create_2d(kgem, width, height, bpp))
7306 bo = kgem_create_buffer_2d(kgem,
7313 kgem_bo_destroy(kgem, bo);
7338 void kgem_buffer_read_sync(struct kgem *kgem, struct kgem_bo *_bo)
7365 __kgem_busy(kgem, bo->base.handle)));
7367 assert(bo->mmapped == MMAPPED_GTT || bo->base.snoop || kgem->has_llc);
7375 if (do_ioctl(kgem->fd, DRM_IOCTL_I915_GEM_SET_DOMAIN, &set_domain)) {
7377 kgem_throttle(kgem);
7380 if (gem_read(kgem->fd,
7385 kgem_bo_maybe_retire(kgem, &bo->base);
7431 kgem_replace_bo(struct kgem *kgem,
7451 assert(kgem_bo_can_blt(kgem, src));
7456 dst = search_linear_cache(kgem, size, 0);
7458 dst = search_linear_cache(kgem, size, CREATE_INACTIVE);
7460 handle = gem_create(kgem->fd, size);
7466 gem_close(kgem->fd, handle);
7470 debug_alloc__bo(kgem, dst);
7473 dst->unique_id = kgem_get_unique_id(kgem);
7476 assert(kgem_bo_can_blt(kgem, dst));
7478 kgem_set_mode(kgem, KGEM_BLT, dst);
7479 if (!kgem_check_batch(kgem, 10) ||
7480 !kgem_check_reloc(kgem, 2) ||
7481 !kgem_check_many_bo_fenced(kgem, src, dst, NULL)) {
7482 kgem_submit(kgem);
7483 if (!kgem_check_many_bo_fenced(kgem, src, dst, NULL)) {
7484 kgem_bo_destroy(kgem, dst);
7487 _kgem_set_mode(kgem, KGEM_BLT);
7493 if (kgem->gen >= 040 && src->tiling) {
7507 b = kgem->batch + kgem->nbatch;
7508 if (kgem->gen >= 0100) {
7514 kgem_add_reloc64(kgem, kgem->nbatch + 4, dst,
7522 kgem_add_reloc64(kgem, kgem->nbatch + 8, src,
7526 kgem->nbatch += 10;
7532 b[4] = kgem_add_reloc(kgem, kgem->nbatch + 4, dst,
7539 b[7] = kgem_add_reloc(kgem, kgem->nbatch + 7, src,
7543 kgem->nbatch += 8;
7549 bool kgem_bo_convert_to_gpu(struct kgem *kgem,
7554 __FUNCTION__, bo->handle, flags, __kgem_bo_is_busy(kgem, bo)));
7557 if (kgem->has_llc)
7560 if (flags & MOVE_ASYNC_HINT && __kgem_bo_is_busy(kgem, bo))
7565 kgem_bo_submit(kgem, bo);
7567 if (!gem_set_caching(kgem->fd, bo->handle, UNCACHED))