Skip to main content

ComputeCommandRef

Struct ComputeCommandRef 

Source
pub struct ComputeCommandRef<'a> { /* private fields */ }
Expand description

Recording interface for computing commands.

This structure provides a strongly-typed set of methods which allow compute shader code to be executed. An instance is provided to the closure argument of PipelineCommand::record_cmd which may be accessed by binding a ComputePipeline to a command.

§Examples

Basic usage:

my_graph
    .begin_cmd()
    .bind_pipeline(&my_compute_pipeline)
    .record_cmd(move |cmd| {
        // During this closure we have access to the compute functions!
        cmd.dispatch(64, 1, 1);
    });

Implementations§

Source§

impl ComputeCommandRef<'_>

Source

pub fn dispatch( &self, group_count_x: u32, group_count_y: u32, group_count_z: u32, ) -> &Self

Self::dispatch compute work items.

When the command is executed, a global workgroup consisting of group_count_x × group_count_y × group_count_z local workgroups is assembled.

§Examples

Basic usage:

#version 450
#pragma shader_stage(compute)

layout(set = 0, binding = 0, std430) restrict writeonly buffer MyBufer {
    uint my_buf[];
};

void main() {
    // TODO
}
my_graph
    .begin_cmd()
    .debug_name("fill my_buf_node with data")
    .bind_pipeline(&my_compute_pipeline)
    .shader_resource_access(0, my_buf_node, AccessType::ComputeShaderWrite)
    .record_cmd(move |cmd| {
        cmd.dispatch(128, 64, 32);
    });

See vkCmdDispatch.

Source

pub fn dispatch_base( &self, base_group_x: u32, base_group_y: u32, base_group_z: u32, group_count_x: u32, group_count_y: u32, group_count_z: u32, ) -> &Self

Self::dispatch_base compute work items with non-zero base values for the workgroup IDs.

When the command is executed, a global workgroup consisting of group_count_x × group_count_y × group_count_z local workgroups is assembled, with WorkgroupId values ranging from [base_group*, base_group* + group_count*) in each component.

Self::dispatch is equivalent to dispatch_base(0, 0, 0, group_count_x, group_count_y, group_count_z).

See vkCmdDispatchBase.

Source

pub fn dispatch_indirect( &self, args_buf: impl Into<AnyBufferNode>, args_offset: DeviceSize, ) -> &Self

Dispatch compute work items with indirect parameters.

dispatch_indirect behaves similarly to Self::dispatch except that the parameters are read by the device from args_buf during execution. The parameters of the dispatch are encoded in a vk::DispatchIndirectCommand structure taken from args_buf starting at args_offset.

§Examples

Basic usage:

let args = DispatchIndirectCommand {
    x: 1,
    y: 2,
    z: 3,
};
let data = bytes_of(&args);
let usage = vk::BufferUsageFlags::INDIRECT_BUFFER | vk::BufferUsageFlags::STORAGE_BUFFER;
let args_buf = Buffer::create_from_slice(&device, usage, data)?;
let args_buf = my_graph.bind_resource(args_buf);

my_graph
    .begin_cmd()
    .debug_name("fill my_buf_node with data")
    .bind_pipeline(&my_compute_pipeline)
    .resource_access(args_buf, AccessType::IndirectBuffer)
    .shader_resource_access(0, my_buf_node, AccessType::ComputeShaderWrite)
    .record_cmd(move |cmd| {
        cmd.dispatch_indirect(args_buf, 0);
    });

See vkCmdDispatchIndirect.

Source

pub fn push_constants(&self, offset: u32, data: &[u8]) -> &Self

Updates push constants.

Push constants represent a high speed path to modify constant data in pipelines that is expected to outperform memory-backed resource updates.

Push constant values can be updated incrementally, causing shader stages to read the new data for push constants modified by this command, while still reading the previous data for push constants not modified by this command.

§Device limitations

See device.physical_device.props.limits.max_push_constants_size for the limits of the current device. You may also check [gpuinfo.org] for a listing of reported limits on other devices.

§Examples

Basic usage:

#version 450
#pragma shader_stage(compute)

layout(push_constant) uniform PushConstants {
    layout(offset = 0) uint the_answer;
} push_constants;

void main()
{
    // TODO: Add bindings to read/write things!
}
my_graph
    .begin_cmd()
    .debug_name("compute the ultimate question")
    .bind_pipeline(&my_compute_pipeline)
    .record_cmd(move |cmd| {
        cmd
            .push_constants(0, &[42])
            .dispatch(1, 1, 1);
    });

See vkCmdPushConstants.

Methods from Deref<Target = CommandRef<'a>>§

Source

pub fn build_accel_struct( &self, infos: &[BuildAccelerationStructureInfo], ) -> &Self

Build acceleration structures.

There is no ordering or synchronization implied between any of the individual acceleration structure builds.

Requires a scratch buffer which was created with the following requirements:

  • Flags must include vk::BufferUsageFlags::SHADER_DEVICE_ADDRESS
  • Size must be equal to or greater than the build_size value returned by AccelerationStructure::size_of, aligned to min_accel_struct_scratch_offset_alignment of PhysicalDevice::accel_struct_properties.
§Examples

Basic usage:

my_graph.begin_cmd()
        .resource_access(index_buf, AccessType::IndexBuffer)
        .resource_access(vertex_buf, AccessType::VertexBuffer)
        .resource_access(scratch_buf, AccessType::AccelerationStructureBufferWrite)
        .resource_access(blas_node, AccessType::AccelerationStructureBuildWrite)
        .record_cmd(move |cmd| {
            let scratch_addr = cmd.resource(scratch_buf).device_address();
            let geom = AccelerationStructureGeometry {
                max_primitive_count: 64,
                flags: vk::GeometryFlagsKHR::OPAQUE,
                geometry: AccelerationStructureGeometryData::Triangles {
                    index_addr: DeviceOrHostAddress::DeviceAddress(
                        cmd.resource(index_buf).device_address()
                    ),
                    index_type: vk::IndexType::UINT32,
                    max_vertex: 42,
                    transform_addr: None,
                    vertex_addr: DeviceOrHostAddress::DeviceAddress(
                        cmd.resource(vertex_buf).device_address(),
                    ),
                    vertex_format: vk::Format::R32G32B32_SFLOAT,
                    vertex_stride: 12,
                },
            };
            let build_range = vk::AccelerationStructureBuildRangeInfoKHR {
                first_vertex: 0,
                primitive_count: 1,
                primitive_offset: 0,
                transform_offset: 0,
            };
            let info = AccelerationStructureGeometryInfo::blas([(geom, build_range)]);

            cmd.build_accel_struct(&[
                BuildAccelerationStructureInfo::new(blas_node, scratch_addr, info)
            ]);
        });

See also:

Source

pub fn build_accel_struct_indirect( &self, infos: &[BuildAccelerationStructureIndirectInfo], ) -> &Self

Builds acceleration structures with some parameters provided on the device.

There is no ordering or synchronization implied between any of the individual acceleration structure builds.

Each BuildAccelerationStructureIndirectInfo::range_base is a buffer device address which points to an array of vk::AccelerationStructureBuildRangeInfoKHR structures defining dynamic offsets to the addresses where geometry data is stored.

Source

pub fn update_accel_struct( &self, infos: &[UpdateAccelerationStructureInfo], ) -> &Self

Update acceleration structures.

There is no ordering or synchronization implied between any of the individual acceleration structure updates.

Requires a scratch buffer which was created with the following requirements:

  • Flags must include vk::BufferUsageFlags::SHADER_DEVICE_ADDRESS
  • Size must be equal to or greater than the update_size value returned by AccelerationStructure::size_of, aligned to min_accel_struct_scratch_offset_alignment of PhysicalDevice::accel_struct_properties.
Source

pub fn update_accel_struct_indirect( &self, infos: &[UpdateAccelerationStructureIndirectInfo], ) -> &Self

Updates acceleration structures with some parameters provided on the device.

There is no ordering or synchronization implied between any of the individual acceleration structure updates.

Each UpdateAccelerationStructureIndirectInfo::range_base is a buffer device address which points to an array of vk::AccelerationStructureBuildRangeInfoKHR structures defining dynamic offsets to the addresses where geometry data is stored.

Source

pub fn resource<N>(&self, resource_node: N) -> &N::Resource
where N: Node,

Returns a borrow of the original Vulkan resource (buffer, image or acceleration structure) which the given bound resource node represents.

Methods from Deref<Target = CommandBuffer>§

Source

pub fn has_executed(&self) -> Result<bool, DriverError>

Returns true after the GPU has executed the previous submission to this command buffer.

See Self::wait_until_executed to block while checking.

Trait Implementations§

Source§

impl<'a> Deref for ComputeCommandRef<'a>

Source§

type Target = CommandRef<'a>

The resulting type after dereferencing.
Source§

fn deref(&self) -> &Self::Target

Dereferences the value.

Auto Trait Implementations§

§

impl<'a> Freeze for ComputeCommandRef<'a>

§

impl<'a> !RefUnwindSafe for ComputeCommandRef<'a>

§

impl<'a> !Send for ComputeCommandRef<'a>

§

impl<'a> !Sync for ComputeCommandRef<'a>

§

impl<'a> Unpin for ComputeCommandRef<'a>

§

impl<'a> UnsafeUnpin for ComputeCommandRef<'a>

§

impl<'a> !UnwindSafe for ComputeCommandRef<'a>

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<P, T> Receiver for P
where P: Deref<Target = T> + ?Sized, T: ?Sized,

Source§

type Target = T

🔬This is a nightly-only experimental API. (arbitrary_self_types)
The target type on which the method may be called.
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.