tirbofish/dropbear · diff
publish: publishing 0.1.0 slank to crates.io Unverified
@@ -4,6 +4,7 @@ package.edition = "2024" package.license = "MIT OR Apache-2.0" package.repository = "https://github.com/tirbofish/dropbear" package.readme = "README.md" +package.authors = ["Thribhu K <4tkbytes@pm.me>"] resolver = "3" members = [ @@ -73,8 +74,9 @@ rapier3d = { version = "0.32", features = [ "simd-stable", "serde-serialize" ] } cbindgen = { version = "0.29.2" } postcard = { version = "1.1"} pollster = "0.4" -yakui = { git = "https://github.com/SecondHalfGames/yakui", rev = "ddf7614" } -yakui-wgpu = { git = "https://github.com/SecondHalfGames/yakui", rev = "ddf7614" } +yakui = { git = "https://github.com/SecondHalfGames/yakui", rev = "af8fc1f" } +yakui-wgpu = { git = "https://github.com/SecondHalfGames/yakui", rev = "af8fc1f" } +yakui-winit = { git = "https://github.com/SecondHalfGames/yakui", rev = "af8fc1f" } thiserror = "2.0" tempfile = "3.24" combine = "4.6" @@ -1,15 +1,17 @@ [package] name = "slank" -version.workspace = true +version = "0.1.0" edition.workspace = true license.workspace = true repository.workspace = true readme = "README.md" +keywords = ["graphics", "shader", "slang", "wgpu", "vulkan"] +authors.workspace = true +description = "A build.rs slang shader compiler" [dependencies] wgpu = { workspace = true, optional = true } -thiserror.workspace = true tempfile.workspace = true anyhow.workspace = true @@ -21,11 +23,10 @@ download-slang = [] use-wgpu = ["wgpu/default", "wgpu/spirv"] [build-dependencies] -dirs = "6.0.0" -reqwest = { version = "0.13.1", features = ["blocking", "json"] } -zip = "7.2.0" -flate2 = "1.1.8" -tar = "0.4.44" +dirs = "6.0" +reqwest = { version = "0.13", features = ["blocking", "json"] } +zip = "7.2" +flate2 = "1.1" +tar = "0.4" anyhow.workspace = true -serde = { workspace = true } -serde_json = "1.0" +serde = { workspace = true } @@ -1,4 +1,52 @@ # slank -A rust version of the slang compiler, ready to be used by wgpu, or vulkan (or any graphics library really, i personally -use wgpu). +A rust version of the slang compiler, ready to be used by wgpu, vulkan or directx (or any graphics library really, i personally +use wgpu). + +# Usage + +Add `slank` to your `[build-dependencies]`. + +In your `build.rs`: +```rust +use slank::{ShaderStage, SlangShaderBuilder, SlangTarget}; +use std::path::Path; + +fn main() { + let out_dir = std::env::var("OUT_DIR").unwrap(); + let dest_path = Path::new(&out_dir).join("shader.spv"); + + SlangShaderBuilder::new("shader_label") + .add_source_path("src/shader.slang").unwrap() + .entry_with_stage("vs_main", ShaderStage::Vertex) + .entry_with_stage("fs_main", ShaderStage::Fragment) + .build(SlangTarget::SpirV).unwrap() + .output(&dest_path).unwrap(); + + println!("cargo:rerun-if-changed=src/shader.slang"); +} +``` + +Then in your main code: + +```rust,ignore +let shader_bytes = slank::include_slang!("shader_label"); + +// optionally +slank::CompiledSlangShader::from_bytes("shader_label", shader_bytes); +``` + +# Features +There are two main features currently available: + +- `download-slang` - Slank downloads the latest slangc compiler from the GitHub releases and stores it + in the user cache. The SLANG_DIR will be set to the directory of the slangc compiler. +- `use-wgpu` - Enables wgpu as a dependency and unlocks utility traits for wgpu. + +# Contribution + +This is part of the larger `dropbear-engine` project, however that shouldn't stop you from contributing to this +repository. It is still missing a lot of different stuff, such as modules, more arguments and better Vulkan/DirectX +library utility support. + +Your help is appreciated. @@ -1,5 +1,8 @@ +use std::fs::File; use std::path::PathBuf; use std::process::Command; +use flate2::read::GzDecoder; +use tar::Archive; fn main() -> anyhow::Result<()> { println!("cargo:rerun-if-changed=build.rs"); @@ -71,7 +74,6 @@ fn find_in_path(name: &str) -> Option<PathBuf> { std::env::split_paths(&paths) .filter_map(|dir| { let full_path = dir.join(name); - // On Windows, also try with .exe extension #[cfg(target_os = "windows")] { if full_path.with_extension("exe").exists() { @@ -125,9 +127,6 @@ fn check_cached_download() -> Option<PathBuf> { #[cfg(feature = "download-slang")] fn download_slang() -> anyhow::Result<PathBuf> { - use std::fs; - - // println!("cargo:warning=Downloading slangc compiler..."); let target_os = std::env::var("CARGO_CFG_TARGET_OS").unwrap(); let target_arch = std::env::var("CARGO_CFG_TARGET_ARCH").unwrap(); @@ -141,16 +140,13 @@ fn download_slang() -> anyhow::Result<PathBuf> { .join("slank") .join("slangc"); - fs::create_dir_all(&cache_dir) + std::fs::create_dir_all(&cache_dir) .map_err(|e| anyhow::anyhow!("Failed to create cache directory: {}", e))?; let archive_path = cache_dir.join(&archive_name); if !archive_path.exists() { - // println!("cargo:warning=Downloading from: {}", download_url); download_file(&download_url, &archive_path)?; - } else { - // println!("cargo:warning=Using cached download: {}", archive_path.display()); } extract_archive(&archive_path, &cache_dir)?; @@ -170,11 +166,11 @@ fn download_slang() -> anyhow::Result<PathBuf> { #[cfg(unix)] { use std::os::unix::fs::PermissionsExt; - let mut perms = fs::metadata(&slangc_exe) + let mut perms = std::fs::metadata(&slangc_exe) .map_err(|e| anyhow::anyhow!("Failed to get permissions: {}", e))? .permissions(); perms.set_mode(0o755); - fs::set_permissions(&slangc_exe, perms) + std::fs::set_permissions(&slangc_exe, perms) .map_err(|e| anyhow::anyhow!("Failed to set permissions: {}", e))?; } @@ -230,8 +226,6 @@ fn get_download_url(version: &str, os: &str, arch: &str) -> anyhow::Result<(Stri #[cfg(feature = "download-slang")] fn download_file(url: &str, dest: &PathBuf) -> anyhow::Result<()> { - use std::fs::File; - let client = reqwest::blocking::Client::builder() .timeout(std::time::Duration::from_secs(600)) .build() @@ -257,8 +251,6 @@ fn download_file(url: &str, dest: &PathBuf) -> anyhow::Result<()> { #[cfg(feature = "download-slang")] fn extract_archive(archive: &PathBuf, dest: &PathBuf) -> anyhow::Result<()> { - use std::fs::File; - let file = File::open(archive) .map_err(|e| anyhow::anyhow!("Failed to open archive: {}", e))?; @@ -269,9 +261,6 @@ fn extract_archive(archive: &PathBuf, dest: &PathBuf) -> anyhow::Result<()> { archive.extract(dest) .map_err(|e| anyhow::anyhow!("Failed to extract zip: {}", e))?; } else { - use flate2::read::GzDecoder; - use tar::Archive; - let tar = GzDecoder::new(file); let mut archive = Archive::new(tar); @@ -34,6 +34,7 @@ impl CompiledSlangShader { } } + /// Returns the label of the shader. pub fn label(&self) -> String { self.label.clone() } @@ -21,11 +21,12 @@ macro_rules! include_slang_path { }; } -pub mod compiled; +mod compiled; pub mod utils; +pub use crate::compiled::*; + use std::{fmt::Display, path::{Path, PathBuf}}; -use crate::compiled::CompiledSlangShader; #[derive(Debug, Clone)] pub struct SourceFile { @@ -71,7 +72,7 @@ pub struct EntryPoint { /// /// Then in your main code: /// ```rust,ignore -/// let shader_bytes = include_bytes!(concat!(env!("OUT_DIR"), "/shader.spv")); +/// let shader_bytes = slank::include_slang!("shader_label") /// ``` pub struct SlangShaderBuilder { label: String, @@ -228,6 +229,10 @@ impl SlangShaderBuilder { self } + /// Compiles to the `OUT_DIR` env variable. It will return an [Err] if it is not ran in + /// a `build.rs` script. + /// + /// Also assumes that this is for wgpu and a [`SlangTarget::SpirV`] target. pub fn compile_to_out_dir(self, target: SlangTarget) -> anyhow::Result<()> { let label = self.label.clone(); let compiled = self.build(target)?; @@ -237,6 +242,7 @@ impl SlangShaderBuilder { compiled.output(&dest).map_err(Into::into) } + /// Builds the slang shader with the arguments provided. pub fn build(self, target: SlangTarget) -> anyhow::Result<CompiledSlangShader> { let slang_dir = PathBuf::from(env!("SLANG_DIR")); let slangc_path = slang_dir.join("bin").join(if cfg!(windows) { "slangc.exe" } else { "slangc" });