From 45c2ee9c5b9a477ac676ef63fb378ab53af7bfac Mon Sep 17 00:00:00 2001 From: Ashley Ruglys Date: Fri, 20 May 2022 16:29:14 +0200 Subject: [PATCH 01/16] Make some (currently hacky) changes to enable multiview in webgl --- src/back/glsl/features.rs | 14 +++++++++++--- src/back/glsl/mod.rs | 15 ++++++++++++++- 2 files changed, 25 insertions(+), 4 deletions(-) diff --git a/src/back/glsl/features.rs b/src/back/glsl/features.rs index 61f0196827..ee78cc2f87 100644 --- a/src/back/glsl/features.rs +++ b/src/back/glsl/features.rs @@ -100,7 +100,7 @@ impl FeaturesManager { check_feature!(CULL_DISTANCE, 450, 300); check_feature!(SAMPLE_VARIABLES, 400, 300); check_feature!(DYNAMIC_ARRAY_SIZE, 430, 310); - check_feature!(MULTI_VIEW, 140, 310); + //check_feature!(MULTI_VIEW, 140, 310); check_feature!(FMA, 400, 310); // Return an error if there are missing features @@ -201,8 +201,12 @@ impl FeaturesManager { } if self.0.contains(Features::MULTI_VIEW) { - // https://github.com/KhronosGroup/GLSL/blob/master/extensions/ext/GL_EXT_multiview.txt - writeln!(out, "#extension GL_EXT_multiview : require")?; + if !version.is_es() { + // https://github.com/KhronosGroup/GLSL/blob/master/extensions/ext/GL_EXT_multiview.txt + writeln!(out, "#extension GL_EXT_multiview : require")?; + } else { + writeln!(out, "#extension GL_OVR_multiview2 : require")?; + } } if self.0.contains(Features::FMA) && version.is_es() { @@ -245,6 +249,10 @@ impl<'a, W> Writer<'a, W> { self.features.request(Features::COMPUTE_SHADER) } + if self.multiview.is_some() { + self.features.request(Features::MULTI_VIEW); + } + for (ty_handle, ty) in self.module.types.iter() { match ty.inner { TypeInner::Scalar { kind, width } => self.scalar_required_features(kind, width), diff --git a/src/back/glsl/mod.rs b/src/back/glsl/mod.rs index 7ede19e4a7..87bd0823c1 100644 --- a/src/back/glsl/mod.rs +++ b/src/back/glsl/mod.rs @@ -230,6 +230,8 @@ pub struct PipelineOptions { /// /// If no entry point that matches is found while creating a [`Writer`], a error will be thrown. pub entry_point: String, + /// XYZ + pub multiview: Option, } /// Reflection info for texture mappings and uniforms. @@ -395,6 +397,8 @@ pub struct Writer<'a, W> { named_expressions: crate::NamedExpressions, /// Set of expressions that need to be baked to avoid unnecessary repetition in output need_bake_expressions: back::NeedBakeExpressions, + /// XYZ + multiview: Option, } impl<'a, W: Write> Writer<'a, W> { @@ -443,7 +447,11 @@ impl<'a, W: Write> Writer<'a, W> { reflection_names_globals: crate::FastHashMap::default(), entry_point: &module.entry_points[ep_idx], entry_point_idx: ep_idx as u16, - + multiview: if pipeline_options.shader_stage == ShaderStage::Vertex { + pipeline_options.multiview + } else { + None + }, block_id: IdGenerator::default(), named_expressions: Default::default(), need_bake_expressions: Default::default(), @@ -532,6 +540,11 @@ impl<'a, W: Write> Writer<'a, W> { } } + if let Some(multiview) = self.multiview { + writeln!(self.out, "layout(num_views = {}) in;", multiview)?; + writeln!(self.out)?; + } + let ep_info = self.info.get_entry_point(self.entry_point_idx as usize); // Write struct types. From eb52d364b7c830a8a1e4401fdaa000fa08d3bc20 Mon Sep 17 00:00:00 2001 From: Ashley Ruglys Date: Fri, 20 May 2022 21:06:13 +0200 Subject: [PATCH 02/16] Fix ViewIndex built in for this extension --- cli/src/main.rs | 1 + src/back/glsl/mod.rs | 3 +++ 2 files changed, 4 insertions(+) diff --git a/cli/src/main.rs b/cli/src/main.rs index 2e4b1b3c35..acbc14cfe0 100644 --- a/cli/src/main.rs +++ b/cli/src/main.rs @@ -443,6 +443,7 @@ fn run() -> Result<(), Box> { "comp" => naga::ShaderStage::Compute, _ => unreachable!(), }, + multiview: None, }; let mut buffer = String::new(); diff --git a/src/back/glsl/mod.rs b/src/back/glsl/mod.rs index 9d1b4d1665..ee8d648e71 100644 --- a/src/back/glsl/mod.rs +++ b/src/back/glsl/mod.rs @@ -3250,6 +3250,8 @@ const fn glsl_scalar( const fn glsl_built_in(built_in: crate::BuiltIn, output: bool) -> &'static str { use crate::BuiltIn as Bi; + let multiview_ovr = true; + match built_in { Bi::Position { .. } => { if output { @@ -3258,6 +3260,7 @@ const fn glsl_built_in(built_in: crate::BuiltIn, output: bool) -> &'static str { "gl_FragCoord" } } + Bi::ViewIndex if multiview_ovr => "int(gl_ViewID_OVR)", Bi::ViewIndex => "gl_ViewIndex", // vertex Bi::BaseInstance => "uint(gl_BaseInstance)", From 91874c739a40e2f378c654f222204a739c82aa63 Mon Sep 17 00:00:00 2001 From: Ashley Ruglys Date: Fri, 20 May 2022 21:14:30 +0200 Subject: [PATCH 03/16] Run cargo fmt, fix tests --- src/front/wgsl/mod.rs | 4 ++-- tests/snapshots.rs | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/front/wgsl/mod.rs b/src/front/wgsl/mod.rs index 7379b51fd6..94c3510d7f 100644 --- a/src/front/wgsl/mod.rs +++ b/src/front/wgsl/mod.rs @@ -1193,8 +1193,8 @@ impl Composition { #[derive(Default)] struct TypeAttributes { // Although WGSL nas no type attributes at the moment, it had them in the past -// (`[[stride]]`) and may as well acquire some again in the future. -// Therefore, we are leaving the plumbing in for now. + // (`[[stride]]`) and may as well acquire some again in the future. + // Therefore, we are leaving the plumbing in for now. } #[derive(Clone, Debug, PartialEq)] diff --git a/tests/snapshots.rs b/tests/snapshots.rs index f6a3749c3c..a455ce6aab 100644 --- a/tests/snapshots.rs +++ b/tests/snapshots.rs @@ -281,6 +281,7 @@ fn write_output_glsl( let pipeline_options = glsl::PipelineOptions { shader_stage: stage, entry_point: ep_name.to_string(), + multiview: None, }; let mut buffer = String::new(); From 639557e034a9c180c8c357dda1871371ca3500d2 Mon Sep 17 00:00:00 2001 From: Ashley Ruglys Date: Sat, 4 Jun 2022 01:02:49 +0200 Subject: [PATCH 04/16] Allow specifying if we're targetting webgl in the glsl version --- cli/src/main.rs | 2 +- src/back/glsl/features.rs | 15 +++++++++------ src/back/glsl/mod.rs | 34 ++++++++++++++++++++++------------ 3 files changed, 32 insertions(+), 19 deletions(-) diff --git a/cli/src/main.rs b/cli/src/main.rs index acbc14cfe0..44f5c2075c 100644 --- a/cli/src/main.rs +++ b/cli/src/main.rs @@ -133,7 +133,7 @@ impl FromStr for GlslProfileArg { Ok(Self(if s.starts_with("core") { Version::Desktop(s[4..].parse().unwrap_or(330)) } else if s.starts_with("es") { - Version::Embedded(s[2..].parse().unwrap_or(310)) + Version::embedded(s[2..].parse().unwrap_or(310)) } else { return Err(format!("Unknown profile: {}", s)); })) diff --git a/src/back/glsl/features.rs b/src/back/glsl/features.rs index d90b48e600..aa316bf27f 100644 --- a/src/back/glsl/features.rs +++ b/src/back/glsl/features.rs @@ -78,7 +78,7 @@ impl FeaturesManager { // Used when both core and es support the feature ($feature:ident, $core:literal, $es:literal) => { if self.0.contains(Features::$feature) - && (version < Version::Desktop($core) || version < Version::Embedded($es)) + && (version < Version::Desktop($core) || version < Version::embedded($es)) { missing |= Features::$feature; } @@ -102,7 +102,10 @@ impl FeaturesManager { check_feature!(CULL_DISTANCE, 450, 300); check_feature!(SAMPLE_VARIABLES, 400, 300); check_feature!(DYNAMIC_ARRAY_SIZE, 430, 310); - //check_feature!(MULTI_VIEW, 140, 310); + match version { + Version::Embedded { is_webgl: true, .. } => check_feature!(MULTI_VIEW, 140, 300), + _ => check_feature!(MULTI_VIEW, 140, 310), + }; // Only available on glsl core, this means that opengl es can't query the number // of samples in a image and neither do bound checks on the sample argument // of texelFecth @@ -206,15 +209,15 @@ impl FeaturesManager { } if self.0.contains(Features::MULTI_VIEW) { - if !version.is_es() { + if let Version::Embedded { is_webgl: true, .. } = version { // https://github.com/KhronosGroup/GLSL/blob/master/extensions/ext/GL_EXT_multiview.txt - writeln!(out, "#extension GL_EXT_multiview : require")?; - } else { writeln!(out, "#extension GL_OVR_multiview2 : require")?; + } else { + writeln!(out, "#extension GL_EXT_multiview : require")?; } } - if self.0.contains(Features::FMA) && version >= Version::Embedded(310) { + if self.0.contains(Features::FMA) && version >= Version::embedded(310) { // https://www.khronos.org/registry/OpenGL/extensions/EXT/EXT_gpu_shader5.txt writeln!(out, "#extension GL_EXT_gpu_shader5 : require")?; } diff --git a/src/back/glsl/mod.rs b/src/back/glsl/mod.rs index ee8d648e71..c1379bff42 100644 --- a/src/back/glsl/mod.rs +++ b/src/back/glsl/mod.rs @@ -116,15 +116,23 @@ pub enum Version { /// `core` GLSL. Desktop(u16), /// `es` GLSL. - Embedded(u16), + Embedded { version: u16, is_webgl: bool }, } impl Version { + /// Create a new embedded version. + pub fn embedded(version: u16) -> Self { + Self::Embedded { + version, + is_webgl: false, + } + } + /// Returns true if self is `Version::Embedded` (i.e. is a es version) const fn is_es(&self) -> bool { match *self { Version::Desktop(_) => false, - Version::Embedded(_) => true, + Version::Embedded { .. } => true, } } @@ -137,7 +145,7 @@ impl Version { fn is_supported(&self) -> bool { match *self { Version::Desktop(v) => SUPPORTED_CORE_VERSIONS.contains(&v), - Version::Embedded(v) => SUPPORTED_ES_VERSIONS.contains(&v), + Version::Embedded { version: v, .. } => SUPPORTED_ES_VERSIONS.contains(&v), } } @@ -148,19 +156,19 @@ impl Version { /// Note: `location=` for vertex inputs and fragment outputs is supported /// unconditionally for GLES 300. fn supports_explicit_locations(&self) -> bool { - *self >= Version::Embedded(310) || *self >= Version::Desktop(410) + *self >= Version::embedded(310) || *self >= Version::Desktop(410) } fn supports_early_depth_test(&self) -> bool { - *self >= Version::Desktop(130) || *self >= Version::Embedded(310) + *self >= Version::Desktop(130) || *self >= Version::embedded(310) } fn supports_std430_layout(&self) -> bool { - *self >= Version::Desktop(430) || *self >= Version::Embedded(310) + *self >= Version::Desktop(430) || *self >= Version::embedded(310) } fn supports_fma_function(&self) -> bool { - *self >= Version::Desktop(400) || *self >= Version::Embedded(310) + *self >= Version::Desktop(400) || *self >= Version::embedded(310) } } @@ -168,7 +176,9 @@ impl PartialOrd for Version { fn partial_cmp(&self, other: &Self) -> Option { match (*self, *other) { (Version::Desktop(x), Version::Desktop(y)) => Some(x.cmp(&y)), - (Version::Embedded(x), Version::Embedded(y)) => Some(x.cmp(&y)), + (Version::Embedded { version: x, .. }, Version::Embedded { version: y, .. }) => { + Some(x.cmp(&y)) + } _ => None, } } @@ -178,7 +188,7 @@ impl fmt::Display for Version { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match *self { Version::Desktop(v) => write!(f, "{} core", v), - Version::Embedded(v) => write!(f, "{} es", v), + Version::Embedded { version: v, .. } => write!(f, "{} es", v), } } } @@ -212,7 +222,7 @@ pub struct Options { impl Default for Options { fn default() -> Self { Options { - version: Version::Embedded(310), + version: Version::embedded(310), writer_flags: WriterFlags::ADJUST_COORDINATE_SPACE, binding_map: BindingMap::default(), } @@ -230,7 +240,7 @@ pub struct PipelineOptions { /// /// If no entry point that matches is found while creating a [`Writer`], a error will be thrown. pub entry_point: String, - /// XYZ + /// How many views to render to. pub multiview: Option, } @@ -397,7 +407,7 @@ pub struct Writer<'a, W> { named_expressions: crate::NamedExpressions, /// Set of expressions that need to be baked to avoid unnecessary repetition in output need_bake_expressions: back::NeedBakeExpressions, - /// XYZ + /// How many views to render to, if a vertex shader. multiview: Option, } From 4c6aaa3cc6201e2666490f5e9148f27b2daaeaf3 Mon Sep 17 00:00:00 2001 From: Ashley Ruglys Date: Sat, 4 Jun 2022 01:05:59 +0200 Subject: [PATCH 05/16] Document multiview2 extension --- src/back/glsl/features.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/back/glsl/features.rs b/src/back/glsl/features.rs index aa316bf27f..af7209aeab 100644 --- a/src/back/glsl/features.rs +++ b/src/back/glsl/features.rs @@ -210,9 +210,10 @@ impl FeaturesManager { if self.0.contains(Features::MULTI_VIEW) { if let Version::Embedded { is_webgl: true, .. } = version { - // https://github.com/KhronosGroup/GLSL/blob/master/extensions/ext/GL_EXT_multiview.txt + // https://www.khronos.org/registry/OpenGL/extensions/OVR/OVR_multiview2.txt writeln!(out, "#extension GL_OVR_multiview2 : require")?; } else { + // https://github.com/KhronosGroup/GLSL/blob/master/extensions/ext/GL_EXT_multiview.txt writeln!(out, "#extension GL_EXT_multiview : require")?; } } From 3c6b5edeb020f2626ab6818bc3e85e1efa79249c Mon Sep 17 00:00:00 2001 From: Ashley Ruglys Date: Sat, 4 Jun 2022 02:03:33 +0200 Subject: [PATCH 06/16] fn embedded -> const fn embedded --- src/back/glsl/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/back/glsl/mod.rs b/src/back/glsl/mod.rs index c1379bff42..17c2a26b70 100644 --- a/src/back/glsl/mod.rs +++ b/src/back/glsl/mod.rs @@ -121,7 +121,7 @@ pub enum Version { impl Version { /// Create a new embedded version. - pub fn embedded(version: u16) -> Self { + pub const fn embedded(version: u16) -> Self { Self::Embedded { version, is_webgl: false, From ae647167a6d83e80d42732e4fa412664eaa1f034 Mon Sep 17 00:00:00 2001 From: Ashley Ruglys Date: Mon, 13 Jun 2022 17:54:55 +0200 Subject: [PATCH 07/16] Fix tests --- tests/in/functions-webgl.param.ron | 5 ++++- tests/in/push-constants.param.ron | 5 ++++- tests/in/quad.param.ron | 5 ++++- tests/in/skybox.param.ron | 5 ++++- 4 files changed, 16 insertions(+), 4 deletions(-) diff --git a/tests/in/functions-webgl.param.ron b/tests/in/functions-webgl.param.ron index bc3dd4a8dd..923da07299 100644 --- a/tests/in/functions-webgl.param.ron +++ b/tests/in/functions-webgl.param.ron @@ -1,6 +1,9 @@ ( glsl: ( - version: Embedded(300), + version: Embedded( + version: 300, + is_webgl: false + ), writer_flags: (bits: 0), binding_map: {}, ), diff --git a/tests/in/push-constants.param.ron b/tests/in/push-constants.param.ron index 0a35edeab8..3972328c9c 100644 --- a/tests/in/push-constants.param.ron +++ b/tests/in/push-constants.param.ron @@ -1,7 +1,10 @@ ( god_mode: true, glsl: ( - version: Embedded(320), + version: Embedded( + version: 320, + is_webgl: false + ), writer_flags: (bits: 0), binding_map: {}, ), diff --git a/tests/in/quad.param.ron b/tests/in/quad.param.ron index acde3aed42..568b961898 100644 --- a/tests/in/quad.param.ron +++ b/tests/in/quad.param.ron @@ -5,7 +5,10 @@ adjust_coordinate_space: true, ), glsl: ( - version: Embedded(300), + version: Embedded( + version: 300, + is_webgl: false + ), writer_flags: (bits: 0), binding_map: {}, ), diff --git a/tests/in/skybox.param.ron b/tests/in/skybox.param.ron index 9c9bd1f30a..b90f2e5a25 100644 --- a/tests/in/skybox.param.ron +++ b/tests/in/skybox.param.ron @@ -37,7 +37,10 @@ fake_missing_bindings: false, ), glsl: ( - version: Embedded(320), + version: Embedded( + version: 320, + is_webgl: false + ), writer_flags: (bits: 0), binding_map: { (group: 0, binding: 0): 0, From a0d9b694c8e04ebfa1f92c38c3de39c0580bcfa1 Mon Sep 17 00:00:00 2001 From: Ashley Ruglys Date: Mon, 13 Jun 2022 18:04:59 +0200 Subject: [PATCH 08/16] Fix benches --- benches/criterion.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/benches/criterion.rs b/benches/criterion.rs index 1175528458..e4a32c0d48 100644 --- a/benches/criterion.rs +++ b/benches/criterion.rs @@ -239,7 +239,7 @@ fn backends(c: &mut Criterion) { b.iter(|| { let mut string = String::new(); let options = naga::back::glsl::Options { - version: naga::back::glsl::Version::Embedded(320), + version: naga::back::glsl::Version::embedded(320), writer_flags: naga::back::glsl::WriterFlags::empty(), binding_map: Default::default(), }; @@ -248,6 +248,7 @@ fn backends(c: &mut Criterion) { let pipeline_options = naga::back::glsl::PipelineOptions { shader_stage: ep.stage, entry_point: ep.name.clone(), + multiview: None, }; match naga::back::glsl::Writer::new( &mut string, From 4c0d7cdaaf237225ab35f545a7a9338356867e8b Mon Sep 17 00:00:00 2001 From: Ashley Ruglys Date: Wed, 15 Jun 2022 15:35:16 +0200 Subject: [PATCH 09/16] Add snapshot tests --- src/back/glsl/mod.rs | 35 +++++++++++++++--- tests/in/multiview_webgl.param.ron | 10 +++++ tests/in/spv/multiview.spv | Bin 0 -> 492 bytes tests/in/spv/multiview_webgl.spv | Bin 0 -> 492 bytes tests/out/glsl/multiview.main.Fragment.glsl | 22 +++++++++++ .../glsl/multiview_webgl.main.Fragment.glsl | 22 +++++++++++ tests/out/wgsl/multiview.wgsl | 15 ++++++++ tests/snapshots.rs | 10 +++++ 8 files changed, 108 insertions(+), 6 deletions(-) create mode 100644 tests/in/multiview_webgl.param.ron create mode 100644 tests/in/spv/multiview.spv create mode 100644 tests/in/spv/multiview_webgl.spv create mode 100644 tests/out/glsl/multiview.main.Fragment.glsl create mode 100644 tests/out/glsl/multiview_webgl.main.Fragment.glsl create mode 100644 tests/out/wgsl/multiview.wgsl diff --git a/src/back/glsl/mod.rs b/src/back/glsl/mod.rs index 32846830db..6d1bae67a3 100644 --- a/src/back/glsl/mod.rs +++ b/src/back/glsl/mod.rs @@ -139,6 +139,13 @@ impl Version { } } + const fn is_webgl(&self) -> bool { + match *self { + Version::Desktop(_) => false, + Version::Embedded { is_webgl, .. } => is_webgl, + } + } + /// Checks the list of currently supported versions and returns true if it contains the /// specified version /// @@ -297,6 +304,7 @@ struct VaryingName<'a> { binding: &'a crate::Binding, stage: ShaderStage, output: bool, + targetting_webgl: bool, } impl fmt::Display for VaryingName<'_> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { @@ -314,7 +322,11 @@ impl fmt::Display for VaryingName<'_> { write!(f, "_{}_location{}", prefix, location,) } crate::Binding::BuiltIn(built_in) => { - write!(f, "{}", glsl_built_in(built_in, self.output)) + write!( + f, + "{}", + glsl_built_in(built_in, self.output, self.targetting_webgl) + ) } } } @@ -1203,7 +1215,11 @@ impl<'a, W: Write> Writer<'a, W> { } => (location, interpolation, sampling), crate::Binding::BuiltIn(built_in) => { if let crate::BuiltIn::Position { invariant: true } = built_in { - writeln!(self.out, "invariant {};", glsl_built_in(built_in, output))?; + writeln!( + self.out, + "invariant {};", + glsl_built_in(built_in, output, self.options.version.is_webgl()) + )?; } return Ok(()); } @@ -1261,6 +1277,7 @@ impl<'a, W: Write> Writer<'a, W> { }, stage: self.entry_point.stage, output, + targetting_webgl: self.options.version.is_webgl(), }; writeln!(self.out, " {};", vname)?; @@ -1401,6 +1418,7 @@ impl<'a, W: Write> Writer<'a, W> { binding: member.binding.as_ref().unwrap(), stage, output: false, + targetting_webgl: self.options.version.is_webgl(), }; if index != 0 { write!(self.out, ", ")?; @@ -1414,6 +1432,7 @@ impl<'a, W: Write> Writer<'a, W> { binding: arg.binding.as_ref().unwrap(), stage, output: false, + targetting_webgl: self.options.version.is_webgl(), }; writeln!(self.out, "{};", varying_name)?; } @@ -1900,6 +1919,7 @@ impl<'a, W: Write> Writer<'a, W> { binding: member.binding.as_ref().unwrap(), stage: ep.stage, output: true, + targetting_webgl: self.options.version.is_webgl(), }; write!(self.out, "{} = ", varying_name)?; @@ -1924,6 +1944,7 @@ impl<'a, W: Write> Writer<'a, W> { binding: result.binding.as_ref().unwrap(), stage: ep.stage, output: true, + targetting_webgl: self.options.version.is_webgl(), }; write!(self.out, "{} = ", name)?; self.write_expr(value, ctx)?; @@ -3592,11 +3613,13 @@ const fn glsl_scalar( } /// Helper function that returns the glsl variable name for a builtin -const fn glsl_built_in(built_in: crate::BuiltIn, output: bool) -> &'static str { +const fn glsl_built_in( + built_in: crate::BuiltIn, + output: bool, + targetting_webgl: bool, +) -> &'static str { use crate::BuiltIn as Bi; - let multiview_ovr = true; - match built_in { Bi::Position { .. } => { if output { @@ -3605,7 +3628,7 @@ const fn glsl_built_in(built_in: crate::BuiltIn, output: bool) -> &'static str { "gl_FragCoord" } } - Bi::ViewIndex if multiview_ovr => "int(gl_ViewID_OVR)", + Bi::ViewIndex if targetting_webgl => "int(gl_ViewID_OVR)", Bi::ViewIndex => "gl_ViewIndex", // vertex Bi::BaseInstance => "uint(gl_BaseInstance)", diff --git a/tests/in/multiview_webgl.param.ron b/tests/in/multiview_webgl.param.ron new file mode 100644 index 0000000000..2a4720427b --- /dev/null +++ b/tests/in/multiview_webgl.param.ron @@ -0,0 +1,10 @@ +( + glsl: ( + version: Embedded( + version: 300, + is_webgl: true + ), + writer_flags: (bits: 0), + binding_map: {}, + ), +) diff --git a/tests/in/spv/multiview.spv b/tests/in/spv/multiview.spv new file mode 100644 index 0000000000000000000000000000000000000000..34159ea8d8c0cfa0995bd5a08c0b10f6c43069e7 GIT binary patch literal 492 zcmY*VO-sW-5Pdcu)u^>ayjQ#z4=RG#TUo_G#Y*jMkz|pDG!&cq@%Q{yUIgDuJj8`z zcHX?1c{4%hqzh~z!9MoTya75y0Qsi@n2RyHpWC~e2fN%9m4EZ@o%vnj;+b@oj@DH^ zIy*mAhaLjCI(I-$$iHm)>`UPZtxt|H4(Bi6B;bq9Lh?;&CyU2_qlhQM&2(zgiOp6k zyRJS9XA56CoBLOnQI=Evc8llBtk~pjLPSPeON59OfL5};%-siw#I?qk!p;fbHYoR` zPHFGaOsz;a02aK_Ave$t$MrU-|3~D+#D+B8X~=~K61-U!h literal 0 HcmV?d00001 diff --git a/tests/in/spv/multiview_webgl.spv b/tests/in/spv/multiview_webgl.spv new file mode 100644 index 0000000000000000000000000000000000000000..34159ea8d8c0cfa0995bd5a08c0b10f6c43069e7 GIT binary patch literal 492 zcmY*VO-sW-5Pdcu)u^>ayjQ#z4=RG#TUo_G#Y*jMkz|pDG!&cq@%Q{yUIgDuJj8`z zcHX?1c{4%hqzh~z!9MoTya75y0Qsi@n2RyHpWC~e2fN%9m4EZ@o%vnj;+b@oj@DH^ zIy*mAhaLjCI(I-$$iHm)>`UPZtxt|H4(Bi6B;bq9Lh?;&CyU2_qlhQM&2(zgiOp6k zyRJS9XA56CoBLOnQI=Evc8llBtk~pjLPSPeON59OfL5};%-siw#I?qk!p;fbHYoR` zPHFGaOsz;a02aK_Ave$t$MrU-|3~D+#D+B8X~=~K61-U!h literal 0 HcmV?d00001 diff --git a/tests/out/glsl/multiview.main.Fragment.glsl b/tests/out/glsl/multiview.main.Fragment.glsl new file mode 100644 index 0000000000..b9dab683b8 --- /dev/null +++ b/tests/out/glsl/multiview.main.Fragment.glsl @@ -0,0 +1,22 @@ +#version 310 es +#extension GL_EXT_multiview : require + +precision highp float; +precision highp int; + +int gen_gl_ViewIndex_1 = 0; + + +void main_1() { + int view_index = 0; + int _e6 = gen_gl_ViewIndex_1; + view_index = _e6; + return; +} + +void main() { + int gen_gl_ViewIndex = gl_ViewIndex; + gen_gl_ViewIndex_1 = gen_gl_ViewIndex; + main_1(); +} + diff --git a/tests/out/glsl/multiview_webgl.main.Fragment.glsl b/tests/out/glsl/multiview_webgl.main.Fragment.glsl new file mode 100644 index 0000000000..bb4ec73ad9 --- /dev/null +++ b/tests/out/glsl/multiview_webgl.main.Fragment.glsl @@ -0,0 +1,22 @@ +#version 300 es +#extension GL_OVR_multiview2 : require + +precision highp float; +precision highp int; + +int gen_gl_ViewIndex_1 = 0; + + +void main_1() { + int view_index = 0; + int _e6 = gen_gl_ViewIndex_1; + view_index = _e6; + return; +} + +void main() { + int gen_gl_ViewIndex = int(gl_ViewID_OVR); + gen_gl_ViewIndex_1 = gen_gl_ViewIndex; + main_1(); +} + diff --git a/tests/out/wgsl/multiview.wgsl b/tests/out/wgsl/multiview.wgsl new file mode 100644 index 0000000000..28063fa897 --- /dev/null +++ b/tests/out/wgsl/multiview.wgsl @@ -0,0 +1,15 @@ +var gl_ViewIndex_1: i32; + +fn main_1() { + var view_index: i32; + + let _e6 = gl_ViewIndex_1; + view_index = _e6; + return; +} + +@fragment +fn main(@builtin(view_index) gl_ViewIndex: i32) { + gl_ViewIndex_1 = gl_ViewIndex; + main_1(); +} diff --git a/tests/snapshots.rs b/tests/snapshots.rs index a19cc1955c..2332465ecc 100644 --- a/tests/snapshots.rs +++ b/tests/snapshots.rs @@ -591,6 +591,16 @@ fn convert_spv_all() { Targets::HLSL | Targets::WGSL | Targets::METAL, ); convert_spv("degrees", false, Targets::empty()); + convert_spv( + "multiview", + true, + Targets::GLSL | Targets::WGSL, + ); + convert_spv( + "multiview_webgl", + true, + Targets::GLSL, + ); } #[cfg(feature = "glsl-in")] From a1fffea44a2a3864e9df5a69d1540a724e59b9c3 Mon Sep 17 00:00:00 2001 From: Ashley Ruglys Date: Wed, 15 Jun 2022 16:35:54 +0200 Subject: [PATCH 10/16] Revamp so that the glsl options have some multiview options. Also add tests --- benches/criterion.rs | 4 +- cli/src/main.rs | 3 +- src/back/glsl/features.rs | 30 +++++--- src/back/glsl/mod.rs | 118 ++++++++++++++++------------- tests/in/functions-webgl.param.ron | 5 +- tests/in/multiview_webgl.param.ron | 11 +-- tests/in/push-constants.param.ron | 5 +- tests/in/quad.param.ron | 5 +- tests/in/skybox.param.ron | 5 +- tests/snapshots.rs | 13 +--- 10 files changed, 102 insertions(+), 97 deletions(-) diff --git a/benches/criterion.rs b/benches/criterion.rs index e4a32c0d48..34866527b0 100644 --- a/benches/criterion.rs +++ b/benches/criterion.rs @@ -239,16 +239,16 @@ fn backends(c: &mut Criterion) { b.iter(|| { let mut string = String::new(); let options = naga::back::glsl::Options { - version: naga::back::glsl::Version::embedded(320), + version: naga::back::glsl::Version::Embedded(320), writer_flags: naga::back::glsl::WriterFlags::empty(), binding_map: Default::default(), + multiview: Default::default(), }; for &(ref module, ref info) in inputs.iter() { for ep in module.entry_points.iter() { let pipeline_options = naga::back::glsl::PipelineOptions { shader_stage: ep.stage, entry_point: ep.name.clone(), - multiview: None, }; match naga::back::glsl::Writer::new( &mut string, diff --git a/cli/src/main.rs b/cli/src/main.rs index f1c72d8b66..efaf5959bc 100644 --- a/cli/src/main.rs +++ b/cli/src/main.rs @@ -133,7 +133,7 @@ impl FromStr for GlslProfileArg { Ok(Self(if s.starts_with("core") { Version::Desktop(s[4..].parse().unwrap_or(330)) } else if s.starts_with("es") { - Version::embedded(s[2..].parse().unwrap_or(310)) + Version::Embedded(s[2..].parse().unwrap_or(310)) } else { return Err(format!("Unknown profile: {}", s)); })) @@ -454,7 +454,6 @@ fn run() -> Result<(), Box> { "comp" => naga::ShaderStage::Compute, _ => unreachable!(), }, - multiview: None, }; let mut buffer = String::new(); diff --git a/src/back/glsl/features.rs b/src/back/glsl/features.rs index 2731b21663..0bc82b6f05 100644 --- a/src/back/glsl/features.rs +++ b/src/back/glsl/features.rs @@ -1,4 +1,4 @@ -use super::{BackendResult, Error, Version, Writer}; +use super::{BackendResult, Error, MultiviewExtension, Version, Writer}; use crate::{ AddressSpace, Binding, Bytes, Expression, Handle, ImageClass, ImageDimension, Interpolation, MathFunction, Sampling, ScalarKind, ShaderStage, StorageFormat, Type, TypeInner, @@ -65,7 +65,11 @@ impl FeaturesManager { /// Checks that all required [`Features`] are available for the specified /// [`Version`](super::Version) otherwise returns an /// [`Error::MissingFeatures`](super::Error::MissingFeatures) - pub fn check_availability(&self, version: Version) -> BackendResult { + pub fn check_availability( + &self, + version: Version, + multiview_extension: Option, + ) -> BackendResult { // Will store all the features that are unavailable let mut missing = Features::empty(); @@ -82,7 +86,7 @@ impl FeaturesManager { // Used when both core and es support the feature ($feature:ident, $core:literal, $es:literal) => { if self.0.contains(Features::$feature) - && (version < Version::Desktop($core) || version < Version::embedded($es)) + && (version < Version::Desktop($core) || version < Version::Embedded($es)) { missing |= Features::$feature; } @@ -106,8 +110,8 @@ impl FeaturesManager { check_feature!(CULL_DISTANCE, 450, 300); check_feature!(SAMPLE_VARIABLES, 400, 300); check_feature!(DYNAMIC_ARRAY_SIZE, 430, 310); - match version { - Version::Embedded { is_webgl: true, .. } => check_feature!(MULTI_VIEW, 140, 300), + match multiview_extension { + Some(MultiviewExtension::OvrMultiview2) => check_feature!(MULTI_VIEW, 140, 300), _ => check_feature!(MULTI_VIEW, 140, 310), }; // Only available on glsl core, this means that opengl es can't query the number @@ -130,7 +134,12 @@ impl FeaturesManager { /// # Notes /// This won't check for feature availability so it might output extensions that aren't even /// supported.[`check_availability`](Self::check_availability) will check feature availability - pub fn write(&self, version: Version, mut out: impl Write) -> BackendResult { + pub fn write( + &self, + version: Version, + multiview_extension: Option, + mut out: impl Write, + ) -> BackendResult { if self.0.contains(Features::COMPUTE_SHADER) && !version.is_es() { // https://www.khronos.org/registry/OpenGL/extensions/ARB/ARB_compute_shader.txt writeln!(out, "#extension GL_ARB_compute_shader : require")?; @@ -215,7 +224,7 @@ impl FeaturesManager { } if self.0.contains(Features::MULTI_VIEW) { - if let Version::Embedded { is_webgl: true, .. } = version { + if let Some(MultiviewExtension::OvrMultiview2) = multiview_extension { // https://www.khronos.org/registry/OpenGL/extensions/OVR/OVR_multiview2.txt writeln!(out, "#extension GL_OVR_multiview2 : require")?; } else { @@ -224,7 +233,7 @@ impl FeaturesManager { } } - if self.0.contains(Features::FMA) && version >= Version::embedded(310) { + if self.0.contains(Features::FMA) && version >= Version::Embedded(310) { // https://www.khronos.org/registry/OpenGL/extensions/EXT/EXT_gpu_shader5.txt writeln!(out, "#extension GL_EXT_gpu_shader5 : require")?; } @@ -277,7 +286,7 @@ impl<'a, W> Writer<'a, W> { self.features.request(Features::COMPUTE_SHADER) } - if self.multiview.is_some() { + if self.options.multiview.is_some() { self.features.request(Features::MULTI_VIEW); } @@ -470,7 +479,8 @@ impl<'a, W> Writer<'a, W> { } } - self.features.check_availability(self.options.version) + self.features + .check_availability(self.options.version, self.multiview_extension()) } /// Helper method that checks the [`Features`] needed by a scalar diff --git a/src/back/glsl/mod.rs b/src/back/glsl/mod.rs index 95bf03ac24..aa59c4b0b3 100644 --- a/src/back/glsl/mod.rs +++ b/src/back/glsl/mod.rs @@ -119,30 +119,15 @@ pub enum Version { /// `core` GLSL. Desktop(u16), /// `es` GLSL. - Embedded { version: u16, is_webgl: bool }, + Embedded(u16), } impl Version { - /// Create a new embedded version. - pub const fn embedded(version: u16) -> Self { - Self::Embedded { - version, - is_webgl: false, - } - } - /// Returns true if self is `Version::Embedded` (i.e. is a es version) const fn is_es(&self) -> bool { match *self { Version::Desktop(_) => false, - Version::Embedded { .. } => true, - } - } - - const fn is_webgl(&self) -> bool { - match *self { - Version::Desktop(_) => false, - Version::Embedded { is_webgl, .. } => is_webgl, + Version::Embedded(_) => true, } } @@ -155,7 +140,7 @@ impl Version { fn is_supported(&self) -> bool { match *self { Version::Desktop(v) => SUPPORTED_CORE_VERSIONS.contains(&v), - Version::Embedded { version: v, .. } => SUPPORTED_ES_VERSIONS.contains(&v), + Version::Embedded(v) => SUPPORTED_ES_VERSIONS.contains(&v), } } @@ -166,19 +151,19 @@ impl Version { /// Note: `location=` for vertex inputs and fragment outputs is supported /// unconditionally for GLES 300. fn supports_explicit_locations(&self) -> bool { - *self >= Version::embedded(310) || *self >= Version::Desktop(410) + *self >= Version::Embedded(310) || *self >= Version::Desktop(410) } fn supports_early_depth_test(&self) -> bool { - *self >= Version::Desktop(130) || *self >= Version::embedded(310) + *self >= Version::Desktop(130) || *self >= Version::Embedded(310) } fn supports_std430_layout(&self) -> bool { - *self >= Version::Desktop(430) || *self >= Version::embedded(310) + *self >= Version::Desktop(430) || *self >= Version::Embedded(310) } fn supports_fma_function(&self) -> bool { - *self >= Version::Desktop(400) || *self >= Version::embedded(310) + *self >= Version::Desktop(400) || *self >= Version::Embedded(310) } } @@ -186,9 +171,7 @@ impl PartialOrd for Version { fn partial_cmp(&self, other: &Self) -> Option { match (*self, *other) { (Version::Desktop(x), Version::Desktop(y)) => Some(x.cmp(&y)), - (Version::Embedded { version: x, .. }, Version::Embedded { version: y, .. }) => { - Some(x.cmp(&y)) - } + (Version::Embedded(x), Version::Embedded(y)) => Some(x.cmp(&y)), _ => None, } } @@ -198,7 +181,7 @@ impl fmt::Display for Version { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match *self { Version::Desktop(v) => write!(f, "{} core", v), - Version::Embedded { version: v, .. } => write!(f, "{} es", v), + Version::Embedded(v) => write!(f, "{} es", v), } } } @@ -227,18 +210,41 @@ pub struct Options { pub writer_flags: WriterFlags, /// Map of resources association to binding locations. pub binding_map: BindingMap, + /// A set of options to use when rendering multiple views. + pub multiview: Option, } impl Default for Options { fn default() -> Self { Options { - version: Version::embedded(310), + version: Version::Embedded(310), writer_flags: WriterFlags::ADJUST_COORDINATE_SPACE, binding_map: BindingMap::default(), + multiview: None, } } } +/// Which multiview extension to use. +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +#[cfg_attr(feature = "serialize", derive(serde::Serialize))] +#[cfg_attr(feature = "deserialize", derive(serde::Deserialize))] +pub enum MultiviewExtension { + // Corresponds to the OpenGL `GL_EXT_multiview` extension. + GLExtMultiview, + // Corresponds to WebGL `OVR_multiview2` extension. + OvrMultiview2, +} + +/// A set of options to use when rendering multiple views. +#[derive(Debug, Clone, PartialEq, Eq, Hash)] +#[cfg_attr(feature = "serialize", derive(serde::Serialize))] +#[cfg_attr(feature = "deserialize", derive(serde::Deserialize))] +pub struct MultiviewOptions { + pub num_views: std::num::NonZeroU32, + pub extension: MultiviewExtension, +} + /// A subset of options meant to be changed per pipeline. #[derive(Debug, Clone, PartialEq, Eq, Hash)] #[cfg_attr(feature = "serialize", derive(serde::Serialize))] @@ -250,8 +256,6 @@ pub struct PipelineOptions { /// /// If no entry point that matches is found while creating a [`Writer`], a error will be thrown. pub entry_point: String, - /// How many views to render to. - pub multiview: Option, } /// Reflection info for texture mappings and uniforms. @@ -304,7 +308,7 @@ struct VaryingName<'a> { binding: &'a crate::Binding, stage: ShaderStage, output: bool, - targetting_webgl: bool, + multiview_extension: Option, } impl fmt::Display for VaryingName<'_> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { @@ -325,7 +329,7 @@ impl fmt::Display for VaryingName<'_> { write!( f, "{}", - glsl_built_in(built_in, self.output, self.targetting_webgl) + glsl_built_in(built_in, self.output, self.multiview_extension) ) } } @@ -424,8 +428,7 @@ pub struct Writer<'a, W> { named_expressions: crate::NamedExpressions, /// Set of expressions that need to be baked to avoid unnecessary repetition in output need_bake_expressions: back::NeedBakeExpressions, - /// How many views to render to, if a vertex shader. - multiview: Option, + shader_stage: ShaderStage, } impl<'a, W: Write> Writer<'a, W> { @@ -477,11 +480,7 @@ impl<'a, W: Write> Writer<'a, W> { reflection_names_globals: crate::FastHashMap::default(), entry_point: &module.entry_points[ep_idx], entry_point_idx: ep_idx as u16, - multiview: if pipeline_options.shader_stage == ShaderStage::Vertex { - pipeline_options.multiview - } else { - None - }, + shader_stage: pipeline_options.shader_stage, block_id: IdGenerator::default(), named_expressions: Default::default(), need_bake_expressions: Default::default(), @@ -514,7 +513,11 @@ impl<'a, W: Write> Writer<'a, W> { // writing the module saving some loops but some older versions (420 or less) required the // extensions to appear before being used, even though extensions are part of the // preprocessor not the processor ¯\_(ツ)_/¯ - self.features.write(self.options.version, &mut self.out)?; + self.features.write( + self.options.version, + self.multiview_extension(), + &mut self.out, + )?; // Write the additional extensions if self @@ -570,9 +573,11 @@ impl<'a, W: Write> Writer<'a, W> { } } - if let Some(multiview) = self.multiview { - writeln!(self.out, "layout(num_views = {}) in;", multiview)?; - writeln!(self.out)?; + if self.shader_stage == ShaderStage::Vertex { + if let Some(multiview) = &self.options.multiview { + writeln!(self.out, "layout(num_views = {}) in;", multiview.num_views)?; + writeln!(self.out)?; + } } let ep_info = self.info.get_entry_point(self.entry_point_idx as usize); @@ -1218,7 +1223,7 @@ impl<'a, W: Write> Writer<'a, W> { writeln!( self.out, "invariant {};", - glsl_built_in(built_in, output, self.options.version.is_webgl()) + glsl_built_in(built_in, output, self.multiview_extension()) )?; } return Ok(()); @@ -1277,7 +1282,7 @@ impl<'a, W: Write> Writer<'a, W> { }, stage: self.entry_point.stage, output, - targetting_webgl: self.options.version.is_webgl(), + multiview_extension: self.multiview_extension(), }; writeln!(self.out, " {};", vname)?; @@ -1418,7 +1423,7 @@ impl<'a, W: Write> Writer<'a, W> { binding: member.binding.as_ref().unwrap(), stage, output: false, - targetting_webgl: self.options.version.is_webgl(), + multiview_extension: self.multiview_extension(), }; if index != 0 { write!(self.out, ", ")?; @@ -1432,7 +1437,7 @@ impl<'a, W: Write> Writer<'a, W> { binding: arg.binding.as_ref().unwrap(), stage, output: false, - targetting_webgl: self.options.version.is_webgl(), + multiview_extension: self.multiview_extension(), }; writeln!(self.out, "{};", varying_name)?; } @@ -1929,7 +1934,7 @@ impl<'a, W: Write> Writer<'a, W> { binding: member.binding.as_ref().unwrap(), stage: ep.stage, output: true, - targetting_webgl: self.options.version.is_webgl(), + multiview_extension: self.multiview_extension(), }; write!(self.out, "{} = ", varying_name)?; @@ -1954,7 +1959,7 @@ impl<'a, W: Write> Writer<'a, W> { binding: result.binding.as_ref().unwrap(), stage: ep.stage, output: true, - targetting_webgl: self.options.version.is_webgl(), + multiview_extension: self.multiview_extension(), }; write!(self.out, "{} = ", name)?; self.write_expr(value, ctx)?; @@ -3601,6 +3606,15 @@ impl<'a, W: Write> Writer<'a, W> { } } +impl<'a, W> Writer<'a, W> { + fn multiview_extension(&self) -> Option { + self.options + .multiview + .as_ref() + .map(|multiview| multiview.extension) + } +} + /// Structure returned by [`glsl_scalar`](glsl_scalar) /// /// It contains both a prefix used in other types and the full type name @@ -3651,10 +3665,10 @@ const fn glsl_scalar( } /// Helper function that returns the glsl variable name for a builtin -const fn glsl_built_in( +fn glsl_built_in( built_in: crate::BuiltIn, output: bool, - targetting_webgl: bool, + multiview_extension: Option, ) -> &'static str { use crate::BuiltIn as Bi; @@ -3666,7 +3680,9 @@ const fn glsl_built_in( "gl_FragCoord" } } - Bi::ViewIndex if targetting_webgl => "int(gl_ViewID_OVR)", + Bi::ViewIndex if multiview_extension == Some(MultiviewExtension::OvrMultiview2) => { + "int(gl_ViewID_OVR)" + } Bi::ViewIndex => "gl_ViewIndex", // vertex Bi::BaseInstance => "uint(gl_BaseInstance)", diff --git a/tests/in/functions-webgl.param.ron b/tests/in/functions-webgl.param.ron index 923da07299..bc3dd4a8dd 100644 --- a/tests/in/functions-webgl.param.ron +++ b/tests/in/functions-webgl.param.ron @@ -1,9 +1,6 @@ ( glsl: ( - version: Embedded( - version: 300, - is_webgl: false - ), + version: Embedded(300), writer_flags: (bits: 0), binding_map: {}, ), diff --git a/tests/in/multiview_webgl.param.ron b/tests/in/multiview_webgl.param.ron index 2a4720427b..cbbb446538 100644 --- a/tests/in/multiview_webgl.param.ron +++ b/tests/in/multiview_webgl.param.ron @@ -1,10 +1,11 @@ ( glsl: ( - version: Embedded( - version: 300, - is_webgl: true - ), + version: Embedded(300), writer_flags: (bits: 0), binding_map: {}, - ), + multiview: Some(( + num_views: 2, + extension: OvrMultiview2 + )) + ) ) diff --git a/tests/in/push-constants.param.ron b/tests/in/push-constants.param.ron index 3972328c9c..0a35edeab8 100644 --- a/tests/in/push-constants.param.ron +++ b/tests/in/push-constants.param.ron @@ -1,10 +1,7 @@ ( god_mode: true, glsl: ( - version: Embedded( - version: 320, - is_webgl: false - ), + version: Embedded(320), writer_flags: (bits: 0), binding_map: {}, ), diff --git a/tests/in/quad.param.ron b/tests/in/quad.param.ron index 568b961898..acde3aed42 100644 --- a/tests/in/quad.param.ron +++ b/tests/in/quad.param.ron @@ -5,10 +5,7 @@ adjust_coordinate_space: true, ), glsl: ( - version: Embedded( - version: 300, - is_webgl: false - ), + version: Embedded(300), writer_flags: (bits: 0), binding_map: {}, ), diff --git a/tests/in/skybox.param.ron b/tests/in/skybox.param.ron index b90f2e5a25..9c9bd1f30a 100644 --- a/tests/in/skybox.param.ron +++ b/tests/in/skybox.param.ron @@ -37,10 +37,7 @@ fake_missing_bindings: false, ), glsl: ( - version: Embedded( - version: 320, - is_webgl: false - ), + version: Embedded(320), writer_flags: (bits: 0), binding_map: { (group: 0, binding: 0): 0, diff --git a/tests/snapshots.rs b/tests/snapshots.rs index 2332465ecc..b0a0419dca 100644 --- a/tests/snapshots.rs +++ b/tests/snapshots.rs @@ -291,7 +291,6 @@ fn write_output_glsl( let pipeline_options = glsl::PipelineOptions { shader_stage: stage, entry_point: ep_name.to_string(), - multiview: None, }; let mut buffer = String::new(); @@ -591,16 +590,8 @@ fn convert_spv_all() { Targets::HLSL | Targets::WGSL | Targets::METAL, ); convert_spv("degrees", false, Targets::empty()); - convert_spv( - "multiview", - true, - Targets::GLSL | Targets::WGSL, - ); - convert_spv( - "multiview_webgl", - true, - Targets::GLSL, - ); + convert_spv("multiview", true, Targets::GLSL | Targets::WGSL); + convert_spv("multiview_webgl", true, Targets::GLSL); } #[cfg(feature = "glsl-in")] From 5d49ee997afbcbbf22705460b642f9c5d74c51bf Mon Sep 17 00:00:00 2001 From: Ashley Ruglys Date: Wed, 15 Jun 2022 16:49:45 +0200 Subject: [PATCH 11/16] Make clippy happier --- src/back/glsl/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/back/glsl/mod.rs b/src/back/glsl/mod.rs index aa59c4b0b3..a83930b36e 100644 --- a/src/back/glsl/mod.rs +++ b/src/back/glsl/mod.rs @@ -574,7 +574,7 @@ impl<'a, W: Write> Writer<'a, W> { } if self.shader_stage == ShaderStage::Vertex { - if let Some(multiview) = &self.options.multiview { + if let Some(multiview) = self.options.multiview.as_ref() { writeln!(self.out, "layout(num_views = {}) in;", multiview.num_views)?; writeln!(self.out)?; } From ef77cc2ebc2b00c3d746291b1f9ba152d2be5b42 Mon Sep 17 00:00:00 2001 From: Ashley Ruglys Date: Thu, 16 Jun 2022 15:55:10 +0200 Subject: [PATCH 12/16] Go back to having is_webgl be part of Version --- benches/criterion.rs | 4 +- cli/src/main.rs | 3 +- src/back/glsl/features.rs | 30 +++----- src/back/glsl/mod.rs | 113 ++++++++++++----------------- tests/in/functions-webgl.param.ron | 5 +- tests/in/multiview_webgl.param.ron | 11 ++- tests/in/push-constants.param.ron | 5 +- tests/in/quad.param.ron | 5 +- tests/in/skybox.param.ron | 5 +- tests/snapshots.rs | 1 + 10 files changed, 84 insertions(+), 98 deletions(-) diff --git a/benches/criterion.rs b/benches/criterion.rs index 34866527b0..80fed4e798 100644 --- a/benches/criterion.rs +++ b/benches/criterion.rs @@ -239,16 +239,16 @@ fn backends(c: &mut Criterion) { b.iter(|| { let mut string = String::new(); let options = naga::back::glsl::Options { - version: naga::back::glsl::Version::Embedded(320), + version: naga::back::glsl::Version::new_embedded(320), writer_flags: naga::back::glsl::WriterFlags::empty(), binding_map: Default::default(), - multiview: Default::default(), }; for &(ref module, ref info) in inputs.iter() { for ep in module.entry_points.iter() { let pipeline_options = naga::back::glsl::PipelineOptions { shader_stage: ep.stage, entry_point: ep.name.clone(), + multiview: None, }; match naga::back::glsl::Writer::new( &mut string, diff --git a/cli/src/main.rs b/cli/src/main.rs index efaf5959bc..e2acb7e269 100644 --- a/cli/src/main.rs +++ b/cli/src/main.rs @@ -133,7 +133,7 @@ impl FromStr for GlslProfileArg { Ok(Self(if s.starts_with("core") { Version::Desktop(s[4..].parse().unwrap_or(330)) } else if s.starts_with("es") { - Version::Embedded(s[2..].parse().unwrap_or(310)) + Version::new_embedded(s[2..].parse().unwrap_or(310)) } else { return Err(format!("Unknown profile: {}", s)); })) @@ -454,6 +454,7 @@ fn run() -> Result<(), Box> { "comp" => naga::ShaderStage::Compute, _ => unreachable!(), }, + multiview: None, }; let mut buffer = String::new(); diff --git a/src/back/glsl/features.rs b/src/back/glsl/features.rs index 0bc82b6f05..281d7167b3 100644 --- a/src/back/glsl/features.rs +++ b/src/back/glsl/features.rs @@ -1,4 +1,4 @@ -use super::{BackendResult, Error, MultiviewExtension, Version, Writer}; +use super::{BackendResult, Error, Version, Writer}; use crate::{ AddressSpace, Binding, Bytes, Expression, Handle, ImageClass, ImageDimension, Interpolation, MathFunction, Sampling, ScalarKind, ShaderStage, StorageFormat, Type, TypeInner, @@ -65,11 +65,7 @@ impl FeaturesManager { /// Checks that all required [`Features`] are available for the specified /// [`Version`](super::Version) otherwise returns an /// [`Error::MissingFeatures`](super::Error::MissingFeatures) - pub fn check_availability( - &self, - version: Version, - multiview_extension: Option, - ) -> BackendResult { + pub fn check_availability(&self, version: Version) -> BackendResult { // Will store all the features that are unavailable let mut missing = Features::empty(); @@ -86,7 +82,7 @@ impl FeaturesManager { // Used when both core and es support the feature ($feature:ident, $core:literal, $es:literal) => { if self.0.contains(Features::$feature) - && (version < Version::Desktop($core) || version < Version::Embedded($es)) + && (version < Version::Desktop($core) || version < Version::new_embedded($es)) { missing |= Features::$feature; } @@ -110,8 +106,8 @@ impl FeaturesManager { check_feature!(CULL_DISTANCE, 450, 300); check_feature!(SAMPLE_VARIABLES, 400, 300); check_feature!(DYNAMIC_ARRAY_SIZE, 430, 310); - match multiview_extension { - Some(MultiviewExtension::OvrMultiview2) => check_feature!(MULTI_VIEW, 140, 300), + match version { + Version::Embedded { is_webgl: true, .. } => check_feature!(MULTI_VIEW, 140, 300), _ => check_feature!(MULTI_VIEW, 140, 310), }; // Only available on glsl core, this means that opengl es can't query the number @@ -134,12 +130,7 @@ impl FeaturesManager { /// # Notes /// This won't check for feature availability so it might output extensions that aren't even /// supported.[`check_availability`](Self::check_availability) will check feature availability - pub fn write( - &self, - version: Version, - multiview_extension: Option, - mut out: impl Write, - ) -> BackendResult { + pub fn write(&self, version: Version, mut out: impl Write) -> BackendResult { if self.0.contains(Features::COMPUTE_SHADER) && !version.is_es() { // https://www.khronos.org/registry/OpenGL/extensions/ARB/ARB_compute_shader.txt writeln!(out, "#extension GL_ARB_compute_shader : require")?; @@ -224,7 +215,7 @@ impl FeaturesManager { } if self.0.contains(Features::MULTI_VIEW) { - if let Some(MultiviewExtension::OvrMultiview2) = multiview_extension { + if let Version::Embedded { is_webgl: true, .. } = version { // https://www.khronos.org/registry/OpenGL/extensions/OVR/OVR_multiview2.txt writeln!(out, "#extension GL_OVR_multiview2 : require")?; } else { @@ -233,7 +224,7 @@ impl FeaturesManager { } } - if self.0.contains(Features::FMA) && version >= Version::Embedded(310) { + if self.0.contains(Features::FMA) && version >= Version::new_embedded(310) { // https://www.khronos.org/registry/OpenGL/extensions/EXT/EXT_gpu_shader5.txt writeln!(out, "#extension GL_EXT_gpu_shader5 : require")?; } @@ -286,7 +277,7 @@ impl<'a, W> Writer<'a, W> { self.features.request(Features::COMPUTE_SHADER) } - if self.options.multiview.is_some() { + if self.multiview.is_some() { self.features.request(Features::MULTI_VIEW); } @@ -479,8 +470,7 @@ impl<'a, W> Writer<'a, W> { } } - self.features - .check_availability(self.options.version, self.multiview_extension()) + self.features.check_availability(self.options.version) } /// Helper method that checks the [`Features`] needed by a scalar diff --git a/src/back/glsl/mod.rs b/src/back/glsl/mod.rs index a83930b36e..0ffc783d94 100644 --- a/src/back/glsl/mod.rs +++ b/src/back/glsl/mod.rs @@ -119,15 +119,31 @@ pub enum Version { /// `core` GLSL. Desktop(u16), /// `es` GLSL. - Embedded(u16), + Embedded { version: u16, is_webgl: bool }, } impl Version { + /// Create a new non-WebGL embedded version + pub const fn new_embedded(version: u16) -> Self { + Self::Embedded { + version, + is_webgl: false, + } + } + /// Returns true if self is `Version::Embedded` (i.e. is a es version) const fn is_es(&self) -> bool { match *self { Version::Desktop(_) => false, - Version::Embedded(_) => true, + Version::Embedded { .. } => true, + } + } + + /// Returns true if targetting WebGL + const fn is_webgl(&self) -> bool { + match *self { + Version::Desktop(_) => false, + Version::Embedded { is_webgl, .. } => is_webgl, } } @@ -140,7 +156,7 @@ impl Version { fn is_supported(&self) -> bool { match *self { Version::Desktop(v) => SUPPORTED_CORE_VERSIONS.contains(&v), - Version::Embedded(v) => SUPPORTED_ES_VERSIONS.contains(&v), + Version::Embedded { version: v, .. } => SUPPORTED_ES_VERSIONS.contains(&v), } } @@ -151,19 +167,19 @@ impl Version { /// Note: `location=` for vertex inputs and fragment outputs is supported /// unconditionally for GLES 300. fn supports_explicit_locations(&self) -> bool { - *self >= Version::Embedded(310) || *self >= Version::Desktop(410) + *self >= Version::Desktop(410) || *self >= Version::new_embedded(310) } fn supports_early_depth_test(&self) -> bool { - *self >= Version::Desktop(130) || *self >= Version::Embedded(310) + *self >= Version::Desktop(130) || *self >= Version::new_embedded(310) } fn supports_std430_layout(&self) -> bool { - *self >= Version::Desktop(430) || *self >= Version::Embedded(310) + *self >= Version::Desktop(430) || *self >= Version::new_embedded(310) } fn supports_fma_function(&self) -> bool { - *self >= Version::Desktop(400) || *self >= Version::Embedded(310) + *self >= Version::Desktop(400) || *self >= Version::new_embedded(310) } } @@ -171,7 +187,9 @@ impl PartialOrd for Version { fn partial_cmp(&self, other: &Self) -> Option { match (*self, *other) { (Version::Desktop(x), Version::Desktop(y)) => Some(x.cmp(&y)), - (Version::Embedded(x), Version::Embedded(y)) => Some(x.cmp(&y)), + (Version::Embedded { version: x, .. }, Version::Embedded { version: y, .. }) => { + Some(x.cmp(&y)) + } _ => None, } } @@ -181,7 +199,7 @@ impl fmt::Display for Version { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match *self { Version::Desktop(v) => write!(f, "{} core", v), - Version::Embedded(v) => write!(f, "{} es", v), + Version::Embedded { version: v, .. } => write!(f, "{} es", v), } } } @@ -210,41 +228,18 @@ pub struct Options { pub writer_flags: WriterFlags, /// Map of resources association to binding locations. pub binding_map: BindingMap, - /// A set of options to use when rendering multiple views. - pub multiview: Option, } impl Default for Options { fn default() -> Self { Options { - version: Version::Embedded(310), + version: Version::new_embedded(310), writer_flags: WriterFlags::ADJUST_COORDINATE_SPACE, binding_map: BindingMap::default(), - multiview: None, } } } -/// Which multiview extension to use. -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] -#[cfg_attr(feature = "serialize", derive(serde::Serialize))] -#[cfg_attr(feature = "deserialize", derive(serde::Deserialize))] -pub enum MultiviewExtension { - // Corresponds to the OpenGL `GL_EXT_multiview` extension. - GLExtMultiview, - // Corresponds to WebGL `OVR_multiview2` extension. - OvrMultiview2, -} - -/// A set of options to use when rendering multiple views. -#[derive(Debug, Clone, PartialEq, Eq, Hash)] -#[cfg_attr(feature = "serialize", derive(serde::Serialize))] -#[cfg_attr(feature = "deserialize", derive(serde::Deserialize))] -pub struct MultiviewOptions { - pub num_views: std::num::NonZeroU32, - pub extension: MultiviewExtension, -} - /// A subset of options meant to be changed per pipeline. #[derive(Debug, Clone, PartialEq, Eq, Hash)] #[cfg_attr(feature = "serialize", derive(serde::Serialize))] @@ -256,6 +251,8 @@ pub struct PipelineOptions { /// /// If no entry point that matches is found while creating a [`Writer`], a error will be thrown. pub entry_point: String, + /// How many views to render to, if doing multiview rendering. + pub multiview: Option, } /// Reflection info for texture mappings and uniforms. @@ -308,7 +305,7 @@ struct VaryingName<'a> { binding: &'a crate::Binding, stage: ShaderStage, output: bool, - multiview_extension: Option, + targetting_webgl: bool, } impl fmt::Display for VaryingName<'_> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { @@ -329,7 +326,7 @@ impl fmt::Display for VaryingName<'_> { write!( f, "{}", - glsl_built_in(built_in, self.output, self.multiview_extension) + glsl_built_in(built_in, self.output, self.targetting_webgl) ) } } @@ -428,7 +425,8 @@ pub struct Writer<'a, W> { named_expressions: crate::NamedExpressions, /// Set of expressions that need to be baked to avoid unnecessary repetition in output need_bake_expressions: back::NeedBakeExpressions, - shader_stage: ShaderStage, + /// How many views to render to, if doing multiview rendering. + multiview: Option, } impl<'a, W: Write> Writer<'a, W> { @@ -480,7 +478,7 @@ impl<'a, W: Write> Writer<'a, W> { reflection_names_globals: crate::FastHashMap::default(), entry_point: &module.entry_points[ep_idx], entry_point_idx: ep_idx as u16, - shader_stage: pipeline_options.shader_stage, + multiview: pipeline_options.multiview, block_id: IdGenerator::default(), named_expressions: Default::default(), need_bake_expressions: Default::default(), @@ -513,11 +511,7 @@ impl<'a, W: Write> Writer<'a, W> { // writing the module saving some loops but some older versions (420 or less) required the // extensions to appear before being used, even though extensions are part of the // preprocessor not the processor ¯\_(ツ)_/¯ - self.features.write( - self.options.version, - self.multiview_extension(), - &mut self.out, - )?; + self.features.write(self.options.version, &mut self.out)?; // Write the additional extensions if self @@ -573,9 +567,9 @@ impl<'a, W: Write> Writer<'a, W> { } } - if self.shader_stage == ShaderStage::Vertex { - if let Some(multiview) = self.options.multiview.as_ref() { - writeln!(self.out, "layout(num_views = {}) in;", multiview.num_views)?; + if self.entry_point.stage == ShaderStage::Vertex { + if let Some(multiview) = self.multiview.as_ref() { + writeln!(self.out, "layout(num_views = {}) in;", multiview)?; writeln!(self.out)?; } } @@ -1223,7 +1217,7 @@ impl<'a, W: Write> Writer<'a, W> { writeln!( self.out, "invariant {};", - glsl_built_in(built_in, output, self.multiview_extension()) + glsl_built_in(built_in, output, self.options.version.is_webgl()) )?; } return Ok(()); @@ -1282,7 +1276,7 @@ impl<'a, W: Write> Writer<'a, W> { }, stage: self.entry_point.stage, output, - multiview_extension: self.multiview_extension(), + targetting_webgl: self.options.version.is_webgl(), }; writeln!(self.out, " {};", vname)?; @@ -1423,7 +1417,7 @@ impl<'a, W: Write> Writer<'a, W> { binding: member.binding.as_ref().unwrap(), stage, output: false, - multiview_extension: self.multiview_extension(), + targetting_webgl: self.options.version.is_webgl(), }; if index != 0 { write!(self.out, ", ")?; @@ -1437,7 +1431,7 @@ impl<'a, W: Write> Writer<'a, W> { binding: arg.binding.as_ref().unwrap(), stage, output: false, - multiview_extension: self.multiview_extension(), + targetting_webgl: self.options.version.is_webgl(), }; writeln!(self.out, "{};", varying_name)?; } @@ -1934,7 +1928,7 @@ impl<'a, W: Write> Writer<'a, W> { binding: member.binding.as_ref().unwrap(), stage: ep.stage, output: true, - multiview_extension: self.multiview_extension(), + targetting_webgl: self.options.version.is_webgl(), }; write!(self.out, "{} = ", varying_name)?; @@ -1959,7 +1953,7 @@ impl<'a, W: Write> Writer<'a, W> { binding: result.binding.as_ref().unwrap(), stage: ep.stage, output: true, - multiview_extension: self.multiview_extension(), + targetting_webgl: self.options.version.is_webgl(), }; write!(self.out, "{} = ", name)?; self.write_expr(value, ctx)?; @@ -3606,15 +3600,6 @@ impl<'a, W: Write> Writer<'a, W> { } } -impl<'a, W> Writer<'a, W> { - fn multiview_extension(&self) -> Option { - self.options - .multiview - .as_ref() - .map(|multiview| multiview.extension) - } -} - /// Structure returned by [`glsl_scalar`](glsl_scalar) /// /// It contains both a prefix used in other types and the full type name @@ -3665,10 +3650,10 @@ const fn glsl_scalar( } /// Helper function that returns the glsl variable name for a builtin -fn glsl_built_in( +const fn glsl_built_in( built_in: crate::BuiltIn, output: bool, - multiview_extension: Option, + targetting_webgl: bool, ) -> &'static str { use crate::BuiltIn as Bi; @@ -3680,9 +3665,7 @@ fn glsl_built_in( "gl_FragCoord" } } - Bi::ViewIndex if multiview_extension == Some(MultiviewExtension::OvrMultiview2) => { - "int(gl_ViewID_OVR)" - } + Bi::ViewIndex if targetting_webgl => "int(gl_ViewID_OVR)", Bi::ViewIndex => "gl_ViewIndex", // vertex Bi::BaseInstance => "uint(gl_BaseInstance)", diff --git a/tests/in/functions-webgl.param.ron b/tests/in/functions-webgl.param.ron index bc3dd4a8dd..923da07299 100644 --- a/tests/in/functions-webgl.param.ron +++ b/tests/in/functions-webgl.param.ron @@ -1,6 +1,9 @@ ( glsl: ( - version: Embedded(300), + version: Embedded( + version: 300, + is_webgl: false + ), writer_flags: (bits: 0), binding_map: {}, ), diff --git a/tests/in/multiview_webgl.param.ron b/tests/in/multiview_webgl.param.ron index cbbb446538..2a4720427b 100644 --- a/tests/in/multiview_webgl.param.ron +++ b/tests/in/multiview_webgl.param.ron @@ -1,11 +1,10 @@ ( glsl: ( - version: Embedded(300), + version: Embedded( + version: 300, + is_webgl: true + ), writer_flags: (bits: 0), binding_map: {}, - multiview: Some(( - num_views: 2, - extension: OvrMultiview2 - )) - ) + ), ) diff --git a/tests/in/push-constants.param.ron b/tests/in/push-constants.param.ron index 0a35edeab8..3972328c9c 100644 --- a/tests/in/push-constants.param.ron +++ b/tests/in/push-constants.param.ron @@ -1,7 +1,10 @@ ( god_mode: true, glsl: ( - version: Embedded(320), + version: Embedded( + version: 320, + is_webgl: false + ), writer_flags: (bits: 0), binding_map: {}, ), diff --git a/tests/in/quad.param.ron b/tests/in/quad.param.ron index acde3aed42..568b961898 100644 --- a/tests/in/quad.param.ron +++ b/tests/in/quad.param.ron @@ -5,7 +5,10 @@ adjust_coordinate_space: true, ), glsl: ( - version: Embedded(300), + version: Embedded( + version: 300, + is_webgl: false + ), writer_flags: (bits: 0), binding_map: {}, ), diff --git a/tests/in/skybox.param.ron b/tests/in/skybox.param.ron index 9c9bd1f30a..b90f2e5a25 100644 --- a/tests/in/skybox.param.ron +++ b/tests/in/skybox.param.ron @@ -37,7 +37,10 @@ fake_missing_bindings: false, ), glsl: ( - version: Embedded(320), + version: Embedded( + version: 320, + is_webgl: false + ), writer_flags: (bits: 0), binding_map: { (group: 0, binding: 0): 0, diff --git a/tests/snapshots.rs b/tests/snapshots.rs index b0a0419dca..0a60163986 100644 --- a/tests/snapshots.rs +++ b/tests/snapshots.rs @@ -291,6 +291,7 @@ fn write_output_glsl( let pipeline_options = glsl::PipelineOptions { shader_stage: stage, entry_point: ep_name.to_string(), + multiview: None, }; let mut buffer = String::new(); From 16feed39f0f9bd2c1367e5d195ae9d2c39ce6374 Mon Sep 17 00:00:00 2001 From: Ashley Ruglys Date: Tue, 21 Jun 2022 16:59:06 +0200 Subject: [PATCH 13/16] Use wgsl as input for tests --- tests/in/multiview.param.ron | 3 +++ tests/in/multiview.wgsl | 2 ++ tests/in/multiview_webgl.param.ron | 13 +++++----- tests/in/multiview_webgl.wgsl | 2 ++ tests/in/spv/multiview.spv | Bin 492 -> 0 bytes tests/in/spv/multiview_webgl.spv | Bin 492 -> 0 bytes tests/out/glsl/multiview.main.Fragment.glsl | 22 ----------------- tests/out/glsl/multiview.main.Vertex.glsl | 15 ++++++++++++ .../glsl/multiview_webgl.main.Fragment.glsl | 22 ----------------- .../out/glsl/multiview_webgl.main.Vertex.glsl | 14 +++++++++++ tests/out/spv/multiview.spvasm | 23 ++++++++++++++++++ tests/out/spv/multiview_webgl.spvasm | 23 ++++++++++++++++++ tests/out/wgsl/multiview.wgsl | 15 ++---------- tests/out/wgsl/multiview_webgl.wgsl | 4 +++ tests/snapshots.rs | 14 ++++++++--- 15 files changed, 106 insertions(+), 66 deletions(-) create mode 100644 tests/in/multiview.param.ron create mode 100644 tests/in/multiview.wgsl create mode 100644 tests/in/multiview_webgl.wgsl delete mode 100644 tests/in/spv/multiview.spv delete mode 100644 tests/in/spv/multiview_webgl.spv delete mode 100644 tests/out/glsl/multiview.main.Fragment.glsl create mode 100644 tests/out/glsl/multiview.main.Vertex.glsl delete mode 100644 tests/out/glsl/multiview_webgl.main.Fragment.glsl create mode 100644 tests/out/glsl/multiview_webgl.main.Vertex.glsl create mode 100644 tests/out/spv/multiview.spvasm create mode 100644 tests/out/spv/multiview_webgl.spvasm create mode 100644 tests/out/wgsl/multiview_webgl.wgsl diff --git a/tests/in/multiview.param.ron b/tests/in/multiview.param.ron new file mode 100644 index 0000000000..35dd990fd6 --- /dev/null +++ b/tests/in/multiview.param.ron @@ -0,0 +1,3 @@ +( + glsl_multiview: Some(2), +) diff --git a/tests/in/multiview.wgsl b/tests/in/multiview.wgsl new file mode 100644 index 0000000000..b4531c8a76 --- /dev/null +++ b/tests/in/multiview.wgsl @@ -0,0 +1,2 @@ +@vertex +fn main(@builtin(view_index) view_index: i32) {} diff --git a/tests/in/multiview_webgl.param.ron b/tests/in/multiview_webgl.param.ron index 2a4720427b..720b51fbbc 100644 --- a/tests/in/multiview_webgl.param.ron +++ b/tests/in/multiview_webgl.param.ron @@ -1,10 +1,11 @@ ( - glsl: ( - version: Embedded( + glsl: ( + version: Embedded ( version: 300, - is_webgl: true - ), + is_webgl: true + ), writer_flags: (bits: 0), - binding_map: {}, - ), + binding_map: {}, + ), + glsl_multiview: Some(2), ) diff --git a/tests/in/multiview_webgl.wgsl b/tests/in/multiview_webgl.wgsl new file mode 100644 index 0000000000..b4531c8a76 --- /dev/null +++ b/tests/in/multiview_webgl.wgsl @@ -0,0 +1,2 @@ +@vertex +fn main(@builtin(view_index) view_index: i32) {} diff --git a/tests/in/spv/multiview.spv b/tests/in/spv/multiview.spv deleted file mode 100644 index 34159ea8d8c0cfa0995bd5a08c0b10f6c43069e7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 492 zcmY*VO-sW-5Pdcu)u^>ayjQ#z4=RG#TUo_G#Y*jMkz|pDG!&cq@%Q{yUIgDuJj8`z zcHX?1c{4%hqzh~z!9MoTya75y0Qsi@n2RyHpWC~e2fN%9m4EZ@o%vnj;+b@oj@DH^ zIy*mAhaLjCI(I-$$iHm)>`UPZtxt|H4(Bi6B;bq9Lh?;&CyU2_qlhQM&2(zgiOp6k zyRJS9XA56CoBLOnQI=Evc8llBtk~pjLPSPeON59OfL5};%-siw#I?qk!p;fbHYoR` zPHFGaOsz;a02aK_Ave$t$MrU-|3~D+#D+B8X~=~K61-U!h diff --git a/tests/in/spv/multiview_webgl.spv b/tests/in/spv/multiview_webgl.spv deleted file mode 100644 index 34159ea8d8c0cfa0995bd5a08c0b10f6c43069e7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 492 zcmY*VO-sW-5Pdcu)u^>ayjQ#z4=RG#TUo_G#Y*jMkz|pDG!&cq@%Q{yUIgDuJj8`z zcHX?1c{4%hqzh~z!9MoTya75y0Qsi@n2RyHpWC~e2fN%9m4EZ@o%vnj;+b@oj@DH^ zIy*mAhaLjCI(I-$$iHm)>`UPZtxt|H4(Bi6B;bq9Lh?;&CyU2_qlhQM&2(zgiOp6k zyRJS9XA56CoBLOnQI=Evc8llBtk~pjLPSPeON59OfL5};%-siw#I?qk!p;fbHYoR` zPHFGaOsz;a02aK_Ave$t$MrU-|3~D+#D+B8X~=~K61-U!h diff --git a/tests/out/glsl/multiview.main.Fragment.glsl b/tests/out/glsl/multiview.main.Fragment.glsl deleted file mode 100644 index b9dab683b8..0000000000 --- a/tests/out/glsl/multiview.main.Fragment.glsl +++ /dev/null @@ -1,22 +0,0 @@ -#version 310 es -#extension GL_EXT_multiview : require - -precision highp float; -precision highp int; - -int gen_gl_ViewIndex_1 = 0; - - -void main_1() { - int view_index = 0; - int _e6 = gen_gl_ViewIndex_1; - view_index = _e6; - return; -} - -void main() { - int gen_gl_ViewIndex = gl_ViewIndex; - gen_gl_ViewIndex_1 = gen_gl_ViewIndex; - main_1(); -} - diff --git a/tests/out/glsl/multiview.main.Vertex.glsl b/tests/out/glsl/multiview.main.Vertex.glsl new file mode 100644 index 0000000000..26b4166c79 --- /dev/null +++ b/tests/out/glsl/multiview.main.Vertex.glsl @@ -0,0 +1,15 @@ +#version 310 es +#extension GL_EXT_multiview : require + +precision highp float; +precision highp int; + +layout(num_views = 2) in; + + +void main() { + int view_index = gl_ViewIndex; + gl_Position.yz = vec2(-gl_Position.y, gl_Position.z * 2.0 - gl_Position.w); + return; +} + diff --git a/tests/out/glsl/multiview_webgl.main.Fragment.glsl b/tests/out/glsl/multiview_webgl.main.Fragment.glsl deleted file mode 100644 index bb4ec73ad9..0000000000 --- a/tests/out/glsl/multiview_webgl.main.Fragment.glsl +++ /dev/null @@ -1,22 +0,0 @@ -#version 300 es -#extension GL_OVR_multiview2 : require - -precision highp float; -precision highp int; - -int gen_gl_ViewIndex_1 = 0; - - -void main_1() { - int view_index = 0; - int _e6 = gen_gl_ViewIndex_1; - view_index = _e6; - return; -} - -void main() { - int gen_gl_ViewIndex = int(gl_ViewID_OVR); - gen_gl_ViewIndex_1 = gen_gl_ViewIndex; - main_1(); -} - diff --git a/tests/out/glsl/multiview_webgl.main.Vertex.glsl b/tests/out/glsl/multiview_webgl.main.Vertex.glsl new file mode 100644 index 0000000000..bb8b6e687d --- /dev/null +++ b/tests/out/glsl/multiview_webgl.main.Vertex.glsl @@ -0,0 +1,14 @@ +#version 300 es +#extension GL_OVR_multiview2 : require + +precision highp float; +precision highp int; + +layout(num_views = 2) in; + + +void main() { + int view_index = int(gl_ViewID_OVR); + return; +} + diff --git a/tests/out/spv/multiview.spvasm b/tests/out/spv/multiview.spvasm new file mode 100644 index 0000000000..bb67d7eba8 --- /dev/null +++ b/tests/out/spv/multiview.spvasm @@ -0,0 +1,23 @@ +; SPIR-V +; Version: 1.1 +; Generator: rspirv +; Bound: 11 +OpCapability Shader +OpCapability MultiView +OpExtension "SPV_KHR_multiview" +%1 = OpExtInstImport "GLSL.std.450" +OpMemoryModel Logical GLSL450 +OpEntryPoint Vertex %8 "main" %5 +OpDecorate %5 BuiltIn ViewIndex +%2 = OpTypeVoid +%3 = OpTypeInt 32 1 +%6 = OpTypePointer Input %3 +%5 = OpVariable %6 Input +%9 = OpTypeFunction %2 +%8 = OpFunction %2 None %9 +%4 = OpLabel +%7 = OpLoad %3 %5 +OpBranch %10 +%10 = OpLabel +OpReturn +OpFunctionEnd \ No newline at end of file diff --git a/tests/out/spv/multiview_webgl.spvasm b/tests/out/spv/multiview_webgl.spvasm new file mode 100644 index 0000000000..bb67d7eba8 --- /dev/null +++ b/tests/out/spv/multiview_webgl.spvasm @@ -0,0 +1,23 @@ +; SPIR-V +; Version: 1.1 +; Generator: rspirv +; Bound: 11 +OpCapability Shader +OpCapability MultiView +OpExtension "SPV_KHR_multiview" +%1 = OpExtInstImport "GLSL.std.450" +OpMemoryModel Logical GLSL450 +OpEntryPoint Vertex %8 "main" %5 +OpDecorate %5 BuiltIn ViewIndex +%2 = OpTypeVoid +%3 = OpTypeInt 32 1 +%6 = OpTypePointer Input %3 +%5 = OpVariable %6 Input +%9 = OpTypeFunction %2 +%8 = OpFunction %2 None %9 +%4 = OpLabel +%7 = OpLoad %3 %5 +OpBranch %10 +%10 = OpLabel +OpReturn +OpFunctionEnd \ No newline at end of file diff --git a/tests/out/wgsl/multiview.wgsl b/tests/out/wgsl/multiview.wgsl index 28063fa897..3ea9676b8c 100644 --- a/tests/out/wgsl/multiview.wgsl +++ b/tests/out/wgsl/multiview.wgsl @@ -1,15 +1,4 @@ -var gl_ViewIndex_1: i32; - -fn main_1() { - var view_index: i32; - - let _e6 = gl_ViewIndex_1; - view_index = _e6; +@vertex +fn main(@builtin(view_index) view_index: i32) { return; } - -@fragment -fn main(@builtin(view_index) gl_ViewIndex: i32) { - gl_ViewIndex_1 = gl_ViewIndex; - main_1(); -} diff --git a/tests/out/wgsl/multiview_webgl.wgsl b/tests/out/wgsl/multiview_webgl.wgsl new file mode 100644 index 0000000000..3ea9676b8c --- /dev/null +++ b/tests/out/wgsl/multiview_webgl.wgsl @@ -0,0 +1,4 @@ +@vertex +fn main(@builtin(view_index) view_index: i32) { + return; +} diff --git a/tests/snapshots.rs b/tests/snapshots.rs index 204d52690a..1ec43b9bd5 100644 --- a/tests/snapshots.rs +++ b/tests/snapshots.rs @@ -79,6 +79,9 @@ struct Parameters { hlsl: naga::back::hlsl::Options, #[serde(default)] wgsl: WgslOutParameters, + #[cfg(all(feature = "deserialize", feature = "glsl-out"))] + #[serde(default)] + glsl_multiview: Option, } #[allow(unused_variables)] @@ -162,6 +165,7 @@ fn check_targets(module: &naga::Module, name: &str, targets: Targets) { &ep.name, ¶ms.glsl, params.bounds_check_policies, + params.glsl_multiview, ); } } @@ -283,6 +287,7 @@ fn write_output_glsl( ep_name: &str, options: &naga::back::glsl::Options, bounds_check_policies: naga::proc::BoundsCheckPolicies, + multiview: Option, ) { use naga::back::glsl; @@ -291,7 +296,7 @@ fn write_output_glsl( let pipeline_options = glsl::PipelineOptions { shader_stage: stage, entry_point: ep_name.to_string(), - multiview: None, + multiview, }; let mut buffer = String::new(); @@ -532,6 +537,11 @@ fn convert_wgsl() { "binding-arrays", Targets::WGSL | Targets::HLSL | Targets::METAL | Targets::SPIRV, ), + ("multiview", Targets::SPIRV | Targets::GLSL | Targets::WGSL), + ( + "multiview_webgl", + Targets::SPIRV | Targets::GLSL | Targets::WGSL, + ), ]; for &(name, targets) in inputs.iter() { @@ -595,8 +605,6 @@ fn convert_spv_all() { Targets::HLSL | Targets::WGSL | Targets::METAL, ); convert_spv("degrees", false, Targets::empty()); - convert_spv("multiview", true, Targets::GLSL | Targets::WGSL); - convert_spv("multiview_webgl", true, Targets::GLSL); } #[cfg(feature = "glsl-in")] From fbd0cc9443f36d84b1bb2485921e5ee8a92f8b2e Mon Sep 17 00:00:00 2001 From: Ashley Ruglys Date: Tue, 21 Jun 2022 17:11:02 +0200 Subject: [PATCH 14/16] Rename Version::new_embedded to Version::new_gles, fix glsl validation --- benches/criterion.rs | 2 +- cli/src/main.rs | 2 +- src/back/glsl/features.rs | 4 ++-- src/back/glsl/mod.rs | 16 ++++++++-------- tests/out/glsl/multiview.main.Vertex.glsl | 2 -- 5 files changed, 12 insertions(+), 14 deletions(-) diff --git a/benches/criterion.rs b/benches/criterion.rs index 80fed4e798..ee8765b921 100644 --- a/benches/criterion.rs +++ b/benches/criterion.rs @@ -239,7 +239,7 @@ fn backends(c: &mut Criterion) { b.iter(|| { let mut string = String::new(); let options = naga::back::glsl::Options { - version: naga::back::glsl::Version::new_embedded(320), + version: naga::back::glsl::Version::new_gles(320), writer_flags: naga::back::glsl::WriterFlags::empty(), binding_map: Default::default(), }; diff --git a/cli/src/main.rs b/cli/src/main.rs index e2acb7e269..6b924e9951 100644 --- a/cli/src/main.rs +++ b/cli/src/main.rs @@ -133,7 +133,7 @@ impl FromStr for GlslProfileArg { Ok(Self(if s.starts_with("core") { Version::Desktop(s[4..].parse().unwrap_or(330)) } else if s.starts_with("es") { - Version::new_embedded(s[2..].parse().unwrap_or(310)) + Version::new_gles(s[2..].parse().unwrap_or(310)) } else { return Err(format!("Unknown profile: {}", s)); })) diff --git a/src/back/glsl/features.rs b/src/back/glsl/features.rs index 281d7167b3..b898b1d2b3 100644 --- a/src/back/glsl/features.rs +++ b/src/back/glsl/features.rs @@ -82,7 +82,7 @@ impl FeaturesManager { // Used when both core and es support the feature ($feature:ident, $core:literal, $es:literal) => { if self.0.contains(Features::$feature) - && (version < Version::Desktop($core) || version < Version::new_embedded($es)) + && (version < Version::Desktop($core) || version < Version::new_gles($es)) { missing |= Features::$feature; } @@ -224,7 +224,7 @@ impl FeaturesManager { } } - if self.0.contains(Features::FMA) && version >= Version::new_embedded(310) { + if self.0.contains(Features::FMA) && version >= Version::new_gles(310) { // https://www.khronos.org/registry/OpenGL/extensions/EXT/EXT_gpu_shader5.txt writeln!(out, "#extension GL_EXT_gpu_shader5 : require")?; } diff --git a/src/back/glsl/mod.rs b/src/back/glsl/mod.rs index 3191de1222..575fcac953 100644 --- a/src/back/glsl/mod.rs +++ b/src/back/glsl/mod.rs @@ -123,8 +123,8 @@ pub enum Version { } impl Version { - /// Create a new non-WebGL embedded version - pub const fn new_embedded(version: u16) -> Self { + /// Create a new gles version + pub const fn new_gles(version: u16) -> Self { Self::Embedded { version, is_webgl: false, @@ -167,19 +167,19 @@ impl Version { /// Note: `location=` for vertex inputs and fragment outputs is supported /// unconditionally for GLES 300. fn supports_explicit_locations(&self) -> bool { - *self >= Version::Desktop(410) || *self >= Version::new_embedded(310) + *self >= Version::Desktop(410) || *self >= Version::new_gles(310) } fn supports_early_depth_test(&self) -> bool { - *self >= Version::Desktop(130) || *self >= Version::new_embedded(310) + *self >= Version::Desktop(130) || *self >= Version::new_gles(310) } fn supports_std430_layout(&self) -> bool { - *self >= Version::Desktop(430) || *self >= Version::new_embedded(310) + *self >= Version::Desktop(430) || *self >= Version::new_gles(310) } fn supports_fma_function(&self) -> bool { - *self >= Version::Desktop(400) || *self >= Version::new_embedded(310) + *self >= Version::Desktop(400) || *self >= Version::new_gles(310) } } @@ -233,7 +233,7 @@ pub struct Options { impl Default for Options { fn default() -> Self { Options { - version: Version::new_embedded(310), + version: Version::new_gles(310), writer_flags: WriterFlags::ADJUST_COORDINATE_SPACE, binding_map: BindingMap::default(), } @@ -567,7 +567,7 @@ impl<'a, W: Write> Writer<'a, W> { } } - if self.entry_point.stage == ShaderStage::Vertex { + if self.entry_point.stage == ShaderStage::Vertex && self.options.version.is_webgl() { if let Some(multiview) = self.multiview.as_ref() { writeln!(self.out, "layout(num_views = {}) in;", multiview)?; writeln!(self.out)?; diff --git a/tests/out/glsl/multiview.main.Vertex.glsl b/tests/out/glsl/multiview.main.Vertex.glsl index 26b4166c79..a466f7df9e 100644 --- a/tests/out/glsl/multiview.main.Vertex.glsl +++ b/tests/out/glsl/multiview.main.Vertex.glsl @@ -4,8 +4,6 @@ precision highp float; precision highp int; -layout(num_views = 2) in; - void main() { int view_index = gl_ViewIndex; From 428a20646434f9b069fa639d42a2a2db9636d4fa Mon Sep 17 00:00:00 2001 From: Ashley Ruglys Date: Thu, 30 Jun 2022 18:40:14 +0200 Subject: [PATCH 15/16] Run cargo fmt --- tests/snapshots.rs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/tests/snapshots.rs b/tests/snapshots.rs index cef8129751..5859e2b1c5 100644 --- a/tests/snapshots.rs +++ b/tests/snapshots.rs @@ -538,10 +538,7 @@ fn convert_wgsl() { Targets::WGSL | Targets::HLSL | Targets::METAL | Targets::SPIRV, ), ("multiview", Targets::SPIRV | Targets::GLSL | Targets::WGSL), - ( - "multiview_webgl", - Targets::GLSL, - ), + ("multiview_webgl", Targets::GLSL), ( "break-if", Targets::WGSL | Targets::GLSL | Targets::SPIRV | Targets::HLSL | Targets::METAL, From a4e3c3809019b2868cd6afec3cb6421302294ac7 Mon Sep 17 00:00:00 2001 From: Ashley Ruglys Date: Thu, 30 Jun 2022 18:51:09 +0200 Subject: [PATCH 16/16] Fix brand new clippy warnings --- src/back/mod.rs | 2 +- src/valid/analyzer.rs | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/src/back/mod.rs b/src/back/mod.rs index 16b503cfb7..d8e016c008 100644 --- a/src/back/mod.rs +++ b/src/back/mod.rs @@ -59,7 +59,7 @@ struct FunctionCtx<'a> { named_expressions: &'a crate::NamedExpressions, } -impl<'a> FunctionCtx<'_> { +impl FunctionCtx<'_> { /// Helper method that generates a [`NameKey`](crate::proc::NameKey) for a local in the current function const fn name_key(&self, local: crate::Handle) -> crate::proc::NameKey { match self.ty { diff --git a/src/valid/analyzer.rs b/src/valid/analyzer.rs index 9a7130ff93..3f13aba323 100644 --- a/src/valid/analyzer.rs +++ b/src/valid/analyzer.rs @@ -484,7 +484,6 @@ impl FunctionInfo { return Err(ExpressionError::MissingCapabilities(needed_caps)); } - let _ = (); Uniformity { non_uniform_result: self .add_assignable_ref(base, &mut assignable_global)