Bug 1878375 - Synchronize vendored Rust libraries with mozilla-central. r=leftmostcat

mozilla-central: 0d84aa48c2d6687c0f0c4e54bd87db960c71d0fc
comm-central: 6fb59d66a6352e1d7a28f59e23a73a6bc1dac34a

Differential Revision: https://phabricator.services.mozilla.com/D209761

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Thunderbird Updatebot 2024-05-07 23:19:18 +00:00
Родитель 18c8fab9c9
Коммит d93354e048
59 изменённых файлов: 2619 добавлений и 725 удалений

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

@ -21,14 +21,9 @@ git = "https://github.com/franziskuskiefer/cose-rust"
rev = "43c22248d136c8b38fe42ea709d08da6355cf04b"
replace-with = "vendored-sources"
[source."git+https://github.com/gfx-rs/metal-rs?rev=ff8fd3d6dc7792852f8a015458d7e6d42d7fb352"]
git = "https://github.com/gfx-rs/metal-rs"
rev = "ff8fd3d6dc7792852f8a015458d7e6d42d7fb352"
replace-with = "vendored-sources"
[source."git+https://github.com/gfx-rs/wgpu?rev=d00a69615b74ef75aeb428a7c00fa1a91eb13e97"]
[source."git+https://github.com/gfx-rs/wgpu?rev=d5d683d3c491ec8cd2f5cdb43ac61e526cb7c231"]
git = "https://github.com/gfx-rs/wgpu"
rev = "d00a69615b74ef75aeb428a7c00fa1a91eb13e97"
rev = "d5d683d3c491ec8cd2f5cdb43ac61e526cb7c231"
replace-with = "vendored-sources"
[source."git+https://github.com/glandium/mio?rev=9a2ef335c366044ffe73b1c4acabe50a1daefe05"]

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

@ -1034,8 +1034,8 @@ dependencies = [
[[package]]
name = "d3d12"
version = "0.19.0"
source = "git+https://github.com/gfx-rs/wgpu?rev=d00a69615b74ef75aeb428a7c00fa1a91eb13e97#d00a69615b74ef75aeb428a7c00fa1a91eb13e97"
version = "0.20.0"
source = "git+https://github.com/gfx-rs/wgpu?rev=d5d683d3c491ec8cd2f5cdb43ac61e526cb7c231#d5d683d3c491ec8cd2f5cdb43ac61e526cb7c231"
dependencies = [
"bitflags 2.5.0",
"libloading 0.8.3",
@ -3010,8 +3010,9 @@ dependencies = [
[[package]]
name = "metal"
version = "0.27.0"
source = "git+https://github.com/gfx-rs/metal-rs?rev=ff8fd3d6dc7792852f8a015458d7e6d42d7fb352#ff8fd3d6dc7792852f8a015458d7e6d42d7fb352"
version = "0.28.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5637e166ea14be6063a3f8ba5ccb9a4159df7d8f6d61c02fc3d480b1f90dcfcb"
dependencies = [
"bitflags 2.5.0",
"block",
@ -3257,8 +3258,8 @@ checksum = "a2983372caf4480544083767bf2d27defafe32af49ab4df3a0b7fc90793a3664"
[[package]]
name = "naga"
version = "0.19.2"
source = "git+https://github.com/gfx-rs/wgpu?rev=d00a69615b74ef75aeb428a7c00fa1a91eb13e97#d00a69615b74ef75aeb428a7c00fa1a91eb13e97"
version = "0.20.0"
source = "git+https://github.com/gfx-rs/wgpu?rev=d5d683d3c491ec8cd2f5cdb43ac61e526cb7c231#d5d683d3c491ec8cd2f5cdb43ac61e526cb7c231"
dependencies = [
"arrayvec",
"bit-set",
@ -5529,14 +5530,13 @@ dependencies = [
[[package]]
name = "wgpu-core"
version = "0.19.3"
source = "git+https://github.com/gfx-rs/wgpu?rev=d00a69615b74ef75aeb428a7c00fa1a91eb13e97#d00a69615b74ef75aeb428a7c00fa1a91eb13e97"
version = "0.20.0"
source = "git+https://github.com/gfx-rs/wgpu?rev=d5d683d3c491ec8cd2f5cdb43ac61e526cb7c231#d5d683d3c491ec8cd2f5cdb43ac61e526cb7c231"
dependencies = [
"arrayvec",
"bit-vec",
"bitflags 2.5.0",
"cfg_aliases",
"codespan-reporting",
"document-features",
"indexmap 2.2.6",
"log",
@ -5556,8 +5556,8 @@ dependencies = [
[[package]]
name = "wgpu-hal"
version = "0.19.3"
source = "git+https://github.com/gfx-rs/wgpu?rev=d00a69615b74ef75aeb428a7c00fa1a91eb13e97#d00a69615b74ef75aeb428a7c00fa1a91eb13e97"
version = "0.20.0"
source = "git+https://github.com/gfx-rs/wgpu?rev=d5d683d3c491ec8cd2f5cdb43ac61e526cb7c231#d5d683d3c491ec8cd2f5cdb43ac61e526cb7c231"
dependencies = [
"android_system_properties",
"arrayvec",
@ -5595,8 +5595,8 @@ dependencies = [
[[package]]
name = "wgpu-types"
version = "0.19.2"
source = "git+https://github.com/gfx-rs/wgpu?rev=d00a69615b74ef75aeb428a7c00fa1a91eb13e97#d00a69615b74ef75aeb428a7c00fa1a91eb13e97"
version = "0.20.0"
source = "git+https://github.com/gfx-rs/wgpu?rev=d5d683d3c491ec8cd2f5cdb43ac61e526cb7c231#d5d683d3c491ec8cd2f5cdb43ac61e526cb7c231"
dependencies = [
"bitflags 2.5.0",
"js-sys",

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

@ -1 +1 @@
{"mc_workspace_toml": "69d10cf0366d47dfbdc0d2aa5887148a7868a2fcfc67ed441f8d172c7704d25788640eddacb862804bc7ac9dffae3631931bb16131a4d068434089fff8b45202", "mc_gkrust_toml": "7b85230288493ac65c5496e68dd5b14661b51bc7667784c7afd8608bccb814195ca20d8e6a29f207190024607037f6621fa527c370be69bb9e28fc1cb51a8700", "mc_cargo_lock": "1395de27388bdfba890a884d7adc1965c69edcd22c8a320106ca14a93baec8c24990342de3dca1e63f0ad3bed20acfecec14b2135ab1b5644f734f20c4db3d6d"}
{"mc_workspace_toml": "69d10cf0366d47dfbdc0d2aa5887148a7868a2fcfc67ed441f8d172c7704d25788640eddacb862804bc7ac9dffae3631931bb16131a4d068434089fff8b45202", "mc_gkrust_toml": "7b85230288493ac65c5496e68dd5b14661b51bc7667784c7afd8608bccb814195ca20d8e6a29f207190024607037f6621fa527c370be69bb9e28fc1cb51a8700", "mc_cargo_lock": "04934e849b60fe346c1d04d816c06c65eb87d611ae1f855f45ef33aec1d6466d4559b8d3881e85a0d2628e8cb12b6e61e8a267e9bb045de65940ed9a0db96197"}

2
third_party/rust/d3d12/.cargo-checksum.json поставляемый
Просмотреть файл

@ -1 +1 @@
{"files":{"CHANGELOG.md":"45fa76b0e5bc51721887147000e9e78a5934cb04d1ad628e501ef2082763d353","Cargo.toml":"a3135c67216ba021525ebc8d18dc3de5d779f1a1ddde5f25f4439acabd45824a","README.md":"76cee3209f773a62535de6c9724b53f158406359f35b4d48b17ac3747b6c102e","src/com.rs":"cfd6556a7abf38cba57559038f9f2cf86274418448fb2745436c251a99575e05","src/command_allocator.rs":"ef01059a661749470f3772d188fe0fab0f002e1d154facdab4b9b2932f4b2d93","src/command_list.rs":"8723f3b755b721e0dbb234bd604956c1b7922a2368231197495daa3fa6548e63","src/debug.rs":"aa33b98f7c3e71cba75fc42c6ca9af72d96b45122422c16e48525e24590c57bf","src/descriptor.rs":"fea0b820de1566b54d17d8d0c67e6f5a2126eda19526397eb710ff7d6db9db9e","src/device.rs":"c1dd479aabd22bced0d407523d60629ad1da439fb47ad89fe7b48bae1c4b23e5","src/dxgi.rs":"1516186845b91bf3df813a29b4a0e00a85ca5649fb7a2755da43fba984c41a42","src/heap.rs":"dae2380684896c97e97ed022929f79ce2cc4f5418a3ec34883086f7c88f423d0","src/lib.rs":"612e2f471b84502d219da3fb86ee13f3cbd6faf17d77407bab6c84e51ec424d0","src/pso.rs":"ff819c321536695e34a3be9a6051cf3e57765049a4a2035db6ab27add5a7978a","src/query.rs":"ff61a2b76a108afc1f082724bb9b07ac8b52afbe97356e0fcf6df0ff7e53e07d","src/queue.rs":"bd32813d0b8a3bedf3223b69ade9f9c799a138a9e27d970f86435d9ce32d1557","src/resource.rs":"8989cdb7c3ee0687c826047f39f85148459d9219754f20a970bf8aaa09b96e27","src/sync.rs":"5c287fb7498242a397eb1f08887be9cff9b48dc7cb13af5792cce5f7182b55f8"},"package":null}
{"files":{"CHANGELOG.md":"45fa76b0e5bc51721887147000e9e78a5934cb04d1ad628e501ef2082763d353","Cargo.toml":"9938addd7ce2c7785a9ca11eb0049271317f9b05fdf0d7330d4a80f0e07ab500","README.md":"76cee3209f773a62535de6c9724b53f158406359f35b4d48b17ac3747b6c102e","src/com.rs":"cfd6556a7abf38cba57559038f9f2cf86274418448fb2745436c251a99575e05","src/command_allocator.rs":"ef01059a661749470f3772d188fe0fab0f002e1d154facdab4b9b2932f4b2d93","src/command_list.rs":"8723f3b755b721e0dbb234bd604956c1b7922a2368231197495daa3fa6548e63","src/debug.rs":"aa33b98f7c3e71cba75fc42c6ca9af72d96b45122422c16e48525e24590c57bf","src/descriptor.rs":"fea0b820de1566b54d17d8d0c67e6f5a2126eda19526397eb710ff7d6db9db9e","src/device.rs":"c1dd479aabd22bced0d407523d60629ad1da439fb47ad89fe7b48bae1c4b23e5","src/dxgi.rs":"1516186845b91bf3df813a29b4a0e00a85ca5649fb7a2755da43fba984c41a42","src/heap.rs":"dae2380684896c97e97ed022929f79ce2cc4f5418a3ec34883086f7c88f423d0","src/lib.rs":"612e2f471b84502d219da3fb86ee13f3cbd6faf17d77407bab6c84e51ec424d0","src/pso.rs":"ff819c321536695e34a3be9a6051cf3e57765049a4a2035db6ab27add5a7978a","src/query.rs":"ff61a2b76a108afc1f082724bb9b07ac8b52afbe97356e0fcf6df0ff7e53e07d","src/queue.rs":"bd32813d0b8a3bedf3223b69ade9f9c799a138a9e27d970f86435d9ce32d1557","src/resource.rs":"8989cdb7c3ee0687c826047f39f85148459d9219754f20a970bf8aaa09b96e27","src/sync.rs":"5c287fb7498242a397eb1f08887be9cff9b48dc7cb13af5792cce5f7182b55f8"},"package":null}

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

@ -12,7 +12,7 @@
[package]
edition = "2018"
name = "d3d12"
version = "0.19.0"
version = "0.20.0"
authors = ["gfx-rs developers"]
description = "Low level D3D12 API wrapper"
documentation = "https://docs.rs/d3d12"

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

1569
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.27.0"
version = "0.28.0"
authors = ["gfx-rs developers"]
exclude = [
"guide/**/*",
@ -90,35 +90,54 @@ required-features = ["dispatch"]
[[example]]
name = "fence"
[dependencies]
bitflags = "2"
block = "0.1.6"
core-graphics-types = "0.1.3"
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.3"
[dependencies.dispatch]
version = "0.2"
optional = true
[dependencies.foreign-types]
version = "0.5"
[dependencies.log]
version = "0.4"
[dependencies.objc]
version = "0.2.4"
[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 = ["core-graphics-types/link"]
mps = []
private = []
[workspace]
members = ["examples/texture"]

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

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

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

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

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

@ -13,7 +13,7 @@
edition = "2021"
rust-version = "1.74"
name = "naga"
version = "0.19.2"
version = "0.20.0"
authors = ["gfx-rs developers"]
exclude = [
"bin/**/*",

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

@ -129,8 +129,10 @@ pub fn process_overrides<'a>(
Expression::Constant(c_h)
}
Expression::Constant(c_h) => {
adjusted_constant_initializers.insert(c_h);
module.constants[c_h].init = adjusted_global_expressions[c_h.index()];
if adjusted_constant_initializers.insert(c_h) {
let init = &mut module.constants[c_h].init;
*init = adjusted_global_expressions[init.index()];
}
expr
}
expr => expr,

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

@ -248,7 +248,7 @@ impl LocalImageType {
/// this, by converting everything possible to a `LocalType` before inspecting
/// it.
///
/// ## `Localtype` equality and SPIR-V `OpType` uniqueness
/// ## `LocalType` equality and SPIR-V `OpType` uniqueness
///
/// The definition of `Eq` on `LocalType` is carefully chosen to help us follow
/// certain SPIR-V rules. SPIR-V §2.8 requires some classes of `OpType...`

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

@ -970,6 +970,11 @@ impl Writer {
handle: Handle<crate::Type>,
) -> Result<Word, Error> {
let ty = &arena[handle];
// If it's a type that needs SPIR-V capabilities, request them now.
// This needs to happen regardless of the LocalType lookup succeeding,
// because some types which map to the same LocalType have different
// capability requirements. See https://github.com/gfx-rs/wgpu/issues/5569
self.request_type_capabilities(&ty.inner)?;
let id = if let Some(local) = make_local(&ty.inner) {
// This type can be represented as a `LocalType`, so check if we've
// already written an instruction for it. If not, do so now, with
@ -985,10 +990,6 @@ impl Writer {
self.write_type_declaration_local(id, local);
// If it's a type that needs SPIR-V capabilities, request them now,
// so write_type_declaration_local can stay infallible.
self.request_type_capabilities(&ty.inner)?;
id
}
}

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

@ -0,0 +1,74 @@
use std::{error::Error, fmt};
#[derive(Clone, Debug)]
pub struct ShaderError<E> {
/// The source code of the shader.
pub source: String,
pub label: Option<String>,
pub inner: Box<E>,
}
#[cfg(feature = "wgsl-in")]
impl fmt::Display for ShaderError<crate::front::wgsl::ParseError> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let label = self.label.as_deref().unwrap_or_default();
let string = self.inner.emit_to_string(&self.source);
write!(f, "\nShader '{label}' parsing {string}")
}
}
#[cfg(feature = "glsl-in")]
impl fmt::Display for ShaderError<crate::front::glsl::ParseErrors> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let label = self.label.as_deref().unwrap_or_default();
let string = self.inner.emit_to_string(&self.source);
write!(f, "\nShader '{label}' parsing {string}")
}
}
#[cfg(feature = "spv-in")]
impl fmt::Display for ShaderError<crate::front::spv::Error> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let label = self.label.as_deref().unwrap_or_default();
let string = self.inner.emit_to_string(&self.source);
write!(f, "\nShader '{label}' parsing {string}")
}
}
impl fmt::Display for ShaderError<crate::WithSpan<crate::valid::ValidationError>> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
use codespan_reporting::{
diagnostic::{Diagnostic, Label},
files::SimpleFile,
term,
};
let label = self.label.as_deref().unwrap_or_default();
let files = SimpleFile::new(label, &self.source);
let config = term::Config::default();
let mut writer = term::termcolor::NoColor::new(Vec::new());
let diagnostic = Diagnostic::error().with_labels(
self.inner
.spans()
.map(|&(span, ref desc)| {
Label::primary((), span.to_range().unwrap()).with_message(desc.to_owned())
})
.collect(),
);
term::emit(&mut writer, &config, &files, &diagnostic).expect("cannot write error");
write!(
f,
"\nShader validation {}",
String::from_utf8_lossy(&writer.into_inner())
)
}
}
impl<E> Error for ShaderError<E>
where
ShaderError<E>: fmt::Display,
E: Error + 'static,
{
fn source(&self) -> Option<&(dyn Error + 'static)> {
Some(&self.inner)
}
}

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

@ -1,4 +1,5 @@
use super::token::TokenValue;
use crate::SourceLocation;
use crate::{proc::ConstantEvaluatorError, Span};
use codespan_reporting::diagnostic::{Diagnostic, Label};
use codespan_reporting::files::SimpleFile;
@ -137,14 +138,21 @@ pub struct Error {
pub meta: Span,
}
impl Error {
/// Returns a [`SourceLocation`] for the error message.
pub fn location(&self, source: &str) -> Option<SourceLocation> {
Some(self.meta.location(source))
}
}
/// A collection of errors returned during shader parsing.
#[derive(Clone, Debug)]
#[cfg_attr(test, derive(PartialEq))]
pub struct ParseError {
pub struct ParseErrors {
pub errors: Vec<Error>,
}
impl ParseError {
impl ParseErrors {
pub fn emit_to_writer(&self, writer: &mut impl WriteColor, source: &str) {
self.emit_to_writer_with_path(writer, source, "glsl");
}
@ -172,19 +180,19 @@ impl ParseError {
}
}
impl std::fmt::Display for ParseError {
impl std::fmt::Display for ParseErrors {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
self.errors.iter().try_for_each(|e| write!(f, "{e:?}"))
}
}
impl std::error::Error for ParseError {
impl std::error::Error for ParseErrors {
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
None
}
}
impl From<Vec<Error>> for ParseError {
impl From<Vec<Error>> for ParseErrors {
fn from(errors: Vec<Error>) -> Self {
Self { errors }
}

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

@ -13,7 +13,7 @@ To begin, take a look at the documentation for the [`Frontend`].
*/
pub use ast::{Precision, Profile};
pub use error::{Error, ErrorKind, ExpectedToken, ParseError};
pub use error::{Error, ErrorKind, ExpectedToken, ParseErrors};
pub use token::TokenValue;
use crate::{proc::Layouter, FastHashMap, FastHashSet, Handle, Module, ShaderStage, Span, Type};
@ -196,7 +196,7 @@ impl Frontend {
&mut self,
options: &Options,
source: &str,
) -> std::result::Result<Module, ParseError> {
) -> std::result::Result<Module, ParseErrors> {
self.reset(options.stage);
let lexer = lex::Lexer::new(source, &options.defines);

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

@ -1,7 +1,7 @@
use super::{
ast::Profile,
error::ExpectedToken,
error::{Error, ErrorKind, ParseError},
error::{Error, ErrorKind, ParseErrors},
token::TokenValue,
Frontend, Options, Span,
};
@ -21,7 +21,7 @@ fn version() {
)
.err()
.unwrap(),
ParseError {
ParseErrors {
errors: vec![Error {
kind: ErrorKind::InvalidVersion(99000),
meta: Span::new(9, 14)
@ -37,7 +37,7 @@ fn version() {
)
.err()
.unwrap(),
ParseError {
ParseErrors {
errors: vec![Error {
kind: ErrorKind::InvalidVersion(449),
meta: Span::new(9, 12)
@ -53,7 +53,7 @@ fn version() {
)
.err()
.unwrap(),
ParseError {
ParseErrors {
errors: vec![Error {
kind: ErrorKind::InvalidProfile("smart".into()),
meta: Span::new(13, 18),
@ -69,7 +69,7 @@ fn version() {
)
.err()
.unwrap(),
ParseError {
ParseErrors {
errors: vec![
Error {
kind: ErrorKind::PreprocessorError(PreprocessorError::UnexpectedHash,),
@ -455,7 +455,7 @@ fn functions() {
)
.err()
.unwrap(),
ParseError {
ParseErrors {
errors: vec![Error {
kind: ErrorKind::SemanticError("Function already defined".into()),
meta: Span::new(134, 152),
@ -634,7 +634,7 @@ fn implicit_conversions() {
)
.err()
.unwrap(),
ParseError {
ParseErrors {
errors: vec![Error {
kind: ErrorKind::SemanticError("Unknown function \'test\'".into()),
meta: Span::new(156, 165),
@ -658,7 +658,7 @@ fn implicit_conversions() {
)
.err()
.unwrap(),
ParseError {
ParseErrors {
errors: vec![Error {
kind: ErrorKind::SemanticError("Ambiguous best function for \'test\'".into()),
meta: Span::new(158, 165),

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

@ -5,7 +5,7 @@ use codespan_reporting::files::SimpleFile;
use codespan_reporting::term;
use termcolor::{NoColor, WriteColor};
#[derive(Debug, thiserror::Error)]
#[derive(Clone, Debug, thiserror::Error)]
pub enum Error {
#[error("invalid header")]
InvalidHeader,

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

@ -13,6 +13,7 @@ use thiserror::Error;
#[derive(Clone, Debug)]
pub struct ParseError {
message: String,
// The first span should be the primary span, and the other ones should be complementary.
labels: Vec<(Span, Cow<'static, str>)>,
notes: Vec<String>,
}

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

@ -274,6 +274,7 @@ pub mod back;
mod block;
#[cfg(feature = "compact")]
pub mod compact;
pub mod error;
pub mod front;
pub mod keywords;
pub mod proc;

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

@ -950,10 +950,10 @@ impl<'a> ConstantEvaluator<'a> {
pattern: [crate::SwizzleComponent; 4],
) -> Result<Handle<Expression>, ConstantEvaluatorError> {
let mut get_dst_ty = |ty| match self.types[ty].inner {
crate::TypeInner::Vector { size: _, scalar } => Ok(self.types.insert(
TypeInner::Vector { size: _, scalar } => Ok(self.types.insert(
Type {
name: None,
inner: crate::TypeInner::Vector { size, scalar },
inner: TypeInner::Vector { size, scalar },
},
span,
)),
@ -1244,13 +1244,11 @@ impl<'a> ConstantEvaluator<'a> {
Expression::ZeroValue(ty) | Expression::Compose { ty, .. } => {
match self.types[ty].inner {
TypeInner::Array { size, .. } => match size {
crate::ArraySize::Constant(len) => {
ArraySize::Constant(len) => {
let expr = Expression::Literal(Literal::U32(len.get()));
self.register_evaluated_expr(expr, span)
}
crate::ArraySize::Dynamic => {
Err(ConstantEvaluatorError::ArrayLengthDynamic)
}
ArraySize::Dynamic => Err(ConstantEvaluatorError::ArrayLengthDynamic),
},
_ => Err(ConstantEvaluatorError::InvalidArrayLengthArg),
}
@ -1313,7 +1311,7 @@ impl<'a> ConstantEvaluator<'a> {
Expression::ZeroValue(ty)
if matches!(
self.types[ty].inner,
crate::TypeInner::Scalar(crate::Scalar {
TypeInner::Scalar(crate::Scalar {
kind: ScalarKind::Uint,
..
})
@ -1628,7 +1626,7 @@ impl<'a> ConstantEvaluator<'a> {
return self.cast(expr, target, span);
};
let crate::TypeInner::Array {
let TypeInner::Array {
base: _,
size,
stride: _,

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

@ -239,7 +239,7 @@ pub enum GuardedIndex {
pub fn find_checked_indexes(
module: &crate::Module,
function: &crate::Function,
info: &crate::valid::FunctionInfo,
info: &valid::FunctionInfo,
policies: BoundsCheckPolicies,
) -> BitSet {
use crate::Expression as Ex;
@ -321,7 +321,7 @@ pub fn access_needs_check(
mut index: GuardedIndex,
module: &crate::Module,
function: &crate::Function,
info: &crate::valid::FunctionInfo,
info: &valid::FunctionInfo,
) -> Option<IndexableLength> {
let base_inner = info[base].ty.inner_with(&module.types);
// Unwrap safety: `Err` here indicates unindexable base types and invalid

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

@ -72,8 +72,8 @@ impl Span {
pub fn location(&self, source: &str) -> SourceLocation {
let prefix = &source[..self.start as usize];
let line_number = prefix.matches('\n').count() as u32 + 1;
let line_start = prefix.rfind('\n').map(|pos| pos + 1).unwrap_or(0);
let line_position = source[line_start..self.start as usize].chars().count() as u32 + 1;
let line_start = prefix.rfind('\n').map(|pos| pos + 1).unwrap_or(0) as u32;
let line_position = self.start - line_start + 1;
SourceLocation {
line_number,
@ -107,14 +107,14 @@ impl std::ops::Index<Span> for str {
/// Roughly corresponds to the positional members of [`GPUCompilationMessage`][gcm] from
/// the WebGPU specification, except
/// - `offset` and `length` are in bytes (UTF-8 code units), instead of UTF-16 code units.
/// - `line_position` counts entire Unicode code points, instead of UTF-16 code units.
/// - `line_position` is in bytes (UTF-8 code units), instead of UTF-16 code units.
///
/// [gcm]: https://www.w3.org/TR/webgpu/#gpucompilationmessage
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub struct SourceLocation {
/// 1-based line number.
pub line_number: u32,
/// 1-based column of the start of this span, counted in Unicode code points.
/// 1-based column in code units (in bytes) of the start of the span.
pub line_position: u32,
/// 0-based Offset in code units (in bytes) of the start of the span.
pub offset: u32,
@ -136,7 +136,7 @@ impl<E> fmt::Display for WithSpan<E>
where
E: fmt::Display,
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> std::fmt::Result {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
self.inner.fmt(f)
}
}
@ -304,7 +304,7 @@ impl<E> WithSpan<E> {
use term::termcolor::NoColor;
let files = files::SimpleFile::new(path, source);
let config = codespan_reporting::term::Config::default();
let config = term::Config::default();
let mut writer = NoColor::new(Vec::new());
term::emit(&mut writer, &config, &files, &self.diagnostic()).expect("cannot write error");
String::from_utf8(writer.into_inner()).unwrap()

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

@ -835,7 +835,7 @@ impl FunctionInfo {
let req = self.expressions[expr.index()].uniformity.requirements;
if self
.flags
.contains(super::ValidationFlags::CONTROL_FLOW_UNIFORMITY)
.contains(ValidationFlags::CONTROL_FLOW_UNIFORMITY)
&& !req.is_empty()
{
if let Some(cause) = disruptor {

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

@ -194,7 +194,7 @@ impl super::Validator {
use crate::Expression as E;
if !global_expr_kind.is_const_or_override(handle) {
return Err(super::ConstExpressionError::NonConstOrOverride);
return Err(ConstExpressionError::NonConstOrOverride);
}
match gctx.global_expressions[handle] {
@ -211,10 +211,10 @@ impl super::Validator {
}
E::Splat { value, .. } => match *mod_info[value].inner_with(gctx.types) {
crate::TypeInner::Scalar { .. } => {}
_ => return Err(super::ConstExpressionError::InvalidSplatType(value)),
_ => return Err(ConstExpressionError::InvalidSplatType(value)),
},
_ if global_expr_kind.is_const(handle) || !self.allow_overrides => {
return Err(super::ConstExpressionError::NonFullyEvaluatedConst)
return Err(ConstExpressionError::NonFullyEvaluatedConst)
}
// the constant evaluator will report errors about override-expressions
_ => {}

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

@ -1 +1 @@
{"files":{"Cargo.toml":"e8335a4d3544795505ee88baaeba2d8974250deed141053b58c9bfcd8ee3b178","LICENSE.APACHE":"a6cba85bc92e0cff7a450b1d873c0eaa2e9fc96bf472df0247a26bec77bf3ff9","LICENSE.MIT":"c7fea58d1cfe49634cd92e54fc10a9d871f4b275321a4cd8c09e449122caaeb4","build.rs":"a99478d7f63fb41429e3834f4d0e5cd333f94ba1834c68295f929170e16987de","src/binding_model.rs":"f1279d3cd1f84eab37dc85658f32bb4b4f2687c9086f4b4f30e8a4b0d7c1a582","src/command/allocator.rs":"5ca1e40a735f7cb0531d3e5298767963a3c0ee9e264b44d3a356cd7ef16bcb52","src/command/bind.rs":"a37f042484b65d9fdea4cdab3667381623ee9a8943a6d32683d410b92736d306","src/command/bundle.rs":"1c7fceda77668ae5a055bf1d0184b78cc7362f7763d6b6a3c9d1687e4782f908","src/command/clear.rs":"1eb475a48e04a011be381720a420047a3d65fc85be3b9b55e6874c7fd14e40a8","src/command/compute.rs":"7a58ff8f492dc8926ab8cd580c7ae8bf8703df4472f093f4a027f4969f55b0f9","src/command/compute_command.rs":"b00623d80e9aa3bb78c1d8d24ccbc0cbd6f945ef3c9206b8fba5c3ce86753f5e","src/command/draw.rs":"15f9ad857504d8098279f9c789317feba321c9b6b8f0de20b8ba98f358c99d89","src/command/memory_init.rs":"71550dabbf7cc3c3ff6aa4ccd31af080bb5e1cb1e21422daea63fee30294476f","src/command/mod.rs":"947c0dc1e82301e5571579031f0b1b0627d1f6d9c8d3b5e510c37673ea661fc1","src/command/query.rs":"92b5aff8580631c51bc1ba72a45605e704c997684fc6a891640da945712db5ec","src/command/render.rs":"0d529644fe35bfb66aefe2e62ddd2c45adc620c5d5154abf7660e4b1f370fcee","src/command/transfer.rs":"d0324465a5637e8346276a0427446377c21acbb285ff819091673ba5fc365a9c","src/conv.rs":"7e3ffe33b47a6fd3617aabf9f11cc68f1ccbee2c7343b8dbbcd0e8f3447e1ad8","src/device/any_device.rs":"65f47b58939b60f88f47861e65d5d45209492df8e73e7c1b60b3b459f510c09e","src/device/bgl.rs":"f1c372cd632deacb9d0f0880846844c7cbe5f1ca88592ed35dbd59966958b33d","src/device/global.rs":"791faa82517e5eef501d7d77128d8cfaa2b99536b85c2e1c06739e97a3ff391c","src/device/life.rs":"a1d6a62c058b4626c9ed8c20c7bf8dacefe03bbf568e1fc0757fb7914bb07d40","src/device/mod.rs":"aa16ac918714c844820142b4d321ac4e9a51ffef37501c6f5ca48e3817353d16","src/device/queue.rs":"2c8f0a7c39f4b050526c895aa53fb1417c64ea7c018ff1a44c2c7715a77c6c1d","src/device/resource.rs":"207e823354c0077402838c7531bc9fcec75638474d2a870ab4333ffabaa15de2","src/device/trace.rs":"9deb1b083165e07253b4928ac2f564aba06f9089c3aca1c0a1d438d87d981542","src/error.rs":"e3b6b7a69877437f4e46af7f0e8ca1db1822beae7c8448db41c2bae0f64b2bb4","src/global.rs":"fe1ddd4863d50568780bf04382a4fd0d3d8441dd7baff9dacf57e860811b87c9","src/hal_api.rs":"fb65bfab0334cb8b0bbe823b1da6d1e82cd4a312c60a332ce65df9fbc2f74482","src/hash_utils.rs":"e8d484027c7ce81978e4679a5e20af9416ab7d2fa595f1ca95992b29d625b0ca","src/hub.rs":"59aeb5c902fd6707f651994fc9e335a6e7fdd998faebd29c087171e226101405","src/id.rs":"23634dec36eb171cb95c672519e69705d466044dcea29028b58d2288de35f8db","src/identity.rs":"b27d4e06b1f6c25ca2f4ad276fdf8c09a5d71f890b06cbabef7ef62369cb4df6","src/init_tracker/buffer.rs":"61eb9cfaa312135b7a937ff6a3117f531b5b7323fae6553a41d6de9bc106d7e0","src/init_tracker/mod.rs":"a0f64730cc025113b656b4690f9dcb0ec18b8770bc7ef24c7b4ad8bebae03d24","src/init_tracker/texture.rs":"030fd594bf9948fad391390d85c5e1fec7eaf67b6e812c60f2dd59bc4fda8fd5","src/instance.rs":"d4c46ff5d0cc13b09c7b364d6445d30eaf7ea6f50ac9d49b0022b3a6e9377445","src/lib.rs":"77ec01c43b6f5daab174e0831bd98771a708cdfd42b0203f45490b6977ef2923","src/lock/mod.rs":"d7ae9e2dda2d6f6732abe5ce784300708945d911697893522997bb04141decf8","src/lock/rank.rs":"cebf4d1063e2c0bee5015ffaf147f20d108ef4786d9a30acd315b7d0585a3abe","src/lock/ranked.rs":"783283c6152465f555778c51fda0e0c8df84d3e5dedce2fa6d5142dd7a3109c2","src/lock/vanilla.rs":"6db2fbc41ef4abae4700df33e28e74160bce4ea59fad2887d0613e6d5769444d","src/pipeline.rs":"c7a70b5c6323bcedf7cb0ad431a1f22c2d797084ccf5247f015ba398f821e6e3","src/pool.rs":"7899e74874da17c83ec39a88b360de12f564ef4bee2bb1240c37becdaeb57a86","src/present.rs":"a0142445b0ccaebdd097f24f063df9d8306583dbe2e434c8b478a706a89de4d3","src/registry.rs":"1a65f9a3b2a23476a5fa2f0a826d690853c29b80b512e364fbb8374a31999dcf","src/resource.rs":"90d36c359cec532f5955bd3a60dd59fc9754bf27c08e9099a08010c1ea984322","src/snatch.rs":"d5f3d512ae1148c0d63bb9161e643e97ae3097675cb9c75e72635ec55e650c15","src/storage.rs":"0c5a8a732e33ea565528b3a02e7a6c15178bc8dbc49a9cedcd76f8ebb1039b48","src/track/buffer.rs":"8571ebd57302ab9aba4aef4a310a02fe0848485f57ac3a7197393fbfbaddff2e","src/track/metadata.rs":"4b85341adc3b725e326dec0fe691f7e8e6c4e7c0a1ada1d86dd72a0a0b6397e6","src/track/mod.rs":"4d4ebbec98f4d2148767b34240b813d2b2978b52006100f69f71a90e0b584564","src/track/range.rs":"2a15794e79b0470d5ba6b3267173a42f34312878e1cb288f198d2854a7888e53","src/track/stateless.rs":"b49192d248434570c024078cf204ad47f9030ed7a541324bad525881b78f75a4","src/track/texture.rs":"f962f97b582d4b528483f09df8662484159b6f5d19b376de53462d411421cee5","src/validation.rs":"1433e035d656afda97ee047b3247cb1a63844360174d575acf52cac868e27a3c"},"package":null}
{"files":{"Cargo.toml":"ef0dc61297a9dd672d3e0e71ced2973a97f0abdb705432816874867ec4dc873b","LICENSE.APACHE":"a6cba85bc92e0cff7a450b1d873c0eaa2e9fc96bf472df0247a26bec77bf3ff9","LICENSE.MIT":"c7fea58d1cfe49634cd92e54fc10a9d871f4b275321a4cd8c09e449122caaeb4","build.rs":"a99478d7f63fb41429e3834f4d0e5cd333f94ba1834c68295f929170e16987de","src/binding_model.rs":"f1279d3cd1f84eab37dc85658f32bb4b4f2687c9086f4b4f30e8a4b0d7c1a582","src/command/allocator.rs":"5ca1e40a735f7cb0531d3e5298767963a3c0ee9e264b44d3a356cd7ef16bcb52","src/command/bind.rs":"a37f042484b65d9fdea4cdab3667381623ee9a8943a6d32683d410b92736d306","src/command/bundle.rs":"1c7fceda77668ae5a055bf1d0184b78cc7362f7763d6b6a3c9d1687e4782f908","src/command/clear.rs":"1eb475a48e04a011be381720a420047a3d65fc85be3b9b55e6874c7fd14e40a8","src/command/compute.rs":"7a58ff8f492dc8926ab8cd580c7ae8bf8703df4472f093f4a027f4969f55b0f9","src/command/compute_command.rs":"b00623d80e9aa3bb78c1d8d24ccbc0cbd6f945ef3c9206b8fba5c3ce86753f5e","src/command/draw.rs":"15f9ad857504d8098279f9c789317feba321c9b6b8f0de20b8ba98f358c99d89","src/command/memory_init.rs":"71550dabbf7cc3c3ff6aa4ccd31af080bb5e1cb1e21422daea63fee30294476f","src/command/mod.rs":"947c0dc1e82301e5571579031f0b1b0627d1f6d9c8d3b5e510c37673ea661fc1","src/command/query.rs":"92b5aff8580631c51bc1ba72a45605e704c997684fc6a891640da945712db5ec","src/command/render.rs":"6d02d9a9f0c1e58a448cbd30e62e51dca5b8b61e576ece15655c343cc51e84b9","src/command/transfer.rs":"d0324465a5637e8346276a0427446377c21acbb285ff819091673ba5fc365a9c","src/conv.rs":"7e3ffe33b47a6fd3617aabf9f11cc68f1ccbee2c7343b8dbbcd0e8f3447e1ad8","src/device/any_device.rs":"8802f6d9d7fa9cd0b02c5ed57412a2ef01b9ad2b47182e18a914ce4ad5e24fde","src/device/bgl.rs":"f1c372cd632deacb9d0f0880846844c7cbe5f1ca88592ed35dbd59966958b33d","src/device/global.rs":"1881c6729b86423a4ab75db1ae0e3d6a8d34ab4600f3cd5e38bf8768d07b6905","src/device/life.rs":"a65cab56e0eb688d0776e719da785372a742d6a87bd3f3bef9042e9428453c3a","src/device/mod.rs":"aa16ac918714c844820142b4d321ac4e9a51ffef37501c6f5ca48e3817353d16","src/device/queue.rs":"33cc4bb3337d49810dc74bfc2eb8ad97a82023ad263d80700c769d0c0ad9bfe4","src/device/resource.rs":"b0a55d496ca59056854d5d41264f519992b342a4049d1b65a13220d8a76902a1","src/device/trace.rs":"9deb1b083165e07253b4928ac2f564aba06f9089c3aca1c0a1d438d87d981542","src/error.rs":"e3b6b7a69877437f4e46af7f0e8ca1db1822beae7c8448db41c2bae0f64b2bb4","src/global.rs":"fe1ddd4863d50568780bf04382a4fd0d3d8441dd7baff9dacf57e860811b87c9","src/hal_api.rs":"fb65bfab0334cb8b0bbe823b1da6d1e82cd4a312c60a332ce65df9fbc2f74482","src/hash_utils.rs":"e8d484027c7ce81978e4679a5e20af9416ab7d2fa595f1ca95992b29d625b0ca","src/hub.rs":"59aeb5c902fd6707f651994fc9e335a6e7fdd998faebd29c087171e226101405","src/id.rs":"23634dec36eb171cb95c672519e69705d466044dcea29028b58d2288de35f8db","src/identity.rs":"b27d4e06b1f6c25ca2f4ad276fdf8c09a5d71f890b06cbabef7ef62369cb4df6","src/init_tracker/buffer.rs":"61eb9cfaa312135b7a937ff6a3117f531b5b7323fae6553a41d6de9bc106d7e0","src/init_tracker/mod.rs":"a0f64730cc025113b656b4690f9dcb0ec18b8770bc7ef24c7b4ad8bebae03d24","src/init_tracker/texture.rs":"030fd594bf9948fad391390d85c5e1fec7eaf67b6e812c60f2dd59bc4fda8fd5","src/instance.rs":"d4c46ff5d0cc13b09c7b364d6445d30eaf7ea6f50ac9d49b0022b3a6e9377445","src/lib.rs":"77ec01c43b6f5daab174e0831bd98771a708cdfd42b0203f45490b6977ef2923","src/lock/mod.rs":"c7069f05341f1c63f478ed9176f4fbd1a6f633ea71f124c3b4d6c1b02d1febe8","src/lock/rank.rs":"acc3ef80c39297a440a53ec33e437be7fbb56a4bb09e326cfeb3d4bf76f60ac8","src/lock/ranked.rs":"94c2d929b54bc4ea68258bb4d58b692b61accc394dd48dbab5e69f1bdafaeb56","src/lock/vanilla.rs":"a6cd5cc3c1900271783ba146adf07e28424f6fecc5466d54624dbda237770fb4","src/pipeline.rs":"033335a759b801de7c606baf3f2ac8c706b1bbe27b209bcca73093569b604c0e","src/pool.rs":"7899e74874da17c83ec39a88b360de12f564ef4bee2bb1240c37becdaeb57a86","src/present.rs":"1147399ff3a62b69c944001639cd1cf19295e13cf0ddd3850b2736afdb0720b4","src/registry.rs":"1104d6972dad982c6cc6dfd25cbc52d0b8279d7989525d78ed49551434fa3cea","src/resource.rs":"ce469bbd6ae54efb989770b04079ee1a9c248b95f31ad5dae79603f87574878d","src/snatch.rs":"f9849b1050adba708c1b9be5a21ce806c83eef71c4f79b513768918f857fe814","src/storage.rs":"0c5a8a732e33ea565528b3a02e7a6c15178bc8dbc49a9cedcd76f8ebb1039b48","src/track/buffer.rs":"8571ebd57302ab9aba4aef4a310a02fe0848485f57ac3a7197393fbfbaddff2e","src/track/metadata.rs":"4b85341adc3b725e326dec0fe691f7e8e6c4e7c0a1ada1d86dd72a0a0b6397e6","src/track/mod.rs":"0056f0299fa71cc3acca9aa6becba15e0845b8e9000a11780d0b78da2ee01beb","src/track/range.rs":"2a15794e79b0470d5ba6b3267173a42f34312878e1cb288f198d2854a7888e53","src/track/stateless.rs":"b49192d248434570c024078cf204ad47f9030ed7a541324bad525881b78f75a4","src/track/texture.rs":"f962f97b582d4b528483f09df8662484159b6f5d19b376de53462d411421cee5","src/validation.rs":"1433e035d656afda97ee047b3247cb1a63844360174d575acf52cac868e27a3c"},"package":null}

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

@ -13,7 +13,7 @@
edition = "2021"
rust-version = "1.74"
name = "wgpu-core"
version = "0.19.3"
version = "0.20.0"
authors = ["gfx-rs developers"]
description = "WebGPU core logic on wgpu-hal"
homepage = "https://wgpu.rs/"
@ -40,7 +40,6 @@ targets = [
arrayvec = "0.7"
bit-vec = "0.6"
bitflags = "2"
codespan-reporting = "0.11"
document-features = "0.2.8"
indexmap = "2"
log = "0.4"
@ -55,13 +54,13 @@ version = "1.14"
optional = true
[dependencies.hal]
version = "0.19.3"
version = "0.20.0"
path = "../wgpu-hal"
default_features = false
package = "wgpu-hal"
[dependencies.naga]
version = "0.19.2"
version = "0.20.0"
path = "../naga"
[dependencies.profiling]
@ -82,7 +81,7 @@ features = ["serde_derive"]
optional = true
[dependencies.wgt]
version = "0.19.2"
version = "0.20.0"
path = "../wgpu-types"
package = "wgpu-types"

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

@ -2468,10 +2468,6 @@ pub mod render_commands {
use std::{convert::TryInto, num::NonZeroU32};
use wgt::{BufferAddress, BufferSize, Color, DynamicOffset, IndexFormat};
/// # Safety
///
/// This function is unsafe as there is no guarantee that the given pointer is
/// valid for `offset_length` elements.
pub fn wgpu_render_pass_set_bind_group(
pass: &mut RenderPass,
index: u32,
@ -2571,10 +2567,6 @@ pub mod render_commands {
.push(RenderCommand::SetScissor(Rect { x, y, w, h }));
}
/// # Safety
///
/// This function is unsafe as there is no guarantee that the given pointer is
/// valid for `size_bytes` bytes.
pub fn wgpu_render_pass_set_push_constants(
pass: &mut RenderPass,
stages: wgt::ShaderStages,

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

@ -34,7 +34,7 @@ impl AnyDevice {
unsafe fn drop_glue<A: HalApi>(ptr: *mut ()) {
// Drop the arc this instance is holding.
unsafe {
_ = Arc::from_raw(ptr.cast::<A::Surface>());
_ = Arc::from_raw(ptr.cast::<A::Device>());
}
}

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

@ -11,6 +11,7 @@ use crate::{
id::{self, AdapterId, DeviceId, QueueId, SurfaceId},
init_tracker::TextureInitTracker,
instance::{self, Adapter, Surface},
lock::{rank, RwLock},
pipeline, present,
resource::{self, BufferAccessResult},
resource::{BufferAccessError, BufferMapOperation, CreateBufferError, Resource},
@ -20,7 +21,6 @@ use crate::{
use arrayvec::ArrayVec;
use hal::Device as _;
use parking_lot::RwLock;
use wgt::{BufferAddress, TextureFormat};
@ -643,8 +643,10 @@ impl Global {
texture.hal_usage |= hal::TextureUses::COPY_DST;
}
texture.initialization_status =
RwLock::new(TextureInitTracker::new(desc.mip_level_count, 0));
texture.initialization_status = RwLock::new(
rank::TEXTURE_INITIALIZATION_STATUS,
TextureInitTracker::new(desc.mip_level_count, 0),
);
let (id, resource) = fid.assign(Arc::new(texture));
api_log!("Device::create_texture({desc:?}) -> {id:?}");
@ -2031,7 +2033,6 @@ impl Global {
// Wait for all work to finish before configuring the surface.
let snatch_guard = device.snatchable_lock.read();
let fence = device.fence.read();
let fence = fence.as_ref().unwrap();
match device.maintain(fence, wgt::Maintain::Wait, snatch_guard) {
Ok((closures, _)) => {
user_callbacks = closures;
@ -2144,7 +2145,6 @@ impl Global {
) -> Result<DevicePoll, WaitIdleError> {
let snatch_guard = device.snatchable_lock.read();
let fence = device.fence.read();
let fence = fence.as_ref().unwrap();
let (closures, queue_empty) = device.maintain(fence, maintain, snatch_guard)?;
// Some deferred destroys are scheduled in maintain so run this right after

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

@ -93,7 +93,7 @@ impl<A: HalApi> ResourceMaps<A> {
destroyed_textures.clear();
}
pub(crate) fn extend(&mut self, mut other: Self) {
pub(crate) fn extend(&mut self, other: &mut Self) {
let ResourceMaps {
buffers,
staging_buffers,
@ -596,6 +596,18 @@ impl<A: HalApi> LifetimeTracker<A> {
&mut trackers.textures,
|maps| &mut maps.textures,
);
// We may have been suspected because a texture view or bind group
// referring to us was dropped. Remove stale weak references, so that
// the backlink table doesn't grow without bound.
for texture in self.suspected_resources.textures.values() {
texture.views.lock().retain(|view| view.strong_count() > 0);
texture
.bind_groups
.lock()
.retain(|bg| bg.strong_count() > 0);
}
self
}
@ -621,6 +633,13 @@ impl<A: HalApi> LifetimeTracker<A> {
|maps| &mut maps.buffers,
);
// We may have been suspected because a bind group referring to us was
// dropped. Remove stale weak references, so that the backlink table
// doesn't grow without bound.
for buffer in self.suspected_resources.buffers.values() {
buffer.bind_groups.lock().retain(|bg| bg.strong_count() > 0);
}
self
}

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

@ -7,14 +7,14 @@ use crate::{
ClearError, CommandAllocator, CommandBuffer, CopySide, ImageCopyTexture, TransferError,
},
conv,
device::{life::ResourceMaps, DeviceError, WaitIdleError},
device::{DeviceError, WaitIdleError},
get_lowest_common_denom,
global::Global,
hal_api::HalApi,
hal_label,
id::{self, DeviceId, QueueId},
init_tracker::{has_copy_partial_init_tracker_coverage, TextureInitRange},
lock::{rank, Mutex},
lock::{rank, Mutex, RwLockWriteGuard},
resource::{
Buffer, BufferAccessError, BufferMapState, DestroyedBuffer, DestroyedTexture, Resource,
ResourceInfo, ResourceType, StagingBuffer, Texture, TextureInner,
@ -1162,8 +1162,8 @@ impl Global {
let snatch_guard = device.snatchable_lock.read();
// Fence lock must be acquired after the snatch lock everywhere to avoid deadlocks.
let mut fence = device.fence.write();
let fence = fence.as_mut().unwrap();
let mut fence_guard = device.fence.write();
let fence = fence_guard.as_mut().unwrap();
let submit_index = device
.active_submission_index
.fetch_add(1, Ordering::Relaxed)
@ -1183,11 +1183,6 @@ impl Global {
//TODO: if multiple command buffers are submitted, we can re-use the last
// native command buffer of the previous chain instead of always creating
// a temporary one, since the chains are not finished.
let mut temp_suspected = device.temp_suspected.lock();
{
let mut suspected = temp_suspected.replace(ResourceMaps::new()).unwrap();
suspected.clear();
}
// finish all the command buffers first
for &cmb_id in command_buffer_ids {
@ -1235,41 +1230,23 @@ impl Global {
// update submission IDs
for buffer in cmd_buf_trackers.buffers.used_resources() {
let tracker_index = buffer.info.tracker_index();
let raw_buf = match buffer.raw.get(&snatch_guard) {
Some(raw) => raw,
None => {
return Err(QueueSubmitError::DestroyedBuffer(
buffer.info.id(),
));
}
};
if buffer.raw.get(&snatch_guard).is_none() {
return Err(QueueSubmitError::DestroyedBuffer(
buffer.info.id(),
));
}
buffer.info.use_at(submit_index);
if buffer.is_unique() {
if let BufferMapState::Active { .. } = *buffer.map_state.lock()
{
log::warn!("Dropped buffer has a pending mapping.");
unsafe { device.raw().unmap_buffer(raw_buf) }
.map_err(DeviceError::from)?;
}
temp_suspected
.as_mut()
.unwrap()
.buffers
.insert(tracker_index, buffer.clone());
} else {
match *buffer.map_state.lock() {
BufferMapState::Idle => (),
_ => {
return Err(QueueSubmitError::BufferStillMapped(
buffer.info.id(),
))
}
match *buffer.map_state.lock() {
BufferMapState::Idle => (),
_ => {
return Err(QueueSubmitError::BufferStillMapped(
buffer.info.id(),
))
}
}
}
for texture in cmd_buf_trackers.textures.used_resources() {
let tracker_index = texture.info.tracker_index();
let should_extend = match texture.inner.get(&snatch_guard) {
None => {
return Err(QueueSubmitError::DestroyedTexture(
@ -1286,13 +1263,6 @@ impl Global {
}
};
texture.info.use_at(submit_index);
if texture.is_unique() {
temp_suspected
.as_mut()
.unwrap()
.textures
.insert(tracker_index, texture.clone());
}
if should_extend {
unsafe {
used_surface_textures
@ -1303,12 +1273,6 @@ impl Global {
}
for texture_view in cmd_buf_trackers.views.used_resources() {
texture_view.info.use_at(submit_index);
if texture_view.is_unique() {
temp_suspected.as_mut().unwrap().texture_views.insert(
texture_view.as_info().tracker_index(),
texture_view.clone(),
);
}
}
{
for bg in cmd_buf_trackers.bind_groups.used_resources() {
@ -1322,13 +1286,6 @@ impl Global {
for sampler in bg.used.samplers.used_resources() {
sampler.info.use_at(submit_index);
}
if bg.is_unique() {
temp_suspected
.as_mut()
.unwrap()
.bind_groups
.insert(bg.as_info().tracker_index(), bg.clone());
}
}
}
// assert!(cmd_buf_trackers.samplers.is_empty());
@ -1336,32 +1293,14 @@ impl Global {
cmd_buf_trackers.compute_pipelines.used_resources()
{
compute_pipeline.info.use_at(submit_index);
if compute_pipeline.is_unique() {
temp_suspected.as_mut().unwrap().compute_pipelines.insert(
compute_pipeline.as_info().tracker_index(),
compute_pipeline.clone(),
);
}
}
for render_pipeline in
cmd_buf_trackers.render_pipelines.used_resources()
{
render_pipeline.info.use_at(submit_index);
if render_pipeline.is_unique() {
temp_suspected.as_mut().unwrap().render_pipelines.insert(
render_pipeline.as_info().tracker_index(),
render_pipeline.clone(),
);
}
}
for query_set in cmd_buf_trackers.query_sets.used_resources() {
query_set.info.use_at(submit_index);
if query_set.is_unique() {
temp_suspected.as_mut().unwrap().query_sets.insert(
query_set.as_info().tracker_index(),
query_set.clone(),
);
}
}
for bundle in cmd_buf_trackers.bundles.used_resources() {
bundle.info.use_at(submit_index);
@ -1376,13 +1315,6 @@ impl Global {
for query_set in bundle.used.query_sets.read().used_resources() {
query_set.info.use_at(submit_index);
}
if bundle.is_unique() {
temp_suspected
.as_mut()
.unwrap()
.render_bundles
.insert(bundle.as_info().tracker_index(), bundle.clone());
}
}
}
let mut baked = cmdbuf.from_arc_into_baked();
@ -1459,8 +1391,8 @@ impl Global {
}
}
let mut pending_writes = device.pending_writes.lock();
let pending_writes = pending_writes.as_mut().unwrap();
let mut pending_writes_guard = device.pending_writes.lock();
let pending_writes = pending_writes_guard.as_mut().unwrap();
{
used_surface_textures.set_size(hub.textures.read().len());
@ -1550,18 +1482,22 @@ impl Global {
active_executions,
);
// This will schedule destruction of all resources that are no longer needed
// by the user but used in the command stream, among other things.
let (closures, _) = match device.maintain(fence, wgt::Maintain::Poll, snatch_guard) {
Ok(closures) => closures,
Err(WaitIdleError::Device(err)) => return Err(QueueSubmitError::Queue(err)),
Err(WaitIdleError::StuckGpu) => return Err(QueueSubmitError::StuckGpu),
Err(WaitIdleError::WrongSubmissionIndex(..)) => unreachable!(),
};
// pending_write_resources has been drained, so it's empty, but we
// want to retain its heap allocation.
pending_writes.temp_resources = pending_write_resources;
drop(pending_writes_guard);
// This will schedule destruction of all resources that are no longer needed
// by the user but used in the command stream, among other things.
let fence_guard = RwLockWriteGuard::downgrade(fence_guard);
let (closures, _) =
match device.maintain(fence_guard, wgt::Maintain::Poll, snatch_guard) {
Ok(closures) => closures,
Err(WaitIdleError::Device(err)) => return Err(QueueSubmitError::Queue(err)),
Err(WaitIdleError::StuckGpu) => return Err(QueueSubmitError::StuckGpu),
Err(WaitIdleError::WrongSubmissionIndex(..)) => unreachable!(),
};
device.lock_life().post_submit();
(submit_index, closures)

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

@ -13,13 +13,14 @@ use crate::{
hal_api::HalApi,
hal_label,
hub::Hub,
id,
init_tracker::{
BufferInitTracker, BufferInitTrackerAction, MemoryInitKind, TextureInitRange,
TextureInitTracker, TextureInitTrackerAction,
},
instance::Adapter,
lock::{rank, Mutex, MutexGuard},
pipeline,
lock::{rank, Mutex, MutexGuard, RwLock},
pipeline::{self},
pool::ResourcePool,
registry::Registry,
resource::{
@ -42,7 +43,6 @@ use crate::{
use arrayvec::ArrayVec;
use hal::{CommandEncoder as _, Device as _};
use once_cell::sync::OnceCell;
use parking_lot::RwLock;
use smallvec::SmallVec;
use thiserror::Error;
@ -127,9 +127,6 @@ pub struct Device<A: HalApi> {
pub(crate) tracker_indices: TrackerIndexAllocators,
// Life tracker should be locked right after the device and before anything else.
life_tracker: Mutex<LifetimeTracker<A>>,
/// Temporary storage for resource management functions. Cleared at the end
/// of every call (unless an error occurs).
pub(crate) temp_suspected: Mutex<Option<ResourceMaps<A>>>,
/// Pool of bind group layouts, allowing deduplication.
pub(crate) bgl_pool: ResourcePool<bgl::EntryMap, BindGroupLayout<A>>,
pub(crate) alignments: hal::Alignments,
@ -142,6 +139,10 @@ pub struct Device<A: HalApi> {
#[cfg(feature = "trace")]
pub(crate) trace: Mutex<Option<trace::Trace>>,
pub(crate) usage_scopes: UsageScopePool<A>,
/// Temporary storage, cleared at the start of every call,
/// retained only to save allocations.
temp_suspected: Mutex<Option<ResourceMaps<A>>>,
}
pub(crate) enum DeferredDestroy<A: HalApi> {
@ -272,8 +273,8 @@ impl<A: HalApi> Device<A> {
info: ResourceInfo::new("<device>", None),
command_allocator,
active_submission_index: AtomicU64::new(0),
fence: RwLock::new(Some(fence)),
snatchable_lock: unsafe { SnatchLock::new() },
fence: RwLock::new(rank::DEVICE_FENCE, Some(fence)),
snatchable_lock: unsafe { SnatchLock::new(rank::DEVICE_SNATCHABLE_LOCK) },
valid: AtomicBool::new(true),
trackers: Mutex::new(rank::DEVICE_TRACKERS, Tracker::new()),
tracker_indices: TrackerIndexAllocators::new(),
@ -397,11 +398,12 @@ impl<A: HalApi> Device<A> {
/// return it to our callers.)
pub(crate) fn maintain<'this>(
&'this self,
fence: &A::Fence,
fence_guard: crate::lock::RwLockReadGuard<Option<A::Fence>>,
maintain: wgt::Maintain<queue::WrappedSubmissionIndex>,
snatch_guard: SnatchGuard,
) -> Result<(UserClosures, bool), WaitIdleError> {
profiling::scope!("Device::maintain");
let fence = fence_guard.as_ref().unwrap();
let last_done_index = if maintain.is_wait() {
let index_to_wait_for = match maintain {
wgt::Maintain::WaitForSubmissionIndex(submission_index) => {
@ -433,23 +435,9 @@ impl<A: HalApi> Device<A> {
let submission_closures =
life_tracker.triage_submissions(last_done_index, &self.command_allocator);
{
// Normally, `temp_suspected` exists only to save heap
// allocations: it's cleared at the start of the function
// call, and cleared by the end. But `Global::queue_submit` is
// fallible; if it exits early, it may leave some resources in
// `temp_suspected`.
let temp_suspected = self
.temp_suspected
.lock()
.replace(ResourceMaps::new())
.unwrap();
life_tracker.triage_suspected(&self.trackers);
life_tracker.suspected_resources.extend(temp_suspected);
life_tracker.triage_suspected(&self.trackers);
life_tracker.triage_mapped();
}
life_tracker.triage_mapped();
let mapping_closures =
life_tracker.handle_mapping(self.raw(), &self.trackers, &snatch_guard);
@ -481,6 +469,7 @@ impl<A: HalApi> Device<A> {
// Don't hold the locks while calling release_gpu_resources.
drop(life_tracker);
drop(fence_guard);
drop(snatch_guard);
if should_release_gpu_resource {
@ -496,12 +485,14 @@ impl<A: HalApi> Device<A> {
}
pub(crate) fn untrack(&self, trackers: &Tracker<A>) {
// If we have a previously allocated `ResourceMap`, just use that.
let mut temp_suspected = self
.temp_suspected
.lock()
.replace(ResourceMaps::new())
.unwrap();
.take()
.unwrap_or_else(|| ResourceMaps::new());
temp_suspected.clear();
// As the tracker is cleared/dropped, we need to consider all the resources
// that it references for destruction in the next GC pass.
{
@ -562,7 +553,11 @@ impl<A: HalApi> Device<A> {
}
}
}
self.lock_life().suspected_resources.extend(temp_suspected);
self.lock_life()
.suspected_resources
.extend(&mut temp_suspected);
// Save this resource map for later reuse.
*self.temp_suspected.lock() = Some(temp_suspected);
}
pub(crate) fn create_buffer(
@ -656,7 +651,10 @@ impl<A: HalApi> Device<A> {
device: self.clone(),
usage: desc.usage,
size: desc.size,
initialization_status: RwLock::new(BufferInitTracker::new(aligned_size)),
initialization_status: RwLock::new(
rank::BUFFER_INITIALIZATION_STATUS,
BufferInitTracker::new(aligned_size),
),
sync_mapped_writes: Mutex::new(rank::BUFFER_SYNC_MAPPED_WRITES, None),
map_state: Mutex::new(rank::BUFFER_MAP_STATE, resource::BufferMapState::Idle),
info: ResourceInfo::new(
@ -683,10 +681,10 @@ impl<A: HalApi> Device<A> {
desc: desc.map_label(|_| ()),
hal_usage,
format_features,
initialization_status: RwLock::new(TextureInitTracker::new(
desc.mip_level_count,
desc.array_layer_count(),
)),
initialization_status: RwLock::new(
rank::TEXTURE_INITIALIZATION_STATUS,
TextureInitTracker::new(desc.mip_level_count, desc.array_layer_count()),
),
full_range: TextureSelector {
mips: 0..desc.mip_level_count,
layers: 0..desc.array_layer_count(),
@ -695,7 +693,7 @@ impl<A: HalApi> Device<A> {
desc.label.borrow_or_default(),
Some(self.tracker_indices.textures.clone()),
),
clear_mode: RwLock::new(clear_mode),
clear_mode: RwLock::new(rank::TEXTURE_CLEAR_MODE, clear_mode),
views: Mutex::new(rank::TEXTURE_VIEWS, Vec::new()),
bind_groups: Mutex::new(rank::TEXTURE_BIND_GROUPS, Vec::new()),
}
@ -713,7 +711,10 @@ impl<A: HalApi> Device<A> {
device: self.clone(),
usage: desc.usage,
size: desc.size,
initialization_status: RwLock::new(BufferInitTracker::new(0)),
initialization_status: RwLock::new(
rank::BUFFER_INITIALIZATION_STATUS,
BufferInitTracker::new(0),
),
sync_mapped_writes: Mutex::new(rank::BUFFER_SYNC_MAPPED_WRITES, None),
map_state: Mutex::new(rank::BUFFER_MAP_STATE, resource::BufferMapState::Idle),
info: ResourceInfo::new(
@ -1424,7 +1425,7 @@ impl<A: HalApi> Device<A> {
pipeline::ShaderModuleSource::Wgsl(code) => {
profiling::scope!("naga::front::wgsl::parse_str");
let module = naga::front::wgsl::parse_str(&code).map_err(|inner| {
pipeline::CreateShaderModuleError::Parsing(pipeline::ShaderError {
pipeline::CreateShaderModuleError::Parsing(naga::error::ShaderError {
source: code.to_string(),
label: desc.label.as_ref().map(|l| l.to_string()),
inner: Box::new(inner),
@ -1437,7 +1438,7 @@ impl<A: HalApi> Device<A> {
let parser = naga::front::spv::Frontend::new(spv.iter().cloned(), &options);
profiling::scope!("naga::front::spv::Frontend");
let module = parser.parse().map_err(|inner| {
pipeline::CreateShaderModuleError::ParsingSpirV(pipeline::ShaderError {
pipeline::CreateShaderModuleError::ParsingSpirV(naga::error::ShaderError {
source: String::new(),
label: desc.label.as_ref().map(|l| l.to_string()),
inner: Box::new(inner),
@ -1450,7 +1451,7 @@ impl<A: HalApi> Device<A> {
let mut parser = naga::front::glsl::Frontend::default();
profiling::scope!("naga::front::glsl::Frontend.parse");
let module = parser.parse(&options, &code).map_err(|inner| {
pipeline::CreateShaderModuleError::ParsingGlsl(pipeline::ShaderError {
pipeline::CreateShaderModuleError::ParsingGlsl(naga::error::ShaderError {
source: code.to_string(),
label: desc.label.as_ref().map(|l| l.to_string()),
inner: Box::new(inner),
@ -1474,9 +1475,78 @@ impl<A: HalApi> Device<A> {
};
}
use naga::valid::Capabilities as Caps;
profiling::scope!("naga::validate");
let debug_source =
if self.instance_flags.contains(wgt::InstanceFlags::DEBUG) && !source.is_empty() {
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 = self
.create_validator(naga::valid::ValidationFlags::all())
.validate(&module)
.map_err(|inner| {
pipeline::CreateShaderModuleError::Validation(naga::error::ShaderError {
source,
label: desc.label.as_ref().map(|l| l.to_string()),
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,
debug_source,
});
let hal_desc = hal::ShaderModuleDescriptor {
label: desc.label.to_hal(self.instance_flags),
runtime_checks: desc.shader_bound_checks.runtime_checks(),
};
let raw = match unsafe {
self.raw
.as_ref()
.unwrap()
.create_shader_module(&hal_desc, hal_shader)
} {
Ok(raw) => raw,
Err(error) => {
return Err(match error {
hal::ShaderError::Device(error) => {
pipeline::CreateShaderModuleError::Device(error.into())
}
hal::ShaderError::Compilation(ref msg) => {
log::error!("Shader error: {}", msg);
pipeline::CreateShaderModuleError::Generation
}
})
}
};
Ok(pipeline::ShaderModule {
raw: Some(raw),
device: self.clone(),
interface: Some(interface),
info: ResourceInfo::new(desc.label.borrow_or_default(), None),
label: desc.label.borrow_or_default().to_string(),
})
}
/// Create a validator with the given validation flags.
pub fn create_validator(
self: &Arc<Self>,
flags: naga::valid::ValidationFlags,
) -> naga::valid::Validator {
use naga::valid::Capabilities as Caps;
let mut caps = Caps::empty();
caps.set(
Caps::PUSH_CONSTANT,
@ -1554,20 +1624,6 @@ impl<A: HalApi> Device<A> {
self.features.intersects(wgt::Features::SUBGROUP_BARRIER),
);
let debug_source =
if self.instance_flags.contains(wgt::InstanceFlags::DEBUG) && !source.is_empty() {
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 mut subgroup_stages = naga::valid::ShaderStages::empty();
subgroup_stages.set(
naga::valid::ShaderStages::COMPUTE | naga::valid::ShaderStages::FRAGMENT,
@ -1584,57 +1640,10 @@ impl<A: HalApi> Device<A> {
} else {
naga::valid::SubgroupOperationSet::empty()
};
let info = naga::valid::Validator::new(naga::valid::ValidationFlags::all(), caps)
.subgroup_stages(subgroup_stages)
.subgroup_operations(subgroup_operations)
.validate(&module)
.map_err(|inner| {
pipeline::CreateShaderModuleError::Validation(pipeline::ShaderError {
source,
label: desc.label.as_ref().map(|l| l.to_string()),
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,
debug_source,
});
let hal_desc = hal::ShaderModuleDescriptor {
label: desc.label.to_hal(self.instance_flags),
runtime_checks: desc.shader_bound_checks.runtime_checks(),
};
let raw = match unsafe {
self.raw
.as_ref()
.unwrap()
.create_shader_module(&hal_desc, hal_shader)
} {
Ok(raw) => raw,
Err(error) => {
return Err(match error {
hal::ShaderError::Device(error) => {
pipeline::CreateShaderModuleError::Device(error.into())
}
hal::ShaderError::Compilation(ref msg) => {
log::error!("Shader error: {}", msg);
pipeline::CreateShaderModuleError::Generation
}
})
}
};
Ok(pipeline::ShaderModule {
raw: Some(raw),
device: self.clone(),
interface: Some(interface),
info: ResourceInfo::new(desc.label.borrow_or_default(), None),
label: desc.label.borrow_or_default().to_string(),
})
let mut validator = naga::valid::Validator::new(flags, caps);
validator.subgroup_stages(subgroup_stages);
validator.subgroup_operations(subgroup_operations);
validator
}
#[allow(unused_unsafe)]
@ -1944,6 +1953,7 @@ impl<A: HalApi> Device<A> {
used: &mut BindGroupStates<A>,
storage: &'a Storage<Buffer<A>>,
limits: &wgt::Limits,
device_id: id::Id<id::markers::Device>,
snatch_guard: &'a SnatchGuard<'a>,
) -> Result<hal::BufferBinding<'a, A>, binding_model::CreateBindGroupError> {
use crate::binding_model::CreateBindGroupError as Error;
@ -1962,6 +1972,7 @@ impl<A: HalApi> Device<A> {
})
}
};
let (pub_usage, internal_use, range_limit) = match binding_ty {
wgt::BufferBindingType::Uniform => (
wgt::BufferUsages::UNIFORM,
@ -1994,6 +2005,10 @@ impl<A: HalApi> Device<A> {
.add_single(storage, bb.buffer_id, internal_use)
.ok_or(Error::InvalidBuffer(bb.buffer_id))?;
if buffer.device.as_info().id() != device_id {
return Err(DeviceError::WrongDevice.into());
}
check_buffer_usage(bb.buffer_id, buffer.usage, pub_usage)?;
let raw_buffer = buffer
.raw
@ -2072,13 +2087,53 @@ impl<A: HalApi> Device<A> {
})
}
pub(crate) fn create_texture_binding(
view: &TextureView<A>,
internal_use: hal::TextureUses,
pub_usage: wgt::TextureUsages,
fn create_sampler_binding<'a>(
used: &BindGroupStates<A>,
storage: &'a Storage<Sampler<A>>,
id: id::Id<id::markers::Sampler>,
device_id: id::Id<id::markers::Device>,
) -> Result<&'a Sampler<A>, binding_model::CreateBindGroupError> {
use crate::binding_model::CreateBindGroupError as Error;
let sampler = used
.samplers
.add_single(storage, id)
.ok_or(Error::InvalidSampler(id))?;
if sampler.device.as_info().id() != device_id {
return Err(DeviceError::WrongDevice.into());
}
Ok(sampler)
}
pub(crate) fn create_texture_binding<'a>(
self: &Arc<Self>,
binding: u32,
decl: &wgt::BindGroupLayoutEntry,
storage: &'a Storage<TextureView<A>>,
id: id::Id<id::markers::TextureView>,
used: &mut BindGroupStates<A>,
used_texture_ranges: &mut Vec<TextureInitTrackerAction<A>>,
) -> Result<(), binding_model::CreateBindGroupError> {
snatch_guard: &'a SnatchGuard<'a>,
) -> Result<hal::TextureBinding<'a, A>, binding_model::CreateBindGroupError> {
use crate::binding_model::CreateBindGroupError as Error;
let view = used
.views
.add_single(storage, id)
.ok_or(Error::InvalidTextureView(id))?;
if view.device.as_info().id() != self.as_info().id() {
return Err(DeviceError::WrongDevice.into());
}
let (pub_usage, internal_use) = self.texture_use_parameters(
binding,
decl,
view,
"SampledTexture, ReadonlyStorageTexture or WriteonlyStorageTexture",
)?;
let texture = &view.parent;
let texture_id = texture.as_info().id();
// Careful here: the texture may no longer have its own ref count,
@ -2108,7 +2163,12 @@ impl<A: HalApi> Device<A> {
kind: MemoryInitKind::NeedsInitializedMemory,
});
Ok(())
Ok(hal::TextureBinding {
view: view
.raw(snatch_guard)
.ok_or(Error::InvalidTextureView(id))?,
usage: internal_use,
})
}
// This function expects the provided bind group layout to be resolved
@ -2170,6 +2230,7 @@ impl<A: HalApi> Device<A> {
&mut used,
&*buffer_guard,
&self.limits,
self.as_info().id(),
&snatch_guard,
)?;
@ -2193,105 +2254,86 @@ impl<A: HalApi> Device<A> {
&mut used,
&*buffer_guard,
&self.limits,
self.as_info().id(),
&snatch_guard,
)?;
hal_buffers.push(bb);
}
(res_index, num_bindings)
}
Br::Sampler(id) => {
match decl.ty {
wgt::BindingType::Sampler(ty) => {
let sampler = used
.samplers
.add_single(&*sampler_guard, id)
.ok_or(Error::InvalidSampler(id))?;
Br::Sampler(id) => match decl.ty {
wgt::BindingType::Sampler(ty) => {
let sampler = Self::create_sampler_binding(
&used,
&sampler_guard,
id,
self.as_info().id(),
)?;
if sampler.device.as_info().id() != self.as_info().id() {
return Err(DeviceError::WrongDevice.into());
}
// Allowed sampler values for filtering and comparison
let (allowed_filtering, allowed_comparison) = match ty {
wgt::SamplerBindingType::Filtering => (None, false),
wgt::SamplerBindingType::NonFiltering => (Some(false), false),
wgt::SamplerBindingType::Comparison => (None, true),
};
if let Some(allowed_filtering) = allowed_filtering {
if allowed_filtering != sampler.filtering {
return Err(Error::WrongSamplerFiltering {
binding,
layout_flt: allowed_filtering,
sampler_flt: sampler.filtering,
});
}
}
if allowed_comparison != sampler.comparison {
return Err(Error::WrongSamplerComparison {
let (allowed_filtering, allowed_comparison) = match ty {
wgt::SamplerBindingType::Filtering => (None, false),
wgt::SamplerBindingType::NonFiltering => (Some(false), false),
wgt::SamplerBindingType::Comparison => (None, true),
};
if let Some(allowed_filtering) = allowed_filtering {
if allowed_filtering != sampler.filtering {
return Err(Error::WrongSamplerFiltering {
binding,
layout_cmp: allowed_comparison,
sampler_cmp: sampler.comparison,
layout_flt: allowed_filtering,
sampler_flt: sampler.filtering,
});
}
let res_index = hal_samplers.len();
hal_samplers.push(sampler.raw());
(res_index, 1)
}
_ => {
return Err(Error::WrongBindingType {
if allowed_comparison != sampler.comparison {
return Err(Error::WrongSamplerComparison {
binding,
actual: decl.ty,
expected: "Sampler",
})
layout_cmp: allowed_comparison,
sampler_cmp: sampler.comparison,
});
}
let res_index = hal_samplers.len();
hal_samplers.push(sampler.raw());
(res_index, 1)
}
}
_ => {
return Err(Error::WrongBindingType {
binding,
actual: decl.ty,
expected: "Sampler",
})
}
},
Br::SamplerArray(ref bindings_array) => {
let num_bindings = bindings_array.len();
Self::check_array_binding(self.features, decl.count, num_bindings)?;
let res_index = hal_samplers.len();
for &id in bindings_array.iter() {
let sampler = used
.samplers
.add_single(&*sampler_guard, id)
.ok_or(Error::InvalidSampler(id))?;
if sampler.device.as_info().id() != self.as_info().id() {
return Err(DeviceError::WrongDevice.into());
}
let sampler = Self::create_sampler_binding(
&used,
&sampler_guard,
id,
self.as_info().id(),
)?;
hal_samplers.push(sampler.raw());
}
(res_index, num_bindings)
}
Br::TextureView(id) => {
let view = used
.views
.add_single(&*texture_view_guard, id)
.ok_or(Error::InvalidTextureView(id))?;
let (pub_usage, internal_use) = self.texture_use_parameters(
let tb = self.create_texture_binding(
binding,
decl,
view,
"SampledTexture, ReadonlyStorageTexture or WriteonlyStorageTexture",
)?;
Self::create_texture_binding(
view,
internal_use,
pub_usage,
&texture_view_guard,
id,
&mut used,
&mut used_texture_ranges,
&snatch_guard,
)?;
let res_index = hal_textures.len();
hal_textures.push(hal::TextureBinding {
view: view
.raw(&snatch_guard)
.ok_or(Error::InvalidTextureView(id))?,
usage: internal_use,
});
hal_textures.push(tb);
(res_index, 1)
}
Br::TextureViewArray(ref bindings_array) => {
@ -2300,26 +2342,17 @@ impl<A: HalApi> Device<A> {
let res_index = hal_textures.len();
for &id in bindings_array.iter() {
let view = used
.views
.add_single(&*texture_view_guard, id)
.ok_or(Error::InvalidTextureView(id))?;
let (pub_usage, internal_use) =
self.texture_use_parameters(binding, decl, view,
"SampledTextureArray, ReadonlyStorageTextureArray or WriteonlyStorageTextureArray")?;
Self::create_texture_binding(
view,
internal_use,
pub_usage,
let tb = self.create_texture_binding(
binding,
decl,
&texture_view_guard,
id,
&mut used,
&mut used_texture_ranges,
&snatch_guard,
)?;
hal_textures.push(hal::TextureBinding {
view: view
.raw(&snatch_guard)
.ok_or(Error::InvalidTextureView(id))?,
usage: internal_use,
});
hal_textures.push(tb);
}
(res_index, num_bindings)

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

@ -35,7 +35,7 @@ mod ranked;
mod vanilla;
#[cfg(wgpu_validate_locks)]
pub use ranked::{Mutex, MutexGuard};
pub use ranked::{Mutex, MutexGuard, RwLock, RwLockReadGuard, RwLockWriteGuard};
#[cfg(not(wgpu_validate_locks))]
pub use vanilla::{Mutex, MutexGuard};
pub use vanilla::{Mutex, MutexGuard, RwLock, RwLockReadGuard, RwLockWriteGuard};

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

@ -45,7 +45,7 @@ macro_rules! define_lock_ranks {
{
$(
$( #[ $attr:meta ] )*
rank $name:ident $member:literal followed by { $( $follower:ident ),* $(,)? };
rank $name:ident $member:literal followed by { $( $follower:ident ),* $(,)? }
)*
} => {
// An enum that assigns a unique number to each rank.
@ -55,9 +55,9 @@ macro_rules! define_lock_ranks {
bitflags::bitflags! {
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
/// A bitflags type representing a set of lock ranks.
pub struct LockRankSet: u32 {
pub struct LockRankSet: u64 {
$(
const $name = 1 << (LockRankNumber:: $name as u32);
const $name = 1 << (LockRankNumber:: $name as u64);
)*
}
}
@ -87,57 +87,84 @@ macro_rules! define_lock_ranks {
}
define_lock_ranks! {
rank DEVICE_TEMP_SUSPECTED "Device::temp_suspected" followed by {
SHARED_TRACKER_INDEX_ALLOCATOR_INNER,
COMMAND_BUFFER_DATA,
DEVICE_TRACKERS,
}
rank COMMAND_BUFFER_DATA "CommandBuffer::data" followed by {
DEVICE_SNATCHABLE_LOCK,
DEVICE_USAGE_SCOPES,
SHARED_TRACKER_INDEX_ALLOCATOR_INNER,
BUFFER_BIND_GROUP_STATE_BUFFERS,
TEXTURE_BIND_GROUP_STATE_TEXTURES,
BUFFER_MAP_STATE,
STATELESS_BIND_GROUP_STATE_RESOURCES,
};
rank STAGING_BUFFER_RAW "StagingBuffer::raw" followed by { };
rank COMMAND_ALLOCATOR_FREE_ENCODERS "CommandAllocator::free_encoders" followed by {
}
rank DEVICE_SNATCHABLE_LOCK "Device::snatchable_lock" followed by {
SHARED_TRACKER_INDEX_ALLOCATOR_INNER,
};
rank DEVICE_TRACKERS "Device::trackers" followed by { };
rank DEVICE_LIFE_TRACKER "Device::life_tracker" followed by {
COMMAND_ALLOCATOR_FREE_ENCODERS,
DEVICE_TRACE,
BUFFER_MAP_STATE,
BUFFER_BIND_GROUP_STATE_BUFFERS,
TEXTURE_BIND_GROUP_STATE_TEXTURES,
STATELESS_BIND_GROUP_STATE_RESOURCES,
// Uncomment this to see an interesting cycle.
// DEVICE_TEMP_SUSPECTED,
};
rank DEVICE_TEMP_SUSPECTED "Device::temp_suspected" followed by {
// COMMAND_BUFFER_DATA,
}
rank BUFFER_MAP_STATE "Buffer::map_state" followed by {
DEVICE_PENDING_WRITES,
SHARED_TRACKER_INDEX_ALLOCATOR_INNER,
COMMAND_BUFFER_DATA,
DEVICE_TRACKERS,
};
DEVICE_TRACE,
}
rank DEVICE_PENDING_WRITES "Device::pending_writes" followed by {
COMMAND_ALLOCATOR_FREE_ENCODERS,
SHARED_TRACKER_INDEX_ALLOCATOR_INNER,
DEVICE_LIFE_TRACKER,
};
rank DEVICE_DEFERRED_DESTROY "Device::deferred_destroy" followed by { };
}
rank DEVICE_LIFE_TRACKER "Device::life_tracker" followed by {
COMMAND_ALLOCATOR_FREE_ENCODERS,
// Uncomment this to see an interesting cycle.
// DEVICE_TEMP_SUSPECTED,
DEVICE_TRACE,
}
rank COMMAND_ALLOCATOR_FREE_ENCODERS "CommandAllocator::free_encoders" followed by {
SHARED_TRACKER_INDEX_ALLOCATOR_INNER,
}
rank BUFFER_BIND_GROUPS "Buffer::bind_groups" followed by { }
rank BUFFER_BIND_GROUP_STATE_BUFFERS "BufferBindGroupState::buffers" followed by { }
rank BUFFER_INITIALIZATION_STATUS "Buffer::initialization_status" followed by { }
rank BUFFER_SYNC_MAPPED_WRITES "Buffer::sync_mapped_writes" followed by { }
rank DEVICE_DEFERRED_DESTROY "Device::deferred_destroy" followed by { }
rank DEVICE_FENCE "Device::fence" followed by { }
#[allow(dead_code)]
rank DEVICE_TRACE "Device::trace" followed by { };
rank DEVICE_USAGE_SCOPES "Device::usage_scopes" followed by { };
rank BUFFER_SYNC_MAPPED_WRITES "Buffer::sync_mapped_writes" followed by { };
rank BUFFER_MAP_STATE "Buffer::map_state" followed by { DEVICE_PENDING_WRITES };
rank BUFFER_BIND_GROUPS "Buffer::bind_groups" followed by { };
rank TEXTURE_VIEWS "Texture::views" followed by { };
rank TEXTURE_BIND_GROUPS "Texture::bind_groups" followed by { };
rank IDENTITY_MANAGER_VALUES "IdentityManager::values" followed by { };
rank RESOURCE_POOL_INNER "ResourcePool::inner" followed by { };
rank BUFFER_BIND_GROUP_STATE_BUFFERS "BufferBindGroupState::buffers" followed by { };
rank STATELESS_BIND_GROUP_STATE_RESOURCES "StatelessBindGroupState::resources" followed by { };
rank TEXTURE_BIND_GROUP_STATE_TEXTURES "TextureBindGroupState::textures" followed by { };
rank SHARED_TRACKER_INDEX_ALLOCATOR_INNER "SharedTrackerIndexAllocator::inner" followed by { };
rank SURFACE_PRESENTATION "Surface::presentation" followed by { };
rank DEVICE_TRACE "Device::trace" followed by { }
rank DEVICE_TRACKERS "Device::trackers" followed by { }
rank DEVICE_USAGE_SCOPES "Device::usage_scopes" followed by { }
rank IDENTITY_MANAGER_VALUES "IdentityManager::values" followed by { }
rank REGISTRY_STORAGE "Registry::storage" followed by { }
rank RENDER_BUNDLE_SCOPE_BUFFERS "RenderBundleScope::buffers" followed by { }
rank RENDER_BUNDLE_SCOPE_TEXTURES "RenderBundleScope::textures" followed by { }
rank RENDER_BUNDLE_SCOPE_BIND_GROUPS "RenderBundleScope::bind_groups" followed by { }
rank RENDER_BUNDLE_SCOPE_RENDER_PIPELINES "RenderBundleScope::render_pipelines" followed by { }
rank RENDER_BUNDLE_SCOPE_QUERY_SETS "RenderBundleScope::query_sets" followed by { }
rank RESOURCE_POOL_INNER "ResourcePool::inner" followed by { }
rank SHARED_TRACKER_INDEX_ALLOCATOR_INNER "SharedTrackerIndexAllocator::inner" followed by { }
rank STAGING_BUFFER_RAW "StagingBuffer::raw" followed by { }
rank STATELESS_BIND_GROUP_STATE_RESOURCES "StatelessBindGroupState::resources" followed by { }
rank SURFACE_PRESENTATION "Surface::presentation" followed by { }
rank TEXTURE_BIND_GROUPS "Texture::bind_groups" followed by { }
rank TEXTURE_BIND_GROUP_STATE_TEXTURES "TextureBindGroupState::textures" followed by { }
rank TEXTURE_INITIALIZATION_STATUS "Texture::initialization_status" followed by { }
rank TEXTURE_CLEAR_MODE "Texture::clear_mode" followed by { }
rank TEXTURE_VIEWS "Texture::views" followed by { }
#[cfg(test)]
rank PAWN "pawn" followed by { ROOK, BISHOP };
rank PAWN "pawn" followed by { ROOK, BISHOP }
#[cfg(test)]
rank ROOK "rook" followed by { KNIGHT };
rank ROOK "rook" followed by { KNIGHT }
#[cfg(test)]
rank KNIGHT "knight" followed by { };
rank KNIGHT "knight" followed by { }
#[cfg(test)]
rank BISHOP "bishop" followed by { };
rank BISHOP "bishop" followed by { }
}

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

@ -1,8 +1,8 @@
//! Lock types that enforce well-ranked lock acquisition order.
//!
//! This module's [`Mutex`] type is instrumented to check that `wgpu-core`
//! acquires locks according to their rank, to prevent deadlocks. To use it,
//! put `--cfg wgpu_validate_locks` in `RUSTFLAGS`.
//! This module's [`Mutex`] and [`RwLock` types are instrumented to check that
//! `wgpu-core` acquires locks according to their rank, to prevent deadlocks. To
//! use it, put `--cfg wgpu_validate_locks` in `RUSTFLAGS`.
//!
//! The [`LockRank`] constants in the [`lock::rank`] module describe edges in a
//! directed graph of lock acquisitions: each lock's rank says, if this is the most
@ -81,7 +81,11 @@ pub struct Mutex<T> {
/// [mod]: crate::lock::ranked
pub struct MutexGuard<'a, T> {
inner: parking_lot::MutexGuard<'a, T>,
saved: LockState,
saved: LockStateGuard,
}
thread_local! {
static LOCK_STATE: Cell<LockState> = const { Cell::new(LockState::INITIAL) };
}
/// Per-thread state for the deadlock checker.
@ -103,8 +107,77 @@ impl LockState {
};
}
/// A container that restores a [`LockState`] when dropped.
///
/// This type serves two purposes:
///
/// - Operations like `RwLockWriteGuard::downgrade` would like to be able to
/// destructure lock guards and reassemble their pieces into new guards, but
/// if the guard type itself implements `Drop`, we can't destructure it
/// without unsafe code or pointless `Option`s whose state is almost always
/// statically known.
///
/// - We can just implement `Drop` for this type once, and then use it in lock
/// guards, rather than implementing `Drop` separately for each guard type.
struct LockStateGuard(LockState);
impl Drop for LockStateGuard {
fn drop(&mut self) {
release(self.0)
}
}
/// Check and record the acquisition of a lock with `new_rank`.
///
/// Check that acquiring a lock with `new_rank` is permitted at this point, and
/// update the per-thread state accordingly.
///
/// Return the `LockState` that must be restored when this thread is released.
fn acquire(new_rank: LockRank, location: &'static Location<'static>) -> LockState {
let state = LOCK_STATE.get();
// Initially, it's fine to acquire any lock. So we only
// need to check when `last_acquired` is `Some`.
if let Some((ref last_rank, ref last_location)) = state.last_acquired {
assert!(
last_rank.followers.contains(new_rank.bit),
"Attempt to acquire nested mutexes in wrong order:\n\
last locked {:<35} at {}\n\
now locking {:<35} at {}\n\
Locking {} after locking {} is not permitted.",
last_rank.bit.name(),
last_location,
new_rank.bit.name(),
location,
new_rank.bit.name(),
last_rank.bit.name(),
);
}
LOCK_STATE.set(LockState {
last_acquired: Some((new_rank, location)),
depth: state.depth + 1,
});
state
}
/// Record the release of a lock whose saved state was `saved`.
///
/// Check that locks are being acquired in stacking order, and update the
/// per-thread state accordingly.
fn release(saved: LockState) {
let prior = LOCK_STATE.replace(saved);
// Although Rust allows mutex guards to be dropped in any
// order, this analysis requires that locks be acquired and
// released in stack order: the next lock to be released must be
// the most recently acquired lock still held.
assert_eq!(
prior.depth,
saved.depth + 1,
"Lock not released in stacking order"
);
}
impl<T> Mutex<T> {
#[inline]
pub fn new(rank: LockRank, value: T) -> Mutex<T> {
Mutex {
inner: parking_lot::Mutex::new(value),
@ -112,59 +185,16 @@ impl<T> Mutex<T> {
}
}
#[inline]
#[track_caller]
pub fn lock(&self) -> MutexGuard<T> {
let state = LOCK_STATE.get();
let location = Location::caller();
// Initially, it's fine to acquire any lock. So we only
// need to check when `last_acquired` is `Some`.
if let Some((ref last_rank, ref last_location)) = state.last_acquired {
assert!(
last_rank.followers.contains(self.rank.bit),
"Attempt to acquire nested mutexes in wrong order:\n\
last locked {:<35} at {}\n\
now locking {:<35} at {}\n\
Locking {} after locking {} is not permitted.",
last_rank.bit.name(),
last_location,
self.rank.bit.name(),
location,
self.rank.bit.name(),
last_rank.bit.name(),
);
}
LOCK_STATE.set(LockState {
last_acquired: Some((self.rank, location)),
depth: state.depth + 1,
});
let saved = acquire(self.rank, Location::caller());
MutexGuard {
inner: self.inner.lock(),
saved: state,
saved: LockStateGuard(saved),
}
}
}
impl<'a, T> Drop for MutexGuard<'a, T> {
fn drop(&mut self) {
let prior = LOCK_STATE.replace(self.saved);
// Although Rust allows mutex guards to be dropped in any
// order, this analysis requires that locks be acquired and
// released in stack order: the next lock to be released must be
// the most recently acquired lock still held.
assert_eq!(
prior.depth,
self.saved.depth + 1,
"Lock not released in stacking order"
);
}
}
thread_local! {
static LOCK_STATE: Cell<LockState> = const { Cell::new(LockState::INITIAL) };
}
impl<'a, T> std::ops::Deref for MutexGuard<'a, T> {
type Target = T;
@ -185,6 +215,109 @@ impl<T: std::fmt::Debug> std::fmt::Debug for Mutex<T> {
}
}
/// An `RwLock` instrumented for deadlock prevention.
///
/// This is just a wrapper around a [`parking_lot::RwLock`], along with
/// its rank in the `wgpu_core` lock ordering.
///
/// For details, see [the module documentation][mod].
///
/// [mod]: crate::lock::ranked
pub struct RwLock<T> {
inner: parking_lot::RwLock<T>,
rank: LockRank,
}
/// A read guard produced by locking [`RwLock`] for reading.
///
/// This is just a wrapper around a [`parking_lot::RwLockReadGuard`], along with
/// the state needed to track lock acquisition.
///
/// For details, see [the module documentation][mod].
///
/// [mod]: crate::lock::ranked
pub struct RwLockReadGuard<'a, T> {
inner: parking_lot::RwLockReadGuard<'a, T>,
saved: LockStateGuard,
}
/// A write guard produced by locking [`RwLock`] for writing.
///
/// This is just a wrapper around a [`parking_lot::RwLockWriteGuard`], along
/// with the state needed to track lock acquisition.
///
/// For details, see [the module documentation][mod].
///
/// [mod]: crate::lock::ranked
pub struct RwLockWriteGuard<'a, T> {
inner: parking_lot::RwLockWriteGuard<'a, T>,
saved: LockStateGuard,
}
impl<T> RwLock<T> {
pub fn new(rank: LockRank, value: T) -> RwLock<T> {
RwLock {
inner: parking_lot::RwLock::new(value),
rank,
}
}
#[track_caller]
pub fn read(&self) -> RwLockReadGuard<T> {
let saved = acquire(self.rank, Location::caller());
RwLockReadGuard {
inner: self.inner.read(),
saved: LockStateGuard(saved),
}
}
#[track_caller]
pub fn write(&self) -> RwLockWriteGuard<T> {
let saved = acquire(self.rank, Location::caller());
RwLockWriteGuard {
inner: self.inner.write(),
saved: LockStateGuard(saved),
}
}
}
impl<'a, T> RwLockWriteGuard<'a, T> {
pub fn downgrade(this: Self) -> RwLockReadGuard<'a, T> {
RwLockReadGuard {
inner: parking_lot::RwLockWriteGuard::downgrade(this.inner),
saved: this.saved,
}
}
}
impl<T: std::fmt::Debug> std::fmt::Debug for RwLock<T> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
self.inner.fmt(f)
}
}
impl<'a, T> std::ops::Deref for RwLockReadGuard<'a, T> {
type Target = T;
fn deref(&self) -> &Self::Target {
self.inner.deref()
}
}
impl<'a, T> std::ops::Deref for RwLockWriteGuard<'a, T> {
type Target = T;
fn deref(&self) -> &Self::Target {
self.inner.deref()
}
}
impl<'a, T> std::ops::DerefMut for RwLockWriteGuard<'a, T> {
fn deref_mut(&mut self) -> &mut Self::Target {
self.inner.deref_mut()
}
}
/// Locks can be acquired in the order indicated by their ranks.
#[test]
fn permitted() {

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

@ -6,7 +6,7 @@
/// A plain wrapper around [`parking_lot::Mutex`].
///
/// This is just like [`parking_lot::Mutex`], except that our [`new`]
/// method takes a rank, indicating where the new mutex should sitc in
/// method takes a rank, indicating where the new mutex should sit in
/// `wgpu-core`'s lock ordering. The rank is ignored.
///
/// See the [`lock`] module documentation for other wrappers.
@ -21,12 +21,10 @@ pub struct Mutex<T>(parking_lot::Mutex<T>);
pub struct MutexGuard<'a, T>(parking_lot::MutexGuard<'a, T>);
impl<T> Mutex<T> {
#[inline]
pub fn new(_rank: super::rank::LockRank, value: T) -> Mutex<T> {
Mutex(parking_lot::Mutex::new(value))
}
#[inline]
pub fn lock(&self) -> MutexGuard<T> {
MutexGuard(self.0.lock())
}
@ -51,3 +49,73 @@ impl<T: std::fmt::Debug> std::fmt::Debug for Mutex<T> {
self.0.fmt(f)
}
}
/// A plain wrapper around [`parking_lot::RwLock`].
///
/// This is just like [`parking_lot::RwLock`], except that our [`new`]
/// method takes a rank, indicating where the new mutex should sit in
/// `wgpu-core`'s lock ordering. The rank is ignored.
///
/// See the [`lock`] module documentation for other wrappers.
///
/// [`new`]: RwLock::new
/// [`lock`]: crate::lock
pub struct RwLock<T>(parking_lot::RwLock<T>);
/// A read guard produced by locking [`RwLock`] as a reader.
///
/// This is just a wrapper around a [`parking_lot::RwLockReadGuard`].
pub struct RwLockReadGuard<'a, T>(parking_lot::RwLockReadGuard<'a, T>);
/// A write guard produced by locking [`RwLock`] as a writer.
///
/// This is just a wrapper around a [`parking_lot::RwLockWriteGuard`].
pub struct RwLockWriteGuard<'a, T>(parking_lot::RwLockWriteGuard<'a, T>);
impl<T> RwLock<T> {
pub fn new(_rank: super::rank::LockRank, value: T) -> RwLock<T> {
RwLock(parking_lot::RwLock::new(value))
}
pub fn read(&self) -> RwLockReadGuard<T> {
RwLockReadGuard(self.0.read())
}
pub fn write(&self) -> RwLockWriteGuard<T> {
RwLockWriteGuard(self.0.write())
}
}
impl<'a, T> RwLockWriteGuard<'a, T> {
pub fn downgrade(this: Self) -> RwLockReadGuard<'a, T> {
RwLockReadGuard(parking_lot::RwLockWriteGuard::downgrade(this.0))
}
}
impl<T: std::fmt::Debug> std::fmt::Debug for RwLock<T> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
self.0.fmt(f)
}
}
impl<'a, T> std::ops::Deref for RwLockReadGuard<'a, T> {
type Target = T;
fn deref(&self) -> &Self::Target {
self.0.deref()
}
}
impl<'a, T> std::ops::Deref for RwLockWriteGuard<'a, T> {
type Target = T;
fn deref(&self) -> &Self::Target {
self.0.deref()
}
}
impl<'a, T> std::ops::DerefMut for RwLockWriteGuard<'a, T> {
fn deref_mut(&mut self) -> &mut Self::Target {
self.0.deref_mut()
}
}

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

@ -10,7 +10,8 @@ use crate::{
resource_log, validation, Label,
};
use arrayvec::ArrayVec;
use std::{borrow::Cow, error::Error, fmt, marker::PhantomData, num::NonZeroU32, sync::Arc};
use naga::error::ShaderError;
use std::{borrow::Cow, marker::PhantomData, num::NonZeroU32, sync::Arc};
use thiserror::Error;
/// Information about buffer bindings, which
@ -107,79 +108,8 @@ impl<A: HalApi> ShaderModule<A> {
}
}
#[derive(Clone, Debug)]
pub struct ShaderError<E> {
pub source: String,
pub label: Option<String>,
pub inner: Box<E>,
}
#[cfg(feature = "wgsl")]
impl fmt::Display for ShaderError<naga::front::wgsl::ParseError> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let label = self.label.as_deref().unwrap_or_default();
let string = self.inner.emit_to_string(&self.source);
write!(f, "\nShader '{label}' parsing {string}")
}
}
#[cfg(feature = "glsl")]
impl fmt::Display for ShaderError<naga::front::glsl::ParseError> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let label = self.label.as_deref().unwrap_or_default();
let string = self.inner.emit_to_string(&self.source);
write!(f, "\nShader '{label}' parsing {string}")
}
}
#[cfg(feature = "spirv")]
impl fmt::Display for ShaderError<naga::front::spv::Error> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let label = self.label.as_deref().unwrap_or_default();
let string = self.inner.emit_to_string(&self.source);
write!(f, "\nShader '{label}' parsing {string}")
}
}
impl fmt::Display for ShaderError<naga::WithSpan<naga::valid::ValidationError>> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
use codespan_reporting::{
diagnostic::{Diagnostic, Label},
files::SimpleFile,
term,
};
let label = self.label.as_deref().unwrap_or_default();
let files = SimpleFile::new(label, &self.source);
let config = term::Config::default();
let mut writer = term::termcolor::NoColor::new(Vec::new());
let diagnostic = Diagnostic::error().with_labels(
self.inner
.spans()
.map(|&(span, ref desc)| {
Label::primary((), span.to_range().unwrap()).with_message(desc.to_owned())
})
.collect(),
);
term::emit(&mut writer, &config, &files, &diagnostic).expect("cannot write error");
write!(
f,
"\nShader validation {}",
String::from_utf8_lossy(&writer.into_inner())
)
}
}
impl<E> Error for ShaderError<E>
where
ShaderError<E>: fmt::Display,
E: Error + 'static,
{
fn source(&self) -> Option<&(dyn Error + 'static)> {
Some(&self.inner)
}
}
//Note: `Clone` would require `WithSpan: Clone`.
#[derive(Debug, Error)]
#[derive(Clone, Debug, Error)]
#[non_exhaustive]
pub enum CreateShaderModuleError {
#[cfg(feature = "wgsl")]
@ -187,7 +117,7 @@ pub enum CreateShaderModuleError {
Parsing(#[from] ShaderError<naga::front::wgsl::ParseError>),
#[cfg(feature = "glsl")]
#[error(transparent)]
ParsingGlsl(#[from] ShaderError<naga::front::glsl::ParseError>),
ParsingGlsl(#[from] ShaderError<naga::front::glsl::ParseErrors>),
#[cfg(feature = "spirv")]
#[error(transparent)]
ParsingSpirV(#[from] ShaderError<naga::front::spv::Error>),
@ -209,17 +139,6 @@ pub enum CreateShaderModuleError {
},
}
impl CreateShaderModuleError {
pub fn location(&self, source: &str) -> Option<naga::SourceLocation> {
match *self {
#[cfg(feature = "wgsl")]
CreateShaderModuleError::Parsing(ref err) => err.inner.location(source),
CreateShaderModuleError::Validation(ref err) => err.inner.location(source),
_ => None,
}
}
}
/// Describes a programmable pipeline stage.
#[derive(Clone, Debug)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]

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

@ -21,14 +21,13 @@ use crate::{
hal_api::HalApi,
hal_label, id,
init_tracker::TextureInitTracker,
lock::{rank, Mutex},
lock::{rank, Mutex, RwLock},
resource::{self, ResourceInfo},
snatch::Snatchable,
track,
};
use hal::{Queue as _, Surface as _};
use parking_lot::RwLock;
use thiserror::Error;
use wgt::SurfaceStatus as Status;
@ -216,7 +215,10 @@ impl Global {
desc: texture_desc,
hal_usage,
format_features,
initialization_status: RwLock::new(TextureInitTracker::new(1, 1)),
initialization_status: RwLock::new(
rank::TEXTURE_INITIALIZATION_STATUS,
TextureInitTracker::new(1, 1),
),
full_range: track::TextureSelector {
layers: 0..1,
mips: 0..1,
@ -225,9 +227,12 @@ impl Global {
"<Surface Texture>",
Some(device.tracker_indices.textures.clone()),
),
clear_mode: RwLock::new(resource::TextureClearMode::Surface {
clear_view: Some(clear_view),
}),
clear_mode: RwLock::new(
rank::TEXTURE_CLEAR_MODE,
resource::TextureClearMode::Surface {
clear_view: Some(clear_view),
},
),
views: Mutex::new(rank::TEXTURE_VIEWS, Vec::new()),
bind_groups: Mutex::new(rank::TEXTURE_BIND_GROUPS, Vec::new()),
};

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

@ -1,11 +1,11 @@
use std::sync::Arc;
use parking_lot::{RwLock, RwLockReadGuard, RwLockWriteGuard};
use wgt::Backend;
use crate::{
id::Id,
identity::IdentityManager,
lock::{rank, RwLock, RwLockReadGuard, RwLockWriteGuard},
resource::Resource,
storage::{Element, InvalidId, Storage},
};
@ -48,7 +48,7 @@ impl<T: Resource> Registry<T> {
pub(crate) fn new(backend: Backend) -> Self {
Self {
identity: Arc::new(IdentityManager::new()),
storage: RwLock::new(Storage::new()),
storage: RwLock::new(rank::REGISTRY_STORAGE, Storage::new()),
backend,
}
}

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

@ -13,7 +13,7 @@ use crate::{
TextureViewId,
},
init_tracker::{BufferInitTracker, TextureInitTracker},
lock::Mutex,
lock::{Mutex, RwLock},
resource, resource_log,
snatch::{ExclusiveSnatchGuard, SnatchGuard, Snatchable},
track::{SharedTrackerIndexAllocator, TextureSelector, TrackerIndex},
@ -22,7 +22,6 @@ use crate::{
};
use hal::CommandEncoder;
use parking_lot::RwLock;
use smallvec::SmallVec;
use thiserror::Error;
use wgt::WasmNotSendSync;

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

@ -1,6 +1,6 @@
#![allow(unused)]
use parking_lot::{RwLock, RwLockReadGuard, RwLockWriteGuard};
use crate::lock::{RwLock, RwLockReadGuard, RwLockWriteGuard};
use std::{
backtrace::Backtrace,
cell::{Cell, RefCell, UnsafeCell},
@ -8,6 +8,8 @@ use std::{
thread,
};
use crate::lock::rank;
/// A guard that provides read access to snatchable data.
pub struct SnatchGuard<'a>(RwLockReadGuard<'a, ()>);
/// A guard that allows snatching the snatchable data.
@ -128,9 +130,9 @@ impl SnatchLock {
/// right SnatchLock (the one associated to the same device). This method is unsafe
/// to force force sers to think twice about creating a SnatchLock. The only place this
/// method should be called is when creating the device.
pub unsafe fn new() -> Self {
pub unsafe fn new(rank: rank::LockRank) -> Self {
SnatchLock {
lock: RwLock::new(()),
lock: RwLock::new(rank, ()),
}
}

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

@ -105,12 +105,11 @@ use crate::{
binding_model, command, conv,
hal_api::HalApi,
id,
lock::{rank, Mutex},
lock::{rank, Mutex, RwLock},
pipeline, resource,
snatch::SnatchGuard,
};
use parking_lot::RwLock;
use std::{fmt, ops, sync::Arc};
use thiserror::Error;
@ -489,11 +488,26 @@ impl<A: HalApi> RenderBundleScope<A> {
/// Create the render bundle scope and pull the maximum IDs from the hubs.
pub fn new() -> Self {
Self {
buffers: RwLock::new(BufferUsageScope::default()),
textures: RwLock::new(TextureUsageScope::default()),
bind_groups: RwLock::new(StatelessTracker::new()),
render_pipelines: RwLock::new(StatelessTracker::new()),
query_sets: RwLock::new(StatelessTracker::new()),
buffers: RwLock::new(
rank::RENDER_BUNDLE_SCOPE_BUFFERS,
BufferUsageScope::default(),
),
textures: RwLock::new(
rank::RENDER_BUNDLE_SCOPE_TEXTURES,
TextureUsageScope::default(),
),
bind_groups: RwLock::new(
rank::RENDER_BUNDLE_SCOPE_BIND_GROUPS,
StatelessTracker::new(),
),
render_pipelines: RwLock::new(
rank::RENDER_BUNDLE_SCOPE_RENDER_PIPELINES,
StatelessTracker::new(),
),
query_sets: RwLock::new(
rank::RENDER_BUNDLE_SCOPE_QUERY_SETS,
StatelessTracker::new(),
),
}
}

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

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

@ -13,7 +13,7 @@
edition = "2021"
rust-version = "1.74"
name = "wgpu-hal"
version = "0.19.3"
version = "0.20.0"
authors = ["gfx-rs developers"]
description = "WebGPU hardware abstraction layer"
homepage = "https://wgpu.rs/"
@ -63,7 +63,7 @@ version = "0.13.1"
optional = true
[dependencies.naga]
version = "0.19.2"
version = "0.20.0"
path = "../naga"
[dependencies.profiling]
@ -71,17 +71,17 @@ version = "1"
default-features = false
[dependencies.wgt]
version = "0.19.2"
version = "0.20.0"
path = "../wgpu-types"
package = "wgpu-types"
[dev-dependencies]
cfg-if = "1"
env_logger = "0.11"
glam = "0.25.0"
glam = "0.27.0"
[dev-dependencies.naga]
version = "0.19.2"
version = "0.20.0"
path = "../naga"
features = ["wgsl-in"]
@ -162,9 +162,7 @@ version = "0.1"
optional = true
[target."cfg(any(target_os=\"macos\", target_os=\"ios\"))".dependencies.metal]
version = "0.27.0"
git = "https://github.com/gfx-rs/metal-rs"
rev = "ff8fd3d6dc7792852f8a015458d7e6d42d7fb352"
version = "0.28.0"
[target."cfg(not(target_arch = \"wasm32\"))".dependencies.ash]
version = "0.37.3"
@ -226,7 +224,7 @@ version = "0.5"
optional = true
[target."cfg(windows)".dependencies.d3d12]
version = "0.19.0"
version = "0.20.0"
path = "../d3d12/"
features = ["libloading"]
optional = true

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

@ -845,6 +845,7 @@ fn main() {
}
}
ex.render();
window.request_redraw();
}
_ => {
example.as_mut().unwrap().update(event);

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

@ -224,7 +224,7 @@ pub fn map_polygon_mode(mode: wgt::PolygonMode) -> d3d12_ty::D3D12_FILL_MODE {
}
/// D3D12 doesn't support passing factors ending in `_COLOR` for alpha blending
/// (see https://learn.microsoft.com/en-us/windows/win32/api/d3d12/ns-d3d12-d3d12_render_target_blend_desc).
/// (see <https://learn.microsoft.com/en-us/windows/win32/api/d3d12/ns-d3d12-d3d12_render_target_blend_desc>).
/// Therefore this function takes an additional `is_alpha` argument
/// which if set will return an equivalent `_ALPHA` factor.
fn map_blend_factor(factor: wgt::BlendFactor, is_alpha: bool) -> d3d12_ty::D3D12_BLEND {

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

@ -440,7 +440,7 @@ impl Texture {
}
}
/// see https://learn.microsoft.com/en-us/windows/win32/direct3d12/subresources#plane-slice
/// see <https://learn.microsoft.com/en-us/windows/win32/direct3d12/subresources#plane-slice>
fn calc_subresource(&self, mip_level: u32, array_layer: u32, plane: u32) -> u32 {
mip_level + (array_layer + plane * self.array_layer_count()) * self.mip_level_count
}

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

@ -549,22 +549,28 @@ impl Inner {
let mut khr_context_flags = 0;
let supports_khr_context = display_extensions.contains("EGL_KHR_create_context");
//TODO: make it so `Device` == EGL Context
let mut context_attributes = vec![
khronos_egl::CONTEXT_MAJOR_VERSION,
3, // Request GLES 3.0 or higher
];
if force_gles_minor_version != wgt::Gles3MinorVersion::Automatic {
let mut context_attributes = vec![];
if supports_opengl {
context_attributes.push(khronos_egl::CONTEXT_MAJOR_VERSION);
context_attributes.push(3);
context_attributes.push(khronos_egl::CONTEXT_MINOR_VERSION);
context_attributes.push(match force_gles_minor_version {
wgt::Gles3MinorVersion::Version0 => 0,
wgt::Gles3MinorVersion::Version1 => 1,
wgt::Gles3MinorVersion::Version2 => 2,
_ => unreachable!(),
});
context_attributes.push(3);
if force_gles_minor_version != wgt::Gles3MinorVersion::Automatic {
log::warn!("Ignoring specified GLES minor version as OpenGL is used");
}
} else {
context_attributes.push(khronos_egl::CONTEXT_MAJOR_VERSION);
context_attributes.push(3); // Request GLES 3.0 or higher
if force_gles_minor_version != wgt::Gles3MinorVersion::Automatic {
context_attributes.push(khronos_egl::CONTEXT_MINOR_VERSION);
context_attributes.push(match force_gles_minor_version {
wgt::Gles3MinorVersion::Automatic => unreachable!(),
wgt::Gles3MinorVersion::Version0 => 0,
wgt::Gles3MinorVersion::Version1 => 1,
wgt::Gles3MinorVersion::Version2 => 2,
});
}
}
if flags.contains(wgt::InstanceFlags::DEBUG) {
if version >= (1, 5) {
log::debug!("\tEGL context: +debug");
@ -594,8 +600,6 @@ impl Inner {
// because it's for desktop GL only, not GLES.
log::warn!("\tEGL context: -robust access");
}
//TODO do we need `khronos_egl::CONTEXT_OPENGL_NOTIFICATION_STRATEGY_EXT`?
}
if khr_context_flags != 0 {
context_attributes.push(EGL_CONTEXT_FLAGS_KHR);
@ -1130,6 +1134,13 @@ impl Surface {
unsafe { gl.bind_framebuffer(glow::DRAW_FRAMEBUFFER, None) };
unsafe { gl.bind_framebuffer(glow::READ_FRAMEBUFFER, Some(sc.framebuffer)) };
if !matches!(self.srgb_kind, SrgbFrameBufferKind::None) {
// 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
// in the shader, and also this blit.
@ -1147,6 +1158,11 @@ impl Surface {
glow::NEAREST,
)
};
if !matches!(self.srgb_kind, SrgbFrameBufferKind::None) {
unsafe { gl.enable(glow::FRAMEBUFFER_SRGB) };
}
unsafe { gl.bind_framebuffer(glow::READ_FRAMEBUFFER, None) };
self.egl

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

@ -406,6 +406,24 @@ pub trait Api: Clone + fmt::Debug + Sized {
type TextureView: fmt::Debug + WasmNotSendSync;
type Sampler: fmt::Debug + WasmNotSendSync;
type QuerySet: fmt::Debug + WasmNotSendSync;
/// A value you can block on to wait for something to finish.
///
/// A `Fence` holds a monotonically increasing [`FenceValue`]. You can call
/// [`Device::wait`] to block until a fence reaches or passes a value you
/// choose. [`Queue::submit`] can take a `Fence` and a [`FenceValue`] to
/// store in it when the submitted work is complete.
///
/// Attempting to set a fence to a value less than its current value has no
/// effect.
///
/// Waiting on a fence returns as soon as the fence reaches *or passes* the
/// requested value. This implies that, in order to reliably determine when
/// an operation has completed, operations must finish in order of
/// increasing fence values: if a higher-valued operation were to finish
/// before a lower-valued operation, then waiting for the fence to reach the
/// lower value could return before the lower-valued operation has actually
/// finished.
type Fence: fmt::Debug + WasmNotSendSync;
type BindGroupLayout: fmt::Debug + WasmNotSendSync;
@ -605,7 +623,25 @@ pub trait Device: WasmNotSendSync {
&self,
fence: &<Self::A as Api>::Fence,
) -> Result<FenceValue, DeviceError>;
/// Calling wait with a lower value than the current fence value will immediately return.
/// Wait for `fence` to reach `value`.
///
/// Operations like [`Queue::submit`] can accept a [`Fence`] and a
/// [`FenceValue`] to store in it, so you can use this `wait` function
/// to wait for a given queue submission to finish execution.
///
/// The `value` argument must be a value that some actual operation you have
/// already presented to the device is going to store in `fence`. You cannot
/// wait for values yet to be submitted. (This restriction accommodates
/// implementations like the `vulkan` backend's [`FencePool`] that must
/// allocate a distinct synchronization object for each fence value one is
/// able to wait for.)
///
/// Calling `wait` with a lower [`FenceValue`] than `fence`'s current value
/// returns immediately.
///
/// [`Fence`]: Api::Fence
/// [`FencePool`]: vulkan/enum.Fence.html#variant.FencePool
unsafe fn wait(
&self,
fence: &<Self::A as Api>::Fence,
@ -637,7 +673,30 @@ pub trait Device: WasmNotSendSync {
pub trait Queue: WasmNotSendSync {
type A: Api;
/// Submits the command buffers for execution on GPU.
/// Submit `command_buffers` for execution on GPU.
///
/// If `signal_fence` is `Some(fence, value)`, update `fence` to `value`
/// when the operation is complete. See [`Fence`] for details.
///
/// If two calls to `submit` on a single `Queue` occur in a particular order
/// (that is, they happen on the same thread, or on two threads that have
/// synchronized to establish an ordering), then the first submission's
/// commands all complete execution before any of the second submission's
/// commands begin. All results produced by one submission are visible to
/// the next.
///
/// Within a submission, command buffers execute in the order in which they
/// appear in `command_buffers`. All results produced by one buffer are
/// visible to the next.
///
/// If two calls to `submit` on a single `Queue` from different threads are
/// not synchronized to occur in a particular order, they must pass distinct
/// [`Fence`]s. As explained in the [`Fence`] documentation, waiting for
/// operations to complete is only trustworthy when operations finish in
/// order of increasing fence value, but submissions from different threads
/// cannot determine how to order the fence values if the submissions
/// themselves are unordered. If each thread uses a separate [`Fence`], this
/// problem does not arise.
///
/// Valid usage:
///
@ -652,6 +711,7 @@ pub trait Queue: WasmNotSendSync {
/// - All of the [`SurfaceTexture`][st]s that the command buffers
/// write to appear in the `surface_textures` argument.
///
/// [`Fence`]: Api::Fence
/// [cb]: Api::CommandBuffer
/// [ce]: Api::CommandEncoder
/// [st]: Api::SurfaceTexture

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

@ -817,6 +817,10 @@ impl super::PrivateCapabilities {
&& (device.supports_family(MTLGPUFamily::Metal3)
|| device.supports_family(MTLGPUFamily::Mac2)
|| device.supports_family(MTLGPUFamily::Apple7)),
// https://developer.apple.com/metal/Metal-Feature-Set-Tables.pdf#page=5
int64: family_check
&& (device.supports_family(MTLGPUFamily::Apple3)
|| device.supports_family(MTLGPUFamily::Metal3)),
}
}
@ -890,7 +894,7 @@ impl super::PrivateCapabilities {
}
features.set(
F::SHADER_INT64,
self.msl_version >= MTLLanguageVersion::V2_3,
self.int64 && self.msl_version >= MTLLanguageVersion::V2_3,
);
features.set(

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

@ -270,6 +270,7 @@ struct PrivateCapabilities {
has_unified_memory: Option<bool>,
timestamp_query_support: TimestampQuerySupport,
supports_simd_scoped_operations: bool,
int64: bool,
}
#[derive(Clone, Debug)]
@ -650,7 +651,7 @@ struct BufferResource {
/// Buffers with the [`wgt::BufferBindingType::Storage`] binding type can
/// hold WGSL runtime-sized arrays. When one does, we must pass its size to
/// shader entry points to implement bounds checks and WGSL's `arrayLength`
/// function. See [`device::CompiledShader::sized_bindings`] for details.
/// function. See `device::CompiledShader::sized_bindings` for details.
///
/// [`Storage`]: wgt::BufferBindingType::Storage
binding_size: Option<wgt::BufferSize>,
@ -681,12 +682,12 @@ struct PipelineStageInfo {
/// The buffer argument table index at which we pass runtime-sized arrays' buffer sizes.
///
/// See [`device::CompiledShader::sized_bindings`] for more details.
/// See `device::CompiledShader::sized_bindings` for more details.
sizes_slot: Option<naga::back::msl::Slot>,
/// Bindings of all WGSL `storage` globals that contain runtime-sized arrays.
///
/// See [`device::CompiledShader::sized_bindings`] for more details.
/// See `device::CompiledShader::sized_bindings` for more details.
sized_bindings: Vec<naga::ResourceBinding>,
}
@ -802,7 +803,7 @@ struct CommandState {
///
/// Specifically:
///
/// - The keys are ['ResourceBinding`] values (that is, the WGSL `@group`
/// - The keys are [`ResourceBinding`] values (that is, the WGSL `@group`
/// and `@binding` attributes) for `var<storage>` global variables in the
/// current module that contain runtime-sized arrays.
///
@ -814,7 +815,7 @@ struct CommandState {
/// of the buffers listed in [`stage_infos.S.sized_bindings`], which we must
/// pass to the entry point.
///
/// See [`device::CompiledShader::sized_bindings`] for more details.
/// See `device::CompiledShader::sized_bindings` for more details.
///
/// [`ResourceBinding`]: naga::ResourceBinding
storage_buffer_length_map: rustc_hash::FxHashMap<naga::ResourceBinding, wgt::BufferSize>,

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

@ -35,6 +35,8 @@ fn indexing_features() -> wgt::Features {
/// [`PhysicalDeviceFeatures::from_extensions_and_requested_features`]
/// constructs an value of this type indicating which Vulkan features to
/// enable, based on the `wgpu_types::Features` requested.
///
/// [`Instance::expose_adapter`]: super::Instance::expose_adapter
#[derive(Debug, Default)]
pub struct PhysicalDeviceFeatures {
/// Basic Vulkan 1.0 features.
@ -86,6 +88,9 @@ pub struct PhysicalDeviceFeatures {
///
/// However, we do populate this when creating a device if
/// [`Features::RAY_TRACING_ACCELERATION_STRUCTURE`] is requested.
///
/// [`Instance::expose_adapter`]: super::Instance::expose_adapter
/// [`Features::RAY_TRACING_ACCELERATION_STRUCTURE`]: wgt::Features::RAY_TRACING_ACCELERATION_STRUCTURE
buffer_device_address: Option<vk::PhysicalDeviceBufferDeviceAddressFeaturesKHR>,
/// Features provided by `VK_KHR_ray_query`,
@ -95,6 +100,8 @@ pub struct PhysicalDeviceFeatures {
/// this from `vkGetPhysicalDeviceFeatures2`.
///
/// However, we do populate this when creating a device if ray tracing is requested.
///
/// [`Instance::expose_adapter`]: super::Instance::expose_adapter
ray_query: Option<vk::PhysicalDeviceRayQueryFeaturesKHR>,
/// Features provided by `VK_KHR_zero_initialize_workgroup_memory`, promoted
@ -181,6 +188,7 @@ impl PhysicalDeviceFeatures {
/// [`Features`]: wgt::Features
/// [`DownlevelFlags`]: wgt::DownlevelFlags
/// [`PrivateCapabilities`]: super::PrivateCapabilities
/// [`add_to_device_create_builder`]: PhysicalDeviceFeatures::add_to_device_create_builder
/// [`DeviceCreateInfoBuilder`]: vk::DeviceCreateInfoBuilder
/// [`Adapter::required_device_extensions`]: super::Adapter::required_device_extensions
fn from_extensions_and_requested_features(
@ -459,6 +467,9 @@ impl PhysicalDeviceFeatures {
/// Given `self`, together with the instance and physical device it was
/// built from, and a `caps` also built from those, determine which wgpu
/// features and downlevel flags the device can support.
///
/// [`Features`]: wgt::Features
/// [`DownlevelFlags`]: wgt::DownlevelFlags
fn to_wgpu(
&self,
instance: &ash::Instance,

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

@ -559,9 +559,47 @@ pub struct QuerySet {
raw: vk::QueryPool,
}
/// The [`Api::Fence`] type for [`vulkan::Api`].
///
/// This is an `enum` because there are two possible implementations of
/// `wgpu-hal` fences on Vulkan: Vulkan fences, which work on any version of
/// Vulkan, and Vulkan timeline semaphores, which are easier and cheaper but
/// require non-1.0 features.
///
/// [`Device::create_fence`] returns a [`TimelineSemaphore`] if
/// [`VK_KHR_timeline_semaphore`] is available and enabled, and a [`FencePool`]
/// otherwise.
///
/// [`Api::Fence`]: crate::Api::Fence
/// [`vulkan::Api`]: Api
/// [`Device::create_fence`]: crate::Device::create_fence
/// [`TimelineSemaphore`]: Fence::TimelineSemaphore
/// [`VK_KHR_timeline_semaphore`]: https://registry.khronos.org/vulkan/specs/1.3-extensions/html/vkspec.html#VK_KHR_timeline_semaphore
/// [`FencePool`]: Fence::FencePool
#[derive(Debug)]
pub enum Fence {
/// A Vulkan [timeline semaphore].
///
/// These are simpler to use than Vulkan fences, since timeline semaphores
/// work exactly the way [`wpgu_hal::Api::Fence`] is specified to work.
///
/// [timeline semaphore]: https://registry.khronos.org/vulkan/specs/1.3-extensions/html/vkspec.html#synchronization-semaphores
/// [`wpgu_hal::Api::Fence`]: crate::Api::Fence
TimelineSemaphore(vk::Semaphore),
/// A collection of Vulkan [fence]s, each associated with a [`FenceValue`].
///
/// The effective [`FenceValue`] of this variant is the greater of
/// `last_completed` and the maximum value associated with a signalled fence
/// in `active`.
///
/// Fences are available in all versions of Vulkan, but since they only have
/// two states, "signaled" and "unsignaled", we need to use a separate fence
/// for each queue submission we might want to wait for, and remember which
/// [`FenceValue`] each one represents.
///
/// [fence]: https://registry.khronos.org/vulkan/specs/1.3-extensions/html/vkspec.html#synchronization-fences
/// [`FenceValue`]: crate::FenceValue
FencePool {
last_completed: crate::FenceValue,
/// The pending fence values have to be ascending.
@ -571,21 +609,32 @@ pub enum Fence {
}
impl Fence {
/// Return the highest [`FenceValue`] among the signalled fences in `active`.
///
/// As an optimization, assume that we already know that the fence has
/// reached `last_completed`, and don't bother checking fences whose values
/// are less than that: those fences remain in the `active` array only
/// because we haven't called `maintain` yet to clean them up.
///
/// [`FenceValue`]: crate::FenceValue
fn check_active(
device: &ash::Device,
mut max_value: crate::FenceValue,
mut last_completed: crate::FenceValue,
active: &[(crate::FenceValue, vk::Fence)],
) -> Result<crate::FenceValue, crate::DeviceError> {
for &(value, raw) in active.iter() {
unsafe {
if value > max_value && device.get_fence_status(raw)? {
max_value = value;
if value > last_completed && device.get_fence_status(raw)? {
last_completed = value;
}
}
}
Ok(max_value)
Ok(last_completed)
}
/// Return the highest signalled [`FenceValue`] for `self`.
///
/// [`FenceValue`]: crate::FenceValue
fn get_latest(
&self,
device: &ash::Device,
@ -606,6 +655,18 @@ impl Fence {
}
}
/// Trim the internal state of this [`Fence`].
///
/// This function has no externally visible effect, but you should call it
/// periodically to keep this fence's resource consumption under control.
///
/// For fences using the [`FencePool`] implementation, this function
/// recycles fences that have been signaled. If you don't call this,
/// [`Queue::submit`] will just keep allocating a new Vulkan fence every
/// time it's called.
///
/// [`FencePool`]: Fence::FencePool
/// [`Queue::submit`]: crate::Queue::submit
fn maintain(&mut self, device: &ash::Device) -> Result<(), crate::DeviceError> {
match *self {
Self::TimelineSemaphore(_) => {}

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

@ -1 +1 @@
{"files":{"Cargo.toml":"9c95789feb6b72f758d225f0931bfa1c4cbe768cc8292a78324d89e58b9803c9","LICENSE.APACHE":"a6cba85bc92e0cff7a450b1d873c0eaa2e9fc96bf472df0247a26bec77bf3ff9","LICENSE.MIT":"c7fea58d1cfe49634cd92e54fc10a9d871f4b275321a4cd8c09e449122caaeb4","src/assertions.rs":"3fe98027aa73970c8ab7874a3e13dbfd6faa87df2081beb5c83aeec4c60f372f","src/lib.rs":"1426b5ed459028bd41a1e0d5e89e681f2bc3c34c60e68ba07cf16dc90054aa57","src/math.rs":"4d03039736dd6926feb139bc68734cb59df34ede310427bbf059e5c925e0af3b"},"package":null}
{"files":{"Cargo.toml":"d8f88446d6c1740116442320eca91e06ce9a2f4713179195c1be44e8ab1fc42d","LICENSE.APACHE":"a6cba85bc92e0cff7a450b1d873c0eaa2e9fc96bf472df0247a26bec77bf3ff9","LICENSE.MIT":"c7fea58d1cfe49634cd92e54fc10a9d871f4b275321a4cd8c09e449122caaeb4","src/assertions.rs":"3fe98027aa73970c8ab7874a3e13dbfd6faa87df2081beb5c83aeec4c60f372f","src/lib.rs":"0e844b150863abdecee2a2cb44245330f22ab48d8ab14f15f06c13f96213bdf3","src/math.rs":"4d03039736dd6926feb139bc68734cb59df34ede310427bbf059e5c925e0af3b"},"package":null}

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

@ -13,7 +13,7 @@
edition = "2021"
rust-version = "1.74"
name = "wgpu-types"
version = "0.19.2"
version = "0.20.0"
authors = ["gfx-rs developers"]
description = "WebGPU types"
homepage = "https://wgpu.rs/"

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

@ -1143,7 +1143,7 @@ pub struct Limits {
/// pipeline output data, across all color attachments.
pub max_color_attachment_bytes_per_sample: u32,
/// Maximum number of bytes used for workgroup memory in a compute entry point. Defaults to
/// 16352. Higher is "better".
/// 16384. Higher is "better".
pub max_compute_workgroup_storage_size: u32,
/// Maximum value of the product of the `workgroup_size` dimensions for a compute entry-point.
/// Defaults to 256. Higher is "better".
@ -1184,6 +1184,14 @@ pub struct Limits {
impl Default for Limits {
fn default() -> Self {
Self::defaults()
}
}
impl Limits {
// Rust doesn't allow const in trait implementations, so we break this out
// to allow reusing these defaults in const contexts like `downlevel_defaults`
const fn defaults() -> Self {
Self {
max_texture_dimension_1d: 8192,
max_texture_dimension_2d: 8192,
@ -1198,10 +1206,10 @@ impl Default for Limits {
max_storage_buffers_per_shader_stage: 8,
max_storage_textures_per_shader_stage: 4,
max_uniform_buffers_per_shader_stage: 12,
max_uniform_buffer_binding_size: 64 << 10,
max_storage_buffer_binding_size: 128 << 20,
max_uniform_buffer_binding_size: 64 << 10, // (64 KiB)
max_storage_buffer_binding_size: 128 << 20, // (128 MiB)
max_vertex_buffers: 8,
max_buffer_size: 256 << 20,
max_buffer_size: 256 << 20, // (256 MiB)
max_vertex_attributes: 16,
max_vertex_buffer_array_stride: 2048,
min_uniform_buffer_offset_alignment: 256,
@ -1221,9 +1229,7 @@ impl Default for Limits {
max_non_sampler_bindings: 1_000_000,
}
}
}
impl Limits {
/// These default limits are guaranteed to be compatible with GLES-3.1, and D3D11
///
/// Those limits are as follows (different from default are marked with *):
@ -1256,7 +1262,7 @@ impl Limits {
/// max_inter_stage_shader_components: 60,
/// max_color_attachments: 8,
/// max_color_attachment_bytes_per_sample: 32,
/// max_compute_workgroup_storage_size: 16352,
/// max_compute_workgroup_storage_size: 16352, // *
/// max_compute_invocations_per_workgroup: 256,
/// max_compute_workgroup_size_x: 256,
/// max_compute_workgroup_size_y: 256,
@ -1271,37 +1277,11 @@ impl Limits {
max_texture_dimension_1d: 2048,
max_texture_dimension_2d: 2048,
max_texture_dimension_3d: 256,
max_texture_array_layers: 256,
max_bind_groups: 4,
max_bindings_per_bind_group: 1000,
max_dynamic_uniform_buffers_per_pipeline_layout: 8,
max_dynamic_storage_buffers_per_pipeline_layout: 4,
max_sampled_textures_per_shader_stage: 16,
max_samplers_per_shader_stage: 16,
max_storage_buffers_per_shader_stage: 4,
max_storage_textures_per_shader_stage: 4,
max_uniform_buffers_per_shader_stage: 12,
max_uniform_buffer_binding_size: 16 << 10,
max_storage_buffer_binding_size: 128 << 20,
max_vertex_buffers: 8,
max_vertex_attributes: 16,
max_vertex_buffer_array_stride: 2048,
min_subgroup_size: 0,
max_subgroup_size: 0,
max_push_constant_size: 0,
min_uniform_buffer_offset_alignment: 256,
min_storage_buffer_offset_alignment: 256,
max_inter_stage_shader_components: 60,
max_color_attachments: 8,
max_color_attachment_bytes_per_sample: 32,
max_uniform_buffer_binding_size: 16 << 10, // (16 KiB)
// see: https://developer.apple.com/metal/Metal-Feature-Set-Tables.pdf#page=7
max_compute_workgroup_storage_size: 16352,
max_compute_invocations_per_workgroup: 256,
max_compute_workgroup_size_x: 256,
max_compute_workgroup_size_y: 256,
max_compute_workgroup_size_z: 64,
max_compute_workgroups_per_dimension: 65535,
max_buffer_size: 256 << 20,
max_non_sampler_bindings: 1_000_000,
..Self::defaults()
}
}
@ -7114,7 +7094,7 @@ pub struct InstanceDescriptor {
pub flags: InstanceFlags,
/// Which DX12 shader compiler to use.
pub dx12_shader_compiler: Dx12Compiler,
/// Which OpenGL ES 3 minor version to request.
/// Which OpenGL ES 3 minor version to request. Will be ignored if OpenGL is available.
pub gles_minor_version: Gles3MinorVersion,
}