anv: Add support for new MMAP_OFFSET ioctl.
authorRafael Antognolli <rafael.antognolli@intel.com>
Fri, 18 Jan 2019 23:05:55 +0000 (15:05 -0800)
committerRafael Antognolli <rafael.antognolli@intel.com>
Mon, 20 Apr 2020 17:59:06 +0000 (10:59 -0700)
v2: Update getparam check (Ken).

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

Signed-off-by: Jordan Justen <jordan.l.justen@intel.com>
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/intel/vulkan/anv_device.c
src/intel/vulkan/anv_gem.c
src/intel/vulkan/anv_private.h

index f80b4f6676335c673522fa7d4f117431f730f37c..1462b76157600e899229b7f0e72b9f46b828ce35 100644 (file)
@@ -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;
 
index bdaebb9bc27c054cbfc177b45ef69c664f3333bb..3ad8400caf3e48d56d2366eb8b1c6ef229f3518e 100644 (file)
@@ -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);
 }
 
index a0d954df5ef79bc81c471deffa890d6479cf4d25..2f32ecebc6d44a44a6b401695798263186d1017c 100644 (file)
@@ -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;