Add support for multi view extensions

This commit is contained in:
João Capucho
2021-09-19 20:46:07 +01:00
committed by Dzmitry Malyshau
parent cd65484a22
commit 60d0bf850b
9 changed files with 63 additions and 1 deletions

View File

@@ -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 {

View File

@@ -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)",

View File

@@ -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)))
}
})
}
}

View File

@@ -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)?;
}

View File

@@ -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<usize>,
) -> Result<(), Error> {
fn has_view_index_check(
ir_module: &crate::Module,
binding: Option<&crate::Binding>,
ty: Handle<crate::Type>,
) -> 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);

View File

@@ -121,6 +121,7 @@ pub(super) fn map_builtin(word: spirv::Word) -> Result<crate::BuiltIn, Error> {
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,

View File

@@ -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"];

View File

@@ -307,6 +307,7 @@ pub enum StorageClass {
#[cfg_attr(feature = "deserialize", derive(Deserialize))]
pub enum BuiltIn {
Position,
ViewIndex,
// vertex
BaseInstance,
BaseVertex,

View File

@@ -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