use {
super::{cmd_ref::CommandRef, pipeline::PipelineCommand},
crate::{driver::compute::ComputePipeline, node::AnyBufferNode},
ash::vk,
std::ops::Deref,
};
impl PipelineCommand<'_, ComputePipeline> {
pub fn record_cmd(mut self, func: impl FnOnce(ComputeCommandRef<'_>) + Send + 'static) -> Self {
self.record_cmd_mut(func);
self
}
pub fn record_cmd_mut(&mut self, func: impl FnOnce(ComputeCommandRef<'_>) + Send + 'static) {
let pipeline = self
.cmd
.cmd()
.expect_last_pipeline()
.expect_compute()
.clone();
self.cmd.push_exec(move |cmd| {
func(ComputeCommandRef { cmd, pipeline });
});
}
pub(crate) fn record_stream_mut(
&mut self,
func: impl for<'r> Fn(ComputeCommandRef<'r>) + Send + Sync + 'static,
) {
let pipeline = self
.cmd
.cmd()
.expect_last_pipeline()
.expect_compute()
.clone();
self.cmd.push_reusable_exec(move |cmd| {
func(ComputeCommandRef {
cmd,
pipeline: pipeline.clone(),
});
});
}
}
pub struct ComputeCommandRef<'a> {
cmd: CommandRef<'a>,
pipeline: ComputePipeline,
}
impl ComputeCommandRef<'_> {
#[profiling::function]
pub fn dispatch(&self, group_count_x: u32, group_count_y: u32, group_count_z: u32) -> &Self {
unsafe {
self.cmd.device.cmd_dispatch(
self.cmd.handle,
group_count_x,
group_count_y,
group_count_z,
);
}
self
}
#[profiling::function]
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 {
unsafe {
self.cmd.device.cmd_dispatch_base(
self.cmd.handle,
base_group_x,
base_group_y,
base_group_z,
group_count_x,
group_count_y,
group_count_z,
);
}
self
}
#[profiling::function]
pub fn dispatch_indirect(
&self,
args_buf: impl Into<AnyBufferNode>,
args_offset: vk::DeviceSize,
) -> &Self {
let args_buf = args_buf.into();
let args_buf = self.resource(args_buf);
unsafe {
self.cmd
.device
.cmd_dispatch_indirect(self.cmd.handle, args_buf.handle, args_offset);
}
self
}
#[profiling::function]
pub fn push_constants(&self, offset: u32, data: &[u8]) -> &Self {
self.cmd_push_constants(
self.pipeline.inner.layout,
self.pipeline.inner.push_constants.as_slice(),
offset,
data,
);
self
}
}
impl<'a> Deref for ComputeCommandRef<'a> {
type Target = CommandRef<'a>;
fn deref(&self) -> &Self::Target {
&self.cmd
}
}