diff --git a/docs/features.txt b/docs/features.txt index d1abd80080f..baeb4b9a95f 100644 --- a/docs/features.txt +++ b/docs/features.txt @@ -707,7 +707,7 @@ Khronos extensions that are not part of any Vulkan version: VK_EXT_swapchain_colorspace DONE (anv, hk, lvp, nvk, radv, tu, v3dv, vn) VK_EXT_depth_clamp_zero_one DONE (anv, nvk, panvk, pvr, radv, tu, v3dv/vc7+, vn) VK_INTEL_shader_integer_functions2 DONE (anv, hasvk, radv) - VK_EXT_map_memory_placed DONE (anv, hk, nvk, radv, tu) + VK_EXT_map_memory_placed DONE (anv, hk, nvk, pvr, radv, tu) VK_MESA_image_alignment_control DONE (anv, nvk, radv) VK_EXT_legacy_dithering DONE (anv, tu, vn) VK_QCOM_fragment_density_map_offset DONE (tu) diff --git a/docs/relnotes/new_features.txt b/docs/relnotes/new_features.txt index ba809dff6b9..9a6984af0c4 100644 --- a/docs/relnotes/new_features.txt +++ b/docs/relnotes/new_features.txt @@ -81,3 +81,4 @@ VK_KHR_shader_relaxed_extended_instruction on pvr VK_EXT_shader_replicated_composites on pvr VK_KHR_device_group_creation on pvr VK_KHR_map_memory2 on pvr +VK_EXT_map_memory_placed on pvr diff --git a/src/imagination/vulkan/pvr_bo.c b/src/imagination/vulkan/pvr_bo.c index 2c59144217c..fa55e96b843 100644 --- a/src/imagination/vulkan/pvr_bo.c +++ b/src/imagination/vulkan/pvr_bo.c @@ -365,7 +365,7 @@ VkResult pvr_bo_alloc(struct pvr_device *device, goto err_free_bo; if (flags & PVR_BO_ALLOC_FLAG_CPU_MAPPED) { - result = device->ws->ops->buffer_map(pvr_bo->bo); + result = device->ws->ops->buffer_map(pvr_bo->bo, NULL); if (result != VK_SUCCESS) goto err_buffer_destroy; @@ -419,7 +419,7 @@ VkResult pvr_bo_cpu_map(struct pvr_device *device, struct pvr_bo *pvr_bo) { assert(!pvr_bo->bo->map); - return device->ws->ops->buffer_map(pvr_bo->bo); + return device->ws->ops->buffer_map(pvr_bo->bo, NULL); } /** diff --git a/src/imagination/vulkan/pvr_device.c b/src/imagination/vulkan/pvr_device.c index d4d92c687ec..a3f272c10d4 100644 --- a/src/imagination/vulkan/pvr_device.c +++ b/src/imagination/vulkan/pvr_device.c @@ -240,6 +240,7 @@ static void pvr_physical_device_get_supported_extensions( .EXT_image_2d_view_of_3d = true, .EXT_index_type_uint8 = false, .EXT_line_rasterization = true, + .EXT_map_memory_placed = true, .EXT_physical_device_drm = true, .EXT_private_data = true, .EXT_provoking_vertex = true, @@ -457,6 +458,11 @@ static void pvr_physical_device_get_supported_features( .image2DViewOf3D = true, .sampler2DViewOf3D = true, + /* VK_EXT_map_memory_placed */ + .memoryMapPlaced = true, + .memoryMapRangePlaced = false, + .memoryUnmapReserve = false, + /* Vulkan 1.3 / VK_EXT_private_data */ .privateData = true, @@ -799,6 +805,9 @@ static bool pvr_physical_device_get_properties( /* VK_EXT_extended_dynamic_state3 */ .dynamicPrimitiveTopologyUnrestricted = false, + /* VK_EXT_map_memory_placed */ + .minPlacedMemoryMapAlignment = pdevice->ws->page_size, + /* VK_EXT_provoking_vertex */ .provokingVertexModePerPipeline = true, .transformFeedbackPreservesTriangleFanProvokingVertex = false, @@ -2777,6 +2786,14 @@ VkResult pvr_MapMemory2(VkDevice _device, offset = pMemoryMapInfo->offset; size = vk_device_memory_range(&mem->vk, offset, pMemoryMapInfo->size); + void *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); + 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 @@ -2803,7 +2820,7 @@ VkResult pvr_MapMemory2(VkDevice _device, } /* Map it all at once */ - result = device->ws->ops->buffer_map(mem->bo); + result = device->ws->ops->buffer_map(mem->bo, addr); if (result != VK_SUCCESS) return result; diff --git a/src/imagination/vulkan/winsys/powervr/pvr_drm_bo.c b/src/imagination/vulkan/winsys/powervr/pvr_drm_bo.c index f5c4e45ae88..67bbd015e83 100644 --- a/src/imagination/vulkan/winsys/powervr/pvr_drm_bo.c +++ b/src/imagination/vulkan/winsys/powervr/pvr_drm_bo.c @@ -299,7 +299,7 @@ VkResult pvr_drm_winsys_buffer_get_fd(struct pvr_winsys_bo *bo, return VK_SUCCESS; } -VkResult pvr_drm_winsys_buffer_map(struct pvr_winsys_bo *bo) +VkResult pvr_drm_winsys_buffer_map(struct pvr_winsys_bo *bo, void *addr) { struct pvr_drm_winsys_bo *drm_bo = to_pvr_drm_winsys_bo(bo); struct pvr_drm_winsys *drm_ws = to_pvr_drm_winsys(bo->ws); @@ -313,7 +313,8 @@ VkResult pvr_drm_winsys_buffer_map(struct pvr_winsys_bo *bo) if (result != VK_SUCCESS) goto err_out; - result = pvr_mmap(bo->size, + result = pvr_mmap(addr, + bo->size, PROT_READ | PROT_WRITE, MAP_SHARED, drm_ws->base.render_fd, diff --git a/src/imagination/vulkan/winsys/pvr_winsys.h b/src/imagination/vulkan/winsys/pvr_winsys.h index aa2b41d04ef..955faba0383 100644 --- a/src/imagination/vulkan/winsys/pvr_winsys.h +++ b/src/imagination/vulkan/winsys/pvr_winsys.h @@ -369,7 +369,7 @@ struct pvr_winsys_ops { VkResult (*buffer_get_fd)(struct pvr_winsys_bo *bo, int *const fd_out); - VkResult (*buffer_map)(struct pvr_winsys_bo *bo); + VkResult (*buffer_map)(struct pvr_winsys_bo *bo, void *addr); void (*buffer_unmap)(struct pvr_winsys_bo *bo); VkResult (*heap_alloc)(struct pvr_winsys_heap *heap, diff --git a/src/imagination/vulkan/winsys/pvr_winsys_helper.c b/src/imagination/vulkan/winsys/pvr_winsys_helper.c index 167eea7a528..b59c4c84c7f 100644 --- a/src/imagination/vulkan/winsys/pvr_winsys_helper.c +++ b/src/imagination/vulkan/winsys/pvr_winsys_helper.c @@ -322,15 +322,15 @@ pvr_winsys_helper_fill_static_memory(struct pvr_winsys *const ws, { VkResult result; - result = ws->ops->buffer_map(general_vma->bo); + result = ws->ops->buffer_map(general_vma->bo, NULL); if (result != VK_SUCCESS) goto err_out; - result = ws->ops->buffer_map(pds_vma->bo); + result = ws->ops->buffer_map(pds_vma->bo, NULL); if (result != VK_SUCCESS) goto err_pvr_srv_winsys_buffer_unmap_general; - result = ws->ops->buffer_map(usc_vma->bo); + result = ws->ops->buffer_map(usc_vma->bo, NULL); if (result != VK_SUCCESS) goto err_pvr_srv_winsys_buffer_unmap_pds; diff --git a/src/imagination/vulkan/winsys/pvr_winsys_helper.h b/src/imagination/vulkan/winsys/pvr_winsys_helper.h index 295ea06517a..ea4a2b55162 100644 --- a/src/imagination/vulkan/winsys/pvr_winsys_helper.h +++ b/src/imagination/vulkan/winsys/pvr_winsys_helper.h @@ -82,14 +82,18 @@ pvr_winsys_helper_fill_static_memory(struct pvr_winsys *const ws, struct pvr_winsys_vma *const pds_vma, struct pvr_winsys_vma *const usc_vma); -static inline VkResult pvr_mmap(const size_t len, +static inline VkResult pvr_mmap(void *addr, + const size_t len, const int prot, - const int flags, + int flags, const int fd, const off_t offset, void **const map_out) { - void *const map = mmap(NULL, len, prot, flags, fd, offset); + if (addr) + flags |= MAP_FIXED; + + void *const map = mmap(addr, len, prot, flags, fd, offset); if (map == MAP_FAILED) { const int err = errno; return vk_errorf(NULL, diff --git a/src/imagination/vulkan/winsys/pvrsrvkm/pvr_srv_bo.c b/src/imagination/vulkan/winsys/pvrsrvkm/pvr_srv_bo.c index d62c0c2609e..d0da258a4b6 100644 --- a/src/imagination/vulkan/winsys/pvrsrvkm/pvr_srv_bo.c +++ b/src/imagination/vulkan/winsys/pvrsrvkm/pvr_srv_bo.c @@ -297,7 +297,7 @@ VkResult pvr_srv_winsys_buffer_get_fd(struct pvr_winsys_bo *bo, return VK_SUCCESS; } -VkResult pvr_srv_winsys_buffer_map(struct pvr_winsys_bo *bo) +VkResult pvr_srv_winsys_buffer_map(struct pvr_winsys_bo *bo, void *addr) { struct pvr_srv_winsys_bo *srv_bo = to_pvr_srv_winsys_bo(bo); struct pvr_winsys *ws = bo->ws; @@ -310,7 +310,8 @@ VkResult pvr_srv_winsys_buffer_map(struct pvr_winsys_bo *bo) assert(!bo->map); /* Map the full PMR to CPU space */ - result = pvr_mmap(bo->size, + result = pvr_mmap(addr, + bo->size, prot, MAP_SHARED, ws->render_fd,