Skip to content

spirv: optionally emit nir_demote instead of nir_discard for OpKill

This MR is an attempt to start cleaning up the mess that we call discard.

The semantics of discard differ between GLSL and HLSL and their various implementations. Subsequently, numerous of application bugs occurred and SPV_EXT_demote_to_helper_invocation was written in order to clarify the behavior. In NIR, we now have 3 different intrinsics for 2 things, and while demote and terminate have clear semantics, discard still doesn't.

Therefore, I'd like to entirely remove nir_intrinsic_discard:

  • For Vulkan, the spec states that the behavior of OpKill is implementation defined: The OpTerminateInvocation instruction, along with the OpDemoteToHelperInvocation instruction from the VK_EXT_shader_demote_to_helper_invocation extension, together replace the OpKill instruction, which could behave like either of these instructions. I think, because of game bugs, the default behavior should be demote.
  • For GLSL, I think the situation is comparable as radeonSI lowers discard to demote by default. For this MR, I left it unchanged.

I also added a patch to make gl_HelperInvocation always volatile. Although this is the replacement for OpIsHelperInvocationEXT, currently, there is no GLSL support and application bugs are likely.

These changes should be pretty much in line with what Nvidia and AMD do in their proprietary drivers.

v2: Make it optional instead of unconditional.

Edited by Daniel Schürmann

Merge request reports