From 0c8d8ae13c35eee643fd508c56e23cb4ca95ede7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Roberto=20de=20Souza?= Date: Thu, 9 Feb 2023 06:29:28 -0800 Subject: [PATCH] anv: Add gem_mmap to kmd backend MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: José Roberto de Souza Reviewed-by: Lionel Landwerlin Part-of: --- src/intel/vulkan/anv_allocator.c | 9 ++-- src/intel/vulkan/anv_device.c | 10 +--- src/intel/vulkan/anv_gem.c | 64 +++---------------------- src/intel/vulkan/anv_gem_stubs.c | 27 +++++++---- src/intel/vulkan/anv_kmd_backend.h | 7 +++ src/intel/vulkan/anv_private.h | 5 +- src/intel/vulkan/i915/anv_kmd_backend.c | 64 +++++++++++++++++++++++++ 7 files changed, 104 insertions(+), 82 deletions(-) diff --git a/src/intel/vulkan/anv_allocator.c b/src/intel/vulkan/anv_allocator.c index f84f0ee36d0..f419d475a7b 100644 --- a/src/intel/vulkan/anv_allocator.c +++ b/src/intel/vulkan/anv_allocator.c @@ -1503,7 +1503,7 @@ anv_device_alloc_bo(struct anv_device *device, if (alloc_flags & ANV_BO_ALLOC_MAPPED) { VkResult result = anv_device_map_bo(device, &new_bo, 0, size, - 0 /* gem_flags */, &new_bo.map); + 0 /* propertyFlags */, &new_bo.map); if (unlikely(result != VK_SUCCESS)) { device->kmd_backend->gem_close(device, new_bo.gem_handle); return result; @@ -1562,16 +1562,13 @@ anv_device_map_bo(struct anv_device *device, struct anv_bo *bo, uint64_t offset, size_t size, - uint32_t gem_flags, + VkMemoryPropertyFlags property_flags, void **map_out) { assert(!bo->from_host_ptr); assert(size > 0); - if (bo->map_wc) - gem_flags |= I915_MMAP_WC; - - void *map = anv_gem_mmap(device, bo, offset, size, gem_flags); + void *map = anv_gem_mmap(device, bo, offset, size, property_flags); if (unlikely(map == MAP_FAILED)) return vk_errorf(device, VK_ERROR_MEMORY_MAP_FAILED, "mmap failed: %m"); diff --git a/src/intel/vulkan/anv_device.c b/src/intel/vulkan/anv_device.c index 33c4d123ad4..061e1e199ac 100644 --- a/src/intel/vulkan/anv_device.c +++ b/src/intel/vulkan/anv_device.c @@ -4255,12 +4255,6 @@ VkResult anv_MapMemory( "Memory object already mapped."); } - uint32_t gem_flags = 0; - - if (!device->info->has_llc && - (mem->type->propertyFlags & VK_MEMORY_PROPERTY_HOST_COHERENT_BIT)) - gem_flags |= I915_MMAP_WC; - /* GEM will fail to map if the offset isn't 4k-aligned. Round down. */ uint64_t map_offset; if (!device->physical->info.has_mmap_offset) @@ -4274,8 +4268,8 @@ VkResult anv_MapMemory( map_size = align64(map_size, 4096); void *map; - VkResult result = anv_device_map_bo(device, mem->bo, map_offset, - map_size, gem_flags, &map); + VkResult result = anv_device_map_bo(device, mem->bo, map_offset, map_size, + mem->type->propertyFlags, &map); if (result != VK_SUCCESS) return result; diff --git a/src/intel/vulkan/anv_gem.c b/src/intel/vulkan/anv_gem.c index e705af37e05..14f450a5a58 100644 --- a/src/intel/vulkan/anv_gem.c +++ b/src/intel/vulkan/anv_gem.c @@ -32,64 +32,12 @@ #include "anv_private.h" #include "common/intel_gem.h" -/** - * Wrapper around DRM_IOCTL_I915_GEM_MMAP. Returns MAP_FAILED on error. - */ -static void* -anv_gem_mmap_offset(struct anv_device *device, uint32_t gem_handle, - uint64_t offset, uint64_t size, uint32_t flags) +void * +anv_gem_mmap(struct anv_device *device, struct anv_bo *bo, uint64_t offset, + uint64_t size, VkMemoryPropertyFlags property_flags) { - struct drm_i915_gem_mmap_offset gem_mmap = { - .handle = gem_handle, - .flags = device->info->has_local_mem ? I915_MMAP_OFFSET_FIXED : - (flags & I915_MMAP_WC) ? I915_MMAP_OFFSET_WC : I915_MMAP_OFFSET_WB, - }; - assert(offset == 0); - - /* Get the fake offset back */ - int ret = intel_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) -{ - assert(!device->info->has_local_mem); - - struct drm_i915_gem_mmap gem_mmap = { - .handle = gem_handle, - .offset = offset, - .size = size, - .flags = flags, - }; - - int ret = intel_ioctl(device->fd, DRM_IOCTL_I915_GEM_MMAP, &gem_mmap); - if (ret != 0) - return MAP_FAILED; - - 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, struct anv_bo *bo, - uint64_t offset, uint64_t size, uint32_t flags) -{ - uint32_t gem_handle = bo->gem_handle; - void *map; - if (device->physical->info.has_mmap_offset) - map = anv_gem_mmap_offset(device, gem_handle, offset, size, flags); - else - map = anv_gem_mmap_legacy(device, gem_handle, offset, size, flags); + void *map = device->kmd_backend->gem_mmap(device, bo, offset, size, + property_flags); if (map != MAP_FAILED) VG(VALGRIND_MALLOCLIKE_BLOCK(map, size, 0, 1)); @@ -98,7 +46,7 @@ anv_gem_mmap(struct anv_device *device, struct anv_bo *bo, } /* 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(). + * this map is no longer valid. Pair this with gem_mmap(). */ void anv_gem_munmap(struct anv_device *device, void *p, uint64_t size) diff --git a/src/intel/vulkan/anv_gem_stubs.c b/src/intel/vulkan/anv_gem_stubs.c index 943513dd6bc..83740d6a163 100644 --- a/src/intel/vulkan/anv_gem_stubs.c +++ b/src/intel/vulkan/anv_gem_stubs.c @@ -48,19 +48,29 @@ stub_gem_create(struct anv_device *device, return fd; } -void* -anv_gem_mmap(struct anv_device *device, struct anv_bo *bo, - uint64_t offset, uint64_t size, uint32_t flags) +static void * +stub_gem_mmap(struct anv_device *device, struct anv_bo *bo, uint64_t offset, + uint64_t size, VkMemoryPropertyFlags property_flags) { - /* Ignore flags, as they're specific to I915_GEM_MMAP. */ - (void) flags; + return mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, bo->gem_handle, + offset); +} - return mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, - bo->gem_handle, offset); +void * +anv_gem_mmap(struct anv_device *device, struct anv_bo *bo, uint64_t offset, + uint64_t size, VkMemoryPropertyFlags property_flags) +{ + void *map = device->kmd_backend->gem_mmap(device, bo, offset, size, + property_flags); + + if (map != MAP_FAILED) + VG(VALGRIND_MALLOCLIKE_BLOCK(map, size, 0, 1)); + + return map; } /* 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(). + * this map is no longer valid. Pair this with gem_mmap(). */ void anv_gem_munmap(struct anv_device *device, void *p, uint64_t size) @@ -123,6 +133,7 @@ const struct anv_kmd_backend *anv_stub_kmd_backend_get(void) static const struct anv_kmd_backend stub_backend = { .gem_create = stub_gem_create, .gem_close = stub_gem_close, + .gem_mmap = stub_gem_mmap, }; return &stub_backend; } diff --git a/src/intel/vulkan/anv_kmd_backend.h b/src/intel/vulkan/anv_kmd_backend.h index c8d01b63313..33cbd084965 100644 --- a/src/intel/vulkan/anv_kmd_backend.h +++ b/src/intel/vulkan/anv_kmd_backend.h @@ -25,9 +25,12 @@ #include +#include "vulkan/vulkan_core.h" + #include "dev/intel_device_info.h" #include "dev/intel_kmd.h" +struct anv_bo; enum anv_bo_alloc_flags; struct anv_device; @@ -41,6 +44,10 @@ struct anv_kmd_backend { uint16_t num_regions, uint64_t size, enum anv_bo_alloc_flags alloc_flags); void (*gem_close)(struct anv_device *device, uint32_t handle); + /* Returns MAP_FAILED on error */ + void *(*gem_mmap)(struct anv_device *device, struct anv_bo *bo, + uint64_t offset, uint64_t size, + VkMemoryPropertyFlags property_flags); }; const struct anv_kmd_backend *anv_kmd_backend_get(enum intel_kmd_type type); diff --git a/src/intel/vulkan/anv_private.h b/src/intel/vulkan/anv_private.h index 78b956fd7e0..1c0bb0a2a11 100644 --- a/src/intel/vulkan/anv_private.h +++ b/src/intel/vulkan/anv_private.h @@ -1349,8 +1349,9 @@ VkResult anv_queue_submit(struct vk_queue *queue, VkResult anv_queue_submit_simple_batch(struct anv_queue *queue, struct anv_batch *batch); -void* anv_gem_mmap(struct anv_device *device, struct anv_bo *bo, - uint64_t offset, uint64_t size, uint32_t flags); +void * +anv_gem_mmap(struct anv_device *device, struct anv_bo *bo, uint64_t offset, + uint64_t size, VkMemoryPropertyFlags property_flags); void anv_gem_munmap(struct anv_device *device, void *p, uint64_t size); uint32_t anv_gem_userptr(struct anv_device *device, void *mem, size_t size); int anv_gem_wait(struct anv_device *device, uint32_t gem_handle, int64_t *timeout_ns); diff --git a/src/intel/vulkan/i915/anv_kmd_backend.c b/src/intel/vulkan/i915/anv_kmd_backend.c index 892cdeb70fd..ee9a5a493f9 100644 --- a/src/intel/vulkan/i915/anv_kmd_backend.c +++ b/src/intel/vulkan/i915/anv_kmd_backend.c @@ -21,6 +21,8 @@ * IN THE SOFTWARE. */ +#include + #include "anv_private.h" #include "drm-uapi/i915_drm.h" @@ -84,12 +86,74 @@ i915_gem_close(struct anv_device *device, uint32_t handle) intel_ioctl(device->fd, DRM_IOCTL_GEM_CLOSE, &close); } +static void * +i915_gem_mmap_offset(struct anv_device *device, struct anv_bo *bo, + uint64_t size, uint32_t flags) +{ + struct drm_i915_gem_mmap_offset gem_mmap = { + .handle = bo->gem_handle, + .flags = flags, + }; + if (intel_ioctl(device->fd, DRM_IOCTL_I915_GEM_MMAP_OFFSET, &gem_mmap)) + return MAP_FAILED; + + return mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, + device->fd, gem_mmap.offset); +} + +static void * +i915_gem_mmap_legacy(struct anv_device *device, struct anv_bo *bo, uint64_t offset, + uint64_t size, uint32_t flags) +{ + struct drm_i915_gem_mmap gem_mmap = { + .handle = bo->gem_handle, + .offset = offset, + .size = size, + .flags = flags, + }; + if (intel_ioctl(device->fd, DRM_IOCTL_I915_GEM_MMAP, &gem_mmap)) + return MAP_FAILED; + + return (void *)(uintptr_t) gem_mmap.addr_ptr; +} + +static uint32_t +mmap_calc_flags(struct anv_device *device, struct anv_bo *bo, + VkMemoryPropertyFlags property_flags) +{ + if (device->info->has_local_mem) + return I915_MMAP_OFFSET_FIXED; + + uint32_t flags = 0; + if (!device->info->has_llc && + (property_flags & VK_MEMORY_PROPERTY_HOST_COHERENT_BIT)) + flags |= I915_MMAP_WC; + if (bo->map_wc) + flags |= I915_MMAP_WC; + + if (likely(device->physical->info.has_mmap_offset)) + flags = (flags & I915_MMAP_WC) ? I915_MMAP_OFFSET_WC : I915_MMAP_OFFSET_WB; + return flags; +} + +static void * +i915_gem_mmap(struct anv_device *device, struct anv_bo *bo, uint64_t offset, + uint64_t size, VkMemoryPropertyFlags property_flags) +{ + const uint32_t flags = mmap_calc_flags(device, bo, property_flags); + + if (likely(device->physical->info.has_mmap_offset)) + return i915_gem_mmap_offset(device, bo, size, flags); + return i915_gem_mmap_legacy(device, bo, offset, size, flags); +} + const struct anv_kmd_backend * anv_i915_kmd_backend_get(void) { static const struct anv_kmd_backend i915_backend = { .gem_create = i915_gem_create, .gem_close = i915_gem_close, + .gem_mmap = i915_gem_mmap, }; return &i915_backend; }