KhronosGroup / KhronosGroup/GLSL

Implicit derivatives, uniform control flow, and SPIR-V.

Open
#52 0 comments 0 reactions 1 assignee View on GitHub

@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

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.