Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[OMM] Remove validation masking, update spec #377

Open
wants to merge 6 commits into
base: main
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
160 changes: 92 additions & 68 deletions proposals/0024-opacity-micromaps.md
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,10 @@ doesn't apply for inline raytracing however. `RayQuery` objects are
independent of raytracing pipelines. For `RayQuery` the template for
instantiating the object includes a new optional `RAYQUERY_FLAGS` parameter:

`RayQuery<RAY_FLAGS, RAYQUERY_FLAGS>`
```
template<uint StaticRayFlags, uint RayQueryFlags = RAYQUERY_FLAG_NONE>
class RayQuery;
```

```hlsl
enum RAYQUERY_FLAG : uint
Expand Down Expand Up @@ -112,15 +115,30 @@ In HLSL under DXC, these are defined as static const uint values:
```hlsl
static const uint RAYTRACING_PIPELINE_FLAG_ALLOW_OPACITY_MICROMAPS = 0x400;
static const uint RAY_FLAG_FORCE_OMM_2_STATE = 0x400;
static const uint RAYQUERY_FLAG_NONE = 0;
static const uint RAYQUERY_FLAG_ALLOW_OPACITY_MICROMAPS = 0x1;
```

Each of the above flag value definitions except `RAYQUERY_FLAG_NONE` will
have an availability attribute applied, restricting their use to
shader model 6.9 and above.

> Note: the fact that these flags have the same value is only a coincidence.

### Interchange Format Additions

This adds no DXIL operations or metadata, it only adds a new flag value that
may be used with existing DXIL operation parameters, returned by a DXIL
operation.
This adds a new DXIL operation, `AllocateRayQuery2`, to Shader Model 6.9.
This is a new version of `AllocateRayQuery` that has a `RayQueryFlags`
parameter corresponding to the new template argument in HLSL.
When the `RayQueryFlags` template argument is non-zero, this new
`AllocateRayQuery2` DXIL op is used, otherwise the current `AllocateRayQuery`
DXIL op is used.

The new DXIL Op, `AllocateRayQuery2`, will have this signature:
```DXIL
; Function Attrs: nounwind
declare i32 @dx.op.allocateRayQuery2(i32 OpCode, i32 constRayFlags, i32 RayQueryFlags)
```

The DXIL operations which either accept or return `RayFlags`, and therefore may
accept or return the new `RAY_FLAG_FORCE_OMM_2_STATE` are the following (along
Expand All @@ -131,21 +149,21 @@ with brief descriptions):
- `RayQuery_TraceRayInline` - Trace a ray (with ray flags OR'd with the
RayQuery's constant ray flags)

When lowering to DXIL intrinsics, we will mask the flags using the legal mask
for the shader target. This will prevent undefined behavior if invalid flags
were specified and either warnings were ignored, or the flags were not a known
constant value during semantic analysis.

In `DxilConstants.h`, the `RayFlag::ForceOMM2State` flag is added.
Propose adding ValidMask values for diagnostics and validation.
In `DxilConstants.h`, the `RayFlag::ForceOMM2State` flag is added, and a new
`RayQueryFlag` enum is added, mirroring the `RAYQUERY_FLAG` enum
defined in HLSL.

```cpp
// Corresponds to RAY_FLAG_* in HLSL
enum class RayFlag : uint32_t {
...
ForceOMM2State = 0x400, // Force 2-state in Opacity Micromaps
ValidMask_1_8 = 0x3ff, // valid mask up through DXIL 1.8
ValidMask = 0x7ff, // current valid mask
ForceOMM2State = 0x400 // Force 2-state in Opacity Micromaps
};

// Corresponds to RAYQUERY_FLAG_* in HLSL
enum class RayQueryFlag : uint32_t {
None = 0,
AllowOpacityMicromaps = 1
};
```

Expand All @@ -164,82 +182,83 @@ a reachable use of one of the new flags is encountered.
A reachable use is one that is found by traversing AST from active entry and
export functions, or from subobject declarations when compiling a library.
Traversal will follow local function calls, as well as traversing referenced
decls and initializers.
decls (`DeclRef`s and `DeclRefExpr`s) and initializers.

As an implementation detail, an attribute may be used on the new flag
definitions, such as an existing Clang availability attribute or a new custom
HLSL-specific attribute.

AST traversal from entry points will traverse DeclRefs and initializers to
detect the use of the new ray flag. AST traversal will be added for subobject
declarations on library targets to detect any use of the new pipeline flag.
HLSL-specific attribute. Specifically, of the new flags introduced,
`RAYTRACING_PIPELINE_FLAG_ALLOW_OPACITY_MICROMAPS`,
`RAY_FLAG_FORCE_OMM_2_STATE`, and `RAYQUERY_FLAG_ALLOW_OPACITY_MICROMAPS`
will have an availability attribute, which restricts their usage to
shader model 6.9. `RAYQUERY_FLAG_NONE` will be left unrestricted.

This will have implications for uses of these flags outside of the intended
targets. Since they are just uint values, it's technically legal to refer to
tex3d marked this conversation as resolved.
Show resolved Hide resolved
them elsewhere, so we will use a warning which defaults to warning rather than
using DefaultError like we would for calls to unsupported intrinsic functions.
them elsewhere, so we will use a DefaultError warning, since this will be the
only diagnostic used to catch use of these flags in an earlier shader model.

Proposed warning diagnostic:

- `"potential misuse of built-in constant %0 in shader model %1; introduced in shader model %2"`.
This new warning will have a new warning group to allow it to be targeted
easily for command-line override, such as `hlsl-availability-constant`.

When compiling a library with the
`RaytracingPipelineFlags::AllowOpacityMicromaps` flag set in a
[Raytracing pipeline config1][pipeline-config] subobject,
a new DefaultError warning diagnostic will be added if the shader model is less
than 6.9. This will detect the case where the flag is not spelled out and
caught by AST traversal.
A check will be added on the declaration of a RayQuery object
(when not dependent), so that when the RayQueryFlags template argument is
non-zero, it requires shader model 6.9 or above.

Current HLSL diagnostics in DXC do not verify `RayFlags` values in any context.
`TraceRay()` and `RayQuery::TraceRayInline()` accept non-immediate values, but
the `RayFlags` provided as a template argument to `RayQuery` must be immediate.
Proposed DefaultError warning diagnostic:
- `"A non-zero value for the RayQueryFlags template argument requires shader model 6.9 or above."`.

In addition to the AST traversal detecting any explicit use of the new flag,
the same DefaultError warning diagnostic will be added to detect when the
new ray flag is used at the `RayQuery` template argument, `TraceRay()`, or
`RayQuery::TraceRayInline()` (when it is immediate).
This can make use of the new `ValidMask*` values.
A check will be added on the declaration of a RayQuery object
(when not dependent), so that when `RAY_FLAG_FORCE_OMM_2_STATE` is set on
the RayFlags template argument, and `RAYQUERY_FLAG_ALLOW_OPACITY_MICROMAPS`
is not set on the RayQueryFlags template argument, a DefaultError warning
is emitted.

Proposed DefaultError warning diagnostic:
- `"When using 'RAY_FLAG_FORCE_OMM_2_STATE' in RayFlags, RayQueryFlags must have RAYQUERY_FLAG_ALLOW_OPACITY_MICROMAPS set."`.

- `"%select{RaytracingPipelineFlags|RayFlags}0 (0x%1) includes unsupported bits for shader model %2; valid mask: 0x%3"`.
This new warning will have a different warning group, such as
`hlsl-availability`.

> See Issue [RayQuery Template Diagnostics](#rayquery-template-diagnostics).
A check will be added at the call site of `RayQuery::TraceRayInline` that will
emit a DefaultError warning when a constant `RayFlags` parameter has the
`RAY_FLAG_FORCE_OMM_2_STATE` flag set, and the RayQuery object's
`RayQueryFlags` template argument does not have the
`RAYQUERY_FLAG_ALLOW_OPACITY_MICROMAPS` flag set.
The same warning message is emitted, but a diagnostic note should also
point to the RayQuery object declaration, where this RayQueryFlag needs to be
specified.

#### Validation Changes
Four DXIL operations accept `RayFlags` as input, but only two requires these
flags input to be immediate: `AllocateRayQuery` and `AllocateRayQuery2`.

Validation will be added to ensure that the shader model is at least 6.9 when
the `RaytracingPipelineFlags::AllowOpacityMicromaps` is used in a
[Raytracing pipeline config1][pipeline-config] subobject.

Proposed validation error diagnostic:
Validation will be added to ensure the flags are constant on input to
the `AllocateRayQuery` and `AllocateRayQuery2` DXIL operation.

- `"RaytracingPipelineFlags in RaytracingPipelineConfig1 subobject '%0' specifies unknown flags (0x%1) for shader model %2; valid mask: 0x%3"`
Proposed validation error diagnostics:

Three DXIL operations accept `RayFlags` as input, but only one requires this
input to be immediate: `AllocateRayQuery`.
- `"constRayFlags argument of AllocateRayQuery '%0' must be constant"`
- `"constRayFlags and RayQueryFlags arguments of AllocateRayQuery2 '%0' must be constant"`

Validation will be added to check the `RayFlags` parameters for each applicable
DXIL operation, with an error emitted if the flags are constant, the new flag
is used, and the shader model is less than 6.9.
Finally, validation will be added for the `AllocateRayQuery2` DXIL operation
to ensure that when `RAY_FLAG_FORCE_OMM_2_STATE` is set on the constRayFlags
argument, the `RAYQUERY_FLAG_ALLOW_OPACITY_MICROMAPS` is also set on the
RayQueryFlags argument.
tex3d marked this conversation as resolved.
Show resolved Hide resolved

Proposed validation error diagnostic:

- `"RayFlags used in '%0' specifies unknown flags (0x%1) for shader model %2; valid mask: 0x%3"`
- `"RAYQUERY_FLAG_ALLOW_OPACITY_MICROMAPS must be set for RayQueryFlags when RAY_FLAG_FORCE_OMM_2_STATE is set for constRayFlags on AllocateRayQuery2 operation %0."`.

Validation will also be added to ensure the flags are constant on input to
the `AllocateRayQuery` DXIL operation.

Proposed validation error diagnostic:

- `"ConstRayFlags argument of AllocateRayQuery '%0' must be constant"`

### Runtime Additions

The new `AllocateRayQuery2` DXIL op is a required part of shader model 6.9.
Drivers that do not support OMM must ignore the new flags:
`RAYTRACING_PIPELINE_FLAG_ALLOW_OPACITY_MICROMAPS`,
`RAYQUERY_FLAG_ALLOW_OPACITY_MICROMAPS`, and `RAY_FLAG_FORCE_OMM_2_STATE`.
This is equivalent to a driver that does support OMM traversing a BVH built
without OMM data.

#### Runtime information

##### RDAT
Expand Down Expand Up @@ -304,6 +323,8 @@ See [Opacity Micromaps][dxr-omm] in the Raytracing spec for details.
- Test use and value of new flags using ast-dump
- Test that new flag values in intrinsics and RayQuery template argument make
it through to appropriate DXIL operation arguments.
- Test optional template argument to RayQuery generates appropriate DXIL
opreation and that the optional flag makes it through to the argument list.
- Use D3DReflect test to verify new flag value in `RaytracingPipelineConfig1`
subobject `Flags` field.
- Use D3DReflect test to verify min shader model of 6.9 when new ray flag has
Expand All @@ -315,21 +336,24 @@ See [Opacity Micromaps][dxr-omm] in the Raytracing spec for details.
### Diagnostics

- Check availability-based diagnostics for each flag, including recursing
through DeclRefs and their initializers.
through DeclRefs, DeclExprRefs, and their initializers.
- Check both DXR entry scenarios and non-library RayQuery scenarios.
- Check that any RayQuery object with the `RayFlag::ForceOMM2State` flag
in its first template argument also has an accompanying
`RAYQUERY_FLAG_ALLOW_OPACITY_MICROMAPS` flag.
- Check diagnostics for subobject, and lack of diagnostics for non-library
target, where subobjects are ignored.
- Check diagnostics for constant flag values used without the explicit
spelling of the new flags (like using `0x400`) in each applicable scenario.
- Check diagnostics for constant flag scenarios with unknown bits set.
- Test the custom HLSL availability attribute, that it correctly locates
values declared in unintuitive ways, through function calls, namespaces,
etc.

### Validation

- Check constant flag validation for shader models 6.9 and for an earlier
shader model, for each applicable intrinsic.
- Also check validation for when unknown flag bits are set.
- Check subobject flag validation for a shader model less than 6.9.
- Compile with the flag to 6.9 and change the target for manual assembly.
- Check constant value validation on `AllocateRayQuery` and `AllocateRayQuery2`
DXIL ops.
- Check `AllocateRayQuery2` DXIL op validation for
`RAYQUERY_FLAG_ALLOW_OPACITY_MICROMAPS` requirement when
`RAY_FLAG_FORCE_OMM_2_STATE` is used.

### Execution

Expand Down