use super::{CommandBuffer, CommandBufferDescriptor, Device, ResidencySet};
use crate::Error;
pub struct CommandQueue {
pub(crate) inner: metal_rust_ffi::CommandQueue,
}
impl CommandQueue {
pub(crate) const fn from_ffi(inner: metal_rust_ffi::CommandQueue) -> Self {
Self { inner }
}
#[must_use]
pub fn device(&self) -> Device {
Device::from_ffi(self.inner.device())
}
#[must_use]
pub fn label(&self) -> Option<String> {
self.inner.label()
}
pub fn set_label(&self, label: Option<&str>) {
self.inner.set_label(label);
}
pub fn command_buffer(&self) -> Result<CommandBuffer, Error> {
self.inner
.command_buffer()
.map(CommandBuffer::from_ffi)
.map_err(Error::from_ffi)
}
pub fn command_buffer_with_descriptor(
&self,
descriptor: &CommandBufferDescriptor,
) -> Result<CommandBuffer, Error> {
if !descriptor.retained_references()? {
return Err(Error::invalid_argument(
"safe command buffers must retain every referenced resource",
));
}
self.inner
.command_buffer_with_descriptor(&descriptor.inner)
.map(CommandBuffer::from_ffi)
.map_err(Error::from_ffi)
}
pub fn insert_debug_capture_boundary(&self) {
self.inner.insert_debug_capture_boundary();
}
pub fn add_residency_sets(&self, sets: &[&ResidencySet]) -> Result<(), Error> {
let sets = sets.iter().map(|set| &set.inner).collect::<Vec<_>>();
self.inner
.add_residency_sets(&sets)
.map_err(Error::from_ffi)
}
pub fn remove_residency_sets(&self, sets: &[&ResidencySet]) -> Result<(), Error> {
let sets = sets.iter().map(|set| &set.inner).collect::<Vec<_>>();
self.inner
.remove_residency_sets(&sets)
.map_err(Error::from_ffi)
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::ErrorKind;
#[test]
fn descriptor_cannot_disable_resource_retention() {
let Some(device) = Device::system_default() else {
return;
};
let Ok(queue) = device.new_command_queue(None) else {
return;
};
let Ok(descriptor) = CommandBufferDescriptor::new() else {
return;
};
if descriptor.set_retained_references(false).is_err() {
return;
}
let error = match queue.command_buffer_with_descriptor(&descriptor) {
Ok(_) => panic!("non-retaining command buffer must be rejected"),
Err(error) => error,
};
assert_eq!(error.kind(), ErrorKind::InvalidArgument);
}
}