Skip to content

Commit b538522

Browse files
fix(core): validate effective buf. binding size is aligned to 4 (gfx-rs#8041)
The WebGPU spec. `createBindGroup` [states][spec-ref] (emphasis mine): > Device timeline initialization steps: > > … > > 2. If any of the following conditions are unsatisfied generate a > validation error, invalidate _bindGroup_ and return. > > … > > For each `GPUBindGroupEntry` _bindingDescriptor_ in > _descriptor_.`entries`: > > - … > > - If the defined binding member for _layoutBinding_ is: > > - … > > - `buffer` > > - … > > - If _layoutBinding_.`buffer`.`type` is > > - … > > - `"storage"` or `"read-only-storage"` > > - … > > - effective buffer binding size(_bufferBinding_) is a multiple of 4. [spec-ref]: https://www.w3.org/TR/webgpu/#dom-gpudevice-createbindgroup We were not implementing this check of effective buffer binding size. Check that it's a multiple of 4, including `webgpu:api,validation,createBindGroup:buffer,effective_buffer_binding_size:*` that this is now implemented as intended.
1 parent 8cd4bd6 commit b538522

4 files changed

Lines changed: 21 additions & 0 deletions

File tree

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,10 @@ Naga now requires that no type be larger than 1 GB. This limit may be lowered in
6565

6666
### Bug Fixes
6767

68+
#### General
69+
70+
- Validate that effective buffer binding size is aligned to 4 when creating bind groups with buffer entries.. By @ErichDonGubler in [8041](https://github.com/gfx-rs/wgpu/pull/8041).
71+
6872
#### Vulkan
6973

7074
Fix `STATUS_HEAP_CORRUPTION` crash when concurrently calling `create_sampler`. By @atlv24 in [#8043](https://github.com/gfx-rs/wgpu/pull/8043).

cts_runner/test.lst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ webgpu:api,operation,render_pass,storeOp:render_pass_store_op,color_attachment_w
1919
webgpu:api,operation,render_pass,storeOp:render_pass_store_op,color_attachment_only:*
2020
webgpu:api,operation,render_pass,storeOp:render_pass_store_op,multiple_color_attachments:*
2121
webgpu:api,operation,render_pass,storeOp:render_pass_store_op,depth_stencil_attachment_only:*
22+
webgpu:api,validation,createBindGroup:buffer,effective_buffer_binding_size:*
2223
webgpu:api,validation,encoding,beginComputePass:*
2324
webgpu:api,validation,encoding,beginRenderPass:*
2425
webgpu:api,validation,encoding,cmds,clearBuffer:*

wgpu-core/src/binding_model.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,8 @@ pub enum CreateBindGroupError {
167167
MissingTextureUsage(#[from] MissingTextureUsageError),
168168
#[error("Binding declared as a single item, but bind group is using it as an array")]
169169
SingleBindingExpected,
170+
#[error("Effective buffer binding size {size} for storage buffers is expected to align to {alignment}, but size is {size}")]
171+
UnalignedEffectiveBufferBindingSizeForStorage { alignment: u8, size: u64 },
170172
#[error("Buffer offset {0} does not respect device's requested `{1}` limit {2}")]
171173
UnalignedBufferOffset(wgt::BufferAddress, &'static str, u32),
172174
#[error(
@@ -275,6 +277,7 @@ impl WebGpuError for CreateBindGroupError {
275277
| Self::DuplicateBinding(_)
276278
| Self::MissingBindingDeclaration(_)
277279
| Self::SingleBindingExpected
280+
| Self::UnalignedEffectiveBufferBindingSizeForStorage { .. }
278281
| Self::UnalignedBufferOffset(_, _, _)
279282
| Self::BufferRangeTooLarge { .. }
280283
| Self::WrongBindingType { .. }

wgpu-core/src/device/resource.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2542,6 +2542,19 @@ impl Device {
25422542
buffer.check_usage(pub_usage)?;
25432543

25442544
let (bb, bind_size) = buffer.binding(bb.offset, bb.size, snatch_guard)?;
2545+
2546+
if matches!(binding_ty, wgt::BufferBindingType::Storage { .. }) {
2547+
let storage_buf_size_alignment = 4;
2548+
2549+
let aligned = bind_size % u64::from(storage_buf_size_alignment) == 0;
2550+
if !aligned {
2551+
return Err(Error::UnalignedEffectiveBufferBindingSizeForStorage {
2552+
alignment: storage_buf_size_alignment,
2553+
size: bind_size,
2554+
});
2555+
}
2556+
}
2557+
25452558
let bind_end = bb.offset + bind_size;
25462559

25472560
if bind_size > range_limit as u64 {

0 commit comments

Comments
 (0)