From 41006d7a88cb29b59a4f104fe513b85f83d67898 Mon Sep 17 00:00:00 2001 From: Imbris <2002109+Imberflur@users.noreply.github.com> Date: Mon, 19 Sep 2022 00:41:29 -0400 Subject: [PATCH] Buffer usages mismatch check and documentation for mapped_at_creation size requirement. (#3023) Co-authored-by: Connor Fitzgerald --- CHANGELOG.md | 2 + player/tests/data/buffer-copy.ron | 4 +- player/tests/data/clear-buffer-texture.ron | 2 +- player/tests/data/zero-init-buffer.ron | 2 +- wgpu-core/src/device/mod.rs | 14 +++++ wgpu-types/src/lib.rs | 3 + wgpu/tests/buffer_usages.rs | 65 ++++++++++++++++++++++ wgpu/tests/root.rs | 1 + 8 files changed, 89 insertions(+), 4 deletions(-) create mode 100644 wgpu/tests/buffer_usages.rs diff --git a/CHANGELOG.md b/CHANGELOG.md index 804b90d40c..d88698cc38 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -82,6 +82,8 @@ SurfaceConfiguration { - Improve the validation and error reporting of buffer mappings by @nical in [#2848](https://github.com/gfx-rs/wgpu/pull/2848) - Fix compilation errors when using wgpu-core in isolation while targetting `wasm32-unknown-unknown` by @Seamooo in [#2922](https://github.com/gfx-rs/wgpu/pull/2922) - Fixed opening of RenderDoc library by @abuffseagull in [#2930](https://github.com/gfx-rs/wgpu/pull/2930) +- Added missing validation for `BufferUsages` mismatches when `Features::MAPPABLE_PRIMARY_BUFFERS` is not + enabled. By @imberflur in [#3023](https://github.com/gfx-rs/wgpu/pull/3023) - Fixed `CommandEncoder` not being `Send` and `Sync` on web by @i509VCB in [#3025](https://github.com/gfx-rs/wgpu/pull/3025) #### Metal diff --git a/player/tests/data/buffer-copy.ron b/player/tests/data/buffer-copy.ron index c2fad09a28..58cce3b1c2 100644 --- a/player/tests/data/buffer-copy.ron +++ b/player/tests/data/buffer-copy.ron @@ -1,5 +1,5 @@ ( - features: 0x0, + features: 0x1_0000, expectations: [ ( name: "basic", @@ -29,4 +29,4 @@ ), Submit(1, []), ], -) \ No newline at end of file +) diff --git a/player/tests/data/clear-buffer-texture.ron b/player/tests/data/clear-buffer-texture.ron index fd54ca9ea5..023164282f 100644 --- a/player/tests/data/clear-buffer-texture.ron +++ b/player/tests/data/clear-buffer-texture.ron @@ -1,5 +1,5 @@ ( - features: 0x0000_0004_0000_0000, + features: 0x0000_0004_0001_0000, expectations: [ ( name: "Quad", diff --git a/player/tests/data/zero-init-buffer.ron b/player/tests/data/zero-init-buffer.ron index 1381ea7393..ca75c658fc 100644 --- a/player/tests/data/zero-init-buffer.ron +++ b/player/tests/data/zero-init-buffer.ron @@ -1,5 +1,5 @@ ( - features: 0x0, + features: 0x1_0000, expectations: [ // Ensuring that mapping zero-inits buffers. ( diff --git a/wgpu-core/src/device/mod.rs b/wgpu-core/src/device/mod.rs index 41f3e50be2..0142265fbe 100644 --- a/wgpu-core/src/device/mod.rs +++ b/wgpu-core/src/device/mod.rs @@ -589,6 +589,20 @@ impl Device { return Err(resource::CreateBufferError::EmptyUsage); } + if !self + .features + .contains(wgt::Features::MAPPABLE_PRIMARY_BUFFERS) + { + use wgt::BufferUsages as Bu; + let write_mismatch = desc.usage.contains(Bu::MAP_WRITE) + && !(Bu::MAP_WRITE | Bu::COPY_SRC).contains(desc.usage); + let read_mismatch = desc.usage.contains(Bu::MAP_READ) + && !(Bu::MAP_READ | Bu::COPY_DST).contains(desc.usage); + if write_mismatch || read_mismatch { + return Err(resource::CreateBufferError::UsageMismatch(desc.usage)); + } + } + if desc.mapped_at_creation { if desc.size % wgt::COPY_BUFFER_ALIGNMENT != 0 { return Err(resource::CreateBufferError::UnalignedSize); diff --git a/wgpu-types/src/lib.rs b/wgpu-types/src/lib.rs index 25bf4c5d35..1b698bd9d4 100644 --- a/wgpu-types/src/lib.rs +++ b/wgpu-types/src/lib.rs @@ -2913,6 +2913,9 @@ pub struct BufferDescriptor { pub usage: BufferUsages, /// Allows a buffer to be mapped immediately after they are made. It does not have to be [`BufferUsages::MAP_READ`] or /// [`BufferUsages::MAP_WRITE`], all buffers are allowed to be mapped at creation. + /// + /// If this is `true`, [`size`](#structfield.size) must be a multiple of + /// [`COPY_BUFFER_ALIGNMENT`]. pub mapped_at_creation: bool, } diff --git a/wgpu/tests/buffer_usages.rs b/wgpu/tests/buffer_usages.rs new file mode 100644 index 0000000000..ebf679ca05 --- /dev/null +++ b/wgpu/tests/buffer_usages.rs @@ -0,0 +1,65 @@ +//! Tests for buffer usages validation. + +use wgt::BufferAddress; + +use crate::common::{initialize_test, TestParameters}; + +#[test] +fn buffer_usage() { + fn try_create( + usages: &[wgpu::BufferUsages], + enable_mappable_primary_buffers: bool, + should_panic: bool, + ) { + let mut parameters = TestParameters::default(); + if enable_mappable_primary_buffers { + parameters = parameters.features(wgpu::Features::MAPPABLE_PRIMARY_BUFFERS); + } + if should_panic { + parameters = parameters.failure(); + } + + initialize_test(parameters, |ctx| { + for usage in usages.iter().copied() { + let _buffer = ctx.device.create_buffer(&wgpu::BufferDescriptor { + label: None, + size: BUFFER_SIZE, + usage, + mapped_at_creation: false, + }); + } + }); + } + + use wgpu::BufferUsages as Bu; + + let always_valid = [ + Bu::MAP_READ, + Bu::MAP_WRITE, + Bu::MAP_READ | Bu::COPY_DST, + Bu::MAP_WRITE | Bu::COPY_SRC, + ]; + // MAP_READ can only be paired with COPY_DST and MAP_WRITE can only be paired with COPY_SRC + // (unless Features::MAPPABlE_PRIMARY_BUFFERS is enabled). + let needs_mappable_primary_buffers = [ + Bu::MAP_READ | Bu::COPY_DST | Bu::COPY_SRC, + Bu::MAP_WRITE | Bu::COPY_SRC | Bu::COPY_DST, + Bu::MAP_READ | Bu::MAP_WRITE, + Bu::MAP_WRITE | Bu::MAP_READ, + Bu::MAP_READ | Bu::COPY_DST | Bu::STORAGE, + Bu::MAP_WRITE | Bu::COPY_SRC | Bu::STORAGE, + wgpu::BufferUsages::all(), + ]; + let always_fail = [Bu::empty()]; + + try_create(&always_valid, false, false); + try_create(&always_valid, true, false); + + try_create(&needs_mappable_primary_buffers, false, true); + try_create(&needs_mappable_primary_buffers, true, false); + + try_create(&always_fail, false, true); + try_create(&always_fail, true, true); +} + +const BUFFER_SIZE: BufferAddress = 1234; diff --git a/wgpu/tests/root.rs b/wgpu/tests/root.rs index c8ad63e175..788767131e 100644 --- a/wgpu/tests/root.rs +++ b/wgpu/tests/root.rs @@ -2,6 +2,7 @@ mod common; mod buffer_copy; +mod buffer_usages; mod clear_texture; mod device; mod example_wgsl;