From 0f73f99beb7bf25c3907ca38fdfadfda12df7d5d Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Fri, 19 Sep 2025 16:01:37 +1000 Subject: [PATCH 1/3] Fix simplest-shader on ash runner. The background should be green, not blue, to match the wgpu runner. --- examples/runners/ash/src/main.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/runners/ash/src/main.rs b/examples/runners/ash/src/main.rs index f7beae0aee..6f3040f66a 100644 --- a/examples/runners/ash/src/main.rs +++ b/examples/runners/ash/src/main.rs @@ -951,7 +951,7 @@ impl RenderCtx { let framebuffer = self.framebuffers[present_index as usize]; let clear_values = [vk::ClearValue { color: vk::ClearColorValue { - float32: [0.0, 0.0, 1.0, 0.0], + float32: [0.0, 1.0, 0.0, 0.0], }, }]; From 2175b8bd73acf283057526e60e1722915518aa64 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Thu, 18 Sep 2025 17:59:12 +1000 Subject: [PATCH 2/3] Enable simplest-shader and mouse-shader on the ash runner. mouse-shader doesn't work fully. But it's an example, so partial function is still reasonable. --- examples/README.md | 9 ++- examples/runners/ash/src/main.rs | 99 ++++++++++++++++++++++---------- 2 files changed, 76 insertions(+), 32 deletions(-) diff --git a/examples/README.md b/examples/README.md index 73762867c3..c90060e415 100644 --- a/examples/README.md +++ b/examples/README.md @@ -20,8 +20,7 @@ The runners: [wasm](https://webassembly.org/). - **ash:** runs the shader code on the GPU using [ash](https://crates.io/crates/ash), a Vulkan wrapper crate for Rust. -- **CPU:** runs the shader code directly on the CPU, using rayon for - parallelism. +- **CPU:** runs the shader code on the CPU, using rayon for parallelism. Not all shaders work with all runners. The following combinations are supported. @@ -52,6 +51,12 @@ supported. down arrows to adjust the sun's intensity. Use F5 to recompile the shader code (but note that the image won't redraw afterwards unless the intensity is adjusted). + - `cargo run --release -p example-runner-ash -- --shader=sky` also runs the sky shader. + - `cargo run --release -p example-runner-ash -- --shader=simplest` runs the simplest shader. + - `cargo run --release -p example-runner-ash -- --shader=mouse` runs the + mouse shader. The click-and-drag functionality is missing and the image + only animates on mouse or keyboard input, but it still is a useful example. + A pull request to fix these shortcomings would be welcome! - CPU runner: - `cargo run --release -p example-runner-cpu` runs the sky shader. diff --git a/examples/runners/ash/src/main.rs b/examples/runners/ash/src/main.rs index 6f3040f66a..5ee94b440a 100644 --- a/examples/runners/ash/src/main.rs +++ b/examples/runners/ash/src/main.rs @@ -84,19 +84,51 @@ use std::{ ffi::{CStr, CString}, fs::File, os::raw::c_char, + path::PathBuf, sync::mpsc::{TryRecvError, TrySendError, sync_channel}, thread, }; -use clap::Parser; +use clap::{Parser, ValueEnum}; use spirv_builder::{MetadataPrintout, SpirvBuilder}; use shared::ShaderConstants; +// This runner currently doesn't run the `compute` shader example. +#[derive(Debug, PartialEq, Eq, Copy, Clone, ValueEnum)] +pub enum RustGPUShader { + Simplest, + Sky, + Mouse, +} + +impl RustGPUShader { + // The form with dashes, e.g. `sky-shader`. + fn crate_name(&self) -> &'static str { + match self { + RustGPUShader::Simplest => "simplest-shader", + RustGPUShader::Sky => "sky-shader", + RustGPUShader::Mouse => "mouse-shader", + } + } + + // The form with underscores, e.g. `sky_shader`. + fn crate_ident(&self) -> &'static str { + match self { + RustGPUShader::Simplest => "simplest_shader", + RustGPUShader::Sky => "sky_shader", + RustGPUShader::Mouse => "mouse_shader", + } + } +} + #[derive(Debug, Parser)] #[command()] pub struct Options { + #[arg(short, long, default_value = "sky")] + shader: RustGPUShader, + /// Use Vulkan debug layer (requires Vulkan SDK installed) #[arg(short, long)] debug_layer: bool, @@ -115,7 +147,7 @@ pub fn main() { } let options = Options::parse(); - let shaders = compile_shaders(); + let shaders = compile_shaders(&options.shader); // runtime setup let event_loop = EventLoop::new().unwrap(); @@ -138,17 +170,19 @@ pub fn main() { for SpvFile { name, data } in shaders { ctx.insert_shader_module(name, &data); } + + let crate_ident = options.shader.crate_ident(); ctx.build_pipelines( vk::PipelineCache::null(), vec![( - // HACK(eddyb) used to be `module: "sky_shader"` but we need `multimodule` - // for `debugPrintf` instrumentation to work (see `compile_shaders`). + // HACK(eddyb) we need `multimodule` for `debugPrintf` + // instrumentation to work (see `compile_shaders`). VertexShaderEntryPoint { - module: "sky_shader::main_vs".into(), + module: format!("{crate_ident}::main_vs"), entry_point: "main_vs".into(), }, FragmentShaderEntryPoint { - module: "sky_shader::main_fs".into(), + module: format!("{crate_ident}::main_fs"), entry_point: "main_fs".into(), }, )], @@ -203,7 +237,7 @@ pub fn main() { let compiler_sender = compiler_sender.clone(); thread::spawn(move || { if let Err(TrySendError::Disconnected(_)) = - compiler_sender.try_send(compile_shaders()) + compiler_sender.try_send(compile_shaders(&options.shader)) { panic!("compiler sender disconnected unexpectedly"); }; @@ -236,29 +270,33 @@ pub fn main() { .unwrap(); } -pub fn compile_shaders() -> Vec { - SpirvBuilder::new( - concat!(env!("CARGO_MANIFEST_DIR"), "/../../shaders/sky-shader"), - "spirv-unknown-vulkan1.1", - ) - .print_metadata(MetadataPrintout::None) - .shader_panic_strategy(spirv_builder::ShaderPanicStrategy::DebugPrintfThenExit { - print_inputs: true, - print_backtrace: true, - }) - // HACK(eddyb) needed because of `debugPrintf` instrumentation limitations - // (see https://github.com/KhronosGroup/SPIRV-Tools/issues/4892). - .multimodule(true) - .build() - .unwrap() - .module - .unwrap_multi() - .iter() - .map(|(name, path)| SpvFile { - name: format!("sky_shader::{name}"), - data: read_spv(&mut File::open(path).unwrap()).unwrap(), - }) - .collect() +pub fn compile_shaders(shader: &RustGPUShader) -> Vec { + let manifest_dir = env!("CARGO_MANIFEST_DIR"); + let crate_path = [manifest_dir, "..", "..", "shaders", shader.crate_name()] + .iter() + .copied() + .collect::(); + let crate_ident = shader.crate_ident(); + + SpirvBuilder::new(crate_path, "spirv-unknown-vulkan1.1") + .print_metadata(MetadataPrintout::None) + .shader_panic_strategy(spirv_builder::ShaderPanicStrategy::DebugPrintfThenExit { + print_inputs: true, + print_backtrace: true, + }) + // HACK(eddyb) needed because of `debugPrintf` instrumentation limitations + // (see https://github.com/KhronosGroup/SPIRV-Tools/issues/4892). + .multimodule(true) + .build() + .unwrap() + .module + .unwrap_multi() + .iter() + .map(|(name, path)| SpvFile { + name: format!("{crate_ident}::{name}"), + data: read_spv(&mut File::open(path).unwrap()).unwrap(), + }) + .collect() } #[derive(Debug)] @@ -685,6 +723,7 @@ pub struct RenderCtx { pub recompiling_shaders: bool, pub start: std::time::Instant, + // Only used for sky-shader. // NOTE(eddyb) this acts like an integration test for specialization constants. pub sky_fs_spec_id_0x5007_sun_intensity_extra_spec_const_factor: u32, } From 3c08300d674a09e1d3452913f1651f41c7cdc99a Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Thu, 25 Sep 2025 08:02:14 +1000 Subject: [PATCH 3/3] Update some out-of-date comments. --- examples/runners/ash/src/main.rs | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/examples/runners/ash/src/main.rs b/examples/runners/ash/src/main.rs index 5ee94b440a..445ca75ee6 100644 --- a/examples/runners/ash/src/main.rs +++ b/examples/runners/ash/src/main.rs @@ -175,8 +175,6 @@ pub fn main() { ctx.build_pipelines( vk::PipelineCache::null(), vec![( - // HACK(eddyb) we need `multimodule` for `debugPrintf` - // instrumentation to work (see `compile_shaders`). VertexShaderEntryPoint { module: format!("{crate_ident}::main_vs"), entry_point: "main_vs".into(), @@ -284,8 +282,9 @@ pub fn compile_shaders(shader: &RustGPUShader) -> Vec { print_inputs: true, print_backtrace: true, }) - // HACK(eddyb) needed because of `debugPrintf` instrumentation limitations - // (see https://github.com/KhronosGroup/SPIRV-Tools/issues/4892). + // TODO: `multimodule` is no longer needed since + // https://github.com/KhronosGroup/SPIRV-Tools/issues/4892 was fixed, but removing it is + // non-trivial and hasn't been done et. .multimodule(true) .build() .unwrap()