diff --git a/naga/src/front/spv/mod.rs b/naga/src/front/spv/mod.rs index 2b97da46c5a..12610083a4d 100644 --- a/naga/src/front/spv/mod.rs +++ b/naga/src/front/spv/mod.rs @@ -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, @@ -578,7 +578,6 @@ pub struct Frontend { lookup_type: FastHashMap, lookup_void_type: Option, lookup_storage_buffer_types: FastHashMap, crate::StorageAccess>, - // Lookup for samplers and sampled images, storing flags on how they are used. lookup_constant: FastHashMap, lookup_variable: FastHashMap, lookup_expression: FastHashMap, diff --git a/rust-toolchain.toml b/rust-toolchain.toml index 642513ae4e1..aa10fa14ebe 100644 --- a/rust-toolchain.toml +++ b/rust-toolchain.toml @@ -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"] diff --git a/tests/src/lib.rs b/tests/src/lib.rs index 9df1edfd76c..fcc16158754 100644 --- a/tests/src/lib.rs +++ b/tests/src/lib.rs @@ -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(device: &wgpu::Device, callback: impl FnOnce() -> T) -> T { +pub fn fail( + 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 } @@ -46,9 +64,14 @@ pub fn valid(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(device: &wgpu::Device, should_fail: bool, callback: impl FnOnce() -> T) -> T { +pub fn fail_if( + 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) } diff --git a/tests/tests/bind_group_layout_dedup.rs b/tests/tests/bind_group_layout_dedup.rs index 3d74e62cba1..e4262ea2155 100644 --- a/tests/tests/bind_group_layout_dedup.rs +++ b/tests/tests/bind_group_layout_dedup.rs @@ -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] @@ -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, + ) } diff --git a/tests/tests/buffer.rs b/tests/tests/buffer.rs index 24102673152..e2316daadce 100644 --- a/tests/tests/buffer.rs +++ b/tests/tests/buffer.rs @@ -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 @@ -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] @@ -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] @@ -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`" + )), + ); }); diff --git a/tests/tests/buffer_copy.rs b/tests/tests/buffer_copy.rs index 9733255ba64..698097f1b62 100644 --- a/tests/tests/buffer_copy.rs +++ b/tests/tests/buffer_copy.rs @@ -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] diff --git a/tests/tests/buffer_usages.rs b/tests/tests/buffer_usages.rs index d002b8f074f..e0cadeed8a5 100644 --- a/tests/tests/buffer_usages.rs +++ b/tests/tests/buffer_usages.rs @@ -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, + ); } } @@ -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; } @@ -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; diff --git a/tests/tests/device.rs b/tests/tests/device.rs index 3e782932965..e2ed9f5b60d 100644 --- a/tests/tests/device.rs +++ b/tests/tests/device.rs @@ -298,224 +298,317 @@ static DEVICE_DESTROY_THEN_MORE: GpuTestConfiguration = GpuTestConfiguration::ne // the device is not valid. // Creating a command encoder should fail. - fail(&ctx.device, || { - ctx.device - .create_command_encoder(&wgpu::CommandEncoderDescriptor::default()); - }); + fail( + &ctx.device, + || { + ctx.device + .create_command_encoder(&wgpu::CommandEncoderDescriptor::default()); + }, + None, + ); // Creating a buffer should fail. - fail(&ctx.device, || { - ctx.device.create_buffer(&wgpu::BufferDescriptor { - label: None, - size: 256, - usage: wgpu::BufferUsages::MAP_WRITE | wgpu::BufferUsages::COPY_SRC, - mapped_at_creation: false, - }); - }); + fail( + &ctx.device, + || { + ctx.device.create_buffer(&wgpu::BufferDescriptor { + label: None, + size: 256, + usage: wgpu::BufferUsages::MAP_WRITE | wgpu::BufferUsages::COPY_SRC, + mapped_at_creation: false, + }); + }, + None, + ); // Creating a texture should fail. - fail(&ctx.device, || { - ctx.device.create_texture(&wgpu::TextureDescriptor { - label: None, - size: wgpu::Extent3d { - width: 512, - height: 512, - depth_or_array_layers: 1, - }, - mip_level_count: 2, - sample_count: 1, - dimension: wgpu::TextureDimension::D2, - format: wgpu::TextureFormat::Rg8Uint, - usage: wgpu::TextureUsages::COPY_SRC, - view_formats: &[], - }); - }); + fail( + &ctx.device, + || { + ctx.device.create_texture(&wgpu::TextureDescriptor { + label: None, + size: wgpu::Extent3d { + width: 512, + height: 512, + depth_or_array_layers: 1, + }, + mip_level_count: 2, + sample_count: 1, + dimension: wgpu::TextureDimension::D2, + format: wgpu::TextureFormat::Rg8Uint, + usage: wgpu::TextureUsages::COPY_SRC, + view_formats: &[], + }); + }, + None, + ); // Texture clear should fail. - fail(&ctx.device, || { - encoder_for_clear.clear_texture( - &texture_for_write, - &wgpu::ImageSubresourceRange { - aspect: wgpu::TextureAspect::All, - base_mip_level: 0, - mip_level_count: None, - base_array_layer: 0, - array_layer_count: None, - }, - ); - }); + fail( + &ctx.device, + || { + encoder_for_clear.clear_texture( + &texture_for_write, + &wgpu::ImageSubresourceRange { + aspect: wgpu::TextureAspect::All, + base_mip_level: 0, + mip_level_count: None, + base_array_layer: 0, + array_layer_count: None, + }, + ); + }, + None, + ); // Creating a compute pass should fail. - fail(&ctx.device, || { - encoder_for_compute_pass.begin_compute_pass(&wgpu::ComputePassDescriptor { - label: None, - timestamp_writes: None, - }); - }); + fail( + &ctx.device, + || { + encoder_for_compute_pass.begin_compute_pass(&wgpu::ComputePassDescriptor { + label: None, + timestamp_writes: None, + }); + }, + None, + ); // Creating a render pass should fail. - fail(&ctx.device, || { - encoder_for_render_pass.begin_render_pass(&wgpu::RenderPassDescriptor { - label: None, - color_attachments: &[Some(wgpu::RenderPassColorAttachment { - ops: wgpu::Operations::default(), - resolve_target: None, - view: &target_view, - })], - depth_stencil_attachment: None, - timestamp_writes: None, - occlusion_query_set: None, - }); - }); + fail( + &ctx.device, + || { + encoder_for_render_pass.begin_render_pass(&wgpu::RenderPassDescriptor { + label: None, + color_attachments: &[Some(wgpu::RenderPassColorAttachment { + ops: wgpu::Operations::default(), + resolve_target: None, + view: &target_view, + })], + depth_stencil_attachment: None, + timestamp_writes: None, + occlusion_query_set: None, + }); + }, + None, + ); // Copying a buffer to a buffer should fail. - fail(&ctx.device, || { - encoder_for_buffer_buffer_copy.copy_buffer_to_buffer( - &buffer_source, - 0, - &buffer_dest, - 0, - 256, - ); - }); + fail( + &ctx.device, + || { + encoder_for_buffer_buffer_copy.copy_buffer_to_buffer( + &buffer_source, + 0, + &buffer_dest, + 0, + 256, + ); + }, + None, + ); // Copying a buffer to a texture should fail. - fail(&ctx.device, || { - encoder_for_buffer_texture_copy.copy_buffer_to_texture( - wgpu::ImageCopyBuffer { - buffer: &buffer_source, - layout: wgpu::ImageDataLayout { - offset: 0, - bytes_per_row: Some(4), - rows_per_image: None, + fail( + &ctx.device, + || { + encoder_for_buffer_texture_copy.copy_buffer_to_texture( + wgpu::ImageCopyBuffer { + buffer: &buffer_source, + layout: wgpu::ImageDataLayout { + offset: 0, + bytes_per_row: Some(4), + rows_per_image: None, + }, }, - }, - texture_for_write.as_image_copy(), - texture_extent, - ); - }); + texture_for_write.as_image_copy(), + texture_extent, + ); + }, + None, + ); // Copying a texture to a buffer should fail. - fail(&ctx.device, || { - encoder_for_texture_buffer_copy.copy_texture_to_buffer( - texture_for_read.as_image_copy(), - wgpu::ImageCopyBuffer { - buffer: &buffer_source, - layout: wgpu::ImageDataLayout { - offset: 0, - bytes_per_row: Some(4), - rows_per_image: None, + fail( + &ctx.device, + || { + encoder_for_texture_buffer_copy.copy_texture_to_buffer( + texture_for_read.as_image_copy(), + wgpu::ImageCopyBuffer { + buffer: &buffer_source, + layout: wgpu::ImageDataLayout { + offset: 0, + bytes_per_row: Some(4), + rows_per_image: None, + }, }, - }, - texture_extent, - ); - }); + texture_extent, + ); + }, + None, + ); // Copying a texture to a texture should fail. - fail(&ctx.device, || { - encoder_for_texture_texture_copy.copy_texture_to_texture( - texture_for_read.as_image_copy(), - texture_for_write.as_image_copy(), - texture_extent, - ); - }); + fail( + &ctx.device, + || { + encoder_for_texture_texture_copy.copy_texture_to_texture( + texture_for_read.as_image_copy(), + texture_for_write.as_image_copy(), + texture_extent, + ); + }, + None, + ); // Creating a bind group layout should fail. - fail(&ctx.device, || { - ctx.device - .create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor { - label: None, - entries: &[], - }); - }); + fail( + &ctx.device, + || { + ctx.device + .create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor { + label: None, + entries: &[], + }); + }, + None, + ); // Creating a bind group should fail. - fail(&ctx.device, || { - ctx.device.create_bind_group(&wgpu::BindGroupDescriptor { - label: None, - layout: &bind_group_layout, - entries: &[wgpu::BindGroupEntry { - binding: 0, - resource: wgpu::BindingResource::Buffer( - buffer_source.as_entire_buffer_binding(), - ), - }], - }); - }); - - // Creating a pipeline layout should fail. - fail(&ctx.device, || { - ctx.device - .create_pipeline_layout(&wgpu::PipelineLayoutDescriptor { + fail( + &ctx.device, + || { + ctx.device.create_bind_group(&wgpu::BindGroupDescriptor { label: None, - bind_group_layouts: &[], - push_constant_ranges: &[], + layout: &bind_group_layout, + entries: &[wgpu::BindGroupEntry { + binding: 0, + resource: wgpu::BindingResource::Buffer( + buffer_source.as_entire_buffer_binding(), + ), + }], }); - }); + }, + None, + ); + + // Creating a pipeline layout should fail. + fail( + &ctx.device, + || { + ctx.device + .create_pipeline_layout(&wgpu::PipelineLayoutDescriptor { + label: None, + bind_group_layouts: &[], + push_constant_ranges: &[], + }); + }, + None, + ); // Creating a shader module should fail. - fail(&ctx.device, || { - ctx.device - .create_shader_module(wgpu::ShaderModuleDescriptor { - label: None, - source: wgpu::ShaderSource::Wgsl(std::borrow::Cow::Borrowed("")), - }); - }); + fail( + &ctx.device, + || { + ctx.device + .create_shader_module(wgpu::ShaderModuleDescriptor { + label: None, + source: wgpu::ShaderSource::Wgsl(std::borrow::Cow::Borrowed("")), + }); + }, + None, + ); // Creating a shader module spirv should fail. - fail(&ctx.device, || unsafe { - ctx.device - .create_shader_module_spirv(&wgpu::ShaderModuleDescriptorSpirV { - label: None, - source: std::borrow::Cow::Borrowed(&[]), - }); - }); + fail( + &ctx.device, + || unsafe { + ctx.device + .create_shader_module_spirv(&wgpu::ShaderModuleDescriptorSpirV { + label: None, + source: std::borrow::Cow::Borrowed(&[]), + }); + }, + None, + ); // Creating a render pipeline should fail. - fail(&ctx.device, || { - ctx.device - .create_render_pipeline(&wgpu::RenderPipelineDescriptor { - label: None, - layout: None, - vertex: wgpu::VertexState { + fail( + &ctx.device, + || { + ctx.device + .create_render_pipeline(&wgpu::RenderPipelineDescriptor { + label: None, + layout: None, + vertex: wgpu::VertexState { + module: &shader_module, + entry_point: "", + compilation_options: Default::default(), + buffers: &[], + }, + primitive: wgpu::PrimitiveState::default(), + depth_stencil: None, + multisample: wgpu::MultisampleState::default(), + fragment: None, + multiview: None, + cache: None, + }); + }, + None, + ); + + // Creating a compute pipeline should fail. + fail( + &ctx.device, + || { + ctx.device + .create_compute_pipeline(&wgpu::ComputePipelineDescriptor { + label: None, + layout: None, module: &shader_module, entry_point: "", compilation_options: Default::default(), - buffers: &[], - }, - primitive: wgpu::PrimitiveState::default(), - depth_stencil: None, - multisample: wgpu::MultisampleState::default(), - fragment: None, - multiview: None, - cache: None, - }); - }); + cache: None, + }); + }, + None, + ); // Creating a compute pipeline should fail. - fail(&ctx.device, || { - ctx.device - .create_compute_pipeline(&wgpu::ComputePipelineDescriptor { - label: None, - layout: None, - module: &shader_module, - entry_point: "", - compilation_options: Default::default(), - cache: None, - }); - }); + fail( + &ctx.device, + || { + ctx.device + .create_compute_pipeline(&wgpu::ComputePipelineDescriptor { + label: None, + layout: None, + module: &shader_module, + entry_point: "", + compilation_options: Default::default(), + cache: None, + }); + }, + None, + ); // Buffer map should fail. - fail(&ctx.device, || { - buffer_for_map - .slice(..) - .map_async(wgpu::MapMode::Write, |_| ()); - }); + fail( + &ctx.device, + || { + buffer_for_map + .slice(..) + .map_async(wgpu::MapMode::Write, |_| ()); + }, + None, + ); // Buffer unmap should fail. - fail(&ctx.device, || { - buffer_for_unmap.unmap(); - }); + fail( + &ctx.device, + || { + buffer_for_unmap.unmap(); + }, + None, + ); }); #[gpu_test] @@ -677,21 +770,22 @@ static DIFFERENT_BGL_ORDER_BW_SHADER_AND_API: GpuTestConfiguration = GpuTestConf // resource type) in the wrong list of a different resource type. Let's reproduce that // here. - let trivial_shaders_with_some_reversed_bindings = "\ -@group(0) @binding(3) var myTexture2: texture_2d; -@group(0) @binding(2) var myTexture1: texture_2d; -@group(0) @binding(1) var mySampler: sampler; - -@fragment -fn fs_main(@builtin(position) pos: vec4) -> @location(0) vec4f { - return textureSample(myTexture1, mySampler, pos.xy) + textureSample(myTexture2, mySampler, pos.xy); -} - -@vertex -fn vs_main() -> @builtin(position) vec4 { - return vec4(0.0, 0.0, 0.0, 1.0); -} -"; + let trivial_shaders_with_some_reversed_bindings = concat!( + "@group(0) @binding(3) var myTexture2: texture_2d;\n", + "@group(0) @binding(2) var myTexture1: texture_2d;\n", + "@group(0) @binding(1) var mySampler: sampler;\n", + "\n", + "@fragment\n", + "fn fs_main(@builtin(position) pos: vec4) -> @location(0) vec4f {\n", + " return textureSample(myTexture1, mySampler, pos.xy) \n", + " + textureSample(myTexture2, mySampler, pos.xy);\n", + "}\n", + "\n", + "@vertex\n", + "fn vs_main() -> @builtin(position) vec4 {\n", + " return vec4(0.0, 0.0, 0.0, 1.0);\n", + "}\n", + ); let trivial_shaders_with_some_reversed_bindings = ctx.device @@ -759,7 +853,7 @@ fn vs_main() -> @builtin(position) vec4 { depth_stencil: None, multisample: wgt::MultisampleState::default(), multiview: None, - cache: None + cache: None, }); // fail(&ctx.device, || { diff --git a/tests/tests/encoder.rs b/tests/tests/encoder.rs index 3858e3d0703..83f575c4c82 100644 --- a/tests/tests/encoder.rs +++ b/tests/tests/encoder.rs @@ -58,10 +58,14 @@ static DROP_ENCODER_AFTER_ERROR: GpuTestConfiguration = GpuTestConfiguration::ne }); // Set a bad viewport on renderpass, triggering an error. - fail(&ctx.device, || { - renderpass.set_viewport(0.0, 0.0, -1.0, -1.0, 0.0, 1.0); - drop(renderpass); - }); + fail( + &ctx.device, + || { + renderpass.set_viewport(0.0, 0.0, -1.0, -1.0, 0.0, 1.0); + drop(renderpass); + }, + None, + ); // This is the actual interesting error condition. We've created // a CommandEncoder which errored out when processing a command. diff --git a/tests/tests/external_texture.rs b/tests/tests/external_texture.rs index 44517b91c3c..6dba884a338 100644 --- a/tests/tests/external_texture.rs +++ b/tests/tests/external_texture.rs @@ -264,24 +264,29 @@ static IMAGE_BITMAP_IMPORT: GpuTestConfiguration = view_formats: &[], }); - fail_if(&ctx.device, !valid, || { - ctx.queue.copy_external_image_to_texture( - &wgpu::ImageCopyExternalImage { - source: source.clone(), - origin: src_origin, - flip_y: src_flip_y, - }, - wgpu::ImageCopyTextureTagged { - texture: &texture, - mip_level: 0, - origin: dest_origin, - aspect: wgpu::TextureAspect::All, - color_space: dest_color_space, - premultiplied_alpha: dest_premultiplied, - }, - copy_size, - ); - }); + fail_if( + &ctx.device, + !valid, + || { + ctx.queue.copy_external_image_to_texture( + &wgpu::ImageCopyExternalImage { + source: source.clone(), + origin: src_origin, + flip_y: src_flip_y, + }, + wgpu::ImageCopyTextureTagged { + texture: &texture, + mip_level: 0, + origin: dest_origin, + aspect: wgpu::TextureAspect::All, + color_space: dest_color_space, + premultiplied_alpha: dest_premultiplied, + }, + copy_size, + ); + }, + None, + ); let readback_buffer = ctx.device.create_buffer(&wgpu::BufferDescriptor { label: Some("readback buffer"), diff --git a/tests/tests/float32_filterable.rs b/tests/tests/float32_filterable.rs index c170deda9b3..ee288ac799a 100644 --- a/tests/tests/float32_filterable.rs +++ b/tests/tests/float32_filterable.rs @@ -58,9 +58,13 @@ static FLOAT32_FILTERABLE_WITHOUT_FEATURE: GpuTestConfiguration = GpuTestConfigu // Float 32 textures can be used as non-filterable only create_texture_binding(device, wgpu::TextureFormat::R32Float, false); // This is supposed to fail, since we have not activated the feature - fail(&ctx.device, || { - create_texture_binding(device, wgpu::TextureFormat::R32Float, true); - }); + fail( + &ctx.device, + || { + create_texture_binding(device, wgpu::TextureFormat::R32Float, true); + }, + None, + ); }); #[gpu_test] diff --git a/tests/tests/life_cycle.rs b/tests/tests/life_cycle.rs index e4654024316..e959743a599 100644 --- a/tests/tests/life_cycle.rs +++ b/tests/tests/life_cycle.rs @@ -18,11 +18,15 @@ static BUFFER_DESTROY: GpuTestConfiguration = .await .panic_on_timeout(); - fail(&ctx.device, || { - buffer - .slice(..) - .map_async(wgpu::MapMode::Write, move |_| {}); - }); + fail( + &ctx.device, + || { + buffer + .slice(..) + .map_async(wgpu::MapMode::Write, move |_| {}); + }, + None, + ); buffer.destroy(); diff --git a/tests/tests/nv12_texture/mod.rs b/tests/tests/nv12_texture/mod.rs index fa386f86539..6b5a4e0c6b3 100644 --- a/tests/tests/nv12_texture/mod.rs +++ b/tests/tests/nv12_texture/mod.rs @@ -141,12 +141,16 @@ static NV12_TEXTURE_VIEW_PLANE_ON_NON_PLANAR_FORMAT: GpuTestConfiguration = sample_count: 1, view_formats: &[], }); - fail(&ctx.device, || { - let _ = tex.create_view(&wgpu::TextureViewDescriptor { - aspect: wgpu::TextureAspect::Plane0, - ..Default::default() - }); - }); + fail( + &ctx.device, + || { + let _ = tex.create_view(&wgpu::TextureViewDescriptor { + aspect: wgpu::TextureAspect::Plane0, + ..Default::default() + }); + }, + None, + ); }); #[gpu_test] @@ -168,13 +172,17 @@ static NV12_TEXTURE_VIEW_PLANE_OUT_OF_BOUNDS: GpuTestConfiguration = GpuTestConf sample_count: 1, view_formats: &[], }); - fail(&ctx.device, || { - let _ = tex.create_view(&wgpu::TextureViewDescriptor { - format: Some(wgpu::TextureFormat::R8Unorm), - aspect: wgpu::TextureAspect::Plane2, - ..Default::default() - }); - }); + fail( + &ctx.device, + || { + let _ = tex.create_view(&wgpu::TextureViewDescriptor { + format: Some(wgpu::TextureFormat::R8Unorm), + aspect: wgpu::TextureAspect::Plane2, + ..Default::default() + }); + }, + None, + ); }); #[gpu_test] @@ -196,13 +204,17 @@ static NV12_TEXTURE_BAD_FORMAT_VIEW_PLANE: GpuTestConfiguration = GpuTestConfigu sample_count: 1, view_formats: &[], }); - fail(&ctx.device, || { - let _ = tex.create_view(&wgpu::TextureViewDescriptor { - format: Some(wgpu::TextureFormat::Rg8Unorm), - aspect: wgpu::TextureAspect::Plane0, - ..Default::default() - }); - }); + fail( + &ctx.device, + || { + let _ = tex.create_view(&wgpu::TextureViewDescriptor { + format: Some(wgpu::TextureFormat::Rg8Unorm), + aspect: wgpu::TextureAspect::Plane0, + ..Default::default() + }); + }, + None, + ); }); #[gpu_test] @@ -215,16 +227,20 @@ static NV12_TEXTURE_BAD_SIZE: GpuTestConfiguration = GpuTestConfiguration::new() depth_or_array_layers: 1, }; - fail(&ctx.device, || { - let _ = ctx.device.create_texture(&wgpu::TextureDescriptor { - label: None, - dimension: wgpu::TextureDimension::D2, - size, - format: wgpu::TextureFormat::NV12, - usage: wgpu::TextureUsages::TEXTURE_BINDING, - mip_level_count: 1, - sample_count: 1, - view_formats: &[], - }); - }); + fail( + &ctx.device, + || { + let _ = ctx.device.create_texture(&wgpu::TextureDescriptor { + label: None, + dimension: wgpu::TextureDimension::D2, + size, + format: wgpu::TextureFormat::NV12, + usage: wgpu::TextureUsages::TEXTURE_BINDING, + mip_level_count: 1, + sample_count: 1, + view_formats: &[], + }); + }, + None, + ); }); diff --git a/tests/tests/pipeline.rs b/tests/tests/pipeline.rs index 2591bf5d102..99d0e8da4aa 100644 --- a/tests/tests/pipeline.rs +++ b/tests/tests/pipeline.rs @@ -13,27 +13,31 @@ static PIPELINE_DEFAULT_LAYOUT_BAD_MODULE: GpuTestConfiguration = GpuTestConfigu .run_sync(|ctx| { ctx.device.push_error_scope(wgpu::ErrorFilter::Validation); - fail(&ctx.device, || { - let module = ctx - .device - .create_shader_module(wgpu::ShaderModuleDescriptor { - label: None, - source: wgpu::ShaderSource::Wgsl("not valid wgsl".into()), - }); + fail( + &ctx.device, + || { + let module = ctx + .device + .create_shader_module(wgpu::ShaderModuleDescriptor { + label: None, + source: wgpu::ShaderSource::Wgsl("not valid wgsl".into()), + }); - let pipeline = ctx - .device - .create_compute_pipeline(&wgpu::ComputePipelineDescriptor { - label: Some("mandelbrot compute pipeline"), - layout: None, - module: &module, - entry_point: "doesn't exist", - compilation_options: Default::default(), - cache: None, - }); + let pipeline = + ctx.device + .create_compute_pipeline(&wgpu::ComputePipelineDescriptor { + label: Some("mandelbrot compute pipeline"), + layout: None, + module: &module, + entry_point: "doesn't exist", + compilation_options: Default::default(), + cache: None, + }); - pipeline.get_bind_group_layout(0); - }); + pipeline.get_bind_group_layout(0); + }, + None, + ); }); const TRIVIAL_VERTEX_SHADER_DESC: wgpu::ShaderModuleDescriptor = wgpu::ShaderModuleDescriptor { @@ -47,34 +51,40 @@ const TRIVIAL_VERTEX_SHADER_DESC: wgpu::ShaderModuleDescriptor = wgpu::ShaderMod static NO_TARGETLESS_RENDER: GpuTestConfiguration = GpuTestConfiguration::new() .parameters(TestParameters::default()) .run_sync(|ctx| { - fail(&ctx.device, || { - // Testing multisampling is important, because some backends don't behave well if one - // tries to compile code in an unsupported multisample count. Failing to validate here - // has historically resulted in requesting the back end to compile code. - for power_of_two in [1, 2, 4, 8, 16, 32, 64] { - ctx.device - .create_render_pipeline(&wgpu::RenderPipelineDescriptor { - label: None, - layout: None, - vertex: wgpu::VertexState { - module: &ctx.device.create_shader_module(TRIVIAL_VERTEX_SHADER_DESC), - entry_point: "main", - compilation_options: Default::default(), - buffers: &[], - }, - primitive: Default::default(), - depth_stencil: None, - multisample: wgpu::MultisampleState { - count: power_of_two, - ..Default::default() - }, - fragment: None, - multiview: None, - cache: None, - }); - } - }) - // TODO: concrete error message: - // At least one color attachment or depth-stencil attachment was expected, but no - // render target for the pipeline was specified. + fail( + &ctx.device, + || { + // Testing multisampling is important, because some backends don't behave well if one + // tries to compile code in an unsupported multisample count. Failing to validate here + // has historically resulted in requesting the back end to compile code. + for power_of_two in [1, 2, 4, 8, 16, 32, 64] { + ctx.device + .create_render_pipeline(&wgpu::RenderPipelineDescriptor { + label: None, + layout: None, + vertex: wgpu::VertexState { + module: &ctx + .device + .create_shader_module(TRIVIAL_VERTEX_SHADER_DESC), + entry_point: "main", + compilation_options: Default::default(), + buffers: &[], + }, + primitive: Default::default(), + depth_stencil: None, + multisample: wgpu::MultisampleState { + count: power_of_two, + ..Default::default() + }, + fragment: None, + multiview: None, + cache: None, + }); + } + }, + Some(concat!( + "At least one color attachment or depth-stencil attachment was expected, ", + "but no render target for the pipeline was specified." + )), + ) }); diff --git a/tests/tests/queue_transfer.rs b/tests/tests/queue_transfer.rs index a1ae41572b6..79a79e0ecfc 100644 --- a/tests/tests/queue_transfer.rs +++ b/tests/tests/queue_transfer.rs @@ -22,26 +22,30 @@ static QUEUE_WRITE_TEXTURE_OVERFLOW: GpuTestConfiguration = let data = vec![255; 128]; - fail(&ctx.device, || { - ctx.queue.write_texture( - wgpu::ImageCopyTexture { - texture: &texture, - mip_level: 0, - origin: wgpu::Origin3d { x: 0, y: 0, z: 1 }, - aspect: wgpu::TextureAspect::All, - }, - &data, - wgpu::ImageDataLayout { - offset: 0, - bytes_per_row: Some(879161360), - //bytes_per_image: 4294967295, - rows_per_image: Some(4294967295 / 879161360), - }, - wgpu::Extent3d { - width: 3056263286, - height: 64, - depth_or_array_layers: 4294967295, - }, - ); - }); + fail( + &ctx.device, + || { + ctx.queue.write_texture( + wgpu::ImageCopyTexture { + texture: &texture, + mip_level: 0, + origin: wgpu::Origin3d { x: 0, y: 0, z: 1 }, + aspect: wgpu::TextureAspect::All, + }, + &data, + wgpu::ImageDataLayout { + offset: 0, + bytes_per_row: Some(879161360), + //bytes_per_image: 4294967295, + rows_per_image: Some(4294967295 / 879161360), + }, + wgpu::Extent3d { + width: 3056263286, + height: 64, + depth_or_array_layers: 4294967295, + }, + ); + }, + None, + ); }); diff --git a/tests/tests/resource_error.rs b/tests/tests/resource_error.rs index 0a81801a9ab..98b55044a7d 100644 --- a/tests/tests/resource_error.rs +++ b/tests/tests/resource_error.rs @@ -4,45 +4,59 @@ use wgpu_test::{fail, gpu_test, valid, GpuTestConfiguration}; static BAD_BUFFER: GpuTestConfiguration = GpuTestConfiguration::new().run_sync(|ctx| { // Create a buffer with bad parameters and call a few methods. // Validation should fail but there should be not panic. - let buffer = fail(&ctx.device, || { - ctx.device.create_buffer(&wgpu::BufferDescriptor { - label: None, - size: 99999999, - usage: wgpu::BufferUsages::MAP_READ | wgpu::BufferUsages::STORAGE, - mapped_at_creation: false, - }) - }); + let buffer = fail( + &ctx.device, + || { + ctx.device.create_buffer(&wgpu::BufferDescriptor { + label: None, + size: 99999999, + usage: wgpu::BufferUsages::MAP_READ | wgpu::BufferUsages::STORAGE, + mapped_at_creation: false, + }) + }, + None, + ); - fail(&ctx.device, || { - buffer.slice(..).map_async(wgpu::MapMode::Write, |_| {}) - }); - fail(&ctx.device, || buffer.unmap()); + fail( + &ctx.device, + || buffer.slice(..).map_async(wgpu::MapMode::Write, |_| {}), + None, + ); + fail(&ctx.device, || buffer.unmap(), None); valid(&ctx.device, || buffer.destroy()); valid(&ctx.device, || buffer.destroy()); }); #[gpu_test] static BAD_TEXTURE: GpuTestConfiguration = GpuTestConfiguration::new().run_sync(|ctx| { - let texture = fail(&ctx.device, || { - ctx.device.create_texture(&wgpu::TextureDescriptor { - label: None, - size: wgpu::Extent3d { - width: 0, - height: 12345678, - depth_or_array_layers: 9001, - }, - mip_level_count: 2000, - sample_count: 27, - dimension: wgpu::TextureDimension::D2, - format: wgpu::TextureFormat::Rgba8UnormSrgb, - usage: wgpu::TextureUsages::all(), - view_formats: &[], - }) - }); + let texture = fail( + &ctx.device, + || { + ctx.device.create_texture(&wgpu::TextureDescriptor { + label: None, + size: wgpu::Extent3d { + width: 0, + height: 12345678, + depth_or_array_layers: 9001, + }, + mip_level_count: 2000, + sample_count: 27, + dimension: wgpu::TextureDimension::D2, + format: wgpu::TextureFormat::Rgba8UnormSrgb, + usage: wgpu::TextureUsages::all(), + view_formats: &[], + }) + }, + None, + ); - fail(&ctx.device, || { - let _ = texture.create_view(&wgpu::TextureViewDescriptor::default()); - }); + fail( + &ctx.device, + || { + let _ = texture.create_view(&wgpu::TextureViewDescriptor::default()); + }, + None, + ); valid(&ctx.device, || texture.destroy()); valid(&ctx.device, || texture.destroy()); }); diff --git a/tests/tests/texture_bounds.rs b/tests/tests/texture_bounds.rs index 48b933109de..469d1ab1ce4 100644 --- a/tests/tests/texture_bounds.rs +++ b/tests/tests/texture_bounds.rs @@ -8,19 +8,24 @@ static BAD_COPY_ORIGIN_TEST: GpuTestConfiguration = GpuTestConfiguration::new(). let texture = ctx.device.create_texture(&TEXTURE_DESCRIPTOR); let data = vec![255; BUFFER_SIZE as usize]; - fail_if(&ctx.device, should_panic, || { - ctx.queue.write_texture( - wgpu::ImageCopyTexture { - texture: &texture, - mip_level: 0, - origin, - aspect: wgpu::TextureAspect::All, - }, - &data, - BUFFER_COPY_LAYOUT, - size, - ) - }); + fail_if( + &ctx.device, + should_panic, + || { + ctx.queue.write_texture( + wgpu::ImageCopyTexture { + texture: &texture, + mip_level: 0, + origin, + aspect: wgpu::TextureAspect::All, + }, + &data, + BUFFER_COPY_LAYOUT, + size, + ) + }, + None, + ); }; try_origin(wgpu::Origin3d { x: 0, y: 0, z: 0 }, TEXTURE_SIZE, false); diff --git a/tests/tests/transfer.rs b/tests/tests/transfer.rs index f8bd43530b2..e69f9755983 100644 --- a/tests/tests/transfer.rs +++ b/tests/tests/transfer.rs @@ -35,31 +35,35 @@ static COPY_OVERFLOW_Z: GpuTestConfiguration = GpuTestConfiguration::new().run_s view_formats: &[], }); - fail(&ctx.device, || { - // Validation should catch the silly selected z layer range without panicking. - encoder.copy_texture_to_texture( - wgpu::ImageCopyTexture { - texture: &t1, - mip_level: 1, - origin: wgpu::Origin3d::ZERO, - aspect: wgpu::TextureAspect::All, - }, - wgpu::ImageCopyTexture { - texture: &t2, - mip_level: 1, - origin: wgpu::Origin3d { - x: 0, - y: 0, - z: 3824276442, + fail( + &ctx.device, + || { + // Validation should catch the silly selected z layer range without panicking. + encoder.copy_texture_to_texture( + wgpu::ImageCopyTexture { + texture: &t1, + mip_level: 1, + origin: wgpu::Origin3d::ZERO, + aspect: wgpu::TextureAspect::All, }, - aspect: wgpu::TextureAspect::All, - }, - wgpu::Extent3d { - width: 100, - height: 3, - depth_or_array_layers: 613286111, - }, - ); - ctx.queue.submit(Some(encoder.finish())); - }); + wgpu::ImageCopyTexture { + texture: &t2, + mip_level: 1, + origin: wgpu::Origin3d { + x: 0, + y: 0, + z: 3824276442, + }, + aspect: wgpu::TextureAspect::All, + }, + wgpu::Extent3d { + width: 100, + height: 3, + depth_or_array_layers: 613286111, + }, + ); + ctx.queue.submit(Some(encoder.finish())); + }, + None, + ); });