Skip to content

Add PhysicalStorageBuffer support via PhysicalPtr<T> - #699

Open
dsvensson wants to merge 6 commits into
Rust-GPU:mainfrom
dsvensson:physical_storage
Open

dsvensson wants to merge 6 commits into
Rust-GPU:mainfrom
dsvensson:physical_storage

Conversation

@dsvensson

@dsvensson dsvensson commented Nov 11, 2026 •

Copy link
Copy Markdown

This adds spirv_std::ptr::PhysicalPtr<T>, a typed 64-bit device address for buffer device address / PhysicalStorageBuffer.

It picks up where #237 left off (thanks to Joerg Wollenschlaeger for the original work), but it's a much smaller change. PhysicalPtr is just a u64 and all pointer math happens on the integer. It only becomes a real pointer at the point of access. That leaves three small things for the linker:

  • infer the PhysicalStorageBuffer storage class for the result of OpConvertUToPtr
  • switch to PhysicalStorageBuffer64 addressing when a module has such pointers
  • add the required Aligned operand to loads and stores through them

Nothing in codegen changes, pointer width (#238) is left alone, and shaders that don't use PhysicalPtr compile to exactly what they did before. The first commit also turns #[spirv(physical_storage_buffer)] on an entry-point parameter into an error; it used to produce invalid SPIR-V.

A big chunk of the PR is the difftest, let me know if you want me to do it in some other way.

I've been running variations of this branch for my lightmap baker the past ~6 months to be able to work with >4GB buffers, as well as better ergonomy, and it has been working great.

Related: #119, #237

dsvensson and others added 6 commits November 11, 2026 18:44
…eters.

`PhysicalStorageBuffer` pointers are made from addresses at runtime, so no
interface variable can have that storage class.

Co-authored-by: Joerg Wollenschlaeger <joerg.wollenschlaeger@gmail.com>
…tr`.

Storage class inference was only seeded by `OpVariable`, so a pointer made
from an integer fell back to `Function`. In shaders such a pointer can only
be a `PhysicalStorageBuffer` one, which its instruction signature now states.

`Builder::inttoptr` emits `OpConvertUToPtr` too, always as a zombie. Those
keep their previous inference: with `--no-early-report-zombies` a conflict
would otherwise abort compilation before the zombie gets reported.
…sical pointers.

The presence of `PhysicalStorageBuffer` pointer types decides this, not the
capability: `spirv-val` skips its logical pointer checks for a whole module
under `PhysicalStorageBuffer64`, so modules without such pointers stay
`Logical`.

Co-authored-by: Joerg Wollenschlaeger <joerg.wollenschlaeger@gmail.com>
…nters.

SPIR-V requires it on every such load and store, but codegen cannot tell
which accesses those are before storage classes are inferred. The alignment
used is the size of the largest scalar in the pointee, which Vulkan requires
of such accesses anyway. An `Aligned` written in `asm!` is kept.
A typed 64-bit device address, for memory in the `PhysicalStorageBuffer`
storage class (Vulkan's `bufferDeviceAddress`). Address arithmetic is done
on the integer; `as_ptr` turns it into a pointer with `OpConvertUToPtr`.

Co-authored-by: Joerg Wollenschlaeger <joerg.wollenschlaeger@gmail.com>
`AshBackend` can now be created with `bufferDeviceAddress` enabled, and
hand a test the device address of each buffer before the dispatch.

This branch has not been deployed

No deployments
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.

1 participant