Skip to content

[DX] Sparse / reserved Texture2D + RWTexture2D support (#1050)#1234

Draft
alsepkow wants to merge 12 commits into
llvm:mainfrom
alsepkow:alex/dx-sparse-1050
Draft

[DX] Sparse / reserved Texture2D + RWTexture2D support (#1050)#1234
alsepkow wants to merge 12 commits into
llvm:mainfrom
alsepkow:alex/dx-sparse-1050

Conversation

@alsepkow

@alsepkow alsepkow commented May 27, 2026

Copy link
Copy Markdown
Collaborator

EXPERIMENTAL - NOT FOR REVIEW

AI-assisted exploration driving design discussion for llvm/wg-hlsl#400. Not intended for review/merge in current form.

Adds D3D12 backend support for sparse (reserved) Texture2D and RWTexture2D resources via CreateReservedResource plus UpdateTileMappings, with tile-precise data-behavior tests covering both fully-mapped and partial-mapping cases.

The schema gains Resource.IsReserved and Resource.TilesMapped. In lib/API/DX/Device.cpp, setupReservedResource is now texture-aware: it queries the texture's standard tile shape via GetResourceTiling, creates the placed resource with ID3D12Device::CreateReservedResource, and binds tile mappings to a single backing ID3D12Heap via UpdateTileMappings driven by TilesMapped. Validation in getResourceDescription ensures any resource declared with tile mappings is also flagged reserved. Capabilities.h exposes TiledResourcesTier for REQUIRES gating.

Tests live under Feature/Sparse: Reserved2DTexture.basic, Reserved2DTexture.unmapped, Reserved2DTexture.partial-mapping, Reserved2DTexture.partial-mapping-grid (2x2 checkerboard), and ReservedRWTexture2D.basic. All five PASS on d3d12 (NVIDIA RTX 5060 Ti) and warp-d3d12.

Build is clean on Windows MSVC. Regression sweep on Sparse|HLSLLib|Textures|Basic|Semantics|Bugs|ViewInstancing|MSAA shows no new failures (3 baseline failures on NVIDIA: Mandelbrot, PartiallyMappedResources buffer, firstbit*.64 XPASS).

Deferred: VK port (vkQueueBindSparse + sparseResidencyImage2D) is on the parent issue. Sparse UAV partial-mapping coverage would need a shader-side reduction since Result.Offset / Result.Size are buffer-only; the fully-mapped UAV case is covered here. CheckAccessFullyMapped on Texture2D returned true for unmapped tiles on both NVIDIA and WARP (it works correctly for buffers); data-behavior coverage is the meaningful signal, so a status-bit test is deferred until a runtime path actually distinguishes.

Refs #1050


Assisted by Claude Opus 4.7.

Copilot AI and others added 12 commits May 26, 2026 23:52
Extends the existing reserved-resource path (previously buffer-only) to handle Texture2D sparse resources correctly:

* Adds getNumTilesForTexture() which calls ID3D12Device::GetResourceTiling to learn the true tile count of a sparse Texture2D, since ResDesc.Width for a texture is in pixels (not bytes) and the previous getNumTiles math would under-report the standard 64KB tile count.

* setupReservedResource now branches on ResDesc.Dimension so buffers continue to use the byte-based calculation while textures use the runtime-reported tile count.

Adds two foundational tests in test/Feature/Sparse/:

* Reserved2DTexture.basic.test - 64x64 RGBA32 sparse Texture2D (exactly one standard tile), TilesMapped unset so the default "map every tile" path is exercised; compute shader copies every texel into a flat structured buffer for a BufferExact round-trip check. PASSes on d3d12 (RTX 5060 Ti) and warp-d3d12.

* Reserved2DTexture.unmapped.test - same texture, TilesMapped: 0 so no heap is attached. Verifies create/bind/dispatch plumbing without sampling the unmapped tile (which is undefined on Tiled Resources Tier 1 hardware).

Both tests UNSUPPORTED on Vulkan/Metal until those backends gain a sparse-texture equivalent, and XFAIL on Clang pending Texture2D Load/Sample intrinsic lowering.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Exercises the per-tile mapping path wired in the previous commit by

creating a 128x64 RGBA32 reserved Texture2D (2 standard 64KB tiles),

mapping only the first tile via TilesMapped: 1, and verifying that

Texture2D.Load returns the uploaded data for the mapped tile and zero

for the unmapped tile. CheckAccessFullyMapped on Tex2D is intentionally

not asserted: current NVIDIA and warp drivers report status unreliably

for tiled textures even though it works for buffers.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Adds a 128x128 RGBA32 sparse texture (2x2 tile grid) with TilesMapped: 2.

The first two tiles form the top row of the tile grid; the bottom row is

left unmapped. Reads from each quadrant verify that the contiguous

first-N-tiles mapping spans tile rows correctly: the existing

partial-mapping test only covers a single row of tiles (2x1 grid).

Passes on RTX 5060 Ti and WARP.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Adds a sparse / reserved RWTexture2D smoke test that exercises the UAV

code path through createUAV + setupReservedResource. A 64x64 RGBA32

fully-mapped sparse RWTexture2D is written by a compute shader (copying

from a normal Texture2D SRV with a .bgra swizzle) and the readback

verifies the data round-trips. Companion to Reserved2DTexture.basic.test

which covers only the SRV path.

Passes on RTX 5060 Ti.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Picks up the DriverVer fix (upstream llvm#1228) so clang-tidy stops failing on Device.cpp.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Fixes misc-const-correctness warnings-as-errors from clang-tidy in CI.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…branch

The previous commit on this branch picked up uncommitted lines from a parallel branch checkout (PowerShell script raced with a sibling branch's working tree). That VRS Tier2 capability query belongs to llvm#1044, not the sparse-texture PR. Removed.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The shared YAML 'IsReserved' field is honored only by DX today; VK and
MTL silently created non-sparse resources, breaking the shared contract.
Add explicit not-supported errors so the divergence is visible.

Tests in Feature/Sparse already mark themselves UNSUPPORTED: Vulkan,Metal,
so this guard is belt-and-suspenders and exists to keep the contract
honest across backends.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The shader does not Load the texture (only verifies create/bind/dispatch),
so clang-dxc passes cleanly on both clang-d3d12 and clang-warp-d3d12.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…grid}

Both tests declare status for Texture2D.Load but never read it — only the
data return value is BufferExact-checked. clang-dxc compiles the Load
overload cleanly (the status output is just an unused parameter), and CI
confirms both tests XPASS on windows-intel and windows-nvidia clang-d3d12.

Mirrors bb01e34 which removed the same stale marker from
Reserved2DTexture.unmapped for the same reason.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants