Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Coherent storage #6277

Draft
wants to merge 2 commits into
base: trunk
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion naga/src/back/glsl/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1166,8 +1166,12 @@ impl<'a, W: Write> Writer<'a, W> {
}
}

if let crate::AddressSpace::Storage { access } = global.space {
if let crate::AddressSpace::Storage { access, coherent } = global.space {
self.write_storage_access(access)?;

if coherent {
write!(self.out, "coherent ")?;
}
}

if let Some(storage_qualifier) = glsl_storage_qualifier(global.space) {
Expand Down
2 changes: 1 addition & 1 deletion naga/src/back/hlsl/help.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1052,7 +1052,7 @@ impl<'a, W: Write> super::Writer<'a, W> {
}
};
let storage_access = match global_var.space {
crate::AddressSpace::Storage { access } => access,
crate::AddressSpace::Storage { access, .. } => access,
_ => crate::StorageAccess::default(),
};
let wal = WrappedArrayLength {
Expand Down
7 changes: 4 additions & 3 deletions naga/src/back/hlsl/writer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -829,13 +829,14 @@ impl<'a, W: fmt::Write> super::Writer<'a, W> {
write!(self.out, "cbuffer")?;
"b"
}
crate::AddressSpace::Storage { access } => {
crate::AddressSpace::Storage { access, coherent } => {
let globallycoherent = if coherent { "globallycoherent " } else { "" };
let (prefix, register) = if access.contains(crate::StorageAccess::STORE) {
("RW", "u")
} else {
("", "t")
};
write!(self.out, "{prefix}ByteAddressBuffer")?;
write!(self.out, "{globallycoherent}{prefix}ByteAddressBuffer")?;
register
}
crate::AddressSpace::Handle => {
Expand Down Expand Up @@ -3463,7 +3464,7 @@ impl<'a, W: fmt::Write> super::Writer<'a, W> {
};

let storage_access = match var.space {
crate::AddressSpace::Storage { access } => access,
crate::AddressSpace::Storage { access, .. } => access,
_ => crate::StorageAccess::default(),
};
let wrapped_array_length = WrappedArrayLength {
Expand Down
4 changes: 2 additions & 2 deletions naga/src/back/msl/writer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -307,7 +307,7 @@ impl<'a> TypedGlobalVariable<'a> {
let name = &self.names[&NameKey::GlobalVariable(self.handle)];

let storage_access = match var.space {
crate::AddressSpace::Storage { access } => access,
crate::AddressSpace::Storage { access, .. } => access,
_ => match self.module.types[var.ty].inner {
crate::TypeInner::Image {
class: crate::ImageClass::Storage { access, .. },
Expand Down Expand Up @@ -5138,7 +5138,7 @@ impl<W: Write> Writer<W> {
// supporting MSL 1.2.
//
// [what's new]: https://developer.apple.com/library/archive/documentation/Miscellaneous/Conceptual/MetalProgrammingGuide/WhatsNewiniOS10tvOS10andOSX1012/WhatsNewiniOS10tvOS10andOSX1012.html
crate::AddressSpace::Storage { access }
crate::AddressSpace::Storage { access, .. }
if access.contains(crate::StorageAccess::STORE)
&& ep.stage == crate::ShaderStage::Fragment =>
{
Expand Down
8 changes: 7 additions & 1 deletion naga/src/back/spv/writer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1688,7 +1688,13 @@ impl Writer {
}

let storage_access = match global_variable.space {
crate::AddressSpace::Storage { access } => Some(access),
crate::AddressSpace::Storage { access, coherent } => {
if coherent {
self.decorate(id, Decoration::Coherent, &[]);
}

Some(access)
}
_ => match ir_module.types[global_variable.ty].inner {
crate::TypeInner::Image {
class: crate::ImageClass::Storage { access, .. },
Expand Down
1 change: 1 addition & 0 deletions naga/src/front/glsl/parser/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,7 @@ impl<'source> ParsingContext<'source> {
TokenValue::Buffer => {
StorageQualifier::AddressSpace(AddressSpace::Storage {
access: crate::StorageAccess::all(),
coherent: false,
})
}
_ => unreachable!(),
Expand Down
2 changes: 1 addition & 1 deletion naga/src/front/glsl/variables.rs
Original file line number Diff line number Diff line change
Expand Up @@ -487,7 +487,7 @@ impl Frontend {
}
StorageQualifier::AddressSpace(mut space) => {
match space {
AddressSpace::Storage { ref mut access } => {
AddressSpace::Storage { ref mut access, .. } => {
if let Some((allowed_access, _)) = qualifiers.storage_access.take() {
*access = allowed_access;
}
Expand Down
1 change: 1 addition & 0 deletions naga/src/front/spv/convert.rs
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,7 @@ pub(super) fn map_storage_class(word: spirv::Word) -> Result<super::ExtendedClas
Some(Sc::StorageBuffer) => Ec::Global(crate::AddressSpace::Storage {
//Note: this is restricted by decorations later
access: crate::StorageAccess::all(),
coherent: false, // TODO?
}),
// we expect the `Storage` case to be filtered out before calling this function.
Some(Sc::Uniform) => Ec::Global(crate::AddressSpace::Uniform),
Expand Down
8 changes: 6 additions & 2 deletions naga/src/front/spv/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4825,6 +4825,7 @@ impl<I: Iterator<Item = u32>> Frontend<I> {
{
crate::AddressSpace::Storage {
access: crate::StorageAccess::default(),
coherent: false,
}
} else {
match map_storage_class(storage_class)? {
Expand Down Expand Up @@ -5489,13 +5490,16 @@ impl<I: Iterator<Item = u32>> Frontend<I> {
}

let ext_class = match self.lookup_storage_buffer_types.get(&ty) {
Some(&access) => ExtendedClass::Global(crate::AddressSpace::Storage { access }),
Some(&access) => ExtendedClass::Global(crate::AddressSpace::Storage {
access,
coherent: false,
}),
None => map_storage_class(storage_class)?,
};

let (inner, var) = match ext_class {
ExtendedClass::Global(mut space) => {
if let crate::AddressSpace::Storage { ref mut access } = space {
if let crate::AddressSpace::Storage { ref mut access, .. } = space {
*access &= dec.flags.to_storage_access();
}
let var = crate::GlobalVariable {
Expand Down
1 change: 1 addition & 0 deletions naga/src/front/wgsl/parse/conv.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ pub fn map_address_space(word: &str, span: Span) -> Result<crate::AddressSpace,
"uniform" => Ok(crate::AddressSpace::Uniform),
"storage" => Ok(crate::AddressSpace::Storage {
access: crate::StorageAccess::default(),
coherent: false,
}),
"push_constant" => Ok(crate::AddressSpace::PushConstant),
"function" => Ok(crate::AddressSpace::Function),
Expand Down
35 changes: 32 additions & 3 deletions naga/src/front/wgsl/parse/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use crate::front::wgsl::parse::lexer::{Lexer, Token};
use crate::front::wgsl::parse::number::Number;
use crate::front::wgsl::Scalar;
use crate::front::SymbolTable;
use crate::{Arena, FastIndexSet, Handle, ShaderStage, Span};
use crate::{Arena, FastIndexSet, Handle, ShaderStage, Span, StorageAccess};

pub mod ast;
pub mod conv;
Expand Down Expand Up @@ -985,7 +985,21 @@ impl Parser {
// defaulting to `read`
crate::StorageAccess::LOAD
};
crate::AddressSpace::Storage { access }

let coherent = if access.contains(StorageAccess::LOAD | StorageAccess::STORE)
&& lexer.skip(Token::Separator(','))
{
let (ident, span) = self.next_ident_with_span()?;
if ident == "coherent" {
Ok(true)
} else {
Err(Error::UnexpectedComponents(span)) // TODO
}
} else {
Ok(false)
}?;

crate::AddressSpace::Storage { access, coherent }
}
_ => conv::map_address_space(class_str, span)?,
};
Expand Down Expand Up @@ -1275,12 +1289,27 @@ impl Parser {
let mut space = conv::map_address_space(ident, span)?;
lexer.expect(Token::Separator(','))?;
let base = self.type_decl(lexer, ctx)?;
if let crate::AddressSpace::Storage { ref mut access } = space {
if let crate::AddressSpace::Storage {
ref mut access,
ref mut coherent,
} = space
{
*access = if lexer.skip(Token::Separator(',')) {
lexer.next_storage_access()?
} else {
crate::StorageAccess::LOAD
};

*coherent = if lexer.skip(Token::Separator(',')) {
let (ident, span) = self.next_ident_with_span()?;
if ident == "coherent" {
Ok(true)
} else {
Err(Error::UnexpectedComponents(span)) // TODO
}
} else {
Ok(false)
}?;
}
lexer.expect_generic_paren('>')?;
ast::Type::Pointer { base, space }
Expand Down
5 changes: 4 additions & 1 deletion naga/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -377,7 +377,10 @@ pub enum AddressSpace {
/// Uniform buffer data.
Uniform,
/// Storage buffer data, potentially mutable.
Storage { access: StorageAccess },
Storage {
access: StorageAccess,
coherent: bool,
},
/// Opaque handles, such as samplers and images.
Handle,
/// Push constants.
Expand Down
3 changes: 2 additions & 1 deletion wgpu-core/src/validation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -370,6 +370,7 @@ impl Resource {
naga_access.set(naga::StorageAccess::STORE, !read_only);
naga::AddressSpace::Storage {
access: naga_access,
coherent: false,
}
}
};
Expand Down Expand Up @@ -500,7 +501,7 @@ impl Resource {
ResourceType::Buffer { size } => BindingType::Buffer {
ty: match self.class {
naga::AddressSpace::Uniform => wgt::BufferBindingType::Uniform,
naga::AddressSpace::Storage { access } => wgt::BufferBindingType::Storage {
naga::AddressSpace::Storage { access, .. } => wgt::BufferBindingType::Storage {
read_only: access == naga::StorageAccess::LOAD,
},
_ => return Err(BindingError::WrongType),
Expand Down
2 changes: 1 addition & 1 deletion wgpu-hal/src/metal/device.rs
Original file line number Diff line number Diff line change
Expand Up @@ -229,7 +229,7 @@ impl super::Device {
None => continue,
};
let storage_access_store = match var.space {
naga::AddressSpace::Storage { access } => {
naga::AddressSpace::Storage { access, .. } => {
access.contains(naga::StorageAccess::STORE)
}
_ => false,
Expand Down
Loading