aboutsummaryrefslogtreecommitdiffstats
path: root/src/intel
diff options
context:
space:
mode:
Diffstat (limited to 'src/intel')
-rw-r--r--src/intel/vulkan/anv_device.c9
-rw-r--r--src/intel/vulkan/anv_gem.c44
-rw-r--r--src/intel/vulkan/anv_private.h1
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;