diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..22dc292 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,7 @@ +# Contributing to this repository + +Useful steps to work on the source code and generated bindings in this repository. + +## Regenerating Bindings + +This crate contains bindings generated by `bindgen`. Typically, the included bindings can be used as-is, but if needed they can be regenerated by running `cargo run -p bindings_generator`. Updated headers and licenses should be copied to the `./bindings_generator/vendor/` folder. diff --git a/Cargo.toml b/Cargo.toml index f0fc858..302f79c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -9,7 +9,7 @@ repository = "https://github.com/Traverse-Research/saxaboom" description = "Binding library for Metal Shader Converter" include = ["src", "LICENSE"] categories = ["api-bindings", "external-ffi-bindings", "graphics", "compilers"] -keywords = ["metal", "shader", "metal_irconverter", "apple", "macos", "ios"] +keywords = ["metal", "shader", "metal_irconverter", "apple", "macos"] [workspace] members = [ diff --git a/README.md b/README.md index be28290..82c892d 100644 --- a/README.md +++ b/README.md @@ -1,31 +1,56 @@ # 🤘 Saxaboom [![Actions Status](https://github.com/Traverse-Research/saxaboom/actions/workflows/ci.yml/badge.svg)](https://github.com/Traverse-Research/saxaboom/actions) -[![Latest version](https://img.shields.io/crates/v/saxaboom.svg?logo=rust)](https://crates.io/crates/saxaboom) -[![Documentation](https://docs.rs/saxaboom/badge.svg)](https://docs.rs/saxaboom) -[![Lines of code](https://tokei.rs/b1/github/Traverse-Research/saxaboom)](https://github.com/Traverse-Research/saxaboom) -![MIT](https://img.shields.io/badge/license-MIT-blue.svg) +[![Latest version](https://img.shields.io/crates/v/saxaboom.svg?logo=rust)][`saxaboom`] +[![Documentation](https://img.shields.io/docsrs/saxaboom/latest?logo=docs.rs)](https://docs.rs/saxaboom) +![Apache](https://img.shields.io/badge/license-Apache-blue.svg) [![Contributor Covenant](https://img.shields.io/badge/contributor%20covenant-v1.4%20adopted-ff69b4.svg)](./CODE_OF_CONDUCT.md) [![Banner](banner.png)](https://traverseresearch.nl) -Small helper library around [Metal shader converter] to create metal shader libraries from DXIL files. - -[Metal shader converter]: https://developer.apple.com/metal/shader-converter/ +[`saxaboom`] is a small helper library around [Metal shader converter] to create metal shader libraries from `DXIL` files (HLSL source code). See also [`saxaboom-runtime`] which provides the runtime structures and interop with the [`metal`] crate needed to make use of the resulting `metallib` shaders. ## Usage -Add this to your Cargo.toml: +Add this to your `Cargo.toml`: ```toml [dependencies] saxaboom = "0.1.0" ``` -```rust -// A code example +Example to compile `DXIL` to `metallib`: + +```rust,no_run +use saxaboom::{ffi, MetalIrConverter}; + +fn main() -> Result<(), Box> { + // Load the library + let metal_irconverter = MetalIrConverter::new("libmetalirconverter.dylib").unwrap(); + // Create an instance of IRCompiler + let mut compiler = metal_irconverter.create_compiler(); + // Create an object containing DXIL bytes, replace &[0u8] with your DXIL data + let dxil = metal_irconverter.create_object_from_dxil(&[0u8]); + + // See `IRCompiler` docs for possible state that can be set on the compiler before compiling + // DXIL source, such as a global root signatures and various raytracing parameters. + + // Compile the `dxil` data blob with entrypoint `main` into mtllib + let mtllib = compiler.alloc_compile_and_link(c"main", &dxil)?; + + let reflection = mtllib.reflection(); + let mtl_binary = mtllib + .metal_lib_binary() + .expect("Compiled object should contain a `metallib`"); + let bytecode = mtl_binary.byte_code(); + + Ok(()) +} ``` -## Regenerating Bindings -This crate contains bindings generated by `bindgen`. Typically, the included bindings can be used as-is, but if needed -they can be regenerated by running `cargo run -p bindings_generator`. +For using the loaded `metallib` shaders at runtime most effectively, consult [`saxaboom-runtime`]. + +[Metal shader converter]: https://developer.apple.com/metal/shader-converter/ +[`saxaboom`]: https://crates.io/crates/saxaboom +[`saxaboom-runtime`]: https://crates.io/crates/saxaboom-runtime +[`metal`]: https://crates.io/crates/metal diff --git a/examples/compute_shader.rs b/examples/compute_shader.rs index be149a8..729846b 100644 --- a/examples/compute_shader.rs +++ b/examples/compute_shader.rs @@ -26,60 +26,59 @@ fn create_static_sampler( } fn main() -> Result<(), Box> { - unsafe { - // Load the library - let metal_irconverter = MetalIrConverter::new("libmetalirconverter.dylib").unwrap(); - // Create an instance of IRCompiler - let mut compiler = metal_irconverter.create_compiler(); - - // Create an explicit root signature layout - let mut parameters = create_root_parameters(); - let mut static_samplers = create_static_samplers(); - - let desc_1_1 = ffi::IRRootSignatureDescriptor1 { - Flags: ffi::IRRootSignatureFlags::CBVSRVUAVHeapDirectlyIndexed, - NumParameters: parameters.len() as u32, - pParameters: parameters.as_mut_ptr(), - NumStaticSamplers: static_samplers.len() as u32, - pStaticSamplers: static_samplers.as_mut_ptr(), - }; - - let desc = ffi::IRVersionedRootSignatureDescriptor { - version: ffi::IRRootSignatureVersion::_1_1, - u_1: ffi::IRVersionedRootSignatureDescriptor_u { desc_1_1 }, - }; - - let root_sig = metal_irconverter.create_root_signature_from_descriptor(&desc)?; - compiler.set_global_root_signature(&root_sig); - - // Load DXIL - let dxil = include_bytes!("assets/memcpy.cs.dxil"); - let obj = metal_irconverter.create_object_from_dxil(dxil); - - // Convert to Metal - let mtllib = compiler.alloc_compile_and_link(c"main", &obj)?; - let mtl_binary = mtllib - .metal_lib_binary() - .expect("Compiled object should contain a `metallib`"); - - // Get Metal bytecode - let metal_bytecode = mtl_binary.byte_code(); - dbg!(metal_bytecode.len()); - dbg!(mtllib.r#type()); - dbg!(mtllib.metal_ir_shader_stage()); - - // Get reflection from the shader - let mtl_reflection = mtllib.reflection(); - - let compute_info = mtl_reflection.map(|mtl_reflection| { - mtl_reflection - .compute_info(ffi::IRReflectionVersion::_1_0) - .unwrap() - .u_1 - .info_1_0 - }); - dbg!(compute_info); - } + // Load the library + let metal_irconverter = MetalIrConverter::new("libmetalirconverter.dylib").unwrap(); + // Create an instance of IRCompiler + let mut compiler = metal_irconverter.create_compiler(); + + // Create an explicit root signature layout + let mut parameters = create_root_parameters(); + let mut static_samplers = create_static_samplers(); + + let desc_1_1 = ffi::IRRootSignatureDescriptor1 { + Flags: ffi::IRRootSignatureFlags::CBVSRVUAVHeapDirectlyIndexed, + NumParameters: parameters.len() as u32, + pParameters: parameters.as_mut_ptr(), + NumStaticSamplers: static_samplers.len() as u32, + pStaticSamplers: static_samplers.as_mut_ptr(), + }; + + let desc = ffi::IRVersionedRootSignatureDescriptor { + version: ffi::IRRootSignatureVersion::_1_1, + u_1: ffi::IRVersionedRootSignatureDescriptor_u { desc_1_1 }, + }; + + let root_sig = metal_irconverter.create_root_signature_from_descriptor(&desc)?; + compiler.set_global_root_signature(&root_sig); + + // Load DXIL + let dxil = include_bytes!("assets/memcpy.cs.dxil"); + let dxil = metal_irconverter.create_object_from_dxil(dxil); + + // Convert to Metal + let mtllib = compiler.alloc_compile_and_link(c"main", &dxil)?; + let mtl_binary = mtllib + .metal_lib_binary() + .expect("Compiled object should contain a `metallib`"); + + // Get Metal bytecode + let metal_bytecode = mtl_binary.byte_code(); + dbg!(metal_bytecode.len()); + dbg!(mtllib.r#type()); + dbg!(mtllib.metal_ir_shader_stage()); + + // Get reflection from the shader + let mtl_reflection = mtllib.reflection(); + + let compute_info = mtl_reflection.map(|mtl_reflection| unsafe { + mtl_reflection + .compute_info(ffi::IRReflectionVersion::_1_0) + .unwrap() + .u_1 + .info_1_0 + }); + dbg!(compute_info); + Ok(()) } diff --git a/release.toml b/release.toml index ce3e640..c3dd0da 100644 --- a/release.toml +++ b/release.toml @@ -6,7 +6,8 @@ sign-tag = true publish = false pre-release-replacements = [ - { file = "README.md", search = "saxaboom = .*", replace = "{{crate_name}} = \"{{version}}\"" }, + { file = "README.md", search = "saxaboom = .*", replace = "saxaboom = \"{{version}}\"", min = 0 }, + { file = "README.md", search = "saxaboom-runtime = .*", replace = "saxaboom-runtime = \"{{version}}\"", min = 0 }, ] # cargo-release only allows using {{version}} in the commit title when creating one diff --git a/runtime/Cargo.toml b/runtime/Cargo.toml index b254568..e640c30 100644 --- a/runtime/Cargo.toml +++ b/runtime/Cargo.toml @@ -8,7 +8,7 @@ homepage = "https://traverseresearch.nl" repository = "https://github.com/Traverse-Research/saxaboom" description = "Runtime definitions for Metal Shader Converter" categories = ["api-bindings", "external-ffi-bindings", "graphics"] -keywords = ["metal", "shader", "metal_irconverter", "apple", "macos", "ios"] +keywords = ["metal", "shader", "metal_irconverter", "apple", "macos"] [package.metadata.docs.rs] targets = [ diff --git a/runtime/README.md b/runtime/README.md deleted file mode 120000 index 32d46ee..0000000 --- a/runtime/README.md +++ /dev/null @@ -1 +0,0 @@ -../README.md \ No newline at end of file diff --git a/runtime/README.md b/runtime/README.md new file mode 100644 index 0000000..7f35710 --- /dev/null +++ b/runtime/README.md @@ -0,0 +1,35 @@ +# 🤘 Saxaboom runtime + +[![Actions Status](https://github.com/Traverse-Research/saxaboom/actions/workflows/ci.yml/badge.svg)](https://github.com/Traverse-Research/saxaboom/actions) +[![Latest version](https://img.shields.io/crates/v/saxaboom-runtime.svg?logo=rust)][`saxaboom-runtime`] +[![Documentation](https://img.shields.io/docsrs/saxaboom-runtime/latest?logo=docs.rs)](https://docs.rs/saxaboom-runtime) +![Apache](https://img.shields.io/badge/license-Apache-blue.svg) +[![Contributor Covenant](https://img.shields.io/badge/contributor%20covenant-v1.4%20adopted-ff69b4.svg)](../CODE_OF_CONDUCT.md) + +[![Banner](../banner.png)](https://traverseresearch.nl) + +[`saxaboom-runtime`] provides the runtime structures and interop with the [`metal`] crate needed to make use of the `metallib` shaders generated by [`saxaboom`] (bindings for [Metal shader converter]). + +## Usage + +After compiling your `DXIL` shaders to `metallib` using [`saxaboom`], follow these steps in your render backend. + +Add this to your `Cargo.toml`: + +```toml +[dependencies] +saxaboom-runtime = "0.1.0" +``` + +```rust,no_run +use saxaboom_runtime::ffi::IRDescriptorTableEntry; + +let gpu_address = 0; // TODO: Read from metal::Buffer::gpu_address() +let metadata = IRDescriptorTableEntry::buffer_metadata(&todo!("Fill saxaboom_runtime::BufferView")); +let buffer_descriptor = IRDescriptorTableEntry::buffer(gpu_address, metadata); +``` + +[Metal shader converter]: https://developer.apple.com/metal/shader-converter/ +[`saxaboom`]: https://crates.io/crates/saxaboom +[`saxaboom-runtime`]: https://crates.io/crates/saxaboom-runtime +[`metal`]: https://crates.io/crates/metal