i965/bufmgr: Add support for MMAP_OFFSET ioctl.
authorRafael Antognolli <rafael.antognolli@intel.com>
Fri, 14 Dec 2018 22:02:04 +0000 (14:02 -0800)
committerRafael Antognolli <rafael.antognolli@intel.com>
Mon, 20 Apr 2020 17:59:06 +0000 (10:59 -0700)
Use the new DRM_IOCTL_I915_GEM_MMAP_OFFSET ioctl when available.

v2: update getparam check (Ken).

Reviewed-by: Kenneth Graunke <kenneth@whitecape.org>
Reviewed-by: Jordan Justen <jordan.l.justen@intel.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/1675>

src/mesa/drivers/dri/i965/brw_bufmgr.c

index d7c65f00690a8a348e67ec0cb9d0b1611830dbc0..9b706c42e38a4cb74b1d57d10435312db9bc04ad 100644 (file)
@@ -156,6 +156,7 @@ struct brw_bufmgr {
 
    bool has_llc:1;
    bool has_mmap_wc:1;
+   bool has_mmap_offset:1;
    bool bo_reuse:1;
 
    uint64_t initial_kflags;
@@ -979,10 +980,45 @@ brw_bo_gem_mmap_legacy(struct brw_context *brw, struct brw_bo *bo, bool wc)
    return map;
 }
 
+static void *
+brw_bo_gem_mmap_offset(struct brw_context *brw, struct brw_bo *bo, bool wc)
+{
+   struct brw_bufmgr *bufmgr = bo->bufmgr;
+
+   struct drm_i915_gem_mmap_offset mmap_arg = {
+      .handle = bo->gem_handle,
+      .flags = wc ? I915_MMAP_OFFSET_WC : I915_MMAP_OFFSET_WB,
+   };
+
+   /* Get the fake offset back */
+   int ret = drmIoctl(bufmgr->fd, DRM_IOCTL_I915_GEM_MMAP_OFFSET, &mmap_arg);
+   if (ret != 0) {
+      DBG("%s:%d: Error preparing buffer %d (%s): %s .\n",
+          __FILE__, __LINE__, bo->gem_handle, bo->name, strerror(errno));
+      return NULL;
+   }
+
+   /* And map it */
+   void *map = drm_mmap(0, bo->size, PROT_READ | PROT_WRITE, MAP_SHARED,
+                        bufmgr->fd, mmap_arg.offset);
+   if (map == MAP_FAILED) {
+      DBG("%s:%d: Error mapping buffer %d (%s): %s .\n",
+          __FILE__, __LINE__, bo->gem_handle, bo->name, strerror(errno));
+      return NULL;
+   }
+
+   return map;
+}
+
 static void *
 brw_bo_gem_mmap(struct brw_context *brw, struct brw_bo *bo, bool wc)
 {
-   return brw_bo_gem_mmap_legacy(brw, bo, wc);
+   struct brw_bufmgr *bufmgr = bo->bufmgr;
+
+   if (bufmgr->has_mmap_offset)
+      return brw_bo_gem_mmap_offset(brw, bo, wc);
+   else
+      return brw_bo_gem_mmap_legacy(brw, bo, wc);
 }
 
 static void *
@@ -1730,6 +1766,7 @@ brw_bufmgr_create(struct gen_device_info *devinfo, int fd, bool bo_reuse)
    bufmgr->has_llc = devinfo->has_llc;
    bufmgr->has_mmap_wc = gem_param(fd, I915_PARAM_MMAP_VERSION) > 0;
    bufmgr->bo_reuse = bo_reuse;
+   bufmgr->has_mmap_offset = gem_param(fd, I915_PARAM_MMAP_GTT_VERSION) >= 4;
 
    const uint64_t _4GB = 4ull << 30;