Skip to content

Commit

Permalink
Merge branch 'trunk' into objc2-metal
Browse files Browse the repository at this point in the history
  • Loading branch information
madsmtm authored May 23, 2024
2 parents 721d41c + b898cdf commit 50783c4
Show file tree
Hide file tree
Showing 18 changed files with 699 additions and 485 deletions.
5 changes: 2 additions & 3 deletions naga/src/front/spv/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -313,14 +313,14 @@ struct LookupVariable {
type_id: spirv::Word,
}

/// Information about SPIR-V result ids, stored in `Parser::lookup_expression`.
/// Information about SPIR-V result ids, stored in `Frontend::lookup_expression`.
#[derive(Clone, Debug)]
struct LookupExpression {
/// The `Expression` constructed for this result.
///
/// Note that, while a SPIR-V result id can be used in any block dominated
/// by its definition, a Naga `Expression` is only in scope for the rest of
/// its subtree. `Parser::get_expr_handle` takes care of spilling the result
/// its subtree. `Frontend::get_expr_handle` takes care of spilling the result
/// to a `LocalVariable` which can then be used anywhere.
handle: Handle<crate::Expression>,

Expand Down Expand Up @@ -578,7 +578,6 @@ pub struct Frontend<I> {
lookup_type: FastHashMap<spirv::Word, LookupType>,
lookup_void_type: Option<spirv::Word>,
lookup_storage_buffer_types: FastHashMap<Handle<crate::Type>, crate::StorageAccess>,
// Lookup for samplers and sampled images, storing flags on how they are used.
lookup_constant: FastHashMap<spirv::Word, LookupConstant>,
lookup_variable: FastHashMap<spirv::Word, LookupVariable>,
lookup_expression: FastHashMap<spirv::Word, LookupExpression>,
Expand Down
6 changes: 0 additions & 6 deletions rust-toolchain.toml
Original file line number Diff line number Diff line change
@@ -1,9 +1,3 @@
# If you see this, run "rustup self update" to get rustup 1.23 or newer.

# NOTE: above comment is for older `rustup` (before TOML support was added),
# which will treat the first line as the toolchain name, and therefore show it
# to the user in the error, instead of "error: invalid channel name '[toolchain]'".

[toolchain]
channel = "1.76" # Needed for deno & cts_runner. Firefox's MSRV is 1.74
components = ["rustfmt", "clippy"]
Expand Down
31 changes: 27 additions & 4 deletions tests/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,28 @@ pub use run::{execute_test, TestingContext};
pub use wgpu_macros::gpu_test;

/// Run some code in an error scope and assert that validation fails.
pub fn fail<T>(device: &wgpu::Device, callback: impl FnOnce() -> T) -> T {
pub fn fail<T>(
device: &wgpu::Device,
callback: impl FnOnce() -> T,
expected_msg_substring: Option<&'static str>,
) -> T {
device.push_error_scope(wgpu::ErrorFilter::Validation);
let result = callback();
assert!(pollster::block_on(device.pop_error_scope()).is_some());
let validation_error = pollster::block_on(device.pop_error_scope())
.expect("expected validation error in callback, but no validation error was emitted");
if let Some(expected_msg_substring) = expected_msg_substring {
let lowered_expected = expected_msg_substring.to_lowercase();
let lowered_actual = validation_error.to_string().to_lowercase();
assert!(
lowered_actual.contains(&lowered_expected),
concat!(
"expected validation error case-insensitively containing {:?}, ",
"but it was not present in actual error message:\n{:?}"
),
expected_msg_substring,
validation_error
);
}

result
}
Expand All @@ -46,9 +64,14 @@ pub fn valid<T>(device: &wgpu::Device, callback: impl FnOnce() -> T) -> T {

/// Run some code in an error scope and assert that validation succeeds or fails depending on the
/// provided `should_fail` boolean.
pub fn fail_if<T>(device: &wgpu::Device, should_fail: bool, callback: impl FnOnce() -> T) -> T {
pub fn fail_if<T>(
device: &wgpu::Device,
should_fail: bool,
callback: impl FnOnce() -> T,
expected_msg_substring: Option<&'static str>,
) -> T {
if should_fail {
fail(device, callback)
fail(device, callback, expected_msg_substring)
} else {
valid(device, callback)
}
Expand Down
20 changes: 14 additions & 6 deletions tests/tests/bind_group_layout_dedup.rs
Original file line number Diff line number Diff line change
Expand Up @@ -368,9 +368,13 @@ fn separate_programs_have_incompatible_derived_bgls(ctx: TestingContext) {
pass.set_bind_group(0, &bg2, &[]);
pass.dispatch_workgroups(1, 1, 1);

fail(&ctx.device, || {
drop(pass);
});
fail(
&ctx.device,
|| {
drop(pass);
},
None,
);
}

#[gpu_test]
Expand Down Expand Up @@ -436,7 +440,11 @@ fn derived_bgls_incompatible_with_regular_bgls(ctx: TestingContext) {
pass.set_bind_group(0, &bg, &[]);
pass.dispatch_workgroups(1, 1, 1);

fail(&ctx.device, || {
drop(pass);
})
fail(
&ctx.device,
|| {
drop(pass);
},
None,
)
}
104 changes: 56 additions & 48 deletions tests/tests/buffer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -217,17 +217,21 @@ static MINIMUM_BUFFER_BINDING_SIZE_LAYOUT: GpuTestConfiguration = GpuTestConfigu
push_constant_ranges: &[],
});

wgpu_test::fail(&ctx.device, || {
ctx.device
.create_compute_pipeline(&wgpu::ComputePipelineDescriptor {
label: None,
layout: Some(&pipeline_layout),
module: &shader_module,
entry_point: "main",
compilation_options: Default::default(),
cache: None,
});
});
wgpu_test::fail(
&ctx.device,
|| {
ctx.device
.create_compute_pipeline(&wgpu::ComputePipelineDescriptor {
label: None,
layout: Some(&pipeline_layout),
module: &shader_module,
entry_point: "main",
compilation_options: Default::default(),
cache: None,
});
},
None,
);
});

/// The WebGPU algorithm [validating shader binding][vsb] requires
Expand Down Expand Up @@ -314,21 +318,25 @@ static MINIMUM_BUFFER_BINDING_SIZE_DISPATCH: GpuTestConfiguration = GpuTestConfi
}],
});

wgpu_test::fail(&ctx.device, || {
let mut encoder = ctx.device.create_command_encoder(&Default::default());
wgpu_test::fail(
&ctx.device,
|| {
let mut encoder = ctx.device.create_command_encoder(&Default::default());

let mut pass = encoder.begin_compute_pass(&wgpu::ComputePassDescriptor {
label: None,
timestamp_writes: None,
});
let mut pass = encoder.begin_compute_pass(&wgpu::ComputePassDescriptor {
label: None,
timestamp_writes: None,
});

pass.set_bind_group(0, &bind_group, &[]);
pass.set_pipeline(&pipeline);
pass.dispatch_workgroups(1, 1, 1);
pass.set_bind_group(0, &bind_group, &[]);
pass.set_pipeline(&pipeline);
pass.dispatch_workgroups(1, 1, 1);

drop(pass);
let _ = encoder.finish();
});
drop(pass);
let _ = encoder.finish();
},
None,
);
});

#[gpu_test]
Expand All @@ -346,16 +354,15 @@ static CLEAR_OFFSET_OUTSIDE_RESOURCE_BOUNDS: GpuTestConfiguration = GpuTestConfi

let out_of_bounds = size.checked_add(wgpu::COPY_BUFFER_ALIGNMENT).unwrap();

ctx.device.push_error_scope(wgpu::ErrorFilter::Validation);
ctx.device
.create_command_encoder(&Default::default())
.clear_buffer(&buffer, out_of_bounds, None);
let err_msg = pollster::block_on(ctx.device.pop_error_scope())
.unwrap()
.to_string();
assert!(err_msg.contains(
"Clear of 20..20 would end up overrunning the bounds of the buffer of size 16"
));
wgpu_test::fail(
&ctx.device,
|| {
ctx.device
.create_command_encoder(&Default::default())
.clear_buffer(&buffer, out_of_bounds, None)
},
Some("Clear of 20..20 would end up overrunning the bounds of the buffer of size 16"),
);
});

#[gpu_test]
Expand All @@ -373,19 +380,20 @@ static CLEAR_OFFSET_PLUS_SIZE_OUTSIDE_U64_BOUNDS: GpuTestConfiguration =
let max_valid_offset = u64::MAX - (u64::MAX % wgpu::COPY_BUFFER_ALIGNMENT);
let smallest_aligned_invalid_size = wgpu::COPY_BUFFER_ALIGNMENT;

ctx.device.push_error_scope(wgpu::ErrorFilter::Validation);
ctx.device
.create_command_encoder(&Default::default())
.clear_buffer(
&buffer,
max_valid_offset,
Some(smallest_aligned_invalid_size),
);
let err_msg = pollster::block_on(ctx.device.pop_error_scope())
.unwrap()
.to_string();
assert!(err_msg.contains(concat!(
"Clear starts at offset 18446744073709551612 with size of 4, ",
"but these added together exceed `u64::MAX`"
)));
wgpu_test::fail(
&ctx.device,
|| {
ctx.device
.create_command_encoder(&Default::default())
.clear_buffer(
&buffer,
max_valid_offset,
Some(smallest_aligned_invalid_size),
)
},
Some(concat!(
"Clear starts at offset 18446744073709551612 with size of 4, ",
"but these added together exceed `u64::MAX`"
)),
);
});
9 changes: 6 additions & 3 deletions tests/tests/buffer_copy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,12 @@ fn try_copy(
) {
let buffer = ctx.device.create_buffer(&BUFFER_DESCRIPTOR);
let data = vec![255; size as usize];
fail_if(&ctx.device, should_fail, || {
ctx.queue.write_buffer(&buffer, offset, &data)
});
fail_if(
&ctx.device,
should_fail,
|| ctx.queue.write_buffer(&buffer, offset, &data),
None,
);
}

#[gpu_test]
Expand Down
53 changes: 34 additions & 19 deletions tests/tests/buffer_usages.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,14 +31,19 @@ fn try_create(ctx: TestingContext, usages: &[(bool, &[wgpu::BufferUsages])]) {
.iter()
.flat_map(|&(expect_error, usages)| usages.iter().copied().map(move |u| (expect_error, u)))
{
fail_if(&ctx.device, expect_validation_error, || {
let _buffer = ctx.device.create_buffer(&wgpu::BufferDescriptor {
label: None,
size: BUFFER_SIZE,
usage,
mapped_at_creation: false,
});
});
fail_if(
&ctx.device,
expect_validation_error,
|| {
let _buffer = ctx.device.create_buffer(&wgpu::BufferDescriptor {
label: None,
size: BUFFER_SIZE,
usage,
mapped_at_creation: false,
});
},
None,
);
}
}

Expand Down Expand Up @@ -89,14 +94,19 @@ async fn map_test(

let mut buffer = None;

fail_if(&ctx.device, buffer_creation_validation_error, || {
buffer = Some(ctx.device.create_buffer(&wgpu::BufferDescriptor {
label: None,
size,
usage,
mapped_at_creation: false,
}));
});
fail_if(
&ctx.device,
buffer_creation_validation_error,
|| {
buffer = Some(ctx.device.create_buffer(&wgpu::BufferDescriptor {
label: None,
size,
usage,
mapped_at_creation: false,
}));
},
None,
);
if buffer_creation_validation_error {
return;
}
Expand All @@ -107,9 +117,14 @@ async fn map_test(
|| (map_mode_type == Ma::Read && !usage.contains(Bu::MAP_READ))
|| (map_mode_type == Ma::Write && !usage.contains(Bu::MAP_WRITE));

fail_if(&ctx.device, map_async_validation_error, || {
buffer.slice(0..size).map_async(map_mode_type, |_| {});
});
fail_if(
&ctx.device,
map_async_validation_error,
|| {
buffer.slice(0..size).map_async(map_mode_type, |_| {});
},
None,
);

if map_async_validation_error {
return;
Expand Down
Loading

0 comments on commit 50783c4

Please sign in to comment.