From d10590936b446cce7db1d1105b1ee47ec4fd4be5 Mon Sep 17 00:00:00 2001 From: Zoxc Date: Tue, 24 Oct 2023 11:56:04 +0200 Subject: [PATCH] Don't use layout qualifiers to allow for GLSL 140 support (#2575) --- src/back/glsl/mod.rs | 61 ++++++++++++++++--- ...age-restrict.fragment_shader.Fragment.glsl | 18 +++--- ...k-image-rzsw.fragment_shader.Fragment.glsl | 18 +++--- 3 files changed, 71 insertions(+), 26 deletions(-) diff --git a/src/back/glsl/mod.rs b/src/back/glsl/mod.rs index 60431e986e..592c72a9a5 100644 --- a/src/back/glsl/mod.rs +++ b/src/back/glsl/mod.rs @@ -55,6 +55,7 @@ use std::{ cmp::Ordering, fmt, fmt::{Error as FmtError, Write}, + mem, }; use thiserror::Error; @@ -64,7 +65,7 @@ mod features; mod keywords; /// List of supported `core` GLSL versions. -pub const SUPPORTED_CORE_VERSIONS: &[u16] = &[330, 400, 410, 420, 430, 440, 450]; +pub const SUPPORTED_CORE_VERSIONS: &[u16] = &[140, 150, 330, 400, 410, 420, 430, 440, 450, 460]; /// List of supported `es` GLSL versions. pub const SUPPORTED_ES_VERSIONS: &[u16] = &[300, 310, 320]; @@ -163,6 +164,10 @@ impl Version { } } + fn supports_io_locations(&self) -> bool { + *self >= Version::Desktop(330) || *self >= Version::new_gles(300) + } + /// Checks if the version supports all of the explicit layouts: /// - `location=` qualifiers for bindings /// - `binding=` qualifiers for resources @@ -285,12 +290,25 @@ pub struct PipelineOptions { pub multiview: Option, } +#[derive(Debug)] +pub struct VaryingLocation { + /// The location of the global. + /// This corresponds to `layout(location = ..)` in GLSL. + pub location: u32, + /// The index which can be used for dual source blending. + /// This corresponds to `layout(index = ..)` in GLSL. + pub index: u32, +} + /// Reflection info for texture mappings and uniforms. +#[derive(Debug)] pub struct ReflectionInfo { /// Mapping between texture names and variables/samplers. pub texture_mapping: crate::FastHashMap, /// Mapping between uniform variables and names. pub uniforms: crate::FastHashMap, String>, + /// Mapping between names and attribute locations. + pub varying: crate::FastHashMap, } /// Mapping between a texture and its sampler, if it exists. @@ -463,6 +481,8 @@ pub struct Writer<'a, W> { need_bake_expressions: back::NeedBakeExpressions, /// How many views to render to, if doing multiview rendering. multiview: Option, + /// Mapping of varying variables to their location. Needed for reflections. + varying: crate::FastHashMap, } impl<'a, W: Write> Writer<'a, W> { @@ -525,6 +545,7 @@ impl<'a, W: Write> Writer<'a, W> { block_id: IdGenerator::default(), named_expressions: Default::default(), need_bake_expressions: Default::default(), + varying: Default::default(), }; // Find all features required to print this module @@ -1006,9 +1027,16 @@ impl<'a, W: Write> Writer<'a, W> { Ic::Storage { format, .. } => ("image", format.into(), "", ""), }; + let precision = if self.options.version.is_es() { + "highp " + } else { + "" + }; + write!( self.out, - "highp {}{}{}{}{}{}", + "{}{}{}{}{}{}{}", + precision, glsl_scalar(kind, 4)?.prefix, base, glsl_dimension(dim), @@ -1367,13 +1395,25 @@ impl<'a, W: Write> Writer<'a, W> { }; // Write the I/O locations, if allowed - if self.options.version.supports_explicit_locations() || !emit_interpolation_and_auxiliary { - if second_blend_source { - write!(self.out, "layout(location = {location}, index = 1) ")?; + let io_location = if self.options.version.supports_explicit_locations() + || !emit_interpolation_and_auxiliary + { + if self.options.version.supports_io_locations() { + if second_blend_source { + write!(self.out, "layout(location = {location}, index = 1) ")?; + } else { + write!(self.out, "layout(location = {location}) ")?; + } + None } else { - write!(self.out, "layout(location = {location}) ")?; + Some(VaryingLocation { + location, + index: second_blend_source as u32, + }) } - } + } else { + None + }; // Write the interpolation qualifier. if let Some(interp) = interpolation { @@ -1417,6 +1457,10 @@ impl<'a, W: Write> Writer<'a, W> { }; writeln!(self.out, " {vname};")?; + if let Some(location) = io_location { + self.varying.insert(vname.to_string(), location); + } + Ok(()) } @@ -4000,7 +4044,7 @@ impl<'a, W: Write> Writer<'a, W> { } /// Helper method used to produce the reflection info that's returned to the user - fn collect_reflection_info(&self) -> Result { + fn collect_reflection_info(&mut self) -> Result { use std::collections::hash_map::Entry; let info = self.info.get_entry_point(self.entry_point_idx as usize); let mut texture_mapping = crate::FastHashMap::default(); @@ -4057,6 +4101,7 @@ impl<'a, W: Write> Writer<'a, W> { Ok(ReflectionInfo { texture_mapping, uniforms, + varying: mem::take(&mut self.varying), }) } } diff --git a/tests/out/glsl/bounds-check-image-restrict.fragment_shader.Fragment.glsl b/tests/out/glsl/bounds-check-image-restrict.fragment_shader.Fragment.glsl index cf5a2806f6..f582e85ec7 100644 --- a/tests/out/glsl/bounds-check-image-restrict.fragment_shader.Fragment.glsl +++ b/tests/out/glsl/bounds-check-image-restrict.fragment_shader.Fragment.glsl @@ -1,22 +1,22 @@ #version 430 core #extension GL_ARB_shader_texture_image_samples : require -uniform highp sampler1D _group_0_binding_0_fs; +uniform sampler1D _group_0_binding_0_fs; -uniform highp sampler2D _group_0_binding_1_fs; +uniform sampler2D _group_0_binding_1_fs; -uniform highp sampler2DArray _group_0_binding_2_fs; +uniform sampler2DArray _group_0_binding_2_fs; -uniform highp sampler3D _group_0_binding_3_fs; +uniform sampler3D _group_0_binding_3_fs; -uniform highp sampler2DMS _group_0_binding_4_fs; +uniform sampler2DMS _group_0_binding_4_fs; -layout(rgba8) writeonly uniform highp image1D _group_0_binding_8_fs; +layout(rgba8) writeonly uniform image1D _group_0_binding_8_fs; -layout(rgba8) writeonly uniform highp image2D _group_0_binding_9_fs; +layout(rgba8) writeonly uniform image2D _group_0_binding_9_fs; -layout(rgba8) writeonly uniform highp image2DArray _group_0_binding_10_fs; +layout(rgba8) writeonly uniform image2DArray _group_0_binding_10_fs; -layout(rgba8) writeonly uniform highp image3D _group_0_binding_11_fs; +layout(rgba8) writeonly uniform image3D _group_0_binding_11_fs; layout(location = 0) out vec4 _fs2p_location0; diff --git a/tests/out/glsl/bounds-check-image-rzsw.fragment_shader.Fragment.glsl b/tests/out/glsl/bounds-check-image-rzsw.fragment_shader.Fragment.glsl index 4a6718e397..b2096add79 100644 --- a/tests/out/glsl/bounds-check-image-rzsw.fragment_shader.Fragment.glsl +++ b/tests/out/glsl/bounds-check-image-rzsw.fragment_shader.Fragment.glsl @@ -1,22 +1,22 @@ #version 430 core #extension GL_ARB_shader_texture_image_samples : require -uniform highp sampler1D _group_0_binding_0_fs; +uniform sampler1D _group_0_binding_0_fs; -uniform highp sampler2D _group_0_binding_1_fs; +uniform sampler2D _group_0_binding_1_fs; -uniform highp sampler2DArray _group_0_binding_2_fs; +uniform sampler2DArray _group_0_binding_2_fs; -uniform highp sampler3D _group_0_binding_3_fs; +uniform sampler3D _group_0_binding_3_fs; -uniform highp sampler2DMS _group_0_binding_4_fs; +uniform sampler2DMS _group_0_binding_4_fs; -layout(rgba8) writeonly uniform highp image1D _group_0_binding_8_fs; +layout(rgba8) writeonly uniform image1D _group_0_binding_8_fs; -layout(rgba8) writeonly uniform highp image2D _group_0_binding_9_fs; +layout(rgba8) writeonly uniform image2D _group_0_binding_9_fs; -layout(rgba8) writeonly uniform highp image2DArray _group_0_binding_10_fs; +layout(rgba8) writeonly uniform image2DArray _group_0_binding_10_fs; -layout(rgba8) writeonly uniform highp image3D _group_0_binding_11_fs; +layout(rgba8) writeonly uniform image3D _group_0_binding_11_fs; layout(location = 0) out vec4 _fs2p_location0;