mirror of
https://github.com/gfx-rs/wgpu.git
synced 2025-12-08 21:26:17 +00:00
Context dynamic dispatch (#3051)
This commit is contained in:
parent
de070b2846
commit
052bd17d41
@ -115,6 +115,7 @@ Additionally `Surface::get_default_config` now returns an Option and returns Non
|
|||||||
- Make `Surface::get_default_config` return an Option to prevent panics. By @cwfitzgerald in [#3157](https://github.com/gfx-rs/wgpu/pull/3157)
|
- Make `Surface::get_default_config` return an Option to prevent panics. By @cwfitzgerald in [#3157](https://github.com/gfx-rs/wgpu/pull/3157)
|
||||||
- Lower the `max_buffer_size` limit value for compatibility with Apple2 and WebGPU compliance. By @jinleili in [#3255](https://github.com/gfx-rs/wgpu/pull/3255)
|
- Lower the `max_buffer_size` limit value for compatibility with Apple2 and WebGPU compliance. By @jinleili in [#3255](https://github.com/gfx-rs/wgpu/pull/3255)
|
||||||
- Dereferencing a buffer view is now marked inline. By @Wumpf in [#3307](https://github.com/gfx-rs/wgpu/pull/3307)
|
- Dereferencing a buffer view is now marked inline. By @Wumpf in [#3307](https://github.com/gfx-rs/wgpu/pull/3307)
|
||||||
|
- The `strict_assert` family of macros was moved to `wgpu-types`. By @i509VCB in [#3051](https://github.com/gfx-rs/wgpu/pull/3051)
|
||||||
|
|
||||||
#### WebGPU
|
#### WebGPU
|
||||||
|
|
||||||
|
|||||||
@ -34,7 +34,7 @@ emscripten = ["hal/emscripten"]
|
|||||||
|
|
||||||
# Apply run-time checks, even in release builds. These are in addition
|
# Apply run-time checks, even in release builds. These are in addition
|
||||||
# to the validation carried out at public APIs in all builds.
|
# to the validation carried out at public APIs in all builds.
|
||||||
strict_asserts = []
|
strict_asserts = ["wgt/strict_asserts"]
|
||||||
angle = ["hal/gles"]
|
angle = ["hal/gles"]
|
||||||
# Enable API tracing
|
# Enable API tracing
|
||||||
trace = ["ron", "serde", "wgt/trace", "arrayvec/serde", "naga/serialize"]
|
trace = ["ron", "serde", "wgt/trace", "arrayvec/serde", "naga/serialize"]
|
||||||
|
|||||||
@ -93,6 +93,13 @@ impl<T> From<SerialId> for Id<T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<T> Id<T> {
|
impl<T> Id<T> {
|
||||||
|
/// # Safety
|
||||||
|
///
|
||||||
|
/// The raw id must be valid for the type.
|
||||||
|
pub unsafe fn from_raw(raw: NonZeroId) -> Self {
|
||||||
|
Self(raw, PhantomData)
|
||||||
|
}
|
||||||
|
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
pub(crate) fn dummy(index: u32) -> Valid<Self> {
|
pub(crate) fn dummy(index: u32) -> Valid<Self> {
|
||||||
Valid(Id::zip(index, 1, Backend::Empty))
|
Valid(Id::zip(index, 1, Backend::Empty))
|
||||||
@ -165,6 +172,7 @@ pub(crate) struct Valid<I>(pub I);
|
|||||||
/// need to construct `Id` values directly, or access their components, like the
|
/// need to construct `Id` values directly, or access their components, like the
|
||||||
/// WGPU recording player, may use this trait to do so.
|
/// WGPU recording player, may use this trait to do so.
|
||||||
pub trait TypedId: Copy {
|
pub trait TypedId: Copy {
|
||||||
|
fn as_raw(&self) -> NonZeroId;
|
||||||
fn zip(index: Index, epoch: Epoch, backend: Backend) -> Self;
|
fn zip(index: Index, epoch: Epoch, backend: Backend) -> Self;
|
||||||
fn unzip(self) -> (Index, Epoch, Backend);
|
fn unzip(self) -> (Index, Epoch, Backend);
|
||||||
fn into_raw(self) -> NonZeroId;
|
fn into_raw(self) -> NonZeroId;
|
||||||
@ -172,6 +180,10 @@ pub trait TypedId: Copy {
|
|||||||
|
|
||||||
#[allow(trivial_numeric_casts)]
|
#[allow(trivial_numeric_casts)]
|
||||||
impl<T> TypedId for Id<T> {
|
impl<T> TypedId for Id<T> {
|
||||||
|
fn as_raw(&self) -> NonZeroId {
|
||||||
|
self.0
|
||||||
|
}
|
||||||
|
|
||||||
fn zip(index: Index, epoch: Epoch, backend: Backend) -> Self {
|
fn zip(index: Index, epoch: Epoch, backend: Backend) -> Self {
|
||||||
assert_eq!(0, epoch >> EPOCH_BITS);
|
assert_eq!(0, epoch >> EPOCH_BITS);
|
||||||
assert_eq!(0, (index as IdType) >> INDEX_BITS);
|
assert_eq!(0, (index as IdType) >> INDEX_BITS);
|
||||||
|
|||||||
@ -35,9 +35,6 @@
|
|||||||
clippy::pattern_type_mismatch,
|
clippy::pattern_type_mismatch,
|
||||||
)]
|
)]
|
||||||
|
|
||||||
#[macro_use]
|
|
||||||
mod assertions;
|
|
||||||
|
|
||||||
pub mod binding_model;
|
pub mod binding_model;
|
||||||
pub mod command;
|
pub mod command;
|
||||||
mod conv;
|
mod conv;
|
||||||
|
|||||||
@ -19,6 +19,7 @@ use crate::{
|
|||||||
LifeGuard, RefCount,
|
LifeGuard, RefCount,
|
||||||
};
|
};
|
||||||
use hal::BufferUses;
|
use hal::BufferUses;
|
||||||
|
use wgt::{strict_assert, strict_assert_eq};
|
||||||
|
|
||||||
impl ResourceUses for BufferUses {
|
impl ResourceUses for BufferUses {
|
||||||
const EXCLUSIVE: Self = Self::EXCLUSIVE;
|
const EXCLUSIVE: Self = Self::EXCLUSIVE;
|
||||||
|
|||||||
@ -7,6 +7,7 @@ use crate::{
|
|||||||
};
|
};
|
||||||
use bit_vec::BitVec;
|
use bit_vec::BitVec;
|
||||||
use std::{borrow::Cow, marker::PhantomData, mem};
|
use std::{borrow::Cow, marker::PhantomData, mem};
|
||||||
|
use wgt::strict_assert;
|
||||||
|
|
||||||
/// A set of resources, holding a [`RefCount`] and epoch for each member.
|
/// A set of resources, holding a [`RefCount`] and epoch for each member.
|
||||||
///
|
///
|
||||||
|
|||||||
@ -114,6 +114,7 @@ pub(crate) use stateless::{StatelessBindGroupSate, StatelessTracker};
|
|||||||
pub(crate) use texture::{
|
pub(crate) use texture::{
|
||||||
TextureBindGroupState, TextureSelector, TextureTracker, TextureUsageScope,
|
TextureBindGroupState, TextureSelector, TextureTracker, TextureUsageScope,
|
||||||
};
|
};
|
||||||
|
use wgt::strict_assert_ne;
|
||||||
|
|
||||||
/// A structure containing all the information about a particular resource
|
/// A structure containing all the information about a particular resource
|
||||||
/// transition. User code should be able to generate a pipeline barrier
|
/// transition. User code should be able to generate a pipeline barrier
|
||||||
|
|||||||
@ -34,6 +34,7 @@ use hal::TextureUses;
|
|||||||
|
|
||||||
use arrayvec::ArrayVec;
|
use arrayvec::ArrayVec;
|
||||||
use naga::FastHashMap;
|
use naga::FastHashMap;
|
||||||
|
use wgt::{strict_assert, strict_assert_eq};
|
||||||
|
|
||||||
use std::{borrow::Cow, iter, marker::PhantomData, ops::Range, vec::Drain};
|
use std::{borrow::Cow, iter, marker::PhantomData, ops::Range, vec::Drain};
|
||||||
|
|
||||||
|
|||||||
@ -18,6 +18,7 @@ rustdoc-args = ["--cfg", "docsrs"]
|
|||||||
[features]
|
[features]
|
||||||
trace = ["serde"]
|
trace = ["serde"]
|
||||||
replay = ["serde"]
|
replay = ["serde"]
|
||||||
|
strict_asserts = []
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
bitflags = "1"
|
bitflags = "1"
|
||||||
|
|||||||
66
wgpu-types/src/assertions.rs
Normal file
66
wgpu-types/src/assertions.rs
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
//! Macros for validation internal to the wgpu.
|
||||||
|
//!
|
||||||
|
//! This module defines assertion macros that respect `wgpu-type`'s
|
||||||
|
//! `"strict_asserts"` feature.
|
||||||
|
//!
|
||||||
|
//! Because `wgpu-core`'s public APIs validate their arguments in all
|
||||||
|
//! types of builds, for performance, the `track` module skips some of
|
||||||
|
//! Rust's usual run-time checks on its internal operations in release
|
||||||
|
//! builds. However, some `wgpu-core` applications have a strong
|
||||||
|
//! preference for robustness over performance. To accommodate them,
|
||||||
|
//! `wgpu-core`'s `"strict_asserts"` feature enables that validation
|
||||||
|
//! in both debug and release builds.
|
||||||
|
|
||||||
|
/// This is equivalent to [`std::assert`] if the `strict_asserts` feature is activated.
|
||||||
|
#[cfg(feature = "strict_asserts")]
|
||||||
|
#[macro_export]
|
||||||
|
macro_rules! strict_assert {
|
||||||
|
( $( $arg:tt )* ) => {
|
||||||
|
assert!( $( $arg )* )
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// This is equivalent to [`std::assert_eq`] if the `strict_asserts` feature is activated.
|
||||||
|
#[cfg(feature = "strict_asserts")]
|
||||||
|
#[macro_export]
|
||||||
|
macro_rules! strict_assert_eq {
|
||||||
|
( $( $arg:tt )* ) => {
|
||||||
|
assert_eq!( $( $arg )* )
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// This is equivalent to [`std::assert_ne`] if the `strict_asserts` feature is activated.
|
||||||
|
#[cfg(feature = "strict_asserts")]
|
||||||
|
#[macro_export]
|
||||||
|
macro_rules! strict_assert_ne {
|
||||||
|
( $( $arg:tt )* ) => {
|
||||||
|
assert_ne!( $( $arg )* )
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// This is equivalent to [`std::assert`] if the `strict_asserts` feature is activated.
|
||||||
|
#[cfg(not(feature = "strict_asserts"))]
|
||||||
|
#[macro_export]
|
||||||
|
macro_rules! strict_assert {
|
||||||
|
( $( $arg:tt )* ) => {
|
||||||
|
debug_assert!( $( $arg )* )
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/// This is equivalent to [`std::assert_eq`] if the `strict_asserts` feature is activated.
|
||||||
|
#[cfg(not(feature = "strict_asserts"))]
|
||||||
|
#[macro_export]
|
||||||
|
macro_rules! strict_assert_eq {
|
||||||
|
( $( $arg:tt )* ) => {
|
||||||
|
debug_assert_eq!( $( $arg )* )
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/// This is equivalent to [`std::assert_ne`] if the `strict_asserts` feature is activated.
|
||||||
|
#[cfg(not(feature = "strict_asserts"))]
|
||||||
|
#[macro_export]
|
||||||
|
macro_rules! strict_assert_ne {
|
||||||
|
( $( $arg:tt )* ) => {
|
||||||
|
debug_assert_ne!( $( $arg )* )
|
||||||
|
};
|
||||||
|
}
|
||||||
@ -14,6 +14,8 @@ use serde::{Deserialize, Serialize};
|
|||||||
use std::hash::{Hash, Hasher};
|
use std::hash::{Hash, Hasher};
|
||||||
use std::{num::NonZeroU32, ops::Range};
|
use std::{num::NonZeroU32, ops::Range};
|
||||||
|
|
||||||
|
mod assertions;
|
||||||
|
|
||||||
// Use this macro instead of the one provided by the bitflags_serde_shim crate
|
// Use this macro instead of the one provided by the bitflags_serde_shim crate
|
||||||
// because the latter produces an error when deserializing bits that are not
|
// because the latter produces an error when deserializing bits that are not
|
||||||
// specified in the bitflags, while we want deserialization to succeed and
|
// specified in the bitflags, while we want deserialization to succeed and
|
||||||
|
|||||||
@ -76,7 +76,10 @@ name = "water"
|
|||||||
test = true
|
test = true
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = ["wgsl", "expose-ids"]
|
default = ["wgsl", "expose-ids", "strict_asserts"]
|
||||||
|
# Apply run-time checks, even in release builds. These are in addition
|
||||||
|
# to the validation carried out at public APIs in all builds.
|
||||||
|
strict_asserts = ["wgc/strict_asserts", "wgt/strict_asserts"]
|
||||||
spirv = ["naga/spv-in"]
|
spirv = ["naga/spv-in"]
|
||||||
glsl = ["naga/glsl-in"]
|
glsl = ["naga/glsl-in"]
|
||||||
wgsl = ["wgc?/wgsl"]
|
wgsl = ["wgc?/wgsl"]
|
||||||
@ -148,10 +151,10 @@ raw-window-handle.workspace = true
|
|||||||
serde = { workspace = true, features = ["derive"], optional = true }
|
serde = { workspace = true, features = ["derive"], optional = true }
|
||||||
smallvec.workspace = true
|
smallvec.workspace = true
|
||||||
static_assertions.workspace = true
|
static_assertions.workspace = true
|
||||||
|
cfg-if.workspace = true
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
bitflags.workspace = true
|
bitflags.workspace = true
|
||||||
cfg-if.workspace = true
|
|
||||||
bytemuck = { workspace = true, features = ["derive"] }
|
bytemuck = { workspace = true, features = ["derive"] }
|
||||||
glam.workspace = true
|
glam.workspace = true
|
||||||
ddsfile.workspace = true
|
ddsfile.workspace = true
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@ -1,9 +1,9 @@
|
|||||||
#[cfg(all(target_arch = "wasm32", not(feature = "webgl")))]
|
#[cfg(all(target_arch = "wasm32", not(feature = "webgl")))]
|
||||||
mod web;
|
mod web;
|
||||||
#[cfg(all(target_arch = "wasm32", not(feature = "webgl")))]
|
#[cfg(all(target_arch = "wasm32", not(feature = "webgl")))]
|
||||||
pub(crate) use web::{BufferMappedRange, Context, QueueWriteBuffer};
|
pub(crate) use web::Context;
|
||||||
|
|
||||||
#[cfg(any(not(target_arch = "wasm32"), feature = "webgl"))]
|
#[cfg(any(not(target_arch = "wasm32"), feature = "webgl"))]
|
||||||
mod direct;
|
mod direct;
|
||||||
#[cfg(any(not(target_arch = "wasm32"), feature = "webgl"))]
|
#[cfg(any(not(target_arch = "wasm32"), feature = "webgl"))]
|
||||||
pub(crate) use direct::{BufferMappedRange, Context, QueueWriteBuffer};
|
pub(crate) use direct::Context;
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
3815
wgpu/src/context.rs
Normal file
3815
wgpu/src/context.rs
Normal file
File diff suppressed because it is too large
Load Diff
1619
wgpu/src/lib.rs
1619
wgpu/src/lib.rs
File diff suppressed because it is too large
Load Diff
@ -74,7 +74,10 @@ pub fn make_spirv_raw(data: &[u8]) -> Cow<[u32]> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// CPU accessible buffer used to download data back from the GPU.
|
/// CPU accessible buffer used to download data back from the GPU.
|
||||||
pub struct DownloadBuffer(Arc<super::Buffer>, super::BufferMappedRange);
|
pub struct DownloadBuffer(
|
||||||
|
Arc<super::Buffer>,
|
||||||
|
Box<dyn crate::context::BufferMappedRange>,
|
||||||
|
);
|
||||||
|
|
||||||
impl DownloadBuffer {
|
impl DownloadBuffer {
|
||||||
/// Asynchronously read the contents of a buffer.
|
/// Asynchronously read the contents of a buffer.
|
||||||
@ -111,9 +114,10 @@ impl DownloadBuffer {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let mapped_range = super::Context::buffer_get_mapped_range(
|
let mapped_range = super::DynContext::buffer_get_mapped_range(
|
||||||
&*download.context,
|
&*download.context,
|
||||||
&download.id,
|
&download.id,
|
||||||
|
download.data.as_ref(),
|
||||||
0..size,
|
0..size,
|
||||||
);
|
);
|
||||||
callback(Ok(Self(download, mapped_range)));
|
callback(Ok(Self(download, mapped_range)));
|
||||||
@ -124,7 +128,7 @@ impl DownloadBuffer {
|
|||||||
impl std::ops::Deref for DownloadBuffer {
|
impl std::ops::Deref for DownloadBuffer {
|
||||||
type Target = [u8];
|
type Target = [u8];
|
||||||
fn deref(&self) -> &[u8] {
|
fn deref(&self) -> &[u8] {
|
||||||
super::BufferMappedRangeSlice::slice(&self.1)
|
self.1.slice()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -94,7 +94,8 @@ fn double_wait_on_submission() {
|
|||||||
let cmd_buf = generate_dummy_work(&ctx);
|
let cmd_buf = generate_dummy_work(&ctx);
|
||||||
|
|
||||||
let index = ctx.queue.submit(Some(cmd_buf));
|
let index = ctx.queue.submit(Some(cmd_buf));
|
||||||
ctx.device.poll(Maintain::WaitForSubmissionIndex(index));
|
ctx.device
|
||||||
|
.poll(Maintain::WaitForSubmissionIndex(index.clone()));
|
||||||
ctx.device.poll(Maintain::WaitForSubmissionIndex(index));
|
ctx.device.poll(Maintain::WaitForSubmissionIndex(index));
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user