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);
229 static inline struct sna *__to_sna(struct kgem *kgem)
232 return container_of(kgem, struct sna, kgem);
271 static void debug_alloc(struct kgem *kgem, size_t size)
273 kgem->debug_memory.bo_allocs++;
274 kgem->debug_memory.bo_bytes += size;
276 static void debug_alloc__bo(struct kgem *kgem, struct kgem_bo *bo)
278 debug_alloc(kgem, bytes(bo));
285 static void assert_tiling(struct kgem *kgem, struct kgem_bo *bo)
291 if (!kgem->can_fence && kgem->gen >= 040 && bo->tiling)
297 (void)do_ioctl(kgem->fd, DRM_IOCTL_I915_GEM_GET_TILING, &tiling);
301 static void assert_caching(struct kgem *kgem, struct kgem_bo *bo)
304 int expect = kgem->has_llc ? SNOOPED : UNCACHED;
310 (void)do_ioctl(kgem->fd, LOCAL_IOCTL_I915_GEM_GET_CACHING, &arg);
326 #define assert_tiling(kgem, bo)
327 #define assert_caching(kgem, bo)
331 static int __find_debugfs(struct kgem *kgem)
350 static int kgem_get_minor(struct kgem *kgem)
354 if (fstat(kgem->fd, &st))
355 return __find_debugfs(kgem);
358 return __find_debugfs(kgem);
363 static bool find_hang_state(struct kgem *kgem, char *path, int maxlen)
365 int minor = kgem_get_minor(kgem);
388 static bool has_error_state(struct kgem *kgem, char *path)
403 static int kgem_get_screen_index(struct kgem *kgem)
405 return __to_sna(kgem)->scrn->scrnIndex;
409 __kgem_set_wedged(struct kgem *kgem)
414 if (kgem->wedged)
418 find_hang_state(kgem, path, sizeof(path)) &&
419 has_error_state(kgem, path)) {
420 xf86DrvMsg(kgem_get_screen_index(kgem), X_ERROR,
426 kgem->wedged = true;
427 sna_render_mark_wedged(__to_sna(kgem));
430 static void kgem_sna_reset(struct kgem *kgem)
432 struct sna *sna = __to_sna(kgem);
438 static void kgem_sna_flush(struct kgem *kgem)
440 struct sna *sna = __to_sna(kgem);
448 static bool kgem_bo_rmfb(struct kgem *kgem, struct kgem_bo *bo)
454 do_ioctl(kgem->fd, DRM_IOCTL_MODE_RMFB, &bo->delta);
461 static bool kgem_set_tiling(struct kgem *kgem, struct kgem_bo *bo,
485 if (ioctl(kgem->fd, DRM_IOCTL_I915_GEM_SET_TILING, &set_tiling) == 0) {
505 if (err == EBUSY && kgem_bo_rmfb(kgem, bo))
547 static bool __kgem_throttle(struct kgem *kgem, bool harder)
554 if (ioctl(kgem->fd, DRM_IOCTL_I915_GEM_THROTTLE) == 0) {
555 kgem->need_throttle = 0;
566 static bool __kgem_throttle_retire(struct kgem *kgem, unsigned flags)
568 if (flags & CREATE_NO_RETIRE || !kgem->need_retire) {
573 if (kgem_retire(kgem))
576 if (flags & CREATE_NO_THROTTLE || !kgem->need_throttle) {
581 __kgem_throttle(kgem, false);
582 return kgem_retire(kgem);
585 static void *__kgem_bo_map__gtt(struct kgem *kgem, struct kgem_bo *bo)
594 if (bo->tiling && !kgem->can_fence)
600 if ((err = do_ioctl(kgem->fd, DRM_IOCTL_I915_GEM_MMAP_GTT, >t))) {
605 (void)__kgem_throttle_retire(kgem, 0);
606 if (kgem_expire_cache(kgem))
609 if (kgem_cleanup_cache(kgem))
619 kgem->fd, gtt.offset);
626 if (__kgem_throttle_retire(kgem, 0))
629 if (kgem_cleanup_cache(kgem))
645 static void *__kgem_bo_map__wc(struct kgem *kgem, struct kgem_bo *bo)
652 assert(kgem->has_wc_mmap);
661 if ((err = do_ioctl(kgem->fd, LOCAL_IOCTL_I915_GEM_MMAP_v2, &wc))) {
666 if (__kgem_throttle_retire(kgem, 0))
669 if (kgem_cleanup_cache(kgem))
683 static void *__kgem_bo_map__cpu(struct kgem *kgem, struct kgem_bo *bo)
694 if ((err = do_ioctl(kgem->fd, LOCAL_IOCTL_I915_GEM_MMAP, &arg))) {
699 if (__kgem_throttle_retire(kgem, 0))
702 if (kgem_cleanup_cache(kgem))
782 bool __kgem_busy(struct kgem *kgem, int handle)
788 busy.busy = !kgem->wedged;
789 (void)do_ioctl(kgem->fd, DRM_IOCTL_I915_GEM_BUSY, &busy);
791 __FUNCTION__, handle, busy.busy, kgem->wedged));
796 static void kgem_bo_retire(struct kgem *kgem, struct kgem_bo *bo)
800 __kgem_busy(kgem, bo->handle)));
805 __kgem_retire_requests_upto(kgem, bo);
806 ASSERT_IDLE(kgem, bo->handle);
810 static void kgem_bo_maybe_retire(struct kgem *kgem, struct kgem_bo *bo)
814 __kgem_busy(kgem, bo->handle)));
819 if (!__kgem_busy(kgem, bo->handle))
820 __kgem_retire_requests_upto(kgem, bo);
823 ASSERT_IDLE(kgem, bo->handle);
827 bool kgem_bo_write(struct kgem *kgem, struct kgem_bo *bo,
835 ASSERT_IDLE(kgem, bo->handle);
840 if (bo->domain == DOMAIN_CPU || (kgem->has_llc && !bo->scanout)) {
843 ptr = __kgem_bo_map__cpu(kgem, bo);
844 } else if (kgem->has_wc_mmap) {
847 ptr = __kgem_bo_map__wc(kgem, bo);
855 if ((err = gem_write(kgem->fd, bo->handle, 0, length, data))) {
860 (void)__kgem_throttle_retire(kgem, 0);
861 if (kgem_expire_cache(kgem))
864 if (kgem_cleanup_cache(kgem))
874 kgem_bo_maybe_retire(kgem, bo);
893 kgem_bo_set_purgeable(struct kgem *kgem, struct kgem_bo *bo)
903 if (do_ioctl(kgem->fd, DRM_IOCTL_I915_GEM_MADVISE, &madv) == 0) {
905 kgem->need_purge |= !madv.retained && bo->domain != DOMAIN_CPU;
911 kgem_bo_is_retained(struct kgem *kgem, struct kgem_bo *bo)
924 if (do_ioctl(kgem->fd, DRM_IOCTL_I915_GEM_MADVISE, &madv) == 0)
932 kgem_bo_clear_purgeable(struct kgem *kgem, struct kgem_bo *bo)
944 if (do_ioctl(kgem->fd, DRM_IOCTL_I915_GEM_MADVISE, &madv) == 0) {
946 kgem->need_purge |= !madv.retained && bo->domain != DOMAIN_CPU;
1023 static struct kgem_request *__kgem_request_alloc(struct kgem *kgem)
1027 if (unlikely(kgem->wedged)) {
1028 rq = &kgem->static_request;
1036 rq = &kgem->static_request;
1058 static struct list *inactive(struct kgem *kgem, int num_pages)
1062 return &kgem->inactive[cache_bucket(num_pages)];
1065 static struct list *active(struct kgem *kgem, int num_pages, int tiling)
1069 return &kgem->active[cache_bucket(num_pages)][tiling];
1174 static int gem_param(struct kgem *kgem, int name)
1182 if (do_ioctl(kgem->fd, DRM_IOCTL_I915_GETPARAM, &gp))
1189 static bool test_has_execbuffer2(struct kgem *kgem)
1196 return do_ioctl(kgem->fd,
1201 static bool test_has_no_reloc(struct kgem *kgem)
1206 return gem_param(kgem, LOCAL_I915_PARAM_HAS_NO_RELOC) > 0;
1209 static bool test_has_handle_lut(struct kgem *kgem)
1214 return gem_param(kgem, LOCAL_I915_PARAM_HAS_HANDLE_LUT) > 0;
1217 static bool test_has_wt(struct kgem *kgem)
1222 return gem_param(kgem, LOCAL_I915_PARAM_HAS_WT) > 0;
1225 static bool test_has_semaphores_enabled(struct kgem *kgem)
1234 ret = gem_param(kgem, LOCAL_I915_PARAM_HAS_SEMAPHORES);
1249 static bool is_hw_supported(struct kgem *kgem,
1255 if (!test_has_execbuffer2(kgem))
1258 if (kgem->gen == (unsigned)-1) /* unknown chipset, assume future gen */
1259 return kgem->has_blt;
1266 if (kgem->gen == 060 && dev && dev->revision < 8) {
1271 if (kgem->gen >= 060) /* Only if the kernel supports the BLT ring */
1272 return kgem->has_blt;
1277 static bool test_has_relaxed_fencing(struct kgem *kgem)
1279 if (kgem->gen < 040) {
1283 return gem_param(kgem, LOCAL_I915_PARAM_HAS_RELAXED_FENCING) > 0;
1288 static bool test_has_coherent_mmap_gtt(struct kgem *kgem)
1293 return gem_param(kgem, LOCAL_I915_PARAM_MMAP_GTT_COHERENT) > 0;
1296 static bool test_has_llc(struct kgem *kgem)
1303 has_llc = gem_param(kgem, LOCAL_I915_PARAM_HAS_LLC);
1306 has_llc = kgem->gen >= 060;
1312 static bool test_has_wc_mmap(struct kgem *kgem)
1321 if (kgem->gen < 033)
1324 if (gem_param(kgem, LOCAL_I915_PARAM_MMAP_VERSION) < 1)
1328 wc.handle = gem_create(kgem->fd, 1);
1332 ret = do_ioctl(kgem->fd, LOCAL_IOCTL_I915_GEM_MMAP_v2, &wc) == 0;
1333 gem_close(kgem->fd, wc.handle);
1338 static bool test_has_caching(struct kgem *kgem)
1347 if (kgem->gen == 040)
1350 handle = gem_create(kgem->fd, 1);
1354 ret = gem_set_caching(kgem->fd, handle, UNCACHED);
1355 gem_close(kgem->fd, handle);
1359 static bool test_has_userptr(struct kgem *kgem)
1368 if (kgem->gen == 040)
1380 do_ioctl(kgem->fd, LOCAL_IOCTL_I915_GEM_USERPTR, &arg)) {
1382 if (do_ioctl(kgem->fd, LOCAL_IOCTL_I915_GEM_USERPTR, &arg))
1386 gem_close(kgem->fd, arg.handle);
1393 static bool test_has_create2(struct kgem *kgem)
1404 if (do_ioctl(kgem->fd, LOCAL_IOCTL_I915_GEM_CREATE2, &args) == 0)
1405 gem_close(kgem->fd, args.handle);
1413 static bool test_can_blt_y(struct kgem *kgem)
1437 if (kgem->gen < 060)
1441 object.handle = gem_create(kgem->fd, 1);
1443 ret = gem_write(kgem->fd, object.handle, 0, sizeof(batch), batch);
1452 ret = do_ioctl(kgem->fd,
1456 gem_close(kgem->fd, object.handle);
1479 static bool test_can_scanout_y(struct kgem *kgem)
1493 arg.handle = gem_create(kgem->fd, 1);
1495 if (gem_set_tiling(kgem->fd, arg.handle, I915_TILING_Y, arg.pitch))
1496 ret = do_ioctl(kgem->fd, DRM_IOCTL_MODE_ADDFB, &arg) == 0;
1518 if (drmIoctl(kgem->fd, LOCAL_IOCTL_MODE_ADDFB2, &f) == 0) {
1523 do_ioctl(kgem->fd, DRM_IOCTL_MODE_RMFB, &arg.fb_id);
1524 gem_close(kgem->fd, arg.handle);
1529 static bool test_has_dirtyfb(struct kgem *kgem)
1543 create.handle = gem_create(kgem->fd, 1);
1547 if (drmIoctl(kgem->fd, DRM_IOCTL_MODE_ADDFB, &create) == 0) {
1552 ret = drmIoctl(kgem->fd,
1561 drmIoctl(kgem->fd,
1565 gem_close(kgem->fd, create.handle);
1570 static bool test_has_secure_batches(struct kgem *kgem)
1575 return gem_param(kgem, LOCAL_I915_PARAM_HAS_SECURE_BATCHES) > 0;
1578 static bool test_has_pinned_batches(struct kgem *kgem)
1583 return gem_param(kgem, LOCAL_I915_PARAM_HAS_PINNED_BATCHES) > 0;
1586 static bool kgem_init_pinned_batches(struct kgem *kgem)
1593 if (unlikely(kgem->wedged))
1603 pin.handle = gem_create(kgem->fd, size[n]);
1612 gem_close(kgem->fd, pin.handle);
1617 ret = do_ioctl(kgem->fd, DRM_IOCTL_I915_GEM_PIN, &pin);
1619 gem_close(kgem->fd, pin.handle);
1624 debug_alloc__bo(kgem, bo);
1625 list_add(&bo->list, &kgem->pinned_batches[n]);
1632 for (n = 0; n < ARRAY_SIZE(kgem->pinned_batches); n++) {
1633 while (!list_is_empty(&kgem->pinned_batches[n])) {
1634 kgem_bo_destroy(kgem,
1635 list_first_entry(&kgem->pinned_batches[n],
1645 if (ret != -ENODEV && kgem->gen == 020)
1648 kgem->has_pinned_batches = false;
1655 handle = gem_create(kgem->fd, size[n]);
1661 gem_close(kgem->fd, handle);
1665 debug_alloc__bo(kgem, bo);
1666 list_add(&bo->list, &kgem->pinned_batches[n]);
1671 static void kgem_init_swizzling(struct kgem *kgem)
1682 tiling.handle = gem_create(kgem->fd, 1);
1686 if (!gem_set_tiling(kgem->fd, tiling.handle, I915_TILING_X, 512))
1689 if (do_ioctl(kgem->fd, LOCAL_IOCTL_I915_GEM_GET_TILING, &tiling))
1695 kgem->can_fence =
1699 if (kgem->gen < 050 && tiling.phys_swizzle_mode != tiling.swizzle_mode)
1703 choose_memcpy_tiled_x(kgem,
1705 __to_sna(kgem)->cpu_features);
1707 gem_close(kgem->fd, tiling.handle);
1708 DBG(("%s: can fence?=%d\n", __FUNCTION__, kgem->can_fence));
1711 static void kgem_fixup_relocs(struct kgem *kgem, struct kgem_bo *bo, int shrink)
1715 bo->target_handle = kgem->has_handle_lut ? kgem->nexec : bo->handle;
1717 assert(kgem->nreloc__self <= 256);
1718 if (kgem->nreloc__self == 0)
1722 __FUNCTION__, kgem->nreloc__self,
1723 kgem->nreloc__self == 256 ? "+" : "",
1725 for (n = 0; n < kgem->nreloc__self; n++) {
1726 int i = kgem->reloc__self[n];
1729 assert(kgem->reloc[i].target_handle == ~0U);
1730 kgem->reloc[i].target_handle = bo->target_handle;
1731 kgem->reloc[i].presumed_offset = bo->presumed_offset;
1733 if (kgem->reloc[i].read_domains == I915_GEM_DOMAIN_INSTRUCTION) {
1736 kgem->reloc[i].delta,
1737 kgem->reloc[i].delta - shrink));
1739 kgem->reloc[i].delta -= shrink;
1741 addr = (int)kgem->reloc[i].delta + bo->presumed_offset;
1742 kgem->batch[kgem->reloc[i].offset/sizeof(uint32_t)] = addr;
1743 if (kgem->gen >= 0100)
1744 kgem->batch[kgem->reloc[i].offset/sizeof(uint32_t) + 1] = addr >> 32;
1748 for (n = kgem->reloc__self[255]; n < kgem->nreloc; n++) {
1749 if (kgem->reloc[n].target_handle == ~0U) {
1752 kgem->reloc[n].target_handle = bo->target_handle;
1753 kgem->reloc[n].presumed_offset = bo->presumed_offset;
1755 if (kgem->reloc[n].read_domains == I915_GEM_DOMAIN_INSTRUCTION) {
1758 kgem->reloc[n].delta,
1759 kgem->reloc[n].delta - shrink));
1760 kgem->reloc[n].delta -= shrink;
1763 addr = (int)kgem->reloc[n].delta + bo->presumed_offset;
1764 kgem->batch[kgem->reloc[n].offset/sizeof(uint32_t)] = addr;
1765 if (kgem->gen >= 0100)
1766 kgem->batch[kgem->reloc[n].offset/sizeof(uint32_t) + 1] = addr >> 32;
1773 for (n = 0; n < kgem->nreloc; n++) {
1774 if (kgem->reloc[n].offset >= sizeof(uint32_t)*kgem->nbatch)
1775 kgem->reloc[n].offset -= shrink;
1780 static int kgem_bo_wait(struct kgem *kgem, struct kgem_bo *bo)
1799 ret = do_ioctl(kgem->fd, LOCAL_IOCTL_I915_GEM_WAIT, &wait);
1807 ret = do_ioctl(kgem->fd,
1813 __kgem_retire_requests_upto(kgem, bo);
1818 static struct kgem_bo *kgem_new_batch(struct kgem *kgem)
1823 last = kgem->batch_bo;
1825 kgem_fixup_relocs(kgem, last, 0);
1826 kgem->batch = NULL;
1829 if (kgem->batch) {
1835 if (!kgem->has_llc)
1839 kgem->batch_bo = kgem_create_linear(kgem,
1840 sizeof(uint32_t)*kgem->batch_size,
1842 if (kgem->batch_bo)
1843 kgem->batch = kgem_bo_map__cpu(kgem, kgem->batch_bo);
1844 if (kgem->batch == NULL) {
1845 int ring = kgem->ring == KGEM_BLT;
1846 assert(ring < ARRAY_SIZE(kgem->requests));
1848 if (kgem->batch_bo) {
1849 kgem_bo_destroy(kgem, kgem->batch_bo);
1850 kgem->batch_bo = NULL;
1853 if (!list_is_empty(&kgem->requests[ring])) {
1856 rq = list_first_entry(&kgem->requests[ring],
1861 if (kgem_bo_wait(kgem, rq->bo) == 0)
1867 if (kgem_cleanup_cache(kgem))
1872 __FUNCTION__, sizeof(uint32_t)*kgem->batch_size));
1873 if (posix_memalign((void **)&kgem->batch, PAGE_SIZE,
1874 ALIGN(sizeof(uint32_t) * kgem->batch_size, PAGE_SIZE))) {
1876 __kgem_set_wedged(kgem);
1880 __FUNCTION__, kgem->batch_bo->handle,
1881 sizeof(uint32_t)*kgem->batch_size));
1882 kgem_bo_sync__cpu(kgem, kgem->batch_bo);
1891 no_retire(struct kgem *kgem)
1893 (void)kgem;
1897 no_expire(struct kgem *kgem)
1899 (void)kgem;
1903 no_context_switch(struct kgem *kgem, int new_mode)
1905 (void)kgem;
1947 void kgem_init(struct kgem *kgem, int fd, struct pci_device *dev, unsigned gen)
1956 kgem->fd = fd;
1957 kgem->gen = gen;
1959 kgem->retire = no_retire;
1960 kgem->expire = no_expire;
1961 kgem->context_switch = no_context_switch;
1963 list_init(&kgem->requests[0]);
1964 list_init(&kgem->requests[1]);
1965 list_init(&kgem->batch_buffers);
1966 list_init(&kgem->active_buffers);
1967 list_init(&kgem->flushing);
1968 list_init(&kgem->large);
1969 list_init(&kgem->large_inactive);
1970 list_init(&kgem->snoop);
1971 list_init(&kgem->scanout);
1972 for (i = 0; i < ARRAY_SIZE(kgem->pinned_batches); i++)
1973 list_init(&kgem->pinned_batches[i]);
1974 for (i = 0; i < ARRAY_SIZE(kgem->inactive); i++)
1975 list_init(&kgem->inactive[i]);
1976 for (i = 0; i < ARRAY_SIZE(kgem->active); i++) {
1977 for (j = 0; j < ARRAY_SIZE(kgem->active[i]); j++)
1978 list_init(&kgem->active[i][j]);
1980 for (i = 0; i < ARRAY_SIZE(kgem->vma); i++) {
1981 for (j = 0; j < ARRAY_SIZE(kgem->vma[i].inactive); j++)
1982 list_init(&kgem->vma[i].inactive[j]);
1984 kgem->vma[MAP_GTT].count = -MAX_GTT_VMA_CACHE;
1985 kgem->vma[MAP_CPU].count = -MAX_CPU_VMA_CACHE;
1987 kgem->has_blt = gem_param(kgem, LOCAL_I915_PARAM_HAS_BLT) > 0;
1989 kgem->has_blt));
1991 kgem->has_relaxed_delta =
1992 gem_param(kgem, LOCAL_I915_PARAM_HAS_RELAXED_DELTA) > 0;
1994 kgem->has_relaxed_delta));
1996 kgem->has_relaxed_fencing = test_has_relaxed_fencing(kgem);
1998 kgem->has_relaxed_fencing));
2000 kgem->has_coherent_mmap_gtt = test_has_coherent_mmap_gtt(kgem);
2002 kgem->has_coherent_mmap_gtt));
2004 kgem->has_llc = test_has_llc(kgem);
2006 kgem->has_llc));
2008 kgem->has_wt = test_has_wt(kgem);
2010 kgem->has_wt));
2012 kgem->has_wc_mmap = test_has_wc_mmap(kgem);
2014 kgem->has_wc_mmap));
2016 kgem->has_caching = test_has_caching(kgem);
2018 kgem->has_caching));
2020 kgem->has_userptr = test_has_userptr(kgem);
2022 kgem->has_userptr));
2024 kgem->has_create2 = test_has_create2(kgem);
2026 kgem->has_create2));
2028 kgem->has_no_reloc = test_has_no_reloc(kgem);
2030 kgem->has_no_reloc));
2032 kgem->has_handle_lut = test_has_handle_lut(kgem);
2034 kgem->has_handle_lut));
2036 kgem->has_semaphores = false;
2037 if (kgem->has_blt && test_has_semaphores_enabled(kgem))
2038 kgem->has_semaphores = true;
2040 kgem->has_semaphores));
2042 kgem->can_blt_cpu = gen >= 030;
2044 kgem->can_blt_cpu));
2046 kgem->can_blt_y = test_can_blt_y(kgem);
2048 kgem->can_blt_y));
2050 kgem->can_render_y = gen != 021 && (gen >> 3) != 4;
2052 kgem->can_render_y));
2054 kgem->can_scanout_y = test_can_scanout_y(kgem);
2056 kgem->can_scanout_y));
2058 kgem->has_dirtyfb = test_has_dirtyfb(kgem);
2059 DBG(("%s: has dirty fb? %d\n", __FUNCTION__, kgem->has_dirtyfb));
2061 kgem->has_secure_batches = test_has_secure_batches(kgem);
2063 kgem->has_secure_batches));
2065 kgem->has_pinned_batches = test_has_pinned_batches(kgem);
2067 kgem->has_pinned_batches));
2069 if (!is_hw_supported(kgem, dev)) {
2070 xf86DrvMsg(kgem_get_screen_index(kgem), X_WARNING,
2072 __kgem_set_wedged(kgem);
2073 } else if (__kgem_throttle(kgem, false)) {
2074 xf86DrvMsg(kgem_get_screen_index(kgem), X_WARNING,
2076 __kgem_set_wedged(kgem);
2079 kgem->batch_size = UINT16_MAX & ~7;
2080 if (gen == 020 && !kgem->has_pinned_batches)
2082 kgem->batch_size = 4*1024;
2085 kgem->batch_size = PAGE_SIZE / sizeof(uint32_t);
2087 kgem->batch_size = 16*1024;
2088 if (!kgem->has_relaxed_delta && kgem->batch_size > 4*1024)
2089 kgem->batch_size = 4*1024;
2091 if (!kgem_init_pinned_batches(kgem)) {
2092 xf86DrvMsg(kgem_get_screen_index(kgem), X_WARNING,
2094 __kgem_set_wedged(kgem);
2098 kgem->batch_size));
2099 kgem_new_batch(kgem);
2101 kgem->half_cpu_cache_pages = cpu_cache_size() >> 13;
2103 __FUNCTION__, cpu_cache_size(), kgem->half_cpu_cache_pages));
2105 kgem->next_request = __kgem_request_alloc(kgem);
2108 !DBG_NO_CPU && (kgem->has_llc | kgem->has_userptr | kgem->has_caching),
2109 kgem->has_llc, kgem->has_caching, kgem->has_userptr));
2112 kgem->aperture_total = gtt_size;
2113 kgem->aperture_high = gtt_size * 3/4;
2114 kgem->aperture_low = gtt_size * 1/3;
2117 kgem->aperture_high /= 2;
2118 kgem->aperture_low /= 2;
2121 kgem->aperture_low, kgem->aperture_low / (1024*1024),
2122 kgem->aperture_high, kgem->aperture_high / (1024*1024)));
2124 kgem->aperture_mappable = 256 * 1024 * 1024;
2126 kgem->aperture_mappable = agp_aperture_size(dev, gen);
2127 if (kgem->aperture_mappable == 0 || kgem->aperture_mappable > gtt_size)
2128 kgem->aperture_mappable = gtt_size;
2130 kgem->aperture_mappable, kgem->aperture_mappable / (1024*1024)));
2132 kgem->aperture_fenceable = MIN(256*1024*1024, kgem->aperture_mappable);
2134 kgem->aperture_fenceable, kgem->aperture_fenceable / (1024*1024)));
2136 kgem->buffer_size = 64 * 1024;
2137 while (kgem->buffer_size < kgem->aperture_mappable >> 10)
2138 kgem->buffer_size *= 2;
2139 if (kgem->buffer_size >> 12 > kgem->half_cpu_cache_pages)
2140 kgem->buffer_size = kgem->half_cpu_cache_pages << 12;
2141 kgem->buffer_size = 1 << __fls(kgem->buffer_size);
2143 kgem->buffer_size, kgem->buffer_size / 1024));
2144 assert(kgem->buffer_size);
2146 kgem->max_object_size = 3 * (kgem->aperture_high >> 12) << 10;
2147 kgem->max_gpu_size = kgem->max_object_size;
2148 if (!kgem->has_llc && kgem->max_gpu_size > MAX_CACHE_SIZE)
2149 kgem->max_gpu_size = MAX_CACHE_SIZE;
2155 totalram = kgem->aperture_total;
2158 if (kgem->max_object_size > totalram / 2)
2159 kgem->max_object_size = totalram / 2;
2160 if (kgem->max_gpu_size > totalram / 4)
2161 kgem->max_gpu_size = totalram / 4;
2163 if (kgem->aperture_high > totalram / 2) {
2164 kgem->aperture_high = totalram / 2;
2165 kgem->aperture_low = kgem->aperture_high / 4;
2167 kgem->aperture_low, kgem->aperture_low / (1024*1024),
2168 kgem->aperture_high, kgem->aperture_high / (1024*1024)));
2171 kgem->max_cpu_size = kgem->max_object_size;
2173 half_gpu_max = kgem->max_gpu_size / 2;
2174 kgem->max_copy_tile_size = (MAX_CACHE_SIZE + 1)/2;
2175 if (kgem->max_copy_tile_size > half_gpu_max)
2176 kgem->max_copy_tile_size = half_gpu_max;
2178 if (kgem->has_llc)
2179 kgem->max_upload_tile_size = kgem->max_copy_tile_size;
2181 kgem->max_upload_tile_size = kgem->aperture_fenceable / 4;
2182 if (kgem->max_upload_tile_size > half_gpu_max)
2183 kgem->max_upload_tile_size = half_gpu_max;
2184 if (kgem->max_upload_tile_size > kgem->aperture_high/2)
2185 kgem->max_upload_tile_size = kgem->aperture_high/2;
2186 if (kgem->max_upload_tile_size > kgem->aperture_low)
2187 kgem->max_upload_tile_size = kgem->aperture_low;
2188 if (kgem->max_upload_tile_size < 16*PAGE_SIZE)
2189 kgem->max_upload_tile_size = 16*PAGE_SIZE;
2191 kgem->large_object_size = MAX_CACHE_SIZE;
2192 if (kgem->large_object_size > half_gpu_max)
2193 kgem->large_object_size = half_gpu_max;
2194 if (kgem->max_copy_tile_size > kgem->aperture_high/2)
2195 kgem->max_copy_tile_size = kgem->aperture_high/2;
2196 if (kgem->max_copy_tile_size > kgem->aperture_low)
2197 kgem->max_copy_tile_size = kgem->aperture_low;
2198 if (kgem->max_copy_tile_size < 16*PAGE_SIZE)
2199 kgem->max_copy_tile_size = 16*PAGE_SIZE;
2201 if (kgem->has_llc | kgem->has_caching | kgem->has_userptr) {
2202 if (kgem->large_object_size > kgem->max_cpu_size)
2203 kgem->large_object_size = kgem->max_cpu_size;
2205 kgem->max_cpu_size = 0;
2207 kgem->max_cpu_size = 0;
2210 __FUNCTION__, kgem->max_object_size));
2212 __FUNCTION__, kgem->large_object_size));
2215 kgem->max_gpu_size, kgem->max_cpu_size,
2216 kgem->max_upload_tile_size, kgem->max_copy_tile_size));
2219 kgem->aperture_mappable /= PAGE_SIZE;
2220 kgem->aperture_fenceable /= PAGE_SIZE;
2221 kgem->aperture_low /= PAGE_SIZE;
2222 kgem->aperture_high /= PAGE_SIZE;
2223 kgem->aperture_total /= PAGE_SIZE;
2225 kgem->fence_max = gem_param(kgem, I915_PARAM_NUM_FENCES_AVAIL) - 2;
2226 if ((int)kgem->fence_max < 0)
2227 kgem->fence_max = 5; /* minimum safe value for all hw */
2228 DBG(("%s: max fences=%d\n", __FUNCTION__, kgem->fence_max));
2230 kgem->batch_flags_base = 0;
2231 if (kgem->has_no_reloc)
2232 kgem->batch_flags_base |= LOCAL_I915_EXEC_NO_RELOC;
2233 if (kgem->has_handle_lut)
2234 kgem->batch_flags_base |= LOCAL_I915_EXEC_HANDLE_LUT;
2235 if (kgem->has_pinned_batches)
2236 kgem->batch_flags_base |= LOCAL_I915_EXEC_IS_PINNED;
2238 kgem_init_swizzling(kgem);
2242 static uint32_t kgem_get_unique_id(struct kgem *kgem)
2245 id = ++kgem->unique_id;
2247 id = ++kgem->unique_id;
2251 inline static uint32_t kgem_pitch_alignment(struct kgem *kgem, unsigned flags)
2257 if (kgem->gen >= 0100)
2262 void kgem_get_tile_size(struct kgem *kgem, int tiling, int pitch,
2265 if (kgem->gen <= 030) {
2267 if (kgem->gen < 030) {
2301 if (tiling && kgem->gen < 033)
2305 static uint32_t kgem_surface_size(struct kgem *kgem,
2321 if (kgem->gen <= 030) {
2323 if (kgem->gen < 030) {
2333 kgem_pitch_alignment(kgem, flags));
2341 kgem_pitch_alignment(kgem, flags));
2355 if (!kgem->has_relaxed_fencing)
2363 if (kgem->gen >= 040)
2390 if (kgem->gen < 030)
2399 bool kgem_check_surface_size(struct kgem *kgem,
2416 min_size = kgem_surface_size(kgem, kgem->has_relaxed_fencing, 0,
2428 kgem_get_tile_size(kgem, tiling, min_pitch,
2440 static uint32_t kgem_aligned_height(struct kgem *kgem,
2445 if (kgem->gen <= 030) {
2446 tile_height = tiling ? kgem->gen < 030 ? 16 : 8 : 1;
2462 if (!kgem->has_relaxed_fencing)
2469 kgem_add_handle(struct kgem *kgem, struct kgem_bo *bo)
2474 __FUNCTION__, bo->handle, kgem->nexec));
2476 assert(kgem->nexec < ARRAY_SIZE(kgem->exec));
2477 bo->target_handle = kgem->has_handle_lut ? kgem->nexec : bo->handle;
2478 exec = memset(&kgem->exec[kgem->nexec++], 0, sizeof(*exec));
2482 kgem->aperture += num_pages(bo);
2487 static void kgem_add_bo(struct kgem *kgem, struct kgem_bo *bo)
2492 bo->exec = kgem_add_handle(kgem, bo);
2493 bo->rq = MAKE_REQUEST(kgem->next_request, kgem->ring);
2495 list_move_tail(&bo->request, &kgem->next_request->buffers);
2497 list_move(&bo->list, &kgem->batch_buffers);
2500 kgem->flush |= bo->flush;
2503 static void kgem_clear_swctrl(struct kgem *kgem)
2507 if (kgem->bcs_state == 0)
2511 __FUNCTION__, kgem->bcs_state));
2513 b = kgem->batch + kgem->nbatch;
2514 kgem->nbatch += 7;
2525 kgem->bcs_state = 0;
2528 static uint32_t kgem_end_batch(struct kgem *kgem)
2530 kgem_clear_swctrl(kgem);
2531 kgem->batch[kgem->nbatch++] = MI_BATCH_BUFFER_END;
2532 if (kgem->nbatch & 1)
2533 kgem->batch[kgem->nbatch++] = MI_NOOP;
2535 return kgem->nbatch;
2538 static void kgem_bo_binding_free(struct kgem *kgem, struct kgem_bo *bo)
2550 static void kgem_bo_free(struct kgem *kgem, struct kgem_bo *bo)
2559 kgem->debug_memory.bo_allocs--;
2560 kgem->debug_memory.bo_bytes -= bytes(bo);
2563 kgem_bo_binding_free(kgem, bo);
2564 kgem_bo_rmfb(kgem, bo);
2568 assert(!__kgem_busy(kgem, bo->handle));
2580 bo->handle, list_is_empty(&bo->vma) ? 0 : kgem->vma[bo->map__gtt == NULL && bo->map__wc == NULL].count));
2584 kgem->vma[bo->map__gtt == NULL && bo->map__wc == NULL].count--;
2600 gem_close(kgem->fd, bo->handle);
2609 inline static void kgem_bo_move_to_inactive(struct kgem *kgem,
2627 assert_tiling(kgem, bo);
2628 assert_caching(kgem, bo);
2629 ASSERT_IDLE(kgem, bo->handle);
2639 list_move(&bo->list, &kgem->large_inactive);
2643 list_move(&bo->list, &kgem->inactive[bucket(bo)]);
2644 if (bo->map__gtt && !kgem_bo_can_map(kgem, bo)) {
2651 list_add(&bo->vma, &kgem->vma[0].inactive[bucket(bo)]);
2652 kgem->vma[0].count++;
2655 list_add(&bo->vma, &kgem->vma[1].inactive[bucket(bo)]);
2656 kgem->vma[1].count++;
2660 kgem->need_expire = true;
2697 inline static void kgem_bo_remove_from_inactive(struct kgem *kgem,
2709 kgem->vma[bo->map__gtt == NULL && bo->map__wc == NULL].count--;
2713 inline static void kgem_bo_remove_from_active(struct kgem *kgem,
2720 if (RQ(bo->rq) == (void *)kgem) {
2727 static void _kgem_bo_delete_buffer(struct kgem *kgem, struct kgem_bo *bo)
2738 static bool check_scanout_size(struct kgem *kgem,
2749 if (do_ioctl(kgem->fd, DRM_IOCTL_MODE_GETFB, &info))
2752 gem_close(kgem->fd, info.handle);
2765 static void kgem_bo_move_to_scanout(struct kgem *kgem, struct kgem_bo *bo)
2777 kgem_bo_free(kgem, bo);
2785 list_move_tail(&bo->list, &kgem->scanout);
2787 list_move(&bo->list, &kgem->scanout);
2789 kgem->need_expire = true;
2792 static void kgem_bo_move_to_snoop(struct kgem *kgem, struct kgem_bo *bo)
2804 kgem_bo_free(kgem, bo);
2808 if (num_pages(bo) > kgem->max_cpu_size >> 13) {
2810 __FUNCTION__, bo->handle, num_pages(bo), kgem->max_cpu_size >> 13));
2811 kgem_bo_free(kgem, bo);
2819 list_add(&bo->list, &kgem->snoop);
2820 kgem->need_expire = true;
2823 static bool kgem_bo_move_to_cache(struct kgem *kgem, struct kgem_bo *bo)
2832 kgem_bo_free(kgem, bo);
2834 kgem_bo_move_to_snoop(kgem, bo);
2836 kgem_bo_move_to_scanout(kgem, bo);
2838 kgem_bo_move_to_inactive(kgem, bo);
2841 kgem_bo_free(kgem, bo);
2847 search_snoop_cache(struct kgem *kgem, unsigned int num_pages, unsigned flags)
2853 if ((kgem->has_caching | kgem->has_userptr) == 0)
2856 if (list_is_empty(&kgem->snoop)) {
2858 if (!__kgem_throttle_retire(kgem, flags)) {
2864 list_for_each_entry(bo, &kgem->snoop, list) {
2905 void kgem_bo_undo(struct kgem *kgem, struct kgem_bo *bo)
2907 if (kgem->nexec != 1 || bo->exec == NULL)
2914 assert(bo->exec == &_kgem_dummy_exec || bo->exec == &kgem->exec[0]);
2915 assert(kgem->exec[0].handle == bo->handle);
2916 assert(RQ(bo->rq) == kgem->next_request);
2919 kgem_reset(kgem);
2922 assert(kgem->nreloc == 0);
2923 assert(kgem->nexec == 0);
2927 void kgem_bo_pair_undo(struct kgem *kgem, struct kgem_bo *a, struct kgem_bo *b)
2929 if (kgem->nexec > 2)
2932 if (kgem->nexec == 1) {
2934 kgem_bo_undo(kgem, a);
2936 kgem_bo_undo(kgem, b);
2948 a->handle, a->proxy ? -1 : a->exec - kgem->exec,
2949 b->handle, b->proxy ? -1 : b->exec - kgem->exec));
2952 a->exec == &kgem->exec[0] ||
2953 a->exec == &kgem->exec[1]);
2954 assert(a->handle == kgem->exec[0].handle || a->handle == kgem->exec[1].handle);
2955 assert(RQ(a->rq) == kgem->next_request);
2957 b->exec == &kgem->exec[0] ||
2958 b->exec == &kgem->exec[1]);
2959 assert(b->handle == kgem->exec[0].handle || b->handle == kgem->exec[1].handle);
2960 assert(RQ(b->rq) == kgem->next_request);
2964 kgem_reset(kgem);
2968 assert(kgem->nreloc == 0);
2969 assert(kgem->nexec == 0);
2974 static void __kgem_bo_destroy(struct kgem *kgem, struct kgem_bo *bo)
2983 assert_tiling(kgem, bo);
2997 if (bo->exec == NULL && bo->rq && !__kgem_busy(kgem, bo->handle))
3000 kgem_bo_move_to_snoop(kgem, bo);
3007 kgem_bo_move_to_scanout(kgem, bo);
3025 assert_caching(kgem, bo);
3027 kgem_bo_undo(kgem, bo);
3030 if (bo->rq && bo->exec == NULL && !__kgem_busy(kgem, bo->handle))
3038 cache = &kgem->active[bucket(bo)][bo->tiling];
3040 cache = &kgem->large;
3049 if (!kgem->has_llc && bo->domain == DOMAIN_CPU)
3056 kgem_bo_move_to_inactive(kgem, bo);
3061 kgem_bo_free(kgem, bo);
3064 static void kgem_bo_unref(struct kgem *kgem, struct kgem_bo *bo)
3068 __kgem_bo_destroy(kgem, bo);
3071 static void kgem_buffer_release(struct kgem *kgem, struct kgem_buffer *bo)
3086 kgem_bo_destroy(kgem, cached);
3090 void kgem_retire__buffers(struct kgem *kgem)
3092 while (!list_is_empty(&kgem->active_buffers)) {
3094 list_last_entry(&kgem->active_buffers,
3101 assert(bo->base.exec == NULL || RQ(bo->base.rq) == kgem->next_request);
3108 kgem_buffer_release(kgem, bo);
3109 kgem_bo_unref(kgem, &bo->base);
3113 static bool kgem_retire__flushing(struct kgem *kgem)
3118 list_for_each_entry_safe(bo, next, &kgem->flushing, request) {
3119 assert(RQ(bo->rq) == (void *)kgem);
3122 if (__kgem_busy(kgem, bo->handle))
3130 retired |= kgem_bo_move_to_cache(kgem, bo);
3135 list_for_each_entry(bo, &kgem->flushing, request)
3141 kgem->need_retire |= !list_is_empty(&kgem->flushing);
3146 static bool __kgem_bo_flush(struct kgem *kgem, struct kgem_bo *bo)
3157 busy.busy = !kgem->wedged;
3158 (void)do_ioctl(kgem->fd, DRM_IOCTL_I915_GEM_BUSY, &busy);
3160 __FUNCTION__, bo->handle, busy.busy, kgem->wedged));
3167 list_add(&bo->request, &kgem->flushing);
3168 bo->rq = MAKE_REQUEST(kgem, !!(busy.busy & ~0x1ffff));
3170 kgem->need_retire = true;
3174 static bool __kgem_retire_rq(struct kgem *kgem, struct kgem_request *rq)
3181 assert(rq != (struct kgem_request *)kgem);
3182 assert(rq != &kgem->static_request);
3184 if (rq == kgem->fence[rq->ring])
3185 kgem->fence[rq->ring] = NULL;
3200 if (unlikely(__kgem_bo_flush(kgem, bo))) {
3212 retired |= kgem_bo_move_to_cache(kgem, bo);
3221 kgem_bo_move_to_inactive(kgem, rq->bo);
3229 static bool kgem_retire__requests_ring(struct kgem *kgem, int ring)
3233 assert(ring < ARRAY_SIZE(kgem->requests));
3234 while (!list_is_empty(&kgem->requests[ring])) {
3239 rq = list_first_entry(&kgem->requests[ring],
3245 if (__kgem_busy(kgem, rq->bo->handle))
3248 retired |= __kgem_retire_rq(kgem, rq);
3256 list_for_each_entry(bo, &kgem->requests[ring], request)
3260 if (!list_is_empty(&kgem->requests[ring]))
3261 bo = list_first_entry(&kgem->requests[ring],
3273 static bool kgem_retire__requests(struct kgem *kgem)
3278 for (n = 0; n < ARRAY_SIZE(kgem->requests); n++) {
3279 retired |= kgem_retire__requests_ring(kgem, n);
3280 kgem->need_retire |= !list_is_empty(&kgem->requests[n]);
3286 bool kgem_retire(struct kgem *kgem)
3290 DBG(("%s, need_retire?=%d\n", __FUNCTION__, kgem->need_retire));
3292 kgem->need_retire = false;
3294 retired |= kgem_retire__flushing(kgem);
3295 retired |= kgem_retire__requests(kgem);
3298 __FUNCTION__, retired, kgem->need_retire));
3300 kgem->retire(kgem);
3305 bool __kgem_ring_is_idle(struct kgem *kgem, int ring)
3309 assert(ring < ARRAY_SIZE(kgem->requests));
3310 assert(!list_is_empty(&kgem->requests[ring]));
3312 rq = kgem->fence[ring];
3316 if (__kgem_busy(kgem, rq->bo->handle)) {
3323 tmp = list_first_entry(&kgem->requests[ring],
3327 __kgem_retire_rq(kgem, tmp);
3330 assert(kgem->fence[ring] == NULL);
3331 if (list_is_empty(&kgem->requests[ring]))
3335 rq = list_last_entry(&kgem->requests[ring],
3340 if (__kgem_busy(kgem, rq->bo->handle)) {
3343 kgem->fence[ring] = rq;
3350 while (!list_is_empty(&kgem->requests[ring])) {
3351 rq = list_first_entry(&kgem->requests[ring],
3355 __kgem_retire_rq(kgem, rq);
3361 bool __kgem_retire_requests_upto(struct kgem *kgem, struct kgem_bo *bo)
3364 struct list *requests = &kgem->requests[rq->ring];
3368 assert(rq != &kgem->static_request);
3369 if (rq == (struct kgem_request *)kgem) {
3374 assert(rq->ring < ARRAY_SIZE(kgem->requests));
3378 __kgem_retire_rq(kgem, tmp);
3388 static void kgem_commit__check_reloc(struct kgem *kgem)
3390 struct kgem_request *rq = kgem->next_request;
3392 bool has_64bit = kgem->gen >= 0100;
3395 for (i = 0; i < kgem->nreloc; i++) {
3397 if (bo->target_handle == kgem->reloc[i].target_handle) {
3399 gem_read(kgem->fd, rq->bo->handle, &value, kgem->reloc[i].offset, has_64bit ? 8 : 4);
3400 assert(bo->exec->offset == -1 || value == bo->exec->offset + (int)kgem->reloc[i].delta);
3407 #define kgem_commit__check_reloc(kgem)
3411 static void kgem_commit__check_buffers(struct kgem *kgem)
3415 list_for_each_entry(bo, &kgem->active_buffers, base.list)
3419 #define kgem_commit__check_buffers(kgem)
3422 static void kgem_commit(struct kgem *kgem)
3424 struct kgem_request *rq = kgem->next_request;
3427 kgem_commit__check_reloc(kgem);
3448 kgem_bo_free(kgem, bo);
3462 kgem->scanout_busy |= bo->scanout && bo->needs_flush;
3465 if (rq == &kgem->static_request) {
3474 if (do_ioctl(kgem->fd, DRM_IOCTL_I915_GEM_SET_DOMAIN, &set_domain)) {
3476 kgem_throttle(kgem);
3493 _kgem_bo_destroy(kgem, bo);
3496 kgem_retire(kgem);
3502 gem_close(kgem->fd, rq->bo->handle);
3503 kgem_cleanup_cache(kgem);
3505 assert(rq != (struct kgem_request *)kgem);
3506 assert(rq->ring < ARRAY_SIZE(kgem->requests));
3508 list_add_tail(&rq->list, &kgem->requests[rq->ring]);
3509 kgem->need_throttle = kgem->need_retire = 1;
3511 if (kgem->fence[rq->ring] == NULL &&
3512 __kgem_busy(kgem, rq->bo->handle))
3513 kgem->fence[rq->ring] = rq;
3516 kgem->next_request = NULL;
3518 kgem_commit__check_buffers(kgem);
3521 static void kgem_close_list(struct kgem *kgem, struct list *head)
3524 kgem_bo_free(kgem, list_first_entry(head, struct kgem_bo, list));
3527 static void kgem_close_inactive(struct kgem *kgem)
3531 for (i = 0; i < ARRAY_SIZE(kgem->inactive); i++) {
3532 kgem_close_list(kgem, &kgem->inactive[i]);
3533 assert(list_is_empty(&kgem->inactive[i]));
3537 static void kgem_finish_buffers(struct kgem *kgem)
3541 list_for_each_entry_safe(bo, next, &kgem->batch_buffers, base.list) {
3570 (kgem->has_llc || bo->mmapped == MMAPPED_GTT || bo->base.snoop)) {
3575 &kgem->active_buffers);
3576 kgem->need_retire = true;
3594 assert(bo->base.rq == MAKE_REQUEST(kgem->next_request, kgem->ring));
3603 shrink = search_snoop_cache(kgem, alloc,
3615 map = kgem_bo_map__cpu(kgem, shrink);
3620 kgem->has_handle_lut ? bo->base.target_handle : shrink->handle;
3621 for (n = 0; n < kgem->nreloc; n++) {
3622 if (kgem->reloc[n].target_handle == bo->base.target_handle) {
3623 uint64_t addr = (int)kgem->reloc[n].delta + shrink->presumed_offset;
3624 kgem->batch[kgem->reloc[n].offset/sizeof(kgem->batch[0])] = addr;
3625 if (kgem->gen >= 0100)
3626 kgem->batch[kgem->reloc[n].offset/sizeof(kgem->batch[0]) + 1] = addr >> 32;
3628 kgem->reloc[n].target_handle = shrink->target_handle;
3629 kgem->reloc[n].presumed_offset = shrink->presumed_offset;
3651 __kgem_bo_destroy(kgem, shrink);
3654 shrink = search_linear_cache(kgem, alloc,
3665 if (gem_write__cachealigned(kgem->fd, shrink->handle,
3668 kgem->has_handle_lut ? bo->base.target_handle : shrink->handle;
3669 for (n = 0; n < kgem->nreloc; n++) {
3670 if (kgem->reloc[n].target_handle == bo->base.target_handle) {
3671 uint64_t addr = (int)kgem->reloc[n].delta + shrink->presumed_offset;
3672 kgem->batch[kgem->reloc[n].offset/sizeof(kgem->batch[0])] = addr;
3673 if (kgem->gen >= 0100)
3674 kgem->batch[kgem->reloc[n].offset/sizeof(kgem->batch[0]) + 1] = addr >> 32;
3676 kgem->reloc[n].target_handle = shrink->target_handle;
3677 kgem->reloc[n].presumed_offset = shrink->presumed_offset;
3699 __kgem_bo_destroy(kgem, shrink);
3705 ASSERT_IDLE(kgem, bo->base.handle);
3707 gem_write__cachealigned(kgem->fd, bo->base.handle,
3715 kgem_bo_unref(kgem, &bo->base);
3719 static void kgem_cleanup(struct kgem *kgem)
3723 for (n = 0; n < ARRAY_SIZE(kgem->requests); n++) {
3724 while (!list_is_empty(&kgem->requests[n])) {
3727 rq = list_first_entry(&kgem->requests[n],
3742 kgem_bo_free(kgem, bo);
3746 kgem_bo_free(kgem, rq->bo);
3752 kgem_close_inactive(kgem);
3756 kgem_batch_write(struct kgem *kgem,
3765 assert(!__kgem_busy(kgem, bo->handle));
3770 return gem_write(kgem->fd, bo->handle, 0, sizeof(batch), batch);
3777 if (bo->domain == DOMAIN_CPU || kgem->has_llc) {
3780 ptr = __kgem_bo_map__cpu(kgem, bo);
3781 } else if (kgem->has_wc_mmap) {
3784 ptr = __kgem_bo_map__wc(kgem, bo);
3787 memcpy(ptr, kgem->batch, sizeof(uint32_t)*kgem->nbatch);
3788 if (kgem->surface != kgem->batch_size) {
3789 ret = PAGE_ALIGN(sizeof(uint32_t) * kgem->batch_size);
3790 ret -= sizeof(uint32_t) * kgem->surface;
3792 memcpy(ptr, kgem->batch + kgem->surface,
3793 (kgem->batch_size - kgem->surface)*sizeof(uint32_t));
3799 if (kgem->surface == kgem->batch_size) {
3800 if ((ret = gem_write__cachealigned(kgem->fd, bo->handle,
3801 0, sizeof(uint32_t)*kgem->nbatch,
3802 kgem->batch)) == 0)
3809 if (kgem->surface < kgem->nbatch + PAGE_SIZE/sizeof(uint32_t)) {
3810 assert(size == PAGE_ALIGN(kgem->batch_size*sizeof(uint32_t)));
3811 if ((ret = gem_write__cachealigned(kgem->fd, bo->handle,
3812 0, kgem->batch_size*sizeof(uint32_t),
3813 kgem->batch)) == 0)
3820 if ((ret = gem_write__cachealigned(kgem->fd, bo->handle,
3821 0, sizeof(uint32_t)*kgem->nbatch,
3822 kgem->batch)))
3825 ret = PAGE_ALIGN(sizeof(uint32_t) * kgem->batch_size);
3826 ret -= sizeof(uint32_t) * kgem->surface;
3827 assert(size-ret >= kgem->nbatch*sizeof(uint32_t));
3828 if (gem_write(kgem->fd, bo->handle,
3829 size - ret, (kgem->batch_size - kgem->surface)*sizeof(uint32_t),
3830 kgem->batch + kgem->surface))
3838 (void)__kgem_throttle_retire(kgem, 0);
3839 if (kgem_expire_cache(kgem))
3842 if (kgem_cleanup_cache(kgem))
3850 void kgem_reset(struct kgem *kgem)
3852 if (kgem->next_request) {
3853 struct kgem_request *rq = kgem->next_request;
3869 if (bo->needs_flush && __kgem_busy(kgem, bo->handle)) {
3871 list_add(&bo->request, &kgem->flushing);
3872 bo->rq = (void *)kgem;
3873 kgem->need_retire = true;
3880 kgem_bo_move_to_cache(kgem, bo);
3883 if (rq != &kgem->static_request) {
3889 kgem->nfence = 0;
3890 kgem->nexec = 0;
3891 kgem->nreloc = 0;
3892 kgem->nreloc__self = 0;
3893 kgem->aperture = 0;
3894 kgem->aperture_fenced = 0;
3895 kgem->aperture_max_fence = 0;
3896 kgem->nbatch = 0;
3897 kgem->surface = kgem->batch_size;
3898 kgem->mode = KGEM_NONE;
3899 kgem->needs_semaphore = false;
3900 kgem->needs_reservation = false;
3901 kgem->flush = 0;
3902 kgem->batch_flags = kgem->batch_flags_base;
3903 assert(kgem->batch);
3905 kgem->next_request = __kgem_request_alloc(kgem);
3907 kgem_sna_reset(kgem);
3910 static int compact_batch_surface(struct kgem *kgem, int *shrink)
3914 if (!kgem->has_relaxed_delta)
3915 return kgem->batch_size * sizeof(uint32_t);
3918 n = ALIGN(kgem->batch_size, 1024);
3919 size = n - kgem->surface + kgem->nbatch;
3926 static struct kgem_bo *first_available(struct kgem *kgem, struct list *list)
3935 if (__kgem_busy(kgem, bo->handle))
3938 __kgem_retire_rq(kgem, RQ(bo->rq));
3953 kgem_create_batch(struct kgem *kgem)
3959 if (kgem->surface != kgem->batch_size)
3960 size = compact_batch_surface(kgem, &shrink);
3962 size = kgem->nbatch * sizeof(uint32_t);
3965 bo = first_available(kgem, &kgem->pinned_batches[0]);
3971 bo = first_available(kgem, &kgem->pinned_batches[1]);
3976 if (kgem->gen == 020) {
3977 bo = kgem_create_linear(kgem, size, CREATE_CACHED | CREATE_TEMPORARY);
3982 if (kgem->has_pinned_batches) {
3983 bo = kgem_create_linear(kgem, size, CREATE_CACHED | CREATE_TEMPORARY);
3985 kgem->batch_flags &= ~LOCAL_I915_EXEC_IS_PINNED;
3991 bo = list_first_entry(&kgem->pinned_batches[size > 4096],
3994 list_move_tail(&bo->list, &kgem->pinned_batches[size > 4096]);
3997 if (kgem_bo_wait(kgem, bo))
4000 kgem_retire(kgem);
4007 if (kgem->surface != kgem->batch_size)
4008 size = kgem->batch_size * sizeof(uint32_t);
4010 size = kgem->nbatch * sizeof(uint32_t);
4013 if (!kgem->batch_bo || !kgem->has_llc) {
4014 bo = kgem_create_linear(kgem, size, CREATE_NO_THROTTLE);
4017 kgem_fixup_relocs(kgem, bo, shrink);
4018 if (kgem_batch_write(kgem, bo, size)) {
4019 kgem_bo_destroy(kgem, bo);
4026 return kgem_new_batch(kgem);
4048 static void dump_debugfs(struct kgem *kgem, const char *name)
4051 int minor = kgem_get_minor(kgem);
4065 static void dump_gtt_info(struct kgem *kgem)
4067 dump_debugfs(kgem, "i915_gem_gtt");
4070 static void dump_fence_regs(struct kgem *kgem)
4072 dump_debugfs(kgem, "i915_gem_fence_regs");
4076 static int do_execbuf(struct kgem *kgem, struct drm_i915_gem_execbuffer2 *execbuf)
4081 ret = do_ioctl(kgem->fd, DRM_IOCTL_I915_GEM_EXECBUFFER2, execbuf);
4086 (void)__kgem_throttle_retire(kgem, 0);
4087 if (kgem_expire_cache(kgem))
4090 if (kgem_cleanup_cache(kgem))
4094 ret = do_ioctl(kgem->fd, DRM_IOCTL_I915_GEM_EXECBUFFER2, execbuf);
4103 xf86DrvMsg(kgem_get_screen_index(kgem), X_WARNING,
4106 if (sna_mode_disable(__to_sna(kgem))) {
4107 kgem_cleanup_cache(kgem);
4108 ret = do_ioctl(kgem->fd,
4112 sna_mode_enable(__to_sna(kgem));
4118 void _kgem_submit(struct kgem *kgem)
4125 assert(!kgem->wedged);
4127 assert(kgem->nbatch);
4128 assert(kgem->nbatch <= KGEM_BATCH_SIZE(kgem));
4129 assert(kgem->nbatch <= kgem->surface);
4131 batch_end = kgem_end_batch(kgem);
4132 kgem_sna_flush(kgem);
4135 kgem->mode, kgem->ring, kgem->batch_flags,
4136 batch_end, kgem->nbatch, kgem->surface, kgem->batch_size,
4137 kgem->nreloc, kgem->nexec, kgem->nfence, kgem->aperture, kgem->aperture_fenced));
4139 assert(kgem->nbatch <= kgem->batch_size);
4140 assert(kgem->nbatch <= kgem->surface);
4141 assert(kgem->nreloc <= ARRAY_SIZE(kgem->reloc));
4142 assert(kgem->nexec < ARRAY_SIZE(kgem->exec));
4143 assert(kgem->nfence <= kgem->fence_max);
4145 kgem_finish_buffers(kgem);
4148 __kgem_batch_debug(kgem, batch_end);
4151 rq = kgem->next_request;
4154 rq->bo = kgem_create_batch(kgem);
4160 i = kgem->nexec++;
4161 kgem->exec[i].handle = rq->bo->handle;
4162 kgem->exec[i].relocation_count = kgem->nreloc;
4163 kgem->exec[i].relocs_ptr = (uintptr_t)kgem->reloc;
4164 kgem->exec[i].alignment = 0;
4165 kgem->exec[i].offset = rq->bo->presumed_offset;
4167 kgem->exec[i].flags = EXEC_OBJECT_NEEDS_FENCE;
4168 kgem->exec[i].rsvd1 = 0;
4169 kgem->exec[i].rsvd2 = 0;
4171 rq->bo->exec = &kgem->exec[i];
4172 rq->bo->rq = MAKE_REQUEST(rq, kgem->ring); /* useful sanity check */
4174 rq->ring = kgem->ring == KGEM_BLT;
4177 execbuf.buffers_ptr = (uintptr_t)kgem->exec;
4178 execbuf.buffer_count = kgem->nexec;
4179 if (kgem->gen < 030)
4181 execbuf.flags = kgem->ring | kgem->batch_flags;
4188 ret = write(fd, kgem->batch, batch_end*sizeof(uint32_t));
4193 ret = do_execbuf(kgem, &execbuf);
4198 kgem_throttle(kgem);
4199 if (!kgem->wedged) {
4200 xf86DrvMsg(kgem_get_screen_index(kgem), X_ERROR,
4203 __kgem_set_wedged(kgem);
4208 kgem->mode, kgem->ring, batch_end, kgem->nbatch, kgem->surface,
4209 kgem->nreloc, kgem->nexec, kgem->nfence, kgem->aperture, kgem->aperture_fenced, kgem->aperture_high, kgem->aperture_total, -ret);
4211 for (i = 0; i < kgem->nexec; i++) {
4214 list_for_each_entry(bo, &kgem->next_request->buffers, request) {
4215 if (bo->handle == kgem->exec[i].handle) {
4222 kgem->exec[i].handle,
4223 (int)kgem->exec[i].offset,
4226 (int)(kgem->exec[i].flags & EXEC_OBJECT_NEEDS_FENCE),
4230 for (i = 0; i < kgem->nreloc; i++) {
4233 (int)kgem->reloc[i].offset,
4234 kgem->reloc[i].target_handle,
4235 kgem->reloc[i].delta,
4236 kgem->reloc[i].read_domains,
4237 kgem->reloc[i].write_domain,
4238 (int)kgem->reloc[i].presumed_offset);
4243 if (do_ioctl(kgem->fd, DRM_IOCTL_I915_GEM_GET_APERTURE, &aperture) == 0)
4250 dump_gtt_info(kgem);
4252 dump_fence_regs(kgem);
4257 int ignored = write(fd, kgem->batch, batch_end*sizeof(uint32_t));
4274 ret = do_ioctl(kgem->fd, DRM_IOCTL_I915_GEM_SET_DOMAIN, &set_domain);
4278 if (gem_read(kgem->fd, rq->bo->handle, kgem->batch, 0, batch_end*sizeof(uint32_t)) == 0)
4279 __kgem_batch_debug(kgem, batch_end);
4282 kgem_commit(kgem);
4285 if (unlikely(kgem->wedged))
4286 kgem_cleanup(kgem);
4288 kgem_reset(kgem);
4290 assert(kgem->next_request != NULL);
4293 void kgem_throttle(struct kgem *kgem)
4295 if (unlikely(kgem->wedged))
4298 if (__kgem_throttle(kgem, true)) {
4299 xf86DrvMsg(kgem_get_screen_index(kgem), X_ERROR,
4301 __kgem_set_wedged(kgem);
4302 kgem->need_throttle = false;
4306 int kgem_is_wedged(struct kgem *kgem)
4308 return __kgem_throttle(kgem, true);
4311 static void kgem_purge_cache(struct kgem *kgem)
4316 for (i = 0; i < ARRAY_SIZE(kgem->inactive); i++) {
4317 list_for_each_entry_safe(bo, next, &kgem->inactive[i], list) {
4318 if (!kgem_bo_is_retained(kgem, bo)) {
4321 kgem_bo_free(kgem, bo);
4326 kgem->need_purge = false;
4329 void kgem_clean_scanout_cache(struct kgem *kgem)
4331 while (!list_is_empty(&kgem->scanout)) {
4334 bo = list_first_entry(&kgem->scanout, struct kgem_bo, list);
4341 if (bo->exec || __kgem_busy(kgem, bo->handle))
4348 kgem_bo_rmfb(kgem, bo);
4353 if (kgem->has_llc &&
4354 !gem_set_caching(kgem->fd, bo->handle, SNOOPED))
4359 __kgem_bo_destroy(kgem, bo);
4363 void kgem_clean_large_cache(struct kgem *kgem)
4365 while (!list_is_empty(&kgem->large_inactive)) {
4366 kgem_bo_free(kgem,
4367 list_first_entry(&kgem->large_inactive,
4373 bool kgem_expire_cache(struct kgem *kgem)
4396 kgem_clean_large_cache(kgem);
4397 if (__to_sna(kgem)->scrn->vtSema)
4398 kgem_clean_scanout_cache(kgem);
4401 list_for_each_entry(bo, &kgem->snoop, list) {
4411 while (!list_is_empty(&kgem->snoop)) {
4412 bo = list_last_entry(&kgem->snoop, struct kgem_bo, list);
4417 kgem_bo_free(kgem, bo);
4424 list_for_each_entry(bo, &kgem->snoop, list)
4431 kgem_retire(kgem);
4432 if (unlikely(kgem->wedged))
4433 kgem_cleanup(kgem);
4435 kgem->expire(kgem);
4437 if (kgem->need_purge)
4438 kgem_purge_cache(kgem);
4440 if (kgem->need_retire)
4441 kgem_retire(kgem);
4445 for (i = 0; i < ARRAY_SIZE(kgem->inactive); i++) {
4446 idle &= list_is_empty(&kgem->inactive[i]);
4447 list_for_each_entry(bo, &kgem->inactive[i], list) {
4454 kgem_bo_set_purgeable(kgem, bo);
4460 kgem->need_expire = !idle;
4465 for (i = 0; i < ARRAY_SIZE(kgem->inactive); i++) {
4469 while (!list_is_empty(&kgem->inactive[i])) {
4470 bo = list_last_entry(&kgem->inactive[i],
4484 kgem_bo_free(kgem, bo);
4489 list_splice_tail(&preserve, &kgem->inactive[i]);
4496 for (i = 0; i < ARRAY_SIZE(kgem->inactive); i++)
4497 list_for_each_entry(bo, &kgem->inactive[i], list)
4507 kgem->need_expire = !idle;
4513 bool kgem_cleanup_cache(struct kgem *kgem)
4521 for (n = 0; n < ARRAY_SIZE(kgem->requests); n++) {
4522 if (!list_is_empty(&kgem->requests[n])) {
4525 rq = list_last_entry(&kgem->requests[n],
4533 kgem_bo_wait(kgem, rq->bo);
4535 assert(list_is_empty(&kgem->requests[n]));
4538 kgem_retire(kgem);
4539 kgem_cleanup(kgem);
4541 DBG(("%s: need_expire?=%d\n", __FUNCTION__, kgem->need_expire));
4542 if (!kgem->need_expire)
4545 for (i = 0; i < ARRAY_SIZE(kgem->inactive); i++) {
4546 while (!list_is_empty(&kgem->inactive[i]))
4547 kgem_bo_free(kgem,
4548 list_last_entry(&kgem->inactive[i],
4552 kgem_clean_large_cache(kgem);
4553 kgem_clean_scanout_cache(kgem);
4555 while (!list_is_empty(&kgem->snoop))
4556 kgem_bo_free(kgem,
4557 list_last_entry(&kgem->snoop,
4566 kgem->need_purge = false;
4567 kgem->need_expire = false;
4574 search_linear_cache(struct kgem *kgem, unsigned int num_pages, unsigned flags)
4590 cache = use_active ? &kgem->large : &kgem->large_inactive;
4600 if (use_active && kgem->gen < 040)
4603 if (!kgem_set_tiling(kgem, bo,
4610 if (bo->purged && !kgem_bo_clear_purgeable(kgem, bo))
4614 if (RQ(bo->rq) == (void *)kgem) {
4620 assert_tiling(kgem, bo);
4625 kgem_bo_free(kgem, bo);
4633 if (__kgem_throttle_retire(kgem, flags))
4639 if (!use_active && list_is_empty(inactive(kgem, num_pages))) {
4648 if (list_is_empty(active(kgem, num_pages, I915_TILING_NONE))) {
4653 if (!__kgem_throttle_retire(kgem, flags)) {
4658 if (list_is_empty(inactive(kgem, num_pages))) {
4669 cache = &kgem->vma[for_cpu].inactive[cache_bucket(num_pages)];
4684 if (bo->purged && !kgem_bo_clear_purgeable(kgem, bo)) {
4685 kgem_bo_free(kgem, bo);
4689 if (!kgem_set_tiling(kgem, bo, I915_TILING_NONE, 0)) {
4690 kgem_bo_free(kgem, bo);
4694 kgem_bo_remove_from_inactive(kgem, bo);
4705 assert_tiling(kgem, bo);
4706 ASSERT_MAYBE_IDLE(kgem, bo->handle, !use_active);
4713 if (flags & CREATE_CPU_MAP && !kgem->has_llc)
4717 cache = use_active ? active(kgem, num_pages, I915_TILING_NONE) : inactive(kgem, num_pages);
4729 kgem->gen <= 040 &&
4733 if (bo->purged && !kgem_bo_clear_purgeable(kgem, bo)) {
4734 kgem_bo_free(kgem, bo);
4745 if (!kgem_set_tiling(kgem, bo, I915_TILING_NONE, 0))
4769 if (flags & CREATE_GTT_MAP && !kgem_bo_can_map(kgem, bo))
4782 kgem_bo_remove_from_active(kgem, bo);
4784 kgem_bo_remove_from_inactive(kgem, bo);
4796 assert_tiling(kgem, bo);
4797 ASSERT_MAYBE_IDLE(kgem, bo->handle, !use_active);
4805 kgem_bo_remove_from_active(kgem, first);
4807 kgem_bo_remove_from_inactive(kgem, first);
4818 ASSERT_MAYBE_IDLE(kgem, first->handle, !use_active);
4825 struct kgem_bo *kgem_create_for_name(struct kgem *kgem, uint32_t name)
4835 if (do_ioctl(kgem->fd, DRM_IOCTL_GEM_OPEN, &open_arg))
4842 if (do_ioctl(kgem->fd, DRM_IOCTL_I915_GEM_GET_TILING, &tiling)) {
4844 gem_close(kgem->fd, open_arg.handle);
4852 gem_close(kgem->fd, open_arg.handle);
4856 bo->unique_id = kgem_get_unique_id(kgem);
4860 kgem_bo_unclean(kgem, bo);
4862 debug_alloc__bo(kgem, bo);
4866 struct kgem_bo *kgem_create_for_prime(struct kgem *kgem, int name, uint32_t size)
4880 if (do_ioctl(kgem->fd, DRM_IOCTL_PRIME_FD_TO_HANDLE, &args)) {
4887 if (do_ioctl(kgem->fd, DRM_IOCTL_I915_GEM_GET_TILING, &tiling)) {
4889 gem_close(kgem->fd, args.handle);
4900 gem_close(kgem->fd, args.handle);
4910 gem_close(kgem->fd, args.handle);
4914 bo->unique_id = kgem_get_unique_id(kgem);
4924 caching.caching = kgem->has_llc;
4925 (void)drmIoctl(kgem->fd, LOCAL_IOCTL_I915_GEM_GET_CACHING, &caching);
4929 if (kgem->has_llc) {
4936 if (!kgem->has_llc) {
4942 kgem_bo_free(kgem, bo);
4954 debug_alloc__bo(kgem, bo);
4961 int kgem_bo_export_to_prime(struct kgem *kgem, struct kgem_bo *bo)
4966 assert(kgem_bo_is_fenced(kgem, bo));
4972 if (do_ioctl(kgem->fd, DRM_IOCTL_PRIME_HANDLE_TO_FD, &args))
4982 struct kgem_bo *kgem_create_linear(struct kgem *kgem, int size, unsigned flags)
4990 if (flags & CREATE_GTT_MAP && kgem->has_llc) {
4997 bo = search_linear_cache(kgem, size, CREATE_INACTIVE | flags);
5002 ASSERT_IDLE(kgem, bo->handle);
5011 handle = gem_create(kgem->fd, size);
5018 gem_close(kgem->fd, handle);
5022 debug_alloc__bo(kgem, bo);
5026 int kgem_choose_tiling(struct kgem *kgem, int tiling, int width, int height, int bpp)
5031 if (kgem->gen < 040) {
5059 if (tiling == I915_TILING_Y && !kgem->can_render_y)
5134 unsigned kgem_can_create_2d(struct kgem *kgem,
5156 size = kgem_surface_size(kgem, false, 0,
5161 if (size <= kgem->max_cpu_size)
5163 if (size > 4096 && size <= kgem->max_gpu_size)
5165 if (size <= PAGE_SIZE*kgem->aperture_mappable/4 || kgem->has_wc_mmap)
5167 if (size > kgem->large_object_size)
5169 if (size > kgem->max_object_size) {
5171 __FUNCTION__, size, kgem->max_object_size));
5176 tiling = kgem_choose_tiling(kgem, I915_TILING_X,
5179 size = kgem_surface_size(kgem, false, 0,
5183 if (size > 0 && size <= kgem->max_gpu_size)
5185 if (size > 0 && size <= PAGE_SIZE*kgem->aperture_mappable/4)
5187 if (size > PAGE_SIZE*kgem->aperture_mappable/4)
5189 if (size > kgem->large_object_size)
5191 if (size > kgem->max_object_size) {
5193 __FUNCTION__, size, kgem->max_object_size));
5196 if (kgem->gen < 040) {
5200 if (fence_size > kgem->max_gpu_size)
5202 if (fence_size > PAGE_SIZE*kgem->aperture_fenceable/4)
5210 inline int kgem_bo_fenced_size(struct kgem *kgem, struct kgem_bo *bo)
5215 assert_tiling(kgem, bo);
5216 assert(kgem->gen < 040);
5218 if (kgem->gen < 030)
5229 __kgem_bo_create_as_display(struct kgem *kgem, int size, int tiling, int pitch)
5234 if (!kgem->has_create2)
5244 if (do_ioctl(kgem->fd, LOCAL_IOCTL_I915_GEM_CREATE2, &args)) {
5246 if (do_ioctl(kgem->fd, LOCAL_IOCTL_I915_GEM_CREATE2, &args))
5252 gem_close(kgem->fd, args.handle);
5256 bo->unique_id = kgem_get_unique_id(kgem);
5265 if (__kgem_busy(kgem, bo->handle)) {
5267 list_add(&bo->request, &kgem->flushing);
5268 bo->rq = (void *)kgem;
5269 kgem->need_retire = true;
5272 assert_tiling(kgem, bo);
5273 debug_alloc__bo(kgem, bo);
5278 static void __kgem_bo_make_scanout(struct kgem *kgem,
5282 ScrnInfoPtr scrn = __to_sna(kgem)->scrn;
5302 if (kgem->has_llc) {
5303 if (!gem_set_caching(kgem->fd, bo->handle, DISPLAY) &&
5304 !gem_set_caching(kgem->fd, bo->handle, UNCACHED))
5314 bo->map__gtt = __kgem_bo_map__gtt(kgem, bo);
5323 if (do_ioctl(kgem->fd, DRM_IOCTL_MODE_ADDFB, &arg) == 0) {
5338 static void set_gpu_tiling(struct kgem *kgem,
5348 kgem->vma[0].count--;
5358 bool kgem_bo_is_fenced(struct kgem *kgem, struct kgem_bo *bo)
5362 assert(kgem);
5368 (void)do_ioctl(kgem->fd, DRM_IOCTL_I915_GEM_GET_TILING, &tiling);
5372 struct kgem_bo *kgem_create_2d(struct kgem *kgem,
5398 size = kgem_surface_size(kgem, kgem->has_relaxed_fencing, flags,
5411 list_for_each_entry_reverse(bo, &kgem->scanout, list) {
5415 assert_tiling(kgem, bo);
5424 if (bo->delta && !check_scanout_size(kgem, bo, width, height))
5425 kgem_bo_rmfb(kgem, bo);
5434 bo->unique_id = kgem_get_unique_id(kgem);
5437 assert(bo->pitch*kgem_aligned_height(kgem, height, bo->tiling) <= kgem_bo_size(bo));
5438 assert_tiling(kgem, bo);
5446 last->unique_id = kgem_get_unique_id(kgem);
5449 assert(last->pitch*kgem_aligned_height(kgem, height, last->tiling) <= kgem_bo_size(last));
5450 assert_tiling(kgem, last);
5455 if (__to_sna(kgem)->scrn->vtSema) {
5456 ScrnInfoPtr scrn = __to_sna(kgem)->scrn;
5458 list_for_each_entry_reverse(bo, &kgem->scanout, list) {
5474 kgem_bo_rmfb(kgem, bo);
5478 if (!kgem_set_tiling(kgem, bo,
5481 __kgem_bo_destroy(kgem, bo);
5494 if (do_ioctl(kgem->fd, DRM_IOCTL_MODE_ADDFB, &arg)) {
5496 __kgem_bo_destroy(kgem, bo);
5501 bo->unique_id = kgem_get_unique_id(kgem);
5505 assert(bo->pitch*kgem_aligned_height(kgem, height, bo->tiling) <= kgem_bo_size(bo));
5506 assert_tiling(kgem, bo);
5515 bo = __kgem_bo_create_as_display(kgem, size, tiling, pitch);
5529 tiled_height = kgem_aligned_height(kgem, height, tiling);
5531 list_for_each_entry(bo, &kgem->large, list) {
5536 assert_tiling(kgem, bo);
5538 if (kgem->gen < 040) {
5552 if (!kgem_set_tiling(kgem, bo, tiling, pitch)) {
5560 set_gpu_tiling(kgem, bo, tiling, pitch);
5564 kgem_bo_remove_from_active(kgem, bo);
5566 bo->unique_id = kgem_get_unique_id(kgem);
5570 assert(bo->pitch*kgem_aligned_height(kgem, height, bo->tiling) <= kgem_bo_size(bo));
5571 assert_tiling(kgem, bo);
5577 __kgem_throttle_retire(kgem, flags);
5578 list_for_each_entry(bo, &kgem->large_inactive, list) {
5582 assert_tiling(kgem, bo);
5587 if (!kgem_set_tiling(kgem, bo, tiling, pitch)) {
5588 if (kgem->gen >= 040 && !exact)
5589 set_gpu_tiling(kgem, bo, tiling, pitch);
5594 if (bo->purged && !kgem_bo_clear_purgeable(kgem, bo)) {
5595 kgem_bo_free(kgem, bo);
5602 bo->unique_id = kgem_get_unique_id(kgem);
5606 assert(bo->pitch*kgem_aligned_height(kgem, height, bo->tiling) <= kgem_bo_size(bo));
5607 assert_tiling(kgem, bo);
5611 __kgem_bo_make_scanout(kgem, bo, width, height);
5621 if (kgem->has_llc && tiling == I915_TILING_NONE)
5626 cache = &kgem->vma[for_cpu].inactive[bucket];
5637 assert_tiling(kgem, bo);
5645 if (flags & UNCACHED && !kgem->has_llc && bo->domain != DOMAIN_CPU)
5651 !kgem_set_tiling(kgem, bo,
5655 kgem_bo_free(kgem, bo);
5660 if (bo->purged && !kgem_bo_clear_purgeable(kgem, bo)) {
5661 kgem_bo_free(kgem, bo);
5671 bo->unique_id = kgem_get_unique_id(kgem);
5673 kgem_bo_remove_from_inactive(kgem, bo);
5681 ASSERT_IDLE(kgem, bo->handle);
5682 assert(bo->pitch*kgem_aligned_height(kgem, height, bo->tiling) <= kgem_bo_size(bo));
5683 assert_tiling(kgem, bo);
5688 __kgem_throttle_retire(kgem, flags));
5690 if (flags & CREATE_CPU_MAP && !kgem->has_llc) {
5691 if (list_is_empty(&kgem->active[bucket][tiling]) &&
5692 list_is_empty(&kgem->inactive[bucket]))
5708 cache = &kgem->active[bucket][tiling];
5710 tiled_height = kgem_aligned_height(kgem, height, tiling);
5719 assert_tiling(kgem, bo);
5721 if (kgem->gen < 040) {
5735 if (!kgem_set_tiling(kgem, bo, tiling, pitch)) {
5743 set_gpu_tiling(kgem, bo, tiling, pitch);
5749 kgem_bo_remove_from_active(kgem, bo);
5751 bo->unique_id = kgem_get_unique_id(kgem);
5755 assert(bo->pitch*kgem_aligned_height(kgem, height, bo->tiling) <= kgem_bo_size(bo));
5756 assert_tiling(kgem, bo);
5769 assert_tiling(kgem, bo);
5774 kgem_bo_remove_from_active(kgem, bo);
5777 bo->unique_id = kgem_get_unique_id(kgem);
5781 assert(bo->pitch*kgem_aligned_height(kgem, height, bo->tiling) <= kgem_bo_size(bo));
5782 assert_tiling(kgem, bo);
5788 if (kgem->gen >= 040) {
5790 cache = &kgem->active[bucket][i];
5797 assert_tiling(kgem, bo);
5802 if (!kgem_set_tiling(kgem, bo, tiling, pitch)) {
5803 if (exact || kgem->gen < 040)
5806 set_gpu_tiling(kgem, bo, tiling, pitch);
5811 kgem_bo_remove_from_active(kgem, bo);
5813 bo->unique_id = kgem_get_unique_id(kgem);
5817 assert(bo->pitch*kgem_aligned_height(kgem, height, bo->tiling) <= kgem_bo_size(bo));
5818 assert_tiling(kgem, bo);
5825 tiled_height = kgem_surface_size(kgem, kgem->has_relaxed_fencing, flags,
5827 cache = active(kgem, tiled_height / PAGE_SIZE, i);
5828 tiled_height = kgem_aligned_height(kgem, height, i);
5835 assert_tiling(kgem, bo);
5850 kgem_bo_remove_from_active(kgem, bo);
5852 bo->unique_id = kgem_get_unique_id(kgem);
5856 assert(bo->pitch*kgem_aligned_height(kgem, height, bo->tiling) <= kgem_bo_size(bo));
5857 assert_tiling(kgem, bo);
5877 cache = &kgem->inactive[bucket];
5883 assert_tiling(kgem, bo);
5891 if (!kgem_set_tiling(kgem, bo, tiling, pitch)) {
5892 if (exact || kgem->gen < 040) {
5893 kgem_bo_free(kgem, bo);
5897 set_gpu_tiling(kgem, bo, tiling, pitch);
5900 if (bo->purged && !kgem_bo_clear_purgeable(kgem, bo)) {
5901 kgem_bo_free(kgem, bo);
5905 kgem_bo_remove_from_inactive(kgem, bo);
5912 bo->unique_id = kgem_get_unique_id(kgem);
5919 ASSERT_MAYBE_IDLE(kgem, bo->handle, flags & CREATE_INACTIVE);
5920 assert(bo->pitch*kgem_aligned_height(kgem, height, bo->tiling) <= kgem_bo_size(bo));
5921 assert_tiling(kgem, bo);
5925 __kgem_bo_make_scanout(kgem, bo, width, height);
5931 list_for_each_entry_reverse(bo, &kgem->active[bucket][tiling], list) {
5938 if (__kgem_busy(kgem, bo->handle)) {
5943 if (!kgem->need_throttle) {
5948 __kgem_throttle(kgem, false);
5949 } while (__kgem_busy(kgem, bo->handle));
5954 kgem_bo_remove_from_active(kgem, bo);
5957 if (!kgem_set_tiling(kgem, bo, tiling, pitch)) {
5958 if (exact || kgem->gen < 040)
5961 set_gpu_tiling(kgem, bo, tiling, pitch);
5966 bo->unique_id = kgem_get_unique_id(kgem);
5970 assert(bo->pitch*kgem_aligned_height(kgem, height, bo->tiling) <= kgem_bo_size(bo));
5971 assert_tiling(kgem, bo);
5975 __kgem_bo_make_scanout(kgem, bo, width, height);
5996 handle = gem_create(kgem->fd, size);
6005 gem_close(kgem->fd, handle);
6009 bo->unique_id = kgem_get_unique_id(kgem);
6010 if (kgem_set_tiling(kgem, bo, tiling, pitch)) {
6012 __kgem_bo_make_scanout(kgem, bo, width, height);
6014 if (kgem->gen >= 040) {
6015 assert(!kgem->can_fence);
6021 gem_close(kgem->fd, handle);
6028 assert(bytes(bo) >= bo->pitch * kgem_aligned_height(kgem, height, bo->tiling));
6029 assert_tiling(kgem, bo);
6031 debug_alloc__bo(kgem, bo);
6039 struct kgem_bo *kgem_create_cpu_2d(struct kgem *kgem,
6053 if (kgem->has_llc) {
6054 bo = kgem_create_2d(kgem, width, height, bpp,
6060 assert_tiling(kgem, bo);
6062 if (kgem_bo_map__cpu(kgem, bo) == NULL) {
6063 kgem_bo_destroy(kgem, bo);
6079 bo = search_snoop_cache(kgem, NUM_PAGES(size), 0);
6082 assert_tiling(kgem, bo);
6086 bo->unique_id = kgem_get_unique_id(kgem);
6090 if (kgem->has_caching) {
6091 bo = kgem_create_linear(kgem, size, flags);
6096 assert_tiling(kgem, bo);
6098 assert(!__kgem_busy(kgem, bo->handle));
6099 if (!gem_set_caching(kgem->fd, bo->handle, SNOOPED)) {
6100 kgem_bo_destroy(kgem, bo);
6105 if (kgem_bo_map__cpu(kgem, bo) == NULL) {
6106 kgem_bo_destroy(kgem, bo);
6111 bo->unique_id = kgem_get_unique_id(kgem);
6115 if (kgem->has_userptr) {
6123 bo = kgem_create_map(kgem, ptr, size, false);
6130 bo->unique_id = kgem_get_unique_id(kgem);
6137 void _kgem_bo_destroy(struct kgem *kgem, struct kgem_bo *bo)
6144 kgem_bo_binding_free(kgem, bo);
6151 _kgem_bo_delete_buffer(kgem, bo);
6153 kgem_bo_unref(kgem, bo->proxy);
6162 __kgem_bo_destroy(kgem, bo);
6165 static void __kgem_flush(struct kgem *kgem, struct kgem_bo *bo)
6172 if (!__kgem_busy(kgem, bo->handle))
6179 void kgem_scanout_flush(struct kgem *kgem, struct kgem_bo *bo)
6184 kgem_bo_submit(kgem, bo);
6192 __kgem_flush(kgem, bo);
6194 if (bo->scanout && kgem->needs_dirtyfb) {
6198 (void)drmIoctl(kgem->fd, DRM_IOCTL_MODE_DIRTYFB, &cmd);
6207 inline static bool nearly_idle(struct kgem *kgem)
6209 int ring = kgem->ring == KGEM_BLT;
6211 assert(ring < ARRAY_SIZE(kgem->requests));
6212 if (list_is_singular(&kgem->requests[ring]))
6215 return __kgem_ring_is_idle(kgem, ring);
6218 inline static bool needs_semaphore(struct kgem *kgem, struct kgem_bo *bo)
6220 if (kgem->needs_semaphore)
6223 if (bo->rq == NULL || RQ_RING(bo->rq) == kgem->ring)
6226 kgem->needs_semaphore = true;
6230 inline static bool needs_reservation(struct kgem *kgem, struct kgem_bo *bo)
6232 if (kgem->needs_reservation)
6238 kgem->needs_reservation = true;
6239 return nearly_idle(kgem);
6242 inline static bool needs_batch_flush(struct kgem *kgem, struct kgem_bo *bo)
6246 if (needs_semaphore(kgem, bo)) {
6251 if (needs_reservation(kgem, bo)) {
6256 return kgem->nreloc ? flush : false;
6259 static bool aperture_check(struct kgem *kgem, unsigned num_pages)
6264 if (kgem->aperture)
6268 reserve = kgem->aperture_mappable / 2;
6269 if (kgem->gen < 033 && reserve < kgem->aperture_max_fence)
6270 reserve = kgem->aperture_max_fence;
6271 if (!kgem->has_llc)
6272 reserve += kgem->nexec * PAGE_SIZE * 2;
6275 __FUNCTION__, num_pages, reserve, kgem->aperture_total));
6279 aperture.aper_available_size = kgem->aperture_total;
6281 (void)do_ioctl(kgem->fd, DRM_IOCTL_I915_GEM_GET_APERTURE, &aperture);
6291 static inline bool kgem_flush(struct kgem *kgem, bool flush)
6293 if (unlikely(kgem->wedged))
6296 if (kgem->nreloc == 0)
6299 if (__to_sna(kgem)->flags & SNA_POWERSAVE)
6302 if (kgem->flush == flush && kgem->aperture < kgem->aperture_low)
6306 __FUNCTION__, kgem->flush, flush, kgem->aperture, kgem->aperture_low, kgem_ring_is_idle(kgem, kgem->ring)));
6307 return !kgem_ring_is_idle(kgem, kgem->ring);
6310 bool kgem_check_bo(struct kgem *kgem, ...)
6319 va_start(ap, kgem);
6326 if (needs_batch_flush(kgem, bo)) {
6345 if (kgem->nexec + num_exec >= KGEM_EXEC_SIZE(kgem)) {
6347 kgem->nexec, num_exec, KGEM_EXEC_SIZE(kgem)));
6351 if (num_pages + kgem->aperture > kgem->aperture_high) {
6353 __FUNCTION__, kgem->aperture, num_pages, kgem->aperture_high));
6354 return aperture_check(kgem, num_pages);
6360 return kgem_flush(kgem, flush);
6363 bool kgem_check_bo_fenced(struct kgem *kgem, struct kgem_bo *bo)
6371 if (kgem->gen < 040 &&
6378 if (kgem->nfence >= kgem->fence_max)
6381 if (kgem->aperture_fenced) {
6382 size = 3*kgem->aperture_fenced;
6383 if (kgem->aperture_total == kgem->aperture_mappable)
6384 size += kgem->aperture;
6385 if (size > kgem->aperture_fenceable &&
6386 kgem_ring_is_idle(kgem, kgem->ring)) {
6392 size = kgem_bo_fenced_size(kgem, bo);
6393 if (size > kgem->aperture_max_fence)
6394 kgem->aperture_max_fence = size;
6395 size += kgem->aperture_fenced;
6396 if (kgem->gen < 033 && size < 2 * kgem->aperture_max_fence)
6397 size = 2 * kgem->aperture_max_fence;
6398 if (kgem->aperture_total == kgem->aperture_mappable)
6399 size += kgem->aperture;
6400 if (size > kgem->aperture_fenceable) {
6402 __FUNCTION__, size, kgem->aperture_fenced, kgem->aperture_max_fence, kgem->aperture, kgem->aperture_fenceable));
6410 if (kgem->nexec >= KGEM_EXEC_SIZE(kgem) - 1)
6413 if (needs_batch_flush(kgem, bo))
6416 assert_tiling(kgem, bo);
6417 if (kgem->gen < 040 && bo->tiling != I915_TILING_NONE) {
6422 if (kgem->nfence >= kgem->fence_max)
6425 if (kgem->aperture_fenced) {
6426 size = 3*kgem->aperture_fenced;
6427 if (kgem->aperture_total == kgem->aperture_mappable)
6428 size += kgem->aperture;
6429 if (size > kgem->aperture_fenceable &&
6430 kgem_ring_is_idle(kgem, kgem->ring)) {
6436 size = kgem_bo_fenced_size(kgem, bo);
6437 if (size > kgem->aperture_max_fence)
6438 kgem->aperture_max_fence = size;
6439 size += kgem->aperture_fenced;
6440 if (kgem->gen < 033 && size < 2 * kgem->aperture_max_fence)
6441 size = 2 * kgem->aperture_max_fence;
6442 if (kgem->aperture_total == kgem->aperture_mappable)
6443 size += kgem->aperture;
6444 if (size > kgem->aperture_fenceable) {
6446 __FUNCTION__, size, kgem->aperture_fenced, kgem->aperture_max_fence, kgem->aperture, kgem->aperture_fenceable));
6451 if (kgem->aperture + kgem->aperture_fenced + num_pages(bo) > kgem->aperture_high) {
6453 __FUNCTION__, kgem->aperture, num_pages(bo), kgem->aperture_high));
6454 return aperture_check(kgem, num_pages(bo));
6460 return kgem_flush(kgem, bo->flush);
6463 bool kgem_check_many_bo_fenced(struct kgem *kgem, ...)
6474 va_start(ap, kgem);
6481 if (kgem->gen >= 040 || bo->tiling == I915_TILING_NONE)
6485 fenced_size += kgem_bo_fenced_size(kgem, bo);
6492 if (needs_batch_flush(kgem, bo)) {
6497 assert_tiling(kgem, bo);
6500 if (kgem->gen < 040 && bo->tiling) {
6501 uint32_t size = kgem_bo_fenced_size(kgem, bo);
6502 if (size > kgem->aperture_max_fence)
6503 kgem->aperture_max_fence = size;
6516 if (kgem->nfence + num_fence > kgem->fence_max)
6519 if (kgem->aperture_fenced) {
6520 size = 3*kgem->aperture_fenced;
6521 if (kgem->aperture_total == kgem->aperture_mappable)
6522 size += kgem->aperture;
6523 if (size > kgem->aperture_fenceable &&
6524 kgem_ring_is_idle(kgem, kgem->ring)) {
6530 size = kgem->aperture_fenced;
6532 if (kgem->gen < 033 && size < 2 * kgem->aperture_max_fence)
6533 size = 2 * kgem->aperture_max_fence;
6534 if (kgem->aperture_total == kgem->aperture_mappable)
6535 size += kgem->aperture;
6536 if (size > kgem->aperture_fenceable) {
6538 __FUNCTION__, size, kgem->aperture_fenced, kgem->aperture_max_fence, kgem->aperture, kgem->aperture_fenceable));
6546 if (kgem->nexec + num_exec >= KGEM_EXEC_SIZE(kgem))
6549 if (num_pages + kgem->aperture > kgem->aperture_high - kgem->aperture_fenced) {
6551 __FUNCTION__, kgem->aperture, kgem->aperture_fenced, num_pages, kgem->aperture_high));
6552 return aperture_check(kgem, num_pages);
6558 return kgem_flush(kgem, flush);
6561 void __kgem_bcs_set_tiling(struct kgem *kgem,
6571 assert(kgem->mode == KGEM_BLT);
6572 assert(dst == NULL || kgem_bo_can_blt(kgem, dst));
6573 assert(src == NULL || kgem_bo_can_blt(kgem, src));
6581 if (kgem->bcs_state == state)
6585 kgem->bcs_state, state));
6588 if (!kgem_check_batch(kgem, 24)) {
6589 _kgem_submit(kgem);
6590 _kgem_set_mode(kgem, KGEM_BLT);
6595 b = kgem->batch + kgem->nbatch;
6596 if (kgem->nbatch) {
6605 kgem->nbatch = b - kgem->batch;
6607 kgem->bcs_state = state;
6610 uint32_t kgem_add_reloc(struct kgem *kgem,
6621 assert(kgem->gen < 0100);
6624 index = kgem->nreloc++;
6625 assert(index < ARRAY_SIZE(kgem->reloc));
6626 kgem->reloc[index].offset = pos * sizeof(kgem->batch[0]);
6628 assert(kgem->mode != KGEM_NONE);
6638 &kgem->next_request->buffers);
6639 bo->rq = MAKE_REQUEST(kgem->next_request,
6640 kgem->ring);
6654 kgem_add_bo(kgem, bo);
6655 assert(bo->rq == MAKE_REQUEST(kgem->next_request, kgem->ring));
6656 assert(RQ_RING(bo->rq) == kgem->ring);
6658 if (kgem->gen < 040 && read_write_domain & KGEM_RELOC_FENCED) {
6662 assert(kgem->nfence < kgem->fence_max);
6663 kgem->aperture_fenced +=
6664 kgem_bo_fenced_size(kgem, bo);
6665 kgem->nfence++;
6670 kgem->reloc[index].delta = delta;
6671 kgem->reloc[index].target_handle = bo->target_handle;
6672 kgem->reloc[index].presumed_offset = bo->presumed_offset;
6675 assert(!bo->snoop || kgem->can_blt_cpu);
6681 kgem->reloc[index].delta = delta;
6682 kgem->reloc[index].target_handle = ~0U;
6683 kgem->reloc[index].presumed_offset = 0;
6684 if (kgem->nreloc__self < 256)
6685 kgem->reloc__self[kgem->nreloc__self++] = index;
6687 kgem->reloc[index].read_domains = read_write_domain >> 16;
6688 kgem->reloc[index].write_domain = read_write_domain & 0x7fff;
6693 uint64_t kgem_add_reloc64(struct kgem *kgem,
6704 assert(kgem->gen >= 0100);
6707 index = kgem->nreloc++;
6708 assert(index < ARRAY_SIZE(kgem->reloc));
6709 kgem->reloc[index].offset = pos * sizeof(kgem->batch[0]);
6711 assert(kgem->mode != KGEM_NONE);
6721 &kgem->next_request->buffers);
6722 bo->rq = MAKE_REQUEST(kgem->next_request,
6723 kgem->ring);
6737 kgem_add_bo(kgem, bo);
6738 assert(bo->rq == MAKE_REQUEST(kgem->next_request, kgem->ring));
6739 assert(RQ_RING(bo->rq) == kgem->ring);
6743 kgem->reloc[index].delta = delta;
6744 kgem->reloc[index].target_handle = bo->target_handle;
6745 kgem->reloc[index].presumed_offset = bo->presumed_offset;
6748 assert(!bo->snoop || kgem->can_blt_cpu);
6756 kgem->reloc[index].delta = delta;
6757 kgem->reloc[index].target_handle = ~0U;
6758 kgem->reloc[index].presumed_offset = 0;
6759 if (kgem->nreloc__self < 256)
6760 kgem->reloc__self[kgem->nreloc__self++] = index;
6762 kgem->reloc[index].read_domains = read_write_domain >> 16;
6763 kgem->reloc[index].write_domain = read_write_domain & 0x7fff;
6768 static void kgem_trim_vma_cache(struct kgem *kgem, int type, int bucket)
6773 __FUNCTION__, type, kgem->vma[type].count, bucket));
6774 if (kgem->vma[type].count <= 0)
6777 if (kgem->need_purge)
6778 kgem_purge_cache(kgem);
6788 while (kgem->vma[type].count > 0) {
6792 bo == NULL && j < ARRAY_SIZE(kgem->vma[type].inactive);
6794 struct list *head = &kgem->vma[type].inactive[i++%ARRAY_SIZE(kgem->vma[type].inactive)];
6822 kgem->vma[type].count--;
6826 static void *__kgem_bo_map__gtt_or_wc(struct kgem *kgem, struct kgem_bo *bo)
6835 kgem_trim_vma_cache(kgem, MAP_GTT, bucket(bo));
6837 if (bo->tiling || !kgem->has_wc_mmap) {
6838 assert(kgem->gen != 021 || bo->tiling != I915_TILING_Y);
6839 warn_unless(num_pages(bo) <= kgem->aperture_mappable / 2);
6843 ptr = __kgem_bo_map__gtt(kgem, bo);
6847 ptr = __kgem_bo_map__wc(kgem, bo);
6853 void *kgem_bo_map__async(struct kgem *kgem, struct kgem_bo *bo)
6860 assert_tiling(kgem, bo);
6863 if (bo->tiling == I915_TILING_NONE && !bo->scanout && kgem->has_llc) {
6866 return kgem_bo_map__cpu(kgem, bo);
6869 return __kgem_bo_map__gtt_or_wc(kgem, bo);
6872 void *kgem_bo_map(struct kgem *kgem, struct kgem_bo *bo)
6882 assert_tiling(kgem, bo);
6886 (kgem->has_llc || bo->domain == DOMAIN_CPU)) {
6889 ptr = kgem_bo_map__cpu(kgem, bo);
6891 kgem_bo_sync__cpu(kgem, bo);
6895 ptr = __kgem_bo_map__gtt_or_wc(kgem, bo);
6901 bo->needs_flush, bo->domain, __kgem_busy(kgem, bo->handle)));
6909 if (do_ioctl(kgem->fd, DRM_IOCTL_I915_GEM_SET_DOMAIN, &set_domain)) {
6911 kgem_throttle(kgem);
6914 kgem_bo_retire(kgem, bo);
6922 void *kgem_bo_map__gtt(struct kgem *kgem, struct kgem_bo *bo)
6930 assert_tiling(kgem, bo);
6933 return __kgem_bo_map__gtt_or_wc(kgem, bo);
6936 void *kgem_bo_map__wc(struct kgem *kgem, struct kgem_bo *bo)
6943 assert_tiling(kgem, bo);
6948 if (!kgem->has_wc_mmap)
6951 kgem_trim_vma_cache(kgem, MAP_GTT, bucket(bo));
6952 return __kgem_bo_map__wc(kgem, bo);
6955 void *kgem_bo_map__cpu(struct kgem *kgem, struct kgem_bo *bo)
6962 assert_tiling(kgem, bo);
6967 kgem_trim_vma_cache(kgem, MAP_CPU, bucket(bo));
6969 return __kgem_bo_map__cpu(kgem, bo);
6972 void *kgem_bo_map__debug(struct kgem *kgem, struct kgem_bo *bo)
6976 if (bo->tiling == I915_TILING_NONE && kgem->has_llc) {
6979 ptr = __kgem_bo_map__cpu(kgem, bo);
6980 } else if (bo->tiling || !kgem->has_wc_mmap) {
6983 ptr = __kgem_bo_map__gtt(kgem, bo);
6987 ptr = __kgem_bo_map__wc(kgem, bo);
6994 uint32_t kgem_bo_flink(struct kgem *kgem, struct kgem_bo *bo)
6998 assert(kgem_bo_is_fenced(kgem, bo));
7002 if (do_ioctl(kgem->fd, DRM_IOCTL_GEM_FLINK, &flink))
7014 kgem_bo_unclean(kgem, bo);
7019 struct kgem_bo *kgem_create_map(struct kgem *kgem,
7030 ptr, size, read_only, kgem->has_userptr));
7031 if (!kgem->has_userptr)
7041 handle = gem_userptr(kgem->fd,
7045 if (read_only && kgem->has_wc_mmap) {
7048 handle = gem_userptr(kgem->fd,
7056 if (do_ioctl(kgem->fd, DRM_IOCTL_I915_GEM_SET_DOMAIN, &set_domain)) {
7057 gem_close(kgem->fd, handle);
7069 gem_close(kgem->fd, handle);
7073 bo->unique_id = kgem_get_unique_id(kgem);
7074 bo->snoop = !kgem->has_llc;
7075 debug_alloc__bo(kgem, bo);
7080 proxy = kgem_create_proxy(kgem, bo,
7082 kgem_bo_destroy(kgem, bo);
7096 void kgem_bo_sync__cpu(struct kgem *kgem, struct kgem_bo *bo)
7100 assert_tiling(kgem, bo);
7102 kgem_bo_submit(kgem, bo);
7116 __kgem_busy(kgem, bo->handle)));
7123 if (do_ioctl(kgem->fd, DRM_IOCTL_I915_GEM_SET_DOMAIN, &set_domain)) {
7125 kgem_throttle(kgem);
7128 kgem_bo_retire(kgem, bo);
7134 void kgem_bo_sync__cpu_full(struct kgem *kgem, struct kgem_bo *bo, bool write)
7138 assert_tiling(kgem, bo);
7141 kgem_bo_submit(kgem, bo);
7151 if (bo->rq == NULL && (kgem->has_llc || bo->snoop) && !write)
7160 __kgem_busy(kgem, bo->handle)));
7167 if (do_ioctl(kgem->fd, DRM_IOCTL_I915_GEM_SET_DOMAIN, &set_domain)) {
7169 kgem_throttle(kgem);
7173 kgem_bo_retire(kgem, bo);
7178 kgem_bo_maybe_retire(kgem, bo);
7184 void kgem_bo_sync__gtt(struct kgem *kgem, struct kgem_bo *bo)
7189 assert_tiling(kgem, bo);
7192 kgem_bo_submit(kgem, bo);
7195 !kgem->has_coherent_mmap_gtt ||
7202 __kgem_busy(kgem, bo->handle)));
7209 if (do_ioctl(kgem->fd, DRM_IOCTL_I915_GEM_SET_DOMAIN, &set_domain)) {
7211 kgem_throttle(kgem);
7214 kgem_bo_retire(kgem, bo);
7220 void kgem_clear_dirty(struct kgem *kgem)
7222 struct list * const buffers = &kgem->next_request->buffers;
7233 struct kgem_bo *kgem_create_proxy(struct kgem *kgem,
7247 bo->unique_id = kgem_get_unique_id(kgem);
7264 assert(RQ(target->rq) == kgem->next_request);
7265 list_move_tail(&bo->request, &kgem->next_request->buffers);
7304 use_snoopable_buffer(struct kgem *kgem, uint32_t flags)
7307 return kgem->gen >= 030;
7336 search_snoopable_buffer(struct kgem *kgem, unsigned alloc)
7341 old = search_snoop_cache(kgem, alloc, 0);
7363 bo->mem = kgem_bo_map__cpu(kgem, &bo->base);
7366 kgem_bo_free(kgem, &bo->base);
7377 create_snoopable_buffer(struct kgem *kgem, unsigned alloc)
7382 if (kgem->has_llc) {
7389 old = search_linear_cache(kgem, alloc,
7394 handle = gem_create(kgem->fd, alloc);
7401 debug_alloc__bo(kgem, &bo->base);
7410 bo->mem = kgem_bo_map__cpu(kgem, &bo->base);
7415 kgem_bo_free(kgem, &bo->base);
7418 if (kgem->has_caching) {
7425 old = search_linear_cache(kgem, alloc,
7430 handle = gem_create(kgem->fd, alloc);
7437 debug_alloc__bo(kgem, &bo->base);
7445 assert(!__kgem_busy(kgem, bo->base.handle));
7447 if (!gem_set_caching(kgem->fd, bo->base.handle, SNOOPED))
7452 bo->mem = kgem_bo_map__cpu(kgem, &bo->base);
7460 kgem_bo_free(kgem, &bo->base);
7463 if (kgem->has_userptr) {
7474 handle = gem_userptr(kgem->fd, bo->mem, alloc * PAGE_SIZE, false);
7482 debug_alloc__bo(kgem, &bo->base);
7499 struct kgem_bo *kgem_create_buffer(struct kgem *kgem,
7514 assert(size <= kgem->max_object_size);
7517 list_for_each_entry(bo, &kgem->batch_buffers, base.list) {
7529 gem_write__cachealigned(kgem->fd, bo->base.handle,
7566 list_for_each_entry(bo, &kgem->active_buffers, base.list) {
7571 assert(bo->mmapped == MMAPPED_GTT || kgem->has_llc || bo->base.snoop);
7584 list_move(&bo->base.list, &kgem->batch_buffers);
7591 !__kgem_busy(kgem, bo->base.handle))) {
7599 kgem_bo_sync__cpu(kgem, &bo->base);
7602 kgem_bo_sync__gtt(kgem, &bo->base);
7608 list_move(&bo->base.list, &kgem->batch_buffers);
7617 alloc = ALIGN(2*size, kgem->buffer_size);
7619 alloc = ALIGN(size, kgem->buffer_size);
7625 if (alloc > kgem->aperture_mappable / 4 && !kgem->has_wc_mmap)
7628 if (kgem->has_llc &&
7636 old = search_linear_cache(kgem, alloc, CREATE_CPU_MAP);
7638 old = search_linear_cache(kgem, alloc, CREATE_INACTIVE | CREATE_CPU_MAP);
7640 old = search_linear_cache(kgem, NUM_PAGES(size), CREATE_INACTIVE | CREATE_CPU_MAP);
7647 uint32_t handle = gem_create(kgem->fd, alloc);
7653 debug_alloc__bo(kgem, &bo->base);
7661 bo->mem = kgem_bo_map__cpu(kgem, &bo->base);
7664 kgem_bo_sync__cpu(kgem, &bo->base);
7669 kgem_bo_free(kgem, &bo->base);
7685 old = search_linear_cache(kgem, alloc,
7695 if (do_ioctl(kgem->fd,
7700 kgem_bo_move_to_inactive(kgem, old);
7707 old = search_linear_cache(kgem, NUM_PAGES(size),
7710 old = search_linear_cache(kgem, alloc, CREATE_INACTIVE);
7711 if (old && !kgem_bo_can_map(kgem, old)) {
7712 _kgem_bo_destroy(kgem, old);
7719 assert(kgem_bo_can_map(kgem, old));
7733 bo->mem = kgem_bo_map(kgem, &bo->base);
7742 kgem_bo_free(kgem, &bo->base);
7753 if (use_snoopable_buffer(kgem, flags)) {
7754 bo = search_snoopable_buffer(kgem, alloc);
7757 kgem_bo_sync__cpu(kgem, &bo->base);
7763 bo = create_snoopable_buffer(kgem, alloc);
7773 old = search_linear_cache(kgem, alloc, 0);
7775 old = search_linear_cache(kgem, alloc, CREATE_INACTIVE);
7788 if (use_snoopable_buffer(kgem, flags)) {
7789 bo = create_snoopable_buffer(kgem, alloc);
7801 old = search_linear_cache(kgem, alloc, hint);
7808 uint32_t handle = gem_create(kgem->fd, alloc);
7818 debug_alloc__bo(kgem, &bo->base);
7826 bo->mem = kgem_bo_map__cpu(kgem, &bo->base);
7828 kgem_bo_sync__cpu(kgem, &bo->base);
7838 kgem_bo_free(kgem, old);
7865 list_add(&bo->base.list, &kgem->batch_buffers);
7875 return kgem_create_proxy(kgem, &bo->base, offset, size);
7884 struct kgem_bo *kgem_create_buffer_2d(struct kgem *kgem,
7895 stride = ALIGN(stride, kgem->gen >= 0100 ? 32 : 4);
7900 bo = kgem_create_buffer(kgem, stride * ALIGN(height, 2), flags, ret);
7931 bo->unique_id = kgem_get_unique_id(kgem);
7935 struct kgem_bo *kgem_upload_source_image(struct kgem *kgem,
7945 if (!kgem_can_create_2d(kgem, width, height, bpp))
7957 bo = kgem_create_buffer_2d(kgem,
7964 kgem_bo_destroy(kgem, bo);
7989 void kgem_buffer_read_sync(struct kgem *kgem, struct kgem_bo *_bo)
8016 __kgem_busy(kgem, bo->base.handle)));
8018 assert(bo->mmapped == MMAPPED_GTT || bo->base.snoop || kgem->has_llc);
8026 if (do_ioctl(kgem->fd, DRM_IOCTL_I915_GEM_SET_DOMAIN, &set_domain)) {
8028 kgem_throttle(kgem);
8031 if (gem_read(kgem->fd,
8036 kgem_bo_maybe_retire(kgem, &bo->base);
8082 kgem_replace_bo(struct kgem *kgem,
8102 assert(kgem_bo_can_blt(kgem, src));
8107 dst = search_linear_cache(kgem, size, 0);
8109 dst = search_linear_cache(kgem, size, CREATE_INACTIVE);
8111 handle = gem_create(kgem->fd, size);
8117 gem_close(kgem->fd, handle);
8121 debug_alloc__bo(kgem, dst);
8124 dst->unique_id = kgem_get_unique_id(kgem);
8127 assert(kgem_bo_can_blt(kgem, dst));
8129 kgem_set_mode(kgem, KGEM_BLT, dst);
8130 if (!kgem_check_batch(kgem, 10) ||
8131 !kgem_check_reloc(kgem, 2) ||
8132 !kgem_check_many_bo_fenced(kgem, src, dst, NULL)) {
8133 kgem_submit(kgem);
8134 if (!kgem_check_many_bo_fenced(kgem, src, dst, NULL)) {
8135 kgem_bo_destroy(kgem, dst);
8138 _kgem_set_mode(kgem, KGEM_BLT);
8140 kgem_bcs_set_tiling(kgem, src, dst);
8145 if (kgem->gen >= 040 && src->tiling) {
8159 b = kgem->batch + kgem->nbatch;
8160 if (kgem->gen >= 0100) {
8166 kgem_add_reloc64(kgem, kgem->nbatch + 4, dst,
8174 kgem_add_reloc64(kgem, kgem->nbatch + 8, src,
8178 kgem->nbatch += 10;
8184 b[4] = kgem_add_reloc(kgem, kgem->nbatch + 4, dst,
8191 b[7] = kgem_add_reloc(kgem, kgem->nbatch + 7, src,
8195 kgem->nbatch += 8;
8201 bool kgem_bo_convert_to_gpu(struct kgem *kgem,
8206 __FUNCTION__, bo->handle, flags, __kgem_bo_is_busy(kgem, bo)));
8212 if (kgem->has_llc)
8215 if (flags & MOVE_ASYNC_HINT && __kgem_bo_is_busy(kgem, bo))
8220 kgem_bo_submit(kgem, bo);
8222 if (!gem_set_caching(kgem->fd, bo->handle, UNCACHED))