diff --git a/src/back/glsl/mod.rs b/src/back/glsl/mod.rs index 77bd8dd386..a8c41faf85 100644 --- a/src/back/glsl/mod.rs +++ b/src/back/glsl/mod.rs @@ -48,11 +48,11 @@ use crate::{ CallGraph, CallGraphBuilder, Interface, NameKey, Namer, ResolveContext, ResolveError, Typifier, Visitor, }, - Arena, ArraySize, BinaryOperator, BuiltIn, Bytes, ConservativeDepth, Constant, ConstantInner, - DerivativeAxis, Expression, FastHashMap, Function, GlobalVariable, Handle, ImageClass, - Interpolation, LocalVariable, Module, RelationalFunction, ScalarKind, ScalarValue, ShaderStage, - Statement, StorageAccess, StorageClass, StorageFormat, StructMember, Type, TypeInner, - UnaryOperator, + Arena, ArraySize, BinaryOperator, Binding, BuiltIn, Bytes, ConservativeDepth, Constant, + ConstantInner, DerivativeAxis, Expression, FastHashMap, Function, GlobalVariable, Handle, + ImageClass, Interpolation, LocalVariable, Module, RelationalFunction, ScalarKind, ScalarValue, + ShaderStage, Statement, StorageAccess, StorageClass, StorageFormat, StructMember, Type, + TypeInner, UnaryOperator, }; use features::FeaturesManager; use std::{ @@ -713,12 +713,40 @@ 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 - let name = &self.names[&NameKey::GlobalVariable(handle)]; - writeln!(self.out, " {};", name)?; + writeln!(self.out, " {};", self.get_global_name(handle, global))?; Ok(()) } + /// Helper method used to get a name for a global + /// + /// Globals have different naming schemes depending on their binding: + /// - Globals without bindings use the name from the [`Namer`](crate::proc::Namer) + /// - Globals with builtin bindings get the from [`glsl_built_in`](glsl_built_in) + /// - Globals with location bindings are named `_location_X` where `X` is the location + /// - Globals with resource binding are named `_group_X_binding_Y` where `X` + /// is the group and `Y` is the binding + fn get_global_name(&self, handle: Handle, global: &GlobalVariable) -> String { + match global.binding { + Some(Binding::Location(location)) => { + format!( + " _location_{}{}", + location, + match (self.options.entry_point.0, global.class) { + (ShaderStage::Fragment, StorageClass::Input) => "_vs", + (ShaderStage::Vertex, StorageClass::Output) => "_vs", + _ => "", + } + ) + } + Some(Binding::Resource { group, binding }) => { + format!(" _group_{}_binding_{}", group, binding) + } + Some(Binding::BuiltIn(built_in)) => glsl_built_in(built_in).to_string(), + None => self.names[&NameKey::GlobalVariable(handle)].clone(), + } + } + /// Helper method used to write functions (both entry points and regular functions) /// /// # Notes @@ -1156,23 +1184,11 @@ impl<'a, W: Write> Writer<'a, W> { Expression::FunctionArgument(pos) => { write!(self.out, "{}", ctx.get_arg(pos, &self.names))? } - // Global variables need some special work, if they are a builtin we write the glsl - // variable name produced by `glsl_built_in` otherwise we write the global name - // produced by the `Namer` + // Global variables need some special work for their name but + // `get_global_name` does the work for us Expression::GlobalVariable(handle) => { - if let Some(crate::Binding::BuiltIn(built_in)) = - self.module.global_variables[handle].binding - { - // Global is a builtin so get the glsl variable name - write!(self.out, "{}", glsl_built_in(built_in))? - } else { - // Global isn't a builtin so just write the name - write!( - self.out, - "{}", - &self.names[&NameKey::GlobalVariable(handle)] - )? - } + let global = &self.module.global_variables[handle]; + write!(self.out, "{}", self.get_global_name(handle, global))? } // A local is written as it's name Expression::LocalVariable(handle) => { diff --git a/tests/snapshots/snapshots__quad-Fragment.glsl.snap b/tests/snapshots/snapshots__quad-Fragment.glsl.snap index 4bbecf0def..75d517f2fa 100644 --- a/tests/snapshots/snapshots__quad-Fragment.glsl.snap +++ b/tests/snapshots/snapshots__quad-Fragment.glsl.snap @@ -8,13 +8,13 @@ precision highp float; -in vec2 v_uv1; +in vec2 _location_0_vs; uniform sampler2D u_texture; -out vec4 o_color; +out vec4 _location_0; void main() { - o_color = texture(u_texture, vec2(v_uv1)); + _location_0 = texture( _group_0_binding_0, vec2( _location_0_vs)); return; } diff --git a/tests/snapshots/snapshots__quad-Vertex.glsl.snap b/tests/snapshots/snapshots__quad-Vertex.glsl.snap index eb95684f4b..d79cd676a2 100644 --- a/tests/snapshots/snapshots__quad-Vertex.glsl.snap +++ b/tests/snapshots/snapshots__quad-Vertex.glsl.snap @@ -8,14 +8,14 @@ precision highp float; -in vec2 a_pos; -in vec2 a_uv; -out vec2 v_uv; +in vec2 _location_0; +in vec2 _location_1; +out vec2 _location_0_vs; void main() { - v_uv = a_uv; - gl_Position = vec4((1.2 * a_pos), 0.0, 1.0); + _location_0_vs = _location_1; + gl_Position = vec4((1.2 * _location_0), 0.0, 1.0); return; } diff --git a/tests/snapshots/snapshots__skybox-Fragment.glsl.snap b/tests/snapshots/snapshots__skybox-Fragment.glsl.snap index 54bf9ef72f..24583ee9fb 100644 --- a/tests/snapshots/snapshots__skybox-Fragment.glsl.snap +++ b/tests/snapshots/snapshots__skybox-Fragment.glsl.snap @@ -13,12 +13,12 @@ struct Data { }; uniform samplerCube r_texture; -in vec3 in_uv; -out vec4 out_color; +in vec3 _location_0_vs; +out vec4 _location_0; void main() { - out_color = texture(r_texture, vec3(in_uv)); + _location_0 = texture( _group_0_binding_1, vec3( _location_0_vs)); return; } diff --git a/tests/snapshots/snapshots__skybox-Vertex.glsl.snap b/tests/snapshots/snapshots__skybox-Vertex.glsl.snap index 2dc3726d0d..14efd3e491 100644 --- a/tests/snapshots/snapshots__skybox-Vertex.glsl.snap +++ b/tests/snapshots/snapshots__skybox-Vertex.glsl.snap @@ -12,8 +12,8 @@ struct Data { mat4x4 view; }; -out vec3 out_uv; -uniform Data r_data; +out vec3 _location_0_vs; +uniform Data _group_0_binding_0; void main() { int tmp1_; @@ -22,8 +22,8 @@ void main() { tmp1_ = (int(gl_VertexID) / 2); tmp2_ = (int(gl_VertexID) & 1); - unprojected = (r_data.proj_inv * vec4(((float(tmp1_) * 4.0) - 1.0), ((float(tmp2_) * 4.0) - 1.0), 0.0, 1.0)); - out_uv = (transpose(mat3x3(vec3(r_data.view[0][0], r_data.view[0][1], r_data.view[0][2]), vec3(r_data.view[1][0], r_data.view[1][1], r_data.view[1][2]), vec3(r_data.view[2][0], r_data.view[2][1], r_data.view[2][2]))) * vec3(unprojected[0], unprojected[1], unprojected[2])); + unprojected = ( _group_0_binding_0.proj_inv * vec4(((float(tmp1_) * 4.0) - 1.0), ((float(tmp2_) * 4.0) - 1.0), 0.0, 1.0)); + _location_0_vs = (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(unprojected[0], unprojected[1], unprojected[2])); gl_Position = vec4(((float(tmp1_) * 4.0) - 1.0), ((float(tmp2_) * 4.0) - 1.0), 0.0, 1.0); return; }