Skip to content

Commit a9e34bd

Browse files
MarijnS95claude
andcommitted
Add per-instance InstanceFlags YAML field and front-CCW test
Introduces AccelerationStructureInstanceFlags with bit values that intentionally match D3D12_RAYTRACING_INSTANCE_FLAGS, VkGeometryInstance- FlagBitsKHR, and MTLAccelerationStructureInstanceOptions so backends can pass the value through unchanged. YAML exposes the field as a bitset list (e.g. `InstanceFlags: [TriangleCullDisable, ForceOpaque]`). The covering test sets TriangleFrontCounterclockwise on one of two instances and verifies CommittedTriangleFrontFace() flips against the same BLAS. Part of the inline-RT test coverage epic (#1258). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent 852802f commit a9e34bd

8 files changed

Lines changed: 135 additions & 3 deletions

File tree

include/API/AccelerationStructure.h

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,26 @@
1414
#include "API/Resources.h"
1515

1616
#include "llvm/ADT/ArrayRef.h"
17+
#include "llvm/ADT/BitmaskEnum.h"
1718
#include "llvm/ADT/SmallVector.h"
1819
#include "llvm/Support/Error.h"
1920

2021
#include <cstdint>
2122
#include <variant>
2223

2324
namespace offloadtest {
25+
LLVM_ENABLE_BITMASK_ENUMS_IN_NAMESPACE();
26+
27+
// Bit values match D3D12_RAYTRACING_INSTANCE_FLAGS, VkGeometryInstanceFlagBits-
28+
// KHR, and MTLAccelerationStructureInstanceOptions so backends can pass the
29+
// value through unchanged.
30+
enum AccelerationStructureInstanceFlags : uint32_t {
31+
InstanceFlagNone = 0,
32+
TriangleCullDisable = 1 << 0,
33+
TriangleFrontCounterclockwise = 1 << 1,
34+
ForceOpaque = 1 << 2,
35+
ForceNonOpaque = 1 << 3,
36+
};
2437

2538
struct AccelerationStructureSizes {
2639
uint64_t ResultDataMaxSizeInBytes = 0;
@@ -57,6 +70,7 @@ struct AccelerationStructureInstance {
5770
uint8_t InstanceMask = 0xFF;
5871
// 24-bit; high bits are truncated by the backend to match DXR's bitfield.
5972
uint32_t InstanceContributionToHitGroupIndex = 0;
73+
AccelerationStructureInstanceFlags Flags = InstanceFlagNone;
6074
AccelerationStructure *BLAS = nullptr;
6175
};
6276

@@ -178,4 +192,9 @@ class AccelerationStructure {
178192

179193
} // namespace offloadtest
180194

195+
namespace llvm {
196+
LLVM_DECLARE_ENUM_AS_BITMASK(::offloadtest::AccelerationStructureInstanceFlags,
197+
::offloadtest::ForceNonOpaque);
198+
} // namespace llvm
199+
181200
#endif // OFFLOADTEST_API_ACCELERATIONSTRUCTURE_H

include/Support/Pipeline.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#ifndef OFFLOADTEST_SUPPORT_PIPELINE_H
1414
#define OFFLOADTEST_SUPPORT_PIPELINE_H
1515

16+
#include "API/AccelerationStructure.h"
1617
#include "API/Enums.h"
1718
#include "API/Resources.h"
1819
#include "llvm/ADT/SmallVector.h"
@@ -516,6 +517,7 @@ struct InstanceDesc {
516517
uint32_t InstanceID = 0;
517518
uint8_t InstanceMask = 0xFF;
518519
uint32_t InstanceContributionToHitGroupIndex = 0;
520+
AccelerationStructureInstanceFlags Flags = InstanceFlagNone;
519521
};
520522

521523
struct TLASDesc {
@@ -736,6 +738,19 @@ template <> struct MappingTraits<offloadtest::AccelerationStructureDescs> {
736738
static void mapping(IO &I, offloadtest::AccelerationStructureDescs &D);
737739
};
738740

741+
template <>
742+
struct ScalarBitSetTraits<offloadtest::AccelerationStructureInstanceFlags> {
743+
static void bitset(IO &I,
744+
offloadtest::AccelerationStructureInstanceFlags &V) {
745+
#define BIT_CASE(Val) I.bitSetCase(V, #Val, offloadtest::Val)
746+
BIT_CASE(TriangleCullDisable);
747+
BIT_CASE(TriangleFrontCounterclockwise);
748+
BIT_CASE(ForceOpaque);
749+
BIT_CASE(ForceNonOpaque);
750+
#undef BIT_CASE
751+
}
752+
};
753+
739754
template <> struct ScalarEnumerationTraits<offloadtest::Rule> {
740755
static void enumeration(IO &I, offloadtest::Rule &V) {
741756
#define ENUM_CASE(Val) I.enumCase(V, #Val, offloadtest::Rule::Val)

lib/API/DX/Device.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3067,7 +3067,9 @@ llvm::Error DXComputeEncoder::batchBuildAS(llvm::ArrayRef<ASBuildItem> Items) {
30673067
NI.InstanceMask = Inst.InstanceMask;
30683068
NI.InstanceContributionToHitGroupIndex =
30693069
Inst.InstanceContributionToHitGroupIndex & 0xFFFFFFu;
3070-
NI.Flags = D3D12_RAYTRACING_INSTANCE_FLAG_NONE;
3070+
// Bits in AccelerationStructureInstanceFlags match
3071+
// D3D12_RAYTRACING_INSTANCE_FLAGS by design.
3072+
NI.Flags = static_cast<D3D12_RAYTRACING_INSTANCE_FLAGS>(Inst.Flags);
30713073
auto *BLASPtr = llvm::cast<DXAccelerationStructure>(Inst.BLAS);
30723074
NI.AccelerationStructure = BLASPtr->getGPUVirtualAddress();
30733075
Native.push_back(NI);

lib/API/Device.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -202,6 +202,7 @@ llvm::Error offloadtest::buildPipelineAccelerationStructures(
202202
Inst.InstanceMask = I.InstanceMask;
203203
Inst.InstanceContributionToHitGroupIndex =
204204
I.InstanceContributionToHitGroupIndex;
205+
Inst.Flags = I.Flags;
205206
Inst.BLAS = It->second;
206207
Req.Instances.push_back(Inst);
207208
}

lib/API/MTL/MTLDevice.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2515,7 +2515,10 @@ llvm::Error MTLComputeEncoder::batchBuildAS(llvm::ArrayRef<ASBuildItem> Items) {
25152515
for (int Row = 0; Row < 3; ++Row)
25162516
for (int Col = 0; Col < 4; ++Col)
25172517
D.transformationMatrix.columns[Col][Row] = Src.Transform[Row][Col];
2518-
D.options = MTL::AccelerationStructureInstanceOptionNone;
2518+
// Bits in AccelerationStructureInstanceFlags match
2519+
// MTLAccelerationStructureInstanceOptions by design.
2520+
D.options =
2521+
static_cast<MTL::AccelerationStructureInstanceOptions>(Src.Flags);
25192522
D.mask = Src.InstanceMask;
25202523
D.intersectionFunctionTableOffset = 0;
25212524
D.accelerationStructureIndex = InstanceASIdx[I];

lib/API/VK/Device.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4399,7 +4399,9 @@ llvm::Error VKComputeEncoder::batchBuildAS(llvm::ArrayRef<ASBuildItem> Items) {
43994399
NI.mask = Inst.InstanceMask;
44004400
NI.instanceShaderBindingTableRecordOffset =
44014401
Inst.InstanceContributionToHitGroupIndex & 0xFFFFFFu;
4402-
NI.flags = 0;
4402+
// Bits in AccelerationStructureInstanceFlags match
4403+
// VkGeometryInstanceFlagBitsKHR by design.
4404+
NI.flags = static_cast<VkGeometryInstanceFlagsKHR>(Inst.Flags);
44034405
auto *BLASPtr = llvm::cast<VulkanAccelerationStructure>(Inst.BLAS);
44044406
NI.accelerationStructureReference = BLASPtr->getDeviceAddress();
44054407
Native.push_back(NI);

lib/Support/Pipeline.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -670,6 +670,7 @@ void MappingTraits<offloadtest::InstanceDesc>::mapping(
670670
D.InstanceMask = static_cast<uint8_t>(Mask);
671671
I.mapOptional("InstanceContributionToHitGroupIndex",
672672
D.InstanceContributionToHitGroupIndex, 0u);
673+
I.mapOptional("InstanceFlags", D.Flags, offloadtest::InstanceFlagNone);
673674
}
674675

675676
void MappingTraits<offloadtest::TLASDesc>::mapping(IO &I,
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
#--- source.hlsl
2+
3+
[[vk::binding(0, 0)]] RaytracingAccelerationStructure Scene : register(t0);
4+
[[vk::binding(1, 0)]] RWStructuredBuffer<uint> Output : register(u0);
5+
6+
[numthreads(2,1,1)]
7+
void main(uint3 tid : SV_DispatchThreadID) {
8+
// The triangle vertices wind CW from +z under the DX / VK / MTL ray-
9+
// traversal convention. Two instances tiled along x: instance 0 has no
10+
// flags (front-facing), instance 1 has TriangleFrontCounterclockwise
11+
// (winding interpretation flips → back-facing).
12+
RayDesc Ray;
13+
Ray.Origin = float3((float(tid.x) - 0.5) * 4.0, 0, 1);
14+
Ray.Direction = float3(0, 0, -1);
15+
Ray.TMin = 0.0;
16+
Ray.TMax = 100.0;
17+
RayQuery<RAY_FLAG_NONE> Q;
18+
Q.TraceRayInline(Scene, RAY_FLAG_NONE, 0xFF, Ray);
19+
Q.Proceed();
20+
Output[tid.x] = Q.CommittedStatus() == COMMITTED_TRIANGLE_HIT
21+
? (uint)Q.CommittedTriangleFrontFace()
22+
: 0xFFFFFFFF;
23+
}
24+
//--- pipeline.yaml
25+
---
26+
Shaders:
27+
- Stage: Compute
28+
Entry: main
29+
Buffers:
30+
- Name: Vertices
31+
Format: Float32
32+
Stride: 12
33+
Data: [ 0.0, 1.0, 0.0, -1.0, -1.0, 0.0, 1.0, -1.0, 0.0 ]
34+
- Name: Output
35+
Format: UInt32
36+
Stride: 4
37+
FillSize: 8
38+
- Name: Expected
39+
Format: UInt32
40+
Stride: 4
41+
# Instance 0: default winding → front face (1)
42+
# Instance 1: TriangleFrontCounterclockwise flips → back face (0)
43+
Data: [ 1, 0 ]
44+
AccelerationStructures:
45+
BLAS:
46+
- Name: TriangleBLAS
47+
Triangles:
48+
- VertexBuffer: Vertices
49+
VertexFormat: RGB32Float
50+
VertexStride: 12
51+
VertexCount: 3
52+
TLAS:
53+
- Name: Scene
54+
Instances:
55+
- BLAS: TriangleBLAS
56+
Transform: [1, 0, 0, -2, 0, 1, 0, 0, 0, 0, 1, 0]
57+
- BLAS: TriangleBLAS
58+
Transform: [1, 0, 0, 2, 0, 1, 0, 0, 0, 0, 1, 0]
59+
InstanceFlags: [TriangleFrontCounterclockwise]
60+
DescriptorSets:
61+
- Resources:
62+
- Name: Scene
63+
Kind: AccelerationStructure
64+
DirectXBinding:
65+
Register: 0
66+
Space: 0
67+
VulkanBinding:
68+
Binding: 0
69+
- Name: Output
70+
Kind: RWStructuredBuffer
71+
DirectXBinding:
72+
Register: 0
73+
Space: 0
74+
VulkanBinding:
75+
Binding: 1
76+
Results:
77+
- Result: InstanceFlags
78+
Rule: BufferExact
79+
Actual: Output
80+
Expected: Expected
81+
...
82+
#--- end
83+
84+
# REQUIRES: acceleration-structure
85+
# XFAIL: Clang
86+
87+
# RUN: split-file %s %t
88+
# RUN: %dxc_target -T cs_6_5 -Fo %t.o %t/source.hlsl
89+
# RUN: %offloader %t/pipeline.yaml %t.o

0 commit comments

Comments
 (0)