use super::{
BlitCommandEncoder, BlitPassDescriptor, BufferReadback, CommandBufferErrorOption,
CommandBufferStatus, ComputeCommandEncoder, ComputePassDescriptor, DispatchType, Event,
LogContainer, RenderCommandEncoder, RenderPassDescriptor, ResidencySet,
};
use crate::{Drawable, Error};
impl super::CommandBufferEncoderInfo {
pub fn debug_signposts(&self) -> Result<Option<Vec<String>>, Error> {
self.inner.debug_signpost_strings().map_err(Error::from_ffi)
}
}
pub struct TextureReadback {
pub(crate) inner: metal_rust_ffi::TextureReadback,
}
pub struct TextureReadbackData {
pub bytes: Vec<u8>,
pub bytes_per_row: usize,
pub width: usize,
pub height: usize,
}
pub struct CommandBuffer {
pub(crate) inner: metal_rust_ffi::CommandBuffer,
}
impl CommandBuffer {
pub(crate) const fn from_ffi(inner: metal_rust_ffi::CommandBuffer) -> Self {
Self { inner }
}
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)
}
pub fn on_scheduled(
&mut self,
handler: impl FnOnce(Result<(), Error>) + Send + 'static,
) -> Result<(), Error> {
self.inner
.on_scheduled(move |result| handler(result.map_err(Error::from_ffi)))
.map_err(Error::from_ffi)
}
#[must_use]
pub fn device(&self) -> crate::Device {
crate::Device::from_ffi(self.inner.device())
}
#[must_use]
pub fn command_queue(&self) -> crate::CommandQueue {
crate::CommandQueue::from_ffi(self.inner.command_queue())
}
#[must_use]
pub fn label(&self) -> Option<String> {
self.inner.label()
}
pub fn set_label(&self, value: Option<&str>) {
self.inner.set_label(value);
}
#[must_use]
pub fn retained_references(&self) -> bool {
self.inner.retained_references()
}
pub fn push_debug_group(&mut self, value: &str) {
self.inner.push_debug_group(value);
}
pub fn pop_debug_group(&mut self) {
self.inner.pop_debug_group();
}
pub fn present_drawable_at_time(
&mut self,
drawable: &Drawable,
presentation_time: f64,
) -> Result<(), Error> {
self.inner
.present_drawable_at_time(&drawable.inner, presentation_time)
.map_err(Error::from_ffi)
}
pub fn present_drawable_after_minimum_duration(
&mut self,
drawable: &Drawable,
duration: f64,
) -> Result<(), Error> {
self.inner
.present_drawable_after_minimum_duration(&drawable.inner, duration)
.map_err(Error::from_ffi)
}
#[must_use]
pub fn gpu_start_time(&self) -> f64 {
self.inner.gpu_start_time()
}
#[must_use]
pub fn gpu_end_time(&self) -> f64 {
self.inner.gpu_end_time()
}
#[must_use]
pub fn kernel_start_time(&self) -> f64 {
self.inner.kernel_start_time()
}
#[must_use]
pub fn kernel_end_time(&self) -> f64 {
self.inner.kernel_end_time()
}
pub fn render_encoder<'a>(
&'a mut self,
descriptor: &RenderPassDescriptor,
) -> Result<RenderCommandEncoder<'a>, Error> {
self.inner
.render_encoder(&descriptor.inner)
.map(|inner| RenderCommandEncoder { inner })
.map_err(Error::from_ffi)
}
pub fn compute_encoder<'a>(
&'a mut self,
descriptor: &ComputePassDescriptor,
) -> Result<ComputeCommandEncoder<'a>, Error> {
self.inner
.compute_encoder(&descriptor.inner)
.map(|inner| ComputeCommandEncoder { inner })
.map_err(Error::from_ffi)
}
pub fn compute_encoder_default<'a>(&'a mut self) -> Result<ComputeCommandEncoder<'a>, Error> {
self.inner
.compute_encoder_default()
.map(|inner| ComputeCommandEncoder { inner })
.map_err(Error::from_ffi)
}
pub fn compute_encoder_with_dispatch_type<'a>(
&'a mut self,
dispatch_type: DispatchType,
) -> Result<ComputeCommandEncoder<'a>, Error> {
self.inner
.compute_encoder_with_dispatch_type(dispatch_type)
.map(|inner| ComputeCommandEncoder { inner })
.map_err(Error::from_ffi)
}
pub fn blit_encoder<'a>(&'a mut self) -> Result<BlitCommandEncoder<'a>, Error> {
self.inner
.blit_encoder()
.map(|inner| BlitCommandEncoder { inner })
.map_err(Error::from_ffi)
}
pub fn blit_encoder_with_descriptor<'a>(
&'a mut self,
descriptor: &BlitPassDescriptor,
) -> Result<BlitCommandEncoder<'a>, Error> {
self.inner
.blit_encoder_with_descriptor(&descriptor.inner)
.map(|inner| BlitCommandEncoder { inner })
.map_err(Error::from_ffi)
}
pub fn encode_wait(&mut self, event: &Event, value: u64) -> Result<(), Error> {
self.inner
.encode_wait(&event.inner, value)
.map_err(Error::from_ffi)
}
pub fn encode_signal_event(&mut self, event: &Event, value: u64) -> Result<(), Error> {
self.inner
.encode_signal_event(&event.inner, value)
.map_err(Error::from_ffi)
}
pub fn use_residency_sets(&mut self, sets: &[&ResidencySet]) -> Result<(), Error> {
let sets = sets.iter().map(|set| &set.inner).collect::<Vec<_>>();
self.inner
.use_residency_sets(&sets)
.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) -> SubmittedCommandBuffer {
SubmittedCommandBuffer {
inner: self.inner.commit(),
}
}
pub fn present_drawable(&mut self, drawable: &Drawable) {
self.inner.present_drawable(&drawable.inner);
}
#[must_use]
pub fn status(&self) -> CommandBufferStatus {
self.inner.status()
}
#[must_use]
pub fn error(&self) -> Option<Error> {
self.inner.error().map(Error::from_ffi)
}
pub fn error_options(&self) -> Result<CommandBufferErrorOption, Error> {
self.inner.error_options().map_err(Error::from_ffi)
}
}
pub struct SubmittedCommandBuffer {
inner: metal_rust_ffi::SubmittedCommandBuffer,
}
impl SubmittedCommandBuffer {
pub fn wait_until_scheduled(&self) -> Result<(), Error> {
self.inner.wait_until_scheduled().map_err(Error::from_ffi)
}
pub fn wait(self) -> Result<CompletedCommandBuffer, Error> {
self.inner
.wait()
.map(|inner| CompletedCommandBuffer { inner })
.map_err(Error::from_ffi)
}
#[must_use]
pub fn status(&self) -> CommandBufferStatus {
self.inner.status()
}
}
pub struct CompletedCommandBuffer {
inner: metal_rust_ffi::CompletedCommandBuffer,
}
impl CompletedCommandBuffer {
pub fn logs(&self) -> Result<LogContainer, Error> {
self.inner
.logs()
.map(LogContainer::from_ffi)
.map_err(Error::from_ffi)
}
pub fn resolve_buffer(&self, readback: BufferReadback) -> Result<Vec<u8>, Error> {
self.inner
.resolve_buffer(readback.inner)
.map_err(Error::from_ffi)
}
pub fn resolve_texture(&self, readback: TextureReadback) -> Result<TextureReadbackData, Error> {
self.inner
.resolve_texture(readback.inner)
.map(|value| TextureReadbackData {
bytes: value.bytes,
bytes_per_row: value.bytes_per_row,
width: value.width,
height: value.height,
})
.map_err(Error::from_ffi)
}
#[must_use]
pub fn status(&self) -> CommandBufferStatus {
self.inner.status()
}
}