pvr: support VK_KHR_map_memory2

Signed-off-by: Simon Perretta <simon.perretta@imgtec.com>
Reviewed-by: Frank Binns <frank.binns@imgtec.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/37726>
This commit is contained in:
Simon Perretta 2025-10-03 11:01:41 +01:00 committed by Marge Bot
parent d0608fd3d6
commit 8dcfbcde52
4 changed files with 43 additions and 31 deletions

View file

@ -521,7 +521,7 @@ Vulkan 1.4 -- all DONE: anv, hk, lvp, nvk, panvk/v10+, radv/gfx8+, tu/a7xx+, vn
VK_KHR_load_store_op_none DONE (anv, lvp, nvk, panvk, radv, tu, v3dv, vn) VK_KHR_load_store_op_none DONE (anv, lvp, nvk, panvk, radv, tu, v3dv, vn)
VK_KHR_maintenance5 DONE (anv, lvp, nvk, panvk/v10+, radv, tu, v3dv, vn) VK_KHR_maintenance5 DONE (anv, lvp, nvk, panvk/v10+, radv, tu, v3dv, vn)
VK_KHR_maintenance6 DONE (anv, lvp, nvk, panvk/v10+, radv, tu, vn) VK_KHR_maintenance6 DONE (anv, lvp, nvk, panvk/v10+, radv, tu, vn)
VK_KHR_map_memory2 DONE (anv, lvp, nvk, panvk, radv, tu, vn) VK_KHR_map_memory2 DONE (anv, lvp, nvk, panvk, pvr, radv, tu, vn)
VK_KHR_push_descriptor DONE (anv, hasvk, lvp, nvk, panvk, radv, tu, vn) VK_KHR_push_descriptor DONE (anv, hasvk, lvp, nvk, panvk, radv, tu, vn)
VK_KHR_shader_expect_assume DONE (anv, dzn, hasvk, lvp, nvk, panvk, pvr, radv, tu, v3dv, vn) VK_KHR_shader_expect_assume DONE (anv, dzn, hasvk, lvp, nvk, panvk, pvr, radv, tu, v3dv, vn)
VK_KHR_shader_float_controls2 DONE (anv, lvp, nvk, panvk/v10+, radv, tu, vn) VK_KHR_shader_float_controls2 DONE (anv, lvp, nvk, panvk/v10+, radv, tu, vn)

View file

@ -80,3 +80,4 @@ VK_KHR_shader_non_semantic_info on pvr
VK_KHR_shader_relaxed_extended_instruction on pvr VK_KHR_shader_relaxed_extended_instruction on pvr
VK_EXT_shader_replicated_composites on pvr VK_EXT_shader_replicated_composites on pvr
VK_KHR_device_group_creation on pvr VK_KHR_device_group_creation on pvr
VK_KHR_map_memory2 on pvr

View file

@ -83,6 +83,7 @@
#include "util/os_misc.h" #include "util/os_misc.h"
#include "util/u_math.h" #include "util/u_math.h"
#include "vk_alloc.h" #include "vk_alloc.h"
#include "vk_device_memory.h"
#include "vk_extensions.h" #include "vk_extensions.h"
#include "vk_log.h" #include "vk_log.h"
#include "vk_object.h" #include "vk_object.h"
@ -205,6 +206,7 @@ static void pvr_physical_device_get_supported_extensions(
.KHR_maintenance1 = true, .KHR_maintenance1 = true,
.KHR_maintenance2 = true, .KHR_maintenance2 = true,
.KHR_maintenance3 = true, .KHR_maintenance3 = true,
.KHR_map_memory2 = true,
.KHR_multiview = true, .KHR_multiview = true,
.KHR_present_id2 = PVR_USE_WSI_PLATFORM, .KHR_present_id2 = PVR_USE_WSI_PLATFORM,
.KHR_present_wait2 = PVR_USE_WSI_PLATFORM, .KHR_present_wait2 = PVR_USE_WSI_PLATFORM,
@ -2591,10 +2593,10 @@ VkResult pvr_AllocateMemory(VkDevice _device,
if (aligned_alloc_size > mem_heap->size) if (aligned_alloc_size > mem_heap->size)
return VK_ERROR_OUT_OF_DEVICE_MEMORY; return VK_ERROR_OUT_OF_DEVICE_MEMORY;
mem = vk_object_alloc(&device->vk, mem = vk_device_memory_create(&device->vk,
pAllocator, pAllocateInfo,
sizeof(*mem), pAllocator,
VK_OBJECT_TYPE_DEVICE_MEMORY); sizeof(*mem));
if (!mem) if (!mem)
return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY); return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
@ -2629,7 +2631,7 @@ VkResult pvr_AllocateMemory(VkDevice _device,
fd_info->fd, fd_info->fd,
&mem->bo); &mem->bo);
if (result != VK_SUCCESS) if (result != VK_SUCCESS)
goto err_vk_object_free_mem; goto err_vk_device_memory_destroy;
/* For security purposes, we reject importing the bo if it's smaller /* For security purposes, we reject importing the bo if it's smaller
* than the requested allocation size. This prevents a malicious client * than the requested allocation size. This prevents a malicious client
@ -2647,7 +2649,7 @@ VkResult pvr_AllocateMemory(VkDevice _device,
pAllocateInfo->allocationSize, pAllocateInfo->allocationSize,
mem->bo->size); mem->bo->size);
device->ws->ops->buffer_destroy(mem->bo); device->ws->ops->buffer_destroy(mem->bo);
goto err_vk_object_free_mem; goto err_vk_device_memory_destroy;
} }
/* From the Vulkan spec: /* From the Vulkan spec:
@ -2681,15 +2683,15 @@ VkResult pvr_AllocateMemory(VkDevice _device,
PVR_WINSYS_BO_FLAG_CPU_ACCESS, PVR_WINSYS_BO_FLAG_CPU_ACCESS,
&mem->bo); &mem->bo);
if (result != VK_SUCCESS) if (result != VK_SUCCESS)
goto err_vk_object_free_mem; goto err_vk_device_memory_destroy;
} }
*pMem = pvr_device_memory_to_handle(mem); *pMem = pvr_device_memory_to_handle(mem);
return VK_SUCCESS; return VK_SUCCESS;
err_vk_object_free_mem: err_vk_device_memory_destroy:
vk_object_free(&device->vk, pAllocator, mem); vk_device_memory_destroy(&device->vk, pAllocator, &mem->vk);
return result; return result;
} }
@ -2754,18 +2756,17 @@ void pvr_FreeMemory(VkDevice _device,
device->ws->ops->buffer_destroy(mem->bo); device->ws->ops->buffer_destroy(mem->bo);
vk_object_free(&device->vk, pAllocator, mem); vk_device_memory_destroy(&device->vk, pAllocator, &mem->vk);
} }
VkResult pvr_MapMemory(VkDevice _device, VkResult pvr_MapMemory2(VkDevice _device,
VkDeviceMemory _memory, const VkMemoryMapInfo *pMemoryMapInfo,
VkDeviceSize offset, void **ppData)
VkDeviceSize size,
VkMemoryMapFlags flags,
void **ppData)
{ {
VK_FROM_HANDLE(pvr_device, device, _device); VK_FROM_HANDLE(pvr_device, device, _device);
VK_FROM_HANDLE(pvr_device_memory, mem, _memory); VK_FROM_HANDLE(pvr_device_memory, mem, pMemoryMapInfo->memory);
VkDeviceSize offset;
VkDeviceSize size;
VkResult result; VkResult result;
if (!mem) { if (!mem) {
@ -2773,8 +2774,8 @@ VkResult pvr_MapMemory(VkDevice _device,
return VK_SUCCESS; return VK_SUCCESS;
} }
if (size == VK_WHOLE_SIZE) offset = pMemoryMapInfo->offset;
size = mem->bo->size - offset; size = vk_device_memory_range(&mem->vk, offset, pMemoryMapInfo->size);
/* From the Vulkan spec version 1.0.32 docs for MapMemory: /* From the Vulkan spec version 1.0.32 docs for MapMemory:
* *
@ -2787,10 +2788,18 @@ VkResult pvr_MapMemory(VkDevice _device,
assert(size > 0); assert(size > 0);
assert(offset + size <= mem->bo->size); assert(offset + size <= mem->bo->size);
/* Check if already mapped */ /* From the Vulkan 1.2.194 spec:
if (mem->bo->map) { *
*ppData = (uint8_t *)mem->bo->map + offset; * "memory must not be currently host mapped"
return VK_SUCCESS; */
if (mem->bo->map != NULL) {
return vk_errorf(device,
VK_ERROR_MEMORY_MAP_FAILED,
"Memory object already mapped.");
}
vk_foreach_struct_const (ext, pMemoryMapInfo->pNext) {
vk_debug_ignored_stype(ext->sType);
} }
/* Map it all at once */ /* Map it all at once */
@ -2803,15 +2812,16 @@ VkResult pvr_MapMemory(VkDevice _device,
return VK_SUCCESS; return VK_SUCCESS;
} }
void pvr_UnmapMemory(VkDevice _device, VkDeviceMemory _memory) VkResult pvr_UnmapMemory2(VkDevice _device,
const VkMemoryUnmapInfo *pMemoryUnmapInfo)
{ {
VK_FROM_HANDLE(pvr_device, device, _device); VK_FROM_HANDLE(pvr_device, device, _device);
VK_FROM_HANDLE(pvr_device_memory, mem, _memory); VK_FROM_HANDLE(pvr_device_memory, mem, pMemoryUnmapInfo->memory);
if (!mem || !mem->bo->map) if (mem && mem->bo->map)
return; device->ws->ops->buffer_unmap(mem->bo);
device->ws->ops->buffer_unmap(mem->bo); return VK_SUCCESS;
} }
VkResult pvr_FlushMappedMemoryRanges(VkDevice _device, VkResult pvr_FlushMappedMemoryRanges(VkDevice _device,

View file

@ -15,6 +15,7 @@
#define PVR_DEVICE_H #define PVR_DEVICE_H
#include "vk_device.h" #include "vk_device.h"
#include "vk_device_memory.h"
#include "vk_instance.h" #include "vk_instance.h"
#include "vk_physical_device.h" #include "vk_physical_device.h"
@ -205,7 +206,7 @@ struct pvr_device {
}; };
struct pvr_device_memory { struct pvr_device_memory {
struct vk_object_base base; struct vk_device_memory vk;
struct pvr_winsys_bo *bo; struct pvr_winsys_bo *bo;
}; };
@ -220,7 +221,7 @@ VK_DEFINE_HANDLE_CASTS(pvr_physical_device,
VK_OBJECT_TYPE_PHYSICAL_DEVICE) VK_OBJECT_TYPE_PHYSICAL_DEVICE)
VK_DEFINE_NONDISP_HANDLE_CASTS(pvr_device_memory, VK_DEFINE_NONDISP_HANDLE_CASTS(pvr_device_memory,
base, vk.base,
VkDeviceMemory, VkDeviceMemory,
VK_OBJECT_TYPE_DEVICE_MEMORY) VK_OBJECT_TYPE_DEVICE_MEMORY)