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 <paulo.r.zanoni@intel.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/13610>
(cherry picked from commit 90ac06e502)
This commit is contained in:
Jason Ekstrand 2021-10-30 16:57:02 -05:00 committed by Eric Engestrom
parent e426a9e586
commit 6bbf2110db
3 changed files with 11 additions and 5 deletions

View file

@ -544,7 +544,7 @@
"description": "anv: Fix FlushMappedMemoryRanges for odd mmap offsets",
"nominated": true,
"nomination_type": 0,
"resolution": 0,
"resolution": 1,
"main_sha": null,
"because_sha": null
},

View file

@ -4030,8 +4030,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;
}
@ -4050,6 +4051,7 @@ void anv_UnmapMemory(
mem->map = NULL;
mem->map_size = 0;
mem->map_delta = 0;
}
static void
@ -4059,14 +4061,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));
}
}

View file

@ -1769,6 +1769,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.
*/