Module: Mesa Branch: main Commit: 7bdfabb641109437af6c9db1179161f6d5c9043f URL: http://cgit.freedesktop.org/mesa/mesa/commit/?id=7bdfabb641109437af6c9db1179161f6d5c9043f
Author: José Roberto de Souza <jose.so...@intel.com> Date: Thu Sep 7 14:34:10 2023 -0700 anv: Calculate mmap mode based on alloc_flags When anv_device_map_bo() is called from anv_device_alloc_bo() it gets VkMemoryPropertyFlags set to 0 so it ends up with a write-combine caching for integrated platforms with LLC, see 'if (!(property_flags & VK_MEMORY_PROPERTY_HOST_CACHED_BIT)))'. Current approach also has issues when mapping with anv_MapMemory2KHR() as it would not have information to know that BO is a scanout. It was also not properly calculating mmap mode for platforms with PAT uAPI before "anv: Change default PAT entry to WC". So here storing alloc_flags to anv_bo so there is no mismatches between different code paths then using it to properly calculate the mmap mode. alloc_flags in anv_bo will also be used to calculate PAT index in future patches. Signed-off-by: José Roberto de Souza <jose.so...@intel.com> Reviewed-by: Lionel Landwerlin <lionel.g.landwer...@intel.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/26099> --- src/intel/vulkan/anv_allocator.c | 46 ++++++++++++++++++++++++++++++--- src/intel/vulkan/anv_device.c | 3 +-- src/intel/vulkan/anv_gem.c | 5 ++-- src/intel/vulkan/anv_gem_stubs.c | 7 +++-- src/intel/vulkan/anv_kmd_backend.h | 3 +-- src/intel/vulkan/anv_private.h | 8 ++++-- src/intel/vulkan/genX_video.c | 2 +- src/intel/vulkan/i915/anv_kmd_backend.c | 24 ++++++++++------- src/intel/vulkan/xe/anv_kmd_backend.c | 2 +- 9 files changed, 71 insertions(+), 29 deletions(-) diff --git a/src/intel/vulkan/anv_allocator.c b/src/intel/vulkan/anv_allocator.c index 0a01190b296..7e15cbe1c38 100644 --- a/src/intel/vulkan/anv_allocator.c +++ b/src/intel/vulkan/anv_allocator.c @@ -1423,6 +1423,39 @@ anv_bo_vma_alloc_or_close(struct anv_device *device, return VK_SUCCESS; } +enum intel_device_info_mmap_mode +anv_bo_get_mmap_mode(struct anv_device *device, struct anv_bo *bo) +{ + enum anv_bo_alloc_flags alloc_flags = bo->alloc_flags; + + if (device->info->has_set_pat_uapi) + return anv_device_get_pat_entry(device, alloc_flags)->mmap; + + if (anv_physical_device_has_vram(device->physical)) { + if (alloc_flags & ANV_BO_ALLOC_NO_LOCAL_MEM) + return INTEL_DEVICE_INFO_MMAP_MODE_WB; + + return INTEL_DEVICE_INFO_MMAP_MODE_WC; + } + + /* gfx9 atom */ + if (!device->info->has_llc) { + /* ANV_BO_ALLOC_SNOOPED means that user wants a cached and coherent memory + * but to achieve it without LLC in older platforms + * DRM_IOCTL_I915_GEM_SET_CACHING needs to be supported and set. + */ + if (alloc_flags & ANV_BO_ALLOC_SNOOPED) + return INTEL_DEVICE_INFO_MMAP_MODE_WB; + + return INTEL_DEVICE_INFO_MMAP_MODE_WC; + } + + if (alloc_flags & (ANV_BO_ALLOC_SCANOUT | ANV_BO_ALLOC_EXTERNAL)) + return INTEL_DEVICE_INFO_MMAP_MODE_WC; + + return INTEL_DEVICE_INFO_MMAP_MODE_WB; +} + VkResult anv_device_alloc_bo(struct anv_device *device, const char *name, @@ -1480,6 +1513,7 @@ anv_device_alloc_bo(struct anv_device *device, .size = size, .actual_size = actual_size, .flags = bo_flags, + .alloc_flags = alloc_flags, .is_external = (alloc_flags & ANV_BO_ALLOC_EXTERNAL), .has_client_visible_address = (alloc_flags & ANV_BO_ALLOC_CLIENT_VISIBLE_ADDRESS) != 0, @@ -1488,8 +1522,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 /* propertyFlags */, &new_bo.map); + VkResult result = anv_device_map_bo(device, &new_bo, 0, size, &new_bo.map); if (unlikely(result != VK_SUCCESS)) { device->kmd_backend->gem_close(device, &new_bo); return result; @@ -1526,13 +1559,12 @@ anv_device_map_bo(struct anv_device *device, struct anv_bo *bo, uint64_t offset, size_t size, - VkMemoryPropertyFlags property_flags, void **map_out) { assert(!bo->from_host_ptr); assert(size > 0); - void *map = anv_gem_mmap(device, bo, offset, size, property_flags); + void *map = anv_gem_mmap(device, bo, offset, size); if (unlikely(map == MAP_FAILED)) return vk_errorf(device, VK_ERROR_MEMORY_MAP_FAILED, "mmap failed: %m"); @@ -1617,6 +1649,8 @@ anv_device_import_bo_from_host_ptr(struct anv_device *device, __sync_fetch_and_add(&bo->refcount, 1); } else { + /* Makes sure that userptr gets WB mmap caching and right VM PAT index */ + alloc_flags |= (ANV_BO_ALLOC_SNOOPED | ANV_BO_ALLOC_NO_LOCAL_MEM); struct anv_bo new_bo = { .name = "host-ptr", .gem_handle = gem_handle, @@ -1626,6 +1660,7 @@ anv_device_import_bo_from_host_ptr(struct anv_device *device, .actual_size = size, .map = host_ptr, .flags = bo_flags, + .alloc_flags = alloc_flags, .is_external = true, .from_host_ptr = true, .has_client_visible_address = @@ -1707,12 +1742,15 @@ anv_device_import_bo(struct anv_device *device, __sync_fetch_and_add(&bo->refcount, 1); } else { + /* so imported bos get WB and correct PAT index */ + alloc_flags |= (ANV_BO_ALLOC_SNOOPED | ANV_BO_ALLOC_NO_LOCAL_MEM); struct anv_bo new_bo = { .name = "imported", .gem_handle = gem_handle, .refcount = 1, .offset = -1, .is_external = true, + .alloc_flags = alloc_flags, .has_client_visible_address = (alloc_flags & ANV_BO_ALLOC_CLIENT_VISIBLE_ADDRESS) != 0, }; diff --git a/src/intel/vulkan/anv_device.c b/src/intel/vulkan/anv_device.c index 17c76fe14c0..16b39f26e85 100644 --- a/src/intel/vulkan/anv_device.c +++ b/src/intel/vulkan/anv_device.c @@ -4326,8 +4326,7 @@ VkResult anv_MapMemory2KHR( map_size = align64(map_size, 4096); void *map; - VkResult result = anv_device_map_bo(device, mem->bo, map_offset, map_size, - mem->type->propertyFlags, &map); + VkResult result = anv_device_map_bo(device, mem->bo, map_offset, map_size, &map); if (result != VK_SUCCESS) return result; diff --git a/src/intel/vulkan/anv_gem.c b/src/intel/vulkan/anv_gem.c index 5514149dfd5..80f33cc7c9a 100644 --- a/src/intel/vulkan/anv_gem.c +++ b/src/intel/vulkan/anv_gem.c @@ -36,10 +36,9 @@ void * anv_gem_mmap(struct anv_device *device, struct anv_bo *bo, uint64_t offset, - uint64_t size, VkMemoryPropertyFlags property_flags) + uint64_t size) { - void *map = device->kmd_backend->gem_mmap(device, bo, offset, size, - property_flags); + void *map = device->kmd_backend->gem_mmap(device, bo, offset, size); if (map != MAP_FAILED) VG(VALGRIND_MALLOCLIKE_BLOCK(map, size, 0, 1)); diff --git a/src/intel/vulkan/anv_gem_stubs.c b/src/intel/vulkan/anv_gem_stubs.c index a22491012c4..f2b8103ea81 100644 --- a/src/intel/vulkan/anv_gem_stubs.c +++ b/src/intel/vulkan/anv_gem_stubs.c @@ -52,7 +52,7 @@ stub_gem_create(struct anv_device *device, static void * stub_gem_mmap(struct anv_device *device, struct anv_bo *bo, uint64_t offset, - uint64_t size, VkMemoryPropertyFlags property_flags) + uint64_t size) { return mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, bo->gem_handle, offset); @@ -95,10 +95,9 @@ stub_bo_alloc_flags_to_bo_flags(struct anv_device *device, void * anv_gem_mmap(struct anv_device *device, struct anv_bo *bo, uint64_t offset, - uint64_t size, VkMemoryPropertyFlags property_flags) + uint64_t size) { - void *map = device->kmd_backend->gem_mmap(device, bo, offset, size, - property_flags); + void *map = device->kmd_backend->gem_mmap(device, bo, offset, size); if (map != MAP_FAILED) VG(VALGRIND_MALLOCLIKE_BLOCK(map, size, 0, 1)); diff --git a/src/intel/vulkan/anv_kmd_backend.h b/src/intel/vulkan/anv_kmd_backend.h index ff1e969a222..ed860eba81f 100644 --- a/src/intel/vulkan/anv_kmd_backend.h +++ b/src/intel/vulkan/anv_kmd_backend.h @@ -66,8 +66,7 @@ struct anv_kmd_backend { void (*gem_close)(struct anv_device *device, struct anv_bo *bo); /* 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); + uint64_t offset, uint64_t size); /* Bind things however you want. */ int (*vm_bind)(struct anv_device *device, int num_binds, struct anv_vm_bind *binds); diff --git a/src/intel/vulkan/anv_private.h b/src/intel/vulkan/anv_private.h index 3da57fbd78d..d8851ad7f6d 100644 --- a/src/intel/vulkan/anv_private.h +++ b/src/intel/vulkan/anv_private.h @@ -455,6 +455,8 @@ struct anv_bo { /** Flags to pass to the kernel through drm_i915_exec_object2::flags */ uint32_t flags; + enum anv_bo_alloc_flags alloc_flags; + /** True if this BO may be shared with other processes */ bool is_external:1; @@ -478,6 +480,9 @@ anv_bo_ref(struct anv_bo *bo) return bo; } +enum intel_device_info_mmap_mode +anv_bo_get_mmap_mode(struct anv_device *device, struct anv_bo *bo); + struct anv_address { struct anv_bo *bo; int64_t offset; @@ -1800,7 +1805,6 @@ VkResult anv_device_map_bo(struct anv_device *device, struct anv_bo *bo, uint64_t offset, size_t size, - uint32_t gem_flags, void **map_out); void anv_device_unmap_bo(struct anv_device *device, struct anv_bo *bo, @@ -1859,7 +1863,7 @@ void anv_queue_trace(struct anv_queue *queue, const char *label, void * anv_gem_mmap(struct anv_device *device, struct anv_bo *bo, uint64_t offset, - uint64_t size, VkMemoryPropertyFlags property_flags); + uint64_t size); void anv_gem_munmap(struct anv_device *device, void *p, uint64_t size); int anv_gem_wait(struct anv_device *device, uint32_t gem_handle, int64_t *timeout_ns); int anv_gem_set_tiling(struct anv_device *device, uint32_t gem_handle, diff --git a/src/intel/vulkan/genX_video.c b/src/intel/vulkan/genX_video.c index b01d2cfaa2c..e2351d7b7a5 100644 --- a/src/intel/vulkan/genX_video.c +++ b/src/intel/vulkan/genX_video.c @@ -597,7 +597,7 @@ anv_h265_decode_video(struct anv_cmd_buffer *cmd_buffer, /* Slice parsing */ uint32_t last_slice = h265_pic_info->sliceSegmentCount - 1; void *slice_map = anv_gem_mmap(cmd_buffer->device, src_buffer->address.bo, - src_buffer->address.offset, frame_info->srcBufferRange, 0); + src_buffer->address.offset, frame_info->srcBufferRange); struct vk_video_h265_slice_params slice_params[h265_pic_info->sliceSegmentCount]; diff --git a/src/intel/vulkan/i915/anv_kmd_backend.c b/src/intel/vulkan/i915/anv_kmd_backend.c index 38a266780b6..1d0cb178abc 100644 --- a/src/intel/vulkan/i915/anv_kmd_backend.c +++ b/src/intel/vulkan/i915/anv_kmd_backend.c @@ -164,18 +164,22 @@ i915_gem_mmap_legacy(struct anv_device *device, struct anv_bo *bo, uint64_t offs } static uint32_t -mmap_calc_flags(struct anv_device *device, struct anv_bo *bo, - VkMemoryPropertyFlags property_flags) +mmap_calc_flags(struct anv_device *device, struct anv_bo *bo) { 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 (!(property_flags & VK_MEMORY_PROPERTY_HOST_CACHED_BIT)) - flags |= I915_MMAP_WC; + uint32_t flags; + switch (anv_bo_get_mmap_mode(device, bo)) { + case INTEL_DEVICE_INFO_MMAP_MODE_WC: + flags = I915_MMAP_WC; + break; + case INTEL_DEVICE_INFO_MMAP_MODE_UC: + unreachable("Missing"); + default: + /* no flags == WB */ + flags = 0; + } if (likely(device->physical->info.has_mmap_offset)) flags = (flags & I915_MMAP_WC) ? I915_MMAP_OFFSET_WC : I915_MMAP_OFFSET_WB; @@ -184,9 +188,9 @@ mmap_calc_flags(struct anv_device *device, struct anv_bo *bo, static void * i915_gem_mmap(struct anv_device *device, struct anv_bo *bo, uint64_t offset, - uint64_t size, VkMemoryPropertyFlags property_flags) + uint64_t size) { - const uint32_t flags = mmap_calc_flags(device, bo, property_flags); + const uint32_t flags = mmap_calc_flags(device, bo); if (likely(device->physical->info.has_mmap_offset)) return i915_gem_mmap_offset(device, bo, size, flags); diff --git a/src/intel/vulkan/xe/anv_kmd_backend.c b/src/intel/vulkan/xe/anv_kmd_backend.c index c3c22d98be7..a3883c8e61f 100644 --- a/src/intel/vulkan/xe/anv_kmd_backend.c +++ b/src/intel/vulkan/xe/anv_kmd_backend.c @@ -81,7 +81,7 @@ xe_gem_close(struct anv_device *device, struct anv_bo *bo) static void * xe_gem_mmap(struct anv_device *device, struct anv_bo *bo, uint64_t offset, - uint64_t size, VkMemoryPropertyFlags property_flags) + uint64_t size) { struct drm_xe_gem_mmap_offset args = { .handle = bo->gem_handle,