use {
super::{PipelineCommand, cmd_ref::CommandRef},
crate::driver::{device::Device, ray_trace::RayTracePipeline},
ash::vk,
std::ops::Deref,
};
impl PipelineCommand<'_, RayTracePipeline> {
pub fn record_cmd(
mut self,
func: impl FnOnce(RayTraceCommandRef<'_>) + Send + 'static,
) -> Self {
self.record_cmd_mut(func);
self
}
pub fn record_cmd_mut(&mut self, func: impl FnOnce(RayTraceCommandRef<'_>) + Send + 'static) {
let pipeline = self
.cmd
.cmd()
.expect_last_pipeline()
.expect_ray_trace()
.clone();
#[cfg(debug_assertions)]
let dynamic_stack_size = pipeline.inner.info.dynamic_stack_size;
self.cmd.push_exec(move |cmd| {
func(RayTraceCommandRef {
cmd,
#[cfg(debug_assertions)]
dynamic_stack_size,
pipeline,
});
});
}
}
pub struct RayTraceCommandRef<'a> {
cmd: CommandRef<'a>,
#[cfg(debug_assertions)]
dynamic_stack_size: bool,
pipeline: RayTracePipeline,
}
impl RayTraceCommandRef<'_> {
#[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,
offset,
data,
);
self
}
#[profiling::function]
pub fn set_stack_size(&self, pipeline_stack_size: u32) -> &Self {
#[cfg(debug_assertions)]
assert!(self.dynamic_stack_size);
let ray_trace_ext = Device::expect_ray_trace_ext(&self.cmd.device);
unsafe {
ray_trace_ext
.cmd_set_ray_tracing_pipeline_stack_size(self.cmd.handle, pipeline_stack_size);
}
self
}
#[allow(clippy::too_many_arguments)]
#[profiling::function]
pub fn trace_rays(
&self,
raygen_shader_binding_table: &vk::StridedDeviceAddressRegionKHR,
miss_shader_binding_table: &vk::StridedDeviceAddressRegionKHR,
hit_shader_binding_table: &vk::StridedDeviceAddressRegionKHR,
callable_shader_binding_table: &vk::StridedDeviceAddressRegionKHR,
width: u32,
height: u32,
depth: u32,
) -> &Self {
let ray_trace_ext = Device::expect_ray_trace_ext(&self.cmd.device);
unsafe {
ray_trace_ext.cmd_trace_rays(
self.cmd.handle,
raygen_shader_binding_table,
miss_shader_binding_table,
hit_shader_binding_table,
callable_shader_binding_table,
width,
height,
depth,
);
}
self
}
#[profiling::function]
pub fn trace_rays_indirect(
&self,
raygen_shader_binding_table: &vk::StridedDeviceAddressRegionKHR,
miss_shader_binding_table: &vk::StridedDeviceAddressRegionKHR,
hit_shader_binding_table: &vk::StridedDeviceAddressRegionKHR,
callable_shader_binding_table: &vk::StridedDeviceAddressRegionKHR,
indirect_device_address: vk::DeviceAddress,
) -> &Self {
let ray_trace_ext = Device::expect_ray_trace_ext(&self.cmd.device);
unsafe {
ray_trace_ext.cmd_trace_rays_indirect(
self.cmd.handle,
raygen_shader_binding_table,
miss_shader_binding_table,
hit_shader_binding_table,
callable_shader_binding_table,
indirect_device_address,
)
}
self
}
}
impl<'a> Deref for RayTraceCommandRef<'a> {
type Target = CommandRef<'a>;
fn deref(&self) -> &Self::Target {
&self.cmd
}
}
#[allow(unused)]
mod deprecated {
use {
crate::{
Node,
cmd::{
Binding, PipelineCommand, Subresource, SubresourceRange, ViewInfo,
ray_trace::RayTraceCommandRef,
},
driver::ray_trace::RayTracePipeline,
},
vk_sync::AccessType,
};
impl RayTraceCommandRef<'_> {
#[deprecated = "use push_constants function"]
#[doc(hidden)]
pub fn push_constants_offset(&self, offset: u32, data: &[u8]) -> &Self {
self.push_constants(offset, data)
}
}
impl PipelineCommand<'_, RayTracePipeline> {
#[deprecated = "use shader_resource_access"]
#[doc(hidden)]
pub fn read_descriptor<N>(self, descriptor: impl Into<Binding>, node: N) -> Self
where
N: Node + Subresource,
N::Info: Copy,
SubresourceRange: From<N::Info>,
ViewInfo: From<N::Info>,
{
self.shader_resource_access(
descriptor,
node,
AccessType::RayTracingShaderReadSampledImageOrUniformTexelBuffer,
)
}
#[deprecated = "use shader_subresource_access"]
#[doc(hidden)]
pub fn read_descriptor_as<N>(
self,
descriptor: impl Into<Binding>,
node: N,
node_view: impl Into<N::Info>,
) -> Self
where
N: Node + Subresource,
N::Info: Copy,
SubresourceRange: From<N::Info>,
ViewInfo: From<N::Info>,
{
self.shader_subresource_access(
descriptor,
node,
node_view,
AccessType::RayTracingShaderReadSampledImageOrUniformTexelBuffer,
)
}
#[deprecated = "use record_cmd function"]
#[doc(hidden)]
pub fn record_ray_trace(
self,
func: impl FnOnce(RayTraceCommandRef<'_>, ()) + Send + 'static,
) -> Self {
self.record_cmd(|cmd| {
func(cmd, ());
})
}
#[deprecated = "use shader_resource_access function with AccessType::AnyShaderWrite"]
#[doc(hidden)]
pub fn write_descriptor<N>(self, descriptor: impl Into<Binding>, node: N) -> Self
where
N: Node + Subresource,
N::Info: Copy,
SubresourceRange: From<N::Info>,
ViewInfo: From<N::Info>,
{
self.shader_resource_access(descriptor, node, AccessType::AnyShaderWrite)
}
#[deprecated = "use shader_subresource_access function with AccessType::AnyShaderWrite"]
#[doc(hidden)]
pub fn write_descriptor_as<N>(
self,
descriptor: impl Into<Binding>,
node: N,
node_view: impl Into<N::Info>,
) -> Self
where
N: Node + Subresource,
N::Info: Copy,
SubresourceRange: From<N::Info>,
ViewInfo: From<N::Info>,
{
self.shader_subresource_access(descriptor, node, node_view, AccessType::AnyShaderWrite)
}
}
}