2
votes

When I tried to migrate my OpenGL implementation to Vulkan, I found that 'uniform atomic_uint' is not supported in Vulkan. My use case is simple: incrementing an integer across all fragments. I tried to search the solution but did not find any latest solution.

Here is a list of old solutions:

  1. https://software.intel.com/en-us/articles/opengl-performance-tips-atomic-counter-buffers-versus-shader-storage-buffer-objects. It said that OpenGL atomic counter is similar to SSBO atomic operation and it may be implemented as SSBO atomic operations on some platforms. (Not sure whether it is still true today).

  2. https://community.khronos.org/t/vulkan-atomic-counters/7146. It also said to use image load/store or atomic operations on SSBO as a replacement. (But the content is 2 years old.)

Since Vulkan is still growing, can anyone suggest a latest standard way to do atomic increment over an integer using GLSL in Vulkan?

Edit:

I've got my answer, but I will add more details. In my OpenGL code, I have a render pass with a vertex shader and a fragment shader (No compute shader involved). In the fragment shader, I have the following glsl (simplified):

#version 450
layout (binding = 0) uniform atomic_uint fragmentCount;

void main()
{
  atomicCounterIncrement(fragmentCount);
}

This shader works fine in OpenGL because OpenGL has enum 'GL_ATOMIC_COUNTER_BUFFER' in glBindBuffer and keyword 'atomic_uint' in glsl. However, Vulkan does not have the corresponding built-in keyword. Therefore, I try to seek a replacement for it. I did not ask how to query the number of fragments being rendered, though the shader here looks like I'm doing that. I was wondering whether this 'atomic counter' in general graphics shaders exists in Vulkan. As Nicol Bolas pointed out, there is no such thing in Vulkan and hardware-wise there is no implementation on NVIDIA GPU, so I decide to use SSBO and AtomicAdd to do the same thing.

Hope this makes my problem clearer.

1
What are you actually trying to do? Occlusion queries using VK_QUERY_CONTROL_PRECISE_BIT might make a lot more sense if you just want a count of fragments. Atomics are expensive.solidpixel
Please specify what exactly you are trying to do, you state your use case is "incrementing an integer across all fragments" which doesn't really tell us what you are attempting to do. You can do things like warp voting in vulkan to get information from threads in a warp with out atomics, and you may be able to use that information instead of your incrementing. It is very likely for what ever you are doing there is a better solution than using atomics in the first place.Krupip

1 Answers

3
votes

Atomic counters don't exist in Vulkan, so you'll have to go with one of those solutions.

BTW, atomic counters, as a distinct hardware concept, are only something that existed on AMD hardware. That is why Vulkan doesn't support them; non-AMD hardware basically emulates them as SSBO work.