mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-24 05:11:16 +00:00
Bug 1865218 - Update wgpu
to revision 3ec547cdcaaa14488327d8f1b5f7736278c4178d. r=webgpu-reviewers,supply-chain-reviewers,ErichDonGubler
Differential Revision: https://phabricator.services.mozilla.com/D193850
This commit is contained in:
parent
e246c64e78
commit
efa811a62f
@ -25,9 +25,9 @@ git = "https://github.com/franziskuskiefer/cose-rust"
|
||||
rev = "43c22248d136c8b38fe42ea709d08da6355cf04b"
|
||||
replace-with = "vendored-sources"
|
||||
|
||||
[source."git+https://github.com/gfx-rs/wgpu?rev=ba3d6898f18c25bb5a2b8ba18790134b97758e83"]
|
||||
[source."git+https://github.com/gfx-rs/wgpu?rev=3ec547cdcaaa14488327d8f1b5f7736278c4178d"]
|
||||
git = "https://github.com/gfx-rs/wgpu"
|
||||
rev = "ba3d6898f18c25bb5a2b8ba18790134b97758e83"
|
||||
rev = "3ec547cdcaaa14488327d8f1b5f7736278c4178d"
|
||||
replace-with = "vendored-sources"
|
||||
|
||||
[source."git+https://github.com/glandium/warp?rev=4af45fae95bc98b0eba1ef0db17e1dac471bb23d"]
|
||||
|
14
Cargo.lock
generated
14
Cargo.lock
generated
@ -1146,7 +1146,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "d3d12"
|
||||
version = "0.7.0"
|
||||
source = "git+https://github.com/gfx-rs/wgpu?rev=ba3d6898f18c25bb5a2b8ba18790134b97758e83#ba3d6898f18c25bb5a2b8ba18790134b97758e83"
|
||||
source = "git+https://github.com/gfx-rs/wgpu?rev=3ec547cdcaaa14488327d8f1b5f7736278c4178d#3ec547cdcaaa14488327d8f1b5f7736278c4178d"
|
||||
dependencies = [
|
||||
"bitflags 2.4.0",
|
||||
"libloading",
|
||||
@ -3760,7 +3760,7 @@ checksum = "a2983372caf4480544083767bf2d27defafe32af49ab4df3a0b7fc90793a3664"
|
||||
[[package]]
|
||||
name = "naga"
|
||||
version = "0.14.0"
|
||||
source = "git+https://github.com/gfx-rs/wgpu?rev=ba3d6898f18c25bb5a2b8ba18790134b97758e83#ba3d6898f18c25bb5a2b8ba18790134b97758e83"
|
||||
source = "git+https://github.com/gfx-rs/wgpu?rev=3ec547cdcaaa14488327d8f1b5f7736278c4178d#3ec547cdcaaa14488327d8f1b5f7736278c4178d"
|
||||
dependencies = [
|
||||
"bit-set",
|
||||
"bitflags 2.4.0",
|
||||
@ -5426,9 +5426,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "termcolor"
|
||||
version = "1.2.0"
|
||||
version = "1.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "be55cf8942feac5c765c2c993422806843c9a9a45d4d5c407ad6dd2ea95eb9b6"
|
||||
checksum = "ff1bc3d3f05aff0403e8ac0d92ced918ec05b666a43f83297ccef5bea8a3d449"
|
||||
dependencies = [
|
||||
"winapi-util",
|
||||
]
|
||||
@ -6347,7 +6347,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "wgpu-core"
|
||||
version = "0.18.0"
|
||||
source = "git+https://github.com/gfx-rs/wgpu?rev=ba3d6898f18c25bb5a2b8ba18790134b97758e83#ba3d6898f18c25bb5a2b8ba18790134b97758e83"
|
||||
source = "git+https://github.com/gfx-rs/wgpu?rev=3ec547cdcaaa14488327d8f1b5f7736278c4178d#3ec547cdcaaa14488327d8f1b5f7736278c4178d"
|
||||
dependencies = [
|
||||
"arrayvec",
|
||||
"bit-vec",
|
||||
@ -6370,7 +6370,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "wgpu-hal"
|
||||
version = "0.18.0"
|
||||
source = "git+https://github.com/gfx-rs/wgpu?rev=ba3d6898f18c25bb5a2b8ba18790134b97758e83#ba3d6898f18c25bb5a2b8ba18790134b97758e83"
|
||||
source = "git+https://github.com/gfx-rs/wgpu?rev=3ec547cdcaaa14488327d8f1b5f7736278c4178d#3ec547cdcaaa14488327d8f1b5f7736278c4178d"
|
||||
dependencies = [
|
||||
"android_system_properties",
|
||||
"arrayvec",
|
||||
@ -6407,7 +6407,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "wgpu-types"
|
||||
version = "0.18.0"
|
||||
source = "git+https://github.com/gfx-rs/wgpu?rev=ba3d6898f18c25bb5a2b8ba18790134b97758e83#ba3d6898f18c25bb5a2b8ba18790134b97758e83"
|
||||
source = "git+https://github.com/gfx-rs/wgpu?rev=3ec547cdcaaa14488327d8f1b5f7736278c4178d#3ec547cdcaaa14488327d8f1b5f7736278c4178d"
|
||||
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 = "ba3d6898f18c25bb5a2b8ba18790134b97758e83"
|
||||
rev = "3ec547cdcaaa14488327d8f1b5f7736278c4178d"
|
||||
#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,36 +27,36 @@ 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 = "ba3d6898f18c25bb5a2b8ba18790134b97758e83"
|
||||
rev = "3ec547cdcaaa14488327d8f1b5f7736278c4178d"
|
||||
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 = "ba3d6898f18c25bb5a2b8ba18790134b97758e83"
|
||||
rev = "3ec547cdcaaa14488327d8f1b5f7736278c4178d"
|
||||
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 = "ba3d6898f18c25bb5a2b8ba18790134b97758e83"
|
||||
rev = "3ec547cdcaaa14488327d8f1b5f7736278c4178d"
|
||||
features = ["vulkan"]
|
||||
|
||||
[dependencies.wgt]
|
||||
package = "wgpu-types"
|
||||
git = "https://github.com/gfx-rs/wgpu"
|
||||
rev = "ba3d6898f18c25bb5a2b8ba18790134b97758e83"
|
||||
rev = "3ec547cdcaaa14488327d8f1b5f7736278c4178d"
|
||||
|
||||
[dependencies.wgh]
|
||||
package = "wgpu-hal"
|
||||
git = "https://github.com/gfx-rs/wgpu"
|
||||
rev = "ba3d6898f18c25bb5a2b8ba18790134b97758e83"
|
||||
rev = "3ec547cdcaaa14488327d8f1b5f7736278c4178d"
|
||||
|
||||
[target.'cfg(windows)'.dependencies.d3d12]
|
||||
git = "https://github.com/gfx-rs/wgpu"
|
||||
rev = "ba3d6898f18c25bb5a2b8ba18790134b97758e83"
|
||||
rev = "3ec547cdcaaa14488327d8f1b5f7736278c4178d"
|
||||
|
||||
[target.'cfg(windows)'.dependencies]
|
||||
winapi = "0.3"
|
||||
|
@ -20,11 +20,11 @@ origin:
|
||||
|
||||
# Human-readable identifier for this version/release
|
||||
# Generally "version NNN", "tag SSS", "bookmark SSS"
|
||||
release: commit ba3d6898f18c25bb5a2b8ba18790134b97758e83
|
||||
release: commit 3ec547cdcaaa14488327d8f1b5f7736278c4178d
|
||||
|
||||
# Revision to pull in
|
||||
# Must be a long or short commit SHA (long preferred)
|
||||
revision: ba3d6898f18c25bb5a2b8ba18790134b97758e83
|
||||
revision: 3ec547cdcaaa14488327d8f1b5f7736278c4178d
|
||||
|
||||
license: ['MIT', 'Apache-2.0']
|
||||
|
||||
|
@ -1294,7 +1294,7 @@ pub unsafe extern "C" fn wgpu_queue_write_texture(
|
||||
/// Returns the block size or zero if the format has multiple aspects (for example depth+stencil).
|
||||
#[no_mangle]
|
||||
pub extern "C" fn wgpu_texture_format_block_size_single_aspect(format: wgt::TextureFormat) -> u32 {
|
||||
format.block_size(None).unwrap_or(0)
|
||||
format.block_copy_size(None).unwrap_or(0)
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
|
@ -1166,6 +1166,11 @@ who = "Nicolas Silva <nical@fastmail.com>"
|
||||
criteria = "safe-to-deploy"
|
||||
delta = "0.7.0 -> 0.7.0@git:ba3d6898f18c25bb5a2b8ba18790134b97758e83"
|
||||
|
||||
[[audits.d3d12]]
|
||||
who = "Teodor Tanasoaia <ttanasoaia@mozilla.com>"
|
||||
criteria = "safe-to-deploy"
|
||||
delta = "0.7.0@git:ba3d6898f18c25bb5a2b8ba18790134b97758e83 -> 0.7.0@git:3ec547cdcaaa14488327d8f1b5f7736278c4178d"
|
||||
|
||||
[[audits.darling]]
|
||||
who = "Mike Hommey <mh+mozilla@glandium.org>"
|
||||
criteria = "safe-to-deploy"
|
||||
@ -2349,6 +2354,11 @@ who = "Nicolas Silva <nical@fastmail.com>"
|
||||
criteria = "safe-to-deploy"
|
||||
delta = "0.14.0@git:34e947de4b3e0b0d6b0e2f40cede926467ea9f1e -> 0.14.0@git:ba3d6898f18c25bb5a2b8ba18790134b97758e83"
|
||||
|
||||
[[audits.naga]]
|
||||
who = "Teodor Tanasoaia <ttanasoaia@mozilla.com>"
|
||||
criteria = "safe-to-deploy"
|
||||
delta = "0.14.0@git:ba3d6898f18c25bb5a2b8ba18790134b97758e83 -> 0.14.0@git:3ec547cdcaaa14488327d8f1b5f7736278c4178d"
|
||||
|
||||
[[audits.net2]]
|
||||
who = "Mike Hommey <mh+mozilla@glandium.org>"
|
||||
criteria = "safe-to-run"
|
||||
@ -4048,6 +4058,11 @@ who = "Nicolas Silva <nical@fastmail.com>"
|
||||
criteria = "safe-to-deploy"
|
||||
delta = "0.18.0@git:34e947de4b3e0b0d6b0e2f40cede926467ea9f1e -> 0.18.0@git:ba3d6898f18c25bb5a2b8ba18790134b97758e83"
|
||||
|
||||
[[audits.wgpu-core]]
|
||||
who = "Teodor Tanasoaia <ttanasoaia@mozilla.com>"
|
||||
criteria = "safe-to-deploy"
|
||||
delta = "0.18.0@git:ba3d6898f18c25bb5a2b8ba18790134b97758e83 -> 0.18.0@git:3ec547cdcaaa14488327d8f1b5f7736278c4178d"
|
||||
|
||||
[[audits.wgpu-hal]]
|
||||
who = "Dzmitry Malyshau <kvark@fastmail.com>"
|
||||
criteria = "safe-to-deploy"
|
||||
@ -4101,6 +4116,11 @@ who = "Nicolas Silva <nical@fastmail.com>"
|
||||
criteria = "safe-to-deploy"
|
||||
delta = "0.18.0@git:34e947de4b3e0b0d6b0e2f40cede926467ea9f1e -> 0.18.0@git:ba3d6898f18c25bb5a2b8ba18790134b97758e83"
|
||||
|
||||
[[audits.wgpu-hal]]
|
||||
who = "Teodor Tanasoaia <ttanasoaia@mozilla.com>"
|
||||
criteria = "safe-to-deploy"
|
||||
delta = "0.18.0@git:ba3d6898f18c25bb5a2b8ba18790134b97758e83 -> 0.18.0@git:3ec547cdcaaa14488327d8f1b5f7736278c4178d"
|
||||
|
||||
[[audits.wgpu-types]]
|
||||
who = "Dzmitry Malyshau <kvark@fastmail.com>"
|
||||
criteria = "safe-to-deploy"
|
||||
@ -4154,6 +4174,11 @@ who = "Nicolas Silva <nical@fastmail.com>"
|
||||
criteria = "safe-to-deploy"
|
||||
delta = "0.18.0@git:34e947de4b3e0b0d6b0e2f40cede926467ea9f1e -> 0.18.0@git:ba3d6898f18c25bb5a2b8ba18790134b97758e83"
|
||||
|
||||
[[audits.wgpu-types]]
|
||||
who = "Teodor Tanasoaia <ttanasoaia@mozilla.com>"
|
||||
criteria = "safe-to-deploy"
|
||||
delta = "0.18.0@git:ba3d6898f18c25bb5a2b8ba18790134b97758e83 -> 0.18.0@git:3ec547cdcaaa14488327d8f1b5f7736278c4178d"
|
||||
|
||||
[[audits.whatsys]]
|
||||
who = "Bobby Holley <bobbyholley@gmail.com>"
|
||||
criteria = "safe-to-deploy"
|
||||
|
@ -538,6 +538,13 @@ user-id = 189
|
||||
user-login = "BurntSushi"
|
||||
user-name = "Andrew Gallant"
|
||||
|
||||
[[publisher.termcolor]]
|
||||
version = "1.4.0"
|
||||
when = "2023-11-14"
|
||||
user-id = 189
|
||||
user-login = "BurntSushi"
|
||||
user-name = "Andrew Gallant"
|
||||
|
||||
[[publisher.threadbound]]
|
||||
version = "0.1.5"
|
||||
when = "2022-12-17"
|
||||
|
2
third_party/rust/naga/.cargo-checksum.json
vendored
2
third_party/rust/naga/.cargo-checksum.json
vendored
File diff suppressed because one or more lines are too long
4
third_party/rust/naga/Cargo.toml
vendored
4
third_party/rust/naga/Cargo.toml
vendored
@ -74,7 +74,7 @@ version = "0.2.1"
|
||||
optional = true
|
||||
|
||||
[dependencies.serde]
|
||||
version = "1.0.191"
|
||||
version = "1.0.192"
|
||||
features = ["derive"]
|
||||
optional = true
|
||||
|
||||
@ -83,7 +83,7 @@ version = "0.2"
|
||||
optional = true
|
||||
|
||||
[dependencies.termcolor]
|
||||
version = "1.0.4"
|
||||
version = "1.4.0"
|
||||
optional = true
|
||||
|
||||
[dependencies.unicode-xid]
|
||||
|
21
third_party/rust/naga/src/arena.rs
vendored
21
third_party/rust/naga/src/arena.rs
vendored
@ -430,11 +430,26 @@ impl<T> Arena<T> {
|
||||
P: FnMut(Handle<T>, &mut T) -> bool,
|
||||
{
|
||||
let mut index = 0;
|
||||
let mut retained = 0;
|
||||
self.data.retain_mut(|elt| {
|
||||
let handle = Handle::new(Index::new(index as u32 + 1).unwrap());
|
||||
let keep = predicate(handle, elt);
|
||||
|
||||
// Since `predicate` needs mutable access to each element,
|
||||
// we can't feasibly call it twice, so we have to compact
|
||||
// spans by hand in parallel as part of this iteration.
|
||||
#[cfg(feature = "span")]
|
||||
if keep {
|
||||
self.span_info[retained] = self.span_info[index];
|
||||
retained += 1;
|
||||
}
|
||||
|
||||
index += 1;
|
||||
let handle = Handle::new(Index::new(index).unwrap());
|
||||
predicate(handle, elt)
|
||||
})
|
||||
keep
|
||||
});
|
||||
|
||||
#[cfg(feature = "span")]
|
||||
self.span_info.truncate(retained);
|
||||
}
|
||||
}
|
||||
|
||||
|
14
third_party/rust/naga/src/back/glsl/features.rs
vendored
14
third_party/rust/naga/src/back/glsl/features.rs
vendored
@ -1,7 +1,7 @@
|
||||
use super::{BackendResult, Error, Version, Writer};
|
||||
use crate::{
|
||||
AddressSpace, Binding, Bytes, Expression, Handle, ImageClass, ImageDimension, Interpolation,
|
||||
Sampling, ScalarKind, ShaderStage, StorageFormat, Type, TypeInner,
|
||||
AddressSpace, Binding, Expression, Handle, ImageClass, ImageDimension, Interpolation, Sampling,
|
||||
Scalar, ScalarKind, ShaderStage, StorageFormat, Type, TypeInner,
|
||||
};
|
||||
use std::fmt::Write;
|
||||
|
||||
@ -275,10 +275,10 @@ impl<'a, W> Writer<'a, W> {
|
||||
|
||||
for (ty_handle, ty) in self.module.types.iter() {
|
||||
match ty.inner {
|
||||
TypeInner::Scalar { kind, width } => self.scalar_required_features(kind, width),
|
||||
TypeInner::Vector { kind, width, .. } => self.scalar_required_features(kind, width),
|
||||
TypeInner::Scalar(scalar) => self.scalar_required_features(scalar),
|
||||
TypeInner::Vector { scalar, .. } => self.scalar_required_features(scalar),
|
||||
TypeInner::Matrix { width, .. } => {
|
||||
self.scalar_required_features(ScalarKind::Float, width)
|
||||
self.scalar_required_features(Scalar::float(width))
|
||||
}
|
||||
TypeInner::Array { base, size, .. } => {
|
||||
if let TypeInner::Array { .. } = self.module.types[base].inner {
|
||||
@ -463,8 +463,8 @@ impl<'a, W> Writer<'a, W> {
|
||||
}
|
||||
|
||||
/// Helper method that checks the [`Features`] needed by a scalar
|
||||
fn scalar_required_features(&mut self, kind: ScalarKind, width: Bytes) {
|
||||
if kind == ScalarKind::Float && width == 8 {
|
||||
fn scalar_required_features(&mut self, scalar: Scalar) {
|
||||
if scalar.kind == ScalarKind::Float && scalar.width == 8 {
|
||||
self.features.request(Features::DOUBLE_TYPE);
|
||||
}
|
||||
}
|
||||
|
133
third_party/rust/naga/src/back/glsl/mod.rs
vendored
133
third_party/rust/naga/src/back/glsl/mod.rs
vendored
@ -471,8 +471,8 @@ pub enum Error {
|
||||
#[error("A call was made to an unsupported external: {0}")]
|
||||
UnsupportedExternal(String),
|
||||
/// A scalar with an unsupported width was requested.
|
||||
#[error("A scalar with an unsupported width was requested: {0:?} {1:?}")]
|
||||
UnsupportedScalar(crate::ScalarKind, crate::Bytes),
|
||||
#[error("A scalar with an unsupported width was requested: {0:?}")]
|
||||
UnsupportedScalar(crate::Scalar),
|
||||
/// A image was used with multiple samplers, which isn't supported.
|
||||
#[error("A image was used with multiple samplers")]
|
||||
ImageMultipleSamplers,
|
||||
@ -963,27 +963,20 @@ impl<'a, W: Write> Writer<'a, W> {
|
||||
fn write_value_type(&mut self, inner: &TypeInner) -> BackendResult {
|
||||
match *inner {
|
||||
// Scalars are simple we just get the full name from `glsl_scalar`
|
||||
TypeInner::Scalar { kind, width }
|
||||
| TypeInner::Atomic { kind, width }
|
||||
TypeInner::Scalar(scalar)
|
||||
| TypeInner::Atomic(scalar)
|
||||
| TypeInner::ValuePointer {
|
||||
size: None,
|
||||
kind,
|
||||
width,
|
||||
scalar,
|
||||
space: _,
|
||||
} => write!(self.out, "{}", glsl_scalar(kind, width)?.full)?,
|
||||
} => write!(self.out, "{}", glsl_scalar(scalar)?.full)?,
|
||||
// Vectors are just `gvecN` where `g` is the scalar prefix and `N` is the vector size
|
||||
TypeInner::Vector { size, kind, width }
|
||||
TypeInner::Vector { size, scalar }
|
||||
| TypeInner::ValuePointer {
|
||||
size: Some(size),
|
||||
kind,
|
||||
width,
|
||||
scalar,
|
||||
space: _,
|
||||
} => write!(
|
||||
self.out,
|
||||
"{}vec{}",
|
||||
glsl_scalar(kind, width)?.prefix,
|
||||
size as u8
|
||||
)?,
|
||||
} => write!(self.out, "{}vec{}", glsl_scalar(scalar)?.prefix, size as u8)?,
|
||||
// Matrices are written with `gmatMxN` where `g` is the scalar prefix (only floats and
|
||||
// doubles are allowed), `M` is the columns count and `N` is the rows count
|
||||
//
|
||||
@ -996,7 +989,7 @@ impl<'a, W: Write> Writer<'a, W> {
|
||||
} => write!(
|
||||
self.out,
|
||||
"{}mat{}x{}",
|
||||
glsl_scalar(crate::ScalarKind::Float, width)?.prefix,
|
||||
glsl_scalar(crate::Scalar::float(width))?.prefix,
|
||||
columns as u8,
|
||||
rows as u8
|
||||
)?,
|
||||
@ -1083,7 +1076,7 @@ impl<'a, W: Write> Writer<'a, W> {
|
||||
self.out,
|
||||
"{}{}{}{}{}{}{}",
|
||||
precision,
|
||||
glsl_scalar(kind, 4)?.prefix,
|
||||
glsl_scalar(crate::Scalar { kind, width: 4 })?.prefix,
|
||||
base,
|
||||
glsl_dimension(dim),
|
||||
ms,
|
||||
@ -1278,7 +1271,7 @@ impl<'a, W: Write> Writer<'a, W> {
|
||||
crate::MathFunction::Dot => {
|
||||
// if the expression is a Dot product with integer arguments,
|
||||
// then the args needs baking as well
|
||||
if let TypeInner::Scalar { kind, .. } = *inner {
|
||||
if let TypeInner::Scalar(crate::Scalar { kind, .. }) = *inner {
|
||||
match kind {
|
||||
crate::ScalarKind::Sint | crate::ScalarKind::Uint => {
|
||||
self.need_bake_expressions.insert(arg);
|
||||
@ -2802,10 +2795,10 @@ impl<'a, W: Write> Writer<'a, W> {
|
||||
if let Some(expr) = level {
|
||||
let cast_to_int = matches!(
|
||||
*ctx.resolve_type(expr, &self.module.types),
|
||||
crate::TypeInner::Scalar {
|
||||
crate::TypeInner::Scalar(crate::Scalar {
|
||||
kind: crate::ScalarKind::Uint,
|
||||
..
|
||||
}
|
||||
})
|
||||
);
|
||||
|
||||
write!(self.out, ", ")?;
|
||||
@ -2906,19 +2899,19 @@ impl<'a, W: Write> Writer<'a, W> {
|
||||
let right_inner = ctx.resolve_type(right, &self.module.types);
|
||||
|
||||
let function = match (left_inner, right_inner) {
|
||||
(&Ti::Vector { kind, .. }, &Ti::Vector { .. }) => match op {
|
||||
(&Ti::Vector { scalar, .. }, &Ti::Vector { .. }) => match op {
|
||||
Bo::Less
|
||||
| Bo::LessEqual
|
||||
| Bo::Greater
|
||||
| Bo::GreaterEqual
|
||||
| Bo::Equal
|
||||
| Bo::NotEqual => BinaryOperation::VectorCompare,
|
||||
Bo::Modulo if kind == Sk::Float => BinaryOperation::Modulo,
|
||||
Bo::And if kind == Sk::Bool => {
|
||||
Bo::Modulo if scalar.kind == Sk::Float => BinaryOperation::Modulo,
|
||||
Bo::And if scalar.kind == Sk::Bool => {
|
||||
op = crate::BinaryOperator::LogicalAnd;
|
||||
BinaryOperation::VectorComponentWise
|
||||
}
|
||||
Bo::InclusiveOr if kind == Sk::Bool => {
|
||||
Bo::InclusiveOr if scalar.kind == Sk::Bool => {
|
||||
op = crate::BinaryOperator::LogicalOr;
|
||||
BinaryOperation::VectorComponentWise
|
||||
}
|
||||
@ -3171,7 +3164,11 @@ impl<'a, W: Write> Writer<'a, W> {
|
||||
// geometry
|
||||
Mf::Dot => match *ctx.resolve_type(arg, &self.module.types) {
|
||||
crate::TypeInner::Vector {
|
||||
kind: crate::ScalarKind::Float,
|
||||
scalar:
|
||||
crate::Scalar {
|
||||
kind: crate::ScalarKind::Float,
|
||||
..
|
||||
},
|
||||
..
|
||||
} => "dot",
|
||||
crate::TypeInner::Vector { size, .. } => {
|
||||
@ -3226,9 +3223,9 @@ impl<'a, W: Write> Writer<'a, W> {
|
||||
// bits
|
||||
Mf::CountTrailingZeros => {
|
||||
match *ctx.resolve_type(arg, &self.module.types) {
|
||||
crate::TypeInner::Vector { size, kind, .. } => {
|
||||
crate::TypeInner::Vector { size, scalar, .. } => {
|
||||
let s = back::vector_size_str(size);
|
||||
if let crate::ScalarKind::Uint = kind {
|
||||
if let crate::ScalarKind::Uint = scalar.kind {
|
||||
write!(self.out, "min(uvec{s}(findLSB(")?;
|
||||
self.write_expr(arg, ctx)?;
|
||||
write!(self.out, ")), uvec{s}(32u))")?;
|
||||
@ -3238,8 +3235,8 @@ impl<'a, W: Write> Writer<'a, W> {
|
||||
write!(self.out, ")), uvec{s}(32u)))")?;
|
||||
}
|
||||
}
|
||||
crate::TypeInner::Scalar { kind, .. } => {
|
||||
if let crate::ScalarKind::Uint = kind {
|
||||
crate::TypeInner::Scalar(scalar) => {
|
||||
if let crate::ScalarKind::Uint = scalar.kind {
|
||||
write!(self.out, "min(uint(findLSB(")?;
|
||||
self.write_expr(arg, ctx)?;
|
||||
write!(self.out, ")), 32u)")?;
|
||||
@ -3256,10 +3253,10 @@ impl<'a, W: Write> Writer<'a, W> {
|
||||
Mf::CountLeadingZeros => {
|
||||
if self.options.version.supports_integer_functions() {
|
||||
match *ctx.resolve_type(arg, &self.module.types) {
|
||||
crate::TypeInner::Vector { size, kind, .. } => {
|
||||
crate::TypeInner::Vector { size, scalar } => {
|
||||
let s = back::vector_size_str(size);
|
||||
|
||||
if let crate::ScalarKind::Uint = kind {
|
||||
if let crate::ScalarKind::Uint = scalar.kind {
|
||||
write!(self.out, "uvec{s}(ivec{s}(31) - findMSB(")?;
|
||||
self.write_expr(arg, ctx)?;
|
||||
write!(self.out, "))")?;
|
||||
@ -3271,8 +3268,8 @@ impl<'a, W: Write> Writer<'a, W> {
|
||||
write!(self.out, ", ivec{s}(0)))")?;
|
||||
}
|
||||
}
|
||||
crate::TypeInner::Scalar { kind, .. } => {
|
||||
if let crate::ScalarKind::Uint = kind {
|
||||
crate::TypeInner::Scalar(scalar) => {
|
||||
if let crate::ScalarKind::Uint = scalar.kind {
|
||||
write!(self.out, "uint(31 - findMSB(")?;
|
||||
} else {
|
||||
write!(self.out, "(")?;
|
||||
@ -3287,10 +3284,10 @@ impl<'a, W: Write> Writer<'a, W> {
|
||||
};
|
||||
} else {
|
||||
match *ctx.resolve_type(arg, &self.module.types) {
|
||||
crate::TypeInner::Vector { size, kind, .. } => {
|
||||
crate::TypeInner::Vector { size, scalar } => {
|
||||
let s = back::vector_size_str(size);
|
||||
|
||||
if let crate::ScalarKind::Uint = kind {
|
||||
if let crate::ScalarKind::Uint = scalar.kind {
|
||||
write!(self.out, "uvec{s}(")?;
|
||||
write!(self.out, "vec{s}(31.0) - floor(log2(vec{s}(")?;
|
||||
self.write_expr(arg, ctx)?;
|
||||
@ -3305,8 +3302,8 @@ impl<'a, W: Write> Writer<'a, W> {
|
||||
write!(self.out, ", ivec{s}(0u))))")?;
|
||||
}
|
||||
}
|
||||
crate::TypeInner::Scalar { kind, .. } => {
|
||||
if let crate::ScalarKind::Uint = kind {
|
||||
crate::TypeInner::Scalar(scalar) => {
|
||||
if let crate::ScalarKind::Uint = scalar.kind {
|
||||
write!(self.out, "uint(31.0 - floor(log2(float(")?;
|
||||
self.write_expr(arg, ctx)?;
|
||||
write!(self.out, ") + 0.5)))")?;
|
||||
@ -3360,14 +3357,17 @@ impl<'a, W: Write> Writer<'a, W> {
|
||||
// Check if the argument is an unsigned integer and return the vector size
|
||||
// in case it's a vector
|
||||
let maybe_uint_size = match *ctx.resolve_type(arg, &self.module.types) {
|
||||
crate::TypeInner::Scalar {
|
||||
crate::TypeInner::Scalar(crate::Scalar {
|
||||
kind: crate::ScalarKind::Uint,
|
||||
..
|
||||
} => Some(None),
|
||||
}) => Some(None),
|
||||
crate::TypeInner::Vector {
|
||||
kind: crate::ScalarKind::Uint,
|
||||
scalar:
|
||||
crate::Scalar {
|
||||
kind: crate::ScalarKind::Uint,
|
||||
..
|
||||
},
|
||||
size,
|
||||
..
|
||||
} => Some(Some(size)),
|
||||
_ => None,
|
||||
};
|
||||
@ -3450,7 +3450,10 @@ impl<'a, W: Write> Writer<'a, W> {
|
||||
match convert {
|
||||
Some(width) => {
|
||||
// this is similar to `write_type`, but with the target kind
|
||||
let scalar = glsl_scalar(target_kind, width)?;
|
||||
let scalar = glsl_scalar(crate::Scalar {
|
||||
kind: target_kind,
|
||||
width,
|
||||
})?;
|
||||
match *inner {
|
||||
TypeInner::Matrix { columns, rows, .. } => write!(
|
||||
self.out,
|
||||
@ -3471,10 +3474,12 @@ impl<'a, W: Write> Writer<'a, W> {
|
||||
use crate::ScalarKind as Sk;
|
||||
|
||||
let target_vector_type = match *inner {
|
||||
TypeInner::Vector { size, width, .. } => Some(TypeInner::Vector {
|
||||
TypeInner::Vector { size, scalar } => Some(TypeInner::Vector {
|
||||
size,
|
||||
width,
|
||||
kind: target_kind,
|
||||
scalar: crate::Scalar {
|
||||
kind: target_kind,
|
||||
width: scalar.width,
|
||||
},
|
||||
}),
|
||||
_ => None,
|
||||
};
|
||||
@ -3613,14 +3618,17 @@ impl<'a, W: Write> Writer<'a, W> {
|
||||
// Otherwise write just the expression (and the 1D hack if needed)
|
||||
None => {
|
||||
let uvec_size = match *ctx.resolve_type(coordinate, &self.module.types) {
|
||||
TypeInner::Scalar {
|
||||
TypeInner::Scalar(crate::Scalar {
|
||||
kind: crate::ScalarKind::Uint,
|
||||
..
|
||||
} => Some(None),
|
||||
}) => Some(None),
|
||||
TypeInner::Vector {
|
||||
size,
|
||||
kind: crate::ScalarKind::Uint,
|
||||
..
|
||||
scalar:
|
||||
crate::Scalar {
|
||||
kind: crate::ScalarKind::Uint,
|
||||
..
|
||||
},
|
||||
} => Some(Some(size as u32)),
|
||||
_ => None,
|
||||
};
|
||||
@ -3953,7 +3961,11 @@ impl<'a, W: Write> Writer<'a, W> {
|
||||
// End the first branch
|
||||
write!(self.out, " : ")?;
|
||||
// Write the 0 value
|
||||
write!(self.out, "{}vec4(", glsl_scalar(kind, 4)?.prefix,)?;
|
||||
write!(
|
||||
self.out,
|
||||
"{}vec4(",
|
||||
glsl_scalar(crate::Scalar { kind, width: 4 })?.prefix,
|
||||
)?;
|
||||
self.write_zero_init_scalar(kind)?;
|
||||
// Close the zero value constructor
|
||||
write!(self.out, ")")?;
|
||||
@ -4006,13 +4018,13 @@ impl<'a, W: Write> Writer<'a, W> {
|
||||
fn write_zero_init_value(&mut self, ty: Handle<crate::Type>) -> BackendResult {
|
||||
let inner = &self.module.types[ty].inner;
|
||||
match *inner {
|
||||
TypeInner::Scalar { kind, .. } | TypeInner::Atomic { kind, .. } => {
|
||||
self.write_zero_init_scalar(kind)?;
|
||||
TypeInner::Scalar(scalar) | TypeInner::Atomic(scalar) => {
|
||||
self.write_zero_init_scalar(scalar.kind)?;
|
||||
}
|
||||
TypeInner::Vector { kind, .. } => {
|
||||
TypeInner::Vector { scalar, .. } => {
|
||||
self.write_value_type(inner)?;
|
||||
write!(self.out, "(")?;
|
||||
self.write_zero_init_scalar(kind)?;
|
||||
self.write_zero_init_scalar(scalar.kind)?;
|
||||
write!(self.out, ")")?;
|
||||
}
|
||||
TypeInner::Matrix { .. } => {
|
||||
@ -4265,13 +4277,10 @@ struct ScalarString<'a> {
|
||||
///
|
||||
/// # Errors
|
||||
/// If a [`Float`](crate::ScalarKind::Float) with an width that isn't 4 or 8
|
||||
const fn glsl_scalar(
|
||||
kind: crate::ScalarKind,
|
||||
width: crate::Bytes,
|
||||
) -> Result<ScalarString<'static>, Error> {
|
||||
const fn glsl_scalar(scalar: crate::Scalar) -> Result<ScalarString<'static>, Error> {
|
||||
use crate::ScalarKind as Sk;
|
||||
|
||||
Ok(match kind {
|
||||
Ok(match scalar.kind {
|
||||
Sk::Sint => ScalarString {
|
||||
prefix: "i",
|
||||
full: "int",
|
||||
@ -4280,7 +4289,7 @@ const fn glsl_scalar(
|
||||
prefix: "u",
|
||||
full: "uint",
|
||||
},
|
||||
Sk::Float => match width {
|
||||
Sk::Float => match scalar.width {
|
||||
4 => ScalarString {
|
||||
prefix: "",
|
||||
full: "float",
|
||||
@ -4289,7 +4298,7 @@ const fn glsl_scalar(
|
||||
prefix: "d",
|
||||
full: "double",
|
||||
},
|
||||
_ => return Err(Error::UnsupportedScalar(kind, width)),
|
||||
_ => return Err(Error::UnsupportedScalar(scalar)),
|
||||
},
|
||||
Sk::Bool => ScalarString {
|
||||
prefix: "b",
|
||||
|
24
third_party/rust/naga/src/back/hlsl/conv.rs
vendored
24
third_party/rust/naga/src/back/hlsl/conv.rs
vendored
@ -13,21 +13,23 @@ impl crate::ScalarKind {
|
||||
Self::Bool => unreachable!(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl crate::Scalar {
|
||||
/// Helper function that returns scalar related strings
|
||||
///
|
||||
/// <https://docs.microsoft.com/en-us/windows/win32/direct3dhlsl/dx-graphics-hlsl-scalar>
|
||||
pub(super) const fn to_hlsl_str(self, width: crate::Bytes) -> Result<&'static str, Error> {
|
||||
match self {
|
||||
Self::Sint => Ok("int"),
|
||||
Self::Uint => Ok("uint"),
|
||||
Self::Float => match width {
|
||||
pub(super) const fn to_hlsl_str(self) -> Result<&'static str, Error> {
|
||||
match self.kind {
|
||||
crate::ScalarKind::Sint => Ok("int"),
|
||||
crate::ScalarKind::Uint => Ok("uint"),
|
||||
crate::ScalarKind::Float => match self.width {
|
||||
2 => Ok("half"),
|
||||
4 => Ok("float"),
|
||||
8 => Ok("double"),
|
||||
_ => Err(Error::UnsupportedScalar(self, width)),
|
||||
_ => Err(Error::UnsupportedScalar(self)),
|
||||
},
|
||||
Self::Bool => Ok("bool"),
|
||||
crate::ScalarKind::Bool => Ok("bool"),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -71,10 +73,10 @@ impl crate::TypeInner {
|
||||
names: &'a crate::FastHashMap<crate::proc::NameKey, String>,
|
||||
) -> Result<Cow<'a, str>, Error> {
|
||||
Ok(match gctx.types[base].inner {
|
||||
crate::TypeInner::Scalar { kind, width } => Cow::Borrowed(kind.to_hlsl_str(width)?),
|
||||
crate::TypeInner::Vector { size, kind, width } => Cow::Owned(format!(
|
||||
crate::TypeInner::Scalar(scalar) => Cow::Borrowed(scalar.to_hlsl_str()?),
|
||||
crate::TypeInner::Vector { size, scalar } => Cow::Owned(format!(
|
||||
"{}{}",
|
||||
kind.to_hlsl_str(width)?,
|
||||
scalar.to_hlsl_str()?,
|
||||
crate::back::vector_size_str(size)
|
||||
)),
|
||||
crate::TypeInner::Matrix {
|
||||
@ -83,7 +85,7 @@ impl crate::TypeInner {
|
||||
width,
|
||||
} => Cow::Owned(format!(
|
||||
"{}{}x{}",
|
||||
crate::ScalarKind::Float.to_hlsl_str(width)?,
|
||||
crate::Scalar::float(width).to_hlsl_str()?,
|
||||
crate::back::vector_size_str(columns),
|
||||
crate::back::vector_size_str(rows),
|
||||
)),
|
||||
|
12
third_party/rust/naga/src/back/hlsl/help.rs
vendored
12
third_party/rust/naga/src/back/hlsl/help.rs
vendored
@ -133,7 +133,7 @@ impl<'a, W: Write> super::Writer<'a, W> {
|
||||
}
|
||||
crate::ImageClass::Sampled { kind, multi } => {
|
||||
let multi_str = if multi { "MS" } else { "" };
|
||||
let scalar_kind_str = kind.to_hlsl_str(4)?;
|
||||
let scalar_kind_str = crate::Scalar { kind, width: 4 }.to_hlsl_str()?;
|
||||
write!(self.out, "{multi_str}<{scalar_kind_str}4>")?
|
||||
}
|
||||
crate::ImageClass::Storage { format, .. } => {
|
||||
@ -658,8 +658,7 @@ impl<'a, W: Write> super::Writer<'a, W> {
|
||||
let vec_ty = match module.types[member.ty].inner {
|
||||
crate::TypeInner::Matrix { rows, width, .. } => crate::TypeInner::Vector {
|
||||
size: rows,
|
||||
kind: crate::ScalarKind::Float,
|
||||
width,
|
||||
scalar: crate::Scalar::float(width),
|
||||
},
|
||||
_ => unreachable!(),
|
||||
};
|
||||
@ -737,10 +736,9 @@ impl<'a, W: Write> super::Writer<'a, W> {
|
||||
_ => unreachable!(),
|
||||
};
|
||||
let scalar_ty = match module.types[member.ty].inner {
|
||||
crate::TypeInner::Matrix { width, .. } => crate::TypeInner::Scalar {
|
||||
kind: crate::ScalarKind::Float,
|
||||
width,
|
||||
},
|
||||
crate::TypeInner::Matrix { width, .. } => {
|
||||
crate::TypeInner::Scalar(crate::Scalar::float(width))
|
||||
}
|
||||
_ => unreachable!(),
|
||||
};
|
||||
self.write_value_type(module, &scalar_ty)?;
|
||||
|
4
third_party/rust/naga/src/back/hlsl/mod.rs
vendored
4
third_party/rust/naga/src/back/hlsl/mod.rs
vendored
@ -241,8 +241,8 @@ pub struct ReflectionInfo {
|
||||
pub enum Error {
|
||||
#[error(transparent)]
|
||||
IoError(#[from] FmtError),
|
||||
#[error("A scalar with an unsupported width was requested: {0:?} {1:?}")]
|
||||
UnsupportedScalar(crate::ScalarKind, crate::Bytes),
|
||||
#[error("A scalar with an unsupported width was requested: {0:?}")]
|
||||
UnsupportedScalar(crate::Scalar),
|
||||
#[error("{0}")]
|
||||
Unimplemented(String), // TODO: Error used only during development
|
||||
#[error("{0}")]
|
||||
|
32
third_party/rust/naga/src/back/hlsl/storage.rs
vendored
32
third_party/rust/naga/src/back/hlsl/storage.rs
vendored
@ -157,25 +157,21 @@ impl<W: fmt::Write> super::Writer<'_, W> {
|
||||
func_ctx: &FunctionCtx,
|
||||
) -> BackendResult {
|
||||
match *result_ty.inner_with(&module.types) {
|
||||
crate::TypeInner::Scalar { kind, width: _ } => {
|
||||
crate::TypeInner::Scalar(scalar) => {
|
||||
// working around the borrow checker in `self.write_expr`
|
||||
let chain = mem::take(&mut self.temp_access_chain);
|
||||
let var_name = &self.names[&NameKey::GlobalVariable(var_handle)];
|
||||
let cast = kind.to_hlsl_cast();
|
||||
let cast = scalar.kind.to_hlsl_cast();
|
||||
write!(self.out, "{cast}({var_name}.Load(")?;
|
||||
self.write_storage_address(module, &chain, func_ctx)?;
|
||||
write!(self.out, "))")?;
|
||||
self.temp_access_chain = chain;
|
||||
}
|
||||
crate::TypeInner::Vector {
|
||||
size,
|
||||
kind,
|
||||
width: _,
|
||||
} => {
|
||||
crate::TypeInner::Vector { size, scalar } => {
|
||||
// working around the borrow checker in `self.write_expr`
|
||||
let chain = mem::take(&mut self.temp_access_chain);
|
||||
let var_name = &self.names[&NameKey::GlobalVariable(var_handle)];
|
||||
let cast = kind.to_hlsl_cast();
|
||||
let cast = scalar.kind.to_hlsl_cast();
|
||||
write!(self.out, "{}({}.Load{}(", cast, var_name, size as u8)?;
|
||||
self.write_storage_address(module, &chain, func_ctx)?;
|
||||
write!(self.out, "))")?;
|
||||
@ -189,7 +185,7 @@ impl<W: fmt::Write> super::Writer<'_, W> {
|
||||
write!(
|
||||
self.out,
|
||||
"{}{}x{}(",
|
||||
crate::ScalarKind::Float.to_hlsl_str(width)?,
|
||||
crate::Scalar::float(width).to_hlsl_str()?,
|
||||
columns as u8,
|
||||
rows as u8,
|
||||
)?;
|
||||
@ -199,8 +195,7 @@ impl<W: fmt::Write> super::Writer<'_, W> {
|
||||
let iter = (0..columns as u32).map(|i| {
|
||||
let ty_inner = crate::TypeInner::Vector {
|
||||
size: rows,
|
||||
kind: crate::ScalarKind::Float,
|
||||
width,
|
||||
scalar: crate::Scalar::float(width),
|
||||
};
|
||||
(TypeResolution::Value(ty_inner), i * row_stride)
|
||||
});
|
||||
@ -296,7 +291,7 @@ impl<W: fmt::Write> super::Writer<'_, W> {
|
||||
}
|
||||
};
|
||||
match *ty_resolution.inner_with(&module.types) {
|
||||
crate::TypeInner::Scalar { .. } => {
|
||||
crate::TypeInner::Scalar(_) => {
|
||||
// working around the borrow checker in `self.write_expr`
|
||||
let chain = mem::take(&mut self.temp_access_chain);
|
||||
let var_name = &self.names[&NameKey::GlobalVariable(var_handle)];
|
||||
@ -330,7 +325,7 @@ impl<W: fmt::Write> super::Writer<'_, W> {
|
||||
self.out,
|
||||
"{}{}{}x{} {}{} = ",
|
||||
level.next(),
|
||||
crate::ScalarKind::Float.to_hlsl_str(width)?,
|
||||
crate::Scalar::float(width).to_hlsl_str()?,
|
||||
columns as u8,
|
||||
rows as u8,
|
||||
STORE_TEMP_NAME,
|
||||
@ -348,8 +343,7 @@ impl<W: fmt::Write> super::Writer<'_, W> {
|
||||
.push(SubAccess::Offset(i * row_stride));
|
||||
let ty_inner = crate::TypeInner::Vector {
|
||||
size: rows,
|
||||
kind: crate::ScalarKind::Float,
|
||||
width,
|
||||
scalar: crate::Scalar::float(width),
|
||||
};
|
||||
let sv = StoreValue::TempIndex {
|
||||
depth,
|
||||
@ -470,8 +464,8 @@ impl<W: fmt::Write> super::Writer<'_, W> {
|
||||
crate::TypeInner::Pointer { base, .. } => match module.types[base].inner {
|
||||
crate::TypeInner::Struct { ref members, .. } => Parent::Struct(members),
|
||||
crate::TypeInner::Array { stride, .. } => Parent::Array { stride },
|
||||
crate::TypeInner::Vector { width, .. } => Parent::Array {
|
||||
stride: width as u32,
|
||||
crate::TypeInner::Vector { scalar, .. } => Parent::Array {
|
||||
stride: scalar.width as u32,
|
||||
},
|
||||
crate::TypeInner::Matrix { rows, width, .. } => Parent::Array {
|
||||
// The stride between matrices is the count of rows as this is how
|
||||
@ -480,8 +474,8 @@ impl<W: fmt::Write> super::Writer<'_, W> {
|
||||
},
|
||||
_ => unreachable!(),
|
||||
},
|
||||
crate::TypeInner::ValuePointer { width, .. } => Parent::Array {
|
||||
stride: width as u32,
|
||||
crate::TypeInner::ValuePointer { scalar, .. } => Parent::Array {
|
||||
stride: scalar.width as u32,
|
||||
},
|
||||
_ => unreachable!(),
|
||||
};
|
||||
|
43
third_party/rust/naga/src/back/hlsl/writer.rs
vendored
43
third_party/rust/naga/src/back/hlsl/writer.rs
vendored
@ -912,8 +912,7 @@ impl<'a, W: fmt::Write> super::Writer<'a, W> {
|
||||
} if member.binding.is_none() && rows == crate::VectorSize::Bi => {
|
||||
let vec_ty = crate::TypeInner::Vector {
|
||||
size: rows,
|
||||
kind: crate::ScalarKind::Float,
|
||||
width,
|
||||
scalar: crate::Scalar::float(width),
|
||||
};
|
||||
let field_name_key = NameKey::StructMember(handle, index as u32);
|
||||
|
||||
@ -1024,14 +1023,14 @@ impl<'a, W: fmt::Write> super::Writer<'a, W> {
|
||||
/// Adds no trailing or leading whitespace
|
||||
pub(super) fn write_value_type(&mut self, module: &Module, inner: &TypeInner) -> BackendResult {
|
||||
match *inner {
|
||||
TypeInner::Scalar { kind, width } | TypeInner::Atomic { kind, width } => {
|
||||
write!(self.out, "{}", kind.to_hlsl_str(width)?)?;
|
||||
TypeInner::Scalar(scalar) | TypeInner::Atomic(scalar) => {
|
||||
write!(self.out, "{}", scalar.to_hlsl_str()?)?;
|
||||
}
|
||||
TypeInner::Vector { size, kind, width } => {
|
||||
TypeInner::Vector { size, scalar } => {
|
||||
write!(
|
||||
self.out,
|
||||
"{}{}",
|
||||
kind.to_hlsl_str(width)?,
|
||||
scalar.to_hlsl_str()?,
|
||||
back::vector_size_str(size)
|
||||
)?;
|
||||
}
|
||||
@ -1047,7 +1046,7 @@ impl<'a, W: fmt::Write> super::Writer<'a, W> {
|
||||
write!(
|
||||
self.out,
|
||||
"{}{}x{}",
|
||||
crate::ScalarKind::Float.to_hlsl_str(width)?,
|
||||
crate::Scalar::float(width).to_hlsl_str()?,
|
||||
back::vector_size_str(columns),
|
||||
back::vector_size_str(rows),
|
||||
)?;
|
||||
@ -2484,7 +2483,7 @@ impl<'a, W: fmt::Write> super::Writer<'a, W> {
|
||||
write!(self.out, ")")?;
|
||||
|
||||
// return x component if return type is scalar
|
||||
if let TypeInner::Scalar { .. } = *func_ctx.resolve_type(expr, &module.types) {
|
||||
if let TypeInner::Scalar(_) = *func_ctx.resolve_type(expr, &module.types) {
|
||||
write!(self.out, ".x")?;
|
||||
}
|
||||
}
|
||||
@ -2567,23 +2566,27 @@ impl<'a, W: fmt::Write> super::Writer<'a, W> {
|
||||
let inner = func_ctx.resolve_type(expr, &module.types);
|
||||
match convert {
|
||||
Some(dst_width) => {
|
||||
let scalar = crate::Scalar {
|
||||
kind,
|
||||
width: dst_width,
|
||||
};
|
||||
match *inner {
|
||||
TypeInner::Vector { size, .. } => {
|
||||
write!(
|
||||
self.out,
|
||||
"{}{}(",
|
||||
kind.to_hlsl_str(dst_width)?,
|
||||
scalar.to_hlsl_str()?,
|
||||
back::vector_size_str(size)
|
||||
)?;
|
||||
}
|
||||
TypeInner::Scalar { .. } => {
|
||||
write!(self.out, "{}(", kind.to_hlsl_str(dst_width)?,)?;
|
||||
TypeInner::Scalar(_) => {
|
||||
write!(self.out, "{}(", scalar.to_hlsl_str()?,)?;
|
||||
}
|
||||
TypeInner::Matrix { columns, rows, .. } => {
|
||||
write!(
|
||||
self.out,
|
||||
"{}{}x{}(",
|
||||
kind.to_hlsl_str(dst_width)?,
|
||||
scalar.to_hlsl_str()?,
|
||||
back::vector_size_str(columns),
|
||||
back::vector_size_str(rows)
|
||||
)?;
|
||||
@ -2964,14 +2967,14 @@ impl<'a, W: fmt::Write> super::Writer<'a, W> {
|
||||
}
|
||||
Function::CountTrailingZeros => {
|
||||
match *func_ctx.resolve_type(arg, &module.types) {
|
||||
TypeInner::Vector { size, kind, .. } => {
|
||||
TypeInner::Vector { size, scalar } => {
|
||||
let s = match size {
|
||||
crate::VectorSize::Bi => ".xx",
|
||||
crate::VectorSize::Tri => ".xxx",
|
||||
crate::VectorSize::Quad => ".xxxx",
|
||||
};
|
||||
|
||||
if let ScalarKind::Uint = kind {
|
||||
if let ScalarKind::Uint = scalar.kind {
|
||||
write!(self.out, "min((32u){s}, firstbitlow(")?;
|
||||
self.write_expr(module, arg, func_ctx)?;
|
||||
write!(self.out, "))")?;
|
||||
@ -2981,8 +2984,8 @@ impl<'a, W: fmt::Write> super::Writer<'a, W> {
|
||||
write!(self.out, ")))")?;
|
||||
}
|
||||
}
|
||||
TypeInner::Scalar { kind, .. } => {
|
||||
if let ScalarKind::Uint = kind {
|
||||
TypeInner::Scalar(scalar) => {
|
||||
if let ScalarKind::Uint = scalar.kind {
|
||||
write!(self.out, "min(32u, firstbitlow(")?;
|
||||
self.write_expr(module, arg, func_ctx)?;
|
||||
write!(self.out, "))")?;
|
||||
@ -2999,14 +3002,14 @@ impl<'a, W: fmt::Write> super::Writer<'a, W> {
|
||||
}
|
||||
Function::CountLeadingZeros => {
|
||||
match *func_ctx.resolve_type(arg, &module.types) {
|
||||
TypeInner::Vector { size, kind, .. } => {
|
||||
TypeInner::Vector { size, scalar } => {
|
||||
let s = match size {
|
||||
crate::VectorSize::Bi => ".xx",
|
||||
crate::VectorSize::Tri => ".xxx",
|
||||
crate::VectorSize::Quad => ".xxxx",
|
||||
};
|
||||
|
||||
if let ScalarKind::Uint = kind {
|
||||
if let ScalarKind::Uint = scalar.kind {
|
||||
write!(self.out, "((31u){s} - firstbithigh(")?;
|
||||
self.write_expr(module, arg, func_ctx)?;
|
||||
write!(self.out, "))")?;
|
||||
@ -3021,8 +3024,8 @@ impl<'a, W: fmt::Write> super::Writer<'a, W> {
|
||||
write!(self.out, ")))")?;
|
||||
}
|
||||
}
|
||||
TypeInner::Scalar { kind, .. } => {
|
||||
if let ScalarKind::Uint = kind {
|
||||
TypeInner::Scalar(scalar) => {
|
||||
if let ScalarKind::Uint = scalar.kind {
|
||||
write!(self.out, "(31u - firstbithigh(")?;
|
||||
self.write_expr(module, arg, func_ctx)?;
|
||||
write!(self.out, "))")?;
|
||||
|
185
third_party/rust/naga/src/back/msl/writer.rs
vendored
185
third_party/rust/naga/src/back/msl/writer.rs
vendored
@ -45,28 +45,28 @@ pub(crate) const FREXP_FUNCTION: &str = "naga_frexp";
|
||||
/// - A two element slice `[ROWS COLUMNS]` produces a matrix of the given size.
|
||||
fn put_numeric_type(
|
||||
out: &mut impl Write,
|
||||
kind: crate::ScalarKind,
|
||||
scalar: crate::Scalar,
|
||||
sizes: &[crate::VectorSize],
|
||||
) -> Result<(), FmtError> {
|
||||
match (kind, sizes) {
|
||||
(kind, &[]) => {
|
||||
write!(out, "{}", kind.to_msl_name())
|
||||
match (scalar, sizes) {
|
||||
(scalar, &[]) => {
|
||||
write!(out, "{}", scalar.to_msl_name())
|
||||
}
|
||||
(kind, &[rows]) => {
|
||||
(scalar, &[rows]) => {
|
||||
write!(
|
||||
out,
|
||||
"{}::{}{}",
|
||||
NAMESPACE,
|
||||
kind.to_msl_name(),
|
||||
scalar.to_msl_name(),
|
||||
back::vector_size_str(rows)
|
||||
)
|
||||
}
|
||||
(kind, &[rows, columns]) => {
|
||||
(scalar, &[rows, columns]) => {
|
||||
write!(
|
||||
out,
|
||||
"{}::{}{}x{}",
|
||||
NAMESPACE,
|
||||
kind.to_msl_name(),
|
||||
scalar.to_msl_name(),
|
||||
back::vector_size_str(columns),
|
||||
back::vector_size_str(rows)
|
||||
)
|
||||
@ -96,13 +96,13 @@ impl<'a> Display for TypeContext<'a> {
|
||||
}
|
||||
|
||||
match ty.inner {
|
||||
crate::TypeInner::Scalar { kind, .. } => put_numeric_type(out, kind, &[]),
|
||||
crate::TypeInner::Atomic { kind, .. } => {
|
||||
write!(out, "{}::atomic_{}", NAMESPACE, kind.to_msl_name())
|
||||
crate::TypeInner::Scalar(scalar) => put_numeric_type(out, scalar, &[]),
|
||||
crate::TypeInner::Atomic(scalar) => {
|
||||
write!(out, "{}::atomic_{}", NAMESPACE, scalar.to_msl_name())
|
||||
}
|
||||
crate::TypeInner::Vector { size, kind, .. } => put_numeric_type(out, kind, &[size]),
|
||||
crate::TypeInner::Vector { size, scalar } => put_numeric_type(out, scalar, &[size]),
|
||||
crate::TypeInner::Matrix { columns, rows, .. } => {
|
||||
put_numeric_type(out, crate::ScalarKind::Float, &[rows, columns])
|
||||
put_numeric_type(out, crate::Scalar::F32, &[rows, columns])
|
||||
}
|
||||
crate::TypeInner::Pointer { base, space } => {
|
||||
let sub = Self {
|
||||
@ -118,8 +118,7 @@ impl<'a> Display for TypeContext<'a> {
|
||||
}
|
||||
crate::TypeInner::ValuePointer {
|
||||
size,
|
||||
kind,
|
||||
width: _,
|
||||
scalar,
|
||||
space,
|
||||
} => {
|
||||
match space.to_msl_name() {
|
||||
@ -127,8 +126,8 @@ impl<'a> Display for TypeContext<'a> {
|
||||
None => return Ok(()),
|
||||
};
|
||||
match size {
|
||||
Some(rows) => put_numeric_type(out, kind, &[rows])?,
|
||||
None => put_numeric_type(out, kind, &[])?,
|
||||
Some(rows) => put_numeric_type(out, scalar, &[rows])?,
|
||||
None => put_numeric_type(out, scalar, &[])?,
|
||||
};
|
||||
|
||||
write!(out, "&")
|
||||
@ -194,7 +193,7 @@ impl<'a> Display for TypeContext<'a> {
|
||||
("texture", "", format.into(), access)
|
||||
}
|
||||
};
|
||||
let base_name = kind.to_msl_name();
|
||||
let base_name = crate::Scalar { kind, width: 4 }.to_msl_name();
|
||||
let array_str = if arrayed { "_array" } else { "" };
|
||||
write!(
|
||||
out,
|
||||
@ -319,13 +318,26 @@ pub struct Writer<W> {
|
||||
struct_member_pads: FastHashSet<(Handle<crate::Type>, u32)>,
|
||||
}
|
||||
|
||||
impl crate::ScalarKind {
|
||||
impl crate::Scalar {
|
||||
const fn to_msl_name(self) -> &'static str {
|
||||
use crate::ScalarKind as Sk;
|
||||
match self {
|
||||
Self::Float => "float",
|
||||
Self::Sint => "int",
|
||||
Self::Uint => "uint",
|
||||
Self::Bool => "bool",
|
||||
Self {
|
||||
kind: Sk::Float,
|
||||
width: _,
|
||||
} => "float",
|
||||
Self {
|
||||
kind: Sk::Sint,
|
||||
width: _,
|
||||
} => "int",
|
||||
Self {
|
||||
kind: Sk::Uint,
|
||||
width: _,
|
||||
} => "uint",
|
||||
Self {
|
||||
kind: Sk::Bool,
|
||||
width: _,
|
||||
} => "bool",
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -343,7 +355,7 @@ fn should_pack_struct_member(
|
||||
span: u32,
|
||||
index: usize,
|
||||
module: &crate::Module,
|
||||
) -> Option<crate::ScalarKind> {
|
||||
) -> Option<crate::Scalar> {
|
||||
let member = &members[index];
|
||||
//Note: this is imperfect - the same structure can be used for host-shared
|
||||
// things, where packed float would matter.
|
||||
@ -362,9 +374,8 @@ fn should_pack_struct_member(
|
||||
match *ty_inner {
|
||||
crate::TypeInner::Vector {
|
||||
size: crate::VectorSize::Tri,
|
||||
width: 4,
|
||||
kind,
|
||||
} if member.offset & 0xF != 0 || is_tight => Some(kind),
|
||||
scalar: scalar @ crate::Scalar { width: 4, .. },
|
||||
} if member.offset & 0xF != 0 || is_tight => Some(scalar),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
@ -442,10 +453,10 @@ impl crate::Type {
|
||||
|
||||
match self.inner {
|
||||
// value types are concise enough, we only alias them if they are named
|
||||
Ti::Scalar { .. }
|
||||
Ti::Scalar(_)
|
||||
| Ti::Vector { .. }
|
||||
| Ti::Matrix { .. }
|
||||
| Ti::Atomic { .. }
|
||||
| Ti::Atomic(_)
|
||||
| Ti::Pointer { .. }
|
||||
| Ti::ValuePointer { .. } => self.name.is_some(),
|
||||
// composite types are better to be aliased, regardless of the name
|
||||
@ -549,10 +560,7 @@ impl<'a> ExpressionContext<'a> {
|
||||
index::access_needs_check(base, index, self.module, self.function, self.info)
|
||||
}
|
||||
|
||||
fn get_packed_vec_kind(
|
||||
&self,
|
||||
expr_handle: Handle<crate::Expression>,
|
||||
) -> Option<crate::ScalarKind> {
|
||||
fn get_packed_vec_kind(&self, expr_handle: Handle<crate::Expression>) -> Option<crate::Scalar> {
|
||||
match self.function.expressions[expr_handle] {
|
||||
crate::Expression::AccessIndex { base, index } => {
|
||||
let ty = match *self.resolve_type(base) {
|
||||
@ -673,7 +681,8 @@ impl<W: Write> Writer<W> {
|
||||
crate::TypeInner::Image { dim, .. } => dim,
|
||||
ref other => unreachable!("Unexpected type {:?}", other),
|
||||
};
|
||||
let coordinate_type = kind.to_msl_name();
|
||||
let scalar = crate::Scalar { kind, width: 4 };
|
||||
let coordinate_type = scalar.to_msl_name();
|
||||
match dim {
|
||||
crate::ImageDimension::D1 => {
|
||||
// Since 1D textures never have mipmaps, MSL requires that the
|
||||
@ -721,11 +730,11 @@ impl<W: Write> Writer<W> {
|
||||
) -> BackendResult {
|
||||
// coordinates in IR are int, but Metal expects uint
|
||||
match *context.resolve_type(expr) {
|
||||
crate::TypeInner::Scalar { .. } => {
|
||||
put_numeric_type(&mut self.out, crate::ScalarKind::Uint, &[])?
|
||||
crate::TypeInner::Scalar(_) => {
|
||||
put_numeric_type(&mut self.out, crate::Scalar::U32, &[])?
|
||||
}
|
||||
crate::TypeInner::Vector { size, .. } => {
|
||||
put_numeric_type(&mut self.out, crate::ScalarKind::Uint, &[size])?
|
||||
put_numeric_type(&mut self.out, crate::Scalar::U32, &[size])?
|
||||
}
|
||||
_ => return Err(Error::Validation),
|
||||
};
|
||||
@ -1299,7 +1308,7 @@ impl<W: Write> Writer<W> {
|
||||
};
|
||||
write!(self.out, "{ty_name}")?;
|
||||
match module.types[ty].inner {
|
||||
crate::TypeInner::Scalar { .. }
|
||||
crate::TypeInner::Scalar(_)
|
||||
| crate::TypeInner::Vector { .. }
|
||||
| crate::TypeInner::Matrix { .. } => {
|
||||
self.put_call_parameters_impl(
|
||||
@ -1326,11 +1335,11 @@ impl<W: Write> Writer<W> {
|
||||
}
|
||||
}
|
||||
crate::Expression::Splat { size, value } => {
|
||||
let scalar_kind = match *get_expr_ty(ctx, value).inner_with(&module.types) {
|
||||
crate::TypeInner::Scalar { kind, .. } => kind,
|
||||
let scalar = match *get_expr_ty(ctx, value).inner_with(&module.types) {
|
||||
crate::TypeInner::Scalar(scalar) => scalar,
|
||||
_ => return Err(Error::Validation),
|
||||
};
|
||||
put_numeric_type(&mut self.out, scalar_kind, &[size])?;
|
||||
put_numeric_type(&mut self.out, scalar, &[size])?;
|
||||
write!(self.out, "(")?;
|
||||
put_expression(self, ctx, value)?;
|
||||
write!(self.out, ")")?;
|
||||
@ -1626,10 +1635,10 @@ impl<W: Write> Writer<W> {
|
||||
accept,
|
||||
reject,
|
||||
} => match *context.resolve_type(condition) {
|
||||
crate::TypeInner::Scalar {
|
||||
crate::TypeInner::Scalar(crate::Scalar {
|
||||
kind: crate::ScalarKind::Bool,
|
||||
..
|
||||
} => {
|
||||
}) => {
|
||||
if !is_scoped {
|
||||
write!(self.out, "(")?;
|
||||
}
|
||||
@ -1643,7 +1652,11 @@ impl<W: Write> Writer<W> {
|
||||
}
|
||||
}
|
||||
crate::TypeInner::Vector {
|
||||
kind: crate::ScalarKind::Bool,
|
||||
scalar:
|
||||
crate::Scalar {
|
||||
kind: crate::ScalarKind::Bool,
|
||||
..
|
||||
},
|
||||
..
|
||||
} => {
|
||||
write!(self.out, "{NAMESPACE}::select(")?;
|
||||
@ -1687,7 +1700,7 @@ impl<W: Write> Writer<W> {
|
||||
|
||||
let arg_type = context.resolve_type(arg);
|
||||
let scalar_argument = match arg_type {
|
||||
&crate::TypeInner::Scalar { .. } => true,
|
||||
&crate::TypeInner::Scalar(_) => true,
|
||||
_ => false,
|
||||
};
|
||||
|
||||
@ -1732,7 +1745,11 @@ impl<W: Write> Writer<W> {
|
||||
// geometry
|
||||
Mf::Dot => match *context.resolve_type(arg) {
|
||||
crate::TypeInner::Vector {
|
||||
kind: crate::ScalarKind::Float,
|
||||
scalar:
|
||||
crate::Scalar {
|
||||
kind: crate::ScalarKind::Float,
|
||||
..
|
||||
},
|
||||
..
|
||||
} => "dot",
|
||||
crate::TypeInner::Vector { size, .. } => {
|
||||
@ -1838,16 +1855,16 @@ impl<W: Write> Writer<W> {
|
||||
|
||||
// or metal will complain that select is ambiguous
|
||||
match *inner {
|
||||
crate::TypeInner::Vector { size, kind, .. } => {
|
||||
crate::TypeInner::Vector { size, scalar } => {
|
||||
let size = back::vector_size_str(size);
|
||||
if let crate::ScalarKind::Sint = kind {
|
||||
if let crate::ScalarKind::Sint = scalar.kind {
|
||||
write!(self.out, "int{size}")?;
|
||||
} else {
|
||||
write!(self.out, "uint{size}")?;
|
||||
}
|
||||
}
|
||||
crate::TypeInner::Scalar { kind, .. } => {
|
||||
if let crate::ScalarKind::Sint = kind {
|
||||
crate::TypeInner::Scalar(scalar) => {
|
||||
if let crate::ScalarKind::Sint = scalar.kind {
|
||||
write!(self.out, "int")?;
|
||||
} else {
|
||||
write!(self.out, "uint")?;
|
||||
@ -1893,19 +1910,15 @@ impl<W: Write> Writer<W> {
|
||||
kind,
|
||||
convert,
|
||||
} => match *context.resolve_type(expr) {
|
||||
crate::TypeInner::Scalar {
|
||||
kind: src_kind,
|
||||
width: src_width,
|
||||
}
|
||||
| crate::TypeInner::Vector {
|
||||
kind: src_kind,
|
||||
width: src_width,
|
||||
..
|
||||
} => {
|
||||
crate::TypeInner::Scalar(src) | crate::TypeInner::Vector { scalar: src, .. } => {
|
||||
let target_scalar = crate::Scalar {
|
||||
kind,
|
||||
width: convert.unwrap_or(src.width),
|
||||
};
|
||||
let is_bool_cast =
|
||||
kind == crate::ScalarKind::Bool || src_kind == crate::ScalarKind::Bool;
|
||||
kind == crate::ScalarKind::Bool || src.kind == crate::ScalarKind::Bool;
|
||||
let op = match convert {
|
||||
Some(w) if w == src_width || is_bool_cast => "static_cast",
|
||||
Some(w) if w == src.width || is_bool_cast => "static_cast",
|
||||
Some(8) if kind == crate::ScalarKind::Float => {
|
||||
return Err(Error::CapabilityNotSupported(valid::Capabilities::FLOAT64))
|
||||
}
|
||||
@ -1915,16 +1928,24 @@ impl<W: Write> Writer<W> {
|
||||
write!(self.out, "{op}<")?;
|
||||
match *context.resolve_type(expr) {
|
||||
crate::TypeInner::Vector { size, .. } => {
|
||||
put_numeric_type(&mut self.out, kind, &[size])?
|
||||
put_numeric_type(&mut self.out, target_scalar, &[size])?
|
||||
}
|
||||
_ => put_numeric_type(&mut self.out, kind, &[])?,
|
||||
_ => put_numeric_type(&mut self.out, target_scalar, &[])?,
|
||||
};
|
||||
write!(self.out, ">(")?;
|
||||
self.put_expression(expr, context, true)?;
|
||||
write!(self.out, ")")?;
|
||||
}
|
||||
crate::TypeInner::Matrix { columns, rows, .. } => {
|
||||
put_numeric_type(&mut self.out, kind, &[rows, columns])?;
|
||||
crate::TypeInner::Matrix {
|
||||
columns,
|
||||
rows,
|
||||
width,
|
||||
} => {
|
||||
let target_scalar = crate::Scalar {
|
||||
kind,
|
||||
width: convert.unwrap_or(width),
|
||||
};
|
||||
put_numeric_type(&mut self.out, target_scalar, &[rows, columns])?;
|
||||
write!(self.out, "(")?;
|
||||
self.put_expression(expr, context, true)?;
|
||||
write!(self.out, ")")?;
|
||||
@ -2008,8 +2029,8 @@ impl<W: Write> Writer<W> {
|
||||
context: &ExpressionContext,
|
||||
is_scoped: bool,
|
||||
) -> BackendResult {
|
||||
if let Some(scalar_kind) = context.get_packed_vec_kind(expr_handle) {
|
||||
write!(self.out, "{}::{}3(", NAMESPACE, scalar_kind.to_msl_name())?;
|
||||
if let Some(scalar) = context.get_packed_vec_kind(expr_handle) {
|
||||
write!(self.out, "{}::{}3(", NAMESPACE, scalar.to_msl_name())?;
|
||||
self.put_expression(expr_handle, context, is_scoped)?;
|
||||
write!(self.out, ")")?;
|
||||
} else {
|
||||
@ -2475,8 +2496,8 @@ impl<W: Write> Writer<W> {
|
||||
// check what kind of product this is depending
|
||||
// on the resolve type of the Dot function itself
|
||||
let inner = context.resolve_type(expr_handle);
|
||||
if let crate::TypeInner::Scalar { kind, .. } = *inner {
|
||||
match kind {
|
||||
if let crate::TypeInner::Scalar(scalar) = *inner {
|
||||
match scalar.kind {
|
||||
crate::ScalarKind::Sint | crate::ScalarKind::Uint => {
|
||||
self.need_bake_expressions.insert(arg);
|
||||
self.need_bake_expressions.insert(arg1.unwrap());
|
||||
@ -2522,14 +2543,19 @@ impl<W: Write> Writer<W> {
|
||||
};
|
||||
write!(self.out, "{ty_name}")?;
|
||||
}
|
||||
TypeResolution::Value(crate::TypeInner::Scalar { kind, .. }) => {
|
||||
put_numeric_type(&mut self.out, kind, &[])?;
|
||||
TypeResolution::Value(crate::TypeInner::Scalar(scalar)) => {
|
||||
put_numeric_type(&mut self.out, scalar, &[])?;
|
||||
}
|
||||
TypeResolution::Value(crate::TypeInner::Vector { size, kind, .. }) => {
|
||||
put_numeric_type(&mut self.out, kind, &[size])?;
|
||||
TypeResolution::Value(crate::TypeInner::Vector { size, scalar }) => {
|
||||
put_numeric_type(&mut self.out, scalar, &[size])?;
|
||||
}
|
||||
TypeResolution::Value(crate::TypeInner::Matrix { columns, rows, .. }) => {
|
||||
put_numeric_type(&mut self.out, crate::ScalarKind::Float, &[rows, columns])?;
|
||||
TypeResolution::Value(crate::TypeInner::Matrix {
|
||||
columns,
|
||||
rows,
|
||||
width,
|
||||
}) => {
|
||||
let element = crate::Scalar::float(width);
|
||||
put_numeric_type(&mut self.out, element, &[rows, columns])?;
|
||||
}
|
||||
TypeResolution::Value(ref other) => {
|
||||
log::warn!("Type {:?} isn't a known local", other); //TEMP!
|
||||
@ -3292,13 +3318,13 @@ impl<W: Write> Writer<W> {
|
||||
|
||||
// If the member should be packed (as is the case for a misaligned vec3) issue a packed vector
|
||||
match should_pack_struct_member(members, span, index, module) {
|
||||
Some(kind) => {
|
||||
Some(scalar) => {
|
||||
writeln!(
|
||||
self.out,
|
||||
"{}{}::packed_{}3 {};",
|
||||
back::INDENT,
|
||||
NAMESPACE,
|
||||
kind.to_msl_name(),
|
||||
scalar.to_msl_name(),
|
||||
member_name
|
||||
)?;
|
||||
}
|
||||
@ -3322,11 +3348,10 @@ impl<W: Write> Writer<W> {
|
||||
// for 3-component vectors, add one component
|
||||
if let crate::TypeInner::Vector {
|
||||
size: crate::VectorSize::Tri,
|
||||
kind: _,
|
||||
width,
|
||||
scalar,
|
||||
} = *ty_inner
|
||||
{
|
||||
last_offset += width as u32;
|
||||
last_offset += scalar.width as u32;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
179
third_party/rust/naga/src/back/spv/block.rs
vendored
179
third_party/rust/naga/src/back/spv/block.rs
vendored
@ -12,7 +12,7 @@ use spirv::Word;
|
||||
|
||||
fn get_dimension(type_inner: &crate::TypeInner) -> Dimension {
|
||||
match *type_inner {
|
||||
crate::TypeInner::Scalar { .. } => Dimension::Scalar,
|
||||
crate::TypeInner::Scalar(_) => Dimension::Scalar,
|
||||
crate::TypeInner::Vector { .. } => Dimension::Vector,
|
||||
crate::TypeInner::Matrix { .. } => Dimension::Matrix,
|
||||
_ => unreachable!(),
|
||||
@ -78,8 +78,7 @@ impl Writer {
|
||||
) -> Result<(), Error> {
|
||||
let float_ptr_type_id = self.get_type_id(LookupType::Local(LocalType::Value {
|
||||
vector_size: None,
|
||||
kind: crate::ScalarKind::Float,
|
||||
width: 4,
|
||||
scalar: crate::Scalar::F32,
|
||||
pointer_space: Some(spirv::StorageClass::Output),
|
||||
}));
|
||||
let index_y_id = self.get_index_constant(1);
|
||||
@ -93,8 +92,7 @@ impl Writer {
|
||||
|
||||
let float_type_id = self.get_type_id(LookupType::Local(LocalType::Value {
|
||||
vector_size: None,
|
||||
kind: crate::ScalarKind::Float,
|
||||
width: 4,
|
||||
scalar: crate::Scalar::F32,
|
||||
pointer_space: None,
|
||||
}));
|
||||
let load_id = self.id_gen.next();
|
||||
@ -120,8 +118,7 @@ impl Writer {
|
||||
) -> Result<(), Error> {
|
||||
let float_type_id = self.get_type_id(LookupType::Local(LocalType::Value {
|
||||
vector_size: None,
|
||||
kind: crate::ScalarKind::Float,
|
||||
width: 4,
|
||||
scalar: crate::Scalar::F32,
|
||||
pointer_space: None,
|
||||
}));
|
||||
let zero_scalar_id = self.get_constant_scalar(crate::Literal::F32(0.0));
|
||||
@ -489,8 +486,8 @@ impl<'w> BlockContext<'w> {
|
||||
|
||||
let spirv_op = match op {
|
||||
crate::BinaryOperator::Add => match *left_ty_inner {
|
||||
crate::TypeInner::Scalar { kind, .. }
|
||||
| crate::TypeInner::Vector { kind, .. } => match kind {
|
||||
crate::TypeInner::Scalar(scalar)
|
||||
| crate::TypeInner::Vector { scalar, .. } => match scalar.kind {
|
||||
crate::ScalarKind::Float => spirv::Op::FAdd,
|
||||
_ => spirv::Op::IAdd,
|
||||
},
|
||||
@ -517,8 +514,8 @@ impl<'w> BlockContext<'w> {
|
||||
_ => unimplemented!(),
|
||||
},
|
||||
crate::BinaryOperator::Subtract => match *left_ty_inner {
|
||||
crate::TypeInner::Scalar { kind, .. }
|
||||
| crate::TypeInner::Vector { kind, .. } => match kind {
|
||||
crate::TypeInner::Scalar(scalar)
|
||||
| crate::TypeInner::Vector { scalar, .. } => match scalar.kind {
|
||||
crate::ScalarKind::Float => spirv::Op::FSub,
|
||||
_ => spirv::Op::ISub,
|
||||
},
|
||||
@ -741,20 +738,19 @@ impl<'w> BlockContext<'w> {
|
||||
other => unimplemented!("Unexpected max({:?})", other),
|
||||
}),
|
||||
Mf::Saturate => {
|
||||
let (maybe_size, width) = match *arg_ty {
|
||||
crate::TypeInner::Vector { size, width, .. } => (Some(size), width),
|
||||
crate::TypeInner::Scalar { width, .. } => (None, width),
|
||||
let (maybe_size, scalar) = match *arg_ty {
|
||||
crate::TypeInner::Vector { size, scalar } => (Some(size), scalar),
|
||||
crate::TypeInner::Scalar(scalar) => (None, scalar),
|
||||
ref other => unimplemented!("Unexpected saturate({:?})", other),
|
||||
};
|
||||
let kind = crate::ScalarKind::Float;
|
||||
let mut arg1_id = self.writer.get_constant_scalar_with(0, kind, width)?;
|
||||
let mut arg2_id = self.writer.get_constant_scalar_with(1, kind, width)?;
|
||||
let scalar = crate::Scalar::float(scalar.width);
|
||||
let mut arg1_id = self.writer.get_constant_scalar_with(0, scalar)?;
|
||||
let mut arg2_id = self.writer.get_constant_scalar_with(1, scalar)?;
|
||||
|
||||
if let Some(size) = maybe_size {
|
||||
let ty = LocalType::Value {
|
||||
vector_size: Some(size),
|
||||
kind,
|
||||
width,
|
||||
scalar,
|
||||
pointer_space: None,
|
||||
}
|
||||
.into();
|
||||
@ -805,7 +801,11 @@ impl<'w> BlockContext<'w> {
|
||||
// geometry
|
||||
Mf::Dot => match *self.fun_info[arg].ty.inner_with(&self.ir_module.types) {
|
||||
crate::TypeInner::Vector {
|
||||
kind: crate::ScalarKind::Float,
|
||||
scalar:
|
||||
crate::Scalar {
|
||||
kind: crate::ScalarKind::Float,
|
||||
..
|
||||
},
|
||||
..
|
||||
} => MathOp::Custom(Instruction::binary(
|
||||
spirv::Op::Dot,
|
||||
@ -866,13 +866,12 @@ impl<'w> BlockContext<'w> {
|
||||
// if the selector is a scalar, we need to splat it
|
||||
(
|
||||
&crate::TypeInner::Vector { size, .. },
|
||||
&crate::TypeInner::Scalar { kind, width },
|
||||
&crate::TypeInner::Scalar(scalar),
|
||||
) => {
|
||||
let selector_type_id =
|
||||
self.get_type_id(LookupType::Local(LocalType::Value {
|
||||
vector_size: Some(size),
|
||||
kind,
|
||||
width,
|
||||
scalar,
|
||||
pointer_space: None,
|
||||
}));
|
||||
self.temp_list.clear();
|
||||
@ -915,14 +914,12 @@ impl<'w> BlockContext<'w> {
|
||||
arg0_id,
|
||||
)),
|
||||
Mf::CountTrailingZeros => {
|
||||
let kind = crate::ScalarKind::Uint;
|
||||
|
||||
let uint_id = match *arg_ty {
|
||||
crate::TypeInner::Vector { size, width, .. } => {
|
||||
crate::TypeInner::Vector { size, mut scalar } => {
|
||||
scalar.kind = crate::ScalarKind::Uint;
|
||||
let ty = LocalType::Value {
|
||||
vector_size: Some(size),
|
||||
kind,
|
||||
width,
|
||||
scalar,
|
||||
pointer_space: None,
|
||||
}
|
||||
.into();
|
||||
@ -930,13 +927,14 @@ impl<'w> BlockContext<'w> {
|
||||
self.temp_list.clear();
|
||||
self.temp_list.resize(
|
||||
size as _,
|
||||
self.writer.get_constant_scalar_with(32, kind, width)?,
|
||||
self.writer.get_constant_scalar_with(32, scalar)?,
|
||||
);
|
||||
|
||||
self.writer.get_constant_composite(ty, &self.temp_list)
|
||||
}
|
||||
crate::TypeInner::Scalar { width, .. } => {
|
||||
self.writer.get_constant_scalar_with(32, kind, width)?
|
||||
crate::TypeInner::Scalar(mut scalar) => {
|
||||
scalar.kind = crate::ScalarKind::Uint;
|
||||
self.writer.get_constant_scalar_with(32, scalar)?
|
||||
}
|
||||
_ => unreachable!(),
|
||||
};
|
||||
@ -959,14 +957,12 @@ impl<'w> BlockContext<'w> {
|
||||
))
|
||||
}
|
||||
Mf::CountLeadingZeros => {
|
||||
let kind = crate::ScalarKind::Sint;
|
||||
|
||||
let (int_type_id, int_id) = match *arg_ty {
|
||||
crate::TypeInner::Vector { size, width, .. } => {
|
||||
crate::TypeInner::Vector { size, mut scalar } => {
|
||||
scalar.kind = crate::ScalarKind::Sint;
|
||||
let ty = LocalType::Value {
|
||||
vector_size: Some(size),
|
||||
kind,
|
||||
width,
|
||||
scalar,
|
||||
pointer_space: None,
|
||||
}
|
||||
.into();
|
||||
@ -974,7 +970,7 @@ impl<'w> BlockContext<'w> {
|
||||
self.temp_list.clear();
|
||||
self.temp_list.resize(
|
||||
size as _,
|
||||
self.writer.get_constant_scalar_with(31, kind, width)?,
|
||||
self.writer.get_constant_scalar_with(31, scalar)?,
|
||||
);
|
||||
|
||||
(
|
||||
@ -982,15 +978,17 @@ impl<'w> BlockContext<'w> {
|
||||
self.writer.get_constant_composite(ty, &self.temp_list),
|
||||
)
|
||||
}
|
||||
crate::TypeInner::Scalar { width, .. } => (
|
||||
self.get_type_id(LookupType::Local(LocalType::Value {
|
||||
vector_size: None,
|
||||
kind,
|
||||
width,
|
||||
pointer_space: None,
|
||||
})),
|
||||
self.writer.get_constant_scalar_with(31, kind, width)?,
|
||||
),
|
||||
crate::TypeInner::Scalar(mut scalar) => {
|
||||
scalar.kind = crate::ScalarKind::Sint;
|
||||
(
|
||||
self.get_type_id(LookupType::Local(LocalType::Value {
|
||||
vector_size: None,
|
||||
scalar,
|
||||
pointer_space: None,
|
||||
})),
|
||||
self.writer.get_constant_scalar_with(31, scalar)?,
|
||||
)
|
||||
}
|
||||
_ => unreachable!(),
|
||||
};
|
||||
|
||||
@ -1139,13 +1137,13 @@ impl<'w> BlockContext<'w> {
|
||||
use crate::ScalarKind as Sk;
|
||||
|
||||
let expr_id = self.cached[expr];
|
||||
let (src_kind, src_size, src_width, is_matrix) =
|
||||
let (src_scalar, src_size, is_matrix) =
|
||||
match *self.fun_info[expr].ty.inner_with(&self.ir_module.types) {
|
||||
crate::TypeInner::Scalar { kind, width } => (kind, None, width, false),
|
||||
crate::TypeInner::Vector { kind, width, size } => {
|
||||
(kind, Some(size), width, false)
|
||||
crate::TypeInner::Scalar(scalar) => (scalar, None, false),
|
||||
crate::TypeInner::Vector { scalar, size } => (scalar, Some(size), false),
|
||||
crate::TypeInner::Matrix { width, .. } => {
|
||||
(crate::Scalar::float(width), None, true)
|
||||
}
|
||||
crate::TypeInner::Matrix { width, .. } => (kind, None, width, true),
|
||||
ref other => {
|
||||
log::error!("As source {:?}", other);
|
||||
return Err(Error::Validation("Unexpected Expression::As source"));
|
||||
@ -1163,11 +1161,12 @@ impl<'w> BlockContext<'w> {
|
||||
// we only support identity casts for matrices
|
||||
Cast::Unary(spirv::Op::CopyObject)
|
||||
} else {
|
||||
match (src_kind, kind, convert) {
|
||||
match (src_scalar.kind, kind, convert) {
|
||||
// Filter out identity casts. Some Adreno drivers are
|
||||
// confused by no-op OpBitCast instructions.
|
||||
(src_kind, kind, convert)
|
||||
if src_kind == kind && convert.unwrap_or(src_width) == src_width =>
|
||||
if src_kind == kind
|
||||
&& convert.filter(|&width| width != src_scalar.width).is_none() =>
|
||||
{
|
||||
Cast::Identity
|
||||
}
|
||||
@ -1175,20 +1174,18 @@ impl<'w> BlockContext<'w> {
|
||||
(_, _, None) => Cast::Unary(spirv::Op::Bitcast),
|
||||
// casting to a bool - generate `OpXxxNotEqual`
|
||||
(_, Sk::Bool, Some(_)) => {
|
||||
let op = match src_kind {
|
||||
let op = match src_scalar.kind {
|
||||
Sk::Sint | Sk::Uint => spirv::Op::INotEqual,
|
||||
Sk::Float => spirv::Op::FUnordNotEqual,
|
||||
Sk::Bool => unreachable!(),
|
||||
};
|
||||
let zero_scalar_id = self
|
||||
.writer
|
||||
.get_constant_scalar_with(0, src_kind, src_width)?;
|
||||
let zero_scalar_id =
|
||||
self.writer.get_constant_scalar_with(0, src_scalar)?;
|
||||
let zero_id = match src_size {
|
||||
Some(size) => {
|
||||
let ty = LocalType::Value {
|
||||
vector_size: Some(size),
|
||||
kind: src_kind,
|
||||
width: src_width,
|
||||
scalar: src_scalar,
|
||||
pointer_space: None,
|
||||
}
|
||||
.into();
|
||||
@ -1205,16 +1202,19 @@ impl<'w> BlockContext<'w> {
|
||||
}
|
||||
// casting from a bool - generate `OpSelect`
|
||||
(Sk::Bool, _, Some(dst_width)) => {
|
||||
let dst_scalar = crate::Scalar {
|
||||
kind,
|
||||
width: dst_width,
|
||||
};
|
||||
let zero_scalar_id =
|
||||
self.writer.get_constant_scalar_with(0, kind, dst_width)?;
|
||||
self.writer.get_constant_scalar_with(0, dst_scalar)?;
|
||||
let one_scalar_id =
|
||||
self.writer.get_constant_scalar_with(1, kind, dst_width)?;
|
||||
self.writer.get_constant_scalar_with(1, dst_scalar)?;
|
||||
let (accept_id, reject_id) = match src_size {
|
||||
Some(size) => {
|
||||
let ty = LocalType::Value {
|
||||
vector_size: Some(size),
|
||||
kind,
|
||||
width: dst_width,
|
||||
scalar: dst_scalar,
|
||||
pointer_space: None,
|
||||
}
|
||||
.into();
|
||||
@ -1239,15 +1239,17 @@ impl<'w> BlockContext<'w> {
|
||||
}
|
||||
(Sk::Float, Sk::Uint, Some(_)) => Cast::Unary(spirv::Op::ConvertFToU),
|
||||
(Sk::Float, Sk::Sint, Some(_)) => Cast::Unary(spirv::Op::ConvertFToS),
|
||||
(Sk::Float, Sk::Float, Some(dst_width)) if src_width != dst_width => {
|
||||
(Sk::Float, Sk::Float, Some(dst_width))
|
||||
if src_scalar.width != dst_width =>
|
||||
{
|
||||
Cast::Unary(spirv::Op::FConvert)
|
||||
}
|
||||
(Sk::Sint, Sk::Float, Some(_)) => Cast::Unary(spirv::Op::ConvertSToF),
|
||||
(Sk::Sint, Sk::Sint, Some(dst_width)) if src_width != dst_width => {
|
||||
(Sk::Sint, Sk::Sint, Some(dst_width)) if src_scalar.width != dst_width => {
|
||||
Cast::Unary(spirv::Op::SConvert)
|
||||
}
|
||||
(Sk::Uint, Sk::Float, Some(_)) => Cast::Unary(spirv::Op::ConvertUToF),
|
||||
(Sk::Uint, Sk::Uint, Some(dst_width)) if src_width != dst_width => {
|
||||
(Sk::Uint, Sk::Uint, Some(dst_width)) if src_scalar.width != dst_width => {
|
||||
Cast::Unary(spirv::Op::UConvert)
|
||||
}
|
||||
// We assume it's either an identity cast, or int-uint.
|
||||
@ -1334,10 +1336,12 @@ impl<'w> BlockContext<'w> {
|
||||
let object_ty = self.fun_info[accept].ty.inner_with(&self.ir_module.types);
|
||||
|
||||
if let (
|
||||
&crate::TypeInner::Scalar {
|
||||
kind: crate::ScalarKind::Bool,
|
||||
width,
|
||||
},
|
||||
&crate::TypeInner::Scalar(
|
||||
condition_scalar @ crate::Scalar {
|
||||
kind: crate::ScalarKind::Bool,
|
||||
..
|
||||
},
|
||||
),
|
||||
&crate::TypeInner::Vector { size, .. },
|
||||
) = (condition_ty, object_ty)
|
||||
{
|
||||
@ -1347,8 +1351,7 @@ impl<'w> BlockContext<'w> {
|
||||
let bool_vector_type_id =
|
||||
self.get_type_id(LookupType::Local(LocalType::Value {
|
||||
vector_size: Some(size),
|
||||
kind: crate::ScalarKind::Bool,
|
||||
width,
|
||||
scalar: condition_scalar,
|
||||
pointer_space: None,
|
||||
}));
|
||||
|
||||
@ -1598,8 +1601,7 @@ impl<'w> BlockContext<'w> {
|
||||
|
||||
let vector_type_id = self.get_type_id(LookupType::Local(LocalType::Value {
|
||||
vector_size: Some(rows),
|
||||
kind: crate::ScalarKind::Float,
|
||||
width,
|
||||
scalar: crate::Scalar::float(width),
|
||||
pointer_space: None,
|
||||
}));
|
||||
|
||||
@ -1649,7 +1651,10 @@ impl<'w> BlockContext<'w> {
|
||||
vector: &crate::TypeInner,
|
||||
) {
|
||||
let (size, kind) = match *vector {
|
||||
crate::TypeInner::Vector { size, kind, .. } => (size, kind),
|
||||
crate::TypeInner::Vector {
|
||||
size,
|
||||
scalar: crate::Scalar { kind, .. },
|
||||
} => (size, kind),
|
||||
_ => unreachable!(),
|
||||
};
|
||||
|
||||
@ -2193,14 +2198,14 @@ impl<'w> BlockContext<'w> {
|
||||
),
|
||||
crate::AtomicFunction::Min => {
|
||||
let spirv_op = match *value_inner {
|
||||
crate::TypeInner::Scalar {
|
||||
crate::TypeInner::Scalar(crate::Scalar {
|
||||
kind: crate::ScalarKind::Sint,
|
||||
width: _,
|
||||
} => spirv::Op::AtomicSMin,
|
||||
crate::TypeInner::Scalar {
|
||||
}) => spirv::Op::AtomicSMin,
|
||||
crate::TypeInner::Scalar(crate::Scalar {
|
||||
kind: crate::ScalarKind::Uint,
|
||||
width: _,
|
||||
} => spirv::Op::AtomicUMin,
|
||||
}) => spirv::Op::AtomicUMin,
|
||||
_ => unimplemented!(),
|
||||
};
|
||||
Instruction::atomic_binary(
|
||||
@ -2215,14 +2220,14 @@ impl<'w> BlockContext<'w> {
|
||||
}
|
||||
crate::AtomicFunction::Max => {
|
||||
let spirv_op = match *value_inner {
|
||||
crate::TypeInner::Scalar {
|
||||
crate::TypeInner::Scalar(crate::Scalar {
|
||||
kind: crate::ScalarKind::Sint,
|
||||
width: _,
|
||||
} => spirv::Op::AtomicSMax,
|
||||
crate::TypeInner::Scalar {
|
||||
}) => spirv::Op::AtomicSMax,
|
||||
crate::TypeInner::Scalar(crate::Scalar {
|
||||
kind: crate::ScalarKind::Uint,
|
||||
width: _,
|
||||
} => spirv::Op::AtomicUMax,
|
||||
}) => spirv::Op::AtomicUMax,
|
||||
_ => unimplemented!(),
|
||||
};
|
||||
Instruction::atomic_binary(
|
||||
@ -2248,11 +2253,10 @@ impl<'w> BlockContext<'w> {
|
||||
}
|
||||
crate::AtomicFunction::Exchange { compare: Some(cmp) } => {
|
||||
let scalar_type_id = match *value_inner {
|
||||
crate::TypeInner::Scalar { kind, width } => {
|
||||
crate::TypeInner::Scalar(scalar) => {
|
||||
self.get_type_id(LookupType::Local(LocalType::Value {
|
||||
vector_size: None,
|
||||
kind,
|
||||
width,
|
||||
scalar,
|
||||
pointer_space: None,
|
||||
}))
|
||||
}
|
||||
@ -2261,8 +2265,7 @@ impl<'w> BlockContext<'w> {
|
||||
let bool_type_id =
|
||||
self.get_type_id(LookupType::Local(LocalType::Value {
|
||||
vector_size: None,
|
||||
kind: crate::ScalarKind::Bool,
|
||||
width: crate::BOOL_WIDTH,
|
||||
scalar: crate::Scalar::BOOL,
|
||||
pointer_space: None,
|
||||
}));
|
||||
|
||||
|
59
third_party/rust/naga/src/back/spv/image.rs
vendored
59
third_party/rust/naga/src/back/spv/image.rs
vendored
@ -128,8 +128,7 @@ impl Load {
|
||||
crate::ImageClass::Depth { .. } => {
|
||||
ctx.get_type_id(LookupType::Local(LocalType::Value {
|
||||
vector_size: Some(crate::VectorSize::Quad),
|
||||
kind: crate::ScalarKind::Float,
|
||||
width: 4,
|
||||
scalar: crate::Scalar::F32,
|
||||
pointer_space: None,
|
||||
}))
|
||||
}
|
||||
@ -292,18 +291,16 @@ impl<'w> BlockContext<'w> {
|
||||
|
||||
// Find the component type of `coordinates`, and figure out the size the
|
||||
// combined coordinate vector will have.
|
||||
let (component_kind, size) = match *inner_ty {
|
||||
Ti::Scalar { kind, width: 4 } => (kind, Some(Vs::Bi)),
|
||||
let (component_scalar, size) = match *inner_ty {
|
||||
Ti::Scalar(scalar @ crate::Scalar { width: 4, .. }) => (scalar, Some(Vs::Bi)),
|
||||
Ti::Vector {
|
||||
kind,
|
||||
width: 4,
|
||||
scalar: scalar @ crate::Scalar { width: 4, .. },
|
||||
size: Vs::Bi,
|
||||
} => (kind, Some(Vs::Tri)),
|
||||
} => (scalar, Some(Vs::Tri)),
|
||||
Ti::Vector {
|
||||
kind,
|
||||
width: 4,
|
||||
scalar: scalar @ crate::Scalar { width: 4, .. },
|
||||
size: Vs::Tri,
|
||||
} => (kind, Some(Vs::Quad)),
|
||||
} => (scalar, Some(Vs::Quad)),
|
||||
Ti::Vector { size: Vs::Quad, .. } => {
|
||||
return Err(Error::Validation("extending vec4 coordinate"));
|
||||
}
|
||||
@ -317,16 +314,16 @@ impl<'w> BlockContext<'w> {
|
||||
let array_index_id = self.cached[array_index];
|
||||
let ty = &self.fun_info[array_index].ty;
|
||||
let inner_ty = ty.inner_with(&self.ir_module.types);
|
||||
let array_index_kind = if let Ti::Scalar { kind, width: 4 } = *inner_ty {
|
||||
debug_assert!(matches!(
|
||||
kind,
|
||||
crate::ScalarKind::Sint | crate::ScalarKind::Uint
|
||||
));
|
||||
kind
|
||||
} else {
|
||||
unreachable!("we only allow i32 and u32");
|
||||
let array_index_scalar = match *inner_ty {
|
||||
Ti::Scalar(
|
||||
scalar @ crate::Scalar {
|
||||
kind: crate::ScalarKind::Sint | crate::ScalarKind::Uint,
|
||||
width: 4,
|
||||
},
|
||||
) => scalar,
|
||||
_ => unreachable!("we only allow i32 and u32"),
|
||||
};
|
||||
let cast = match (component_kind, array_index_kind) {
|
||||
let cast = match (component_scalar.kind, array_index_scalar.kind) {
|
||||
(crate::ScalarKind::Sint, crate::ScalarKind::Sint)
|
||||
| (crate::ScalarKind::Uint, crate::ScalarKind::Uint) => None,
|
||||
(crate::ScalarKind::Sint, crate::ScalarKind::Uint)
|
||||
@ -341,8 +338,7 @@ impl<'w> BlockContext<'w> {
|
||||
let reconciled_array_index_id = if let Some(cast) = cast {
|
||||
let component_ty_id = self.get_type_id(LookupType::Local(LocalType::Value {
|
||||
vector_size: None,
|
||||
kind: component_kind,
|
||||
width: 4,
|
||||
scalar: component_scalar,
|
||||
pointer_space: None,
|
||||
}));
|
||||
let reconciled_id = self.gen_id();
|
||||
@ -360,8 +356,7 @@ impl<'w> BlockContext<'w> {
|
||||
// Find the SPIR-V type for the combined coordinates/index vector.
|
||||
let type_id = self.get_type_id(LookupType::Local(LocalType::Value {
|
||||
vector_size: size,
|
||||
kind: component_kind,
|
||||
width: 4,
|
||||
scalar: component_scalar,
|
||||
pointer_space: None,
|
||||
}));
|
||||
|
||||
@ -532,8 +527,7 @@ impl<'w> BlockContext<'w> {
|
||||
|
||||
let i32_type_id = self.get_type_id(LookupType::Local(LocalType::Value {
|
||||
vector_size: None,
|
||||
kind: crate::ScalarKind::Sint,
|
||||
width: 4,
|
||||
scalar: crate::Scalar::I32,
|
||||
pointer_space: None,
|
||||
}));
|
||||
|
||||
@ -620,8 +614,7 @@ impl<'w> BlockContext<'w> {
|
||||
let bool_type_id = self.writer.get_bool_type_id();
|
||||
let i32_type_id = self.get_type_id(LookupType::Local(LocalType::Value {
|
||||
vector_size: None,
|
||||
kind: crate::ScalarKind::Sint,
|
||||
width: 4,
|
||||
scalar: crate::Scalar::I32,
|
||||
pointer_space: None,
|
||||
}));
|
||||
|
||||
@ -688,8 +681,7 @@ impl<'w> BlockContext<'w> {
|
||||
// Compare the coordinates against the bounds.
|
||||
let coords_bool_type_id = self.get_type_id(LookupType::Local(LocalType::Value {
|
||||
vector_size: coordinates.size,
|
||||
kind: crate::ScalarKind::Bool,
|
||||
width: 1,
|
||||
scalar: crate::Scalar::BOOL,
|
||||
pointer_space: None,
|
||||
}));
|
||||
let coords_conds_id = self.gen_id();
|
||||
@ -844,8 +836,7 @@ impl<'w> BlockContext<'w> {
|
||||
let sample_result_type_id = if needs_sub_access {
|
||||
self.get_type_id(LookupType::Local(LocalType::Value {
|
||||
vector_size: Some(crate::VectorSize::Quad),
|
||||
kind: crate::ScalarKind::Float,
|
||||
width: 4,
|
||||
scalar: crate::Scalar::F32,
|
||||
pointer_space: None,
|
||||
}))
|
||||
} else {
|
||||
@ -1045,8 +1036,7 @@ impl<'w> BlockContext<'w> {
|
||||
};
|
||||
let extended_size_type_id = self.get_type_id(LookupType::Local(LocalType::Value {
|
||||
vector_size,
|
||||
kind: crate::ScalarKind::Uint,
|
||||
width: 4,
|
||||
scalar: crate::Scalar::U32,
|
||||
pointer_space: None,
|
||||
}));
|
||||
|
||||
@ -1116,8 +1106,7 @@ impl<'w> BlockContext<'w> {
|
||||
};
|
||||
let extended_size_type_id = self.get_type_id(LookupType::Local(LocalType::Value {
|
||||
vector_size: Some(vec_size),
|
||||
kind: crate::ScalarKind::Uint,
|
||||
width: 4,
|
||||
scalar: crate::Scalar::U32,
|
||||
pointer_space: None,
|
||||
}));
|
||||
let id_extended = self.gen_id();
|
||||
|
27
third_party/rust/naga/src/back/spv/mod.rs
vendored
27
third_party/rust/naga/src/back/spv/mod.rs
vendored
@ -276,8 +276,7 @@ enum LocalType {
|
||||
/// If `None`, this represents a scalar type. If `Some`, this represents
|
||||
/// a vector type of the given size.
|
||||
vector_size: Option<crate::VectorSize>,
|
||||
kind: crate::ScalarKind,
|
||||
width: crate::Bytes,
|
||||
scalar: crate::Scalar,
|
||||
pointer_space: Option<spirv::StorageClass>,
|
||||
},
|
||||
/// A matrix of floating-point values.
|
||||
@ -355,18 +354,14 @@ struct LookupFunctionType {
|
||||
|
||||
fn make_local(inner: &crate::TypeInner) -> Option<LocalType> {
|
||||
Some(match *inner {
|
||||
crate::TypeInner::Scalar { kind, width } | crate::TypeInner::Atomic { kind, width } => {
|
||||
LocalType::Value {
|
||||
vector_size: None,
|
||||
kind,
|
||||
width,
|
||||
pointer_space: None,
|
||||
}
|
||||
}
|
||||
crate::TypeInner::Vector { size, kind, width } => LocalType::Value {
|
||||
crate::TypeInner::Scalar(scalar) | crate::TypeInner::Atomic(scalar) => LocalType::Value {
|
||||
vector_size: None,
|
||||
scalar,
|
||||
pointer_space: None,
|
||||
},
|
||||
crate::TypeInner::Vector { size, scalar } => LocalType::Value {
|
||||
vector_size: Some(size),
|
||||
kind,
|
||||
width,
|
||||
scalar,
|
||||
pointer_space: None,
|
||||
},
|
||||
crate::TypeInner::Matrix {
|
||||
@ -384,13 +379,11 @@ fn make_local(inner: &crate::TypeInner) -> Option<LocalType> {
|
||||
},
|
||||
crate::TypeInner::ValuePointer {
|
||||
size,
|
||||
kind,
|
||||
width,
|
||||
scalar,
|
||||
space,
|
||||
} => LocalType::Value {
|
||||
vector_size: size,
|
||||
kind,
|
||||
width,
|
||||
scalar,
|
||||
pointer_space: Some(helpers::map_storage_class(space)),
|
||||
},
|
||||
crate::TypeInner::Image {
|
||||
|
25
third_party/rust/naga/src/back/spv/ray.rs
vendored
25
third_party/rust/naga/src/back/spv/ray.rs
vendored
@ -21,12 +21,10 @@ impl<'w> BlockContext<'w> {
|
||||
//Note: composite extract indices and types must match `generate_ray_desc_type`
|
||||
let desc_id = self.cached[descriptor];
|
||||
let acc_struct_id = self.get_handle_id(acceleration_structure);
|
||||
let width = 4;
|
||||
|
||||
let flag_type_id = self.get_type_id(LookupType::Local(LocalType::Value {
|
||||
vector_size: None,
|
||||
kind: crate::ScalarKind::Uint,
|
||||
width,
|
||||
scalar: crate::Scalar::U32,
|
||||
pointer_space: None,
|
||||
}));
|
||||
let ray_flags_id = self.gen_id();
|
||||
@ -46,8 +44,7 @@ impl<'w> BlockContext<'w> {
|
||||
|
||||
let scalar_type_id = self.get_type_id(LookupType::Local(LocalType::Value {
|
||||
vector_size: None,
|
||||
kind: crate::ScalarKind::Float,
|
||||
width,
|
||||
scalar: crate::Scalar::F32,
|
||||
pointer_space: None,
|
||||
}));
|
||||
let tmin_id = self.gen_id();
|
||||
@ -67,8 +64,7 @@ impl<'w> BlockContext<'w> {
|
||||
|
||||
let vector_type_id = self.get_type_id(LookupType::Local(LocalType::Value {
|
||||
vector_size: Some(crate::VectorSize::Tri),
|
||||
kind: crate::ScalarKind::Float,
|
||||
width,
|
||||
scalar: crate::Scalar::F32,
|
||||
pointer_space: None,
|
||||
}));
|
||||
let ray_origin_id = self.gen_id();
|
||||
@ -115,7 +111,6 @@ impl<'w> BlockContext<'w> {
|
||||
query: Handle<crate::Expression>,
|
||||
block: &mut Block,
|
||||
) -> spirv::Word {
|
||||
let width = 4;
|
||||
let query_id = self.cached[query];
|
||||
let intersection_id = self.writer.get_constant_scalar(crate::Literal::U32(
|
||||
spirv::RayQueryIntersection::RayQueryCommittedIntersectionKHR as _,
|
||||
@ -123,8 +118,7 @@ impl<'w> BlockContext<'w> {
|
||||
|
||||
let flag_type_id = self.get_type_id(LookupType::Local(LocalType::Value {
|
||||
vector_size: None,
|
||||
kind: crate::ScalarKind::Uint,
|
||||
width,
|
||||
scalar: crate::Scalar::U32,
|
||||
pointer_space: None,
|
||||
}));
|
||||
let kind_id = self.gen_id();
|
||||
@ -178,8 +172,7 @@ impl<'w> BlockContext<'w> {
|
||||
|
||||
let scalar_type_id = self.get_type_id(LookupType::Local(LocalType::Value {
|
||||
vector_size: None,
|
||||
kind: crate::ScalarKind::Float,
|
||||
width,
|
||||
scalar: crate::Scalar::F32,
|
||||
pointer_space: None,
|
||||
}));
|
||||
let t_id = self.gen_id();
|
||||
@ -193,8 +186,7 @@ impl<'w> BlockContext<'w> {
|
||||
|
||||
let barycentrics_type_id = self.get_type_id(LookupType::Local(LocalType::Value {
|
||||
vector_size: Some(crate::VectorSize::Bi),
|
||||
kind: crate::ScalarKind::Float,
|
||||
width,
|
||||
scalar: crate::Scalar::F32,
|
||||
pointer_space: None,
|
||||
}));
|
||||
let barycentrics_id = self.gen_id();
|
||||
@ -208,8 +200,7 @@ impl<'w> BlockContext<'w> {
|
||||
|
||||
let bool_type_id = self.get_type_id(LookupType::Local(LocalType::Value {
|
||||
vector_size: None,
|
||||
kind: crate::ScalarKind::Bool,
|
||||
width: crate::BOOL_WIDTH,
|
||||
scalar: crate::Scalar::BOOL,
|
||||
pointer_space: None,
|
||||
}));
|
||||
let front_face_id = self.gen_id();
|
||||
@ -224,7 +215,7 @@ impl<'w> BlockContext<'w> {
|
||||
let transform_type_id = self.get_type_id(LookupType::Local(LocalType::Matrix {
|
||||
columns: crate::VectorSize::Quad,
|
||||
rows: crate::VectorSize::Tri,
|
||||
width,
|
||||
width: 4,
|
||||
}));
|
||||
let object_to_world_id = self.gen_id();
|
||||
block.body.push(Instruction::ray_query_get_intersection(
|
||||
|
76
third_party/rust/naga/src/back/spv/writer.rs
vendored
76
third_party/rust/naga/src/back/spv/writer.rs
vendored
@ -238,8 +238,7 @@ impl Writer {
|
||||
pub(super) fn get_uint_type_id(&mut self) -> Word {
|
||||
let local_type = LocalType::Value {
|
||||
vector_size: None,
|
||||
kind: crate::ScalarKind::Uint,
|
||||
width: 4,
|
||||
scalar: crate::Scalar::U32,
|
||||
pointer_space: None,
|
||||
};
|
||||
self.get_type_id(local_type.into())
|
||||
@ -248,8 +247,7 @@ impl Writer {
|
||||
pub(super) fn get_float_type_id(&mut self) -> Word {
|
||||
let local_type = LocalType::Value {
|
||||
vector_size: None,
|
||||
kind: crate::ScalarKind::Float,
|
||||
width: 4,
|
||||
scalar: crate::Scalar::F32,
|
||||
pointer_space: None,
|
||||
};
|
||||
self.get_type_id(local_type.into())
|
||||
@ -258,8 +256,7 @@ impl Writer {
|
||||
pub(super) fn get_uint3_type_id(&mut self) -> Word {
|
||||
let local_type = LocalType::Value {
|
||||
vector_size: Some(crate::VectorSize::Tri),
|
||||
kind: crate::ScalarKind::Uint,
|
||||
width: 4,
|
||||
scalar: crate::Scalar::U32,
|
||||
pointer_space: None,
|
||||
};
|
||||
self.get_type_id(local_type.into())
|
||||
@ -268,8 +265,7 @@ impl Writer {
|
||||
pub(super) fn get_float_pointer_type_id(&mut self, class: spirv::StorageClass) -> Word {
|
||||
let lookup_type = LookupType::Local(LocalType::Value {
|
||||
vector_size: None,
|
||||
kind: crate::ScalarKind::Float,
|
||||
width: 4,
|
||||
scalar: crate::Scalar::F32,
|
||||
pointer_space: Some(class),
|
||||
});
|
||||
if let Some(&id) = self.lookup_type.get(&lookup_type) {
|
||||
@ -287,8 +283,7 @@ impl Writer {
|
||||
pub(super) fn get_uint3_pointer_type_id(&mut self, class: spirv::StorageClass) -> Word {
|
||||
let lookup_type = LookupType::Local(LocalType::Value {
|
||||
vector_size: Some(crate::VectorSize::Tri),
|
||||
kind: crate::ScalarKind::Uint,
|
||||
width: 4,
|
||||
scalar: crate::Scalar::U32,
|
||||
pointer_space: Some(class),
|
||||
});
|
||||
if let Some(&id) = self.lookup_type.get(&lookup_type) {
|
||||
@ -306,8 +301,7 @@ impl Writer {
|
||||
pub(super) fn get_bool_type_id(&mut self) -> Word {
|
||||
let local_type = LocalType::Value {
|
||||
vector_size: None,
|
||||
kind: crate::ScalarKind::Bool,
|
||||
width: 1,
|
||||
scalar: crate::Scalar::BOOL,
|
||||
pointer_space: None,
|
||||
};
|
||||
self.get_type_id(local_type.into())
|
||||
@ -316,8 +310,7 @@ impl Writer {
|
||||
pub(super) fn get_bool3_type_id(&mut self) -> Word {
|
||||
let local_type = LocalType::Value {
|
||||
vector_size: Some(crate::VectorSize::Tri),
|
||||
kind: crate::ScalarKind::Bool,
|
||||
width: 1,
|
||||
scalar: crate::Scalar::BOOL,
|
||||
pointer_space: None,
|
||||
};
|
||||
self.get_type_id(local_type.into())
|
||||
@ -802,18 +795,13 @@ impl Writer {
|
||||
))
|
||||
}
|
||||
|
||||
fn make_scalar(
|
||||
&mut self,
|
||||
id: Word,
|
||||
kind: crate::ScalarKind,
|
||||
width: crate::Bytes,
|
||||
) -> Instruction {
|
||||
fn make_scalar(&mut self, id: Word, scalar: crate::Scalar) -> Instruction {
|
||||
use crate::ScalarKind as Sk;
|
||||
|
||||
let bits = (width * BITS_PER_BYTE) as u32;
|
||||
match kind {
|
||||
let bits = (scalar.width * BITS_PER_BYTE) as u32;
|
||||
match scalar.kind {
|
||||
Sk::Sint | Sk::Uint => {
|
||||
let signedness = if kind == Sk::Sint {
|
||||
let signedness = if scalar.kind == Sk::Sint {
|
||||
super::instructions::Signedness::Signed
|
||||
} else {
|
||||
super::instructions::Signedness::Unsigned
|
||||
@ -894,20 +882,17 @@ impl Writer {
|
||||
let instruction = match local_ty {
|
||||
LocalType::Value {
|
||||
vector_size: None,
|
||||
kind,
|
||||
width,
|
||||
scalar,
|
||||
pointer_space: None,
|
||||
} => self.make_scalar(id, kind, width),
|
||||
} => self.make_scalar(id, scalar),
|
||||
LocalType::Value {
|
||||
vector_size: Some(size),
|
||||
kind,
|
||||
width,
|
||||
scalar,
|
||||
pointer_space: None,
|
||||
} => {
|
||||
let scalar_id = self.get_type_id(LookupType::Local(LocalType::Value {
|
||||
vector_size: None,
|
||||
kind,
|
||||
width,
|
||||
scalar,
|
||||
pointer_space: None,
|
||||
}));
|
||||
Instruction::type_vector(id, scalar_id, size)
|
||||
@ -919,8 +904,7 @@ impl Writer {
|
||||
} => {
|
||||
let vector_id = self.get_type_id(LookupType::Local(LocalType::Value {
|
||||
vector_size: Some(rows),
|
||||
kind: crate::ScalarKind::Float,
|
||||
width,
|
||||
scalar: crate::Scalar::float(width),
|
||||
pointer_space: None,
|
||||
}));
|
||||
Instruction::type_matrix(id, vector_id, columns)
|
||||
@ -931,14 +915,12 @@ impl Writer {
|
||||
}
|
||||
LocalType::Value {
|
||||
vector_size,
|
||||
kind,
|
||||
width,
|
||||
scalar,
|
||||
pointer_space: Some(class),
|
||||
} => {
|
||||
let type_id = self.get_type_id(LookupType::Local(LocalType::Value {
|
||||
vector_size,
|
||||
kind,
|
||||
width,
|
||||
scalar,
|
||||
pointer_space: None,
|
||||
}));
|
||||
Instruction::type_pointer(id, class, type_id)
|
||||
@ -946,8 +928,10 @@ impl Writer {
|
||||
LocalType::Image(image) => {
|
||||
let local_type = LocalType::Value {
|
||||
vector_size: None,
|
||||
kind: image.sampled_type,
|
||||
width: 4,
|
||||
scalar: crate::Scalar {
|
||||
kind: image.sampled_type,
|
||||
width: 4,
|
||||
},
|
||||
pointer_space: None,
|
||||
};
|
||||
let type_id = self.get_type_id(LookupType::Local(local_type));
|
||||
@ -1060,8 +1044,8 @@ impl Writer {
|
||||
|
||||
// These all have TypeLocal representations, so they should have been
|
||||
// handled by `write_type_declaration_local` above.
|
||||
crate::TypeInner::Scalar { .. }
|
||||
| crate::TypeInner::Atomic { .. }
|
||||
crate::TypeInner::Scalar(_)
|
||||
| crate::TypeInner::Atomic(_)
|
||||
| crate::TypeInner::Vector { .. }
|
||||
| crate::TypeInner::Matrix { .. }
|
||||
| crate::TypeInner::Pointer { .. }
|
||||
@ -1151,11 +1135,10 @@ impl Writer {
|
||||
pub(super) fn get_constant_scalar_with(
|
||||
&mut self,
|
||||
value: u8,
|
||||
kind: crate::ScalarKind,
|
||||
width: crate::Bytes,
|
||||
scalar: crate::Scalar,
|
||||
) -> Result<Word, Error> {
|
||||
Ok(
|
||||
self.get_constant_scalar(crate::Literal::new(value, kind, width).ok_or(
|
||||
self.get_constant_scalar(crate::Literal::new(value, scalar).ok_or(
|
||||
Error::Validation("Unexpected kind and/or width for Literal"),
|
||||
)?),
|
||||
)
|
||||
@ -1185,8 +1168,7 @@ impl Writer {
|
||||
}
|
||||
let type_id = self.get_type_id(LookupType::Local(LocalType::Value {
|
||||
vector_size: None,
|
||||
kind: value.scalar_kind(),
|
||||
width: value.width(),
|
||||
scalar: value.scalar(),
|
||||
pointer_space: None,
|
||||
}));
|
||||
let instruction = match *value {
|
||||
@ -1602,8 +1584,8 @@ impl Writer {
|
||||
// > shader, must be decorated Flat
|
||||
if class == spirv::StorageClass::Input && stage == crate::ShaderStage::Fragment {
|
||||
let is_flat = match ir_module.types[ty].inner {
|
||||
crate::TypeInner::Scalar { kind, .. }
|
||||
| crate::TypeInner::Vector { kind, .. } => match kind {
|
||||
crate::TypeInner::Scalar(scalar)
|
||||
| crate::TypeInner::Vector { scalar, .. } => match scalar.kind {
|
||||
Sk::Uint | Sk::Sint | Sk::Bool => true,
|
||||
Sk::Float => false,
|
||||
},
|
||||
|
85
third_party/rust/naga/src/back/wgsl/writer.rs
vendored
85
third_party/rust/naga/src/back/wgsl/writer.rs
vendored
@ -426,11 +426,11 @@ impl<W: Write> Writer<W> {
|
||||
/// Adds no trailing or leading whitespace
|
||||
fn write_value_type(&mut self, module: &Module, inner: &TypeInner) -> BackendResult {
|
||||
match *inner {
|
||||
TypeInner::Vector { size, kind, width } => write!(
|
||||
TypeInner::Vector { size, scalar } => write!(
|
||||
self.out,
|
||||
"vec{}<{}>",
|
||||
back::vector_size_str(size),
|
||||
scalar_kind_str(kind, width),
|
||||
scalar_kind_str(scalar),
|
||||
)?,
|
||||
TypeInner::Sampler { comparison: false } => {
|
||||
write!(self.out, "sampler")?;
|
||||
@ -452,7 +452,7 @@ impl<W: Write> Writer<W> {
|
||||
Ic::Sampled { kind, multi } => (
|
||||
"",
|
||||
if multi { "multisampled_" } else { "" },
|
||||
scalar_kind_str(kind, 4),
|
||||
scalar_kind_str(crate::Scalar { kind, width: 4 }),
|
||||
"",
|
||||
),
|
||||
Ic::Depth { multi } => {
|
||||
@ -481,11 +481,11 @@ impl<W: Write> Writer<W> {
|
||||
write!(self.out, "<{format_str}{storage_str}>")?;
|
||||
}
|
||||
}
|
||||
TypeInner::Scalar { kind, width } => {
|
||||
write!(self.out, "{}", scalar_kind_str(kind, width))?;
|
||||
TypeInner::Scalar(scalar) => {
|
||||
write!(self.out, "{}", scalar_kind_str(scalar))?;
|
||||
}
|
||||
TypeInner::Atomic { kind, width } => {
|
||||
write!(self.out, "atomic<{}>", scalar_kind_str(kind, width))?;
|
||||
TypeInner::Atomic(scalar) => {
|
||||
write!(self.out, "atomic<{}>", scalar_kind_str(scalar))?;
|
||||
}
|
||||
TypeInner::Array {
|
||||
base,
|
||||
@ -524,14 +524,14 @@ impl<W: Write> Writer<W> {
|
||||
TypeInner::Matrix {
|
||||
columns,
|
||||
rows,
|
||||
width: _,
|
||||
width,
|
||||
} => {
|
||||
write!(
|
||||
self.out,
|
||||
//TODO: Can matrix be other than f32?
|
||||
"mat{}x{}<f32>",
|
||||
"mat{}x{}<{}>",
|
||||
back::vector_size_str(columns),
|
||||
back::vector_size_str(rows),
|
||||
scalar_kind_str(crate::Scalar::float(width))
|
||||
)?;
|
||||
}
|
||||
TypeInner::Pointer { base, space } => {
|
||||
@ -552,13 +552,12 @@ impl<W: Write> Writer<W> {
|
||||
}
|
||||
TypeInner::ValuePointer {
|
||||
size: None,
|
||||
kind,
|
||||
width,
|
||||
scalar,
|
||||
space,
|
||||
} => {
|
||||
let (address, maybe_access) = address_space_str(space);
|
||||
if let Some(space) = address {
|
||||
write!(self.out, "ptr<{}, {}", space, scalar_kind_str(kind, width))?;
|
||||
write!(self.out, "ptr<{}, {}", space, scalar_kind_str(scalar))?;
|
||||
if let Some(access) = maybe_access {
|
||||
write!(self.out, ", {access}")?;
|
||||
}
|
||||
@ -571,8 +570,7 @@ impl<W: Write> Writer<W> {
|
||||
}
|
||||
TypeInner::ValuePointer {
|
||||
size: Some(size),
|
||||
kind,
|
||||
width,
|
||||
scalar,
|
||||
space,
|
||||
} => {
|
||||
let (address, maybe_access) = address_space_str(space);
|
||||
@ -582,7 +580,7 @@ impl<W: Write> Writer<W> {
|
||||
"ptr<{}, vec{}<{}>",
|
||||
space,
|
||||
back::vector_size_str(size),
|
||||
scalar_kind_str(kind, width)
|
||||
scalar_kind_str(scalar)
|
||||
)?;
|
||||
if let Some(access) = maybe_access {
|
||||
write!(self.out, ", {access}")?;
|
||||
@ -1414,7 +1412,11 @@ impl<W: Write> Writer<W> {
|
||||
width,
|
||||
..
|
||||
} => {
|
||||
let scalar_kind_str = scalar_kind_str(kind, convert.unwrap_or(width));
|
||||
let scalar = crate::Scalar {
|
||||
kind,
|
||||
width: convert.unwrap_or(width),
|
||||
};
|
||||
let scalar_kind_str = scalar_kind_str(scalar);
|
||||
write!(
|
||||
self.out,
|
||||
"mat{}x{}<{}>",
|
||||
@ -1423,17 +1425,28 @@ impl<W: Write> Writer<W> {
|
||||
scalar_kind_str
|
||||
)?;
|
||||
}
|
||||
TypeInner::Vector { size, width, .. } => {
|
||||
TypeInner::Vector {
|
||||
size,
|
||||
scalar: crate::Scalar { width, .. },
|
||||
} => {
|
||||
let scalar = crate::Scalar {
|
||||
kind,
|
||||
width: convert.unwrap_or(width),
|
||||
};
|
||||
let vector_size_str = back::vector_size_str(size);
|
||||
let scalar_kind_str = scalar_kind_str(kind, convert.unwrap_or(width));
|
||||
let scalar_kind_str = scalar_kind_str(scalar);
|
||||
if convert.is_some() {
|
||||
write!(self.out, "vec{vector_size_str}<{scalar_kind_str}>")?;
|
||||
} else {
|
||||
write!(self.out, "bitcast<vec{vector_size_str}<{scalar_kind_str}>>")?;
|
||||
}
|
||||
}
|
||||
TypeInner::Scalar { width, .. } => {
|
||||
let scalar_kind_str = scalar_kind_str(kind, convert.unwrap_or(width));
|
||||
TypeInner::Scalar(crate::Scalar { width, .. }) => {
|
||||
let scalar = crate::Scalar {
|
||||
kind,
|
||||
width: convert.unwrap_or(width),
|
||||
};
|
||||
let scalar_kind_str = scalar_kind_str(scalar);
|
||||
if convert.is_some() {
|
||||
write!(self.out, "{scalar_kind_str}")?
|
||||
} else {
|
||||
@ -1783,15 +1796,31 @@ const fn image_dimension_str(dim: crate::ImageDimension) -> &'static str {
|
||||
}
|
||||
}
|
||||
|
||||
const fn scalar_kind_str(kind: crate::ScalarKind, width: u8) -> &'static str {
|
||||
const fn scalar_kind_str(scalar: crate::Scalar) -> &'static str {
|
||||
use crate::Scalar;
|
||||
use crate::ScalarKind as Sk;
|
||||
|
||||
match (kind, width) {
|
||||
(Sk::Float, 8) => "f64",
|
||||
(Sk::Float, 4) => "f32",
|
||||
(Sk::Sint, 4) => "i32",
|
||||
(Sk::Uint, 4) => "u32",
|
||||
(Sk::Bool, 1) => "bool",
|
||||
match scalar {
|
||||
Scalar {
|
||||
kind: Sk::Float,
|
||||
width: 8,
|
||||
} => "f64",
|
||||
Scalar {
|
||||
kind: Sk::Float,
|
||||
width: 4,
|
||||
} => "f32",
|
||||
Scalar {
|
||||
kind: Sk::Sint,
|
||||
width: 4,
|
||||
} => "i32",
|
||||
Scalar {
|
||||
kind: Sk::Uint,
|
||||
width: 4,
|
||||
} => "u32",
|
||||
Scalar {
|
||||
kind: Sk::Bool,
|
||||
width: 1,
|
||||
} => "bool",
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
|
177
third_party/rust/naga/src/compact/expressions.rs
vendored
177
third_party/rust/naga/src/compact/expressions.rs
vendored
@ -1,8 +1,7 @@
|
||||
use super::{HandleMap, HandleSet, ModuleMap};
|
||||
use crate::arena::{Arena, Handle, UniqueArena};
|
||||
use crate::arena::{Arena, Handle};
|
||||
|
||||
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.
|
||||
@ -21,34 +20,51 @@ pub struct ExpressionTracer<'tracer> {
|
||||
/// 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>,
|
||||
)>,
|
||||
/// The used set for the module's `const_expressions` arena.
|
||||
///
|
||||
/// If `None`, we are already tracing the constant expressions,
|
||||
/// and `expressions_used` already refers to their handle set.
|
||||
pub const_expressions_used: Option<&'tracer mut HandleSet<crate::Expression>>,
|
||||
}
|
||||
|
||||
impl<'tracer> ExpressionTracer<'tracer> {
|
||||
pub fn trace_expression(&mut self, expr: Handle<crate::Expression>) {
|
||||
/// Propagate usage through `self.expressions`, starting with `self.expressions_used`.
|
||||
///
|
||||
/// Treat `self.expressions_used` as the initial set of "known
|
||||
/// live" expressions, and follow through to identify all
|
||||
/// transitively used expressions.
|
||||
///
|
||||
/// Mark types, constants, and constant expressions used directly
|
||||
/// by `self.expressions` as used. Items used indirectly are not
|
||||
/// marked.
|
||||
///
|
||||
/// [fe]: crate::Function::expressions
|
||||
/// [ce]: crate::Module::const_expressions
|
||||
pub fn trace_expressions(&mut self) {
|
||||
log::trace!(
|
||||
"entering trace_expression of {}",
|
||||
if self.const_expressions.is_some() {
|
||||
if self.const_expressions_used.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) {
|
||||
|
||||
// We don't need recursion or a work list. Because an
|
||||
// expression may only refer to other expressions that precede
|
||||
// it in the arena, it suffices to make a single pass over the
|
||||
// arena from back to front, marking the referents of used
|
||||
// expressions as used themselves.
|
||||
for (handle, expr) in self.expressions.iter().rev() {
|
||||
// If this expression isn't used, it doesn't matter what it uses.
|
||||
if !self.expressions_used.contains(handle) {
|
||||
continue;
|
||||
}
|
||||
|
||||
log::trace!("tracing new expression {:?}", expr);
|
||||
|
||||
use crate::Expression as Ex;
|
||||
match self.expressions[expr] {
|
||||
match *expr {
|
||||
// Expressions that do not contain handles that need to be traced.
|
||||
Ex::Literal(_)
|
||||
| Ex::FunctionArgument(_)
|
||||
@ -59,24 +75,34 @@ impl<'tracer> ExpressionTracer<'tracer> {
|
||||
|
||||
Ex::Constant(handle) => {
|
||||
self.constants_used.insert(handle);
|
||||
let constant = &self.constants[handle];
|
||||
self.trace_type(constant.ty);
|
||||
self.trace_const_expression(constant.init);
|
||||
// Constants and expressions are mutually recursive, which
|
||||
// complicates our nice one-pass algorithm. However, since
|
||||
// constants don't refer to each other, we can get around
|
||||
// this by looking *through* each constant and marking its
|
||||
// initializer as used. Since `expr` refers to the constant,
|
||||
// and the constant refers to the initializer, it must
|
||||
// precede `expr` in the arena.
|
||||
let init = self.constants[handle].init;
|
||||
match self.const_expressions_used {
|
||||
Some(ref mut used) => used.insert(init),
|
||||
None => self.expressions_used.insert(init),
|
||||
}
|
||||
}
|
||||
Ex::ZeroValue(ty) => self.trace_type(ty),
|
||||
Ex::ZeroValue(ty) => self.types_used.insert(ty),
|
||||
Ex::Compose { ty, ref components } => {
|
||||
self.trace_type(ty);
|
||||
work_list.extend(components);
|
||||
self.types_used.insert(ty);
|
||||
self.expressions_used
|
||||
.insert_iter(components.iter().cloned());
|
||||
}
|
||||
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::Access { base, index } => self.expressions_used.insert_iter([base, index]),
|
||||
Ex::AccessIndex { base, index: _ } => self.expressions_used.insert(base),
|
||||
Ex::Splat { size: _, value } => self.expressions_used.insert(value),
|
||||
Ex::Swizzle {
|
||||
size: _,
|
||||
vector,
|
||||
pattern: _,
|
||||
} => work_list.push(vector),
|
||||
Ex::Load { pointer } => work_list.push(pointer),
|
||||
} => self.expressions_used.insert(vector),
|
||||
Ex::Load { pointer } => self.expressions_used.insert(pointer),
|
||||
Ex::ImageSample {
|
||||
image,
|
||||
sampler,
|
||||
@ -87,20 +113,20 @@ impl<'tracer> ExpressionTracer<'tracer> {
|
||||
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);
|
||||
self.expressions_used
|
||||
.insert_iter([image, sampler, coordinate]);
|
||||
self.expressions_used.insert_iter(array_index);
|
||||
match self.const_expressions_used {
|
||||
Some(ref mut used) => used.insert_iter(offset),
|
||||
None => self.expressions_used.insert_iter(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]),
|
||||
Sl::Exact(expr) | Sl::Bias(expr) => self.expressions_used.insert(expr),
|
||||
Sl::Gradient { x, y } => self.expressions_used.insert_iter([x, y]),
|
||||
}
|
||||
work_list.extend(depth_ref);
|
||||
self.expressions_used.insert_iter(depth_ref);
|
||||
}
|
||||
Ex::ImageLoad {
|
||||
image,
|
||||
@ -109,33 +135,37 @@ impl<'tracer> ExpressionTracer<'tracer> {
|
||||
sample,
|
||||
level,
|
||||
} => {
|
||||
work_list.push(image);
|
||||
work_list.push(coordinate);
|
||||
work_list.extend(array_index);
|
||||
work_list.extend(sample);
|
||||
work_list.extend(level);
|
||||
self.expressions_used.insert(image);
|
||||
self.expressions_used.insert(coordinate);
|
||||
self.expressions_used.insert_iter(array_index);
|
||||
self.expressions_used.insert_iter(sample);
|
||||
self.expressions_used.insert_iter(level);
|
||||
}
|
||||
Ex::ImageQuery { image, ref query } => {
|
||||
work_list.push(image);
|
||||
self.expressions_used.insert(image);
|
||||
use crate::ImageQuery as Iq;
|
||||
match *query {
|
||||
Iq::Size { level } => work_list.extend(level),
|
||||
Iq::Size { level } => self.expressions_used.insert_iter(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::Unary { op: _, expr } => self.expressions_used.insert(expr),
|
||||
Ex::Binary { op: _, left, right } => {
|
||||
self.expressions_used.insert_iter([left, right]);
|
||||
}
|
||||
Ex::Select {
|
||||
condition,
|
||||
accept,
|
||||
reject,
|
||||
} => work_list.extend([condition, accept, reject]),
|
||||
} => self
|
||||
.expressions_used
|
||||
.insert_iter([condition, accept, reject]),
|
||||
Ex::Derivative {
|
||||
axis: _,
|
||||
ctrl: _,
|
||||
expr,
|
||||
} => work_list.push(expr),
|
||||
Ex::Relational { fun: _, argument } => work_list.push(argument),
|
||||
} => self.expressions_used.insert(expr),
|
||||
Ex::Relational { fun: _, argument } => self.expressions_used.insert(argument),
|
||||
Ex::Math {
|
||||
fun: _,
|
||||
arg,
|
||||
@ -143,61 +173,26 @@ impl<'tracer> ExpressionTracer<'tracer> {
|
||||
arg2,
|
||||
arg3,
|
||||
} => {
|
||||
work_list.push(arg);
|
||||
work_list.extend(arg1);
|
||||
work_list.extend(arg2);
|
||||
work_list.extend(arg3);
|
||||
self.expressions_used.insert(arg);
|
||||
self.expressions_used.insert_iter(arg1);
|
||||
self.expressions_used.insert_iter(arg2);
|
||||
self.expressions_used.insert_iter(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),
|
||||
} => self.expressions_used.insert(expr),
|
||||
Ex::AtomicResult { ty, comparison: _ } => self.types_used.insert(ty),
|
||||
Ex::WorkGroupUniformLoadResult { ty } => self.types_used.insert(ty),
|
||||
Ex::ArrayLength(expr) => self.expressions_used.insert(expr),
|
||||
Ex::RayQueryGetIntersection {
|
||||
query,
|
||||
committed: _,
|
||||
} => work_list.push(query),
|
||||
} => self.expressions_used.insert(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 {
|
||||
|
41
third_party/rust/naga/src/compact/functions.rs
vendored
41
third_party/rust/naga/src/compact/functions.rs
vendored
@ -1,10 +1,9 @@
|
||||
use super::handle_set_map::HandleSet;
|
||||
use super::{FunctionMap, ModuleMap};
|
||||
use crate::arena::Handle;
|
||||
|
||||
pub struct FunctionTracer<'a> {
|
||||
pub module: &'a crate::Module,
|
||||
pub function: &'a crate::Function,
|
||||
pub constants: &'a crate::Arena<crate::Constant>,
|
||||
|
||||
pub types_used: &'a mut HandleSet<crate::Type>,
|
||||
pub constants_used: &'a mut HandleSet<crate::Constant>,
|
||||
@ -17,57 +16,43 @@ pub struct FunctionTracer<'a> {
|
||||
impl<'a> FunctionTracer<'a> {
|
||||
pub fn trace(&mut self) {
|
||||
for argument in self.function.arguments.iter() {
|
||||
self.trace_type(argument.ty);
|
||||
self.types_used.insert(argument.ty);
|
||||
}
|
||||
|
||||
if let Some(ref result) = self.function.result {
|
||||
self.trace_type(result.ty);
|
||||
self.types_used.insert(result.ty);
|
||||
}
|
||||
|
||||
for (_, local) in self.function.local_variables.iter() {
|
||||
self.trace_type(local.ty);
|
||||
self.types_used.insert(local.ty);
|
||||
if let Some(init) = local.init {
|
||||
self.trace_expression(init);
|
||||
self.expressions_used.insert(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);
|
||||
for (&value, _name) in &self.function.named_expressions {
|
||||
self.expressions_used.insert(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);
|
||||
}
|
||||
|
||||
fn as_type(&mut self) -> super::types::TypeTracer {
|
||||
super::types::TypeTracer {
|
||||
types: &self.module.types,
|
||||
types_used: self.types_used,
|
||||
}
|
||||
// Given that `trace_block` has marked the expressions used
|
||||
// directly by statements, walk the arena to find all
|
||||
// expressions used, directly or indirectly.
|
||||
self.as_expression().trace_expressions();
|
||||
}
|
||||
|
||||
fn as_expression(&mut self) -> super::expressions::ExpressionTracer {
|
||||
super::expressions::ExpressionTracer {
|
||||
types: &self.module.types,
|
||||
constants: &self.module.constants,
|
||||
constants: self.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,
|
||||
)),
|
||||
const_expressions_used: Some(&mut self.const_expressions_used),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -26,13 +26,23 @@ impl<T> HandleSet<T> {
|
||||
}
|
||||
|
||||
/// 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 {
|
||||
pub fn insert(&mut self, handle: Handle<T>) {
|
||||
// Note that, oddly, `Handle::index` does not return a 1-based
|
||||
// `Index`, but rather a zero-based `usize`.
|
||||
self.members.insert(handle.index())
|
||||
self.members.insert(handle.index());
|
||||
}
|
||||
|
||||
/// Add handles from `iter` to the set.
|
||||
pub fn insert_iter(&mut self, iter: impl IntoIterator<Item = Handle<T>>) {
|
||||
for handle in iter {
|
||||
self.insert(handle);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn contains(&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.contains(handle.index())
|
||||
}
|
||||
}
|
||||
|
||||
@ -148,6 +158,8 @@ impl<T: 'static> HandleMap<T> {
|
||||
// Build a zero-based end-exclusive range, given one-based handle indices.
|
||||
compacted = first1.get() - 1..last1.get();
|
||||
} else {
|
||||
// The range contains only a single live handle, which
|
||||
// we identified with the first `find_map` call.
|
||||
compacted = first1.get() - 1..first1.get();
|
||||
}
|
||||
} else {
|
||||
|
53
third_party/rust/naga/src/compact/mod.rs
vendored
53
third_party/rust/naga/src/compact/mod.rs
vendored
@ -36,9 +36,9 @@ pub fn compact(module: &mut crate::Module) {
|
||||
{
|
||||
for (_, global) in module.global_variables.iter() {
|
||||
log::trace!("tracing global {:?}", global.name);
|
||||
module_tracer.as_type().trace_type(global.ty);
|
||||
module_tracer.types_used.insert(global.ty);
|
||||
if let Some(init) = global.init {
|
||||
module_tracer.as_const_expression().trace_expression(init);
|
||||
module_tracer.const_expressions_used.insert(init);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -50,25 +50,23 @@ pub fn compact(module: &mut crate::Module) {
|
||||
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);
|
||||
module_tracer.const_expressions_used.insert(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.
|
||||
// expressions each function uses, and produce maps for each
|
||||
// function from pre-compaction to post-compaction expression
|
||||
// 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);
|
||||
let mut function_tracer = module_tracer.as_function(f);
|
||||
function_tracer.trace();
|
||||
FunctionMap::from(function_tracer)
|
||||
})
|
||||
@ -81,12 +79,30 @@ pub fn compact(module: &mut crate::Module) {
|
||||
.iter()
|
||||
.map(|e| {
|
||||
log::trace!("tracing entry point {:?}", e.function.name);
|
||||
let mut used = module_tracer.enter_function(&e.function);
|
||||
let mut used = module_tracer.as_function(&e.function);
|
||||
used.trace();
|
||||
FunctionMap::from(used)
|
||||
})
|
||||
.collect();
|
||||
|
||||
// Given that the above steps have marked all the constant
|
||||
// expressions used directly by globals, constants, functions, and
|
||||
// entry points, walk the constant expression arena to find all
|
||||
// constant expressions used, directly or indirectly.
|
||||
module_tracer.as_const_expression().trace_expressions();
|
||||
|
||||
// Constants' initializers are taken care of already, because
|
||||
// expression tracing sees through constants. But we still need to
|
||||
// note type usage.
|
||||
for (handle, constant) in module.constants.iter() {
|
||||
if module_tracer.constants_used.contains(handle) {
|
||||
module_tracer.types_used.insert(constant.ty);
|
||||
}
|
||||
}
|
||||
|
||||
// Propagate usage through types.
|
||||
module_tracer.as_type().trace_types();
|
||||
|
||||
// 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
|
||||
@ -189,15 +205,14 @@ impl<'module> ModuleTracer<'module> {
|
||||
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);
|
||||
self.types_used.insert(ray_desc);
|
||||
}
|
||||
if let Some(ray_intersection) = *ray_intersection {
|
||||
type_tracer.trace_type(ray_intersection);
|
||||
self.types_used.insert(ray_intersection);
|
||||
}
|
||||
for (_, &handle) in predeclared_types {
|
||||
type_tracer.trace_type(handle);
|
||||
self.types_used.insert(handle);
|
||||
}
|
||||
}
|
||||
|
||||
@ -210,24 +225,22 @@ impl<'module> ModuleTracer<'module> {
|
||||
|
||||
fn as_const_expression(&mut self) -> expressions::ExpressionTracer {
|
||||
expressions::ExpressionTracer {
|
||||
types: &self.module.types,
|
||||
constants: &self.module.constants,
|
||||
expressions: &self.module.const_expressions,
|
||||
constants: &self.module.constants,
|
||||
types_used: &mut self.types_used,
|
||||
constants_used: &mut self.constants_used,
|
||||
expressions_used: &mut self.const_expressions_used,
|
||||
const_expressions: None,
|
||||
const_expressions_used: None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn enter_function<'tracer>(
|
||||
pub fn as_function<'tracer>(
|
||||
&'tracer mut self,
|
||||
function: &'tracer crate::Function,
|
||||
) -> FunctionTracer<'tracer> {
|
||||
FunctionTracer {
|
||||
module: self.module,
|
||||
function,
|
||||
|
||||
constants: &self.module.constants,
|
||||
types_used: &mut self.types_used,
|
||||
constants_used: &mut self.constants_used,
|
||||
const_expressions_used: &mut self.const_expressions_used,
|
||||
|
50
third_party/rust/naga/src/compact/statements.rs
vendored
50
third_party/rust/naga/src/compact/statements.rs
vendored
@ -22,7 +22,7 @@ impl FunctionTracer<'_> {
|
||||
ref accept,
|
||||
ref reject,
|
||||
} => {
|
||||
self.trace_expression(condition);
|
||||
self.expressions_used.insert(condition);
|
||||
worklist.push(accept);
|
||||
worklist.push(reject);
|
||||
}
|
||||
@ -30,7 +30,7 @@ impl FunctionTracer<'_> {
|
||||
selector,
|
||||
ref cases,
|
||||
} => {
|
||||
self.trace_expression(selector);
|
||||
self.expressions_used.insert(selector);
|
||||
for case in cases {
|
||||
worklist.push(&case.body);
|
||||
}
|
||||
@ -41,15 +41,17 @@ impl FunctionTracer<'_> {
|
||||
break_if,
|
||||
} => {
|
||||
if let Some(break_if) = break_if {
|
||||
self.trace_expression(break_if);
|
||||
self.expressions_used.insert(break_if);
|
||||
}
|
||||
worklist.push(body);
|
||||
worklist.push(continuing);
|
||||
}
|
||||
St::Return { value: Some(value) } => self.trace_expression(value),
|
||||
St::Return { value: Some(value) } => {
|
||||
self.expressions_used.insert(value);
|
||||
}
|
||||
St::Store { pointer, value } => {
|
||||
self.trace_expression(pointer);
|
||||
self.trace_expression(value);
|
||||
self.expressions_used.insert(pointer);
|
||||
self.expressions_used.insert(value);
|
||||
}
|
||||
St::ImageStore {
|
||||
image,
|
||||
@ -57,12 +59,12 @@ impl FunctionTracer<'_> {
|
||||
array_index,
|
||||
value,
|
||||
} => {
|
||||
self.trace_expression(image);
|
||||
self.trace_expression(coordinate);
|
||||
self.expressions_used.insert(image);
|
||||
self.expressions_used.insert(coordinate);
|
||||
if let Some(array_index) = array_index {
|
||||
self.trace_expression(array_index);
|
||||
self.expressions_used.insert(array_index);
|
||||
}
|
||||
self.trace_expression(value);
|
||||
self.expressions_used.insert(value);
|
||||
}
|
||||
St::Atomic {
|
||||
pointer,
|
||||
@ -70,14 +72,14 @@ impl FunctionTracer<'_> {
|
||||
value,
|
||||
result,
|
||||
} => {
|
||||
self.trace_expression(pointer);
|
||||
self.expressions_used.insert(pointer);
|
||||
self.trace_atomic_function(fun);
|
||||
self.trace_expression(value);
|
||||
self.trace_expression(result);
|
||||
self.expressions_used.insert(value);
|
||||
self.expressions_used.insert(result);
|
||||
}
|
||||
St::WorkGroupUniformLoad { pointer, result } => {
|
||||
self.trace_expression(pointer);
|
||||
self.trace_expression(result);
|
||||
self.expressions_used.insert(pointer);
|
||||
self.expressions_used.insert(result);
|
||||
}
|
||||
St::Call {
|
||||
function: _,
|
||||
@ -85,14 +87,14 @@ impl FunctionTracer<'_> {
|
||||
result,
|
||||
} => {
|
||||
for expr in arguments {
|
||||
self.trace_expression(*expr);
|
||||
self.expressions_used.insert(*expr);
|
||||
}
|
||||
if let Some(result) = result {
|
||||
self.trace_expression(result);
|
||||
self.expressions_used.insert(result);
|
||||
}
|
||||
}
|
||||
St::RayQuery { query, ref fun } => {
|
||||
self.trace_expression(query);
|
||||
self.expressions_used.insert(query);
|
||||
self.trace_ray_query_function(fun);
|
||||
}
|
||||
|
||||
@ -112,7 +114,9 @@ impl FunctionTracer<'_> {
|
||||
match *fun {
|
||||
Af::Exchange {
|
||||
compare: Some(expr),
|
||||
} => self.trace_expression(expr),
|
||||
} => {
|
||||
self.expressions_used.insert(expr);
|
||||
}
|
||||
Af::Exchange { compare: None }
|
||||
| Af::Add
|
||||
| Af::Subtract
|
||||
@ -131,10 +135,12 @@ impl FunctionTracer<'_> {
|
||||
acceleration_structure,
|
||||
descriptor,
|
||||
} => {
|
||||
self.trace_expression(acceleration_structure);
|
||||
self.trace_expression(descriptor);
|
||||
self.expressions_used.insert(acceleration_structure);
|
||||
self.expressions_used.insert(descriptor);
|
||||
}
|
||||
Qf::Proceed { result } => {
|
||||
self.expressions_used.insert(result);
|
||||
}
|
||||
Qf::Proceed { result } => self.trace_expression(result),
|
||||
Qf::Terminate => {}
|
||||
}
|
||||
}
|
||||
|
35
third_party/rust/naga/src/compact/types.rs
vendored
35
third_party/rust/naga/src/compact/types.rs
vendored
@ -7,16 +7,25 @@ pub struct TypeTracer<'a> {
|
||||
}
|
||||
|
||||
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) {
|
||||
/// Propagate usage through `self.types`, starting with `self.types_used`.
|
||||
///
|
||||
/// Treat `self.types_used` as the initial set of "known
|
||||
/// live" types, and follow through to identify all
|
||||
/// transitively used types.
|
||||
pub fn trace_types(&mut self) {
|
||||
// We don't need recursion or a work list. Because an
|
||||
// expression may only refer to other expressions that precede
|
||||
// it in the arena, it suffices to make a single pass over the
|
||||
// arena from back to front, marking the referents of used
|
||||
// expressions as used themselves.
|
||||
for (handle, ty) in self.types.iter().rev() {
|
||||
// If this type isn't used, it doesn't matter what it uses.
|
||||
if !self.types_used.contains(handle) {
|
||||
continue;
|
||||
}
|
||||
|
||||
use crate::TypeInner as Ti;
|
||||
match self.types[ty].inner {
|
||||
match ty.inner {
|
||||
// Types that do not contain handles.
|
||||
Ti::Scalar { .. }
|
||||
| Ti::Vector { .. }
|
||||
@ -29,19 +38,19 @@ impl<'a> TypeTracer<'a> {
|
||||
| Ti::RayQuery => {}
|
||||
|
||||
// Types that do contain handles.
|
||||
Ti::Pointer { base, space: _ } => work_list.push(base),
|
||||
Ti::Array {
|
||||
Ti::Pointer { base, space: _ }
|
||||
| Ti::Array {
|
||||
base,
|
||||
size: _,
|
||||
stride: _,
|
||||
} => work_list.push(base),
|
||||
}
|
||||
| Ti::BindingArray { base, size: _ } => self.types_used.insert(base),
|
||||
Ti::Struct {
|
||||
ref members,
|
||||
span: _,
|
||||
} => {
|
||||
work_list.extend(members.iter().map(|m| m.ty));
|
||||
self.types_used.insert_iter(members.iter().map(|m| m.ty));
|
||||
}
|
||||
Ti::BindingArray { base, size: _ } => work_list.push(base),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -54,10 +63,10 @@ impl ModuleMap {
|
||||
use crate::TypeInner as Ti;
|
||||
match ty.inner {
|
||||
// Types that do not contain handles.
|
||||
Ti::Scalar { .. }
|
||||
Ti::Scalar(_)
|
||||
| Ti::Vector { .. }
|
||||
| Ti::Matrix { .. }
|
||||
| Ti::Atomic { .. }
|
||||
| Ti::Atomic(_)
|
||||
| Ti::ValuePointer { .. }
|
||||
| Ti::Image { .. }
|
||||
| Ti::Sampler { .. }
|
||||
|
392
third_party/rust/naga/src/front/glsl/builtins.rs
vendored
392
third_party/rust/naga/src/front/glsl/builtins.rs
vendored
@ -9,7 +9,7 @@ use super::{
|
||||
use crate::{
|
||||
BinaryOperator, DerivativeAxis as Axis, DerivativeControl as Ctrl, Expression, Handle,
|
||||
ImageClass, ImageDimension as Dim, ImageQuery, MathFunction, Module, RelationalFunction,
|
||||
SampleLevel, ScalarKind as Sk, Span, Type, TypeInner, UnaryOperator, VectorSize,
|
||||
SampleLevel, Scalar, ScalarKind as Sk, Span, Type, TypeInner, UnaryOperator, VectorSize,
|
||||
};
|
||||
|
||||
impl crate::ScalarKind {
|
||||
@ -54,18 +54,17 @@ impl Module {
|
||||
}
|
||||
|
||||
const fn make_coords_arg(number_of_components: usize, kind: Sk) -> TypeInner {
|
||||
let width = 4;
|
||||
let scalar = Scalar { kind, width: 4 };
|
||||
|
||||
match number_of_components {
|
||||
1 => TypeInner::Scalar { kind, width },
|
||||
1 => TypeInner::Scalar(scalar),
|
||||
_ => TypeInner::Vector {
|
||||
size: match number_of_components {
|
||||
2 => VectorSize::Bi,
|
||||
3 => VectorSize::Tri,
|
||||
_ => VectorSize::Quad,
|
||||
},
|
||||
kind,
|
||||
width,
|
||||
scalar,
|
||||
},
|
||||
}
|
||||
}
|
||||
@ -98,7 +97,6 @@ pub fn inject_builtin(
|
||||
inject_double_builtin(declaration, module, name)
|
||||
}
|
||||
|
||||
let width = 4;
|
||||
match name {
|
||||
"texture"
|
||||
| "textureGrad"
|
||||
@ -235,18 +233,12 @@ pub fn inject_builtin(
|
||||
let mut args = vec![image, vector];
|
||||
|
||||
if num_coords == 5 {
|
||||
args.push(TypeInner::Scalar {
|
||||
kind: Sk::Float,
|
||||
width,
|
||||
});
|
||||
args.push(TypeInner::Scalar(Scalar::F32));
|
||||
}
|
||||
|
||||
match level_type {
|
||||
TextureLevelType::Lod => {
|
||||
args.push(TypeInner::Scalar {
|
||||
kind: Sk::Float,
|
||||
width,
|
||||
});
|
||||
args.push(TypeInner::Scalar(Scalar::F32));
|
||||
}
|
||||
TextureLevelType::Grad => {
|
||||
args.push(make_coords_arg(num_coords_from_dim, Sk::Float));
|
||||
@ -260,10 +252,7 @@ pub fn inject_builtin(
|
||||
}
|
||||
|
||||
if bias {
|
||||
args.push(TypeInner::Scalar {
|
||||
kind: Sk::Float,
|
||||
width,
|
||||
});
|
||||
args.push(TypeInner::Scalar(Scalar::F32));
|
||||
}
|
||||
|
||||
declaration
|
||||
@ -290,10 +279,7 @@ pub fn inject_builtin(
|
||||
let mut args = vec![image];
|
||||
|
||||
if !multi {
|
||||
args.push(TypeInner::Scalar {
|
||||
kind: Sk::Sint,
|
||||
width,
|
||||
})
|
||||
args.push(TypeInner::Scalar(Scalar::I32))
|
||||
}
|
||||
|
||||
declaration
|
||||
@ -323,14 +309,7 @@ pub fn inject_builtin(
|
||||
let dim_value = image_dims_to_coords_size(dim);
|
||||
let coordinates = make_coords_arg(dim_value + arrayed as usize, Sk::Sint);
|
||||
|
||||
let mut args = vec![
|
||||
image,
|
||||
coordinates,
|
||||
TypeInner::Scalar {
|
||||
kind: Sk::Sint,
|
||||
width,
|
||||
},
|
||||
];
|
||||
let mut args = vec![image, coordinates, TypeInner::Scalar(Scalar::I32)];
|
||||
|
||||
if offset {
|
||||
args.push(make_coords_arg(dim_value, Sk::Sint));
|
||||
@ -441,8 +420,7 @@ pub fn inject_builtin(
|
||||
coordinates,
|
||||
TypeInner::Vector {
|
||||
size: VectorSize::Quad,
|
||||
kind,
|
||||
width,
|
||||
scalar: Scalar { kind, width: 4 },
|
||||
},
|
||||
];
|
||||
|
||||
@ -464,7 +442,6 @@ fn inject_standard_builtins(
|
||||
module: &mut Module,
|
||||
name: &str,
|
||||
) {
|
||||
let width = 4;
|
||||
match name {
|
||||
"sampler1D" | "sampler1DArray" | "sampler2D" | "sampler2DArray" | "sampler2DMS"
|
||||
| "sampler2DMSArray" | "sampler3D" | "samplerCube" | "samplerCubeArray" => {
|
||||
@ -544,12 +521,12 @@ fn inject_standard_builtins(
|
||||
0b10 => Some(VectorSize::Tri),
|
||||
_ => Some(VectorSize::Quad),
|
||||
};
|
||||
let kind = Sk::Float;
|
||||
let scalar = Scalar::F32;
|
||||
|
||||
declaration.overloads.push(module.add_builtin(
|
||||
vec![match size {
|
||||
Some(size) => TypeInner::Vector { size, kind, width },
|
||||
None => TypeInner::Scalar { kind, width },
|
||||
Some(size) => TypeInner::Vector { size, scalar },
|
||||
None => TypeInner::Scalar(scalar),
|
||||
}],
|
||||
match name {
|
||||
"sin" => MacroCall::MathFunction(MathFunction::Sin),
|
||||
@ -595,15 +572,15 @@ fn inject_standard_builtins(
|
||||
0b10 => Some(VectorSize::Tri),
|
||||
_ => Some(VectorSize::Quad),
|
||||
};
|
||||
let kind = match name {
|
||||
"intBitsToFloat" => Sk::Sint,
|
||||
_ => Sk::Uint,
|
||||
let scalar = match name {
|
||||
"intBitsToFloat" => Scalar::I32,
|
||||
_ => Scalar::U32,
|
||||
};
|
||||
|
||||
declaration.overloads.push(module.add_builtin(
|
||||
vec![match size {
|
||||
Some(size) => TypeInner::Vector { size, kind, width },
|
||||
None => TypeInner::Scalar { kind, width },
|
||||
Some(size) => TypeInner::Vector { size, scalar },
|
||||
None => TypeInner::Scalar(scalar),
|
||||
}],
|
||||
MacroCall::BitCast(Sk::Float),
|
||||
))
|
||||
@ -619,10 +596,10 @@ fn inject_standard_builtins(
|
||||
0b10 => Some(VectorSize::Tri),
|
||||
_ => Some(VectorSize::Quad),
|
||||
};
|
||||
let kind = Sk::Float;
|
||||
let scalar = Scalar::F32;
|
||||
let ty = || match size {
|
||||
Some(size) => TypeInner::Vector { size, kind, width },
|
||||
None => TypeInner::Scalar { kind, width },
|
||||
Some(size) => TypeInner::Vector { size, scalar },
|
||||
None => TypeInner::Scalar(scalar),
|
||||
};
|
||||
|
||||
declaration.overloads.push(
|
||||
@ -642,14 +619,14 @@ fn inject_standard_builtins(
|
||||
0b10 => Some(VectorSize::Tri),
|
||||
_ => Some(VectorSize::Quad),
|
||||
};
|
||||
let kind = match bits >> 2 {
|
||||
0b0 => Sk::Float,
|
||||
_ => Sk::Sint,
|
||||
let scalar = match bits >> 2 {
|
||||
0b0 => Scalar::F32,
|
||||
_ => Scalar::I32,
|
||||
};
|
||||
|
||||
let args = vec![match size {
|
||||
Some(size) => TypeInner::Vector { size, kind, width },
|
||||
None => TypeInner::Scalar { kind, width },
|
||||
Some(size) => TypeInner::Vector { size, scalar },
|
||||
None => TypeInner::Scalar(scalar),
|
||||
}];
|
||||
|
||||
declaration.overloads.push(module.add_builtin(
|
||||
@ -684,9 +661,9 @@ fn inject_standard_builtins(
|
||||
// bit 0 - int/uint
|
||||
// bit 1 through 2 - dims
|
||||
for bits in 0..0b1000 {
|
||||
let kind = match bits & 0b1 {
|
||||
0b0 => Sk::Sint,
|
||||
_ => Sk::Uint,
|
||||
let scalar = match bits & 0b1 {
|
||||
0b0 => Scalar::I32,
|
||||
_ => Scalar::U32,
|
||||
};
|
||||
let size = match bits >> 1 {
|
||||
0b00 => None,
|
||||
@ -696,39 +673,27 @@ fn inject_standard_builtins(
|
||||
};
|
||||
|
||||
let ty = || match size {
|
||||
Some(size) => TypeInner::Vector { size, kind, width },
|
||||
None => TypeInner::Scalar { kind, width },
|
||||
Some(size) => TypeInner::Vector { size, scalar },
|
||||
None => TypeInner::Scalar(scalar),
|
||||
};
|
||||
|
||||
let mut args = vec![ty()];
|
||||
|
||||
match fun {
|
||||
MathFunction::ExtractBits => {
|
||||
args.push(TypeInner::Scalar {
|
||||
kind: Sk::Sint,
|
||||
width: 4,
|
||||
});
|
||||
args.push(TypeInner::Scalar {
|
||||
kind: Sk::Sint,
|
||||
width: 4,
|
||||
});
|
||||
args.push(TypeInner::Scalar(Scalar::I32));
|
||||
args.push(TypeInner::Scalar(Scalar::I32));
|
||||
}
|
||||
MathFunction::InsertBits => {
|
||||
args.push(ty());
|
||||
args.push(TypeInner::Scalar {
|
||||
kind: Sk::Sint,
|
||||
width: 4,
|
||||
});
|
||||
args.push(TypeInner::Scalar {
|
||||
kind: Sk::Sint,
|
||||
width: 4,
|
||||
});
|
||||
args.push(TypeInner::Scalar(Scalar::I32));
|
||||
args.push(TypeInner::Scalar(Scalar::I32));
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
||||
// we need to cast the return type of findLsb / findMsb
|
||||
let mc = if kind == Sk::Uint {
|
||||
let mc = if scalar.kind == Sk::Uint {
|
||||
match mc {
|
||||
MacroCall::MathFunction(MathFunction::FindLsb) => MacroCall::FindLsbUint,
|
||||
MacroCall::MathFunction(MathFunction::FindMsb) => MacroCall::FindMsbUint,
|
||||
@ -754,15 +719,13 @@ fn inject_standard_builtins(
|
||||
let ty = match fun {
|
||||
MathFunction::Pack4x8snorm | MathFunction::Pack4x8unorm => TypeInner::Vector {
|
||||
size: crate::VectorSize::Quad,
|
||||
kind: Sk::Float,
|
||||
width: 4,
|
||||
scalar: Scalar::F32,
|
||||
},
|
||||
MathFunction::Pack2x16unorm
|
||||
| MathFunction::Pack2x16snorm
|
||||
| MathFunction::Pack2x16float => TypeInner::Vector {
|
||||
size: crate::VectorSize::Bi,
|
||||
kind: Sk::Float,
|
||||
width: 4,
|
||||
scalar: Scalar::F32,
|
||||
},
|
||||
_ => unreachable!(),
|
||||
};
|
||||
@ -784,10 +747,7 @@ fn inject_standard_builtins(
|
||||
_ => unreachable!(),
|
||||
};
|
||||
|
||||
let args = vec![TypeInner::Scalar {
|
||||
kind: Sk::Uint,
|
||||
width: 4,
|
||||
}];
|
||||
let args = vec![TypeInner::Scalar(Scalar::U32)];
|
||||
|
||||
declaration
|
||||
.overloads
|
||||
@ -808,10 +768,10 @@ fn inject_standard_builtins(
|
||||
0b10 => Some(VectorSize::Tri),
|
||||
_ => Some(VectorSize::Quad),
|
||||
};
|
||||
let kind = Sk::Float;
|
||||
let scalar = Scalar::F32;
|
||||
let ty = || match size {
|
||||
Some(size) => TypeInner::Vector { size, kind, width },
|
||||
None => TypeInner::Scalar { kind, width },
|
||||
Some(size) => TypeInner::Vector { size, scalar },
|
||||
None => TypeInner::Scalar(scalar),
|
||||
};
|
||||
|
||||
let mut args = vec![ty()];
|
||||
@ -837,8 +797,7 @@ fn inject_standard_builtins(
|
||||
|
||||
let args = vec![TypeInner::Vector {
|
||||
size,
|
||||
kind: Sk::Bool,
|
||||
width: crate::BOOL_WIDTH,
|
||||
scalar: Scalar::BOOL,
|
||||
}];
|
||||
|
||||
let fun = match name {
|
||||
@ -853,19 +812,19 @@ fn inject_standard_builtins(
|
||||
}
|
||||
"lessThan" | "greaterThan" | "lessThanEqual" | "greaterThanEqual" => {
|
||||
for bits in 0..0b1001 {
|
||||
let (size, kind) = match bits {
|
||||
0b0000 => (VectorSize::Bi, Sk::Float),
|
||||
0b0001 => (VectorSize::Tri, Sk::Float),
|
||||
0b0010 => (VectorSize::Quad, Sk::Float),
|
||||
0b0011 => (VectorSize::Bi, Sk::Sint),
|
||||
0b0100 => (VectorSize::Tri, Sk::Sint),
|
||||
0b0101 => (VectorSize::Quad, Sk::Sint),
|
||||
0b0110 => (VectorSize::Bi, Sk::Uint),
|
||||
0b0111 => (VectorSize::Tri, Sk::Uint),
|
||||
_ => (VectorSize::Quad, Sk::Uint),
|
||||
let (size, scalar) = match bits {
|
||||
0b0000 => (VectorSize::Bi, Scalar::F32),
|
||||
0b0001 => (VectorSize::Tri, Scalar::F32),
|
||||
0b0010 => (VectorSize::Quad, Scalar::F32),
|
||||
0b0011 => (VectorSize::Bi, Scalar::I32),
|
||||
0b0100 => (VectorSize::Tri, Scalar::I32),
|
||||
0b0101 => (VectorSize::Quad, Scalar::I32),
|
||||
0b0110 => (VectorSize::Bi, Scalar::U32),
|
||||
0b0111 => (VectorSize::Tri, Scalar::U32),
|
||||
_ => (VectorSize::Quad, Scalar::U32),
|
||||
};
|
||||
|
||||
let ty = || TypeInner::Vector { size, kind, width };
|
||||
let ty = || TypeInner::Vector { size, scalar };
|
||||
let args = vec![ty(), ty()];
|
||||
|
||||
let fun = MacroCall::Binary(match name {
|
||||
@ -881,28 +840,22 @@ fn inject_standard_builtins(
|
||||
}
|
||||
"equal" | "notEqual" => {
|
||||
for bits in 0..0b1100 {
|
||||
let (size, kind) = match bits {
|
||||
0b0000 => (VectorSize::Bi, Sk::Float),
|
||||
0b0001 => (VectorSize::Tri, Sk::Float),
|
||||
0b0010 => (VectorSize::Quad, Sk::Float),
|
||||
0b0011 => (VectorSize::Bi, Sk::Sint),
|
||||
0b0100 => (VectorSize::Tri, Sk::Sint),
|
||||
0b0101 => (VectorSize::Quad, Sk::Sint),
|
||||
0b0110 => (VectorSize::Bi, Sk::Uint),
|
||||
0b0111 => (VectorSize::Tri, Sk::Uint),
|
||||
0b1000 => (VectorSize::Quad, Sk::Uint),
|
||||
0b1001 => (VectorSize::Bi, Sk::Bool),
|
||||
0b1010 => (VectorSize::Tri, Sk::Bool),
|
||||
_ => (VectorSize::Quad, Sk::Bool),
|
||||
let (size, scalar) = match bits {
|
||||
0b0000 => (VectorSize::Bi, Scalar::F32),
|
||||
0b0001 => (VectorSize::Tri, Scalar::F32),
|
||||
0b0010 => (VectorSize::Quad, Scalar::F32),
|
||||
0b0011 => (VectorSize::Bi, Scalar::I32),
|
||||
0b0100 => (VectorSize::Tri, Scalar::I32),
|
||||
0b0101 => (VectorSize::Quad, Scalar::I32),
|
||||
0b0110 => (VectorSize::Bi, Scalar::U32),
|
||||
0b0111 => (VectorSize::Tri, Scalar::U32),
|
||||
0b1000 => (VectorSize::Quad, Scalar::U32),
|
||||
0b1001 => (VectorSize::Bi, Scalar::BOOL),
|
||||
0b1010 => (VectorSize::Tri, Scalar::BOOL),
|
||||
_ => (VectorSize::Quad, Scalar::BOOL),
|
||||
};
|
||||
|
||||
let width = if let Sk::Bool = kind {
|
||||
crate::BOOL_WIDTH
|
||||
} else {
|
||||
width
|
||||
};
|
||||
|
||||
let ty = || TypeInner::Vector { size, kind, width };
|
||||
let ty = || TypeInner::Vector { size, scalar };
|
||||
let args = vec![ty(), ty()];
|
||||
|
||||
let fun = MacroCall::Binary(match name {
|
||||
@ -919,10 +872,10 @@ fn inject_standard_builtins(
|
||||
// bit 0 through 1 - scalar kind
|
||||
// bit 2 through 4 - dims
|
||||
for bits in 0..0b11100 {
|
||||
let kind = match bits & 0b11 {
|
||||
0b00 => Sk::Float,
|
||||
0b01 => Sk::Sint,
|
||||
0b10 => Sk::Uint,
|
||||
let scalar = match bits & 0b11 {
|
||||
0b00 => Scalar::F32,
|
||||
0b01 => Scalar::I32,
|
||||
0b10 => Scalar::U32,
|
||||
_ => continue,
|
||||
};
|
||||
let (size, second_size) = match bits >> 2 {
|
||||
@ -937,12 +890,12 @@ fn inject_standard_builtins(
|
||||
|
||||
let args = vec![
|
||||
match size {
|
||||
Some(size) => TypeInner::Vector { size, kind, width },
|
||||
None => TypeInner::Scalar { kind, width },
|
||||
Some(size) => TypeInner::Vector { size, scalar },
|
||||
None => TypeInner::Scalar(scalar),
|
||||
},
|
||||
match second_size {
|
||||
Some(size) => TypeInner::Vector { size, kind, width },
|
||||
None => TypeInner::Scalar { kind, width },
|
||||
Some(size) => TypeInner::Vector { size, scalar },
|
||||
None => TypeInner::Scalar(scalar),
|
||||
},
|
||||
];
|
||||
|
||||
@ -969,25 +922,25 @@ fn inject_standard_builtins(
|
||||
0b10 => Some(VectorSize::Quad),
|
||||
_ => None,
|
||||
};
|
||||
let (kind, splatted, boolean) = match bits >> 2 {
|
||||
0b000 => (Sk::Sint, false, true),
|
||||
0b001 => (Sk::Uint, false, true),
|
||||
0b010 => (Sk::Float, false, true),
|
||||
0b011 => (Sk::Float, false, false),
|
||||
_ => (Sk::Float, true, false),
|
||||
let (scalar, splatted, boolean) = match bits >> 2 {
|
||||
0b000 => (Scalar::I32, false, true),
|
||||
0b001 => (Scalar::U32, false, true),
|
||||
0b010 => (Scalar::F32, false, true),
|
||||
0b011 => (Scalar::F32, false, false),
|
||||
_ => (Scalar::F32, true, false),
|
||||
};
|
||||
|
||||
let ty = |kind, width| match size {
|
||||
Some(size) => TypeInner::Vector { size, kind, width },
|
||||
None => TypeInner::Scalar { kind, width },
|
||||
let ty = |scalar| match size {
|
||||
Some(size) => TypeInner::Vector { size, scalar },
|
||||
None => TypeInner::Scalar(scalar),
|
||||
};
|
||||
let args = vec![
|
||||
ty(kind, width),
|
||||
ty(kind, width),
|
||||
ty(scalar),
|
||||
ty(scalar),
|
||||
match (boolean, splatted) {
|
||||
(true, _) => ty(Sk::Bool, crate::BOOL_WIDTH),
|
||||
(_, false) => TypeInner::Scalar { kind, width },
|
||||
_ => ty(kind, width),
|
||||
(true, _) => ty(Scalar::BOOL),
|
||||
(_, false) => TypeInner::Scalar(scalar),
|
||||
_ => ty(scalar),
|
||||
},
|
||||
];
|
||||
|
||||
@ -1009,10 +962,10 @@ fn inject_standard_builtins(
|
||||
// 0b11010 is the last element since splatted single elements
|
||||
// were already added
|
||||
for bits in 0..0b11011 {
|
||||
let kind = match bits & 0b11 {
|
||||
0b00 => Sk::Float,
|
||||
0b01 => Sk::Sint,
|
||||
0b10 => Sk::Uint,
|
||||
let scalar = match bits & 0b11 {
|
||||
0b00 => Scalar::F32,
|
||||
0b01 => Scalar::I32,
|
||||
0b10 => Scalar::U32,
|
||||
_ => continue,
|
||||
};
|
||||
let size = match (bits >> 2) & 0b11 {
|
||||
@ -1024,11 +977,11 @@ fn inject_standard_builtins(
|
||||
let splatted = bits & 0b10000 == 0b10000;
|
||||
|
||||
let base_ty = || match size {
|
||||
Some(size) => TypeInner::Vector { size, kind, width },
|
||||
None => TypeInner::Scalar { kind, width },
|
||||
Some(size) => TypeInner::Vector { size, scalar },
|
||||
None => TypeInner::Scalar(scalar),
|
||||
};
|
||||
let limit_ty = || match splatted {
|
||||
true => TypeInner::Scalar { kind, width },
|
||||
true => TypeInner::Scalar(scalar),
|
||||
false => base_ty(),
|
||||
};
|
||||
|
||||
@ -1049,7 +1002,6 @@ fn inject_standard_builtins(
|
||||
|
||||
/// Injects the builtins into declaration that need doubles
|
||||
fn inject_double_builtin(declaration: &mut FunctionDeclaration, module: &mut Module, name: &str) {
|
||||
let width = 8;
|
||||
match name {
|
||||
"abs" | "sign" => {
|
||||
// bits layout
|
||||
@ -1061,11 +1013,11 @@ fn inject_double_builtin(declaration: &mut FunctionDeclaration, module: &mut Mod
|
||||
0b10 => Some(VectorSize::Tri),
|
||||
_ => Some(VectorSize::Quad),
|
||||
};
|
||||
let kind = Sk::Float;
|
||||
let scalar = Scalar::F64;
|
||||
|
||||
let args = vec![match size {
|
||||
Some(size) => TypeInner::Vector { size, kind, width },
|
||||
None => TypeInner::Scalar { kind, width },
|
||||
Some(size) => TypeInner::Vector { size, scalar },
|
||||
None => TypeInner::Scalar(scalar),
|
||||
}];
|
||||
|
||||
declaration.overloads.push(module.add_builtin(
|
||||
@ -1091,16 +1043,16 @@ fn inject_double_builtin(declaration: &mut FunctionDeclaration, module: &mut Mod
|
||||
0b101 => (Some(VectorSize::Tri), Some(VectorSize::Tri)),
|
||||
_ => (Some(VectorSize::Quad), Some(VectorSize::Quad)),
|
||||
};
|
||||
let kind = Sk::Float;
|
||||
let scalar = Scalar::F64;
|
||||
|
||||
let args = vec![
|
||||
match size {
|
||||
Some(size) => TypeInner::Vector { size, kind, width },
|
||||
None => TypeInner::Scalar { kind, width },
|
||||
Some(size) => TypeInner::Vector { size, scalar },
|
||||
None => TypeInner::Scalar(scalar),
|
||||
},
|
||||
match second_size {
|
||||
Some(size) => TypeInner::Vector { size, kind, width },
|
||||
None => TypeInner::Scalar { kind, width },
|
||||
Some(size) => TypeInner::Vector { size, scalar },
|
||||
None => TypeInner::Scalar(scalar),
|
||||
},
|
||||
];
|
||||
|
||||
@ -1127,24 +1079,24 @@ fn inject_double_builtin(declaration: &mut FunctionDeclaration, module: &mut Mod
|
||||
0b10 => Some(VectorSize::Tri),
|
||||
_ => None,
|
||||
};
|
||||
let kind = Sk::Float;
|
||||
let scalar = Scalar::F64;
|
||||
let (splatted, boolean) = match bits >> 2 {
|
||||
0b00 => (false, false),
|
||||
0b01 => (false, true),
|
||||
_ => (true, false),
|
||||
};
|
||||
|
||||
let ty = |kind, width| match size {
|
||||
Some(size) => TypeInner::Vector { size, kind, width },
|
||||
None => TypeInner::Scalar { kind, width },
|
||||
let ty = |scalar| match size {
|
||||
Some(size) => TypeInner::Vector { size, scalar },
|
||||
None => TypeInner::Scalar(scalar),
|
||||
};
|
||||
let args = vec![
|
||||
ty(kind, width),
|
||||
ty(kind, width),
|
||||
ty(scalar),
|
||||
ty(scalar),
|
||||
match (boolean, splatted) {
|
||||
(true, _) => ty(Sk::Bool, crate::BOOL_WIDTH),
|
||||
(_, false) => TypeInner::Scalar { kind, width },
|
||||
_ => ty(kind, width),
|
||||
(true, _) => ty(Scalar::BOOL),
|
||||
(_, false) => TypeInner::Scalar(scalar),
|
||||
_ => ty(scalar),
|
||||
},
|
||||
];
|
||||
|
||||
@ -1165,7 +1117,7 @@ fn inject_double_builtin(declaration: &mut FunctionDeclaration, module: &mut Mod
|
||||
// 0b110 is the last element since splatted with single elements
|
||||
// is equal to normal single elements
|
||||
for bits in 0..0b111 {
|
||||
let kind = Sk::Float;
|
||||
let scalar = Scalar::F64;
|
||||
let size = match bits & 0b11 {
|
||||
0b00 => Some(VectorSize::Bi),
|
||||
0b01 => Some(VectorSize::Tri),
|
||||
@ -1175,11 +1127,11 @@ fn inject_double_builtin(declaration: &mut FunctionDeclaration, module: &mut Mod
|
||||
let splatted = bits & 0b100 == 0b100;
|
||||
|
||||
let base_ty = || match size {
|
||||
Some(size) => TypeInner::Vector { size, kind, width },
|
||||
None => TypeInner::Scalar { kind, width },
|
||||
Some(size) => TypeInner::Vector { size, scalar },
|
||||
None => TypeInner::Scalar(scalar),
|
||||
};
|
||||
let limit_ty = || match splatted {
|
||||
true => TypeInner::Scalar { kind, width },
|
||||
true => TypeInner::Scalar(scalar),
|
||||
false => base_ty(),
|
||||
};
|
||||
|
||||
@ -1192,14 +1144,15 @@ fn inject_double_builtin(declaration: &mut FunctionDeclaration, module: &mut Mod
|
||||
}
|
||||
"lessThan" | "greaterThan" | "lessThanEqual" | "greaterThanEqual" | "equal"
|
||||
| "notEqual" => {
|
||||
let scalar = Scalar::F64;
|
||||
for bits in 0..0b11 {
|
||||
let (size, kind) = match bits {
|
||||
0b00 => (VectorSize::Bi, Sk::Float),
|
||||
0b01 => (VectorSize::Tri, Sk::Float),
|
||||
_ => (VectorSize::Quad, Sk::Float),
|
||||
let size = match bits {
|
||||
0b00 => VectorSize::Bi,
|
||||
0b01 => VectorSize::Tri,
|
||||
_ => VectorSize::Quad,
|
||||
};
|
||||
|
||||
let ty = || TypeInner::Vector { size, kind, width };
|
||||
let ty = || TypeInner::Vector { size, scalar };
|
||||
let args = vec![ty(), ty()];
|
||||
|
||||
let fun = MacroCall::Binary(match name {
|
||||
@ -1227,6 +1180,10 @@ fn inject_common_builtin(
|
||||
name: &str,
|
||||
float_width: crate::Bytes,
|
||||
) {
|
||||
let float_scalar = Scalar {
|
||||
kind: Sk::Float,
|
||||
width: float_width,
|
||||
};
|
||||
match name {
|
||||
"ceil" | "round" | "roundEven" | "floor" | "fract" | "trunc" | "sqrt" | "inversesqrt"
|
||||
| "normalize" | "length" | "isinf" | "isnan" => {
|
||||
@ -1243,13 +1200,9 @@ fn inject_common_builtin(
|
||||
let args = vec![match size {
|
||||
Some(size) => TypeInner::Vector {
|
||||
size,
|
||||
kind: Sk::Float,
|
||||
width: float_width,
|
||||
},
|
||||
None => TypeInner::Scalar {
|
||||
kind: Sk::Float,
|
||||
width: float_width,
|
||||
scalar: float_scalar,
|
||||
},
|
||||
None => TypeInner::Scalar(float_scalar),
|
||||
}];
|
||||
|
||||
let fun = match name {
|
||||
@ -1280,16 +1233,9 @@ fn inject_common_builtin(
|
||||
0b10 => Some(VectorSize::Tri),
|
||||
_ => Some(VectorSize::Quad),
|
||||
};
|
||||
let ty = |kind| match size {
|
||||
Some(size) => TypeInner::Vector {
|
||||
size,
|
||||
kind,
|
||||
width: float_width,
|
||||
},
|
||||
None => TypeInner::Scalar {
|
||||
kind,
|
||||
width: float_width,
|
||||
},
|
||||
let ty = |scalar| match size {
|
||||
Some(size) => TypeInner::Vector { size, scalar },
|
||||
None => TypeInner::Scalar(scalar),
|
||||
};
|
||||
|
||||
let fun = match name {
|
||||
@ -1300,15 +1246,14 @@ fn inject_common_builtin(
|
||||
_ => unreachable!(),
|
||||
};
|
||||
|
||||
let second_kind = if fun == MacroCall::MathFunction(MathFunction::Ldexp) {
|
||||
Sk::Sint
|
||||
} else {
|
||||
Sk::Float
|
||||
let second_scalar = match fun {
|
||||
MacroCall::MathFunction(MathFunction::Ldexp) => Scalar::I32,
|
||||
_ => float_scalar,
|
||||
};
|
||||
|
||||
declaration
|
||||
.overloads
|
||||
.push(module.add_builtin(vec![ty(Sk::Float), ty(second_kind)], fun))
|
||||
.push(module.add_builtin(vec![ty(float_scalar), ty(second_scalar)], fun))
|
||||
}
|
||||
}
|
||||
"transpose" => {
|
||||
@ -1389,13 +1334,9 @@ fn inject_common_builtin(
|
||||
args.push(match maybe_size {
|
||||
Some(size) => TypeInner::Vector {
|
||||
size,
|
||||
kind: Sk::Float,
|
||||
width: float_width,
|
||||
},
|
||||
None => TypeInner::Scalar {
|
||||
kind: Sk::Float,
|
||||
width: float_width,
|
||||
scalar: float_scalar,
|
||||
},
|
||||
None => TypeInner::Scalar(float_scalar),
|
||||
})
|
||||
}
|
||||
|
||||
@ -1414,13 +1355,11 @@ fn inject_common_builtin(
|
||||
let args = vec![
|
||||
TypeInner::Vector {
|
||||
size: VectorSize::Tri,
|
||||
kind: Sk::Float,
|
||||
width: float_width,
|
||||
scalar: float_scalar,
|
||||
},
|
||||
TypeInner::Vector {
|
||||
size: VectorSize::Tri,
|
||||
kind: Sk::Float,
|
||||
width: float_width,
|
||||
scalar: float_scalar,
|
||||
},
|
||||
];
|
||||
|
||||
@ -1447,13 +1386,11 @@ fn inject_common_builtin(
|
||||
let args = vec![
|
||||
TypeInner::Vector {
|
||||
size: size1,
|
||||
kind: Sk::Float,
|
||||
width: float_width,
|
||||
scalar: float_scalar,
|
||||
},
|
||||
TypeInner::Vector {
|
||||
size: size2,
|
||||
kind: Sk::Float,
|
||||
width: float_width,
|
||||
scalar: float_scalar,
|
||||
},
|
||||
];
|
||||
|
||||
@ -1476,13 +1413,9 @@ fn inject_common_builtin(
|
||||
let ty = || match size {
|
||||
Some(size) => TypeInner::Vector {
|
||||
size,
|
||||
kind: Sk::Float,
|
||||
width: float_width,
|
||||
},
|
||||
None => TypeInner::Scalar {
|
||||
kind: Sk::Float,
|
||||
width: float_width,
|
||||
scalar: float_scalar,
|
||||
},
|
||||
None => TypeInner::Scalar(float_scalar),
|
||||
};
|
||||
let args = vec![ty(), ty(), ty()];
|
||||
|
||||
@ -1509,22 +1442,11 @@ fn inject_common_builtin(
|
||||
let ty = || match size {
|
||||
Some(size) => TypeInner::Vector {
|
||||
size,
|
||||
kind: Sk::Float,
|
||||
width: float_width,
|
||||
},
|
||||
None => TypeInner::Scalar {
|
||||
kind: Sk::Float,
|
||||
width: float_width,
|
||||
scalar: float_scalar,
|
||||
},
|
||||
None => TypeInner::Scalar(float_scalar),
|
||||
};
|
||||
let args = vec![
|
||||
ty(),
|
||||
ty(),
|
||||
TypeInner::Scalar {
|
||||
kind: Sk::Float,
|
||||
width: 4,
|
||||
},
|
||||
];
|
||||
let args = vec![ty(), ty(), TypeInner::Scalar(Scalar::F32)];
|
||||
declaration
|
||||
.overloads
|
||||
.push(module.add_builtin(args, MacroCall::MathFunction(MathFunction::Refract)))
|
||||
@ -1549,19 +1471,12 @@ fn inject_common_builtin(
|
||||
let base_ty = || match size {
|
||||
Some(size) => TypeInner::Vector {
|
||||
size,
|
||||
kind: Sk::Float,
|
||||
width: float_width,
|
||||
},
|
||||
None => TypeInner::Scalar {
|
||||
kind: Sk::Float,
|
||||
width: float_width,
|
||||
scalar: float_scalar,
|
||||
},
|
||||
None => TypeInner::Scalar(float_scalar),
|
||||
};
|
||||
let ty = || match splatted {
|
||||
true => TypeInner::Scalar {
|
||||
kind: Sk::Float,
|
||||
width: float_width,
|
||||
},
|
||||
true => TypeInner::Scalar(float_scalar),
|
||||
false => base_ty(),
|
||||
};
|
||||
declaration.overloads.push(module.add_builtin(
|
||||
@ -1810,8 +1725,7 @@ impl MacroCall {
|
||||
name: None,
|
||||
inner: TypeInner::Vector {
|
||||
size,
|
||||
kind: crate::ScalarKind::Uint,
|
||||
width: 4,
|
||||
scalar: Scalar::U32,
|
||||
},
|
||||
},
|
||||
Span::default(),
|
||||
@ -2100,7 +2014,7 @@ fn texture_call(
|
||||
let mut array_index = comps.array_index;
|
||||
|
||||
if let Some(ref mut array_index_expr) = array_index {
|
||||
ctx.conversion(array_index_expr, meta, Sk::Sint, 4)?;
|
||||
ctx.conversion(array_index_expr, meta, Scalar::I32)?;
|
||||
}
|
||||
|
||||
Ok(ctx.add_expression(
|
||||
|
110
third_party/rust/naga/src/front/glsl/context.rs
vendored
110
third_party/rust/naga/src/front/glsl/context.rs
vendored
@ -9,8 +9,8 @@ use super::{
|
||||
};
|
||||
use crate::{
|
||||
front::Typifier, proc::Emitter, AddressSpace, Arena, BinaryOperator, Block, Expression,
|
||||
FastHashMap, FunctionArgument, Handle, Literal, LocalVariable, RelationalFunction, ScalarKind,
|
||||
Span, Statement, Type, TypeInner, VectorSize,
|
||||
FastHashMap, FunctionArgument, Handle, Literal, LocalVariable, RelationalFunction, Scalar,
|
||||
ScalarKind, Span, Statement, Type, TypeInner, VectorSize,
|
||||
};
|
||||
use std::ops::Index;
|
||||
|
||||
@ -602,7 +602,7 @@ impl<'a> Context<'a> {
|
||||
|
||||
match op {
|
||||
BinaryOperator::ShiftLeft | BinaryOperator::ShiftRight => {
|
||||
self.implicit_conversion(&mut right, right_meta, ScalarKind::Uint, 4)?
|
||||
self.implicit_conversion(&mut right, right_meta, Scalar::U32)?
|
||||
}
|
||||
_ => self
|
||||
.binary_implicit_conversion(&mut left, left_meta, &mut right, right_meta)?,
|
||||
@ -824,9 +824,9 @@ impl<'a> Context<'a> {
|
||||
_ => self.add_expression(Expression::Binary { left, op, right }, meta)?,
|
||||
},
|
||||
(
|
||||
&TypeInner::Scalar {
|
||||
&TypeInner::Scalar(Scalar {
|
||||
width: left_width, ..
|
||||
},
|
||||
}),
|
||||
&TypeInner::Matrix {
|
||||
rows,
|
||||
columns,
|
||||
@ -911,9 +911,9 @@ impl<'a> Context<'a> {
|
||||
columns,
|
||||
width: left_width,
|
||||
},
|
||||
&TypeInner::Scalar {
|
||||
&TypeInner::Scalar(Scalar {
|
||||
width: right_width, ..
|
||||
},
|
||||
}),
|
||||
) => {
|
||||
// Check that the two arguments have the same width
|
||||
if left_width != right_width {
|
||||
@ -1100,37 +1100,24 @@ impl<'a> Context<'a> {
|
||||
|
||||
// We need to do some custom implicit conversions since the two target expressions
|
||||
// are in different bodies
|
||||
if let (
|
||||
Some((accept_power, accept_width, accept_kind)),
|
||||
Some((reject_power, reject_width, reject_kind)),
|
||||
) = (
|
||||
if let (Some((accept_power, accept_scalar)), Some((reject_power, reject_scalar))) = (
|
||||
// Get the components of both branches and calculate the type power
|
||||
self.expr_scalar_components(accept, accept_meta)?
|
||||
.and_then(|(kind, width)| Some((type_power(kind, width)?, width, kind))),
|
||||
.and_then(|scalar| Some((type_power(scalar)?, scalar))),
|
||||
self.expr_scalar_components(reject, reject_meta)?
|
||||
.and_then(|(kind, width)| Some((type_power(kind, width)?, width, kind))),
|
||||
.and_then(|scalar| Some((type_power(scalar)?, scalar))),
|
||||
) {
|
||||
match accept_power.cmp(&reject_power) {
|
||||
std::cmp::Ordering::Less => {
|
||||
accept_body = self.with_body(accept_body, |ctx| {
|
||||
ctx.conversion(
|
||||
&mut accept,
|
||||
accept_meta,
|
||||
reject_kind,
|
||||
reject_width,
|
||||
)?;
|
||||
ctx.conversion(&mut accept, accept_meta, reject_scalar)?;
|
||||
Ok(())
|
||||
})?;
|
||||
}
|
||||
std::cmp::Ordering::Equal => {}
|
||||
std::cmp::Ordering::Greater => {
|
||||
reject_body = self.with_body(reject_body, |ctx| {
|
||||
ctx.conversion(
|
||||
&mut reject,
|
||||
reject_meta,
|
||||
accept_kind,
|
||||
accept_width,
|
||||
)?;
|
||||
ctx.conversion(&mut reject, reject_meta, accept_scalar)?;
|
||||
Ok(())
|
||||
})?;
|
||||
}
|
||||
@ -1201,8 +1188,8 @@ impl<'a> Context<'a> {
|
||||
ref ty => ty,
|
||||
};
|
||||
|
||||
if let Some((kind, width)) = scalar_components(ty) {
|
||||
self.implicit_conversion(&mut value, value_meta, kind, width)?;
|
||||
if let Some(scalar) = scalar_components(ty) {
|
||||
self.implicit_conversion(&mut value, value_meta, scalar)?;
|
||||
}
|
||||
|
||||
self.lower_store(pointer, value, meta)?;
|
||||
@ -1218,13 +1205,13 @@ impl<'a> Context<'a> {
|
||||
};
|
||||
|
||||
let res = match *self.resolve_type(left, meta)? {
|
||||
TypeInner::Scalar { kind, width } => {
|
||||
let ty = TypeInner::Scalar { kind, width };
|
||||
Literal::one(kind, width).map(|i| (ty, i, None, None))
|
||||
TypeInner::Scalar(scalar) => {
|
||||
let ty = TypeInner::Scalar(scalar);
|
||||
Literal::one(scalar).map(|i| (ty, i, None, None))
|
||||
}
|
||||
TypeInner::Vector { size, kind, width } => {
|
||||
let ty = TypeInner::Vector { size, kind, width };
|
||||
Literal::one(kind, width).map(|i| (ty, i, Some(size), None))
|
||||
TypeInner::Vector { size, scalar } => {
|
||||
let ty = TypeInner::Vector { size, scalar };
|
||||
Literal::one(scalar).map(|i| (ty, i, Some(size), None))
|
||||
}
|
||||
TypeInner::Matrix {
|
||||
columns,
|
||||
@ -1236,8 +1223,11 @@ impl<'a> Context<'a> {
|
||||
rows,
|
||||
width,
|
||||
};
|
||||
Literal::one(ScalarKind::Float, width)
|
||||
.map(|i| (ty, i, Some(rows), Some(columns)))
|
||||
Literal::one(Scalar {
|
||||
kind: ScalarKind::Float,
|
||||
width,
|
||||
})
|
||||
.map(|i| (ty, i, Some(rows), Some(columns)))
|
||||
}
|
||||
_ => None,
|
||||
};
|
||||
@ -1323,19 +1313,14 @@ impl<'a> Context<'a> {
|
||||
Expression::Literal(Literal::U32(size.get())),
|
||||
meta,
|
||||
)?;
|
||||
self.forced_conversion(
|
||||
&mut array_length,
|
||||
meta,
|
||||
ScalarKind::Sint,
|
||||
4,
|
||||
)?;
|
||||
self.forced_conversion(&mut array_length, meta, Scalar::I32)?;
|
||||
array_length
|
||||
}
|
||||
// let the error be handled in type checking if it's not a dynamic array
|
||||
_ => {
|
||||
let mut array_length = self
|
||||
.add_expression(Expression::ArrayLength(lowered_array), meta)?;
|
||||
self.conversion(&mut array_length, meta, ScalarKind::Sint, 4)?;
|
||||
self.conversion(&mut array_length, meta, Scalar::I32)?;
|
||||
array_length
|
||||
}
|
||||
}
|
||||
@ -1376,7 +1361,7 @@ impl<'a> Context<'a> {
|
||||
&mut self,
|
||||
expr: Handle<Expression>,
|
||||
meta: Span,
|
||||
) -> Result<Option<(ScalarKind, crate::Bytes)>> {
|
||||
) -> Result<Option<Scalar>> {
|
||||
let ty = self.resolve_type(expr, meta)?;
|
||||
Ok(scalar_components(ty))
|
||||
}
|
||||
@ -1384,21 +1369,20 @@ impl<'a> Context<'a> {
|
||||
pub fn expr_power(&mut self, expr: Handle<Expression>, meta: Span) -> Result<Option<u32>> {
|
||||
Ok(self
|
||||
.expr_scalar_components(expr, meta)?
|
||||
.and_then(|(kind, width)| type_power(kind, width)))
|
||||
.and_then(type_power))
|
||||
}
|
||||
|
||||
pub fn conversion(
|
||||
&mut self,
|
||||
expr: &mut Handle<Expression>,
|
||||
meta: Span,
|
||||
kind: ScalarKind,
|
||||
width: crate::Bytes,
|
||||
scalar: Scalar,
|
||||
) -> Result<()> {
|
||||
*expr = self.add_expression(
|
||||
Expression::As {
|
||||
expr: *expr,
|
||||
kind,
|
||||
convert: Some(width),
|
||||
kind: scalar.kind,
|
||||
convert: Some(scalar.width),
|
||||
},
|
||||
meta,
|
||||
)?;
|
||||
@ -1410,14 +1394,13 @@ impl<'a> Context<'a> {
|
||||
&mut self,
|
||||
expr: &mut Handle<Expression>,
|
||||
meta: Span,
|
||||
kind: ScalarKind,
|
||||
width: crate::Bytes,
|
||||
scalar: Scalar,
|
||||
) -> Result<()> {
|
||||
if let (Some(tgt_power), Some(expr_power)) =
|
||||
(type_power(kind, width), self.expr_power(*expr, meta)?)
|
||||
(type_power(scalar), self.expr_power(*expr, meta)?)
|
||||
{
|
||||
if tgt_power > expr_power {
|
||||
self.conversion(expr, meta, kind, width)?;
|
||||
self.conversion(expr, meta, scalar)?;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1428,12 +1411,11 @@ impl<'a> Context<'a> {
|
||||
&mut self,
|
||||
expr: &mut Handle<Expression>,
|
||||
meta: Span,
|
||||
kind: ScalarKind,
|
||||
width: crate::Bytes,
|
||||
scalar: Scalar,
|
||||
) -> Result<()> {
|
||||
if let Some((expr_scalar_kind, expr_width)) = self.expr_scalar_components(*expr, meta)? {
|
||||
if expr_scalar_kind != kind || expr_width != width {
|
||||
self.conversion(expr, meta, kind, width)?;
|
||||
if let Some(expr_scalar) = self.expr_scalar_components(*expr, meta)? {
|
||||
if expr_scalar != scalar {
|
||||
self.conversion(expr, meta, scalar)?;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1450,21 +1432,17 @@ impl<'a> Context<'a> {
|
||||
let left_components = self.expr_scalar_components(*left, left_meta)?;
|
||||
let right_components = self.expr_scalar_components(*right, right_meta)?;
|
||||
|
||||
if let (
|
||||
Some((left_power, left_width, left_kind)),
|
||||
Some((right_power, right_width, right_kind)),
|
||||
) = (
|
||||
left_components.and_then(|(kind, width)| Some((type_power(kind, width)?, width, kind))),
|
||||
right_components
|
||||
.and_then(|(kind, width)| Some((type_power(kind, width)?, width, kind))),
|
||||
if let (Some((left_power, left_scalar)), Some((right_power, right_scalar))) = (
|
||||
left_components.and_then(|scalar| Some((type_power(scalar)?, scalar))),
|
||||
right_components.and_then(|scalar| Some((type_power(scalar)?, scalar))),
|
||||
) {
|
||||
match left_power.cmp(&right_power) {
|
||||
std::cmp::Ordering::Less => {
|
||||
self.conversion(left, left_meta, right_kind, right_width)?;
|
||||
self.conversion(left, left_meta, right_scalar)?;
|
||||
}
|
||||
std::cmp::Ordering::Equal => {}
|
||||
std::cmp::Ordering::Greater => {
|
||||
self.conversion(right, right_meta, left_kind, left_width)?;
|
||||
self.conversion(right, right_meta, left_scalar)?;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
186
third_party/rust/naga/src/front/glsl/functions.rs
vendored
186
third_party/rust/naga/src/front/glsl/functions.rs
vendored
@ -8,7 +8,7 @@ use super::{
|
||||
};
|
||||
use crate::{
|
||||
front::glsl::types::type_power, proc::ensure_block_returns, AddressSpace, Block, EntryPoint,
|
||||
Expression, Function, FunctionArgument, FunctionResult, Handle, Literal, LocalVariable,
|
||||
Expression, Function, FunctionArgument, FunctionResult, Handle, Literal, LocalVariable, Scalar,
|
||||
ScalarKind, Span, Statement, StructMember, Type, TypeInner,
|
||||
};
|
||||
use std::iter;
|
||||
@ -20,7 +20,7 @@ struct ProxyWrite {
|
||||
/// A pointer to read the value of the store
|
||||
value: Handle<Expression>,
|
||||
/// An optional conversion to be applied
|
||||
convert: Option<(ScalarKind, crate::Bytes)>,
|
||||
convert: Option<Scalar>,
|
||||
}
|
||||
|
||||
impl Frontend {
|
||||
@ -68,10 +68,14 @@ impl Frontend {
|
||||
let expr_is_bool = expr_type.scalar_kind() == Some(ScalarKind::Bool);
|
||||
|
||||
// Special case: if casting from a bool, we need to use Select and not As.
|
||||
match ctx.module.types[ty].inner.scalar_kind() {
|
||||
Some(result_scalar_kind) if expr_is_bool && result_scalar_kind != ScalarKind::Bool => {
|
||||
let l0 = Literal::zero(result_scalar_kind, 4).unwrap();
|
||||
let l1 = Literal::one(result_scalar_kind, 4).unwrap();
|
||||
match ctx.module.types[ty].inner.scalar() {
|
||||
Some(result_scalar) if expr_is_bool && result_scalar.kind != ScalarKind::Bool => {
|
||||
let result_scalar = Scalar {
|
||||
width: 4,
|
||||
..result_scalar
|
||||
};
|
||||
let l0 = Literal::zero(result_scalar).unwrap();
|
||||
let l1 = Literal::one(result_scalar).unwrap();
|
||||
let mut reject = ctx.add_expression(Expression::Literal(l0), expr_meta)?;
|
||||
let mut accept = ctx.add_expression(Expression::Literal(l1), expr_meta)?;
|
||||
|
||||
@ -93,24 +97,16 @@ impl Frontend {
|
||||
}
|
||||
|
||||
Ok(match ctx.module.types[ty].inner {
|
||||
TypeInner::Vector { size, kind, width } if vector_size.is_none() => {
|
||||
ctx.forced_conversion(&mut value, expr_meta, kind, width)?;
|
||||
TypeInner::Vector { size, scalar } if vector_size.is_none() => {
|
||||
ctx.forced_conversion(&mut value, expr_meta, scalar)?;
|
||||
|
||||
if let TypeInner::Scalar { .. } = *ctx.resolve_type(value, expr_meta)? {
|
||||
ctx.add_expression(Expression::Splat { size, value }, meta)?
|
||||
} else {
|
||||
self.vector_constructor(
|
||||
ctx,
|
||||
ty,
|
||||
size,
|
||||
kind,
|
||||
width,
|
||||
&[(value, expr_meta)],
|
||||
meta,
|
||||
)?
|
||||
self.vector_constructor(ctx, ty, size, scalar, &[(value, expr_meta)], meta)?
|
||||
}
|
||||
}
|
||||
TypeInner::Scalar { kind, width } => {
|
||||
TypeInner::Scalar(scalar) => {
|
||||
let mut expr = value;
|
||||
if let TypeInner::Vector { .. } | TypeInner::Matrix { .. } =
|
||||
*ctx.resolve_type(value, expr_meta)?
|
||||
@ -136,23 +132,23 @@ impl Frontend {
|
||||
|
||||
ctx.add_expression(
|
||||
Expression::As {
|
||||
kind,
|
||||
kind: scalar.kind,
|
||||
expr,
|
||||
convert: Some(width),
|
||||
convert: Some(scalar.width),
|
||||
},
|
||||
meta,
|
||||
)?
|
||||
}
|
||||
TypeInner::Vector { size, kind, width } => {
|
||||
TypeInner::Vector { size, scalar } => {
|
||||
if vector_size.map_or(true, |s| s != size) {
|
||||
value = ctx.vector_resize(size, value, expr_meta)?;
|
||||
}
|
||||
|
||||
ctx.add_expression(
|
||||
Expression::As {
|
||||
kind,
|
||||
kind: scalar.kind,
|
||||
expr: value,
|
||||
convert: Some(width),
|
||||
convert: Some(scalar.width),
|
||||
},
|
||||
meta,
|
||||
)?
|
||||
@ -166,8 +162,8 @@ impl Frontend {
|
||||
let scalar_components = members
|
||||
.get(0)
|
||||
.and_then(|member| scalar_components(&ctx.module.types[member.ty].inner));
|
||||
if let Some((kind, width)) = scalar_components {
|
||||
ctx.implicit_conversion(&mut value, expr_meta, kind, width)?;
|
||||
if let Some(scalar) = scalar_components {
|
||||
ctx.implicit_conversion(&mut value, expr_meta, scalar)?;
|
||||
}
|
||||
|
||||
ctx.add_expression(
|
||||
@ -181,8 +177,8 @@ impl Frontend {
|
||||
|
||||
TypeInner::Array { base, .. } => {
|
||||
let scalar_components = scalar_components(&ctx.module.types[base].inner);
|
||||
if let Some((kind, width)) = scalar_components {
|
||||
ctx.implicit_conversion(&mut value, expr_meta, kind, width)?;
|
||||
if let Some(scalar) = scalar_components {
|
||||
ctx.implicit_conversion(&mut value, expr_meta, scalar)?;
|
||||
}
|
||||
|
||||
ctx.add_expression(
|
||||
@ -220,9 +216,13 @@ impl Frontend {
|
||||
// `Expression::As` doesn't support matrix width
|
||||
// casts so we need to do some extra work for casts
|
||||
|
||||
ctx.forced_conversion(&mut value, expr_meta, ScalarKind::Float, width)?;
|
||||
let element_scalar = Scalar {
|
||||
kind: ScalarKind::Float,
|
||||
width,
|
||||
};
|
||||
ctx.forced_conversion(&mut value, expr_meta, element_scalar)?;
|
||||
match *ctx.resolve_type(value, expr_meta)? {
|
||||
TypeInner::Scalar { .. } => {
|
||||
TypeInner::Scalar(_) => {
|
||||
// If a matrix is constructed with a single scalar value, then that
|
||||
// value is used to initialize all the values along the diagonal of
|
||||
// the matrix; the rest are given zeros.
|
||||
@ -231,14 +231,13 @@ impl Frontend {
|
||||
name: None,
|
||||
inner: TypeInner::Vector {
|
||||
size: rows,
|
||||
kind: ScalarKind::Float,
|
||||
width,
|
||||
scalar: element_scalar,
|
||||
},
|
||||
},
|
||||
meta,
|
||||
);
|
||||
|
||||
let zero_literal = Literal::zero(ScalarKind::Float, width).unwrap();
|
||||
let zero_literal = Literal::zero(element_scalar).unwrap();
|
||||
let zero = ctx.add_expression(Expression::Literal(zero_literal), meta)?;
|
||||
|
||||
for i in 0..columns as u32 {
|
||||
@ -268,8 +267,8 @@ impl Frontend {
|
||||
// (column i, row j) in the argument will be initialized from there. All
|
||||
// other components will be initialized to the identity matrix.
|
||||
|
||||
let zero_literal = Literal::zero(ScalarKind::Float, width).unwrap();
|
||||
let one_literal = Literal::one(ScalarKind::Float, width).unwrap();
|
||||
let zero_literal = Literal::zero(element_scalar).unwrap();
|
||||
let one_literal = Literal::one(element_scalar).unwrap();
|
||||
|
||||
let zero = ctx.add_expression(Expression::Literal(zero_literal), meta)?;
|
||||
let one = ctx.add_expression(Expression::Literal(one_literal), meta)?;
|
||||
@ -279,8 +278,7 @@ impl Frontend {
|
||||
name: None,
|
||||
inner: TypeInner::Vector {
|
||||
size: rows,
|
||||
kind: ScalarKind::Float,
|
||||
width,
|
||||
scalar: element_scalar,
|
||||
},
|
||||
},
|
||||
meta,
|
||||
@ -360,15 +358,14 @@ impl Frontend {
|
||||
ctx: &mut Context,
|
||||
ty: Handle<Type>,
|
||||
size: crate::VectorSize,
|
||||
kind: ScalarKind,
|
||||
width: crate::Bytes,
|
||||
scalar: Scalar,
|
||||
args: &[(Handle<Expression>, Span)],
|
||||
meta: Span,
|
||||
) -> Result<Handle<Expression>> {
|
||||
let mut components = Vec::with_capacity(size as usize);
|
||||
|
||||
for (mut arg, expr_meta) in args.iter().copied() {
|
||||
ctx.forced_conversion(&mut arg, expr_meta, kind, width)?;
|
||||
ctx.forced_conversion(&mut arg, expr_meta, scalar)?;
|
||||
|
||||
if components.len() >= size as usize {
|
||||
break;
|
||||
@ -429,8 +426,12 @@ impl Frontend {
|
||||
} => {
|
||||
let mut flattened = Vec::with_capacity(columns as usize * rows as usize);
|
||||
|
||||
let element_scalar = Scalar {
|
||||
kind: ScalarKind::Float,
|
||||
width,
|
||||
};
|
||||
for (mut arg, meta) in args.iter().copied() {
|
||||
ctx.forced_conversion(&mut arg, meta, ScalarKind::Float, width)?;
|
||||
ctx.forced_conversion(&mut arg, meta, element_scalar)?;
|
||||
|
||||
match *ctx.resolve_type(arg, meta)? {
|
||||
TypeInner::Vector { size, .. } => {
|
||||
@ -453,8 +454,7 @@ impl Frontend {
|
||||
name: None,
|
||||
inner: TypeInner::Vector {
|
||||
size: rows,
|
||||
kind: ScalarKind::Float,
|
||||
width,
|
||||
scalar: element_scalar,
|
||||
},
|
||||
},
|
||||
meta,
|
||||
@ -471,14 +471,14 @@ impl Frontend {
|
||||
}
|
||||
None
|
||||
}
|
||||
TypeInner::Vector { size, kind, width } => {
|
||||
return self.vector_constructor(ctx, ty, size, kind, width, &args, meta)
|
||||
TypeInner::Vector { size, scalar } => {
|
||||
return self.vector_constructor(ctx, ty, size, scalar, &args, meta)
|
||||
}
|
||||
TypeInner::Array { base, .. } => {
|
||||
for (mut arg, meta) in args.iter().copied() {
|
||||
let scalar_components = scalar_components(&ctx.module.types[base].inner);
|
||||
if let Some((kind, width)) = scalar_components {
|
||||
ctx.implicit_conversion(&mut arg, meta, kind, width)?;
|
||||
if let Some(scalar) = scalar_components {
|
||||
ctx.implicit_conversion(&mut arg, meta, scalar)?;
|
||||
}
|
||||
|
||||
components.push(arg)
|
||||
@ -503,8 +503,8 @@ impl Frontend {
|
||||
for ((mut arg, meta), scalar_components) in
|
||||
args.iter().copied().zip(struct_member_data.iter().copied())
|
||||
{
|
||||
if let Some((kind, width)) = scalar_components {
|
||||
ctx.implicit_conversion(&mut arg, meta, kind, width)?;
|
||||
if let Some(scalar) = scalar_components {
|
||||
ctx.implicit_conversion(&mut arg, meta, scalar)?;
|
||||
}
|
||||
|
||||
components.push(arg)
|
||||
@ -813,8 +813,8 @@ impl Frontend {
|
||||
let scalar_comps = scalar_components(&ctx.module.types[*parameter].inner);
|
||||
|
||||
// Apply implicit conversions as needed
|
||||
if let Some((kind, width)) = scalar_comps {
|
||||
ctx.implicit_conversion(&mut handle, meta, kind, width)?;
|
||||
if let Some(scalar) = scalar_comps {
|
||||
ctx.implicit_conversion(&mut handle, meta, scalar)?;
|
||||
}
|
||||
|
||||
arguments.push(handle)
|
||||
@ -850,8 +850,8 @@ impl Frontend {
|
||||
meta,
|
||||
)?;
|
||||
|
||||
if let Some((kind, width)) = proxy_write.convert {
|
||||
ctx.conversion(&mut value, meta, kind, width)?;
|
||||
if let Some(scalar) = proxy_write.convert {
|
||||
ctx.conversion(&mut value, meta, scalar)?;
|
||||
}
|
||||
|
||||
ctx.emit_restart();
|
||||
@ -893,10 +893,10 @@ impl Frontend {
|
||||
// If the argument is to be passed as a pointer but the type of the
|
||||
// expression returns a vector it must mean that it was for example
|
||||
// swizzled and it must be spilled into a local before calling
|
||||
TypeInner::Vector { size, kind, width } => Some(ctx.module.types.insert(
|
||||
TypeInner::Vector { size, scalar } => Some(ctx.module.types.insert(
|
||||
Type {
|
||||
name: None,
|
||||
inner: TypeInner::Vector { size, kind, width },
|
||||
inner: TypeInner::Vector { size, scalar },
|
||||
},
|
||||
Span::default(),
|
||||
)),
|
||||
@ -906,13 +906,12 @@ impl Frontend {
|
||||
TypeInner::Pointer { base, space } if space != AddressSpace::Function => Some(base),
|
||||
TypeInner::ValuePointer {
|
||||
size,
|
||||
kind,
|
||||
width,
|
||||
scalar,
|
||||
space,
|
||||
} if space != AddressSpace::Function => {
|
||||
let inner = match size {
|
||||
Some(size) => TypeInner::Vector { size, kind, width },
|
||||
None => TypeInner::Scalar { kind, width },
|
||||
Some(size) => TypeInner::Vector { size, scalar },
|
||||
None => TypeInner::Scalar(scalar),
|
||||
};
|
||||
|
||||
Some(
|
||||
@ -1512,31 +1511,22 @@ fn conversion(target: &TypeInner, source: &TypeInner) -> Option<Conversion> {
|
||||
use ScalarKind::*;
|
||||
|
||||
// Gather the `ScalarKind` and scalar width from both the target and the source
|
||||
let (target_kind, target_width, source_kind, source_width) = match (target, source) {
|
||||
let (target_scalar, source_scalar) = match (target, source) {
|
||||
// Conversions between scalars are allowed
|
||||
(
|
||||
&TypeInner::Scalar {
|
||||
kind: tgt_kind,
|
||||
width: tgt_width,
|
||||
},
|
||||
&TypeInner::Scalar {
|
||||
kind: src_kind,
|
||||
width: src_width,
|
||||
},
|
||||
) => (tgt_kind, tgt_width, src_kind, src_width),
|
||||
(&TypeInner::Scalar(tgt_scalar), &TypeInner::Scalar(src_scalar)) => {
|
||||
(tgt_scalar, src_scalar)
|
||||
}
|
||||
// Conversions between vectors of the same size are allowed
|
||||
(
|
||||
&TypeInner::Vector {
|
||||
kind: tgt_kind,
|
||||
size: tgt_size,
|
||||
width: tgt_width,
|
||||
scalar: tgt_scalar,
|
||||
},
|
||||
&TypeInner::Vector {
|
||||
kind: src_kind,
|
||||
size: src_size,
|
||||
width: src_width,
|
||||
scalar: src_scalar,
|
||||
},
|
||||
) if tgt_size == src_size => (tgt_kind, tgt_width, src_kind, src_width),
|
||||
) if tgt_size == src_size => (tgt_scalar, src_scalar),
|
||||
// Conversions between matrices of the same size are allowed
|
||||
(
|
||||
&TypeInner::Matrix {
|
||||
@ -1549,29 +1539,41 @@ fn conversion(target: &TypeInner, source: &TypeInner) -> Option<Conversion> {
|
||||
columns: src_cols,
|
||||
width: src_width,
|
||||
},
|
||||
) if tgt_cols == src_cols && tgt_rows == src_rows => (Float, tgt_width, Float, src_width),
|
||||
) if tgt_cols == src_cols && tgt_rows == src_rows => {
|
||||
(Scalar::float(tgt_width), Scalar::float(src_width))
|
||||
}
|
||||
_ => return None,
|
||||
};
|
||||
|
||||
// Check if source can be converted into target, if this is the case then the type
|
||||
// power of target must be higher than that of source
|
||||
let target_power = type_power(target_kind, target_width);
|
||||
let source_power = type_power(source_kind, source_width);
|
||||
let target_power = type_power(target_scalar);
|
||||
let source_power = type_power(source_scalar);
|
||||
if target_power < source_power {
|
||||
return None;
|
||||
}
|
||||
|
||||
Some(
|
||||
match ((target_kind, target_width), (source_kind, source_width)) {
|
||||
// A conversion from a float to a double is special
|
||||
((Float, 8), (Float, 4)) => Conversion::FloatToDouble,
|
||||
// A conversion from an integer to a float is special
|
||||
((Float, 4), (Sint | Uint, _)) => Conversion::IntToFloat,
|
||||
// A conversion from an integer to a double is special
|
||||
((Float, 8), (Sint | Uint, _)) => Conversion::IntToDouble,
|
||||
_ => Conversion::Other,
|
||||
},
|
||||
)
|
||||
Some(match (target_scalar, source_scalar) {
|
||||
// A conversion from a float to a double is special
|
||||
(Scalar::F64, Scalar::F32) => Conversion::FloatToDouble,
|
||||
// A conversion from an integer to a float is special
|
||||
(
|
||||
Scalar::F32,
|
||||
Scalar {
|
||||
kind: Sint | Uint,
|
||||
width: _,
|
||||
},
|
||||
) => Conversion::IntToFloat,
|
||||
// A conversion from an integer to a double is special
|
||||
(
|
||||
Scalar::F64,
|
||||
Scalar {
|
||||
kind: Sint | Uint,
|
||||
width: _,
|
||||
},
|
||||
) => Conversion::IntToDouble,
|
||||
_ => Conversion::Other,
|
||||
})
|
||||
}
|
||||
|
||||
/// Helper method returning all the non standard builtin variations needed
|
||||
@ -1581,10 +1583,10 @@ fn builtin_required_variations<'a>(args: impl Iterator<Item = &'a TypeInner>) ->
|
||||
|
||||
for ty in args {
|
||||
match *ty {
|
||||
TypeInner::ValuePointer { kind, width, .. }
|
||||
| TypeInner::Scalar { kind, width }
|
||||
| TypeInner::Vector { kind, width, .. } => {
|
||||
if kind == ScalarKind::Float && width == 8 {
|
||||
TypeInner::ValuePointer { scalar, .. }
|
||||
| TypeInner::Scalar(scalar)
|
||||
| TypeInner::Vector { scalar, .. } => {
|
||||
if scalar == Scalar::F64 {
|
||||
variations |= BuiltinVariations::DOUBLE
|
||||
}
|
||||
}
|
||||
|
@ -16,7 +16,7 @@ use super::{
|
||||
error::{Error, ErrorKind},
|
||||
Span,
|
||||
};
|
||||
use crate::{proc::Alignment, Handle, Type, TypeInner, UniqueArena};
|
||||
use crate::{proc::Alignment, Handle, Scalar, Type, TypeInner, UniqueArena};
|
||||
|
||||
/// Struct with information needed for defining a struct member.
|
||||
///
|
||||
@ -53,12 +53,15 @@ pub fn calculate_offset(
|
||||
let (align, span) = match types[ty].inner {
|
||||
// 1. If the member is a scalar consuming N basic machine units,
|
||||
// the base alignment is N.
|
||||
TypeInner::Scalar { width, .. } => (Alignment::from_width(width), width as u32),
|
||||
TypeInner::Scalar(Scalar { width, .. }) => (Alignment::from_width(width), width as u32),
|
||||
// 2. If the member is a two- or four-component vector with components
|
||||
// consuming N basic machine units, the base alignment is 2N or 4N, respectively.
|
||||
// 3. If the member is a three-component vector with components consuming N
|
||||
// basic machine units, the base alignment is 4N.
|
||||
TypeInner::Vector { size, width, .. } => (
|
||||
TypeInner::Vector {
|
||||
size,
|
||||
scalar: Scalar { width, .. },
|
||||
} => (
|
||||
Alignment::from(size) * Alignment::from_width(width),
|
||||
size as u32 * width as u32,
|
||||
),
|
||||
|
@ -13,8 +13,8 @@ use crate::{
|
||||
Error, ErrorKind, Frontend, Span,
|
||||
},
|
||||
proc::Alignment,
|
||||
AddressSpace, Expression, FunctionResult, Handle, ScalarKind, Statement, StructMember, Type,
|
||||
TypeInner,
|
||||
AddressSpace, Expression, FunctionResult, Handle, Scalar, ScalarKind, Statement, StructMember,
|
||||
Type, TypeInner,
|
||||
};
|
||||
|
||||
use super::{DeclarationContext, ParsingContext, Result};
|
||||
@ -34,10 +34,10 @@ fn element_or_member_type(
|
||||
) -> Handle<Type> {
|
||||
match types[ty].inner {
|
||||
// The child type of a vector is a scalar of the same kind and width
|
||||
TypeInner::Vector { kind, width, .. } => types.insert(
|
||||
TypeInner::Vector { scalar, .. } => types.insert(
|
||||
Type {
|
||||
name: None,
|
||||
inner: TypeInner::Scalar { kind, width },
|
||||
inner: TypeInner::Scalar(scalar),
|
||||
},
|
||||
Default::default(),
|
||||
),
|
||||
@ -48,8 +48,7 @@ fn element_or_member_type(
|
||||
name: None,
|
||||
inner: TypeInner::Vector {
|
||||
size: rows,
|
||||
kind: ScalarKind::Float,
|
||||
width,
|
||||
scalar: Scalar::float(width),
|
||||
},
|
||||
},
|
||||
Default::default(),
|
||||
@ -156,8 +155,8 @@ impl<'source> ParsingContext<'source> {
|
||||
let (mut init, init_meta) = ctx.lower_expect(stmt, frontend, expr, ExprPos::Rhs)?;
|
||||
|
||||
let scalar_components = scalar_components(&ctx.module.types[ty].inner);
|
||||
if let Some((kind, width)) = scalar_components {
|
||||
ctx.implicit_conversion(&mut init, init_meta, kind, width)?;
|
||||
if let Some(scalar) = scalar_components {
|
||||
ctx.implicit_conversion(&mut init, init_meta, scalar)?;
|
||||
}
|
||||
|
||||
Ok((init, init_meta))
|
||||
@ -233,9 +232,8 @@ impl<'source> ParsingContext<'source> {
|
||||
let (mut expr, init_meta) = self.parse_initializer(frontend, ty, ctx.ctx)?;
|
||||
|
||||
let scalar_components = scalar_components(&ctx.ctx.module.types[ty].inner);
|
||||
if let Some((kind, width)) = scalar_components {
|
||||
ctx.ctx
|
||||
.implicit_conversion(&mut expr, init_meta, kind, width)?;
|
||||
if let Some(scalar) = scalar_components {
|
||||
ctx.ctx.implicit_conversion(&mut expr, init_meta, scalar)?;
|
||||
}
|
||||
|
||||
ctx.ctx.is_const = prev_const;
|
||||
@ -509,10 +507,10 @@ impl<'source> ParsingContext<'source> {
|
||||
let (ty, meta) = self.parse_type_non_void(frontend, ctx)?;
|
||||
|
||||
match ctx.module.types[ty].inner {
|
||||
TypeInner::Scalar {
|
||||
TypeInner::Scalar(Scalar {
|
||||
kind: ScalarKind::Float | ScalarKind::Sint,
|
||||
..
|
||||
} => {}
|
||||
}) => {}
|
||||
_ => frontend.errors.push(Error {
|
||||
kind: ErrorKind::SemanticError(
|
||||
"Precision statement can only work on floats and ints".into(),
|
||||
|
@ -509,7 +509,7 @@ fn functions() {
|
||||
|
||||
#[test]
|
||||
fn constants() {
|
||||
use crate::{Constant, Expression, ScalarKind, Type, TypeInner};
|
||||
use crate::{Constant, Expression, Type, TypeInner};
|
||||
|
||||
let mut frontend = Frontend::default();
|
||||
|
||||
@ -536,10 +536,7 @@ fn constants() {
|
||||
ty,
|
||||
&Type {
|
||||
name: None,
|
||||
inner: TypeInner::Scalar {
|
||||
kind: ScalarKind::Float,
|
||||
width: 4
|
||||
}
|
||||
inner: TypeInner::Scalar(crate::Scalar::F32)
|
||||
}
|
||||
);
|
||||
|
||||
|
61
third_party/rust/naga/src/front/glsl/types.rs
vendored
61
third_party/rust/naga/src/front/glsl/types.rs
vendored
@ -1,6 +1,6 @@
|
||||
use super::{context::Context, Error, ErrorKind, Result, Span};
|
||||
use crate::{
|
||||
proc::ResolveContext, Bytes, Expression, Handle, ImageClass, ImageDimension, ScalarKind, Type,
|
||||
proc::ResolveContext, Expression, Handle, ImageClass, ImageDimension, Scalar, ScalarKind, Type,
|
||||
TypeInner, VectorSize,
|
||||
};
|
||||
|
||||
@ -8,38 +8,23 @@ pub fn parse_type(type_name: &str) -> Option<Type> {
|
||||
match type_name {
|
||||
"bool" => Some(Type {
|
||||
name: None,
|
||||
inner: TypeInner::Scalar {
|
||||
kind: ScalarKind::Bool,
|
||||
width: crate::BOOL_WIDTH,
|
||||
},
|
||||
inner: TypeInner::Scalar(Scalar::BOOL),
|
||||
}),
|
||||
"float" => Some(Type {
|
||||
name: None,
|
||||
inner: TypeInner::Scalar {
|
||||
kind: ScalarKind::Float,
|
||||
width: 4,
|
||||
},
|
||||
inner: TypeInner::Scalar(Scalar::F32),
|
||||
}),
|
||||
"double" => Some(Type {
|
||||
name: None,
|
||||
inner: TypeInner::Scalar {
|
||||
kind: ScalarKind::Float,
|
||||
width: 8,
|
||||
},
|
||||
inner: TypeInner::Scalar(Scalar::F64),
|
||||
}),
|
||||
"int" => Some(Type {
|
||||
name: None,
|
||||
inner: TypeInner::Scalar {
|
||||
kind: ScalarKind::Sint,
|
||||
width: 4,
|
||||
},
|
||||
inner: TypeInner::Scalar(Scalar::I32),
|
||||
}),
|
||||
"uint" => Some(Type {
|
||||
name: None,
|
||||
inner: TypeInner::Scalar {
|
||||
kind: ScalarKind::Uint,
|
||||
width: 4,
|
||||
},
|
||||
inner: TypeInner::Scalar(Scalar::U32),
|
||||
}),
|
||||
"sampler" | "samplerShadow" => Some(Type {
|
||||
name: None,
|
||||
@ -48,13 +33,13 @@ pub fn parse_type(type_name: &str) -> Option<Type> {
|
||||
},
|
||||
}),
|
||||
word => {
|
||||
fn kind_width_parse(ty: &str) -> Option<(ScalarKind, u8)> {
|
||||
fn kind_width_parse(ty: &str) -> Option<Scalar> {
|
||||
Some(match ty {
|
||||
"" => (ScalarKind::Float, 4),
|
||||
"b" => (ScalarKind::Bool, crate::BOOL_WIDTH),
|
||||
"i" => (ScalarKind::Sint, 4),
|
||||
"u" => (ScalarKind::Uint, 4),
|
||||
"d" => (ScalarKind::Float, 8),
|
||||
"" => Scalar::F32,
|
||||
"b" => Scalar::BOOL,
|
||||
"i" => Scalar::I32,
|
||||
"u" => Scalar::U32,
|
||||
"d" => Scalar::F64,
|
||||
_ => return None,
|
||||
})
|
||||
}
|
||||
@ -73,12 +58,12 @@ pub fn parse_type(type_name: &str) -> Option<Type> {
|
||||
|
||||
let kind = iter.next()?;
|
||||
let size = iter.next()?;
|
||||
let (kind, width) = kind_width_parse(kind)?;
|
||||
let scalar = kind_width_parse(kind)?;
|
||||
let size = size_parse(size)?;
|
||||
|
||||
Some(Type {
|
||||
name: None,
|
||||
inner: TypeInner::Vector { size, kind, width },
|
||||
inner: TypeInner::Vector { size, scalar },
|
||||
})
|
||||
};
|
||||
|
||||
@ -87,7 +72,7 @@ pub fn parse_type(type_name: &str) -> Option<Type> {
|
||||
|
||||
let kind = iter.next()?;
|
||||
let size = iter.next()?;
|
||||
let (_, width) = kind_width_parse(kind)?;
|
||||
let Scalar { width, .. } = kind_width_parse(kind)?;
|
||||
|
||||
let (columns, rows) = if let Some(size) = size_parse(size) {
|
||||
(size, size)
|
||||
@ -204,21 +189,21 @@ pub fn parse_type(type_name: &str) -> Option<Type> {
|
||||
}
|
||||
}
|
||||
|
||||
pub const fn scalar_components(ty: &TypeInner) -> Option<(ScalarKind, Bytes)> {
|
||||
pub const fn scalar_components(ty: &TypeInner) -> Option<Scalar> {
|
||||
match *ty {
|
||||
TypeInner::Scalar { kind, width } => Some((kind, width)),
|
||||
TypeInner::Vector { kind, width, .. } => Some((kind, width)),
|
||||
TypeInner::Matrix { width, .. } => Some((ScalarKind::Float, width)),
|
||||
TypeInner::ValuePointer { kind, width, .. } => Some((kind, width)),
|
||||
TypeInner::Scalar(scalar)
|
||||
| TypeInner::Vector { scalar, .. }
|
||||
| TypeInner::ValuePointer { scalar, .. } => Some(scalar),
|
||||
TypeInner::Matrix { width, .. } => Some(Scalar::float(width)),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
pub const fn type_power(kind: ScalarKind, width: Bytes) -> Option<u32> {
|
||||
Some(match kind {
|
||||
pub const fn type_power(scalar: Scalar) -> Option<u32> {
|
||||
Some(match scalar.kind {
|
||||
ScalarKind::Sint => 0,
|
||||
ScalarKind::Uint => 1,
|
||||
ScalarKind::Float if width == 4 => 2,
|
||||
ScalarKind::Float if scalar.width == 4 => 2,
|
||||
ScalarKind::Float => 3,
|
||||
ScalarKind::Bool => return None,
|
||||
})
|
||||
|
@ -6,8 +6,8 @@ use super::{
|
||||
};
|
||||
use crate::{
|
||||
AddressSpace, Binding, BuiltIn, Constant, Expression, GlobalVariable, Handle, Interpolation,
|
||||
LocalVariable, ResourceBinding, ScalarKind, ShaderStage, SwizzleComponent, Type, TypeInner,
|
||||
VectorSize,
|
||||
LocalVariable, ResourceBinding, Scalar, ScalarKind, ShaderStage, SwizzleComponent, Type,
|
||||
TypeInner, VectorSize,
|
||||
};
|
||||
|
||||
pub struct VarDeclaration<'a, 'key> {
|
||||
@ -109,8 +109,7 @@ impl Frontend {
|
||||
"gl_Position" => BuiltInData {
|
||||
inner: TypeInner::Vector {
|
||||
size: VectorSize::Quad,
|
||||
kind: ScalarKind::Float,
|
||||
width: 4,
|
||||
scalar: Scalar::F32,
|
||||
},
|
||||
builtin: BuiltIn::Position { invariant: false },
|
||||
mutable: true,
|
||||
@ -119,8 +118,7 @@ impl Frontend {
|
||||
"gl_FragCoord" => BuiltInData {
|
||||
inner: TypeInner::Vector {
|
||||
size: VectorSize::Quad,
|
||||
kind: ScalarKind::Float,
|
||||
width: 4,
|
||||
scalar: Scalar::F32,
|
||||
},
|
||||
builtin: BuiltIn::Position { invariant: false },
|
||||
mutable: false,
|
||||
@ -129,8 +127,7 @@ impl Frontend {
|
||||
"gl_PointCoord" => BuiltInData {
|
||||
inner: TypeInner::Vector {
|
||||
size: VectorSize::Bi,
|
||||
kind: ScalarKind::Float,
|
||||
width: 4,
|
||||
scalar: Scalar::F32,
|
||||
},
|
||||
builtin: BuiltIn::PointCoord,
|
||||
mutable: false,
|
||||
@ -143,8 +140,7 @@ impl Frontend {
|
||||
| "gl_LocalInvocationID" => BuiltInData {
|
||||
inner: TypeInner::Vector {
|
||||
size: VectorSize::Tri,
|
||||
kind: ScalarKind::Uint,
|
||||
width: 4,
|
||||
scalar: Scalar::U32,
|
||||
},
|
||||
builtin: match name {
|
||||
"gl_GlobalInvocationID" => BuiltIn::GlobalInvocationId,
|
||||
@ -158,19 +154,13 @@ impl Frontend {
|
||||
storage: StorageQualifier::Input,
|
||||
},
|
||||
"gl_FrontFacing" => BuiltInData {
|
||||
inner: TypeInner::Scalar {
|
||||
kind: ScalarKind::Bool,
|
||||
width: crate::BOOL_WIDTH,
|
||||
},
|
||||
inner: TypeInner::Scalar(Scalar::BOOL),
|
||||
builtin: BuiltIn::FrontFacing,
|
||||
mutable: false,
|
||||
storage: StorageQualifier::Input,
|
||||
},
|
||||
"gl_PointSize" | "gl_FragDepth" => BuiltInData {
|
||||
inner: TypeInner::Scalar {
|
||||
kind: ScalarKind::Float,
|
||||
width: 4,
|
||||
},
|
||||
inner: TypeInner::Scalar(Scalar::F32),
|
||||
builtin: match name {
|
||||
"gl_PointSize" => BuiltIn::PointSize,
|
||||
"gl_FragDepth" => BuiltIn::FragDepth,
|
||||
@ -183,10 +173,7 @@ impl Frontend {
|
||||
let base = ctx.module.types.insert(
|
||||
Type {
|
||||
name: None,
|
||||
inner: TypeInner::Scalar {
|
||||
kind: ScalarKind::Float,
|
||||
width: 4,
|
||||
},
|
||||
inner: TypeInner::Scalar(Scalar::F32),
|
||||
},
|
||||
meta,
|
||||
);
|
||||
@ -219,10 +206,7 @@ impl Frontend {
|
||||
};
|
||||
|
||||
BuiltInData {
|
||||
inner: TypeInner::Scalar {
|
||||
kind: ScalarKind::Uint,
|
||||
width: 4,
|
||||
},
|
||||
inner: TypeInner::Scalar(Scalar::U32),
|
||||
builtin,
|
||||
mutable: false,
|
||||
storage: StorageQualifier::Input,
|
||||
|
15
third_party/rust/naga/src/front/spv/image.rs
vendored
15
third_party/rust/naga/src/front/spv/image.rs
vendored
@ -1,4 +1,7 @@
|
||||
use crate::arena::{Handle, UniqueArena};
|
||||
use crate::{
|
||||
arena::{Handle, UniqueArena},
|
||||
Scalar,
|
||||
};
|
||||
|
||||
use super::{Error, LookupExpression, LookupHelper as _};
|
||||
|
||||
@ -61,8 +64,11 @@ fn extract_image_coordinates(
|
||||
ctx: &mut super::BlockContext,
|
||||
) -> (Handle<crate::Expression>, Option<Handle<crate::Expression>>) {
|
||||
let (given_size, kind) = match ctx.type_arena[coordinate_ty].inner {
|
||||
crate::TypeInner::Scalar { kind, .. } => (None, kind),
|
||||
crate::TypeInner::Vector { size, kind, .. } => (Some(size), kind),
|
||||
crate::TypeInner::Scalar(Scalar { kind, .. }) => (None, kind),
|
||||
crate::TypeInner::Vector {
|
||||
size,
|
||||
scalar: Scalar { kind, .. },
|
||||
} => (Some(size), kind),
|
||||
ref other => unreachable!("Unexpected texture coordinate {:?}", other),
|
||||
};
|
||||
|
||||
@ -73,8 +79,7 @@ fn extract_image_coordinates(
|
||||
name: None,
|
||||
inner: crate::TypeInner::Vector {
|
||||
size,
|
||||
kind,
|
||||
width: 4,
|
||||
scalar: Scalar { kind, width: 4 },
|
||||
},
|
||||
})
|
||||
.expect("Required coordinate type should have been set up by `parse_type_image`!")
|
||||
|
76
third_party/rust/naga/src/front/spv/mod.rs
vendored
76
third_party/rust/naga/src/front/spv/mod.rs
vendored
@ -2829,22 +2829,22 @@ impl<I: Iterator<Item = u32>> Frontend<I> {
|
||||
|
||||
let value_lexp = self.lookup_expression.lookup(value_id)?;
|
||||
let ty_lookup = self.lookup_type.lookup(result_type_id)?;
|
||||
let (kind, width) = match ctx.type_arena[ty_lookup.handle].inner {
|
||||
crate::TypeInner::Scalar { kind, width }
|
||||
| crate::TypeInner::Vector { kind, width, .. } => (kind, width),
|
||||
crate::TypeInner::Matrix { width, .. } => (crate::ScalarKind::Float, width),
|
||||
let scalar = match ctx.type_arena[ty_lookup.handle].inner {
|
||||
crate::TypeInner::Scalar(scalar)
|
||||
| crate::TypeInner::Vector { scalar, .. } => scalar,
|
||||
crate::TypeInner::Matrix { width, .. } => crate::Scalar::float(width),
|
||||
_ => return Err(Error::InvalidAsType(ty_lookup.handle)),
|
||||
};
|
||||
|
||||
let expr = crate::Expression::As {
|
||||
expr: get_expr_handle!(value_id, value_lexp),
|
||||
kind,
|
||||
convert: if kind == crate::ScalarKind::Bool {
|
||||
kind: scalar.kind,
|
||||
convert: if scalar.kind == crate::ScalarKind::Bool {
|
||||
Some(crate::BOOL_WIDTH)
|
||||
} else if inst.op == Op::Bitcast {
|
||||
None
|
||||
} else {
|
||||
Some(width)
|
||||
Some(scalar.width)
|
||||
},
|
||||
};
|
||||
self.lookup_expression.insert(
|
||||
@ -3356,10 +3356,10 @@ impl<I: Iterator<Item = u32>> Frontend<I> {
|
||||
let selector_lty = self.lookup_type.lookup(selector_lexp.type_id)?;
|
||||
let selector_handle = get_expr_handle!(selector, selector_lexp);
|
||||
let selector = match ctx.type_arena[selector_lty.handle].inner {
|
||||
crate::TypeInner::Scalar {
|
||||
crate::TypeInner::Scalar(crate::Scalar {
|
||||
kind: crate::ScalarKind::Uint,
|
||||
width: _,
|
||||
} => {
|
||||
}) => {
|
||||
// IR expects a signed integer, so do a bitcast
|
||||
ctx.expressions.append(
|
||||
crate::Expression::As {
|
||||
@ -3370,10 +3370,10 @@ impl<I: Iterator<Item = u32>> Frontend<I> {
|
||||
span,
|
||||
)
|
||||
}
|
||||
crate::TypeInner::Scalar {
|
||||
crate::TypeInner::Scalar(crate::Scalar {
|
||||
kind: crate::ScalarKind::Sint,
|
||||
width: _,
|
||||
} => selector_handle,
|
||||
}) => selector_handle,
|
||||
ref other => unimplemented!("Unexpected selector {:?}", other),
|
||||
};
|
||||
|
||||
@ -4244,10 +4244,7 @@ impl<I: Iterator<Item = u32>> Frontend<I> {
|
||||
self.switch(ModuleState::Type, inst.op)?;
|
||||
inst.expect(2)?;
|
||||
let id = self.next()?;
|
||||
let inner = crate::TypeInner::Scalar {
|
||||
kind: crate::ScalarKind::Bool,
|
||||
width: crate::BOOL_WIDTH,
|
||||
};
|
||||
let inner = crate::TypeInner::Scalar(crate::Scalar::BOOL);
|
||||
self.lookup_type.insert(
|
||||
id,
|
||||
LookupType {
|
||||
@ -4275,14 +4272,14 @@ impl<I: Iterator<Item = u32>> Frontend<I> {
|
||||
let id = self.next()?;
|
||||
let width = self.next()?;
|
||||
let sign = self.next()?;
|
||||
let inner = crate::TypeInner::Scalar {
|
||||
let inner = crate::TypeInner::Scalar(crate::Scalar {
|
||||
kind: match sign {
|
||||
0 => crate::ScalarKind::Uint,
|
||||
1 => crate::ScalarKind::Sint,
|
||||
_ => return Err(Error::InvalidSign(sign)),
|
||||
},
|
||||
width: map_width(width)?,
|
||||
};
|
||||
});
|
||||
self.lookup_type.insert(
|
||||
id,
|
||||
LookupType {
|
||||
@ -4309,10 +4306,7 @@ impl<I: Iterator<Item = u32>> Frontend<I> {
|
||||
inst.expect(3)?;
|
||||
let id = self.next()?;
|
||||
let width = self.next()?;
|
||||
let inner = crate::TypeInner::Scalar {
|
||||
kind: crate::ScalarKind::Float,
|
||||
width: map_width(width)?,
|
||||
};
|
||||
let inner = crate::TypeInner::Scalar(crate::Scalar::float(map_width(width)?));
|
||||
self.lookup_type.insert(
|
||||
id,
|
||||
LookupType {
|
||||
@ -4340,15 +4334,14 @@ impl<I: Iterator<Item = u32>> Frontend<I> {
|
||||
let id = self.next()?;
|
||||
let type_id = self.next()?;
|
||||
let type_lookup = self.lookup_type.lookup(type_id)?;
|
||||
let (kind, width) = match module.types[type_lookup.handle].inner {
|
||||
crate::TypeInner::Scalar { kind, width } => (kind, width),
|
||||
let scalar = match module.types[type_lookup.handle].inner {
|
||||
crate::TypeInner::Scalar(scalar) => scalar,
|
||||
_ => return Err(Error::InvalidInnerType(type_id)),
|
||||
};
|
||||
let component_count = self.next()?;
|
||||
let inner = crate::TypeInner::Vector {
|
||||
size: map_vector_size(component_count)?,
|
||||
kind,
|
||||
width,
|
||||
scalar,
|
||||
};
|
||||
self.lookup_type.insert(
|
||||
id,
|
||||
@ -4381,10 +4374,10 @@ impl<I: Iterator<Item = u32>> Frontend<I> {
|
||||
|
||||
let vector_type_lookup = self.lookup_type.lookup(vector_type_id)?;
|
||||
let inner = match module.types[vector_type_lookup.handle].inner {
|
||||
crate::TypeInner::Vector { size, width, .. } => crate::TypeInner::Matrix {
|
||||
crate::TypeInner::Vector { size, scalar } => crate::TypeInner::Matrix {
|
||||
columns: map_vector_size(num_columns)?,
|
||||
rows: size,
|
||||
width,
|
||||
width: scalar.width,
|
||||
},
|
||||
_ => return Err(Error::InvalidInnerType(vector_type_id)),
|
||||
};
|
||||
@ -4761,11 +4754,10 @@ impl<I: Iterator<Item = u32>> Frontend<I> {
|
||||
crate::Type {
|
||||
name: None,
|
||||
inner: {
|
||||
let kind = crate::ScalarKind::Float;
|
||||
let width = 4;
|
||||
let scalar = crate::Scalar::F32;
|
||||
match dim.required_coordinate_size() {
|
||||
None => crate::TypeInner::Scalar { kind, width },
|
||||
Some(size) => crate::TypeInner::Vector { size, kind, width },
|
||||
None => crate::TypeInner::Scalar(scalar),
|
||||
Some(size) => crate::TypeInner::Vector { size, scalar },
|
||||
}
|
||||
},
|
||||
},
|
||||
@ -4870,30 +4862,30 @@ impl<I: Iterator<Item = u32>> Frontend<I> {
|
||||
let ty = type_lookup.handle;
|
||||
|
||||
let literal = match module.types[ty].inner {
|
||||
crate::TypeInner::Scalar {
|
||||
crate::TypeInner::Scalar(crate::Scalar {
|
||||
kind: crate::ScalarKind::Uint,
|
||||
width,
|
||||
} => {
|
||||
}) => {
|
||||
let low = self.next()?;
|
||||
match width {
|
||||
4 => crate::Literal::U32(low),
|
||||
_ => return Err(Error::InvalidTypeWidth(width as u32)),
|
||||
}
|
||||
}
|
||||
crate::TypeInner::Scalar {
|
||||
crate::TypeInner::Scalar(crate::Scalar {
|
||||
kind: crate::ScalarKind::Sint,
|
||||
width,
|
||||
} => {
|
||||
}) => {
|
||||
let low = self.next()?;
|
||||
match width {
|
||||
4 => crate::Literal::I32(low as i32),
|
||||
_ => return Err(Error::InvalidTypeWidth(width as u32)),
|
||||
}
|
||||
}
|
||||
crate::TypeInner::Scalar {
|
||||
crate::TypeInner::Scalar(crate::Scalar {
|
||||
kind: crate::ScalarKind::Float,
|
||||
width,
|
||||
} => {
|
||||
}) => {
|
||||
let low = self.next()?;
|
||||
match width {
|
||||
4 => crate::Literal::F32(f32::from_bits(low)),
|
||||
@ -5167,17 +5159,15 @@ impl<I: Iterator<Item = u32>> Frontend<I> {
|
||||
| crate::BuiltIn::SampleIndex
|
||||
| crate::BuiltIn::VertexIndex
|
||||
| crate::BuiltIn::PrimitiveIndex
|
||||
| crate::BuiltIn::LocalInvocationIndex => Some(crate::TypeInner::Scalar {
|
||||
kind: crate::ScalarKind::Uint,
|
||||
width: 4,
|
||||
}),
|
||||
| crate::BuiltIn::LocalInvocationIndex => {
|
||||
Some(crate::TypeInner::Scalar(crate::Scalar::U32))
|
||||
}
|
||||
crate::BuiltIn::GlobalInvocationId
|
||||
| crate::BuiltIn::LocalInvocationId
|
||||
| crate::BuiltIn::WorkGroupId
|
||||
| crate::BuiltIn::WorkGroupSize => Some(crate::TypeInner::Vector {
|
||||
size: crate::VectorSize::Tri,
|
||||
kind: crate::ScalarKind::Uint,
|
||||
width: 4,
|
||||
scalar: crate::Scalar::U32,
|
||||
}),
|
||||
_ => None,
|
||||
};
|
||||
|
73
third_party/rust/naga/src/front/type_gen.rs
vendored
73
third_party/rust/naga/src/front/type_gen.rs
vendored
@ -25,24 +25,17 @@ impl crate::Module {
|
||||
return handle;
|
||||
}
|
||||
|
||||
let width = 4;
|
||||
let ty_flag = self.types.insert(
|
||||
crate::Type {
|
||||
name: None,
|
||||
inner: crate::TypeInner::Scalar {
|
||||
width,
|
||||
kind: crate::ScalarKind::Uint,
|
||||
},
|
||||
inner: crate::TypeInner::Scalar(crate::Scalar::U32),
|
||||
},
|
||||
Span::UNDEFINED,
|
||||
);
|
||||
let ty_scalar = self.types.insert(
|
||||
crate::Type {
|
||||
name: None,
|
||||
inner: crate::TypeInner::Scalar {
|
||||
width,
|
||||
kind: crate::ScalarKind::Float,
|
||||
},
|
||||
inner: crate::TypeInner::Scalar(crate::Scalar::F32),
|
||||
},
|
||||
Span::UNDEFINED,
|
||||
);
|
||||
@ -51,8 +44,7 @@ impl crate::Module {
|
||||
name: None,
|
||||
inner: crate::TypeInner::Vector {
|
||||
size: crate::VectorSize::Tri,
|
||||
kind: crate::ScalarKind::Float,
|
||||
width,
|
||||
scalar: crate::Scalar::F32,
|
||||
},
|
||||
},
|
||||
Span::UNDEFINED,
|
||||
@ -127,24 +119,17 @@ impl crate::Module {
|
||||
return handle;
|
||||
}
|
||||
|
||||
let width = 4;
|
||||
let ty_flag = self.types.insert(
|
||||
crate::Type {
|
||||
name: None,
|
||||
inner: crate::TypeInner::Scalar {
|
||||
width,
|
||||
kind: crate::ScalarKind::Uint,
|
||||
},
|
||||
inner: crate::TypeInner::Scalar(crate::Scalar::U32),
|
||||
},
|
||||
Span::UNDEFINED,
|
||||
);
|
||||
let ty_scalar = self.types.insert(
|
||||
crate::Type {
|
||||
name: None,
|
||||
inner: crate::TypeInner::Scalar {
|
||||
width,
|
||||
kind: crate::ScalarKind::Float,
|
||||
},
|
||||
inner: crate::TypeInner::Scalar(crate::Scalar::F32),
|
||||
},
|
||||
Span::UNDEFINED,
|
||||
);
|
||||
@ -152,9 +137,8 @@ impl crate::Module {
|
||||
crate::Type {
|
||||
name: None,
|
||||
inner: crate::TypeInner::Vector {
|
||||
width,
|
||||
size: crate::VectorSize::Bi,
|
||||
kind: crate::ScalarKind::Float,
|
||||
scalar: crate::Scalar::F32,
|
||||
},
|
||||
},
|
||||
Span::UNDEFINED,
|
||||
@ -162,10 +146,7 @@ impl crate::Module {
|
||||
let ty_bool = self.types.insert(
|
||||
crate::Type {
|
||||
name: None,
|
||||
inner: crate::TypeInner::Scalar {
|
||||
width: crate::BOOL_WIDTH,
|
||||
kind: crate::ScalarKind::Bool,
|
||||
},
|
||||
inner: crate::TypeInner::Scalar(crate::Scalar::BOOL),
|
||||
},
|
||||
Span::UNDEFINED,
|
||||
);
|
||||
@ -175,7 +156,7 @@ impl crate::Module {
|
||||
inner: crate::TypeInner::Matrix {
|
||||
columns: crate::VectorSize::Quad,
|
||||
rows: crate::VectorSize::Tri,
|
||||
width,
|
||||
width: 4,
|
||||
},
|
||||
},
|
||||
Span::UNDEFINED,
|
||||
@ -277,28 +258,26 @@ impl crate::Module {
|
||||
}
|
||||
|
||||
let ty = match special_type {
|
||||
crate::PredeclaredType::AtomicCompareExchangeWeakResult { kind, width } => {
|
||||
crate::PredeclaredType::AtomicCompareExchangeWeakResult(scalar) => {
|
||||
let bool_ty = self.types.insert(
|
||||
crate::Type {
|
||||
name: None,
|
||||
inner: crate::TypeInner::Scalar {
|
||||
kind: crate::ScalarKind::Bool,
|
||||
width: crate::BOOL_WIDTH,
|
||||
},
|
||||
inner: crate::TypeInner::Scalar(crate::Scalar::BOOL),
|
||||
},
|
||||
Span::UNDEFINED,
|
||||
);
|
||||
let scalar_ty = self.types.insert(
|
||||
crate::Type {
|
||||
name: None,
|
||||
inner: crate::TypeInner::Scalar { kind, width },
|
||||
inner: crate::TypeInner::Scalar(scalar),
|
||||
},
|
||||
Span::UNDEFINED,
|
||||
);
|
||||
|
||||
crate::Type {
|
||||
name: Some(format!(
|
||||
"__atomic_compare_exchange_result<{kind:?},{width}>"
|
||||
"__atomic_compare_exchange_result<{:?},{}>",
|
||||
scalar.kind, scalar.width,
|
||||
)),
|
||||
inner: crate::TypeInner::Struct {
|
||||
members: vec![
|
||||
@ -323,10 +302,7 @@ impl crate::Module {
|
||||
let float_ty = self.types.insert(
|
||||
crate::Type {
|
||||
name: None,
|
||||
inner: crate::TypeInner::Scalar {
|
||||
kind: crate::ScalarKind::Float,
|
||||
width,
|
||||
},
|
||||
inner: crate::TypeInner::Scalar(crate::Scalar::float(width)),
|
||||
},
|
||||
Span::UNDEFINED,
|
||||
);
|
||||
@ -337,8 +313,7 @@ impl crate::Module {
|
||||
name: None,
|
||||
inner: crate::TypeInner::Vector {
|
||||
size,
|
||||
kind: crate::ScalarKind::Float,
|
||||
width,
|
||||
scalar: crate::Scalar::float(width),
|
||||
},
|
||||
},
|
||||
Span::UNDEFINED,
|
||||
@ -379,10 +354,7 @@ impl crate::Module {
|
||||
let float_ty = self.types.insert(
|
||||
crate::Type {
|
||||
name: None,
|
||||
inner: crate::TypeInner::Scalar {
|
||||
kind: crate::ScalarKind::Float,
|
||||
width,
|
||||
},
|
||||
inner: crate::TypeInner::Scalar(crate::Scalar::float(width)),
|
||||
},
|
||||
Span::UNDEFINED,
|
||||
);
|
||||
@ -390,10 +362,10 @@ impl crate::Module {
|
||||
let int_ty = self.types.insert(
|
||||
crate::Type {
|
||||
name: None,
|
||||
inner: crate::TypeInner::Scalar {
|
||||
inner: crate::TypeInner::Scalar(crate::Scalar {
|
||||
kind: crate::ScalarKind::Sint,
|
||||
width,
|
||||
},
|
||||
}),
|
||||
},
|
||||
Span::UNDEFINED,
|
||||
);
|
||||
@ -404,8 +376,7 @@ impl crate::Module {
|
||||
name: None,
|
||||
inner: crate::TypeInner::Vector {
|
||||
size,
|
||||
kind: crate::ScalarKind::Float,
|
||||
width,
|
||||
scalar: crate::Scalar::float(width),
|
||||
},
|
||||
},
|
||||
Span::UNDEFINED,
|
||||
@ -415,8 +386,10 @@ impl crate::Module {
|
||||
name: None,
|
||||
inner: crate::TypeInner::Vector {
|
||||
size,
|
||||
kind: crate::ScalarKind::Sint,
|
||||
width,
|
||||
scalar: crate::Scalar {
|
||||
kind: crate::ScalarKind::Sint,
|
||||
width,
|
||||
},
|
||||
},
|
||||
},
|
||||
Span::UNDEFINED,
|
||||
|
@ -65,7 +65,7 @@ impl Constructor<(Handle<crate::Type>, &crate::TypeInner)> {
|
||||
format!("mat{}x{}<?>", columns as u32, rows as u32,)
|
||||
}
|
||||
Self::PartialArray => "array<?, ?>".to_string(),
|
||||
Self::Type((handle, _inner)) => ctx.format_type(handle),
|
||||
Self::Type((handle, _inner)) => handle.to_wgsl(&ctx.module.to_ctx()),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -185,11 +185,11 @@ impl<'source, 'temp> Lowerer<'source, 'temp> {
|
||||
ty_inner: &crate::TypeInner::Scalar { .. },
|
||||
..
|
||||
},
|
||||
Constructor::Type((_, &crate::TypeInner::Scalar { kind, width })),
|
||||
Constructor::Type((_, &crate::TypeInner::Scalar(scalar))),
|
||||
) => crate::Expression::As {
|
||||
expr: component,
|
||||
kind,
|
||||
convert: Some(width),
|
||||
kind: scalar.kind,
|
||||
convert: Some(scalar.width),
|
||||
},
|
||||
|
||||
// Vector conversion (vector -> vector)
|
||||
@ -203,14 +203,13 @@ impl<'source, 'temp> Lowerer<'source, 'temp> {
|
||||
_,
|
||||
&crate::TypeInner::Vector {
|
||||
size: dst_size,
|
||||
kind: dst_kind,
|
||||
width: dst_width,
|
||||
scalar: dst_scalar,
|
||||
},
|
||||
)),
|
||||
) if dst_size == src_size => crate::Expression::As {
|
||||
expr: component,
|
||||
kind: dst_kind,
|
||||
convert: Some(dst_width),
|
||||
kind: dst_scalar.kind,
|
||||
convert: Some(dst_scalar.width),
|
||||
},
|
||||
|
||||
// Vector conversion (vector -> vector) - partial
|
||||
@ -294,23 +293,17 @@ impl<'source, 'temp> Lowerer<'source, 'temp> {
|
||||
(
|
||||
Components::One {
|
||||
component,
|
||||
ty_inner:
|
||||
&crate::TypeInner::Scalar {
|
||||
kind: src_kind,
|
||||
width: src_width,
|
||||
..
|
||||
},
|
||||
ty_inner: &crate::TypeInner::Scalar(src_scalar),
|
||||
..
|
||||
},
|
||||
Constructor::Type((
|
||||
_,
|
||||
&crate::TypeInner::Vector {
|
||||
size,
|
||||
kind: dst_kind,
|
||||
width: dst_width,
|
||||
scalar: dst_scalar,
|
||||
},
|
||||
)),
|
||||
) if dst_kind == src_kind || dst_width == src_width => crate::Expression::Splat {
|
||||
) if dst_scalar == src_scalar => crate::Expression::Splat {
|
||||
size,
|
||||
value: component,
|
||||
},
|
||||
@ -320,8 +313,7 @@ impl<'source, 'temp> Lowerer<'source, 'temp> {
|
||||
Components::Many {
|
||||
components,
|
||||
first_component_ty_inner:
|
||||
&crate::TypeInner::Scalar { kind, width }
|
||||
| &crate::TypeInner::Vector { kind, width, .. },
|
||||
&crate::TypeInner::Scalar(scalar) | &crate::TypeInner::Vector { scalar, .. },
|
||||
..
|
||||
},
|
||||
Constructor::PartialVector { size },
|
||||
@ -333,9 +325,9 @@ impl<'source, 'temp> Lowerer<'source, 'temp> {
|
||||
&crate::TypeInner::Scalar { .. } | &crate::TypeInner::Vector { .. },
|
||||
..
|
||||
},
|
||||
Constructor::Type((_, &crate::TypeInner::Vector { size, width, kind })),
|
||||
Constructor::Type((_, &crate::TypeInner::Vector { size, scalar })),
|
||||
) => {
|
||||
let inner = crate::TypeInner::Vector { size, kind, width };
|
||||
let inner = crate::TypeInner::Vector { size, scalar };
|
||||
let ty = ctx.ensure_type_exists(inner);
|
||||
crate::Expression::Compose { ty, components }
|
||||
}
|
||||
@ -344,7 +336,7 @@ impl<'source, 'temp> Lowerer<'source, 'temp> {
|
||||
(
|
||||
Components::Many {
|
||||
components,
|
||||
first_component_ty_inner: &crate::TypeInner::Scalar { width, .. },
|
||||
first_component_ty_inner: &crate::TypeInner::Scalar(crate::Scalar { width, .. }),
|
||||
..
|
||||
},
|
||||
Constructor::PartialMatrix { columns, rows },
|
||||
@ -365,8 +357,7 @@ impl<'source, 'temp> Lowerer<'source, 'temp> {
|
||||
)),
|
||||
) => {
|
||||
let vec_ty = ctx.ensure_type_exists(crate::TypeInner::Vector {
|
||||
width,
|
||||
kind: crate::ScalarKind::Float,
|
||||
scalar: crate::Scalar::float(width),
|
||||
size: rows,
|
||||
});
|
||||
|
||||
@ -395,7 +386,11 @@ impl<'source, 'temp> Lowerer<'source, 'temp> {
|
||||
(
|
||||
Components::Many {
|
||||
components,
|
||||
first_component_ty_inner: &crate::TypeInner::Vector { width, .. },
|
||||
first_component_ty_inner:
|
||||
&crate::TypeInner::Vector {
|
||||
scalar: crate::Scalar { width, .. },
|
||||
..
|
||||
},
|
||||
..
|
||||
},
|
||||
Constructor::PartialMatrix { columns, rows },
|
||||
@ -460,7 +455,7 @@ impl<'source, 'temp> Lowerer<'source, 'temp> {
|
||||
|
||||
// Bad conversion (type cast)
|
||||
(Components::One { span, ty_inner, .. }, constructor) => {
|
||||
let from_type = ctx.format_typeinner(ty_inner);
|
||||
let from_type = ty_inner.to_wgsl(&ctx.module.to_ctx());
|
||||
return Err(Error::BadTypeCast {
|
||||
span,
|
||||
from_type,
|
||||
|
113
third_party/rust/naga/src/front/wgsl/lower/mod.rs
vendored
113
third_party/rust/naga/src/front/wgsl/lower/mod.rs
vendored
@ -7,7 +7,6 @@ use crate::front::wgsl::parse::{ast, conv};
|
||||
use crate::front::Typifier;
|
||||
use crate::proc::{
|
||||
ensure_block_returns, Alignment, ConstantEvaluator, Emitter, Layouter, ResolveContext,
|
||||
TypeResolution,
|
||||
};
|
||||
use crate::{Arena, FastHashMap, FastIndexMap, Handle, Span};
|
||||
|
||||
@ -59,6 +58,8 @@ macro_rules! resolve_inner_binary {
|
||||
/// Returns a &[`TypeResolution`].
|
||||
///
|
||||
/// See the documentation of [`resolve_inner!`] for why this macro is necessary.
|
||||
///
|
||||
/// [`TypeResolution`]: crate::proc::TypeResolution
|
||||
macro_rules! resolve {
|
||||
($ctx:ident, $expr:expr) => {{
|
||||
$ctx.grow_types($expr)?;
|
||||
@ -486,6 +487,7 @@ impl<'source, 'temp, 'out> ExpressionContext<'source, 'temp, 'out> {
|
||||
/// [`resolve_inner!`] or [`resolve_inner_binary!`].
|
||||
///
|
||||
/// [`self.typifier`]: ExpressionContext::typifier
|
||||
/// [`TypeResolution`]: crate::proc::TypeResolution
|
||||
/// [`register_type`]: Self::register_type
|
||||
/// [`Typifier`]: Typifier
|
||||
fn grow_types(
|
||||
@ -632,25 +634,6 @@ impl<'source, 'temp, 'out> ExpressionContext<'source, 'temp, 'out> {
|
||||
}
|
||||
}
|
||||
|
||||
fn format_typeinner(&self, inner: &crate::TypeInner) -> String {
|
||||
inner.to_wgsl(self.module.to_ctx())
|
||||
}
|
||||
|
||||
fn format_type(&self, handle: Handle<crate::Type>) -> String {
|
||||
let ty = &self.module.types[handle];
|
||||
match ty.name {
|
||||
Some(ref name) => name.clone(),
|
||||
None => self.format_typeinner(&ty.inner),
|
||||
}
|
||||
}
|
||||
|
||||
fn format_type_resolution(&self, resolution: &TypeResolution) -> String {
|
||||
match *resolution {
|
||||
TypeResolution::Handle(handle) => self.format_type(handle),
|
||||
TypeResolution::Value(ref inner) => self.format_typeinner(inner),
|
||||
}
|
||||
}
|
||||
|
||||
fn ensure_type_exists(&mut self, inner: crate::TypeInner) -> Handle<crate::Type> {
|
||||
self.as_global().ensure_type_exists(inner)
|
||||
}
|
||||
@ -925,22 +908,11 @@ impl<'source, 'temp> Lowerer<'source, 'temp> {
|
||||
|
||||
if let Some(explicit) = explicit_ty {
|
||||
if explicit != inferred_type {
|
||||
let ty = &ctx.module.types[explicit];
|
||||
let expected = ty
|
||||
.name
|
||||
.clone()
|
||||
.unwrap_or_else(|| ty.inner.to_wgsl(ctx.module.to_ctx()));
|
||||
|
||||
let ty = &ctx.module.types[inferred_type];
|
||||
let got = ty
|
||||
.name
|
||||
.clone()
|
||||
.unwrap_or_else(|| ty.inner.to_wgsl(ctx.module.to_ctx()));
|
||||
|
||||
let gctx = ctx.module.to_ctx();
|
||||
return Err(Error::InitializationTypeMismatch {
|
||||
name: c.name.span,
|
||||
expected,
|
||||
got,
|
||||
expected: explicit.to_wgsl(&gctx),
|
||||
got: inferred_type.to_wgsl(&gctx),
|
||||
});
|
||||
}
|
||||
}
|
||||
@ -1128,10 +1100,11 @@ impl<'source, 'temp> Lowerer<'source, 'temp> {
|
||||
.inner
|
||||
.equivalent(&ctx.module.types[init_ty].inner, &ctx.module.types)
|
||||
{
|
||||
let gctx = &ctx.module.to_ctx();
|
||||
return Err(Error::InitializationTypeMismatch {
|
||||
name: l.name.span,
|
||||
expected: ctx.format_type(ty),
|
||||
got: ctx.format_type(init_ty),
|
||||
expected: ty.to_wgsl(gctx),
|
||||
got: init_ty.to_wgsl(gctx),
|
||||
});
|
||||
}
|
||||
}
|
||||
@ -1166,10 +1139,11 @@ impl<'source, 'temp> Lowerer<'source, 'temp> {
|
||||
.inner
|
||||
.equivalent(initializer_ty, &ctx.module.types)
|
||||
{
|
||||
let gctx = &ctx.module.to_ctx();
|
||||
return Err(Error::InitializationTypeMismatch {
|
||||
name: v.name.span,
|
||||
expected: ctx.format_type(explicit),
|
||||
got: ctx.format_typeinner(initializer_ty),
|
||||
expected: explicit.to_wgsl(gctx),
|
||||
got: initializer_ty.to_wgsl(gctx),
|
||||
});
|
||||
}
|
||||
explicit
|
||||
@ -1413,22 +1387,19 @@ impl<'source, 'temp> Lowerer<'source, 'temp> {
|
||||
};
|
||||
|
||||
let mut ectx = ctx.as_expression(block, &mut emitter);
|
||||
let (kind, width) = match *resolve_inner!(ectx, target_handle) {
|
||||
let scalar = match *resolve_inner!(ectx, target_handle) {
|
||||
crate::TypeInner::ValuePointer {
|
||||
size: None,
|
||||
kind,
|
||||
width,
|
||||
..
|
||||
} => (kind, width),
|
||||
size: None, scalar, ..
|
||||
} => scalar,
|
||||
crate::TypeInner::Pointer { base, .. } => match ectx.module.types[base].inner {
|
||||
crate::TypeInner::Scalar { kind, width } => (kind, width),
|
||||
crate::TypeInner::Scalar(scalar) => scalar,
|
||||
_ => return Err(Error::BadIncrDecrReferenceType(value_span)),
|
||||
},
|
||||
_ => return Err(Error::BadIncrDecrReferenceType(value_span)),
|
||||
};
|
||||
let literal = match kind {
|
||||
let literal = match scalar.kind {
|
||||
crate::ScalarKind::Sint | crate::ScalarKind::Uint => {
|
||||
crate::Literal::one(kind, width)
|
||||
crate::Literal::one(scalar)
|
||||
.ok_or(Error::BadIncrDecrReferenceType(value_span))?
|
||||
}
|
||||
_ => return Err(Error::BadIncrDecrReferenceType(value_span)),
|
||||
@ -1608,21 +1579,17 @@ impl<'source, 'temp> Lowerer<'source, 'temp> {
|
||||
match *inner {
|
||||
crate::TypeInner::Pointer { base, .. } => &ctx.module.types[base].inner,
|
||||
crate::TypeInner::ValuePointer {
|
||||
size: None,
|
||||
kind,
|
||||
width,
|
||||
..
|
||||
size: None, scalar, ..
|
||||
} => {
|
||||
temp_inner = crate::TypeInner::Scalar { kind, width };
|
||||
temp_inner = crate::TypeInner::Scalar(scalar);
|
||||
&temp_inner
|
||||
}
|
||||
crate::TypeInner::ValuePointer {
|
||||
size: Some(size),
|
||||
kind,
|
||||
width,
|
||||
scalar,
|
||||
..
|
||||
} => {
|
||||
temp_inner = crate::TypeInner::Vector { size, kind, width };
|
||||
temp_inner = crate::TypeInner::Vector { size, scalar };
|
||||
&temp_inner
|
||||
}
|
||||
_ => unreachable!(
|
||||
@ -1679,22 +1646,23 @@ impl<'source, 'temp> Lowerer<'source, 'temp> {
|
||||
let expr = self.expression(expr, ctx)?;
|
||||
let to_resolved = self.resolve_ast_type(to, &mut ctx.as_global())?;
|
||||
|
||||
let kind = match ctx.module.types[to_resolved].inner {
|
||||
crate::TypeInner::Scalar { kind, .. } => kind,
|
||||
crate::TypeInner::Vector { kind, .. } => kind,
|
||||
let element_scalar = match ctx.module.types[to_resolved].inner {
|
||||
crate::TypeInner::Scalar(scalar) => scalar,
|
||||
crate::TypeInner::Vector { scalar, .. } => scalar,
|
||||
_ => {
|
||||
let ty = resolve!(ctx, expr);
|
||||
let gctx = &ctx.module.to_ctx();
|
||||
return Err(Error::BadTypeCast {
|
||||
from_type: ctx.format_type_resolution(ty),
|
||||
from_type: ty.to_wgsl(gctx),
|
||||
span: ty_span,
|
||||
to_type: ctx.format_type(to_resolved),
|
||||
to_type: to_resolved.to_wgsl(gctx),
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
Typed::Plain(crate::Expression::As {
|
||||
expr,
|
||||
kind,
|
||||
kind: element_scalar.kind,
|
||||
convert: None,
|
||||
})
|
||||
}
|
||||
@ -1785,10 +1753,10 @@ impl<'source, 'temp> Lowerer<'source, 'temp> {
|
||||
) && {
|
||||
matches!(
|
||||
resolve_inner!(ctx, argument),
|
||||
&crate::TypeInner::Scalar {
|
||||
&crate::TypeInner::Scalar(crate::Scalar {
|
||||
kind: crate::ScalarKind::Bool,
|
||||
..
|
||||
}
|
||||
})
|
||||
)
|
||||
};
|
||||
|
||||
@ -1828,10 +1796,14 @@ impl<'source, 'temp> Lowerer<'source, 'temp> {
|
||||
|
||||
if fun == crate::MathFunction::Modf || fun == crate::MathFunction::Frexp {
|
||||
if let Some((size, width)) = match *resolve_inner!(ctx, arg) {
|
||||
crate::TypeInner::Scalar { width, .. } => Some((None, width)),
|
||||
crate::TypeInner::Vector { size, width, .. } => {
|
||||
Some((Some(size), width))
|
||||
crate::TypeInner::Scalar(crate::Scalar { width, .. }) => {
|
||||
Some((None, width))
|
||||
}
|
||||
crate::TypeInner::Vector {
|
||||
size,
|
||||
scalar: crate::Scalar { width, .. },
|
||||
..
|
||||
} => Some((Some(size), width)),
|
||||
_ => None,
|
||||
} {
|
||||
ctx.module.generate_predeclared_type(
|
||||
@ -1976,13 +1948,12 @@ impl<'source, 'temp> Lowerer<'source, 'temp> {
|
||||
args.finish()?;
|
||||
|
||||
let expression = match *resolve_inner!(ctx, value) {
|
||||
crate::TypeInner::Scalar { kind, width } => {
|
||||
crate::TypeInner::Scalar(scalar) => {
|
||||
crate::Expression::AtomicResult {
|
||||
ty: ctx.module.generate_predeclared_type(
|
||||
crate::PredeclaredType::AtomicCompareExchangeWeakResult {
|
||||
kind,
|
||||
width,
|
||||
},
|
||||
crate::PredeclaredType::AtomicCompareExchangeWeakResult(
|
||||
scalar,
|
||||
),
|
||||
),
|
||||
comparison: true,
|
||||
}
|
||||
|
295
third_party/rust/naga/src/front/wgsl/mod.rs
vendored
295
third_party/rust/naga/src/front/wgsl/mod.rs
vendored
@ -10,6 +10,7 @@ mod lower;
|
||||
mod parse;
|
||||
#[cfg(test)]
|
||||
mod tests;
|
||||
mod to_wgsl;
|
||||
|
||||
use crate::front::wgsl::error::Error;
|
||||
use crate::front::wgsl::parse::Parser;
|
||||
@ -17,6 +18,7 @@ use thiserror::Error;
|
||||
|
||||
pub use crate::front::wgsl::error::ParseError;
|
||||
use crate::front::wgsl::lower::Lowerer;
|
||||
use crate::Scalar;
|
||||
|
||||
pub struct Frontend {
|
||||
parser: Parser,
|
||||
@ -45,296 +47,3 @@ impl Frontend {
|
||||
pub fn parse_str(source: &str) -> Result<crate::Module, ParseError> {
|
||||
Frontend::new().parse(source)
|
||||
}
|
||||
|
||||
impl crate::StorageFormat {
|
||||
const fn to_wgsl(self) -> &'static str {
|
||||
use crate::StorageFormat as Sf;
|
||||
match self {
|
||||
Sf::R8Unorm => "r8unorm",
|
||||
Sf::R8Snorm => "r8snorm",
|
||||
Sf::R8Uint => "r8uint",
|
||||
Sf::R8Sint => "r8sint",
|
||||
Sf::R16Uint => "r16uint",
|
||||
Sf::R16Sint => "r16sint",
|
||||
Sf::R16Float => "r16float",
|
||||
Sf::Rg8Unorm => "rg8unorm",
|
||||
Sf::Rg8Snorm => "rg8snorm",
|
||||
Sf::Rg8Uint => "rg8uint",
|
||||
Sf::Rg8Sint => "rg8sint",
|
||||
Sf::R32Uint => "r32uint",
|
||||
Sf::R32Sint => "r32sint",
|
||||
Sf::R32Float => "r32float",
|
||||
Sf::Rg16Uint => "rg16uint",
|
||||
Sf::Rg16Sint => "rg16sint",
|
||||
Sf::Rg16Float => "rg16float",
|
||||
Sf::Rgba8Unorm => "rgba8unorm",
|
||||
Sf::Rgba8Snorm => "rgba8snorm",
|
||||
Sf::Rgba8Uint => "rgba8uint",
|
||||
Sf::Rgba8Sint => "rgba8sint",
|
||||
Sf::Bgra8Unorm => "bgra8unorm",
|
||||
Sf::Rgb10a2Uint => "rgb10a2uint",
|
||||
Sf::Rgb10a2Unorm => "rgb10a2unorm",
|
||||
Sf::Rg11b10Float => "rg11b10float",
|
||||
Sf::Rg32Uint => "rg32uint",
|
||||
Sf::Rg32Sint => "rg32sint",
|
||||
Sf::Rg32Float => "rg32float",
|
||||
Sf::Rgba16Uint => "rgba16uint",
|
||||
Sf::Rgba16Sint => "rgba16sint",
|
||||
Sf::Rgba16Float => "rgba16float",
|
||||
Sf::Rgba32Uint => "rgba32uint",
|
||||
Sf::Rgba32Sint => "rgba32sint",
|
||||
Sf::Rgba32Float => "rgba32float",
|
||||
Sf::R16Unorm => "r16unorm",
|
||||
Sf::R16Snorm => "r16snorm",
|
||||
Sf::Rg16Unorm => "rg16unorm",
|
||||
Sf::Rg16Snorm => "rg16snorm",
|
||||
Sf::Rgba16Unorm => "rgba16unorm",
|
||||
Sf::Rgba16Snorm => "rgba16snorm",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl crate::TypeInner {
|
||||
/// Formats the type as it is written in wgsl.
|
||||
///
|
||||
/// For example `vec3<f32>`.
|
||||
///
|
||||
/// Note: The names of a `TypeInner::Struct` is not known. Therefore this method will simply return "struct" for them.
|
||||
fn to_wgsl(&self, gctx: crate::proc::GlobalCtx) -> String {
|
||||
use crate::TypeInner as Ti;
|
||||
|
||||
match *self {
|
||||
Ti::Scalar { kind, width } => Scalar { kind, width }.to_wgsl(),
|
||||
Ti::Vector { size, kind, width } => {
|
||||
let scalar = Scalar { kind, width };
|
||||
format!("vec{}<{}>", size as u32, scalar.to_wgsl())
|
||||
}
|
||||
Ti::Matrix {
|
||||
columns,
|
||||
rows,
|
||||
width,
|
||||
} => {
|
||||
format!(
|
||||
"mat{}x{}<{}>",
|
||||
columns as u32,
|
||||
rows as u32,
|
||||
Scalar {
|
||||
kind: crate::ScalarKind::Float,
|
||||
width
|
||||
}
|
||||
.to_wgsl(),
|
||||
)
|
||||
}
|
||||
Ti::Atomic { kind, width } => {
|
||||
format!("atomic<{}>", Scalar { kind, width }.to_wgsl())
|
||||
}
|
||||
Ti::Pointer { base, .. } => {
|
||||
let base = &gctx.types[base];
|
||||
let name = base.name.as_deref().unwrap_or("unknown");
|
||||
format!("ptr<{name}>")
|
||||
}
|
||||
Ti::ValuePointer { kind, width, .. } => {
|
||||
format!("ptr<{}>", Scalar { kind, width }.to_wgsl())
|
||||
}
|
||||
Ti::Array { base, size, .. } => {
|
||||
let member_type = &gctx.types[base];
|
||||
let base = member_type.name.as_deref().unwrap_or("unknown");
|
||||
match size {
|
||||
crate::ArraySize::Constant(size) => format!("array<{base}, {size}>"),
|
||||
crate::ArraySize::Dynamic => format!("array<{base}>"),
|
||||
}
|
||||
}
|
||||
Ti::Struct { .. } => {
|
||||
// TODO: Actually output the struct?
|
||||
"struct".to_string()
|
||||
}
|
||||
Ti::Image {
|
||||
dim,
|
||||
arrayed,
|
||||
class,
|
||||
} => {
|
||||
let dim_suffix = match dim {
|
||||
crate::ImageDimension::D1 => "_1d",
|
||||
crate::ImageDimension::D2 => "_2d",
|
||||
crate::ImageDimension::D3 => "_3d",
|
||||
crate::ImageDimension::Cube => "_cube",
|
||||
};
|
||||
let array_suffix = if arrayed { "_array" } else { "" };
|
||||
|
||||
let class_suffix = match class {
|
||||
crate::ImageClass::Sampled { multi: true, .. } => "_multisampled",
|
||||
crate::ImageClass::Depth { multi: false } => "_depth",
|
||||
crate::ImageClass::Depth { multi: true } => "_depth_multisampled",
|
||||
crate::ImageClass::Sampled { multi: false, .. }
|
||||
| crate::ImageClass::Storage { .. } => "",
|
||||
};
|
||||
|
||||
let type_in_brackets = match class {
|
||||
crate::ImageClass::Sampled { kind, .. } => {
|
||||
// Note: The only valid widths are 4 bytes wide.
|
||||
// The lexer has already verified this, so we can safely assume it here.
|
||||
// https://gpuweb.github.io/gpuweb/wgsl/#sampled-texture-type
|
||||
let element_type = Scalar { kind, width: 4 }.to_wgsl();
|
||||
format!("<{element_type}>")
|
||||
}
|
||||
crate::ImageClass::Depth { multi: _ } => String::new(),
|
||||
crate::ImageClass::Storage { format, access } => {
|
||||
if access.contains(crate::StorageAccess::STORE) {
|
||||
format!("<{},write>", format.to_wgsl())
|
||||
} else {
|
||||
format!("<{}>", format.to_wgsl())
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
format!("texture{class_suffix}{dim_suffix}{array_suffix}{type_in_brackets}")
|
||||
}
|
||||
Ti::Sampler { .. } => "sampler".to_string(),
|
||||
Ti::AccelerationStructure => "acceleration_structure".to_string(),
|
||||
Ti::RayQuery => "ray_query".to_string(),
|
||||
Ti::BindingArray { base, size, .. } => {
|
||||
let member_type = &gctx.types[base];
|
||||
let base = member_type.name.as_deref().unwrap_or("unknown");
|
||||
match size {
|
||||
crate::ArraySize::Constant(size) => format!("binding_array<{base}, {size}>"),
|
||||
crate::ArraySize::Dynamic => format!("binding_array<{base}>"),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mod type_inner_tests {
|
||||
|
||||
#[test]
|
||||
fn to_wgsl() {
|
||||
use std::num::NonZeroU32;
|
||||
|
||||
let mut types = crate::UniqueArena::new();
|
||||
|
||||
let mytype1 = types.insert(
|
||||
crate::Type {
|
||||
name: Some("MyType1".to_string()),
|
||||
inner: crate::TypeInner::Struct {
|
||||
members: vec![],
|
||||
span: 0,
|
||||
},
|
||||
},
|
||||
Default::default(),
|
||||
);
|
||||
let mytype2 = types.insert(
|
||||
crate::Type {
|
||||
name: Some("MyType2".to_string()),
|
||||
inner: crate::TypeInner::Struct {
|
||||
members: vec![],
|
||||
span: 0,
|
||||
},
|
||||
},
|
||||
Default::default(),
|
||||
);
|
||||
|
||||
let gctx = crate::proc::GlobalCtx {
|
||||
types: &types,
|
||||
constants: &crate::Arena::new(),
|
||||
const_expressions: &crate::Arena::new(),
|
||||
};
|
||||
let array = crate::TypeInner::Array {
|
||||
base: mytype1,
|
||||
stride: 4,
|
||||
size: crate::ArraySize::Constant(unsafe { NonZeroU32::new_unchecked(32) }),
|
||||
};
|
||||
assert_eq!(array.to_wgsl(gctx), "array<MyType1, 32>");
|
||||
|
||||
let mat = crate::TypeInner::Matrix {
|
||||
rows: crate::VectorSize::Quad,
|
||||
columns: crate::VectorSize::Bi,
|
||||
width: 8,
|
||||
};
|
||||
assert_eq!(mat.to_wgsl(gctx), "mat2x4<f64>");
|
||||
|
||||
let ptr = crate::TypeInner::Pointer {
|
||||
base: mytype2,
|
||||
space: crate::AddressSpace::Storage {
|
||||
access: crate::StorageAccess::default(),
|
||||
},
|
||||
};
|
||||
assert_eq!(ptr.to_wgsl(gctx), "ptr<MyType2>");
|
||||
|
||||
let img1 = crate::TypeInner::Image {
|
||||
dim: crate::ImageDimension::D2,
|
||||
arrayed: false,
|
||||
class: crate::ImageClass::Sampled {
|
||||
kind: crate::ScalarKind::Float,
|
||||
multi: true,
|
||||
},
|
||||
};
|
||||
assert_eq!(img1.to_wgsl(gctx), "texture_multisampled_2d<f32>");
|
||||
|
||||
let img2 = crate::TypeInner::Image {
|
||||
dim: crate::ImageDimension::Cube,
|
||||
arrayed: true,
|
||||
class: crate::ImageClass::Depth { multi: false },
|
||||
};
|
||||
assert_eq!(img2.to_wgsl(gctx), "texture_depth_cube_array");
|
||||
|
||||
let img3 = crate::TypeInner::Image {
|
||||
dim: crate::ImageDimension::D2,
|
||||
arrayed: false,
|
||||
class: crate::ImageClass::Depth { multi: true },
|
||||
};
|
||||
assert_eq!(img3.to_wgsl(gctx), "texture_depth_multisampled_2d");
|
||||
|
||||
let array = crate::TypeInner::BindingArray {
|
||||
base: mytype1,
|
||||
size: crate::ArraySize::Constant(unsafe { NonZeroU32::new_unchecked(32) }),
|
||||
};
|
||||
assert_eq!(array.to_wgsl(gctx), "binding_array<MyType1, 32>");
|
||||
}
|
||||
}
|
||||
|
||||
/// Characteristics of a scalar type.
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
pub struct Scalar {
|
||||
/// How the value's bits are to be interpreted.
|
||||
pub kind: crate::ScalarKind,
|
||||
|
||||
/// The size of the value in bytes.
|
||||
pub width: crate::Bytes,
|
||||
}
|
||||
|
||||
impl Scalar {
|
||||
/// Format a scalar kind+width as a type is written in wgsl.
|
||||
///
|
||||
/// Examples: `f32`, `u64`, `bool`.
|
||||
fn to_wgsl(self) -> String {
|
||||
let prefix = match self.kind {
|
||||
crate::ScalarKind::Sint => "i",
|
||||
crate::ScalarKind::Uint => "u",
|
||||
crate::ScalarKind::Float => "f",
|
||||
crate::ScalarKind::Bool => return "bool".to_string(),
|
||||
};
|
||||
format!("{}{}", prefix, self.width * 8)
|
||||
}
|
||||
|
||||
const fn to_inner_scalar(self) -> crate::TypeInner {
|
||||
crate::TypeInner::Scalar {
|
||||
kind: self.kind,
|
||||
width: self.width,
|
||||
}
|
||||
}
|
||||
|
||||
const fn to_inner_vector(self, size: crate::VectorSize) -> crate::TypeInner {
|
||||
crate::TypeInner::Vector {
|
||||
size,
|
||||
kind: self.kind,
|
||||
width: self.width,
|
||||
}
|
||||
}
|
||||
|
||||
const fn to_inner_atomic(self) -> crate::TypeInner {
|
||||
crate::TypeInner::Atomic {
|
||||
kind: self.kind,
|
||||
width: self.width,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -307,10 +307,7 @@ impl Parser {
|
||||
"vec2f" => {
|
||||
return Ok(Some(ast::ConstructorType::Vector {
|
||||
size: crate::VectorSize::Bi,
|
||||
scalar: Scalar {
|
||||
kind: crate::ScalarKind::Float,
|
||||
width: 4,
|
||||
},
|
||||
scalar: Scalar::F32,
|
||||
}))
|
||||
}
|
||||
"vec3" => ast::ConstructorType::PartialVector {
|
||||
@ -319,28 +316,19 @@ impl Parser {
|
||||
"vec3i" => {
|
||||
return Ok(Some(ast::ConstructorType::Vector {
|
||||
size: crate::VectorSize::Tri,
|
||||
scalar: Scalar {
|
||||
kind: crate::ScalarKind::Sint,
|
||||
width: 4,
|
||||
},
|
||||
scalar: Scalar::I32,
|
||||
}))
|
||||
}
|
||||
"vec3u" => {
|
||||
return Ok(Some(ast::ConstructorType::Vector {
|
||||
size: crate::VectorSize::Tri,
|
||||
scalar: Scalar {
|
||||
kind: crate::ScalarKind::Uint,
|
||||
width: 4,
|
||||
},
|
||||
scalar: Scalar::U32,
|
||||
}))
|
||||
}
|
||||
"vec3f" => {
|
||||
return Ok(Some(ast::ConstructorType::Vector {
|
||||
size: crate::VectorSize::Tri,
|
||||
scalar: Scalar {
|
||||
kind: crate::ScalarKind::Float,
|
||||
width: 4,
|
||||
},
|
||||
scalar: Scalar::F32,
|
||||
}))
|
||||
}
|
||||
"vec4" => ast::ConstructorType::PartialVector {
|
||||
@ -349,28 +337,19 @@ impl Parser {
|
||||
"vec4i" => {
|
||||
return Ok(Some(ast::ConstructorType::Vector {
|
||||
size: crate::VectorSize::Quad,
|
||||
scalar: Scalar {
|
||||
kind: crate::ScalarKind::Sint,
|
||||
width: 4,
|
||||
},
|
||||
scalar: Scalar::I32,
|
||||
}))
|
||||
}
|
||||
"vec4u" => {
|
||||
return Ok(Some(ast::ConstructorType::Vector {
|
||||
size: crate::VectorSize::Quad,
|
||||
scalar: Scalar {
|
||||
kind: crate::ScalarKind::Uint,
|
||||
width: 4,
|
||||
},
|
||||
scalar: Scalar::U32,
|
||||
}))
|
||||
}
|
||||
"vec4f" => {
|
||||
return Ok(Some(ast::ConstructorType::Vector {
|
||||
size: crate::VectorSize::Quad,
|
||||
scalar: Scalar {
|
||||
kind: crate::ScalarKind::Float,
|
||||
width: 4,
|
||||
},
|
||||
scalar: Scalar::F32,
|
||||
}))
|
||||
}
|
||||
"mat2x2" => ast::ConstructorType::PartialMatrix {
|
||||
@ -1109,10 +1088,7 @@ impl Parser {
|
||||
},
|
||||
"vec2f" => ast::Type::Vector {
|
||||
size: crate::VectorSize::Bi,
|
||||
scalar: Scalar {
|
||||
kind: crate::ScalarKind::Float,
|
||||
width: 4,
|
||||
},
|
||||
scalar: Scalar::F32,
|
||||
},
|
||||
"vec3" => {
|
||||
let scalar = lexer.next_scalar_generic()?;
|
||||
@ -1137,10 +1113,7 @@ impl Parser {
|
||||
},
|
||||
"vec3f" => ast::Type::Vector {
|
||||
size: crate::VectorSize::Tri,
|
||||
scalar: Scalar {
|
||||
kind: crate::ScalarKind::Float,
|
||||
width: 4,
|
||||
},
|
||||
scalar: Scalar::F32,
|
||||
},
|
||||
"vec4" => {
|
||||
let scalar = lexer.next_scalar_generic()?;
|
||||
@ -1165,10 +1138,7 @@ impl Parser {
|
||||
},
|
||||
"vec4f" => ast::Type::Vector {
|
||||
size: crate::VectorSize::Quad,
|
||||
scalar: Scalar {
|
||||
kind: crate::ScalarKind::Float,
|
||||
width: 4,
|
||||
},
|
||||
scalar: Scalar::F32,
|
||||
},
|
||||
"mat2x2" => {
|
||||
self.matrix_scalar_type(lexer, crate::VectorSize::Bi, crate::VectorSize::Bi)?
|
||||
|
283
third_party/rust/naga/src/front/wgsl/to_wgsl.rs
vendored
Normal file
283
third_party/rust/naga/src/front/wgsl/to_wgsl.rs
vendored
Normal file
@ -0,0 +1,283 @@
|
||||
//! Producing the WGSL forms of types, for use in error messages.
|
||||
|
||||
use crate::proc::GlobalCtx;
|
||||
use crate::Handle;
|
||||
|
||||
impl crate::proc::TypeResolution {
|
||||
pub fn to_wgsl(&self, gctx: &GlobalCtx) -> String {
|
||||
match *self {
|
||||
crate::proc::TypeResolution::Handle(handle) => handle.to_wgsl(gctx),
|
||||
crate::proc::TypeResolution::Value(ref inner) => inner.to_wgsl(gctx),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Handle<crate::Type> {
|
||||
/// Formats the type as it is written in wgsl.
|
||||
///
|
||||
/// For example `vec3<f32>`.
|
||||
pub fn to_wgsl(self, gctx: &GlobalCtx) -> String {
|
||||
let ty = &gctx.types[self];
|
||||
match ty.name {
|
||||
Some(ref name) => name.clone(),
|
||||
None => ty.inner.to_wgsl(gctx),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl crate::TypeInner {
|
||||
/// Formats the type as it is written in wgsl.
|
||||
///
|
||||
/// For example `vec3<f32>`.
|
||||
///
|
||||
/// Note: `TypeInner::Struct` doesn't include the name of the
|
||||
/// struct type. Therefore this method will simply return "struct"
|
||||
/// for them.
|
||||
pub fn to_wgsl(&self, gctx: &GlobalCtx) -> String {
|
||||
use crate::TypeInner as Ti;
|
||||
|
||||
match *self {
|
||||
Ti::Scalar(scalar) => scalar.to_wgsl(),
|
||||
Ti::Vector { size, scalar } => {
|
||||
format!("vec{}<{}>", size as u32, scalar.to_wgsl())
|
||||
}
|
||||
Ti::Matrix {
|
||||
columns,
|
||||
rows,
|
||||
width,
|
||||
} => {
|
||||
format!(
|
||||
"mat{}x{}<{}>",
|
||||
columns as u32,
|
||||
rows as u32,
|
||||
crate::Scalar::float(width).to_wgsl(),
|
||||
)
|
||||
}
|
||||
Ti::Atomic(scalar) => {
|
||||
format!("atomic<{}>", scalar.to_wgsl())
|
||||
}
|
||||
Ti::Pointer { base, .. } => {
|
||||
let base = &gctx.types[base];
|
||||
let name = base.name.as_deref().unwrap_or("unknown");
|
||||
format!("ptr<{name}>")
|
||||
}
|
||||
Ti::ValuePointer { scalar, .. } => {
|
||||
format!("ptr<{}>", scalar.to_wgsl())
|
||||
}
|
||||
Ti::Array { base, size, .. } => {
|
||||
let member_type = &gctx.types[base];
|
||||
let base = member_type.name.as_deref().unwrap_or("unknown");
|
||||
match size {
|
||||
crate::ArraySize::Constant(size) => format!("array<{base}, {size}>"),
|
||||
crate::ArraySize::Dynamic => format!("array<{base}>"),
|
||||
}
|
||||
}
|
||||
Ti::Struct { .. } => {
|
||||
// TODO: Actually output the struct?
|
||||
"struct".to_string()
|
||||
}
|
||||
Ti::Image {
|
||||
dim,
|
||||
arrayed,
|
||||
class,
|
||||
} => {
|
||||
let dim_suffix = match dim {
|
||||
crate::ImageDimension::D1 => "_1d",
|
||||
crate::ImageDimension::D2 => "_2d",
|
||||
crate::ImageDimension::D3 => "_3d",
|
||||
crate::ImageDimension::Cube => "_cube",
|
||||
};
|
||||
let array_suffix = if arrayed { "_array" } else { "" };
|
||||
|
||||
let class_suffix = match class {
|
||||
crate::ImageClass::Sampled { multi: true, .. } => "_multisampled",
|
||||
crate::ImageClass::Depth { multi: false } => "_depth",
|
||||
crate::ImageClass::Depth { multi: true } => "_depth_multisampled",
|
||||
crate::ImageClass::Sampled { multi: false, .. }
|
||||
| crate::ImageClass::Storage { .. } => "",
|
||||
};
|
||||
|
||||
let type_in_brackets = match class {
|
||||
crate::ImageClass::Sampled { kind, .. } => {
|
||||
// Note: The only valid widths are 4 bytes wide.
|
||||
// The lexer has already verified this, so we can safely assume it here.
|
||||
// https://gpuweb.github.io/gpuweb/wgsl/#sampled-texture-type
|
||||
let element_type = crate::Scalar { kind, width: 4 }.to_wgsl();
|
||||
format!("<{element_type}>")
|
||||
}
|
||||
crate::ImageClass::Depth { multi: _ } => String::new(),
|
||||
crate::ImageClass::Storage { format, access } => {
|
||||
if access.contains(crate::StorageAccess::STORE) {
|
||||
format!("<{},write>", format.to_wgsl())
|
||||
} else {
|
||||
format!("<{}>", format.to_wgsl())
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
format!("texture{class_suffix}{dim_suffix}{array_suffix}{type_in_brackets}")
|
||||
}
|
||||
Ti::Sampler { .. } => "sampler".to_string(),
|
||||
Ti::AccelerationStructure => "acceleration_structure".to_string(),
|
||||
Ti::RayQuery => "ray_query".to_string(),
|
||||
Ti::BindingArray { base, size, .. } => {
|
||||
let member_type = &gctx.types[base];
|
||||
let base = member_type.name.as_deref().unwrap_or("unknown");
|
||||
match size {
|
||||
crate::ArraySize::Constant(size) => format!("binding_array<{base}, {size}>"),
|
||||
crate::ArraySize::Dynamic => format!("binding_array<{base}>"),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl crate::Scalar {
|
||||
/// Format a scalar kind+width as a type is written in wgsl.
|
||||
///
|
||||
/// Examples: `f32`, `u64`, `bool`.
|
||||
pub fn to_wgsl(self) -> String {
|
||||
let prefix = match self.kind {
|
||||
crate::ScalarKind::Sint => "i",
|
||||
crate::ScalarKind::Uint => "u",
|
||||
crate::ScalarKind::Float => "f",
|
||||
crate::ScalarKind::Bool => return "bool".to_string(),
|
||||
};
|
||||
format!("{}{}", prefix, self.width * 8)
|
||||
}
|
||||
}
|
||||
|
||||
impl crate::StorageFormat {
|
||||
pub const fn to_wgsl(self) -> &'static str {
|
||||
use crate::StorageFormat as Sf;
|
||||
match self {
|
||||
Sf::R8Unorm => "r8unorm",
|
||||
Sf::R8Snorm => "r8snorm",
|
||||
Sf::R8Uint => "r8uint",
|
||||
Sf::R8Sint => "r8sint",
|
||||
Sf::R16Uint => "r16uint",
|
||||
Sf::R16Sint => "r16sint",
|
||||
Sf::R16Float => "r16float",
|
||||
Sf::Rg8Unorm => "rg8unorm",
|
||||
Sf::Rg8Snorm => "rg8snorm",
|
||||
Sf::Rg8Uint => "rg8uint",
|
||||
Sf::Rg8Sint => "rg8sint",
|
||||
Sf::R32Uint => "r32uint",
|
||||
Sf::R32Sint => "r32sint",
|
||||
Sf::R32Float => "r32float",
|
||||
Sf::Rg16Uint => "rg16uint",
|
||||
Sf::Rg16Sint => "rg16sint",
|
||||
Sf::Rg16Float => "rg16float",
|
||||
Sf::Rgba8Unorm => "rgba8unorm",
|
||||
Sf::Rgba8Snorm => "rgba8snorm",
|
||||
Sf::Rgba8Uint => "rgba8uint",
|
||||
Sf::Rgba8Sint => "rgba8sint",
|
||||
Sf::Bgra8Unorm => "bgra8unorm",
|
||||
Sf::Rgb10a2Uint => "rgb10a2uint",
|
||||
Sf::Rgb10a2Unorm => "rgb10a2unorm",
|
||||
Sf::Rg11b10Float => "rg11b10float",
|
||||
Sf::Rg32Uint => "rg32uint",
|
||||
Sf::Rg32Sint => "rg32sint",
|
||||
Sf::Rg32Float => "rg32float",
|
||||
Sf::Rgba16Uint => "rgba16uint",
|
||||
Sf::Rgba16Sint => "rgba16sint",
|
||||
Sf::Rgba16Float => "rgba16float",
|
||||
Sf::Rgba32Uint => "rgba32uint",
|
||||
Sf::Rgba32Sint => "rgba32sint",
|
||||
Sf::Rgba32Float => "rgba32float",
|
||||
Sf::R16Unorm => "r16unorm",
|
||||
Sf::R16Snorm => "r16snorm",
|
||||
Sf::Rg16Unorm => "rg16unorm",
|
||||
Sf::Rg16Snorm => "rg16snorm",
|
||||
Sf::Rgba16Unorm => "rgba16unorm",
|
||||
Sf::Rgba16Snorm => "rgba16snorm",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mod tests {
|
||||
#[test]
|
||||
fn to_wgsl() {
|
||||
use std::num::NonZeroU32;
|
||||
|
||||
let mut types = crate::UniqueArena::new();
|
||||
|
||||
let mytype1 = types.insert(
|
||||
crate::Type {
|
||||
name: Some("MyType1".to_string()),
|
||||
inner: crate::TypeInner::Struct {
|
||||
members: vec![],
|
||||
span: 0,
|
||||
},
|
||||
},
|
||||
Default::default(),
|
||||
);
|
||||
let mytype2 = types.insert(
|
||||
crate::Type {
|
||||
name: Some("MyType2".to_string()),
|
||||
inner: crate::TypeInner::Struct {
|
||||
members: vec![],
|
||||
span: 0,
|
||||
},
|
||||
},
|
||||
Default::default(),
|
||||
);
|
||||
|
||||
let gctx = crate::proc::GlobalCtx {
|
||||
types: &types,
|
||||
constants: &crate::Arena::new(),
|
||||
const_expressions: &crate::Arena::new(),
|
||||
};
|
||||
let array = crate::TypeInner::Array {
|
||||
base: mytype1,
|
||||
stride: 4,
|
||||
size: crate::ArraySize::Constant(unsafe { NonZeroU32::new_unchecked(32) }),
|
||||
};
|
||||
assert_eq!(array.to_wgsl(&gctx), "array<MyType1, 32>");
|
||||
|
||||
let mat = crate::TypeInner::Matrix {
|
||||
rows: crate::VectorSize::Quad,
|
||||
columns: crate::VectorSize::Bi,
|
||||
width: 8,
|
||||
};
|
||||
assert_eq!(mat.to_wgsl(&gctx), "mat2x4<f64>");
|
||||
|
||||
let ptr = crate::TypeInner::Pointer {
|
||||
base: mytype2,
|
||||
space: crate::AddressSpace::Storage {
|
||||
access: crate::StorageAccess::default(),
|
||||
},
|
||||
};
|
||||
assert_eq!(ptr.to_wgsl(&gctx), "ptr<MyType2>");
|
||||
|
||||
let img1 = crate::TypeInner::Image {
|
||||
dim: crate::ImageDimension::D2,
|
||||
arrayed: false,
|
||||
class: crate::ImageClass::Sampled {
|
||||
kind: crate::ScalarKind::Float,
|
||||
multi: true,
|
||||
},
|
||||
};
|
||||
assert_eq!(img1.to_wgsl(&gctx), "texture_multisampled_2d<f32>");
|
||||
|
||||
let img2 = crate::TypeInner::Image {
|
||||
dim: crate::ImageDimension::Cube,
|
||||
arrayed: true,
|
||||
class: crate::ImageClass::Depth { multi: false },
|
||||
};
|
||||
assert_eq!(img2.to_wgsl(&gctx), "texture_depth_cube_array");
|
||||
|
||||
let img3 = crate::TypeInner::Image {
|
||||
dim: crate::ImageDimension::D2,
|
||||
arrayed: false,
|
||||
class: crate::ImageClass::Depth { multi: true },
|
||||
};
|
||||
assert_eq!(img3.to_wgsl(&gctx), "texture_depth_multisampled_2d");
|
||||
|
||||
let array = crate::TypeInner::BindingArray {
|
||||
base: mytype1,
|
||||
size: crate::ArraySize::Constant(unsafe { NonZeroU32::new_unchecked(32) }),
|
||||
};
|
||||
assert_eq!(array.to_wgsl(&gctx), "binding_array<MyType1, 32>");
|
||||
}
|
||||
}
|
31
third_party/rust/naga/src/lib.rs
vendored
31
third_party/rust/naga/src/lib.rs
vendored
@ -472,6 +472,19 @@ pub enum ScalarKind {
|
||||
Bool,
|
||||
}
|
||||
|
||||
/// Characteristics of a scalar type.
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
|
||||
#[cfg_attr(feature = "serialize", derive(Serialize))]
|
||||
#[cfg_attr(feature = "deserialize", derive(Deserialize))]
|
||||
#[cfg_attr(feature = "arbitrary", derive(Arbitrary))]
|
||||
pub struct Scalar {
|
||||
/// How the value's bits are to be interpreted.
|
||||
pub kind: ScalarKind,
|
||||
|
||||
/// This size of the value in bytes.
|
||||
pub width: Bytes,
|
||||
}
|
||||
|
||||
/// Size of an array.
|
||||
#[repr(u8)]
|
||||
#[derive(Clone, Copy, Debug, Hash, Eq, Ord, PartialEq, PartialOrd)]
|
||||
@ -677,13 +690,9 @@ pub struct Type {
|
||||
#[cfg_attr(feature = "arbitrary", derive(Arbitrary))]
|
||||
pub enum TypeInner {
|
||||
/// Number of integral or floating-point kind.
|
||||
Scalar { kind: ScalarKind, width: Bytes },
|
||||
Scalar(Scalar),
|
||||
/// Vector of numbers.
|
||||
Vector {
|
||||
size: VectorSize,
|
||||
kind: ScalarKind,
|
||||
width: Bytes,
|
||||
},
|
||||
Vector { size: VectorSize, scalar: Scalar },
|
||||
/// Matrix of floats.
|
||||
Matrix {
|
||||
columns: VectorSize,
|
||||
@ -691,7 +700,7 @@ pub enum TypeInner {
|
||||
width: Bytes,
|
||||
},
|
||||
/// Atomic scalar.
|
||||
Atomic { kind: ScalarKind, width: Bytes },
|
||||
Atomic(Scalar),
|
||||
/// Pointer to another type.
|
||||
///
|
||||
/// Pointers to scalars and vectors should be treated as equivalent to
|
||||
@ -737,8 +746,7 @@ pub enum TypeInner {
|
||||
/// [`TypeResolution::Value`]: proc::TypeResolution::Value
|
||||
ValuePointer {
|
||||
size: Option<VectorSize>,
|
||||
kind: ScalarKind,
|
||||
width: Bytes,
|
||||
scalar: Scalar,
|
||||
space: AddressSpace,
|
||||
},
|
||||
|
||||
@ -1966,10 +1974,7 @@ pub struct EntryPoint {
|
||||
#[cfg_attr(feature = "deserialize", derive(Deserialize))]
|
||||
#[cfg_attr(feature = "arbitrary", derive(Arbitrary))]
|
||||
pub enum PredeclaredType {
|
||||
AtomicCompareExchangeWeakResult {
|
||||
kind: ScalarKind,
|
||||
width: Bytes,
|
||||
},
|
||||
AtomicCompareExchangeWeakResult(Scalar),
|
||||
ModfResult {
|
||||
size: Option<VectorSize>,
|
||||
width: Bytes,
|
||||
|
101
third_party/rust/naga/src/proc/constant_evaluator.rs
vendored
101
third_party/rust/naga/src/proc/constant_evaluator.rs
vendored
@ -404,7 +404,7 @@ impl<'a> ConstantEvaluator<'a> {
|
||||
let expr = self.check_and_get(expr)?;
|
||||
|
||||
match convert {
|
||||
Some(width) => self.cast(expr, kind, width, span),
|
||||
Some(width) => self.cast(expr, crate::Scalar { kind, width }, span),
|
||||
None => Err(ConstantEvaluatorError::NotImplemented(
|
||||
"bitcast built-in function".into(),
|
||||
)),
|
||||
@ -462,12 +462,11 @@ impl<'a> ConstantEvaluator<'a> {
|
||||
) -> Result<Handle<Expression>, ConstantEvaluatorError> {
|
||||
match self.expressions[value] {
|
||||
Expression::Literal(literal) => {
|
||||
let kind = literal.scalar_kind();
|
||||
let width = literal.width();
|
||||
let scalar = literal.scalar();
|
||||
let ty = self.types.insert(
|
||||
Type {
|
||||
name: None,
|
||||
inner: TypeInner::Vector { size, kind, width },
|
||||
inner: TypeInner::Vector { size, scalar },
|
||||
},
|
||||
span,
|
||||
);
|
||||
@ -479,7 +478,7 @@ impl<'a> ConstantEvaluator<'a> {
|
||||
}
|
||||
Expression::ZeroValue(ty) => {
|
||||
let inner = match self.types[ty].inner {
|
||||
TypeInner::Scalar { kind, width } => TypeInner::Vector { size, kind, width },
|
||||
TypeInner::Scalar(scalar) => TypeInner::Vector { size, scalar },
|
||||
_ => return Err(ConstantEvaluatorError::SplatScalarOnly),
|
||||
};
|
||||
let res_ty = self.types.insert(Type { name: None, inner }, span);
|
||||
@ -498,14 +497,10 @@ impl<'a> ConstantEvaluator<'a> {
|
||||
pattern: [crate::SwizzleComponent; 4],
|
||||
) -> Result<Handle<Expression>, ConstantEvaluatorError> {
|
||||
let mut get_dst_ty = |ty| match self.types[ty].inner {
|
||||
crate::TypeInner::Vector {
|
||||
size: _,
|
||||
kind,
|
||||
width,
|
||||
} => Ok(self.types.insert(
|
||||
crate::TypeInner::Vector { size: _, scalar } => Ok(self.types.insert(
|
||||
Type {
|
||||
name: None,
|
||||
inner: crate::TypeInner::Vector { size, kind, width },
|
||||
inner: crate::TypeInner::Vector { size, scalar },
|
||||
},
|
||||
span,
|
||||
)),
|
||||
@ -611,7 +606,10 @@ impl<'a> ConstantEvaluator<'a> {
|
||||
&& matches!(
|
||||
self.types[ty0].inner,
|
||||
crate::TypeInner::Vector {
|
||||
kind: crate::ScalarKind::Float,
|
||||
scalar: crate::Scalar {
|
||||
kind: ScalarKind::Float,
|
||||
..
|
||||
},
|
||||
..
|
||||
}
|
||||
) =>
|
||||
@ -709,7 +707,10 @@ impl<'a> ConstantEvaluator<'a> {
|
||||
&& matches!(
|
||||
self.types[ty0].inner,
|
||||
crate::TypeInner::Vector {
|
||||
kind: crate::ScalarKind::Float,
|
||||
scalar: crate::Scalar {
|
||||
kind: ScalarKind::Float,
|
||||
..
|
||||
},
|
||||
..
|
||||
}
|
||||
) =>
|
||||
@ -831,10 +832,10 @@ impl<'a> ConstantEvaluator<'a> {
|
||||
Expression::ZeroValue(ty)
|
||||
if matches!(
|
||||
self.types[ty].inner,
|
||||
crate::TypeInner::Scalar {
|
||||
kind: crate::ScalarKind::Uint,
|
||||
crate::TypeInner::Scalar(crate::Scalar {
|
||||
kind: ScalarKind::Uint,
|
||||
..
|
||||
}
|
||||
})
|
||||
) =>
|
||||
{
|
||||
Ok(0)
|
||||
@ -873,18 +874,17 @@ impl<'a> ConstantEvaluator<'a> {
|
||||
span: Span,
|
||||
) -> Result<Handle<Expression>, ConstantEvaluatorError> {
|
||||
match self.types[ty].inner {
|
||||
TypeInner::Scalar { kind, width } => {
|
||||
TypeInner::Scalar(scalar) => {
|
||||
let expr = Expression::Literal(
|
||||
Literal::zero(kind, width)
|
||||
.ok_or(ConstantEvaluatorError::TypeNotConstructible)?,
|
||||
Literal::zero(scalar).ok_or(ConstantEvaluatorError::TypeNotConstructible)?,
|
||||
);
|
||||
self.register_evaluated_expr(expr, span)
|
||||
}
|
||||
TypeInner::Vector { size, kind, width } => {
|
||||
TypeInner::Vector { size, scalar } => {
|
||||
let scalar_ty = self.types.insert(
|
||||
Type {
|
||||
name: None,
|
||||
inner: TypeInner::Scalar { kind, width },
|
||||
inner: TypeInner::Scalar(scalar),
|
||||
},
|
||||
span,
|
||||
);
|
||||
@ -905,8 +905,7 @@ impl<'a> ConstantEvaluator<'a> {
|
||||
name: None,
|
||||
inner: TypeInner::Vector {
|
||||
size: rows,
|
||||
kind: ScalarKind::Float,
|
||||
width,
|
||||
scalar: crate::Scalar::float(width),
|
||||
},
|
||||
},
|
||||
span,
|
||||
@ -943,43 +942,44 @@ impl<'a> ConstantEvaluator<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
/// Convert the scalar components of `expr` to `kind` and `target_width`.
|
||||
/// Convert the scalar components of `expr` to `target`.
|
||||
///
|
||||
/// Treat `span` as the location of the resulting expression.
|
||||
pub fn cast(
|
||||
&mut self,
|
||||
expr: Handle<Expression>,
|
||||
kind: ScalarKind,
|
||||
target_width: crate::Bytes,
|
||||
target: crate::Scalar,
|
||||
span: Span,
|
||||
) -> Result<Handle<Expression>, ConstantEvaluatorError> {
|
||||
use crate::Scalar as Sc;
|
||||
|
||||
let expr = self.eval_zero_value_and_splat(expr, span)?;
|
||||
|
||||
let expr = match self.expressions[expr] {
|
||||
Expression::Literal(literal) => {
|
||||
let literal = match (kind, target_width) {
|
||||
(ScalarKind::Sint, 4) => Literal::I32(match literal {
|
||||
let literal = match target {
|
||||
Sc::I32 => Literal::I32(match literal {
|
||||
Literal::I32(v) => v,
|
||||
Literal::U32(v) => v as i32,
|
||||
Literal::F32(v) => v as i32,
|
||||
Literal::Bool(v) => v as i32,
|
||||
Literal::F64(_) => return Err(ConstantEvaluatorError::InvalidCastArg),
|
||||
}),
|
||||
(ScalarKind::Uint, 4) => Literal::U32(match literal {
|
||||
Sc::U32 => Literal::U32(match literal {
|
||||
Literal::I32(v) => v as u32,
|
||||
Literal::U32(v) => v,
|
||||
Literal::F32(v) => v as u32,
|
||||
Literal::Bool(v) => v as u32,
|
||||
Literal::F64(_) => return Err(ConstantEvaluatorError::InvalidCastArg),
|
||||
}),
|
||||
(ScalarKind::Float, 4) => Literal::F32(match literal {
|
||||
Sc::F32 => Literal::F32(match literal {
|
||||
Literal::I32(v) => v as f32,
|
||||
Literal::U32(v) => v as f32,
|
||||
Literal::F32(v) => v,
|
||||
Literal::Bool(v) => v as u32 as f32,
|
||||
Literal::F64(_) => return Err(ConstantEvaluatorError::InvalidCastArg),
|
||||
}),
|
||||
(ScalarKind::Bool, crate::BOOL_WIDTH) => Literal::Bool(match literal {
|
||||
Sc::BOOL => Literal::Bool(match literal {
|
||||
Literal::I32(v) => v != 0,
|
||||
Literal::U32(v) => v != 0,
|
||||
Literal::F32(v) => v != 0.0,
|
||||
@ -997,20 +997,19 @@ impl<'a> ConstantEvaluator<'a> {
|
||||
let ty_inner = match self.types[ty].inner {
|
||||
TypeInner::Vector { size, .. } => TypeInner::Vector {
|
||||
size,
|
||||
kind,
|
||||
width: target_width,
|
||||
scalar: target,
|
||||
},
|
||||
TypeInner::Matrix { columns, rows, .. } => TypeInner::Matrix {
|
||||
columns,
|
||||
rows,
|
||||
width: target_width,
|
||||
width: target.width,
|
||||
},
|
||||
_ => return Err(ConstantEvaluatorError::InvalidCastArg),
|
||||
};
|
||||
|
||||
let mut components = src_components.clone();
|
||||
for component in &mut components {
|
||||
*component = self.cast(*component, kind, target_width, span)?;
|
||||
*component = self.cast(*component, target, span)?;
|
||||
}
|
||||
|
||||
let ty = self.types.insert(
|
||||
@ -1305,10 +1304,7 @@ mod tests {
|
||||
let scalar_ty = types.insert(
|
||||
Type {
|
||||
name: None,
|
||||
inner: TypeInner::Scalar {
|
||||
kind: ScalarKind::Sint,
|
||||
width: 4,
|
||||
},
|
||||
inner: TypeInner::Scalar(crate::Scalar::I32),
|
||||
},
|
||||
Default::default(),
|
||||
);
|
||||
@ -1318,8 +1314,7 @@ mod tests {
|
||||
name: None,
|
||||
inner: TypeInner::Vector {
|
||||
size: VectorSize::Bi,
|
||||
kind: ScalarKind::Sint,
|
||||
width: 4,
|
||||
scalar: crate::Scalar::I32,
|
||||
},
|
||||
},
|
||||
Default::default(),
|
||||
@ -1441,10 +1436,7 @@ mod tests {
|
||||
let scalar_ty = types.insert(
|
||||
Type {
|
||||
name: None,
|
||||
inner: TypeInner::Scalar {
|
||||
kind: ScalarKind::Sint,
|
||||
width: 4,
|
||||
},
|
||||
inner: TypeInner::Scalar(crate::Scalar::I32),
|
||||
},
|
||||
Default::default(),
|
||||
);
|
||||
@ -1509,8 +1501,7 @@ mod tests {
|
||||
name: None,
|
||||
inner: TypeInner::Vector {
|
||||
size: VectorSize::Tri,
|
||||
kind: ScalarKind::Float,
|
||||
width: 4,
|
||||
scalar: crate::Scalar::F32,
|
||||
},
|
||||
},
|
||||
Default::default(),
|
||||
@ -1649,10 +1640,7 @@ mod tests {
|
||||
let i32_ty = types.insert(
|
||||
Type {
|
||||
name: None,
|
||||
inner: TypeInner::Scalar {
|
||||
kind: ScalarKind::Sint,
|
||||
width: 4,
|
||||
},
|
||||
inner: TypeInner::Scalar(crate::Scalar::I32),
|
||||
},
|
||||
Default::default(),
|
||||
);
|
||||
@ -1662,8 +1650,7 @@ mod tests {
|
||||
name: None,
|
||||
inner: TypeInner::Vector {
|
||||
size: VectorSize::Bi,
|
||||
kind: ScalarKind::Sint,
|
||||
width: 4,
|
||||
scalar: crate::Scalar::I32,
|
||||
},
|
||||
},
|
||||
Default::default(),
|
||||
@ -1733,10 +1720,7 @@ mod tests {
|
||||
let i32_ty = types.insert(
|
||||
Type {
|
||||
name: None,
|
||||
inner: TypeInner::Scalar {
|
||||
kind: ScalarKind::Sint,
|
||||
width: 4,
|
||||
},
|
||||
inner: TypeInner::Scalar(crate::Scalar::I32),
|
||||
},
|
||||
Default::default(),
|
||||
);
|
||||
@ -1746,8 +1730,7 @@ mod tests {
|
||||
name: None,
|
||||
inner: TypeInner::Vector {
|
||||
size: VectorSize::Bi,
|
||||
kind: ScalarKind::Sint,
|
||||
width: 4,
|
||||
scalar: crate::Scalar::I32,
|
||||
},
|
||||
},
|
||||
Default::default(),
|
||||
|
9
third_party/rust/naga/src/proc/layouter.rs
vendored
9
third_party/rust/naga/src/proc/layouter.rs
vendored
@ -171,17 +171,16 @@ impl Layouter {
|
||||
for (ty_handle, ty) in gctx.types.iter().skip(self.layouts.len()) {
|
||||
let size = ty.inner.size(gctx);
|
||||
let layout = match ty.inner {
|
||||
Ti::Scalar { width, .. } | Ti::Atomic { width, .. } => {
|
||||
let alignment = Alignment::new(width as u32)
|
||||
Ti::Scalar(scalar) | Ti::Atomic(scalar) => {
|
||||
let alignment = Alignment::new(scalar.width as u32)
|
||||
.ok_or(LayoutErrorInner::NonPowerOfTwoWidth.with(ty_handle))?;
|
||||
TypeLayout { size, alignment }
|
||||
}
|
||||
Ti::Vector {
|
||||
size: vec_size,
|
||||
width,
|
||||
..
|
||||
scalar,
|
||||
} => {
|
||||
let alignment = Alignment::new(width as u32)
|
||||
let alignment = Alignment::new(scalar.width as u32)
|
||||
.ok_or(LayoutErrorInner::NonPowerOfTwoWidth.with(ty_handle))?;
|
||||
TypeLayout {
|
||||
size,
|
||||
|
171
third_party/rust/naga/src/proc/mod.rs
vendored
171
third_party/rust/naga/src/proc/mod.rs
vendored
@ -77,6 +77,52 @@ impl super::ScalarKind {
|
||||
}
|
||||
}
|
||||
|
||||
impl super::Scalar {
|
||||
pub const I32: Self = Self {
|
||||
kind: crate::ScalarKind::Sint,
|
||||
width: 4,
|
||||
};
|
||||
pub const U32: Self = Self {
|
||||
kind: crate::ScalarKind::Uint,
|
||||
width: 4,
|
||||
};
|
||||
pub const F32: Self = Self {
|
||||
kind: crate::ScalarKind::Float,
|
||||
width: 4,
|
||||
};
|
||||
pub const F64: Self = Self {
|
||||
kind: crate::ScalarKind::Float,
|
||||
width: 8,
|
||||
};
|
||||
pub const BOOL: Self = Self {
|
||||
kind: crate::ScalarKind::Bool,
|
||||
width: crate::BOOL_WIDTH,
|
||||
};
|
||||
|
||||
/// Construct a float `Scalar` with the given width.
|
||||
///
|
||||
/// This is especially common when dealing with
|
||||
/// `TypeInner::Matrix`, where the scalar kind is implicit.
|
||||
pub const fn float(width: crate::Bytes) -> Self {
|
||||
Self {
|
||||
kind: crate::ScalarKind::Float,
|
||||
width,
|
||||
}
|
||||
}
|
||||
|
||||
pub const fn to_inner_scalar(self) -> crate::TypeInner {
|
||||
crate::TypeInner::Scalar(self)
|
||||
}
|
||||
|
||||
pub const fn to_inner_vector(self, size: crate::VectorSize) -> crate::TypeInner {
|
||||
crate::TypeInner::Vector { size, scalar: self }
|
||||
}
|
||||
|
||||
pub const fn to_inner_atomic(self) -> crate::TypeInner {
|
||||
crate::TypeInner::Atomic(self)
|
||||
}
|
||||
}
|
||||
|
||||
impl PartialEq for crate::Literal {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
match (*self, *other) {
|
||||
@ -118,8 +164,8 @@ impl std::hash::Hash for crate::Literal {
|
||||
}
|
||||
|
||||
impl crate::Literal {
|
||||
pub const fn new(value: u8, kind: crate::ScalarKind, width: crate::Bytes) -> Option<Self> {
|
||||
match (value, kind, width) {
|
||||
pub const fn new(value: u8, scalar: crate::Scalar) -> Option<Self> {
|
||||
match (value, scalar.kind, scalar.width) {
|
||||
(value, crate::ScalarKind::Float, 8) => Some(Self::F64(value as _)),
|
||||
(value, crate::ScalarKind::Float, 4) => Some(Self::F32(value as _)),
|
||||
(value, crate::ScalarKind::Uint, 4) => Some(Self::U32(value as _)),
|
||||
@ -130,12 +176,12 @@ impl crate::Literal {
|
||||
}
|
||||
}
|
||||
|
||||
pub const fn zero(kind: crate::ScalarKind, width: crate::Bytes) -> Option<Self> {
|
||||
Self::new(0, kind, width)
|
||||
pub const fn zero(scalar: crate::Scalar) -> Option<Self> {
|
||||
Self::new(0, scalar)
|
||||
}
|
||||
|
||||
pub const fn one(kind: crate::ScalarKind, width: crate::Bytes) -> Option<Self> {
|
||||
Self::new(1, kind, width)
|
||||
pub const fn one(scalar: crate::Scalar) -> Option<Self> {
|
||||
Self::new(1, scalar)
|
||||
}
|
||||
|
||||
pub const fn width(&self) -> crate::Bytes {
|
||||
@ -145,44 +191,41 @@ impl crate::Literal {
|
||||
Self::Bool(_) => 1,
|
||||
}
|
||||
}
|
||||
pub const fn scalar_kind(&self) -> crate::ScalarKind {
|
||||
pub const fn scalar(&self) -> crate::Scalar {
|
||||
match *self {
|
||||
Self::F64(_) | Self::F32(_) => crate::ScalarKind::Float,
|
||||
Self::U32(_) => crate::ScalarKind::Uint,
|
||||
Self::I32(_) => crate::ScalarKind::Sint,
|
||||
Self::Bool(_) => crate::ScalarKind::Bool,
|
||||
Self::F64(_) => crate::Scalar::F64,
|
||||
Self::F32(_) => crate::Scalar::F32,
|
||||
Self::U32(_) => crate::Scalar::U32,
|
||||
Self::I32(_) => crate::Scalar::I32,
|
||||
Self::Bool(_) => crate::Scalar::BOOL,
|
||||
}
|
||||
}
|
||||
pub const fn scalar_kind(&self) -> crate::ScalarKind {
|
||||
self.scalar().kind
|
||||
}
|
||||
pub const fn ty_inner(&self) -> crate::TypeInner {
|
||||
crate::TypeInner::Scalar {
|
||||
kind: self.scalar_kind(),
|
||||
width: self.width(),
|
||||
}
|
||||
crate::TypeInner::Scalar(self.scalar())
|
||||
}
|
||||
}
|
||||
|
||||
pub const POINTER_SPAN: u32 = 4;
|
||||
|
||||
impl super::TypeInner {
|
||||
pub const fn scalar_kind(&self) -> Option<super::ScalarKind> {
|
||||
pub const fn scalar(&self) -> Option<super::Scalar> {
|
||||
use crate::TypeInner as Ti;
|
||||
match *self {
|
||||
super::TypeInner::Scalar { kind, .. } | super::TypeInner::Vector { kind, .. } => {
|
||||
Some(kind)
|
||||
}
|
||||
super::TypeInner::Matrix { .. } => Some(super::ScalarKind::Float),
|
||||
Ti::Scalar(scalar) | Ti::Vector { scalar, .. } => Some(scalar),
|
||||
Ti::Matrix { width, .. } => Some(super::Scalar::float(width)),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
pub const fn scalar_width(&self) -> Option<u8> {
|
||||
// Multiply by 8 to get the bit width
|
||||
match *self {
|
||||
super::TypeInner::Scalar { width, .. } | super::TypeInner::Vector { width, .. } => {
|
||||
Some(width * 8)
|
||||
}
|
||||
super::TypeInner::Matrix { width, .. } => Some(width * 8),
|
||||
_ => None,
|
||||
}
|
||||
pub fn scalar_kind(&self) -> Option<super::ScalarKind> {
|
||||
self.scalar().map(|scalar| scalar.kind)
|
||||
}
|
||||
|
||||
pub fn scalar_width(&self) -> Option<u8> {
|
||||
self.scalar().map(|scalar| scalar.width * 8)
|
||||
}
|
||||
|
||||
pub const fn pointer_space(&self) -> Option<crate::AddressSpace> {
|
||||
@ -206,12 +249,8 @@ impl super::TypeInner {
|
||||
/// Get the size of this type.
|
||||
pub fn size(&self, _gctx: GlobalCtx) -> u32 {
|
||||
match *self {
|
||||
Self::Scalar { kind: _, width } | Self::Atomic { kind: _, width } => width as u32,
|
||||
Self::Vector {
|
||||
size,
|
||||
kind: _,
|
||||
width,
|
||||
} => size as u32 * width as u32,
|
||||
Self::Scalar(scalar) | Self::Atomic(scalar) => scalar.width as u32,
|
||||
Self::Vector { size, scalar } => size as u32 * scalar.width as u32,
|
||||
// matrices are treated as arrays of aligned columns
|
||||
Self::Matrix {
|
||||
columns,
|
||||
@ -255,16 +294,14 @@ impl super::TypeInner {
|
||||
use crate::TypeInner as Ti;
|
||||
match *self {
|
||||
Ti::Pointer { base, space } => match types[base].inner {
|
||||
Ti::Scalar { kind, width } => Some(Ti::ValuePointer {
|
||||
Ti::Scalar(scalar) => Some(Ti::ValuePointer {
|
||||
size: None,
|
||||
kind,
|
||||
width,
|
||||
scalar,
|
||||
space,
|
||||
}),
|
||||
Ti::Vector { size, kind, width } => Some(Ti::ValuePointer {
|
||||
Ti::Vector { size, scalar } => Some(Ti::ValuePointer {
|
||||
size: Some(size),
|
||||
kind,
|
||||
width,
|
||||
scalar,
|
||||
space,
|
||||
}),
|
||||
_ => None,
|
||||
@ -318,13 +355,10 @@ impl super::TypeInner {
|
||||
|
||||
pub fn component_type(&self, index: usize) -> Option<TypeResolution> {
|
||||
Some(match *self {
|
||||
Self::Vector { kind, width, .. } => {
|
||||
TypeResolution::Value(crate::TypeInner::Scalar { kind, width })
|
||||
}
|
||||
Self::Vector { scalar, .. } => TypeResolution::Value(crate::TypeInner::Scalar(scalar)),
|
||||
Self::Matrix { rows, width, .. } => TypeResolution::Value(crate::TypeInner::Vector {
|
||||
size: rows,
|
||||
kind: crate::ScalarKind::Float,
|
||||
width,
|
||||
scalar: crate::Scalar::float(width),
|
||||
}),
|
||||
Self::Array {
|
||||
base,
|
||||
@ -628,7 +662,7 @@ impl GlobalCtx<'_> {
|
||||
match arena[handle] {
|
||||
crate::Expression::Literal(literal) => Some(literal),
|
||||
crate::Expression::ZeroValue(ty) => match gctx.types[ty].inner {
|
||||
crate::TypeInner::Scalar { kind, width } => crate::Literal::zero(kind, width),
|
||||
crate::TypeInner::Scalar(scalar) => crate::Literal::zero(scalar),
|
||||
_ => None,
|
||||
},
|
||||
_ => None,
|
||||
@ -661,17 +695,19 @@ pub fn flatten_compose<'arenas>(
|
||||
expressions: &'arenas crate::Arena<crate::Expression>,
|
||||
types: &'arenas crate::UniqueArena<crate::Type>,
|
||||
) -> impl Iterator<Item = crate::Handle<crate::Expression>> + 'arenas {
|
||||
// Returning `impl Iterator` is a bit tricky. We may or may not want to
|
||||
// flatten the components, but we have to settle on a single concrete
|
||||
// type to return. The below is a single iterator chain that handles
|
||||
// both the flattening and non-flattening cases.
|
||||
// Returning `impl Iterator` is a bit tricky. We may or may not
|
||||
// want to flatten the components, but we have to settle on a
|
||||
// single concrete type to return. This function returns a single
|
||||
// iterator chain that handles both the flattening and
|
||||
// non-flattening cases.
|
||||
let (size, is_vector) = if let crate::TypeInner::Vector { size, .. } = types[ty].inner {
|
||||
(size as usize, true)
|
||||
} else {
|
||||
(components.len(), false)
|
||||
};
|
||||
|
||||
fn flattener<'c>(
|
||||
/// Flatten `Compose` expressions if `is_vector` is true.
|
||||
fn flatten_compose<'c>(
|
||||
component: &'c crate::Handle<crate::Expression>,
|
||||
is_vector: bool,
|
||||
expressions: &'c crate::Arena<crate::Expression>,
|
||||
@ -688,14 +724,35 @@ pub fn flatten_compose<'arenas>(
|
||||
std::slice::from_ref(component)
|
||||
}
|
||||
|
||||
// Expressions like `vec4(vec3(vec2(6, 7), 8), 9)` require us to flatten
|
||||
// two levels.
|
||||
/// Flatten `Splat` expressions if `is_vector` is true.
|
||||
fn flatten_splat<'c>(
|
||||
component: &'c crate::Handle<crate::Expression>,
|
||||
is_vector: bool,
|
||||
expressions: &'c crate::Arena<crate::Expression>,
|
||||
) -> impl Iterator<Item = crate::Handle<crate::Expression>> {
|
||||
let mut expr = *component;
|
||||
let mut count = 1;
|
||||
if is_vector {
|
||||
if let crate::Expression::Splat { size, value } = expressions[expr] {
|
||||
expr = value;
|
||||
count = size as usize;
|
||||
}
|
||||
}
|
||||
std::iter::repeat(expr).take(count)
|
||||
}
|
||||
|
||||
// Expressions like `vec4(vec3(vec2(6, 7), 8), 9)` require us to
|
||||
// flatten up to two levels of `Compose` expressions.
|
||||
//
|
||||
// Expressions like `vec4(vec3(1.0), 1.0)` require us to flatten
|
||||
// `Splat` expressions. Fortunately, the operand of a `Splat` must
|
||||
// be a scalar, so we can stop there.
|
||||
components
|
||||
.iter()
|
||||
.flat_map(move |component| flattener(component, is_vector, expressions))
|
||||
.flat_map(move |component| flattener(component, is_vector, expressions))
|
||||
.flat_map(move |component| flatten_compose(component, is_vector, expressions))
|
||||
.flat_map(move |component| flatten_compose(component, is_vector, expressions))
|
||||
.flat_map(move |component| flatten_splat(component, is_vector, expressions))
|
||||
.take(size)
|
||||
.cloned()
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
241
third_party/rust/naga/src/proc/typifier.rs
vendored
241
third_party/rust/naga/src/proc/typifier.rs
vendored
@ -119,8 +119,8 @@ impl Clone for TypeResolution {
|
||||
match *self {
|
||||
Self::Handle(handle) => Self::Handle(handle),
|
||||
Self::Value(ref v) => Self::Value(match *v {
|
||||
Ti::Scalar { kind, width } => Ti::Scalar { kind, width },
|
||||
Ti::Vector { size, kind, width } => Ti::Vector { size, kind, width },
|
||||
Ti::Scalar(scalar) => Ti::Scalar(scalar),
|
||||
Ti::Vector { size, scalar } => Ti::Vector { size, scalar },
|
||||
Ti::Matrix {
|
||||
rows,
|
||||
columns,
|
||||
@ -133,13 +133,11 @@ impl Clone for TypeResolution {
|
||||
Ti::Pointer { base, space } => Ti::Pointer { base, space },
|
||||
Ti::ValuePointer {
|
||||
size,
|
||||
kind,
|
||||
width,
|
||||
scalar,
|
||||
space,
|
||||
} => Ti::ValuePointer {
|
||||
size,
|
||||
kind,
|
||||
width,
|
||||
scalar,
|
||||
space,
|
||||
},
|
||||
_ => unreachable!("Unexpected clone type: {:?}", v),
|
||||
@ -243,36 +241,24 @@ impl<'a> ResolveContext<'a> {
|
||||
Ti::Array { base, .. } => TypeResolution::Handle(base),
|
||||
Ti::Matrix { rows, width, .. } => TypeResolution::Value(Ti::Vector {
|
||||
size: rows,
|
||||
kind: crate::ScalarKind::Float,
|
||||
width,
|
||||
scalar: crate::Scalar::float(width),
|
||||
}),
|
||||
Ti::Vector {
|
||||
size: _,
|
||||
kind,
|
||||
width,
|
||||
} => TypeResolution::Value(Ti::Scalar { kind, width }),
|
||||
Ti::Vector { size: _, scalar } => TypeResolution::Value(Ti::Scalar(scalar)),
|
||||
Ti::ValuePointer {
|
||||
size: Some(_),
|
||||
kind,
|
||||
width,
|
||||
scalar,
|
||||
space,
|
||||
} => TypeResolution::Value(Ti::ValuePointer {
|
||||
size: None,
|
||||
kind,
|
||||
width,
|
||||
scalar,
|
||||
space,
|
||||
}),
|
||||
Ti::Pointer { base, space } => {
|
||||
TypeResolution::Value(match types[base].inner {
|
||||
Ti::Array { base, .. } => Ti::Pointer { base, space },
|
||||
Ti::Vector {
|
||||
size: _,
|
||||
kind,
|
||||
width,
|
||||
} => Ti::ValuePointer {
|
||||
Ti::Vector { size: _, scalar } => Ti::ValuePointer {
|
||||
size: None,
|
||||
kind,
|
||||
width,
|
||||
scalar,
|
||||
space,
|
||||
},
|
||||
// Matrices are only dynamically indexed behind a pointer
|
||||
@ -281,9 +267,8 @@ impl<'a> ResolveContext<'a> {
|
||||
rows,
|
||||
width,
|
||||
} => Ti::ValuePointer {
|
||||
kind: crate::ScalarKind::Float,
|
||||
size: Some(rows),
|
||||
width,
|
||||
scalar: crate::Scalar::float(width),
|
||||
space,
|
||||
},
|
||||
Ti::BindingArray { base, .. } => Ti::Pointer { base, space },
|
||||
@ -307,11 +292,11 @@ impl<'a> ResolveContext<'a> {
|
||||
},
|
||||
crate::Expression::AccessIndex { base, index } => {
|
||||
match *past(base)?.inner_with(types) {
|
||||
Ti::Vector { size, kind, width } => {
|
||||
Ti::Vector { size, scalar } => {
|
||||
if index >= size as u32 {
|
||||
return Err(ResolveError::OutOfBoundsIndex { expr: base, index });
|
||||
}
|
||||
TypeResolution::Value(Ti::Scalar { kind, width })
|
||||
TypeResolution::Value(Ti::Scalar(scalar))
|
||||
}
|
||||
Ti::Matrix {
|
||||
columns,
|
||||
@ -323,8 +308,7 @@ impl<'a> ResolveContext<'a> {
|
||||
}
|
||||
TypeResolution::Value(crate::TypeInner::Vector {
|
||||
size: rows,
|
||||
kind: crate::ScalarKind::Float,
|
||||
width,
|
||||
scalar: crate::Scalar::float(width),
|
||||
})
|
||||
}
|
||||
Ti::Array { base, .. } => TypeResolution::Handle(base),
|
||||
@ -336,8 +320,7 @@ impl<'a> ResolveContext<'a> {
|
||||
}
|
||||
Ti::ValuePointer {
|
||||
size: Some(size),
|
||||
kind,
|
||||
width,
|
||||
scalar,
|
||||
space,
|
||||
} => {
|
||||
if index >= size as u32 {
|
||||
@ -345,8 +328,7 @@ impl<'a> ResolveContext<'a> {
|
||||
}
|
||||
TypeResolution::Value(Ti::ValuePointer {
|
||||
size: None,
|
||||
kind,
|
||||
width,
|
||||
scalar,
|
||||
space,
|
||||
})
|
||||
}
|
||||
@ -355,14 +337,13 @@ impl<'a> ResolveContext<'a> {
|
||||
space,
|
||||
} => TypeResolution::Value(match types[ty_base].inner {
|
||||
Ti::Array { base, .. } => Ti::Pointer { base, space },
|
||||
Ti::Vector { size, kind, width } => {
|
||||
Ti::Vector { size, scalar } => {
|
||||
if index >= size as u32 {
|
||||
return Err(ResolveError::OutOfBoundsIndex { expr: base, index });
|
||||
}
|
||||
Ti::ValuePointer {
|
||||
size: None,
|
||||
kind,
|
||||
width,
|
||||
scalar,
|
||||
space,
|
||||
}
|
||||
}
|
||||
@ -376,8 +357,7 @@ impl<'a> ResolveContext<'a> {
|
||||
}
|
||||
Ti::ValuePointer {
|
||||
size: Some(rows),
|
||||
kind: crate::ScalarKind::Float,
|
||||
width,
|
||||
scalar: crate::Scalar::float(width),
|
||||
space,
|
||||
}
|
||||
}
|
||||
@ -410,9 +390,7 @@ impl<'a> ResolveContext<'a> {
|
||||
}
|
||||
}
|
||||
crate::Expression::Splat { size, value } => match *past(value)?.inner_with(types) {
|
||||
Ti::Scalar { kind, width } => {
|
||||
TypeResolution::Value(Ti::Vector { size, kind, width })
|
||||
}
|
||||
Ti::Scalar(scalar) => TypeResolution::Value(Ti::Vector { size, scalar }),
|
||||
ref other => {
|
||||
log::error!("Scalar type {:?}", other);
|
||||
return Err(ResolveError::InvalidScalar(value));
|
||||
@ -423,11 +401,9 @@ impl<'a> ResolveContext<'a> {
|
||||
vector,
|
||||
pattern: _,
|
||||
} => match *past(vector)?.inner_with(types) {
|
||||
Ti::Vector {
|
||||
size: _,
|
||||
kind,
|
||||
width,
|
||||
} => TypeResolution::Value(Ti::Vector { size, kind, width }),
|
||||
Ti::Vector { size: _, scalar } => {
|
||||
TypeResolution::Value(Ti::Vector { size, scalar })
|
||||
}
|
||||
ref other => {
|
||||
log::error!("Vector type {:?}", other);
|
||||
return Err(ResolveError::InvalidVector(vector));
|
||||
@ -464,20 +440,19 @@ impl<'a> ResolveContext<'a> {
|
||||
}
|
||||
crate::Expression::Load { pointer } => match *past(pointer)?.inner_with(types) {
|
||||
Ti::Pointer { base, space: _ } => {
|
||||
if let Ti::Atomic { kind, width } = types[base].inner {
|
||||
TypeResolution::Value(Ti::Scalar { kind, width })
|
||||
if let Ti::Atomic(scalar) = types[base].inner {
|
||||
TypeResolution::Value(Ti::Scalar(scalar))
|
||||
} else {
|
||||
TypeResolution::Handle(base)
|
||||
}
|
||||
}
|
||||
Ti::ValuePointer {
|
||||
size,
|
||||
kind,
|
||||
width,
|
||||
scalar,
|
||||
space: _,
|
||||
} => TypeResolution::Value(match size {
|
||||
Some(size) => Ti::Vector { size, kind, width },
|
||||
None => Ti::Scalar { kind, width },
|
||||
Some(size) => Ti::Vector { size, scalar },
|
||||
None => Ti::Scalar(scalar),
|
||||
}),
|
||||
ref other => {
|
||||
log::error!("Pointer type {:?}", other);
|
||||
@ -490,11 +465,13 @@ impl<'a> ResolveContext<'a> {
|
||||
..
|
||||
} => match *past(image)?.inner_with(types) {
|
||||
Ti::Image { class, .. } => TypeResolution::Value(Ti::Vector {
|
||||
kind: match class {
|
||||
crate::ImageClass::Sampled { kind, multi: _ } => kind,
|
||||
_ => crate::ScalarKind::Float,
|
||||
scalar: crate::Scalar {
|
||||
kind: match class {
|
||||
crate::ImageClass::Sampled { kind, multi: _ } => kind,
|
||||
_ => crate::ScalarKind::Float,
|
||||
},
|
||||
width: 4,
|
||||
},
|
||||
width: 4,
|
||||
size: crate::VectorSize::Quad,
|
||||
}),
|
||||
ref other => {
|
||||
@ -505,18 +482,16 @@ impl<'a> ResolveContext<'a> {
|
||||
crate::Expression::ImageSample { image, .. }
|
||||
| crate::Expression::ImageLoad { image, .. } => match *past(image)?.inner_with(types) {
|
||||
Ti::Image { class, .. } => TypeResolution::Value(match class {
|
||||
crate::ImageClass::Depth { multi: _ } => Ti::Scalar {
|
||||
kind: crate::ScalarKind::Float,
|
||||
width: 4,
|
||||
},
|
||||
crate::ImageClass::Depth { multi: _ } => Ti::Scalar(crate::Scalar::F32),
|
||||
crate::ImageClass::Sampled { kind, multi: _ } => Ti::Vector {
|
||||
kind,
|
||||
width: 4,
|
||||
scalar: crate::Scalar { kind, width: 4 },
|
||||
size: crate::VectorSize::Quad,
|
||||
},
|
||||
crate::ImageClass::Storage { format, .. } => Ti::Vector {
|
||||
kind: format.into(),
|
||||
width: 4,
|
||||
scalar: crate::Scalar {
|
||||
kind: format.into(),
|
||||
width: 4,
|
||||
},
|
||||
size: crate::VectorSize::Quad,
|
||||
},
|
||||
}),
|
||||
@ -528,19 +503,14 @@ impl<'a> ResolveContext<'a> {
|
||||
crate::Expression::ImageQuery { image, query } => TypeResolution::Value(match query {
|
||||
crate::ImageQuery::Size { level: _ } => match *past(image)?.inner_with(types) {
|
||||
Ti::Image { dim, .. } => match dim {
|
||||
crate::ImageDimension::D1 => Ti::Scalar {
|
||||
kind: crate::ScalarKind::Uint,
|
||||
width: 4,
|
||||
},
|
||||
crate::ImageDimension::D1 => Ti::Scalar(crate::Scalar::U32),
|
||||
crate::ImageDimension::D2 | crate::ImageDimension::Cube => Ti::Vector {
|
||||
size: crate::VectorSize::Bi,
|
||||
kind: crate::ScalarKind::Uint,
|
||||
width: 4,
|
||||
scalar: crate::Scalar::U32,
|
||||
},
|
||||
crate::ImageDimension::D3 => Ti::Vector {
|
||||
size: crate::VectorSize::Tri,
|
||||
kind: crate::ScalarKind::Uint,
|
||||
width: 4,
|
||||
scalar: crate::Scalar::U32,
|
||||
},
|
||||
},
|
||||
ref other => {
|
||||
@ -550,10 +520,7 @@ impl<'a> ResolveContext<'a> {
|
||||
},
|
||||
crate::ImageQuery::NumLevels
|
||||
| crate::ImageQuery::NumLayers
|
||||
| crate::ImageQuery::NumSamples => Ti::Scalar {
|
||||
kind: crate::ScalarKind::Uint,
|
||||
width: 4,
|
||||
},
|
||||
| crate::ImageQuery::NumSamples => Ti::Scalar(crate::Scalar::U32),
|
||||
}),
|
||||
crate::Expression::Unary { expr, .. } => past(expr)?.clone(),
|
||||
crate::Expression::Binary { op, left, right } => match op {
|
||||
@ -585,8 +552,7 @@ impl<'a> ResolveContext<'a> {
|
||||
&Ti::Vector { .. },
|
||||
) => TypeResolution::Value(Ti::Vector {
|
||||
size: rows,
|
||||
kind: crate::ScalarKind::Float,
|
||||
width,
|
||||
scalar: crate::Scalar::float(width),
|
||||
}),
|
||||
(
|
||||
&Ti::Vector { .. },
|
||||
@ -597,8 +563,7 @@ impl<'a> ResolveContext<'a> {
|
||||
},
|
||||
) => TypeResolution::Value(Ti::Vector {
|
||||
size: columns,
|
||||
kind: crate::ScalarKind::Float,
|
||||
width,
|
||||
scalar: crate::Scalar::float(width),
|
||||
}),
|
||||
(&Ti::Scalar { .. }, _) => res_right.clone(),
|
||||
(_, &Ti::Scalar { .. }) => res_left.clone(),
|
||||
@ -618,11 +583,10 @@ impl<'a> ResolveContext<'a> {
|
||||
| crate::BinaryOperator::GreaterEqual
|
||||
| crate::BinaryOperator::LogicalAnd
|
||||
| crate::BinaryOperator::LogicalOr => {
|
||||
let kind = crate::ScalarKind::Bool;
|
||||
let width = crate::BOOL_WIDTH;
|
||||
let scalar = crate::Scalar::BOOL;
|
||||
let inner = match *past(left)?.inner_with(types) {
|
||||
Ti::Scalar { .. } => Ti::Scalar { kind, width },
|
||||
Ti::Vector { size, .. } => Ti::Vector { size, kind, width },
|
||||
Ti::Scalar { .. } => Ti::Scalar(scalar),
|
||||
Ti::Vector { size, .. } => Ti::Vector { size, scalar },
|
||||
ref other => {
|
||||
return Err(ResolveError::IncompatibleOperands(format!(
|
||||
"{op:?}({other:?}, _)"
|
||||
@ -643,20 +607,13 @@ impl<'a> ResolveContext<'a> {
|
||||
crate::Expression::Derivative { expr, .. } => past(expr)?.clone(),
|
||||
crate::Expression::Relational { fun, argument } => match fun {
|
||||
crate::RelationalFunction::All | crate::RelationalFunction::Any => {
|
||||
TypeResolution::Value(Ti::Scalar {
|
||||
kind: crate::ScalarKind::Bool,
|
||||
width: crate::BOOL_WIDTH,
|
||||
})
|
||||
TypeResolution::Value(Ti::Scalar(crate::Scalar::BOOL))
|
||||
}
|
||||
crate::RelationalFunction::IsNan | crate::RelationalFunction::IsInf => {
|
||||
match *past(argument)?.inner_with(types) {
|
||||
Ti::Scalar { .. } => TypeResolution::Value(Ti::Scalar {
|
||||
kind: crate::ScalarKind::Bool,
|
||||
width: crate::BOOL_WIDTH,
|
||||
}),
|
||||
Ti::Scalar { .. } => TypeResolution::Value(Ti::Scalar(crate::Scalar::BOOL)),
|
||||
Ti::Vector { size, .. } => TypeResolution::Value(Ti::Vector {
|
||||
kind: crate::ScalarKind::Bool,
|
||||
width: crate::BOOL_WIDTH,
|
||||
scalar: crate::Scalar::BOOL,
|
||||
size,
|
||||
}),
|
||||
ref other => {
|
||||
@ -714,14 +671,16 @@ impl<'a> ResolveContext<'a> {
|
||||
Mf::Pow => res_arg.clone(),
|
||||
Mf::Modf | Mf::Frexp => {
|
||||
let (size, width) = match res_arg.inner_with(types) {
|
||||
&Ti::Scalar {
|
||||
&Ti::Scalar(crate::Scalar {
|
||||
kind: crate::ScalarKind::Float,
|
||||
width,
|
||||
} => (None, width),
|
||||
&Ti::Vector {
|
||||
kind: crate::ScalarKind::Float,
|
||||
size,
|
||||
width,
|
||||
}) => (None, width),
|
||||
&Ti::Vector {
|
||||
scalar: crate::Scalar {
|
||||
kind: crate::ScalarKind::Float,
|
||||
width,
|
||||
},
|
||||
size,
|
||||
} => (Some(size), width),
|
||||
ref other =>
|
||||
return Err(ResolveError::IncompatibleOperands(format!("{fun:?}({other:?}, _)")))
|
||||
@ -740,10 +699,9 @@ impl<'a> ResolveContext<'a> {
|
||||
// geometry
|
||||
Mf::Dot => match *res_arg.inner_with(types) {
|
||||
Ti::Vector {
|
||||
kind,
|
||||
size: _,
|
||||
width,
|
||||
} => TypeResolution::Value(Ti::Scalar { kind, width }),
|
||||
scalar,
|
||||
} => TypeResolution::Value(Ti::Scalar(scalar)),
|
||||
ref other =>
|
||||
return Err(ResolveError::IncompatibleOperands(
|
||||
format!("{fun:?}({other:?}, _)")
|
||||
@ -754,7 +712,14 @@ impl<'a> ResolveContext<'a> {
|
||||
format!("{fun:?}(_, None)")
|
||||
))?;
|
||||
match (res_arg.inner_with(types), past(arg1)?.inner_with(types)) {
|
||||
(&Ti::Vector {kind: _, size: columns,width}, &Ti::Vector{ size: rows, .. }) => TypeResolution::Value(Ti::Matrix { columns, rows, width }),
|
||||
(
|
||||
&Ti::Vector { size: columns, scalar },
|
||||
&Ti::Vector{ size: rows, .. }
|
||||
) => TypeResolution::Value(Ti::Matrix {
|
||||
columns,
|
||||
rows,
|
||||
width: scalar.width
|
||||
}),
|
||||
(left, right) =>
|
||||
return Err(ResolveError::IncompatibleOperands(
|
||||
format!("{fun:?}({left:?}, {right:?})")
|
||||
@ -764,8 +729,8 @@ impl<'a> ResolveContext<'a> {
|
||||
Mf::Cross => res_arg.clone(),
|
||||
Mf::Distance |
|
||||
Mf::Length => match *res_arg.inner_with(types) {
|
||||
Ti::Scalar {width,kind} |
|
||||
Ti::Vector {width,kind,size:_} => TypeResolution::Value(Ti::Scalar { kind, width }),
|
||||
Ti::Scalar(scalar) |
|
||||
Ti::Vector {scalar,size:_} => TypeResolution::Value(Ti::Scalar(scalar)),
|
||||
ref other => return Err(ResolveError::IncompatibleOperands(
|
||||
format!("{fun:?}({other:?})")
|
||||
)),
|
||||
@ -814,7 +779,7 @@ impl<'a> ResolveContext<'a> {
|
||||
Ti::Matrix {
|
||||
width,
|
||||
..
|
||||
} => TypeResolution::Value(Ti::Scalar { kind: crate::ScalarKind::Float, width }),
|
||||
} => TypeResolution::Value(Ti::Scalar(crate::Scalar::float(width))),
|
||||
ref other => return Err(ResolveError::IncompatibleOperands(
|
||||
format!("{fun:?}({other:?})")
|
||||
)),
|
||||
@ -828,10 +793,17 @@ impl<'a> ResolveContext<'a> {
|
||||
Mf::InsertBits |
|
||||
Mf::FindLsb |
|
||||
Mf::FindMsb => match *res_arg.inner_with(types) {
|
||||
Ti::Scalar { kind: kind @ (crate::ScalarKind::Sint | crate::ScalarKind::Uint), width } =>
|
||||
TypeResolution::Value(Ti::Scalar { kind, width }),
|
||||
Ti::Vector { size, kind: kind @ (crate::ScalarKind::Sint | crate::ScalarKind::Uint), width } =>
|
||||
TypeResolution::Value(Ti::Vector { size, kind, width }),
|
||||
Ti::Scalar(scalar @ crate::Scalar {
|
||||
kind: crate::ScalarKind::Sint | crate::ScalarKind::Uint,
|
||||
..
|
||||
}) => TypeResolution::Value(Ti::Scalar(scalar)),
|
||||
Ti::Vector {
|
||||
size,
|
||||
scalar: scalar @ crate::Scalar {
|
||||
kind: crate::ScalarKind::Sint | crate::ScalarKind::Uint,
|
||||
..
|
||||
}
|
||||
} => TypeResolution::Value(Ti::Vector { size, scalar }),
|
||||
ref other => return Err(ResolveError::IncompatibleOperands(
|
||||
format!("{fun:?}({other:?})")
|
||||
)),
|
||||
@ -841,13 +813,19 @@ impl<'a> ResolveContext<'a> {
|
||||
Mf::Pack4x8unorm |
|
||||
Mf::Pack2x16snorm |
|
||||
Mf::Pack2x16unorm |
|
||||
Mf::Pack2x16float => TypeResolution::Value(Ti::Scalar { kind: crate::ScalarKind::Uint, width: 4 }),
|
||||
Mf::Pack2x16float => TypeResolution::Value(Ti::Scalar(crate::Scalar::U32)),
|
||||
// data unpacking
|
||||
Mf::Unpack4x8snorm |
|
||||
Mf::Unpack4x8unorm => TypeResolution::Value(Ti::Vector { size: crate::VectorSize::Quad, kind: crate::ScalarKind::Float, width: 4 }),
|
||||
Mf::Unpack4x8unorm => TypeResolution::Value(Ti::Vector {
|
||||
size: crate::VectorSize::Quad,
|
||||
scalar: crate::Scalar::F32
|
||||
}),
|
||||
Mf::Unpack2x16snorm |
|
||||
Mf::Unpack2x16unorm |
|
||||
Mf::Unpack2x16float => TypeResolution::Value(Ti::Vector { size: crate::VectorSize::Bi, kind: crate::ScalarKind::Float, width: 4 }),
|
||||
Mf::Unpack2x16float => TypeResolution::Value(Ti::Vector {
|
||||
size: crate::VectorSize::Bi,
|
||||
scalar: crate::Scalar::F32
|
||||
}),
|
||||
}
|
||||
}
|
||||
crate::Expression::As {
|
||||
@ -855,18 +833,21 @@ impl<'a> ResolveContext<'a> {
|
||||
kind,
|
||||
convert,
|
||||
} => match *past(expr)?.inner_with(types) {
|
||||
Ti::Scalar { kind: _, width } => TypeResolution::Value(Ti::Scalar {
|
||||
kind,
|
||||
width: convert.unwrap_or(width),
|
||||
}),
|
||||
Ti::Scalar(crate::Scalar { width, .. }) => {
|
||||
TypeResolution::Value(Ti::Scalar(crate::Scalar {
|
||||
kind,
|
||||
width: convert.unwrap_or(width),
|
||||
}))
|
||||
}
|
||||
Ti::Vector {
|
||||
kind: _,
|
||||
size,
|
||||
width,
|
||||
scalar: crate::Scalar { kind: _, width },
|
||||
} => TypeResolution::Value(Ti::Vector {
|
||||
kind,
|
||||
size,
|
||||
width: convert.unwrap_or(width),
|
||||
scalar: crate::Scalar {
|
||||
kind,
|
||||
width: convert.unwrap_or(width),
|
||||
},
|
||||
}),
|
||||
Ti::Matrix {
|
||||
columns,
|
||||
@ -890,14 +871,12 @@ impl<'a> ResolveContext<'a> {
|
||||
.ok_or(ResolveError::FunctionReturnsVoid)?;
|
||||
TypeResolution::Handle(result.ty)
|
||||
}
|
||||
crate::Expression::ArrayLength(_) => TypeResolution::Value(Ti::Scalar {
|
||||
kind: crate::ScalarKind::Uint,
|
||||
width: 4,
|
||||
}),
|
||||
crate::Expression::RayQueryProceedResult => TypeResolution::Value(Ti::Scalar {
|
||||
kind: crate::ScalarKind::Bool,
|
||||
width: crate::BOOL_WIDTH,
|
||||
}),
|
||||
crate::Expression::ArrayLength(_) => {
|
||||
TypeResolution::Value(Ti::Scalar(crate::Scalar::U32))
|
||||
}
|
||||
crate::Expression::RayQueryProceedResult => {
|
||||
TypeResolution::Value(Ti::Scalar(crate::Scalar::BOOL))
|
||||
}
|
||||
crate::Expression::RayQueryGetIntersection { .. } => {
|
||||
let result = self
|
||||
.special_types
|
||||
|
7
third_party/rust/naga/src/valid/analyzer.rs
vendored
7
third_party/rust/naga/src/valid/analyzer.rs
vendored
@ -159,10 +159,10 @@ impl ExpressionInfo {
|
||||
ref_count: 0,
|
||||
assignable_global: None,
|
||||
// this doesn't matter at this point, will be overwritten
|
||||
ty: TypeResolution::Value(crate::TypeInner::Scalar {
|
||||
ty: TypeResolution::Value(crate::TypeInner::Scalar(crate::Scalar {
|
||||
kind: crate::ScalarKind::Bool,
|
||||
width: 0,
|
||||
}),
|
||||
})),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1070,8 +1070,7 @@ fn uniform_control_flow() {
|
||||
name: None,
|
||||
inner: crate::TypeInner::Vector {
|
||||
size: crate::VectorSize::Bi,
|
||||
kind: crate::ScalarKind::Float,
|
||||
width: 4,
|
||||
scalar: crate::Scalar::F32,
|
||||
},
|
||||
},
|
||||
Default::default(),
|
||||
|
15
third_party/rust/naga/src/valid/compose.rs
vendored
15
third_party/rust/naga/src/valid/compose.rs
vendored
@ -24,19 +24,15 @@ pub fn validate_compose(
|
||||
|
||||
match gctx.types[self_ty_handle].inner {
|
||||
// vectors are composed from scalars or other vectors
|
||||
Ti::Vector { size, kind, width } => {
|
||||
Ti::Vector { size, scalar } => {
|
||||
let mut total = 0;
|
||||
for (index, comp_res) in component_resolutions.enumerate() {
|
||||
total += match *comp_res.inner_with(gctx.types) {
|
||||
Ti::Scalar {
|
||||
kind: comp_kind,
|
||||
width: comp_width,
|
||||
} if comp_kind == kind && comp_width == width => 1,
|
||||
Ti::Scalar(comp_scalar) if comp_scalar == scalar => 1,
|
||||
Ti::Vector {
|
||||
size: comp_size,
|
||||
kind: comp_kind,
|
||||
width: comp_width,
|
||||
} if comp_kind == kind && comp_width == width => comp_size as u32,
|
||||
scalar: comp_scalar,
|
||||
} if comp_scalar == scalar => comp_size as u32,
|
||||
ref other => {
|
||||
log::error!("Vector component[{}] type {:?}", index, other);
|
||||
return Err(ComposeError::ComponentType {
|
||||
@ -60,8 +56,7 @@ pub fn validate_compose(
|
||||
} => {
|
||||
let inner = Ti::Vector {
|
||||
size: rows,
|
||||
kind: crate::ScalarKind::Float,
|
||||
width,
|
||||
scalar: crate::Scalar::float(width),
|
||||
};
|
||||
if columns as usize != component_resolutions.len() {
|
||||
return Err(ComposeError::ComponentCount {
|
||||
|
400
third_party/rust/naga/src/valid/expression.rs
vendored
400
third_party/rust/naga/src/valid/expression.rs
vendored
@ -221,7 +221,7 @@ impl super::Validator {
|
||||
info: &FunctionInfo,
|
||||
mod_info: &ModuleInfo,
|
||||
) -> Result<ShaderStages, ExpressionError> {
|
||||
use crate::{Expression as E, ScalarKind as Sk, TypeInner as Ti};
|
||||
use crate::{Expression as E, Scalar as Sc, ScalarKind as Sk, TypeInner as Ti};
|
||||
|
||||
let resolver = ExpressionTypeResolver {
|
||||
root,
|
||||
@ -246,10 +246,10 @@ impl super::Validator {
|
||||
};
|
||||
match resolver[index] {
|
||||
//TODO: only allow one of these
|
||||
Ti::Scalar {
|
||||
Ti::Scalar(Sc {
|
||||
kind: Sk::Sint | Sk::Uint,
|
||||
width: _,
|
||||
} => {}
|
||||
..
|
||||
}) => {}
|
||||
ref other => {
|
||||
log::error!("Indexing by {:?}", other);
|
||||
return Err(ExpressionError::InvalidIndexType(index));
|
||||
@ -412,10 +412,10 @@ impl super::Validator {
|
||||
}
|
||||
if let Some(expr) = array_index {
|
||||
match resolver[expr] {
|
||||
Ti::Scalar {
|
||||
Ti::Scalar(Sc {
|
||||
kind: Sk::Sint | Sk::Uint,
|
||||
width: _,
|
||||
} => {}
|
||||
..
|
||||
}) => {}
|
||||
_ => return Err(ExpressionError::InvalidImageArrayIndexType(expr)),
|
||||
}
|
||||
}
|
||||
@ -452,13 +452,15 @@ impl super::Validator {
|
||||
crate::ImageDimension::D3 | crate::ImageDimension::Cube => 3,
|
||||
};
|
||||
match resolver[coordinate] {
|
||||
Ti::Scalar {
|
||||
Ti::Scalar(Sc {
|
||||
kind: Sk::Float, ..
|
||||
} if num_components == 1 => {}
|
||||
}) if num_components == 1 => {}
|
||||
Ti::Vector {
|
||||
size,
|
||||
kind: Sk::Float,
|
||||
..
|
||||
scalar:
|
||||
Sc {
|
||||
kind: Sk::Float, ..
|
||||
},
|
||||
} if size as u32 == num_components => {}
|
||||
_ => return Err(ExpressionError::InvalidImageCoordinateType(dim, coordinate)),
|
||||
}
|
||||
@ -466,11 +468,10 @@ impl super::Validator {
|
||||
// check constant offset
|
||||
if let Some(const_expr) = offset {
|
||||
match *mod_info[const_expr].inner_with(&module.types) {
|
||||
Ti::Scalar { kind: Sk::Sint, .. } if num_components == 1 => {}
|
||||
Ti::Scalar(Sc { kind: Sk::Sint, .. }) if num_components == 1 => {}
|
||||
Ti::Vector {
|
||||
size,
|
||||
kind: Sk::Sint,
|
||||
..
|
||||
scalar: Sc { kind: Sk::Sint, .. },
|
||||
} if size as u32 == num_components => {}
|
||||
_ => {
|
||||
return Err(ExpressionError::InvalidSampleOffset(dim, const_expr));
|
||||
@ -481,9 +482,9 @@ impl super::Validator {
|
||||
// check depth reference type
|
||||
if let Some(expr) = depth_ref {
|
||||
match resolver[expr] {
|
||||
Ti::Scalar {
|
||||
Ti::Scalar(Sc {
|
||||
kind: Sk::Float, ..
|
||||
} => {}
|
||||
}) => {}
|
||||
_ => return Err(ExpressionError::InvalidDepthReference(expr)),
|
||||
}
|
||||
match level {
|
||||
@ -518,44 +519,48 @@ impl super::Validator {
|
||||
crate::SampleLevel::Zero => ShaderStages::all(),
|
||||
crate::SampleLevel::Exact(expr) => {
|
||||
match resolver[expr] {
|
||||
Ti::Scalar {
|
||||
Ti::Scalar(Sc {
|
||||
kind: Sk::Float, ..
|
||||
} => {}
|
||||
}) => {}
|
||||
_ => return Err(ExpressionError::InvalidSampleLevelExactType(expr)),
|
||||
}
|
||||
ShaderStages::all()
|
||||
}
|
||||
crate::SampleLevel::Bias(expr) => {
|
||||
match resolver[expr] {
|
||||
Ti::Scalar {
|
||||
Ti::Scalar(Sc {
|
||||
kind: Sk::Float, ..
|
||||
} => {}
|
||||
}) => {}
|
||||
_ => return Err(ExpressionError::InvalidSampleLevelBiasType(expr)),
|
||||
}
|
||||
ShaderStages::FRAGMENT
|
||||
}
|
||||
crate::SampleLevel::Gradient { x, y } => {
|
||||
match resolver[x] {
|
||||
Ti::Scalar {
|
||||
Ti::Scalar(Sc {
|
||||
kind: Sk::Float, ..
|
||||
} if num_components == 1 => {}
|
||||
}) if num_components == 1 => {}
|
||||
Ti::Vector {
|
||||
size,
|
||||
kind: Sk::Float,
|
||||
..
|
||||
scalar:
|
||||
Sc {
|
||||
kind: Sk::Float, ..
|
||||
},
|
||||
} if size as u32 == num_components => {}
|
||||
_ => {
|
||||
return Err(ExpressionError::InvalidSampleLevelGradientType(dim, x))
|
||||
}
|
||||
}
|
||||
match resolver[y] {
|
||||
Ti::Scalar {
|
||||
Ti::Scalar(Sc {
|
||||
kind: Sk::Float, ..
|
||||
} if num_components == 1 => {}
|
||||
}) if num_components == 1 => {}
|
||||
Ti::Vector {
|
||||
size,
|
||||
kind: Sk::Float,
|
||||
..
|
||||
scalar:
|
||||
Sc {
|
||||
kind: Sk::Float, ..
|
||||
},
|
||||
} if size as u32 == num_components => {}
|
||||
_ => {
|
||||
return Err(ExpressionError::InvalidSampleLevelGradientType(dim, y))
|
||||
@ -592,10 +597,10 @@ impl super::Validator {
|
||||
}
|
||||
if let Some(expr) = array_index {
|
||||
match resolver[expr] {
|
||||
Ti::Scalar {
|
||||
Ti::Scalar(Sc {
|
||||
kind: Sk::Sint | Sk::Uint,
|
||||
width: _,
|
||||
} => {}
|
||||
}) => {}
|
||||
_ => return Err(ExpressionError::InvalidImageArrayIndexType(expr)),
|
||||
}
|
||||
}
|
||||
@ -669,7 +674,7 @@ impl super::Validator {
|
||||
let right_inner = &resolver[right];
|
||||
let good = match op {
|
||||
Bo::Add | Bo::Subtract => match *left_inner {
|
||||
Ti::Scalar { kind, .. } | Ti::Vector { kind, .. } => match kind {
|
||||
Ti::Scalar(scalar) | Ti::Vector { scalar, .. } => match scalar.kind {
|
||||
Sk::Uint | Sk::Sint | Sk::Float => left_inner == right_inner,
|
||||
Sk::Bool => false,
|
||||
},
|
||||
@ -677,7 +682,7 @@ impl super::Validator {
|
||||
_ => false,
|
||||
},
|
||||
Bo::Divide | Bo::Modulo => match *left_inner {
|
||||
Ti::Scalar { kind, .. } | Ti::Vector { kind, .. } => match kind {
|
||||
Ti::Scalar(scalar) | Ti::Vector { scalar, .. } => match scalar.kind {
|
||||
Sk::Uint | Sk::Sint | Sk::Float => left_inner == right_inner,
|
||||
Sk::Bool => false,
|
||||
},
|
||||
@ -690,52 +695,62 @@ impl super::Validator {
|
||||
};
|
||||
let types_match = match (left_inner, right_inner) {
|
||||
// Straight scalar and mixed scalar/vector.
|
||||
(&Ti::Scalar { kind: kind1, .. }, &Ti::Scalar { kind: kind2, .. })
|
||||
| (&Ti::Vector { kind: kind1, .. }, &Ti::Scalar { kind: kind2, .. })
|
||||
| (&Ti::Scalar { kind: kind1, .. }, &Ti::Vector { kind: kind2, .. }) => {
|
||||
kind1 == kind2
|
||||
}
|
||||
(&Ti::Scalar(scalar1), &Ti::Scalar(scalar2))
|
||||
| (
|
||||
&Ti::Vector {
|
||||
scalar: scalar1, ..
|
||||
},
|
||||
&Ti::Scalar(scalar2),
|
||||
)
|
||||
| (
|
||||
&Ti::Scalar(scalar1),
|
||||
&Ti::Vector {
|
||||
scalar: scalar2, ..
|
||||
},
|
||||
) => scalar1 == scalar2,
|
||||
// Scalar/matrix.
|
||||
(
|
||||
&Ti::Scalar {
|
||||
&Ti::Scalar(Sc {
|
||||
kind: Sk::Float, ..
|
||||
},
|
||||
}),
|
||||
&Ti::Matrix { .. },
|
||||
)
|
||||
| (
|
||||
&Ti::Matrix { .. },
|
||||
&Ti::Scalar {
|
||||
&Ti::Scalar(Sc {
|
||||
kind: Sk::Float, ..
|
||||
},
|
||||
}),
|
||||
) => true,
|
||||
// Vector/vector.
|
||||
(
|
||||
&Ti::Vector {
|
||||
kind: kind1,
|
||||
size: size1,
|
||||
..
|
||||
scalar: scalar1,
|
||||
},
|
||||
&Ti::Vector {
|
||||
kind: kind2,
|
||||
size: size2,
|
||||
..
|
||||
scalar: scalar2,
|
||||
},
|
||||
) => kind1 == kind2 && size1 == size2,
|
||||
) => scalar1 == scalar2 && size1 == size2,
|
||||
// Matrix * vector.
|
||||
(
|
||||
&Ti::Matrix { columns, .. },
|
||||
&Ti::Vector {
|
||||
kind: Sk::Float,
|
||||
size,
|
||||
..
|
||||
scalar:
|
||||
Sc {
|
||||
kind: Sk::Float, ..
|
||||
},
|
||||
},
|
||||
) => columns == size,
|
||||
// Vector * matrix.
|
||||
(
|
||||
&Ti::Vector {
|
||||
kind: Sk::Float,
|
||||
size,
|
||||
..
|
||||
scalar:
|
||||
Sc {
|
||||
kind: Sk::Float, ..
|
||||
},
|
||||
},
|
||||
&Ti::Matrix { rows, .. },
|
||||
) => size == rows,
|
||||
@ -744,24 +759,14 @@ impl super::Validator {
|
||||
}
|
||||
_ => false,
|
||||
};
|
||||
let left_width = match *left_inner {
|
||||
Ti::Scalar { width, .. }
|
||||
| Ti::Vector { width, .. }
|
||||
| Ti::Matrix { width, .. } => width,
|
||||
_ => 0,
|
||||
};
|
||||
let right_width = match *right_inner {
|
||||
Ti::Scalar { width, .. }
|
||||
| Ti::Vector { width, .. }
|
||||
| Ti::Matrix { width, .. } => width,
|
||||
_ => 0,
|
||||
};
|
||||
let left_width = left_inner.scalar_width().unwrap_or(0);
|
||||
let right_width = right_inner.scalar_width().unwrap_or(0);
|
||||
kind_allowed && types_match && left_width == right_width
|
||||
}
|
||||
Bo::Equal | Bo::NotEqual => left_inner.is_sized() && left_inner == right_inner,
|
||||
Bo::Less | Bo::LessEqual | Bo::Greater | Bo::GreaterEqual => {
|
||||
match *left_inner {
|
||||
Ti::Scalar { kind, .. } | Ti::Vector { kind, .. } => match kind {
|
||||
Ti::Scalar(scalar) | Ti::Vector { scalar, .. } => match scalar.kind {
|
||||
Sk::Uint | Sk::Sint | Sk::Float => left_inner == right_inner,
|
||||
Sk::Bool => false,
|
||||
},
|
||||
@ -772,16 +777,18 @@ impl super::Validator {
|
||||
}
|
||||
}
|
||||
Bo::LogicalAnd | Bo::LogicalOr => match *left_inner {
|
||||
Ti::Scalar { kind: Sk::Bool, .. } | Ti::Vector { kind: Sk::Bool, .. } => {
|
||||
left_inner == right_inner
|
||||
}
|
||||
Ti::Scalar(Sc { kind: Sk::Bool, .. })
|
||||
| Ti::Vector {
|
||||
scalar: Sc { kind: Sk::Bool, .. },
|
||||
..
|
||||
} => left_inner == right_inner,
|
||||
ref other => {
|
||||
log::error!("Op {:?} left type {:?}", op, other);
|
||||
false
|
||||
}
|
||||
},
|
||||
Bo::And | Bo::InclusiveOr => match *left_inner {
|
||||
Ti::Scalar { kind, .. } | Ti::Vector { kind, .. } => match kind {
|
||||
Ti::Scalar(scalar) | Ti::Vector { scalar, .. } => match scalar.kind {
|
||||
Sk::Bool | Sk::Sint | Sk::Uint => left_inner == right_inner,
|
||||
Sk::Float => false,
|
||||
},
|
||||
@ -791,7 +798,7 @@ impl super::Validator {
|
||||
}
|
||||
},
|
||||
Bo::ExclusiveOr => match *left_inner {
|
||||
Ti::Scalar { kind, .. } | Ti::Vector { kind, .. } => match kind {
|
||||
Ti::Scalar(scalar) | Ti::Vector { scalar, .. } => match scalar.kind {
|
||||
Sk::Sint | Sk::Uint => left_inner == right_inner,
|
||||
Sk::Bool | Sk::Float => false,
|
||||
},
|
||||
@ -801,27 +808,26 @@ impl super::Validator {
|
||||
}
|
||||
},
|
||||
Bo::ShiftLeft | Bo::ShiftRight => {
|
||||
let (base_size, base_kind) = match *left_inner {
|
||||
Ti::Scalar { kind, .. } => (Ok(None), kind),
|
||||
Ti::Vector { size, kind, .. } => (Ok(Some(size)), kind),
|
||||
let (base_size, base_scalar) = match *left_inner {
|
||||
Ti::Scalar(scalar) => (Ok(None), scalar),
|
||||
Ti::Vector { size, scalar } => (Ok(Some(size)), scalar),
|
||||
ref other => {
|
||||
log::error!("Op {:?} base type {:?}", op, other);
|
||||
(Err(()), Sk::Bool)
|
||||
(Err(()), Sc::BOOL)
|
||||
}
|
||||
};
|
||||
let shift_size = match *right_inner {
|
||||
Ti::Scalar { kind: Sk::Uint, .. } => Ok(None),
|
||||
Ti::Scalar(Sc { kind: Sk::Uint, .. }) => Ok(None),
|
||||
Ti::Vector {
|
||||
size,
|
||||
kind: Sk::Uint,
|
||||
..
|
||||
scalar: Sc { kind: Sk::Uint, .. },
|
||||
} => Ok(Some(size)),
|
||||
ref other => {
|
||||
log::error!("Op {:?} shift type {:?}", op, other);
|
||||
Err(())
|
||||
}
|
||||
};
|
||||
match base_kind {
|
||||
match base_scalar.kind {
|
||||
Sk::Sint | Sk::Uint => base_size.is_ok() && base_size == shift_size,
|
||||
Sk::Float | Sk::Bool => false,
|
||||
}
|
||||
@ -850,10 +856,10 @@ impl super::Validator {
|
||||
let accept_inner = &resolver[accept];
|
||||
let reject_inner = &resolver[reject];
|
||||
let condition_good = match resolver[condition] {
|
||||
Ti::Scalar {
|
||||
Ti::Scalar(Sc {
|
||||
kind: Sk::Bool,
|
||||
width: _,
|
||||
} => {
|
||||
}) => {
|
||||
// When `condition` is a single boolean, `accept` and
|
||||
// `reject` can be vectors or scalars.
|
||||
match *accept_inner {
|
||||
@ -863,8 +869,11 @@ impl super::Validator {
|
||||
}
|
||||
Ti::Vector {
|
||||
size,
|
||||
kind: Sk::Bool,
|
||||
width: _,
|
||||
scalar:
|
||||
Sc {
|
||||
kind: Sk::Bool,
|
||||
width: _,
|
||||
},
|
||||
} => match *accept_inner {
|
||||
Ti::Vector {
|
||||
size: other_size, ..
|
||||
@ -880,11 +889,15 @@ impl super::Validator {
|
||||
}
|
||||
E::Derivative { expr, .. } => {
|
||||
match resolver[expr] {
|
||||
Ti::Scalar {
|
||||
Ti::Scalar(Sc {
|
||||
kind: Sk::Float, ..
|
||||
}
|
||||
})
|
||||
| Ti::Vector {
|
||||
kind: Sk::Float, ..
|
||||
scalar:
|
||||
Sc {
|
||||
kind: Sk::Float, ..
|
||||
},
|
||||
..
|
||||
} => {}
|
||||
_ => return Err(ExpressionError::InvalidDerivative),
|
||||
}
|
||||
@ -895,19 +908,18 @@ impl super::Validator {
|
||||
let argument_inner = &resolver[argument];
|
||||
match fun {
|
||||
Rf::All | Rf::Any => match *argument_inner {
|
||||
Ti::Vector { kind: Sk::Bool, .. } => {}
|
||||
Ti::Vector {
|
||||
scalar: Sc { kind: Sk::Bool, .. },
|
||||
..
|
||||
} => {}
|
||||
ref other => {
|
||||
log::error!("All/Any of type {:?}", other);
|
||||
return Err(ExpressionError::InvalidBooleanVector(argument));
|
||||
}
|
||||
},
|
||||
Rf::IsNan | Rf::IsInf => match *argument_inner {
|
||||
Ti::Scalar {
|
||||
kind: Sk::Float, ..
|
||||
}
|
||||
| Ti::Vector {
|
||||
kind: Sk::Float, ..
|
||||
} => {}
|
||||
Ti::Scalar(scalar) | Ti::Vector { scalar, .. }
|
||||
if scalar.kind == Sk::Float => {}
|
||||
ref other => {
|
||||
log::error!("Float test of type {:?}", other);
|
||||
return Err(ExpressionError::InvalidFloatArgument(argument));
|
||||
@ -936,7 +948,9 @@ impl super::Validator {
|
||||
return Err(ExpressionError::WrongArgumentCount(fun));
|
||||
}
|
||||
let good = match *arg_ty {
|
||||
Ti::Scalar { kind, .. } | Ti::Vector { kind, .. } => kind != Sk::Bool,
|
||||
Ti::Scalar(scalar) | Ti::Vector { scalar, .. } => {
|
||||
scalar.kind != Sk::Bool
|
||||
}
|
||||
_ => false,
|
||||
};
|
||||
if !good {
|
||||
@ -949,7 +963,9 @@ impl super::Validator {
|
||||
_ => return Err(ExpressionError::WrongArgumentCount(fun)),
|
||||
};
|
||||
let good = match *arg_ty {
|
||||
Ti::Scalar { kind, .. } | Ti::Vector { kind, .. } => kind != Sk::Bool,
|
||||
Ti::Scalar(scalar) | Ti::Vector { scalar, .. } => {
|
||||
scalar.kind != Sk::Bool
|
||||
}
|
||||
_ => false,
|
||||
};
|
||||
if !good {
|
||||
@ -969,7 +985,9 @@ impl super::Validator {
|
||||
_ => return Err(ExpressionError::WrongArgumentCount(fun)),
|
||||
};
|
||||
let good = match *arg_ty {
|
||||
Ti::Scalar { kind, .. } | Ti::Vector { kind, .. } => kind != Sk::Bool,
|
||||
Ti::Scalar(scalar) | Ti::Vector { scalar, .. } => {
|
||||
scalar.kind != Sk::Bool
|
||||
}
|
||||
_ => false,
|
||||
};
|
||||
if !good {
|
||||
@ -1021,12 +1039,8 @@ impl super::Validator {
|
||||
return Err(ExpressionError::WrongArgumentCount(fun));
|
||||
}
|
||||
match *arg_ty {
|
||||
Ti::Scalar {
|
||||
kind: Sk::Float, ..
|
||||
}
|
||||
| Ti::Vector {
|
||||
kind: Sk::Float, ..
|
||||
} => {}
|
||||
Ti::Scalar(scalar) | Ti::Vector { scalar, .. }
|
||||
if scalar.kind == Sk::Float => {}
|
||||
_ => return Err(ExpressionError::InvalidArgumentType(fun, 0, arg)),
|
||||
}
|
||||
}
|
||||
@ -1035,12 +1049,16 @@ impl super::Validator {
|
||||
return Err(ExpressionError::WrongArgumentCount(fun));
|
||||
}
|
||||
match *arg_ty {
|
||||
Ti::Scalar {
|
||||
Ti::Scalar(Sc {
|
||||
kind: Sk::Float | Sk::Sint,
|
||||
..
|
||||
}
|
||||
})
|
||||
| Ti::Vector {
|
||||
kind: Sk::Float | Sk::Sint,
|
||||
scalar:
|
||||
Sc {
|
||||
kind: Sk::Float | Sk::Sint,
|
||||
..
|
||||
},
|
||||
..
|
||||
} => {}
|
||||
_ => return Err(ExpressionError::InvalidArgumentType(fun, 0, arg)),
|
||||
@ -1052,12 +1070,8 @@ impl super::Validator {
|
||||
_ => return Err(ExpressionError::WrongArgumentCount(fun)),
|
||||
};
|
||||
match *arg_ty {
|
||||
Ti::Scalar {
|
||||
kind: Sk::Float, ..
|
||||
}
|
||||
| Ti::Vector {
|
||||
kind: Sk::Float, ..
|
||||
} => {}
|
||||
Ti::Scalar(scalar) | Ti::Vector { scalar, .. }
|
||||
if scalar.kind == Sk::Float => {}
|
||||
_ => return Err(ExpressionError::InvalidArgumentType(fun, 0, arg)),
|
||||
}
|
||||
if arg1_ty != arg_ty {
|
||||
@ -1072,16 +1086,10 @@ impl super::Validator {
|
||||
if arg1_ty.is_some() || arg2_ty.is_some() || arg3_ty.is_some() {
|
||||
return Err(ExpressionError::WrongArgumentCount(fun));
|
||||
}
|
||||
if !matches!(
|
||||
*arg_ty,
|
||||
Ti::Scalar {
|
||||
kind: Sk::Float,
|
||||
..
|
||||
} | Ti::Vector {
|
||||
kind: Sk::Float,
|
||||
..
|
||||
},
|
||||
) {
|
||||
if !matches!(*arg_ty,
|
||||
Ti::Scalar(scalar) | Ti::Vector { scalar, .. }
|
||||
if scalar.kind == Sk::Float)
|
||||
{
|
||||
return Err(ExpressionError::InvalidArgumentType(fun, 1, arg));
|
||||
}
|
||||
}
|
||||
@ -1091,24 +1099,25 @@ impl super::Validator {
|
||||
_ => return Err(ExpressionError::WrongArgumentCount(fun)),
|
||||
};
|
||||
let size0 = match *arg_ty {
|
||||
Ti::Scalar {
|
||||
Ti::Scalar(Sc {
|
||||
kind: Sk::Float, ..
|
||||
} => None,
|
||||
}) => None,
|
||||
Ti::Vector {
|
||||
kind: Sk::Float,
|
||||
scalar:
|
||||
Sc {
|
||||
kind: Sk::Float, ..
|
||||
},
|
||||
size,
|
||||
..
|
||||
} => Some(size),
|
||||
_ => {
|
||||
return Err(ExpressionError::InvalidArgumentType(fun, 0, arg));
|
||||
}
|
||||
};
|
||||
let good = match *arg1_ty {
|
||||
Ti::Scalar { kind: Sk::Sint, .. } if size0.is_none() => true,
|
||||
Ti::Scalar(Sc { kind: Sk::Sint, .. }) if size0.is_none() => true,
|
||||
Ti::Vector {
|
||||
size,
|
||||
kind: Sk::Sint,
|
||||
..
|
||||
scalar: Sc { kind: Sk::Sint, .. },
|
||||
} if Some(size) == size0 => true,
|
||||
_ => false,
|
||||
};
|
||||
@ -1127,7 +1136,11 @@ impl super::Validator {
|
||||
};
|
||||
match *arg_ty {
|
||||
Ti::Vector {
|
||||
kind: Sk::Float | Sk::Sint | Sk::Uint,
|
||||
scalar:
|
||||
Sc {
|
||||
kind: Sk::Float | Sk::Sint | Sk::Uint,
|
||||
..
|
||||
},
|
||||
..
|
||||
} => {}
|
||||
_ => return Err(ExpressionError::InvalidArgumentType(fun, 0, arg)),
|
||||
@ -1147,7 +1160,11 @@ impl super::Validator {
|
||||
};
|
||||
match *arg_ty {
|
||||
Ti::Vector {
|
||||
kind: Sk::Float, ..
|
||||
scalar:
|
||||
Sc {
|
||||
kind: Sk::Float, ..
|
||||
},
|
||||
..
|
||||
} => {}
|
||||
_ => return Err(ExpressionError::InvalidArgumentType(fun, 0, arg)),
|
||||
}
|
||||
@ -1167,7 +1184,11 @@ impl super::Validator {
|
||||
|
||||
match *arg_ty {
|
||||
Ti::Vector {
|
||||
kind: Sk::Float, ..
|
||||
scalar:
|
||||
Sc {
|
||||
kind: Sk::Float, ..
|
||||
},
|
||||
..
|
||||
} => {}
|
||||
_ => return Err(ExpressionError::InvalidArgumentType(fun, 0, arg)),
|
||||
}
|
||||
@ -1183,13 +1204,17 @@ impl super::Validator {
|
||||
match (arg_ty, arg2_ty) {
|
||||
(
|
||||
&Ti::Vector {
|
||||
width: vector_width,
|
||||
scalar:
|
||||
Sc {
|
||||
width: vector_width,
|
||||
..
|
||||
},
|
||||
..
|
||||
},
|
||||
&Ti::Scalar {
|
||||
&Ti::Scalar(Sc {
|
||||
width: scalar_width,
|
||||
kind: Sk::Float,
|
||||
},
|
||||
}),
|
||||
) if vector_width == scalar_width => {}
|
||||
_ => {
|
||||
return Err(ExpressionError::InvalidArgumentType(
|
||||
@ -1206,7 +1231,11 @@ impl super::Validator {
|
||||
}
|
||||
match *arg_ty {
|
||||
Ti::Vector {
|
||||
kind: Sk::Float, ..
|
||||
scalar:
|
||||
Sc {
|
||||
kind: Sk::Float, ..
|
||||
},
|
||||
..
|
||||
} => {}
|
||||
_ => return Err(ExpressionError::InvalidArgumentType(fun, 0, arg)),
|
||||
}
|
||||
@ -1217,11 +1246,15 @@ impl super::Validator {
|
||||
_ => return Err(ExpressionError::WrongArgumentCount(fun)),
|
||||
};
|
||||
match *arg_ty {
|
||||
Ti::Scalar {
|
||||
Ti::Scalar(Sc {
|
||||
kind: Sk::Float, ..
|
||||
}
|
||||
})
|
||||
| Ti::Vector {
|
||||
kind: Sk::Float, ..
|
||||
scalar:
|
||||
Sc {
|
||||
kind: Sk::Float, ..
|
||||
},
|
||||
..
|
||||
} => {}
|
||||
_ => return Err(ExpressionError::InvalidArgumentType(fun, 0, arg)),
|
||||
}
|
||||
@ -1246,13 +1279,16 @@ impl super::Validator {
|
||||
_ => return Err(ExpressionError::WrongArgumentCount(fun)),
|
||||
};
|
||||
let arg_width = match *arg_ty {
|
||||
Ti::Scalar {
|
||||
Ti::Scalar(Sc {
|
||||
kind: Sk::Float,
|
||||
width,
|
||||
}
|
||||
})
|
||||
| Ti::Vector {
|
||||
kind: Sk::Float,
|
||||
width,
|
||||
scalar:
|
||||
Sc {
|
||||
kind: Sk::Float,
|
||||
width,
|
||||
},
|
||||
..
|
||||
} => width,
|
||||
_ => return Err(ExpressionError::InvalidArgumentType(fun, 0, arg)),
|
||||
@ -1266,10 +1302,10 @@ impl super::Validator {
|
||||
}
|
||||
// the last argument can always be a scalar
|
||||
match *arg2_ty {
|
||||
Ti::Scalar {
|
||||
Ti::Scalar(Sc {
|
||||
kind: Sk::Float,
|
||||
width,
|
||||
} if width == arg_width => {}
|
||||
}) if width == arg_width => {}
|
||||
_ if arg2_ty == arg_ty => {}
|
||||
_ => {
|
||||
return Err(ExpressionError::InvalidArgumentType(
|
||||
@ -1311,12 +1347,16 @@ impl super::Validator {
|
||||
return Err(ExpressionError::WrongArgumentCount(fun));
|
||||
}
|
||||
match *arg_ty {
|
||||
Ti::Scalar {
|
||||
Ti::Scalar(Sc {
|
||||
kind: Sk::Sint | Sk::Uint,
|
||||
..
|
||||
}
|
||||
})
|
||||
| Ti::Vector {
|
||||
kind: Sk::Sint | Sk::Uint,
|
||||
scalar:
|
||||
Sc {
|
||||
kind: Sk::Sint | Sk::Uint,
|
||||
..
|
||||
},
|
||||
..
|
||||
} => {}
|
||||
_ => return Err(ExpressionError::InvalidArgumentType(fun, 0, arg)),
|
||||
@ -1328,12 +1368,16 @@ impl super::Validator {
|
||||
_ => return Err(ExpressionError::WrongArgumentCount(fun)),
|
||||
};
|
||||
match *arg_ty {
|
||||
Ti::Scalar {
|
||||
Ti::Scalar(Sc {
|
||||
kind: Sk::Sint | Sk::Uint,
|
||||
..
|
||||
}
|
||||
})
|
||||
| Ti::Vector {
|
||||
kind: Sk::Sint | Sk::Uint,
|
||||
scalar:
|
||||
Sc {
|
||||
kind: Sk::Sint | Sk::Uint,
|
||||
..
|
||||
},
|
||||
..
|
||||
} => {}
|
||||
_ => return Err(ExpressionError::InvalidArgumentType(fun, 0, arg)),
|
||||
@ -1346,7 +1390,7 @@ impl super::Validator {
|
||||
));
|
||||
}
|
||||
match *arg2_ty {
|
||||
Ti::Scalar { kind: Sk::Uint, .. } => {}
|
||||
Ti::Scalar(Sc { kind: Sk::Uint, .. }) => {}
|
||||
_ => {
|
||||
return Err(ExpressionError::InvalidArgumentType(
|
||||
fun,
|
||||
@ -1356,7 +1400,7 @@ impl super::Validator {
|
||||
}
|
||||
}
|
||||
match *arg3_ty {
|
||||
Ti::Scalar { kind: Sk::Uint, .. } => {}
|
||||
Ti::Scalar(Sc { kind: Sk::Uint, .. }) => {}
|
||||
_ => {
|
||||
return Err(ExpressionError::InvalidArgumentType(
|
||||
fun,
|
||||
@ -1372,18 +1416,22 @@ impl super::Validator {
|
||||
_ => return Err(ExpressionError::WrongArgumentCount(fun)),
|
||||
};
|
||||
match *arg_ty {
|
||||
Ti::Scalar {
|
||||
Ti::Scalar(Sc {
|
||||
kind: Sk::Sint | Sk::Uint,
|
||||
..
|
||||
}
|
||||
})
|
||||
| Ti::Vector {
|
||||
kind: Sk::Sint | Sk::Uint,
|
||||
scalar:
|
||||
Sc {
|
||||
kind: Sk::Sint | Sk::Uint,
|
||||
..
|
||||
},
|
||||
..
|
||||
} => {}
|
||||
_ => return Err(ExpressionError::InvalidArgumentType(fun, 0, arg)),
|
||||
}
|
||||
match *arg1_ty {
|
||||
Ti::Scalar { kind: Sk::Uint, .. } => {}
|
||||
Ti::Scalar(Sc { kind: Sk::Uint, .. }) => {}
|
||||
_ => {
|
||||
return Err(ExpressionError::InvalidArgumentType(
|
||||
fun,
|
||||
@ -1393,7 +1441,7 @@ impl super::Validator {
|
||||
}
|
||||
}
|
||||
match *arg2_ty {
|
||||
Ti::Scalar { kind: Sk::Uint, .. } => {}
|
||||
Ti::Scalar(Sc { kind: Sk::Uint, .. }) => {}
|
||||
_ => {
|
||||
return Err(ExpressionError::InvalidArgumentType(
|
||||
fun,
|
||||
@ -1410,8 +1458,10 @@ impl super::Validator {
|
||||
match *arg_ty {
|
||||
Ti::Vector {
|
||||
size: crate::VectorSize::Bi,
|
||||
kind: Sk::Float,
|
||||
..
|
||||
scalar:
|
||||
Sc {
|
||||
kind: Sk::Float, ..
|
||||
},
|
||||
} => {}
|
||||
_ => return Err(ExpressionError::InvalidArgumentType(fun, 0, arg)),
|
||||
}
|
||||
@ -1423,8 +1473,10 @@ impl super::Validator {
|
||||
match *arg_ty {
|
||||
Ti::Vector {
|
||||
size: crate::VectorSize::Quad,
|
||||
kind: Sk::Float,
|
||||
..
|
||||
scalar:
|
||||
Sc {
|
||||
kind: Sk::Float, ..
|
||||
},
|
||||
} => {}
|
||||
_ => return Err(ExpressionError::InvalidArgumentType(fun, 0, arg)),
|
||||
}
|
||||
@ -1438,7 +1490,7 @@ impl super::Validator {
|
||||
return Err(ExpressionError::WrongArgumentCount(fun));
|
||||
}
|
||||
match *arg_ty {
|
||||
Ti::Scalar { kind: Sk::Uint, .. } => {}
|
||||
Ti::Scalar(Sc { kind: Sk::Uint, .. }) => {}
|
||||
_ => return Err(ExpressionError::InvalidArgumentType(fun, 0, arg)),
|
||||
}
|
||||
}
|
||||
@ -1450,14 +1502,18 @@ impl super::Validator {
|
||||
kind,
|
||||
convert,
|
||||
} => {
|
||||
let base_width = match resolver[expr] {
|
||||
crate::TypeInner::Scalar { width, .. }
|
||||
| crate::TypeInner::Vector { width, .. }
|
||||
| crate::TypeInner::Matrix { width, .. } => width,
|
||||
let mut base_scalar = match resolver[expr] {
|
||||
crate::TypeInner::Scalar(scalar) | crate::TypeInner::Vector { scalar, .. } => {
|
||||
scalar
|
||||
}
|
||||
crate::TypeInner::Matrix { width, .. } => crate::Scalar::float(width),
|
||||
_ => return Err(ExpressionError::InvalidCastArgument),
|
||||
};
|
||||
let width = convert.unwrap_or(base_width);
|
||||
if self.check_width(kind, width).is_err() {
|
||||
base_scalar.kind = kind;
|
||||
if let Some(width) = convert {
|
||||
base_scalar.width = width;
|
||||
}
|
||||
if self.check_width(base_scalar).is_err() {
|
||||
return Err(ExpressionError::InvalidCastArgument);
|
||||
}
|
||||
ShaderStages::all()
|
||||
@ -1465,10 +1521,12 @@ impl super::Validator {
|
||||
E::CallResult(function) => mod_info.functions[function.index()].available_stages,
|
||||
E::AtomicResult { ty, comparison } => {
|
||||
let scalar_predicate = |ty: &crate::TypeInner| match ty {
|
||||
&crate::TypeInner::Scalar {
|
||||
kind: kind @ (crate::ScalarKind::Uint | crate::ScalarKind::Sint),
|
||||
width,
|
||||
} => self.check_width(kind, width).is_ok(),
|
||||
&crate::TypeInner::Scalar(
|
||||
scalar @ Sc {
|
||||
kind: crate::ScalarKind::Uint | crate::ScalarKind::Sint,
|
||||
..
|
||||
},
|
||||
) => self.check_width(scalar).is_ok(),
|
||||
_ => false,
|
||||
};
|
||||
let good = match &module.types[ty].inner {
|
||||
@ -1569,9 +1627,7 @@ impl super::Validator {
|
||||
}
|
||||
|
||||
pub fn validate_literal(&self, literal: crate::Literal) -> Result<(), LiteralError> {
|
||||
let kind = literal.scalar_kind();
|
||||
let width = literal.width();
|
||||
self.check_width(kind, width)?;
|
||||
self.check_width(literal.scalar())?;
|
||||
check_literal_value(literal)?;
|
||||
|
||||
Ok(())
|
||||
|
44
third_party/rust/naga/src/valid/function.rs
vendored
44
third_party/rust/naga/src/valid/function.rs
vendored
@ -345,9 +345,9 @@ impl super::Validator {
|
||||
context: &BlockContext,
|
||||
) -> Result<(), WithSpan<FunctionError>> {
|
||||
let pointer_inner = context.resolve_type(pointer, &self.valid_expression_set)?;
|
||||
let (ptr_kind, ptr_width) = match *pointer_inner {
|
||||
let ptr_scalar = match *pointer_inner {
|
||||
crate::TypeInner::Pointer { base, .. } => match context.types[base].inner {
|
||||
crate::TypeInner::Atomic { kind, width } => (kind, width),
|
||||
crate::TypeInner::Atomic(scalar) => scalar,
|
||||
ref other => {
|
||||
log::error!("Atomic pointer to type {:?}", other);
|
||||
return Err(AtomicError::InvalidPointer(pointer)
|
||||
@ -365,7 +365,7 @@ impl super::Validator {
|
||||
|
||||
let value_inner = context.resolve_type(value, &self.valid_expression_set)?;
|
||||
match *value_inner {
|
||||
crate::TypeInner::Scalar { width, kind } if kind == ptr_kind && width == ptr_width => {}
|
||||
crate::TypeInner::Scalar(scalar) if scalar == ptr_scalar => {}
|
||||
ref other => {
|
||||
log::error!("Atomic operand type {:?}", other);
|
||||
return Err(AtomicError::InvalidOperand(value)
|
||||
@ -387,12 +387,8 @@ impl super::Validator {
|
||||
match context.expressions[result] {
|
||||
crate::Expression::AtomicResult { ty, comparison }
|
||||
if {
|
||||
let scalar_predicate = |ty: &crate::TypeInner| {
|
||||
*ty == crate::TypeInner::Scalar {
|
||||
kind: ptr_kind,
|
||||
width: ptr_width,
|
||||
}
|
||||
};
|
||||
let scalar_predicate =
|
||||
|ty: &crate::TypeInner| *ty == crate::TypeInner::Scalar(ptr_scalar);
|
||||
match &context.types[ty].inner {
|
||||
ty if !comparison => scalar_predicate(ty),
|
||||
&crate::TypeInner::Struct { ref members, .. } if comparison => {
|
||||
@ -445,10 +441,10 @@ impl super::Validator {
|
||||
ref reject,
|
||||
} => {
|
||||
match *context.resolve_type(condition, &self.valid_expression_set)? {
|
||||
Ti::Scalar {
|
||||
Ti::Scalar(crate::Scalar {
|
||||
kind: crate::ScalarKind::Bool,
|
||||
width: _,
|
||||
} => {}
|
||||
}) => {}
|
||||
_ => {
|
||||
return Err(FunctionError::InvalidIfType(condition)
|
||||
.with_span_handle(condition, context.expressions))
|
||||
@ -560,10 +556,10 @@ impl super::Validator {
|
||||
|
||||
if let Some(condition) = break_if {
|
||||
match *context.resolve_type(condition, &self.valid_expression_set)? {
|
||||
Ti::Scalar {
|
||||
Ti::Scalar(crate::Scalar {
|
||||
kind: crate::ScalarKind::Bool,
|
||||
width: _,
|
||||
} => {}
|
||||
}) => {}
|
||||
_ => {
|
||||
return Err(FunctionError::InvalidIfType(condition)
|
||||
.with_span_handle(condition, context.expressions))
|
||||
@ -665,21 +661,19 @@ impl super::Validator {
|
||||
|
||||
let good = match *pointer_ty {
|
||||
Ti::Pointer { base, space: _ } => match context.types[base].inner {
|
||||
Ti::Atomic { kind, width } => *value_ty == Ti::Scalar { kind, width },
|
||||
Ti::Atomic(scalar) => *value_ty == Ti::Scalar(scalar),
|
||||
ref other => value_ty == other,
|
||||
},
|
||||
Ti::ValuePointer {
|
||||
size: Some(size),
|
||||
kind,
|
||||
width,
|
||||
scalar,
|
||||
space: _,
|
||||
} => *value_ty == Ti::Vector { size, kind, width },
|
||||
} => *value_ty == Ti::Vector { size, scalar },
|
||||
Ti::ValuePointer {
|
||||
size: None,
|
||||
kind,
|
||||
width,
|
||||
scalar,
|
||||
space: _,
|
||||
} => *value_ty == Ti::Scalar { kind, width },
|
||||
} => *value_ty == Ti::Scalar(scalar),
|
||||
_ => false,
|
||||
};
|
||||
if !good {
|
||||
@ -768,10 +762,10 @@ impl super::Validator {
|
||||
}
|
||||
if let Some(expr) = array_index {
|
||||
match *context.resolve_type(expr, &self.valid_expression_set)? {
|
||||
Ti::Scalar {
|
||||
Ti::Scalar(crate::Scalar {
|
||||
kind: crate::ScalarKind::Sint | crate::ScalarKind::Uint,
|
||||
width: _,
|
||||
} => {}
|
||||
}) => {}
|
||||
_ => {
|
||||
return Err(FunctionError::InvalidImageStore(
|
||||
ExpressionError::InvalidImageArrayIndexType(expr),
|
||||
@ -783,9 +777,11 @@ impl super::Validator {
|
||||
match class {
|
||||
crate::ImageClass::Storage { format, .. } => {
|
||||
crate::TypeInner::Vector {
|
||||
kind: format.into(),
|
||||
size: crate::VectorSize::Quad,
|
||||
width: 4,
|
||||
scalar: crate::Scalar {
|
||||
kind: format.into(),
|
||||
width: 4,
|
||||
},
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
|
5
third_party/rust/naga/src/valid/handles.rs
vendored
5
third_party/rust/naga/src/valid/handles.rs
vendored
@ -678,10 +678,7 @@ fn constant_deps() {
|
||||
let i32_handle = types.insert(
|
||||
Type {
|
||||
name: None,
|
||||
inner: TypeInner::Scalar {
|
||||
kind: crate::ScalarKind::Sint,
|
||||
width: 4,
|
||||
},
|
||||
inner: TypeInner::Scalar(crate::Scalar::I32),
|
||||
},
|
||||
nowhere,
|
||||
);
|
||||
|
74
third_party/rust/naga/src/valid/interface.rs
vendored
74
third_party/rust/naga/src/valid/interface.rs
vendored
@ -142,9 +142,7 @@ impl VaryingContext<'_> {
|
||||
ty: Handle<crate::Type>,
|
||||
binding: &crate::Binding,
|
||||
) -> Result<(), VaryingError> {
|
||||
use crate::{
|
||||
BuiltIn as Bi, ScalarKind as Sk, ShaderStage as St, TypeInner as Ti, VectorSize as Vs,
|
||||
};
|
||||
use crate::{BuiltIn as Bi, ShaderStage as St, TypeInner as Ti, VectorSize as Vs};
|
||||
|
||||
let ty_inner = &self.types[ty].inner;
|
||||
match *binding {
|
||||
@ -174,44 +172,30 @@ impl VaryingContext<'_> {
|
||||
return Err(VaryingError::UnsupportedCapability(required));
|
||||
}
|
||||
|
||||
let width = 4;
|
||||
let (visible, type_good) = match built_in {
|
||||
Bi::BaseInstance | Bi::BaseVertex | Bi::InstanceIndex | Bi::VertexIndex => (
|
||||
self.stage == St::Vertex && !self.output,
|
||||
*ty_inner
|
||||
== Ti::Scalar {
|
||||
kind: Sk::Uint,
|
||||
width,
|
||||
},
|
||||
*ty_inner == Ti::Scalar(crate::Scalar::U32),
|
||||
),
|
||||
Bi::ClipDistance | Bi::CullDistance => (
|
||||
self.stage == St::Vertex && self.output,
|
||||
match *ty_inner {
|
||||
Ti::Array { base, .. } => {
|
||||
self.types[base].inner
|
||||
== Ti::Scalar {
|
||||
kind: Sk::Float,
|
||||
width,
|
||||
}
|
||||
self.types[base].inner == Ti::Scalar(crate::Scalar::F32)
|
||||
}
|
||||
_ => false,
|
||||
},
|
||||
),
|
||||
Bi::PointSize => (
|
||||
self.stage == St::Vertex && self.output,
|
||||
*ty_inner
|
||||
== Ti::Scalar {
|
||||
kind: Sk::Float,
|
||||
width,
|
||||
},
|
||||
*ty_inner == Ti::Scalar(crate::Scalar::F32),
|
||||
),
|
||||
Bi::PointCoord => (
|
||||
self.stage == St::Fragment && !self.output,
|
||||
*ty_inner
|
||||
== Ti::Vector {
|
||||
size: Vs::Bi,
|
||||
kind: Sk::Float,
|
||||
width,
|
||||
scalar: crate::Scalar::F32,
|
||||
},
|
||||
),
|
||||
Bi::Position { .. } => (
|
||||
@ -223,8 +207,7 @@ impl VaryingContext<'_> {
|
||||
*ty_inner
|
||||
== Ti::Vector {
|
||||
size: Vs::Quad,
|
||||
kind: Sk::Float,
|
||||
width,
|
||||
scalar: crate::Scalar::F32,
|
||||
},
|
||||
),
|
||||
Bi::ViewIndex => (
|
||||
@ -232,59 +215,31 @@ impl VaryingContext<'_> {
|
||||
St::Vertex | St::Fragment => !self.output,
|
||||
St::Compute => false,
|
||||
},
|
||||
*ty_inner
|
||||
== Ti::Scalar {
|
||||
kind: Sk::Sint,
|
||||
width,
|
||||
},
|
||||
*ty_inner == Ti::Scalar(crate::Scalar::I32),
|
||||
),
|
||||
Bi::FragDepth => (
|
||||
self.stage == St::Fragment && self.output,
|
||||
*ty_inner
|
||||
== Ti::Scalar {
|
||||
kind: Sk::Float,
|
||||
width,
|
||||
},
|
||||
*ty_inner == Ti::Scalar(crate::Scalar::F32),
|
||||
),
|
||||
Bi::FrontFacing => (
|
||||
self.stage == St::Fragment && !self.output,
|
||||
*ty_inner
|
||||
== Ti::Scalar {
|
||||
kind: Sk::Bool,
|
||||
width: crate::BOOL_WIDTH,
|
||||
},
|
||||
*ty_inner == Ti::Scalar(crate::Scalar::BOOL),
|
||||
),
|
||||
Bi::PrimitiveIndex => (
|
||||
self.stage == St::Fragment && !self.output,
|
||||
*ty_inner
|
||||
== Ti::Scalar {
|
||||
kind: Sk::Uint,
|
||||
width,
|
||||
},
|
||||
*ty_inner == Ti::Scalar(crate::Scalar::U32),
|
||||
),
|
||||
Bi::SampleIndex => (
|
||||
self.stage == St::Fragment && !self.output,
|
||||
*ty_inner
|
||||
== Ti::Scalar {
|
||||
kind: Sk::Uint,
|
||||
width,
|
||||
},
|
||||
*ty_inner == Ti::Scalar(crate::Scalar::U32),
|
||||
),
|
||||
Bi::SampleMask => (
|
||||
self.stage == St::Fragment,
|
||||
*ty_inner
|
||||
== Ti::Scalar {
|
||||
kind: Sk::Uint,
|
||||
width,
|
||||
},
|
||||
*ty_inner == Ti::Scalar(crate::Scalar::U32),
|
||||
),
|
||||
Bi::LocalInvocationIndex => (
|
||||
self.stage == St::Compute && !self.output,
|
||||
*ty_inner
|
||||
== Ti::Scalar {
|
||||
kind: Sk::Uint,
|
||||
width,
|
||||
},
|
||||
*ty_inner == Ti::Scalar(crate::Scalar::U32),
|
||||
),
|
||||
Bi::GlobalInvocationId
|
||||
| Bi::LocalInvocationId
|
||||
@ -295,8 +250,7 @@ impl VaryingContext<'_> {
|
||||
*ty_inner
|
||||
== Ti::Vector {
|
||||
size: Vs::Tri,
|
||||
kind: Sk::Uint,
|
||||
width,
|
||||
scalar: crate::Scalar::U32,
|
||||
},
|
||||
),
|
||||
};
|
||||
|
29
third_party/rust/naga/src/valid/mod.rs
vendored
29
third_party/rust/naga/src/valid/mod.rs
vendored
@ -264,19 +264,25 @@ impl crate::TypeInner {
|
||||
#[cfg(feature = "validate")]
|
||||
const fn image_storage_coordinates(&self) -> Option<crate::ImageDimension> {
|
||||
match *self {
|
||||
Self::Scalar {
|
||||
Self::Scalar(crate::Scalar {
|
||||
kind: crate::ScalarKind::Sint | crate::ScalarKind::Uint,
|
||||
..
|
||||
} => Some(crate::ImageDimension::D1),
|
||||
}) => Some(crate::ImageDimension::D1),
|
||||
Self::Vector {
|
||||
size: crate::VectorSize::Bi,
|
||||
kind: crate::ScalarKind::Sint | crate::ScalarKind::Uint,
|
||||
..
|
||||
scalar:
|
||||
crate::Scalar {
|
||||
kind: crate::ScalarKind::Sint | crate::ScalarKind::Uint,
|
||||
..
|
||||
},
|
||||
} => Some(crate::ImageDimension::D2),
|
||||
Self::Vector {
|
||||
size: crate::VectorSize::Tri,
|
||||
kind: crate::ScalarKind::Sint | crate::ScalarKind::Uint,
|
||||
..
|
||||
scalar:
|
||||
crate::Scalar {
|
||||
kind: crate::ScalarKind::Sint | crate::ScalarKind::Uint,
|
||||
..
|
||||
},
|
||||
} => Some(crate::ImageDimension::D3),
|
||||
_ => None,
|
||||
}
|
||||
@ -349,10 +355,11 @@ impl Validator {
|
||||
ValidationError::from(e).with_span_handle(handle, &module.types)
|
||||
})?;
|
||||
|
||||
let placeholder = TypeResolution::Value(crate::TypeInner::Scalar {
|
||||
// These should all get overwritten.
|
||||
let placeholder = TypeResolution::Value(crate::TypeInner::Scalar(crate::Scalar {
|
||||
kind: crate::ScalarKind::Bool,
|
||||
width: 0,
|
||||
});
|
||||
}));
|
||||
|
||||
let mut mod_info = ModuleInfo {
|
||||
type_flags: Vec::with_capacity(module.types.len()),
|
||||
@ -482,9 +489,5 @@ fn validate_atomic_compare_exchange_struct(
|
||||
&& members[0].name.as_deref() == Some("old_value")
|
||||
&& scalar_predicate(&types[members[0].ty].inner)
|
||||
&& members[1].name.as_deref() == Some("exchanged")
|
||||
&& types[members[1].ty].inner
|
||||
== crate::TypeInner::Scalar {
|
||||
kind: crate::ScalarKind::Bool,
|
||||
width: crate::BOOL_WIDTH,
|
||||
}
|
||||
&& types[members[1].ty].inner == crate::TypeInner::Scalar(crate::Scalar::BOOL)
|
||||
}
|
||||
|
43
third_party/rust/naga/src/valid/type.rs
vendored
43
third_party/rust/naga/src/valid/type.rs
vendored
@ -224,15 +224,11 @@ impl super::Validator {
|
||||
}
|
||||
}
|
||||
|
||||
pub(super) const fn check_width(
|
||||
&self,
|
||||
kind: crate::ScalarKind,
|
||||
width: crate::Bytes,
|
||||
) -> Result<(), WidthError> {
|
||||
let good = match kind {
|
||||
crate::ScalarKind::Bool => width == crate::BOOL_WIDTH,
|
||||
pub(super) const fn check_width(&self, scalar: crate::Scalar) -> Result<(), WidthError> {
|
||||
let good = match scalar.kind {
|
||||
crate::ScalarKind::Bool => scalar.width == crate::BOOL_WIDTH,
|
||||
crate::ScalarKind::Float => {
|
||||
if width == 8 {
|
||||
if scalar.width == 8 {
|
||||
if !self.capabilities.contains(Capabilities::FLOAT64) {
|
||||
return Err(WidthError::MissingCapability {
|
||||
name: "f64",
|
||||
@ -241,15 +237,15 @@ impl super::Validator {
|
||||
}
|
||||
true
|
||||
} else {
|
||||
width == 4
|
||||
scalar.width == 4
|
||||
}
|
||||
}
|
||||
crate::ScalarKind::Sint | crate::ScalarKind::Uint => width == 4,
|
||||
crate::ScalarKind::Sint | crate::ScalarKind::Uint => scalar.width == 4,
|
||||
};
|
||||
if good {
|
||||
Ok(())
|
||||
} else {
|
||||
Err(WidthError::Invalid(kind, width))
|
||||
Err(WidthError::Invalid(scalar.kind, scalar.width))
|
||||
}
|
||||
}
|
||||
|
||||
@ -266,9 +262,9 @@ impl super::Validator {
|
||||
) -> Result<TypeInfo, TypeError> {
|
||||
use crate::TypeInner as Ti;
|
||||
Ok(match gctx.types[handle].inner {
|
||||
Ti::Scalar { kind, width } => {
|
||||
self.check_width(kind, width)?;
|
||||
let shareable = if kind.is_numeric() {
|
||||
Ti::Scalar(scalar) => {
|
||||
self.check_width(scalar)?;
|
||||
let shareable = if scalar.kind.is_numeric() {
|
||||
TypeFlags::IO_SHAREABLE | TypeFlags::HOST_SHAREABLE
|
||||
} else {
|
||||
TypeFlags::empty()
|
||||
@ -280,12 +276,12 @@ impl super::Validator {
|
||||
| TypeFlags::ARGUMENT
|
||||
| TypeFlags::CONSTRUCTIBLE
|
||||
| shareable,
|
||||
Alignment::from_width(width),
|
||||
Alignment::from_width(scalar.width),
|
||||
)
|
||||
}
|
||||
Ti::Vector { size, kind, width } => {
|
||||
self.check_width(kind, width)?;
|
||||
let shareable = if kind.is_numeric() {
|
||||
Ti::Vector { size, scalar } => {
|
||||
self.check_width(scalar)?;
|
||||
let shareable = if scalar.kind.is_numeric() {
|
||||
TypeFlags::IO_SHAREABLE | TypeFlags::HOST_SHAREABLE
|
||||
} else {
|
||||
TypeFlags::empty()
|
||||
@ -298,7 +294,7 @@ impl super::Validator {
|
||||
| TypeFlags::ARGUMENT
|
||||
| TypeFlags::CONSTRUCTIBLE
|
||||
| shareable,
|
||||
Alignment::from(size) * Alignment::from_width(width),
|
||||
Alignment::from(size) * Alignment::from_width(scalar.width),
|
||||
)
|
||||
}
|
||||
Ti::Matrix {
|
||||
@ -306,7 +302,7 @@ impl super::Validator {
|
||||
rows,
|
||||
width,
|
||||
} => {
|
||||
self.check_width(crate::ScalarKind::Float, width)?;
|
||||
self.check_width(crate::Scalar::float(width))?;
|
||||
TypeInfo::new(
|
||||
TypeFlags::DATA
|
||||
| TypeFlags::SIZED
|
||||
@ -317,7 +313,7 @@ impl super::Validator {
|
||||
Alignment::from(rows) * Alignment::from_width(width),
|
||||
)
|
||||
}
|
||||
Ti::Atomic { kind, width } => {
|
||||
Ti::Atomic(crate::Scalar { kind, width }) => {
|
||||
let good = match kind {
|
||||
crate::ScalarKind::Bool | crate::ScalarKind::Float => false,
|
||||
crate::ScalarKind::Sint | crate::ScalarKind::Uint => width == 4,
|
||||
@ -373,8 +369,7 @@ impl super::Validator {
|
||||
}
|
||||
Ti::ValuePointer {
|
||||
size: _,
|
||||
kind,
|
||||
width,
|
||||
scalar,
|
||||
space,
|
||||
} => {
|
||||
// ValuePointer should be treated the same way as the equivalent
|
||||
@ -384,7 +379,7 @@ impl super::Validator {
|
||||
// However, some cases are trivial: All our implicit base types
|
||||
// are DATA and SIZED, so we can never return
|
||||
// `InvalidPointerBase` or `InvalidPointerToUnsized`.
|
||||
self.check_width(kind, width)?;
|
||||
self.check_width(scalar)?;
|
||||
|
||||
// `Validator::validate_function` actually checks the address
|
||||
// space of pointer arguments explicitly before checking the
|
||||
|
@ -1 +1 @@
|
||||
{"files":{"COPYING":"01c266bced4a434da0051174d6bee16a4c82cf634e2679b6155d40d75012390f","Cargo.toml":"2e1ffefd2c70d47b5097d7ecc26184d92e4e2be1174c53147a617729024a4a51","LICENSE-MIT":"0f96a83840e146e43c0ec96a22ec1f392e0680e6c1226e6f3ba87e0740af850f","README.md":"cc4c882bde8d2ef26ef4770ff30d60eda603d87ae32e16d99525dc88f3377238","UNLICENSE":"7e12e5df4bae12cb21581ba157ced20e1986a0508dd10d0e8a4ab9a4cf94e85c","rustfmt.toml":"1ca600239a27401c4a43f363cf3f38183a212affc1f31bff3ae93234bbaec228","src/lib.rs":"fe62bc640112ffb687366fbe4a084ed3bf749185f77d1e401757ab148313fb7e"},"package":"be55cf8942feac5c765c2c993422806843c9a9a45d4d5c407ad6dd2ea95eb9b6"}
|
||||
{"files":{"COPYING":"01c266bced4a434da0051174d6bee16a4c82cf634e2679b6155d40d75012390f","Cargo.toml":"99e42d9c2cccfe0c7ba563ec3d1eef0ceb1a0a7b1e73722b51b98fb388ab5b39","LICENSE-MIT":"0f96a83840e146e43c0ec96a22ec1f392e0680e6c1226e6f3ba87e0740af850f","README.md":"b07f32791ef31fdc347d1d4a62a0bf0979ab825a361ca9079f31908a0b78ea96","UNLICENSE":"7e12e5df4bae12cb21581ba157ced20e1986a0508dd10d0e8a4ab9a4cf94e85c","rustfmt.toml":"1ca600239a27401c4a43f363cf3f38183a212affc1f31bff3ae93234bbaec228","src/lib.rs":"82d177e0cd4be591e6af29fc422dc996fde5c8ef4c75cdabdd2b12884956fad2"},"package":"ff1bc3d3f05aff0403e8ac0d92ced918ec05b666a43f83297ccef5bea8a3d449"}
|
2
third_party/rust/termcolor/Cargo.toml
vendored
2
third_party/rust/termcolor/Cargo.toml
vendored
@ -12,7 +12,7 @@
|
||||
[package]
|
||||
edition = "2018"
|
||||
name = "termcolor"
|
||||
version = "1.2.0"
|
||||
version = "1.4.0"
|
||||
authors = ["Andrew Gallant <jamslam@gmail.com>"]
|
||||
description = """
|
||||
A simple cross platform library for writing colored text to a terminal.
|
||||
|
23
third_party/rust/termcolor/README.md
vendored
23
third_party/rust/termcolor/README.md
vendored
@ -1,13 +1,13 @@
|
||||
termcolor
|
||||
=========
|
||||
A simple cross platform library for writing colored text to a terminal. This
|
||||
library writes colored text either using standard ANSI escape sequences or
|
||||
by interacting with the Windows console. Several convenient abstractions
|
||||
are provided for use in single-threaded or multi-threaded command line
|
||||
library writes colored text either using standard ANSI escape sequences or by
|
||||
interacting with the Windows console. Several convenient abstractions are
|
||||
provided for use in single-threaded or multi-threaded command line
|
||||
applications.
|
||||
|
||||
[![Build status](https://github.com/BurntSushi/termcolor/workflows/ci/badge.svg)](https://github.com/BurntSushi/termcolor/actions)
|
||||
[![](https://img.shields.io/crates/v/termcolor.svg)](https://crates.io/crates/termcolor)
|
||||
[![crates.io](https://img.shields.io/crates/v/termcolor.svg)](https://crates.io/crates/termcolor)
|
||||
|
||||
Dual-licensed under MIT or the [UNLICENSE](https://unlicense.org/).
|
||||
|
||||
@ -17,12 +17,7 @@ Dual-licensed under MIT or the [UNLICENSE](https://unlicense.org/).
|
||||
|
||||
### Usage
|
||||
|
||||
Add this to your `Cargo.toml`:
|
||||
|
||||
```toml
|
||||
[dependencies]
|
||||
termcolor = "1.1"
|
||||
```
|
||||
Run `cargo add termcolor` to add this dependency to your `Cargo.toml` file.
|
||||
|
||||
### Organization
|
||||
|
||||
@ -47,8 +42,8 @@ analogous type for the Windows console is not provided since it cannot exist.
|
||||
### Example: using `StandardStream`
|
||||
|
||||
The `StandardStream` type in this crate works similarly to `std::io::Stdout`,
|
||||
except it is augmented with methods for coloring by the `WriteColor` trait.
|
||||
For example, to write some green text:
|
||||
except it is augmented with methods for coloring by the `WriteColor` trait. For
|
||||
example, to write some green text:
|
||||
|
||||
```rust
|
||||
use std::io::{self, Write};
|
||||
@ -98,8 +93,8 @@ termcolor will inspect the `TERM` and `NO_COLOR` environment variables:
|
||||
This decision procedure may change over time.
|
||||
|
||||
Currently, `termcolor` does not attempt to detect whether a tty is present or
|
||||
not. To achieve that, please use the [`atty`](https://crates.io/crates/atty)
|
||||
crate.
|
||||
not. To achieve that, please use
|
||||
[`std::io::IsTerminal`](https://doc.rust-lang.org/std/io/trait.IsTerminal.html).
|
||||
|
||||
### Minimum Rust version policy
|
||||
|
||||
|
248
third_party/rust/termcolor/src/lib.rs
vendored
248
third_party/rust/termcolor/src/lib.rs
vendored
@ -10,6 +10,8 @@ to an in memory buffer. While this is easy to do with ANSI escape sequences
|
||||
(because they are in the buffer themselves), it is trickier to do with the
|
||||
Windows console API, which requires synchronous communication.
|
||||
|
||||
In ANSI mode, this crate also provides support for writing hyperlinks.
|
||||
|
||||
# Organization
|
||||
|
||||
The `WriteColor` trait extends the `io::Write` trait with methods for setting
|
||||
@ -85,21 +87,21 @@ is via libc's
|
||||
[`isatty`](https://man7.org/linux/man-pages/man3/isatty.3.html)
|
||||
function.
|
||||
Unfortunately, this notoriously does not work well in Windows environments. To
|
||||
work around that, the currently recommended solution is to use the
|
||||
[`atty`](https://crates.io/crates/atty)
|
||||
crate, which goes out of its way to get this as right as possible in Windows
|
||||
environments.
|
||||
work around that, the recommended solution is to use the standard library's
|
||||
[`IsTerminal`](https://doc.rust-lang.org/std/io/trait.IsTerminal.html) trait.
|
||||
It goes out of its way to get it as right as possible in Windows environments.
|
||||
|
||||
For example, in a command line application that exposes a `--color` flag,
|
||||
your logic for how to enable colors might look like this:
|
||||
|
||||
```rust,ignore
|
||||
use atty;
|
||||
```ignore
|
||||
use std::io::IsTerminal;
|
||||
|
||||
use termcolor::{ColorChoice, StandardStream};
|
||||
|
||||
let preference = argv.get_flag("color").unwrap_or("auto");
|
||||
let mut choice = preference.parse::<ColorChoice>()?;
|
||||
if choice == ColorChoice::Auto && !atty::is(atty::Stream::Stdout) {
|
||||
if choice == ColorChoice::Auto && !std::io::stdin().is_terminal() {
|
||||
choice = ColorChoice::Never;
|
||||
}
|
||||
let stdout = StandardStream::stdout(choice);
|
||||
@ -146,6 +148,10 @@ pub trait WriteColor: io::Write {
|
||||
///
|
||||
/// If there was a problem resetting the color settings, then an error is
|
||||
/// returned.
|
||||
///
|
||||
/// Note that this does not reset hyperlinks. Those need to be
|
||||
/// reset on their own, e.g., by calling `set_hyperlink` with
|
||||
/// [`HyperlinkSpec::none`].
|
||||
fn reset(&mut self) -> io::Result<()>;
|
||||
|
||||
/// Returns true if and only if the underlying writer must synchronously
|
||||
@ -162,15 +168,49 @@ pub trait WriteColor: io::Write {
|
||||
fn is_synchronous(&self) -> bool {
|
||||
false
|
||||
}
|
||||
|
||||
/// Set the current hyperlink of the writer.
|
||||
///
|
||||
/// The typical way to use this is to first call it with a
|
||||
/// [`HyperlinkSpec::open`] to write the actual URI to a tty that supports
|
||||
/// [OSC-8]. At this point, the caller can now write the label for the
|
||||
/// hyperlink. This may include coloring or other styles. Once the caller
|
||||
/// has finished writing the label, one should call this method again with
|
||||
/// [`HyperlinkSpec::close`].
|
||||
///
|
||||
/// If there was a problem setting the hyperlink, then an error is
|
||||
/// returned.
|
||||
///
|
||||
/// This defaults to doing nothing.
|
||||
///
|
||||
/// [OSC8]: https://github.com/Alhadis/OSC8-Adoption/
|
||||
fn set_hyperlink(&mut self, _link: &HyperlinkSpec) -> io::Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Returns true if and only if the underlying writer supports hyperlinks.
|
||||
///
|
||||
/// This can be used to avoid generating hyperlink URIs unnecessarily.
|
||||
///
|
||||
/// This defaults to `false`.
|
||||
fn supports_hyperlinks(&self) -> bool {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, T: ?Sized + WriteColor> WriteColor for &'a mut T {
|
||||
fn supports_color(&self) -> bool {
|
||||
(&**self).supports_color()
|
||||
}
|
||||
fn supports_hyperlinks(&self) -> bool {
|
||||
(&**self).supports_hyperlinks()
|
||||
}
|
||||
fn set_color(&mut self, spec: &ColorSpec) -> io::Result<()> {
|
||||
(&mut **self).set_color(spec)
|
||||
}
|
||||
fn set_hyperlink(&mut self, link: &HyperlinkSpec) -> io::Result<()> {
|
||||
(&mut **self).set_hyperlink(link)
|
||||
}
|
||||
fn reset(&mut self) -> io::Result<()> {
|
||||
(&mut **self).reset()
|
||||
}
|
||||
@ -183,9 +223,15 @@ impl<T: ?Sized + WriteColor> WriteColor for Box<T> {
|
||||
fn supports_color(&self) -> bool {
|
||||
(&**self).supports_color()
|
||||
}
|
||||
fn supports_hyperlinks(&self) -> bool {
|
||||
(&**self).supports_hyperlinks()
|
||||
}
|
||||
fn set_color(&mut self, spec: &ColorSpec) -> io::Result<()> {
|
||||
(&mut **self).set_color(spec)
|
||||
}
|
||||
fn set_hyperlink(&mut self, link: &HyperlinkSpec) -> io::Result<()> {
|
||||
(&mut **self).set_hyperlink(link)
|
||||
}
|
||||
fn reset(&mut self) -> io::Result<()> {
|
||||
(&mut **self).reset()
|
||||
}
|
||||
@ -668,11 +714,21 @@ impl WriteColor for StandardStream {
|
||||
self.wtr.supports_color()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn supports_hyperlinks(&self) -> bool {
|
||||
self.wtr.supports_hyperlinks()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn set_color(&mut self, spec: &ColorSpec) -> io::Result<()> {
|
||||
self.wtr.set_color(spec)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn set_hyperlink(&mut self, link: &HyperlinkSpec) -> io::Result<()> {
|
||||
self.wtr.set_hyperlink(link)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn reset(&mut self) -> io::Result<()> {
|
||||
self.wtr.reset()
|
||||
@ -702,11 +758,21 @@ impl<'a> WriteColor for StandardStreamLock<'a> {
|
||||
self.wtr.supports_color()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn supports_hyperlinks(&self) -> bool {
|
||||
self.wtr.supports_hyperlinks()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn set_color(&mut self, spec: &ColorSpec) -> io::Result<()> {
|
||||
self.wtr.set_color(spec)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn set_hyperlink(&mut self, link: &HyperlinkSpec) -> io::Result<()> {
|
||||
self.wtr.set_hyperlink(link)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn reset(&mut self) -> io::Result<()> {
|
||||
self.wtr.reset()
|
||||
@ -736,6 +802,11 @@ impl WriteColor for BufferedStandardStream {
|
||||
self.wtr.supports_color()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn supports_hyperlinks(&self) -> bool {
|
||||
self.wtr.supports_hyperlinks()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn set_color(&mut self, spec: &ColorSpec) -> io::Result<()> {
|
||||
if self.is_synchronous() {
|
||||
@ -744,6 +815,14 @@ impl WriteColor for BufferedStandardStream {
|
||||
self.wtr.set_color(spec)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn set_hyperlink(&mut self, link: &HyperlinkSpec) -> io::Result<()> {
|
||||
if self.is_synchronous() {
|
||||
self.wtr.flush()?;
|
||||
}
|
||||
self.wtr.set_hyperlink(link)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn reset(&mut self) -> io::Result<()> {
|
||||
self.wtr.reset()
|
||||
@ -787,6 +866,15 @@ impl<W: io::Write> WriteColor for WriterInner<W> {
|
||||
}
|
||||
}
|
||||
|
||||
fn supports_hyperlinks(&self) -> bool {
|
||||
match *self {
|
||||
WriterInner::NoColor(_) => false,
|
||||
WriterInner::Ansi(_) => true,
|
||||
#[cfg(windows)]
|
||||
WriterInner::Windows { .. } => false,
|
||||
}
|
||||
}
|
||||
|
||||
fn set_color(&mut self, spec: &ColorSpec) -> io::Result<()> {
|
||||
match *self {
|
||||
WriterInner::NoColor(ref mut wtr) => wtr.set_color(spec),
|
||||
@ -800,6 +888,15 @@ impl<W: io::Write> WriteColor for WriterInner<W> {
|
||||
}
|
||||
}
|
||||
|
||||
fn set_hyperlink(&mut self, link: &HyperlinkSpec) -> io::Result<()> {
|
||||
match *self {
|
||||
WriterInner::NoColor(ref mut wtr) => wtr.set_hyperlink(link),
|
||||
WriterInner::Ansi(ref mut wtr) => wtr.set_hyperlink(link),
|
||||
#[cfg(windows)]
|
||||
WriterInner::Windows { .. } => Ok(()),
|
||||
}
|
||||
}
|
||||
|
||||
fn reset(&mut self) -> io::Result<()> {
|
||||
match *self {
|
||||
WriterInner::NoColor(ref mut wtr) => wtr.reset(),
|
||||
@ -856,6 +953,16 @@ impl<'a, W: io::Write> WriteColor for WriterInnerLock<'a, W> {
|
||||
}
|
||||
}
|
||||
|
||||
fn supports_hyperlinks(&self) -> bool {
|
||||
match *self {
|
||||
WriterInnerLock::Unreachable(_) => unreachable!(),
|
||||
WriterInnerLock::NoColor(_) => false,
|
||||
WriterInnerLock::Ansi(_) => true,
|
||||
#[cfg(windows)]
|
||||
WriterInnerLock::Windows { .. } => false,
|
||||
}
|
||||
}
|
||||
|
||||
fn set_color(&mut self, spec: &ColorSpec) -> io::Result<()> {
|
||||
match *self {
|
||||
WriterInnerLock::Unreachable(_) => unreachable!(),
|
||||
@ -869,6 +976,16 @@ impl<'a, W: io::Write> WriteColor for WriterInnerLock<'a, W> {
|
||||
}
|
||||
}
|
||||
|
||||
fn set_hyperlink(&mut self, link: &HyperlinkSpec) -> io::Result<()> {
|
||||
match *self {
|
||||
WriterInnerLock::Unreachable(_) => unreachable!(),
|
||||
WriterInnerLock::NoColor(ref mut wtr) => wtr.set_hyperlink(link),
|
||||
WriterInnerLock::Ansi(ref mut wtr) => wtr.set_hyperlink(link),
|
||||
#[cfg(windows)]
|
||||
WriterInnerLock::Windows { .. } => Ok(()),
|
||||
}
|
||||
}
|
||||
|
||||
fn reset(&mut self) -> io::Result<()> {
|
||||
match *self {
|
||||
WriterInnerLock::Unreachable(_) => unreachable!(),
|
||||
@ -1062,11 +1179,11 @@ impl BufferWriter {
|
||||
/// method, which will take color preferences and the environment into
|
||||
/// account. However, buffers can also be manually created using `no_color`,
|
||||
/// `ansi` or `console` (on Windows).
|
||||
#[derive(Debug)]
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct Buffer(BufferInner);
|
||||
|
||||
/// BufferInner is an enumeration of different buffer types.
|
||||
#[derive(Debug)]
|
||||
#[derive(Clone, Debug)]
|
||||
enum BufferInner {
|
||||
/// No coloring information should be applied. This ignores all coloring
|
||||
/// directives.
|
||||
@ -1219,6 +1336,16 @@ impl WriteColor for Buffer {
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn supports_hyperlinks(&self) -> bool {
|
||||
match self.0 {
|
||||
BufferInner::NoColor(_) => false,
|
||||
BufferInner::Ansi(_) => true,
|
||||
#[cfg(windows)]
|
||||
BufferInner::Windows(_) => false,
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn set_color(&mut self, spec: &ColorSpec) -> io::Result<()> {
|
||||
match self.0 {
|
||||
@ -1229,6 +1356,16 @@ impl WriteColor for Buffer {
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn set_hyperlink(&mut self, link: &HyperlinkSpec) -> io::Result<()> {
|
||||
match self.0 {
|
||||
BufferInner::NoColor(ref mut w) => w.set_hyperlink(link),
|
||||
BufferInner::Ansi(ref mut w) => w.set_hyperlink(link),
|
||||
#[cfg(windows)]
|
||||
BufferInner::Windows(ref mut w) => w.set_hyperlink(link),
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn reset(&mut self) -> io::Result<()> {
|
||||
match self.0 {
|
||||
@ -1246,7 +1383,7 @@ impl WriteColor for Buffer {
|
||||
}
|
||||
|
||||
/// Satisfies `WriteColor` but ignores all color options.
|
||||
#[derive(Debug)]
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct NoColor<W>(W);
|
||||
|
||||
impl<W: Write> NoColor<W> {
|
||||
@ -1290,11 +1427,21 @@ impl<W: io::Write> WriteColor for NoColor<W> {
|
||||
false
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn supports_hyperlinks(&self) -> bool {
|
||||
false
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn set_color(&mut self, _: &ColorSpec) -> io::Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn set_hyperlink(&mut self, _: &HyperlinkSpec) -> io::Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn reset(&mut self) -> io::Result<()> {
|
||||
Ok(())
|
||||
@ -1307,7 +1454,7 @@ impl<W: io::Write> WriteColor for NoColor<W> {
|
||||
}
|
||||
|
||||
/// Satisfies `WriteColor` using standard ANSI escape sequences.
|
||||
#[derive(Debug)]
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct Ansi<W>(W);
|
||||
|
||||
impl<W: Write> Ansi<W> {
|
||||
@ -1362,6 +1509,11 @@ impl<W: io::Write> WriteColor for Ansi<W> {
|
||||
true
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn supports_hyperlinks(&self) -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn set_color(&mut self, spec: &ColorSpec) -> io::Result<()> {
|
||||
if spec.reset {
|
||||
@ -1391,6 +1543,15 @@ impl<W: io::Write> WriteColor for Ansi<W> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn set_hyperlink(&mut self, link: &HyperlinkSpec) -> io::Result<()> {
|
||||
self.write_str("\x1B]8;;")?;
|
||||
if let Some(uri) = link.uri() {
|
||||
self.write_all(uri)?;
|
||||
}
|
||||
self.write_str("\x1B\\")
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn reset(&mut self) -> io::Result<()> {
|
||||
self.write_str("\x1B[0m")
|
||||
@ -1522,10 +1683,18 @@ impl WriteColor for io::Sink {
|
||||
false
|
||||
}
|
||||
|
||||
fn supports_hyperlinks(&self) -> bool {
|
||||
false
|
||||
}
|
||||
|
||||
fn set_color(&mut self, _: &ColorSpec) -> io::Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn set_hyperlink(&mut self, _: &HyperlinkSpec) -> io::Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn reset(&mut self) -> io::Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
@ -1624,12 +1793,22 @@ impl WriteColor for WindowsBuffer {
|
||||
true
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn supports_hyperlinks(&self) -> bool {
|
||||
false
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn set_color(&mut self, spec: &ColorSpec) -> io::Result<()> {
|
||||
self.push(Some(spec.clone()));
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn set_hyperlink(&mut self, _: &HyperlinkSpec) -> io::Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn reset(&mut self) -> io::Result<()> {
|
||||
self.push(None);
|
||||
@ -2085,6 +2264,29 @@ impl FromStr for Color {
|
||||
}
|
||||
}
|
||||
|
||||
/// A hyperlink specification.
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct HyperlinkSpec<'a> {
|
||||
uri: Option<&'a [u8]>,
|
||||
}
|
||||
|
||||
impl<'a> HyperlinkSpec<'a> {
|
||||
/// Creates a new hyperlink specification.
|
||||
pub fn open(uri: &'a [u8]) -> HyperlinkSpec<'a> {
|
||||
HyperlinkSpec { uri: Some(uri) }
|
||||
}
|
||||
|
||||
/// Creates a hyperlink specification representing no hyperlink.
|
||||
pub fn close() -> HyperlinkSpec<'a> {
|
||||
HyperlinkSpec { uri: None }
|
||||
}
|
||||
|
||||
/// Returns the URI of the hyperlink if one is attached to this spec.
|
||||
pub fn uri(&self) -> Option<&'a [u8]> {
|
||||
self.uri
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
struct LossyStandardStream<W> {
|
||||
wtr: W,
|
||||
@ -2124,9 +2326,15 @@ impl<W: WriteColor> WriteColor for LossyStandardStream<W> {
|
||||
fn supports_color(&self) -> bool {
|
||||
self.wtr.supports_color()
|
||||
}
|
||||
fn supports_hyperlinks(&self) -> bool {
|
||||
self.wtr.supports_hyperlinks()
|
||||
}
|
||||
fn set_color(&mut self, spec: &ColorSpec) -> io::Result<()> {
|
||||
self.wtr.set_color(spec)
|
||||
}
|
||||
fn set_hyperlink(&mut self, link: &HyperlinkSpec) -> io::Result<()> {
|
||||
self.wtr.set_hyperlink(link)
|
||||
}
|
||||
fn reset(&mut self) -> io::Result<()> {
|
||||
self.wtr.reset()
|
||||
}
|
||||
@ -2170,8 +2378,8 @@ fn write_lossy_utf8<W: io::Write>(mut w: W, buf: &[u8]) -> io::Result<usize> {
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::{
|
||||
Ansi, Color, ColorSpec, ParseColorError, ParseColorErrorKind,
|
||||
StandardStream, WriteColor,
|
||||
Ansi, Color, ColorSpec, HyperlinkSpec, ParseColorError,
|
||||
ParseColorErrorKind, StandardStream, WriteColor,
|
||||
};
|
||||
|
||||
fn assert_is_send<T: Send>() {}
|
||||
@ -2347,4 +2555,18 @@ mod tests {
|
||||
assert!(color1.is_none(), "{:?} => {:?}", color, color1);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_ansi_hyperlink() {
|
||||
let mut buf = Ansi::new(vec![]);
|
||||
buf.set_hyperlink(&HyperlinkSpec::open(b"https://example.com"))
|
||||
.unwrap();
|
||||
buf.write_str("label").unwrap();
|
||||
buf.set_hyperlink(&HyperlinkSpec::close()).unwrap();
|
||||
|
||||
assert_eq!(
|
||||
buf.0,
|
||||
b"\x1B]8;;https://example.com\x1B\\label\x1B]8;;\x1B\\".to_vec()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -1 +1 @@
|
||||
{"files":{"Cargo.toml":"a01dee48cee8d362ac28b8c920b914d11be2362ca6d7d6036b6d786eca348be2","LICENSE.APACHE":"a6cba85bc92e0cff7a450b1d873c0eaa2e9fc96bf472df0247a26bec77bf3ff9","LICENSE.MIT":"c7fea58d1cfe49634cd92e54fc10a9d871f4b275321a4cd8c09e449122caaeb4","src/binding_model.rs":"f6d9b170a9328751b3109c81d6f1b555a6db1410f1b7e67c59cc596a1fd1d293","src/command/bind.rs":"67b8431a32f403e358b9c1593e6e0d64519f5f0b699059e6ea5374800d5c23d9","src/command/bundle.rs":"d5456be31f973fcae55ee01781da963f1c950aa5db7eae4d3c6166d4f1a132ca","src/command/clear.rs":"bf78a5eab40f67343054dc982c51f45caab36fb5bddaf065b7a4c1b7a0ada803","src/command/compute.rs":"8caa0f5fa1956a3747f0b845fdeec2572b9462a7e98fdb5cf7b562c472bd6c4c","src/command/draw.rs":"3687cbde422a29f28c1c3d17e132d912b3b4b2bcc98efca68d1ee0d563a5bf56","src/command/memory_init.rs":"b50d3d20dbf659052f19da2e79469ba6435e06370f19d6ef45e1b1128d9900b7","src/command/mod.rs":"4eac2ac0283c0cfdcc3512af5439fe38e7004e5f406bf52a66d3017ad1ae7632","src/command/query.rs":"d39e1b8cb6a054fd31333a916da5d79a6671a724212c90c490c13e55043a1685","src/command/render.rs":"c445f52d0b82d80033071025446ca2488ef702d4fd452fe4c67b154392630bab","src/command/transfer.rs":"2b6f266ba1155ab42bed23b28abffc1008ce26d60b656f56012b896e63daa111","src/conv.rs":"da95b36b7680ae74ebf810ad8f1decf01bd3eeaff44b3c5af1d4b3c3f0e2059a","src/device/global.rs":"704343ae4ef83e48b362f97a8daa29642cdcb8b02c7599615b250982844ae421","src/device/life.rs":"9ac0aab46de65fd2b493f3ee2c3527e37eaad9dbde1583752958eace71423cef","src/device/mod.rs":"702cd9c88015fb40d8ea838ed607afcfceb5bea809f508c49a70b49d5b9803fd","src/device/queue.rs":"e92840c4cf6af66947cd9b7189f1c539ead08f4610a7dddf9726a8c1294b6a36","src/device/resource.rs":"8ae77a27fc7179bb2020aaa41ce7deba4db33d239ca42ba3307d3b3c34d3b363","src/device/trace.rs":"21408dfd2c99e3ce36a77d08ba86cf52f32bb376ed82690bbbf74937bfd42cbe","src/error.rs":"ca37282283985e2b7d184b2ab7ca6f53f726432d920f8d8477bfff6fab9b34e2","src/global.rs":"cf551de97c3eb5acd0c2710da09ebd92cc863ad0bb0f53c0fd4911bf8cd3ad97","src/hal_api.rs":"92a2f0cb80f192693530ed61048919bbad446742c2370bf0944c44b1c5df8362","src/hub.rs":"b4207d0a450da9e1d9edb0abc3c99e495132793ebe26af78ea07397d2e5c0b85","src/id.rs":"ef7b3a77110277f4eb2fa1a2ae3d89318023b74d5671181684d2845ef7b7d87a","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":"37b1d19ebbc03642368c0ef668f5f897a3cac8a6cccc553b50f3de5c800fde8b","src/lib.rs":"71d42899594be62c2e7074618e03f3639b5ef510b42d6dde660aaa4d5672691e","src/pipeline.rs":"4741c36fad7dedb856c3254f7869cad68dcf143aaac280f7f5920009b13c899a","src/present.rs":"a81f62ca967825f777a5f0d32defb2febb8793406c527d08c6ab0e129df5a81a","src/registry.rs":"4098413de7f48e9ff15d0246793be47a0d54c95b4c8594baf9fafd222a90ba84","src/resource.rs":"f140a1071d03dccae9859047c063dcd289e653352d635082dba76ef37a6ca4c3","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":"815961f6a38cd0691aa8af85e739fd3668133c0ca8937c84bfe698070490d418"},"package":null}
|
||||
{"files":{"Cargo.toml":"a01dee48cee8d362ac28b8c920b914d11be2362ca6d7d6036b6d786eca348be2","LICENSE.APACHE":"a6cba85bc92e0cff7a450b1d873c0eaa2e9fc96bf472df0247a26bec77bf3ff9","LICENSE.MIT":"c7fea58d1cfe49634cd92e54fc10a9d871f4b275321a4cd8c09e449122caaeb4","src/binding_model.rs":"f6d9b170a9328751b3109c81d6f1b555a6db1410f1b7e67c59cc596a1fd1d293","src/command/bind.rs":"67b8431a32f403e358b9c1593e6e0d64519f5f0b699059e6ea5374800d5c23d9","src/command/bundle.rs":"d5456be31f973fcae55ee01781da963f1c950aa5db7eae4d3c6166d4f1a132ca","src/command/clear.rs":"9c4c1734705a79b64a31540ddf7ec4e9f10b9d923b6d21783d98314a7b10bb25","src/command/compute.rs":"8caa0f5fa1956a3747f0b845fdeec2572b9462a7e98fdb5cf7b562c472bd6c4c","src/command/draw.rs":"3687cbde422a29f28c1c3d17e132d912b3b4b2bcc98efca68d1ee0d563a5bf56","src/command/memory_init.rs":"b50d3d20dbf659052f19da2e79469ba6435e06370f19d6ef45e1b1128d9900b7","src/command/mod.rs":"4eac2ac0283c0cfdcc3512af5439fe38e7004e5f406bf52a66d3017ad1ae7632","src/command/query.rs":"d39e1b8cb6a054fd31333a916da5d79a6671a724212c90c490c13e55043a1685","src/command/render.rs":"c445f52d0b82d80033071025446ca2488ef702d4fd452fe4c67b154392630bab","src/command/transfer.rs":"1fc4d8a87eef3241134f0e6d3bb617511629afe10fddb16440f688e17bee7719","src/conv.rs":"da95b36b7680ae74ebf810ad8f1decf01bd3eeaff44b3c5af1d4b3c3f0e2059a","src/device/global.rs":"2ccbc26fddb9291fecd0fe3c5e85c806cf77319fe2818a8684a81bed3ea7e649","src/device/life.rs":"6a7cbf7d47155fe1171387221141eefab135868196a03b0bba86ab168d9dee58","src/device/mod.rs":"a7627267001bbadb7309f4f0721ecec404dcba06bd6aab4dd6fa17410fc7402b","src/device/queue.rs":"56cbce0ed748c78d2360e3e042ffade1d941231acbb873d7aab4ac65b938ad06","src/device/resource.rs":"c4173ab900d5332984bb20e5e2733c4c1aa799e06bfe1e975fe55982ec3cdf29","src/device/trace.rs":"21408dfd2c99e3ce36a77d08ba86cf52f32bb376ed82690bbbf74937bfd42cbe","src/error.rs":"ca37282283985e2b7d184b2ab7ca6f53f726432d920f8d8477bfff6fab9b34e2","src/global.rs":"cf551de97c3eb5acd0c2710da09ebd92cc863ad0bb0f53c0fd4911bf8cd3ad97","src/hal_api.rs":"92a2f0cb80f192693530ed61048919bbad446742c2370bf0944c44b1c5df8362","src/hub.rs":"b4207d0a450da9e1d9edb0abc3c99e495132793ebe26af78ea07397d2e5c0b85","src/id.rs":"ef7b3a77110277f4eb2fa1a2ae3d89318023b74d5671181684d2845ef7b7d87a","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":"37b1d19ebbc03642368c0ef668f5f897a3cac8a6cccc553b50f3de5c800fde8b","src/lib.rs":"71d42899594be62c2e7074618e03f3639b5ef510b42d6dde660aaa4d5672691e","src/pipeline.rs":"4741c36fad7dedb856c3254f7869cad68dcf143aaac280f7f5920009b13c899a","src/present.rs":"a81f62ca967825f777a5f0d32defb2febb8793406c527d08c6ab0e129df5a81a","src/registry.rs":"4098413de7f48e9ff15d0246793be47a0d54c95b4c8594baf9fafd222a90ba84","src/resource.rs":"f140a1071d03dccae9859047c063dcd289e653352d635082dba76ef37a6ca4c3","src/storage.rs":"11ccae01252ae68727a256e5db6826f74973cfc753a18dedf7fabf8aef5596cc","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":"8b4db473ef01d3603f45eac6bf613874624755bc2f85972720ca94db7b556753"},"package":null}
|
@ -331,7 +331,7 @@ fn clear_texture_via_buffer_copies<A: hal::Api>(
|
||||
let mut zero_buffer_copy_regions = Vec::new();
|
||||
let buffer_copy_pitch = alignments.buffer_copy_pitch.get() as u32;
|
||||
let (block_width, block_height) = texture_desc.format.block_dimensions();
|
||||
let block_size = texture_desc.format.block_size(None).unwrap();
|
||||
let block_size = texture_desc.format.block_copy_size(None).unwrap();
|
||||
|
||||
let bytes_per_row_alignment = get_lowest_common_denom(buffer_copy_pitch, block_size);
|
||||
|
||||
|
@ -254,7 +254,7 @@ pub(crate) fn validate_linear_texture_data(
|
||||
|
||||
let offset = layout.offset;
|
||||
|
||||
let block_size = format.block_size(Some(aspect)).unwrap() as BufferAddress;
|
||||
let block_size = format.block_copy_size(Some(aspect)).unwrap() as BufferAddress;
|
||||
let (block_width, block_height) = format.block_dimensions();
|
||||
let block_width = block_width as BufferAddress;
|
||||
let block_height = block_height as BufferAddress;
|
||||
|
57
third_party/rust/wgpu-core/src/device/global.rs
vendored
57
third_party/rust/wgpu-core/src/device/global.rs
vendored
@ -3,7 +3,9 @@ use crate::device::trace;
|
||||
use crate::{
|
||||
binding_model::{self, BindGroupLayout},
|
||||
command, conv,
|
||||
device::{life::WaitIdleError, map_buffer, queue, Device, DeviceError, HostMap},
|
||||
device::{
|
||||
life::WaitIdleError, map_buffer, queue, Device, DeviceError, DeviceLostClosure, HostMap,
|
||||
},
|
||||
global::Global,
|
||||
hal_api::HalApi,
|
||||
hub::Token,
|
||||
@ -494,7 +496,7 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
||||
log::trace!("Buffer::destroy {buffer_id:?}");
|
||||
let (mut buffer_guard, _) = hub.buffers.write(&mut token);
|
||||
let buffer = buffer_guard
|
||||
.get_mut(buffer_id)
|
||||
.get_and_mark_destroyed(buffer_id)
|
||||
.map_err(|_| resource::DestroyError::Invalid)?;
|
||||
|
||||
let device = &mut device_guard[buffer.device_id.value];
|
||||
@ -549,7 +551,7 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
||||
|
||||
let (ref_count, last_submit_index, device_id) = {
|
||||
let (mut buffer_guard, _) = hub.buffers.write(&mut token);
|
||||
match buffer_guard.get_mut(buffer_id) {
|
||||
match buffer_guard.get_occupied_or_destroyed_mut(buffer_id) {
|
||||
Ok(buffer) => {
|
||||
let ref_count = buffer.life_guard.ref_count.take().unwrap();
|
||||
let last_submit_index = buffer.life_guard.life_count();
|
||||
@ -799,7 +801,7 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
||||
|
||||
let (mut texture_guard, _) = hub.textures.write(&mut token);
|
||||
let texture = texture_guard
|
||||
.get_mut(texture_id)
|
||||
.get_and_mark_destroyed(texture_id)
|
||||
.map_err(|_| resource::DestroyError::Invalid)?;
|
||||
|
||||
let device = &mut device_guard[texture.device_id.value];
|
||||
@ -853,7 +855,7 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
||||
|
||||
let (ref_count, last_submit_index, device_id) = {
|
||||
let (mut texture_guard, _) = hub.textures.write(&mut token);
|
||||
match texture_guard.get_mut(texture_id) {
|
||||
match texture_guard.get_occupied_or_destroyed_mut(texture_id) {
|
||||
Ok(texture) => {
|
||||
let ref_count = texture.life_guard.ref_count.take().unwrap();
|
||||
let last_submit_index = texture.life_guard.life_count();
|
||||
@ -2672,6 +2674,21 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn device_set_device_lost_closure<A: HalApi>(
|
||||
&self,
|
||||
device_id: DeviceId,
|
||||
device_lost_closure: DeviceLostClosure,
|
||||
) {
|
||||
let hub = A::hub(self);
|
||||
let mut token = Token::root();
|
||||
|
||||
let (mut device_guard, mut token) = hub.devices.write(&mut token);
|
||||
if let Ok(device) = device_guard.get_mut(device_id) {
|
||||
let mut life_tracker = device.lock_life(&mut token);
|
||||
life_tracker.device_lost_closure = Some(device_lost_closure);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn device_destroy<A: HalApi>(&self, device_id: DeviceId) {
|
||||
log::trace!("Device::destroy {device_id:?}");
|
||||
|
||||
@ -2683,36 +2700,26 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
||||
// Follow the steps at
|
||||
// https://gpuweb.github.io/gpuweb/#dom-gpudevice-destroy.
|
||||
|
||||
// It's legal to call destroy multiple times, but if the device
|
||||
// is already invalid, there's nothing more to do. There's also
|
||||
// no need to return an error.
|
||||
if !device.valid {
|
||||
return;
|
||||
}
|
||||
|
||||
// The last part of destroy is to lose the device. The spec says
|
||||
// delay that until all "currently-enqueued operations on any
|
||||
// queue on this device are completed."
|
||||
|
||||
// TODO: implement this delay.
|
||||
|
||||
// Finish by losing the device.
|
||||
|
||||
// TODO: associate this "destroyed" reason more tightly with
|
||||
// the GPUDeviceLostReason defined in webgpu.idl.
|
||||
device.lose(Some("destroyed"));
|
||||
// queue on this device are completed." This is accomplished by
|
||||
// setting valid to false, and then relying upon maintain to
|
||||
// check for empty queues and a DeviceLostClosure. At that time,
|
||||
// the DeviceLostClosure will be called with "destroyed" as the
|
||||
// reason.
|
||||
device.valid = false;
|
||||
}
|
||||
}
|
||||
|
||||
pub fn device_lose<A: HalApi>(&self, device_id: DeviceId, reason: Option<&str>) {
|
||||
log::trace!("Device::lose {device_id:?}");
|
||||
pub fn device_mark_lost<A: HalApi>(&self, device_id: DeviceId, message: &str) {
|
||||
log::trace!("Device::mark_lost {device_id:?}");
|
||||
|
||||
let hub = A::hub(self);
|
||||
let mut token = Token::root();
|
||||
|
||||
let (mut device_guard, _) = hub.devices.write(&mut token);
|
||||
let (mut device_guard, mut token) = hub.devices.write(&mut token);
|
||||
if let Ok(device) = device_guard.get_mut(device_id) {
|
||||
device.lose(reason);
|
||||
device.lose(&mut token, message);
|
||||
}
|
||||
}
|
||||
|
||||
|
45
third_party/rust/wgpu-core/src/device/life.rs
vendored
45
third_party/rust/wgpu-core/src/device/life.rs
vendored
@ -3,7 +3,7 @@ use crate::device::trace;
|
||||
use crate::{
|
||||
device::{
|
||||
queue::{EncoderInFlight, SubmittedWorkDoneClosure, TempResource},
|
||||
DeviceError,
|
||||
DeviceError, DeviceLostClosure,
|
||||
},
|
||||
hal_api::HalApi,
|
||||
hub::{Hub, Token},
|
||||
@ -313,6 +313,11 @@ pub(super) struct LifetimeTracker<A: hal::Api> {
|
||||
/// must happen _after_ all mapped buffer callbacks are mapped, so we defer them
|
||||
/// here until the next time the device is maintained.
|
||||
work_done_closures: SmallVec<[SubmittedWorkDoneClosure; 1]>,
|
||||
|
||||
/// Closure to be called on "lose the device". This is invoked directly by
|
||||
/// device.lose or by the UserCallbacks returned from maintain when the device
|
||||
/// has been destroyed and its queues are empty.
|
||||
pub device_lost_closure: Option<DeviceLostClosure>,
|
||||
}
|
||||
|
||||
impl<A: hal::Api> LifetimeTracker<A> {
|
||||
@ -326,6 +331,7 @@ impl<A: hal::Api> LifetimeTracker<A> {
|
||||
free_resources: NonReferencedResources::new(),
|
||||
ready_to_map: Vec::new(),
|
||||
work_done_closures: SmallVec::new(),
|
||||
device_lost_closure: None,
|
||||
}
|
||||
}
|
||||
|
||||
@ -834,21 +840,22 @@ impl<A: HalApi> LifetimeTracker<A> {
|
||||
|
||||
for stored in self.mapped.drain(..) {
|
||||
let resource_id = stored.value;
|
||||
let buf = &buffer_guard[resource_id];
|
||||
// The buffer may have been destroyed since the map request.
|
||||
if let Ok(buf) = buffer_guard.get(resource_id.0) {
|
||||
let submit_index = buf.life_guard.life_count();
|
||||
log::trace!(
|
||||
"Mapping of {:?} at submission {:?} gets assigned to active {:?}",
|
||||
resource_id,
|
||||
submit_index,
|
||||
self.active.iter().position(|a| a.index == submit_index)
|
||||
);
|
||||
|
||||
let submit_index = buf.life_guard.life_count();
|
||||
log::trace!(
|
||||
"Mapping of {:?} at submission {:?} gets assigned to active {:?}",
|
||||
resource_id,
|
||||
submit_index,
|
||||
self.active.iter().position(|a| a.index == submit_index)
|
||||
);
|
||||
|
||||
self.active
|
||||
.iter_mut()
|
||||
.find(|a| a.index == submit_index)
|
||||
.map_or(&mut self.ready_to_map, |a| &mut a.mapped)
|
||||
.push(resource_id);
|
||||
self.active
|
||||
.iter_mut()
|
||||
.find(|a| a.index == submit_index)
|
||||
.map_or(&mut self.ready_to_map, |a| &mut a.mapped)
|
||||
.push(resource_id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -873,7 +880,13 @@ impl<A: HalApi> LifetimeTracker<A> {
|
||||
Vec::with_capacity(self.ready_to_map.len());
|
||||
let mut trackers = trackers.lock();
|
||||
for buffer_id in self.ready_to_map.drain(..) {
|
||||
let buffer = &mut buffer_guard[buffer_id];
|
||||
let buffer = match buffer_guard.get_occupied_or_destroyed_mut(buffer_id.0) {
|
||||
Ok(buf) => buf,
|
||||
Err(..) => {
|
||||
// The buffer may have been destroyed since the map request.
|
||||
continue;
|
||||
}
|
||||
};
|
||||
if buffer.life_guard.ref_count.is_none() && trackers.buffers.remove_abandoned(buffer_id)
|
||||
{
|
||||
buffer.map_state = resource::BufferMapState::Idle;
|
||||
|
98
third_party/rust/wgpu-core/src/device/mod.rs
vendored
98
third_party/rust/wgpu-core/src/device/mod.rs
vendored
@ -12,8 +12,9 @@ use crate::{
|
||||
use arrayvec::ArrayVec;
|
||||
use hal::Device as _;
|
||||
use smallvec::SmallVec;
|
||||
use std::os::raw::c_char;
|
||||
use thiserror::Error;
|
||||
use wgt::{BufferAddress, TextureFormat};
|
||||
use wgt::{BufferAddress, DeviceLostReason, TextureFormat};
|
||||
|
||||
use std::{iter, num::NonZeroU32, ptr};
|
||||
|
||||
@ -169,12 +170,15 @@ pub type BufferMapPendingClosure = (BufferMapOperation, BufferAccessResult);
|
||||
pub struct UserClosures {
|
||||
pub mappings: Vec<BufferMapPendingClosure>,
|
||||
pub submissions: SmallVec<[queue::SubmittedWorkDoneClosure; 1]>,
|
||||
pub device_lost_invocations: SmallVec<[DeviceLostInvocation; 1]>,
|
||||
}
|
||||
|
||||
impl UserClosures {
|
||||
fn extend(&mut self, other: Self) {
|
||||
self.mappings.extend(other.mappings);
|
||||
self.submissions.extend(other.submissions);
|
||||
self.device_lost_invocations
|
||||
.extend(other.device_lost_invocations);
|
||||
}
|
||||
|
||||
fn fire(self) {
|
||||
@ -189,6 +193,98 @@ impl UserClosures {
|
||||
for closure in self.submissions {
|
||||
closure.call();
|
||||
}
|
||||
for invocation in self.device_lost_invocations {
|
||||
invocation
|
||||
.closure
|
||||
.call(invocation.reason, invocation.message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(any(
|
||||
not(target_arch = "wasm32"),
|
||||
all(
|
||||
feature = "fragile-send-sync-non-atomic-wasm",
|
||||
not(target_feature = "atomics")
|
||||
)
|
||||
))]
|
||||
pub type DeviceLostCallback = Box<dyn FnOnce(DeviceLostReason, String) + Send + 'static>;
|
||||
#[cfg(not(any(
|
||||
not(target_arch = "wasm32"),
|
||||
all(
|
||||
feature = "fragile-send-sync-non-atomic-wasm",
|
||||
not(target_feature = "atomics")
|
||||
)
|
||||
)))]
|
||||
pub type DeviceLostCallback = Box<dyn FnOnce(DeviceLostReason, String) + 'static>;
|
||||
|
||||
#[repr(C)]
|
||||
pub struct DeviceLostClosureC {
|
||||
pub callback: unsafe extern "C" fn(user_data: *mut u8, reason: u8, message: *const c_char),
|
||||
pub user_data: *mut u8,
|
||||
}
|
||||
|
||||
#[cfg(any(
|
||||
not(target_arch = "wasm32"),
|
||||
all(
|
||||
feature = "fragile-send-sync-non-atomic-wasm",
|
||||
not(target_feature = "atomics")
|
||||
)
|
||||
))]
|
||||
unsafe impl Send for DeviceLostClosureC {}
|
||||
|
||||
pub struct DeviceLostClosure {
|
||||
// We wrap this so creating the enum in the C variant can be unsafe,
|
||||
// allowing our call function to be safe.
|
||||
inner: DeviceLostClosureInner,
|
||||
}
|
||||
|
||||
pub struct DeviceLostInvocation {
|
||||
closure: DeviceLostClosure,
|
||||
reason: DeviceLostReason,
|
||||
message: String,
|
||||
}
|
||||
|
||||
enum DeviceLostClosureInner {
|
||||
Rust { callback: DeviceLostCallback },
|
||||
C { inner: DeviceLostClosureC },
|
||||
}
|
||||
|
||||
impl DeviceLostClosure {
|
||||
pub fn from_rust(callback: DeviceLostCallback) -> Self {
|
||||
Self {
|
||||
inner: DeviceLostClosureInner::Rust { callback },
|
||||
}
|
||||
}
|
||||
|
||||
/// # Safety
|
||||
///
|
||||
/// - The callback pointer must be valid to call with the provided `user_data`
|
||||
/// pointer.
|
||||
///
|
||||
/// - Both pointers must point to `'static` data, as the callback may happen at
|
||||
/// an unspecified time.
|
||||
pub unsafe fn from_c(inner: DeviceLostClosureC) -> Self {
|
||||
Self {
|
||||
inner: DeviceLostClosureInner::C { inner },
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(trivial_casts)]
|
||||
pub(crate) fn call(self, reason: DeviceLostReason, message: String) {
|
||||
match self.inner {
|
||||
DeviceLostClosureInner::Rust { callback } => callback(reason, message),
|
||||
// SAFETY: the contract of the call to from_c says that this unsafe is sound.
|
||||
DeviceLostClosureInner::C { inner } => unsafe {
|
||||
// We need to pass message as a c_char typed pointer. To avoid trivial
|
||||
// conversion warnings on some platforms, we use the allow lint.
|
||||
(inner.callback)(
|
||||
inner.user_data,
|
||||
reason as u8,
|
||||
message.as_ptr() as *const c_char,
|
||||
)
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
34
third_party/rust/wgpu-core/src/device/queue.rs
vendored
34
third_party/rust/wgpu-core/src/device/queue.rs
vendored
@ -697,7 +697,7 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
||||
let block_size = dst
|
||||
.desc
|
||||
.format
|
||||
.block_size(Some(destination.aspect))
|
||||
.block_copy_size(Some(destination.aspect))
|
||||
.unwrap();
|
||||
let bytes_per_row_alignment =
|
||||
get_lowest_common_denom(device.alignments.buffer_copy_pitch.get() as u32, block_size);
|
||||
@ -1110,13 +1110,12 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
||||
// it, so make sure to set_size on it.
|
||||
used_surface_textures.set_size(texture_guard.len());
|
||||
|
||||
// TODO: ideally we would use `get_and_mark_destroyed` but the code here
|
||||
// wants to consume the command buffer.
|
||||
#[allow(unused_mut)]
|
||||
let mut cmdbuf = match hub
|
||||
.command_buffers
|
||||
.unregister_locked(cmb_id, &mut *command_buffer_guard)
|
||||
{
|
||||
Some(cmdbuf) => cmdbuf,
|
||||
None => continue,
|
||||
let mut cmdbuf = match command_buffer_guard.replace_with_error(cmb_id) {
|
||||
Ok(cmdbuf) => cmdbuf,
|
||||
Err(_) => continue,
|
||||
};
|
||||
|
||||
if cmdbuf.device_id.value.0 != queue_id {
|
||||
@ -1140,13 +1139,16 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
||||
|
||||
// update submission IDs
|
||||
for id in cmdbuf.trackers.buffers.used() {
|
||||
let buffer = &mut buffer_guard[id];
|
||||
let raw_buf = match buffer.raw {
|
||||
Some(ref raw) => raw,
|
||||
None => {
|
||||
let buffer = match buffer_guard.get(id.0) {
|
||||
Ok(buf) => buf,
|
||||
Err(..) => {
|
||||
return Err(QueueSubmitError::DestroyedBuffer(id.0));
|
||||
}
|
||||
};
|
||||
// get fails if the buffer is invalid or destroyed so we can assume
|
||||
// the raw buffer is not None.
|
||||
let raw_buf = buffer.raw.as_ref().unwrap();
|
||||
|
||||
if !buffer.life_guard.use_at(submit_index) {
|
||||
if let BufferMapState::Active { .. } = buffer.map_state {
|
||||
log::warn!("Dropped buffer has a pending mapping.");
|
||||
@ -1162,10 +1164,16 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
||||
}
|
||||
}
|
||||
for id in cmdbuf.trackers.textures.used() {
|
||||
let texture = &mut texture_guard[id];
|
||||
let texture = match texture_guard.get_mut(id.0) {
|
||||
Ok(tex) => tex,
|
||||
Err(..) => {
|
||||
return Err(QueueSubmitError::DestroyedTexture(id.0));
|
||||
}
|
||||
};
|
||||
|
||||
let should_extend = match texture.inner {
|
||||
TextureInner::Native { raw: None } => {
|
||||
return Err(QueueSubmitError::DestroyedTexture(id.0));
|
||||
unreachable!();
|
||||
}
|
||||
TextureInner::Native { raw: Some(_) } => false,
|
||||
TextureInner::Surface {
|
||||
|
@ -8,8 +8,8 @@ use crate::{
|
||||
command, conv,
|
||||
device::life::WaitIdleError,
|
||||
device::{
|
||||
AttachmentData, CommandAllocator, MissingDownlevelFlags, MissingFeatures,
|
||||
RenderPassContext, CLEANUP_WAIT_MS,
|
||||
AttachmentData, CommandAllocator, DeviceLostInvocation, MissingDownlevelFlags,
|
||||
MissingFeatures, RenderPassContext, CLEANUP_WAIT_MS,
|
||||
},
|
||||
hal_api::HalApi,
|
||||
hal_label,
|
||||
@ -34,7 +34,7 @@ use hal::{CommandEncoder as _, Device as _};
|
||||
use parking_lot::{Mutex, MutexGuard};
|
||||
use smallvec::SmallVec;
|
||||
use thiserror::Error;
|
||||
use wgt::{TextureFormat, TextureSampleType, TextureViewDimension};
|
||||
use wgt::{DeviceLostReason, TextureFormat, TextureSampleType, TextureViewDimension};
|
||||
|
||||
use std::{borrow::Cow, iter, num::NonZeroU32};
|
||||
|
||||
@ -315,9 +315,24 @@ impl<A: HalApi> Device<A> {
|
||||
let mapping_closures = life_tracker.handle_mapping(hub, &self.raw, &self.trackers, token);
|
||||
life_tracker.cleanup(&self.raw);
|
||||
|
||||
// Detect if we have been destroyed and now need to lose the device.
|
||||
// If we are invalid (set at start of destroy) and our queue is empty,
|
||||
// and we have a DeviceLostClosure, return the closure to be called by
|
||||
// our caller. This will complete the steps for both destroy and for
|
||||
// "lose the device".
|
||||
let mut device_lost_invocations = SmallVec::new();
|
||||
if !self.valid && life_tracker.queue_empty() && life_tracker.device_lost_closure.is_some() {
|
||||
device_lost_invocations.push(DeviceLostInvocation {
|
||||
closure: life_tracker.device_lost_closure.take().unwrap(),
|
||||
reason: DeviceLostReason::Destroyed,
|
||||
message: String::new(),
|
||||
});
|
||||
}
|
||||
|
||||
let closures = UserClosures {
|
||||
mappings: mapping_closures,
|
||||
submissions: submission_closures,
|
||||
device_lost_invocations,
|
||||
};
|
||||
Ok((closures, life_tracker.queue_empty()))
|
||||
}
|
||||
@ -342,42 +357,90 @@ impl<A: HalApi> Device<A> {
|
||||
let (sampler_guard, _) = hub.samplers.read(&mut token);
|
||||
|
||||
for id in trackers.buffers.used() {
|
||||
if buffer_guard[id].life_guard.ref_count.is_none() {
|
||||
if buffer_guard
|
||||
.get_occupied_or_destroyed(id.0)
|
||||
.unwrap()
|
||||
.life_guard
|
||||
.ref_count
|
||||
.is_none()
|
||||
{
|
||||
self.temp_suspected.buffers.push(id);
|
||||
}
|
||||
}
|
||||
for id in trackers.textures.used() {
|
||||
if texture_guard[id].life_guard.ref_count.is_none() {
|
||||
if texture_guard
|
||||
.get_occupied_or_destroyed(id.0)
|
||||
.unwrap()
|
||||
.life_guard
|
||||
.ref_count
|
||||
.is_none()
|
||||
{
|
||||
self.temp_suspected.textures.push(id);
|
||||
}
|
||||
}
|
||||
for id in trackers.views.used() {
|
||||
if texture_view_guard[id].life_guard.ref_count.is_none() {
|
||||
if texture_view_guard
|
||||
.get_occupied_or_destroyed(id.0)
|
||||
.unwrap()
|
||||
.life_guard
|
||||
.ref_count
|
||||
.is_none()
|
||||
{
|
||||
self.temp_suspected.texture_views.push(id);
|
||||
}
|
||||
}
|
||||
for id in trackers.bind_groups.used() {
|
||||
if bind_group_guard[id].life_guard.ref_count.is_none() {
|
||||
if bind_group_guard
|
||||
.get_occupied_or_destroyed(id.0)
|
||||
.unwrap()
|
||||
.life_guard
|
||||
.ref_count
|
||||
.is_none()
|
||||
{
|
||||
self.temp_suspected.bind_groups.push(id);
|
||||
}
|
||||
}
|
||||
for id in trackers.samplers.used() {
|
||||
if sampler_guard[id].life_guard.ref_count.is_none() {
|
||||
if sampler_guard
|
||||
.get_occupied_or_destroyed(id.0)
|
||||
.unwrap()
|
||||
.life_guard
|
||||
.ref_count
|
||||
.is_none()
|
||||
{
|
||||
self.temp_suspected.samplers.push(id);
|
||||
}
|
||||
}
|
||||
for id in trackers.compute_pipelines.used() {
|
||||
if compute_pipe_guard[id].life_guard.ref_count.is_none() {
|
||||
if compute_pipe_guard
|
||||
.get_occupied_or_destroyed(id.0)
|
||||
.unwrap()
|
||||
.life_guard
|
||||
.ref_count
|
||||
.is_none()
|
||||
{
|
||||
self.temp_suspected.compute_pipelines.push(id);
|
||||
}
|
||||
}
|
||||
for id in trackers.render_pipelines.used() {
|
||||
if render_pipe_guard[id].life_guard.ref_count.is_none() {
|
||||
if render_pipe_guard
|
||||
.get_occupied_or_destroyed(id.0)
|
||||
.unwrap()
|
||||
.life_guard
|
||||
.ref_count
|
||||
.is_none()
|
||||
{
|
||||
self.temp_suspected.render_pipelines.push(id);
|
||||
}
|
||||
}
|
||||
for id in trackers.query_sets.used() {
|
||||
if query_set_guard[id].life_guard.ref_count.is_none() {
|
||||
if query_set_guard
|
||||
.get_occupied_or_destroyed(id.0)
|
||||
.unwrap()
|
||||
.life_guard
|
||||
.ref_count
|
||||
.is_none()
|
||||
{
|
||||
self.temp_suspected.query_sets.push(id);
|
||||
}
|
||||
}
|
||||
@ -3304,17 +3367,23 @@ impl<A: HalApi> Device<A> {
|
||||
})
|
||||
}
|
||||
|
||||
pub(crate) fn lose(&mut self, _reason: Option<&str>) {
|
||||
pub(crate) fn lose<'this, 'token: 'this>(
|
||||
&'this mut self,
|
||||
token: &mut Token<'token, Self>,
|
||||
message: &str,
|
||||
) {
|
||||
// Follow the steps at https://gpuweb.github.io/gpuweb/#lose-the-device.
|
||||
|
||||
// Mark the device explicitly as invalid. This is checked in various
|
||||
// places to prevent new work from being submitted.
|
||||
self.valid = false;
|
||||
|
||||
// The following steps remain in "lose the device":
|
||||
// 1) Resolve the GPUDevice device.lost promise.
|
||||
|
||||
// TODO: triggger this passively or actively, and supply the reason.
|
||||
let mut life_tracker = self.lock_life(token);
|
||||
if life_tracker.device_lost_closure.is_some() {
|
||||
let device_lost_closure = life_tracker.device_lost_closure.take().unwrap();
|
||||
device_lost_closure.call(DeviceLostReason::Unknown, message.to_string());
|
||||
}
|
||||
|
||||
// 2) Complete any outstanding mapAsync() steps.
|
||||
// 3) Complete any outstanding onSubmittedWorkDone() steps.
|
||||
|
99
third_party/rust/wgpu-core/src/storage.rs
vendored
99
third_party/rust/wgpu-core/src/storage.rs
vendored
@ -14,6 +14,10 @@ pub(crate) enum Element<T> {
|
||||
/// epoch.
|
||||
Occupied(T, Epoch),
|
||||
|
||||
/// Like `Occupied`, but the resource has been marked as destroyed
|
||||
/// and hasn't been dropped yet.
|
||||
Destroyed(T, Epoch),
|
||||
|
||||
/// Like `Occupied`, but an error occurred when creating the
|
||||
/// resource.
|
||||
///
|
||||
@ -68,9 +72,11 @@ impl<T, I: id::TypedId> Storage<T, I> {
|
||||
let (index, epoch, _) = id.unzip();
|
||||
match self.map.get(index as usize) {
|
||||
Some(&Element::Vacant) => false,
|
||||
Some(&Element::Occupied(_, storage_epoch) | &Element::Error(storage_epoch, _)) => {
|
||||
storage_epoch == epoch
|
||||
}
|
||||
Some(
|
||||
&Element::Occupied(_, storage_epoch)
|
||||
| &Element::Destroyed(_, storage_epoch)
|
||||
| &Element::Error(storage_epoch, _),
|
||||
) => storage_epoch == epoch,
|
||||
None => false,
|
||||
}
|
||||
}
|
||||
@ -87,7 +93,9 @@ impl<T, I: id::TypedId> Storage<T, I> {
|
||||
let (result, storage_epoch) = match self.map.get(index as usize) {
|
||||
Some(&Element::Occupied(ref v, epoch)) => (Ok(Some(v)), epoch),
|
||||
Some(&Element::Vacant) => return Ok(None),
|
||||
Some(&Element::Error(epoch, ..)) => (Err(InvalidId), epoch),
|
||||
Some(&Element::Error(epoch, ..)) | Some(&Element::Destroyed(.., epoch)) => {
|
||||
(Err(InvalidId), epoch)
|
||||
}
|
||||
None => return Err(InvalidId),
|
||||
};
|
||||
assert_eq!(
|
||||
@ -106,6 +114,7 @@ impl<T, I: id::TypedId> Storage<T, I> {
|
||||
Some(&Element::Occupied(ref v, epoch)) => (Ok(v), epoch),
|
||||
Some(&Element::Vacant) => panic!("{}[{}] does not exist", self.kind, index),
|
||||
Some(&Element::Error(epoch, ..)) => (Err(InvalidId), epoch),
|
||||
Some(&Element::Destroyed(.., epoch)) => (Err(InvalidId), epoch),
|
||||
None => return Err(InvalidId),
|
||||
};
|
||||
assert_eq!(
|
||||
@ -124,6 +133,46 @@ impl<T, I: id::TypedId> Storage<T, I> {
|
||||
Some(&mut Element::Occupied(ref mut v, epoch)) => (Ok(v), epoch),
|
||||
Some(&mut Element::Vacant) | None => panic!("{}[{}] does not exist", self.kind, index),
|
||||
Some(&mut Element::Error(epoch, ..)) => (Err(InvalidId), epoch),
|
||||
Some(&mut Element::Destroyed(.., epoch)) => (Err(InvalidId), epoch),
|
||||
};
|
||||
assert_eq!(
|
||||
epoch, storage_epoch,
|
||||
"{}[{}] is no longer alive",
|
||||
self.kind, index
|
||||
);
|
||||
result
|
||||
}
|
||||
|
||||
/// Like `get_mut`, but returns the element even if it is destroyed.
|
||||
///
|
||||
/// In practice, most API entry points should use `get`/`get_mut` so that a
|
||||
/// destroyed resource leads to a validation error. This should be used internally
|
||||
/// in places where we want to do some manipulation potentially after the element
|
||||
/// was destroyed (for example the drop implementation).
|
||||
pub(crate) fn get_occupied_or_destroyed_mut(&mut self, id: I) -> Result<&mut T, InvalidId> {
|
||||
let (index, epoch, _) = id.unzip();
|
||||
let (result, storage_epoch) = match self.map.get_mut(index as usize) {
|
||||
Some(&mut Element::Occupied(ref mut v, epoch))
|
||||
| Some(&mut Element::Destroyed(ref mut v, epoch)) => (Ok(v), epoch),
|
||||
Some(&mut Element::Vacant) | None => panic!("{}[{}] does not exist", self.kind, index),
|
||||
Some(&mut Element::Error(epoch, ..)) => (Err(InvalidId), epoch),
|
||||
};
|
||||
assert_eq!(
|
||||
epoch, storage_epoch,
|
||||
"{}[{}] is no longer alive",
|
||||
self.kind, index
|
||||
);
|
||||
result
|
||||
}
|
||||
|
||||
pub(crate) fn get_occupied_or_destroyed(&self, id: I) -> Result<&T, InvalidId> {
|
||||
let (index, epoch, _) = id.unzip();
|
||||
let (result, storage_epoch) = match self.map.get(index as usize) {
|
||||
Some(&Element::Occupied(ref v, epoch)) | Some(&Element::Destroyed(ref v, epoch)) => {
|
||||
(Ok(v), epoch)
|
||||
}
|
||||
Some(&Element::Vacant) | None => panic!("{}[{}] does not exist", self.kind, index),
|
||||
Some(&Element::Error(epoch, ..)) => (Err(InvalidId), epoch),
|
||||
};
|
||||
assert_eq!(
|
||||
epoch, storage_epoch,
|
||||
@ -137,7 +186,7 @@ impl<T, I: id::TypedId> Storage<T, I> {
|
||||
match self.map[id as usize] {
|
||||
Element::Occupied(ref v, _) => v,
|
||||
Element::Vacant => panic!("{}[{}] does not exist", self.kind, id),
|
||||
Element::Error(_, _) => panic!(""),
|
||||
Element::Error(_, _) | Element::Destroyed(..) => panic!(""),
|
||||
}
|
||||
}
|
||||
|
||||
@ -169,6 +218,42 @@ impl<T, I: id::TypedId> Storage<T, I> {
|
||||
self.insert_impl(index as usize, Element::Error(epoch, label.to_string()))
|
||||
}
|
||||
|
||||
pub(crate) fn replace_with_error(&mut self, id: I) -> Result<T, InvalidId> {
|
||||
let (index, epoch, _) = id.unzip();
|
||||
match std::mem::replace(
|
||||
&mut self.map[index as usize],
|
||||
Element::Error(epoch, String::new()),
|
||||
) {
|
||||
Element::Vacant => panic!("Cannot access vacant resource"),
|
||||
Element::Occupied(value, storage_epoch) => {
|
||||
assert_eq!(epoch, storage_epoch);
|
||||
Ok(value)
|
||||
}
|
||||
_ => Err(InvalidId),
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn get_and_mark_destroyed(&mut self, id: I) -> Result<&mut T, InvalidId> {
|
||||
let (index, epoch, _) = id.unzip();
|
||||
let slot = &mut self.map[index as usize];
|
||||
// borrowck dance: we have to move the element out before we can replace it
|
||||
// with another variant with the same value.
|
||||
if let &mut Element::Occupied(..) = slot {
|
||||
if let Element::Occupied(value, storage_epoch) =
|
||||
std::mem::replace(slot, Element::Vacant)
|
||||
{
|
||||
debug_assert_eq!(storage_epoch, epoch);
|
||||
*slot = Element::Destroyed(value, storage_epoch);
|
||||
}
|
||||
}
|
||||
|
||||
if let Element::Destroyed(ref mut value, ..) = *slot {
|
||||
Ok(value)
|
||||
} else {
|
||||
Err(InvalidId)
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn force_replace(&mut self, id: I, value: T) {
|
||||
let (index, epoch, _) = id.unzip();
|
||||
self.map[index as usize] = Element::Occupied(value, epoch);
|
||||
@ -177,7 +262,7 @@ impl<T, I: id::TypedId> Storage<T, I> {
|
||||
pub(crate) fn remove(&mut self, id: I) -> Option<T> {
|
||||
let (index, epoch, _) = id.unzip();
|
||||
match std::mem::replace(&mut self.map[index as usize], Element::Vacant) {
|
||||
Element::Occupied(value, storage_epoch) => {
|
||||
Element::Occupied(value, storage_epoch) | Element::Destroyed(value, storage_epoch) => {
|
||||
assert_eq!(epoch, storage_epoch);
|
||||
Some(value)
|
||||
}
|
||||
@ -224,7 +309,7 @@ impl<T, I: id::TypedId> Storage<T, I> {
|
||||
};
|
||||
for element in self.map.iter() {
|
||||
match *element {
|
||||
Element::Occupied(..) => report.num_occupied += 1,
|
||||
Element::Occupied(..) | Element::Destroyed(..) => report.num_occupied += 1,
|
||||
Element::Vacant => report.num_vacant += 1,
|
||||
Element::Error(..) => report.num_error += 1,
|
||||
}
|
||||
|
114
third_party/rust/wgpu-core/src/validation.rs
vendored
114
third_party/rust/wgpu-core/src/validation.rs
vendored
@ -57,13 +57,18 @@ impl NumericDimension {
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
pub struct NumericType {
|
||||
dim: NumericDimension,
|
||||
kind: naga::ScalarKind,
|
||||
width: naga::Bytes,
|
||||
scalar: naga::Scalar,
|
||||
}
|
||||
|
||||
impl fmt::Display for NumericType {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "{:?}{}{}", self.kind, self.width * 8, self.dim)
|
||||
write!(
|
||||
f,
|
||||
"{:?}{}{}",
|
||||
self.scalar.kind,
|
||||
self.scalar.width * 8,
|
||||
self.dim
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@ -592,77 +597,76 @@ impl Resource {
|
||||
|
||||
impl NumericType {
|
||||
fn from_vertex_format(format: wgt::VertexFormat) -> Self {
|
||||
use naga::{ScalarKind as Sk, VectorSize as Vs};
|
||||
use naga::{Scalar, VectorSize as Vs};
|
||||
use wgt::VertexFormat as Vf;
|
||||
|
||||
let (dim, kind, width) = match format {
|
||||
Vf::Uint32 => (NumericDimension::Scalar, Sk::Uint, 4),
|
||||
let (dim, scalar) = match format {
|
||||
Vf::Uint32 => (NumericDimension::Scalar, Scalar::U32),
|
||||
Vf::Uint8x2 | Vf::Uint16x2 | Vf::Uint32x2 => {
|
||||
(NumericDimension::Vector(Vs::Bi), Sk::Uint, 4)
|
||||
(NumericDimension::Vector(Vs::Bi), Scalar::U32)
|
||||
}
|
||||
Vf::Uint32x3 => (NumericDimension::Vector(Vs::Tri), Sk::Uint, 4),
|
||||
Vf::Uint32x3 => (NumericDimension::Vector(Vs::Tri), Scalar::U32),
|
||||
Vf::Uint8x4 | Vf::Uint16x4 | Vf::Uint32x4 => {
|
||||
(NumericDimension::Vector(Vs::Quad), Sk::Uint, 4)
|
||||
(NumericDimension::Vector(Vs::Quad), Scalar::U32)
|
||||
}
|
||||
Vf::Sint32 => (NumericDimension::Scalar, Sk::Sint, 4),
|
||||
Vf::Sint32 => (NumericDimension::Scalar, Scalar::I32),
|
||||
Vf::Sint8x2 | Vf::Sint16x2 | Vf::Sint32x2 => {
|
||||
(NumericDimension::Vector(Vs::Bi), Sk::Sint, 4)
|
||||
(NumericDimension::Vector(Vs::Bi), Scalar::I32)
|
||||
}
|
||||
Vf::Sint32x3 => (NumericDimension::Vector(Vs::Tri), Sk::Sint, 4),
|
||||
Vf::Sint32x3 => (NumericDimension::Vector(Vs::Tri), Scalar::I32),
|
||||
Vf::Sint8x4 | Vf::Sint16x4 | Vf::Sint32x4 => {
|
||||
(NumericDimension::Vector(Vs::Quad), Sk::Sint, 4)
|
||||
(NumericDimension::Vector(Vs::Quad), Scalar::I32)
|
||||
}
|
||||
Vf::Float32 => (NumericDimension::Scalar, Sk::Float, 4),
|
||||
Vf::Float32 => (NumericDimension::Scalar, Scalar::F32),
|
||||
Vf::Unorm8x2
|
||||
| Vf::Snorm8x2
|
||||
| Vf::Unorm16x2
|
||||
| Vf::Snorm16x2
|
||||
| Vf::Float16x2
|
||||
| Vf::Float32x2 => (NumericDimension::Vector(Vs::Bi), Sk::Float, 4),
|
||||
Vf::Float32x3 => (NumericDimension::Vector(Vs::Tri), Sk::Float, 4),
|
||||
| Vf::Float32x2 => (NumericDimension::Vector(Vs::Bi), Scalar::F32),
|
||||
Vf::Float32x3 => (NumericDimension::Vector(Vs::Tri), Scalar::F32),
|
||||
Vf::Unorm8x4
|
||||
| Vf::Snorm8x4
|
||||
| Vf::Unorm16x4
|
||||
| Vf::Snorm16x4
|
||||
| Vf::Float16x4
|
||||
| Vf::Float32x4 => (NumericDimension::Vector(Vs::Quad), Sk::Float, 4),
|
||||
Vf::Float64 => (NumericDimension::Scalar, Sk::Float, 8),
|
||||
Vf::Float64x2 => (NumericDimension::Vector(Vs::Bi), Sk::Float, 8),
|
||||
Vf::Float64x3 => (NumericDimension::Vector(Vs::Tri), Sk::Float, 8),
|
||||
Vf::Float64x4 => (NumericDimension::Vector(Vs::Quad), Sk::Float, 8),
|
||||
| Vf::Float32x4 => (NumericDimension::Vector(Vs::Quad), Scalar::F32),
|
||||
Vf::Float64 => (NumericDimension::Scalar, Scalar::F64),
|
||||
Vf::Float64x2 => (NumericDimension::Vector(Vs::Bi), Scalar::F64),
|
||||
Vf::Float64x3 => (NumericDimension::Vector(Vs::Tri), Scalar::F64),
|
||||
Vf::Float64x4 => (NumericDimension::Vector(Vs::Quad), Scalar::F64),
|
||||
};
|
||||
|
||||
NumericType {
|
||||
dim,
|
||||
kind,
|
||||
//Note: Shader always sees data as int, uint, or float.
|
||||
// It doesn't know if the original is normalized in a tighter form.
|
||||
width,
|
||||
scalar,
|
||||
}
|
||||
}
|
||||
|
||||
fn from_texture_format(format: wgt::TextureFormat) -> Self {
|
||||
use naga::{ScalarKind as Sk, VectorSize as Vs};
|
||||
use naga::{Scalar, VectorSize as Vs};
|
||||
use wgt::TextureFormat as Tf;
|
||||
|
||||
let (dim, kind) = match format {
|
||||
let (dim, scalar) = match format {
|
||||
Tf::R8Unorm | Tf::R8Snorm | Tf::R16Float | Tf::R32Float => {
|
||||
(NumericDimension::Scalar, Sk::Float)
|
||||
(NumericDimension::Scalar, Scalar::F32)
|
||||
}
|
||||
Tf::R8Uint | Tf::R16Uint | Tf::R32Uint => (NumericDimension::Scalar, Sk::Uint),
|
||||
Tf::R8Sint | Tf::R16Sint | Tf::R32Sint => (NumericDimension::Scalar, Sk::Sint),
|
||||
Tf::R8Uint | Tf::R16Uint | Tf::R32Uint => (NumericDimension::Scalar, Scalar::U32),
|
||||
Tf::R8Sint | Tf::R16Sint | Tf::R32Sint => (NumericDimension::Scalar, Scalar::I32),
|
||||
Tf::Rg8Unorm | Tf::Rg8Snorm | Tf::Rg16Float | Tf::Rg32Float => {
|
||||
(NumericDimension::Vector(Vs::Bi), Sk::Float)
|
||||
(NumericDimension::Vector(Vs::Bi), Scalar::F32)
|
||||
}
|
||||
Tf::Rg8Uint | Tf::Rg16Uint | Tf::Rg32Uint => {
|
||||
(NumericDimension::Vector(Vs::Bi), Sk::Uint)
|
||||
(NumericDimension::Vector(Vs::Bi), Scalar::U32)
|
||||
}
|
||||
Tf::Rg8Sint | Tf::Rg16Sint | Tf::Rg32Sint => {
|
||||
(NumericDimension::Vector(Vs::Bi), Sk::Sint)
|
||||
(NumericDimension::Vector(Vs::Bi), Scalar::I32)
|
||||
}
|
||||
Tf::R16Snorm | Tf::R16Unorm => (NumericDimension::Scalar, Sk::Float),
|
||||
Tf::Rg16Snorm | Tf::Rg16Unorm => (NumericDimension::Vector(Vs::Bi), Sk::Float),
|
||||
Tf::Rgba16Snorm | Tf::Rgba16Unorm => (NumericDimension::Vector(Vs::Quad), Sk::Float),
|
||||
Tf::R16Snorm | Tf::R16Unorm => (NumericDimension::Scalar, Scalar::F32),
|
||||
Tf::Rg16Snorm | Tf::Rg16Unorm => (NumericDimension::Vector(Vs::Bi), Scalar::F32),
|
||||
Tf::Rgba16Snorm | Tf::Rgba16Unorm => (NumericDimension::Vector(Vs::Quad), Scalar::F32),
|
||||
Tf::Rgba8Unorm
|
||||
| Tf::Rgba8UnormSrgb
|
||||
| Tf::Rgba8Snorm
|
||||
@ -670,14 +674,14 @@ impl NumericType {
|
||||
| Tf::Bgra8UnormSrgb
|
||||
| Tf::Rgb10a2Unorm
|
||||
| Tf::Rgba16Float
|
||||
| Tf::Rgba32Float => (NumericDimension::Vector(Vs::Quad), Sk::Float),
|
||||
| Tf::Rgba32Float => (NumericDimension::Vector(Vs::Quad), Scalar::F32),
|
||||
Tf::Rgba8Uint | Tf::Rgba16Uint | Tf::Rgba32Uint | Tf::Rgb10a2Uint => {
|
||||
(NumericDimension::Vector(Vs::Quad), Sk::Uint)
|
||||
(NumericDimension::Vector(Vs::Quad), Scalar::U32)
|
||||
}
|
||||
Tf::Rgba8Sint | Tf::Rgba16Sint | Tf::Rgba32Sint => {
|
||||
(NumericDimension::Vector(Vs::Quad), Sk::Sint)
|
||||
(NumericDimension::Vector(Vs::Quad), Scalar::I32)
|
||||
}
|
||||
Tf::Rg11b10Float => (NumericDimension::Vector(Vs::Tri), Sk::Float),
|
||||
Tf::Rg11b10Float => (NumericDimension::Vector(Vs::Tri), Scalar::F32),
|
||||
Tf::Stencil8
|
||||
| Tf::Depth16Unorm
|
||||
| Tf::Depth32Float
|
||||
@ -686,7 +690,7 @@ impl NumericType {
|
||||
| Tf::Depth24PlusStencil8 => {
|
||||
panic!("Unexpected depth format")
|
||||
}
|
||||
Tf::Rgb9e5Ufloat => (NumericDimension::Vector(Vs::Tri), Sk::Float),
|
||||
Tf::Rgb9e5Ufloat => (NumericDimension::Vector(Vs::Tri), Scalar::F32),
|
||||
Tf::Bc1RgbaUnorm
|
||||
| Tf::Bc1RgbaUnormSrgb
|
||||
| Tf::Bc2RgbaUnorm
|
||||
@ -698,36 +702,35 @@ impl NumericType {
|
||||
| Tf::Etc2Rgb8A1Unorm
|
||||
| Tf::Etc2Rgb8A1UnormSrgb
|
||||
| Tf::Etc2Rgba8Unorm
|
||||
| Tf::Etc2Rgba8UnormSrgb => (NumericDimension::Vector(Vs::Quad), Sk::Float),
|
||||
| Tf::Etc2Rgba8UnormSrgb => (NumericDimension::Vector(Vs::Quad), Scalar::F32),
|
||||
Tf::Bc4RUnorm | Tf::Bc4RSnorm | Tf::EacR11Unorm | Tf::EacR11Snorm => {
|
||||
(NumericDimension::Scalar, Sk::Float)
|
||||
(NumericDimension::Scalar, Scalar::F32)
|
||||
}
|
||||
Tf::Bc5RgUnorm | Tf::Bc5RgSnorm | Tf::EacRg11Unorm | Tf::EacRg11Snorm => {
|
||||
(NumericDimension::Vector(Vs::Bi), Sk::Float)
|
||||
(NumericDimension::Vector(Vs::Bi), Scalar::F32)
|
||||
}
|
||||
Tf::Bc6hRgbUfloat | Tf::Bc6hRgbFloat | Tf::Etc2Rgb8Unorm | Tf::Etc2Rgb8UnormSrgb => {
|
||||
(NumericDimension::Vector(Vs::Tri), Sk::Float)
|
||||
(NumericDimension::Vector(Vs::Tri), Scalar::F32)
|
||||
}
|
||||
Tf::Astc {
|
||||
block: _,
|
||||
channel: _,
|
||||
} => (NumericDimension::Vector(Vs::Quad), Sk::Float),
|
||||
} => (NumericDimension::Vector(Vs::Quad), Scalar::F32),
|
||||
};
|
||||
|
||||
NumericType {
|
||||
dim,
|
||||
kind,
|
||||
//Note: Shader always sees data as int, uint, or float.
|
||||
// It doesn't know if the original is normalized in a tighter form.
|
||||
width: 4,
|
||||
scalar,
|
||||
}
|
||||
}
|
||||
|
||||
fn is_subtype_of(&self, other: &NumericType) -> bool {
|
||||
if self.width > other.width {
|
||||
if self.scalar.width > other.scalar.width {
|
||||
return false;
|
||||
}
|
||||
if self.kind != other.kind {
|
||||
if self.scalar.kind != other.scalar.kind {
|
||||
return false;
|
||||
}
|
||||
match (self.dim, other.dim) {
|
||||
@ -742,7 +745,7 @@ impl NumericType {
|
||||
}
|
||||
|
||||
fn is_compatible_with(&self, other: &NumericType) -> bool {
|
||||
if self.kind != other.kind {
|
||||
if self.scalar.kind != other.scalar.kind {
|
||||
return false;
|
||||
}
|
||||
match (self.dim, other.dim) {
|
||||
@ -778,15 +781,13 @@ impl Interface {
|
||||
arena: &naga::UniqueArena<naga::Type>,
|
||||
) {
|
||||
let numeric_ty = match arena[ty].inner {
|
||||
naga::TypeInner::Scalar { kind, width } => NumericType {
|
||||
naga::TypeInner::Scalar(scalar) => NumericType {
|
||||
dim: NumericDimension::Scalar,
|
||||
kind,
|
||||
width,
|
||||
scalar,
|
||||
},
|
||||
naga::TypeInner::Vector { size, kind, width } => NumericType {
|
||||
naga::TypeInner::Vector { size, scalar } => NumericType {
|
||||
dim: NumericDimension::Vector(size),
|
||||
kind,
|
||||
width,
|
||||
scalar,
|
||||
},
|
||||
naga::TypeInner::Matrix {
|
||||
columns,
|
||||
@ -794,8 +795,7 @@ impl Interface {
|
||||
width,
|
||||
} => NumericType {
|
||||
dim: NumericDimension::Matrix(columns, rows),
|
||||
kind: naga::ScalarKind::Float,
|
||||
width,
|
||||
scalar: naga::Scalar::float(width),
|
||||
},
|
||||
naga::TypeInner::Struct { ref members, .. } => {
|
||||
for member in members {
|
||||
|
File diff suppressed because one or more lines are too long
@ -39,7 +39,7 @@ impl crate::BufferTextureCopy {
|
||||
let actual = self.buffer_layout.bytes_per_row.unwrap_or_else(|| {
|
||||
// this may happen for single-line updates
|
||||
let block_size = format
|
||||
.block_size(Some(self.texture_base.aspect.map()))
|
||||
.block_copy_size(Some(self.texture_base.aspect.map()))
|
||||
.unwrap();
|
||||
(self.size.width / block_width) * block_size
|
||||
});
|
||||
|
46
third_party/rust/wgpu-hal/src/gles/queue.rs
vendored
46
third_party/rust/wgpu-hal/src/gles/queue.rs
vendored
@ -564,7 +564,7 @@ impl super::Queue {
|
||||
ref copy,
|
||||
} => {
|
||||
let (block_width, block_height) = dst_format.block_dimensions();
|
||||
let block_size = dst_format.block_size(None).unwrap();
|
||||
let block_size = dst_format.block_copy_size(None).unwrap();
|
||||
let format_desc = self.shared.describe_texture_format(dst_format);
|
||||
let row_texels = copy
|
||||
.buffer_layout
|
||||
@ -702,7 +702,7 @@ impl super::Queue {
|
||||
dst_target: _,
|
||||
ref copy,
|
||||
} => {
|
||||
let block_size = src_format.block_size(None).unwrap();
|
||||
let block_size = src_format.block_copy_size(None).unwrap();
|
||||
if src_format.is_compressed() {
|
||||
log::error!("Not implemented yet: compressed texture copy to buffer");
|
||||
return;
|
||||
@ -1463,33 +1463,27 @@ impl super::Queue {
|
||||
//
|
||||
// --- Float 1-4 Component ---
|
||||
//
|
||||
naga::TypeInner::Scalar {
|
||||
kind: naga::ScalarKind::Float,
|
||||
width: 4,
|
||||
} => {
|
||||
naga::TypeInner::Scalar(naga::Scalar::F32) => {
|
||||
let data = unsafe { get_data::<f32, 1>(data_bytes, offset)[0] };
|
||||
unsafe { gl.uniform_1_f32(location, data) };
|
||||
}
|
||||
naga::TypeInner::Vector {
|
||||
kind: naga::ScalarKind::Float,
|
||||
size: naga::VectorSize::Bi,
|
||||
width: 4,
|
||||
scalar: naga::Scalar::F32,
|
||||
} => {
|
||||
let data = unsafe { get_data::<f32, 2>(data_bytes, offset) };
|
||||
unsafe { gl.uniform_2_f32_slice(location, data) };
|
||||
}
|
||||
naga::TypeInner::Vector {
|
||||
kind: naga::ScalarKind::Float,
|
||||
size: naga::VectorSize::Tri,
|
||||
width: 4,
|
||||
scalar: naga::Scalar::F32,
|
||||
} => {
|
||||
let data = unsafe { get_data::<f32, 3>(data_bytes, offset) };
|
||||
unsafe { gl.uniform_3_f32_slice(location, data) };
|
||||
}
|
||||
naga::TypeInner::Vector {
|
||||
kind: naga::ScalarKind::Float,
|
||||
size: naga::VectorSize::Quad,
|
||||
width: 4,
|
||||
scalar: naga::Scalar::F32,
|
||||
} => {
|
||||
let data = unsafe { get_data::<f32, 4>(data_bytes, offset) };
|
||||
unsafe { gl.uniform_4_f32_slice(location, data) };
|
||||
@ -1498,33 +1492,27 @@ impl super::Queue {
|
||||
//
|
||||
// --- Int 1-4 Component ---
|
||||
//
|
||||
naga::TypeInner::Scalar {
|
||||
kind: naga::ScalarKind::Sint,
|
||||
width: 4,
|
||||
} => {
|
||||
naga::TypeInner::Scalar(naga::Scalar::I32) => {
|
||||
let data = unsafe { get_data::<i32, 1>(data_bytes, offset)[0] };
|
||||
unsafe { gl.uniform_1_i32(location, data) };
|
||||
}
|
||||
naga::TypeInner::Vector {
|
||||
kind: naga::ScalarKind::Sint,
|
||||
size: naga::VectorSize::Bi,
|
||||
width: 4,
|
||||
scalar: naga::Scalar::I32,
|
||||
} => {
|
||||
let data = unsafe { get_data::<i32, 2>(data_bytes, offset) };
|
||||
unsafe { gl.uniform_2_i32_slice(location, data) };
|
||||
}
|
||||
naga::TypeInner::Vector {
|
||||
kind: naga::ScalarKind::Sint,
|
||||
size: naga::VectorSize::Tri,
|
||||
width: 4,
|
||||
scalar: naga::Scalar::I32,
|
||||
} => {
|
||||
let data = unsafe { get_data::<i32, 3>(data_bytes, offset) };
|
||||
unsafe { gl.uniform_3_i32_slice(location, data) };
|
||||
}
|
||||
naga::TypeInner::Vector {
|
||||
kind: naga::ScalarKind::Sint,
|
||||
size: naga::VectorSize::Quad,
|
||||
width: 4,
|
||||
scalar: naga::Scalar::I32,
|
||||
} => {
|
||||
let data = unsafe { get_data::<i32, 4>(data_bytes, offset) };
|
||||
unsafe { gl.uniform_4_i32_slice(location, data) };
|
||||
@ -1533,33 +1521,27 @@ impl super::Queue {
|
||||
//
|
||||
// --- Uint 1-4 Component ---
|
||||
//
|
||||
naga::TypeInner::Scalar {
|
||||
kind: naga::ScalarKind::Uint,
|
||||
width: 4,
|
||||
} => {
|
||||
naga::TypeInner::Scalar(naga::Scalar::U32) => {
|
||||
let data = unsafe { get_data::<u32, 1>(data_bytes, offset)[0] };
|
||||
unsafe { gl.uniform_1_u32(location, data) };
|
||||
}
|
||||
naga::TypeInner::Vector {
|
||||
kind: naga::ScalarKind::Uint,
|
||||
size: naga::VectorSize::Bi,
|
||||
width: 4,
|
||||
scalar: naga::Scalar::U32,
|
||||
} => {
|
||||
let data = unsafe { get_data::<u32, 2>(data_bytes, offset) };
|
||||
unsafe { gl.uniform_2_u32_slice(location, data) };
|
||||
}
|
||||
naga::TypeInner::Vector {
|
||||
kind: naga::ScalarKind::Uint,
|
||||
size: naga::VectorSize::Tri,
|
||||
width: 4,
|
||||
scalar: naga::Scalar::U32,
|
||||
} => {
|
||||
let data = unsafe { get_data::<u32, 3>(data_bytes, offset) };
|
||||
unsafe { gl.uniform_3_u32_slice(location, data) };
|
||||
}
|
||||
naga::TypeInner::Vector {
|
||||
kind: naga::ScalarKind::Uint,
|
||||
size: naga::VectorSize::Quad,
|
||||
width: 4,
|
||||
scalar: naga::Scalar::U32,
|
||||
} => {
|
||||
let data = unsafe { get_data::<u32, 4>(data_bytes, offset) };
|
||||
unsafe { gl.uniform_4_u32_slice(location, data) };
|
||||
|
@ -23,7 +23,7 @@ impl super::Texture {
|
||||
buffer_offset: r.buffer_layout.offset,
|
||||
buffer_row_length: r.buffer_layout.bytes_per_row.map_or(0, |bpr| {
|
||||
let block_size = format
|
||||
.block_size(Some(r.texture_base.aspect.map()))
|
||||
.block_copy_size(Some(r.texture_base.aspect.map()))
|
||||
.unwrap();
|
||||
block_width * (bpr / block_size)
|
||||
}),
|
||||
|
3
third_party/rust/wgpu-hal/src/vulkan/conv.rs
vendored
3
third_party/rust/wgpu-hal/src/vulkan/conv.rs
vendored
@ -451,8 +451,7 @@ pub fn map_vk_present_mode(mode: vk::PresentModeKHR) -> Option<wgt::PresentMode>
|
||||
} else if mode == vk::PresentModeKHR::FIFO {
|
||||
Some(wgt::PresentMode::Fifo)
|
||||
} else if mode == vk::PresentModeKHR::FIFO_RELAXED {
|
||||
//Some(wgt::PresentMode::Relaxed)
|
||||
None
|
||||
Some(wgt::PresentMode::FifoRelaxed)
|
||||
} else {
|
||||
log::warn!("Unrecognized present mode {:?}", mode);
|
||||
None
|
||||
|
@ -1 +1 @@
|
||||
{"files":{"Cargo.toml":"e45ee369c8f91526056ba7f46504e270da1d8b2de65431bbaf36426bcd54da68","LICENSE.APACHE":"a6cba85bc92e0cff7a450b1d873c0eaa2e9fc96bf472df0247a26bec77bf3ff9","LICENSE.MIT":"c7fea58d1cfe49634cd92e54fc10a9d871f4b275321a4cd8c09e449122caaeb4","src/assertions.rs":"3fe98027aa73970c8ab7874a3e13dbfd6faa87df2081beb5c83aeec4c60f372f","src/lib.rs":"82e95f3af2d4e7279e5ea31897fb51dd614e4c6cae9c23ddd2b8b5b6bb2ad35a","src/math.rs":"4d03039736dd6926feb139bc68734cb59df34ede310427bbf059e5c925e0af3b"},"package":null}
|
||||
{"files":{"Cargo.toml":"e45ee369c8f91526056ba7f46504e270da1d8b2de65431bbaf36426bcd54da68","LICENSE.APACHE":"a6cba85bc92e0cff7a450b1d873c0eaa2e9fc96bf472df0247a26bec77bf3ff9","LICENSE.MIT":"c7fea58d1cfe49634cd92e54fc10a9d871f4b275321a4cd8c09e449122caaeb4","src/assertions.rs":"3fe98027aa73970c8ab7874a3e13dbfd6faa87df2081beb5c83aeec4c60f372f","src/lib.rs":"4e1ef56078799af2c15ca573a05b5deebbb084b447a5840cd61971afa4c73924","src/math.rs":"4d03039736dd6926feb139bc68734cb59df34ede310427bbf059e5c925e0af3b"},"package":null}
|
40
third_party/rust/wgpu-types/src/lib.rs
vendored
40
third_party/rust/wgpu-types/src/lib.rs
vendored
@ -2813,7 +2813,9 @@ impl TextureFormat {
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the dimension of a block of texels.
|
||||
/// Returns the dimension of a [block](https://gpuweb.github.io/gpuweb/#texel-block) of texels.
|
||||
///
|
||||
/// Uncompressed formats have a block dimension of `(1, 1)`.
|
||||
pub fn block_dimensions(&self) -> (u32, u32) {
|
||||
match *self {
|
||||
Self::R8Unorm
|
||||
@ -3225,14 +3227,34 @@ impl TextureFormat {
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the [texel block size](https://gpuweb.github.io/gpuweb/#texel-block-size)
|
||||
/// of this format.
|
||||
/// The number of bytes one [texel block](https://gpuweb.github.io/gpuweb/#texel-block) occupies during an image copy, if applicable.
|
||||
///
|
||||
/// Known as the [texel block copy footprint](https://gpuweb.github.io/gpuweb/#texel-block-copy-footprint).
|
||||
///
|
||||
/// Note that for uncompressed formats this is the same as the size of a single texel,
|
||||
/// since uncompressed formats have a block size of 1x1.
|
||||
///
|
||||
/// Returns `None` if any of the following are true:
|
||||
/// - the format is combined depth-stencil and no `aspect` was provided
|
||||
/// - the format is `Depth24Plus`
|
||||
/// - the format is `Depth24PlusStencil8` and `aspect` is depth.
|
||||
#[deprecated(since = "0.19.0", note = "Use `block_copy_size` instead.")]
|
||||
pub fn block_size(&self, aspect: Option<TextureAspect>) -> Option<u32> {
|
||||
self.block_copy_size(aspect)
|
||||
}
|
||||
|
||||
/// The number of bytes one [texel block](https://gpuweb.github.io/gpuweb/#texel-block) occupies during an image copy, if applicable.
|
||||
///
|
||||
/// Known as the [texel block copy footprint](https://gpuweb.github.io/gpuweb/#texel-block-copy-footprint).
|
||||
///
|
||||
/// Note that for uncompressed formats this is the same as the size of a single texel,
|
||||
/// since uncompressed formats have a block size of 1x1.
|
||||
///
|
||||
/// Returns `None` if any of the following are true:
|
||||
/// - the format is combined depth-stencil and no `aspect` was provided
|
||||
/// - the format is `Depth24Plus`
|
||||
/// - the format is `Depth24PlusStencil8` and `aspect` is depth.
|
||||
pub fn block_copy_size(&self, aspect: Option<TextureAspect>) -> Option<u32> {
|
||||
match *self {
|
||||
Self::R8Unorm | Self::R8Snorm | Self::R8Uint | Self::R8Sint => Some(1),
|
||||
|
||||
@ -6707,3 +6729,15 @@ mod send_sync {
|
||||
)))]
|
||||
impl<T> WasmNotSync for T {}
|
||||
}
|
||||
|
||||
/// Reason for "lose the device".
|
||||
///
|
||||
/// Corresponds to [WebGPU `GPUDeviceLostReason`](https://gpuweb.github.io/gpuweb/#enumdef-gpudevicelostreason).
|
||||
#[repr(u8)]
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
pub enum DeviceLostReason {
|
||||
/// Triggered by driver
|
||||
Unknown = 0,
|
||||
/// After Device::destroy
|
||||
Destroyed = 1,
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user