mirror of
https://github.com/gfx-rs/wgpu.git
synced 2026-04-22 03:02:01 -04:00
Add support for multi view extensions
This commit is contained in:
committed by
Dzmitry Malyshau
parent
cd65484a22
commit
60d0bf850b
@@ -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 {
|
||||
|
||||
@@ -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)",
|
||||
|
||||
@@ -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)))
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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)?;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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"];
|
||||
|
||||
|
||||
@@ -307,6 +307,7 @@ pub enum StorageClass {
|
||||
#[cfg_attr(feature = "deserialize", derive(Deserialize))]
|
||||
pub enum BuiltIn {
|
||||
Position,
|
||||
ViewIndex,
|
||||
// vertex
|
||||
BaseInstance,
|
||||
BaseVertex,
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user