anv/device: Handle non-4k-aligned calls to MapMemory

As per the spec:

   minMemoryMapAlignment is the minimum required alignment, in bytes, of
   host-visible memory allocations within the host address space. When
   mapping a memory allocation with vkMapMemory, subtracting offset bytes
   from the returned pointer will always produce a multiple of the value of
   this limit.
This commit is contained in:
Jason Ekstrand 2016-01-01 09:26:06 -08:00
parent 6b5cbdb317
commit f076d5330d

View file

@ -468,7 +468,7 @@ void anv_GetPhysicalDeviceProperties(
.maxViewportDimensions = { (1 << 14), (1 << 14) },
.viewportBoundsRange = { -1.0, 1.0 }, /* FIXME */
.viewportSubPixelBits = 13, /* We take a float? */
.minMemoryMapAlignment = 64, /* A cache line */
.minMemoryMapAlignment = 4096, /* A page */
.minTexelBufferOffsetAlignment = 1,
.minUniformBufferOffsetAlignment = 1,
.minStorageBufferOffsetAlignment = 1,
@ -1082,10 +1082,19 @@ VkResult anv_MapMemory(
if (!device->info.has_llc && mem->type_index == 0)
gem_flags |= I915_MMAP_WC;
mem->map = anv_gem_mmap(device, mem->bo.gem_handle, offset, size, gem_flags);
mem->map_size = size;
/* GEM will fail to map if the offset isn't 4k-aligned. Round down. */
uint64_t map_offset = offset & ~4095ull;
assert(offset >= map_offset);
uint64_t map_size = (offset + size) - map_offset;
*ppData = mem->map;
/* Let's map whole pages */
map_size = (map_size + 4095) & ~4095ull;
mem->map = anv_gem_mmap(device, mem->bo.gem_handle,
map_offset, map_size, gem_flags);
mem->map_size = map_size;
*ppData = mem->map + (offset - map_offset);
return VK_SUCCESS;
}