From d62fdc0a2e9e1124880da3c10f256ecd3a06a5fb Mon Sep 17 00:00:00 2001 From: Simon Perretta Date: Fri, 3 Oct 2025 12:23:25 +0100 Subject: [PATCH] pvr: support VK_EXT_map_memory_placed.memoryUnmapReserve Signed-off-by: Simon Perretta Reviewed-by: Frank Binns Part-of: --- src/imagination/vulkan/pvr_bo.c | 6 ++--- src/imagination/vulkan/pvr_device.c | 11 +++++---- .../vulkan/winsys/powervr/pvr_drm_bo.c | 7 ++++-- .../vulkan/winsys/powervr/pvr_drm_bo.h | 4 ++-- src/imagination/vulkan/winsys/pvr_winsys.h | 2 +- .../vulkan/winsys/pvr_winsys_helper.c | 10 ++++---- .../vulkan/winsys/pvr_winsys_helper.h | 23 ++++++++++++++++++- .../vulkan/winsys/pvrsrvkm/pvr_srv_bo.c | 7 ++++-- .../vulkan/winsys/pvrsrvkm/pvr_srv_bo.h | 4 ++-- 9 files changed, 52 insertions(+), 22 deletions(-) diff --git a/src/imagination/vulkan/pvr_bo.c b/src/imagination/vulkan/pvr_bo.c index fa55e96b843..a321f358e61 100644 --- a/src/imagination/vulkan/pvr_bo.c +++ b/src/imagination/vulkan/pvr_bo.c @@ -390,7 +390,7 @@ err_heap_free: err_buffer_unmap: if (flags & PVR_BO_ALLOC_FLAG_CPU_MAPPED) - device->ws->ops->buffer_unmap(pvr_bo->bo); + device->ws->ops->buffer_unmap(pvr_bo->bo, false); err_buffer_destroy: device->ws->ops->buffer_destroy(pvr_bo->bo); @@ -455,7 +455,7 @@ void pvr_bo_cpu_unmap(struct pvr_device *device, struct pvr_bo *pvr_bo) } #endif /* defined(HAVE_VALGRIND) */ - device->ws->ops->buffer_unmap(bo); + device->ws->ops->buffer_unmap(bo, false); } /** @@ -484,7 +484,7 @@ void pvr_bo_free(struct pvr_device *device, struct pvr_bo *pvr_bo) device->ws->ops->heap_free(pvr_bo->vma); if (pvr_bo->bo->map) - device->ws->ops->buffer_unmap(pvr_bo->bo); + device->ws->ops->buffer_unmap(pvr_bo->bo, false); device->ws->ops->buffer_destroy(pvr_bo->bo); diff --git a/src/imagination/vulkan/pvr_device.c b/src/imagination/vulkan/pvr_device.c index a3f272c10d4..92d7cb2fcfb 100644 --- a/src/imagination/vulkan/pvr_device.c +++ b/src/imagination/vulkan/pvr_device.c @@ -461,7 +461,7 @@ static void pvr_physical_device_get_supported_features( /* VK_EXT_map_memory_placed */ .memoryMapPlaced = true, .memoryMapRangePlaced = false, - .memoryUnmapReserve = false, + .memoryUnmapReserve = true, /* Vulkan 1.3 / VK_EXT_private_data */ .privateData = true, @@ -2761,7 +2761,7 @@ void pvr_FreeMemory(VkDevice _device, * unmapped. */ if (mem->bo->map) - device->ws->ops->buffer_unmap(mem->bo); + device->ws->ops->buffer_unmap(mem->bo, false); device->ws->ops->buffer_destroy(mem->bo); @@ -2835,8 +2835,11 @@ VkResult pvr_UnmapMemory2(VkDevice _device, VK_FROM_HANDLE(pvr_device, device, _device); VK_FROM_HANDLE(pvr_device_memory, mem, pMemoryUnmapInfo->memory); - if (mem && mem->bo->map) - device->ws->ops->buffer_unmap(mem->bo); + if (mem && mem->bo->map) { + bool reserve = + !!(pMemoryUnmapInfo->flags & VK_MEMORY_UNMAP_RESERVE_BIT_EXT); + return device->ws->ops->buffer_unmap(mem->bo, reserve); + } return VK_SUCCESS; } diff --git a/src/imagination/vulkan/winsys/powervr/pvr_drm_bo.c b/src/imagination/vulkan/winsys/powervr/pvr_drm_bo.c index 67bbd015e83..15d4299f825 100644 --- a/src/imagination/vulkan/winsys/powervr/pvr_drm_bo.c +++ b/src/imagination/vulkan/winsys/powervr/pvr_drm_bo.c @@ -334,19 +334,22 @@ err_out: return result; } -void pvr_drm_winsys_buffer_unmap(struct pvr_winsys_bo *bo) +VkResult pvr_drm_winsys_buffer_unmap(struct pvr_winsys_bo *bo, bool reserve) { struct pvr_drm_winsys_bo *drm_bo = to_pvr_drm_winsys_bo(bo); + VkResult result; assert(bo->map); - pvr_munmap(bo->map, bo->size); + result = pvr_munmap(bo->map, bo->size, reserve); VG(VALGRIND_FREELIKE_BLOCK(bo->map, 0)); bo->map = NULL; pvr_drm_buffer_release(drm_bo); + + return result; } /* This function must be used to allocate from a heap carveout and must only be diff --git a/src/imagination/vulkan/winsys/powervr/pvr_drm_bo.h b/src/imagination/vulkan/winsys/powervr/pvr_drm_bo.h index 25272269b5a..b7879b17354 100644 --- a/src/imagination/vulkan/winsys/powervr/pvr_drm_bo.h +++ b/src/imagination/vulkan/winsys/powervr/pvr_drm_bo.h @@ -67,8 +67,8 @@ void pvr_drm_winsys_buffer_destroy(struct pvr_winsys_bo *bo); VkResult pvr_drm_winsys_buffer_get_fd(struct pvr_winsys_bo *bo, int *const fd_out); -VkResult pvr_drm_winsys_buffer_map(struct pvr_winsys_bo *bo); -void pvr_drm_winsys_buffer_unmap(struct pvr_winsys_bo *bo); +VkResult pvr_drm_winsys_buffer_map(struct pvr_winsys_bo *bo, void *addr); +VkResult pvr_drm_winsys_buffer_unmap(struct pvr_winsys_bo *bo, bool reserve); VkResult pvr_drm_heap_alloc_carveout(struct pvr_winsys_heap *const heap, const pvr_dev_addr_t carveout_dev_addr, diff --git a/src/imagination/vulkan/winsys/pvr_winsys.h b/src/imagination/vulkan/winsys/pvr_winsys.h index 955faba0383..ca16f067e18 100644 --- a/src/imagination/vulkan/winsys/pvr_winsys.h +++ b/src/imagination/vulkan/winsys/pvr_winsys.h @@ -370,7 +370,7 @@ struct pvr_winsys_ops { VkResult (*buffer_get_fd)(struct pvr_winsys_bo *bo, int *const fd_out); VkResult (*buffer_map)(struct pvr_winsys_bo *bo, void *addr); - void (*buffer_unmap)(struct pvr_winsys_bo *bo); + VkResult (*buffer_unmap)(struct pvr_winsys_bo *bo, bool reserve); VkResult (*heap_alloc)(struct pvr_winsys_heap *heap, uint64_t size, diff --git a/src/imagination/vulkan/winsys/pvr_winsys_helper.c b/src/imagination/vulkan/winsys/pvr_winsys_helper.c index b59c4c84c7f..9e9888edeae 100644 --- a/src/imagination/vulkan/winsys/pvr_winsys_helper.c +++ b/src/imagination/vulkan/winsys/pvr_winsys_helper.c @@ -342,17 +342,17 @@ pvr_winsys_helper_fill_static_memory(struct pvr_winsys *const ws, pvr_setup_static_pixel_event_program(pds_vma->bo->map, pds_vma->heap->static_data_offsets.eot); - ws->ops->buffer_unmap(usc_vma->bo); - ws->ops->buffer_unmap(pds_vma->bo); - ws->ops->buffer_unmap(general_vma->bo); + ws->ops->buffer_unmap(usc_vma->bo, false); + ws->ops->buffer_unmap(pds_vma->bo, false); + ws->ops->buffer_unmap(general_vma->bo, false); return VK_SUCCESS; err_pvr_srv_winsys_buffer_unmap_pds: - ws->ops->buffer_unmap(pds_vma->bo); + ws->ops->buffer_unmap(pds_vma->bo, false); err_pvr_srv_winsys_buffer_unmap_general: - ws->ops->buffer_unmap(general_vma->bo); + ws->ops->buffer_unmap(general_vma->bo, false); err_out: return result; diff --git a/src/imagination/vulkan/winsys/pvr_winsys_helper.h b/src/imagination/vulkan/winsys/pvr_winsys_helper.h index ea4a2b55162..d975be166ba 100644 --- a/src/imagination/vulkan/winsys/pvr_winsys_helper.h +++ b/src/imagination/vulkan/winsys/pvr_winsys_helper.h @@ -108,8 +108,29 @@ static inline VkResult pvr_mmap(void *addr, return VK_SUCCESS; } -static inline VkResult pvr_munmap(void *const addr, const size_t len) +static inline VkResult +pvr_munmap(void *const addr, const size_t len, bool reserve) { + if (reserve) { + void *ret = mmap(addr, + len, + PROT_NONE, + MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED, + -1, + 0); + + if (ret == MAP_FAILED) { + const int err = errno; + return vk_errorf(NULL, + VK_ERROR_UNKNOWN, + "mmap(reserve) failed (errno %d: %s)", + err, + strerror(err)); + } + + return VK_SUCCESS; + } + const int ret = munmap(addr, len); if (ret) { const int err = errno; diff --git a/src/imagination/vulkan/winsys/pvrsrvkm/pvr_srv_bo.c b/src/imagination/vulkan/winsys/pvrsrvkm/pvr_srv_bo.c index d0da258a4b6..d454e3bfcfe 100644 --- a/src/imagination/vulkan/winsys/pvrsrvkm/pvr_srv_bo.c +++ b/src/imagination/vulkan/winsys/pvrsrvkm/pvr_srv_bo.c @@ -329,9 +329,10 @@ VkResult pvr_srv_winsys_buffer_map(struct pvr_winsys_bo *bo, void *addr) return VK_SUCCESS; } -void pvr_srv_winsys_buffer_unmap(struct pvr_winsys_bo *bo) +VkResult pvr_srv_winsys_buffer_unmap(struct pvr_winsys_bo *bo, bool reserve) { struct pvr_srv_winsys_bo *srv_bo = to_pvr_srv_winsys_bo(bo); + VkResult result; /* output error if trying to unmap memory that is not previously mapped */ assert(bo->map); @@ -339,11 +340,13 @@ void pvr_srv_winsys_buffer_unmap(struct pvr_winsys_bo *bo) VG(VALGRIND_FREELIKE_BLOCK(bo->map, 0)); /* Unmap the whole PMR from CPU space */ - pvr_munmap(bo->map, bo->size); + result = pvr_munmap(bo->map, bo->size, reserve); bo->map = NULL; buffer_release(srv_bo); + + return result; } /* This function must be used to allocate from a heap carveout and must only be diff --git a/src/imagination/vulkan/winsys/pvrsrvkm/pvr_srv_bo.h b/src/imagination/vulkan/winsys/pvrsrvkm/pvr_srv_bo.h index 86bc257c521..5fd7f3d5a83 100644 --- a/src/imagination/vulkan/winsys/pvrsrvkm/pvr_srv_bo.h +++ b/src/imagination/vulkan/winsys/pvrsrvkm/pvr_srv_bo.h @@ -155,8 +155,8 @@ void pvr_srv_winsys_buffer_destroy(struct pvr_winsys_bo *bo); VkResult pvr_srv_winsys_buffer_get_fd(struct pvr_winsys_bo *bo, int *const fd_out); -VkResult pvr_srv_winsys_buffer_map(struct pvr_winsys_bo *bo); -void pvr_srv_winsys_buffer_unmap(struct pvr_winsys_bo *bo); +VkResult pvr_srv_winsys_buffer_map(struct pvr_winsys_bo *bo, void *addr); +VkResult pvr_srv_winsys_buffer_unmap(struct pvr_winsys_bo *bo, bool reserve); VkResult pvr_srv_heap_alloc_carveout(struct pvr_winsys_heap *heap, const pvr_dev_addr_t carveout_dev_addr,