pub trait ComputeDevice {
type Buffer;
type Pipeline;
type Error: Debug;
// Required methods
fn device_buffer(&self, bytes: u64) -> Result<Self::Buffer, Self::Error>;
fn upload(&self, data: &[u8]) -> Result<Self::Buffer, Self::Error>;
fn download(
&self,
buffer: &Self::Buffer,
out: &mut [u8],
) -> Result<(), Self::Error>;
fn pipeline(
&self,
code: &[u8],
bindings: u32,
) -> Result<Self::Pipeline, Self::Error>;
fn dispatch(
&self,
pipeline: &Self::Pipeline,
buffers: &[&Self::Buffer],
groups: [u32; 3],
) -> Result<(), Self::Error>;
fn buffer_len(&self, buffer: &Self::Buffer) -> u64;
}Expand description
A device you can allocate on, submit a compute shader to, and read back from — one uniform surface over Vulkan, D3D12, and OpenGL.
Implemented on the backend’s owned device/context type (Vulkan Context,
D3D12 Context, OpenGL GlDevice, Metal Context, Level Zero Context).
Every method blocks until the GPU has finished the operation, matching the
one-shot submission model the backends already use; batching and async are
concrete-type concerns layered on top.
The associated types keep this zero-cost — there is no boxing and no
vtable. The trait is therefore not dyn-safe by design; use it as a generic
bound (fn run<C: ComputeDevice>(dev: &C)), not a trait object.
Required Associated Types§
Required Methods§
Sourcefn device_buffer(&self, bytes: u64) -> Result<Self::Buffer, Self::Error>
fn device_buffer(&self, bytes: u64) -> Result<Self::Buffer, Self::Error>
Allocate an uninitialized device-local buffer of bytes.
Sourcefn upload(&self, data: &[u8]) -> Result<Self::Buffer, Self::Error>
fn upload(&self, data: &[u8]) -> Result<Self::Buffer, Self::Error>
Stage data into a fresh device-local buffer and wait for the copy.
The buffer is sized to data.len().
Sourcefn download(
&self,
buffer: &Self::Buffer,
out: &mut [u8],
) -> Result<(), Self::Error>
fn download( &self, buffer: &Self::Buffer, out: &mut [u8], ) -> Result<(), Self::Error>
Copy a device-local buffer back to host memory, reading
min(out.len(), len) bytes.
Sourcefn pipeline(
&self,
code: &[u8],
bindings: u32,
) -> Result<Self::Pipeline, Self::Error>
fn pipeline( &self, code: &[u8], bindings: u32, ) -> Result<Self::Pipeline, Self::Error>
Compile code (see the module table for the per-backend format) into a
pipeline that binds bindings storage buffers at slots 0..bindings.
Sourcefn dispatch(
&self,
pipeline: &Self::Pipeline,
buffers: &[&Self::Buffer],
groups: [u32; 3],
) -> Result<(), Self::Error>
fn dispatch( &self, pipeline: &Self::Pipeline, buffers: &[&Self::Buffer], groups: [u32; 3], ) -> Result<(), Self::Error>
Bind buffers to slots 0..buffers.len() and dispatch a
groups[0] × groups[1] × groups[2] grid of workgroups, then block until
it completes. buffers.len() should match the pipeline’s bindings.
Sourcefn buffer_len(&self, buffer: &Self::Buffer) -> u64
fn buffer_len(&self, buffer: &Self::Buffer) -> u64
Length of a buffer in bytes.
Dyn Compatibility§
This trait is dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety".