use super::{
Buffer, Device, IOCommandQueueDescriptor, IOCompressionMethod, IOScratchBuffer,
IOScratchBufferAllocator, IOStatus, Origin, SharedEvent, Size, Texture,
};
use crate::Error;
use std::path::Path;
impl IOScratchBufferAllocator {
pub fn new_scratch_buffer(
&self,
minimum_size: usize,
) -> Result<Option<IOScratchBuffer>, Error> {
self.inner
.new_scratch_buffer(minimum_size)
.map(|value| value.map(IOScratchBuffer::from_ffi))
.map_err(Error::from_ffi)
}
}
#[derive(Clone)]
pub struct IoFileHandle {
inner: metal_rust_ffi::IoFileHandle,
}
impl IoFileHandle {
#[must_use]
pub fn label(&self) -> Option<String> {
self.inner.label()
}
pub fn set_label(&self, label: Option<&str>) {
self.inner.set_label(label);
}
}
#[derive(Clone)]
pub struct IoCommandQueue {
inner: metal_rust_ffi::IoCommandQueue,
}
impl IoCommandQueue {
#[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 enqueue_barrier(&self) -> Result<(), Error> {
self.inner.enqueue_barrier().map_err(Error::from_ffi)
}
pub fn command_buffer(&self) -> Result<IoCommandBuffer, Error> {
self.inner
.command_buffer()
.map(|inner| IoCommandBuffer { inner })
.map_err(Error::from_ffi)
}
pub fn read_bytes(
&self,
source: &IoFileHandle,
source_offset: usize,
length: usize,
) -> Result<Vec<u8>, Error> {
self.inner
.read_bytes(&source.inner, source_offset, length)
.map_err(Error::from_ffi)
}
}
pub struct IoCommandBuffer {
inner: metal_rust_ffi::IoCommandBuffer,
}
impl IoCommandBuffer {
#[must_use]
pub fn status(&self) -> IOStatus {
self.inner.status()
}
#[must_use]
pub fn error(&self) -> Option<Error> {
self.inner.error().map(Error::from_ffi)
}
pub fn on_complete(
&mut self,
handler: impl FnOnce(Result<(), Error>) + Send + 'static,
) -> Result<(), Error> {
self.inner
.on_complete(move |result| handler(result.map_err(Error::from_ffi)))
.map_err(Error::from_ffi)
}
#[must_use]
pub fn label(&self) -> Option<String> {
self.inner.label()
}
pub fn set_label(&mut self, label: Option<&str>) {
self.inner.set_label(label);
}
pub fn push_debug_group(&mut self, label: &str) {
self.inner.push_debug_group(label);
}
pub fn pop_debug_group(&mut self) {
self.inner.pop_debug_group();
}
pub fn add_barrier(&mut self) -> Result<(), Error> {
self.inner.add_barrier().map_err(Error::from_ffi)
}
pub fn load_buffer(
&mut self,
destination: &Buffer,
destination_offset: usize,
length: usize,
source: &IoFileHandle,
source_offset: usize,
) -> Result<(), Error> {
self.inner
.load_buffer(
&destination.inner,
destination_offset,
length,
&source.inner,
source_offset,
)
.map_err(Error::from_ffi)
}
#[allow(clippy::too_many_arguments)]
pub fn load_texture(
&mut self,
destination: &Texture,
slice: usize,
level: usize,
size: Size,
source_bytes_per_row: usize,
source_bytes_per_image: usize,
destination_origin: Origin,
source: &IoFileHandle,
source_offset: usize,
) -> Result<(), Error> {
self.inner
.load_texture(
&destination.inner,
slice,
level,
size,
source_bytes_per_row,
source_bytes_per_image,
destination_origin,
&source.inner,
source_offset,
)
.map_err(Error::from_ffi)
}
pub fn copy_status_to_buffer(
&mut self,
destination: &Buffer,
offset: usize,
) -> Result<(), Error> {
self.inner
.copy_status_to_buffer(&destination.inner, offset)
.map_err(Error::from_ffi)
}
pub fn wait_for_event(&mut self, event: &SharedEvent, value: u64) -> Result<(), Error> {
self.inner
.wait_for_event(&event.inner, value)
.map_err(Error::from_ffi)
}
pub fn signal_event(&mut self, event: &SharedEvent, value: u64) -> Result<(), Error> {
self.inner
.signal_event(&event.inner, value)
.map_err(Error::from_ffi)
}
pub fn enqueue(&mut self) -> Result<(), Error> {
self.inner.enqueue().map_err(Error::from_ffi)
}
#[must_use]
pub fn commit(self) -> SubmittedIoCommandBuffer {
SubmittedIoCommandBuffer {
inner: self.inner.commit(),
}
}
}
pub struct SubmittedIoCommandBuffer {
inner: metal_rust_ffi::SubmittedIoCommandBuffer,
}
impl SubmittedIoCommandBuffer {
#[must_use]
pub fn status(&self) -> IOStatus {
self.inner.status()
}
#[must_use]
pub fn error(&self) -> Option<Error> {
self.inner.error().map(Error::from_ffi)
}
pub fn try_cancel(&self) -> Result<(), Error> {
self.inner.try_cancel().map_err(Error::from_ffi)
}
pub fn wait(self) -> Result<CompletedIoCommandBuffer, Error> {
self.inner
.wait()
.map(|inner| CompletedIoCommandBuffer { inner })
.map_err(Error::from_ffi)
}
}
pub struct CompletedIoCommandBuffer {
inner: metal_rust_ffi::CompletedIoCommandBuffer,
}
impl CompletedIoCommandBuffer {
#[must_use]
pub fn status(&self) -> IOStatus {
self.inner.status()
}
#[must_use]
pub fn label(&self) -> Option<String> {
self.inner.label()
}
#[must_use]
pub fn error(&self) -> Option<Error> {
self.inner.error().map(Error::from_ffi)
}
}
impl Device {
pub fn new_io_command_queue(
&self,
descriptor: &IOCommandQueueDescriptor,
) -> Result<IoCommandQueue, Error> {
self.inner
.new_io_command_queue(&descriptor.inner)
.map(|inner| IoCommandQueue { inner })
.map_err(Error::from_ffi)
}
pub fn new_io_file_handle(
&self,
path: impl AsRef<Path>,
compression: Option<IOCompressionMethod>,
) -> Result<IoFileHandle, Error> {
self.inner
.new_io_file_handle(path.as_ref(), compression)
.map(|inner| IoFileHandle { inner })
.map_err(Error::from_ffi)
}
}
pub struct IoCompressionContext {
inner: metal_rust_ffi::IoCompressionContext,
}
impl IoCompressionContext {
pub fn default_chunk_size() -> Result<usize, Error> {
metal_rust_ffi::IoCompressionContext::default_chunk_size().map_err(Error::from_ffi)
}
pub fn new(
path: impl AsRef<Path>,
method: IOCompressionMethod,
chunk_size: usize,
) -> Result<Self, Error> {
metal_rust_ffi::IoCompressionContext::new(path.as_ref(), method, chunk_size)
.map(|inner| Self { inner })
.map_err(Error::from_ffi)
}
pub fn append(&mut self, bytes: &[u8]) -> Result<(), Error> {
self.inner.append(bytes).map_err(Error::from_ffi)
}
pub fn finish(self) -> Result<(), Error> {
self.inner.finish().map_err(Error::from_ffi)
}
}