llvm / llvm/offload-test-suite
[EPIC]: Improve inline raytracing test coverage
Nobody has claimed this yet.
- Dominant language
- C++
- Stars
- 18
- Forks
- 39
- Avg merge
- 2d 18h
- Merged PRs (30d)
- 40
Description
This issue tracks expanding the inline raytracing (`RayQuery`) test suite. The bring-up PRs introduce a baseline of three scenarios under `test/Feature/InlineRT/` β a single-triangle hit, an indexed triangle hit, and instance selection via translated transforms. The list below walks the HLSL inline-RT spec surface β limited to behavior observable from a shader, since that is what this suite tests β and notes what becomes testable after those PRs land versus what still needs further framework / YAML work.
### Bring-up PRs (foundation for everything below)
- [x] YAML-driven acceleration structure definitions in `.test` files
- https://github.com/llvm/offload-test-suite/pull/1214
- [ ] RT acceleration structure abstraction (size queries, resource allocation) π
- https://github.com/llvm/offload-test-suite/pull/1232
- [ ] Bind acceleration structures and enable the InlineRT tests π
- https://github.com/llvm/offload-test-suite/pull/1245
Legend:
- [ ] Not started
- [ ] In progress ποΈ
- [ ] In review π
- [x] Finished (merged in main)
- π testable on top of the bring-up PRs above
- ποΈ requires additional backend or YAML work first
## RayQuery API surface (`cs_6_5`)
### `TraceRayInline` parameters
- [ ] `RAY_FLAG_NONE`, default mask `0xFF` π
- covered by the bring-up tests in #1245
- [ ] Per-call `RayFlags` argument != template flags (runtime-OR with template) β π
- [ ] `InstanceInclusionMask` filtering β TLAS instances with various `InstanceMask` values, query with overlapping/disjoint masks π
- covered by `instance-mask.test` in #1274
- [ ] `RayDesc` with non-axis-aligned direction (no auto-normalization) β π
- [ ] `RayDesc` with `TMin > 0` excluding a near hit π
- covered by `tmin-tmax-clip.test` in #1271
- [ ] `RayDesc` with `TMax` clipping a far hit π
- covered by `tmin-tmax-clip.test` in #1271
- [ ] Multiple `TraceRayInline` calls on the same `RayQuery` object β π
- [ ] Multiple distinct `RayQuery` objects in the same shader β π
### Template `` (compile-time)
- [ ] `RAY_FLAG_FORCE_OPAQUE` (skips any-hit / non-opaque candidate path) β π
- [ ] `RAY_FLAG_FORCE_NON_OPAQUE` (forces candidate path even for opaque geom) β π
- [ ] `RAY_FLAG_ACCEPT_FIRST_HIT_AND_END_SEARCH` β verify single `Proceed()` iteration stops on first hit β π
- [ ] `RAY_FLAG_CULL_BACK_FACING_TRIANGLES` β π
- [ ] `RAY_FLAG_CULL_FRONT_FACING_TRIANGLES` β π
- [ ] `RAY_FLAG_CULL_OPAQUE` β π
- [ ] `RAY_FLAG_CULL_NON_OPAQUE` β π
- [ ] `RAY_FLAG_SKIP_TRIANGLES` (mixed BLAS, triangles skipped, AABBs hit) β π (procedural path wired in #1289)
- [ ] `RAY_FLAG_SKIP_PROCEDURAL_PRIMITIVES` β π (procedural path wired in #1289)
- [ ] Combined flags (e.g. `CULL_BACK_FACING | ACCEPT_FIRST_HIT_AND_END_SEARCH`) β π
### Candidate-path methods (inside `Proceed()` loop)
- [ ] `CandidateType()` β `CANDIDATE_NON_OPAQUE_TRIANGLE` vs `CANDIDATE_PROCEDURAL_PRIMITIVE` β ποΈ (non-opaque + procedural)
- [ ] `CandidateProceduralPrimitiveNonOpaque()` β ποΈ
- [ ] `CandidateTriangleRayT()` β π (needs non-opaque geometry)
- [ ] `CandidateInstanceIndex()` / `CandidateInstanceID()` β π
- [ ] `CandidateInstanceContributionToHitGroupIndex()` β π (YAML field added in #1286)
- [ ] `CandidateGeometryIndex()` (multi-geometry BLAS) β ποΈ (YAML: multi-geom)
- [ ] `CandidatePrimitiveIndex()` β π
- [ ] `CandidateObjectRayOrigin()` / `CandidateObjectRayDirection()` β π
- [ ] `CandidateObjectToWorld3x4()` / `CandidateObjectToWorld4x3()` β π
- [ ] `CandidateWorldToObject3x4()` / `CandidateWorldToObject4x3()` β π
- [ ] `CandidateTriangleFrontFace()` β π
- [ ] `CandidateTriangleBarycentrics()` (verify u/v at known points) β π
- [ ] `CommitNonOpaqueTriangleHit()` accept/reject patterns β π
- [ ] `CommitProceduralPrimitiveHit(t)` accept/reject β ποΈ
### Committed-hit methods
- [ ] `CommittedStatus()` β `COMMITTED_TRIANGLE_HIT` π
- covered by the bring-up tests in #1245
- [ ] `CommittedStatus()` β `COMMITTED_NOTHING` (miss path) π
- covered by `miss-status.test` in #1271
- [ ] `CommittedStatus()` β `COMMITTED_PROCEDURAL_PRIMITIVE_HIT` π
- covered by `aabb-procedural.test` in #1289
- [ ] `CommittedRayT()` β verify exact `t` for axis-aligned ray-plane hit π
- covered by `ray-t.test` in #1271
- [ ] `CommittedInstanceIndex()` (TLAS position) vs `CommittedInstanceID()` (user data) on shuffled instance order β π
- [ ] `CommittedInstanceID()` π
- multi-instance scenario covered in #1245
- [ ] `CommittedInstanceContributionToHitGroupIndex()` π
- covered by `instance-contribution.test` in #1286
- [ ] `CommittedGeometryIndex()` β ποΈ (YAML: multiple geoms per BLAS)
- [ ] `CommittedPrimitiveIndex()` β multi-triangle BLAS, primitive lookup π
- covered by `primitive-index.test` in #1272
- [ ] `CommittedObjectRayOrigin()` / `CommittedObjectRayDirection()` β verify transform of world-space ray into instance space β π
- [ ] `CommittedObjectToWorld3x4()` / `4x3()` round-trip β π
- [ ] `CommittedWorldToObject3x4()` / `4x3()` β π
- [ ] `CommittedTriangleFrontFace()` (CW vs CCW winding) β π
- [ ] `CommittedTriangleBarycentrics()` β known centroid/edge π
- covered by `barycentrics.test` in #1271
### Ray-side methods
- [ ] `RayFlags()` π
- covered by `world-ray-echo.test` in #1271
- [ ] `WorldRayOrigin()` / `WorldRayDirection()` (echo input) π
- covered by `world-ray-echo.test` in #1271
- [ ] `RayTMin()` π
- covered by `world-ray-echo.test` in #1271
- [ ] `Abort()` mid-`Proceed()` (no commit afterwards) β π
## BLAS geometry coverage (shader-visible facets)
- [ ] Single triangle, non-indexed, `RGB32Float` π
- covered by `triangle-setup.test` in #1245
- [ ] Indexed triangles, `Uint32` indices π
- covered by `indexed-triangle-setup.test` in #1245
- [ ] `Uint16` index buffer β verify primitive lookup unchanged β π
- [ ] Alternate vertex formats: `RG32Float` (z=0), `RGBA16Float`, `RG16Float`, `R10G10B10A2_UNORM`, `RGBA8_SNORM` (precision of barycentrics / object-space ray vs `RGB32Float`) β π
- [ ] Per-triangle-geometry `Transform3x4` (BLAS-side bake; visible via `Object*` queries) π
- covered by `geometry-transform.test` in #1288
- [ ] Multiple triangle geometries in one BLAS β verify `*GeometryIndex` β ποΈ
- [ ] Non-opaque geometry (`Opaque: false`) β drives candidate path β ποΈ (YAML field)
- [ ] AABB / procedural geometry β exercises procedural candidate path π
- covered by `aabb-procedural.test` in #1289
- [ ] Mixed-opacity geometries within one BLAS β ποΈ
- [ ] Degenerate triangles (zero area) β must not produce hits β π
- [ ] Watertightness across shared triangle edges β π
## TLAS instance coverage (shader-visible facets)
- [ ] Multiple instances, distinct translations, distinct `InstanceID` π
- covered by `multi-instance.test` in #1245
- [ ] Rotation/scale transforms (verify `Object*` / `*ToWorld` / `*ToObject`) β π
- [ ] Non-uniform scale + skew (verify `WorldToObject` inverse) β π
- [ ] Instance with negative-determinant transform β front/back flip β π
- [ ] `InstanceMask` filtered by `InstanceInclusionMask` π
- covered by `instance-mask.test` in #1274
- [ ] `InstanceContributionToHitGroupIndex` π
- covered by `instance-contribution.test` in #1286
- [ ] Per-instance flags:
- `TRIANGLE_CULL_DISABLE` overrides ray cull flags β π (YAML field added in #1287)
- `TRIANGLE_FRONT_COUNTERCLOCKWISE` flips `*TriangleFrontFace` π
- covered by `instance-flags.test` in #1287
- `FORCE_OPAQUE` / `FORCE_NON_OPAQUE` overrides β π (YAML field added in #1287)
- [ ] Same BLAS referenced by multiple instances (sharing) β π
- [ ] Empty TLAS (no instances) β currently rejected at build, may want a miss-only path β ποΈ
## Shader control flow
- [ ] Divergent rays per thread (1D dispatch, per-thread direction) π
- covered by `primitive-index.test` in #1272
- [ ] `RayQuery` as a function parameter (`inout`) β π
- [ ] `RayQuery` as a struct member β π
- [ ] Nested `RayQuery` (second trace inside a `Proceed()` loop) β ποΈ (non-opaque)
- [ ] Two independent `RayQuery` objects with different template flags in the same shader β π
- [ ] Conditional `TraceRayInline` (skip on lane mask) β π
- [ ] Loop-driven `Proceed()` with explicit `while (Q.Proceed())` instead of single-shot β π
- [ ] Re-using one `RayQuery` for sequential rays without dynamic state leak β π
- [ ] Storing committed-hit results in groupshared and reading from another lane β π
## Numerical / vendor edge behavior (shader-observable)
- [ ] Ray exactly hitting a vertex / edge β π
- [ ] `TMin == hit distance` (boundary inclusive vs exclusive) β π
- [ ] `TMax == hit distance` (boundary inclusive vs exclusive) β π
- [ ] NaN / Inf in ray origin or direction β must miss safely β π
- [ ] Very large scene scales (numerical precision) β π
- [ ] Very thin/sliver triangles β π
- [ ] Backface culling consistency between DX/VK/MTL (combined with `*TriangleFrontFace` and `CULL_*` ray flags) β π
## Stages other than compute
Inline RT is allowed in every shader stage from SM 6.5 onward. Adding coverage needs the AS-binding plumbing on those pipelines, but the framework already supports each stage individually.
- [ ] `RayQuery` from a pixel shader β ποΈ (PS-side AS binding)
- [ ] `RayQuery` from a vertex shader β ποΈ
- [ ] `RayQuery` from a mesh shader β ποΈ
- [ ] `RayQuery` from a hull / domain / geometry shader β ποΈ
## Framework / YAML follow-ups
Listed inline above where they block tests; aggregated here for the framework worklist. Limited to gaps that block a shader-visible test.
- [ ] YAML `InstanceFlags` field on `AccelerationStructureInstance` π #1287
- [ ] YAML `InstanceContributionToHitGroupIndex` π #1286
- [ ] YAML `Transform` on `TriangleGeometryDesc` (per-geometry bake) π #1288
- [ ] Multiple geometries per BLAS (`Triangles:` is already a list, but exercise it from a shader)
- [ ] AABB / procedural geometry in YAML (descriptors exist, no shader tests) π #1289
- [ ] Bind AS to non-compute stages
Contributor guide
No contributing guide indexed for this repository
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.
Research direction
Start with the existing tests under test/Feature/InlineRT/ and review the bring-up dependencies linked in the checklist, especially the acceleration-structure and binding work. Use the unchecked RayQuery, geometry, instance, control-flow, and shader-stage items to select a narrowly scoped test; completion means adding coverage for that scenario and recording it in this tracking issue.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- cpp, yaml
- Domain
- computer-graphics, testing-qa
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Quiet
- Clarity
- Needs clarification
- Newbie friendliness
- 25/100