use std::{marker::PhantomData, ops::Range, sync::Arc, thread};
use crate::context::DynContext;
use crate::*;
#[derive(Debug)]
pub struct CommandEncoder {
pub(crate) context: Arc<C>,
pub(crate) data: Box<Data>,
}
#[cfg(send_sync)]
static_assertions::assert_impl_all!(CommandEncoder: Send, Sync);
impl Drop for CommandEncoder {
fn drop(&mut self) {
if !thread::panicking() {
self.context.command_encoder_drop(self.data.as_ref());
}
}
}
pub type CommandEncoderDescriptor<'a> = wgt::CommandEncoderDescriptor<Label<'a>>;
static_assertions::assert_impl_all!(CommandEncoderDescriptor<'_>: Send, Sync);
pub use wgt::ImageCopyBuffer as ImageCopyBufferBase;
pub type ImageCopyBuffer<'a> = ImageCopyBufferBase<&'a Buffer>;
#[cfg(send_sync)]
static_assertions::assert_impl_all!(ImageCopyBuffer<'_>: Send, Sync);
pub use wgt::ImageCopyTexture as ImageCopyTextureBase;
pub type ImageCopyTexture<'a> = ImageCopyTextureBase<&'a Texture>;
#[cfg(send_sync)]
static_assertions::assert_impl_all!(ImageCopyTexture<'_>: Send, Sync);
pub use wgt::ImageCopyTextureTagged as ImageCopyTextureTaggedBase;
pub type ImageCopyTextureTagged<'a> = ImageCopyTextureTaggedBase<&'a Texture>;
#[cfg(send_sync)]
static_assertions::assert_impl_all!(ImageCopyTexture<'_>: Send, Sync);
impl CommandEncoder {
pub fn finish(mut self) -> CommandBuffer {
let data = DynContext::command_encoder_finish(&*self.context, self.data.as_mut());
CommandBuffer {
context: Arc::clone(&self.context),
data: Some(data),
}
}
pub fn begin_render_pass<'encoder>(
&'encoder mut self,
desc: &RenderPassDescriptor<'_>,
) -> RenderPass<'encoder> {
let data =
DynContext::command_encoder_begin_render_pass(&*self.context, self.data.as_ref(), desc);
RenderPass {
inner: RenderPassInner {
data,
context: self.context.clone(),
},
encoder_guard: PhantomData,
}
}
pub fn begin_compute_pass<'encoder>(
&'encoder mut self,
desc: &ComputePassDescriptor<'_>,
) -> ComputePass<'encoder> {
let data = DynContext::command_encoder_begin_compute_pass(
&*self.context,
self.data.as_ref(),
desc,
);
ComputePass {
inner: ComputePassInner {
data,
context: self.context.clone(),
},
encoder_guard: PhantomData,
}
}
pub fn copy_buffer_to_buffer(
&mut self,
source: &Buffer,
source_offset: BufferAddress,
destination: &Buffer,
destination_offset: BufferAddress,
copy_size: BufferAddress,
) {
DynContext::command_encoder_copy_buffer_to_buffer(
&*self.context,
self.data.as_ref(),
source.data.as_ref(),
source_offset,
destination.data.as_ref(),
destination_offset,
copy_size,
);
}
pub fn copy_buffer_to_texture(
&mut self,
source: ImageCopyBuffer<'_>,
destination: ImageCopyTexture<'_>,
copy_size: Extent3d,
) {
DynContext::command_encoder_copy_buffer_to_texture(
&*self.context,
self.data.as_ref(),
source,
destination,
copy_size,
);
}
pub fn copy_texture_to_buffer(
&mut self,
source: ImageCopyTexture<'_>,
destination: ImageCopyBuffer<'_>,
copy_size: Extent3d,
) {
DynContext::command_encoder_copy_texture_to_buffer(
&*self.context,
self.data.as_ref(),
source,
destination,
copy_size,
);
}
pub fn copy_texture_to_texture(
&mut self,
source: ImageCopyTexture<'_>,
destination: ImageCopyTexture<'_>,
copy_size: Extent3d,
) {
DynContext::command_encoder_copy_texture_to_texture(
&*self.context,
self.data.as_ref(),
source,
destination,
copy_size,
);
}
pub fn clear_texture(&mut self, texture: &Texture, subresource_range: &ImageSubresourceRange) {
DynContext::command_encoder_clear_texture(
&*self.context,
self.data.as_ref(),
texture.data.as_ref(),
subresource_range,
);
}
pub fn clear_buffer(
&mut self,
buffer: &Buffer,
offset: BufferAddress,
size: Option<BufferAddress>,
) {
DynContext::command_encoder_clear_buffer(
&*self.context,
self.data.as_ref(),
buffer.data.as_ref(),
offset,
size,
);
}
pub fn insert_debug_marker(&mut self, label: &str) {
DynContext::command_encoder_insert_debug_marker(&*self.context, self.data.as_ref(), label);
}
pub fn push_debug_group(&mut self, label: &str) {
DynContext::command_encoder_push_debug_group(&*self.context, self.data.as_ref(), label);
}
pub fn pop_debug_group(&mut self) {
DynContext::command_encoder_pop_debug_group(&*self.context, self.data.as_ref());
}
pub fn resolve_query_set(
&mut self,
query_set: &QuerySet,
query_range: Range<u32>,
destination: &Buffer,
destination_offset: BufferAddress,
) {
DynContext::command_encoder_resolve_query_set(
&*self.context,
self.data.as_ref(),
query_set.data.as_ref(),
query_range.start,
query_range.end - query_range.start,
destination.data.as_ref(),
destination_offset,
)
}
#[cfg(wgpu_core)]
pub unsafe fn as_hal_mut<
A: wgc::hal_api::HalApi,
F: FnOnce(Option<&mut A::CommandEncoder>) -> R,
R,
>(
&mut self,
hal_command_encoder_callback: F,
) -> Option<R> {
self.context
.as_any()
.downcast_ref::<crate::backend::ContextWgpuCore>()
.map(|ctx| unsafe {
ctx.command_encoder_as_hal_mut::<A, F, R>(
crate::context::downcast_ref(self.data.as_ref()),
hal_command_encoder_callback,
)
})
}
}
impl CommandEncoder {
pub fn write_timestamp(&mut self, query_set: &QuerySet, query_index: u32) {
DynContext::command_encoder_write_timestamp(
&*self.context,
self.data.as_mut(),
query_set.data.as_ref(),
query_index,
)
}
}