KhronosGroup / KhronosGroup/GLSL
Implicit derivatives, uniform control flow, and SPIR-V.
@johnkslang is already working on this.
Since Jan 22, 2019.
- Dominant language
- JavaScript
- Stars
- 458
- Forks
- 114
- Avg merge
- 4m
- Merged PRs (30d)
- 1
Description
The SPIR-V specification has a number of definitions that deal with implicit derivatives. Let's start with 2.19: Derivatives:
In all cases, derivatives are well defined only if the derivative group has uniform control flow.
The terms "derivative group" and "uniform control flow" are defined as:
Derivative Group: Defined only for the Fragment Execution Model: The set of invocations collectively processing a single point, line, or triangle, including any helper invocations.
Uniform Control Flow: Uniform control flow (or converged control flow) occurs when all invocations in the invocation group or derivative group execute the same control-flow path (and hence the same sequence of dynamic instances of instructions).
Put simply, implicit derivatives are well-defined under SPIR-V's rules if you have uniform control flow among all fragment shader invocations that process a primitive.
GLSL 4.60 defines things a bit differently. Its definition of Uniform Control Flow is:
Uniform control flow (or converged control flow) occurs when all invocations in the invocation group execute the same control-flow path (and hence the same sequence of dynamic instances of instructions).
Notice the lack of a statement about "derivative groups". That's important. In OpenGL, like in Vulkan, an "invocation group" is defined as:
For graphics shaders, an invocation group is an implementation-dependent subset1 of the set of shader invocations of a given shader stage which are produced by a single drawing command.
Incidentally, footnote 1 effectively says that you have to assume the worst-case: that all invocations of a stage from a single draw command are in the same invocation group. Which means that an invocation group must be assumed to be larger than a single primitive.
That's unfortunate, because GLSL says in section 8.9:
Implicit derivatives are undefined within non-uniform control flow and for non-fragment shader texture fetches.
Because of the lack of a concept of "derivative groups", this can only refer to uniform control flow within an invocation group. Which is rather larger than a derivative group.
However, GLSL's section 6.4 says:
Control flow exits the shader, and subsequent implicit or explicit derivatives are undefined when this control flow is non-uniform (meaning different fragments within the primitive take different control paths).
Emphasis added. So it seems clear that the original intent is that uniformity only needs to be within a primitive, not within a full invocation group.
This all needs to be clarified. And as with prior cases, I suspect the best thing to do is just copy SPIR-V's wording. After all, since we can load SPIR-V shaders now, those shaders still have to be able to act under SPIR-V's rules. So hardware has to be able to have the concept of derivative groups and uniformity within them as distinct from invocation groups.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Assessment
This issue has not been assessed yet.