From 7d6a3ca9c16f8d5144d8890996c583d81cd860e1 Mon Sep 17 00:00:00 2001 From: Jason Ekstrand Date: Sat, 30 Oct 2021 16:57:02 -0500 Subject: [PATCH] anv: Fix FlushMappedMemoryRanges for odd mmap offsets When the client calls vkMapMemory(), we have to align the requested offset down to the nearest page or else the map will fail. On platforms where we have DRM_IOCTL_I915_GEM_MMAP_OFFSET, we always map the whole buffer. In either case, the original map may start before the requested offset and we need to take that into account when we clflush. Cc: mesa-stable@lists.freedesktop.org Reviewed-by: Paulo Zanoni Part-of: (cherry picked from commit 90ac06e5029b9f0c702c92e97696c9cdb97b08d6) --- .pick_status.json | 2 +- src/intel/vulkan/anv_device.c | 11 +++++++---- src/intel/vulkan/anv_private.h | 3 +++ 3 files changed, 11 insertions(+), 5 deletions(-) diff --git a/.pick_status.json b/.pick_status.json index 195de5a6163..60a30d780a3 100644 --- a/.pick_status.json +++ b/.pick_status.json @@ -517,7 +517,7 @@ "description": "anv: Fix FlushMappedMemoryRanges for odd mmap offsets", "nominated": true, "nomination_type": 0, - "resolution": 0, + "resolution": 1, "main_sha": null, "because_sha": null }, diff --git a/src/intel/vulkan/anv_device.c b/src/intel/vulkan/anv_device.c index ce29517ed85..5efb68fcdfa 100644 --- a/src/intel/vulkan/anv_device.c +++ b/src/intel/vulkan/anv_device.c @@ -4270,8 +4270,9 @@ VkResult anv_MapMemory( mem->map = map; mem->map_size = map_size; + mem->map_delta = (offset - map_offset); - *ppData = mem->map + (offset - map_offset); + *ppData = mem->map + mem->map_delta; return VK_SUCCESS; } @@ -4290,6 +4291,7 @@ void anv_UnmapMemory( mem->map = NULL; mem->map_size = 0; + mem->map_delta = 0; } static void @@ -4299,14 +4301,15 @@ clflush_mapped_ranges(struct anv_device *device, { for (uint32_t i = 0; i < count; i++) { ANV_FROM_HANDLE(anv_device_memory, mem, ranges[i].memory); - if (ranges[i].offset >= mem->map_size) + uint64_t map_offset = ranges[i].offset + mem->map_delta; + if (map_offset >= mem->map_size) continue; if (mem->type->propertyFlags & VK_MEMORY_PROPERTY_HOST_COHERENT_BIT) continue; - intel_clflush_range(mem->map + ranges[i].offset, - MIN2(ranges[i].size, mem->map_size - ranges[i].offset)); + intel_clflush_range(mem->map + map_offset, + MIN2(ranges[i].size, mem->map_size - map_offset)); } } diff --git a/src/intel/vulkan/anv_private.h b/src/intel/vulkan/anv_private.h index a845aaf680b..4105a688a42 100644 --- a/src/intel/vulkan/anv_private.h +++ b/src/intel/vulkan/anv_private.h @@ -1816,6 +1816,9 @@ struct anv_device_memory { VkDeviceSize map_size; void * map; + /* The map, from the user PoV is map + map_delta */ + uint32_t map_delta; + /* If set, we are holding reference to AHardwareBuffer * which we must release when memory is freed. */