From c05dd048981f4003780b31405e5528a49a91179c Mon Sep 17 00:00:00 2001 From: Matt Coster Date: Fri, 28 Apr 2023 14:57:26 +0100 Subject: [PATCH] pvr: Return VkResult from winsys buffer_map operation This allows VK_ERROR_MEMORY_MAP_FAILED to propagate correctly. Signed-off-by: Matt Coster Reviewed-by: Frank Binns Part-of: --- src/imagination/vulkan/pvr_bo.c | 19 +++++---- src/imagination/vulkan/pvr_bo.h | 10 ++--- src/imagination/vulkan/pvr_device.c | 10 ++--- src/imagination/vulkan/pvr_dump_bo.c | 2 +- src/imagination/vulkan/winsys/pvr_winsys.h | 2 +- .../vulkan/winsys/pvr_winsys_helper.c | 25 +++++------- .../vulkan/winsys/pvr_winsys_helper.h | 40 +++++++++++++++++++ .../vulkan/winsys/pvrsrvkm/pvr_srv_bo.c | 25 ++++++------ .../vulkan/winsys/pvrsrvkm/pvr_srv_bo.h | 2 +- 9 files changed, 83 insertions(+), 52 deletions(-) diff --git a/src/imagination/vulkan/pvr_bo.c b/src/imagination/vulkan/pvr_bo.c index c77fbd46e78..cce1ae5eaaf 100644 --- a/src/imagination/vulkan/pvr_bo.c +++ b/src/imagination/vulkan/pvr_bo.c @@ -370,14 +370,12 @@ VkResult pvr_bo_alloc(struct pvr_device *device, goto err_free_bo; if (flags & PVR_BO_ALLOC_FLAG_CPU_MAPPED) { - void *map = device->ws->ops->buffer_map(pvr_bo->bo); - if (!map) { - result = VK_ERROR_MEMORY_MAP_FAILED; + result = device->ws->ops->buffer_map(pvr_bo->bo); + if (result != VK_SUCCESS) goto err_buffer_destroy; - } if (flags & PVR_BO_ALLOC_FLAG_ZERO_ON_ALLOC) - VG(VALGRIND_MAKE_MEM_DEFINED(map, pvr_bo->bo->size)); + VG(VALGRIND_MAKE_MEM_DEFINED(pvr_bo->bo->map, pvr_bo->bo->size)); } result = device->ws->ops->heap_alloc(heap, size, alignment, &pvr_bo->vma); @@ -423,7 +421,7 @@ err_out: * * \sa #pvr_bo_alloc(), #PVR_BO_ALLOC_FLAG_CPU_MAPPED */ -void *pvr_bo_cpu_map(struct pvr_device *device, struct pvr_bo *pvr_bo) +VkResult pvr_bo_cpu_map(struct pvr_device *device, struct pvr_bo *pvr_bo) { assert(!pvr_bo->bo->map); @@ -706,10 +704,11 @@ void *pvr_bo_suballoc_get_map_addr(const struct pvr_suballoc_bo *suballoc_bo) } #if defined(HAVE_VALGRIND) -void *pvr_bo_cpu_map_unchanged(struct pvr_device *device, struct pvr_bo *pvr_bo) +VkResult pvr_bo_cpu_map_unchanged(struct pvr_device *device, + struct pvr_bo *pvr_bo) { - void *map = pvr_bo_cpu_map(device, pvr_bo); - if (map) { + VkResult result = pvr_bo_cpu_map(device, pvr_bo); + if (result == VK_SUCCESS) { unsigned ret = VALGRIND_SET_VBITS(pvr_bo->bo->map, pvr_bo->bo->vbits, pvr_bo->bo->size); @@ -717,6 +716,6 @@ void *pvr_bo_cpu_map_unchanged(struct pvr_device *device, struct pvr_bo *pvr_bo) mesa_loge("Failed to set vbits; expect bad valgrind results."); } - return map; + return result; } #endif /* defined(HAVE_VALGRIND) */ diff --git a/src/imagination/vulkan/pvr_bo.h b/src/imagination/vulkan/pvr_bo.h index 80d24e54419..296dcc8ca4d 100644 --- a/src/imagination/vulkan/pvr_bo.h +++ b/src/imagination/vulkan/pvr_bo.h @@ -128,7 +128,7 @@ VkResult pvr_bo_alloc(struct pvr_device *device, uint64_t alignment, uint64_t flags, struct pvr_bo **const bo_out); -void *pvr_bo_cpu_map(struct pvr_device *device, struct pvr_bo *bo); +VkResult pvr_bo_cpu_map(struct pvr_device *device, struct pvr_bo *bo); void pvr_bo_cpu_unmap(struct pvr_device *device, struct pvr_bo *bo); void pvr_bo_free(struct pvr_device *device, struct pvr_bo *bo); @@ -146,11 +146,11 @@ void pvr_bo_suballoc_free(struct pvr_suballoc_bo *suballoc_bo); void *pvr_bo_suballoc_get_map_addr(const struct pvr_suballoc_bo *suballoc_bo); #if defined(HAVE_VALGRIND) -void *pvr_bo_cpu_map_unchanged(struct pvr_device *device, - struct pvr_bo *pvr_bo); +VkResult pvr_bo_cpu_map_unchanged(struct pvr_device *device, + struct pvr_bo *pvr_bo); #else /* defined(HAVE_VALGRIND) */ -static ALWAYS_INLINE void *pvr_bo_cpu_map_unchanged(struct pvr_device *device, - struct pvr_bo *pvr_bo) +static ALWAYS_INLINE VkResult +pvr_bo_cpu_map_unchanged(struct pvr_device *device, struct pvr_bo *pvr_bo) { return pvr_bo_cpu_map(device, pvr_bo); } diff --git a/src/imagination/vulkan/pvr_device.c b/src/imagination/vulkan/pvr_device.c index 8198d2d0253..cd898b451ee 100644 --- a/src/imagination/vulkan/pvr_device.c +++ b/src/imagination/vulkan/pvr_device.c @@ -2184,7 +2184,7 @@ VkResult pvr_MapMemory(VkDevice _device, { PVR_FROM_HANDLE(pvr_device, device, _device); PVR_FROM_HANDLE(pvr_device_memory, mem, _memory); - void *map; + VkResult result; if (!mem) { *ppData = NULL; @@ -2212,11 +2212,11 @@ VkResult pvr_MapMemory(VkDevice _device, } /* Map it all at once */ - map = device->ws->ops->buffer_map(mem->bo); - if (!map) - return vk_error(device, VK_ERROR_MEMORY_MAP_FAILED); + result = device->ws->ops->buffer_map(mem->bo); + if (result != VK_SUCCESS) + return result; - *ppData = map + offset; + *ppData = mem->bo->map + offset; return VK_SUCCESS; } diff --git a/src/imagination/vulkan/pvr_dump_bo.c b/src/imagination/vulkan/pvr_dump_bo.c index 89d1225d51d..e563aa715f0 100644 --- a/src/imagination/vulkan/pvr_dump_bo.c +++ b/src/imagination/vulkan/pvr_dump_bo.c @@ -40,7 +40,7 @@ bool pvr_dump_bo_ctx_push(struct pvr_dump_bo_ctx *const ctx, bool did_map_bo = false; if (!bo->bo->map) { - if (!pvr_bo_cpu_map_unchanged(device, bo)) + if (pvr_bo_cpu_map_unchanged(device, bo) != VK_SUCCESS) goto err_out; did_map_bo = true; diff --git a/src/imagination/vulkan/winsys/pvr_winsys.h b/src/imagination/vulkan/winsys/pvr_winsys.h index 23afbf8b746..259f01d90d8 100644 --- a/src/imagination/vulkan/winsys/pvr_winsys.h +++ b/src/imagination/vulkan/winsys/pvr_winsys.h @@ -408,7 +408,7 @@ struct pvr_winsys_ops { VkResult (*buffer_get_fd)(struct pvr_winsys_bo *bo, int *const fd_out); - void *(*buffer_map)(struct pvr_winsys_bo *bo); + VkResult (*buffer_map)(struct pvr_winsys_bo *bo); void (*buffer_unmap)(struct pvr_winsys_bo *bo); VkResult (*heap_alloc)(struct pvr_winsys_heap *heap, diff --git a/src/imagination/vulkan/winsys/pvr_winsys_helper.c b/src/imagination/vulkan/winsys/pvr_winsys_helper.c index b488c2adc56..74c2cc8daca 100644 --- a/src/imagination/vulkan/winsys/pvr_winsys_helper.c +++ b/src/imagination/vulkan/winsys/pvr_winsys_helper.c @@ -318,33 +318,26 @@ pvr_winsys_helper_fill_static_memory(struct pvr_winsys *const ws, struct pvr_winsys_vma *const pds_vma, struct pvr_winsys_vma *const usc_vma) { - uint8_t *general_ptr, *pds_ptr, *usc_ptr; VkResult result; - general_ptr = ws->ops->buffer_map(general_vma->bo); - if (!general_ptr) { - result = VK_ERROR_MEMORY_MAP_FAILED; + result = ws->ops->buffer_map(general_vma->bo); + if (result != VK_SUCCESS) goto err_out; - } - pds_ptr = ws->ops->buffer_map(pds_vma->bo); - if (!pds_ptr) { - result = VK_ERROR_MEMORY_MAP_FAILED; + result = ws->ops->buffer_map(pds_vma->bo); + if (result != VK_SUCCESS) goto err_pvr_srv_winsys_buffer_unmap_general; - } - usc_ptr = ws->ops->buffer_map(usc_vma->bo); - if (!usc_ptr) { - result = VK_ERROR_MEMORY_MAP_FAILED; + result = ws->ops->buffer_map(usc_vma->bo); + if (result != VK_SUCCESS) goto err_pvr_srv_winsys_buffer_unmap_pds; - } - pvr_setup_static_vdm_sync(pds_ptr, + pvr_setup_static_vdm_sync(pds_vma->bo->map, pds_vma->heap->static_data_offsets.vdm_sync, - usc_ptr, + usc_vma->bo->map, usc_vma->heap->static_data_offsets.vdm_sync); - pvr_setup_static_pixel_event_program(pds_ptr, + pvr_setup_static_pixel_event_program(pds_vma->bo->map, pds_vma->heap->static_data_offsets.eot); ws->ops->buffer_unmap(usc_vma->bo); diff --git a/src/imagination/vulkan/winsys/pvr_winsys_helper.h b/src/imagination/vulkan/winsys/pvr_winsys_helper.h index 2960eef0123..79ab8d1b1db 100644 --- a/src/imagination/vulkan/winsys/pvr_winsys_helper.h +++ b/src/imagination/vulkan/winsys/pvr_winsys_helper.h @@ -26,8 +26,11 @@ #include #include +#include #include #include +#include +#include #include #include "pvr_types.h" @@ -79,6 +82,43 @@ pvr_winsys_helper_fill_static_memory(struct pvr_winsys *const ws, struct pvr_winsys_vma *const pds_vma, struct pvr_winsys_vma *const usc_vma); +static inline VkResult pvr_mmap(const size_t len, + const int prot, + const int flags, + const int fd, + const off_t offset, + void **const map_out) +{ + void *const map = mmap(NULL, len, prot, flags, fd, offset); + if (map == MAP_FAILED) { + const int err = errno; + return vk_errorf(NULL, + VK_ERROR_MEMORY_MAP_FAILED, + "mmap failed (errno %d: %s)", + err, + strerror(err)); + } + + *map_out = map; + + return VK_SUCCESS; +} + +static inline VkResult pvr_munmap(void *const addr, const size_t len) +{ + const int ret = munmap(addr, len); + if (ret) { + const int err = errno; + return vk_errorf(NULL, + VK_ERROR_UNKNOWN, + "munmap failed (errno %d: %s)", + err, + strerror(err)); + } + + return VK_SUCCESS; +} + #define pvr_ioctlf(fd, request, arg, error, fmt, args...) \ ({ \ VkResult _result = VK_SUCCESS; \ diff --git a/src/imagination/vulkan/winsys/pvrsrvkm/pvr_srv_bo.c b/src/imagination/vulkan/winsys/pvrsrvkm/pvr_srv_bo.c index 62c8d6cc910..8eea994ae17 100644 --- a/src/imagination/vulkan/winsys/pvrsrvkm/pvr_srv_bo.c +++ b/src/imagination/vulkan/winsys/pvrsrvkm/pvr_srv_bo.c @@ -299,28 +299,28 @@ VkResult pvr_srv_winsys_buffer_get_fd(struct pvr_winsys_bo *bo, return VK_SUCCESS; } -void *pvr_srv_winsys_buffer_map(struct pvr_winsys_bo *bo) +VkResult pvr_srv_winsys_buffer_map(struct pvr_winsys_bo *bo) { struct pvr_srv_winsys_bo *srv_bo = to_pvr_srv_winsys_bo(bo); struct pvr_winsys *ws = bo->ws; const int prot = (srv_bo->flags & PVR_SRV_MEMALLOCFLAG_CPU_WRITEABLE ? PROT_WRITE : 0) | (srv_bo->flags & PVR_SRV_MEMALLOCFLAG_CPU_READABLE ? PROT_READ : 0); + VkResult result; /* assert if memory is already mapped */ assert(!bo->map); /* Map the full PMR to CPU space */ - bo->map = mmap(NULL, - bo->size, - prot, - MAP_SHARED, - ws->render_fd, - (off_t)srv_bo->pmr << ws->log2_page_size); - if (bo->map == MAP_FAILED) { + result = pvr_mmap(bo->size, + prot, + MAP_SHARED, + ws->render_fd, + (off_t)srv_bo->pmr << ws->log2_page_size, + &bo->map); + if (result != VK_SUCCESS) { bo->map = NULL; - vk_error(NULL, VK_ERROR_MEMORY_MAP_FAILED); - return NULL; + return result; } VG(VALGRIND_MALLOCLIKE_BLOCK(bo->map, @@ -331,7 +331,7 @@ void *pvr_srv_winsys_buffer_map(struct pvr_winsys_bo *bo) buffer_acquire(srv_bo); - return bo->map; + return VK_SUCCESS; } void pvr_srv_winsys_buffer_unmap(struct pvr_winsys_bo *bo) @@ -344,8 +344,7 @@ 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 */ - if (munmap(bo->map, bo->size)) - vk_error(NULL, VK_ERROR_UNKNOWN); + pvr_munmap(bo->map, bo->size); bo->map = NULL; diff --git a/src/imagination/vulkan/winsys/pvrsrvkm/pvr_srv_bo.h b/src/imagination/vulkan/winsys/pvrsrvkm/pvr_srv_bo.h index d20f231c163..5fe6ad4df71 100644 --- a/src/imagination/vulkan/winsys/pvrsrvkm/pvr_srv_bo.h +++ b/src/imagination/vulkan/winsys/pvrsrvkm/pvr_srv_bo.h @@ -156,7 +156,7 @@ 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); -void *pvr_srv_winsys_buffer_map(struct pvr_winsys_bo *bo); +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_heap_alloc_reserved(struct pvr_winsys_heap *heap,