2024-02-10 16:04:16 +11:00
|
|
|
use array_concat::concat_arrays;
|
2024-02-11 12:59:01 +11:00
|
|
|
use bytemuck::{Pod, Zeroable};
|
|
|
|
use icrate::Metal::{
|
|
|
|
MTLBuffer, MTLDevice, MTLPrimitiveTypeTriangleStrip, MTLRenderCommandEncoder,
|
|
|
|
MTLResourceStorageModeManaged, MTLResourceStorageModeShared,
|
|
|
|
};
|
|
|
|
use librashader_runtime::quad::QuadType;
|
2024-02-10 16:04:16 +11:00
|
|
|
use objc2::rc::Id;
|
|
|
|
use objc2::runtime::ProtocolObject;
|
2024-02-11 12:59:01 +11:00
|
|
|
use std::ffi::c_void;
|
|
|
|
use std::ptr::NonNull;
|
2024-02-10 16:04:16 +11:00
|
|
|
|
|
|
|
use crate::error::{FilterChainError, Result};
|
2024-02-12 12:38:55 +11:00
|
|
|
use crate::graphics_pipeline::VERTEX_BUFFER_INDEX;
|
2024-02-10 16:04:16 +11:00
|
|
|
|
2024-02-11 12:59:01 +11:00
|
|
|
#[repr(C)]
|
|
|
|
#[derive(Debug, Copy, Clone, Default, Zeroable, Pod)]
|
2024-02-12 16:43:51 +11:00
|
|
|
pub(crate) struct MetalVertex {
|
|
|
|
pub position: [f32; 4],
|
|
|
|
pub texcoord: [f32; 2],
|
2024-02-11 12:59:01 +11:00
|
|
|
}
|
|
|
|
|
2024-02-12 16:43:51 +11:00
|
|
|
const OFFSCREEN_VBO_DATA: [MetalVertex; 4] = [
|
2024-02-11 12:59:01 +11:00
|
|
|
MetalVertex {
|
2024-02-12 16:43:51 +11:00
|
|
|
position: [-1.0, -1.0, 0.0, 1.0],
|
2024-02-11 12:59:01 +11:00
|
|
|
texcoord: [0.0, 1.0],
|
|
|
|
},
|
|
|
|
MetalVertex {
|
2024-02-12 16:43:51 +11:00
|
|
|
position: [-1.0, 1.0, 0.0, 1.0],
|
|
|
|
texcoord: [0.0, 0.0],
|
|
|
|
},
|
|
|
|
MetalVertex {
|
|
|
|
position: [1.0, -1.0, 0.0, 1.0],
|
2024-02-11 12:59:01 +11:00
|
|
|
texcoord: [1.0, 1.0],
|
|
|
|
},
|
2024-02-12 16:43:51 +11:00
|
|
|
MetalVertex {
|
|
|
|
position: [1.0, 1.0, 0.0, 1.0],
|
|
|
|
texcoord: [1.0, 0.0],
|
|
|
|
},
|
|
|
|
];
|
|
|
|
|
|
|
|
|
|
|
|
const FINAL_VBO_DATA: [MetalVertex; 4] = [
|
2024-02-11 12:59:01 +11:00
|
|
|
MetalVertex {
|
|
|
|
position: [0.0, 0.0, 0.0, 1.0],
|
2024-02-12 16:43:51 +11:00
|
|
|
texcoord: [0.0, 1.0],
|
|
|
|
},
|
|
|
|
MetalVertex {
|
|
|
|
position: [0.0, 1.0, 0.0, 1.0],
|
2024-02-11 12:59:01 +11:00
|
|
|
texcoord: [0.0, 0.0],
|
|
|
|
},
|
|
|
|
MetalVertex {
|
|
|
|
position: [1.0, 0.0, 0.0, 1.0],
|
2024-02-12 16:43:51 +11:00
|
|
|
texcoord: [1.0, 1.0],
|
|
|
|
},
|
|
|
|
MetalVertex {
|
|
|
|
position: [1.0, 1.0, 0.0, 1.0],
|
2024-02-11 12:59:01 +11:00
|
|
|
texcoord: [1.0, 0.0],
|
|
|
|
},
|
|
|
|
];
|
|
|
|
|
2024-02-10 16:04:16 +11:00
|
|
|
#[rustfmt::skip]
|
|
|
|
const VBO_OFFSCREEN: [f32; 16] = [
|
|
|
|
// Offscreen
|
|
|
|
-1.0f32, -1.0, 0.0, 0.0,
|
|
|
|
-1.0, 1.0, 0.0, 1.0,
|
|
|
|
1.0, -1.0, 1.0, 0.0,
|
|
|
|
1.0, 1.0, 1.0, 1.0,
|
|
|
|
];
|
|
|
|
|
|
|
|
#[rustfmt::skip]
|
|
|
|
const VBO_DEFAULT_FINAL: [f32; 16] = [
|
|
|
|
// Final
|
|
|
|
0.0f32, 0.0, 0.0, 0.0,
|
|
|
|
0.0, 1.0, 0.0, 1.0,
|
|
|
|
1.0, 0.0, 1.0, 0.0,
|
|
|
|
1.0, 1.0, 1.0, 1.0,
|
|
|
|
];
|
|
|
|
|
2024-02-12 16:43:51 +11:00
|
|
|
const VBO_DATA: [MetalVertex; 8] = concat_arrays!(OFFSCREEN_VBO_DATA, FINAL_VBO_DATA);
|
2024-02-10 16:04:16 +11:00
|
|
|
|
|
|
|
pub struct DrawQuad {
|
|
|
|
buffer: Id<ProtocolObject<dyn MTLBuffer>>,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl DrawQuad {
|
|
|
|
pub fn new(device: &ProtocolObject<dyn MTLDevice>) -> Result<DrawQuad> {
|
|
|
|
let vbo_data: &'static [u8] = bytemuck::cast_slice(&VBO_DATA);
|
2024-02-12 16:43:51 +11:00
|
|
|
// let buffer = unsafe {
|
|
|
|
// device
|
|
|
|
// .newBufferWithBytes_length_options(
|
|
|
|
// // SAFETY: this pointer is const.
|
|
|
|
// // https://developer.apple.com/documentation/metal/mtldevice/1433429-newbufferwithbytes
|
|
|
|
// NonNull::new_unchecked(vbo_data.as_ptr() as *mut c_void),
|
|
|
|
// vbo_data.len(),
|
|
|
|
// if cfg!(target_os = "ios") {
|
|
|
|
// MTLResourceStorageModeShared
|
|
|
|
// } else {
|
|
|
|
// MTLResourceStorageModeManaged
|
|
|
|
// },
|
|
|
|
// )
|
|
|
|
// .ok_or(FilterChainError::BufferError)?
|
|
|
|
// };
|
|
|
|
|
2024-02-12 09:54:13 +11:00
|
|
|
let buffer = unsafe {
|
|
|
|
device
|
|
|
|
.newBufferWithBytes_length_options(
|
|
|
|
// SAFETY: this pointer is const.
|
|
|
|
// https://developer.apple.com/documentation/metal/mtldevice/1433429-newbufferwithbytes
|
|
|
|
NonNull::new_unchecked(vbo_data.as_ptr() as *mut c_void),
|
|
|
|
vbo_data.len(),
|
|
|
|
if cfg!(target_os = "ios") {
|
|
|
|
MTLResourceStorageModeShared
|
|
|
|
} else {
|
|
|
|
MTLResourceStorageModeManaged
|
|
|
|
},
|
|
|
|
)
|
|
|
|
.ok_or(FilterChainError::BufferError)?
|
2024-02-10 16:04:16 +11:00
|
|
|
};
|
|
|
|
|
|
|
|
Ok(DrawQuad { buffer })
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn draw_quad(&self, cmd: &ProtocolObject<dyn MTLRenderCommandEncoder>, vbo: QuadType) {
|
2024-02-11 12:59:01 +11:00
|
|
|
// TODO: need to see how naga outputs MSL
|
2024-02-10 16:04:16 +11:00
|
|
|
let offset = match vbo {
|
|
|
|
QuadType::Offscreen => 0,
|
|
|
|
QuadType::Final => 4,
|
|
|
|
};
|
|
|
|
|
|
|
|
unsafe {
|
2024-02-12 16:43:51 +11:00
|
|
|
cmd.setVertexBuffer_offset_atIndex(Some(&self.buffer), 0, VERTEX_BUFFER_INDEX);
|
|
|
|
cmd.drawPrimitives_vertexStart_vertexCount(MTLPrimitiveTypeTriangleStrip,
|
|
|
|
offset,
|
|
|
|
4);
|
2024-02-10 16:04:16 +11:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|