use crate::{
ffi, texture_usage, util::take_optional_string, MetalDevice, MetalFunction, TextureDescriptor,
};
use core::ffi::c_void;
pub mod primitive_type {
pub const POINT: usize = 0;
pub const LINE: usize = 1;
pub const LINE_STRIP: usize = 2;
pub const TRIANGLE: usize = 3;
pub const TRIANGLE_STRIP: usize = 4;
}
pub mod load_action {
pub const DONT_CARE: usize = 0;
pub const LOAD: usize = 1;
pub const CLEAR: usize = 2;
}
pub mod store_action {
pub const DONT_CARE: usize = 0;
pub const STORE: usize = 1;
pub const MULTISAMPLE_RESOLVE: usize = 2;
pub const STORE_AND_MULTISAMPLE_RESOLVE: usize = 3;
}
pub struct RenderPipelineState {
ptr: *mut c_void,
}
unsafe impl Send for RenderPipelineState {}
unsafe impl Sync for RenderPipelineState {}
impl Drop for RenderPipelineState {
fn drop(&mut self) {
if !self.ptr.is_null() {
unsafe { ffi::am_object_release(self.ptr) };
self.ptr = core::ptr::null_mut();
}
}
}
impl RenderPipelineState {
#[must_use]
pub const fn as_ptr(&self) -> *mut c_void {
self.ptr
}
fn wrap(ptr: *mut c_void) -> Option<Self> {
if ptr.is_null() {
None
} else {
Some(Self { ptr })
}
}
#[must_use]
pub fn label(&self) -> Option<String> {
unsafe { take_optional_string(ffi::am_object_copy_label(self.ptr)) }
}
}
impl MetalDevice {
pub fn new_render_pipeline_state(
&self,
vertex: &MetalFunction,
fragment: &MetalFunction,
color_pixel_format: usize,
sample_count: usize,
) -> Result<RenderPipelineState, String> {
let mut err: *mut core::ffi::c_char = core::ptr::null_mut();
let ptr = unsafe {
ffi::am_device_new_render_pipeline_state(
self.as_ptr(),
vertex.as_ptr(),
fragment.as_ptr(),
color_pixel_format,
sample_count,
&mut err,
)
};
RenderPipelineState::wrap(ptr).ok_or_else(|| unsafe {
take_optional_string(err)
.unwrap_or_else(|| "MTLDevice.makeRenderPipelineState returned nil".to_string())
})
}
}
impl TextureDescriptor {
#[must_use]
pub const fn render_target_2d(width: usize, height: usize, pixel_format: usize) -> Self {
Self {
pixel_format,
width,
height,
mipmapped: false,
usage: texture_usage::RENDER_TARGET | texture_usage::SHADER_READ,
storage_mode: crate::storage_mode::PRIVATE,
}
}
}