diff --git a/src/nouveau/vulkan/nvk_device_memory.c b/src/nouveau/vulkan/nvk_device_memory.c index 522da85a135..9d0d6e48e05 100644 --- a/src/nouveau/vulkan/nvk_device_memory.c +++ b/src/nouveau/vulkan/nvk_device_memory.c @@ -279,7 +279,8 @@ nvk_MapMemory2KHR(VkDevice device, vk_device_memory_range(&mem->vk, pMemoryMapInfo->offset, pMemoryMapInfo->size); - enum nvkmd_mem_map_flags map_flags = NVKMD_MEM_MAP_RDWR; + enum nvkmd_mem_map_flags map_flags = NVKMD_MEM_MAP_CLIENT | + NVKMD_MEM_MAP_RDWR; void *fixed_addr = NULL; if (pMemoryMapInfo->flags & VK_MEMORY_MAP_PLACED_BIT_EXT) { @@ -315,7 +316,8 @@ nvk_MapMemory2KHR(VkDevice device, } void *mem_map; - result = nvkmd_mem_map(mem->mem, &mem->vk.base, map_flags, fixed_addr, &mem_map); + result = nvkmd_mem_map(mem->mem, &mem->vk.base, map_flags, + fixed_addr, &mem_map); if (result != VK_SUCCESS) return result; @@ -334,9 +336,9 @@ nvk_UnmapMemory2KHR(VkDevice device, return VK_SUCCESS; if (pMemoryUnmapInfo->flags & VK_MEMORY_UNMAP_RESERVE_BIT_EXT) { - return nvkmd_mem_overmap(mem->mem, &mem->vk.base, 0); + return nvkmd_mem_overmap(mem->mem, &mem->vk.base, NVKMD_MEM_MAP_CLIENT); } else { - nvkmd_mem_unmap(mem->mem, 0); + nvkmd_mem_unmap(mem->mem, NVKMD_MEM_MAP_CLIENT); return VK_SUCCESS; } } diff --git a/src/nouveau/vulkan/nvkmd/nvkmd.c b/src/nouveau/vulkan/nvkmd/nvkmd.c index 7885a96d592..60aa5abe02f 100644 --- a/src/nouveau/vulkan/nvkmd/nvkmd.c +++ b/src/nouveau/vulkan/nvkmd/nvkmd.c @@ -207,6 +207,9 @@ nvkmd_mem_unref(struct nvkmd_mem *mem) if (!p_atomic_dec_zero(&mem->refcnt)) return; + if (mem->client_map != NULL) + mem->ops->unmap(mem, NVKMD_MEM_MAP_CLIENT, mem->client_map); + if (mem->map != NULL) mem->ops->unmap(mem, 0, mem->map); @@ -218,14 +221,27 @@ nvkmd_mem_map(struct nvkmd_mem *mem, struct vk_object_base *log_obj, enum nvkmd_mem_map_flags flags, void *fixed_addr, void **map_out) { - assert(mem->map == NULL); - void *map = NULL; - VkResult result = mem->ops->map(mem, log_obj, flags, fixed_addr, &map); - if (result != VK_SUCCESS) - return result; - mem->map = map; + if (flags & NVKMD_MEM_MAP_CLIENT) { + assert(mem->client_map == NULL); + + VkResult result = mem->ops->map(mem, log_obj, flags, fixed_addr, &map); + if (result != VK_SUCCESS) + return result; + + mem->client_map = map; + } else { + assert(!(flags & NVKMD_MEM_MAP_FIXED)); + assert(mem->map == NULL); + + VkResult result = mem->ops->map(mem, log_obj, flags, fixed_addr, &map); + if (result != VK_SUCCESS) + return result; + + mem->map = map; + } + if (map_out != NULL) *map_out = map; @@ -235,7 +251,13 @@ nvkmd_mem_map(struct nvkmd_mem *mem, struct vk_object_base *log_obj, void nvkmd_mem_unmap(struct nvkmd_mem *mem, enum nvkmd_mem_map_flags flags) { - assert(mem->map != NULL); - mem->ops->unmap(mem, flags, mem->map); - mem->map = NULL; + if (flags & NVKMD_MEM_MAP_CLIENT) { + assert(mem->client_map != NULL); + mem->ops->unmap(mem, flags, mem->client_map); + mem->client_map = NULL; + } else { + assert(mem->map != NULL); + mem->ops->unmap(mem, flags, mem->map); + mem->map = NULL; + } } diff --git a/src/nouveau/vulkan/nvkmd/nvkmd.h b/src/nouveau/vulkan/nvkmd/nvkmd.h index a73289d5a39..c2eb4159668 100644 --- a/src/nouveau/vulkan/nvkmd/nvkmd.h +++ b/src/nouveau/vulkan/nvkmd/nvkmd.h @@ -57,7 +57,16 @@ enum nvkmd_mem_map_flags { NVKMD_MEM_MAP_RD = 1 << 0, NVKMD_MEM_MAP_WR = 1 << 1, NVKMD_MEM_MAP_RDWR = NVKMD_MEM_MAP_RD | NVKMD_MEM_MAP_WR, - NVKMD_MEM_MAP_FIXED = 1 << 2, + + /** Create a client mapping + * + * This sets nvkmd_mem::client_map instead of nvkmd_mem::map. These + * mappings may be different from internal mappings. Only client mappings + * can be used with MAP_FIXED or unmapped with nvkmd_mem_overmap(). + */ + NVKMD_MEM_MAP_CLIENT = 1 << 2, + + NVKMD_MEM_MAP_FIXED = 1 << 3, }; enum nvkmd_va_flags { @@ -222,6 +231,7 @@ struct nvkmd_mem { uint64_t size_B; struct nvkmd_va *va; void *map; + void *client_map; }; void nvkmd_mem_init(struct nvkmd_dev *dev, @@ -467,10 +477,13 @@ static inline VkResult MUST_CHECK nvkmd_mem_overmap(struct nvkmd_mem *mem, struct vk_object_base *log_obj, enum nvkmd_mem_map_flags flags) { - assert(mem->map != NULL); - VkResult result = mem->ops->overmap(mem, log_obj, flags, mem->map); + assert(flags & NVKMD_MEM_MAP_CLIENT); + assert(mem->client_map != NULL); + + VkResult result = mem->ops->overmap(mem, log_obj, flags, mem->client_map); if (result == VK_SUCCESS) - mem->map = NULL; + mem->client_map = NULL; + return result; }