KhronosGroup / MoltenVK

MoltenVK is a Vulkan Portability implementation. It layers a subset of the high-performance, industry-standard Vulkan graphics and compute API over Apple's Metal graphics framework, enabling Vulkan applications to run on macOS, iOS and tvOS.
Apache License 2.0
4.79k stars 423 forks source link

Implement `VK_EXT_host_image_copy` #2113

Open DUOLabs333 opened 9 months ago

DUOLabs333 commented 9 months ago

It's not a complete blocker, but it would make copying images to memory easier (instead of having to go through the whole VkBuffer setup).

spnda commented 9 months ago

Implementing this extension is doable with the current Metal API in theory, but there's a few changes required first.

The vkCopyImageToImageEXT will require a blit pass to copy from one texture to another, as Metal has no other API for doing so. This kinda eliminates the point of the extension, but I think its fine since the other paths have a potential optimization value. The sync implications should be fine though, as the Vulkan functions require the user to add sync for any other device usages of the resource.

As vkCopyMemoryToImageEXT and vkCopyImageToMemoryEXT both allow copying to and from DEVICE_LOCAL only memory, there are some changes needed. The Metal API for copying to and from textures only for Private resources. Perhaps there's some way we can somehow force StorageModeShared for resources with VK_FORMAT_FEATURE_2_HOST_IMAGE_TRANSFER_BIT_EXT enabled on Apple GPUs. Otherwise we would again need blit passes, which eliminate the point of the extension. And I don't see this being feasible on any non-shared memory architecture.

billhollings commented 9 months ago

Perhaps there's some way we can somehow force StorageModeShared for resources with VK_FORMAT_FEATURE_2_HOST_IMAGE_TRANSFER_BIT_EXT

Yes. I'd say if VK_FORMAT_FEATURE_2_HOST_IMAGE_TRANSFER_BIT_EXT is set when the image is created, we should force either Shared or Managed memory.

For the actual copying, consider using MVKImagePlane::getMTLTextureContent() and MVKImagePlane::updateMTLTextureContent. And I expect arranging them back-to-back should work for vkCopyImageToImageEXT() too, without the need for a command-buffer-based BLIT command.