SteamVR violates the OpenXR standard when using a single swapchain with array layers
When you construct an application that uses a single XrSwapchain with two array layers, one for each eye, SteamVR will emit a Vulkan validation error with every frame (provided validation layers are enabled). The error message reads
vkQueueSubmit(): pSubmits[0].pCommandBuffers[0] command buffer VkCommandBuffer expects VkImage (subresource: aspectMask 0x1 array layer 1, mip level 0) to be in layout VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL--instead, current layout is VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL.
This originates from a call to vkQueueSubmit somewhere inside of SteamVR, not the application code. It occurs because SteamVR is expecting the second array layer to be in layout VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL. This violates the OpenXR standard which states in section 12.20 on the XR_KHR_vulkan_enable extension that:
When an application releases a swapchain image by calling
xrReleaseSwapchainImage, in a session created usingXrGraphicsBindingVulkanKHR, the OpenXR runtime must interpret the image as:• Having a memory layout compatible with
VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMALfor color images, orVK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMALfor depth images.
I have written a demo program where this issue can be turned on and off by toggling between a single or dual swapchain setup, available on my GitLab here along with usage instructions and a description of its internal functionality.
IIRC it has that behavior even without array layers, both with Vulkan and DirectX 12.
With a single swapchain or dual?
It's been a while, I think I mostly tested with dual under DX12. I don't think there has been any instance where I've attached the debugger and not having it spammed with the layout errors.
It did also used to spam the console with performance warnings (2 per frame) about performing operations on images in VK_IMAGE_LAYOUT_GENERAL but those got fixed at some point.
I'm also getting a lot of validation errors even without array layers. Using two swapchains per eye (color & depth, mostly following the OpenXR tutorial setup) and just by acquiring/waiting/releasing the OpenXR swapchain images. Some of them are:
Validation Error: [ VUID-VkImageCreateInfo-pNext-01443 ] | MessageID = 0x18d987f6 | vkCreateImage(): pCreateInfo->pNext<VkExternalMemoryImageCreateInfo>.handleTypes is 16 but pCreateInfo->initialLayout is VK_IMAGE_LAYOUT_PREINITIALIZED. The Vulkan spec states: If the pNext chain includes a VkExternalMemoryImageCreateInfo or VkExternalMemoryImageCreateInfoNV structure whose handleTypes member is not 0, initialLayout must be VK_IMAGE_LAYOUT_UNDEFINED (https://vulkan.lunarg.com/doc/view/1.3.280.0/windows/1.3-extensions/vkspec.html#VUID-VkImageCreateInfo-pNext-01443)
Validation Error: [ UNASSIGNED-CoreValidation-DrawState-InvalidImageLayout ] Object 0: handle = 0x24eba1e02d0, type = VK_OBJECT_TYPE_COMMAND_BUFFER; Object 1: handle = 0xe9484f0000001218, type = VK_OBJECT_TYPE_IMAGE; | MessageID = 0x4dae5635 | vkQueueSubmit(): pSubmits[0].pCommandBuffers[0] command buffer VkCommandBuffer 0x24eba1e02d0[] expects VkImage 0xe9484f0000001218[] (subresource: aspectMask 0x1 array layer 0, mip level 0) to be in layout VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL--instead, current layout is VK_IMAGE_LAYOUT_UNDEFINED.
Validation Error: [ VUID-VkImageSubresourceRange-aspectMask-requiredbitmask ] | MessageID = 0x13969ea4 | vkCmdPipelineBarrier(): pImageMemoryBarriers[0].aspectMask is zero. The Vulkan spec states: aspectMask must not be 0 (https://vulkan.lunarg.com/doc/view/1.3.280.0/windows/1.3-extensions/vkspec.html#VUID-VkImageSubresourceRange-aspectMask-requiredbitmask)
Validation Error: [ UNASSIGNED-ImageBarrier-InvalidImageAspect ] Object 0: handle = 0x3eb07000000000c8, type = VK_OBJECT_TYPE_IMAGE; | MessageID = 0x409a7207 | vkCmdPipelineBarrier(): pImageMemoryBarriers[0].image Using format (VK_FORMAT_D32_SFLOAT_S8_UINT) with aspect flags (VkImageAspectFlags(0)) but depth/stencil image formats must have at least one of VK_IMAGE_ASPECT_DEPTH_BIT and VK_IMAGE_ASPECT_STENCIL_BIT set.
Validation Error: [ VUID-VkImageMemoryBarrier-oldLayout-01208 ] Object 0: handle = 0x3eb07000000000c8, type = VK_OBJECT_TYPE_IMAGE; | MessageID = 0xf855a75b | vkCmdPipelineBarrier(): pImageMemoryBarriers[0].newLayout (VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL) is not compatible with VkImage 0x3eb07000000000c8[] usage flags VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT. The Vulkan spec states: If srcQueueFamilyIndex and dstQueueFamilyIndex define a queue family ownership transfer or oldLayout and newLayout define an image layout transition, and oldLayout or newLayout is VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL then image must have been created with VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT (https://vulkan.lunarg.com/doc/view/1.3.280.0/windows/1.3-extensions/vkspec.html#VUID-VkImageMemoryBarrier-oldLayout-01208)
Validation Error: [ VUID-VkImageMemoryBarrier-image-03320 ] Object 0: handle = 0x3eb07000000000c8, type = VK_OBJECT_TYPE_IMAGE; | MessageID = 0x46c14ae3 | vkCmdPipelineBarrier(): pImageMemoryBarriers[0].image (VkImage 0x3eb07000000000c8[]) has depth/stencil format VK_FORMAT_D32_SFLOAT_S8_UINT, but its aspectMask is VkImageAspectFlags(0). The Vulkan spec states: If image has a depth/stencil format with both depth and stencil and the separateDepthStencilLayouts feature is not enabled, then the aspectMask member of subresourceRange must include both VK_IMAGE_ASPECT_DEPTH_BIT and VK_IMAGE_ASPECT_STENCIL_BIT (https://vulkan.lunarg.com/doc/view/1.3.280.0/windows/1.3-extensions/vkspec.html#VUID-VkImageMemoryBarrier-image-03320)
Validation Error: [ VUID-VkImageMemoryBarrier-oldLayout-01212 ] Object 0: handle = 0x3eb07000000000c8, type = VK_OBJECT_TYPE_IMAGE; | MessageID = 0xff795e16 | vkCmdPipelineBarrier(): pImageMemoryBarriers[0].newLayout (VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL) is not compatible with VkImage 0x3eb07000000000c8[] usage flags VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT. The Vulkan spec states: If srcQueueFamilyIndex and dstQueueFamilyIndex define a queue family ownership transfer or oldLayout and newLayout define an image layout transition, and oldLayout or newLayout is VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL then image must have been created with VK_IMAGE_USAGE_TRANSFER_SRC_BIT (https://vulkan.lunarg.com/doc/view/1.3.280.0/windows/1.3-extensions/vkspec.html#VUID-VkImageMemoryBarrier-oldLayout-01212)
I'm creating my color swapchains with usage flags XR_SWAPCHAIN_USAGE_SAMPLED_BIT | XR_SWAPCHAIN_USAGE_COLOR_ATTACHMENT_BIT | XR_SWAPCHAIN_USAGE_TRANSFER_SRC_BIT | XR_SWAPCHAIN_USAGE_TRANSFER_DST_BIT and VK_FORMAT_R8G8B8A8_SRGB format, their image views having aspect VK_IMAGE_ASPECT_COLOR_BIT. My depth swapchains with usage flags XR_SWAPCHAIN_USAGE_SAMPLED_BIT | XR_SWAPCHAIN_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | XR_SWAPCHAIN_USAGE_TRANSFER_SRC_BIT | XR_SWAPCHAIN_USAGE_TRANSFER_DST_BIT and VK_FORMAT_D32_SFLOAT_S8_UINT format, their image views having aspect VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT.
I don't understand why are these happening since I seem to be creating swapchains/images with the proper flags. They seem to be missing transfer appropriate layouts, or messing color attachment layouts with depth images, empty aspect masks etc.
Are all these errors practically negligible?
I don't understand why are these happening since I seem to be creating swapchains/images with the proper flags. They seem to be missing transfer appropriate layouts, or messing color attachment layouts with depth images, empty aspect masks etc.
Are all these errors practically negligible?
It all seems to be issues with the SteamVR runtime creating them with the wrong flags and not transitioning them correctly. They seem to be clear-cut OpenXR spec violations. AFAIK I don't think the issues affect functionality, at least with current Vulkan runtimes, but they may have some performance impact.
+1 - I'm trying to get as simple of a proof of concept integration of OpenXR into my engine as possible and no matter how I set it up it's flooding my output with validation errors for every frame, no matter what I do.
Validation Error: [ UNASSIGNED-CoreValidation-DrawState-InvalidImageLayout ] Object 0: handle = 0x772fe5a12dc0, type = VK_OBJECT_TYPE_COMMAND_BUFFER; Object 1: handle = 0xf4e28d00000001db, name = BlankEyeBuffer, type = VK_OBJECT_TYPE_IMAGE; | MessageID = 0x4dae5635 | vkQueueSubmit(): pSubmits[0].pCommandBuffers[0] command buffer VkCommandBuffer 0x772fe5a12dc0[] expects VkImage 0xf4e28d00000001db[BlankEyeBuffer] (subresource: aspectMask 0x1 array layer 0, mip level 0) to be in layout VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL--instead, current layout is VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL.
^-- That is what I get when I'm not doing any drawing to the xr swap chain images; just starting the frame, acquiring swap chain images, releasing the images, and finishing the frame with no layers specified, which the standard says is allowed and should result in a blank/cleared output.
If I instead try to do a basic clear or render to the xr swap chain images, and provide valid layer data when finishing the frame, I get:
Validation Error: [ UNASSIGNED-CoreValidation-DrawState-InvalidImageLayout ] Object 0: handle = 0x7b8729a001c0, type = VK_OBJECT_TYPE_COMMAND_BUFFER; Object 1: handle = 0x9aa7dc0000000293, type = VK_OBJECT_TYPE_IMAGE; | MessageID = 0x4dae5635 | vkQueueSubmit(): pSubmits[0].pCommandBuffers[0] command buffer VkCommandBuffer 0x7b8729a001c0[] expects VkImage 0x9aa7dc0000000293[] (subresource: aspectMask 0x1 array layer 0, mip level 0) to be in layout VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL--instead, current layout is VK_IMAGE_LAYOUT_GENERAL.
I've tried reordering begin/wait/end frame calls, acquire/release swapchain calls around, thinking I was calling them at the wrong times but nothing I do seems to make the validation errors go away. Even though the errors are being output I can successfully get my connected headset to see the xr swap chain image manipulations I make.
Ubuntu 24.04, Vulkan 1.2.X, SteamVR build id 15141130, SteamVR runtime version 2.7.4
I'm also getting a lot of validation errors even without array layers. Using two swapchains per eye (color & depth, mostly following the OpenXR tutorial setup) and just by acquiring/waiting/releasing the OpenXR swapchain images. Some of them are:
Are you sure these are coming from SteamVR? I've never seen SteamVR produce anything like these and some of them are quite extreme, for example these:
pImageMemoryBarriers[0].aspectMask is zero expects VkImage to be in layout VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL--instead, current layout is VK_IMAGE_LAYOUT_UNDEFINED
Depending on where they occur these might actually cause visible artifacting. Could you provide a code sample that causes these?
Some of the others are less harmful though, for example these:
oldLayout or newLayout is VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL then image must have been created with VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT oldLayout or newLayout is VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL then image must have been created with VK_IMAGE_USAGE_TRANSFER_SRC_BIT
I've caused hundreds of errors like these and at least on RADV (Mesa Vulkan driver for AMD graphics) they never seem to cause artifacting, although there might exist a driver/graphics device somewhere out there where they do.
Depending on where they occur these might actually cause visible artifacting. Could you provide a code sample that causes these?
@amini-allight I'm getting them while running the OpenXR tutorial, around at the beginning of the program. They don't seem to be per frame so probably won't be causing any artifacts. I'm using Vulkan SDK 1.3.280. Please keep in mind that if you're interested in running the tutorial, the validation layers don't seem to be enabled. They are enabled in the
GraphicsAPI_Vulkan::GraphicsAPI_Vulkan()
constructor, but not in the
GraphicsAPI_Vulkan::GraphicsAPI_Vulkan(XrInstance m_xrInstance, XrSystemId systemId)
one which is what it ends up being used.
I'm also attaching a log of the validation errors I'm getting in the first few seconds of execution just in case they're more useful in order to anyone. validation errors.txt
Ah I didn't realize they were one-offs, much less serious in that case.