Mesa (master): anv: Add support for new MMAP_OFFSET ioctl.

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Mon Apr 20 19:08:51 UTC 2020


Module: Mesa
Branch: master
Commit: 4abf0837cdb14b10a58d28766d5c1d3698d8a6d8
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=4abf0837cdb14b10a58d28766d5c1d3698d8a6d8

Author: Rafael Antognolli <rafael.antognolli at intel.com>
Date:   Fri Jan 18 15:05:55 2019 -0800

anv: Add support for new MMAP_OFFSET ioctl.

v2: Update getparam check (Ken).

[jordan.l.justen at intel.com: use 0 offset for MMAP_OFFSET]

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

---

 src/intel/vulkan/anv_device.c  |  9 ++++++++-
 src/intel/vulkan/anv_gem.c     | 44 ++++++++++++++++++++++++++++++++++++++----
 src/intel/vulkan/anv_private.h |  1 +
 3 files changed, 49 insertions(+), 5 deletions(-)

diff --git a/src/intel/vulkan/anv_device.c b/src/intel/vulkan/anv_device.c
index f80b4f66763..1462b761576 100644
--- a/src/intel/vulkan/anv_device.c
+++ b/src/intel/vulkan/anv_device.c
@@ -477,6 +477,9 @@ anv_physical_device_try_create(struct anv_instance *instance,
    device->always_flush_cache =
       driQueryOptionb(&instance->dri_options, "always_flush_cache");
 
+   device->has_mmap_offset =
+      anv_gem_get_param(fd, I915_PARAM_MMAP_GTT_VERSION) >= 4;
+
    /* GENs prior to 8 do not support EU/Subslice info */
    if (device->info.gen >= 8) {
       device->subslice_total = anv_gem_get_param(fd, I915_PARAM_SUBSLICE_TOTAL);
@@ -3697,7 +3700,11 @@ VkResult anv_MapMemory(
       gem_flags |= I915_MMAP_WC;
 
    /* GEM will fail to map if the offset isn't 4k-aligned.  Round down. */
-   uint64_t map_offset = offset & ~4095ull;
+   uint64_t map_offset;
+   if (!device->physical->has_mmap_offset)
+      map_offset = offset & ~4095ull;
+   else
+      map_offset = 0;
    assert(offset >= map_offset);
    uint64_t map_size = (offset + size) - map_offset;
 
diff --git a/src/intel/vulkan/anv_gem.c b/src/intel/vulkan/anv_gem.c
index bdaebb9bc27..3ad8400caf3 100644
--- a/src/intel/vulkan/anv_gem.c
+++ b/src/intel/vulkan/anv_gem.c
@@ -67,9 +67,31 @@ anv_gem_close(struct anv_device *device, uint32_t gem_handle)
 /**
  * Wrapper around DRM_IOCTL_I915_GEM_MMAP. Returns MAP_FAILED on error.
  */
-void*
-anv_gem_mmap(struct anv_device *device, uint32_t gem_handle,
-             uint64_t offset, uint64_t size, uint32_t flags)
+static void*
+anv_gem_mmap_offset(struct anv_device *device, uint32_t gem_handle,
+                    uint64_t offset, uint64_t size, uint32_t flags)
+{
+   struct drm_i915_gem_mmap_offset gem_mmap = {
+      .handle = gem_handle,
+      .flags = (flags & I915_MMAP_WC) ?
+         I915_MMAP_OFFSET_WC : I915_MMAP_OFFSET_WB,
+   };
+   assert(offset == 0);
+
+   /* Get the fake offset back */
+   int ret = gen_ioctl(device->fd, DRM_IOCTL_I915_GEM_MMAP_OFFSET, &gem_mmap);
+   if (ret != 0)
+      return MAP_FAILED;
+
+   /* And map it */
+   void *map = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED,
+                    device->fd, gem_mmap.offset);
+   return map;
+}
+
+static void*
+anv_gem_mmap_legacy(struct anv_device *device, uint32_t gem_handle,
+                    uint64_t offset, uint64_t size, uint32_t flags)
 {
    struct drm_i915_gem_mmap gem_mmap = {
       .handle = gem_handle,
@@ -86,13 +108,27 @@ anv_gem_mmap(struct anv_device *device, uint32_t gem_handle,
    return (void *)(uintptr_t) gem_mmap.addr_ptr;
 }
 
+/**
+ * Wrapper around DRM_IOCTL_I915_GEM_MMAP. Returns MAP_FAILED on error.
+ */
+void*
+anv_gem_mmap(struct anv_device *device, uint32_t gem_handle,
+             uint64_t offset, uint64_t size, uint32_t flags)
+{
+   if (device->physical->has_mmap_offset)
+      return anv_gem_mmap_offset(device, gem_handle, offset, size, flags);
+   else
+      return anv_gem_mmap_legacy(device, gem_handle, offset, size, flags);
+}
+
 /* This is just a wrapper around munmap, but it also notifies valgrind that
  * this map is no longer valid.  Pair this with anv_gem_mmap().
  */
 void
 anv_gem_munmap(struct anv_device *device, void *p, uint64_t size)
 {
-   VG(VALGRIND_FREELIKE_BLOCK(p, 0));
+   if (!device->physical->has_mmap_offset)
+      VG(VALGRIND_FREELIKE_BLOCK(p, 0));
    munmap(p, size);
 }
 
diff --git a/src/intel/vulkan/anv_private.h b/src/intel/vulkan/anv_private.h
index a0d954df5ef..2f32ecebc6d 100644
--- a/src/intel/vulkan/anv_private.h
+++ b/src/intel/vulkan/anv_private.h
@@ -1044,6 +1044,7 @@ struct anv_physical_device {
     bool                                        has_context_priority;
     bool                                        has_context_isolation;
     bool                                        has_mem_available;
+    bool                                        has_mmap_offset;
     uint64_t                                    gtt_size;
 
     bool                                        use_softpin;



More information about the mesa-commit mailing list