This two fragment shaders that exhibit undefined behavior. In GLSL,
it is undefined to use implicit or explicit derivatives in
non-uniform control flow [1]. The SPIR-V produced by glslang contained
similar undefined behavior, which results in incorrect codegen
with the amdvlk's LLPC shader compiler, and produces visually
incorrect image.
This PR fixes this issue by hoisting the sampling so that it's
executed before discarding. It's a simple fix and may not be
the optimial way to resolve this issue.
[1]
https://www.khronos.org/registry/OpenGL/specs/gl/GLSLangSpec.4.60.pdf
p. 137.
GLSLang determines the content of the builtin block based on the shading
language version. In the case of 420 vs 450, the difference is whether
the gl_CullDistance member is present.
Vulkan requires that the builtin interface block be the same on both
sides of a shader interface not involving the fragment shader, so this
leads to undefined behavior. This is caught by recent versions of the
validation layers.
Fix the issue by using GLSL 450 for both shaders in the pipeline.
The SPIRV previously checked in had various issues -- most commonly, it
would use the VertexId and InstanceId builtins rather than the
replacmenet VertexIndex and InstanceIndex builtins required by Vulkan.
- shader: add barrier at the end of each iteration to avoid writing before the reading finished
- cpp: add synchronization between compute and graphics, the image barrier is not enough for the data visibility between different submission
modified: data/shaders/computenbody/particle_calculate.comp
modified: data/shaders/computenbody/particle_calculate.comp.spv
modified: examples/computenbody/computenbody.cpp
The sample count was previously fixed at 8, which is not supported
on some platforms. The code now checks for the maximum supported
sample count and uses that instead.
If you would prefer the upper limit to be fixed at 8, that is
obviously trivial to change.