From 87b2b12be4f182c421b142a35ba1372c2610500c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois?= Date: Wed, 7 Dec 2022 23:10:27 +0000 Subject: [PATCH] ShaderDefVal: add an `UInt` option (#6881) # Objective - Fixes #6841 - In some case, the number of maximum storage buffers is `u32::MAX` which doesn't fit in a `i32` ## Solution - Add an option to have a `u32` in a `ShaderDefVal` --- crates/bevy_pbr/src/render/light.rs | 4 +-- crates/bevy_pbr/src/render/mesh.rs | 4 +-- .../src/render_resource/pipeline_cache.rs | 15 ++++++++-- .../bevy_render/src/render_resource/shader.rs | 30 +++++++++++-------- 4 files changed, 35 insertions(+), 18 deletions(-) diff --git a/crates/bevy_pbr/src/render/light.rs b/crates/bevy_pbr/src/render/light.rs index 8b9faeb99854f..e23c1c811c4d7 100644 --- a/crates/bevy_pbr/src/render/light.rs +++ b/crates/bevy_pbr/src/render/light.rs @@ -321,9 +321,9 @@ impl SpecializedMeshPipeline for ShadowPipeline { let mut bind_group_layout = vec![self.view_layout.clone()]; let mut shader_defs = Vec::new(); - shader_defs.push(ShaderDefVal::Int( + shader_defs.push(ShaderDefVal::UInt( "MAX_DIRECTIONAL_LIGHTS".to_string(), - MAX_DIRECTIONAL_LIGHTS as i32, + MAX_DIRECTIONAL_LIGHTS as u32, )); if layout.contains(Mesh::ATTRIBUTE_JOINT_INDEX) diff --git a/crates/bevy_pbr/src/render/mesh.rs b/crates/bevy_pbr/src/render/mesh.rs index 15fa70b81e8df..1c88cc99883bb 100644 --- a/crates/bevy_pbr/src/render/mesh.rs +++ b/crates/bevy_pbr/src/render/mesh.rs @@ -590,9 +590,9 @@ impl SpecializedMeshPipeline for MeshPipeline { vertex_attributes.push(Mesh::ATTRIBUTE_NORMAL.at_shader_location(1)); } - shader_defs.push(ShaderDefVal::Int( + shader_defs.push(ShaderDefVal::UInt( "MAX_DIRECTIONAL_LIGHTS".to_string(), - MAX_DIRECTIONAL_LIGHTS as i32, + MAX_DIRECTIONAL_LIGHTS as u32, )); if layout.contains(Mesh::ATTRIBUTE_UV_0) { diff --git a/crates/bevy_render/src/render_resource/pipeline_cache.rs b/crates/bevy_render/src/render_resource/pipeline_cache.rs index b13c39e1fbecc..0209c2e8c9d97 100644 --- a/crates/bevy_render/src/render_resource/pipeline_cache.rs +++ b/crates/bevy_render/src/render_resource/pipeline_cache.rs @@ -123,6 +123,7 @@ struct ShaderCache { pub enum ShaderDefVal { Bool(String, bool), Int(String, i32), + UInt(String, u32), } impl From<&str> for ShaderDefVal { @@ -137,6 +138,16 @@ impl From for ShaderDefVal { } } +impl ShaderDefVal { + pub fn value_as_string(&self) -> String { + match self { + ShaderDefVal::Bool(_, def) => def.to_string(), + ShaderDefVal::Int(_, def) => def.to_string(), + ShaderDefVal::UInt(_, def) => def.to_string(), + } + } +} + impl ShaderCache { fn get( &mut self, @@ -176,9 +187,9 @@ impl ShaderCache { shader_defs.push("SIXTEEN_BYTE_ALIGNMENT".into()); } - shader_defs.push(ShaderDefVal::Int( + shader_defs.push(ShaderDefVal::UInt( String::from("AVAILABLE_STORAGE_BUFFER_BINDINGS"), - render_device.limits().max_storage_buffers_per_shader_stage as i32, + render_device.limits().max_storage_buffers_per_shader_stage, )); debug!( diff --git a/crates/bevy_render/src/render_resource/shader.rs b/crates/bevy_render/src/render_resource/shader.rs index 74df14a9c7e7e..569234abeeb6d 100644 --- a/crates/bevy_render/src/render_resource/shader.rs +++ b/crates/bevy_render/src/render_resource/shader.rs @@ -425,7 +425,9 @@ impl ShaderProcessor { let shader_defs_unique = HashMap::::from_iter(shader_defs.iter().map(|v| match v { - ShaderDefVal::Bool(k, _) | ShaderDefVal::Int(k, _) => (k.clone(), v.clone()), + ShaderDefVal::Bool(k, _) | ShaderDefVal::Int(k, _) | ShaderDefVal::UInt(k, _) => { + (k.clone(), v.clone()) + } })); let mut scopes = vec![true]; let mut final_string = String::new(); @@ -484,6 +486,16 @@ impl ShaderProcessor { })?; act_on(*def, val, op.as_str())? } + ShaderDefVal::UInt(name, def) => { + let val = val.as_str().parse().map_err(|_| { + ProcessShaderError::InvalidShaderDefComparisonValue { + shader_def_name: name.clone(), + value: val.as_str().to_string(), + expected: "uint".to_string(), + } + })?; + act_on(*def, val, op.as_str())? + } }; scopes.push(*scopes.last().unwrap() && new_scope); } else if self.else_regex.is_match(line) { @@ -536,24 +548,18 @@ impl ShaderProcessor { for capture in self.def_regex.captures_iter(line) { let def = capture.get(1).unwrap(); if let Some(def) = shader_defs_unique.get(def.as_str()) { - let def = match def { - ShaderDefVal::Bool(_, def) => def.to_string(), - ShaderDefVal::Int(_, def) => def.to_string(), - }; - line_with_defs = - self.def_regex.replace(&line_with_defs, def).to_string(); + line_with_defs = self + .def_regex + .replace(&line_with_defs, def.value_as_string()) + .to_string(); } } for capture in self.def_regex_delimited.captures_iter(line) { let def = capture.get(1).unwrap(); if let Some(def) = shader_defs_unique.get(def.as_str()) { - let def = match def { - ShaderDefVal::Bool(_, def) => def.to_string(), - ShaderDefVal::Int(_, def) => def.to_string(), - }; line_with_defs = self .def_regex_delimited - .replace(&line_with_defs, def) + .replace(&line_with_defs, def.value_as_string()) .to_string(); } }