nvk: Implement VK_EXT_map_memory_placed

Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/27599>
This commit is contained in:
Faith Ekstrand
2024-02-13 12:03:16 -06:00
committed by Marge Bot
parent 4092685057
commit 19cd3bb721
3 changed files with 39 additions and 2 deletions

View File

@@ -282,6 +282,13 @@ nvk_MapMemory2KHR(VkDevice device,
vk_device_memory_range(&mem->vk, pMemoryMapInfo->offset,
pMemoryMapInfo->size);
void *fixed_addr = NULL;
if (pMemoryMapInfo->flags & VK_MEMORY_MAP_PLACED_BIT_EXT) {
const VkMemoryMapPlacedInfoEXT *placed_info =
vk_find_struct_const(pMemoryMapInfo->pNext, MEMORY_MAP_PLACED_INFO_EXT);
fixed_addr = placed_info->pPlacedAddress;
}
/* From the Vulkan spec version 1.0.32 docs for MapMemory:
*
* * If size is not equal to VK_WHOLE_SIZE, size must be greater than 0
@@ -307,7 +314,7 @@ nvk_MapMemory2KHR(VkDevice device,
"Memory object already mapped.");
}
mem->map = nouveau_ws_bo_map(mem->bo, NOUVEAU_WS_BO_RDWR, NULL);
mem->map = nouveau_ws_bo_map(mem->bo, NOUVEAU_WS_BO_RDWR, fixed_addr);
if (mem->map == NULL) {
return vk_errorf(dev, VK_ERROR_MEMORY_MAP_FAILED,
"Memory object couldn't be mapped.");
@@ -322,12 +329,22 @@ VKAPI_ATTR VkResult VKAPI_CALL
nvk_UnmapMemory2KHR(VkDevice device,
const VkMemoryUnmapInfoKHR *pMemoryUnmapInfo)
{
VK_FROM_HANDLE(nvk_device, dev, device);
VK_FROM_HANDLE(nvk_device_memory, mem, pMemoryUnmapInfo->memory);
if (mem == NULL)
return VK_SUCCESS;
nouveau_ws_bo_unmap(mem->bo, mem->map);
if (pMemoryUnmapInfo->flags & VK_MEMORY_UNMAP_RESERVE_BIT_EXT) {
int err = nouveau_ws_bo_overmap(mem->bo, mem->map);
if (err) {
return vk_errorf(dev, VK_ERROR_MEMORY_MAP_FAILED,
"Failed to map over original mapping");
}
} else {
nouveau_ws_bo_unmap(mem->bo, mem->map);
}
mem->map = NULL;
return VK_SUCCESS;

View File

@@ -176,6 +176,7 @@ nvk_get_device_extensions(const struct nvk_instance *instance,
.EXT_inline_uniform_block = true,
.EXT_line_rasterization = true,
.EXT_load_store_op_none = true,
.EXT_map_memory_placed = true,
.EXT_multi_draw = true,
.EXT_mutable_descriptor_type = true,
.EXT_non_seamless_cube_map = true,
@@ -470,6 +471,11 @@ nvk_get_device_features(const struct nv_device_info *info,
.stippledBresenhamLines = true,
.stippledSmoothLines = true,
/* VK_EXT_map_memory_placed */
.memoryMapPlaced = true,
.memoryMapRangePlaced = false,
.memoryUnmapReserve = true,
/* VK_EXT_multi_draw */
.multiDraw = true,
@@ -550,6 +556,9 @@ nvk_get_device_properties(const struct nvk_instance *instance,
VK_SAMPLE_COUNT_4_BIT |
VK_SAMPLE_COUNT_8_BIT;
uint64_t os_page_size = 4096;
os_get_page_size(&os_page_size);
*properties = (struct vk_properties) {
.apiVersion = nvk_get_vk_version(info),
.driverVersion = vk_get_driver_version(),
@@ -785,6 +794,9 @@ nvk_get_device_properties(const struct nvk_instance *instance,
/* VK_KHR_line_rasterization */
.lineSubPixelPrecisionBits = 8,
/* VK_EXT_map_memory_placed */
.minPlacedMemoryMapAlignment = os_page_size,
/* VK_EXT_multi_draw */
.maxMultiDrawCount = UINT32_MAX,

View File

@@ -89,6 +89,14 @@ nouveau_ws_bo_unmap(struct nouveau_ws_bo *bo, void *ptr)
munmap(ptr, bo->size);
}
static inline int
nouveau_ws_bo_overmap(struct nouveau_ws_bo *bo, void *ptr)
{
void *map = mmap(ptr, bo->size, PROT_NONE,
MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED, -1, 0);
return map == MAP_FAILED ? -1 : 0;
}
#ifdef __cplusplus
}
#endif