cancel
Showing results for 
Search instead for 
Did you mean: 

Archives Discussions

asylum29
Adept II

Vulkan fails to clear the depth buffer

(Radeon R7 360, latest driver)

In a nutshell: I have a tile-based deferred renderer with the following workflow:

- gbuffer render pass (2 color and 1 depth attachment)
- light cull/accumulation compute shader
- forward render pass (using the same depth buffer as the gbuffer pass)

The problem is the following: the gbuffer and accumulation passes work fine, however the forward render pass ignores my request to clear the depth buffer (therefore using compare_op_less discards all fragments).

First, a link to the code: GitHub - asylum2010/Asylum_Tutorials: Code for tutorials posted on my blog.

Repro:
- set 71_Deferred as startup project
- compile and run (it should work as for now)
- main.cpp line 549: change VK_COMPARE_OP_LESS_OR_EQUAL to VK_COMPARE_OP_LESS
=> the issue is clearly visible

I couldn't find any particular reason why the driver doesn't clear the depth buffer.

0 Likes
1 Solution

You're running two separate renderpasses within the same command buffer, and are not using any kind of synchronization to serialize their execution. As per Vulkan spec:

The work involved in performing action commands is often allowed to overlap or to be reordered, but doing so must not alter the state to be used by each action command. In general, action commands are those commands that alter framebuffer attachments, read/write buffer or image memory, or write to query pools.

You're either going to need to use events or external subpass dependencies to make this work correctly. Other alternatives include splitting a single command buffer you're using right now to two separate command buffers, each hosting one renderpass, or merging two renderpasses into one.

View solution in original post

0 Likes
24 Replies
dwitczak
Staff

Thank you for your report. Can you confirm the latest validation layers do not report any issues for your application?

0 Likes

The project does not build with VS 2013 / VS 2015. Since there's no CMake available, would you mind creating a solution which works with either of the two IDEs? Thanks.

0 Likes

Created a branch named "vs2015" so the (vulkan) samples should build fine now.

GitHub - asylum2010/Asylum_Tutorials at vs2015

0 Likes

With a fairly recent build of validation layers, I'm being informed about a handful of errors your Vulkan application makes. I worked around the first issue, but the DS one would likely take more time I'd need to spend looking around your code. Please fix all errors reported by the latest validation layers (GitHub - KhronosGroup/Vulkan-LoaderAndValidationLayers: Vulkan loader and validation layers ) and I'll be happy to revisit this report.

Here's a diff which fixes one of the issues I'm seeing being reported:

$ git diff

diff --git a/ShaderTutors/common/vkx.cpp b/ShaderTutors/common/vkx.cpp

index 3631b1f..c8fcf37 100644

--- a/ShaderTutors/common/vkx.cpp

+++ b/ShaderTutors/common/vkx.cpp

@@ -1454,7 +1454,7 @@ void VulkanImage::UploadToVRAM(VkCommandBuffer commandbuffer, bool generatemips)

                        width = (extents.width >> i);

                        height = (extents.height >> i);

-                       blit.dstOffsets[1].x = width;

+                       blit.dstOffsets[1].x = (width <= 0) ? 1 : width;

                        blit.dstOffsets[1].y = height;

                        blit.dstOffsets[1].z = 1;

                        blit.dstSubresource.mipLevel = i;

0 Likes

edit: fixed all validator issues I could (the problem still persists tho).

0 Likes

Thanks. Going to have a look soon.

0 Likes

I'm still seeing the following debug call-back:

DS ... encountered the following validation error at vkCmdDrawIndexed9) time: Descriptor in binding #2 at global descriptor index 2 requires an image view of type VK_IMAGE_VIEW_TYPE_2D but got VK_IMAGE_VIEW_TYPE_CUBE.

It's reported on a per-frame basis. Using validation layer build from a commit with SHA 888cae09036ec622d6014e18efbda55e6226cf22.

0 Likes

They committed in the meantime yea... but I don't get this error.
Moreover I don't see how is it even possible... Could you give me some hints where it's called from? (callstack, shader used, etc.)

0 Likes

Come to think of it, there was an issue about flare1.jpg which fails to read for some reason (?). I replaced it with the DDS file, which probably holds the cubemap, and which explains the failure. My bad here

0 Likes

I encountered that flare1.jpg issue too but it happens pretty rare. Tried appverif.exe, nothing bad... Also tried page heap but it crashes in ntdll.dll so its not much of a use.

0 Likes

OK, so it seems like depth info is not correctly calculated in the g-buffer pass' FS, which is awkward. If you try storing other values to the r32f texture, they're fine.

Which version of glslang are you using? Would you mind updating your static library binaries to the latest version, available in the project's repository? A few, potentially related, bugs were recently fixed there. I'd like to know if updating the library to the latest version does any good.

0 Likes

Oh, and one thing I discovered already. Your g-buffer pass' FS tries to store a vec4 to a single-component R32F texture, so there's a mismatch between the number of components to be stored and the actual number of comps available in the bound texture.

Edit: Me and another team member did a bit of a research on this, and it turns out vec4->float writes are fine (although it's a corner case which is not immediately obvious). Sorry for the confusion.

0 Likes

There's also a missing buffer barrier. Before the Model->Draw() call, your application updates contents of the buffer which holds uniform buffer data. This is done by recording a bunch of vkCmdUpdateBuffer() calls. However, you do not seem to be synchronizing these write ops with the vertex shader where the matrices are accessed.

0 Likes

Fixed the shader, updated libs but no effect. I'm currently trying to debug this ReadFile error which causes the flare texture to corrupt. As soon as I'm done I commit.
However I don't think that the gbuffer pass would write wrong depth values. Simply the forward pass doesn't clear the depth buffer (as visible in RenderDoc).

0 Likes

I see now. Got misled by depth buffer values located in the <0.95, 1.0> range. Let me investigate this further. I'll get back to you later today or on Monday.

0 Likes

You're running two separate renderpasses within the same command buffer, and are not using any kind of synchronization to serialize their execution. As per Vulkan spec:

The work involved in performing action commands is often allowed to overlap or to be reordered, but doing so must not alter the state to be used by each action command. In general, action commands are those commands that alter framebuffer attachments, read/write buffer or image memory, or write to query pools.

You're either going to need to use events or external subpass dependencies to make this work correctly. Other alternatives include splitting a single command buffer you're using right now to two separate command buffers, each hosting one renderpass, or merging two renderpasses into one.

0 Likes

Ehh...and imagine that all of these work perfectly on nvidia cards... : /
I will look into it, thanks.

0 Likes

No problem, glad to be of help.

Please consider marking this thread as answered for improved clarity of the thread list on the main forum's page 🙂

0 Likes

Well I tried events, I tried external dependencies (the core validation crashes tho when I use VK_SUBPASS_EXTERNAL) but none of them solved the problem. It's not even obvious to me how to fill out these structures (tried the SaschaWillems example but it didn't help). Back to square one I guess...

0 Likes

I've got a couple of things on my plate this week so I can't make any promises, but I'll do my best to try to find some time to help you with this.

0 Likes

Apparently this did the trick:

VkSubpassDependency   dependencies[2];


// (in addition)

dependencies[0].srcSubpass   = VK_SUBPASS_EXTERNAL;

dependencies[0].srcAccessMask    = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT|VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;

dependencies[0].srcStageMask    = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;

dependencies[0].dstSubpass   = 0;

dependencies[0].dstAccessMask    = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT|VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;

dependencies[0].dstStageMask    = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;

dependencies[0].dependencyFlags    = VK_DEPENDENCY_BY_REGION_BIT;


// (this was already part of the code)

dependencies[1].srcSubpass   = 0;

dependencies[1].srcAccessMask    = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT|VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;

dependencies[1].srcStageMask    = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;

dependencies[1].dstSubpass   = 1;

dependencies[1].dstAccessMask    = VK_ACCESS_INPUT_ATTACHMENT_READ_BIT;

dependencies[1].dstStageMask    = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;

dependencies[1].dependencyFlags    = VK_DEPENDENCY_BY_REGION_BIT;

Awesome 🙂

By the way, you mentioned you ran into crashes when using validation layers. For the sake of improving their quality, could you consider submitting the description of the problem on the project's Github? You can find it under Issues · KhronosGroup/Vulkan-LoaderAndValidationLayers · GitHub  . Thanks!

0 Likes

I did, and by the time I got their reply they merged the fix so its ok now.

Ok.
I committed my fixes so far (but these barrier thingies really give me a headache...apparently my mipmap generation is somewhat invalid too).

0 Likes