Bug 1857243 - Update `wgpu` to revision 1495e159faf721cbf87a0634157682f454a963fb. r=webgpu-reviewers,supply-chain-reviewers,ErichDonGubler

Differential Revision: https://phabricator.services.mozilla.com/D190208
This commit is contained in:
Nicolas Silva 2023-10-05 20:22:27 +00:00
Родитель c04c99325f
Коммит faf195158d
66 изменённых файлов: 2027 добавлений и 263 удалений

Просмотреть файл

@ -30,14 +30,14 @@ git = "https://github.com/gfx-rs/metal-rs/"
rev = "d24f1a4"
replace-with = "vendored-sources"
[source."git+https://github.com/gfx-rs/naga?rev=df8107b7"]
[source."git+https://github.com/gfx-rs/naga?rev=6668d0694cc51ee66c71c2ca3a1ab1081956299b"]
git = "https://github.com/gfx-rs/naga"
rev = "df8107b7"
rev = "6668d0694cc51ee66c71c2ca3a1ab1081956299b"
replace-with = "vendored-sources"
[source."git+https://github.com/gfx-rs/wgpu?rev=9a76c483da4891fb7046c579e36d7c54bdb0b251"]
[source."git+https://github.com/gfx-rs/wgpu?rev=1495e159faf721cbf87a0634157682f454a963fb"]
git = "https://github.com/gfx-rs/wgpu"
rev = "9a76c483da4891fb7046c579e36d7c54bdb0b251"
rev = "1495e159faf721cbf87a0634157682f454a963fb"
replace-with = "vendored-sources"
[source."git+https://github.com/glandium/prost?rev=95964e9d33df3c2a9c3f14285e262867cab6f96b"]

8
Cargo.lock сгенерированный
Просмотреть файл

@ -3755,7 +3755,7 @@ checksum = "a2983372caf4480544083767bf2d27defafe32af49ab4df3a0b7fc90793a3664"
[[package]]
name = "naga"
version = "0.13.0"
source = "git+https://github.com/gfx-rs/naga?rev=df8107b7#df8107b78812cc2b1e3d5de35279cedc1f0da3fb"
source = "git+https://github.com/gfx-rs/naga?rev=6668d0694cc51ee66c71c2ca3a1ab1081956299b#6668d0694cc51ee66c71c2ca3a1ab1081956299b"
dependencies = [
"bit-set",
"bitflags 2.4.0",
@ -6339,7 +6339,7 @@ dependencies = [
[[package]]
name = "wgpu-core"
version = "0.17.0"
source = "git+https://github.com/gfx-rs/wgpu?rev=9a76c483da4891fb7046c579e36d7c54bdb0b251#9a76c483da4891fb7046c579e36d7c54bdb0b251"
source = "git+https://github.com/gfx-rs/wgpu?rev=1495e159faf721cbf87a0634157682f454a963fb#1495e159faf721cbf87a0634157682f454a963fb"
dependencies = [
"arrayvec",
"bit-vec",
@ -6362,7 +6362,7 @@ dependencies = [
[[package]]
name = "wgpu-hal"
version = "0.17.0"
source = "git+https://github.com/gfx-rs/wgpu?rev=9a76c483da4891fb7046c579e36d7c54bdb0b251#9a76c483da4891fb7046c579e36d7c54bdb0b251"
source = "git+https://github.com/gfx-rs/wgpu?rev=1495e159faf721cbf87a0634157682f454a963fb#1495e159faf721cbf87a0634157682f454a963fb"
dependencies = [
"android_system_properties",
"arrayvec",
@ -6398,7 +6398,7 @@ dependencies = [
[[package]]
name = "wgpu-types"
version = "0.17.0"
source = "git+https://github.com/gfx-rs/wgpu?rev=9a76c483da4891fb7046c579e36d7c54bdb0b251#9a76c483da4891fb7046c579e36d7c54bdb0b251"
source = "git+https://github.com/gfx-rs/wgpu?rev=1495e159faf721cbf87a0634157682f454a963fb#1495e159faf721cbf87a0634157682f454a963fb"
dependencies = [
"bitflags 2.4.0",
"js-sys",

Просмотреть файл

@ -17,7 +17,7 @@ default = []
[dependencies.wgc]
package = "wgpu-core"
git = "https://github.com/gfx-rs/wgpu"
rev = "9a76c483da4891fb7046c579e36d7c54bdb0b251"
rev = "1495e159faf721cbf87a0634157682f454a963fb"
#Note: "replay" shouldn't ideally be needed,
# but it allows us to serialize everything across IPC.
features = ["replay", "trace", "serial-pass", "strict_asserts", "wgsl"]
@ -27,32 +27,32 @@ features = ["replay", "trace", "serial-pass", "strict_asserts", "wgsl"]
[target.'cfg(any(target_os = "macos", target_os = "ios"))'.dependencies.wgc]
package = "wgpu-core"
git = "https://github.com/gfx-rs/wgpu"
rev = "9a76c483da4891fb7046c579e36d7c54bdb0b251"
rev = "1495e159faf721cbf87a0634157682f454a963fb"
features = ["metal"]
# We want the wgpu-core Direct3D backends on Windows.
[target.'cfg(windows)'.dependencies.wgc]
package = "wgpu-core"
git = "https://github.com/gfx-rs/wgpu"
rev = "9a76c483da4891fb7046c579e36d7c54bdb0b251"
rev = "1495e159faf721cbf87a0634157682f454a963fb"
features = ["dx11", "dx12"]
# We want the wgpu-core Vulkan backend on Linux and Windows.
[target.'cfg(any(windows, all(unix, not(any(target_os = "macos", target_os = "ios")))))'.dependencies.wgc]
package = "wgpu-core"
git = "https://github.com/gfx-rs/wgpu"
rev = "9a76c483da4891fb7046c579e36d7c54bdb0b251"
rev = "1495e159faf721cbf87a0634157682f454a963fb"
features = ["vulkan"]
[dependencies.wgt]
package = "wgpu-types"
git = "https://github.com/gfx-rs/wgpu"
rev = "9a76c483da4891fb7046c579e36d7c54bdb0b251"
rev = "1495e159faf721cbf87a0634157682f454a963fb"
[dependencies.wgh]
package = "wgpu-hal"
git = "https://github.com/gfx-rs/wgpu"
rev = "9a76c483da4891fb7046c579e36d7c54bdb0b251"
rev = "1495e159faf721cbf87a0634157682f454a963fb"
[target.'cfg(windows)'.dependencies]
d3d12 = "0.7.0"

Просмотреть файл

@ -20,11 +20,11 @@ origin:
# Human-readable identifier for this version/release
# Generally "version NNN", "tag SSS", "bookmark SSS"
release: commit 9a76c483da4891fb7046c579e36d7c54bdb0b251
release: commit 1495e159faf721cbf87a0634157682f454a963fb
# Revision to pull in
# Must be a long or short commit SHA (long preferred)
revision: 9a76c483da4891fb7046c579e36d7c54bdb0b251
revision: 1495e159faf721cbf87a0634157682f454a963fb
license: ['MIT', 'Apache-2.0']

Просмотреть файл

@ -436,7 +436,7 @@ mod foreign {
impl HasErrorBufferType for DeviceError {
fn error_type(&self) -> ErrorBufferType {
match self {
DeviceError::Invalid => ErrorBufferType::Validation,
DeviceError::Invalid | DeviceError::WrongDevice => ErrorBufferType::Validation,
DeviceError::Lost => ErrorBufferType::None,
DeviceError::OutOfMemory => ErrorBufferType::OutOfMemory,
DeviceError::ResourceCreationFailed => ErrorBufferType::Internal,

Просмотреть файл

@ -2344,6 +2344,11 @@ who = "Nicolas Silva <nical@fastmail.com>"
criteria = "safe-to-deploy"
delta = "0.13.0@git:cc87b8f9eb30bb55d0735b89d3df3e099e1a6e7c -> 0.13.0@git:df8107b78812cc2b1e3d5de35279cedc1f0da3fb"
[[audits.naga]]
who = "Nicolas Silva <nical@fastmail.com>"
criteria = "safe-to-deploy"
delta = "0.13.0@git:df8107b78812cc2b1e3d5de35279cedc1f0da3fb -> 0.13.0@git:6668d0694cc51ee66c71c2ca3a1ab1081956299b"
[[audits.net2]]
who = "Mike Hommey <mh+mozilla@glandium.org>"
criteria = "safe-to-run"
@ -4073,6 +4078,11 @@ who = "Nicolas Silva <nical@fastmail.com>"
criteria = "safe-to-deploy"
delta = "0.17.0@git:7fea9e934efd8d5dc03b9aa3e06b775c1ac4a23e -> 0.17.0@git:7e0d6c971f900f6a8f01a9de9c41f7894164a82c"
[[audits.wgpu-core]]
who = "Nicolas Silva <nical@fastmail.com>"
criteria = "safe-to-deploy"
delta = "0.17.0@git:9a76c483da4891fb7046c579e36d7c54bdb0b251 -> 0.17.0@git:1495e159faf721cbf87a0634157682f454a963fb"
[[audits.wgpu-hal]]
who = "Dzmitry Malyshau <kvark@fastmail.com>"
criteria = "safe-to-deploy"
@ -4196,6 +4206,11 @@ who = "Nicolas Silva <nical@fastmail.com>"
criteria = "safe-to-deploy"
delta = "0.17.0@git:7fea9e934efd8d5dc03b9aa3e06b775c1ac4a23e -> 0.17.0@git:7e0d6c971f900f6a8f01a9de9c41f7894164a82c"
[[audits.wgpu-hal]]
who = "Nicolas Silva <nical@fastmail.com>"
criteria = "safe-to-deploy"
delta = "0.17.0@git:9a76c483da4891fb7046c579e36d7c54bdb0b251 -> 0.17.0@git:1495e159faf721cbf87a0634157682f454a963fb"
[[audits.wgpu-types]]
who = "Dzmitry Malyshau <kvark@fastmail.com>"
criteria = "safe-to-deploy"
@ -4319,6 +4334,11 @@ who = "Nicolas Silva <nical@fastmail.com>"
criteria = "safe-to-deploy"
delta = "0.17.0@git:7fea9e934efd8d5dc03b9aa3e06b775c1ac4a23e -> 0.17.0@git:7e0d6c971f900f6a8f01a9de9c41f7894164a82c"
[[audits.wgpu-types]]
who = "Nicolas Silva <nical@fastmail.com>"
criteria = "safe-to-deploy"
delta = "0.17.0@git:9a76c483da4891fb7046c579e36d7c54bdb0b251 -> 0.17.0@git:1495e159faf721cbf87a0634157682f454a963fb"
[[audits.whatsys]]
who = "Bobby Holley <bobbyholley@gmail.com>"
criteria = "safe-to-deploy"

2
third_party/rust/naga/.cargo-checksum.json поставляемый

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

1
third_party/rust/naga/Cargo.toml поставляемый
Просмотреть файл

@ -130,6 +130,7 @@ arbitrary = [
"indexmap/arbitrary",
]
clone = []
compact = []
default = []
deserialize = [
"serde",

81
third_party/rust/naga/src/arena.rs поставляемый
Просмотреть файл

@ -5,8 +5,7 @@ use std::{cmp::Ordering, fmt, hash, marker::PhantomData, num::NonZeroU32, ops};
/// the same size and representation as `Handle<T>`.
type Index = NonZeroU32;
use crate::Span;
use indexmap::set::IndexSet;
use crate::{FastIndexSet, Span};
#[derive(Clone, Copy, Debug, thiserror::Error, PartialEq)]
#[error("Handle {index} of {kind} is either not present, or inaccessible yet")]
@ -192,12 +191,31 @@ impl<T> Iterator for Range<T> {
}
impl<T> Range<T> {
/// Return a range enclosing handles `first` through `last`, inclusive.
pub fn new_from_bounds(first: Handle<T>, last: Handle<T>) -> Self {
Self {
inner: (first.index() as u32)..(last.index() as u32 + 1),
marker: Default::default(),
}
}
/// Return the first and last handles included in `self`.
///
/// If `self` is an empty range, there are no handles included, so
/// return `None`.
pub fn first_and_last(&self) -> Option<(Handle<T>, Handle<T>)> {
if self.inner.start < self.inner.end {
Some((
// `Range::new_from_bounds` expects a 1-based, start- and
// end-inclusive range, but `self.inner` is a zero-based,
// end-exclusive range.
Handle::new(Index::new(self.inner.start + 1).unwrap()),
Handle::new(Index::new(self.inner.end).unwrap()),
))
} else {
None
}
}
}
/// An arena holding some kind of component (e.g., type, constant,
@ -382,6 +400,19 @@ impl<T> Arena<T> {
Ok(())
}
}
#[cfg(feature = "compact")]
pub(crate) fn retain_mut<P>(&mut self, mut predicate: P)
where
P: FnMut(Handle<T>, &mut T) -> bool,
{
let mut index = 0;
self.data.retain_mut(|elt| {
index += 1;
let handle = Handle::new(Index::new(index).unwrap());
predicate(handle, elt)
})
}
}
#[cfg(feature = "deserialize")]
@ -484,11 +515,11 @@ mod tests {
/// `UniqueArena` is `HashSet`-like.
#[cfg_attr(feature = "clone", derive(Clone))]
pub struct UniqueArena<T> {
set: IndexSet<T>,
set: FastIndexSet<T>,
/// Spans for the elements, indexed by handle.
///
/// The length of this vector is always equal to `set.len()`. `IndexSet`
/// The length of this vector is always equal to `set.len()`. `FastIndexSet`
/// promises that its elements "are indexed in a compact range, without
/// holes in the range 0..set.len()", so we can always use the indices
/// returned by insertion as indices into this vector.
@ -500,7 +531,7 @@ impl<T> UniqueArena<T> {
/// Create a new arena with no initial capacity allocated.
pub fn new() -> Self {
UniqueArena {
set: IndexSet::new(),
set: FastIndexSet::default(),
#[cfg(feature = "span")]
span_info: Vec::new(),
}
@ -544,6 +575,44 @@ impl<T> UniqueArena<T> {
Span::default()
}
}
#[cfg(feature = "compact")]
pub(crate) fn drain_all(&mut self) -> UniqueArenaDrain<T> {
UniqueArenaDrain {
inner_elts: self.set.drain(..),
#[cfg(feature = "span")]
inner_spans: self.span_info.drain(..),
index: Index::new(1).unwrap(),
}
}
}
#[cfg(feature = "compact")]
pub(crate) struct UniqueArenaDrain<'a, T> {
inner_elts: indexmap::set::Drain<'a, T>,
#[cfg(feature = "span")]
inner_spans: std::vec::Drain<'a, Span>,
index: Index,
}
#[cfg(feature = "compact")]
impl<'a, T> Iterator for UniqueArenaDrain<'a, T> {
type Item = (Handle<T>, T, Span);
fn next(&mut self) -> Option<Self::Item> {
match self.inner_elts.next() {
Some(elt) => {
let handle = Handle::new(self.index);
self.index = self.index.checked_add(1).unwrap();
#[cfg(feature = "span")]
let span = self.inner_spans.next().unwrap();
#[cfg(not(feature = "span"))]
let span = Span::default();
Some((handle, elt, span))
}
None => None,
}
}
}
impl<T: Eq + hash::Hash> UniqueArena<T> {
@ -671,7 +740,7 @@ where
where
D: serde::Deserializer<'de>,
{
let set = IndexSet::deserialize(deserializer)?;
let set = FastIndexSet::deserialize(deserializer)?;
#[cfg(feature = "span")]
let span_info = std::iter::repeat(Span::default()).take(set.len()).collect();

2
third_party/rust/naga/src/back/dot/mod.rs поставляемый
Просмотреть файл

@ -18,7 +18,7 @@ use std::{
};
/// Configuration options for the dot backend
#[derive(Default)]
#[derive(Clone, Default)]
pub struct Options {
/// Only emit function bodies
pub cfg_only: bool,

Просмотреть файл

@ -209,11 +209,6 @@ 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) {
if let Version::Embedded { is_webgl: true, .. } = version {
// https://www.khronos.org/registry/OpenGL/extensions/OVR/OVR_multiview2.txt
@ -362,6 +357,7 @@ impl<'a, W> Writer<'a, W> {
| StorageFormat::Rg16Uint
| StorageFormat::Rg16Sint
| StorageFormat::Rg16Float
| StorageFormat::Rgb10a2Uint
| StorageFormat::Rgb10a2Unorm
| StorageFormat::Rg11b10Float
| StorageFormat::Rg32Uint

34
third_party/rust/naga/src/back/glsl/mod.rs поставляемый
Просмотреть файл

@ -189,6 +189,10 @@ impl Version {
*self >= Version::Desktop(400) || *self >= Version::new_gles(310)
}
fn supports_frexp_function(&self) -> bool {
*self >= Version::Desktop(400) || *self >= Version::new_gles(310)
}
fn supports_derivative_control(&self) -> bool {
*self >= Version::Desktop(450)
}
@ -667,15 +671,27 @@ impl<'a, W: Write> Writer<'a, W> {
let struct_name = &self.names[&NameKey::Type(*struct_ty)];
writeln!(self.out)?;
writeln!(
self.out,
"{} {defined_func_name}({arg_type_name} arg) {{
if !self.options.version.supports_frexp_function()
&& matches!(type_key, &crate::PredeclaredType::FrexpResult { .. })
{
writeln!(
self.out,
"{struct_name} {defined_func_name}({arg_type_name} arg) {{
{other_type_name} other = arg == {arg_type_name}(0) ? {other_type_name}(0) : {other_type_name}({arg_type_name}(1) + log2(arg));
{arg_type_name} fract = arg * exp2({arg_type_name}(-other));
return {struct_name}(fract, other);
}}",
)?;
} else {
writeln!(
self.out,
"{struct_name} {defined_func_name}({arg_type_name} arg) {{
{other_type_name} other;
{arg_type_name} fract = {called_func_name}(arg, other);
return {}(fract, other);
return {struct_name}(fract, other);
}}",
struct_name, struct_name
)?;
)?;
}
}
&crate::PredeclaredType::AtomicCompareExchangeWeakResult { .. } => {}
}
@ -1113,7 +1129,8 @@ impl<'a, W: Write> Writer<'a, W> {
let ty_name = &self.names[&NameKey::Type(global.ty)];
let block_name = format!(
"{}_block_{}{:?}",
ty_name,
// avoid double underscores as they are reserved in GLSL
ty_name.trim_end_matches('_'),
self.block_id.generate(),
self.entry_point.stage,
);
@ -4221,7 +4238,8 @@ const fn glsl_storage_format(format: crate::StorageFormat) -> &'static str {
Sf::Rgba8Snorm => "rgba8_snorm",
Sf::Rgba8Uint => "rgba8ui",
Sf::Rgba8Sint => "rgba8i",
Sf::Rgb10a2Unorm => "rgb10_a2ui",
Sf::Rgb10a2Uint => "rgb10_a2ui",
Sf::Rgb10a2Unorm => "rgb10_a2",
Sf::Rg11b10Float => "r11f_g11f_b10f",
Sf::Rg32Uint => "rg32ui",
Sf::Rg32Sint => "rg32i",

3
third_party/rust/naga/src/back/hlsl/conv.rs поставляемый
Просмотреть файл

@ -129,7 +129,8 @@ impl crate::StorageFormat {
| Self::Rgba16Uint
| Self::R32Uint
| Self::Rg32Uint
| Self::Rgba32Uint => "uint4",
| Self::Rgba32Uint
| Self::Rgb10a2Uint => "uint4",
Self::Rgba8Sint
| Self::Rgba16Sint
| Self::R32Sint

Просмотреть файл

@ -2352,12 +2352,7 @@ impl<'a, W: fmt::Write> super::Writer<'a, W> {
}
}
Expression::FunctionArgument(pos) => {
let key = match func_ctx.ty {
back::FunctionType::Function(handle) => NameKey::FunctionArgument(handle, pos),
back::FunctionType::EntryPoint(index) => {
NameKey::EntryPointArgument(index, pos)
}
};
let key = func_ctx.argument_key(pos);
let name = &self.names[&key];
write!(self.out, "{name}")?;
}

23
third_party/rust/naga/src/back/mod.rs поставляемый
Просмотреть файл

@ -37,13 +37,28 @@ impl std::fmt::Display for Level {
}
}
/// Stores the current function type (either a regular function or an entry point)
/// Whether we're generating an entry point or a regular function.
///
/// Also stores data needed to identify it (handle for a regular function or index for an entry point)
/// Backend languages often require different code for a [`Function`]
/// depending on whether it represents an [`EntryPoint`] or not.
/// Backends can pass common code one of these values to select the
/// right behavior.
///
/// These values also carry enough information to find the `Function`
/// in the [`Module`]: the `Handle` for a regular function, or the
/// index into [`Module::entry_points`] for an entry point.
///
/// [`Function`]: crate::Function
/// [`EntryPoint`]: crate::EntryPoint
/// [`Module`]: crate::Module
/// [`Module::entry_points`]: crate::Module::entry_points
enum FunctionType {
/// A regular function and it's handle
/// A regular function.
Function(crate::Handle<crate::Function>),
/// A entry point and it's index
/// An [`EntryPoint`], and its index in [`Module::entry_points`].
///
/// [`EntryPoint`]: crate::EntryPoint
/// [`Module::entry_points`]: crate::Module::entry_points
EntryPoint(crate::proc::EntryPointIndex),
}

51
third_party/rust/naga/src/back/msl/writer.rs поставляемый
Просмотреть файл

@ -3689,6 +3689,15 @@ impl<W: Write> Writer<W> {
}
};
// Since `Namer.reset` wasn't expecting struct members to be
// suddenly injected into another namespace like this,
// `self.names` doesn't keep them distinct from other variables.
// Generate fresh names for these arguments, and remember the
// mapping.
let mut flattened_member_names = FastHashMap::default();
// Varyings' members get their own namespace
let mut varyings_namer = crate::proc::Namer::default();
// List all the Naga `EntryPoint`'s `Function`'s arguments,
// flattening structs into their members. In Metal, we will pass
// each of these values to the entry point as a separate argument—
@ -3704,6 +3713,14 @@ impl<W: Write> Writer<W> {
member.ty,
member.binding.as_ref(),
));
let name_key = NameKey::StructMember(arg.ty, member_index);
let name = match member.binding {
Some(crate::Binding::Location { .. }) => {
varyings_namer.call(&self.names[&name_key])
}
_ => self.namer.call(&self.names[&name_key]),
};
flattened_member_names.insert(name_key, name);
}
}
_ => flattened_arguments.push((
@ -3727,7 +3744,10 @@ impl<W: Write> Writer<W> {
_ => continue,
};
has_varyings = true;
let name = &self.names[name_key];
let name = match *name_key {
NameKey::StructMember(..) => &flattened_member_names[name_key],
_ => &self.names[name_key],
};
let ty_name = TypeContext {
handle: ty,
gctx: module.to_ctx(),
@ -3840,27 +3860,14 @@ impl<W: Write> Writer<W> {
// Then pass the remaining arguments not included in the varyings
// struct.
//
// Since `Namer.reset` wasn't expecting struct members to be
// suddenly injected into the normal namespace like this,
// `self.names` doesn't keep them distinct from other variables.
// Generate fresh names for these arguments, and remember the
// mapping.
let mut flattened_member_names = FastHashMap::default();
for &(ref name_key, ty, binding) in flattened_arguments.iter() {
let binding = match binding {
Some(binding @ &crate::Binding::BuiltIn { .. }) => binding,
_ => continue,
};
let name = if let NameKey::StructMember(ty, index) = *name_key {
// We should always insert a fresh entry here, but use
// `or_insert` to get a reference to the `String` we just
// inserted.
flattened_member_names
.entry(NameKey::StructMember(ty, index))
.or_insert_with(|| self.namer.call(&self.names[name_key]))
} else {
&self.names[name_key]
let name = match *name_key {
NameKey::StructMember(..) => &flattened_member_names[name_key],
_ => &self.names[name_key],
};
if binding == &crate::Binding::BuiltIn(crate::BuiltIn::LocalInvocationId) {
@ -4057,15 +4064,7 @@ impl<W: Write> Writer<W> {
)?;
for (member_index, member) in members.iter().enumerate() {
let key = NameKey::StructMember(arg.ty, member_index as u32);
// If it's not in the varying struct, then we should
// have passed it as its own argument and assigned
// it a new name.
let name = match member.binding {
Some(crate::Binding::BuiltIn { .. }) => {
&flattened_member_names[&key]
}
_ => &self.names[&key],
};
let name = &flattened_member_names[&key];
if member_index != 0 {
write!(self.out, ", ")?;
}

Просмотреть файл

@ -1064,7 +1064,8 @@ impl From<crate::StorageFormat> for spirv::ImageFormat {
Sf::Rgba8Snorm => Self::Rgba8Snorm,
Sf::Rgba8Uint => Self::Rgba8ui,
Sf::Rgba8Sint => Self::Rgba8i,
Sf::Rgb10a2Unorm => Self::Rgb10a2ui,
Sf::Rgb10a2Uint => Self::Rgb10a2ui,
Sf::Rgb10a2Unorm => Self::Rgb10A2,
Sf::Rg11b10Float => Self::R11fG11fB10f,
Sf::Rg32Uint => Self::Rg32ui,
Sf::Rg32Sint => Self::Rg32i,

2
third_party/rust/naga/src/back/spv/mod.rs поставляемый
Просмотреть файл

@ -85,7 +85,7 @@ impl IdGenerator {
#[derive(Debug, Clone)]
pub struct DebugInfo<'a> {
pub source_code: &'a str,
pub file_name: &'a str,
pub file_name: &'a std::path::Path,
}
/// A SPIR-V block to which we are still adding instructions.

22
third_party/rust/naga/src/back/spv/writer.rs поставляемый
Просмотреть файл

@ -1514,8 +1514,20 @@ impl Writer {
// vertex
Bi::BaseInstance => BuiltIn::BaseInstance,
Bi::BaseVertex => BuiltIn::BaseVertex,
Bi::ClipDistance => BuiltIn::ClipDistance,
Bi::CullDistance => BuiltIn::CullDistance,
Bi::ClipDistance => {
self.require_any(
"`clip_distance` built-in",
&[spirv::Capability::ClipDistance],
)?;
BuiltIn::ClipDistance
}
Bi::CullDistance => {
self.require_any(
"`cull_distance` built-in",
&[spirv::Capability::CullDistance],
)?;
BuiltIn::CullDistance
}
Bi::InstanceIndex => BuiltIn::InstanceIndex,
Bi::PointSize => BuiltIn::PointSize,
Bi::VertexIndex => BuiltIn::VertexIndex,
@ -1840,8 +1852,10 @@ impl Writer {
if self.flags.contains(WriterFlags::DEBUG) {
if let Some(debug_info) = debug_info.as_ref() {
let source_file_id = self.id_gen.next();
self.debugs
.push(Instruction::string(debug_info.file_name, source_file_id));
self.debugs.push(Instruction::string(
&debug_info.file_name.display().to_string(),
source_file_id,
));
debug_info_inner = Some(DebugInfoInner {
source_code: debug_info.source_code,

10
third_party/rust/naga/src/back/wgsl/writer.rs поставляемый
Просмотреть файл

@ -247,14 +247,7 @@ impl<W: Write> Writer<W> {
self.write_attributes(&map_binding_to_attribute(binding))?;
}
// Write argument name
let argument_name = match func_ctx.ty {
back::FunctionType::Function(handle) => {
&self.names[&NameKey::FunctionArgument(handle, index as u32)]
}
back::FunctionType::EntryPoint(ep_index) => {
&self.names[&NameKey::EntryPointArgument(ep_index, index as u32)]
}
};
let argument_name = &self.names[&func_ctx.argument_key(index as u32)];
write!(self.out, "{argument_name}: ")?;
// Write argument type
@ -1837,6 +1830,7 @@ const fn storage_format_str(format: crate::StorageFormat) -> &'static str {
Sf::Rgba8Snorm => "rgba8snorm",
Sf::Rgba8Uint => "rgba8uint",
Sf::Rgba8Sint => "rgba8sint",
Sf::Rgb10a2Uint => "rgb10a2uint",
Sf::Rgb10a2Unorm => "rgb10a2unorm",
Sf::Rg11b10Float => "rg11b10float",
Sf::Rg32Uint => "rg32uint",

395
third_party/rust/naga/src/compact/expressions.rs поставляемый Normal file
Просмотреть файл

@ -0,0 +1,395 @@
use super::{HandleMap, HandleSet, ModuleMap};
use crate::arena::{Arena, Handle, UniqueArena};
pub struct ExpressionTracer<'tracer> {
pub types: &'tracer UniqueArena<crate::Type>,
pub constants: &'tracer Arena<crate::Constant>,
/// The arena in which we are currently tracing expressions.
pub expressions: &'tracer Arena<crate::Expression>,
/// The used map for `types`.
pub types_used: &'tracer mut HandleSet<crate::Type>,
/// The used map for `constants`.
pub constants_used: &'tracer mut HandleSet<crate::Constant>,
/// The used set for `arena`.
///
/// This points to whatever arena holds the expressions we are
/// currently tracing: either a function's expression arena, or
/// the module's constant expression arena.
pub expressions_used: &'tracer mut HandleSet<crate::Expression>,
/// The constant expression arena and its used map, if we haven't
/// switched to tracing constant expressions yet.
pub const_expressions: Option<(
&'tracer Arena<crate::Expression>,
&'tracer mut HandleSet<crate::Expression>,
)>,
}
impl<'tracer> ExpressionTracer<'tracer> {
pub fn trace_expression(&mut self, expr: Handle<crate::Expression>) {
log::trace!(
"entering trace_expression of {}",
if self.const_expressions.is_some() {
"function expressions"
} else {
"const expressions"
}
);
let mut work_list = vec![expr];
while let Some(expr) = work_list.pop() {
// If we've already seen this expression, no need to trace further.
if !self.expressions_used.insert(expr) {
continue;
}
log::trace!("tracing new expression {:?}", expr);
use crate::Expression as Ex;
match self.expressions[expr] {
// Expressions that do not contain handles that need to be traced.
Ex::Literal(_)
| Ex::FunctionArgument(_)
| Ex::GlobalVariable(_)
| Ex::LocalVariable(_)
| Ex::CallResult(_)
| Ex::RayQueryProceedResult => {}
Ex::Constant(handle) => {
self.constants_used.insert(handle);
let constant = &self.constants[handle];
self.trace_type(constant.ty);
self.trace_const_expression(constant.init);
}
Ex::ZeroValue(ty) => self.trace_type(ty),
Ex::Compose { ty, ref components } => {
self.trace_type(ty);
work_list.extend(components);
}
Ex::Access { base, index } => work_list.extend([base, index]),
Ex::AccessIndex { base, index: _ } => work_list.push(base),
Ex::Splat { size: _, value } => work_list.push(value),
Ex::Swizzle {
size: _,
vector,
pattern: _,
} => work_list.push(vector),
Ex::Load { pointer } => work_list.push(pointer),
Ex::ImageSample {
image,
sampler,
gather: _,
coordinate,
array_index,
offset,
ref level,
depth_ref,
} => {
work_list.push(image);
work_list.push(sampler);
work_list.push(coordinate);
work_list.extend(array_index);
if let Some(offset) = offset {
self.trace_const_expression(offset);
}
use crate::SampleLevel as Sl;
match *level {
Sl::Auto | Sl::Zero => {}
Sl::Exact(expr) | Sl::Bias(expr) => work_list.push(expr),
Sl::Gradient { x, y } => work_list.extend([x, y]),
}
work_list.extend(depth_ref);
}
Ex::ImageLoad {
image,
coordinate,
array_index,
sample,
level,
} => {
work_list.push(image);
work_list.push(coordinate);
work_list.extend(array_index);
work_list.extend(sample);
work_list.extend(level);
}
Ex::ImageQuery { image, ref query } => {
work_list.push(image);
use crate::ImageQuery as Iq;
match *query {
Iq::Size { level } => work_list.extend(level),
Iq::NumLevels | Iq::NumLayers | Iq::NumSamples => {}
}
}
Ex::Unary { op: _, expr } => work_list.push(expr),
Ex::Binary { op: _, left, right } => work_list.extend([left, right]),
Ex::Select {
condition,
accept,
reject,
} => work_list.extend([condition, accept, reject]),
Ex::Derivative {
axis: _,
ctrl: _,
expr,
} => work_list.push(expr),
Ex::Relational { fun: _, argument } => work_list.push(argument),
Ex::Math {
fun: _,
arg,
arg1,
arg2,
arg3,
} => {
work_list.push(arg);
work_list.extend(arg1);
work_list.extend(arg2);
work_list.extend(arg3);
}
Ex::As {
expr,
kind: _,
convert: _,
} => work_list.push(expr),
Ex::AtomicResult { ty, comparison: _ } => self.trace_type(ty),
Ex::WorkGroupUniformLoadResult { ty } => self.trace_type(ty),
Ex::ArrayLength(expr) => work_list.push(expr),
Ex::RayQueryGetIntersection {
query,
committed: _,
} => work_list.push(query),
}
}
}
fn trace_type(&mut self, ty: Handle<crate::Type>) {
let mut types_used = super::types::TypeTracer {
types: self.types,
types_used: self.types_used,
};
types_used.trace_type(ty);
}
pub fn as_const_expression(&mut self) -> ExpressionTracer {
match self.const_expressions {
Some((ref mut exprs, ref mut exprs_used)) => ExpressionTracer {
expressions: exprs,
expressions_used: exprs_used,
types: self.types,
constants: self.constants,
types_used: self.types_used,
constants_used: self.constants_used,
const_expressions: None,
},
None => ExpressionTracer {
types: self.types,
constants: self.constants,
expressions: self.expressions,
types_used: self.types_used,
constants_used: self.constants_used,
expressions_used: self.expressions_used,
const_expressions: None,
},
}
}
fn trace_const_expression(&mut self, const_expr: Handle<crate::Expression>) {
self.as_const_expression().trace_expression(const_expr);
}
}
impl ModuleMap {
/// Fix up all handles in `expr`.
///
/// Use the expression handle remappings in `operand_map`, and all
/// other mappings from `self`.
pub fn adjust_expression(
&self,
expr: &mut crate::Expression,
operand_map: &HandleMap<crate::Expression>,
) {
let adjust = |expr: &mut Handle<crate::Expression>| {
operand_map.adjust(expr);
};
use crate::Expression as Ex;
match *expr {
// Expressions that do not contain handles that need to be adjusted.
Ex::Literal(_)
| Ex::FunctionArgument(_)
| Ex::GlobalVariable(_)
| Ex::LocalVariable(_)
| Ex::CallResult(_)
| Ex::RayQueryProceedResult => {}
// Expressions that contain handles that need to be adjusted.
Ex::Constant(ref mut constant) => self.constants.adjust(constant),
Ex::ZeroValue(ref mut ty) => self.types.adjust(ty),
Ex::Compose {
ref mut ty,
ref mut components,
} => {
self.types.adjust(ty);
for component in components {
adjust(component);
}
}
Ex::Access {
ref mut base,
ref mut index,
} => {
adjust(base);
adjust(index);
}
Ex::AccessIndex {
ref mut base,
index: _,
} => adjust(base),
Ex::Splat {
size: _,
ref mut value,
} => adjust(value),
Ex::Swizzle {
size: _,
ref mut vector,
pattern: _,
} => adjust(vector),
Ex::Load { ref mut pointer } => adjust(pointer),
Ex::ImageSample {
ref mut image,
ref mut sampler,
gather: _,
ref mut coordinate,
ref mut array_index,
ref mut offset,
ref mut level,
ref mut depth_ref,
} => {
adjust(image);
adjust(sampler);
adjust(coordinate);
operand_map.adjust_option(array_index);
// TEST: try adjusting this with plain operand_map
if let Some(ref mut offset) = *offset {
self.const_expressions.adjust(offset);
}
self.adjust_sample_level(level, operand_map);
operand_map.adjust_option(depth_ref);
}
Ex::ImageLoad {
ref mut image,
ref mut coordinate,
ref mut array_index,
ref mut sample,
ref mut level,
} => {
adjust(image);
adjust(coordinate);
operand_map.adjust_option(array_index);
operand_map.adjust_option(sample);
operand_map.adjust_option(level);
}
Ex::ImageQuery {
ref mut image,
ref mut query,
} => {
adjust(image);
self.adjust_image_query(query, operand_map);
}
Ex::Unary {
op: _,
ref mut expr,
} => adjust(expr),
Ex::Binary {
op: _,
ref mut left,
ref mut right,
} => {
adjust(left);
adjust(right);
}
Ex::Select {
ref mut condition,
ref mut accept,
ref mut reject,
} => {
adjust(condition);
adjust(accept);
adjust(reject);
}
Ex::Derivative {
axis: _,
ctrl: _,
ref mut expr,
} => adjust(expr),
Ex::Relational {
fun: _,
ref mut argument,
} => adjust(argument),
Ex::Math {
fun: _,
ref mut arg,
ref mut arg1,
ref mut arg2,
ref mut arg3,
} => {
adjust(arg);
operand_map.adjust_option(arg1);
operand_map.adjust_option(arg2);
operand_map.adjust_option(arg3);
}
Ex::As {
ref mut expr,
kind: _,
convert: _,
} => adjust(expr),
Ex::AtomicResult {
ref mut ty,
comparison: _,
} => self.types.adjust(ty),
Ex::WorkGroupUniformLoadResult { ref mut ty } => self.types.adjust(ty),
Ex::ArrayLength(ref mut expr) => adjust(expr),
Ex::RayQueryGetIntersection {
ref mut query,
committed: _,
} => adjust(query),
}
}
fn adjust_sample_level(
&self,
level: &mut crate::SampleLevel,
operand_map: &HandleMap<crate::Expression>,
) {
let adjust = |expr: &mut Handle<crate::Expression>| operand_map.adjust(expr);
use crate::SampleLevel as Sl;
match *level {
Sl::Auto | Sl::Zero => {}
Sl::Exact(ref mut expr) => adjust(expr),
Sl::Bias(ref mut expr) => adjust(expr),
Sl::Gradient {
ref mut x,
ref mut y,
} => {
adjust(x);
adjust(y);
}
}
}
fn adjust_image_query(
&self,
query: &mut crate::ImageQuery,
operand_map: &HandleMap<crate::Expression>,
) {
use crate::ImageQuery as Iq;
match *query {
Iq::Size { ref mut level } => operand_map.adjust_option(level),
Iq::NumLevels | Iq::NumLayers | Iq::NumSamples => {}
}
}
}

134
third_party/rust/naga/src/compact/functions.rs поставляемый Normal file
Просмотреть файл

@ -0,0 +1,134 @@
use super::handle_set_map::HandleSet;
use super::{FunctionMap, ModuleMap};
use crate::arena::Handle;
pub(super) struct FunctionTracer<'a> {
pub(super) module: &'a crate::Module,
pub(super) function: &'a crate::Function,
pub(super) types_used: &'a mut HandleSet<crate::Type>,
pub(super) constants_used: &'a mut HandleSet<crate::Constant>,
pub(super) const_expressions_used: &'a mut HandleSet<crate::Expression>,
/// Function-local expressions used.
pub(super) expressions_used: HandleSet<crate::Expression>,
}
impl<'a> FunctionTracer<'a> {
pub fn trace(&mut self) {
for argument in self.function.arguments.iter() {
self.trace_type(argument.ty);
}
if let Some(ref result) = self.function.result {
self.trace_type(result.ty);
}
for (_, local) in self.function.local_variables.iter() {
self.trace_type(local.ty);
if let Some(init) = local.init {
// TEST: try changing this to trace_expression
self.trace_const_expression(init);
}
}
// Treat named expressions as alive, for the sake of our test suite,
// which uses `let blah = expr;` to exercise lots of things.
for (value, _name) in &self.function.named_expressions {
self.trace_expression(*value);
}
self.trace_block(&self.function.body);
}
pub fn trace_type(&mut self, ty: Handle<crate::Type>) {
self.as_type().trace_type(ty)
}
pub fn trace_expression(&mut self, expr: Handle<crate::Expression>) {
self.as_expression().trace_expression(expr);
}
pub fn trace_const_expression(&mut self, expr: Handle<crate::Expression>) {
self.as_expression()
.as_const_expression()
.trace_expression(expr);
}
/*
pub fn trace_const_expression(&mut self, const_expr: Handle<crate::Expression>) {
self.as_expression().as_const_expression().trace_expression(const_expr);
}
*/
fn as_type(&mut self) -> super::types::TypeTracer {
super::types::TypeTracer {
types: &self.module.types,
types_used: self.types_used,
}
}
fn as_expression(&mut self) -> super::expressions::ExpressionTracer {
super::expressions::ExpressionTracer {
types: &self.module.types,
constants: &self.module.constants,
expressions: &self.function.expressions,
types_used: self.types_used,
constants_used: self.constants_used,
expressions_used: &mut self.expressions_used,
const_expressions: Some((
&self.module.const_expressions,
&mut self.const_expressions_used,
)),
}
}
}
impl FunctionMap {
pub fn compact(
&self,
function: &mut crate::Function,
module_map: &ModuleMap,
reuse: &mut crate::NamedExpressions,
) {
assert!(reuse.is_empty());
for argument in function.arguments.iter_mut() {
module_map.types.adjust(&mut argument.ty);
}
if let Some(ref mut result) = function.result {
module_map.types.adjust(&mut result.ty);
}
for (_, local) in function.local_variables.iter_mut() {
log::trace!("adjusting local variable {:?}", local.name);
module_map.types.adjust(&mut local.ty);
if let Some(ref mut init) = local.init {
module_map.const_expressions.adjust(init);
}
}
// Drop unused expressions, reusing existing storage.
function.expressions.retain_mut(|handle, expr| {
if self.expressions.used(handle) {
module_map.adjust_expression(expr, &self.expressions);
true
} else {
false
}
});
// Adjust named expressions.
for (mut handle, name) in function.named_expressions.drain(..) {
self.expressions.adjust(&mut handle);
reuse.insert(handle, name);
}
std::mem::swap(&mut function.named_expressions, reuse);
assert!(reuse.is_empty());
// Adjust statements.
self.adjust_block(&mut function.body);
}
}

125
third_party/rust/naga/src/compact/handle_set_map.rs поставляемый Normal file
Просмотреть файл

@ -0,0 +1,125 @@
use crate::arena::{Arena, Handle, UniqueArena};
type Index = std::num::NonZeroU32;
/// A set of `Handle<T>` values.
pub struct HandleSet<T> {
/// Bound on zero-based indexes of handles stored in this set.
len: usize,
/// `members[i]` is true if the handle with zero-based index `i`
/// is a member.
members: bit_set::BitSet,
/// This type is indexed by values of type `T`.
as_keys: std::marker::PhantomData<T>,
}
impl<T> HandleSet<T> {
pub fn for_arena(arena: &impl ArenaType<T>) -> Self {
let len = arena.len();
Self {
len,
members: bit_set::BitSet::with_capacity(len),
as_keys: std::marker::PhantomData,
}
}
/// Add `handle` to the set.
///
/// Return `true` if the handle was not already in the set. In
/// other words, return true if it was newly inserted.
pub fn insert(&mut self, handle: Handle<T>) -> bool {
// Note that, oddly, `Handle::index` does not return a 1-based
// `Index`, but rather a zero-based `usize`.
self.members.insert(handle.index())
}
}
pub trait ArenaType<T> {
fn len(&self) -> usize;
}
impl<T> ArenaType<T> for Arena<T> {
fn len(&self) -> usize {
self.len()
}
}
impl<T: std::hash::Hash + Eq> ArenaType<T> for UniqueArena<T> {
fn len(&self) -> usize {
self.len()
}
}
/// A map from old handle indices to new, compressed handle indices.
pub struct HandleMap<T> {
/// The indices assigned to handles in the compacted module.
///
/// If `new_index[i]` is `Some(n)`, then `n` is the 1-based
/// `Index` of the compacted `Handle` corresponding to the
/// pre-compacted `Handle` whose zero-based index is `i`. ("Clear
/// as mud.")
new_index: Vec<Option<Index>>,
/// This type is indexed by values of type `T`.
as_keys: std::marker::PhantomData<T>,
}
impl<T: 'static> HandleMap<T> {
pub fn from_set(set: HandleSet<T>) -> Self {
let mut next_index = Index::new(1).unwrap();
Self {
new_index: (0..set.len)
.map(|zero_based_index| {
if set.members.contains(zero_based_index) {
// This handle will be retained in the compacted version,
// so assign it a new index.
let this = next_index;
next_index = next_index.checked_add(1).unwrap();
Some(this)
} else {
// This handle will be omitted in the compacted version.
None
}
})
.collect(),
as_keys: std::marker::PhantomData,
}
}
/// Return true if `old` is used in the compacted module.
pub fn used(&self, old: Handle<T>) -> bool {
self.new_index[old.index()].is_some()
}
/// Return the counterpart to `old` in the compacted module.
///
/// If we thought `old` wouldn't be used in the compacted module, return
/// `None`.
pub fn try_adjust(&self, old: Handle<T>) -> Option<Handle<T>> {
log::trace!(
"adjusting {} handle [{}] -> [{:?}]",
std::any::type_name::<T>(),
old.index() + 1,
self.new_index[old.index()]
);
// Note that `Handle::index` returns a zero-based index,
// but `Handle::new` accepts a 1-based `Index`.
self.new_index[old.index()].map(Handle::new)
}
/// Return the counterpart to `old` in the compacted module.
///
/// If we thought `old` wouldn't be used in the compacted module, panic.
pub fn adjust(&self, handle: &mut Handle<T>) {
*handle = self.try_adjust(*handle).unwrap();
}
/// Like `adjust`, but for optional handles.
pub fn adjust_option(&self, handle: &mut Option<Handle<T>>) {
if let Some(ref mut handle) = *handle {
self.adjust(handle);
}
}
}

286
third_party/rust/naga/src/compact/mod.rs поставляемый Normal file
Просмотреть файл

@ -0,0 +1,286 @@
mod expressions;
mod functions;
mod handle_set_map;
mod statements;
mod types;
use crate::{arena, compact::functions::FunctionTracer};
use handle_set_map::{HandleMap, HandleSet};
/// Remove unused types, expressions, and constants from `module`.
///
/// Assuming that all globals, named constants, special types,
/// functions and entry points in `module` are used, determine which
/// types, constants, and expressions (both function-local and global
/// constant expressions) are actually used, and remove the rest,
/// adjusting all handles as necessary. The result should be a module
/// functionally identical to the original.
///
/// This may be useful to apply to modules generated in the snapshot
/// tests. Our backends often generate temporary names based on handle
/// indices, which means that adding or removing unused arena entries
/// can affect the output even though they have no semantic effect.
/// Such meaningless changes add noise to snapshot diffs, making
/// accurate patch review difficult. Compacting the modules before
/// generating snapshots makes the output independent of unused arena
/// entries.
///
/// # Panics
///
/// If `module` has not passed validation, this may panic.
pub fn compact(module: &mut crate::Module) {
let mut module_tracer = ModuleTracer::new(module);
// We treat all globals as used by definition.
log::trace!("tracing global variables");
{
for (_, global) in module.global_variables.iter() {
log::trace!("tracing global {:?}", global.name);
module_tracer.as_type().trace_type(global.ty);
if let Some(init) = global.init {
module_tracer.as_const_expression().trace_expression(init);
}
}
}
// We treat all special types as used by definition.
module_tracer.trace_special_types(&module.special_types);
// We treat all named constants as used by definition.
for (handle, constant) in module.constants.iter() {
if constant.name.is_some() {
module_tracer.constants_used.insert(handle);
module_tracer.as_type().trace_type(constant.ty);
module_tracer
.as_const_expression()
.trace_expression(constant.init);
}
}
// We assume that all functions are used.
//
// Observe which types, constant expressions, constants, and
// expressions each function uses, and produce maps from
// pre-compaction to post-compaction handles.
log::trace!("tracing functions");
let function_maps: Vec<FunctionMap> = module
.functions
.iter()
.map(|(_, f)| {
log::trace!("tracing function {:?}", f.name);
let mut function_tracer = module_tracer.enter_function(f);
function_tracer.trace();
FunctionMap::from(function_tracer)
})
.collect();
// Similiarly, observe what each entry point actually uses.
log::trace!("tracing entry points");
let entry_point_maps: Vec<FunctionMap> = module
.entry_points
.iter()
.map(|e| {
log::trace!("tracing entry point {:?}", e.function.name);
let mut used = module_tracer.enter_function(&e.function);
used.trace();
FunctionMap::from(used)
})
.collect();
// Now that we know what is used and what is never touched,
// produce maps from the `Handle`s that appear in `module` now to
// the corresponding `Handle`s that will refer to the same items
// in the compacted module.
let module_map = ModuleMap::from(module_tracer);
// Drop unused types from the type arena.
//
// `FastIndexSet`s don't have an underlying Vec<T> that we can
// steal, compact in place, and then rebuild the `FastIndexSet`
// from. So we have to rebuild the type arena from scratch.
log::trace!("compacting types");
let mut new_types = arena::UniqueArena::new();
for (old_handle, mut ty, span) in module.types.drain_all() {
if let Some(expected_new_handle) = module_map.types.try_adjust(old_handle) {
module_map.adjust_type(&mut ty);
let actual_new_handle = new_types.insert(ty, span);
assert_eq!(actual_new_handle, expected_new_handle);
}
}
module.types = new_types;
log::trace!("adjusting special types");
module_map.adjust_special_types(&mut module.special_types);
// Drop unused constant expressions, reusing existing storage.
log::trace!("adjusting constant expressions");
module.const_expressions.retain_mut(|handle, expr| {
if module_map.const_expressions.used(handle) {
module_map.adjust_expression(expr, &module_map.const_expressions);
true
} else {
false
}
});
// Drop unused constants in place, reusing existing storage.
log::trace!("adjusting constants");
module.constants.retain_mut(|handle, constant| {
if module_map.constants.used(handle) {
module_map.types.adjust(&mut constant.ty);
module_map.const_expressions.adjust(&mut constant.init);
true
} else {
false
}
});
// Adjust global variables' types and initializers.
log::trace!("adjusting global variables");
for (_, global) in module.global_variables.iter_mut() {
log::trace!("adjusting global {:?}", global.name);
module_map.types.adjust(&mut global.ty);
if let Some(ref mut init) = global.init {
module_map.const_expressions.adjust(init);
}
}
// Temporary storage to help us reuse allocations of existing
// named expression tables.
let mut reused_named_expressions = crate::NamedExpressions::default();
// Compact each function.
for ((_, function), map) in module.functions.iter_mut().zip(function_maps.iter()) {
log::trace!("compacting function {:?}", function.name);
map.compact(function, &module_map, &mut reused_named_expressions);
}
// Compact each entry point.
for (entry, map) in module.entry_points.iter_mut().zip(entry_point_maps.iter()) {
log::trace!("compacting entry point {:?}", entry.function.name);
map.compact(
&mut entry.function,
&module_map,
&mut reused_named_expressions,
);
}
}
struct ModuleTracer<'module> {
module: &'module crate::Module,
types_used: HandleSet<crate::Type>,
constants_used: HandleSet<crate::Constant>,
const_expressions_used: HandleSet<crate::Expression>,
}
impl<'module> ModuleTracer<'module> {
fn new(module: &'module crate::Module) -> Self {
Self {
module,
types_used: HandleSet::for_arena(&module.types),
constants_used: HandleSet::for_arena(&module.constants),
const_expressions_used: HandleSet::for_arena(&module.const_expressions),
}
}
fn trace_special_types(&mut self, special_types: &crate::SpecialTypes) {
let crate::SpecialTypes {
ref ray_desc,
ref ray_intersection,
ref predeclared_types,
} = *special_types;
let mut type_tracer = self.as_type();
if let Some(ray_desc) = *ray_desc {
type_tracer.trace_type(ray_desc);
}
if let Some(ray_intersection) = *ray_intersection {
type_tracer.trace_type(ray_intersection);
}
for (_, &handle) in predeclared_types {
type_tracer.trace_type(handle);
}
}
fn as_type(&mut self) -> types::TypeTracer {
types::TypeTracer {
types: &self.module.types,
types_used: &mut self.types_used,
}
}
fn as_const_expression(&mut self) -> expressions::ExpressionTracer {
expressions::ExpressionTracer {
types: &self.module.types,
constants: &self.module.constants,
expressions: &self.module.const_expressions,
types_used: &mut self.types_used,
constants_used: &mut self.constants_used,
expressions_used: &mut self.const_expressions_used,
const_expressions: None,
}
}
pub fn enter_function<'tracer>(
&'tracer mut self,
function: &'tracer crate::Function,
) -> FunctionTracer<'tracer> {
FunctionTracer {
module: self.module,
function,
types_used: &mut self.types_used,
constants_used: &mut self.constants_used,
const_expressions_used: &mut self.const_expressions_used,
expressions_used: HandleSet::for_arena(&function.expressions),
}
}
}
struct ModuleMap {
types: HandleMap<crate::Type>,
constants: HandleMap<crate::Constant>,
const_expressions: HandleMap<crate::Expression>,
}
impl From<ModuleTracer<'_>> for ModuleMap {
fn from(used: ModuleTracer) -> Self {
ModuleMap {
types: HandleMap::from_set(used.types_used),
constants: HandleMap::from_set(used.constants_used),
const_expressions: HandleMap::from_set(used.const_expressions_used),
}
}
}
impl ModuleMap {
fn adjust_special_types(&self, special: &mut crate::SpecialTypes) {
let crate::SpecialTypes {
ref mut ray_desc,
ref mut ray_intersection,
ref mut predeclared_types,
} = *special;
if let Some(ref mut ray_desc) = *ray_desc {
self.types.adjust(ray_desc);
}
if let Some(ref mut ray_intersection) = *ray_intersection {
self.types.adjust(ray_intersection);
}
for handle in predeclared_types.values_mut() {
self.types.adjust(handle);
}
}
}
struct FunctionMap {
expressions: HandleMap<crate::Expression>,
}
impl From<FunctionTracer<'_>> for FunctionMap {
fn from(used: FunctionTracer) -> Self {
FunctionMap {
expressions: HandleMap::from_set(used.expressions_used),
}
}
}

302
third_party/rust/naga/src/compact/statements.rs поставляемый Normal file
Просмотреть файл

@ -0,0 +1,302 @@
use super::functions::FunctionTracer;
use super::FunctionMap;
use crate::arena::Handle;
impl FunctionTracer<'_> {
pub fn trace_block(&mut self, block: &[crate::Statement]) {
let mut worklist: Vec<&[crate::Statement]> = vec![block];
while let Some(last) = worklist.pop() {
for stmt in last {
use crate::Statement as St;
match *stmt {
St::Emit(ref range) => {
for expr in range.clone() {
log::trace!("trace emitted expression {:?}", expr);
self.trace_expression(expr);
}
}
St::Block(ref block) => worklist.push(block),
St::If {
condition,
ref accept,
ref reject,
} => {
self.trace_expression(condition);
worklist.push(accept);
worklist.push(reject);
}
St::Switch {
selector,
ref cases,
} => {
self.trace_expression(selector);
for case in cases {
worklist.push(&case.body);
}
}
St::Loop {
ref body,
ref continuing,
break_if,
} => {
if let Some(break_if) = break_if {
self.trace_expression(break_if);
}
worklist.push(body);
worklist.push(continuing);
}
St::Return { value: Some(value) } => self.trace_expression(value),
St::Store { pointer, value } => {
self.trace_expression(pointer);
self.trace_expression(value);
}
St::ImageStore {
image,
coordinate,
array_index,
value,
} => {
self.trace_expression(image);
self.trace_expression(coordinate);
if let Some(array_index) = array_index {
self.trace_expression(array_index);
}
self.trace_expression(value);
}
St::Atomic {
pointer,
ref fun,
value,
result,
} => {
self.trace_expression(pointer);
self.trace_atomic_function(fun);
self.trace_expression(value);
self.trace_expression(result);
}
St::WorkGroupUniformLoad { pointer, result } => {
self.trace_expression(pointer);
self.trace_expression(result);
}
St::Call {
function: _,
ref arguments,
result,
} => {
for expr in arguments {
self.trace_expression(*expr);
}
if let Some(result) = result {
self.trace_expression(result);
}
}
St::RayQuery { query, ref fun } => {
self.trace_expression(query);
self.trace_ray_query_function(fun);
}
// Trivial statements.
St::Break
| St::Continue
| St::Kill
| St::Barrier(_)
| St::Return { value: None } => {}
}
}
}
}
fn trace_atomic_function(&mut self, fun: &crate::AtomicFunction) {
use crate::AtomicFunction as Af;
match *fun {
Af::Exchange {
compare: Some(expr),
} => self.trace_expression(expr),
Af::Exchange { compare: None }
| Af::Add
| Af::Subtract
| Af::And
| Af::ExclusiveOr
| Af::InclusiveOr
| Af::Min
| Af::Max => {}
}
}
fn trace_ray_query_function(&mut self, fun: &crate::RayQueryFunction) {
use crate::RayQueryFunction as Qf;
match *fun {
Qf::Initialize {
acceleration_structure,
descriptor,
} => {
self.trace_expression(acceleration_structure);
self.trace_expression(descriptor);
}
Qf::Proceed { result } => self.trace_expression(result),
Qf::Terminate => {}
}
}
}
impl FunctionMap {
pub fn adjust_block(&self, block: &mut [crate::Statement]) {
let mut worklist: Vec<&mut [crate::Statement]> = vec![block];
let adjust = |handle: &mut Handle<crate::Expression>| {
self.expressions.adjust(handle);
};
while let Some(last) = worklist.pop() {
for stmt in last {
use crate::Statement as St;
match *stmt {
St::Emit(ref mut range) => {
// Fortunately, compaction doesn't arbitrarily scramble
// the expressions in the arena, but instead preserves
// the order of the elements while squeezing out unused
// ones. That means that a contiguous range in the
// pre-compacted arena always maps to a contiguous range
// in the post-compacted arena. So we just need to
// adjust the endpoints.
let (mut first, mut last) = range.first_and_last().unwrap();
self.expressions.adjust(&mut first);
self.expressions.adjust(&mut last);
*range = crate::arena::Range::new_from_bounds(first, last);
}
St::Block(ref mut block) => worklist.push(block),
St::If {
ref mut condition,
ref mut accept,
ref mut reject,
} => {
adjust(condition);
worklist.push(accept);
worklist.push(reject);
}
St::Switch {
ref mut selector,
ref mut cases,
} => {
adjust(selector);
for case in cases {
worklist.push(&mut case.body);
}
}
St::Loop {
ref mut body,
ref mut continuing,
ref mut break_if,
} => {
if let Some(ref mut break_if) = *break_if {
adjust(break_if);
}
worklist.push(body);
worklist.push(continuing);
}
St::Return {
value: Some(ref mut value),
} => adjust(value),
St::Store {
ref mut pointer,
ref mut value,
} => {
adjust(pointer);
adjust(value);
}
St::ImageStore {
ref mut image,
ref mut coordinate,
ref mut array_index,
ref mut value,
} => {
adjust(image);
adjust(coordinate);
if let Some(ref mut array_index) = *array_index {
adjust(array_index);
}
adjust(value);
}
St::Atomic {
ref mut pointer,
ref mut fun,
ref mut value,
ref mut result,
} => {
adjust(pointer);
self.adjust_atomic_function(fun);
adjust(value);
adjust(result);
}
St::WorkGroupUniformLoad {
ref mut pointer,
ref mut result,
} => {
adjust(pointer);
adjust(result);
}
St::Call {
function: _,
ref mut arguments,
ref mut result,
} => {
for expr in arguments {
adjust(expr);
}
if let Some(ref mut result) = *result {
adjust(result);
}
}
St::RayQuery {
ref mut query,
ref mut fun,
} => {
adjust(query);
self.adjust_ray_query_function(fun);
}
// Trivial statements.
St::Break
| St::Continue
| St::Kill
| St::Barrier(_)
| St::Return { value: None } => {}
}
}
}
}
fn adjust_atomic_function(&self, fun: &mut crate::AtomicFunction) {
use crate::AtomicFunction as Af;
match *fun {
Af::Exchange {
compare: Some(ref mut expr),
} => {
self.expressions.adjust(expr);
}
Af::Exchange { compare: None }
| Af::Add
| Af::Subtract
| Af::And
| Af::ExclusiveOr
| Af::InclusiveOr
| Af::Min
| Af::Max => {}
}
}
fn adjust_ray_query_function(&self, fun: &mut crate::RayQueryFunction) {
use crate::RayQueryFunction as Qf;
match *fun {
Qf::Initialize {
ref mut acceleration_structure,
ref mut descriptor,
} => {
self.expressions.adjust(acceleration_structure);
self.expressions.adjust(descriptor);
}
Qf::Proceed { ref mut result } => {
self.expressions.adjust(result);
}
Qf::Terminate => {}
}
}
}

93
third_party/rust/naga/src/compact/types.rs поставляемый Normal file
Просмотреть файл

@ -0,0 +1,93 @@
use super::{HandleSet, ModuleMap};
use crate::{Handle, UniqueArena};
pub struct TypeTracer<'a> {
pub types: &'a UniqueArena<crate::Type>,
pub types_used: &'a mut HandleSet<crate::Type>,
}
impl<'a> TypeTracer<'a> {
pub fn trace_type(&mut self, ty: Handle<crate::Type>) {
let mut work_list = vec![ty];
while let Some(ty) = work_list.pop() {
// If we've already seen this type, no need to traverse further.
if !self.types_used.insert(ty) {
continue;
}
use crate::TypeInner as Ti;
match self.types[ty].inner {
// Types that do not contain handles.
Ti::Scalar { .. }
| Ti::Vector { .. }
| Ti::Matrix { .. }
| Ti::Atomic { .. }
| Ti::ValuePointer { .. }
| Ti::Image { .. }
| Ti::Sampler { .. }
| Ti::AccelerationStructure
| Ti::RayQuery => {}
// Types that do contain handles.
Ti::Pointer { base, space: _ } => work_list.push(base),
Ti::Array {
base,
size: _,
stride: _,
} => work_list.push(base),
Ti::Struct {
ref members,
span: _,
} => {
work_list.extend(members.iter().map(|m| m.ty));
}
Ti::BindingArray { base, size: _ } => work_list.push(base),
}
}
}
}
impl ModuleMap {
pub fn adjust_type(&self, ty: &mut crate::Type) {
let adjust = |ty: &mut Handle<crate::Type>| self.types.adjust(ty);
use crate::TypeInner as Ti;
match ty.inner {
// Types that do not contain handles.
Ti::Scalar { .. }
| Ti::Vector { .. }
| Ti::Matrix { .. }
| Ti::Atomic { .. }
| Ti::ValuePointer { .. }
| Ti::Image { .. }
| Ti::Sampler { .. }
| Ti::AccelerationStructure
| Ti::RayQuery => {}
// Types that do contain handles.
Ti::Pointer {
ref mut base,
space: _,
} => adjust(base),
Ti::Array {
ref mut base,
size: _,
stride: _,
} => adjust(base),
Ti::Struct {
ref mut members,
span: _,
} => {
for member in members {
self.types.adjust(&mut member.ty);
}
}
Ti::BindingArray {
ref mut base,
size: _,
} => {
adjust(base);
}
};
}
}

Просмотреть файл

@ -401,6 +401,7 @@ fn map_image_format(word: &str) -> Option<crate::StorageFormat> {
"r32f" => Sf::R32Float,
"r16f" => Sf::R16Float,
"rgba16" => Sf::Rgba16Unorm,
"rgb10_a2ui" => Sf::Rgb10a2Uint,
"rgb10_a2" => Sf::Rgb10a2Unorm,
"rgba8" => Sf::Rgba8Unorm,
"rg16" => Sf::Rg16Unorm,

Просмотреть файл

@ -105,7 +105,8 @@ pub(super) fn map_image_format(word: spirv::Word) -> Result<crate::StorageFormat
Some(spirv::ImageFormat::Rgba8Snorm) => Ok(crate::StorageFormat::Rgba8Snorm),
Some(spirv::ImageFormat::Rgba8ui) => Ok(crate::StorageFormat::Rgba8Uint),
Some(spirv::ImageFormat::Rgba8i) => Ok(crate::StorageFormat::Rgba8Sint),
Some(spirv::ImageFormat::Rgb10a2ui) => Ok(crate::StorageFormat::Rgb10a2Unorm),
Some(spirv::ImageFormat::Rgb10a2ui) => Ok(crate::StorageFormat::Rgb10a2Uint),
Some(spirv::ImageFormat::Rgb10A2) => Ok(crate::StorageFormat::Rgb10a2Unorm),
Some(spirv::ImageFormat::R11fG11fB10f) => Ok(crate::StorageFormat::Rg11b10Float),
Some(spirv::ImageFormat::Rg32ui) => Ok(crate::StorageFormat::Rg32Uint),
Some(spirv::ImageFormat::Rg32i) => Ok(crate::StorageFormat::Rg32Sint),

10
third_party/rust/naga/src/front/spv/mod.rs поставляемый
Просмотреть файл

@ -40,7 +40,7 @@ use function::*;
use crate::{
arena::{Arena, Handle, UniqueArena},
proc::{Alignment, Layouter},
FastHashMap, FastHashSet,
FastHashMap, FastHashSet, FastIndexMap,
};
use num_traits::cast::FromPrimitive;
@ -596,11 +596,7 @@ pub struct Frontend<I> {
/// use that target block id.
///
/// Used to preserve allocations between instruction parsing.
switch_cases: indexmap::IndexMap<
spirv::Word,
(BodyIndex, Vec<i32>),
std::hash::BuildHasherDefault<rustc_hash::FxHasher>,
>,
switch_cases: FastIndexMap<spirv::Word, (BodyIndex, Vec<i32>)>,
/// Tracks access to gl_PerVertex's builtins, it is used to cull unused builtins since initializing those can
/// affect performance and the mere presence of some of these builtins might cause backends to error since they
@ -641,7 +637,7 @@ impl<I: Iterator<Item = u32>> Frontend<I> {
dummy_functions: Arena::new(),
function_call_graph: GraphMap::new(),
options: options.clone(),
switch_cases: indexmap::IndexMap::default(),
switch_cases: FastIndexMap::default(),
gl_per_vertex_builtin_access: FastHashSet::default(),
}
}

Просмотреть файл

@ -6,8 +6,7 @@ use crate::front::wgsl::parse::number::Number;
use crate::front::wgsl::parse::{ast, conv};
use crate::front::{Emitter, Typifier};
use crate::proc::{ensure_block_returns, Alignment, Layouter, ResolveContext, TypeResolution};
use crate::{Arena, FastHashMap, Handle, Span};
use indexmap::IndexMap;
use crate::{Arena, FastHashMap, FastIndexMap, Handle, Span};
mod construction;
@ -79,10 +78,17 @@ pub struct StatementContext<'source, 'temp, 'out> {
/// `Handle`s we have built for them, owned by `Lowerer::lower`.
globals: &'temp mut FastHashMap<&'source str, LoweredGlobalDecl>,
/// A map from `ast::Local` handles to the Naga expressions we've built for them.
/// A map from each `ast::Local` handle to the Naga expression
/// we've built for it:
///
/// The Naga expressions are either [`LocalVariable`] or
/// [`FunctionArgument`] expressions.
/// - WGSL function arguments become Naga [`FunctionArgument`] expressions.
///
/// - WGSL `var` declarations become Naga [`LocalVariable`] expressions.
///
/// - WGSL `let` declararations become arbitrary Naga expressions.
///
/// This always borrows the `local_table` local variable in
/// [`Lowerer::function`].
///
/// [`LocalVariable`]: crate::Expression::LocalVariable
/// [`FunctionArgument`]: crate::Expression::FunctionArgument
@ -94,7 +100,7 @@ pub struct StatementContext<'source, 'temp, 'out> {
naga_expressions: &'out mut Arena<crate::Expression>,
/// Stores the names of expressions that are assigned in `let` statement
/// Also stores the spans of the names, for use in errors.
named_expressions: &'out mut IndexMap<Handle<crate::Expression>, (String, Span)>,
named_expressions: &'out mut FastIndexMap<Handle<crate::Expression>, (String, Span)>,
arguments: &'out [crate::FunctionArgument],
module: &'out mut crate::Module,
}
@ -167,7 +173,11 @@ impl<'a, 'temp> StatementContext<'a, 'temp, '_> {
}
pub struct RuntimeExpressionContext<'temp, 'out> {
local_table: &'temp mut FastHashMap<Handle<ast::Local>, TypedExpression>,
/// A map from [`ast::Local`] handles to the Naga expressions we've built for them.
///
/// This is always [`StatementContext::local_table`] for the
/// enclosing statement; see that documentation for details.
local_table: &'temp FastHashMap<Handle<ast::Local>, TypedExpression>,
naga_expressions: &'out mut Arena<crate::Expression>,
local_vars: &'out Arena<crate::LocalVariable>,
@ -904,7 +914,7 @@ impl<'source, 'temp> Lowerer<'source, 'temp> {
let mut local_table = FastHashMap::default();
let mut local_variables = Arena::new();
let mut expressions = Arena::new();
let mut named_expressions = IndexMap::default();
let mut named_expressions = FastIndexMap::default();
let arguments = f
.arguments

1
third_party/rust/naga/src/front/wgsl/mod.rs поставляемый
Просмотреть файл

@ -71,6 +71,7 @@ impl crate::StorageFormat {
Sf::Rgba8Snorm => "rgba8snorm",
Sf::Rgba8Uint => "rgba8uint",
Sf::Rgba8Sint => "rgba8sint",
Sf::Rgb10a2Uint => "rgb10a2uint",
Sf::Rgb10a2Unorm => "rgb10a2unorm",
Sf::Rg11b10Float => "rg11b10float",
Sf::Rg32Uint => "rg32uint",

Просмотреть файл

@ -1,5 +1,5 @@
use crate::front::wgsl::parse::number::Number;
use crate::{Arena, FastHashSet, Handle, Span};
use crate::{Arena, FastIndexSet, Handle, Span};
use std::hash::Hash;
#[derive(Debug, Default)]
@ -73,7 +73,7 @@ pub struct GlobalDecl<'a> {
/// Names of all module-scope or predeclared objects this
/// declaration uses.
pub dependencies: FastHashSet<Dependency<'a>>,
pub dependencies: FastIndexSet<Dependency<'a>>,
}
#[derive(Debug)]

Просмотреть файл

@ -84,6 +84,7 @@ pub fn map_storage_format(word: &str, span: Span) -> Result<crate::StorageFormat
"rgba8snorm" => Sf::Rgba8Snorm,
"rgba8uint" => Sf::Rgba8Uint,
"rgba8sint" => Sf::Rgba8Sint,
"rgb10a2uint" => Sf::Rgb10a2Uint,
"rgb10a2unorm" => Sf::Rgb10a2Unorm,
"rg11b10float" => Sf::Rg11b10Float,
"rg32uint" => Sf::Rg32Uint,

Просмотреть файл

@ -2,7 +2,7 @@ use crate::front::wgsl::error::{Error, ExpectedToken};
use crate::front::wgsl::parse::lexer::{Lexer, Token};
use crate::front::wgsl::parse::number::Number;
use crate::front::SymbolTable;
use crate::{Arena, FastHashSet, Handle, ShaderStage, Span};
use crate::{Arena, FastIndexSet, Handle, ShaderStage, Span};
pub mod ast;
pub mod conv;
@ -51,7 +51,7 @@ struct ExpressionContext<'input, 'temp, 'out> {
///
/// [`GlobalDecl`]: ast::GlobalDecl
/// [`dependencies`]: ast::GlobalDecl::dependencies
unresolved: &'out mut FastHashSet<ast::Dependency<'input>>,
unresolved: &'out mut FastIndexSet<ast::Dependency<'input>>,
}
impl<'a> ExpressionContext<'a, '_, '_> {
@ -2076,7 +2076,7 @@ impl Parser {
&mut self,
lexer: &mut Lexer<'a>,
out: &mut ast::TranslationUnit<'a>,
dependencies: &mut FastHashSet<ast::Dependency<'a>>,
dependencies: &mut FastIndexSet<ast::Dependency<'a>>,
) -> Result<ast::Function<'a>, Error<'a>> {
self.push_rule_span(Rule::FunctionDecl, lexer);
// read function name
@ -2238,7 +2238,7 @@ impl Parser {
(None, None) => {}
}
let mut dependencies = FastHashSet::default();
let mut dependencies = FastIndexSet::default();
let mut ctx = ExpressionContext {
expressions: &mut out.expressions,
local_table: &mut SymbolTable::default(),

16
third_party/rust/naga/src/lib.rs поставляемый
Просмотреть файл

@ -279,6 +279,8 @@ An override expression can be evaluated at pipeline creation time.
mod arena;
pub mod back;
mod block;
#[cfg(feature = "compact")]
pub mod compact;
pub mod front;
pub mod keywords;
pub mod proc;
@ -308,12 +310,13 @@ pub type FastHashSet<K> = rustc_hash::FxHashSet<K>;
pub type FastIndexSet<K> =
indexmap::IndexSet<K, std::hash::BuildHasherDefault<rustc_hash::FxHasher>>;
/// Insertion-order-preserving hash map (`IndexMap<K, V>`), but with the same
/// hasher as `FastHashMap<K, V>` (faster but not resilient to DoS attacks).
pub type FastIndexMap<K, V> =
indexmap::IndexMap<K, V, std::hash::BuildHasherDefault<rustc_hash::FxHasher>>;
/// Map of expressions that have associated variable names
pub(crate) type NamedExpressions = indexmap::IndexMap<
Handle<Expression>,
String,
std::hash::BuildHasherDefault<rustc_hash::FxHasher>,
>;
pub(crate) type NamedExpressions = FastIndexMap<Handle<Expression>, String>;
/// Early fragment tests.
///
@ -598,6 +601,7 @@ pub enum StorageFormat {
Rgba8Sint,
// Packed 32-bit formats
Rgb10a2Uint,
Rgb10a2Unorm,
Rg11b10Float,
@ -1993,7 +1997,7 @@ pub struct SpecialTypes {
///
/// Call [`Module::generate_predeclared_type`] to populate this if
/// needed and return the handle.
pub predeclared_types: indexmap::IndexMap<PredeclaredType, Handle<Type>>,
pub predeclared_types: FastIndexMap<PredeclaredType, Handle<Type>>,
}
/// Shader module.

1
third_party/rust/naga/src/proc/mod.rs поставляемый
Просмотреть файл

@ -39,6 +39,7 @@ impl From<super::StorageFormat> for super::ScalarKind {
Sf::Rgba8Snorm => Sk::Float,
Sf::Rgba8Uint => Sk::Uint,
Sf::Rgba8Sint => Sk::Sint,
Sf::Rgb10a2Uint => Sk::Uint,
Sf::Rgb10a2Unorm => Sk::Float,
Sf::Rg11b10Float => Sk::Float,
Sf::Rg32Uint => Sk::Uint,

12
third_party/rust/naga/src/proc/namer.rs поставляемый
Просмотреть файл

@ -36,6 +36,7 @@ impl Namer {
/// - Drop leading digits.
/// - Retain only alphanumeric and `_` characters.
/// - Avoid prefixes in [`Namer::reserved_prefixes`].
/// - Replace consecutive `_` characters with a single `_` character.
///
/// The return value is a valid identifier prefix in all of Naga's output languages,
/// and it never ends with a `SEPARATOR` character.
@ -46,6 +47,7 @@ impl Namer {
.trim_end_matches(SEPARATOR);
let base = if !string.is_empty()
&& !string.contains("__")
&& string
.chars()
.all(|c: char| c.is_ascii_alphanumeric() || c == '_')
@ -55,7 +57,13 @@ impl Namer {
let mut filtered = string
.chars()
.filter(|&c| c.is_ascii_alphanumeric() || c == '_')
.collect::<String>();
.fold(String::new(), |mut s, c| {
if s.ends_with('_') && c == '_' {
return s;
}
s.push(c);
s
});
let stripped_len = filtered.trim_end_matches(SEPARATOR).len();
filtered.truncate(stripped_len);
if filtered.is_empty() {
@ -268,4 +276,6 @@ fn test() {
assert_eq!(namer.call("x"), "x");
assert_eq!(namer.call("x"), "x_1");
assert_eq!(namer.call("x1"), "x1_");
assert_eq!(namer.call("__x"), "_x");
assert_eq!(namer.call("1___x"), "_x_1");
}

39
third_party/rust/naga/src/valid/analyzer.rs поставляемый
Просмотреть файл

@ -16,6 +16,10 @@ use std::ops;
pub type NonUniformResult = Option<Handle<crate::Expression>>;
// Remove this once we update our uniformity analysis and
// add support for the `derivative_uniformity` diagnostic
const DISABLE_UNIFORMITY_REQ_FOR_FRAGMENT_STAGE: bool = true;
bitflags::bitflags! {
/// Kinds of expressions that require uniform control flow.
#[cfg_attr(feature = "serialize", derive(serde::Serialize))]
@ -23,8 +27,8 @@ bitflags::bitflags! {
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub struct UniformityRequirements: u8 {
const WORK_GROUP_BARRIER = 0x1;
const DERIVATIVE = 0x2;
const IMPLICIT_LEVEL = 0x4;
const DERIVATIVE = if DISABLE_UNIFORMITY_REQ_FOR_FRAGMENT_STAGE { 0 } else { 0x2 };
const IMPLICIT_LEVEL = if DISABLE_UNIFORMITY_REQ_FOR_FRAGMENT_STAGE { 0 } else { 0x4 };
}
}
@ -1185,21 +1189,28 @@ fn uniform_control_flow() {
.into(),
reject: crate::Block::new(),
};
assert_eq!(
info.process_block(
{
let block_info = info.process_block(
&vec![stmt_emit2, stmt_if_non_uniform].into(),
&[],
None,
&expressions
),
Err(FunctionError::NonUniformControlFlow(
UniformityRequirements::DERIVATIVE,
derivative_expr,
UniformityDisruptor::Expression(non_uniform_global_expr)
)
.with_span()),
);
assert_eq!(info[derivative_expr].ref_count, 1);
&expressions,
);
if DISABLE_UNIFORMITY_REQ_FOR_FRAGMENT_STAGE {
assert_eq!(info[derivative_expr].ref_count, 2);
} else {
assert_eq!(
block_info,
Err(FunctionError::NonUniformControlFlow(
UniformityRequirements::DERIVATIVE,
derivative_expr,
UniformityDisruptor::Expression(non_uniform_global_expr)
)
.with_span()),
);
assert_eq!(info[derivative_expr].ref_count, 1);
}
}
assert_eq!(info[non_uniform_global], GlobalUse::READ);
let stmt_emit3 = S::Emit(emit_range_globals);

Просмотреть файл

@ -492,7 +492,7 @@ impl super::Validator {
} => {}
_ => return Err(ExpressionError::InvalidSampleLevelBiasType(expr)),
}
ShaderStages::all()
ShaderStages::FRAGMENT
}
crate::SampleLevel::Gradient { x, y } => {
match resolver[x] {

28
third_party/rust/naga/src/valid/interface.rs поставляемый
Просмотреть файл

@ -33,6 +33,8 @@ pub enum GlobalVariableError {
),
#[error("Initializer doesn't match the variable type")]
InitializerType,
#[error("Initializer can't be used with address space {0:?}")]
InitializerNotAllowed(crate::AddressSpace),
#[error("Storage address space doesn't support write-only access")]
StorageAddressSpaceWriteOnlyNotSupported,
}
@ -90,6 +92,8 @@ pub enum EntryPointError {
ForbiddenStageOperations,
#[error("Global variable {0:?} is used incorrectly as {1:?}")]
InvalidGlobalUsage(Handle<crate::GlobalVariable>, GlobalUse),
#[error("More than 1 push constant variable is used")]
MoreThanOnePushConstantUsed,
#[error("Bindings for {0:?} conflict with other resource")]
BindingCollision(Handle<crate::GlobalVariable>),
#[error("Argument {0} varying error")]
@ -570,6 +574,13 @@ impl super::Validator {
}
if let Some(init) = var.init {
match var.space {
crate::AddressSpace::Private | crate::AddressSpace::Function => {}
_ => {
return Err(GlobalVariableError::InitializerNotAllowed(var.space));
}
}
let decl_ty = &gctx.types[var.ty].inner;
let init_ty = mod_info[init].inner_with(gctx.types);
if !decl_ty.equivalent(init_ty, gctx.types) {
@ -701,6 +712,23 @@ impl super::Validator {
bg.clear();
}
#[cfg(feature = "validate")]
{
let used_push_constants = module
.global_variables
.iter()
.filter(|&(_, var)| var.space == crate::AddressSpace::PushConstant)
.map(|(handle, _)| handle)
.filter(|&handle| !info[handle].is_empty());
// Check if there is more than one push constant, and error if so.
// Use a loop for when returning multiple errors is supported.
#[allow(clippy::never_loop)]
for handle in used_push_constants.skip(1) {
return Err(EntryPointError::MoreThanOnePushConstantUsed
.with_span_handle(handle, &module.global_variables));
}
}
#[cfg(feature = "validate")]
for (var_handle, var) in module.global_variables.iter() {
let usage = info[var_handle];

Просмотреть файл

@ -1 +1 @@
{"files":{"Cargo.toml":"34e400c82ab56ff7ed3b3e7fcd3d96246d68d6a246c7f12b3403465af1006772","LICENSE.APACHE":"a6cba85bc92e0cff7a450b1d873c0eaa2e9fc96bf472df0247a26bec77bf3ff9","LICENSE.MIT":"c7fea58d1cfe49634cd92e54fc10a9d871f4b275321a4cd8c09e449122caaeb4","src/binding_model.rs":"3322f03854b92abeb4aeb65dda4ef776094713bce1277047fe85be73a9bc7b4e","src/command/bind.rs":"c243a4448b87e9b7274b10873b7091b385413ec0a4ea93cccd6d612214ec9abb","src/command/bundle.rs":"b26eb6cb877a19d203e9d2b8ac3b10e81f6a94b8b68617eac97a3b861cbe102b","src/command/clear.rs":"bf78a5eab40f67343054dc982c51f45caab36fb5bddaf065b7a4c1b7a0ada803","src/command/compute.rs":"08dc942a650315f8f768c3e7632c35ceb385e131e83517e91e3144aa8e53b0dc","src/command/draw.rs":"92facdd0e3fd553af590ecbc0de3491f212e237ea66494ff99f67dbf090d10df","src/command/memory_init.rs":"b50d3d20dbf659052f19da2e79469ba6435e06370f19d6ef45e1b1128d9900b7","src/command/mod.rs":"2d3a4ed71cb865918aec2a60449f785d11a5e8bce188c20bbbaae5d25f6d792e","src/command/query.rs":"d39e1b8cb6a054fd31333a916da5d79a6671a724212c90c490c13e55043a1685","src/command/render.rs":"66f4764771b4c5847931b10da270c227df6446ebc65eaa187f5f7764161482d5","src/command/transfer.rs":"2b6f266ba1155ab42bed23b28abffc1008ce26d60b656f56012b896e63daa111","src/conv.rs":"da95b36b7680ae74ebf810ad8f1decf01bd3eeaff44b3c5af1d4b3c3f0e2059a","src/device/global.rs":"714b06c2c51f7f009e111ca5d07712d3ca2f377c04b5e30e3b551f584c3a1a60","src/device/life.rs":"4afecaf3602e23a4d8c795c29b9e5e148866e728b008884d55f658de29af4fe9","src/device/mod.rs":"df2336f19ff74e7339c02a579d970dbecbee88cbc315f8f35fb355888302fe5a","src/device/queue.rs":"c87ac5e748fc80563dab27f05434612580f89092904d7bcf0550f0be8e68218f","src/device/resource.rs":"e99ed822889179dbccb5ce77e3fe480505298c4bcb02da8b70a527744bb6e22f","src/device/trace.rs":"21408dfd2c99e3ce36a77d08ba86cf52f32bb376ed82690bbbf74937bfd42cbe","src/error.rs":"ca37282283985e2b7d184b2ab7ca6f53f726432d920f8d8477bfff6fab9b34e2","src/global.rs":"cf551de97c3eb5acd0c2710da09ebd92cc863ad0bb0f53c0fd4911bf8cd3ad97","src/hal_api.rs":"92a2f0cb80f192693530ed61048919bbad446742c2370bf0944c44b1c5df8362","src/hub.rs":"48ccada54672a88169c23975ddc3758cd32ed5de577c55ca4f665d0ed17d3233","src/id.rs":"f6245d024586c7fe63ded13b3cb926b940c191bbee56aedc655e8cef74bdd66b","src/identity.rs":"3ce6a3b57c7c4fc0808d13cd342d928c214f32368e45c79d8e2bbf8df887f97f","src/init_tracker/buffer.rs":"a0ebf54a1e6d269c7b4aa0ac7bb8b04fd2cea3221a1d058ff33cb683b2aea3e9","src/init_tracker/mod.rs":"0867f79f83555390d0982d1dc6dcf0d4340e10cb89aa633d3c3ecc45deb3c78c","src/init_tracker/texture.rs":"37b6584aaca11c407d91f77002dcbb48d8a4876e27edd1b71b7929ef966f901d","src/instance.rs":"4a515e6c6895107a9ab8ceffad25a9ced03f7c40a198315dabd7c326c8a21d64","src/lib.rs":"27ff8dd787d41cf412e90d0c4674aa70db59e608f9eb3be485c0bd18e9f13369","src/pipeline.rs":"212d469bc1a2256871f64b3f666f05995a92ce39391c32de3856ef2e11c08e16","src/present.rs":"e92aab52a020ae0ee63a25bf5cb3174cdce09792493e2d5e0644c8861436e805","src/registry.rs":"4098413de7f48e9ff15d0246793be47a0d54c95b4c8594baf9fafd222a90ba84","src/resource.rs":"7d1d841dd185a1a857814cab424a8b892aa8731dddf3373ea9436fa619d655b7","src/storage.rs":"bc70689ba299e9b4d9f4992c4d3f4dd36b1d8e71327595094981fdfd624f811a","src/track/buffer.rs":"dd6f632c6f31b15807148d705c516a8a1a8d72d02b137dd3b9d7c939447917cb","src/track/metadata.rs":"a80bd086ce825f7484ce6318a586c482d06fea0efc9c76bfa0124e480cc8b75e","src/track/mod.rs":"42b791d9a41eb6e62f6d79cae7abb5ab523eeb9e6030b0f95bbb0e26d56ad0ec","src/track/range.rs":"5bbfed6e103b3234d9de8e42057022da6d628c2cc1db6bb51b88f87f2d8adf8b","src/track/stateless.rs":"1d786b5e9558672243ba7d913736561065ef2bd5c6105c935e982486d10841f0","src/track/texture.rs":"7d60dc81ba7f7e2c2819525b90e6e6c7760cb0920e36aeefe98e76cedd49d26e","src/validation.rs":"fa84594ad2804684d298adf540b07723dd744bb5d6b19f1e85e00cbe86337f54"},"package":null}
{"files":{"Cargo.toml":"f3fb91bc5168505f7cfa214f6512f80c2045836165790d882da31d5c31ab45de","LICENSE.APACHE":"a6cba85bc92e0cff7a450b1d873c0eaa2e9fc96bf472df0247a26bec77bf3ff9","LICENSE.MIT":"c7fea58d1cfe49634cd92e54fc10a9d871f4b275321a4cd8c09e449122caaeb4","src/binding_model.rs":"f6d9b170a9328751b3109c81d6f1b555a6db1410f1b7e67c59cc596a1fd1d293","src/command/bind.rs":"67b8431a32f403e358b9c1593e6e0d64519f5f0b699059e6ea5374800d5c23d9","src/command/bundle.rs":"b26eb6cb877a19d203e9d2b8ac3b10e81f6a94b8b68617eac97a3b861cbe102b","src/command/clear.rs":"bf78a5eab40f67343054dc982c51f45caab36fb5bddaf065b7a4c1b7a0ada803","src/command/compute.rs":"08dc942a650315f8f768c3e7632c35ceb385e131e83517e91e3144aa8e53b0dc","src/command/draw.rs":"92facdd0e3fd553af590ecbc0de3491f212e237ea66494ff99f67dbf090d10df","src/command/memory_init.rs":"b50d3d20dbf659052f19da2e79469ba6435e06370f19d6ef45e1b1128d9900b7","src/command/mod.rs":"2d3a4ed71cb865918aec2a60449f785d11a5e8bce188c20bbbaae5d25f6d792e","src/command/query.rs":"d39e1b8cb6a054fd31333a916da5d79a6671a724212c90c490c13e55043a1685","src/command/render.rs":"0f8983c27484d5fd4cfcce4d48770e0f878db0e9cf607cf8e28ceba7dc202b95","src/command/transfer.rs":"2b6f266ba1155ab42bed23b28abffc1008ce26d60b656f56012b896e63daa111","src/conv.rs":"da95b36b7680ae74ebf810ad8f1decf01bd3eeaff44b3c5af1d4b3c3f0e2059a","src/device/global.rs":"d89d50d2d1a6c5440fbeb3753ba10b65a86e213ac537989f8fbc49582bd68893","src/device/life.rs":"9ac0aab46de65fd2b493f3ee2c3527e37eaad9dbde1583752958eace71423cef","src/device/mod.rs":"ea7cb19551dcedd010d4c27479f037a34451563d717f6273fe9e3ef29751ff11","src/device/queue.rs":"0cf8b91791d78fb8fa87df1b728b335eeab8511f8f4f9628a9fb90262f33a12d","src/device/resource.rs":"3862067de696bfd9ff2f9ba162835c39e51121e959ea71739e39684edcb16de2","src/device/trace.rs":"21408dfd2c99e3ce36a77d08ba86cf52f32bb376ed82690bbbf74937bfd42cbe","src/error.rs":"ca37282283985e2b7d184b2ab7ca6f53f726432d920f8d8477bfff6fab9b34e2","src/global.rs":"cf551de97c3eb5acd0c2710da09ebd92cc863ad0bb0f53c0fd4911bf8cd3ad97","src/hal_api.rs":"92a2f0cb80f192693530ed61048919bbad446742c2370bf0944c44b1c5df8362","src/hub.rs":"bf10b7c35849bbe63c2541670a56b625ac55370f2cefdf927cec1a0d2e0c64ff","src/id.rs":"f6245d024586c7fe63ded13b3cb926b940c191bbee56aedc655e8cef74bdd66b","src/identity.rs":"3ce6a3b57c7c4fc0808d13cd342d928c214f32368e45c79d8e2bbf8df887f97f","src/init_tracker/buffer.rs":"a0ebf54a1e6d269c7b4aa0ac7bb8b04fd2cea3221a1d058ff33cb683b2aea3e9","src/init_tracker/mod.rs":"0867f79f83555390d0982d1dc6dcf0d4340e10cb89aa633d3c3ecc45deb3c78c","src/init_tracker/texture.rs":"37b6584aaca11c407d91f77002dcbb48d8a4876e27edd1b71b7929ef966f901d","src/instance.rs":"4a515e6c6895107a9ab8ceffad25a9ced03f7c40a198315dabd7c326c8a21d64","src/lib.rs":"27ff8dd787d41cf412e90d0c4674aa70db59e608f9eb3be485c0bd18e9f13369","src/pipeline.rs":"212d469bc1a2256871f64b3f666f05995a92ce39391c32de3856ef2e11c08e16","src/present.rs":"e92aab52a020ae0ee63a25bf5cb3174cdce09792493e2d5e0644c8861436e805","src/registry.rs":"4098413de7f48e9ff15d0246793be47a0d54c95b4c8594baf9fafd222a90ba84","src/resource.rs":"7d1d841dd185a1a857814cab424a8b892aa8731dddf3373ea9436fa619d655b7","src/storage.rs":"bc70689ba299e9b4d9f4992c4d3f4dd36b1d8e71327595094981fdfd624f811a","src/track/buffer.rs":"dd6f632c6f31b15807148d705c516a8a1a8d72d02b137dd3b9d7c939447917cb","src/track/metadata.rs":"a80bd086ce825f7484ce6318a586c482d06fea0efc9c76bfa0124e480cc8b75e","src/track/mod.rs":"42b791d9a41eb6e62f6d79cae7abb5ab523eeb9e6030b0f95bbb0e26d56ad0ec","src/track/range.rs":"5bbfed6e103b3234d9de8e42057022da6d628c2cc1db6bb51b88f87f2d8adf8b","src/track/stateless.rs":"1d786b5e9558672243ba7d913736561065ef2bd5c6105c935e982486d10841f0","src/track/texture.rs":"7d60dc81ba7f7e2c2819525b90e6e6c7760cb0920e36aeefe98e76cedd49d26e","src/validation.rs":"e01e2504cc55bb360dd2294735d516b0ba024605b10d69a8f1fba527f4b4625d"},"package":null}

4
third_party/rust/wgpu-core/Cargo.toml поставляемый
Просмотреть файл

@ -11,6 +11,7 @@
[package]
edition = "2021"
rust-version = "1.65"
name = "wgpu-core"
version = "0.17.0"
authors = ["wgpu developers"]
@ -55,7 +56,7 @@ package = "wgpu-hal"
[dependencies.naga]
version = "0.13.0"
git = "https://github.com/gfx-rs/naga"
rev = "df8107b7"
rev = "6668d0694cc51ee66c71c2ca3a1ab1081956299b"
features = [
"clone",
"span",
@ -85,7 +86,6 @@ path = "../wgpu-types"
package = "wgpu-types"
[features]
angle = ["hal/gles"]
default = ["link"]
dx11 = ["hal/dx11"]
dx12 = ["hal/dx12"]

Просмотреть файл

@ -446,18 +446,25 @@ pub type BindGroupLayouts<A> = crate::storage::Storage<BindGroupLayout<A>, BindG
/// - produced bind groups
/// - produced pipeline layouts
/// - pipelines with implicit layouts
#[derive(Debug)]
pub struct BindGroupLayout<A: hal::Api> {
pub(crate) raw: A::BindGroupLayout,
pub(crate) device_id: Stored<DeviceId>,
pub(crate) multi_ref_count: MultiRefCount,
pub(crate) entries: BindEntryMap,
// When a layout created and there already exists a compatible layout the new layout
// keeps a reference to the older compatible one. In some places we substitute the
// bind group layout id with its compatible sibling.
// Since this substitution can come at a cost, it is skipped when wgpu-core generates
// its own resource IDs.
pub(crate) compatible_layout: Option<Valid<BindGroupLayoutId>>,
pub(crate) inner: BglOrDuplicate<A>,
}
pub(crate) enum BglOrDuplicate<A: hal::Api> {
Inner(BindGroupLayoutInner<A>),
Duplicate(Valid<BindGroupLayoutId>),
}
pub struct BindGroupLayoutInner<A: hal::Api> {
pub(crate) raw: A::BindGroupLayout,
pub(crate) entries: BindEntryMap,
#[allow(unused)]
pub(crate) dynamic_count: usize,
pub(crate) count_validator: BindingTypeMaxCountValidator,
@ -465,6 +472,34 @@ pub struct BindGroupLayout<A: hal::Api> {
pub(crate) label: String,
}
impl<A: hal::Api> BindGroupLayout<A> {
#[track_caller]
pub(crate) fn assume_deduplicated(&self) -> &BindGroupLayoutInner<A> {
self.as_inner().unwrap()
}
pub(crate) fn as_inner(&self) -> Option<&BindGroupLayoutInner<A>> {
match self.inner {
BglOrDuplicate::Inner(ref inner) => Some(inner),
BglOrDuplicate::Duplicate(_) => None,
}
}
pub(crate) fn into_inner(self) -> Option<BindGroupLayoutInner<A>> {
match self.inner {
BglOrDuplicate::Inner(inner) => Some(inner),
BglOrDuplicate::Duplicate(_) => None,
}
}
pub(crate) fn as_duplicate(&self) -> Option<Valid<BindGroupLayoutId>> {
match self.inner {
BglOrDuplicate::Duplicate(id) => Some(id),
BglOrDuplicate::Inner(_) => None,
}
}
}
impl<A: hal::Api> Resource for BindGroupLayout<A> {
const TYPE: &'static str = "BindGroupLayout";
@ -474,7 +509,7 @@ impl<A: hal::Api> Resource for BindGroupLayout<A> {
fn label(&self) -> &str {
#[cfg(debug_assertions)]
return &self.label;
return self.as_inner().map_or("", |inner| &inner.label);
#[cfg(not(debug_assertions))]
return "";
}
@ -486,8 +521,8 @@ pub(crate) fn try_get_bind_group_layout<A: HalApi>(
id: BindGroupLayoutId,
) -> Option<&BindGroupLayout<A>> {
let layout = layouts.get(id).ok()?;
if let Some(compat) = layout.compatible_layout {
return Some(&layouts[compat]);
if let BglOrDuplicate::Duplicate(original_id) = layout.inner {
return Some(&layouts[original_id]);
}
Some(layout)
@ -499,9 +534,8 @@ pub(crate) fn get_bind_group_layout<A: HalApi>(
) -> (Valid<BindGroupLayoutId>, &BindGroupLayout<A>) {
let layout = &layouts[id];
layout
.compatible_layout
.map(|compat| (compat, &layouts[compat]))
.unwrap_or((id, layout))
.as_duplicate()
.map_or((id, layout), |deduped| (deduped, &layouts[deduped]))
}
#[derive(Clone, Debug, Error)]

Просмотреть файл

@ -38,7 +38,7 @@ mod compat {
}
if let Some(id) = self.assigned {
return bind_group_layouts[id].compatible_layout == self.expected;
return bind_group_layouts[id].as_duplicate() == self.expected;
}
false

Просмотреть файл

@ -10,7 +10,7 @@ use crate::{
RenderCommand, RenderCommandError, StateChange,
},
device::{
AttachmentData, Device, MissingDownlevelFlags, MissingFeatures,
AttachmentData, Device, DeviceError, MissingDownlevelFlags, MissingFeatures,
RenderPassCompatibilityCheckType, RenderPassCompatibilityError, RenderPassContext,
},
error::{ErrorFormatter, PrettyError},
@ -18,7 +18,6 @@ use crate::{
hal_api::HalApi,
hub::Token,
id,
id::DeviceId,
identity::GlobalIdentityHandlerFactory,
init_tracker::{MemoryInitKind, TextureInitRange, TextureInitTrackerAction},
pipeline::{self, PipelineFlags},
@ -520,12 +519,12 @@ pub enum ColorAttachmentError {
/// Error encountered when performing a render pass.
#[derive(Clone, Debug, Error)]
pub enum RenderPassErrorInner {
#[error(transparent)]
Device(DeviceError),
#[error(transparent)]
ColorAttachment(#[from] ColorAttachmentError),
#[error(transparent)]
Encoder(#[from] CommandEncoderError),
#[error("Device {0:?} is invalid")]
InvalidDevice(DeviceId),
#[error("Attachment texture view {0:?} is invalid")]
InvalidAttachment(id::TextureViewId),
#[error("The format of the depth-stencil attachment ({0:?}) is not a depth-stencil format")]
@ -658,6 +657,12 @@ impl From<MissingTextureUsageError> for RenderPassErrorInner {
}
}
impl From<DeviceError> for RenderPassErrorInner {
fn from(error: DeviceError) -> Self {
Self::Device(error)
}
}
/// Error encountered when performing a render pass.
#[derive(Clone, Debug, Error)]
#[error("{scope}")]
@ -1314,7 +1319,10 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
timestamp_writes: Option<&RenderPassTimestampWrites>,
occlusion_query_set_id: Option<id::QuerySetId>,
) -> Result<(), RenderPassError> {
profiling::scope!("CommandEncoder::run_render_pass");
profiling::scope!(
"CommandEncoder::run_render_pass {}",
base.label.unwrap_or("")
);
let init_scope = PassErrorScope::Pass(encoder_id);
let hub = A::hub(self);
@ -1348,12 +1356,11 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
});
}
let device = &device_guard[cmd_buf.device_id.value];
let device_id = cmd_buf.device_id.value;
let device = &device_guard[device_id];
if !device.is_valid() {
return Err(RenderPassErrorInner::InvalidDevice(
cmd_buf.device_id.value.0,
))
.map_pass_err(init_scope);
return Err(DeviceError::Invalid).map_pass_err(init_scope);
}
cmd_buf.encoder.open_pass(base.label);
@ -1423,6 +1430,8 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
num_dynamic_offsets,
bind_group_id,
} => {
log::trace!("RenderPass::set_bind_group {index} {bind_group_id:?}");
let scope = PassErrorScope::SetBindGroup(bind_group_id);
let max_bind_groups = device.limits.max_bind_groups;
if index >= max_bind_groups {
@ -1446,6 +1455,11 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
.add_single(&*bind_group_guard, bind_group_id)
.ok_or(RenderCommandError::InvalidBindGroup(bind_group_id))
.map_pass_err(scope)?;
if bind_group.device_id.value != device_id {
return Err(DeviceError::WrongDevice).map_pass_err(scope);
}
bind_group
.validate_dynamic_bindings(index, &temp_offsets, &cmd_buf.limits)
.map_pass_err(scope)?;
@ -1501,6 +1515,8 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
}
}
RenderCommand::SetPipeline(pipeline_id) => {
log::trace!("RenderPass::set_pipeline {pipeline_id:?}");
let scope = PassErrorScope::SetPipelineRender(pipeline_id);
state.pipeline = Some(pipeline_id);
@ -1511,6 +1527,10 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
.ok_or(RenderCommandError::InvalidPipeline(pipeline_id))
.map_pass_err(scope)?;
if pipeline.device_id.value != device_id {
return Err(DeviceError::WrongDevice).map_pass_err(scope);
}
info.context
.check_compatible(
&pipeline.pass_context,
@ -1620,12 +1640,19 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
offset,
size,
} => {
log::trace!("RenderPass::set_index_buffer {buffer_id:?}");
let scope = PassErrorScope::SetIndexBuffer(buffer_id);
let buffer: &Buffer<A> = info
.usage_scope
.buffers
.merge_single(&*buffer_guard, buffer_id, hal::BufferUses::INDEX)
.map_pass_err(scope)?;
if buffer.device_id.value != device_id {
return Err(DeviceError::WrongDevice).map_pass_err(scope);
}
check_buffer_usage(buffer.usage, BufferUsages::INDEX)
.map_pass_err(scope)?;
let buf_raw = buffer
@ -1666,12 +1693,19 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
offset,
size,
} => {
log::trace!("RenderPass::set_vertex_buffer {slot} {buffer_id:?}");
let scope = PassErrorScope::SetVertexBuffer(buffer_id);
let buffer: &Buffer<A> = info
.usage_scope
.buffers
.merge_single(&*buffer_guard, buffer_id, hal::BufferUses::VERTEX)
.map_pass_err(scope)?;
if buffer.device_id.value != device_id {
return Err(DeviceError::WrongDevice).map_pass_err(scope);
}
check_buffer_usage(buffer.usage, BufferUsages::VERTEX)
.map_pass_err(scope)?;
let buf_raw = buffer
@ -1713,6 +1747,8 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
state.vertex.update_limits();
}
RenderCommand::SetBlendConstant(ref color) => {
log::trace!("RenderPass::set_blend_constant");
state.blend_constant = OptionalState::Set;
let array = [
color.r as f32,
@ -1725,6 +1761,8 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
}
}
RenderCommand::SetStencilReference(value) => {
log::trace!("RenderPass::set_stencil_reference {value}");
state.stencil_reference = value;
if state
.pipeline_flags
@ -1740,6 +1778,8 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
depth_min,
depth_max,
} => {
log::trace!("RenderPass::set_viewport {rect:?}");
let scope = PassErrorScope::SetViewport;
if rect.x < 0.0
|| rect.y < 0.0
@ -1776,6 +1816,8 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
size_bytes,
values_offset,
} => {
log::trace!("RenderPass::set_push_constants");
let scope = PassErrorScope::SetPushConstant;
let values_offset = values_offset
.ok_or(RenderPassErrorInner::InvalidValuesOffset)
@ -1804,6 +1846,8 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
}
}
RenderCommand::SetScissor(ref rect) => {
log::trace!("RenderPass::set_scissor_rect {rect:?}");
let scope = PassErrorScope::SetScissorRect;
if rect.x + rect.w > info.extent.width
|| rect.y + rect.h > info.extent.height
@ -1827,6 +1871,10 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
first_vertex,
first_instance,
} => {
log::trace!(
"RenderPass::draw {vertex_count} {instance_count} {first_vertex} {first_instance}"
);
let indexed = false;
let scope = PassErrorScope::Draw {
indexed,
@ -1869,6 +1917,8 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
base_vertex,
first_instance,
} => {
log::trace!("RenderPass::draw_indexed {index_count} {instance_count} {first_index} {base_vertex} {first_instance}");
let indexed = true;
let scope = PassErrorScope::Draw {
indexed,
@ -1917,6 +1967,8 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
count,
indexed,
} => {
log::trace!("RenderPass::draw_indirect (indexed:{indexed}) {buffer_id:?} {offset} {count:?}");
let scope = PassErrorScope::Draw {
indexed,
indirect: true,
@ -1991,6 +2043,8 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
max_count,
indexed,
} => {
log::trace!("RenderPass::multi_draw_indirect_count (indexed:{indexed}) {buffer_id:?} {offset} {count_buffer_id:?} {count_buffer_offset:?} {max_count:?}");
let scope = PassErrorScope::Draw {
indexed,
indirect: true,
@ -2104,12 +2158,16 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
let label =
str::from_utf8(&base.string_data[string_offset..string_offset + len])
.unwrap();
log::trace!("RenderPass::push_debug_group {label:?}");
string_offset += len;
unsafe {
raw.begin_debug_marker(label);
}
}
RenderCommand::PopDebugGroup => {
log::trace!("RenderPass::pop_debug_group");
let scope = PassErrorScope::PopDebugGroup;
if state.debug_scope_depth == 0 {
return Err(RenderPassErrorInner::InvalidPopDebugGroup)
@ -2124,6 +2182,7 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
let label =
str::from_utf8(&base.string_data[string_offset..string_offset + len])
.unwrap();
log::trace!("RenderPass::insert_debug_marker {label:?}");
string_offset += len;
unsafe {
raw.insert_debug_marker(label);
@ -2133,6 +2192,7 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
query_set_id,
query_index,
} => {
log::trace!("RenderPass::write_timestamps {query_set_id:?} {query_index}");
let scope = PassErrorScope::WriteTimestamp;
device
@ -2156,6 +2216,7 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
.map_pass_err(scope)?;
}
RenderCommand::BeginOcclusionQuery { query_index } => {
log::trace!("RenderPass::begin_occlusion_query {query_index}");
let scope = PassErrorScope::BeginOcclusionQuery;
let query_set_id = occlusion_query_set_id
@ -2180,6 +2241,7 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
.map_pass_err(scope)?;
}
RenderCommand::EndOcclusionQuery => {
log::trace!("RenderPass::end_occlusion_query");
let scope = PassErrorScope::EndOcclusionQuery;
end_occlusion_query(raw, &*query_set_guard, &mut active_query)
@ -2189,6 +2251,7 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
query_set_id,
query_index,
} => {
log::trace!("RenderPass::begin_pipeline_statistics_query {query_set_id:?} {query_index}");
let scope = PassErrorScope::BeginPipelineStatisticsQuery;
let query_set = cmd_buf
@ -2209,12 +2272,14 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
.map_pass_err(scope)?;
}
RenderCommand::EndPipelineStatisticsQuery => {
log::trace!("RenderPass::end_pipeline_statistics_query");
let scope = PassErrorScope::EndPipelineStatisticsQuery;
end_pipeline_statistics_query(raw, &*query_set_guard, &mut active_query)
.map_pass_err(scope)?;
}
RenderCommand::ExecuteBundle(bundle_id) => {
log::trace!("RenderPass::execute_bundle {bundle_id:?}");
let scope = PassErrorScope::ExecuteBundle;
let bundle: &command::RenderBundle<A> = cmd_buf
.trackers
@ -2223,6 +2288,10 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
.ok_or(RenderCommandError::InvalidRenderBundle(bundle_id))
.map_pass_err(scope)?;
if bundle.device_id.value != device_id {
return Err(DeviceError::WrongDevice).map_pass_err(scope);
}
info.context
.check_compatible(
&bundle.context,
@ -2393,7 +2462,6 @@ pub mod render_ffi {
pass: &mut RenderPass,
pipeline_id: id::RenderPipelineId,
) {
log::trace!("RenderPass::set_pipeline {pipeline_id:?}");
if pass.current_pipeline.set_and_check_redundant(pipeline_id) {
return;
}
@ -2411,7 +2479,6 @@ pub mod render_ffi {
offset: BufferAddress,
size: Option<BufferSize>,
) {
log::trace!("RenderPass::set_vertex_buffer {buffer_id:?}");
pass.base.commands.push(RenderCommand::SetVertexBuffer {
slot,
buffer_id,
@ -2428,13 +2495,11 @@ pub mod render_ffi {
offset: BufferAddress,
size: Option<BufferSize>,
) {
log::trace!("RenderPass::set_index_buffer {buffer:?}");
pass.set_index_buffer(buffer, index_format, offset, size);
}
#[no_mangle]
pub extern "C" fn wgpu_render_pass_set_blend_constant(pass: &mut RenderPass, color: &Color) {
log::trace!("RenderPass::set_blend_constant");
pass.base
.commands
.push(RenderCommand::SetBlendConstant(*color));
@ -2442,7 +2507,6 @@ pub mod render_ffi {
#[no_mangle]
pub extern "C" fn wgpu_render_pass_set_stencil_reference(pass: &mut RenderPass, value: u32) {
log::trace!("RenderPass::set_stencil_reference {value}");
pass.base
.commands
.push(RenderCommand::SetStencilReference(value));
@ -2458,7 +2522,6 @@ pub mod render_ffi {
depth_min: f32,
depth_max: f32,
) {
log::trace!("RenderPass::set_viewport {x} {y} {w} {h}");
pass.base.commands.push(RenderCommand::SetViewport {
rect: Rect { x, y, w, h },
depth_min,
@ -2474,7 +2537,6 @@ pub mod render_ffi {
w: u32,
h: u32,
) {
log::trace!("RenderPass::set_scissor_rect {x} {y} {w} {h}");
pass.base
.commands
.push(RenderCommand::SetScissor(Rect { x, y, w, h }));
@ -2492,7 +2554,6 @@ pub mod render_ffi {
size_bytes: u32,
data: *const u8,
) {
log::trace!("RenderPass::set_push_constants");
assert_eq!(
offset & (wgt::PUSH_CONSTANT_ALIGNMENT - 1),
0,
@ -2530,10 +2591,6 @@ pub mod render_ffi {
first_vertex: u32,
first_instance: u32,
) {
log::trace!(
"RenderPass::draw {vertex_count} {instance_count} {first_vertex} {first_instance}"
);
pass.base.commands.push(RenderCommand::Draw {
vertex_count,
instance_count,
@ -2551,7 +2608,6 @@ pub mod render_ffi {
base_vertex: i32,
first_instance: u32,
) {
log::trace!("RenderPass::draw_indexed {index_count} {instance_count} {first_index} {base_vertex} {first_instance}");
pass.base.commands.push(RenderCommand::DrawIndexed {
index_count,
instance_count,
@ -2567,7 +2623,6 @@ pub mod render_ffi {
buffer_id: id::BufferId,
offset: BufferAddress,
) {
log::trace!("RenderPass::draw_indirect {buffer_id:?} {offset}");
pass.base.commands.push(RenderCommand::MultiDrawIndirect {
buffer_id,
offset,
@ -2582,7 +2637,6 @@ pub mod render_ffi {
buffer_id: id::BufferId,
offset: BufferAddress,
) {
log::trace!("RenderPass::draw_indexed_indirect {buffer_id:?} {offset}");
pass.base.commands.push(RenderCommand::MultiDrawIndirect {
buffer_id,
offset,
@ -2598,7 +2652,6 @@ pub mod render_ffi {
offset: BufferAddress,
count: u32,
) {
log::trace!("RenderPass::multi_draw_indirect {buffer_id:?} {offset} {count}");
pass.base.commands.push(RenderCommand::MultiDrawIndirect {
buffer_id,
offset,
@ -2614,7 +2667,6 @@ pub mod render_ffi {
offset: BufferAddress,
count: u32,
) {
log::trace!("RenderPass::multi_draw_indexed_indirect {buffer_id:?} {offset} {count}");
pass.base.commands.push(RenderCommand::MultiDrawIndirect {
buffer_id,
offset,
@ -2632,7 +2684,6 @@ pub mod render_ffi {
count_buffer_offset: BufferAddress,
max_count: u32,
) {
log::trace!("RenderPass::multi_draw_indirect_count {buffer_id:?} {offset} {count_buffer_id:?} {count_buffer_offset} {max_count}");
pass.base
.commands
.push(RenderCommand::MultiDrawIndirectCount {
@ -2654,7 +2705,6 @@ pub mod render_ffi {
count_buffer_offset: BufferAddress,
max_count: u32,
) {
log::trace!("RenderPass::multi_draw_indexed_indirect_count {buffer_id:?} {offset} {count_buffer_id:?} {count_buffer_offset} {max_count}");
pass.base
.commands
.push(RenderCommand::MultiDrawIndirectCount {
@ -2677,10 +2727,7 @@ pub mod render_ffi {
label: RawString,
color: u32,
) {
let cstr = unsafe { ffi::CStr::from_ptr(label) };
log::trace!("RenderPass::push_debug_group {cstr:?}");
let bytes = cstr.to_bytes();
let bytes = unsafe { ffi::CStr::from_ptr(label) }.to_bytes();
pass.base.string_data.extend_from_slice(bytes);
pass.base.commands.push(RenderCommand::PushDebugGroup {
@ -2691,7 +2738,6 @@ pub mod render_ffi {
#[no_mangle]
pub extern "C" fn wgpu_render_pass_pop_debug_group(pass: &mut RenderPass) {
log::trace!("RenderPass::pop_debug_group");
pass.base.commands.push(RenderCommand::PopDebugGroup);
}
@ -2705,10 +2751,7 @@ pub mod render_ffi {
label: RawString,
color: u32,
) {
let cstr = unsafe { ffi::CStr::from_ptr(label) };
log::trace!("RenderPass::insert_debug_marker {cstr:?}");
let bytes = cstr.to_bytes();
let bytes = unsafe { ffi::CStr::from_ptr(label) }.to_bytes();
pass.base.string_data.extend_from_slice(bytes);
pass.base.commands.push(RenderCommand::InsertDebugMarker {
@ -2723,7 +2766,6 @@ pub mod render_ffi {
query_set_id: id::QuerySetId,
query_index: u32,
) {
log::trace!("RenderPass::write_timestamps {query_set_id:?} {query_index}");
pass.base.commands.push(RenderCommand::WriteTimestamp {
query_set_id,
query_index,
@ -2735,7 +2777,6 @@ pub mod render_ffi {
pass: &mut RenderPass,
query_index: u32,
) {
log::trace!("RenderPass::begin_occlusion_query {query_index}");
pass.base
.commands
.push(RenderCommand::BeginOcclusionQuery { query_index });
@ -2743,7 +2784,6 @@ pub mod render_ffi {
#[no_mangle]
pub extern "C" fn wgpu_render_pass_end_occlusion_query(pass: &mut RenderPass) {
log::trace!("RenderPass::end_occlusion_query");
pass.base.commands.push(RenderCommand::EndOcclusionQuery);
}
@ -2753,7 +2793,6 @@ pub mod render_ffi {
query_set_id: id::QuerySetId,
query_index: u32,
) {
log::trace!("RenderPass::begin_pipeline_statistics_query {query_set_id:?} {query_index}");
pass.base
.commands
.push(RenderCommand::BeginPipelineStatisticsQuery {
@ -2764,7 +2803,6 @@ pub mod render_ffi {
#[no_mangle]
pub extern "C" fn wgpu_render_pass_end_pipeline_statistics_query(pass: &mut RenderPass) {
log::trace!("RenderPass::end_pipeline_statistics_query");
pass.base
.commands
.push(RenderCommand::EndPipelineStatisticsQuery);
@ -2780,7 +2818,6 @@ pub mod render_ffi {
render_bundle_ids: *const id::RenderBundleId,
render_bundle_ids_length: usize,
) {
log::trace!("RenderPass::execute_bundles");
for &bundle_id in
unsafe { slice::from_raw_parts(render_bundle_ids, render_bundle_ids_length) }
{

Просмотреть файл

@ -1,7 +1,8 @@
#[cfg(feature = "trace")]
use crate::device::trace;
use crate::{
binding_model, command, conv,
binding_model::{self, BindGroupLayout},
command, conv,
device::{life::WaitIdleError, map_buffer, queue, Device, DeviceError, HostMap},
global::Global,
hal_api::HalApi,
@ -262,7 +263,7 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
};
let id = fid.assign(buffer, &mut token);
log::trace!("Device::create_buffer -> {:?}", id);
log::trace!("Device::create_buffer -> {:?}", id.0);
device
.trackers
@ -616,7 +617,7 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
let ref_count = texture.life_guard.add_ref();
let id = fid.assign(texture, &mut token);
log::trace!("Device::create_texture -> {id:?}");
log::trace!("Device::create_texture -> {:?}", id.0);
device.trackers.lock().textures.insert_single(
id.0,
@ -696,7 +697,7 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
let ref_count = texture.life_guard.add_ref();
let id = fid.assign(texture, &mut token);
log::trace!("Device::create_texture -> {id:?}");
log::trace!("Device::create_texture -> {:?}", id.0);
device.trackers.lock().textures.insert_single(
id.0,
@ -756,7 +757,7 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
let ref_count = buffer.life_guard.add_ref();
let id = fid.assign(buffer, &mut token);
log::trace!("Device::create_buffer -> {id:?}");
log::trace!("Device::create_buffer -> {:?}", id.0);
device
.trackers
@ -1115,7 +1116,7 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
}
let mut compatible_layout = None;
{
let layout = {
let (bgl_guard, _) = hub.bind_group_layouts.read(&mut token);
if let Some(id) =
Device::deduplicate_bind_group_layout(device_id, &entry_map, &*bgl_guard)
@ -1134,19 +1135,26 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
compatible_layout = Some(id::Valid(id));
}
}
let mut layout = match device.create_bind_group_layout(
device_id,
desc.label.borrow_option(),
entry_map,
) {
Ok(layout) => layout,
Err(e) => break e,
if let Some(original_id) = compatible_layout {
let original = &bgl_guard[original_id];
BindGroupLayout {
device_id: original.device_id.clone(),
inner: crate::binding_model::BglOrDuplicate::Duplicate(original_id),
multi_ref_count: crate::MultiRefCount::new(),
}
} else {
match device.create_bind_group_layout(
device_id,
desc.label.borrow_option(),
entry_map,
) {
Ok(layout) => layout,
Err(e) => break e,
}
}
};
layout.compatible_layout = compatible_layout;
let id = fid.assign(layout, &mut token);
if let Some(dupe) = compatible_layout {
@ -1318,8 +1326,12 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
Err(..) => break binding_model::CreateBindGroupError::InvalidLayout,
};
if bind_group_layout.device_id.value.0 != device_id {
break DeviceError::WrongDevice.into();
}
let mut layout_id = id::Valid(desc.layout);
if let Some(id) = bind_group_layout.compatible_layout {
if let Some(id) = bind_group_layout.as_duplicate() {
layout_id = id;
bind_group_layout = &bind_group_layout_guard[id];
}
@ -1869,7 +1881,7 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
let ref_count = pipeline.life_guard.add_ref();
let id = fid.assign(pipeline, &mut token);
log::trace!("Device::create_render_pipeline -> {id:?}");
log::trace!("Device::create_render_pipeline -> {:?}", id.0);
device
.trackers
@ -1916,7 +1928,24 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
None => break binding_model::GetBindGroupLayoutError::InvalidGroupIndex(index),
};
bgl_guard[*id].multi_ref_count.inc();
let layout = &bgl_guard[*id];
layout.multi_ref_count.inc();
if G::ids_are_generated_in_wgpu() {
return (id.0, None);
}
// The ID is provided externally, so we must create a new bind group layout
// with the given ID as a duplicate of the existing one.
let new_layout = BindGroupLayout {
device_id: layout.device_id.clone(),
inner: crate::binding_model::BglOrDuplicate::<A>::Duplicate(*id),
multi_ref_count: crate::MultiRefCount::new(),
};
let fid = hub.bind_group_layouts.prepare(id_in);
let id = fid.assign(new_layout, &mut Token::root());
return (id.0, None);
};
@ -2014,7 +2043,7 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
let ref_count = pipeline.life_guard.add_ref();
let id = fid.assign(pipeline, &mut token);
log::trace!("Device::create_compute_pipeline -> {id:?}");
log::trace!("Device::create_compute_pipeline -> {:?}", id.0);
device
.trackers

Просмотреть файл

@ -776,7 +776,7 @@ impl<A: HalApi> LifetimeTracker<A> {
if bgl.multi_ref_count.dec_and_check_empty() {
// If This layout points to a compatible one, go over the latter
// to decrement the ref count and potentially destroy it.
bgl_to_check = bgl.compatible_layout;
bgl_to_check = bgl.as_duplicate();
log::debug!("Bind group layout {:?} will be destroyed", id);
#[cfg(feature = "trace")]
@ -786,7 +786,9 @@ impl<A: HalApi> LifetimeTracker<A> {
if let Some(lay) =
hub.bind_group_layouts.unregister_locked(id.0, &mut *guard)
{
self.free_resources.bind_group_layouts.push(lay.raw);
if let Some(inner) = lay.into_inner() {
self.free_resources.bind_group_layouts.push(inner.raw);
}
}
}
}

Просмотреть файл

@ -300,6 +300,8 @@ pub enum DeviceError {
OutOfMemory,
#[error("Creation of a resource failed for a reason other than running out of memory.")]
ResourceCreationFailed,
#[error("Attempt to use a resource with a different device from the one that created it")]
WrongDevice,
}
impl From<hal::DeviceError> for DeviceError {

Просмотреть файл

@ -397,6 +397,7 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
}
let result = self.queue_write_staging_buffer_impl(
queue_id,
device,
device_token,
&staging_buffer,
@ -464,6 +465,7 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
}
let result = self.queue_write_staging_buffer_impl(
queue_id,
device,
device_token,
&staging_buffer,
@ -531,6 +533,7 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
fn queue_write_staging_buffer_impl<A: HalApi>(
&self,
device_id: id::DeviceId,
device: &mut super::Device<A>,
device_token: &mut Token<super::Device<A>>,
staging_buffer: &StagingBuffer<A>,
@ -551,6 +554,10 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
.as_ref()
.ok_or(TransferError::InvalidBuffer(buffer_id))?;
if dst.device_id.value.0 != device_id {
return Err(DeviceError::WrongDevice.into());
}
let src_buffer_size = staging_buffer.size;
self.queue_validate_write_buffer_impl(dst, buffer_id, buffer_offset, src_buffer_size)?;
@ -627,6 +634,10 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
.get_mut(destination.texture)
.map_err(|_| TransferError::InvalidTexture(destination.texture))?;
if dst.device_id.value.0 != queue_id {
return Err(DeviceError::WrongDevice.into());
}
if !dst.desc.usage.contains(wgt::TextureUsages::COPY_DST) {
return Err(
TransferError::MissingCopyDstUsageFlag(None, Some(destination.texture)).into(),
@ -1105,6 +1116,11 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
Some(cmdbuf) => cmdbuf,
None => continue,
};
if cmdbuf.device_id.value.0 != queue_id {
return Err(DeviceError::WrongDevice.into());
}
#[cfg(feature = "trace")]
if let Some(ref trace) = device.trace {
trace.lock().add(Action::Submit(

Просмотреть файл

@ -1,7 +1,10 @@
#[cfg(feature = "trace")]
use crate::device::trace;
use crate::{
binding_model::{self, get_bind_group_layout, try_get_bind_group_layout},
binding_model::{
self, get_bind_group_layout, try_get_bind_group_layout, BglOrDuplicate,
BindGroupLayoutInner,
},
command, conv,
device::life::WaitIdleError,
device::{
@ -1392,8 +1395,9 @@ impl<A: HalApi> Device<A> {
.iter(self_id.backend())
.find(|&(_, bgl)| {
bgl.device_id.value.0 == self_id
&& bgl.compatible_layout.is_none()
&& bgl.entries == *entry_map
&& bgl
.as_inner()
.map_or(false, |inner| inner.entries == *entry_map)
})
.map(|(id, value)| {
value.multi_ref_count.inc();
@ -1408,7 +1412,12 @@ impl<A: HalApi> Device<A> {
pipeline_layout
.bind_group_layout_ids
.iter()
.map(|&id| &bgl_guard[id].entries)
.map(|&id| {
&get_bind_group_layout(bgl_guard, id)
.1
.assume_deduplicated()
.entries
})
.collect()
}
@ -1427,7 +1436,9 @@ impl<A: HalApi> Device<A> {
.iter()
.enumerate()
.map(|(group_index, &bgl_id)| pipeline::LateSizedBufferGroup {
shader_sizes: bgl_guard[bgl_id]
shader_sizes: get_bind_group_layout(bgl_guard, bgl_id)
.1
.assume_deduplicated()
.entries
.values()
.filter_map(|entry| match entry.ty {
@ -1639,25 +1650,27 @@ impl<A: HalApi> Device<A> {
.map_err(binding_model::CreateBindGroupLayoutError::TooManyBindings)?;
Ok(binding_model::BindGroupLayout {
raw,
device_id: Stored {
value: id::Valid(self_id),
ref_count: self.life_guard.add_ref(),
},
multi_ref_count: MultiRefCount::new(),
dynamic_count: entry_map
.values()
.filter(|b| b.ty.has_dynamic_offset())
.count(),
count_validator,
entries: entry_map,
#[cfg(debug_assertions)]
label: label.unwrap_or("").to_string(),
compatible_layout: None,
inner: BglOrDuplicate::Inner(BindGroupLayoutInner {
raw,
dynamic_count: entry_map
.values()
.filter(|b| b.ty.has_dynamic_offset())
.count(),
count_validator,
entries: entry_map,
#[cfg(debug_assertions)]
label: label.unwrap_or("").to_string(),
}),
})
}
fn create_buffer_binding<'a>(
device_id: id::DeviceId,
bb: &binding_model::BufferBinding,
binding: u32,
decl: &wgt::BindGroupLayoutEntry,
@ -1715,6 +1728,11 @@ impl<A: HalApi> Device<A> {
.buffers
.add_single(storage, bb.buffer_id, internal_use)
.ok_or(Error::InvalidBuffer(bb.buffer_id))?;
if buffer.device_id.value.0 != device_id {
return Err(DeviceError::WrongDevice.into());
}
check_buffer_usage(buffer.usage, pub_usage)?;
let raw_buffer = buffer
.raw
@ -1785,6 +1803,7 @@ impl<A: HalApi> Device<A> {
}
fn create_texture_binding(
device_id: id::DeviceId,
view: &resource::TextureView<A>,
texture_guard: &Storage<resource::Texture<A>, id::TextureId>,
internal_use: hal::TextureUses,
@ -1806,6 +1825,11 @@ impl<A: HalApi> Device<A> {
.ok_or(binding_model::CreateBindGroupError::InvalidTexture(
view.parent_id.value.0,
))?;
if texture.device_id.value.0 != device_id {
return Err(DeviceError::WrongDevice.into());
}
check_texture_usage(texture.desc.usage, pub_usage)?;
used_texture_ranges.push(TextureInitTrackerAction {
@ -1823,6 +1847,8 @@ impl<A: HalApi> Device<A> {
Ok(())
}
// This function expects the provided bind group layout to be resolved
// (not passing a duplicate) beforehand.
pub(super) fn create_bind_group<G: GlobalIdentityHandlerFactory>(
&self,
self_id: id::DeviceId,
@ -1837,7 +1863,7 @@ impl<A: HalApi> Device<A> {
// Check that the number of entries in the descriptor matches
// the number of entries in the layout.
let actual = desc.entries.len();
let expected = layout.entries.len();
let expected = layout.assume_deduplicated().entries.len();
if actual != expected {
return Err(Error::BindingsNumMismatch { expected, actual });
}
@ -1868,12 +1894,14 @@ impl<A: HalApi> Device<A> {
let binding = entry.binding;
// Find the corresponding declaration in the layout
let decl = layout
.assume_deduplicated()
.entries
.get(&binding)
.ok_or(Error::MissingBindingDeclaration(binding))?;
let (res_index, count) = match entry.resource {
Br::Buffer(ref bb) => {
let bb = Self::create_buffer_binding(
self_id,
bb,
binding,
decl,
@ -1896,6 +1924,7 @@ impl<A: HalApi> Device<A> {
let res_index = hal_buffers.len();
for bb in bindings_array.iter() {
let bb = Self::create_buffer_binding(
self_id,
bb,
binding,
decl,
@ -1918,6 +1947,10 @@ impl<A: HalApi> Device<A> {
.add_single(&*sampler_guard, id)
.ok_or(Error::InvalidSampler(id))?;
if sampler.device_id.value.0 != self_id {
return Err(DeviceError::WrongDevice.into());
}
// Allowed sampler values for filtering and comparison
let (allowed_filtering, allowed_comparison) = match ty {
wgt::SamplerBindingType::Filtering => (None, false),
@ -1966,6 +1999,11 @@ impl<A: HalApi> Device<A> {
.samplers
.add_single(&*sampler_guard, id)
.ok_or(Error::InvalidSampler(id))?;
if sampler.device_id.value.0 != self_id {
return Err(DeviceError::WrongDevice.into());
}
hal_samplers.push(&sampler.raw);
}
@ -1983,6 +2021,7 @@ impl<A: HalApi> Device<A> {
"SampledTexture, ReadonlyStorageTexture or WriteonlyStorageTexture",
)?;
Self::create_texture_binding(
self_id,
view,
&texture_guard,
internal_use,
@ -2011,6 +2050,7 @@ impl<A: HalApi> Device<A> {
Self::texture_use_parameters(binding, decl, view,
"SampledTextureArray, ReadonlyStorageTextureArray or WriteonlyStorageTextureArray")?;
Self::create_texture_binding(
self_id,
view,
&texture_guard,
internal_use,
@ -2044,9 +2084,11 @@ impl<A: HalApi> Device<A> {
}
}
let layout_inner = layout.assume_deduplicated();
let hal_desc = hal::BindGroupDescriptor {
label: desc.label.borrow_option(),
layout: &layout.raw,
layout: &layout_inner.raw,
entries: &hal_entries,
buffers: &hal_buffers,
samplers: &hal_samplers,
@ -2074,7 +2116,7 @@ impl<A: HalApi> Device<A> {
used_texture_ranges,
dynamic_binding_info,
// collect in the order of BGL iteration
late_buffer_binding_sizes: layout
late_buffer_binding_sizes: layout_inner
.entries
.keys()
.flat_map(|binding| late_buffer_binding_sizes.get(binding).cloned())
@ -2304,10 +2346,15 @@ impl<A: HalApi> Device<A> {
// validate total resource counts
for &id in desc.bind_group_layouts.iter() {
let bind_group_layout = bgl_guard
.get(id)
.map_err(|_| Error::InvalidBindGroupLayout(id))?;
count_validator.merge(&bind_group_layout.count_validator);
let Some(bind_group_layout) = try_get_bind_group_layout(bgl_guard, id) else {
return Err(Error::InvalidBindGroupLayout(id));
};
if bind_group_layout.device_id.value.0 != self_id {
return Err(DeviceError::WrongDevice.into());
}
count_validator.merge(&bind_group_layout.assume_deduplicated().count_validator);
}
count_validator
.validate(&self.limits)
@ -2316,7 +2363,12 @@ impl<A: HalApi> Device<A> {
let bgl_vec = desc
.bind_group_layouts
.iter()
.map(|&id| &try_get_bind_group_layout(bgl_guard, id).unwrap().raw)
.map(|&id| {
&try_get_bind_group_layout(bgl_guard, id)
.unwrap()
.assume_deduplicated()
.raw
})
.collect::<Vec<_>>();
let hal_desc = hal::PipelineLayoutDescriptor {
label: desc.label.borrow_option(),
@ -2435,6 +2487,10 @@ impl<A: HalApi> Device<A> {
.get(desc.stage.module)
.map_err(|_| validation::StageError::InvalidModule)?;
if shader_module.device_id.value.0 != self_id {
return Err(DeviceError::WrongDevice.into());
}
{
let flag = wgt::ShaderStages::COMPUTE;
let provided_layouts = match desc.layout {
@ -2478,6 +2534,10 @@ impl<A: HalApi> Device<A> {
.get(pipeline_layout_id)
.map_err(|_| pipeline::CreateComputePipelineError::InvalidLayout)?;
if layout.device_id.value.0 != self_id {
return Err(DeviceError::WrongDevice.into());
}
let late_sized_buffer_groups =
Device::make_late_sized_buffer_groups(&shader_binding_sizes, layout, &*bgl_guard);
@ -2821,11 +2881,20 @@ impl<A: HalApi> Device<A> {
}
})?;
if shader_module.device_id.value.0 != self_id {
return Err(DeviceError::WrongDevice.into());
}
let provided_layouts = match desc.layout {
Some(pipeline_layout_id) => {
let pipeline_layout = pipeline_layout_guard
.get(pipeline_layout_id)
.map_err(|_| pipeline::CreateRenderPipelineError::InvalidLayout)?;
if pipeline_layout.device_id.value.0 != self_id {
return Err(DeviceError::WrongDevice.into());
}
Some(Device::get_introspection_bind_group_layouts(
pipeline_layout,
&*bgl_guard,

6
third_party/rust/wgpu-core/src/hub.rs поставляемый
Просмотреть файл

@ -575,8 +575,10 @@ impl<A: HalApi, F: GlobalIdentityHandlerFactory> Hub<A, F> {
for element in self.bind_group_layouts.data.write().map.drain(..) {
if let Element::Occupied(bgl, _) = element {
let device = &devices[bgl.device_id.value];
unsafe {
device.raw.destroy_bind_group_layout(bgl.raw);
if let Some(inner) = bgl.into_inner() {
unsafe {
device.raw.destroy_bind_group_layout(inner.raw);
}
}
}
}

Просмотреть файл

@ -296,6 +296,7 @@ fn map_storage_format_to_naga(format: wgt::TextureFormat) -> Option<naga::Storag
Tf::Rgba8Uint => Sf::Rgba8Uint,
Tf::Rgba8Sint => Sf::Rgba8Sint,
Tf::Rgb10a2Uint => Sf::Rgb10a2Uint,
Tf::Rgb10a2Unorm => Sf::Rgb10a2Unorm,
Tf::Rg11b10Float => Sf::Rg11b10Float,
@ -350,6 +351,7 @@ fn map_storage_format_from_naga(format: naga::StorageFormat) -> wgt::TextureForm
Sf::Rgba8Uint => Tf::Rgba8Uint,
Sf::Rgba8Sint => Tf::Rgba8Sint,
Sf::Rgb10a2Uint => Tf::Rgb10a2Uint,
Sf::Rgb10a2Unorm => Tf::Rgb10a2Unorm,
Sf::Rg11b10Float => Tf::Rg11b10Float,
@ -667,7 +669,7 @@ impl NumericType {
| Tf::Rgb10a2Unorm
| Tf::Rgba16Float
| Tf::Rgba32Float => (NumericDimension::Vector(Vs::Quad), Sk::Float),
Tf::Rgba8Uint | Tf::Rgba16Uint | Tf::Rgba32Uint => {
Tf::Rgba8Uint | Tf::Rgba16Uint | Tf::Rgba32Uint | Tf::Rgb10a2Uint => {
(NumericDimension::Vector(Vs::Quad), Sk::Uint)
}
Tf::Rgba8Sint | Tf::Rgba16Sint | Tf::Rgba32Sint => {

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

13
third_party/rust/wgpu-hal/Cargo.toml поставляемый
Просмотреть файл

@ -11,7 +11,7 @@
[package]
edition = "2021"
rust-version = "1.60"
rust-version = "1.65"
name = "wgpu-hal"
version = "0.17.0"
authors = ["wgpu developers"]
@ -64,7 +64,7 @@ optional = true
[dependencies.naga]
version = "0.13.0"
git = "https://github.com/gfx-rs/naga"
rev = "df8107b7"
rev = "6668d0694cc51ee66c71c2ca3a1ab1081956299b"
features = ["clone"]
[dependencies.profiling]
@ -83,7 +83,7 @@ env_logger = "0.10"
[dev-dependencies.naga]
version = "0.13.0"
git = "https://github.com/gfx-rs/naga"
rev = "df8107b7"
rev = "6668d0694cc51ee66c71c2ca3a1ab1081956299b"
features = ["wgsl-in"]
[dev-dependencies.winit]
@ -186,7 +186,7 @@ features = ["dynamic"]
optional = true
[target."cfg(not(target_arch = \"wasm32\"))".dependencies.libloading]
version = ">=0.7,<0.9"
version = ">=0.7, <0.9"
optional = true
[target."cfg(not(target_arch = \"wasm32\"))".dependencies.renderdoc-sys]
@ -212,7 +212,7 @@ features = [
]
[target."cfg(target_os = \"emscripten\")".dependencies.libloading]
version = ">=0.7,<0.9"
version = ">=0.7, <0.9"
optional = true
[target."cfg(unix)".dependencies]
@ -228,10 +228,9 @@ features = ["libloading"]
optional = true
[target."cfg(windows)".dependencies.gpu-allocator]
version = "0.22"
version = "0.23"
features = [
"d3d12",
"windows",
"public-winapi",
]
optional = true

Просмотреть файл

@ -34,6 +34,7 @@ pub fn map_texture_format_failable(format: wgt::TextureFormat) -> Option<dxgifor
Tf::Rgba8Uint => DXGI_FORMAT_R8G8B8A8_UINT,
Tf::Rgba8Sint => DXGI_FORMAT_R8G8B8A8_SINT,
Tf::Rgb9e5Ufloat => DXGI_FORMAT_R9G9B9E5_SHAREDEXP,
Tf::Rgb10a2Uint => DXGI_FORMAT_R10G10B10A2_UINT,
Tf::Rgb10a2Unorm => DXGI_FORMAT_R10G10B10A2_UNORM,
Tf::Rg11b10Float => DXGI_FORMAT_R11G11B10_FLOAT,
Tf::Rg32Uint => DXGI_FORMAT_R32G32_UINT,

Просмотреть файл

@ -49,8 +49,9 @@ mod placed {
let device = raw.as_ptr();
match gpu_allocator::d3d12::Allocator::new(&gpu_allocator::d3d12::AllocatorCreateDesc {
device: device.as_windows().clone(),
device: gpu_allocator::d3d12::ID3D12DeviceVersion::Device(device.as_windows().clone()),
debug_settings: Default::default(),
allocation_sizes: gpu_allocator::AllocationSizes::default(),
}) {
Ok(allocator) => Ok(Some(Mutex::new(GpuAllocatorWrapper { allocator }))),
Err(e) => {
@ -213,6 +214,7 @@ mod placed {
log::error!("DX12 gpu-allocator: Internal Error: {}", e);
Self::Lost
}
gpu_allocator::AllocationError::BarrierLayoutNeedsDevice10 => todo!(),
}
}
}

Просмотреть файл

@ -828,6 +828,7 @@ impl crate::Adapter<super::Api> for super::Adapter {
Tf::Rgba8Snorm => filterable,
Tf::Rgba8Uint => renderable | storage,
Tf::Rgba8Sint => renderable | storage,
Tf::Rgb10a2Uint => renderable,
Tf::Rgb10a2Unorm => filterable_renderable,
Tf::Rg11b10Float => filterable | float_renderable,
Tf::Rg32Uint => renderable,

5
third_party/rust/wgpu-hal/src/gles/conv.rs поставляемый
Просмотреть файл

@ -35,6 +35,11 @@ impl super::AdapterShared {
Tf::Bgra8Unorm => (glow::RGBA8, glow::BGRA, glow::UNSIGNED_BYTE), //TODO?
Tf::Rgba8Uint => (glow::RGBA8UI, glow::RGBA_INTEGER, glow::UNSIGNED_BYTE),
Tf::Rgba8Sint => (glow::RGBA8I, glow::RGBA_INTEGER, glow::BYTE),
Tf::Rgb10a2Uint => (
glow::RGB10_A2UI,
glow::RGBA_INTEGER,
glow::UNSIGNED_INT_2_10_10_10_REV,
),
Tf::Rgb10a2Unorm => (
glow::RGB10_A2,
glow::RGBA,

Просмотреть файл

@ -166,6 +166,11 @@ impl crate::Adapter<super::Api> for super::Adapter {
flags.set(Tfc::STORAGE, pc.format_rgba8_srgb_all);
flags
}
Tf::Rgb10a2Uint => {
let mut flags = Tfc::COLOR_ATTACHMENT | msaa_count;
flags.set(Tfc::STORAGE, pc.format_rgb10a2_uint_write);
flags
}
Tf::Rgb10a2Unorm => {
let mut flags = all_caps;
flags.set(Tfc::STORAGE, pc.format_rgb10a2_unorm_all);
@ -399,7 +404,7 @@ const RGB10A2UNORM_ALL: &[MTLFeatureSet] = &[
MTLFeatureSet::macOS_GPUFamily1_v1,
];
const RGB10A2UINT_COLOR_WRITE: &[MTLFeatureSet] = &[
const RGB10A2UINT_WRITE: &[MTLFeatureSet] = &[
MTLFeatureSet::iOS_GPUFamily3_v1,
MTLFeatureSet::tvOS_GPUFamily2_v1,
MTLFeatureSet::macOS_GPUFamily1_v1,
@ -636,8 +641,7 @@ impl super::PrivateCapabilities {
format_rgba8_srgb_no_write: !Self::supports_any(device, RGBA8_SRGB),
format_rgb10a2_unorm_all: Self::supports_any(device, RGB10A2UNORM_ALL),
format_rgb10a2_unorm_no_write: !Self::supports_any(device, RGB10A2UNORM_ALL),
format_rgb10a2_uint_color: !Self::supports_any(device, RGB10A2UINT_COLOR_WRITE),
format_rgb10a2_uint_color_write: Self::supports_any(device, RGB10A2UINT_COLOR_WRITE),
format_rgb10a2_uint_write: Self::supports_any(device, RGB10A2UINT_WRITE),
format_rg11b10_all: Self::supports_any(device, RG11B10FLOAT_ALL),
format_rg11b10_no_write: !Self::supports_any(device, RG11B10FLOAT_ALL),
format_rgb9e5_all: Self::supports_any(device, RGB9E5FLOAT_ALL),
@ -971,6 +975,7 @@ impl super::PrivateCapabilities {
Tf::Bgra8Unorm => BGRA8Unorm,
Tf::Rgba8Uint => RGBA8Uint,
Tf::Rgba8Sint => RGBA8Sint,
Tf::Rgb10a2Uint => RGB10A2Uint,
Tf::Rgb10a2Unorm => RGB10A2Unorm,
Tf::Rg11b10Float => RG11B10Float,
Tf::Rg32Uint => RG32Uint,

3
third_party/rust/wgpu-hal/src/metal/mod.rs поставляемый
Просмотреть файл

@ -208,8 +208,7 @@ struct PrivateCapabilities {
format_rgba8_srgb_no_write: bool,
format_rgb10a2_unorm_all: bool,
format_rgb10a2_unorm_no_write: bool,
format_rgb10a2_uint_color: bool,
format_rgb10a2_uint_color_write: bool,
format_rgb10a2_uint_write: bool,
format_rg11b10_all: bool,
format_rg11b10_no_write: bool,
format_rgb9e5_all: bool,

Просмотреть файл

@ -1223,6 +1223,8 @@ impl super::Adapter {
let naga_options = {
use naga::back::spv;
// The following capabilities are always available
// see https://registry.khronos.org/vulkan/specs/1.3-extensions/html/chap52.html#spirvenv-capabilities
let mut capabilities = vec![
spv::Capability::Shader,
spv::Capability::Matrix,
@ -1230,15 +1232,23 @@ impl super::Adapter {
spv::Capability::Image1D,
spv::Capability::ImageQuery,
spv::Capability::DerivativeControl,
spv::Capability::SampledCubeArray,
spv::Capability::SampleRateShading,
//Note: this is requested always, no matter what the actual
// adapter supports. It's not the responsibility of SPV-out
// translation to handle the storage support for formats.
spv::Capability::StorageImageExtendedFormats,
//TODO: fill out the rest
];
if self
.downlevel_flags
.contains(wgt::DownlevelFlags::CUBE_ARRAY_TEXTURES)
{
capabilities.push(spv::Capability::SampledCubeArray);
}
if self
.downlevel_flags
.contains(wgt::DownlevelFlags::MULTISAMPLED_SHADING)
{
capabilities.push(spv::Capability::SampleRateShading);
}
if features.contains(wgt::Features::MULTIVIEW) {
capabilities.push(spv::Capability::MultiView);
}

Просмотреть файл

@ -34,6 +34,7 @@ impl super::PrivateCapabilities {
Tf::Bgra8Unorm => F::B8G8R8A8_UNORM,
Tf::Rgba8Uint => F::R8G8B8A8_UINT,
Tf::Rgba8Sint => F::R8G8B8A8_SINT,
Tf::Rgb10a2Uint => F::A2B10G10R10_UINT_PACK32,
Tf::Rgb10a2Unorm => F::A2B10G10R10_UNORM_PACK32,
Tf::Rg11b10Float => F::B10G11R11_UFLOAT_PACK32,
Tf::Rg32Uint => F::R32G32_UINT,

Просмотреть файл

@ -157,6 +157,12 @@ impl super::Swapchain {
/// - The device must have been made idle before calling this function.
unsafe fn release_resources(self, device: &ash::Device) -> Self {
profiling::scope!("Swapchain::release_resources");
{
profiling::scope!("vkDeviceWaitIdle");
// We need to also wait until all presentation work is done. Because there is no way to portably wait until
// the presentation work is done, we are forced to wait until the device is idle.
let _ = unsafe { device.device_wait_idle() };
};
unsafe { device.destroy_fence(self.fence, None) };
self
}

Просмотреть файл

@ -1 +1 @@
{"files":{"Cargo.toml":"468c2c0c8fc2f2105248e445cb029a11338f8bde5e0444db5a362ad08c0b68aa","LICENSE.APACHE":"a6cba85bc92e0cff7a450b1d873c0eaa2e9fc96bf472df0247a26bec77bf3ff9","LICENSE.MIT":"c7fea58d1cfe49634cd92e54fc10a9d871f4b275321a4cd8c09e449122caaeb4","src/assertions.rs":"3fe98027aa73970c8ab7874a3e13dbfd6faa87df2081beb5c83aeec4c60f372f","src/lib.rs":"b4a6796691445880ffd9473769db832197f7fc626ccd2c5602a11abddfc7e6d0","src/math.rs":"4d03039736dd6926feb139bc68734cb59df34ede310427bbf059e5c925e0af3b"},"package":null}
{"files":{"Cargo.toml":"60d11013451ea3e3d460b7548e2cc0e3d72ec0fa4d9961d4d4eda3f089bda729","LICENSE.APACHE":"a6cba85bc92e0cff7a450b1d873c0eaa2e9fc96bf472df0247a26bec77bf3ff9","LICENSE.MIT":"c7fea58d1cfe49634cd92e54fc10a9d871f4b275321a4cd8c09e449122caaeb4","src/assertions.rs":"3fe98027aa73970c8ab7874a3e13dbfd6faa87df2081beb5c83aeec4c60f372f","src/lib.rs":"3adc0f2e05ece59fdb86c7a360f8e773dbd60f71911db6f429edc48412949250","src/math.rs":"4d03039736dd6926feb139bc68734cb59df34ede310427bbf059e5c925e0af3b"},"package":null}

1
third_party/rust/wgpu-types/Cargo.toml поставляемый
Просмотреть файл

@ -11,6 +11,7 @@
[package]
edition = "2021"
rust-version = "1.65"
name = "wgpu-types"
version = "0.17.0"
authors = ["wgpu developers"]

25
third_party/rust/wgpu-types/src/lib.rs поставляемый
Просмотреть файл

@ -2148,6 +2148,8 @@ pub enum TextureFormat {
// Packed 32 bit formats
/// Packed unsigned float with 9 bits mantisa for each RGB component, then a common 5 bits exponent
Rgb9e5Ufloat,
/// Red, green, blue, and alpha channels. 10 bit integer for RGB channels, 2 bit integer for alpha channel. Unsigned in shader.
Rgb10a2Uint,
/// Red, green, blue, and alpha channels. 10 bit integer for RGB channels, 2 bit integer for alpha channel. [0, 1023] ([0, 3] for alpha) converted to/from float [0, 1] in shader.
Rgb10a2Unorm,
/// Red, green, and blue channels. 11 bit float with no sign bit for RG channels. 10 bit float with no sign bit for blue channel. Float in shader.
@ -2408,6 +2410,7 @@ impl<'de> Deserialize<'de> for TextureFormat {
"rgba8sint" => TextureFormat::Rgba8Sint,
"bgra8unorm" => TextureFormat::Bgra8Unorm,
"bgra8unorm-srgb" => TextureFormat::Bgra8UnormSrgb,
"rgb10a2uint" => TextureFormat::Rgb10a2Uint,
"rgb10a2unorm" => TextureFormat::Rgb10a2Unorm,
"rg11b10ufloat" => TextureFormat::Rg11b10Float,
"rg32uint" => TextureFormat::Rg32Uint,
@ -2534,6 +2537,7 @@ impl Serialize for TextureFormat {
TextureFormat::Rgba8Sint => "rgba8sint",
TextureFormat::Bgra8Unorm => "bgra8unorm",
TextureFormat::Bgra8UnormSrgb => "bgra8unorm-srgb",
TextureFormat::Rgb10a2Uint => "rgb10a2uint",
TextureFormat::Rgb10a2Unorm => "rgb10a2unorm",
TextureFormat::Rg11b10Float => "rg11b10ufloat",
TextureFormat::Rg32Uint => "rg32uint",
@ -2724,6 +2728,7 @@ impl TextureFormat {
| Self::Bgra8Unorm
| Self::Bgra8UnormSrgb
| Self::Rgb9e5Ufloat
| Self::Rgb10a2Uint
| Self::Rgb10a2Unorm
| Self::Rg11b10Float
| Self::Rg32Uint
@ -2822,6 +2827,7 @@ impl TextureFormat {
| Self::Bgra8Unorm
| Self::Bgra8UnormSrgb
| Self::Rgb9e5Ufloat
| Self::Rgb10a2Uint
| Self::Rgb10a2Unorm
| Self::Rg11b10Float
| Self::Rg32Uint
@ -2931,6 +2937,7 @@ impl TextureFormat {
Self::Rgba8Sint => ( msaa, all_flags),
Self::Bgra8Unorm => (msaa_resolve, attachment),
Self::Bgra8UnormSrgb => (msaa_resolve, attachment),
Self::Rgb10a2Uint => ( msaa, attachment),
Self::Rgb10a2Unorm => (msaa_resolve, attachment),
Self::Rg11b10Float => ( msaa, rg11b10f),
Self::Rg32Uint => ( noaa, all_flags),
@ -3036,7 +3043,8 @@ impl TextureFormat {
| Self::Rgba16Uint
| Self::R32Uint
| Self::Rg32Uint
| Self::Rgba32Uint => Some(uint),
| Self::Rgba32Uint
| Self::Rgb10a2Uint => Some(uint),
Self::R8Sint
| Self::Rg8Sint
@ -3124,7 +3132,9 @@ impl TextureFormat {
| Self::Rg16Sint
| Self::Rg16Float => Some(4),
Self::R32Uint | Self::R32Sint | Self::R32Float => Some(4),
Self::Rgb9e5Ufloat | Self::Rgb10a2Unorm | Self::Rg11b10Float => Some(4),
Self::Rgb9e5Ufloat | Self::Rgb10a2Uint | Self::Rgb10a2Unorm | Self::Rg11b10Float => {
Some(4)
}
Self::Rgba16Unorm
| Self::Rgba16Snorm
@ -3232,7 +3242,7 @@ impl TextureFormat {
| Self::Rgba32Float => 4,
Self::Rgb9e5Ufloat | Self::Rg11b10Float => 3,
Self::Rgb10a2Unorm => 4,
Self::Rgb10a2Uint | Self::Rgb10a2Unorm => 4,
Self::Stencil8 | Self::Depth16Unorm | Self::Depth24Plus | Self::Depth32Float => 1,
@ -3431,6 +3441,10 @@ fn texture_format_serialize() {
serde_json::to_string(&TextureFormat::Bgra8UnormSrgb).unwrap(),
"\"bgra8unorm-srgb\"".to_string()
);
assert_eq!(
serde_json::to_string(&TextureFormat::Rgb10a2Uint).unwrap(),
"\"rgb10a2uint\"".to_string()
);
assert_eq!(
serde_json::to_string(&TextureFormat::Rgb10a2Unorm).unwrap(),
"\"rgb10a2unorm\"".to_string()
@ -3723,6 +3737,10 @@ fn texture_format_deserialize() {
serde_json::from_str::<TextureFormat>("\"bgra8unorm-srgb\"").unwrap(),
TextureFormat::Bgra8UnormSrgb
);
assert_eq!(
serde_json::from_str::<TextureFormat>("\"rgb10a2uint\"").unwrap(),
TextureFormat::Rgb10a2Uint
);
assert_eq!(
serde_json::from_str::<TextureFormat>("\"rgb10a2unorm\"").unwrap(),
TextureFormat::Rgb10a2Unorm
@ -6129,6 +6147,7 @@ impl<T: Copy> ImageCopyTextureTagged<T> {
#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)]
#[cfg_attr(feature = "trace", derive(serde::Serialize))]
#[cfg_attr(feature = "replay", derive(serde::Deserialize))]
#[cfg_attr(feature = "serde", serde(rename_all = "camelCase"))]
pub struct ImageSubresourceRange {
/// Aspect of the texture. Color textures must be [`TextureAspect::All`][TAA].
///