Is This Program Legal?

In a native Windows, headless DSA compliant context, the glsl below compiles. links and binds without error, but never writes any output. One possibility is that it contains some inconsistency that the compiler did not catch. What do you think?

#version 450

#extension GL_KHR_shader_subgroup_arithmetic : require



layout(local_size_x = 256) in;

// using only output buffers....

layout(std430, binding = 10) writeonly restrict buffer DestinationIndices { uint dest_indices\[\]; };

layout(std430, binding = 11) writeonly restrict buffer DestinationKeys    { uint dest_keys\[\];    };

layout(std430, binding = 12) writeonly restrict buffer wg_cntsbuf { uint wg_counts\[\]; };

layout(std430, binding = 13) buffer Counter  { uint output_count; };



void main() {

    uint idx = gl_GlobalInvocationID.x;

    uint siz = dest_indices.length();



    if (idx == 0u) {

        dest_indices\[0\] = 888u;

        dest_keys\[0\]    = 999u;

    }



    bool is_visible = idx < siz; 



    if (is_visible) {

        dest_indices\[idx\] = idx;

        dest_keys\[idx\]    = idx;

    } 



    uint subgroup_passed_count = subgroupAdd(is_visible ? 1u : 0u);

    if (subgroupElect() && subgroup_passed_count > 0u) {

        atomicAdd(output_count, subgroup_passed_count);

    }

}

RESOLVED: Without the ‘writeonly restrict’ qualifiers, it runs as expected.

That’s probably due to the restrict specifically. That tells the shader compiler that the same underlying resource won’t be bound to multiple binding points. If you actually did bind the same resource to multiple, that might have caused output buffering problems (or something) and thus no output.

Though I’m not sure, looking at how you’re using those buffers, how it would make sense to be doing that. You might want to double check that you’re binding things where you expect.