glslang icon indicating copy to clipboard operation
glslang copied to clipboard

GLSL discard behavior

Open Valentin-Sarthou opened this issue 1 month ago • 1 comments

Hello,

Since 93231001597dad1149a5d035af30eda50b9e6b6c (merged in 15.4.0), GLSL's discard now maps to OpDemoteToHelperInvocation instead of OpTerminateInvocation when targeting SPIR-V >= 1.6.

This change has already been discussed in #3954, but I would like to add a few more elements.

From the GLSL 4.60 specification, section 6.4. Jumps, about the discard keyword:

Control flow exits the shader, and subsequent implicit or explicit derivatives are undefined when this control flow is non-uniform

This sentence seems to describe the behavior of OpTerminateInvocation, as opposed to OpDemoteToHelperInvocation.

Also, from the specification of VK_KHR_shader_terminate_invocation:

OpTerminateInvocation provides the behavior required by the GLSL discard statement, and should be used when available by GLSL compilers and applications that need the GLSL discard behavior.

So from what I understand, mapping discard to OpTerminateInvocation was indeed the expected behavior, at least according to the specification.

I understand that the ambiguity of discard may cause bugs in applications, but isn't that why GLSL_EXT_demote_to_helper_invocation and GL_EXT_terminate_invocation were introduced ? The latter states:

It is recommended that programmers use demote [...] or terminateInvocation instead of discard.

Is it reasonable for glslang to deviate from the GLSL, VK and EXTs specifications on this point? Am I missing something?

Valentin-Sarthou avatar Nov 03 '25 14:11 Valentin-Sarthou

While that is indeed what the spec says, in practice every Mesa driver sets discard_is_demote so the options for glslang were to continue emitting OpKill which then gets translated into a demote, or else actually emit TerminateInvocation which changes the behavior of existing shader code and results in brokenness.

arcady-lunarg avatar Dec 12 '25 19:12 arcady-lunarg

Thank you for your answer.

I understand the issue with MESA drivers, and the necessity to be able to match the behavior they introduced in https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/27617/commits

But what about drivers from other vendors?
In my experience, OpenGL drivers from major vendors always treat discard as a "terminate" operation.
So when porting OpenGL applications to Vulkan and using glslang for shader code compatibility, there will also be a change of behavior.

What about adding an option in glslang similar to MESA's discard_is_demote, so that applications can choose which behavior they want? (keeping the default to "demote" for compatibility with MESA) I can do the PR.

Valentin-Sarthou avatar Dec 15 '25 10:12 Valentin-Sarthou

I think it would be a reasonable thing to add as a command-line option (and you would also have to expose it via the C and C++ API).

arcady-lunarg avatar Dec 15 '25 17:12 arcady-lunarg