tu: Implement VK_EXT_map_memory_placed

Signed-off-by: Mark Collins <mark@igalia.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/28928>
This commit is contained in:
Mark Collins
2024-04-25 10:28:49 +00:00
parent 6d2de5b5b0
commit 220dae5870
11 changed files with 53 additions and 37 deletions
+1 -1
View File
@@ -164,7 +164,7 @@ tu_cs_add_bo(struct tu_cs *cs, uint32_t size)
return result; return result;
} }
result = tu_bo_map(cs->device, new_bo); result = tu_bo_map(cs->device, new_bo, NULL);
if (result != VK_SUCCESS) { if (result != VK_SUCCESS) {
tu_bo_finish(cs->device, new_bo); tu_bo_finish(cs->device, new_bo);
return result; return result;
+2 -2
View File
@@ -287,7 +287,7 @@ tu_CreateDescriptorSetLayout(
return vk_error(device, result); return vk_error(device, result);
} }
result = tu_bo_map(device, set_layout->embedded_samplers); result = tu_bo_map(device, set_layout->embedded_samplers, NULL);
if (result != VK_SUCCESS) { if (result != VK_SUCCESS) {
tu_bo_finish(device, set_layout->embedded_samplers); tu_bo_finish(device, set_layout->embedded_samplers);
vk_object_free(&device->vk, pAllocator, set_layout); vk_object_free(&device->vk, pAllocator, set_layout);
@@ -805,7 +805,7 @@ tu_CreateDescriptorPool(VkDevice _device,
if (ret) if (ret)
goto fail_alloc; goto fail_alloc;
ret = tu_bo_map(device, pool->bo); ret = tu_bo_map(device, pool->bo, NULL);
if (ret) if (ret)
goto fail_map; goto fail_map;
} else { } else {
+25 -8
View File
@@ -244,6 +244,7 @@ get_device_extensions(const struct tu_physical_device *device,
.EXT_inline_uniform_block = true, .EXT_inline_uniform_block = true,
.EXT_line_rasterization = true, .EXT_line_rasterization = true,
.EXT_load_store_op_none = true, .EXT_load_store_op_none = true,
.EXT_map_memory_placed = true,
.EXT_memory_budget = true, .EXT_memory_budget = true,
.EXT_multi_draw = true, .EXT_multi_draw = true,
.EXT_mutable_descriptor_type = true, .EXT_mutable_descriptor_type = true,
@@ -554,6 +555,11 @@ tu_get_features(struct tu_physical_device *pdevice,
/* VK_EXT_image_view_min_lod */ /* VK_EXT_image_view_min_lod */
features->minLod = true; features->minLod = true;
/* VK_EXT_map_memory_placed */
features->memoryMapPlaced = true,
features->memoryMapRangePlaced = false,
features->memoryUnmapReserve = true,
/* VK_EXT_multi_draw */ /* VK_EXT_multi_draw */
features->multiDraw = true; features->multiDraw = true;
@@ -1005,6 +1011,11 @@ tu_get_properties(struct tu_physical_device *pdevice,
vk_shaderModuleIdentifierAlgorithmUUID, vk_shaderModuleIdentifierAlgorithmUUID,
sizeof(props->shaderModuleIdentifierAlgorithmUUID)); sizeof(props->shaderModuleIdentifierAlgorithmUUID));
/* VK_EXT_map_memory_placed */
uint64_t os_page_size = 4096;
os_get_page_size(&os_page_size);
props->minPlacedMemoryMapAlignment = os_page_size,
/* VK_EXT_multi_draw */ /* VK_EXT_multi_draw */
props->maxMultiDrawCount = 2048; props->maxMultiDrawCount = 2048;
@@ -1689,7 +1700,7 @@ tu_trace_read_ts(struct u_trace_context *utctx,
tu_device_wait_u_trace(device, submission_data->syncobj); tu_device_wait_u_trace(device, submission_data->syncobj);
} }
if (tu_bo_map(device, bo) != VK_SUCCESS) { if (tu_bo_map(device, bo, NULL) != VK_SUCCESS) {
return U_TRACE_NO_TIMESTAMP; return U_TRACE_NO_TIMESTAMP;
} }
@@ -2325,7 +2336,7 @@ tu_CreateDevice(VkPhysicalDevice physicalDevice,
goto fail_global_bo; goto fail_global_bo;
} }
result = tu_bo_map(device, device->global_bo); result = tu_bo_map(device, device->global_bo, NULL);
if (result != VK_SUCCESS) { if (result != VK_SUCCESS) {
vk_startup_errorf(device->instance, result, "BO map"); vk_startup_errorf(device->instance, result, "BO map");
goto fail_global_bo_map; goto fail_global_bo_map;
@@ -2876,12 +2887,18 @@ tu_MapMemory2KHR(VkDevice _device, const VkMemoryMapInfoKHR *pMemoryMapInfo, voi
return VK_SUCCESS; return VK_SUCCESS;
} }
if (!mem->bo->map) { void *placed_addr = NULL;
result = tu_bo_map(device, mem->bo); if (pMemoryMapInfo->flags & VK_MEMORY_MAP_PLACED_BIT_EXT) {
if (result != VK_SUCCESS) const VkMemoryMapPlacedInfoEXT *placed_info =
return result; vk_find_struct_const(pMemoryMapInfo->pNext, MEMORY_MAP_PLACED_INFO_EXT);
assert(placed_info != NULL);
placed_addr = placed_info->pPlacedAddress;
} }
result = tu_bo_map(device, mem->bo, placed_addr);
if (result != VK_SUCCESS)
return result;
*ppData = (char *) mem->bo->map + pMemoryMapInfo->offset; *ppData = (char *) mem->bo->map + pMemoryMapInfo->offset;
return VK_SUCCESS; return VK_SUCCESS;
} }
@@ -2895,7 +2912,7 @@ tu_UnmapMemory2KHR(VkDevice _device, const VkMemoryUnmapInfoKHR *pMemoryUnmapInf
if (mem == NULL) if (mem == NULL)
return VK_SUCCESS; return VK_SUCCESS;
return tu_bo_unmap(device, mem->bo, false); return tu_bo_unmap(device, mem->bo, pMemoryUnmapInfo->flags & VK_MEMORY_UNMAP_RESERVE_BIT_EXT);
} }
static void static void
@@ -3011,7 +3028,7 @@ tu_CreateEvent(VkDevice _device,
if (result != VK_SUCCESS) if (result != VK_SUCCESS)
goto fail_alloc; goto fail_alloc;
result = tu_bo_map(device, event->bo); result = tu_bo_map(device, event->bo, NULL);
if (result != VK_SUCCESS) if (result != VK_SUCCESS)
goto fail_map; goto fail_map;
+1 -1
View File
@@ -825,7 +825,7 @@ tu_BindImageMemory2(VkDevice _device,
if (image->vk.usage & VK_IMAGE_USAGE_FRAGMENT_DENSITY_MAP_BIT_EXT) { if (image->vk.usage & VK_IMAGE_USAGE_FRAGMENT_DENSITY_MAP_BIT_EXT) {
if (!mem->bo->map) { if (!mem->bo->map) {
VkResult result = tu_bo_map(device, mem->bo); VkResult result = tu_bo_map(device, mem->bo, NULL);
if (result != VK_SUCCESS) if (result != VK_SUCCESS)
return result; return result;
} }
+8 -2
View File
@@ -58,9 +58,15 @@ tu_bo_finish(struct tu_device *dev, struct tu_bo *bo)
} }
VkResult VkResult
tu_bo_map(struct tu_device *dev, struct tu_bo *bo) tu_bo_map(struct tu_device *dev, struct tu_bo *bo, void *placed_addr)
{ {
return dev->instance->knl->bo_map(dev, bo); if (bo->map && (placed_addr == NULL || placed_addr == bo->map))
return VK_SUCCESS;
else if (bo->map)
/* The BO is already mapped, but with a different address. */
return vk_errorf(dev, VK_ERROR_MEMORY_MAP_FAILED, "Cannot remap BO to a different address");
return dev->instance->knl->bo_map(dev, bo, placed_addr);
} }
VkResult VkResult
+2 -2
View File
@@ -72,7 +72,7 @@ struct tu_knl {
VkResult (*bo_init_dmabuf)(struct tu_device *dev, struct tu_bo **out_bo, VkResult (*bo_init_dmabuf)(struct tu_device *dev, struct tu_bo **out_bo,
uint64_t size, int prime_fd); uint64_t size, int prime_fd);
int (*bo_export_dmabuf)(struct tu_device *dev, struct tu_bo *bo); int (*bo_export_dmabuf)(struct tu_device *dev, struct tu_bo *bo);
VkResult (*bo_map)(struct tu_device *dev, struct tu_bo *bo); VkResult (*bo_map)(struct tu_device *dev, struct tu_bo *bo, void *placed_addr);
void (*bo_allow_dump)(struct tu_device *dev, struct tu_bo *bo); void (*bo_allow_dump)(struct tu_device *dev, struct tu_bo *bo);
void (*bo_finish)(struct tu_device *dev, struct tu_bo *bo); void (*bo_finish)(struct tu_device *dev, struct tu_bo *bo);
void (*bo_set_metadata)(struct tu_device *dev, struct tu_bo *bo, void (*bo_set_metadata)(struct tu_device *dev, struct tu_bo *bo,
@@ -140,7 +140,7 @@ void
tu_bo_finish(struct tu_device *dev, struct tu_bo *bo); tu_bo_finish(struct tu_device *dev, struct tu_bo *bo);
VkResult VkResult
tu_bo_map(struct tu_device *dev, struct tu_bo *bo); tu_bo_map(struct tu_device *dev, struct tu_bo *bo, void *placed_addr);
VkResult VkResult
tu_bo_unmap(struct tu_device *dev, struct tu_bo *bo, bool reserve); tu_bo_unmap(struct tu_device *dev, struct tu_bo *bo, bool reserve);
+5 -7
View File
@@ -562,7 +562,7 @@ msm_bo_init(struct tu_device *dev,
if (result == VK_SUCCESS && if (result == VK_SUCCESS &&
(mem_property & VK_MEMORY_PROPERTY_HOST_CACHED_BIT) && (mem_property & VK_MEMORY_PROPERTY_HOST_CACHED_BIT) &&
!(mem_property & VK_MEMORY_PROPERTY_HOST_COHERENT_BIT)) { !(mem_property & VK_MEMORY_PROPERTY_HOST_COHERENT_BIT)) {
tu_bo_map(dev, bo); tu_bo_map(dev, bo, NULL);
/* Cached non-coherent memory may already have dirty cache lines, /* Cached non-coherent memory may already have dirty cache lines,
* we should clean the cache lines before GPU got the chance to * we should clean the cache lines before GPU got the chance to
@@ -631,17 +631,15 @@ msm_bo_init_dmabuf(struct tu_device *dev,
} }
static VkResult static VkResult
msm_bo_map(struct tu_device *dev, struct tu_bo *bo) msm_bo_map(struct tu_device *dev, struct tu_bo *bo, void *placed_addr)
{ {
if (bo->map)
return VK_SUCCESS;
uint64_t offset = tu_gem_info(dev, bo->gem_handle, MSM_INFO_GET_OFFSET); uint64_t offset = tu_gem_info(dev, bo->gem_handle, MSM_INFO_GET_OFFSET);
if (!offset) if (!offset)
return vk_error(dev, VK_ERROR_OUT_OF_DEVICE_MEMORY); return vk_error(dev, VK_ERROR_OUT_OF_DEVICE_MEMORY);
/* TODO: Should we use the wrapper os_mmap() like Freedreno does? */ /* TODO: Should we use the wrapper os_mmap() like Freedreno does? */
void *map = mmap(0, bo->size, PROT_READ | PROT_WRITE, MAP_SHARED, void *map = mmap(placed_addr, bo->size, PROT_READ | PROT_WRITE,
MAP_SHARED | (placed_addr != NULL ? MAP_FIXED : 0),
dev->fd, offset); dev->fd, offset);
if (map == MAP_FAILED) if (map == MAP_FAILED)
return vk_error(dev, VK_ERROR_MEMORY_MAP_FAILED); return vk_error(dev, VK_ERROR_MEMORY_MAP_FAILED);
@@ -942,7 +940,7 @@ tu_queue_submit_locked(struct tu_queue *queue, struct tu_msm_queue_submit *submi
uint32_t buf[3] = { iova, tu_bo->size, iova >> 32 }; uint32_t buf[3] = { iova, tu_bo->size, iova >> 32 };
fd_rd_output_write_section(rd_output, RD_GPUADDR, buf, 12); fd_rd_output_write_section(rd_output, RD_GPUADDR, buf, 12);
if (bo.flags & MSM_SUBMIT_BO_DUMP || FD_RD_DUMP(FULL)) { if (bo.flags & MSM_SUBMIT_BO_DUMP || FD_RD_DUMP(FULL)) {
msm_bo_map(device, tu_bo); /* note: this would need locking to be safe */ tu_bo_map(device, tu_bo, NULL); /* note: this would need locking to be safe */
fd_rd_output_write_section(rd_output, RD_BUFFER_CONTENTS, tu_bo->map, tu_bo->size); fd_rd_output_write_section(rd_output, RD_BUFFER_CONTENTS, tu_bo->map, tu_bo->size);
} }
} }
+4 -7
View File
@@ -633,7 +633,7 @@ virtio_bo_init(struct tu_device *dev,
if (result == VK_SUCCESS && if (result == VK_SUCCESS &&
(mem_property & VK_MEMORY_PROPERTY_HOST_CACHED_BIT) && (mem_property & VK_MEMORY_PROPERTY_HOST_CACHED_BIT) &&
!(mem_property & VK_MEMORY_PROPERTY_HOST_COHERENT_BIT)) { !(mem_property & VK_MEMORY_PROPERTY_HOST_COHERENT_BIT)) {
tu_bo_map(dev, bo); tu_bo_map(dev, bo, NULL);
/* Cached non-coherent memory may already have dirty cache lines, /* Cached non-coherent memory may already have dirty cache lines,
* we should clean the cache lines before GPU got the chance to * we should clean the cache lines before GPU got the chance to
@@ -724,12 +724,9 @@ out_unlock:
} }
static VkResult static VkResult
virtio_bo_map(struct tu_device *dev, struct tu_bo *bo) virtio_bo_map(struct tu_device *dev, struct tu_bo *bo, void *placed_addr)
{ {
if (bo->map) bo->map = vdrm_bo_map(dev->vdev->vdrm, bo->gem_handle, bo->size, placed_addr);
return VK_SUCCESS;
bo->map = vdrm_bo_map(dev->vdev->vdrm, bo->gem_handle, bo->size);
if (bo->map == MAP_FAILED) if (bo->map == MAP_FAILED)
return vk_error(dev, VK_ERROR_MEMORY_MAP_FAILED); return vk_error(dev, VK_ERROR_MEMORY_MAP_FAILED);
@@ -957,7 +954,7 @@ setup_fence_cmds(struct tu_device *dev)
if (result != VK_SUCCESS) if (result != VK_SUCCESS)
return result; return result;
result = tu_bo_map(dev, vdev->fence_cmds_mem); result = tu_bo_map(dev, vdev->fence_cmds_mem, NULL);
if (result != VK_SUCCESS) if (result != VK_SUCCESS)
return result; return result;
+3 -5
View File
@@ -185,13 +185,11 @@ kgsl_bo_export_dmabuf(struct tu_device *dev, struct tu_bo *bo)
} }
static VkResult static VkResult
kgsl_bo_map(struct tu_device *dev, struct tu_bo *bo) kgsl_bo_map(struct tu_device *dev, struct tu_bo *bo, void *placed_addr)
{ {
if (bo->map)
return VK_SUCCESS;
uint64_t offset = bo->gem_handle << 12; uint64_t offset = bo->gem_handle << 12;
void *map = mmap(0, bo->size, PROT_READ | PROT_WRITE, MAP_SHARED, void *map = mmap(placed_addr, bo->size, PROT_READ | PROT_WRITE,
MAP_SHARED | (placed_addr != NULL ? MAP_FIXED : 0),
dev->physical_device->local_fd, offset); dev->physical_device->local_fd, offset);
if (map == MAP_FAILED) if (map == MAP_FAILED)
return vk_error(dev, VK_ERROR_MEMORY_MAP_FAILED); return vk_error(dev, VK_ERROR_MEMORY_MAP_FAILED);
+1 -1
View File
@@ -320,7 +320,7 @@ tu_CreateQueryPool(VkDevice _device,
return result; return result;
} }
result = tu_bo_map(device, pool->bo); result = tu_bo_map(device, pool->bo, NULL);
if (result != VK_SUCCESS) { if (result != VK_SUCCESS) {
tu_bo_finish(device, pool->bo); tu_bo_finish(device, pool->bo);
vk_object_free(&device->vk, pAllocator, pool); vk_object_free(&device->vk, pAllocator, pool);
+1 -1
View File
@@ -89,7 +89,7 @@ tu_suballoc_bo_alloc(struct tu_suballoc_bo *suballoc_bo,
return result; return result;
} }
VkResult result = tu_bo_map(suballoc->dev, suballoc->bo); VkResult result = tu_bo_map(suballoc->dev, suballoc->bo, NULL);
if (result != VK_SUCCESS) { if (result != VK_SUCCESS) {
tu_bo_finish(suballoc->dev, suballoc->bo); tu_bo_finish(suballoc->dev, suballoc->bo);
return VK_ERROR_OUT_OF_HOST_MEMORY; return VK_ERROR_OUT_OF_HOST_MEMORY;