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.souza@intel.com> Reviewed-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/26099>
This commit is contained in:
committed by
Marge Bot
parent
58301c00da
commit
7bdfabb641
@@ -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,
|
||||
};
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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));
|
||||
|
||||
@@ -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));
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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];
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user