diff --git a/src/virtio/vulkan/vn_device_memory.c b/src/virtio/vulkan/vn_device_memory.c index 687a1071171..82f95e9bebc 100644 --- a/src/virtio/vulkan/vn_device_memory.c +++ b/src/virtio/vulkan/vn_device_memory.c @@ -61,16 +61,24 @@ vn_device_memory_pool_grow_alloc(struct vn_device *dev, result = vn_renderer_bo_create_from_device_memory( dev->renderer, mem->size, mem->base.id, mem_flags, 0, &mem->base_bo); + if (result != VK_SUCCESS) { + assert(!mem->base_bo); + goto fail; + } + + result = + vn_instance_submit_roundtrip(dev->instance, &mem->bo_roundtrip_seqno); if (result != VK_SUCCESS) goto fail; - vn_instance_roundtrip(dev->instance); - + mem->bo_roundtrip_seqno_valid = true; *out_mem = mem; return VK_SUCCESS; fail: + if (mem->base_bo) + vn_renderer_bo_unref(dev->renderer, mem->base_bo); if (mem_handle != VK_NULL_HANDLE) vn_async_vkFreeMemory(dev->instance, dev_handle, mem_handle, NULL); vn_object_base_fini(&mem->base); @@ -100,6 +108,10 @@ vn_device_memory_pool_unref(struct vn_device *dev, if (!vn_renderer_bo_unref(dev->renderer, pool_mem->base_bo)) return; + /* wait on valid bo_roundtrip_seqno before vkFreeMemory */ + if (pool_mem->bo_roundtrip_seqno_valid) + vn_instance_wait_roundtrip(dev->instance, pool_mem->bo_roundtrip_seqno); + vn_async_vkFreeMemory(dev->instance, vn_device_to_handle(dev), vn_device_memory_to_handle(pool_mem), NULL); vn_object_base_fini(&pool_mem->base); @@ -292,7 +304,15 @@ vn_device_memory_alloc(struct vn_device *dev, return result; } - vn_instance_roundtrip(dev->instance); + result = + vn_instance_submit_roundtrip(dev->instance, &mem->bo_roundtrip_seqno); + if (result != VK_SUCCESS) { + vn_renderer_bo_unref(dev->renderer, mem->base_bo); + vn_async_vkFreeMemory(dev->instance, dev_handle, mem_handle, NULL); + return result; + } + + mem->bo_roundtrip_seqno_valid = true; return VK_SUCCESS; } @@ -399,6 +419,10 @@ vn_FreeMemory(VkDevice device, } else { if (mem->base_bo) vn_renderer_bo_unref(dev->renderer, mem->base_bo); + + if (mem->bo_roundtrip_seqno_valid) + vn_instance_wait_roundtrip(dev->instance, mem->bo_roundtrip_seqno); + vn_async_vkFreeMemory(dev->instance, device, memory, NULL); } diff --git a/src/virtio/vulkan/vn_device_memory.h b/src/virtio/vulkan/vn_device_memory.h index 04f23d10541..aedd8465e68 100644 --- a/src/virtio/vulkan/vn_device_memory.h +++ b/src/virtio/vulkan/vn_device_memory.h @@ -28,6 +28,9 @@ struct vn_device_memory { struct vn_device_memory *base_memory; /* non-NULL when mappable or external */ struct vn_renderer_bo *base_bo; + /* enforce kernel and ring ordering between memory export and free */ + bool bo_roundtrip_seqno_valid; + uint32_t bo_roundtrip_seqno; VkDeviceSize base_offset; VkDeviceSize map_end;