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,

Reply via email to