use std::ops::{Deref, DerefMut};
use crate::*;
#[derive(Debug, Clone)]
pub struct Queue {
pub(crate) inner: dispatch::DispatchQueue,
}
#[cfg(send_sync)]
static_assertions::assert_impl_all!(Queue: Send, Sync);
crate::cmp::impl_eq_ord_hash_proxy!(Queue => .inner);
#[derive(Debug, Clone)]
pub struct SubmissionIndex {
#[cfg_attr(
all(
target_arch = "wasm32",
not(target_os = "emscripten"),
not(feature = "webgl"),
),
expect(dead_code)
)]
pub(crate) index: u64,
}
#[cfg(send_sync)]
static_assertions::assert_impl_all!(SubmissionIndex: Send, Sync);
pub use wgt::Maintain as MaintainBase;
pub type Maintain = wgt::Maintain<SubmissionIndex>;
#[cfg(send_sync)]
static_assertions::assert_impl_all!(Maintain: Send, Sync);
pub struct QueueWriteBufferView<'a> {
queue: &'a Queue,
buffer: &'a Buffer,
offset: BufferAddress,
inner: dispatch::DispatchQueueWriteBuffer,
}
#[cfg(send_sync)]
static_assertions::assert_impl_all!(QueueWriteBufferView<'_>: Send, Sync);
impl Deref for QueueWriteBufferView<'_> {
type Target = [u8];
fn deref(&self) -> &Self::Target {
log::warn!("Reading from a QueueWriteBufferView won't yield the contents of the buffer and may be slow.");
self.inner.slice()
}
}
impl DerefMut for QueueWriteBufferView<'_> {
fn deref_mut(&mut self) -> &mut Self::Target {
self.inner.slice_mut()
}
}
impl AsMut<[u8]> for QueueWriteBufferView<'_> {
fn as_mut(&mut self) -> &mut [u8] {
self.inner.slice_mut()
}
}
impl Drop for QueueWriteBufferView<'_> {
fn drop(&mut self) {
self.queue
.inner
.write_staging_buffer(&self.buffer.inner, self.offset, &self.inner);
}
}
impl Queue {
pub fn write_buffer(&self, buffer: &Buffer, offset: BufferAddress, data: &[u8]) {
self.inner.write_buffer(&buffer.inner, offset, data);
}
#[must_use]
pub fn write_buffer_with<'a>(
&'a self,
buffer: &'a Buffer,
offset: BufferAddress,
size: BufferSize,
) -> Option<QueueWriteBufferView<'a>> {
profiling::scope!("Queue::write_buffer_with");
self.inner
.validate_write_buffer(&buffer.inner, offset, size)?;
let staging_buffer = self.inner.create_staging_buffer(size)?;
Some(QueueWriteBufferView {
queue: self,
buffer,
offset,
inner: staging_buffer,
})
}
pub fn write_texture(
&self,
texture: TexelCopyTextureInfo<'_>,
data: &[u8],
data_layout: TexelCopyBufferLayout,
size: Extent3d,
) {
self.inner.write_texture(texture, data, data_layout, size);
}
#[cfg(any(webgpu, webgl))]
pub fn copy_external_image_to_texture(
&self,
source: &wgt::CopyExternalImageSourceInfo,
dest: wgt::CopyExternalImageDestInfo<&api::Texture>,
size: Extent3d,
) {
self.inner
.copy_external_image_to_texture(source, dest, size);
}
pub fn submit<I: IntoIterator<Item = CommandBuffer>>(
&self,
command_buffers: I,
) -> SubmissionIndex {
let mut command_buffers = command_buffers.into_iter().map(|comb| {
comb.inner
.lock()
.take()
.expect("Command buffer already submitted")
});
let index = self.inner.submit(&mut command_buffers);
SubmissionIndex { index }
}
pub fn get_timestamp_period(&self) -> f32 {
self.inner.get_timestamp_period()
}
pub fn on_submitted_work_done(&self, callback: impl FnOnce() + Send + 'static) {
self.inner.on_submitted_work_done(Box::new(callback));
}
}