Bug 1862689 - Update `wgpu` to revision 49b7ec97c164bac9ee877f45cdd806fbefecc5a4. r=webgpu-reviewers,ErichDonGubler

Depends on D192648

Differential Revision: https://phabricator.services.mozilla.com/D192649
This commit is contained in:
Jim Blandy 2023-11-04 00:15:04 +00:00
Родитель d8dc0b9d25
Коммит bd70a71e6c
50 изменённых файлов: 2861 добавлений и 1179 удалений

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

@ -25,19 +25,14 @@ git = "https://github.com/franziskuskiefer/cose-rust"
rev = "43c22248d136c8b38fe42ea709d08da6355cf04b"
replace-with = "vendored-sources"
[source."git+https://github.com/gfx-rs/metal-rs/?rev=d24f1a4"]
git = "https://github.com/gfx-rs/metal-rs/"
rev = "d24f1a4"
replace-with = "vendored-sources"
[source."git+https://github.com/gfx-rs/naga?rev=e25280df9316434ef7752970016d01a3aede3f17"]
[source."git+https://github.com/gfx-rs/naga?rev=92e41b43e437146b5d946eb238de963be1168016"]
git = "https://github.com/gfx-rs/naga"
rev = "e25280df9316434ef7752970016d01a3aede3f17"
rev = "92e41b43e437146b5d946eb238de963be1168016"
replace-with = "vendored-sources"
[source."git+https://github.com/gfx-rs/wgpu?rev=75989192a9c8f70893882ce0f4373ac217d380c3"]
[source."git+https://github.com/gfx-rs/wgpu?rev=49b7ec97c164bac9ee877f45cdd806fbefecc5a4"]
git = "https://github.com/gfx-rs/wgpu"
rev = "75989192a9c8f70893882ce0f4373ac217d380c3"
rev = "49b7ec97c164bac9ee877f45cdd806fbefecc5a4"
replace-with = "vendored-sources"
[source."git+https://github.com/glandium/warp?rev=4af45fae95bc98b0eba1ef0db17e1dac471bb23d"]

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

@ -3382,8 +3382,9 @@ dependencies = [
[[package]]
name = "metal"
version = "0.26.0"
source = "git+https://github.com/gfx-rs/metal-rs/?rev=d24f1a4#d24f1a4ae92470bf87a0c65ecfe78c9299835505"
version = "0.27.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c43f73953f8cbe511f021b58f18c3ce1c3d1ae13fe953293e13345bf83217f25"
dependencies = [
"bitflags 2.4.0",
"block",
@ -3758,8 +3759,8 @@ checksum = "a2983372caf4480544083767bf2d27defafe32af49ab4df3a0b7fc90793a3664"
[[package]]
name = "naga"
version = "0.13.0"
source = "git+https://github.com/gfx-rs/naga?rev=e25280df9316434ef7752970016d01a3aede3f17#e25280df9316434ef7752970016d01a3aede3f17"
version = "0.14.0"
source = "git+https://github.com/gfx-rs/naga?rev=92e41b43e437146b5d946eb238de963be1168016#92e41b43e437146b5d946eb238de963be1168016"
dependencies = [
"bit-set",
"bitflags 2.4.0",
@ -6346,8 +6347,8 @@ dependencies = [
[[package]]
name = "wgpu-core"
version = "0.17.0"
source = "git+https://github.com/gfx-rs/wgpu?rev=75989192a9c8f70893882ce0f4373ac217d380c3#75989192a9c8f70893882ce0f4373ac217d380c3"
version = "0.18.0"
source = "git+https://github.com/gfx-rs/wgpu?rev=49b7ec97c164bac9ee877f45cdd806fbefecc5a4#49b7ec97c164bac9ee877f45cdd806fbefecc5a4"
dependencies = [
"arrayvec",
"bit-vec",
@ -6369,8 +6370,8 @@ dependencies = [
[[package]]
name = "wgpu-hal"
version = "0.17.0"
source = "git+https://github.com/gfx-rs/wgpu?rev=75989192a9c8f70893882ce0f4373ac217d380c3#75989192a9c8f70893882ce0f4373ac217d380c3"
version = "0.18.0"
source = "git+https://github.com/gfx-rs/wgpu?rev=49b7ec97c164bac9ee877f45cdd806fbefecc5a4#49b7ec97c164bac9ee877f45cdd806fbefecc5a4"
dependencies = [
"android_system_properties",
"arrayvec",
@ -6406,8 +6407,8 @@ dependencies = [
[[package]]
name = "wgpu-types"
version = "0.17.0"
source = "git+https://github.com/gfx-rs/wgpu?rev=75989192a9c8f70893882ce0f4373ac217d380c3#75989192a9c8f70893882ce0f4373ac217d380c3"
version = "0.18.0"
source = "git+https://github.com/gfx-rs/wgpu?rev=49b7ec97c164bac9ee877f45cdd806fbefecc5a4#49b7ec97c164bac9ee877f45cdd806fbefecc5a4"
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 = "75989192a9c8f70893882ce0f4373ac217d380c3"
rev = "49b7ec97c164bac9ee877f45cdd806fbefecc5a4"
#Note: "replay" shouldn't ideally be needed,
# but it allows us to serialize everything across IPC.
features = ["replay", "trace", "serial-pass", "strict_asserts", "wgsl"]
@ -27,32 +27,32 @@ features = ["replay", "trace", "serial-pass", "strict_asserts", "wgsl"]
[target.'cfg(any(target_os = "macos", target_os = "ios"))'.dependencies.wgc]
package = "wgpu-core"
git = "https://github.com/gfx-rs/wgpu"
rev = "75989192a9c8f70893882ce0f4373ac217d380c3"
rev = "49b7ec97c164bac9ee877f45cdd806fbefecc5a4"
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 = "75989192a9c8f70893882ce0f4373ac217d380c3"
rev = "49b7ec97c164bac9ee877f45cdd806fbefecc5a4"
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 = "75989192a9c8f70893882ce0f4373ac217d380c3"
rev = "49b7ec97c164bac9ee877f45cdd806fbefecc5a4"
features = ["vulkan"]
[dependencies.wgt]
package = "wgpu-types"
git = "https://github.com/gfx-rs/wgpu"
rev = "75989192a9c8f70893882ce0f4373ac217d380c3"
rev = "49b7ec97c164bac9ee877f45cdd806fbefecc5a4"
[dependencies.wgh]
package = "wgpu-hal"
git = "https://github.com/gfx-rs/wgpu"
rev = "75989192a9c8f70893882ce0f4373ac217d380c3"
rev = "49b7ec97c164bac9ee877f45cdd806fbefecc5a4"
[target.'cfg(windows)'.dependencies]
d3d12 = "0.7.0"

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

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

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

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

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

@ -1,51 +0,0 @@
name: ci
on: [pull_request, push]
env:
RUST_BACKTRACE: 1
CARGO_INCREMENTAL: 0
RUSTFLAGS: "-Cdebuginfo=0 --deny=warnings"
jobs:
build:
runs-on: macos-latest
strategy:
matrix:
channel: [stable, nightly]
steps:
- uses: actions/checkout@v3
- name: Setup rust toolchain
uses: dtolnay/rust-toolchain@stable
with:
toolchain: ${{ matrix.channel }}
- name: Rust Version Info
run: rustc --version && cargo --version
- name: Cache cargo registry
uses: actions/cache@v3
with:
path: ~/.cargo/registry
key: ${{ runner.os }}-${{ matrix.channel }}-cargo-registry-${{ hashFiles('**/Cargo.lock') }}
- name: Cache cargo index
uses: actions/cache@v3
with:
path: ~/.cargo/git
key: ${{ runner.os }}-${{ matrix.channel }}-cargo-index-${{ hashFiles('**/Cargo.lock') }}
- name: Cache cargo build
uses: actions/cache@v3
with:
path: target
key: ${{ runner.os }}-${{ matrix.channel }}-cargo-build-target-${{ hashFiles('**/Cargo.lock') }}
- name: cargo check
run: cargo check --all-features
- name: Run all tests
run: cargo test --all-features

1516
third_party/rust/metal/Cargo.lock сгенерированный поставляемый Normal file

Разница между файлами не показана из-за своего большого размера Загрузить разницу

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

@ -12,7 +12,7 @@
[package]
edition = "2021"
name = "metal"
version = "0.26.0"
version = "0.27.0"
authors = ["gfx-rs developers"]
exclude = [
"guide/**/*",
@ -90,36 +90,55 @@ required-features = ["dispatch"]
[[example]]
name = "fence"
[dependencies]
bitflags = "2"
block = "0.1.6"
core-graphics-types = "0.1"
foreign-types = "0.5"
log = "0.4"
paste = "1"
[dependencies.bitflags]
version = "2"
[dependencies.block]
version = "0.1.6"
[dependencies.core-graphics-types]
version = "0.1"
[dependencies.dispatch]
version = "0.2"
optional = true
[dependencies.foreign-types]
version = "0.5"
[dependencies.log]
version = "0.4"
[dependencies.objc]
version = "0.2.4"
features = ["objc_exception"]
[dev-dependencies]
cocoa = "0.24.0"
cty = "0.2.1"
glam = "0.22"
png = "0.17"
rand = "0.8"
sema = "0.1.4"
winit = "0.27"
[dependencies.paste]
version = "1"
[dev-dependencies.cocoa]
version = "0.24.0"
[dev-dependencies.cty]
version = "0.2.1"
[dev-dependencies.glam]
version = "0.22"
[dev-dependencies.png]
version = "0.17"
[dev-dependencies.rand]
version = "0.8"
[dev-dependencies.sema]
version = "0.1.4"
[dev-dependencies.winit]
version = "0.27"
[features]
default = ["link"]
link = []
mps = []
private = []
[workspace]
members = ["examples/texture"]

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

@ -1 +0,0 @@
out.png

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

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

88
third_party/rust/naga/CHANGELOG.md поставляемый
Просмотреть файл

@ -1,10 +1,94 @@
# Change Log
## Unreleased
## v0.14 (2023-10-25)
#### GENERAL
- Bump MSRV to 1.65 ([#2420](https://github.com/gfx-rs/naga/pull/2420)) **@jimblandy**
- Add support for const-expressions. ([#2309](https://github.com/gfx-rs/naga/pull/2309)) **@teoxoy**, **@jimblandy**
- Add support for the `rgb10a2uint` storage format. ([#2525](https://github.com/gfx-rs/naga/pull/2525)) **@teoxoy**
- Implement module compaction for snapshot testing and the CLI. ([#2472](https://github.com/gfx-rs/naga/pull/2472)) **@jimblandy**
- Fix validation and GLSL parsing of `ldexp`. ([#2449](https://github.com/gfx-rs/naga/pull/2449)) **@fornwall**
- Add support for dual source blending. ([#2427](https://github.com/gfx-rs/naga/pull/2427)) **@freqmod**
- Bump `indexmap` to v2. ([#2426](https://github.com/gfx-rs/naga/pull/2426)) **@daxpedda**
- Bump MSRV to 1.65. ([#2420](https://github.com/gfx-rs/naga/pull/2420)) **@jimblandy**
#### API
- Split `UnaryOperator::Not` into `UnaryOperator::LogicalNot` & `UnaryOperator::BitwiseNot`. ([#2554](https://github.com/gfx-rs/naga/pull/2554)) **@teoxoy**
- Remove `IsFinite` & `IsNormal` relational functions. ([#2532](https://github.com/gfx-rs/naga/pull/2532)) **@teoxoy**
- Derive `PartialEq` on `Expression`. ([#2417](https://github.com/gfx-rs/naga/pull/2417)) **@robtfm**
- Use `FastIndexMap` for `SpecialTypes::predeclared_types`. ([#2495](https://github.com/gfx-rs/naga/pull/2495)) **@jimblandy**
#### CLI
- Change `--generate-debug-symbols` from an `option` to a `switch`. ([#2472](https://github.com/gfx-rs/naga/pull/2472)) **@jimblandy**
- Add support for `.{vert,frag,comp}.glsl` files. ([#2462](https://github.com/gfx-rs/naga/pull/2462)) **@eliemichel**
#### VALIDATOR
- Require `Capabilities::FLOAT64` for 64-bit floating-point literals. ([#2567](https://github.com/gfx-rs/naga/pull/2567)) **@jimblandy**
- Add `Capabilities::CUBE_ARRAY_TEXTURES`. ([#2530](https://github.com/gfx-rs/naga/pull/2530)) **@teoxoy**
- Disallow passing pointers to variables in the workgroup address space to functions. ([#2507](https://github.com/gfx-rs/naga/pull/2507)) **@teoxoy**
- Avoid OOM with large sparse resource bindings. ([#2561](https://github.com/gfx-rs/naga/pull/2561)) **@teoxoy**
- Require that `Function` and `Private` variables be `CONSTRUCTIBLE`. ([#2545](https://github.com/gfx-rs/naga/pull/2545)) **@jimblandy**
- Disallow floating-point NaNs and infinities. ([#2508](https://github.com/gfx-rs/naga/pull/2508)) **@teoxoy**
- Temporarily disable uniformity analysis for the fragment stage. ([#2515](https://github.com/gfx-rs/naga/pull/2515)) **@teoxoy**
- Validate that `textureSampleBias` is only used in the fragment stage. ([#2515](https://github.com/gfx-rs/naga/pull/2515)) **@teoxoy**
- Validate variable initializer for address spaces. ([#2513](https://github.com/gfx-rs/naga/pull/2513)) **@teoxoy**
- Prevent using multiple push constant variables in one entry point. ([#2484](https://github.com/gfx-rs/naga/pull/2484)) **@andriyDev**
- Validate `binding_array` variable address space. ([#2422](https://github.com/gfx-rs/naga/pull/2422)) **@teoxoy**
- Validate storage buffer access. ([#2415](https://github.com/gfx-rs/naga/pull/2415)) **@teoxoy**
#### WGSL-IN
- Fix expected min arg count of `textureLoad`. ([#2584](https://github.com/gfx-rs/naga/pull/2584)) **@teoxoy**
- Turn `Error::Other` into `Error::Internal`, to help devs. ([#2574](https://github.com/gfx-rs/naga/pull/2574)) **@jimblandy**
- Fix OOB typifier indexing. ([#2570](https://github.com/gfx-rs/naga/pull/2570)) **@teoxoy**
- Add support for the `bgra8unorm` storage format. ([#2542](https://github.com/gfx-rs/naga/pull/2542) & [#2550](https://github.com/gfx-rs/naga/pull/2550)) **@nical**
- Remove the `outerProduct` built-in function. ([#2535](https://github.com/gfx-rs/naga/pull/2535)) **@teoxoy**
- Add support for `i32` overload of the `sign` built-in function. ([#2463](https://github.com/gfx-rs/naga/pull/2463)) **@fornwall**
- Properly implement `modf` and `frexp`. ([#2454](https://github.com/gfx-rs/naga/pull/2454)) **@fornwall**
- Add support for scalar overloads of `all` & `any` built-in functions. ([#2445](https://github.com/gfx-rs/naga/pull/2445)) **@fornwall**
- Don't splat the left hand operand of a binary operation if it's not a scalar. ([#2444](https://github.com/gfx-rs/naga/pull/2444)) **@fornwall**
- Avoid splatting all binary operator expressions. ([#2440](https://github.com/gfx-rs/naga/pull/2440)) **@fornwall**
- Error on repeated or missing `@workgroup_size()`. ([#2435](https://github.com/gfx-rs/naga/pull/2435)) **@fornwall**
- Error on repeated attributes. ([#2428](https://github.com/gfx-rs/naga/pull/2428)) **@fornwall**
- Fix error message for invalid `texture{Load,Store}()` on arrayed textures. ([#2432](https://github.com/gfx-rs/naga/pull/2432)) **@fornwall**
#### SPV-IN
- Disable `Modf` & `Frexp` and translate `ModfStruct` & `FrexpStruct` to their IR equivalents. ([#2527](https://github.com/gfx-rs/naga/pull/2527)) **@teoxoy**
- Don't advertise support for `Capability::ImageMSArray` & `Capability::InterpolationFunction`. ([#2529](https://github.com/gfx-rs/naga/pull/2529)) **@teoxoy**
- Fix `OpImageQueries` to allow Uints. ([#2404](https://github.com/gfx-rs/naga/pull/2404)) **@evahop**
#### GLSL-IN
- Disable `modf` & `frexp`. ([#2527](https://github.com/gfx-rs/naga/pull/2527)) **@teoxoy**
#### SPV-OUT
- Require `ClipDistance` & `CullDistance` capabilities if necessary. ([#2528](https://github.com/gfx-rs/naga/pull/2528)) **@teoxoy**
- Change `naga::back::spv::DebugInfo::file_name` to a `&Path`. ([#2501](https://github.com/gfx-rs/naga/pull/2501)) **@jimblandy**
- Always give structs with runtime arrays a `Block` decoration. ([#2455](https://github.com/gfx-rs/naga/pull/2455)) **@TheoDulka**
- Decorate the result of the `OpLoad` with `NonUniform` (not the access chain) when loading images/samplers (resources in the Handle address space). ([#2422](https://github.com/gfx-rs/naga/pull/2422)) **@teoxoy**
- Cache `OpConstantNull`. ([#2414](https://github.com/gfx-rs/naga/pull/2414)) **@evahop**
#### MSL-OUT
- Add and fix minimum Metal version checks for optional functionality. ([#2486](https://github.com/gfx-rs/naga/pull/2486)) **@teoxoy**
- Make varyings' struct members unique. ([#2521](https://github.com/gfx-rs/naga/pull/2521)) **@evahop**
#### GLSL-OUT
- Cull functions that should not be available for a given stage. ([#2531](https://github.com/gfx-rs/naga/pull/2531)) **@teoxoy**
- Rename identifiers containing double underscores. ([#2510](https://github.com/gfx-rs/naga/pull/2510)) **@evahop**
- Polyfill `frexp`. ([#2504](https://github.com/gfx-rs/naga/pull/2504)) **@evahop**
- Add built-in functions to keywords. ([#2410](https://github.com/gfx-rs/naga/pull/2410)) **@fornwall**
#### WGSL-OUT
- Generate correct code for bit complement on integers. ([#2548](https://github.com/gfx-rs/naga/pull/2548)) **@jimblandy**
- Don't include type parameter in splat expressions. ([#2469](https://github.com/gfx-rs/naga/pull/2469)) **@jimblandy**
## v0.13 (2023-07-21)

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

@ -13,7 +13,7 @@
edition = "2021"
rust-version = "1.65"
name = "naga"
version = "0.13.0"
version = "0.14.0"
authors = ["Naga Developers"]
exclude = [
"bin/**/*",

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

@ -41,10 +41,7 @@ pub struct Handle<T> {
impl<T> Clone for Handle<T> {
fn clone(&self) -> Self {
Handle {
index: self.index,
marker: self.marker,
}
*self
}
}
@ -60,7 +57,7 @@ impl<T> Eq for Handle<T> {}
impl<T> PartialOrd for Handle<T> {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
self.index.partial_cmp(&other.index)
Some(self.cmp(other))
}
}

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

@ -98,7 +98,6 @@ impl FeaturesManager {
check_feature!(ARRAY_OF_ARRAYS, 120, 310);
check_feature!(IMAGE_LOAD_STORE, 130, 310);
check_feature!(CONSERVATIVE_DEPTH, 130, 300);
check_feature!(CONSERVATIVE_DEPTH, 130, 300);
check_feature!(NOPERSPECTIVE_QUALIFIER, 130);
check_feature!(SAMPLE_QUALIFIER, 400, 320);
check_feature!(CLIP_DISTANCE, 130, 300 /* with extension */);

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

@ -55,6 +55,7 @@ use std::{
cmp::Ordering,
fmt,
fmt::{Error as FmtError, Write},
mem,
};
use thiserror::Error;
@ -64,7 +65,7 @@ mod features;
mod keywords;
/// List of supported `core` GLSL versions.
pub const SUPPORTED_CORE_VERSIONS: &[u16] = &[330, 400, 410, 420, 430, 440, 450];
pub const SUPPORTED_CORE_VERSIONS: &[u16] = &[140, 150, 330, 400, 410, 420, 430, 440, 450, 460];
/// List of supported `es` GLSL versions.
pub const SUPPORTED_ES_VERSIONS: &[u16] = &[300, 310, 320];
@ -163,6 +164,10 @@ impl Version {
}
}
fn supports_io_locations(&self) -> bool {
*self >= Version::Desktop(330) || *self >= Version::new_gles(300)
}
/// Checks if the version supports all of the explicit layouts:
/// - `location=` qualifiers for bindings
/// - `binding=` qualifiers for resources
@ -285,12 +290,25 @@ pub struct PipelineOptions {
pub multiview: Option<std::num::NonZeroU32>,
}
#[derive(Debug)]
pub struct VaryingLocation {
/// The location of the global.
/// This corresponds to `layout(location = ..)` in GLSL.
pub location: u32,
/// The index which can be used for dual source blending.
/// This corresponds to `layout(index = ..)` in GLSL.
pub index: u32,
}
/// Reflection info for texture mappings and uniforms.
#[derive(Debug)]
pub struct ReflectionInfo {
/// Mapping between texture names and variables/samplers.
pub texture_mapping: crate::FastHashMap<String, TextureMapping>,
/// Mapping between uniform variables and names.
pub uniforms: crate::FastHashMap<Handle<crate::GlobalVariable>, String>,
/// Mapping between names and attribute locations.
pub varying: crate::FastHashMap<String, VaryingLocation>,
}
/// Mapping between a texture and its sampler, if it exists.
@ -463,6 +481,8 @@ pub struct Writer<'a, W> {
need_bake_expressions: back::NeedBakeExpressions,
/// How many views to render to, if doing multiview rendering.
multiview: Option<std::num::NonZeroU32>,
/// Mapping of varying variables to their location. Needed for reflections.
varying: crate::FastHashMap<String, VaryingLocation>,
}
impl<'a, W: Write> Writer<'a, W> {
@ -525,6 +545,7 @@ impl<'a, W: Write> Writer<'a, W> {
block_id: IdGenerator::default(),
named_expressions: Default::default(),
need_bake_expressions: Default::default(),
varying: Default::default(),
};
// Find all features required to print this module
@ -1006,9 +1027,16 @@ impl<'a, W: Write> Writer<'a, W> {
Ic::Storage { format, .. } => ("image", format.into(), "", ""),
};
let precision = if self.options.version.is_es() {
"highp "
} else {
""
};
write!(
self.out,
"highp {}{}{}{}{}{}",
"{}{}{}{}{}{}{}",
precision,
glsl_scalar(kind, 4)?.prefix,
base,
glsl_dimension(dim),
@ -1367,13 +1395,25 @@ impl<'a, W: Write> Writer<'a, W> {
};
// Write the I/O locations, if allowed
if self.options.version.supports_explicit_locations() || !emit_interpolation_and_auxiliary {
if second_blend_source {
write!(self.out, "layout(location = {location}, index = 1) ")?;
let io_location = if self.options.version.supports_explicit_locations()
|| !emit_interpolation_and_auxiliary
{
if self.options.version.supports_io_locations() {
if second_blend_source {
write!(self.out, "layout(location = {location}, index = 1) ")?;
} else {
write!(self.out, "layout(location = {location}) ")?;
}
None
} else {
write!(self.out, "layout(location = {location}) ")?;
Some(VaryingLocation {
location,
index: second_blend_source as u32,
})
}
}
} else {
None
};
// Write the interpolation qualifier.
if let Some(interp) = interpolation {
@ -1417,6 +1457,10 @@ impl<'a, W: Write> Writer<'a, W> {
};
writeln!(self.out, " {vname};")?;
if let Some(location) = io_location {
self.varying.insert(vname.to_string(), location);
}
Ok(())
}
@ -1828,8 +1872,7 @@ impl<'a, W: Write> Writer<'a, W> {
// This is where we can generate intermediate constants for some expression types.
Statement::Emit(ref range) => {
for handle in range.clone() {
let info = &ctx.info[handle];
let ptr_class = info.ty.inner_with(&self.module.types).pointer_space();
let ptr_class = ctx.resolve_type(handle, &self.module.types).pointer_space();
let expr_name = if ptr_class.is_some() {
// GLSL can't save a pointer-valued expression in a variable,
// but we shouldn't ever need to: they should never be named expressions,
@ -1859,7 +1902,7 @@ impl<'a, W: Write> Writer<'a, W> {
if let TypeInner::Image {
class: crate::ImageClass::Sampled { .. },
..
} = *ctx.info[image].ty.inner_with(&self.module.types)
} = *ctx.resolve_type(image, &self.module.types)
{
if let proc::BoundsCheckPolicy::Restrict = self.policies.image_load {
write!(self.out, "{level}")?;
@ -2225,7 +2268,7 @@ impl<'a, W: Write> Writer<'a, W> {
} => {
write!(self.out, "{level}")?;
let res_name = format!("{}{}", back::BAKE_PREFIX, result.index());
let res_ty = ctx.info[result].ty.inner_with(&self.module.types);
let res_ty = ctx.resolve_type(result, &self.module.types);
self.write_value_type(res_ty)?;
write!(self.out, " {res_name} = ")?;
self.named_expressions.insert(result, res_name);
@ -2484,7 +2527,7 @@ impl<'a, W: Write> Writer<'a, W> {
level,
depth_ref,
} => {
let dim = match *ctx.info[image].ty.inner_with(&self.module.types) {
let dim = match *ctx.resolve_type(image, &self.module.types) {
TypeInner::Image { dim, .. } => dim,
_ => unreachable!(),
};
@ -2545,7 +2588,7 @@ impl<'a, W: Write> Writer<'a, W> {
// We need to get the coordinates vector size to later build a vector that's `size + 1`
// if `depth_ref` is some, if it isn't a vector we panic as that's not a valid expression
let mut coord_dim = match *ctx.info[coordinate].ty.inner_with(&self.module.types) {
let mut coord_dim = match *ctx.resolve_type(coordinate, &self.module.types) {
TypeInner::Vector { size, .. } => size as u8,
TypeInner::Scalar { .. } => 1,
_ => unreachable!(),
@ -2672,7 +2715,7 @@ impl<'a, W: Write> Writer<'a, W> {
use crate::ImageClass;
// This will only panic if the module is invalid
let (dim, class) = match *ctx.info[image].ty.inner_with(&self.module.types) {
let (dim, class) = match *ctx.resolve_type(image, &self.module.types) {
TypeInner::Image {
dim,
arrayed: _,
@ -2704,7 +2747,7 @@ impl<'a, W: Write> Writer<'a, W> {
self.write_expr(image, ctx)?;
if let Some(expr) = level {
let cast_to_int = matches!(
*ctx.info[expr].ty.inner_with(&self.module.types),
*ctx.resolve_type(expr, &self.module.types),
crate::TypeInner::Scalar {
kind: crate::ScalarKind::Uint,
..
@ -2779,7 +2822,7 @@ impl<'a, W: Write> Writer<'a, W> {
let operator_or_fn = match op {
crate::UnaryOperator::Negate => "-",
crate::UnaryOperator::LogicalNot => {
match *ctx.info[expr].ty.inner_with(&self.module.types) {
match *ctx.resolve_type(expr, &self.module.types) {
TypeInner::Vector { .. } => "not",
_ => "!",
}
@ -2805,8 +2848,8 @@ impl<'a, W: Write> Writer<'a, W> {
// implemented as a function call
use crate::{BinaryOperator as Bo, ScalarKind as Sk, TypeInner as Ti};
let left_inner = ctx.info[left].ty.inner_with(&self.module.types);
let right_inner = ctx.info[right].ty.inner_with(&self.module.types);
let left_inner = ctx.resolve_type(left, &self.module.types);
let right_inner = ctx.resolve_type(right, &self.module.types);
let function = match (left_inner, right_inner) {
(&Ti::Vector { kind, .. }, &Ti::Vector { .. }) => match op {
@ -2935,7 +2978,7 @@ impl<'a, W: Write> Writer<'a, W> {
accept,
reject,
} => {
let cond_ty = ctx.info[condition].ty.inner_with(&self.module.types);
let cond_ty = ctx.resolve_type(condition, &self.module.types);
let vec_select = if let TypeInner::Vector { .. } = *cond_ty {
true
} else {
@ -3025,7 +3068,7 @@ impl<'a, W: Write> Writer<'a, W> {
self.write_expr(arg, ctx)?;
match *ctx.info[arg].ty.inner_with(&self.module.types) {
match *ctx.resolve_type(arg, &self.module.types) {
crate::TypeInner::Vector { size, .. } => write!(
self.out,
", vec{}(0.0), vec{0}(1.0)",
@ -3072,7 +3115,7 @@ impl<'a, W: Write> Writer<'a, W> {
Mf::Log2 => "log2",
Mf::Pow => "pow",
// geometry
Mf::Dot => match *ctx.info[arg].ty.inner_with(&self.module.types) {
Mf::Dot => match *ctx.resolve_type(arg, &self.module.types) {
crate::TypeInner::Vector {
kind: crate::ScalarKind::Float,
..
@ -3128,7 +3171,7 @@ impl<'a, W: Write> Writer<'a, W> {
Mf::Determinant => "determinant",
// bits
Mf::CountTrailingZeros => {
match *ctx.info[arg].ty.inner_with(&self.module.types) {
match *ctx.resolve_type(arg, &self.module.types) {
crate::TypeInner::Vector { size, kind, .. } => {
let s = back::vector_size_str(size);
if let crate::ScalarKind::Uint = kind {
@ -3158,7 +3201,7 @@ impl<'a, W: Write> Writer<'a, W> {
}
Mf::CountLeadingZeros => {
if self.options.version.supports_integer_functions() {
match *ctx.info[arg].ty.inner_with(&self.module.types) {
match *ctx.resolve_type(arg, &self.module.types) {
crate::TypeInner::Vector { size, kind, .. } => {
let s = back::vector_size_str(size);
@ -3189,7 +3232,7 @@ impl<'a, W: Write> Writer<'a, W> {
_ => unreachable!(),
};
} else {
match *ctx.info[arg].ty.inner_with(&self.module.types) {
match *ctx.resolve_type(arg, &self.module.types) {
crate::TypeInner::Vector { size, kind, .. } => {
let s = back::vector_size_str(size);
@ -3262,7 +3305,7 @@ 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.info[arg].ty.inner_with(&self.module.types) {
let maybe_uint_size = match *ctx.resolve_type(arg, &self.module.types) {
crate::TypeInner::Scalar {
kind: crate::ScalarKind::Uint,
..
@ -3349,7 +3392,7 @@ impl<'a, W: Write> Writer<'a, W> {
kind: target_kind,
convert,
} => {
let inner = ctx.info[expr].ty.inner_with(&self.module.types);
let inner = ctx.resolve_type(expr, &self.module.types);
match convert {
Some(width) => {
// this is similar to `write_type`, but with the target kind
@ -3515,7 +3558,7 @@ impl<'a, W: Write> Writer<'a, W> {
}
// Otherwise write just the expression (and the 1D hack if needed)
None => {
let uvec_size = match *ctx.info[coordinate].ty.inner_with(&self.module.types) {
let uvec_size = match *ctx.resolve_type(coordinate, &self.module.types) {
TypeInner::Scalar {
kind: crate::ScalarKind::Uint,
..
@ -3563,7 +3606,7 @@ impl<'a, W: Write> Writer<'a, W> {
// so we don't need to generate bounds checks (OpenGL 4.2 Core §3.9.20)
// This will only panic if the module is invalid
let dim = match *ctx.info[image].ty.inner_with(&self.module.types) {
let dim = match *ctx.resolve_type(image, &self.module.types) {
TypeInner::Image { dim, .. } => dim,
_ => unreachable!(),
};
@ -3626,7 +3669,7 @@ impl<'a, W: Write> Writer<'a, W> {
// in bounds (`ReadZeroSkipWrite`) or make them a valid texel (`Restrict`).
// This will only panic if the module is invalid
let (dim, class) = match *ctx.info[image].ty.inner_with(&self.module.types) {
let (dim, class) = match *ctx.resolve_type(image, &self.module.types) {
TypeInner::Image {
dim,
arrayed: _,
@ -3891,8 +3934,7 @@ impl<'a, W: Write> Writer<'a, W> {
}
}
let base_ty_res = &ctx.info[named].ty;
let resolved = base_ty_res.inner_with(&self.module.types);
let resolved = ctx.resolve_type(named, &self.module.types);
write!(self.out, " {name}")?;
if let TypeInner::Array { base, size, .. } = *resolved {
@ -4002,7 +4044,7 @@ impl<'a, W: Write> Writer<'a, W> {
}
/// Helper method used to produce the reflection info that's returned to the user
fn collect_reflection_info(&self) -> Result<ReflectionInfo, Error> {
fn collect_reflection_info(&mut self) -> Result<ReflectionInfo, Error> {
use std::collections::hash_map::Entry;
let info = self.info.get_entry_point(self.entry_point_idx as usize);
let mut texture_mapping = crate::FastHashMap::default();
@ -4059,6 +4101,7 @@ impl<'a, W: Write> Writer<'a, W> {
Ok(ReflectionInfo {
texture_mapping,
uniforms,
varying: mem::take(&mut self.varying),
})
}
}

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

@ -244,7 +244,7 @@ impl<'a, W: Write> super::Writer<'a, W> {
const MIP_LEVEL_PARAM: &str = "mip_level";
// Write function return type and name
let ret_ty = func_ctx.info[expr_handle].ty.inner_with(&module.types);
let ret_ty = func_ctx.resolve_type(expr_handle, &module.types);
self.write_value_type(module, ret_ty)?;
write!(self.out, " ")?;
self.write_wrapped_image_query_function_name(wiq)?;
@ -891,7 +891,7 @@ impl<'a, W: Write> super::Writer<'a, W> {
}
}
crate::Expression::ImageQuery { image, query } => {
let wiq = match *func_ctx.info[image].ty.inner_with(&module.types) {
let wiq = match *func_ctx.resolve_type(image, &module.types) {
crate::TypeInner::Image {
dim,
arrayed,
@ -912,9 +912,8 @@ impl<'a, W: Write> super::Writer<'a, W> {
// Write `WrappedConstructor` for structs that are loaded from `AddressSpace::Storage`
// since they will later be used by the fn `write_storage_load`
crate::Expression::Load { pointer } => {
let pointer_space = func_ctx.info[pointer]
.ty
.inner_with(&module.types)
let pointer_space = func_ctx
.resolve_type(pointer, &module.types)
.pointer_space();
if let Some(crate::AddressSpace::Storage { .. }) = pointer_space {
@ -1016,7 +1015,7 @@ impl<'a, W: Write> super::Writer<'a, W> {
if extra == 0 {
self.write_expr(module, coordinate, func_ctx)?;
} else {
let num_coords = match *func_ctx.info[coordinate].ty.inner_with(&module.types) {
let num_coords = match *func_ctx.resolve_type(coordinate, &module.types) {
crate::TypeInner::Scalar { .. } => 1,
crate::TypeInner::Vector { size, .. } => size as usize,
_ => unreachable!(),

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

@ -466,7 +466,7 @@ impl<W: fmt::Write> super::Writer<'_, W> {
}
};
let parent = match *func_ctx.info[next_expr].ty.inner_with(&module.types) {
let parent = match *func_ctx.resolve_type(next_expr, &module.types) {
crate::TypeInner::Pointer { base, .. } => match module.types[base].inner {
crate::TypeInner::Struct { ref members, .. } => Parent::Struct(members),
crate::TypeInner::Array { stride, .. } => Parent::Array { stride },

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

@ -1320,8 +1320,7 @@ impl<'a, W: fmt::Write> super::Writer<'a, W> {
match *stmt {
Statement::Emit(ref range) => {
for handle in range.clone() {
let info = &func_ctx.info[handle];
let ptr_class = info.ty.inner_with(&module.types).pointer_space();
let ptr_class = func_ctx.resolve_type(handle, &module.types).pointer_space();
let expr_name = if ptr_class.is_some() {
// HLSL can't save a pointer-valued expression in a variable,
// but we shouldn't ever need to: they should never be named expressions,
@ -1441,7 +1440,7 @@ impl<'a, W: fmt::Write> super::Writer<'a, W> {
}
}
Statement::Store { pointer, value } => {
let ty_inner = func_ctx.info[pointer].ty.inner_with(&module.types);
let ty_inner = func_ctx.resolve_type(pointer, &module.types);
if let Some(crate::AddressSpace::Storage { .. }) = ty_inner.pointer_space() {
let var_handle = self.fill_access_chain(module, pointer, func_ctx)?;
self.write_storage_store(
@ -1467,8 +1466,7 @@ impl<'a, W: fmt::Write> super::Writer<'a, W> {
}
let get_members = |expr: Handle<crate::Expression>| {
let base_ty_res = &func_ctx.info[expr].ty;
let resolved = base_ty_res.inner_with(&module.types);
let resolved = func_ctx.resolve_type(expr, &module.types);
match *resolved {
TypeInner::Pointer { base, .. } => match module.types[base].inner {
TypeInner::Struct { ref members, .. } => Some(members),
@ -1484,7 +1482,7 @@ impl<'a, W: fmt::Write> super::Writer<'a, W> {
let mut current_expr = pointer;
for _ in 0..3 {
let resolved = func_ctx.info[current_expr].ty.inner_with(&module.types);
let resolved = func_ctx.resolve_type(current_expr, &module.types);
match (resolved, &func_ctx.expressions[current_expr]) {
(
@ -1634,7 +1632,7 @@ impl<'a, W: fmt::Write> super::Writer<'a, W> {
let mut current_expr = pointer;
for _ in 0..3 {
let resolved = func_ctx.info[current_expr].ty.inner_with(&module.types);
let resolved = func_ctx.resolve_type(current_expr, &module.types);
match (resolved, &func_ctx.expressions[current_expr]) {
(
&TypeInner::ValuePointer {
@ -1726,8 +1724,7 @@ impl<'a, W: fmt::Write> super::Writer<'a, W> {
}) = get_inner_matrix_of_struct_array_member(
module, pointer, func_ctx, false,
) {
let mut resolved =
func_ctx.info[pointer].ty.inner_with(&module.types);
let mut resolved = func_ctx.resolve_type(pointer, &module.types);
if let TypeInner::Pointer { base, .. } = *resolved {
resolved = &module.types[base].inner;
}
@ -1854,9 +1851,8 @@ impl<'a, W: fmt::Write> super::Writer<'a, W> {
};
// Validation ensures that `pointer` has a `Pointer` type.
let pointer_space = func_ctx.info[pointer]
.ty
.inner_with(&module.types)
let pointer_space = func_ctx
.resolve_type(pointer, &module.types)
.pointer_space()
.unwrap();
@ -2163,11 +2159,8 @@ impl<'a, W: fmt::Write> super::Writer<'a, W> {
op: crate::BinaryOperator::Multiply,
left,
right,
} if func_ctx.info[left].ty.inner_with(&module.types).is_matrix()
|| func_ctx.info[right]
.ty
.inner_with(&module.types)
.is_matrix() =>
} if func_ctx.resolve_type(left, &module.types).is_matrix()
|| func_ctx.resolve_type(right, &module.types).is_matrix() =>
{
// We intentionally flip the order of multiplication as our matrices are implicitly transposed.
write!(self.out, "mul(")?;
@ -2196,10 +2189,7 @@ impl<'a, W: fmt::Write> super::Writer<'a, W> {
op: crate::BinaryOperator::Modulo,
left,
right,
} if func_ctx.info[left]
.ty
.inner_with(&module.types)
.scalar_kind()
} if func_ctx.resolve_type(left, &module.types).scalar_kind()
== Some(crate::ScalarKind::Float) =>
{
write!(self.out, "fmod(")?;
@ -2216,10 +2206,8 @@ impl<'a, W: fmt::Write> super::Writer<'a, W> {
write!(self.out, ")")?;
}
Expression::Access { base, index } => {
if let Some(crate::AddressSpace::Storage { .. }) = func_ctx.info[expr]
.ty
.inner_with(&module.types)
.pointer_space()
if let Some(crate::AddressSpace::Storage { .. }) =
func_ctx.resolve_type(expr, &module.types).pointer_space()
{
// do nothing, the chain is written on `Load`/`Store`
} else {
@ -2243,8 +2231,7 @@ impl<'a, W: fmt::Write> super::Writer<'a, W> {
return Ok(());
}
let base_ty_res = &func_ctx.info[base].ty;
let resolved = base_ty_res.inner_with(&module.types);
let resolved = func_ctx.resolve_type(base, &module.types);
let non_uniform_qualifier = match *resolved {
TypeInner::BindingArray { .. } => {
@ -2268,10 +2255,8 @@ impl<'a, W: fmt::Write> super::Writer<'a, W> {
}
}
Expression::AccessIndex { base, index } => {
if let Some(crate::AddressSpace::Storage { .. }) = func_ctx.info[expr]
.ty
.inner_with(&module.types)
.pointer_space()
if let Some(crate::AddressSpace::Storage { .. }) =
func_ctx.resolve_type(expr, &module.types).pointer_space()
{
// do nothing, the chain is written on `Load`/`Store`
} else {
@ -2450,7 +2435,7 @@ impl<'a, W: fmt::Write> super::Writer<'a, W> {
dim,
arrayed,
class,
} = *func_ctx.info[image].ty.inner_with(&module.types)
} = *func_ctx.resolve_type(image, &module.types)
{
let wrapped_image_query = WrappedImageQuery {
dim,
@ -2499,8 +2484,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.info[expr].ty.inner_with(&module.types)
{
if let TypeInner::Scalar { .. } = *func_ctx.resolve_type(expr, &module.types) {
write!(self.out, ".x")?;
}
}
@ -2515,9 +2499,8 @@ impl<'a, W: fmt::Write> super::Writer<'a, W> {
write!(self.out, "{}", self.names[&func_ctx.name_key(handle)])?
}
Expression::Load { pointer } => {
match func_ctx.info[pointer]
.ty
.inner_with(&module.types)
match func_ctx
.resolve_type(pointer, &module.types)
.pointer_space()
{
Some(crate::AddressSpace::Storage { .. }) => {
@ -2541,7 +2524,7 @@ impl<'a, W: fmt::Write> super::Writer<'a, W> {
)
.or_else(|| get_inner_matrix_of_global_uniform(module, pointer, func_ctx))
{
let mut resolved = func_ctx.info[pointer].ty.inner_with(&module.types);
let mut resolved = func_ctx.resolve_type(pointer, &module.types);
if let TypeInner::Pointer { base, .. } = *resolved {
resolved = &module.types[base].inner;
}
@ -2581,7 +2564,7 @@ impl<'a, W: fmt::Write> super::Writer<'a, W> {
kind,
convert,
} => {
let inner = func_ctx.info[expr].ty.inner_with(&module.types);
let inner = func_ctx.resolve_type(expr, &module.types);
match convert {
Some(dst_width) => {
match *inner {
@ -2956,11 +2939,8 @@ impl<'a, W: fmt::Write> super::Writer<'a, W> {
write!(self.out, ")")?
}
Function::MissingIntOverload(fun_name) => {
let scalar_kind = &func_ctx.info[arg]
.ty
.inner_with(&module.types)
.scalar_kind();
if let Some(ScalarKind::Sint) = *scalar_kind {
let scalar_kind = func_ctx.resolve_type(arg, &module.types).scalar_kind();
if let Some(ScalarKind::Sint) = scalar_kind {
write!(self.out, "asint({fun_name}(asuint(")?;
self.write_expr(module, arg, func_ctx)?;
write!(self.out, ")))")?;
@ -2971,11 +2951,8 @@ impl<'a, W: fmt::Write> super::Writer<'a, W> {
}
}
Function::MissingIntReturnType(fun_name) => {
let scalar_kind = &func_ctx.info[arg]
.ty
.inner_with(&module.types)
.scalar_kind();
if let Some(ScalarKind::Sint) = *scalar_kind {
let scalar_kind = func_ctx.resolve_type(arg, &module.types).scalar_kind();
if let Some(ScalarKind::Sint) = scalar_kind {
write!(self.out, "asint({fun_name}(")?;
self.write_expr(module, arg, func_ctx)?;
write!(self.out, "))")?;
@ -2986,7 +2963,7 @@ impl<'a, W: fmt::Write> super::Writer<'a, W> {
}
}
Function::CountTrailingZeros => {
match *func_ctx.info[arg].ty.inner_with(&module.types) {
match *func_ctx.resolve_type(arg, &module.types) {
TypeInner::Vector { size, kind, .. } => {
let s = match size {
crate::VectorSize::Bi => ".xx",
@ -3021,7 +2998,7 @@ impl<'a, W: fmt::Write> super::Writer<'a, W> {
return Ok(());
}
Function::CountLeadingZeros => {
match *func_ctx.info[arg].ty.inner_with(&module.types) {
match *func_ctx.resolve_type(arg, &module.types) {
TypeInner::Vector { size, kind, .. } => {
let s = match size {
crate::VectorSize::Bi => ".xx",
@ -3209,8 +3186,7 @@ impl<'a, W: fmt::Write> super::Writer<'a, W> {
}
}
let base_ty_res = &ctx.info[named].ty;
let resolved = base_ty_res.inner_with(&module.types);
let resolved = ctx.resolve_type(named, &module.types);
write!(self.out, " {name}")?;
// If rhs is a array type, we should write array size
@ -3287,7 +3263,7 @@ pub(super) fn get_inner_matrix_of_struct_array_member(
let mut current_base = base;
loop {
let mut resolved = func_ctx.info[current_base].ty.inner_with(&module.types);
let mut resolved = func_ctx.resolve_type(current_base, &module.types);
if let TypeInner::Pointer { base, .. } = *resolved {
resolved = &module.types[base].inner;
};
@ -3344,7 +3320,7 @@ fn get_inner_matrix_of_global_uniform(
let mut current_base = base;
loop {
let mut resolved = func_ctx.info[current_base].ty.inner_with(&module.types);
let mut resolved = func_ctx.resolve_type(current_base, &module.types);
if let TypeInner::Pointer { base, .. } = *resolved {
resolved = &module.types[base].inner;
};

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

@ -135,7 +135,7 @@ impl FunctionCtx<'_> {
};
}
crate::Expression::AccessIndex { base, index } => {
match *self.info[base].ty.inner_with(&module.types) {
match *self.resolve_type(base, &module.types) {
crate::TypeInner::Struct { ref members, .. } => {
if let Some(crate::Binding::BuiltIn(bi)) =
members[index as usize].binding

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

@ -2624,11 +2624,7 @@ impl<W: Write> Writer<W> {
)?;
}
let info = &context.expression.info[handle];
let ptr_class = info
.ty
.inner_with(&context.expression.module.types)
.pointer_space();
let ptr_class = context.expression.resolve_type(handle).pointer_space();
let expr_name = if ptr_class.is_some() {
None // don't bake pointer expressions (just yet)
} else if let Some(name) =

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

@ -177,7 +177,11 @@ pub enum Error<'a> {
InconsistentBinding(Span),
TypeNotConstructible(Span),
TypeNotInferrable(Span),
InitializationTypeMismatch(Span, String, String),
InitializationTypeMismatch {
name: Span,
expected: String,
got: String,
},
MissingType(Span),
MissingAttribute(&'static str, Span),
InvalidAtomicPointer(Span),
@ -233,7 +237,7 @@ pub enum Error<'a> {
},
FunctionReturnsVoid(Span),
InvalidWorkGroupUniformLoad(Span),
Other,
Internal(&'static str),
ExpectedConstExprConcreteIntegerScalar(Span),
ExpectedNonNegative(Span),
ExpectedPositiveArrayLength(Span),
@ -475,15 +479,15 @@ impl<'a> Error<'a> {
labels: vec![(span, "type can't be inferred".into())],
notes: vec![],
},
Error::InitializationTypeMismatch(name_span, ref expected_ty, ref got_ty) => {
Error::InitializationTypeMismatch { name, ref expected, ref got } => {
ParseError {
message: format!(
"the type of `{}` is expected to be `{}`, but got `{}`",
&source[name_span], expected_ty, got_ty,
&source[name], expected, got,
),
labels: vec![(
name_span,
format!("definition of `{}`", &source[name_span]).into(),
name,
format!("definition of `{}`", &source[name]).into(),
)],
notes: vec![],
}
@ -667,10 +671,10 @@ impl<'a> Error<'a> {
labels: vec![(span, "".into())],
notes: vec!["passed type must be a workgroup pointer".into()],
},
Error::Other => ParseError {
message: "other error".to_string(),
Error::Internal(message) => ParseError {
message: "internal WGSL front end error".to_string(),
labels: vec![],
notes: vec![],
notes: vec![message.into()],
},
Error::ExpectedConstExprConcreteIntegerScalar(span) => ParseError {
message: "must be a const-expression that resolves to a concrete integer scalar (u32 or i32)".to_string(),

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

@ -5,47 +5,58 @@ use crate::{Handle, Span};
use crate::front::wgsl::error::Error;
use crate::front::wgsl::lower::{ExpressionContext, Lowerer};
use crate::proc::TypeResolution;
enum ConcreteConstructorHandle {
PartialVector {
size: crate::VectorSize,
},
/// A cooked form of `ast::ConstructorType` that uses Naga types whenever
/// possible.
enum Constructor<T> {
/// A vector construction whose component type is inferred from the
/// argument: `vec3(1.0)`.
PartialVector { size: crate::VectorSize },
/// A matrix construction whose component type is inferred from the
/// argument: `mat2x2(1,2,3,4)`.
PartialMatrix {
columns: crate::VectorSize,
rows: crate::VectorSize,
},
/// An array whose component type and size are inferred from the arguments:
/// `array(3,4,5)`.
PartialArray,
Type(Handle<crate::Type>),
/// A known Naga type.
///
/// When we match on this type, we need to see the `TypeInner` here, but at
/// the point that we build this value we'll still need mutable access to
/// the module later. To avoid borrowing from the module, the type parameter
/// `T` is `Handle<Type>` initially. Then we use `borrow_inner` to produce a
/// version holding a tuple `(Handle<Type>, &TypeInner)`.
Type(T),
}
impl ConcreteConstructorHandle {
fn borrow<'a>(&self, module: &'a crate::Module) -> ConcreteConstructor<'a> {
match *self {
Self::PartialVector { size } => ConcreteConstructor::PartialVector { size },
Self::PartialMatrix { columns, rows } => {
ConcreteConstructor::PartialMatrix { columns, rows }
impl Constructor<Handle<crate::Type>> {
/// Return an equivalent `Constructor` value that includes borrowed
/// `TypeInner` values alongside any type handles.
///
/// The returned form is more convenient to match on, since the patterns
/// can actually see what the handle refers to.
fn borrow_inner(
self,
module: &crate::Module,
) -> Constructor<(Handle<crate::Type>, &crate::TypeInner)> {
match self {
Constructor::PartialVector { size } => Constructor::PartialVector { size },
Constructor::PartialMatrix { columns, rows } => {
Constructor::PartialMatrix { columns, rows }
}
Self::PartialArray => ConcreteConstructor::PartialArray,
Self::Type(handle) => ConcreteConstructor::Type(handle, &module.types[handle].inner),
Constructor::PartialArray => Constructor::PartialArray,
Constructor::Type(handle) => Constructor::Type((handle, &module.types[handle].inner)),
}
}
}
enum ConcreteConstructor<'a> {
PartialVector {
size: crate::VectorSize,
},
PartialMatrix {
columns: crate::VectorSize,
rows: crate::VectorSize,
},
PartialArray,
Type(Handle<crate::Type>, &'a crate::TypeInner),
}
impl ConcreteConstructorHandle {
fn to_error_string(&self, ctx: ExpressionContext) -> String {
impl Constructor<(Handle<crate::Type>, &crate::TypeInner)> {
fn to_error_string(&self, ctx: &ExpressionContext) -> String {
match *self {
Self::PartialVector { size } => {
format!("vec{}<?>", size as u32,)
@ -54,47 +65,7 @@ impl ConcreteConstructorHandle {
format!("mat{}x{}<?>", columns as u32, rows as u32,)
}
Self::PartialArray => "array<?, ?>".to_string(),
Self::Type(ty) => ctx.format_type(ty),
}
}
}
enum ComponentsHandle<'a> {
None,
One {
component: Handle<crate::Expression>,
span: Span,
ty: &'a TypeResolution,
},
Many {
components: Vec<Handle<crate::Expression>>,
spans: Vec<Span>,
first_component_ty: &'a TypeResolution,
},
}
impl<'a> ComponentsHandle<'a> {
fn borrow(self, module: &'a crate::Module) -> Components<'a> {
match self {
Self::None => Components::None,
Self::One {
component,
span,
ty,
} => Components::One {
component,
span,
ty_inner: ty.inner_with(&module.types),
},
Self::Many {
components,
spans,
first_component_ty,
} => Components::Many {
components,
spans,
first_component_ty_inner: first_component_ty.inner_with(&module.types),
},
Self::Type((handle, _inner)) => ctx.format_type(handle),
}
}
}
@ -143,32 +114,31 @@ impl<'source, 'temp> Lowerer<'source, 'temp> {
constructor: &ast::ConstructorType<'source>,
ty_span: Span,
components: &[Handle<ast::Expression<'source>>],
mut ctx: ExpressionContext<'source, '_, '_>,
ctx: &mut ExpressionContext<'source, '_, '_>,
) -> Result<Handle<crate::Expression>, Error<'source>> {
let constructor_h = self.constructor(constructor, ctx.reborrow())?;
let constructor_h = self.constructor(constructor, ctx)?;
let components_h = match *components {
[] => ComponentsHandle::None,
let components = match *components {
[] => Components::None,
[component] => {
let span = ctx.ast_expressions.get_span(component);
let component = self.expression(component, ctx.reborrow())?;
ctx.grow_types(component)?;
let ty = &ctx.typifier()[component];
let component = self.expression(component, ctx)?;
let ty_inner = super::resolve_inner!(ctx, component);
ComponentsHandle::One {
Components::One {
component,
span,
ty,
ty_inner,
}
}
[component, ref rest @ ..] => {
let span = ctx.ast_expressions.get_span(component);
let component = self.expression(component, ctx.reborrow())?;
let component = self.expression(component, ctx)?;
let components = std::iter::once(Ok(component))
.chain(
rest.iter()
.map(|&component| self.expression(component, ctx.reborrow())),
.map(|&component| self.expression(component, ctx)),
)
.collect::<Result<_, _>>()?;
let spans = std::iter::once(span)
@ -178,28 +148,34 @@ impl<'source, 'temp> Lowerer<'source, 'temp> {
)
.collect();
ctx.grow_types(component)?;
let ty = &ctx.typifier()[component];
let first_component_ty_inner = super::resolve_inner!(ctx, component);
ComponentsHandle::Many {
Components::Many {
components,
spans,
first_component_ty: ty,
first_component_ty_inner,
}
}
};
let (components, constructor) = (
components_h.borrow(ctx.module),
constructor_h.borrow(ctx.module),
);
// Even though we computed `constructor` above, wait until now to borrow
// a reference to the `TypeInner`, so that the component-handling code
// above can have mutable access to the type arena.
let constructor = constructor_h.borrow_inner(ctx.module);
let expr = match (components, constructor) {
// Empty constructor
(Components::None, dst_ty) => match dst_ty {
ConcreteConstructor::Type(ty, _) => {
return ctx.append_expression(crate::Expression::ZeroValue(ty), span)
Constructor::Type((result_ty, _)) => {
return ctx.append_expression(crate::Expression::ZeroValue(result_ty), span)
}
Constructor::PartialVector { .. }
| Constructor::PartialMatrix { .. }
| Constructor::PartialArray => {
// We have no arguments from which to infer the result type, so
// partial constructors aren't acceptable here.
return Err(Error::TypeNotInferrable(ty_span));
}
_ => return Err(Error::TypeNotInferrable(ty_span)),
},
// Scalar constructor & conversion (scalar -> scalar)
@ -209,7 +185,7 @@ impl<'source, 'temp> Lowerer<'source, 'temp> {
ty_inner: &crate::TypeInner::Scalar { .. },
..
},
ConcreteConstructor::Type(_, &crate::TypeInner::Scalar { kind, width }),
Constructor::Type((_, &crate::TypeInner::Scalar { kind, width })),
) => crate::Expression::As {
expr: component,
kind,
@ -223,14 +199,14 @@ impl<'source, 'temp> Lowerer<'source, 'temp> {
ty_inner: &crate::TypeInner::Vector { size: src_size, .. },
..
},
ConcreteConstructor::Type(
Constructor::Type((
_,
&crate::TypeInner::Vector {
size: dst_size,
kind: dst_kind,
width: dst_width,
},
),
)),
) if dst_size == src_size => crate::Expression::As {
expr: component,
kind: dst_kind,
@ -241,20 +217,16 @@ impl<'source, 'temp> Lowerer<'source, 'temp> {
(
Components::One {
component,
ty_inner:
&crate::TypeInner::Vector {
size: src_size,
kind: src_kind,
..
},
ty_inner: &crate::TypeInner::Vector { size: src_size, .. },
..
},
ConcreteConstructor::PartialVector { size: dst_size },
) if dst_size == src_size => crate::Expression::As {
expr: component,
kind: src_kind,
convert: None,
},
Constructor::PartialVector { size: dst_size },
) if dst_size == src_size => {
// This is a trivial conversion: the sizes match, and a Partial
// constructor doesn't specify a scalar type, so nothing can
// possibly happen.
return Ok(component);
}
// Matrix conversion (matrix -> matrix)
(
@ -268,14 +240,14 @@ impl<'source, 'temp> Lowerer<'source, 'temp> {
},
..
},
ConcreteConstructor::Type(
Constructor::Type((
_,
&crate::TypeInner::Matrix {
columns: dst_columns,
rows: dst_rows,
width: dst_width,
},
),
)),
) if dst_columns == src_columns && dst_rows == src_rows => crate::Expression::As {
expr: component,
kind: crate::ScalarKind::Float,
@ -294,15 +266,16 @@ impl<'source, 'temp> Lowerer<'source, 'temp> {
},
..
},
ConcreteConstructor::PartialMatrix {
Constructor::PartialMatrix {
columns: dst_columns,
rows: dst_rows,
},
) if dst_columns == src_columns && dst_rows == src_rows => crate::Expression::As {
expr: component,
kind: crate::ScalarKind::Float,
convert: None,
},
) if dst_columns == src_columns && dst_rows == src_rows => {
// This is a trivial conversion: the sizes match, and a Partial
// constructor doesn't specify a scalar type, so nothing can
// possibly happen.
return Ok(component);
}
// Vector constructor (splat) - infer type
(
@ -311,7 +284,7 @@ impl<'source, 'temp> Lowerer<'source, 'temp> {
ty_inner: &crate::TypeInner::Scalar { .. },
..
},
ConcreteConstructor::PartialVector { size },
Constructor::PartialVector { size },
) => crate::Expression::Splat {
size,
value: component,
@ -329,14 +302,14 @@ impl<'source, 'temp> Lowerer<'source, 'temp> {
},
..
},
ConcreteConstructor::Type(
Constructor::Type((
_,
&crate::TypeInner::Vector {
size,
kind: dst_kind,
width: dst_width,
},
),
)),
) if dst_kind == src_kind || dst_width == src_width => crate::Expression::Splat {
size,
value: component,
@ -351,7 +324,7 @@ impl<'source, 'temp> Lowerer<'source, 'temp> {
| &crate::TypeInner::Vector { kind, width, .. },
..
},
ConcreteConstructor::PartialVector { size },
Constructor::PartialVector { size },
)
| (
Components::Many {
@ -360,7 +333,7 @@ impl<'source, 'temp> Lowerer<'source, 'temp> {
&crate::TypeInner::Scalar { .. } | &crate::TypeInner::Vector { .. },
..
},
ConcreteConstructor::Type(_, &crate::TypeInner::Vector { size, width, kind }),
Constructor::Type((_, &crate::TypeInner::Vector { size, width, kind })),
) => {
let inner = crate::TypeInner::Vector { size, kind, width };
let ty = ctx.ensure_type_exists(inner);
@ -374,7 +347,7 @@ impl<'source, 'temp> Lowerer<'source, 'temp> {
first_component_ty_inner: &crate::TypeInner::Scalar { width, .. },
..
},
ConcreteConstructor::PartialMatrix { columns, rows },
Constructor::PartialMatrix { columns, rows },
)
| (
Components::Many {
@ -382,14 +355,14 @@ impl<'source, 'temp> Lowerer<'source, 'temp> {
first_component_ty_inner: &crate::TypeInner::Scalar { .. },
..
},
ConcreteConstructor::Type(
Constructor::Type((
_,
&crate::TypeInner::Matrix {
columns,
rows,
width,
},
),
)),
) => {
let vec_ty = ctx.ensure_type_exists(crate::TypeInner::Vector {
width,
@ -425,7 +398,7 @@ impl<'source, 'temp> Lowerer<'source, 'temp> {
first_component_ty_inner: &crate::TypeInner::Vector { width, .. },
..
},
ConcreteConstructor::PartialMatrix { columns, rows },
Constructor::PartialMatrix { columns, rows },
)
| (
Components::Many {
@ -433,14 +406,14 @@ impl<'source, 'temp> Lowerer<'source, 'temp> {
first_component_ty_inner: &crate::TypeInner::Vector { .. },
..
},
ConcreteConstructor::Type(
Constructor::Type((
_,
&crate::TypeInner::Matrix {
columns,
rows,
width,
},
),
)),
) => {
let ty = ctx.ensure_type_exists(crate::TypeInner::Matrix {
columns,
@ -451,7 +424,7 @@ impl<'source, 'temp> Lowerer<'source, 'temp> {
}
// Array constructor - infer type
(components, ConcreteConstructor::PartialArray) => {
(components, Constructor::PartialArray) => {
let components = components.into_components_vec();
let base = ctx.register_type(components[0])?;
@ -471,36 +444,34 @@ impl<'source, 'temp> Lowerer<'source, 'temp> {
crate::Expression::Compose { ty, components }
}
// Array constructor
(components, ConcreteConstructor::Type(ty, &crate::TypeInner::Array { .. })) => {
// Array or Struct constructor
(
components,
Constructor::Type((
ty,
&crate::TypeInner::Array { .. } | &crate::TypeInner::Struct { .. },
)),
) => {
let components = components.into_components_vec();
crate::Expression::Compose { ty, components }
}
// Struct constructor
(components, ConcreteConstructor::Type(ty, &crate::TypeInner::Struct { .. })) => {
crate::Expression::Compose {
ty,
components: components.into_components_vec(),
}
}
// ERRORS
// Bad conversion (type cast)
(Components::One { span, ty_inner, .. }, _) => {
(Components::One { span, ty_inner, .. }, constructor) => {
let from_type = ctx.format_typeinner(ty_inner);
return Err(Error::BadTypeCast {
span,
from_type,
to_type: constructor_h.to_error_string(ctx.reborrow()),
to_type: constructor.to_error_string(ctx),
});
}
// Too many parameters for scalar constructor
(
Components::Many { spans, .. },
ConcreteConstructor::Type(_, &crate::TypeInner::Scalar { .. }),
Constructor::Type((_, &crate::TypeInner::Scalar { .. })),
) => {
let span = spans[1].until(spans.last().unwrap());
return Err(Error::UnexpectedComponents(span));
@ -509,12 +480,12 @@ impl<'source, 'temp> Lowerer<'source, 'temp> {
// Parameters are of the wrong type for vector or matrix constructor
(
Components::Many { spans, .. },
ConcreteConstructor::Type(
Constructor::Type((
_,
&crate::TypeInner::Vector { .. } | &crate::TypeInner::Matrix { .. },
)
| ConcreteConstructor::PartialVector { .. }
| ConcreteConstructor::PartialMatrix { .. },
))
| Constructor::PartialVector { .. }
| Constructor::PartialMatrix { .. },
) => {
return Err(Error::InvalidConstructorComponentType(spans[0], 0));
}
@ -527,45 +498,35 @@ impl<'source, 'temp> Lowerer<'source, 'temp> {
Ok(expr)
}
/// Build a Naga IR [`Type`] for `constructor` if there is enough
/// information to do so.
/// Build a [`Constructor`] for a WGSL construction expression.
///
/// For `Partial` variants of [`ast::ConstructorType`], we don't know the
/// component type, so in that case we return the appropriate `Partial`
/// variant of [`ConcreteConstructorHandle`].
/// If `constructor` conveys enough information to determine which Naga [`Type`]
/// we're actually building (i.e., it's not a partial constructor), then
/// ensure the `Type` exists in [`ctx.module`], and return
/// [`Constructor::Type`].
///
/// But for the other `ConstructorType` variants, we have everything we need
/// to know to actually produce a Naga IR type. In this case we add to/find
/// in [`ctx.module`] a suitable Naga `Type` and return a
/// [`ConcreteConstructorHandle::Type`] value holding its handle.
///
/// Note that constructing an [`Array`] type may require inserting
/// [`Constant`]s as well as `Type`s into `ctx.module`, to represent the
/// array's length.
/// Otherwise, return the [`Constructor`] partial variant corresponding to
/// `constructor`.
///
/// [`Type`]: crate::Type
/// [`ctx.module`]: ExpressionContext::module
/// [`Array`]: crate::TypeInner::Array
/// [`Constant`]: crate::Constant
fn constructor<'out>(
&mut self,
constructor: &ast::ConstructorType<'source>,
mut ctx: ExpressionContext<'source, '_, 'out>,
) -> Result<ConcreteConstructorHandle, Error<'source>> {
let c = match *constructor {
ctx: &mut ExpressionContext<'source, '_, 'out>,
) -> Result<Constructor<Handle<crate::Type>>, Error<'source>> {
let handle = match *constructor {
ast::ConstructorType::Scalar { width, kind } => {
let ty = ctx.ensure_type_exists(crate::TypeInner::Scalar { width, kind });
ConcreteConstructorHandle::Type(ty)
}
ast::ConstructorType::PartialVector { size } => {
ConcreteConstructorHandle::PartialVector { size }
Constructor::Type(ty)
}
ast::ConstructorType::PartialVector { size } => Constructor::PartialVector { size },
ast::ConstructorType::Vector { size, kind, width } => {
let ty = ctx.ensure_type_exists(crate::TypeInner::Vector { size, kind, width });
ConcreteConstructorHandle::Type(ty)
Constructor::Type(ty)
}
ast::ConstructorType::PartialMatrix { rows, columns } => {
ConcreteConstructorHandle::PartialMatrix { rows, columns }
ast::ConstructorType::PartialMatrix { columns, rows } => {
Constructor::PartialMatrix { columns, rows }
}
ast::ConstructorType::Matrix {
rows,
@ -577,22 +538,22 @@ impl<'source, 'temp> Lowerer<'source, 'temp> {
rows,
width,
});
ConcreteConstructorHandle::Type(ty)
Constructor::Type(ty)
}
ast::ConstructorType::PartialArray => ConcreteConstructorHandle::PartialArray,
ast::ConstructorType::PartialArray => Constructor::PartialArray,
ast::ConstructorType::Array { base, size } => {
let base = self.resolve_ast_type(base, ctx.as_global())?;
let size = self.array_size(size, ctx.as_global())?;
let base = self.resolve_ast_type(base, &mut ctx.as_global())?;
let size = self.array_size(size, &mut ctx.as_global())?;
self.layouter.update(ctx.module.to_ctx()).unwrap();
let stride = self.layouter[base].to_stride();
let ty = ctx.ensure_type_exists(crate::TypeInner::Array { base, size, stride });
ConcreteConstructorHandle::Type(ty)
Constructor::Type(ty)
}
ast::ConstructorType::Type(ty) => ConcreteConstructorHandle::Type(ty),
ast::ConstructorType::Type(ty) => Constructor::Type(ty),
};
Ok(c)
Ok(handle)
}
}

Разница между файлами не показана из-за своего большого размера Загрузить разницу

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

@ -350,9 +350,7 @@ impl<'a> Lexer<'a> {
&mut self,
) -> Result<(&'a str, Span), Error<'a>> {
match self.next() {
(Token::Word(word), span) if word == "_" => {
Err(Error::InvalidIdentifierUnderscore(span))
}
(Token::Word("_"), span) => Err(Error::InvalidIdentifierUnderscore(span)),
(Token::Word(word), span) if word.starts_with("__") => {
Err(Error::ReservedIdentifierPrefix(span))
}

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

@ -55,31 +55,21 @@ struct ExpressionContext<'input, 'temp, 'out> {
}
impl<'a> ExpressionContext<'a, '_, '_> {
fn reborrow(&mut self) -> ExpressionContext<'a, '_, '_> {
ExpressionContext {
expressions: self.expressions,
types: self.types,
local_table: self.local_table,
locals: self.locals,
unresolved: self.unresolved,
}
}
fn parse_binary_op(
&mut self,
lexer: &mut Lexer<'a>,
classifier: impl Fn(Token<'a>) -> Option<crate::BinaryOperator>,
mut parser: impl FnMut(
&mut Lexer<'a>,
ExpressionContext<'a, '_, '_>,
&mut Self,
) -> Result<Handle<ast::Expression<'a>>, Error<'a>>,
) -> Result<Handle<ast::Expression<'a>>, Error<'a>> {
let start = lexer.start_byte_offset();
let mut accumulator = parser(lexer, self.reborrow())?;
let mut accumulator = parser(lexer, self)?;
while let Some(op) = classifier(lexer.peek().0) {
let _ = lexer.next();
let left = accumulator;
let right = parser(lexer, self.reborrow())?;
let right = parser(lexer, self)?;
accumulator = self.expressions.append(
ast::Expression::Binary { op, left, right },
lexer.span_from(start),
@ -157,13 +147,13 @@ impl<'a> BindingParser<'a> {
lexer: &mut Lexer<'a>,
name: &'a str,
name_span: Span,
mut ctx: ExpressionContext<'a, '_, '_>,
ctx: &mut ExpressionContext<'a, '_, '_>,
) -> Result<(), Error<'a>> {
match name {
"location" => {
lexer.expect(Token::Paren('('))?;
self.location
.set(parser.general_expression(lexer, ctx.reborrow())?, name_span)?;
.set(parser.general_expression(lexer, ctx)?, name_span)?;
lexer.expect(Token::Paren(')'))?;
}
"builtin" => {
@ -258,14 +248,14 @@ impl Parser {
fn switch_value<'a>(
&mut self,
lexer: &mut Lexer<'a>,
mut ctx: ExpressionContext<'a, '_, '_>,
ctx: &mut ExpressionContext<'a, '_, '_>,
) -> Result<ast::SwitchValue<'a>, Error<'a>> {
if let Token::Word("default") = lexer.peek().0 {
let _ = lexer.next();
return Ok(ast::SwitchValue::Default);
}
let expr = self.general_expression(lexer, ctx.reborrow())?;
let expr = self.general_expression(lexer, ctx)?;
Ok(ast::SwitchValue::Expr(expr))
}
@ -285,7 +275,7 @@ impl Parser {
lexer: &mut Lexer<'a>,
word: &'a str,
span: Span,
mut ctx: ExpressionContext<'a, '_, '_>,
ctx: &mut ExpressionContext<'a, '_, '_>,
) -> Result<Option<ast::ConstructorType<'a>>, Error<'a>> {
if let Some((kind, width)) = conv::get_scalar_type(word) {
return Ok(Some(ast::ConstructorType::Scalar { kind, width }));
@ -509,9 +499,9 @@ impl Parser {
}
(Token::Paren('<'), ast::ConstructorType::PartialArray) => {
lexer.expect_generic_paren('<')?;
let base = self.type_decl(lexer, ctx.reborrow())?;
let base = self.type_decl(lexer, ctx)?;
let size = if lexer.skip(Token::Separator(',')) {
let expr = self.unary_expression(lexer, ctx.reborrow())?;
let expr = self.unary_expression(lexer, ctx)?;
ast::ArraySize::Constant(expr)
} else {
ast::ArraySize::Dynamic
@ -528,7 +518,7 @@ impl Parser {
fn arguments<'a>(
&mut self,
lexer: &mut Lexer<'a>,
mut ctx: ExpressionContext<'a, '_, '_>,
ctx: &mut ExpressionContext<'a, '_, '_>,
) -> Result<Vec<Handle<ast::Expression<'a>>>, Error<'a>> {
lexer.open_arguments()?;
let mut arguments = Vec::new();
@ -540,7 +530,7 @@ impl Parser {
} else if lexer.skip(Token::Paren(')')) {
break;
}
let arg = self.general_expression(lexer, ctx.reborrow())?;
let arg = self.general_expression(lexer, ctx)?;
arguments.push(arg);
}
@ -554,7 +544,7 @@ impl Parser {
lexer: &mut Lexer<'a>,
name: &'a str,
name_span: Span,
mut ctx: ExpressionContext<'a, '_, '_>,
ctx: &mut ExpressionContext<'a, '_, '_>,
) -> Result<Handle<ast::Expression<'a>>, Error<'a>> {
assert!(self.rules.last().is_some());
@ -563,12 +553,12 @@ impl Parser {
"bitcast" => {
lexer.expect_generic_paren('<')?;
let start = lexer.start_byte_offset();
let to = self.type_decl(lexer, ctx.reborrow())?;
let to = self.type_decl(lexer, ctx)?;
let span = lexer.span_from(start);
lexer.expect_generic_paren('>')?;
lexer.open_arguments()?;
let expr = self.general_expression(lexer, ctx.reborrow())?;
let expr = self.general_expression(lexer, ctx)?;
lexer.close_arguments()?;
ast::Expression::Bitcast {
@ -579,7 +569,7 @@ impl Parser {
}
// everything else must be handled later, since they can be hidden by user-defined functions.
_ => {
let arguments = self.arguments(lexer, ctx.reborrow())?;
let arguments = self.arguments(lexer, ctx)?;
ctx.unresolved.insert(ast::Dependency {
ident: name,
usage: name_span,
@ -603,7 +593,7 @@ impl Parser {
&mut self,
name: &'a str,
name_span: Span,
ctx: ExpressionContext<'a, '_, '_>,
ctx: &mut ExpressionContext<'a, '_, '_>,
) -> ast::IdentExpr<'a> {
match ctx.local_table.lookup(name) {
Some(&local) => ast::IdentExpr::Local(local),
@ -620,14 +610,14 @@ impl Parser {
fn primary_expression<'a>(
&mut self,
lexer: &mut Lexer<'a>,
mut ctx: ExpressionContext<'a, '_, '_>,
ctx: &mut ExpressionContext<'a, '_, '_>,
) -> Result<Handle<ast::Expression<'a>>, Error<'a>> {
self.push_rule_span(Rule::PrimaryExpr, lexer);
let expr = match lexer.peek() {
(Token::Paren('('), _) => {
let _ = lexer.next();
let expr = self.general_expression(lexer, ctx.reborrow())?;
let expr = self.general_expression(lexer, ctx)?;
lexer.expect(Token::Paren(')'))?;
self.pop_rule_span(lexer);
return Ok(expr);
@ -661,9 +651,9 @@ impl Parser {
let start = lexer.start_byte_offset();
let _ = lexer.next();
if let Some(ty) = self.constructor_type(lexer, word, span, ctx.reborrow())? {
if let Some(ty) = self.constructor_type(lexer, word, span, ctx)? {
let ty_span = lexer.span_from(start);
let components = self.arguments(lexer, ctx.reborrow())?;
let components = self.arguments(lexer, ctx)?;
ast::Expression::Construct {
ty,
ty_span,
@ -676,7 +666,7 @@ impl Parser {
self.pop_rule_span(lexer);
return self.function_call(lexer, word, span, ctx);
} else {
let ident = self.ident_expr(word, span, ctx.reborrow());
let ident = self.ident_expr(word, span, ctx);
ast::Expression::Ident(ident)
}
}
@ -692,7 +682,7 @@ impl Parser {
&mut self,
span_start: usize,
lexer: &mut Lexer<'a>,
mut ctx: ExpressionContext<'a, '_, '_>,
ctx: &mut ExpressionContext<'a, '_, '_>,
expr: Handle<ast::Expression<'a>>,
) -> Result<Handle<ast::Expression<'a>>, Error<'a>> {
let mut expr = expr;
@ -707,7 +697,7 @@ impl Parser {
}
Token::Paren('[') => {
let _ = lexer.next();
let index = self.general_expression(lexer, ctx.reborrow())?;
let index = self.general_expression(lexer, ctx)?;
lexer.expect(Token::Paren(']'))?;
ast::Expression::Index { base: expr, index }
@ -726,14 +716,14 @@ impl Parser {
fn unary_expression<'a>(
&mut self,
lexer: &mut Lexer<'a>,
mut ctx: ExpressionContext<'a, '_, '_>,
ctx: &mut ExpressionContext<'a, '_, '_>,
) -> Result<Handle<ast::Expression<'a>>, Error<'a>> {
self.push_rule_span(Rule::UnaryExpr, lexer);
//TODO: refactor this to avoid backing up
let expr = match lexer.peek().0 {
Token::Operation('-') => {
let _ = lexer.next();
let expr = self.unary_expression(lexer, ctx.reborrow())?;
let expr = self.unary_expression(lexer, ctx)?;
let expr = ast::Expression::Unary {
op: crate::UnaryOperator::Negate,
expr,
@ -743,7 +733,7 @@ impl Parser {
}
Token::Operation('!') => {
let _ = lexer.next();
let expr = self.unary_expression(lexer, ctx.reborrow())?;
let expr = self.unary_expression(lexer, ctx)?;
let expr = ast::Expression::Unary {
op: crate::UnaryOperator::LogicalNot,
expr,
@ -753,7 +743,7 @@ impl Parser {
}
Token::Operation('~') => {
let _ = lexer.next();
let expr = self.unary_expression(lexer, ctx.reborrow())?;
let expr = self.unary_expression(lexer, ctx)?;
let expr = ast::Expression::Unary {
op: crate::UnaryOperator::BitwiseNot,
expr,
@ -763,19 +753,19 @@ impl Parser {
}
Token::Operation('*') => {
let _ = lexer.next();
let expr = self.unary_expression(lexer, ctx.reborrow())?;
let expr = self.unary_expression(lexer, ctx)?;
let expr = ast::Expression::Deref(expr);
let span = self.peek_rule_span(lexer);
ctx.expressions.append(expr, span)
}
Token::Operation('&') => {
let _ = lexer.next();
let expr = self.unary_expression(lexer, ctx.reborrow())?;
let expr = self.unary_expression(lexer, ctx)?;
let expr = ast::Expression::AddrOf(expr);
let span = self.peek_rule_span(lexer);
ctx.expressions.append(expr, span)
}
_ => self.singular_expression(lexer, ctx.reborrow())?,
_ => self.singular_expression(lexer, ctx)?,
};
self.pop_rule_span(lexer);
@ -786,12 +776,12 @@ impl Parser {
fn singular_expression<'a>(
&mut self,
lexer: &mut Lexer<'a>,
mut ctx: ExpressionContext<'a, '_, '_>,
ctx: &mut ExpressionContext<'a, '_, '_>,
) -> Result<Handle<ast::Expression<'a>>, Error<'a>> {
let start = lexer.start_byte_offset();
self.push_rule_span(Rule::SingularExpr, lexer);
let primary_expr = self.primary_expression(lexer, ctx.reborrow())?;
let singular_expr = self.postfix(start, lexer, ctx.reborrow(), primary_expr)?;
let primary_expr = self.primary_expression(lexer, ctx)?;
let singular_expr = self.postfix(start, lexer, ctx, primary_expr)?;
self.pop_rule_span(lexer);
Ok(singular_expr)
@ -800,7 +790,7 @@ impl Parser {
fn equality_expression<'a>(
&mut self,
lexer: &mut Lexer<'a>,
mut context: ExpressionContext<'a, '_, '_>,
context: &mut ExpressionContext<'a, '_, '_>,
) -> Result<Handle<ast::Expression<'a>>, Error<'a>> {
// equality_expression
context.parse_binary_op(
@ -811,7 +801,7 @@ impl Parser {
_ => None,
},
// relational_expression
|lexer, mut context| {
|lexer, context| {
context.parse_binary_op(
lexer,
|token| match token {
@ -822,7 +812,7 @@ impl Parser {
_ => None,
},
// shift_expression
|lexer, mut context| {
|lexer, context| {
context.parse_binary_op(
lexer,
|token| match token {
@ -835,7 +825,7 @@ impl Parser {
_ => None,
},
// additive_expression
|lexer, mut context| {
|lexer, context| {
context.parse_binary_op(
lexer,
|token| match token {
@ -846,7 +836,7 @@ impl Parser {
_ => None,
},
// multiplicative_expression
|lexer, mut context| {
|lexer, context| {
context.parse_binary_op(
lexer,
|token| match token {
@ -876,16 +866,16 @@ impl Parser {
fn general_expression<'a>(
&mut self,
lexer: &mut Lexer<'a>,
mut ctx: ExpressionContext<'a, '_, '_>,
ctx: &mut ExpressionContext<'a, '_, '_>,
) -> Result<Handle<ast::Expression<'a>>, Error<'a>> {
self.general_expression_with_span(lexer, ctx.reborrow())
self.general_expression_with_span(lexer, ctx)
.map(|(expr, _)| expr)
}
fn general_expression_with_span<'a>(
&mut self,
lexer: &mut Lexer<'a>,
mut context: ExpressionContext<'a, '_, '_>,
context: &mut ExpressionContext<'a, '_, '_>,
) -> Result<(Handle<ast::Expression<'a>>, Span), Error<'a>> {
self.push_rule_span(Rule::GeneralExpr, lexer);
// logical_or_expression
@ -896,7 +886,7 @@ impl Parser {
_ => None,
},
// logical_and_expression
|lexer, mut context| {
|lexer, context| {
context.parse_binary_op(
lexer,
|token| match token {
@ -904,7 +894,7 @@ impl Parser {
_ => None,
},
// inclusive_or_expression
|lexer, mut context| {
|lexer, context| {
context.parse_binary_op(
lexer,
|token| match token {
@ -912,7 +902,7 @@ impl Parser {
_ => None,
},
// exclusive_or_expression
|lexer, mut context| {
|lexer, context| {
context.parse_binary_op(
lexer,
|token| match token {
@ -922,7 +912,7 @@ impl Parser {
_ => None,
},
// and_expression
|lexer, mut context| {
|lexer, context| {
context.parse_binary_op(
lexer,
|token| match token {
@ -949,7 +939,7 @@ impl Parser {
fn variable_decl<'a>(
&mut self,
lexer: &mut Lexer<'a>,
mut ctx: ExpressionContext<'a, '_, '_>,
ctx: &mut ExpressionContext<'a, '_, '_>,
) -> Result<ast::GlobalVariable<'a>, Error<'a>> {
self.push_rule_span(Rule::VariableDecl, lexer);
let mut space = crate::AddressSpace::Handle;
@ -972,10 +962,10 @@ impl Parser {
}
let name = lexer.next_ident()?;
lexer.expect(Token::Separator(':'))?;
let ty = self.type_decl(lexer, ctx.reborrow())?;
let ty = self.type_decl(lexer, ctx)?;
let init = if lexer.skip(Token::Operation('=')) {
let handle = self.general_expression(lexer, ctx.reborrow())?;
let handle = self.general_expression(lexer, ctx)?;
Some(handle)
} else {
None
@ -995,7 +985,7 @@ impl Parser {
fn struct_body<'a>(
&mut self,
lexer: &mut Lexer<'a>,
mut ctx: ExpressionContext<'a, '_, '_>,
ctx: &mut ExpressionContext<'a, '_, '_>,
) -> Result<Vec<ast::StructMember<'a>>, Error<'a>> {
let mut members = Vec::new();
@ -1015,19 +1005,17 @@ impl Parser {
match lexer.next_ident_with_span()? {
("size", name_span) => {
lexer.expect(Token::Paren('('))?;
let expr = self.general_expression(lexer, ctx.reborrow())?;
let expr = self.general_expression(lexer, ctx)?;
lexer.expect(Token::Paren(')'))?;
size.set(expr, name_span)?;
}
("align", name_span) => {
lexer.expect(Token::Paren('('))?;
let expr = self.general_expression(lexer, ctx.reborrow())?;
let expr = self.general_expression(lexer, ctx)?;
lexer.expect(Token::Paren(')'))?;
align.set(expr, name_span)?;
}
(word, word_span) => {
bind_parser.parse(self, lexer, word, word_span, ctx.reborrow())?
}
(word, word_span) => bind_parser.parse(self, lexer, word, word_span, ctx)?,
}
}
@ -1036,7 +1024,7 @@ impl Parser {
let name = lexer.next_ident()?;
lexer.expect(Token::Separator(':'))?;
let ty = self.type_decl(lexer, ctx.reborrow())?;
let ty = self.type_decl(lexer, ctx)?;
ready = lexer.skip(Token::Separator(','));
members.push(ast::StructMember {
@ -1072,7 +1060,7 @@ impl Parser {
&mut self,
lexer: &mut Lexer<'a>,
word: &'a str,
mut ctx: ExpressionContext<'a, '_, '_>,
ctx: &mut ExpressionContext<'a, '_, '_>,
) -> Result<Option<ast::Type<'a>>, Error<'a>> {
if let Some((kind, width)) = conv::get_scalar_type(word) {
return Ok(Some(ast::Type::Scalar { kind, width }));
@ -1242,9 +1230,9 @@ impl Parser {
}
"array" => {
lexer.expect_generic_paren('<')?;
let base = self.type_decl(lexer, ctx.reborrow())?;
let base = self.type_decl(lexer, ctx)?;
let size = if lexer.skip(Token::Separator(',')) {
let size = self.unary_expression(lexer, ctx.reborrow())?;
let size = self.unary_expression(lexer, ctx)?;
ast::ArraySize::Constant(size)
} else {
ast::ArraySize::Dynamic
@ -1255,9 +1243,9 @@ impl Parser {
}
"binding_array" => {
lexer.expect_generic_paren('<')?;
let base = self.type_decl(lexer, ctx.reborrow())?;
let base = self.type_decl(lexer, ctx)?;
let size = if lexer.skip(Token::Separator(',')) {
let size = self.unary_expression(lexer, ctx.reborrow())?;
let size = self.unary_expression(lexer, ctx)?;
ast::ArraySize::Constant(size)
} else {
ast::ArraySize::Dynamic
@ -1439,13 +1427,13 @@ impl Parser {
fn type_decl<'a>(
&mut self,
lexer: &mut Lexer<'a>,
mut ctx: ExpressionContext<'a, '_, '_>,
ctx: &mut ExpressionContext<'a, '_, '_>,
) -> Result<Handle<ast::Type<'a>>, Error<'a>> {
self.push_rule_span(Rule::TypeDecl, lexer);
let (name, span) = lexer.next_ident_with_span()?;
let ty = match self.type_decl_impl(lexer, name, ctx.reborrow())? {
let ty = match self.type_decl_impl(lexer, name, ctx)? {
Some(ty) => ty,
None => {
ctx.unresolved.insert(ast::Dependency {
@ -1462,11 +1450,11 @@ impl Parser {
Ok(handle)
}
fn assignment_op_and_rhs<'a, 'out>(
fn assignment_op_and_rhs<'a>(
&mut self,
lexer: &mut Lexer<'a>,
mut ctx: ExpressionContext<'a, '_, 'out>,
block: &'out mut ast::Block<'a>,
ctx: &mut ExpressionContext<'a, '_, '_>,
block: &mut ast::Block<'a>,
target: Handle<ast::Expression<'a>>,
span_start: usize,
) -> Result<(), Error<'a>> {
@ -1475,7 +1463,7 @@ impl Parser {
let op = lexer.next();
let (op, value) = match op {
(Token::Operation('='), _) => {
let value = self.general_expression(lexer, ctx.reborrow())?;
let value = self.general_expression(lexer, ctx)?;
(None, value)
}
(Token::AssignmentOperation(c), _) => {
@ -1494,7 +1482,7 @@ impl Parser {
_ => unreachable!(),
};
let value = self.general_expression(lexer, ctx.reborrow())?;
let value = self.general_expression(lexer, ctx)?;
(Some(op), value)
}
token @ (Token::IncrementOperation | Token::DecrementOperation, _) => {
@ -1523,27 +1511,27 @@ impl Parser {
}
/// Parse an assignment statement (will also parse increment and decrement statements)
fn assignment_statement<'a, 'out>(
fn assignment_statement<'a>(
&mut self,
lexer: &mut Lexer<'a>,
mut ctx: ExpressionContext<'a, '_, 'out>,
block: &'out mut ast::Block<'a>,
ctx: &mut ExpressionContext<'a, '_, '_>,
block: &mut ast::Block<'a>,
) -> Result<(), Error<'a>> {
let span_start = lexer.start_byte_offset();
let target = self.general_expression(lexer, ctx.reborrow())?;
let target = self.general_expression(lexer, ctx)?;
self.assignment_op_and_rhs(lexer, ctx, block, target, span_start)
}
/// Parse a function call statement.
/// Expects `ident` to be consumed (not in the lexer).
fn function_statement<'a, 'out>(
fn function_statement<'a>(
&mut self,
lexer: &mut Lexer<'a>,
ident: &'a str,
ident_span: Span,
span_start: usize,
mut context: ExpressionContext<'a, '_, 'out>,
block: &'out mut ast::Block<'a>,
context: &mut ExpressionContext<'a, '_, '_>,
block: &mut ast::Block<'a>,
) -> Result<(), Error<'a>> {
self.push_rule_span(Rule::SingularExpr, lexer);
@ -1551,7 +1539,7 @@ impl Parser {
ident,
usage: ident_span,
});
let arguments = self.arguments(lexer, context.reborrow())?;
let arguments = self.arguments(lexer, context)?;
let span = lexer.span_from(span_start);
block.stmts.push(ast::Statement {
@ -1570,11 +1558,11 @@ impl Parser {
Ok(())
}
fn function_call_or_assignment_statement<'a, 'out>(
fn function_call_or_assignment_statement<'a>(
&mut self,
lexer: &mut Lexer<'a>,
mut context: ExpressionContext<'a, '_, 'out>,
block: &'out mut ast::Block<'a>,
context: &mut ExpressionContext<'a, '_, '_>,
block: &mut ast::Block<'a>,
) -> Result<(), Error<'a>> {
let span_start = lexer.start_byte_offset();
match lexer.peek() {
@ -1583,29 +1571,24 @@ impl Parser {
let cloned = lexer.clone();
let _ = lexer.next();
match lexer.peek() {
(Token::Paren('('), _) => self.function_statement(
lexer,
name,
span,
span_start,
context.reborrow(),
block,
),
(Token::Paren('('), _) => {
self.function_statement(lexer, name, span, span_start, context, block)
}
_ => {
*lexer = cloned;
self.assignment_statement(lexer, context.reborrow(), block)
self.assignment_statement(lexer, context, block)
}
}
}
_ => self.assignment_statement(lexer, context.reborrow(), block),
_ => self.assignment_statement(lexer, context, block),
}
}
fn statement<'a, 'out>(
fn statement<'a>(
&mut self,
lexer: &mut Lexer<'a>,
mut ctx: ExpressionContext<'a, '_, 'out>,
block: &'out mut ast::Block<'a>,
ctx: &mut ExpressionContext<'a, '_, '_>,
block: &mut ast::Block<'a>,
) -> Result<(), Error<'a>> {
self.push_rule_span(Rule::Statement, lexer);
match lexer.peek() {
@ -1615,7 +1598,7 @@ impl Parser {
return Ok(());
}
(Token::Paren('{'), _) => {
let (inner, span) = self.block(lexer, ctx.reborrow())?;
let (inner, span) = self.block(lexer, ctx)?;
block.stmts.push(ast::Statement {
kind: ast::StatementKind::Block(inner),
span,
@ -1628,7 +1611,7 @@ impl Parser {
"_" => {
let _ = lexer.next();
lexer.expect(Token::Operation('='))?;
let expr = self.general_expression(lexer, ctx.reborrow())?;
let expr = self.general_expression(lexer, ctx)?;
lexer.expect(Token::Separator(';'))?;
ast::StatementKind::Ignore(expr)
@ -1638,13 +1621,13 @@ impl Parser {
let name = lexer.next_ident()?;
let given_ty = if lexer.skip(Token::Separator(':')) {
let ty = self.type_decl(lexer, ctx.reborrow())?;
let ty = self.type_decl(lexer, ctx)?;
Some(ty)
} else {
None
};
lexer.expect(Token::Operation('='))?;
let expr_id = self.general_expression(lexer, ctx.reborrow())?;
let expr_id = self.general_expression(lexer, ctx)?;
lexer.expect(Token::Separator(';'))?;
let handle = ctx.declare_local(name)?;
@ -1660,14 +1643,14 @@ impl Parser {
let name = lexer.next_ident()?;
let ty = if lexer.skip(Token::Separator(':')) {
let ty = self.type_decl(lexer, ctx.reborrow())?;
let ty = self.type_decl(lexer, ctx)?;
Some(ty)
} else {
None
};
let init = if lexer.skip(Token::Operation('=')) {
let init = self.general_expression(lexer, ctx.reborrow())?;
let init = self.general_expression(lexer, ctx)?;
Some(init)
} else {
None
@ -1686,7 +1669,7 @@ impl Parser {
"return" => {
let _ = lexer.next();
let value = if lexer.peek().0 != Token::Separator(';') {
let handle = self.general_expression(lexer, ctx.reborrow())?;
let handle = self.general_expression(lexer, ctx)?;
Some(handle)
} else {
None
@ -1696,9 +1679,9 @@ impl Parser {
}
"if" => {
let _ = lexer.next();
let condition = self.general_expression(lexer, ctx.reborrow())?;
let condition = self.general_expression(lexer, ctx)?;
let accept = self.block(lexer, ctx.reborrow())?.0;
let accept = self.block(lexer, ctx)?.0;
let mut elsif_stack = Vec::new();
let mut elseif_span_start = lexer.start_byte_offset();
@ -1709,12 +1692,12 @@ impl Parser {
if !lexer.skip(Token::Word("if")) {
// ... else { ... }
break self.block(lexer, ctx.reborrow())?.0;
break self.block(lexer, ctx)?.0;
}
// ... else if (...) { ... }
let other_condition = self.general_expression(lexer, ctx.reborrow())?;
let other_block = self.block(lexer, ctx.reborrow())?;
let other_condition = self.general_expression(lexer, ctx)?;
let other_block = self.block(lexer, ctx)?;
elsif_stack.push((elseif_span_start, other_condition, other_block));
elseif_span_start = lexer.start_byte_offset();
};
@ -1745,7 +1728,7 @@ impl Parser {
}
"switch" => {
let _ = lexer.next();
let selector = self.general_expression(lexer, ctx.reborrow())?;
let selector = self.general_expression(lexer, ctx)?;
lexer.expect(Token::Paren('{'))?;
let mut cases = Vec::new();
@ -1755,7 +1738,7 @@ impl Parser {
(Token::Word("case"), _) => {
// parse a list of values
let value = loop {
let value = self.switch_value(lexer, ctx.reborrow())?;
let value = self.switch_value(lexer, ctx)?;
if lexer.skip(Token::Separator(',')) {
if lexer.skip(Token::Separator(':')) {
break value;
@ -1771,7 +1754,7 @@ impl Parser {
});
};
let body = self.block(lexer, ctx.reborrow())?.0;
let body = self.block(lexer, ctx)?.0;
cases.push(ast::SwitchCase {
value,
@ -1781,7 +1764,7 @@ impl Parser {
}
(Token::Word("default"), _) => {
lexer.skip(Token::Separator(':'));
let body = self.block(lexer, ctx.reborrow())?.0;
let body = self.block(lexer, ctx)?.0;
cases.push(ast::SwitchCase {
value: ast::SwitchValue::Default,
body,
@ -1797,13 +1780,13 @@ impl Parser {
ast::StatementKind::Switch { selector, cases }
}
"loop" => self.r#loop(lexer, ctx.reborrow())?,
"loop" => self.r#loop(lexer, ctx)?,
"while" => {
let _ = lexer.next();
let mut body = ast::Block::default();
let (condition, span) = lexer.capture_span(|lexer| {
let condition = self.general_expression(lexer, ctx.reborrow())?;
let condition = self.general_expression(lexer, ctx)?;
Ok(condition)
})?;
let mut reject = ast::Block::default();
@ -1821,7 +1804,7 @@ impl Parser {
span,
});
let (block, span) = self.block(lexer, ctx.reborrow())?;
let (block, span) = self.block(lexer, ctx)?;
body.stmts.push(ast::Statement {
kind: ast::StatementKind::Block(block),
span,
@ -1841,9 +1824,11 @@ impl Parser {
if !lexer.skip(Token::Separator(';')) {
let num_statements = block.stmts.len();
let (_, span) = lexer.capture_span(|lexer| {
self.statement(lexer, ctx.reborrow(), block)
})?;
let (_, span) = {
let ctx = &mut *ctx;
let block = &mut *block;
lexer.capture_span(|lexer| self.statement(lexer, ctx, block))?
};
if block.stmts.len() != num_statements {
match block.stmts.last().unwrap().kind {
@ -1858,7 +1843,7 @@ impl Parser {
let mut body = ast::Block::default();
if !lexer.skip(Token::Separator(';')) {
let (condition, span) = lexer.capture_span(|lexer| {
let condition = self.general_expression(lexer, ctx.reborrow())?;
let condition = self.general_expression(lexer, ctx)?;
lexer.expect(Token::Separator(';'))?;
Ok(condition)
})?;
@ -1881,13 +1866,13 @@ impl Parser {
if !lexer.skip(Token::Paren(')')) {
self.function_call_or_assignment_statement(
lexer,
ctx.reborrow(),
ctx,
&mut continuing,
)?;
lexer.expect(Token::Paren(')'))?;
}
let (block, span) = self.block(lexer, ctx.reborrow())?;
let (block, span) = self.block(lexer, ctx)?;
body.stmts.push(ast::Statement {
kind: ast::StatementKind::Block(block),
span,
@ -1926,7 +1911,7 @@ impl Parser {
}
// assignment or a function call
_ => {
self.function_call_or_assignment_statement(lexer, ctx.reborrow(), block)?;
self.function_call_or_assignment_statement(lexer, ctx, block)?;
lexer.expect(Token::Separator(';'))?;
self.pop_rule_span(lexer);
return Ok(());
@ -1937,7 +1922,7 @@ impl Parser {
block.stmts.push(ast::Statement { kind, span });
}
_ => {
self.assignment_statement(lexer, ctx.reborrow(), block)?;
self.assignment_statement(lexer, ctx, block)?;
lexer.expect(Token::Separator(';'))?;
self.pop_rule_span(lexer);
}
@ -1948,7 +1933,7 @@ impl Parser {
fn r#loop<'a>(
&mut self,
lexer: &mut Lexer<'a>,
mut ctx: ExpressionContext<'a, '_, '_>,
ctx: &mut ExpressionContext<'a, '_, '_>,
) -> Result<ast::StatementKind<'a>, Error<'a>> {
let _ = lexer.next();
let mut body = ast::Block::default();
@ -1976,7 +1961,7 @@ impl Parser {
// the break if
lexer.expect(Token::Word("if"))?;
let condition = self.general_expression(lexer, ctx.reborrow())?;
let condition = self.general_expression(lexer, ctx)?;
// Set the condition of the break if to the newly parsed
// expression
break_if = Some(condition);
@ -1994,7 +1979,7 @@ impl Parser {
break;
} else {
// Otherwise try to parse a statement
self.statement(lexer, ctx.reborrow(), &mut continuing)?;
self.statement(lexer, ctx, &mut continuing)?;
}
}
// Since the continuing block must be the last part of the loop body,
@ -2008,7 +1993,7 @@ impl Parser {
break;
}
// Otherwise try to parse a statement
self.statement(lexer, ctx.reborrow(), &mut body)?;
self.statement(lexer, ctx, &mut body)?;
}
ctx.local_table.pop_scope();
@ -2024,7 +2009,7 @@ impl Parser {
fn block<'a>(
&mut self,
lexer: &mut Lexer<'a>,
mut ctx: ExpressionContext<'a, '_, '_>,
ctx: &mut ExpressionContext<'a, '_, '_>,
) -> Result<(ast::Block<'a>, Span), Error<'a>> {
self.push_rule_span(Rule::Block, lexer);
@ -2033,7 +2018,7 @@ impl Parser {
lexer.expect(Token::Paren('{'))?;
let mut block = ast::Block::default();
while !lexer.skip(Token::Paren('}')) {
self.statement(lexer, ctx.reborrow(), &mut block)?;
self.statement(lexer, ctx, &mut block)?;
}
ctx.local_table.pop_scope();
@ -2045,14 +2030,14 @@ impl Parser {
fn varying_binding<'a>(
&mut self,
lexer: &mut Lexer<'a>,
mut ctx: ExpressionContext<'a, '_, '_>,
ctx: &mut ExpressionContext<'a, '_, '_>,
) -> Result<Option<ast::Binding<'a>>, Error<'a>> {
let mut bind_parser = BindingParser::default();
self.push_rule_span(Rule::Attribute, lexer);
while lexer.skip(Token::Attribute) {
let (word, span) = lexer.next_ident_with_span()?;
bind_parser.parse(self, lexer, word, span, ctx.reborrow())?;
bind_parser.parse(self, lexer, word, span, ctx)?;
}
let span = self.pop_rule_span(lexer);
@ -2093,12 +2078,12 @@ impl Parser {
ExpectedToken::Token(Token::Separator(',')),
));
}
let binding = self.varying_binding(lexer, ctx.reborrow())?;
let binding = self.varying_binding(lexer, &mut ctx)?;
let param_name = lexer.next_ident()?;
lexer.expect(Token::Separator(':'))?;
let param_type = self.type_decl(lexer, ctx.reborrow())?;
let param_type = self.type_decl(lexer, &mut ctx)?;
let handle = ctx.declare_local(param_name)?;
arguments.push(ast::FunctionArgument {
@ -2111,8 +2096,8 @@ impl Parser {
}
// read return type
let result = if lexer.skip(Token::Arrow) && !lexer.skip(Token::Word("void")) {
let binding = self.varying_binding(lexer, ctx.reborrow())?;
let ty = self.type_decl(lexer, ctx.reborrow())?;
let binding = self.varying_binding(lexer, &mut ctx)?;
let ty = self.type_decl(lexer, &mut ctx)?;
Some(ast::FunctionResult { ty, binding })
} else {
None
@ -2122,7 +2107,7 @@ impl Parser {
lexer.expect(Token::Paren('{'))?;
let mut body = ast::Block::default();
while !lexer.skip(Token::Paren('}')) {
self.statement(lexer, ctx.reborrow(), &mut body)?;
self.statement(lexer, &mut ctx, &mut body)?;
}
ctx.local_table.pop_scope();
@ -2170,12 +2155,12 @@ impl Parser {
match lexer.next_ident_with_span()? {
("binding", name_span) => {
lexer.expect(Token::Paren('('))?;
bind_index.set(self.general_expression(lexer, ctx.reborrow())?, name_span)?;
bind_index.set(self.general_expression(lexer, &mut ctx)?, name_span)?;
lexer.expect(Token::Paren(')'))?;
}
("group", name_span) => {
lexer.expect(Token::Paren('('))?;
bind_group.set(self.general_expression(lexer, ctx.reborrow())?, name_span)?;
bind_group.set(self.general_expression(lexer, &mut ctx)?, name_span)?;
lexer.expect(Token::Paren(')'))?;
}
("vertex", name_span) => {
@ -2192,7 +2177,7 @@ impl Parser {
lexer.expect(Token::Paren('('))?;
let mut new_workgroup_size = [None; 3];
for (i, size) in new_workgroup_size.iter_mut().enumerate() {
*size = Some(self.general_expression(lexer, ctx.reborrow())?);
*size = Some(self.general_expression(lexer, &mut ctx)?);
match lexer.next() {
(Token::Paren(')'), _) => break,
(Token::Separator(','), _) if i != 2 => (),
@ -2241,14 +2226,14 @@ impl Parser {
(Token::Word("struct"), _) => {
let name = lexer.next_ident()?;
let members = self.struct_body(lexer, ctx)?;
let members = self.struct_body(lexer, &mut ctx)?;
Some(ast::GlobalDeclKind::Struct(ast::Struct { name, members }))
}
(Token::Word("alias"), _) => {
let name = lexer.next_ident()?;
lexer.expect(Token::Operation('='))?;
let ty = self.type_decl(lexer, ctx)?;
let ty = self.type_decl(lexer, &mut ctx)?;
lexer.expect(Token::Separator(';'))?;
Some(ast::GlobalDeclKind::Type(ast::TypeAlias { name, ty }))
}
@ -2256,20 +2241,20 @@ impl Parser {
let name = lexer.next_ident()?;
let ty = if lexer.skip(Token::Separator(':')) {
let ty = self.type_decl(lexer, ctx.reborrow())?;
let ty = self.type_decl(lexer, &mut ctx)?;
Some(ty)
} else {
None
};
lexer.expect(Token::Operation('='))?;
let init = self.general_expression(lexer, ctx)?;
let init = self.general_expression(lexer, &mut ctx)?;
lexer.expect(Token::Separator(';'))?;
Some(ast::GlobalDeclKind::Const(ast::Const { name, ty, init }))
}
(Token::Word("var"), _) => {
let mut var = self.variable_decl(lexer, ctx)?;
let mut var = self.variable_decl(lexer, &mut ctx)?;
var.binding = binding.take();
Some(ast::GlobalDeclKind::Var(var))
}
@ -2305,13 +2290,12 @@ impl Parser {
if !self.rules.is_empty() {
log::error!("Reached the end of global decl, but rule stack is not empty");
log::error!("Rules: {:?}", self.rules);
return Err(Error::Other);
return Err(Error::Internal("rule stack is not empty"));
};
match binding {
None => Ok(()),
// we had the attribute but no var?
Some(_) => Err(Error::Other),
Some(_) => Err(Error::Internal("we had the attribute but no var?")),
}
}

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

@ -1231,7 +1231,7 @@ impl<'a> ConstantEvaluator<'a> {
// expression at a time, `Compose` expressions can only refer to other
// expressions, and `ZeroValue` expressions are always okay.
if let Expression::Literal(literal) = expr {
crate::valid::validate_literal(literal)?;
crate::valid::check_literal_value(literal)?;
}
if let Some(FunctionLocalData {

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

@ -140,6 +140,8 @@ pub enum ConstExpressionError {
Type(#[from] ResolveError),
#[error(transparent)]
Literal(#[from] LiteralError),
#[error(transparent)]
Width(#[from] super::r#type::WidthError),
}
#[derive(Clone, Debug, thiserror::Error)]
@ -149,6 +151,8 @@ pub enum LiteralError {
NaN,
#[error("Float literal is infinite")]
Infinity,
#[error(transparent)]
Width(#[from] super::r#type::WidthError),
}
#[cfg(feature = "validate")]
@ -188,7 +192,7 @@ impl super::Validator {
match gctx.const_expressions[handle] {
E::Literal(literal) => {
validate_literal(literal)?;
self.validate_literal(literal)?;
}
E::Constant(_) | E::ZeroValue(_) => {}
E::Compose { ref components, ty } => {
@ -343,7 +347,7 @@ impl super::Validator {
ShaderStages::all()
}
E::Literal(literal) => {
validate_literal(literal)?;
self.validate_literal(literal)?;
ShaderStages::all()
}
E::Constant(_) | E::ZeroValue(_) => ShaderStages::all(),
@ -1563,9 +1567,18 @@ impl super::Validator {
_ => Err(ExpressionError::ExpectedGlobalVariable),
}
}
pub fn validate_literal(&self, literal: crate::Literal) -> Result<(), LiteralError> {
let kind = literal.scalar_kind();
let width = literal.width();
self.check_width(kind, width)?;
check_literal_value(literal)?;
Ok(())
}
}
pub fn validate_literal(literal: crate::Literal) -> Result<(), LiteralError> {
pub fn check_literal_value(literal: crate::Literal) -> Result<(), LiteralError> {
let is_nan = match literal {
crate::Literal::F64(v) => v.is_nan(),
crate::Literal::F32(v) => v.is_nan(),

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

@ -24,7 +24,7 @@ use std::ops;
use crate::span::{AddSpan as _, WithSpan};
pub use analyzer::{ExpressionInfo, FunctionInfo, GlobalUse, Uniformity, UniformityRequirements};
pub use compose::ComposeError;
pub use expression::{validate_literal, LiteralError};
pub use expression::{check_literal_value, LiteralError};
pub use expression::{ConstExpressionError, ExpressionError};
pub use function::{CallError, FunctionError, LocalVariableError};
pub use interface::{EntryPointError, GlobalVariableError, VaryingError};

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

@ -90,8 +90,6 @@ pub enum Disalignment {
pub enum TypeError {
#[error("Capability {0:?} is required")]
MissingCapability(Capabilities),
#[error("The {0:?} scalar width {1} is not supported")]
InvalidWidth(crate::ScalarKind, crate::Bytes),
#[error("The {0:?} scalar width {1} is not supported for an atomic")]
InvalidAtomicWidth(crate::ScalarKind, crate::Bytes),
#[error("Invalid type for pointer target {0:?}")]
@ -126,6 +124,23 @@ pub enum TypeError {
},
#[error("Structure types must have at least one member")]
EmptyStruct,
#[error(transparent)]
WidthError(#[from] WidthError),
}
#[derive(Clone, Debug, thiserror::Error)]
#[cfg_attr(test, derive(PartialEq))]
pub enum WidthError {
#[error("The {0:?} scalar width {1} is not supported")]
Invalid(crate::ScalarKind, crate::Bytes),
#[error("Using `{name}` values requires the `naga::valid::Capabilities::{flag}` flag")]
MissingCapability {
name: &'static str,
flag: &'static str,
},
#[error("64-bit integers are not yet supported")]
Unsupported64Bit,
}
// Only makes sense if `flags.contains(HOST_SHAREABLE)`
@ -209,16 +224,21 @@ impl super::Validator {
}
}
pub(super) fn check_width(
pub(super) const fn check_width(
&self,
kind: crate::ScalarKind,
width: crate::Bytes,
) -> Result<(), TypeError> {
) -> Result<(), WidthError> {
let good = match kind {
crate::ScalarKind::Bool => width == crate::BOOL_WIDTH,
crate::ScalarKind::Float => {
if width == 8 {
self.require_type_capability(Capabilities::FLOAT64)?;
if !self.capabilities.contains(Capabilities::FLOAT64) {
return Err(WidthError::MissingCapability {
name: "f64",
flag: "FLOAT64",
});
}
true
} else {
width == 4
@ -229,7 +249,7 @@ impl super::Validator {
if good {
Ok(())
} else {
Err(TypeError::InvalidWidth(kind, width))
Err(WidthError::Invalid(kind, width))
}
}

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

@ -1 +1 @@
{"files":{"Cargo.toml":"2e8fc931efa9fbf6e5ea207527f5f9a88488bc4a2bcbb962dbfac1d2b28afec7","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":"92facdd0e3fd553af590ecbc0de3491f212e237ea66494ff99f67dbf090d10df","src/command/memory_init.rs":"b50d3d20dbf659052f19da2e79469ba6435e06370f19d6ef45e1b1128d9900b7","src/command/mod.rs":"4eac2ac0283c0cfdcc3512af5439fe38e7004e5f406bf52a66d3017ad1ae7632","src/command/query.rs":"d39e1b8cb6a054fd31333a916da5d79a6671a724212c90c490c13e55043a1685","src/command/render.rs":"64d5ac0c00401520cb420b41ee9a7fc03a62a66f06b9434f48c7351dd6b0b11c","src/command/transfer.rs":"2b6f266ba1155ab42bed23b28abffc1008ce26d60b656f56012b896e63daa111","src/conv.rs":"da95b36b7680ae74ebf810ad8f1decf01bd3eeaff44b3c5af1d4b3c3f0e2059a","src/device/global.rs":"05febdc453628bf88e7d0fd40026d2ca243ec966094a7de96f0b4fd6b626511c","src/device/life.rs":"9ac0aab46de65fd2b493f3ee2c3527e37eaad9dbde1583752958eace71423cef","src/device/mod.rs":"702cd9c88015fb40d8ea838ed607afcfceb5bea809f508c49a70b49d5b9803fd","src/device/queue.rs":"e92840c4cf6af66947cd9b7189f1c539ead08f4610a7dddf9726a8c1294b6a36","src/device/resource.rs":"1ae0fe31d64b99e5cc8a473c48990e2920c8960577061e62b157bc5360de1df3","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":"c57b61e1b0ef20ece19c1d2ebc513e967ada42fbb53a14a73e9e651062af3535","src/lib.rs":"71d42899594be62c2e7074618e03f3639b5ef510b42d6dde660aaa4d5672691e","src/pipeline.rs":"212d469bc1a2256871f64b3f666f05995a92ce39391c32de3856ef2e11c08e16","src/present.rs":"a81f62ca967825f777a5f0d32defb2febb8793406c527d08c6ab0e129df5a81a","src/registry.rs":"4098413de7f48e9ff15d0246793be47a0d54c95b4c8594baf9fafd222a90ba84","src/resource.rs":"7d1d841dd185a1a857814cab424a8b892aa8731dddf3373ea9436fa619d655b7","src/storage.rs":"bc70689ba299e9b4d9f4992c4d3f4dd36b1d8e71327595094981fdfd624f811a","src/track/buffer.rs":"dd6f632c6f31b15807148d705c516a8a1a8d72d02b137dd3b9d7c939447917cb","src/track/metadata.rs":"a80bd086ce825f7484ce6318a586c482d06fea0efc9c76bfa0124e480cc8b75e","src/track/mod.rs":"42b791d9a41eb6e62f6d79cae7abb5ab523eeb9e6030b0f95bbb0e26d56ad0ec","src/track/range.rs":"5bbfed6e103b3234d9de8e42057022da6d628c2cc1db6bb51b88f87f2d8adf8b","src/track/stateless.rs":"1d786b5e9558672243ba7d913736561065ef2bd5c6105c935e982486d10841f0","src/track/texture.rs":"7d60dc81ba7f7e2c2819525b90e6e6c7760cb0920e36aeefe98e76cedd49d26e","src/validation.rs":"815961f6a38cd0691aa8af85e739fd3668133c0ca8937c84bfe698070490d418"},"package":null}
{"files":{"Cargo.toml":"92e907552b777ef0a66f4e0617eab6b1c36efbc61d438a2e7acede178c79b047","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":"92facdd0e3fd553af590ecbc0de3491f212e237ea66494ff99f67dbf090d10df","src/command/memory_init.rs":"b50d3d20dbf659052f19da2e79469ba6435e06370f19d6ef45e1b1128d9900b7","src/command/mod.rs":"4eac2ac0283c0cfdcc3512af5439fe38e7004e5f406bf52a66d3017ad1ae7632","src/command/query.rs":"d39e1b8cb6a054fd31333a916da5d79a6671a724212c90c490c13e55043a1685","src/command/render.rs":"64d5ac0c00401520cb420b41ee9a7fc03a62a66f06b9434f48c7351dd6b0b11c","src/command/transfer.rs":"2b6f266ba1155ab42bed23b28abffc1008ce26d60b656f56012b896e63daa111","src/conv.rs":"da95b36b7680ae74ebf810ad8f1decf01bd3eeaff44b3c5af1d4b3c3f0e2059a","src/device/global.rs":"05febdc453628bf88e7d0fd40026d2ca243ec966094a7de96f0b4fd6b626511c","src/device/life.rs":"9ac0aab46de65fd2b493f3ee2c3527e37eaad9dbde1583752958eace71423cef","src/device/mod.rs":"702cd9c88015fb40d8ea838ed607afcfceb5bea809f508c49a70b49d5b9803fd","src/device/queue.rs":"e92840c4cf6af66947cd9b7189f1c539ead08f4610a7dddf9726a8c1294b6a36","src/device/resource.rs":"3f2726f9b64fad521dd6268023a2efe2a81cc9f524f03aad5c110b148ac0bd0d","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":"558d0abb437f1bf80c9d97c4b1d9dd17adefb752147c2a237334a5de5687242f","src/lib.rs":"71d42899594be62c2e7074618e03f3639b5ef510b42d6dde660aaa4d5672691e","src/pipeline.rs":"212d469bc1a2256871f64b3f666f05995a92ce39391c32de3856ef2e11c08e16","src/present.rs":"a81f62ca967825f777a5f0d32defb2febb8793406c527d08c6ab0e129df5a81a","src/registry.rs":"4098413de7f48e9ff15d0246793be47a0d54c95b4c8594baf9fafd222a90ba84","src/resource.rs":"7d1d841dd185a1a857814cab424a8b892aa8731dddf3373ea9436fa619d655b7","src/storage.rs":"bc70689ba299e9b4d9f4992c4d3f4dd36b1d8e71327595094981fdfd624f811a","src/track/buffer.rs":"dd6f632c6f31b15807148d705c516a8a1a8d72d02b137dd3b9d7c939447917cb","src/track/metadata.rs":"a80bd086ce825f7484ce6318a586c482d06fea0efc9c76bfa0124e480cc8b75e","src/track/mod.rs":"42b791d9a41eb6e62f6d79cae7abb5ab523eeb9e6030b0f95bbb0e26d56ad0ec","src/track/range.rs":"5bbfed6e103b3234d9de8e42057022da6d628c2cc1db6bb51b88f87f2d8adf8b","src/track/stateless.rs":"1d786b5e9558672243ba7d913736561065ef2bd5c6105c935e982486d10841f0","src/track/texture.rs":"7d60dc81ba7f7e2c2819525b90e6e6c7760cb0920e36aeefe98e76cedd49d26e","src/validation.rs":"815961f6a38cd0691aa8af85e739fd3668133c0ca8937c84bfe698070490d418"},"package":null}

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

@ -13,7 +13,7 @@
edition = "2021"
rust-version = "1.65"
name = "wgpu-core"
version = "0.17.0"
version = "0.18.0"
authors = ["wgpu developers"]
description = "WebGPU core logic on wgpu-hal"
homepage = "https://wgpu.rs/"
@ -48,15 +48,15 @@ smallvec = "1"
thiserror = "1"
[dependencies.hal]
version = "0.17"
version = "0.18.0"
path = "../wgpu-hal"
default_features = false
package = "wgpu-hal"
[dependencies.naga]
version = "0.13.0"
version = "0.14.0"
git = "https://github.com/gfx-rs/naga"
rev = "e25280df9316434ef7752970016d01a3aede3f17"
rev = "92e41b43e437146b5d946eb238de963be1168016"
features = [
"clone",
"span",
@ -81,7 +81,7 @@ features = ["serde_derive"]
optional = true
[dependencies.wgt]
version = "0.17"
version = "0.18.0"
path = "../wgpu-types"
package = "wgpu-types"

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

@ -1317,6 +1317,19 @@ impl<A: HalApi> Device<A> {
.contains(wgt::DownlevelFlags::CUBE_ARRAY_TEXTURES),
);
let debug_source = if self.instance_flags.contains(wgt::InstanceFlags::DEBUG) {
Some(hal::DebugSource {
file_name: Cow::Owned(
desc.label
.as_ref()
.map_or("shader".to_string(), |l| l.to_string()),
),
source_code: Cow::Owned(source.clone()),
})
} else {
None
};
let info = naga::valid::Validator::new(naga::valid::ValidationFlags::all(), caps)
.validate(&module)
.map_err(|inner| {
@ -1326,10 +1339,14 @@ impl<A: HalApi> Device<A> {
inner: Box::new(inner),
})
})?;
let interface =
validation::Interface::new(&module, &info, self.limits.clone(), self.features);
let hal_shader = hal::ShaderInput::Naga(hal::NagaShader { module, info });
let hal_shader = hal::ShaderInput::Naga(hal::NagaShader {
module,
info,
debug_source,
});
let hal_desc = hal::ShaderModuleDescriptor {
label: desc.label.to_hal(self.instance_flags),
runtime_checks: desc.shader_bound_checks.runtime_checks(),

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

@ -615,9 +615,11 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
presentation: None,
#[cfg(all(feature = "vulkan", not(target_arch = "wasm32")))]
vulkan: None,
#[cfg(all(feature = "dx12", windows))]
dx12: self.instance.dx12.as_ref().map(|inst| HalSurface {
raw: unsafe { inst.create_surface_from_visual(visual as _) },
}),
#[cfg(all(feature = "dx11", windows))]
dx11: None,
#[cfg(feature = "gles")]
gl: None,
@ -643,9 +645,11 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
presentation: None,
#[cfg(all(feature = "vulkan", not(target_arch = "wasm32")))]
vulkan: None,
#[cfg(all(feature = "dx12", windows))]
dx12: self.instance.dx12.as_ref().map(|inst| HalSurface {
raw: unsafe { inst.create_surface_from_surface_handle(surface_handle) },
}),
#[cfg(all(feature = "dx11", windows))]
dx11: None,
#[cfg(feature = "gles")]
gl: None,
@ -671,9 +675,11 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
presentation: None,
#[cfg(all(feature = "vulkan", not(target_arch = "wasm32")))]
vulkan: None,
#[cfg(all(feature = "dx12", windows))]
dx12: self.instance.dx12.as_ref().map(|inst| HalSurface {
raw: unsafe { inst.create_surface_from_swap_chain_panel(swap_chain_panel as _) },
}),
#[cfg(all(feature = "dx11", windows))]
dx11: None,
#[cfg(feature = "gles")]
gl: None,

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

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

@ -13,7 +13,7 @@
edition = "2021"
rust-version = "1.65"
name = "wgpu-hal"
version = "0.17.0"
version = "0.18.0"
authors = ["wgpu developers"]
description = "WebGPU hardware abstraction layer"
homepage = "https://wgpu.rs/"
@ -59,13 +59,13 @@ rustc-hash = "1.1"
thiserror = "1"
[dependencies.glow]
version = "0.12.3"
version = "0.13"
optional = true
[dependencies.naga]
version = "0.13.0"
version = "0.14.0"
git = "https://github.com/gfx-rs/naga"
rev = "e25280df9316434ef7752970016d01a3aede3f17"
rev = "92e41b43e437146b5d946eb238de963be1168016"
features = ["clone"]
[dependencies.profiling]
@ -73,7 +73,7 @@ version = "1"
default-features = false
[dependencies.wgt]
version = "0.17"
version = "0.18.0"
path = "../wgpu-types"
package = "wgpu-types"
@ -82,9 +82,9 @@ cfg-if = "1"
env_logger = "0.10"
[dev-dependencies.naga]
version = "0.13.0"
version = "0.14.0"
git = "https://github.com/gfx-rs/naga"
rev = "e25280df9316434ef7752970016d01a3aede3f17"
rev = "92e41b43e437146b5d946eb238de963be1168016"
features = ["wgsl-in"]
[dev-dependencies.winit]
@ -160,16 +160,13 @@ features = [
[target."cfg(any(target_os=\"macos\", target_os=\"ios\"))".dependencies]
core-graphics-types = "0.1"
metal = "0.27.0"
objc = "0.2.5"
[target."cfg(any(target_os=\"macos\", target_os=\"ios\"))".dependencies.block]
version = "0.1"
optional = true
[target."cfg(any(target_os=\"macos\", target_os=\"ios\"))".dependencies.metal]
git = "https://github.com/gfx-rs/metal-rs/"
rev = "d24f1a4"
[target."cfg(not(target_arch = \"wasm32\"))".dependencies.ash]
version = "0.37.3"
optional = true
@ -230,7 +227,7 @@ features = ["libloading"]
optional = true
[target."cfg(windows)".dependencies.glutin_wgl_sys]
version = "0.4"
version = "0.5"
optional = true
[target."cfg(windows)".dependencies.gpu-allocator]

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

@ -156,6 +156,7 @@ impl<A: hal::Api> Example<A> {
hal::NagaShader {
module: Cow::Owned(module),
info,
debug_source: None,
}
};
let shader_desc = hal::ShaderModuleDescriptor {

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

@ -210,16 +210,12 @@ impl super::Adapter {
(glow::VENDOR, glow::RENDERER)
};
let (vendor, renderer) = {
let vendor = unsafe { gl.get_parameter_string(vendor_const) };
let renderer = unsafe { gl.get_parameter_string(renderer_const) };
(vendor, renderer)
};
let vendor = unsafe { gl.get_parameter_string(vendor_const) };
let renderer = unsafe { gl.get_parameter_string(renderer_const) };
let version = unsafe { gl.get_parameter_string(glow::VERSION) };
log::info!("Vendor: {}", vendor);
log::info!("Renderer: {}", renderer);
log::info!("Version: {}", version);
log::trace!("Vendor: {}", vendor);
log::trace!("Renderer: {}", renderer);
log::trace!("Version: {}", version);
let full_ver = Self::parse_full_version(&version).ok();
let es_ver = full_ver
@ -254,27 +250,9 @@ impl super::Adapter {
}
}
let supported = |(req_es_major, req_es_minor), (req_full_major, req_full_minor)| {
let es_supported = es_ver
.map(|es_ver| es_ver >= (req_es_major, req_es_minor))
.unwrap_or_default();
let full_supported = full_ver
.map(|full_ver| full_ver >= (req_full_major, req_full_minor))
.unwrap_or_default();
es_supported || full_supported
};
let supports_storage =
supported((3, 1), (4, 3)) || extensions.contains("GL_ARB_shader_storage_buffer_object");
let supports_compute =
supported((3, 1), (4, 3)) || extensions.contains("GL_ARB_compute_shader");
let supports_work_group_params = supports_compute;
let shading_language_version = {
let sl_version = unsafe { gl.get_parameter_string(glow::SHADING_LANGUAGE_VERSION) };
log::info!("SL version: {}", &sl_version);
log::trace!("SL version: {}", &sl_version);
if full_ver.is_some() {
let (sl_major, sl_minor) = Self::parse_full_version(&sl_version).ok()?;
let mut value = sl_major as u16 * 100 + sl_minor as u16 * 10;
@ -293,6 +271,26 @@ impl super::Adapter {
}
};
log::trace!("Supported GL Extensions: {:#?}", extensions);
let supported = |(req_es_major, req_es_minor), (req_full_major, req_full_minor)| {
let es_supported = es_ver
.map(|es_ver| es_ver >= (req_es_major, req_es_minor))
.unwrap_or_default();
let full_supported = full_ver
.map(|full_ver| full_ver >= (req_full_major, req_full_minor))
.unwrap_or_default();
es_supported || full_supported
};
let supports_storage =
supported((3, 1), (4, 3)) || extensions.contains("GL_ARB_shader_storage_buffer_object");
let supports_compute =
supported((3, 1), (4, 3)) || extensions.contains("GL_ARB_compute_shader");
let supports_work_group_params = supports_compute;
// ANGLE provides renderer strings like: "ANGLE (Apple, Apple M1 Pro, OpenGL 4.1)"
let is_angle = renderer.contains("ANGLE");
@ -385,7 +383,9 @@ impl super::Adapter {
&& (vertex_shader_storage_blocks != 0 || vertex_ssbo_false_zero),
);
downlevel_flags.set(wgt::DownlevelFlags::FRAGMENT_STORAGE, supports_storage);
if extensions.contains("EXT_texture_filter_anisotropic") {
if extensions.contains("EXT_texture_filter_anisotropic")
|| extensions.contains("GL_EXT_texture_filter_anisotropic")
{
let max_aniso =
unsafe { gl.get_parameter_i32(glow::MAX_TEXTURE_MAX_ANISOTROPY_EXT) } as u32;
downlevel_flags.set(wgt::DownlevelFlags::ANISOTROPIC_FILTERING, max_aniso >= 16);
@ -411,6 +411,11 @@ impl super::Adapter {
wgt::DownlevelFlags::MULTISAMPLED_SHADING,
supported((3, 2), (4, 0)) || extensions.contains("OES_sample_variables"),
);
let query_buffers = extensions.contains("GL_ARB_query_buffer_object")
|| extensions.contains("GL_AMD_query_buffer_object");
if query_buffers {
downlevel_flags.set(wgt::DownlevelFlags::NONBLOCKING_QUERY_RESOLVE, true);
}
let mut features = wgt::Features::empty()
| wgt::Features::TEXTURE_ADAPTER_SPECIFIC_FORMAT_FEATURES
@ -418,11 +423,12 @@ impl super::Adapter {
| wgt::Features::PUSH_CONSTANTS;
features.set(
wgt::Features::ADDRESS_MODE_CLAMP_TO_BORDER | wgt::Features::ADDRESS_MODE_CLAMP_TO_ZERO,
extensions.contains("GL_EXT_texture_border_clamp"),
extensions.contains("GL_EXT_texture_border_clamp")
|| extensions.contains("GL_ARB_texture_border_clamp"),
);
features.set(
wgt::Features::DEPTH_CLIP_CONTROL,
extensions.contains("GL_EXT_depth_clamp"),
extensions.contains("GL_EXT_depth_clamp") || extensions.contains("GL_ARB_depth_clamp"),
);
features.set(
wgt::Features::VERTEX_WRITABLE_STORAGE,
@ -431,11 +437,12 @@ impl super::Adapter {
);
features.set(
wgt::Features::MULTIVIEW,
extensions.contains("OVR_multiview2"),
extensions.contains("OVR_multiview2") || extensions.contains("GL_OVR_multiview2"),
);
features.set(
wgt::Features::DUAL_SOURCE_BLENDING,
extensions.contains("GL_EXT_blend_func_extended"),
extensions.contains("GL_EXT_blend_func_extended")
|| extensions.contains("GL_ARB_blend_func_extended"),
);
features.set(
wgt::Features::SHADER_PRIMITIVE_INDEX,
@ -448,6 +455,15 @@ impl super::Adapter {
supported((3, 1), (4, 2)) || extensions.contains("GL_ARB_shader_image_load_store"),
);
features.set(wgt::Features::SHADER_UNUSED_VERTEX_OUTPUT, true);
if extensions.contains("GL_ARB_timer_query") {
features.set(wgt::Features::TIMESTAMP_QUERY, true);
features.set(wgt::Features::TIMESTAMP_QUERY_INSIDE_PASSES, true);
}
let gl_bcn_exts = [
"GL_EXT_texture_compression_s3tc",
"GL_EXT_texture_compression_rgtc",
"GL_ARB_texture_compression_bptc",
];
let gles_bcn_exts = [
"GL_EXT_texture_compression_s3tc_srgb",
"GL_EXT_texture_compression_rgtc",
@ -461,18 +477,23 @@ impl super::Adapter {
];
let bcn_exts = if cfg!(target_arch = "wasm32") {
&webgl_bcn_exts[..]
} else {
} else if es_ver.is_some() {
&gles_bcn_exts[..]
} else {
&gl_bcn_exts[..]
};
features.set(
wgt::Features::TEXTURE_COMPRESSION_BC,
bcn_exts.iter().all(|&ext| extensions.contains(ext)),
);
features.set(
wgt::Features::TEXTURE_COMPRESSION_ETC2,
// This is a part of GLES-3 but not WebGL2 core
!cfg!(target_arch = "wasm32") || extensions.contains("WEBGL_compressed_texture_etc"),
);
let has_etc = if cfg!(target_arch = "wasm32") {
extensions.contains("WEBGL_compressed_texture_etc")
} else {
// This is a required part of GLES3, but not part of Desktop GL at all.
es_ver.is_some()
};
features.set(wgt::Features::TEXTURE_COMPRESSION_ETC2, has_etc);
// `OES_texture_compression_astc` provides 2D + 3D, LDR + HDR support
if extensions.contains("WEBGL_compressed_texture_astc")
|| extensions.contains("GL_OES_texture_compression_astc")
@ -514,7 +535,8 @@ impl super::Adapter {
let mut private_caps = super::PrivateCapabilities::empty();
private_caps.set(
super::PrivateCapabilities::BUFFER_ALLOCATION,
extensions.contains("GL_EXT_buffer_storage"),
extensions.contains("GL_EXT_buffer_storage")
|| extensions.contains("GL_ARB_buffer_storage"),
);
private_caps.set(
super::PrivateCapabilities::SHADER_BINDING_LAYOUT,
@ -538,11 +560,13 @@ impl super::Adapter {
);
private_caps.set(
super::PrivateCapabilities::GET_BUFFER_SUB_DATA,
cfg!(target_arch = "wasm32"),
cfg!(target_arch = "wasm32") || full_ver.is_some(),
);
let color_buffer_float = extensions.contains("GL_EXT_color_buffer_float")
|| extensions.contains("GL_ARB_color_buffer_float")
|| extensions.contains("EXT_color_buffer_float");
let color_buffer_half_float = extensions.contains("GL_EXT_color_buffer_half_float");
let color_buffer_half_float = extensions.contains("GL_EXT_color_buffer_half_float")
|| extensions.contains("GL_ARB_half_float_pixel");
private_caps.set(
super::PrivateCapabilities::COLOR_BUFFER_HALF_FLOAT,
color_buffer_half_float || color_buffer_float,
@ -553,8 +577,13 @@ impl super::Adapter {
);
private_caps.set(
super::PrivateCapabilities::TEXTURE_FLOAT_LINEAR,
extensions.contains("OES_texture_float_linear"),
if full_ver.is_some() {
color_buffer_float
} else {
extensions.contains("OES_texture_float_linear")
},
);
private_caps.set(super::PrivateCapabilities::QUERY_BUFFERS, query_buffers);
let max_texture_size = unsafe { gl.get_parameter_i32(glow::MAX_TEXTURE_SIZE) } as u32;
let max_texture_3d_size = unsafe { gl.get_parameter_i32(glow::MAX_3D_TEXTURE_SIZE) } as u32;

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

@ -31,6 +31,7 @@ pub(super) struct State {
dirty_vbuf_mask: usize,
active_first_instance: u32,
push_offset_to_uniform: ArrayVec<super::UniformDesc, { super::MAX_PUSH_CONSTANTS }>,
end_of_pass_timestamp: Option<glow::Query>,
}
impl super::CommandBuffer {
@ -409,8 +410,9 @@ impl crate::CommandEncoder<super::Api> for super::CommandEncoder {
unsafe fn end_query(&mut self, set: &super::QuerySet, _index: u32) {
self.cmd_buffer.commands.push(C::EndQuery(set.target));
}
unsafe fn write_timestamp(&mut self, _set: &super::QuerySet, _index: u32) {
unimplemented!()
unsafe fn write_timestamp(&mut self, set: &super::QuerySet, index: u32) {
let query = set.queries[index as usize];
self.cmd_buffer.commands.push(C::TimestampQuery(query));
}
unsafe fn reset_queries(&mut self, _set: &super::QuerySet, _range: Range<u32>) {
//TODO: what do we do here?
@ -439,6 +441,16 @@ impl crate::CommandEncoder<super::Api> for super::CommandEncoder {
// render
unsafe fn begin_render_pass(&mut self, desc: &crate::RenderPassDescriptor<super::Api>) {
debug_assert!(self.state.end_of_pass_timestamp.is_none());
if let Some(ref t) = desc.timestamp_writes {
if let Some(index) = t.beginning_of_pass_write_index {
unsafe { self.write_timestamp(t.query_set, index) }
}
self.state.end_of_pass_timestamp = t
.end_of_pass_write_index
.map(|index| t.query_set.queries[index as usize]);
}
self.state.render_size = desc.extent;
self.state.resolve_attachments.clear();
self.state.invalidate_attachments.clear();
@ -623,6 +635,10 @@ impl crate::CommandEncoder<super::Api> for super::CommandEncoder {
}
self.state.vertex_attributes.clear();
self.state.primitive = super::PrimitiveState::default();
if let Some(query) = self.state.end_of_pass_timestamp.take() {
self.cmd_buffer.commands.push(C::TimestampQuery(query));
}
}
unsafe fn set_bind_group(
@ -1030,6 +1046,16 @@ impl crate::CommandEncoder<super::Api> for super::CommandEncoder {
// compute
unsafe fn begin_compute_pass(&mut self, desc: &crate::ComputePassDescriptor<super::Api>) {
debug_assert!(self.state.end_of_pass_timestamp.is_none());
if let Some(ref t) = desc.timestamp_writes {
if let Some(index) = t.beginning_of_pass_write_index {
unsafe { self.write_timestamp(t.query_set, index) }
}
self.state.end_of_pass_timestamp = t
.end_of_pass_write_index
.map(|index| t.query_set.queries[index as usize]);
}
if let Some(label) = desc.label {
let range = self.cmd_buffer.add_marker(label);
self.cmd_buffer.commands.push(C::PushDebugGroup(range));
@ -1041,6 +1067,10 @@ impl crate::CommandEncoder<super::Api> for super::CommandEncoder {
self.cmd_buffer.commands.push(C::PopDebugGroup);
self.state.has_pass_label = false;
}
if let Some(query) = self.state.end_of_pass_timestamp.take() {
self.cmd_buffer.commands.push(C::TimestampQuery(query));
}
}
unsafe fn set_compute_pipeline(&mut self, pipeline: &super::ComputePipeline) {

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

@ -1224,6 +1224,14 @@ impl crate::Device<super::Api> for super::Device {
if gl.supports_debug() {
use std::fmt::Write;
// Initialize the query so we can label it
match desc.ty {
wgt::QueryType::Timestamp => unsafe {
gl.query_counter(query, glow::TIMESTAMP)
},
_ => (),
}
if let Some(label) = desc.label {
temp_string.clear();
let _ = write!(temp_string, "{label}[{i}]");
@ -1238,6 +1246,7 @@ impl crate::Device<super::Api> for super::Device {
queries: queries.into_boxed_slice(),
target: match desc.ty {
wgt::QueryType::Occlusion => glow::ANY_SAMPLES_PASSED_CONSERVATIVE,
wgt::QueryType::Timestamp => glow::TIMESTAMP,
_ => unimplemented!(),
},
})

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

@ -946,7 +946,7 @@ impl crate::Instance<super::Api> for Instance {
let inner = self.inner.lock();
inner.egl.make_current();
let gl = unsafe {
let mut gl = unsafe {
glow::Context::from_loader_function(|name| {
inner
.egl

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

@ -161,6 +161,8 @@ bitflags::bitflags! {
const COLOR_BUFFER_FLOAT = 1 << 9;
/// Supports linear flitering `f32` textures.
const TEXTURE_FLOAT_LINEAR = 1 << 10;
/// Supports query buffer objects.
const QUERY_BUFFERS = 1 << 11;
}
}
@ -775,6 +777,7 @@ enum Command {
SetIndexBuffer(glow::Buffer),
BeginQuery(glow::Query, BindTarget),
EndQuery(BindTarget),
TimestampQuery(glow::Query),
CopyQueryResults {
query_range: Range<u32>,
dst: Buffer,

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

@ -1,4 +1,4 @@
use super::{conv::is_layered_target, Command as C};
use super::{conv::is_layered_target, Command as C, PrivateCapabilities};
use arrayvec::ArrayVec;
use glow::HasContext;
use std::{mem, slice, sync::Arc};
@ -808,34 +808,97 @@ impl super::Queue {
C::EndQuery(target) => {
unsafe { gl.end_query(target) };
}
C::TimestampQuery(query) => {
unsafe { gl.query_counter(query, glow::TIMESTAMP) };
}
C::CopyQueryResults {
ref query_range,
ref dst,
dst_target,
dst_offset,
} => {
self.temp_query_results.clear();
for &query in queries[query_range.start as usize..query_range.end as usize].iter() {
let result = unsafe { gl.get_query_parameter_u32(query, glow::QUERY_RESULT) };
self.temp_query_results.push(result as u64);
}
let query_data = unsafe {
slice::from_raw_parts(
self.temp_query_results.as_ptr() as *const u8,
self.temp_query_results.len() * mem::size_of::<u64>(),
)
};
match dst.raw {
Some(buffer) => {
unsafe { gl.bind_buffer(dst_target, Some(buffer)) };
unsafe {
gl.buffer_sub_data_u8_slice(dst_target, dst_offset as i32, query_data)
};
if self
.shared
.private_caps
.contains(PrivateCapabilities::QUERY_BUFFERS)
&& dst.raw.is_some()
{
unsafe {
// We're assuming that the only relevant queries are 8 byte timestamps or
// occlusion tests.
let query_size = 8;
let query_range_size = query_size * query_range.len();
let buffer = gl.create_buffer().ok();
gl.bind_buffer(glow::QUERY_BUFFER, buffer);
gl.buffer_data_size(
glow::QUERY_BUFFER,
query_range_size as _,
glow::STREAM_COPY,
);
for (i, &query) in queries
[query_range.start as usize..query_range.end as usize]
.iter()
.enumerate()
{
gl.get_query_parameter_u64_with_offset(
query,
glow::QUERY_RESULT,
query_size * i,
)
}
gl.bind_buffer(dst_target, dst.raw);
gl.copy_buffer_sub_data(
glow::QUERY_BUFFER,
dst_target,
0,
dst_offset as _,
query_range_size as _,
);
if let Some(buffer) = buffer {
gl.delete_buffer(buffer)
}
}
None => {
let data = &mut dst.data.as_ref().unwrap().lock().unwrap();
let len = query_data.len().min(data.len());
data[..len].copy_from_slice(&query_data[..len]);
} else {
self.temp_query_results.clear();
for &query in
queries[query_range.start as usize..query_range.end as usize].iter()
{
let mut result: u64 = 0;
unsafe {
let result: *mut u64 = &mut result;
gl.get_query_parameter_u64_with_offset(
query,
glow::QUERY_RESULT,
result as usize,
)
};
self.temp_query_results.push(result);
}
let query_data = unsafe {
slice::from_raw_parts(
self.temp_query_results.as_ptr() as *const u8,
self.temp_query_results.len() * mem::size_of::<u64>(),
)
};
match dst.raw {
Some(buffer) => {
unsafe { gl.bind_buffer(dst_target, Some(buffer)) };
unsafe {
gl.buffer_sub_data_u8_slice(
dst_target,
dst_offset as i32,
query_data,
)
};
}
None => {
let data = &mut dst.data.as_ref().unwrap().lock().unwrap();
let len = query_data.len().min(data.len());
data[..len].copy_from_slice(&query_data[..len]);
}
}
}
}

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

@ -26,9 +26,9 @@ use winapi::{
libloaderapi::{GetModuleHandleA, GetProcAddress, LoadLibraryA},
wingdi::{
wglCreateContext, wglDeleteContext, wglGetCurrentContext, wglGetProcAddress,
wglMakeCurrent, wglShareLists, ChoosePixelFormat, DescribePixelFormat, GetPixelFormat,
SetPixelFormat, SwapBuffers, PFD_DOUBLEBUFFER, PFD_DRAW_TO_WINDOW, PFD_SUPPORT_OPENGL,
PFD_TYPE_RGBA, PIXELFORMATDESCRIPTOR,
wglMakeCurrent, ChoosePixelFormat, DescribePixelFormat, GetPixelFormat, SetPixelFormat,
SwapBuffers, PFD_DOUBLEBUFFER, PFD_DRAW_TO_WINDOW, PFD_SUPPORT_OPENGL, PFD_TYPE_RGBA,
PIXELFORMATDESCRIPTOR,
},
winuser::{
CreateWindowExA, DefWindowProcA, GetDC, RegisterClassExA, ReleaseDC, CS_OWNDC,
@ -133,7 +133,6 @@ unsafe impl Send for WglContext {}
unsafe impl Sync for WglContext {}
struct Inner {
opengl_module: HMODULE,
gl: glow::Context,
device: HDC,
context: WglContext,
@ -388,7 +387,7 @@ impl crate::Instance<super::Api> for Instance {
)
})?;
let gl = unsafe {
let mut gl = unsafe {
glow::Context::from_loader_function(|name| load_gl_func(name, Some(opengl_module)))
};
@ -406,7 +405,7 @@ impl crate::Instance<super::Api> for Instance {
}
if desc.flags.contains(InstanceFlags::VALIDATION) && gl.supports_debug() {
log::info!("Enabling GL debug output");
log::debug!("Enabling GL debug output");
unsafe { gl.enable(glow::DEBUG_OUTPUT) };
unsafe { gl.debug_message_callback(super::gl_debug_message_callback) };
}
@ -421,7 +420,6 @@ impl crate::Instance<super::Api> for Instance {
Ok(Instance {
inner: Arc::new(Mutex::new(Inner {
device: dc,
opengl_module,
gl,
context,
})),
@ -476,12 +474,12 @@ impl Drop for DeviceContextHandle {
}
pub struct Swapchain {
surface_context: WglContext,
surface_gl: glow::Context,
framebuffer: glow::Framebuffer,
renderbuffer: glow::Renderbuffer,
/// Extent because the window lies
extent: wgt::Extent3d,
format: wgt::TextureFormat,
format_desc: super::TextureFormatDesc,
#[allow(unused)]
@ -520,17 +518,25 @@ impl Surface {
window: self.window,
};
// Hold the lock for the shared context as we're using resources from there.
let _inner = context.inner.lock();
let inner = context.inner.lock();
if let Err(e) = sc.surface_context.make_current(dc.device) {
log::error!("unable to make the surface OpenGL context current: {e}",);
if let Err(e) = inner.context.make_current(dc.device) {
log::error!("unable to make the OpenGL context current for surface: {e}",);
return Err(crate::SurfaceError::Other(
"unable to make the surface OpenGL context current",
"unable to make the OpenGL context current for surface",
));
}
let gl = &sc.surface_gl;
let gl = &inner.gl;
unsafe { gl.bind_framebuffer(glow::DRAW_FRAMEBUFFER, None) };
unsafe { gl.bind_framebuffer(glow::READ_FRAMEBUFFER, Some(sc.framebuffer)) };
if self.srgb_capable {
// Disable sRGB conversions for `glBlitFramebuffer` as behavior does diverge between
// drivers and formats otherwise and we want to ensure no sRGB conversions happen.
unsafe { gl.disable(glow::FRAMEBUFFER_SRGB) };
}
// Note the Y-flipping here. GL's presentation is not flipped,
// but main rendering is. Therefore, we Y-flip the output positions
@ -550,6 +556,13 @@ impl Surface {
)
};
if self.srgb_capable {
unsafe { gl.enable(glow::FRAMEBUFFER_SRGB) };
}
unsafe { gl.bind_renderbuffer(glow::RENDERBUFFER, None) };
unsafe { gl.bind_framebuffer(glow::READ_FRAMEBUFFER, None) };
if unsafe { SwapBuffers(dc.device) } == FALSE {
log::error!("unable to swap buffers: {}", Error::last_os_error());
return Err(crate::SurfaceError::Other("unable to swap buffers"));
@ -572,33 +585,6 @@ impl crate::Surface<super::Api> for Surface {
// Remove the old configuration.
unsafe { self.unconfigure(device) };
let format_desc = device.shared.describe_texture_format(config.format);
let inner = &device.shared.context.inner.lock();
if let Err(e) = inner.context.make_current(inner.device) {
log::error!("unable to make the shared OpenGL context current: {e}",);
return Err(crate::SurfaceError::Other(
"unable to make the shared OpenGL context current",
));
}
let gl = &inner.gl;
let renderbuffer = unsafe { gl.create_renderbuffer() }.map_err(|error| {
log::error!("Internal swapchain renderbuffer creation failed: {error}");
crate::DeviceError::OutOfMemory
})?;
unsafe { gl.bind_renderbuffer(glow::RENDERBUFFER, Some(renderbuffer)) };
unsafe {
gl.renderbuffer_storage(
glow::RENDERBUFFER,
format_desc.internal,
config.extent.width as _,
config.extent.height as _,
)
};
// Create the swap chain OpenGL context
let dc = unsafe { GetDC(self.window) };
if dc.is_null() {
log::error!(
@ -621,35 +607,48 @@ impl crate::Surface<super::Api> for Surface {
));
}
let context = unsafe { wglCreateContext(dc.device) };
if context.is_null() {
log::error!(
"unable to create surface OpenGL context: {}",
Error::last_os_error()
);
return Err(crate::SurfaceError::Other(
"unable to create surface OpenGL context",
));
}
let surface_context = WglContext { context };
let format_desc = device.shared.describe_texture_format(config.format);
let inner = &device.shared.context.inner.lock();
if unsafe { wglShareLists(inner.context.context, surface_context.context) } == FALSE {
log::error!(
"unable to share objects between OpenGL contexts: {}",
Error::last_os_error()
);
if let Err(e) = inner.context.make_current(dc.device) {
log::error!("unable to make the OpenGL context current for surface: {e}",);
return Err(crate::SurfaceError::Other(
"unable to share objects between OpenGL contexts",
"unable to make the OpenGL context current for surface",
));
}
if let Err(e) = surface_context.make_current(dc.device) {
log::error!("unable to make the surface OpengL context current: {e}",);
return Err(crate::SurfaceError::Other(
"unable to make the surface OpengL context current",
));
}
let gl = &inner.gl;
let renderbuffer = unsafe { gl.create_renderbuffer() }.map_err(|error| {
log::error!("Internal swapchain renderbuffer creation failed: {error}");
crate::DeviceError::OutOfMemory
})?;
unsafe { gl.bind_renderbuffer(glow::RENDERBUFFER, Some(renderbuffer)) };
unsafe {
gl.renderbuffer_storage(
glow::RENDERBUFFER,
format_desc.internal,
config.extent.width as _,
config.extent.height as _,
)
};
let framebuffer = unsafe { gl.create_framebuffer() }.map_err(|error| {
log::error!("Internal swapchain framebuffer creation failed: {error}");
crate::DeviceError::OutOfMemory
})?;
unsafe { gl.bind_framebuffer(glow::READ_FRAMEBUFFER, Some(framebuffer)) };
unsafe {
gl.framebuffer_renderbuffer(
glow::READ_FRAMEBUFFER,
glow::COLOR_ATTACHMENT0,
glow::RENDERBUFFER,
Some(renderbuffer),
)
};
unsafe { gl.bind_renderbuffer(glow::RENDERBUFFER, None) };
unsafe { gl.bind_framebuffer(glow::READ_FRAMEBUFFER, None) };
// Setup presentation mode
let extra = Wgl::load_with(|name| load_gl_func(name, None));
let extentions = extensions(&extra, dc.device);
if !(extentions.contains("WGL_EXT_swap_control") && extra.SwapIntervalEXT.is_loaded()) {
@ -673,58 +672,7 @@ impl crate::Surface<super::Api> for Surface {
return Err(crate::SurfaceError::Other("unable to set swap interval"));
}
let surface_gl = unsafe {
glow::Context::from_loader_function(|name| {
load_gl_func(name, Some(inner.opengl_module))
})
};
// Check that the surface context OpenGL is new enough to support framebuffers.
let version = unsafe { gl.get_parameter_string(glow::VERSION) };
let version = super::Adapter::parse_full_version(&version);
match version {
Ok(version) => {
if version < (3, 0) {
log::error!(
"surface context OpenGL version ({}.{}) too old",
version.0,
version.1
);
return Err(crate::SurfaceError::Other(
"surface context OpenGL version too old",
));
}
}
Err(e) => {
log::error!("unable to parse surface context OpenGL version: {e}",);
return Err(crate::SurfaceError::Other(
"unable to parse surface context OpenGL version",
));
}
}
let framebuffer = unsafe { surface_gl.create_framebuffer() }.map_err(|error| {
log::error!("Internal swapchain framebuffer creation failed: {error}");
crate::DeviceError::OutOfMemory
})?;
unsafe { surface_gl.bind_framebuffer(glow::READ_FRAMEBUFFER, Some(framebuffer)) };
unsafe {
surface_gl.framebuffer_renderbuffer(
glow::READ_FRAMEBUFFER,
glow::COLOR_ATTACHMENT0,
glow::RENDERBUFFER,
Some(renderbuffer),
)
};
unsafe { surface_gl.bind_renderbuffer(glow::RENDERBUFFER, None) };
unsafe { surface_gl.bind_framebuffer(glow::READ_FRAMEBUFFER, None) };
unsafe { surface_gl.bind_framebuffer(glow::DRAW_FRAMEBUFFER, None) };
unsafe { surface_gl.bind_framebuffer(glow::READ_FRAMEBUFFER, Some(framebuffer)) };
self.swapchain = Some(Swapchain {
surface_context,
surface_gl,
renderbuffer,
framebuffer,
extent: config.extent,

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

@ -1097,6 +1097,8 @@ pub struct NagaShader {
pub module: Cow<'static, naga::Module>,
/// Analysis information of the module.
pub info: naga::valid::ModuleInfo,
/// Source codes for debug
pub debug_source: Option<DebugSource>,
}
// Custom implementation avoids the need to generate Debug impl code
@ -1119,6 +1121,12 @@ pub struct ShaderModuleDescriptor<'a> {
pub runtime_checks: bool,
}
#[derive(Debug, Clone)]
pub struct DebugSource {
pub file_name: Cow<'static, str>,
pub source_code: Cow<'static, str>,
}
/// Describes a programmable pipeline stage.
#[derive(Debug)]
pub struct ProgrammableStage<'a, A: Api> {

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

@ -80,7 +80,8 @@ impl Instance {
impl crate::Instance<Api> for Instance {
unsafe fn init(_desc: &crate::InstanceDescriptor) -> Result<Self, crate::InstanceError> {
//TODO: enable `METAL_DEVICE_WRAPPER_TYPE` environment based on the flags?
// We do not enable metal validation based on the validation flags as it affects the entire
// process. Instead, we enable the validation inside the test harness itself in tests/src/native.rs.
Ok(Instance {
managed_metal_layer_delegate: surface::HalManagedMetalLayerDelegate::new(),
})

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

@ -326,7 +326,8 @@ impl PhysicalDeviceFeatures {
| Df::UNRESTRICTED_INDEX_BUFFER
| Df::INDIRECT_EXECUTION
| Df::VIEW_FORMATS
| Df::UNRESTRICTED_EXTERNAL_TEXTURE_COPIES;
| Df::UNRESTRICTED_EXTERNAL_TEXTURE_COPIES
| Df::NONBLOCKING_QUERY_RESOLVE;
dl_flags.set(
Df::SURFACE_VIEW_FORMATS,

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

@ -723,7 +723,9 @@ impl super::Device {
entry_point: stage.entry_point.to_string(),
shader_stage: naga_stage,
};
let needs_temp_options = !runtime_checks || !binding_map.is_empty();
let needs_temp_options = !runtime_checks
|| !binding_map.is_empty()
|| naga_shader.debug_source.is_some();
let mut temp_options;
let options = if needs_temp_options {
temp_options = self.naga_options.clone();
@ -739,6 +741,14 @@ impl super::Device {
if !binding_map.is_empty() {
temp_options.binding_map = binding_map.clone();
}
if let Some(ref debug) = naga_shader.debug_source {
temp_options.debug_info = Some(naga::back::spv::DebugInfo {
source_code: &debug.source_code,
file_name: debug.file_name.as_ref().as_ref(),
})
}
&temp_options
} else {
&self.naga_options
@ -1513,6 +1523,14 @@ impl crate::Device<super::Api> for super::Device {
});
}
let mut naga_options = self.naga_options.clone();
naga_options.debug_info =
naga_shader
.debug_source
.as_ref()
.map(|d| naga::back::spv::DebugInfo {
source_code: d.source_code.as_ref(),
file_name: d.file_name.as_ref().as_ref(),
});
if !desc.runtime_checks {
naga_options.bounds_check_policies = naga::proc::BoundsCheckPolicies {
index: naga::proc::BoundsCheckPolicy::Unchecked,

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

@ -1 +1 @@
{"files":{"Cargo.toml":"60d11013451ea3e3d460b7548e2cc0e3d72ec0fa4d9961d4d4eda3f089bda729","LICENSE.APACHE":"a6cba85bc92e0cff7a450b1d873c0eaa2e9fc96bf472df0247a26bec77bf3ff9","LICENSE.MIT":"c7fea58d1cfe49634cd92e54fc10a9d871f4b275321a4cd8c09e449122caaeb4","src/assertions.rs":"3fe98027aa73970c8ab7874a3e13dbfd6faa87df2081beb5c83aeec4c60f372f","src/lib.rs":"b874a635584930085c801ccf8b6d6c157298d3e1df55b039d3919cfc0d2cd85b","src/math.rs":"4d03039736dd6926feb139bc68734cb59df34ede310427bbf059e5c925e0af3b"},"package":null}
{"files":{"Cargo.toml":"5740ba85d83eadf690d7571d1b3268c364eaacb311569758b8ea5ed5eeb70580","LICENSE.APACHE":"a6cba85bc92e0cff7a450b1d873c0eaa2e9fc96bf472df0247a26bec77bf3ff9","LICENSE.MIT":"c7fea58d1cfe49634cd92e54fc10a9d871f4b275321a4cd8c09e449122caaeb4","src/assertions.rs":"3fe98027aa73970c8ab7874a3e13dbfd6faa87df2081beb5c83aeec4c60f372f","src/lib.rs":"58eb04d8a2387fd87f3623f7004fb0353020aa9ff6c02aa19166788ab6b7c772","src/math.rs":"4d03039736dd6926feb139bc68734cb59df34ede310427bbf059e5c925e0af3b"},"package":null}

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

@ -13,7 +13,7 @@
edition = "2021"
rust-version = "1.65"
name = "wgpu-types"
version = "0.17.0"
version = "0.18.0"
authors = ["wgpu developers"]
description = "WebGPU types"
homepage = "https://wgpu.rs/"

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

@ -1463,6 +1463,23 @@ bitflags::bitflags! {
///
/// The GLES/WebGL and Vulkan on Android doesn't support this.
const SURFACE_VIEW_FORMATS = 1 << 21;
/// If this is true, calls to `CommandEncoder::resolve_query_set` will be performed on the queue timeline.
///
/// If this is false, calls to `CommandEncoder::resolve_query_set` will be performed on the device (i.e. cpu) timeline
/// and will block that timeline until the query has data. You may work around this limitation by waiting until the submit
/// whose queries you are resolving is fully finished (through use of `queue.on_submitted_work_done`) and only
/// then submitting the resolve_query_set command. The queries will be guarenteed finished, so will not block.
///
/// Supported by:
/// - Vulkan,
/// - DX12
/// - Metal
/// - OpenGL 4.4+
///
/// Not Supported by:
/// - GL ES / WebGL
const NONBLOCKING_QUERY_RESOLVE = 1 << 22;
}
}