pub struct GraphicCommandRef<'a> { /* private fields */ }Expand description
Recording interface for drawing commands.
This structure provides a strongly-typed set of methods which allow raster graphics shader code
to be executed. An instance is provided to the closure argument of
PipelineCommand::record_cmd which may be accessed by binding a GraphicPipeline to a
command.
§Examples
Basic usage:
my_graph
.begin_cmd()
.debug_name("my draw command")
.bind_pipeline(&my_graphic_pipeline)
.color_attachment_image(0, swapchain_image, LoadOp::DontCare, StoreOp::Store)
.record_cmd(move |cmd| {
// During this closure we have access to the drawing functions!
cmd.draw(3, 1, 0, 0);
});Implementations§
Source§impl GraphicCommandRef<'_>
impl GraphicCommandRef<'_>
Sourcepub fn bind_index_buffer(
&self,
buffer: impl Into<AnyBufferNode>,
offset: DeviceSize,
index_ty: IndexType,
) -> &Self
pub fn bind_index_buffer( &self, buffer: impl Into<AnyBufferNode>, offset: DeviceSize, index_ty: IndexType, ) -> &Self
Bind an index buffer to the current command.
offset is the starting offset in bytes within buffer used in index buffer address
calculations.
§Examples
Basic usage:
my_graph
.begin_cmd()
.debug_name("my indexed geometry draw pass")
.bind_pipeline(&my_graphic_pipeline)
.color_attachment_image(0, swapchain_image, LoadOp::DontCare, StoreOp::Store)
.resource_access(my_idx_buf, AccessType::IndexBuffer)
.resource_access(my_vtx_buf, AccessType::VertexBuffer)
.record_cmd(move |cmd| {
cmd
.bind_index_buffer(my_idx_buf, 0, vk::IndexType::UINT16)
.bind_vertex_buffer(0, my_vtx_buf, 0)
.draw_indexed(42, 1, 0, 0, 0);
});Sourcepub fn bind_vertex_buffer(
&self,
binding: u32,
buffer: impl Into<AnyBufferNode>,
offset: DeviceSize,
) -> &Self
pub fn bind_vertex_buffer( &self, binding: u32, buffer: impl Into<AnyBufferNode>, offset: DeviceSize, ) -> &Self
Bind a vertex buffer to the current pass.
The vertex input binding is updated to start at offset from the start of buffer.
§Examples
Basic usage:
my_graph
.begin_cmd()
.debug_name("my unindexed geometry draw pass")
.bind_pipeline(&my_graphic_pipeline)
.color_attachment_image(0, swapchain_image, LoadOp::DontCare, StoreOp::Store)
.resource_access(my_vtx_buf, AccessType::VertexBuffer)
.record_cmd(move |cmd| {
cmd
.bind_vertex_buffer(0, my_vtx_buf, 0)
.draw(42, 1, 0, 0);
});Sourcepub fn bind_vertex_buffers<N>(
&self,
first_binding: u32,
buffer_offsets: impl IntoIterator<Item = (N, DeviceSize)>,
) -> &Selfwhere
N: Into<AnyBufferNode>,
pub fn bind_vertex_buffers<N>(
&self,
first_binding: u32,
buffer_offsets: impl IntoIterator<Item = (N, DeviceSize)>,
) -> &Selfwhere
N: Into<AnyBufferNode>,
Binds multiple vertex buffers to the current pass, starting at the given first_binding.
Each vertex input binding in buffers specifies an offset from the start of the
corresponding buffer.
The vertex input attributes that use each of these bindings will use these updated addresses in their address calculations for subsequent drawing commands.
Sourcepub fn draw(
&self,
vertex_count: u32,
instance_count: u32,
first_vertex: u32,
first_instance: u32,
) -> &Self
pub fn draw( &self, vertex_count: u32, instance_count: u32, first_vertex: u32, first_instance: u32, ) -> &Self
Draw unindexed primitives.
When the command is executed, primitives are assembled using the current primitive topology
and vertex_count consecutive vertex indices with the first vertex_index value equal to
first_vertex. The primitives are drawn instance_count times with instance_index
starting with first_instance and increasing sequentially for each instance.
Sourcepub fn draw_indexed(
&self,
index_count: u32,
instance_count: u32,
first_index: u32,
vertex_offset: i32,
first_instance: u32,
) -> &Self
pub fn draw_indexed( &self, index_count: u32, instance_count: u32, first_index: u32, vertex_offset: i32, first_instance: u32, ) -> &Self
Draw indexed primitives.
When the command is executed, primitives are assembled using the current primitive topology
and index_count vertices whose indices are retrieved from the index buffer. The index
buffer is treated as an array of tightly packed unsigned integers of size defined by the
index_ty parameter with which the buffer was bound.
Sourcepub fn draw_indexed_indirect(
&self,
buffer: impl Into<AnyBufferNode>,
offset: DeviceSize,
draw_count: u32,
stride: u32,
) -> &Self
pub fn draw_indexed_indirect( &self, buffer: impl Into<AnyBufferNode>, offset: DeviceSize, draw_count: u32, stride: u32, ) -> &Self
Draw primitives with indirect parameters and indexed vertices.
draw_indexed_indirect behaves similarly to draw_indexed except that the parameters are
read by the device from buffer during execution. draw_count draws are executed by the
command, with parameters taken from buffer starting at offset and increasing by stride
bytes for each successive draw. The parameters of each draw are encoded in an array of
vk::DrawIndexedIndirectCommand structures.
If draw_count is less than or equal to one, stride is ignored.
§Examples
Basic usage:
const CMD_SIZE: usize = size_of::<vk::DrawIndexedIndirectCommand>();
let cmd = vk::DrawIndexedIndirectCommand {
index_count: 3,
instance_count: 1,
first_index: 0,
vertex_offset: 0,
first_instance: 0,
};
let cmd_data = unsafe {
std::slice::from_raw_parts(&cmd as *const _ as *const _, CMD_SIZE)
};
let buf_flags = vk::BufferUsageFlags::STORAGE_BUFFER;
let buf = Buffer::create_from_slice(&device, buf_flags, cmd_data)?;
let buf_node = my_graph.bind_resource(buf);
my_graph
.begin_cmd()
.debug_name("draw a single triangle")
.bind_pipeline(&my_graphic_pipeline)
.color_attachment_image(0, swapchain_image, LoadOp::DontCare, StoreOp::Store)
.resource_access(my_idx_buf, AccessType::IndexBuffer)
.resource_access(my_vtx_buf, AccessType::VertexBuffer)
.resource_access(buf_node, AccessType::IndirectBuffer)
.record_cmd(move |cmd| {
cmd
.bind_index_buffer(my_idx_buf, 0, vk::IndexType::UINT16)
.bind_vertex_buffer(0, my_vtx_buf, 0)
.draw_indexed_indirect(buf_node, 0, 1, 0);
});Sourcepub fn draw_indexed_indirect_count(
&self,
buffer: impl Into<AnyBufferNode>,
offset: DeviceSize,
count_buf: impl Into<AnyBufferNode>,
count_buf_offset: DeviceSize,
max_draw_count: u32,
stride: u32,
) -> &Self
pub fn draw_indexed_indirect_count( &self, buffer: impl Into<AnyBufferNode>, offset: DeviceSize, count_buf: impl Into<AnyBufferNode>, count_buf_offset: DeviceSize, max_draw_count: u32, stride: u32, ) -> &Self
Draw primitives with indirect parameters, indexed vertices, and draw count.
draw_indexed_indirect_count behaves similarly to draw_indexed_indirect except that the
draw count is read by the device from buffer during execution. The command will read an
unsigned 32-bit integer from count_buf located at count_buf_offset and use this as the
draw count.
max_draw_count specifies the maximum number of draws that will be executed. The actual
number of executed draw calls is the minimum of the count specified in count_buf and
max_draw_count.
stride is the byte stride between successive sets of draw parameters.
Sourcepub fn draw_indirect(
&self,
buffer: impl Into<AnyBufferNode>,
offset: DeviceSize,
draw_count: u32,
stride: u32,
) -> &Self
pub fn draw_indirect( &self, buffer: impl Into<AnyBufferNode>, offset: DeviceSize, draw_count: u32, stride: u32, ) -> &Self
Draw primitives with indirect parameters and unindexed vertices.
Behaves otherwise similar to Self::draw_indexed_indirect.
Sourcepub fn draw_indirect_count(
&self,
buffer: impl Into<AnyBufferNode>,
offset: DeviceSize,
count_buf: impl Into<AnyBufferNode>,
count_buf_offset: DeviceSize,
max_draw_count: u32,
stride: u32,
) -> &Self
pub fn draw_indirect_count( &self, buffer: impl Into<AnyBufferNode>, offset: DeviceSize, count_buf: impl Into<AnyBufferNode>, count_buf_offset: DeviceSize, max_draw_count: u32, stride: u32, ) -> &Self
Draw primitives with indirect parameters, unindexed vertices, and draw count.
Behaves otherwise similar to Self::draw_indexed_indirect_count.
Sourcepub fn push_constants(&self, offset: u32, data: &[u8]) -> &Self
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 code!
}my_graph
.begin_cmd()
.debug_name("draw a quad")
.bind_pipeline(&my_graphic_pipeline)
.color_attachment_image(0, swapchain_image, LoadOp::DontCare, StoreOp::Store)
.record_cmd(move |cmd| {
cmd
.push_constants(0, &[42])
.draw(6, 1, 0, 0);
});See vkCmdPushConstants.
Sourcepub fn set_scissor(&self, first_scissor: u32, scissors: &[Rect2D]) -> &Self
pub fn set_scissor(&self, first_scissor: u32, scissors: &[Rect2D]) -> &Self
Set scissor rectangle dynamically for the current command.
The default scissor state is no-clip.
Sourcepub fn set_viewport(&self, first_viewport: u32, viewports: &[Viewport]) -> &Self
pub fn set_viewport(&self, first_viewport: u32, viewports: &[Viewport]) -> &Self
Set the viewport dynamically for the current command.
The default viewport state is the entire render target as defined by all combined image attachments.
Methods from Deref<Target = CommandRef<'a>>§
Sourcepub fn build_accel_struct(
&self,
infos: &[BuildAccelerationStructureInfo],
) -> &Self
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_sizevalue returned byAccelerationStructure::size_of, aligned tomin_accel_struct_scratch_offset_alignmentofPhysicalDevice::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:
Sourcepub fn build_accel_struct_indirect(
&self,
infos: &[BuildAccelerationStructureIndirectInfo],
) -> &Self
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.
Sourcepub fn update_accel_struct(
&self,
infos: &[UpdateAccelerationStructureInfo],
) -> &Self
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_sizevalue returned byAccelerationStructure::size_of, aligned tomin_accel_struct_scratch_offset_alignmentofPhysicalDevice::accel_struct_properties.
Sourcepub fn update_accel_struct_indirect(
&self,
infos: &[UpdateAccelerationStructureIndirectInfo],
) -> &Self
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.
Methods from Deref<Target = CommandBuffer>§
Sourcepub fn has_executed(&self) -> Result<bool, DriverError>
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.