diff options
Diffstat (limited to 'bindgen/rust/src/ral.rs')
-rw-r--r-- | bindgen/rust/src/ral.rs | 157 |
1 files changed, 146 insertions, 11 deletions
diff --git a/bindgen/rust/src/ral.rs b/bindgen/rust/src/ral.rs index 078121b..3ea69e2 100644 --- a/bindgen/rust/src/ral.rs +++ b/bindgen/rust/src/ral.rs @@ -1,23 +1,25 @@ //! Wrapper around the RAL code in celeritas-core -use std::ffi::c_void; +use std::ffi::{c_void, CString}; use celeritas_sys::{ BufferHandle, GPU_CmdEncoder, GPU_CmdEncoder_BeginRender, GPU_CmdEncoder_EndRender, GPU_EncodeBindShaderData, GPU_GetDefaultEncoder, GPU_GetDefaultRenderpass, GPU_GraphicsPipeline_Create, GPU_Pipeline, GraphicsPipelineDesc, ShaderBindingKind_BINDING_BYTES, ShaderBinding__bindgen_ty_1, - ShaderBinding__bindgen_ty_1__bindgen_ty_1, ShaderVisibility_VISIBILITY_COMPUTE, - ShaderVisibility_VISIBILITY_FRAGMENT, ShaderVisibility_VISIBILITY_VERTEX, TextureHandle, - MAX_SHADER_DATA_LAYOUTS, + ShaderBinding__bindgen_ty_1__bindgen_ty_1, ShaderDesc, ShaderVisibility_VISIBILITY_COMPUTE, + ShaderVisibility_VISIBILITY_FRAGMENT, ShaderVisibility_VISIBILITY_VERTEX, Str8, TextureHandle, + VertexDescription, MAX_SHADER_DATA_LAYOUTS, }; use thiserror::Error; +use crate::IntoFFI; + /// Holds a pointer to the raw `GPU_CmdEncoder` pub struct FrameRenderEncoder(*mut GPU_CmdEncoder); /// Holds a pointer to the raw `GPU_Renderpass` -pub struct RenderPass(*mut celeritas_sys::GPU_Renderpass); +pub struct RenderPass(pub *mut celeritas_sys::GPU_Renderpass); /// Holds a pointer to the raw `GPU_Pipeline` pub struct Pipeline(*mut celeritas_sys::GPU_Pipeline); @@ -58,9 +60,67 @@ impl FrameRenderEncoder { } } +// Vertex Descriptions +pub enum VertexAttrKind { + Floatx1, + Floatx2, + Floatx3, + Floatx4, + U32x1, + U32x2, + U32x3, + U32x4, + I32x1, + I32x2, + I32x3, + I32x4, +} + +pub struct VertexAttribute { + name: String, + kind: VertexAttrKind, +} + +#[derive(Default)] +pub struct VertexDesc { + debug_label: String, + attributes: Vec<VertexAttribute>, +} +impl VertexDesc { + pub fn new(name: String) -> Self { + Self { + debug_label: name, + attributes: vec![], + } + } + pub fn add_attr(mut self, attr_name: &str, kind: VertexAttrKind) -> Self { + self.attributes.push(VertexAttribute { + name: attr_name.to_owned(), + kind, + }); + self + } +} +impl IntoFFI for VertexDesc { + type FFIType = VertexDescription; + + unsafe fn into_ffi(self) -> Self::FFIType { + VertexDescription { + debug_label: todo!(), + attr_names: todo!(), + attributes: todo!(), + attributes_count: todo!(), + use_full_vertex_size: todo!(), + } + } +} + pub struct PipelineBuilder { + name: String, renderpass: Option<RenderPass>, + vertex_description: VertexDesc, data_layouts: Vec<ShaderDataLayout>, + shader_paths: Option<(String, String)>, } #[derive(Debug, Error)] @@ -70,6 +130,17 @@ pub enum RALError { } impl PipelineBuilder { + /// Create a new [PipelineBuilder] + pub fn new(name: String) -> Self { + let vertex_description = VertexDesc::new(format!("{} Vertex Description", name.clone())); + Self { + name, + renderpass: None, + vertex_description, + data_layouts: Vec::new(), + shader_paths: None, + } + } pub fn build(self) -> Result<Pipeline, RALError> { let layouts = [celeritas_sys::ShaderDataLayout::default(); 8]; if self.data_layouts.len() > MAX_SHADER_DATA_LAYOUTS as usize { @@ -78,12 +149,32 @@ impl PipelineBuilder { for (i, layout) in self.data_layouts.iter().enumerate().take(8) { // layouts[i] = celeritas_sys::ShaderDataLayout::from(layout); } + let (vert_path, frag_path) = self.shader_paths.expect("Shader paths must be provided"); + let vert_code = std::fs::read_to_string(vert_path.clone()).expect("msg"); + let frag_code = std::fs::read_to_string(frag_path.clone()).expect("msg"); - let mut desc = GraphicsPipelineDesc { - debug_name: todo!(), - vertex_desc: todo!(), - vs: todo!(), - fs: todo!(), + // TODO: convert VertexDesc -> ffi::VertexDescription + // load shader + let vs = ShaderDesc { + debug_name: "".as_ptr() as *const i8, + filepath: Str8::from_str(&vert_path), + code: Str8::from_str(&vert_code), + is_spirv: false, + is_combined_vert_frag: false, + }; + let fs = ShaderDesc { + debug_name: "".as_ptr() as *const i8, + filepath: Str8::from_str(&frag_path), + code: Str8::from_str(&frag_code), + is_spirv: false, + is_combined_vert_frag: false, + }; + + let desc = GraphicsPipelineDesc { + debug_name: "".as_ptr() as *const _, + vertex_desc: unsafe { self.vertex_description.into_ffi() }, + vs, + fs, data_layouts: layouts, data_layouts_count: layouts.len() as u32, wireframe: false, @@ -100,11 +191,19 @@ impl PipelineBuilder { Ok(Pipeline(p)) } - pub fn add_shader_layout<S: ShaderData>(&mut self) -> &mut Self { + pub fn add_vertex_desc(mut self, vertex_desc: VertexDesc) -> Self { + self.vertex_description = vertex_desc; + self + } + pub fn add_shader_layout<S: ShaderData>(mut self) -> Self { let layout = S::layout(); self.data_layouts.push(layout); self } + pub fn add_shader_src(mut self, vertex_path: &str, fragment_path: &str) -> Self { + self.shader_paths = Some((vertex_path.to_owned(), fragment_path.to_owned())); + self + } } impl Pipeline { @@ -159,6 +258,11 @@ pub struct ShaderDataLayout { pub bindings: heapless::Vec<ShaderBinding, 8>, } impl ShaderDataLayout { + pub fn from_slice(bindings: &[ShaderBinding]) -> Self { + todo!() + } +} +impl ShaderDataLayout { pub fn into_ffi_type(self) -> celeritas_sys::ShaderDataLayout { let mut bindings = [celeritas_sys::ShaderBinding::default(); 8]; for (i, b) in self.bindings.iter().enumerate().take(8) { @@ -210,3 +314,34 @@ impl From<celeritas_sys::PrimitiveTopology> for PrimitiveTopology { } } } +#[cfg(test)] +mod test { + use super::*; + + struct TestData { + a: [f32; 2], + b: [f32; 4], + } + impl ShaderData for TestData { + fn layout() -> ShaderDataLayout { + todo!() + } + + fn bind(&self) { + todo!() + } + } + + #[test] + fn typecheck_pipeline_create() { + let vertex_desc = VertexDesc::new("Empty".into()) + .add_attr("position", VertexAttrKind::Floatx2) + .add_attr("color", VertexAttrKind::Floatx4); + + let mut builder = PipelineBuilder::new("Test Pipeline".into()) + .add_shader_layout::<TestData>() + .add_vertex_desc(vertex_desc); + + let pipeline = builder.build().expect("Should be valid"); + } +} |