[SPIR-V] Add descriptor heap RaytracingAccelerationStructure support - #8518
[SPIR-V] Add descriptor heap RaytracingAccelerationStructure support#8518Jonathan Zakharov (jzakharovnv) wants to merge 13 commits into
Conversation
|
✅ With the latest revision this PR passed the C/C++ code formatter. |
d899b05 to
b12b9ea
Compare
|
@microsoft-github-policy-service agree company="NVIDIA" |
b12b9ea to
23eca97
Compare
| return true; | ||
| } | ||
|
|
||
| if (isRaytracingAccelerationStructure(decl->getType())) { |
There was a problem hiding this comment.
Since acceleration structures are distinct from image and buffers, do they still fit in max(sizeof(image), sizeof(buffer))? If not, the stride will be too small and heap indexing will land in the wrong spot.
Maybe we need to incorporate acceleration structures when computing the default stride if RT is used?
There was a problem hiding this comment.
Good catch, it would be correct to include acceleration structures in the computation for the resource heap stride. Will address this in my next set of commits.
There was a problem hiding this comment.
| @@ -0,0 +1,42 @@ | |||
| // RUN: %dxc -T lib_6_6 -fspv-use-descriptor-heap -fspv-target-env=vulkan1.3 -fvk-resource-heap-stride 64 -fvk-sampler-heap-stride 32 -fspv-extension=SPV_KHR_ray_tracing -fspv-extension=SPV_EXT_descriptor_heap -fspv-extension=SPV_KHR_untyped_pointers -spirv %s | FileCheck %s | |||
There was a problem hiding this comment.
Another result of some clumsy commits and now outdated commits! Should be able to remove the usage of these flags now that strides are computed automatically. Will address next set of commits.
There was a problem hiding this comment.
Addressed with removed erronous CLI options from test
23aff82 to
02f3581
Compare
Diego Novillo (dnovillo)
left a comment
There was a problem hiding this comment.
Only a question left on detecting RT usage of the heap.
| if (shaderModelKindIsRayTracing(fi->shaderModelKind)) { | ||
| needsAccelStruct = true; | ||
| break; | ||
| } |
There was a problem hiding this comment.
This would fail for compute/graphics shaders that need to use RayQuery and have AS on the heap. I think this should be a translation unit walk looking for a vardecls and setting the flag on the first match.
There was a problem hiding this comment.
This ended up being a much harder problem than I anticipated. I filed an issue with #8714 and have provided some work arounds in a revised Included AccelerationStructure in resource heap stride calculation. There also exists the work around of using the options provided in [SPIR-V] Add -fvk-resource-heap-stride / -fvk-sampler-heap-stride.
There was a problem hiding this comment.
This ended up being a much harder problem than I anticipated. I filed an issue with #8714 and have provided some work arounds in a revised Included AccelerationStructure in resource heap stride calculation. There also exists the work around of using the options provided in [SPIR-V] Add -fvk-resource-heap-stride / -fvk-sampler-heap-stride.
Sure. Thanks for documenting workarounds. I think this is now ready.
Building off of microsoft#8281, this commit adds a native lowering via SPV_EXT_descriptor_heap and SPV_KHR_untyped_pointers. ResourceDescriptorHeap and SamplerDescriptorHeap are lowered to untyped variables decorated with ResourceHeapEXT and SamplerHeapEXT. Each heap access emits OpUntypedAccessChainKHR into a runtime array of the appropriate descriptor type. Buffer-like resources (StructuredBuffer, ByteAddressBuffer, ConstantBuffer, TextureBuffer) use OpTypeBufferEXT and OpBufferPointerEXT; image and sampler resources use OpLoad. Interlocked operations on RWTexture use OpUntypedImageTexelPointerEXT. Requires -fspv-target-env=vulkan1.3. Assisted-by: Claude.
6293723 to
20dd181
Compare
There was a problem hiding this comment.
Pull request overview
Extends native SPIR-V descriptor-heap lowering to acceleration structures and broader resource operations.
Changes:
- Adds descriptor-size-based heap strides, including acceleration structures.
- Adds native buffer, image, sampler, atomic, and alias lowering.
- Expands SPIR-V tests and documentation.
Reviewed changes
Copilot reviewed 51 out of 51 changed files in this pull request and generated 15 comments.
Show a summary per file
| File | Description |
|---|---|
tools/clang/unittests/SPIRV/SpirvContextTest.cpp |
Extends runtime-array uniqueness tests. |
tools/clang/test/CodeGenSPIRV/sm6_6.descriptorheap.ext.typed-formats.hlsl |
Tests typed image formats. |
tools/clang/test/CodeGenSPIRV/sm6_6.descriptorheap.ext.texturecube.hlsl |
Tests cube textures and samplers. |
tools/clang/test/CodeGenSPIRV/sm6_6.descriptorheap.ext.texture.hlsl |
Tests texel buffers. |
tools/clang/test/CodeGenSPIRV/sm6_6.descriptorheap.ext.texture-sampler-assignment.hlsl |
Tests resource reassignment. |
tools/clang/test/CodeGenSPIRV/sm6_6.descriptorheap.ext.texture-ms.hlsl |
Tests multisampled textures. |
tools/clang/test/CodeGenSPIRV/sm6_6.descriptorheap.ext.texture-dims.hlsl |
Tests sampled-texture dimensions. |
tools/clang/test/CodeGenSPIRV/sm6_6.descriptorheap.ext.structured-buffer-atomic.hlsl |
Tests structured-buffer atomics. |
tools/clang/test/CodeGenSPIRV/sm6_6.descriptorheap.ext.static-global.hlsl |
Tests static global resources. |
tools/clang/test/CodeGenSPIRV/sm6_6.descriptorheap.ext.sampler-comparison.hlsl |
Tests comparison samplers. |
tools/clang/test/CodeGenSPIRV/sm6_6.descriptorheap.ext.sample-grad-bias.hlsl |
Tests gradient and bias sampling. |
tools/clang/test/CodeGenSPIRV/sm6_6.descriptorheap.ext.rwtexture-dims.hlsl |
Tests storage-texture dimensions. |
tools/clang/test/CodeGenSPIRV/sm6_6.descriptorheap.ext.rwtexture-atomics.hlsl |
Tests untyped image atomics. |
tools/clang/test/CodeGenSPIRV/sm6_6.descriptorheap.ext.rwbyteaddressbuffer.hlsl |
Tests writable byte buffers. |
tools/clang/test/CodeGenSPIRV/sm6_6.descriptorheap.ext.nonuniform.hlsl |
Tests nonuniform-index handling. |
tools/clang/test/CodeGenSPIRV/sm6_6.descriptorheap.ext.mixed-bound.hlsl |
Tests bound and heap resources together. |
tools/clang/test/CodeGenSPIRV/sm6_6.descriptorheap.ext.load-offset.hlsl |
Tests texture-load offsets. |
tools/clang/test/CodeGenSPIRV/sm6_6.descriptorheap.ext.groupshared.hlsl |
Tests groupshared interoperability. |
tools/clang/test/CodeGenSPIRV/sm6_6.descriptorheap.ext.gather.hlsl |
Tests texture gather operations. |
tools/clang/test/CodeGenSPIRV/sm6_6.descriptorheap.ext.function-params.hlsl |
Tests resource function parameters. |
tools/clang/test/CodeGenSPIRV/sm6_6.descriptorheap.ext.discarded.error.hlsl |
Tests discarded-access diagnostics. |
tools/clang/test/CodeGenSPIRV/sm6_6.descriptorheap.ext.counter-ops.error.hlsl |
Tests unsupported counter diagnostics. |
tools/clang/test/CodeGenSPIRV/sm6_6.descriptorheap.ext.constant-texture-buffer.hlsl |
Tests constant and texture buffers. |
tools/clang/test/CodeGenSPIRV/sm6_6.descriptorheap.ext.constant-buffer-assignment.hlsl |
Tests constant-buffer reassignment. |
tools/clang/test/CodeGenSPIRV/sm6_6.descriptorheap.ext.buffer.hlsl |
Tests native buffer lowering. |
tools/clang/test/CodeGenSPIRV/sm6_6.descriptorheap.ext.array-stride.hlsl |
Tests shared heap strides. |
tools/clang/test/CodeGenSPIRV/sm6_6.descriptorheap.ext.array-stride.accelstruct.hlsl |
Tests acceleration-structure stride inclusion. |
tools/clang/test/CodeGenSPIRV/sm6_6.descriptorheap.ext.append-consume.error.hlsl |
Tests append/consume diagnostics. |
tools/clang/test/CodeGenSPIRV/sm6_6.descriptorheap.ext.acceleration-structure.stride.error.hlsl |
Tests missing acceleration stride diagnostics. |
tools/clang/test/CodeGenSPIRV/sm6_6.descriptorheap.ext.acceleration-structure.hlsl |
Tests acceleration-structure heap loads. |
tools/clang/test/CodeGenSPIRV/resource-heap-ext-texture.hlsl |
Removes the superseded aggregate test. |
tools/clang/lib/SPIRV/SpirvType.cpp |
Includes stride IDs in type equality. |
tools/clang/lib/SPIRV/SpirvInstruction.cpp |
Implements new SPIR-V instructions. |
tools/clang/lib/SPIRV/SpirvEmitter.h |
Declares heap-lowering and alias state. |
tools/clang/lib/SPIRV/SpirvEmitter.cpp |
Implements native heap lowering and acceleration support. |
tools/clang/lib/SPIRV/SpirvContext.cpp |
Canonicalizes buffer and runtime-array types. |
tools/clang/lib/SPIRV/SpirvBuilder.cpp |
Builds descriptor-size constants and strides. |
tools/clang/lib/SPIRV/LowerTypeVisitor.cpp |
Lowers untyped image pointers. |
tools/clang/lib/SPIRV/EmitVisitor.h |
Declares new emission handlers. |
tools/clang/lib/SPIRV/EmitVisitor.cpp |
Emits new instructions and decorations. |
tools/clang/lib/SPIRV/DeclResultIdMapper.h |
Declares function-variable aliases. |
tools/clang/lib/SPIRV/DeclResultIdMapper.cpp |
Registers function-variable aliases. |
tools/clang/lib/SPIRV/CapabilityVisitor.cpp |
Enforces Vulkan 1.3 for native heaps. |
tools/clang/lib/SPIRV/AstTypeProbe.cpp |
Recognizes acceleration-structure types. |
tools/clang/include/clang/SPIRV/SpirvVisitor.h |
Adds visitor methods. |
tools/clang/include/clang/SPIRV/SpirvType.h |
Stores runtime-array stride IDs. |
tools/clang/include/clang/SPIRV/SpirvInstruction.h |
Defines new instruction classes. |
tools/clang/include/clang/SPIRV/SpirvContext.h |
Extends type-context APIs. |
tools/clang/include/clang/SPIRV/SpirvBuilder.h |
Exposes descriptor-stride builders. |
tools/clang/include/clang/SPIRV/AstTypeProbe.h |
Declares acceleration-type probing. |
docs/SPIR-V.rst |
Documents native descriptor heaps. |
Comments suppressed due to low confidence (1)
tools/clang/lib/SPIRV/SpirvEmitter.cpp:7072
- Only casts are stripped here, so a syntactically valid parenthesized heap base such as
(ResourceDescriptorHeap)[i]is diagnosed as unsupported even though it still refers directly to the builtin variable. UseIgnoreParenCasts()consistently when resolving the base declaration.
const auto *declRefExpr = dyn_cast<DeclRefExpr>(baseExpr->IgnoreCasts());
const auto *decl =
declRefExpr ? dyn_cast<VarDecl>(declRefExpr->getDecl()) : nullptr;
if (!decl) {
emitError("unsupported ResourceDescriptorHeap/SamplerDescriptorHeap "
"expression",
baseExpr->getExprLoc());
return nullptr;
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| // (Dim2D, depth=0, not-arrayed, non-MS, sampled, Unknown format), so | ||
| // %[[TexDesc]] serves as both the placeholder for the size calculation and | ||
| // the real descriptor type for the Texture2D access below. | ||
| // CHECK-DAG: %[[TexDesc:[a-zA-Z0-9_]+]] = OpTypeImage %float 2D 0 0 0 1 Unknown |
There was a problem hiding this comment.
Fixing test in next set of commits
|
|
||
| // --- Types (user-declared + stride-computation placeholders) --------------- | ||
| // CHECK-DAG: %[[Accel:[a-zA-Z0-9_]+]] = OpTypeAccelerationStructureKHR | ||
| // CHECK-DAG: %[[Img:[a-zA-Z0-9_]+]] = OpTypeImage %float 2D 0 0 0 1 Unknown |
There was a problem hiding this comment.
Fixing test in next set of commits
| if (!needsAccelStruct && !spirvOptions.allowedExtensions.empty()) | ||
| needsAccelStruct = | ||
| featureManager.isExtensionEnabled(Extension::KHR_ray_tracing) || | ||
| featureManager.isExtensionEnabled(Extension::NV_ray_tracing) || | ||
| featureManager.isExtensionEnabled(Extension::KHR_ray_query); |
There was a problem hiding this comment.
| The concrete descriptor type is selected at each heap access. For image, | ||
| sampler, and texel buffer resources, DXC forms a runtime array of that | ||
| descriptor type and decorates the array with a byte ``ArrayStride``, then uses | ||
| ``OpUntypedAccessChainKHR`` followed by ``OpLoad``: |
There was a problem hiding this comment.
Fixing documentation in next set of commits
|
|
||
| // Three distinct descriptor heap sizes exist: | ||
| // the image/Texture2D type (%[[TexDesc]]), the Uniform buffer, and the sampler. | ||
| // Regression test: make sure of no per-element nor per acces behavior exists |
There was a problem hiding this comment.
Fixing test in next set of commits
| auto &alias = descriptorHeapImageAliasVars[dstVar]; | ||
| if (!alias.indexVar) | ||
| alias.indexVar = createDescriptorHeapIndexVar(dstVar); | ||
| alias.imageType = found->second.imageType; | ||
| alias.arrayType = found->second.arrayType; | ||
| alias.heap = found->second.heap; | ||
| storeDescriptorHeapIndex(alias.indexVar, found->second.index, | ||
| found->second.indexType, srcExpr); |
| This path supports texture, RWTexture, sampler, Buffer/RWBuffer, | ||
| StructuredBuffer/RWStructuredBuffer without associated counter operations, | ||
| ByteAddressBuffer/RWByteAddressBuffer, ConstantBuffer, and TextureBuffer heap | ||
| loads, including direct field and array-element accesses for | ||
| ``ConstantBuffer<T>`` and ``TextureBuffer<T>``. ``NonUniformResourceIndex`` is |
| // The heap index expression must be immediately converted to a concrete | ||
| // resource type (an implicit cast inserted by the front-end). If the | ||
| // parent is missing or is not a cast (e.g. the result is discarded as | ||
| // a statement, or used in a context with no target resource type) we | ||
| // cannot determine the resource type. | ||
| const auto *parentExpr = | ||
| dyn_cast_or_null<CastExpr>(parentMap->getParent(expr)); | ||
| if (!parentExpr) { | ||
| emitError("ResourceDescriptorHeap/SamplerDescriptorHeap indexing must " | ||
| "be used as a resource", | ||
| expr->getExprLoc()); | ||
| return nullptr; |
| emitError("acceleration structure loaded from ResourceDescriptorHeap " | ||
| "requires the resource heap stride to account for " | ||
| "acceleration structure descriptors; compile with " | ||
| "-fspv-extension=SPV_KHR_ray_tracing or " | ||
| "-fspv-extension=SPV_KHR_ray_query", | ||
| expr->getExprLoc()); |
|
|
||
| EXPECT_NE(spvContext.getRuntimeArrayType(int32, llvm::None), | ||
| spvContext.getRuntimeArrayType(int32, 32)); |
There was a problem hiding this comment.
Will fix in next set of commits.
|
Extends the SPV_EXT_descriptor_heap native heap lowering to cover RaytracingAccelerationStructure resources loaded from ResourceDescriptorHeap. Acceleration structure descriptors are accessed via OpUntypedAccessChainKHR into a runtime array of OpTypeAccelerationStructureKHR, consistent with the image and sampler paths added in the previous commit.
20dd181 to
568efbb
Compare
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 52 out of 52 changed files in this pull request and generated 1 comment.
Suppressed comments (3)
tools/clang/lib/SPIRV/SpirvEmitter.cpp:5315
- A heap-to-heap reassignment of
RaytracingAccelerationStructurealso reaches this branch becausemixingDetectedincludes(isASType && wasHeap)regardless ofsrcIsHeap. That assignment does not mix bound and heap resources, so this diagnostic is misleading; report the unsupported AS reassignment separately.
emitError("mixing bound and descriptor heap resources in the same variable "
"is not supported with SPV_EXT_descriptor_heap",
loc);
tools/clang/test/CodeGenSPIRV/sm6_6.descriptorheap.ext.array-stride.hlsl:62
- Use the possessive “its” rather than “it's” (“it is”).
// The sampler array just uses the sampler size as it's stride.
docs/SPIR-V.rst:2089
- This is a significant user-visible compiler feature, but
docs/ReleaseNotes.mdhas no native descriptor-heap entry. Please add release-note coverage, or point to the shared release note planned for this four-PR series.
When ``-fspv-use-descriptor-heap`` is specified, DXC lowers
``ResourceDescriptorHeap`` and ``SamplerDescriptorHeap`` through
``SPV_EXT_descriptor_heap`` instead of the default emulated heap path. This
also requires ``SPV_KHR_untyped_pointers`` and ``-fspv-target-env=vulkan1.3``
| (void)doExpr(init->IgnoreParenCasts()); | ||
| tryToAssignDescriptorHeapBufferAlias(decl, init); | ||
| return true; |
There was a problem hiding this comment.
Good catch, will fix
|
Added an analysis on this series: #8517 (comment) |
Building off of #8517, this PR extends the SPV_EXT_descriptor_heap native heap lowering to cover RaytracingAccelerationStructure resources loaded from ResourceDescriptorHeap. It is part 2/4 in a series.
Acceleration structure descriptors are accessed via OpUntypedAccessChainKHR into a runtime array of OpTypeAccelerationStructureKHR, consistent with the image and sampler paths added in the previous commit.
Assisted by an AI agent
Diego Novillo (@dnovillo)