Skip to content

Commit 9a0768d

Browse files
authored
spirv: correctly choose ray_tracing/ray_query caps (microsoft#5662)
Both the ray_query and ray_tracing extensions brings new SPIRV types. But some hardware only support one type. This decision cannot be taken by the trimming pass as both choices could be valid, instead, we should check what extension the user needed. What can be removed however is the logic to emit the capability. This commit also does that. Fixes microsoft#4385 Signed-off-by: Nathan Gauër <[email protected]>
1 parent 21d4cb5 commit 9a0768d

File tree

4 files changed

+62
-19
lines changed

4 files changed

+62
-19
lines changed

tools/clang/lib/SPIRV/CapabilityVisitor.cpp

Lines changed: 21 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -23,15 +23,18 @@ void CapabilityVisitor::addExtension(Extension ext, llvm::StringRef target,
2323
spvBuilder.requireExtension(featureManager.getExtensionName(ext), loc);
2424
}
2525

26-
void CapabilityVisitor::addExtensionAndCapabilitiesIfEnabled(
26+
bool CapabilityVisitor::addExtensionAndCapabilitiesIfEnabled(
2727
Extension ext, llvm::ArrayRef<spv::Capability> capabilities) {
28-
if (featureManager.isExtensionEnabled(ext)) {
29-
addExtension(ext, "", {});
28+
if (!featureManager.isExtensionEnabled(ext)) {
29+
return false;
30+
}
3031

31-
for (auto cap : capabilities) {
32-
addCapability(cap);
33-
}
32+
addExtension(ext, "", {});
33+
34+
for (auto cap : capabilities) {
35+
addCapability(cap);
3436
}
37+
return true;
3538
}
3639

3740
void CapabilityVisitor::addCapability(spv::Capability cap, SourceLocation loc) {
@@ -225,18 +228,6 @@ void CapabilityVisitor::addCapabilityForType(const SpirvType *type,
225228
for (auto field : structType->getFields())
226229
addCapabilityForType(field.type, loc, sc);
227230
}
228-
// AccelerationStructureTypeNV and RayQueryTypeKHR type
229-
// Note: Because AccelerationStructureType can be provided by both
230-
// SPV_KHR_ray_query and SPV_{NV,KHR}_ray_tracing extensions, this logic will
231-
// result in SPV_KHR_ray_query being unnecessarily required in some cases. If
232-
// this is an issue in future (more devices are identified that support
233-
// ray_tracing but not ray_query), then we should consider addressing this
234-
// interaction with a spirv-opt pass instead.
235-
else if (isa<AccelerationStructureTypeNV>(type) ||
236-
isa<RayQueryTypeKHR>(type)) {
237-
addCapability(spv::Capability::RayQueryKHR);
238-
addExtension(Extension::KHR_ray_query, "SPV_KHR_ray_query", {});
239-
}
240231
}
241232

242233
bool CapabilityVisitor::visit(SpirvDecoration *decor) {
@@ -888,6 +879,18 @@ bool CapabilityVisitor::visit(SpirvModule *, Visitor::Phase phase) {
888879
spv::Capability::FragmentShaderPixelInterlockEXT,
889880
spv::Capability::FragmentShaderShadingRateInterlockEXT,
890881
});
882+
883+
// AccelerationStructureType or RayQueryType can be provided by both
884+
// ray_tracing and ray_query extension. By default, we select ray_query to
885+
// provide it. This is an arbitrary decision. If the user wants avoid one
886+
// extension (lack of support by ex), if can be done by providing the list
887+
// of enabled extensions.
888+
if (!addExtensionAndCapabilitiesIfEnabled(Extension::KHR_ray_query,
889+
{spv::Capability::RayQueryKHR})) {
890+
addExtensionAndCapabilitiesIfEnabled(Extension::KHR_ray_tracing,
891+
{spv::Capability::RayTracingKHR});
892+
}
893+
891894
return true;
892895
}
893896

tools/clang/lib/SPIRV/CapabilityVisitor.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,8 @@ class CapabilityVisitor : public Visitor {
6666

6767
/// Checks that the given extension is enabled based on command line arguments
6868
/// before calling addExtension and addCapability.
69-
void addExtensionAndCapabilitiesIfEnabled(
69+
/// Returns `true` if the extension was enabled, `false` otherwise.
70+
bool addExtensionAndCapabilitiesIfEnabled(
7071
Extension ext, llvm::ArrayRef<spv::Capability> capabilities);
7172

7273
/// Checks that the given capability is a valid capability. And if so,
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
// RUN: %dxc -E main -T vs_6_5 -fspv-target-env=vulkan1.2 -fspv-extension=SPV_KHR_ray_query %s -spirv | FileCheck %s
2+
3+
// CHECK-NOT: OpCapability RayTracingKHR
4+
// CHECK: OpCapability RayQueryKHR
5+
// CHECK: OpCapability Shader
6+
// CHECK-NEXT: OpExtension "SPV_KHR_ray_query"
7+
// CHECK-NOT: OpExtension "SPV_KHR_ray_tracing"
8+
9+
RaytracingAccelerationStructure test_bvh;
10+
11+
float main(RayDesc rayDesc : RAYDESC) : OUT {
12+
RayQuery<RAY_FLAG_FORCE_OPAQUE|RAY_FLAG_SKIP_PROCEDURAL_PRIMITIVES> rayQuery1;
13+
rayQuery1.TraceRayInline(test_bvh, 0, 1, rayDesc);
14+
return 0;
15+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
// RUN: %dxc -E main -T lib_6_6 -fspv-target-env=vulkan1.2 -fspv-extension=SPV_KHR_ray_tracing %s -spirv | FileCheck %s
2+
3+
// CHECK-NOT: OpCapability RayQueryKHR
4+
// CHECK: OpCapability RayTracingKHR
5+
// CHECK-NEXT: OpExtension "SPV_KHR_ray_tracing"
6+
// CHECK-NOT: OpExtension "SPV_KHR_ray_query"
7+
8+
RaytracingAccelerationStructure rs;
9+
10+
struct Payload { float4 color; };
11+
struct Attribute { float2 bary; };
12+
13+
[shader("closesthit")]
14+
void main(inout Payload MyPayload, in Attribute MyAttr) {
15+
16+
Payload myPayload = { float4(0.0f,0.0f,0.0f,0.0f) };
17+
RayDesc rayDesc;
18+
rayDesc.Origin = float3(0.0f, 0.0f, 0.0f);
19+
rayDesc.Direction = float3(0.0f, 0.0f, -1.0f);
20+
rayDesc.TMin = 0.0f;
21+
rayDesc.TMax = 1000.0f;
22+
23+
TraceRay(rs, 0x0, 0xff, 0, 1, 0, rayDesc, myPayload);
24+
}

0 commit comments

Comments
 (0)