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

View file

@ -164,7 +164,7 @@ tu_cs_add_bo(struct tu_cs *cs, uint32_t size)
return result;
}
result = tu_bo_map(cs->device, new_bo);
result = tu_bo_map(cs->device, new_bo, NULL);
if (result != VK_SUCCESS) {
tu_bo_finish(cs->device, new_bo);
return result;

View file

@ -287,7 +287,7 @@ tu_CreateDescriptorSetLayout(
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) {
tu_bo_finish(device, set_layout->embedded_samplers);
vk_object_free(&device->vk, pAllocator, set_layout);
@ -805,7 +805,7 @@ tu_CreateDescriptorPool(VkDevice _device,
if (ret)
goto fail_alloc;
ret = tu_bo_map(device, pool->bo);
ret = tu_bo_map(device, pool->bo, NULL);
if (ret)
goto fail_map;
} else {

View file

@ -244,6 +244,7 @@ get_device_extensions(const struct tu_physical_device *device,
.EXT_inline_uniform_block = true,
.EXT_line_rasterization = true,
.EXT_load_store_op_none = true,
.EXT_map_memory_placed = true,
.EXT_memory_budget = true,
.EXT_multi_draw = true,
.EXT_mutable_descriptor_type = true,
@ -554,6 +555,11 @@ tu_get_features(struct tu_physical_device *pdevice,
/* VK_EXT_image_view_min_lod */
features->minLod = true;
/* VK_EXT_map_memory_placed */
features->memoryMapPlaced = true,
features->memoryMapRangePlaced = false,
features->memoryUnmapReserve = true,
/* VK_EXT_multi_draw */
features->multiDraw = true;
@ -1005,6 +1011,11 @@ tu_get_properties(struct tu_physical_device *pdevice,
vk_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 */
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);
}
if (tu_bo_map(device, bo) != VK_SUCCESS) {
if (tu_bo_map(device, bo, NULL) != VK_SUCCESS) {
return U_TRACE_NO_TIMESTAMP;
}
@ -2325,7 +2336,7 @@ tu_CreateDevice(VkPhysicalDevice physicalDevice,
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) {
vk_startup_errorf(device->instance, result, "BO map");
goto fail_global_bo_map;
@ -2876,12 +2887,18 @@ tu_MapMemory2KHR(VkDevice _device, const VkMemoryMapInfoKHR *pMemoryMapInfo, voi
return VK_SUCCESS;
}
if (!mem->bo->map) {
result = tu_bo_map(device, mem->bo);
if (result != VK_SUCCESS)
return result;
void *placed_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);
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;
return VK_SUCCESS;
}
@ -2895,7 +2912,7 @@ tu_UnmapMemory2KHR(VkDevice _device, const VkMemoryUnmapInfoKHR *pMemoryUnmapInf
if (mem == NULL)
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
@ -3011,7 +3028,7 @@ tu_CreateEvent(VkDevice _device,
if (result != VK_SUCCESS)
goto fail_alloc;
result = tu_bo_map(device, event->bo);
result = tu_bo_map(device, event->bo, NULL);
if (result != VK_SUCCESS)
goto fail_map;

View file

@ -825,7 +825,7 @@ tu_BindImageMemory2(VkDevice _device,
if (image->vk.usage & VK_IMAGE_USAGE_FRAGMENT_DENSITY_MAP_BIT_EXT) {
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)
return result;
}

View file

@ -58,9 +58,15 @@ tu_bo_finish(struct tu_device *dev, struct tu_bo *bo)
}
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

View file

@ -72,7 +72,7 @@ struct tu_knl {
VkResult (*bo_init_dmabuf)(struct tu_device *dev, struct tu_bo **out_bo,
uint64_t size, int prime_fd);
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_finish)(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);
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
tu_bo_unmap(struct tu_device *dev, struct tu_bo *bo, bool reserve);

View file

@ -562,7 +562,7 @@ msm_bo_init(struct tu_device *dev,
if (result == VK_SUCCESS &&
(mem_property & VK_MEMORY_PROPERTY_HOST_CACHED_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,
* 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
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);
if (!offset)
return vk_error(dev, VK_ERROR_OUT_OF_DEVICE_MEMORY);
/* 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);
if (map == 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 };
fd_rd_output_write_section(rd_output, RD_GPUADDR, buf, 12);
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);
}
}

View file

@ -633,7 +633,7 @@ virtio_bo_init(struct tu_device *dev,
if (result == VK_SUCCESS &&
(mem_property & VK_MEMORY_PROPERTY_HOST_CACHED_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,
* we should clean the cache lines before GPU got the chance to
@ -724,12 +724,9 @@ out_unlock:
}
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)
return VK_SUCCESS;
bo->map = vdrm_bo_map(dev->vdev->vdrm, bo->gem_handle, bo->size);
bo->map = vdrm_bo_map(dev->vdev->vdrm, bo->gem_handle, bo->size, placed_addr);
if (bo->map == 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)
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)
return result;

View file

@ -185,13 +185,11 @@ kgsl_bo_export_dmabuf(struct tu_device *dev, struct tu_bo *bo)
}
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;
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);
if (map == MAP_FAILED)
return vk_error(dev, VK_ERROR_MEMORY_MAP_FAILED);

View file

@ -320,7 +320,7 @@ tu_CreateQueryPool(VkDevice _device,
return result;
}
result = tu_bo_map(device, pool->bo);
result = tu_bo_map(device, pool->bo, NULL);
if (result != VK_SUCCESS) {
tu_bo_finish(device, pool->bo);
vk_object_free(&device->vk, pAllocator, pool);

View file

@ -89,7 +89,7 @@ tu_suballoc_bo_alloc(struct tu_suballoc_bo *suballoc_bo,
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) {
tu_bo_finish(suballoc->dev, suballoc->bo);
return VK_ERROR_OUT_OF_HOST_MEMORY;