Reproducer Added + Vulkan Fragment - Geometry Shader Issues since the 397(8).xx drivers (beta + officia...

Hello,

I have implemented the Occlusion Culling Project based on NVIDIAs raster method with Vulkan, (based on GitHub - nvpro-samples/gl_occlusion_culling: OpenGL sample for shader-based occlusion culling
)

It has worked so far very well until driver version 397.31. The exe crashes now. After some research i found the cause. To my configuration:

I have an octree where the leaf nodes have geometries. Each leaf node has its NodeId and Bounding Box.
Bounding boxes are stored in a storage buffer that is big enough to store all leaf bounding boxes. (Num Leafs * size of bounding box representation).
Additionally i have a storage buffer (visibility buffer) of size numLeaves * sizeof(unsigned int). Before OC step the visibility buffer is set to zero. Then if the node is visible the fragment shader sets it to 1 (vis_node[node_id] = 1). Further steps evaluate and utilize the results.

After rendering the old visible pass I use point rendering and provide nodeIds as points to trigger vertex shader. Vertex shader passes through the nodeIds to the geometry shader. The geometry shader creates Bounding Box vertices (just like in the project on GitHub) and routes (unchanged) the nodeids to the fragment shader.

The Fragment shader looks something like that

...

layout (early_fragment_tests) in;

layout (binding = 0) buffer BB // storage buffer to mark visible nodes
{
   uint node_vis[];
}; 

layout (location = 0) flat in uint node_id; // ==> input from geometry shader (vertex shader)

void main()
{
   node_vis[node_id] = 1;
}

The error:
The shader crashes because the node_id gets some invalid values that cause access violation on the vis_buffer
It seems the robust buffer access feature is broken.

so if i do this

void main()
{
if (node_id >= 0 && node_id < max_num_leafs)
    node_vis[node_id] = 1;
}

It does not crash. The bug seems to be fixed in 397.40 (beta). However there is another issue
with both driver versions (397.31 with the if in the main())
the node ids seems to be unstable:
Same scene, no camera movements , even if depth test is off (per pipeline and/or by removing early depth test flag).

Some object dont pass the visiblity test (e.g have 1000 NodeIds but visible are only 900 or it alternates)
The problem is that wrong objects are culled away.

This should not happen, actually in can not happen, particullary if the depth test is off.

Further debugging has shown, that the input NodeIds not only exceeds the max num of nodes, but does not provide correct ids:
Lets take 10 NodeIds = max_num_nodes (depth test off)
Correct behavior: NodeIds should be 0,1,2,3,4,5,6,7,8,9 and maybe more (but robust buffer access should catch it)
Behavior with the newest drivers: 0,1,50,4,88,7,8,100 and so on but the ids 2,5,6,9 seem never to appear (getting lost some how).
And sometimes its alternate (with large meshes with many nodeIds).
Even if the nodeIds output from geometry shader are hardcoded to some value (e.g. 0), the input nodeIds in the fragment shader have different random values.

It seems the error is somewhere between the geometry and the fragment shader and the data that should be passed between them is getting corrupt.

It works with older official drivers (tested some versions before the 397.31) and it also works with the 389.20 (.10)
Tested it on different hardware (680 GTX, 960 GTX, 1080 GTX). OS: Win10x64 (no issues with older driver, issues with the newest on every test set up)

Thanks

Update:
The newest driver 397.55 and 397.54 still have the issue (Official Beta Driver (397.55) crash; the vulkan beta driver (397.55) instable (described above)

Update: I have written small seflcontained example that reproduce this bug:

It was created with Microsoft VS 2015.

The important places in code to look at:
bbox.geom - creates bounding boxes and passes throught the node_id to the fragment shader
bbox.frag - receivces the node id as uint with flat modifier. In the main of the shader is the if that shows the issue. If received node id is invalid then bboxes get the red color and white if the node id is valid. If the program runs with bugged driver then color of the bboxes alternates randomly.

Please also read the comments at very begin of the main.cpp

Update: Tested the newest 397.96 driver - the issue is still there!

Some hints how to compile the bug example:
It uses vulkan sdk 1.1.73 (and its Evironment Variables (Paths))
OS: Win10x64

if binary is required please dont hesitate to reply!

Update: Tested the newest 398.11 driver - the issue is still there!

Hi ColAngel,

Could you try again with the latest Nvidia driver and Vulkan SDK? If you still reproduce the issue, please share a minimal demo code with the executable so our engineer can quickly run it to identify if it’s a driver regression first.

Thanks

Hi qgu!
Thanks for respond! Yes the issue is still there. Tested all newest driver (vulkan beta, official beta and official release drivers).

The gitbug code was buggy : here another one link to github code. You just need to check out and compile (VS 2015)

and the exe

https://cloud.3di-xchange.de/index.php/s/NxS18aWooxFIs3g

Password:
M.49{q_/N<@P

As I already mentioned the issue is somewhere between geometry and fragment shader or in geometry shader during compilation to NVIDIA internal machine code.

There is a workaround that seems to work.
I have to set the cutom output variables (not build ins)
before every EmitVertex()

Thank you!
Greetings