From 60d0bf850b5bfeb87aeb5a0d4db6bb4059f80290 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Capucho?= Date: Sun, 19 Sep 2021 20:46:07 +0100 Subject: [PATCH] Add support for multi view extensions --- src/back/glsl/features.rs | 15 +++++++++++++++ src/back/glsl/mod.rs | 1 + src/back/hlsl/conv.rs | 3 +++ src/back/msl/mod.rs | 4 +++- src/back/spv/writer.rs | 27 +++++++++++++++++++++++++++ src/front/spv/convert.rs | 1 + src/front/spv/mod.rs | 1 + src/lib.rs | 1 + src/valid/interface.rs | 11 +++++++++++ 9 files changed, 63 insertions(+), 1 deletion(-) diff --git a/src/back/glsl/features.rs b/src/back/glsl/features.rs index 4253615868..d2e83e0040 100644 --- a/src/back/glsl/features.rs +++ b/src/back/glsl/features.rs @@ -34,6 +34,7 @@ bitflags::bitflags! { const SAMPLE_VARIABLES = 1 << 15; /// Arrays with a dynamic length const DYNAMIC_ARRAY_SIZE = 1 << 16; + const MULTI_VIEW = 1 << 17; } } @@ -101,6 +102,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); // Return an error if there are missing features if missing.is_empty() { @@ -194,6 +196,16 @@ impl FeaturesManager { writeln!(out, "#extension GL_OES_sample_variables : require")?; } + if self.0.contains(Features::SAMPLE_VARIABLES) && version.is_es() { + // https://www.khronos.org/registry/OpenGL/extensions/OES/OES_sample_variables.txt + writeln!(out, "#extension GL_OES_sample_variables : require")?; + } + + 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")?; + } + Ok(()) } } @@ -372,6 +384,9 @@ impl<'a, W> Writer<'a, W> { crate::BuiltIn::SampleIndex => { self.features.request(Features::SAMPLE_VARIABLES) } + crate::BuiltIn::ViewIndex => { + self.features.request(Features::MULTI_VIEW) + } _ => {} }, Binding::Location { diff --git a/src/back/glsl/mod.rs b/src/back/glsl/mod.rs index 62781147b5..bc46c3d0e2 100644 --- a/src/back/glsl/mod.rs +++ b/src/back/glsl/mod.rs @@ -2625,6 +2625,7 @@ fn glsl_built_in(built_in: crate::BuiltIn, output: bool) -> &'static str { "gl_FragCoord" } } + Bi::ViewIndex => "gl_ViewIndex", // vertex Bi::BaseInstance => "uint(gl_BaseInstance)", Bi::BaseVertex => "uint(gl_BaseVertex)", diff --git a/src/back/hlsl/conv.rs b/src/back/hlsl/conv.rs index b8cb10daa2..eb6515f9ce 100644 --- a/src/back/hlsl/conv.rs +++ b/src/back/hlsl/conv.rs @@ -103,6 +103,9 @@ impl crate::BuiltIn { Self::BaseInstance | Self::BaseVertex | Self::WorkGroupSize => { return Err(Error::Unimplemented(format!("builtin {:?}", self))) } + Self::ViewIndex => { + return Err(Error::Custom(format!("Unsupported builtin {:?}", self))) + } }) } } diff --git a/src/back/msl/mod.rs b/src/back/msl/mod.rs index 8e840da05f..de82096a49 100644 --- a/src/back/msl/mod.rs +++ b/src/back/msl/mod.rs @@ -358,7 +358,9 @@ impl ResolvedBinding { Bi::WorkGroupId => "threadgroup_position_in_grid", Bi::WorkGroupSize => "dispatch_threads_per_threadgroup", Bi::NumWorkGroups => "threadgroups_per_grid", - Bi::CullDistance => return Err(Error::UnsupportedBuiltIn(built_in)), + Bi::CullDistance | Bi::ViewIndex => { + return Err(Error::UnsupportedBuiltIn(built_in)) + } }; write!(out, "{}", name)?; } diff --git a/src/back/spv/writer.rs b/src/back/spv/writer.rs index 4b83ff96d4..c9d62f50b8 100644 --- a/src/back/spv/writer.rs +++ b/src/back/spv/writer.rs @@ -1159,6 +1159,10 @@ impl Writer { BuiltIn::FragCoord } } + Bi::ViewIndex => { + self.require_any("`view_index` built-in", &[spirv::Capability::MultiView])?; + BuiltIn::ViewIndex + } // vertex Bi::BaseInstance => BuiltIn::BaseInstance, Bi::BaseVertex => BuiltIn::BaseVertex, @@ -1284,6 +1288,19 @@ impl Writer { mod_info: &ModuleInfo, ep_index: Option, ) -> Result<(), Error> { + fn has_view_index_check( + ir_module: &crate::Module, + binding: Option<&crate::Binding>, + ty: Handle, + ) -> bool { + match ir_module.types[ty].inner { + crate::TypeInner::Struct { ref members, .. } => members.iter().any(|member| { + has_view_index_check(ir_module, member.binding.as_ref(), member.ty) + }), + _ => binding == Some(&crate::Binding::BuiltIn(crate::BuiltIn::ViewIndex)), + } + } + let has_storage_buffers = ir_module .global_variables @@ -1292,11 +1309,21 @@ impl Writer { crate::StorageClass::Storage { .. } => true, _ => false, }); + let has_view_index = ir_module + .entry_points + .iter() + .flat_map(|entry| entry.function.arguments.iter()) + .any(|arg| has_view_index_check(ir_module, arg.binding.as_ref(), arg.ty)); + if self.physical_layout.version < 0x10300 && has_storage_buffers { // enable the storage buffer class on < SPV-1.3 Instruction::extension("SPV_KHR_storage_buffer_storage_class") .to_words(&mut self.logical_layout.extensions); } + if has_view_index { + Instruction::extension("SPV_KHR_multiview") + .to_words(&mut self.logical_layout.extensions) + } Instruction::type_void(self.void_type).to_words(&mut self.logical_layout.declarations); Instruction::ext_inst_import(self.gl450_ext_inst_id, "GLSL.std.450") .to_words(&mut self.logical_layout.ext_inst_imports); diff --git a/src/front/spv/convert.rs b/src/front/spv/convert.rs index 569cb5865a..ce90551526 100644 --- a/src/front/spv/convert.rs +++ b/src/front/spv/convert.rs @@ -121,6 +121,7 @@ pub(super) fn map_builtin(word: spirv::Word) -> Result { use spirv::BuiltIn as Bi; Ok(match spirv::BuiltIn::from_u32(word) { Some(Bi::Position) | Some(Bi::FragCoord) => crate::BuiltIn::Position, + Some(Bi::ViewIndex) => crate::BuiltIn::ViewIndex, // vertex Some(Bi::BaseInstance) => crate::BuiltIn::BaseInstance, Some(Bi::BaseVertex) => crate::BuiltIn::BaseVertex, diff --git a/src/front/spv/mod.rs b/src/front/spv/mod.rs index cdb8e89d91..4869a47868 100644 --- a/src/front/spv/mod.rs +++ b/src/front/spv/mod.rs @@ -75,6 +75,7 @@ pub const SUPPORTED_CAPABILITIES: &[spirv::Capability] = &[ pub const SUPPORTED_EXTENSIONS: &[&str] = &[ "SPV_KHR_storage_buffer_storage_class", "SPV_KHR_vulkan_memory_model", + "SPV_KHR_multiview", ]; pub const SUPPORTED_EXT_SETS: &[&str] = &["GLSL.std.450"]; diff --git a/src/lib.rs b/src/lib.rs index 97af89d3fa..3c83254854 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -307,6 +307,7 @@ pub enum StorageClass { #[cfg_attr(feature = "deserialize", derive(Deserialize))] pub enum BuiltIn { Position, + ViewIndex, // vertex BaseInstance, BaseVertex, diff --git a/src/valid/interface.rs b/src/valid/interface.rs index dccd02bd62..9253042af8 100644 --- a/src/valid/interface.rs +++ b/src/valid/interface.rs @@ -158,6 +158,17 @@ impl VaryingContext<'_> { width, }, ), + Bi::ViewIndex => ( + match self.stage { + St::Vertex | St::Fragment => !self.output, + St::Compute => false, + }, + *ty_inner + == Ti::Scalar { + kind: Sk::Sint, + width, + }, + ), Bi::FragDepth => ( self.stage == St::Fragment && self.output, *ty_inner