Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix several render issues found while debugging XR #68102

Merged
merged 1 commit into from
Nov 3, 2022

Conversation

BastiaanOlij
Copy link
Contributor

@BastiaanOlij BastiaanOlij commented Nov 1, 2022

This PR fixes various issues reported by --gpu-validation found by @rsjtdrjgfuzkfg

[ VUID-VkImageSubresourceRange-levelCount-01720 ] | vkCreateImageView: pCreateInfo->subresourceRange.levelCount is 0. The Vulkan spec states: If levelCount is not VK_REMAINING_MIP_LEVELS, it must be greater than 0 (https://www.khronos.org/registry/vulkan/specs/1.3-extensions/html/vkspec.html#VUID-VkImageSubresourceRange-levelCount-01720)

External textures were setting mipmap levels to 0, not 1.

[ VUID-VkImageViewCreateInfo-image-01762 ] | vkCreateImageView() format VK_FORMAT_R8G8B8A8_UNORM differs from VkImage [...] format VK_FORMAT_R8G8B8A8_SRGB. Formats MUST be IDENTICAL unless VK_IMAGE_CREATE_MUTABLE_FORMAT BIT was set on image creation. The Vulkan spec states: If image was not created with the VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT flag, or if the format of the image is a multi-planar format and if subresourceRange.aspectMask is VK_IMAGE_ASPECT_COLOR_BIT, format must be identical to the format used to create image (https://www.khronos.org/registry/vulkan/specs/1.3-extensions/html/vkspec.html#VUID-VkImageViewCreateInfo-image-01762)

When multiple formats are used, VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT must be set, we do this for normal swap chains but in OpenXR this requires adding XR_SWAPCHAIN_USAGE_MUTABLE_FORMAT_BIT when we create the swap chain

[ VUID-VkImageMemoryBarrier-newLayout-parameter ] | vkCmdPipelineBarrier: value of pImageMemoryBarriers[0].newLayout ([...]) does not fall within the begin..end range of the core VkImageLayout enumeration tokens and is not an extension added token. The Vulkan spec states: newLayout must be a valid VkImageLayout value (https://www.khronos.org/registry/vulkan/specs/1.3-extensions/html/vkspec.html#VUID-VkImageMemoryBarrier-newLayout-parameter)

Our external texture logic was not setting the image layout value at all.

[ VUID-VkRenderPassCreateInfo2-pNext-pNext ] | vkCreateRenderPass2KHR: pCreateInfo->pNext chain includes a structure with unexpected VkStructureType VK_STRUCTURE_TYPE_RENDER_PASS_MULTIVIEW_CREATE_INFO; Allowed structures are [VkRenderPassCreationControlEXT, VkRenderPassCreationFeedbackCreateInfoEXT, VkRenderPassFragmentDensityMapCreateInfoEXT]. This error is based on the Valid Usage documentation for version 224 of the Vulkan header. It is possible that you are using a struct from a private extension or an extension that was added to a later version of the Vulkan header, in which case the use of pCreateInfo->pNext is undefined and may not work correctly with validation enabled The Vulkan spec states: Each pNext member of any structure (including this one) in the pNext chain must be either [message is cut here]

When we originally implemented multiview we did so for vkCreateRenderPass which requires inclusion of this struct.
Now that we use vkCreateRenderPass2KHR the information is already provided and the additional multiview struct is no longer needed.
This took a bit of trickery because we implemented a fallback solution to have vkCreateRenderPass2KHR fall back to vkCreateRenderPass. I'm not including this struct only if we expect to fallback on vkCreateRenderPass.

[ VUID-VkRenderPassCreateInfo2-attachment-02525 ] | vkCreateRenderPass2KHR(): Using format (VK_FORMAT_A2B10G10R10_UNORM_PACK32) with aspect flags (VK_IMAGE_ASPECT_NONE) but color image formats must have the VK_IMAGE_ASPECT_COLOR_BIT set. The Vulkan spec states: If the attachment member of any element of the pInputAttachments member of any element of pSubpasses is not VK_ATTACHMENT_UNUSED, the aspectMask member of that element of pInputAttachments must only include aspects that are present in images of the format specified by the element of pAttachments specified by attachment (https://www.khronos.org/registry/vulkan/specs/1.3-extensions/html/vkspec.html#VUID-VkRenderPassCreateInfo2-attachment-02525)

Since switching to vkCreateRenderPass2KHR we now also need to supply the aspectMask, this was not implemented properly. I'm very surprised this was not reported earlier as it would also effect desktop rendering. My best guess is that many Vulkan drivers ignore this mask in vkCreateRenderPass2KHR.
Anyway, this should set them properly.

[ VUID-VkSubpassDescription2-attachment-02800 ] | vkCreateRenderPass2KHR(): Input attachment pSubpasses[3].pInputAttachments[0] aspect mask must not be 0. The Vulkan spec states: If the attachment member of any element of pInputAttachments is not VK_ATTACHMENT_UNUSED, then the aspectMask member must not be 0 (https://www.khronos.org/registry/vulkan/specs/1.3-extensions/html/vkspec.html#VUID-VkSubpassDescription2-attachment-02800)

I suspect this is fixed by the above fix, but I may still have overlooked something. Since I'm not getting these validation errors I can't verify.

@BastiaanOlij
Copy link
Contributor Author

There is one reported error I haven't fixed yet:

[ VUID-VkSwapchainCreateInfoKHR-imageExtent-01274 ] | vkCreateSwapchainKHR() called with imageExtent = (4320,2160), which is outside the bounds returned by vkGetPhysicalDeviceSurfaceCapabilitiesKHR(): currentExtent = (4320,2160), minImageExtent = (1,1), maxImageExtent = (4096,4096). The Vulkan spec states: imageExtent must be between minImageExtent and maxImageExtent, inclusive, where minImageExtent and maxImageExtent are members of the VkSurfaceCapabilitiesKHR structure returned by vkGetPhysicalDeviceSurfaceCapabilitiesKHR for the surface (https://www.khronos.org/registry/vulkan/specs/1.3-extensions/html/vkspec.html#VUID-VkSwapchainCreateInfoKHR-imageExtent-01274)

This one is really really weird. This happens on a PICO VR headset, the reason seems to be that we initially create a swapchain for output to screen using the screen resolution of the device, which seems to be 4320 x 2160. This never gets used (by us) as we initialise XR mode and start using eye buffers.

The Vulkan driver reports that the maximum supported size is 4096 x 4096, we thus can't allocate a buffer for the full size of the screen. The eye buffers are likely smaller then this maximum size (2560 x 2560 according to the logs the @rsjtdrjgfuzkfg provided).

The fix here I would suggest is to build in checks for this in our Vulkan driver and give a normal warning in the output log and possibly clamp the image size of the swapchain to the maxImageExtent.

That said, it puts up some questions on how the PICO can output the end result to screen when their Vulkan driver does not support their output resolution.

Unless off course these are really two 2160 x 2160 panels and its just a fluke that we get the combined size reported.

@BastiaanOlij BastiaanOlij requested a review from clayjohn November 1, 2022 02:50
@rsjtdrjgfuzkfg
Copy link
Contributor

Test results

I built this on top of the current state of #68023, on which I originally observed the validation errors. With this PR applied, all but two of the errors before the failed pipeline creation disappear: remaining errors are the unfixed error @BastiaanOlij mentioned in the previous comment (VUID-VkSwapchainCreateInfoKHR-imageExtent-01274) and

[ VUID-vkQueueSubmit-fence-00063 ] | vkQueueSubmit(): VkFence 0x18145a00000007b2[] submitted in SIGNALED state. Fences must be reset before being submitted The Vulkan spec states: If fence is not VK_NULL_HANDLE, fence must be unsignaled (https://www.khronos.org/registry/vulkan/specs/1.3-extensions/html/vkspec.html#VUID-vkQueueSubmit-fence-00063)

Regarding VUID-VkSwapchainCreateInfoKHR-imageExtent-01274: I did try clamping in my experiments, that did cause subsequent issues as we do get a valid surface in the (invalid) size, validation layers then complain that we use a different size than the surface...

This PR also fixes most validation errors in scenes that do render properly. Only two total warnings remain there: VUID-VkSwapchainCreateInfoKHR-imageExtent-01274 similar to the failed pipeline scenario (I thus don't think it is relevant for proper rendering) and a single validation error for each frame:

[ VUID-VkPresentInfoKHR-pImageIndices-01296 ] | vkQueuePresentKHR(): pSwapchains[0] images passed to present must be in layout VK_IMAGE_LAYOUT_PRESENT_SRC_KHR or VK_IMAGE_LAYOUT_SHARED_PRESENT_KHR but is in VK_IMAGE_LAYOUT_UNDEFINED. The Vulkan spec states: Each element of pImageIndices must be the index of a presentable image acquired from the swapchain specified by the corresponding element of the pSwapchains array, and the presented image subresource must be in the VK_IMAGE_LAYOUT_PRESENT_SRC_KHR layout at the time the operation is executed on a VkDevice (https://github.com/KhronosGroup/Vulkan-Docs/search?q=)VUID-VkPresentInfoKHR-pImageIndices-01296)

This error also occurs on the failed pipeline scenario, buried in the vast mass of errors that obviously happen when godot tries to use a pipeline that failed to create.

@BastiaanOlij
Copy link
Contributor Author

Well I call that progress I guess :)

Not sure why it would be getting that last one though, unless there is another point where we're not setting the layout correctly.

@clayjohn clayjohn requested a review from RandomShaper November 1, 2022 15:10
Copy link
Member

@clayjohn clayjohn left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The changes look reasonable to me. I would like @RandomShaper to take a look as well as he is more familiar with some of the state than I am

@rsjtdrjgfuzkfg
Copy link
Contributor

rsjtdrjgfuzkfg commented Nov 1, 2022

Correction regarding tests in which rendering works: I do still (again?) get other per-frame errors accompanying VUID-VkPresentInfoKHR-pImageIndices-01296.

I'm not sure why I did not notice / get them in the test I did earlier, but I don't think the changed environment should cause them (I did switch from template apk to custom build with android plugin). So I guess I'm to blame.

Both well-rendering and broken scenes start with the following warnings:

VUID-VkSwapchainCreateInfoKHR-imageExtent-01274
VUID-vkQueueSubmit-fence-00063

Then repeats blocks of:

VUID-VkPresentInfoKHR-pImageIndices-01296
VUID-vkQueueSubmit-fence-00064
UNASSIGNED-CoreValidation-DrawState-InvalidImageLayout
UNASSIGNED-CoreValidation-DrawState-InvalidImageLayout
VUID-vkQueueSubmit-fence-00063
VUID-vkQueueSubmit-fence-00063
  (for broken scenes, pipeline creation fails here for each frame)
UNASSIGNED-CoreValidation-DrawState-InvalidImageLayout
UNASSIGNED-CoreValidation-DrawState-InvalidImageLayout

A scene not rendering properly has the exact same warnings (in terms of IDs, I did not check messages), but the pipeline creation fails before the first repeating block, and within each block at the indicated position.


Edit with concrete warnings from a run that did not render properly:

Startup:

[ VUID-VkSwapchainCreateInfoKHR-imageExtent-01274 ] vkCreateSwapchainKHR() called with imageExtent = (4320,2160), which is outside the bounds returned by vkGetPhysicalDeviceSurfaceCapabilitiesKHR(): currentExtent = (4320,2160), minImageExtent = (1,1), maxImageExtent = (4096,4096). The Vulkan spec states: imageExtent must be between minImageExtent and maxImageExtent, inclusive, where minImageExtent and maxImageExtent are members of the VkSurfaceCapabilitiesKHR structure returned by vkGetPhysicalDeviceSurfaceCapabilitiesKHR for the surface (https://www.khronos.org/registry/vulkan/specs/1.3-extensions/html/vkspec.html#VUID-VkSwapchainCreateInfoKHR-imageExtent-01274)

[ VUID-vkQueueSubmit-fence-00063 ] vkQueueSubmit(): VkFence 0x18145a00000007b2[] submitted in SIGNALED state. Fences must be reset before being submitted The Vulkan spec states: If fence is not VK_NULL_HANDLE, fence must be unsignaled (https://www.khronos.org/registry/vulkan/specs/1.3-extensions/html/vkspec.html#VUID-vkQueueSubmit-fence-00063)

Relevant logcat message: AdrenoVK-0: Failed to link shaders
Pipeline creation failed: vkCreateGraphicsPipelines failed with error -13 for shader 'SceneForwardMobileShaderRD:5'.

First loop:

[ VUID-VkPresentInfoKHR-pImageIndices-01296 ] vkQueuePresentKHR(): pSwapchains[0] images passed to present must be in layout VK_IMAGE_LAYOUT_PRESENT_SRC_KHR or VK_IMAGE_LAYOUT_SHARED_PRESENT_KHR but is in VK_IMAGE_LAYOUT_UNDEFINED. The Vulkan spec states: Each element of pImageIndices must be the index of a presentable image acquired from the swapchain specified by the corresponding element of the pSwapchains array, and the presented image subresource must be in the VK_IMAGE_LAYOUT_PRESENT_SRC_KHR layout at the time the operation is executed on a VkDevice (https://github.com/KhronosGroup/Vulkan-Docs/search?q=)VUID-VkPresentInfoKHR-pImageIndices-01296)

[ VUID-vkQueueSubmit-fence-00064 ] vkQueueSubmit(): VkFence 0x18145a00000007b2[] is already in use by another submission. The Vulkan spec states: If fence is not VK_NULL_HANDLE, fence must not be associated with any other queue command that has not yet completed execution on that queue (https://www.khronos.org/registry/vulkan/specs/1.3-extensions/html/vkspec.html#VUID-vkQueueSubmit-fence-00064)

[ UNASSIGNED-CoreValidation-DrawState-InvalidImageLayout ] vkQueueSubmit(): pSubmits[0].pCommandBuffers[0] command buffer VkCommandBuffer 0x7d92d67410[] expects VkImage 0x5109b300000007ab[] (subresource: aspectMask 0x1 array layer 0, mip level 0) to be in layout VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL--instead, current layout is VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL.

[ UNASSIGNED-CoreValidation-DrawState-InvalidImageLayout ] vkQueueSubmit(): pSubmits[0].pCommandBuffers[0] command buffer VkCommandBuffer 0x7d92d67410[] expects VkImage 0x5109b300000007ab[] (subresource: aspectMask 0x1 array layer 1, mip level 0) to be in layout VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL--instead, current layout is VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL.

[ VUID-vkQueueSubmit-fence-00063 ] vkQueueSubmit(): VkFence 0x24b5ce000000093f[] submitted in SIGNALED state. Fences must be reset before being submitted The Vulkan spec states: If fence is not VK_NULL_HANDLE, fence must be unsignaled (https://www.khronos.org/registry/vulkan/specs/1.3-extensions/html/vkspec.html#VUID-vkQueueSubmit-fence-00063)

[ VUID-vkQueueSubmit-fence-00063 ] vkQueueSubmit(): VkFence 0x5d63eb00000007b3[] submitted in SIGNALED state. Fences must be reset before being submitted The Vulkan spec states: If fence is not VK_NULL_HANDLE, fence must be unsignaled (https://www.khronos.org/registry/vulkan/specs/1.3-extensions/html/vkspec.html#VUID-vkQueueSubmit-fence-00063)

Relevant logcat message: AdrenoVK-0: Failed to link shaders
Pipeline creation failed: vkCreateGraphicsPipelines failed with error -13 for shader 'SceneForwardMobileShaderRD:5'.

[ UNASSIGNED-CoreValidation-DrawState-InvalidImageLayout ] vkQueueSubmit(): pSubmits[0].pCommandBuffers[1] command buffer VkCommandBuffer 0x7da5049a10[] expects VkImage 0xa89fbd00000007ad[] (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_COLOR_ATTACHMENT_OPTIMAL.

[ UNASSIGNED-CoreValidation-DrawState-InvalidImageLayout ] vkQueueSubmit(): pSubmits[0].pCommandBuffers[1] command buffer VkCommandBuffer 0x7da5049a10[] expects VkImage 0xa89fbd00000007ad[] (subresource: aspectMask 0x1 array layer 1, mip level 0) to be in layout VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL--instead, current layout is VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL.

Second loop:

[ VUID-VkPresentInfoKHR-pImageIndices-01296 ] vkQueuePresentKHR(): pSwapchains[0] images passed to present must be in layout VK_IMAGE_LAYOUT_PRESENT_SRC_KHR or VK_IMAGE_LAYOUT_SHARED_PRESENT_KHR but is in VK_IMAGE_LAYOUT_UNDEFINED. The Vulkan spec states: Each element of pImageIndices must be the index of a presentable image acquired from the swapchain specified by the corresponding element of the pSwapchains array, and the presented image subresource must be in the VK_IMAGE_LAYOUT_PRESENT_SRC_KHR layout at the time the operation is executed on a VkDevice (https://github.com/KhronosGroup/Vulkan-Docs/search?q=)VUID-VkPresentInfoKHR-pImageIndices-01296)

[ VUID-vkQueueSubmit-fence-00064 ] vkQueueSubmit(): VkFence 0x5d63eb00000007b3[] is already in use by another submission. The Vulkan spec states: If fence is not VK_NULL_HANDLE, fence must not be associated with any other queue command that has not yet completed execution on that queue (https://www.khronos.org/registry/vulkan/specs/1.3-extensions/html/vkspec.html#VUID-vkQueueSubmit-fence-00064)

[ UNASSIGNED-CoreValidation-DrawState-InvalidImageLayout ] vkQueueSubmit(): pSubmits[0].pCommandBuffers[0] command buffer VkCommandBuffer 0x7d92d67330[] expects VkImage 0xa89fbd00000007ad[] (subresource: aspectMask 0x1 array layer 0, mip level 0) to be in layout VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL--instead, current layout is VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL.

[ UNASSIGNED-CoreValidation-DrawState-InvalidImageLayout ] vkQueueSubmit(): pSubmits[0].pCommandBuffers[0] command buffer VkCommandBuffer 0x7d92d67330[] expects VkImage 0xa89fbd00000007ad[] (subresource: aspectMask 0x1 array layer 1, mip level 0) to be in layout VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL--instead, current layout is VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL.

[ VUID-vkQueueSubmit-fence-00063 ] vkQueueSubmit(): VkFence 0xc85da3000000094a[] submitted in SIGNALED state. Fences must be reset before being submitted The Vulkan spec states: If fence is not VK_NULL_HANDLE, fence must be unsignaled (https://www.khronos.org/registry/vulkan/specs/1.3-extensions/html/vkspec.html#VUID-vkQueueSubmit-fence-00063)

[ VUID-vkQueueSubmit-fence-00063 ] vkQueueSubmit(): VkFence 0x9fde8c00000007b4[] submitted in SIGNALED state. Fences must be reset before being submitted The Vulkan spec states: If fence is not VK_NULL_HANDLE, fence must be unsignaled (https://www.khronos.org/registry/vulkan/specs/1.3-extensions/html/vkspec.html#VUID-vkQueueSubmit-fence-00063)

Relevant logcat message: AdrenoVK-0: Failed to link shaders
Pipeline creation failed: vkCreateGraphicsPipelines failed with error -13 for shader 'SceneForwardMobileShaderRD:5'.

[ UNASSIGNED-CoreValidation-DrawState-InvalidImageLayout ] vkQueueSubmit(): pSubmits[0].pCommandBuffers[1] command buffer VkCommandBuffer 0x7da5049a30[] expects VkImage 0x7d52f00000007af[] (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_COLOR_ATTACHMENT_OPTIMAL.

[ UNASSIGNED-CoreValidation-DrawState-InvalidImageLayout ] vkQueueSubmit(): pSubmits[0].pCommandBuffers[1] command buffer VkCommandBuffer 0x7da5049a30[] expects VkImage 0x7d52f00000007af[] (subresource: aspectMask 0x1 array layer 1, mip level 0) to be in layout VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL--instead, current layout is VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL.

@BastiaanOlij
Copy link
Contributor Author

Hmmm, I think that kind of makes sense, it all sets of a chain of events from the moment it can't create the swapchain, it then can't create the pipeline, it then can't create the shaders or something.

That poses an interesting dilemma for us at some point wanting to skip over the initialisation code all together because on standalone XR that swapchain and the associated windowing code is never used, but without it it doesn't set up the rendering engine correctly.

Anyway, as a test I wonder if we can just rig it to not create a swapchain bigger then 4096x4096 and see if that makes the issue go away.

@BastiaanOlij
Copy link
Contributor Author

@clayjohn @rsjtdrjgfuzkfg btw, seeing this PR fixes the validation errors mentioned in the OP, I think we should merge this PR if we all agree on the fixes (I too would like @RandomShaper to review, hopefully he'll react soon).

That swapchain size issue probably will require further experimentation and would be better to fix in a separate PR.

@rsjtdrjgfuzkfg
Copy link
Contributor

Hmmm, I think that kind of makes sense, it all sets of a chain of events from the moment it can't create the swapchain, it then can't create the pipeline, it then can't create the shaders or something.

Given that I get the exact same warning even when it does render properly (simple scene or forward clustered renderer), I think we're still missing something. I did isolate the issue to having any data pass from vertex to fragment shaders causing the shaders to stop linking when using the mobile renderer, but don't see what could cause it. I dumped the full GLSL shaders and the locations and data types did match up.

That said, of course it would be good to skip the "normal" initialization and thus fix the warning. I'm happy to test things if you have an idea how. :)

btw, seeing this PR fixes the validation errors mentioned in the OP, I think we should merge this PR if we all agree on the fixes

I agree that this PC should get merged; it is self-contained and we can fix any additional issues in other PRs.

@Cyberrebell
Copy link
Contributor

For me this texture.mipmaps = 1; change does fix blackscreen system freeze crashes using an AMD RX 6600 on both Linux and Windows I got since #65227 🎉

@akien-mga akien-mga merged commit c98d614 into godotengine:master Nov 3, 2022
@akien-mga
Copy link
Member

Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants