Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
d935b78
Move `set_buffer_data` and `get_mapped_range` out of `Global`
andyleiserson Sep 29, 2025
179a276
Move `surface_configure` out of `Global`
andyleiserson Oct 2, 2025
d6156a8
Move start/stop debugger capture out of Global
andyleiserson Oct 2, 2025
94cc67e
Add ReferenceType trait for command structures
andyleiserson Sep 25, 2025
3664e75
Create submodule of `device::trace` for recording support
andyleiserson Oct 2, 2025
510baed
Store pointers instead of IDs when tracing (1/2)
andyleiserson Sep 25, 2025
b660760
Store pointers instead of IDs when tracing (2/2)
andyleiserson Oct 1, 2025
f66ab87
Replay traces with pointers as IDs
andyleiserson Sep 29, 2025
13d3740
Clean up device poll API
andyleiserson Oct 23, 2025
be2b30d
Fix debugger capture
andyleiserson Oct 3, 2025
ccb155f
Restore `PointerId(...)` serialized representation
andyleiserson Oct 3, 2025
54a2a4f
Fix Free* operations
andyleiserson Oct 3, 2025
2ccb2c8
Fix get_mapped_range duplication
andyleiserson Oct 22, 2025
4ce4630
Condition macro_rules_attribute dev-dependency on serde feature
andyleiserson Oct 22, 2025
10ed0c4
Remove redundant device validity check and inaccurate comment
andyleiserson Oct 22, 2025
b2c7322
Clarify comment about Arc::as_ptr
andyleiserson Oct 22, 2025
8394c48
Remove stale attributes
andyleiserson Oct 22, 2025
568125f
Fix serde feature gating
andyleiserson Oct 22, 2025
eeb5fe1
Remove get_buffer alias of resolve_buffer_id
andyleiserson Oct 23, 2025
76b32cf
Store failed commands in traces
andyleiserson Oct 23, 2025
6eb6805
Add in-memory tracing and inline data in traces
andyleiserson Aug 1, 2025
73203b7
Tracing tests
andyleiserson Oct 24, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 23 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,7 @@ libloading = "0.8"
libm = { version = "0.2.6", default-features = false }
libtest-mimic = "0.8"
log = "0.4.21"
macro_rules_attribute = "0.2"
nanoserde = "0.2"
nanorand = { version = "0.8", default-features = false, features = ["wyrand"] }
noise = "0.9"
Expand Down
7 changes: 2 additions & 5 deletions deno_webgpu/device.rs
Original file line number Diff line number Diff line change
Expand Up @@ -577,11 +577,8 @@ impl GPUDevice {
multiview: None,
};

let res = wgpu_core::command::RenderBundleEncoder::new(
&wgpu_descriptor,
self.id,
None,
);
let res =
wgpu_core::command::RenderBundleEncoder::new(&wgpu_descriptor, self.id);
let (encoder, err) = match res {
Ok(encoder) => (encoder, None),
Err(e) => (
Expand Down
17 changes: 13 additions & 4 deletions docs/testing.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ This is a table of contents, in the form of the repository's directory structure
- [compile](#wgpu-compile-tests)
- [dependency](#wgpu-dependency-tests)
- [gpu](#wgpu-gpu-tests)
- [trace](#wgpu-trace-tests)
- [validation](#wgpu-validation-tests)

And where applicable [unit-tests](#unit-tests)
Expand Down Expand Up @@ -101,7 +102,7 @@ There are inputs in `wgsl`, `spirv`, and `glsl`. There are outputs for
`hlsl`, `spirv`, `wgsl`, `msl`, `glsl`, and naga's internal IR. The tests
can be configured by a sidecar toml file of the same name as the input file.

This is the goto tool for testing all kinds of codegen and parsing features.
This is the goto tool for testing all kinds of codegen and parsing features.

To avoid clutter we generally use the following pattern:

Expand Down Expand Up @@ -142,7 +143,7 @@ the [wgsl errors](#naga-wgsl-error-tests) tests.

These are tests for the error messages that the `wgsl` frontend
produces. Additionally you can check that a given validation error
is produced by the validator from a given `wgsl` snippet.
is produced by the validator from a given `wgsl` snippet.

## `player` Tests

Expand Down Expand Up @@ -207,14 +208,23 @@ Normal `#[test]`s will not be found in this test crate, as we use a custom harne

See also the [example tests](#example-tests) for additional GPU tests.

## `wgpu` Trace Tests

- Located in: `tests/tests/wgpu_trace.rs`
- Run with `cargo nextest run --test wgpu_trace`
- Use the standard `#[test]` harness.

These tests are focused on testing the tracing functionality in `wgpu`. They
use the a special `noop` backend which does not connect to a real GPU.

## `wgpu` Validation Tests

- Located in: `tests/tests/wgpu-validation`
- Run with `cargo nextest run --test wgpu-validation`
- Use the standard `#[test]` harness.
- `wgpu` integration tests, with access to `wgpu_test` helpers.

These tests are focused on testing the validation inside of `wgpu-core`.
These tests are focused on testing the validation inside of `wgpu-core`.
They are written against the `wgpu` API, but are targeting a special `noop`
backend which does not connect to a real GPU.

Expand All @@ -230,4 +240,3 @@ does not support those features.

Throughout the codebase we have standard `#[test]`s that test individual
functions or small parts of the codebase. These don't run on the gpu.

1 change: 1 addition & 0 deletions player/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ test = false
wgpu-types = { workspace = true, features = ["serde", "std"] }

env_logger.workspace = true
hashbrown.workspace = true
log.workspace = true
raw-window-handle.workspace = true
ron.workspace = true
Expand Down
102 changes: 43 additions & 59 deletions player/src/bin/play.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,15 @@ fn main() {
extern crate wgpu_core as wgc;
extern crate wgpu_types as wgt;

use player::GlobalPlay as _;
use player::Player;
use wgc::device::trace;
use wgpu_core::identity::IdentityManager;
use wgpu_core::command::PointerReferences;

use std::{
fs,
path::{Path, PathBuf},
process::exit,
sync::Arc,
};

#[cfg(feature = "winit")]
Expand Down Expand Up @@ -52,7 +53,7 @@ fn main() {

log::info!("Loading trace '{trace:?}'");
let file = fs::File::open(trace).unwrap();
let mut actions: Vec<trace::Action> = ron::de::from_reader(file).unwrap();
let mut actions: Vec<trace::Action<PointerReferences>> = ron::de::from_reader(file).unwrap();
actions.reverse(); // allows us to pop from the top
log::info!("Found {} actions", actions.len());

Expand All @@ -68,17 +69,14 @@ fn main() {
.build(&event_loop)
.unwrap();

let global =
wgc::global::Global::new("player", &wgt::InstanceDescriptor::from_env_or_default());
let mut command_encoder_id_manager = IdentityManager::new();
let mut command_buffer_id_manager = IdentityManager::new();
let instance_desc = wgt::InstanceDescriptor::from_env_or_default();
let instance = wgc::instance::Instance::new("player", &instance_desc);

#[cfg(feature = "winit")]
let surface = unsafe {
global.instance_create_surface(
instance.create_surface(
window.display_handle().unwrap().into(),
window.window_handle().unwrap().into(),
Some(wgc::id::Id::zip(0, 1)),
)
}
.unwrap();
Expand All @@ -93,50 +91,41 @@ fn main() {
None => (wgt::Backends::all(), wgt::DeviceDescriptor::default()),
};

let adapter = global
.request_adapter(
&wgc::instance::RequestAdapterOptions {
#[cfg(feature = "winit")]
compatible_surface: Some(surface),
#[cfg(not(feature = "winit"))]
compatible_surface: None,
..Default::default()
},
backends,
Some(wgc::id::AdapterId::zip(0, 1)),
)
.expect("Unable to obtain an adapter");

let info = global.adapter_get_info(adapter);
let adapter = Arc::new(
instance
.request_adapter(
&wgt::RequestAdapterOptions {
#[cfg(feature = "winit")]
compatible_surface: Some(&surface),
#[cfg(not(feature = "winit"))]
compatible_surface: None,
..Default::default()
},
backends,
)
.expect("Unable to obtain an adapter"),
);

let info = adapter.get_info();
log::info!("Using '{}'", info.name);

let device = wgc::id::Id::zip(0, 1);
let queue = wgc::id::Id::zip(0, 1);
let res = global.adapter_request_device(adapter, &device_desc, Some(device), Some(queue));
if let Err(e) = res {
panic!("{e:?}");
}
let (device, queue) = adapter
.create_device_and_queue(&device_desc, instance_desc.flags)
.unwrap();

let mut player = Player::default();

log::info!("Executing actions");
#[cfg(not(feature = "winit"))]
{
unsafe { global.device_start_graphics_debugger_capture(device) };
unsafe { device.start_graphics_debugger_capture() };

while let Some(action) = actions.pop() {
global.process(
device,
queue,
action,
&dir,
&mut command_encoder_id_manager,
&mut command_buffer_id_manager,
);
player.process(&device, &queue, action, trace::DiskTraceLoader::new(&dir));
}

unsafe { global.device_stop_graphics_debugger_capture(device) };
global
.device_poll(device, wgt::PollType::wait_indefinitely())
.unwrap();
unsafe { device.stop_graphics_debugger_capture() };
device.poll(wgt::PollType::wait_indefinitely()).unwrap();
}
#[cfg(feature = "winit")]
{
Expand Down Expand Up @@ -170,32 +159,29 @@ fn main() {
resize_config = Some(config);
target.exit();
} else {
let error =
global.surface_configure(surface, device, &config);
let error = device.configure_surface(&surface, &config);
if let Some(e) = error {
panic!("{e:?}");
}
}
}
Some(trace::Action::Present(id)) => {
Some(trace::Action::Present(_id)) => {
frame_count += 1;
log::debug!("Presenting frame {frame_count}");
global.surface_present(id).unwrap();
surface.present().unwrap();
target.exit();
}
Some(trace::Action::DiscardSurfaceTexture(id)) => {
Some(trace::Action::DiscardSurfaceTexture(_id)) => {
log::debug!("Discarding frame {frame_count}");
global.surface_texture_discard(id).unwrap();
surface.discard().unwrap();
target.exit();
}
Some(action) => {
global.process(
device,
queue,
player.process(
&device,
&queue,
action,
&dir,
&mut command_encoder_id_manager,
&mut command_buffer_id_manager,
trace::DiskTraceLoader::new(&dir),
);
}
None => {
Expand All @@ -209,7 +195,7 @@ fn main() {
}
WindowEvent::Resized(_) => {
if let Some(config) = resize_config.take() {
let error = global.surface_configure(surface, device, &config);
let error = device.configure_surface(&surface, &config);
if let Some(e) = error {
panic!("{e:?}");
}
Expand All @@ -229,9 +215,7 @@ fn main() {
},
Event::LoopExiting => {
log::info!("Closing");
global
.device_poll(device, wgt::PollType::wait_indefinitely())
.unwrap();
device.poll(wgt::PollType::wait_indefinitely()).unwrap();
}
_ => {}
}
Expand Down
Loading
Loading