From: Rafael Antognolli Date: Fri, 18 Jan 2019 23:05:55 +0000 (-0800) Subject: anv: Add support for new MMAP_OFFSET ioctl. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=4abf0837cdb14b10a58d28766d5c1d3698d8a6d8;p=mesa.git anv: Add support for new MMAP_OFFSET ioctl. v2: Update getparam check (Ken). [jordan.l.justen@intel.com: use 0 offset for MMAP_OFFSET] Signed-off-by: Jordan Justen Reviewed-by: Kenneth Graunke Reviewed-by: Jordan Justen Part-of: --- 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;