(
options: &Options,
#[cfg(not(any(target_os = "android", target_arch = "wasm32")))] on_watch: Option<
Box<dyn FnMut(CompiledShaderModules) + Send + 'static>,
>,
)
| 119 | } |
| 120 | |
| 121 | fn maybe_watch( |
| 122 | options: &Options, |
| 123 | #[cfg(not(any(target_os = "android", target_arch = "wasm32")))] on_watch: Option< |
| 124 | Box<dyn FnMut(CompiledShaderModules) + Send + 'static>, |
| 125 | >, |
| 126 | ) -> CompiledShaderModules { |
| 127 | #[cfg(not(any(target_os = "android", target_arch = "wasm32")))] |
| 128 | { |
| 129 | use spirv_builder::{CompileResult, MetadataPrintout, SpirvBuilder}; |
| 130 | use std::path::PathBuf; |
| 131 | // Hack: spirv_builder builds into a custom directory if running under cargo, to not |
| 132 | // deadlock, and the default target directory if not. However, packages like `proc-macro2` |
| 133 | // have different configurations when being built here vs. when building |
| 134 | // rustc_codegen_spirv normally, so we *want* to build into a separate target directory, to |
| 135 | // not have to rebuild half the crate graph every time we run. So, pretend we're running |
| 136 | // under cargo by setting these environment variables. |
| 137 | std::env::set_var("OUT_DIR", env!("OUT_DIR")); |
| 138 | std::env::set_var("PROFILE", env!("PROFILE")); |
| 139 | let crate_name = match options.shader { |
| 140 | RustGPUShader::Simplest => "simplest-shader", |
| 141 | RustGPUShader::Sky => "sky-shader", |
| 142 | RustGPUShader::Compute => "compute-shader", |
| 143 | RustGPUShader::Mouse => "mouse-shader", |
| 144 | }; |
| 145 | let manifest_dir = env!("CARGO_MANIFEST_DIR"); |
| 146 | let crate_path = [manifest_dir, "..", "..", "shaders", crate_name] |
| 147 | .iter() |
| 148 | .copied() |
| 149 | .collect::<PathBuf>(); |
| 150 | |
| 151 | let has_debug_printf = options.force_spirv_passthru; |
| 152 | |
| 153 | let builder = SpirvBuilder::new(crate_path, "spirv-unknown-vulkan1.1") |
| 154 | .print_metadata(MetadataPrintout::None) |
| 155 | .shader_panic_strategy(if has_debug_printf { |
| 156 | spirv_builder::ShaderPanicStrategy::DebugPrintfThenExit { |
| 157 | print_inputs: true, |
| 158 | print_backtrace: true, |
| 159 | } |
| 160 | } else { |
| 161 | spirv_builder::ShaderPanicStrategy::SilentExit |
| 162 | }) |
| 163 | // HACK(eddyb) needed because of `debugPrintf` instrumentation limitations |
| 164 | // (see https://github.com/KhronosGroup/SPIRV-Tools/issues/4892). |
| 165 | .multimodule(has_debug_printf); |
| 166 | let initial_result = if let Some(mut f) = on_watch { |
| 167 | builder |
| 168 | .watch(move |compile_result| f(handle_compile_result(compile_result))) |
| 169 | .expect("Configuration is correct for watching") |
| 170 | } else { |
| 171 | builder.build().unwrap() |
| 172 | }; |
| 173 | fn handle_compile_result(compile_result: CompileResult) -> CompiledShaderModules { |
| 174 | let load_spv_module = |path| { |
| 175 | let data = std::fs::read(path).unwrap(); |
| 176 | // FIXME(eddyb) this reallocates all the data pointlessly, there is |
| 177 | // not a good reason to use `ShaderModuleDescriptorSpirV` specifically. |
| 178 | let spirv = Cow::Owned(wgpu::util::make_spirv_raw(&data).into_owned()); |
no test coverage detected