From e6b752ff62aabd3d3f19d807ae2386d173a36e8e Mon Sep 17 00:00:00 2001 From: Matt Coster Date: Tue, 16 Aug 2022 11:07:24 +0100 Subject: [PATCH] pvr: Add pvr_bo_cpu_map_unchanged() helper to load saved vbits on map When HAVE_VALGRIND is set, vbits of the CPU mapping are stored when pvr_bo_cpu_unmap() is called. They can be reloaded by calling pvr_bo_cpu_map_unchanged() instead of pvr_bo_cpu_map(). The vbits are not loaded by default on every map, since they could easily have been changed by the device between the unmap/map calls. Only use pvr_bo_cpu_map_unchanged() when you can safely assume that nothing has changed in the underlying memory. When HAVE_VALGRIND is not set, pvr_bo_cpu_map_unchanged() just inlines to pvr_bo_cpu_map(). Signed-off-by: Matt Coster Reviewed-by: Karmjit Mahil Part-of: --- src/imagination/vulkan/pvr_bo.c | 34 ++++++++++++++++++++-- src/imagination/vulkan/pvr_bo.h | 11 +++++++ src/imagination/vulkan/winsys/pvr_winsys.h | 4 +++ 3 files changed, 47 insertions(+), 2 deletions(-) diff --git a/src/imagination/vulkan/pvr_bo.c b/src/imagination/vulkan/pvr_bo.c index 315c2a36d461c..04350b280abf7 100644 --- a/src/imagination/vulkan/pvr_bo.c +++ b/src/imagination/vulkan/pvr_bo.c @@ -171,8 +171,23 @@ void *pvr_bo_cpu_map(struct pvr_device *device, struct pvr_bo *pvr_bo) */ void pvr_bo_cpu_unmap(struct pvr_device *device, struct pvr_bo *pvr_bo) { - assert(pvr_bo->bo->map); - device->ws->ops->buffer_unmap(pvr_bo->bo); + struct pvr_winsys_bo *bo = pvr_bo->bo; + + assert(bo->map); + +#if defined(HAVE_VALGRIND) + if (!bo->vbits) + bo->vbits = vk_alloc(&device->vk.alloc, + bo->size, + 8, + VK_SYSTEM_ALLOCATION_SCOPE_OBJECT); + if (bo->vbits) + VALGRIND_GET_VBITS(bo->map, bo->vbits, bo->size); + else + mesa_loge("Failed to alloc vbits storage; expect bad valgrind results."); +#endif /* defined(HAVE_VALGRIND) */ + + device->ws->ops->buffer_unmap(bo); } /** @@ -188,6 +203,10 @@ void pvr_bo_free(struct pvr_device *device, struct pvr_bo *pvr_bo) if (!pvr_bo) return; +#if defined(HAVE_VALGRIND) + vk_free(&device->vk.alloc, pvr_bo->bo->vbits); +#endif /* defined(HAVE_VALGRIND) */ + device->ws->ops->vma_unmap(pvr_bo->vma); device->ws->ops->heap_free(pvr_bo->vma); @@ -198,3 +217,14 @@ void pvr_bo_free(struct pvr_device *device, struct pvr_bo *pvr_bo) vk_free(&device->vk.alloc, pvr_bo); } + +#if defined(HAVE_VALGRIND) +void *pvr_bo_cpu_map_unchanged(struct pvr_device *device, struct pvr_bo *pvr_bo) +{ + void *ret = pvr_bo_cpu_map(device, pvr_bo); + if (ret) + VALGRIND_SET_VBITS(pvr_bo->bo->map, pvr_bo->bo->vbits, pvr_bo->bo->size); + + return ret; +} +#endif /* defined(HAVE_VALGRIND) */ diff --git a/src/imagination/vulkan/pvr_bo.h b/src/imagination/vulkan/pvr_bo.h index 4f3565bf6ebd9..bc7fe32b5e424 100644 --- a/src/imagination/vulkan/pvr_bo.h +++ b/src/imagination/vulkan/pvr_bo.h @@ -87,4 +87,15 @@ void *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); +#if defined(HAVE_VALGRIND) +void *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) +{ + return pvr_bo_cpu_map(device, pvr_bo); +} +#endif /* defined(HAVE_VALGRIND) */ + #endif /* PVR_BO_H */ diff --git a/src/imagination/vulkan/winsys/pvr_winsys.h b/src/imagination/vulkan/winsys/pvr_winsys.h index 3013b21e5c043..aa62275fd6f17 100644 --- a/src/imagination/vulkan/winsys/pvr_winsys.h +++ b/src/imagination/vulkan/winsys/pvr_winsys.h @@ -121,6 +121,10 @@ struct pvr_winsys_bo { uint64_t size; bool is_imported; + +#if defined(HAVE_VALGRIND) + char *vbits; +#endif /* defined(HAVE_VALGRIND) */ }; struct pvr_winsys_vma {