Skip to content

Commit f14458b

Browse files
authored
Improve late buffer binding size error (#8484)
1 parent a2db631 commit f14458b

File tree

4 files changed

+50
-20
lines changed

4 files changed

+50
-20
lines changed

tests/tests/wgpu-gpu/buffer.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -354,7 +354,7 @@ static MINIMUM_BUFFER_BINDING_SIZE_DISPATCH: GpuTestConfiguration = GpuTestConfi
354354
drop(pass);
355355
let _ = encoder.finish();
356356
},
357-
Some("buffer is bound with size 16 where the shader expects 32 in group[0] compact index 0"),
357+
Some("In bind group index 0, the buffer bound at binding index 0 is bound with size 16 where the shader expects 32"),
358358
);
359359
});
360360

wgpu-core/src/binding_model.rs

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1164,6 +1164,14 @@ pub(crate) fn buffer_binding_type_bounds_check_alignment(
11641164
}
11651165
}
11661166

1167+
#[derive(Debug)]
1168+
pub(crate) struct BindGroupLateBufferBindingInfo {
1169+
/// The normal binding index in the bind group.
1170+
pub binding_index: u32,
1171+
/// The size that exists at bind time.
1172+
pub size: wgt::BufferSize,
1173+
}
1174+
11671175
#[derive(Debug)]
11681176
pub struct BindGroup {
11691177
pub(crate) raw: Snatchable<Box<dyn hal::DynBindGroup>>,
@@ -1178,7 +1186,7 @@ pub struct BindGroup {
11781186
pub(crate) dynamic_binding_info: Vec<BindGroupDynamicBindingData>,
11791187
/// Actual binding sizes for buffers that don't have `min_binding_size`
11801188
/// specified in BGL. Listed in the order of iteration of `BGL.entries`.
1181-
pub(crate) late_buffer_binding_sizes: Vec<wgt::BufferSize>,
1189+
pub(crate) late_buffer_binding_infos: Vec<BindGroupLateBufferBindingInfo>,
11821190
}
11831191

11841192
impl Drop for BindGroup {
@@ -1289,10 +1297,13 @@ impl WebGpuError for GetBindGroupLayoutError {
12891297
}
12901298

12911299
#[derive(Clone, Debug, Error, Eq, PartialEq)]
1292-
#[error("Buffer is bound with size {bound_size} where the shader expects {shader_size} in group[{group_index}] compact index {compact_index}")]
1300+
#[error(
1301+
"In bind group index {group_index}, the buffer bound at binding index {binding_index} \
1302+
is bound with size {bound_size} where the shader expects {shader_size}."
1303+
)]
12931304
pub struct LateMinBufferBindingSizeMismatch {
12941305
pub group_index: u32,
1295-
pub compact_index: usize,
1306+
pub binding_index: u32,
12961307
pub shader_size: wgt::BufferAddress,
12971308
pub bound_size: wgt::BufferAddress,
12981309
}

wgpu-core/src/command/bind.rs

Lines changed: 23 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -291,6 +291,7 @@ pub enum BinderError {
291291

292292
#[derive(Debug)]
293293
struct LateBufferBinding {
294+
binding_index: u32,
294295
shader_expect_size: wgt::BufferAddress,
295296
bound_size: wgt::BufferAddress,
296297
}
@@ -347,20 +348,25 @@ impl Binder {
347348
self.manager.update_expectations(&new.bind_group_layouts);
348349

349350
// Update the buffer binding sizes that are required by shaders.
351+
350352
for (payload, late_group) in self.payloads.iter_mut().zip(late_sized_buffer_groups) {
351353
payload.late_bindings_effective_count = late_group.shader_sizes.len();
354+
// Update entries that already exist as the bind group was bound before the pipeline
355+
// was bound.
352356
for (late_binding, &shader_expect_size) in payload
353357
.late_buffer_bindings
354358
.iter_mut()
355359
.zip(late_group.shader_sizes.iter())
356360
{
357361
late_binding.shader_expect_size = shader_expect_size;
358362
}
363+
// Add new entries for the bindings that were not known when the bind group was bound.
359364
if late_group.shader_sizes.len() > payload.late_buffer_bindings.len() {
360365
for &shader_expect_size in
361366
late_group.shader_sizes[payload.late_buffer_bindings.len()..].iter()
362367
{
363368
payload.late_buffer_bindings.push(LateBufferBinding {
369+
binding_index: 0,
364370
shader_expect_size,
365371
bound_size: 0,
366372
});
@@ -389,20 +395,27 @@ impl Binder {
389395

390396
// Fill out the actual binding sizes for buffers,
391397
// whose layout doesn't specify `min_binding_size`.
392-
for (late_binding, late_size) in payload
398+
399+
// Update entries that already exist as the pipeline was bound before the group
400+
// was bound.
401+
for (late_binding, late_info) in payload
393402
.late_buffer_bindings
394403
.iter_mut()
395-
.zip(bind_group.late_buffer_binding_sizes.iter())
404+
.zip(bind_group.late_buffer_binding_infos.iter())
396405
{
397-
late_binding.bound_size = late_size.get();
406+
late_binding.binding_index = late_info.binding_index;
407+
late_binding.bound_size = late_info.size.get();
398408
}
399-
if bind_group.late_buffer_binding_sizes.len() > payload.late_buffer_bindings.len() {
400-
for late_size in
401-
bind_group.late_buffer_binding_sizes[payload.late_buffer_bindings.len()..].iter()
409+
410+
// Add new entries for the bindings that were not known when the pipeline was bound.
411+
if bind_group.late_buffer_binding_infos.len() > payload.late_buffer_bindings.len() {
412+
for late_info in
413+
bind_group.late_buffer_binding_infos[payload.late_buffer_bindings.len()..].iter()
402414
{
403415
payload.late_buffer_bindings.push(LateBufferBinding {
416+
binding_index: late_info.binding_index,
404417
shader_expect_size: 0,
405-
bound_size: late_size.get(),
418+
bound_size: late_info.size.get(),
406419
});
407420
}
408421
}
@@ -469,15 +482,13 @@ impl Binder {
469482
) -> Result<(), LateMinBufferBindingSizeMismatch> {
470483
for group_index in self.manager.list_active() {
471484
let payload = &self.payloads[group_index];
472-
for (compact_index, late_binding) in payload.late_buffer_bindings
473-
[..payload.late_bindings_effective_count]
474-
.iter()
475-
.enumerate()
485+
for late_binding in
486+
&payload.late_buffer_bindings[..payload.late_bindings_effective_count]
476487
{
477488
if late_binding.bound_size < late_binding.shader_expect_size {
478489
return Err(LateMinBufferBindingSizeMismatch {
479490
group_index: group_index as u32,
480-
compact_index,
491+
binding_index: late_binding.binding_index,
481492
shader_size: late_binding.shader_expect_size,
482493
bound_size: late_binding.bound_size,
483494
});

wgpu-core/src/device/resource.rs

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,9 @@ use wgt::{
2525
use crate::device::trace;
2626
use crate::{
2727
api_log,
28-
binding_model::{self, BindGroup, BindGroupLayout, BindGroupLayoutEntryError},
28+
binding_model::{
29+
self, BindGroup, BindGroupLateBufferBindingInfo, BindGroupLayout, BindGroupLayoutEntryError,
30+
},
2931
command, conv,
3032
device::{
3133
bgl, create_validator, life::WaitIdleError, map_buffer, AttachmentData,
@@ -3279,10 +3281,16 @@ impl Device {
32793281
.map_err(|e| self.handle_hal_error(e))?;
32803282

32813283
// collect in the order of BGL iteration
3282-
let late_buffer_binding_sizes = layout
3284+
let late_buffer_binding_infos = layout
32833285
.entries
32843286
.indices()
3285-
.flat_map(|binding| late_buffer_binding_sizes.get(&binding).cloned())
3287+
.flat_map(|binding| {
3288+
let size = late_buffer_binding_sizes.get(&binding).cloned()?;
3289+
Some(BindGroupLateBufferBindingInfo {
3290+
binding_index: binding,
3291+
size,
3292+
})
3293+
})
32863294
.collect();
32873295

32883296
let bind_group = BindGroup {
@@ -3295,7 +3303,7 @@ impl Device {
32953303
used_buffer_ranges,
32963304
used_texture_ranges,
32973305
dynamic_binding_info,
3298-
late_buffer_binding_sizes,
3306+
late_buffer_binding_infos,
32993307
};
33003308

33013309
let bind_group = Arc::new(bind_group);

0 commit comments

Comments
 (0)