From 9390aa472da5111e2b325d7aa4a2bee13c6fe92c Mon Sep 17 00:00:00 2001 From: Dzmitry Malyshau Date: Wed, 17 Mar 2021 10:05:47 -0400 Subject: [PATCH] [glsl-out] make varying names to match --- src/back/glsl/mod.rs | 75 +++++++++++++++++------------ tests/out/quad-Fragment.glsl.snap | 8 +-- tests/out/quad-Vertex.glsl.snap | 12 ++--- tests/out/shadow-Fragment.glsl.snap | 12 ++--- tests/out/skybox-Fragment.glsl.snap | 8 +-- tests/out/skybox-Vertex.glsl.snap | 4 +- 6 files changed, 65 insertions(+), 54 deletions(-) diff --git a/src/back/glsl/mod.rs b/src/back/glsl/mod.rs index 25a883e90b..960fc449a5 100644 --- a/src/back/glsl/mod.rs +++ b/src/back/glsl/mod.rs @@ -103,6 +103,11 @@ impl Version { Version::Embedded(v) => SUPPORTED_ES_VERSIONS.contains(&v), } } + + /// Checks if the version supports explicit `layout(location=)` qualifiers. + fn supports_explicit_locations(&self) -> bool { + *self >= Version::Embedded(310) || *self >= Version::Desktop(410) + } } impl PartialOrd for Version { @@ -235,18 +240,23 @@ impl IdGenerator { /// - Varyings with location bindings are named `_location_X` where `X` is the location struct VaryingName<'a> { binding: &'a Binding, + stage: ShaderStage, output: bool, } impl fmt::Display for VaryingName<'_> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match *self.binding { Binding::Location(location, _) => { - write!( - f, - "_{}_location_{}", - if self.output { "out" } else { "in" }, - location, - ) + let prefix = match (self.stage, self.output) { + (ShaderStage::Compute, _) => unreachable!(), + // pipeline to vertex + (ShaderStage::Vertex, false) => "p2vs", + // vertex to fragment + (ShaderStage::Vertex, true) | (ShaderStage::Fragment, false) => "vs2fs", + // fragment to pipeline + (ShaderStage::Fragment, true) => "fs2p", + }; + write!(f, "_{}_location{}", prefix, location,) } Binding::BuiltIn(built_in) => { write!(f, "{}", glsl_built_in(built_in, self.output)) @@ -547,7 +557,7 @@ impl<'a, W: Write> Writer<'a, W> { let fun_info = &self.analysis[handle]; // Write the function - self.write_function(FunctionType::Function(handle), function, fun_info, name)?; + self.write_function(FunctionType::Function(handle), function, fun_info, &name)?; writeln!(self.out)?; } @@ -794,36 +804,28 @@ impl<'a, W: Write> Writer<'a, W> { } } _ => { - let binding = match binding { - Some(binding @ &Binding::Location(..)) => binding, + let (location, interpolation) = match binding { + Some(&Binding::Location(location, interpolation)) => (location, interpolation), _ => return Ok(()), }; // Write the interpolation modifier if needed // // We ignore all interpolation modifiers that aren't used in input globals in fragment // shaders or output globals in vertex shaders - // - // TODO: Should this throw an error? - if let Binding::Location(_, Some(interp)) = *binding { + if let Some(interp) = interpolation { if self.options.shader_stage == ShaderStage::Fragment { write!(self.out, "{} ", glsl_interpolation(interp))?; } } // Write the storage class - if self.options.version >= Version::Embedded(310) - || self.options.version >= Version::Desktop(410) - { - if let Binding::Location(index, ..) = *binding { - write!( - self.out, - "layout(location = {}) {} ", - index, - if output { "out" } else { "in" } - )?; - } else { - write!(self.out, "{} ", if output { "out" } else { "in" })?; - } + if self.options.version.supports_explicit_locations() { + write!( + self.out, + "layout(location = {}) {} ", + location, + if output { "out" } else { "in" } + )?; } else { write!(self.out, "{} ", if output { "out" } else { "in" })?; } @@ -833,7 +835,12 @@ impl<'a, W: Write> Writer<'a, W> { // Finally write the global name and end the global with a `;` and a newline // Leading space is important - writeln!(self.out, " {};", VaryingName { binding, output })?; + let vname = VaryingName { + binding: &Binding::Location(location, None), + stage: self.entry_point.stage, + output, + }; + writeln!(self.out, " {};", vname)?; } } Ok(()) @@ -843,12 +850,12 @@ impl<'a, W: Write> Writer<'a, W> { /// /// # Notes /// Adds a newline - fn write_function>( + fn write_function( &mut self, ty: FunctionType, func: &Function, info: &FunctionInfo, - name: N, + name: &str, ) -> BackendResult { // Create a new typifier and resolve all types for the current function let mut typifier = Typifier::new(); @@ -896,7 +903,7 @@ impl<'a, W: Write> Writer<'a, W> { } // Write the function name and open parentheses for the argument list - write!(self.out, " {}(", name.as_ref())?; + write!(self.out, " {}(", name)?; // Write the comma separated argument list // @@ -923,6 +930,7 @@ impl<'a, W: Write> Writer<'a, W> { // Compose the function arguments from globals, in case of an entry point. if let FunctionType::EntryPoint(ep_index) = ctx.func { + let stage = self.module.entry_points[ep_index as usize].stage; for (index, arg) in func.arguments.iter().enumerate() { write!(self.out, "{}", INDENT)?; self.write_type(arg.ty)?; @@ -939,6 +947,7 @@ impl<'a, W: Write> Writer<'a, W> { for (index, member) in members.iter().enumerate() { let varying_name = VaryingName { binding: member.binding.as_ref().unwrap(), + stage, output: false, }; if index != 0 { @@ -951,6 +960,7 @@ impl<'a, W: Write> Writer<'a, W> { _ => { let varying_name = VaryingName { binding: arg.binding.as_ref().unwrap(), + stage, output: false, }; writeln!(self.out, "{};", varying_name)?; @@ -1342,9 +1352,8 @@ impl<'a, W: Write> Writer<'a, W> { writeln!(self.out, ";")?; } FunctionType::EntryPoint(ep_index) => { - if let Some(ref result) = - self.module.entry_points[ep_index as usize].function.result - { + let ep = &self.module.entry_points[ep_index as usize]; + if let Some(ref result) = ep.function.result { let value = value.unwrap(); match self.module.types[result.ty].inner { crate::TypeInner::Struct { @@ -1354,6 +1363,7 @@ impl<'a, W: Write> Writer<'a, W> { for (index, member) in members.iter().enumerate() { let varying_name = VaryingName { binding: member.binding.as_ref().unwrap(), + stage: ep.stage, output: true, }; write!(self.out, "{} = ", varying_name)?; @@ -1367,6 +1377,7 @@ impl<'a, W: Write> Writer<'a, W> { _ => { let name = VaryingName { binding: result.binding.as_ref().unwrap(), + stage: ep.stage, output: true, }; write!(self.out, "{} = ", name)?; diff --git a/tests/out/quad-Fragment.glsl.snap b/tests/out/quad-Fragment.glsl.snap index 28e2a75f1d..7d873bc762 100644 --- a/tests/out/quad-Fragment.glsl.snap +++ b/tests/out/quad-Fragment.glsl.snap @@ -13,16 +13,16 @@ struct VertexOutput { uniform highp sampler2D _group_0_binding_0; -layout(location = 0) in vec2 _in_location_0; -layout(location = 0) out vec4 _out_location_0; +layout(location = 0) in vec2 _vs2fs_location0; +layout(location = 0) out vec4 _fs2p_location0; void main() { - vec2 uv2 = _in_location_0; + vec2 uv2 = _vs2fs_location0; vec4 _expr4 = texture(_group_0_binding_0, vec2(uv2)); if((_expr4[3] == 0.0)) { discard; } - _out_location_0 = (_expr4[3] * _expr4); + _fs2p_location0 = (_expr4[3] * _expr4); return; } diff --git a/tests/out/quad-Vertex.glsl.snap b/tests/out/quad-Vertex.glsl.snap index 51a1aa2b03..99ff87ef1a 100644 --- a/tests/out/quad-Vertex.glsl.snap +++ b/tests/out/quad-Vertex.glsl.snap @@ -11,17 +11,17 @@ struct VertexOutput { vec4 position; }; -layout(location = 0) in vec2 _in_location_0; -layout(location = 1) in vec2 _in_location_1; -layout(location = 0) out vec2 _out_location_0; +layout(location = 0) in vec2 _p2vs_location0; +layout(location = 1) in vec2 _p2vs_location1; +layout(location = 0) out vec2 _vs2fs_location0; void main() { - vec2 pos = _in_location_0; - vec2 uv1 = _in_location_1; + vec2 pos = _p2vs_location0; + vec2 uv1 = _p2vs_location1; VertexOutput out1; out1.uv = uv1; out1.position = vec4((1.2 * pos), 0.0, 1.0); - _out_location_0 = out1.uv; + _vs2fs_location0 = out1.uv; gl_Position = out1.position; return; } diff --git a/tests/out/shadow-Fragment.glsl.snap b/tests/out/shadow-Fragment.glsl.snap index ff052ae0f8..14501be8d2 100644 --- a/tests/out/shadow-Fragment.glsl.snap +++ b/tests/out/shadow-Fragment.glsl.snap @@ -22,9 +22,9 @@ readonly buffer Lights_block_1 { uniform highp sampler2DArrayShadow _group_0_binding_2; -layout(location = 0) in vec3 _in_location_0; -layout(location = 1) in vec4 _in_location_1; -layout(location = 0) out vec4 _out_location_0; +layout(location = 0) in vec3 _vs2fs_location0; +layout(location = 1) in vec4 _vs2fs_location1; +layout(location = 0) out vec4 _fs2p_location0; float fetch_shadow(uint light_id, vec4 homogeneous_coords) { if((homogeneous_coords[3] <= 0.0)) { @@ -36,8 +36,8 @@ float fetch_shadow(uint light_id, vec4 homogeneous_coords) { } void main() { - vec3 raw_normal = _in_location_0; - vec4 position = _in_location_1; + vec3 raw_normal = _vs2fs_location0; + vec4 position = _vs2fs_location1; vec3 color1 = vec3(0.05, 0.05, 0.05); uint i = 0u; while(true) { @@ -49,7 +49,7 @@ void main() { color1 = (color1 + ((_expr25 * max(0.0, dot(normalize(raw_normal), normalize((vec3(_expr21.pos[0], _expr21.pos[1], _expr21.pos[2]) - vec3(position[0], position[1], position[2])))))) * vec3(_expr21.color[0], _expr21.color[1], _expr21.color[2]))); i = (i + 1u); } - _out_location_0 = vec4(color1, 1.0); + _fs2p_location0 = vec4(color1, 1.0); return; } diff --git a/tests/out/skybox-Fragment.glsl.snap b/tests/out/skybox-Fragment.glsl.snap index 532203d3dc..caf3117b94 100644 --- a/tests/out/skybox-Fragment.glsl.snap +++ b/tests/out/skybox-Fragment.glsl.snap @@ -13,13 +13,13 @@ struct VertexOutput { uniform highp samplerCube _group_0_binding_1; -layout(location = 0) in vec3 _in_location_0; -layout(location = 0) out vec4 _out_location_0; +layout(location = 0) in vec3 _vs2fs_location0; +layout(location = 0) out vec4 _fs2p_location0; void main() { - vec3 uv1 = _in_location_0; + vec3 uv1 = _vs2fs_location0; vec4 _expr4 = texture(_group_0_binding_1, vec3(uv1)); - _out_location_0 = _expr4; + _fs2p_location0 = _expr4; return; } diff --git a/tests/out/skybox-Vertex.glsl.snap b/tests/out/skybox-Vertex.glsl.snap index 3f7c221d58..8c27eed330 100644 --- a/tests/out/skybox-Vertex.glsl.snap +++ b/tests/out/skybox-Vertex.glsl.snap @@ -16,7 +16,7 @@ uniform Data_block_0 { mat4x4 view; } _group_0_binding_0; -layout(location = 0) out vec3 _out_location_0; +layout(location = 0) out vec3 _vs2fs_location0; void main() { uint vertex_index = uint(gl_VertexID); @@ -30,7 +30,7 @@ void main() { out1.uv = (transpose(mat3x3(vec3(_group_0_binding_0.view[0][0], _group_0_binding_0.view[0][1], _group_0_binding_0.view[0][2]), vec3(_group_0_binding_0.view[1][0], _group_0_binding_0.view[1][1], _group_0_binding_0.view[1][2]), vec3(_group_0_binding_0.view[2][0], _group_0_binding_0.view[2][1], _group_0_binding_0.view[2][2]))) * vec3(_expr50[0], _expr50[1], _expr50[2])); out1.position = _expr24; gl_Position = out1.position; - _out_location_0 = out1.uv; + _vs2fs_location0 = out1.uv; return; }