diff --git a/src/asahi/lib/agx_device.c b/src/asahi/lib/agx_device.c index 745685c0e8d..07d93e50bfb 100644 --- a/src/asahi/lib/agx_device.c +++ b/src/asahi/lib/agx_device.c @@ -227,13 +227,13 @@ agx_bo_alloc(struct agx_device *dev, size_t size, size_t align, } static void -agx_bo_mmap(struct agx_device *dev, struct agx_bo *bo) +agx_bo_mmap(struct agx_device *dev, struct agx_bo *bo, void *fixed_addr) { assert(bo->_map == NULL && "not double mapped"); struct drm_asahi_gem_mmap_offset gem_mmap_offset = {.handle = bo->uapi_handle}; - int ret; + int ret, flags; ret = drmIoctl(dev->fd, DRM_IOCTL_ASAHI_GEM_MMAP_OFFSET, &gem_mmap_offset); if (ret) { @@ -241,8 +241,9 @@ agx_bo_mmap(struct agx_device *dev, struct agx_bo *bo) assert(0); } - bo->_map = os_mmap(NULL, bo->size, PROT_READ | PROT_WRITE, MAP_SHARED, - dev->fd, gem_mmap_offset.offset); + flags = MAP_SHARED | (fixed_addr ? MAP_FIXED : 0); + bo->_map = os_mmap(fixed_addr, bo->size, PROT_READ | PROT_WRITE, + flags, dev->fd, gem_mmap_offset.offset); if (bo->_map == MAP_FAILED) { bo->_map = NULL; fprintf(stderr, diff --git a/src/asahi/lib/agx_device.h b/src/asahi/lib/agx_device.h index aabebec93ff..17c900b67aa 100644 --- a/src/asahi/lib/agx_device.h +++ b/src/asahi/lib/agx_device.h @@ -74,7 +74,7 @@ typedef struct { enum agx_bo_flags flags); int (*bo_bind)(struct agx_device *dev, struct drm_asahi_gem_bind_op *ops, uint32_t count); - void (*bo_mmap)(struct agx_device *dev, struct agx_bo *bo); + void (*bo_mmap)(struct agx_device *dev, struct agx_bo *bo, void *fixed_addr); ssize_t (*get_params)(struct agx_device *dev, void *buf, size_t size); int (*submit)(struct agx_device *dev, struct drm_asahi_submit *submit, struct agx_submit_virt *virt); @@ -201,14 +201,20 @@ agx_rw_addr_to_ro(struct agx_device *dev, uint64_t addr) } static inline void * -agx_bo_map(struct agx_bo *bo) +agx_bo_map_placed(struct agx_bo *bo, void *fixed_addr) { if (!bo->_map) - bo->dev->ops.bo_mmap(bo->dev, bo); + bo->dev->ops.bo_mmap(bo->dev, bo, fixed_addr); return bo->_map; } +static inline void * +agx_bo_map(struct agx_bo *bo) +{ + return agx_bo_map_placed(bo, NULL); +} + static inline bool agx_has_soft_fault(struct agx_device *dev) { diff --git a/src/asahi/lib/agx_device_virtio.c b/src/asahi/lib/agx_device_virtio.c index 347faa4e26c..13e4c631c3e 100644 --- a/src/asahi/lib/agx_device_virtio.c +++ b/src/asahi/lib/agx_device_virtio.c @@ -190,9 +190,9 @@ agx_virtio_bo_unbind_object(struct agx_device *dev, uint32_t object_handle) } static void -agx_virtio_bo_mmap(struct agx_device *dev, struct agx_bo *bo) +agx_virtio_bo_mmap(struct agx_device *dev, struct agx_bo *bo, void *fixed_addr) { - bo->_map = vdrm_bo_map(dev->vdrm, bo->handle, bo->size, NULL); + bo->_map = vdrm_bo_map(dev->vdrm, bo->handle, bo->size, fixed_addr); if (bo->_map == MAP_FAILED) { bo->_map = NULL; fprintf(stderr, "mmap failed: result=%p size=0x%llx fd=%i\n", bo->_map, diff --git a/src/asahi/vulkan/hk_device_memory.c b/src/asahi/vulkan/hk_device_memory.c index 69771d2d6a7..de50861103d 100644 --- a/src/asahi/vulkan/hk_device_memory.c +++ b/src/asahi/vulkan/hk_device_memory.c @@ -297,7 +297,7 @@ hk_MapMemory2KHR(VkDevice device, const VkMemoryMapInfoKHR *pMemoryMapInfo, const VkDeviceSize size = vk_device_memory_range( &mem->vk, pMemoryMapInfo->offset, pMemoryMapInfo->size); - UNUSED void *fixed_addr = NULL; + 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); @@ -329,7 +329,8 @@ hk_MapMemory2KHR(VkDevice device, const VkMemoryMapInfoKHR *pMemoryMapInfo, "Memory object already mapped."); } - mem->map = agx_bo_map(mem->bo); + mem->map = agx_bo_map_placed(mem->bo, fixed_addr); + assert(!fixed_addr || mem->map == fixed_addr); *ppData = mem->map + offset; return VK_SUCCESS; @@ -345,16 +346,15 @@ hk_UnmapMemory2KHR(VkDevice device, return VK_SUCCESS; if (pMemoryUnmapInfo->flags & VK_MEMORY_UNMAP_RESERVE_BIT_EXT) { - unreachable("todo"); -#if 0 VK_FROM_HANDLE(hk_device, dev, device); - int err = agx_bo_overmap(mem->bo, mem->map); - if (err) { + void *err = mmap(mem->bo->_map, mem->bo->size, PROT_NONE, + MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED, -1, 0); + if (err == MAP_FAILED) { return vk_errorf(dev, VK_ERROR_MEMORY_MAP_FAILED, "Failed to map over original mapping"); } -#endif + mem->bo->_map = NULL; } else { if (mem->bo->_map) { munmap(mem->bo->_map, mem->bo->size); diff --git a/src/asahi/vulkan/hk_physical_device.c b/src/asahi/vulkan/hk_physical_device.c index b63d1b8270c..0f518d02d9e 100644 --- a/src/asahi/vulkan/hk_physical_device.c +++ b/src/asahi/vulkan/hk_physical_device.c @@ -163,7 +163,7 @@ hk_get_device_extensions(const struct hk_instance *instance, .EXT_inline_uniform_block = true, .EXT_line_rasterization = true, .EXT_load_store_op_none = true, - .EXT_map_memory_placed = false, + .EXT_map_memory_placed = true, .EXT_memory_budget = false, .EXT_multi_draw = true, .EXT_mutable_descriptor_type = true, @@ -535,9 +535,9 @@ hk_get_device_features( .minLod = true, /* VK_EXT_map_memory_placed */ - .memoryMapPlaced = false, + .memoryMapPlaced = true, .memoryMapRangePlaced = false, - .memoryUnmapReserve = false, + .memoryUnmapReserve = true, /* VK_EXT_multi_draw */ .multiDraw = true,