Describe the bug
When using the Vulkan backend and importing an image with ICompositionGpuInterop.ImportImage, the layout of the receiving image is set to VK_IMAGE_LAYOUT_UNDEFINED:
|
initialLayout = VkImageLayout.VK_IMAGE_LAYOUT_UNDEFINED, |
On at least some Nvidia hardware (GTX 1080 with 582.66 drivers, Windows 10) this causes the texture data to get lost after the first layout transition to VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL on the interop side:
|
TransitionLayout(VkImageLayout.VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, VkAccessFlags.VK_ACCESS_TRANSFER_READ_BIT); |
Presumably the driver is discarding the old texture data as it is allowed to do for an undefined initial layout. This is visible in the GpuInterop demo, where the first frame doesn't render correctly and only a white background is displayed:
As a quick hack, if I change the initial layout in the VulkanImage constructor to be VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL that the VulkanSwapchainImage first gets transitioned to, then I get the expected image:
To Reproduce
Run the GpuInterop demo on select Nvidia hardware (GTX 1080 with 582.66 drivers, Windows 10).
Note I have not observed this behavior on other devices (older Intel and newer AMD integrated GPUs). For these, the demo works as expected.
Expected behavior
The GpuInterop demo should render the teapot cleanly on the first frame on all supported devices.
Avalonia version
12.0.5
OS
Windows
Additional context
A proper fix requires a way to pass the layout of the exported image to ImportImage. The simplest place is the PlatformGraphicsExternalMemory struct that takes in other image properties. It could be a simple uint that gets casted to the proper enum on the receiving end for Vulkan. However, The flag wouldn't make sense for OpenGL interop, and I am not sure about Metal, so I don't know if this is the best long-term solution.
Also, and I am not completely sure here, but a fully robust solution might also need to respect the queue family flags that are currently ignored (though this doesn't seem to matter on any device I've tried):
|
srcQueueFamilyIndex = VulkanHelpers.QueueFamilyIgnored, |
|
dstQueueFamilyIndex = VulkanHelpers.QueueFamilyIgnored, |
Describe the bug
When using the Vulkan backend and importing an image with ICompositionGpuInterop.ImportImage, the layout of the receiving image is set to VK_IMAGE_LAYOUT_UNDEFINED:
Avalonia/src/Avalonia.Vulkan/Interop/VulkanImage.cs
Line 106 in 6ef2d0b
On at least some Nvidia hardware (GTX 1080 with 582.66 drivers, Windows 10) this causes the texture data to get lost after the first layout transition to VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL on the interop side:
Avalonia/src/Avalonia.Vulkan/VulkanExternalObjectsFeature.cs
Line 260 in 6ef2d0b
Presumably the driver is discarding the old texture data as it is allowed to do for an undefined initial layout. This is visible in the GpuInterop demo, where the first frame doesn't render correctly and only a white background is displayed:
As a quick hack, if I change the initial layout in the VulkanImage constructor to be VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL that the VulkanSwapchainImage first gets transitioned to, then I get the expected image:
To Reproduce
Run the GpuInterop demo on select Nvidia hardware (GTX 1080 with 582.66 drivers, Windows 10).
Note I have not observed this behavior on other devices (older Intel and newer AMD integrated GPUs). For these, the demo works as expected.
Expected behavior
The GpuInterop demo should render the teapot cleanly on the first frame on all supported devices.
Avalonia version
12.0.5
OS
Windows
Additional context
A proper fix requires a way to pass the layout of the exported image to ImportImage. The simplest place is the PlatformGraphicsExternalMemory struct that takes in other image properties. It could be a simple uint that gets casted to the proper enum on the receiving end for Vulkan. However, The flag wouldn't make sense for OpenGL interop, and I am not sure about Metal, so I don't know if this is the best long-term solution.
Also, and I am not completely sure here, but a fully robust solution might also need to respect the queue family flags that are currently ignored (though this doesn't seem to matter on any device I've tried):
Avalonia/src/Avalonia.Vulkan/Interop/VulkanMemoryHelper.cs
Lines 49 to 50 in 6ef2d0b