par_term_render/custom_shader_renderer/
hot_reload.rs1use anyhow::{Context, Result};
8use wgpu::*;
9
10use super::pipeline::create_render_pipeline;
11use super::transpiler::transpile_glsl_to_wgsl_source;
12use super::{CustomShaderRenderer, write_debug_shader_wgsl};
13
14impl CustomShaderRenderer {
15 pub fn reload_from_source(&mut self, device: &Device, source: &str, name: &str) -> Result<()> {
26 let control_parse = par_term_config::parse_shader_controls(source);
27 for warning in &control_parse.warnings {
28 log::warn!(
29 "Shader control warning line {}: {}",
30 warning.line,
31 warning.message
32 );
33 }
34 let custom_controls = control_parse.controls;
35 let wgsl_source = transpile_glsl_to_wgsl_source(source, name)?;
36
37 log::info!(
38 "Reloading custom shader from source ({} bytes GLSL -> {} bytes WGSL)",
39 source.len(),
40 wgsl_source.len()
41 );
42 log::debug!("Generated WGSL:\n{}", wgsl_source);
43 write_debug_shader_wgsl(name, &wgsl_source);
44
45 let module = naga::front::wgsl::parse_str(&wgsl_source)
47 .context("Custom shader WGSL parse failed")?;
48 let _info = naga::valid::Validator::new(
49 naga::valid::ValidationFlags::all(),
50 naga::valid::Capabilities::empty(),
51 )
52 .validate(&module)
53 .context("Custom shader WGSL validation failed")?;
54
55 let shader_module = device.create_shader_module(ShaderModuleDescriptor {
56 label: Some("Custom Shader Module (reloaded)"),
57 source: ShaderSource::Wgsl(wgsl_source.into()),
58 });
59
60 self.pipeline = create_render_pipeline(
61 device,
62 &shader_module,
63 &self.bind_group_layout,
64 self.surface_format,
65 Some("Custom Shader Pipeline (reloaded)"),
66 );
67 self.custom_controls = custom_controls;
68
69 log::info!("Custom shader reloaded successfully from source");
70 Ok(())
71 }
72}