diff --git a/libdrm/intel/intel_bufmgr.h b/libdrm/intel/intel_bufmgr.h index 4d33521..d6af8ce 100644 --- a/libdrm/intel/intel_bufmgr.h +++ b/libdrm/intel/intel_bufmgr.h @@ -126,5 +126,7 @@ int intel_bo_set_tiling(dri_bo *buf, uint32_t *tiling_mode); int intel_bo_flink(dri_bo *buf, uint32_t *name); +int dri_gem_bo_map_gtt(dri_bo *bo, uint32_t alignment); + #endif /* INTEL_BUFMGR_GEM_H */ diff --git a/libdrm/intel/intel_bufmgr_gem.c b/libdrm/intel/intel_bufmgr_gem.c index 8634fdf..73bdfa5 100644 --- a/libdrm/intel/intel_bufmgr_gem.c +++ b/libdrm/intel/intel_bufmgr_gem.c @@ -35,6 +35,7 @@ */ #include +#include #include #include #include @@ -42,6 +43,8 @@ #include #include #include +#include +#include #include "errno.h" #include "dri_bufmgr.h" @@ -517,6 +520,83 @@ dri_gem_bo_map(dri_bo *bo, int write_enable) return 0; } +int +dri_gem_bo_map_gtt(dri_bo *bo, uint32_t alignment) +{ + dri_bufmgr_gem *bufmgr_gem; + dri_bo_gem *bo_gem = (dri_bo_gem *)bo; + struct drm_i915_gem_set_domain set_domain; + int ret; + + bufmgr_gem = (dri_bufmgr_gem *)bo->bufmgr; + + /* Allow recursive mapping. Mesa may recursively map buffers with + * nested display loops. + */ + if (!bo_gem->mapped) { + + assert(bo->virtual == NULL); + + DBG("bo_map_gtt: %d (%s)\n", bo_gem->gem_handle, bo_gem->name); + + if (bo_gem->virtual == NULL) { + struct drm_i915_gem_mmap_gtt mmap_arg; + + memset(&mmap_arg, 0, sizeof(mmap_arg)); + mmap_arg.handle = bo_gem->gem_handle; + /* Just map the whole object */ + mmap_arg.offset = 0; + mmap_arg.size = bo->size; + mmap_arg.alignment = alignment; + + ret = ioctl(bufmgr_gem->fd, DRM_IOCTL_I915_GEM_MMAP_GTT, + &mmap_arg); + if (ret != 0) { + fprintf(stderr, + "%s:%d: Error preparing buffer map %d (%s): %s .\n", + __FILE__, __LINE__, + bo_gem->gem_handle, bo_gem->name, + strerror(errno)); + return ret; + } + bo_gem->virtual = mmap(0, bo->size, PROT_READ | PROT_WRITE, + MAP_SHARED, bufmgr_gem->fd, + mmap_arg.addr_ptr); + if (bo_gem->virtual == MAP_FAILED) { + fprintf(stderr, + "%s:%d: Error mapping buffer %d (%s): %s .\n", + __FILE__, __LINE__, + bo_gem->gem_handle, bo_gem->name, + strerror(errno)); + return errno; + } + } + + bo->virtual = bo_gem->virtual; + bo_gem->swrast = 0; + bo_gem->mapped = 1; + DBG("bo_map: %d (%s) -> %p\n", bo_gem->gem_handle, bo_gem->name, + bo_gem->virtual); + } + + if (!bo_gem->swrast) { + set_domain.handle = bo_gem->gem_handle; + set_domain.read_domains = I915_GEM_DOMAIN_GTT; + set_domain.write_domain = I915_GEM_DOMAIN_GTT; + do { + ret = ioctl(bufmgr_gem->fd, DRM_IOCTL_I915_GEM_SET_DOMAIN, + &set_domain); + } while (ret == -1 && errno == EINTR); + if (ret != 0) { + fprintf (stderr, "%s:%d: Error setting swrast %d: %s\n", + __FILE__, __LINE__, bo_gem->gem_handle, strerror (errno)); + } + bo_gem->swrast = 1; + } + + return 0; +} + static int dri_gem_bo_unmap(dri_bo *bo) {