diff --git a/src/back/glsl/mod.rs b/src/back/glsl/mod.rs index 81df401d0d..d894241283 100644 --- a/src/back/glsl/mod.rs +++ b/src/back/glsl/mod.rs @@ -214,6 +214,10 @@ bitflags::bitflags! { /// Supports GL_EXT_texture_shadow_lod on the host, which provides /// additional functions on shadows and arrays of shadows. const TEXTURE_SHADOW_LOD = 0x2; + /// Include unused global variables, constants and functions. By default the output will exclude + /// global variables that are not used in the specified entrypoint (including indirect use), + /// all constant declarations, and functions that use excluded global variables. + const INCLUDE_UNUSED_ITEMS = 0x4; } } @@ -599,11 +603,17 @@ impl<'a, W: Write> Writer<'a, W> { // Write the globals // - // We filter all globals that aren't used by the selected entry point as they might be + // Unless explicitly disabled with WriterFlags::INCLUDE_UNUSED_ITEMS, + // we filter all globals that aren't used by the selected entry point as they might be // interfere with each other (i.e. two globals with the same location but different with // different classes) + let include_unused = self + .options + .writer_flags + .contains(WriterFlags::INCLUDE_UNUSED_ITEMS); for (handle, global) in self.module.global_variables.iter() { - if ep_info[handle].is_empty() { + let is_unused = ep_info[handle].is_empty(); + if !include_unused && is_unused { continue; } @@ -679,11 +689,34 @@ impl<'a, W: Write> Writer<'a, W> { TypeInner::Sampler { .. } => continue, // All other globals are written by `write_global` _ => { - if !ep_info[handle].is_empty() { - self.write_global(handle, global)?; - // Add a newline (only for readability) - writeln!(self.out)?; - } + self.write_global(handle, global)?; + // Add a newline (only for readability) + writeln!(self.out)?; + } + } + } + + if include_unused { + // write named constants + for (handle, constant) in self.module.constants.iter() { + if let Some(name) = constant.name.as_ref() { + write!(self.out, "const ")?; + match constant.inner { + crate::ConstantInner::Scalar { width, value } => { + // create a TypeInner to write + let inner = TypeInner::Scalar { + width, + kind: value.scalar_kind(), + }; + self.write_value_type(&inner)?; + } + crate::ConstantInner::Composite { ty, .. } => { + self.write_type(ty)?; + } + }; + write!(self.out, " {} = ", name)?; + self.write_constant(handle)?; + writeln!(self.out, ";")?; } } } @@ -700,7 +733,7 @@ impl<'a, W: Write> Writer<'a, W> { for (handle, function) in self.module.functions.iter() { // Check that the function doesn't use globals that aren't supported // by the current entry point - if !ep_info.dominates_global_use(&self.info[handle]) { + if !include_unused && !ep_info.dominates_global_use(&self.info[handle]) { continue; } diff --git a/src/front/glsl/parser_tests.rs b/src/front/glsl/parser_tests.rs index d6d831aaf6..df6edd21d8 100644 --- a/src/front/glsl/parser_tests.rs +++ b/src/front/glsl/parser_tests.rs @@ -531,7 +531,18 @@ fn constants() { assert_eq!( constants.next().unwrap().1, &Constant { - name: None, + name: Some("a".to_owned()), + specialization: None, + inner: ConstantInner::Scalar { + width: 4, + value: ScalarValue::Float(1.0) + } + } + ); + assert_eq!( + constants.next().unwrap().1, + &Constant { + name: Some("b".to_owned()), specialization: None, inner: ConstantInner::Scalar { width: 4, diff --git a/src/front/glsl/variables.rs b/src/front/glsl/variables.rs index c174c9acf4..ea8c9e8b50 100644 --- a/src/front/glsl/variables.rs +++ b/src/front/glsl/variables.rs @@ -501,6 +501,22 @@ impl Parser { mutable: false, }; + if let Some(name) = name.as_ref() { + let constant = self.module.constants.get_mut(init); + if constant.name.is_none() { + // set the name of the constant + constant.name = Some(name.clone()) + } else { + // add a copy of the constant with the new name + let new_const = Constant { + name: Some(name.clone()), + specialization: constant.specialization, + inner: constant.inner.clone(), + }; + self.module.constants.fetch_or_append(new_const, meta); + } + } + (GlobalOrConstant::Constant(init), lookup) } StorageQualifier::AddressSpace(mut space) => { diff --git a/tests/out/wgsl/931-constant-emitting-vert.wgsl b/tests/out/wgsl/931-constant-emitting-vert.wgsl index dfb5a38a06..e42eeb0543 100644 --- a/tests/out/wgsl/931-constant-emitting-vert.wgsl +++ b/tests/out/wgsl/931-constant-emitting-vert.wgsl @@ -1,3 +1,5 @@ +let constant: i32 = 10; + fn function() -> f32 { return 0.0; } diff --git a/tests/out/wgsl/bevy-pbr-frag.wgsl b/tests/out/wgsl/bevy-pbr-frag.wgsl index cdfafde02c..9bc0449d7e 100644 --- a/tests/out/wgsl/bevy-pbr-frag.wgsl +++ b/tests/out/wgsl/bevy-pbr-frag.wgsl @@ -48,6 +48,12 @@ struct FragmentOutput { @location(0) o_Target: vec4, } +let MAX_POINT_LIGHTS: i32 = 10; + +let MAX_DIRECTIONAL_LIGHTS: i32 = 1; + +let PI: f32 = 3.1415927410125732; + var v_WorldPosition_1: vec3; var v_WorldNormal_1: vec3; var v_Uv_1: vec2; @@ -188,7 +194,7 @@ fn D_GGX(roughness: f32, NoH: f32, h: vec3) -> f32 { k = (_e55 / (_e56 + (_e57 * _e58))); let _e63 = k; let _e64 = k; - d = ((_e63 * _e64) * (1.0 / 3.1415927410125732)); + d = ((_e63 * _e64) * (1.0 / PI)); let _e70 = d; return _e70; } @@ -441,7 +447,7 @@ fn Fd_Burley(roughness_6: f32, NoV_4: f32, NoL_4: f32, LoH_4: f32) -> f32 { viewScatter = _e72; let _e74 = lightScatter; let _e75 = viewScatter; - return ((_e74 * _e75) * (1.0 / 3.1415927410125732)); + return ((_e74 * _e75) * (1.0 / PI)); } fn EnvBRDFApprox(f0_7: vec3, perceptual_roughness: f32, NoV_6: f32) -> vec3 { @@ -1193,7 +1199,7 @@ fn main_1() { let _e227 = i; let _e228 = global_2.NumLights; let _e232 = i; - if !(((_e227 < i32(_e228.x)) && (_e232 < 10))) { + if !(((_e227 < i32(_e228.x)) && (_e232 < MAX_POINT_LIGHTS))) { break; } { @@ -1229,7 +1235,7 @@ fn main_1() { let _e264 = i_1; let _e265 = global_2.NumLights; let _e269 = i_1; - if !(((_e264 < i32(_e265.y)) && (_e269 < 1))) { + if !(((_e264 < i32(_e265.y)) && (_e269 < MAX_DIRECTIONAL_LIGHTS))) { break; } { diff --git a/tests/out/wgsl/constant-array-size-vert.wgsl b/tests/out/wgsl/constant-array-size-vert.wgsl index 15018270f1..3f26c5b15d 100644 --- a/tests/out/wgsl/constant-array-size-vert.wgsl +++ b/tests/out/wgsl/constant-array-size-vert.wgsl @@ -2,6 +2,8 @@ struct Data { vecs: array,42u>, } +let NUM_VECS: i32 = 42; + @group(1) @binding(0) var global: Data; @@ -13,7 +15,7 @@ fn function() -> vec4 { i = 0; loop { let _e9 = i; - if !((_e9 < 42)) { + if !((_e9 < NUM_VECS)) { break; } { diff --git a/tests/out/wgsl/expressions-frag.wgsl b/tests/out/wgsl/expressions-frag.wgsl index 8e4f46ec41..1c8a2aff04 100644 --- a/tests/out/wgsl/expressions-frag.wgsl +++ b/tests/out/wgsl/expressions-frag.wgsl @@ -14,6 +14,7 @@ struct FragmentOutput { @location(0) o_color: vec4, } +let strct: TestStruct = TestStruct(array,2u>(vec4(0u, 0u, 0u, 0u), vec4(1u, 1u, 1u, 1u))); var global: f32; @group(0) @binding(0) var global_1: a_buf; diff --git a/tests/out/wgsl/global-constant-array-vert.wgsl b/tests/out/wgsl/global-constant-array-vert.wgsl index a74aa3f2cc..e066042e21 100644 --- a/tests/out/wgsl/global-constant-array-vert.wgsl +++ b/tests/out/wgsl/global-constant-array-vert.wgsl @@ -1,3 +1,4 @@ +let array_: array = array(1.0, 2.0); var i: u32; fn main_1() { diff --git a/tests/out/wgsl/quad_glsl-vert.wgsl b/tests/out/wgsl/quad_glsl-vert.wgsl index ea4d77401b..cb6f766d53 100644 --- a/tests/out/wgsl/quad_glsl-vert.wgsl +++ b/tests/out/wgsl/quad_glsl-vert.wgsl @@ -3,6 +3,8 @@ struct VertexOutput { @builtin(position) member: vec4, } +let c_scale: f32 = 1.2000000476837158; + var a_pos_1: vec2; var a_uv_1: vec2; var v_uv: vec2; @@ -12,7 +14,7 @@ fn main_1() { let _e4 = a_uv_1; v_uv = _e4; let _e6 = a_pos_1; - let _e7 = (1.2000000476837158 * _e6); + let _e7 = (c_scale * _e6); gl_Position = vec4(_e7.x, _e7.y, 0.0, 1.0); return; }