Skip to content

Commit 468632f

Browse files
andyleisersonjimblandy
authored andcommitted
Restore plumbing of implicit remainder-of-buffer size to backends
1 parent 00406a7 commit 468632f

File tree

19 files changed

+144
-114
lines changed

19 files changed

+144
-114
lines changed

cts_runner/test.lst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ webgpu:api,validation,encoding,cmds,copyTextureToTexture:sample_count:*
2727
//FAIL: webgpu:api,validation,encoding,cmds,copyTextureToTexture:copy_ranges_with_compressed_texture_formats:*
2828
webgpu:api,validation,encoding,cmds,index_access:*
2929
//FAIL: webgpu:api,validation,encoding,cmds,render,draw:*
30+
webgpu:api,validation,encoding,cmds,render,draw:index_buffer_OOB:*
31+
webgpu:api,validation,encoding,cmds,render,draw:unused_buffer_bound:*
3032
webgpu:api,validation,encoding,encoder_state:*
3133
webgpu:api,validation,encoding,encoder_open_state:non_pass_commands:*
3234
webgpu:api,validation,encoding,encoder_open_state:render_pass_commands:*

wgpu-core/src/command/bundle.rs

Lines changed: 9 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -505,7 +505,7 @@ impl RenderBundleEncoder {
505505
buffer_id,
506506
index_format,
507507
offset,
508-
size: size.map(NonZeroU64::get),
508+
size,
509509
});
510510
}
511511
}
@@ -610,7 +610,7 @@ fn set_index_buffer(
610610
buffer_id: id::Id<id::markers::Buffer>,
611611
index_format: wgt::IndexFormat,
612612
offset: u64,
613-
size: Option<wgt::BufferSizeOrZero>,
613+
size: Option<NonZeroU64>,
614614
) -> Result<(), RenderBundleErrorInner> {
615615
let buffer = buffer_guard.get(buffer_id).get()?;
616616

@@ -642,7 +642,7 @@ fn set_vertex_buffer(
642642
slot: u32,
643643
buffer_id: id::Id<id::markers::Buffer>,
644644
offset: u64,
645-
size: Option<wgt::BufferSizeOrZero>,
645+
size: Option<NonZeroU64>,
646646
) -> Result<(), RenderBundleErrorInner> {
647647
let max_vertex_buffers = state.device.limits.max_vertex_buffers;
648648
if slot >= max_vertex_buffers {
@@ -967,11 +967,7 @@ impl RenderBundle {
967967
let bb = unsafe {
968968
// SAFETY: The binding size was checked against the buffer size
969969
// in `set_index_buffer` and again in `IndexState::flush`.
970-
hal::BufferBinding::new_unchecked(
971-
buffer,
972-
*offset,
973-
size.expect("size was resolved in `RenderBundleEncoder::finish`"),
974-
)
970+
hal::BufferBinding::new_unchecked(buffer, *offset, *size)
975971
};
976972
unsafe { raw.set_index_buffer(bb, *index_format) };
977973
}
@@ -985,11 +981,7 @@ impl RenderBundle {
985981
let bb = unsafe {
986982
// SAFETY: The binding size was checked against the buffer size
987983
// in `set_vertex_buffer` and again in `VertexState::flush`.
988-
hal::BufferBinding::new_unchecked(
989-
buffer,
990-
*offset,
991-
size.expect("size was resolved in `RenderBundleEncoder::finish`"),
992-
)
984+
hal::BufferBinding::new_unchecked(buffer, *offset, *size)
993985
};
994986
unsafe { raw.set_vertex_buffer(*slot, bb) };
995987
}
@@ -1176,7 +1168,7 @@ impl IndexState {
11761168
buffer: self.buffer.clone(),
11771169
index_format: self.format,
11781170
offset: self.range.start,
1179-
size: Some(binding_size),
1171+
size: NonZeroU64::new(binding_size),
11801172
})
11811173
} else {
11821174
None
@@ -1232,7 +1224,7 @@ impl VertexState {
12321224
slot,
12331225
buffer: self.buffer.clone(),
12341226
offset: self.range.start,
1235-
size: Some(binding_size),
1227+
size: NonZeroU64::new(binding_size),
12361228
})
12371229
} else {
12381230
None
@@ -1596,7 +1588,7 @@ where
15961588
pub mod bundle_ffi {
15971589
use super::{RenderBundleEncoder, RenderCommand};
15981590
use crate::{id, RawString};
1599-
use core::{convert::TryInto, num::NonZeroU64, slice};
1591+
use core::{convert::TryInto, slice};
16001592
use wgt::{BufferAddress, BufferSize, DynamicOffset, IndexFormat};
16011593

16021594
/// # Safety
@@ -1655,7 +1647,7 @@ pub mod bundle_ffi {
16551647
slot,
16561648
buffer_id,
16571649
offset,
1658-
size: size.map(NonZeroU64::get),
1650+
size,
16591651
});
16601652
}
16611653

wgpu-core/src/command/render.rs

Lines changed: 16 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,12 @@
11
use alloc::{borrow::Cow, sync::Arc, vec::Vec};
2-
use core::{
3-
fmt,
4-
num::{NonZeroU32, NonZeroU64},
5-
str,
6-
};
7-
use hal::ShouldBeNonZeroExt;
2+
use core::{fmt, num::NonZeroU32, ops::Range, str};
83

94
use arrayvec::ArrayVec;
105
use thiserror::Error;
116
use wgt::{
127
error::{ErrorType, WebGpuError},
13-
BufferAddress, BufferSize, BufferSizeOrZero, BufferUsages, Color, DynamicOffset, IndexFormat,
14-
ShaderStages, TextureSelector, TextureUsages, TextureViewDimension, VertexStepMode,
8+
BufferAddress, BufferSize, BufferUsages, Color, DynamicOffset, IndexFormat, ShaderStages,
9+
TextureSelector, TextureUsages, TextureViewDimension, VertexStepMode,
1510
};
1611

1712
use crate::command::{
@@ -362,17 +357,13 @@ struct IndexState {
362357
}
363358

364359
impl IndexState {
365-
fn update_buffer<B: hal::DynBuffer + ?Sized>(
366-
&mut self,
367-
binding: &hal::BufferBinding<'_, B>,
368-
format: IndexFormat,
369-
) {
360+
fn update_buffer(&mut self, range: Range<BufferAddress>, format: IndexFormat) {
370361
self.buffer_format = Some(format);
371362
let shift = match format {
372363
IndexFormat::Uint16 => 1,
373364
IndexFormat::Uint32 => 2,
374365
};
375-
self.limit = binding.size.get() >> shift;
366+
self.limit = (range.end - range.start) >> shift;
376367
}
377368

378369
fn reset(&mut self) {
@@ -2339,7 +2330,7 @@ fn set_index_buffer(
23392330
buffer: Arc<crate::resource::Buffer>,
23402331
index_format: IndexFormat,
23412332
offset: u64,
2342-
size: Option<BufferSizeOrZero>,
2333+
size: Option<BufferSize>,
23432334
) -> Result<(), RenderPassErrorInner> {
23442335
api_log!("RenderPass::set_index_buffer {}", buffer.error_ident());
23452336

@@ -2353,15 +2344,16 @@ fn set_index_buffer(
23532344

23542345
buffer.check_usage(BufferUsages::INDEX)?;
23552346

2356-
let binding = buffer
2347+
let (binding, resolved_size) = buffer
23572348
.binding(offset, size, state.general.snatch_guard)
23582349
.map_err(RenderCommandError::from)?;
2359-
state.index.update_buffer(&binding, index_format);
2350+
let end = offset + resolved_size;
2351+
state.index.update_buffer(offset..end, index_format);
23602352

23612353
state.general.buffer_memory_init_actions.extend(
23622354
buffer.initialization_status.read().create_action(
23632355
&buffer,
2364-
offset..(offset + binding.size.get()),
2356+
offset..end,
23652357
MemoryInitKind::NeedsInitializedMemory,
23662358
),
23672359
);
@@ -2379,7 +2371,7 @@ fn set_vertex_buffer(
23792371
slot: u32,
23802372
buffer: Arc<crate::resource::Buffer>,
23812373
offset: u64,
2382-
size: Option<BufferSizeOrZero>,
2374+
size: Option<BufferSize>,
23832375
) -> Result<(), RenderPassErrorInner> {
23842376
api_log!(
23852377
"RenderPass::set_vertex_buffer {slot} {}",
@@ -2405,15 +2397,15 @@ fn set_vertex_buffer(
24052397

24062398
buffer.check_usage(BufferUsages::VERTEX)?;
24072399

2408-
let binding = buffer
2400+
let (binding, buffer_size) = buffer
24092401
.binding(offset, size, state.general.snatch_guard)
24102402
.map_err(RenderCommandError::from)?;
2411-
state.vertex.buffer_sizes[slot as usize] = Some(binding.size.get());
2403+
state.vertex.buffer_sizes[slot as usize] = Some(buffer_size);
24122404

24132405
state.general.buffer_memory_init_actions.extend(
24142406
buffer.initialization_status.read().create_action(
24152407
&buffer,
2416-
offset..(offset + binding.size.get()),
2408+
offset..(offset + buffer_size),
24172409
MemoryInitKind::NeedsInitializedMemory,
24182410
),
24192411
);
@@ -3090,7 +3082,7 @@ impl Global {
30903082
buffer: pass_try!(base, scope, self.resolve_render_pass_buffer_id(buffer_id)),
30913083
index_format,
30923084
offset,
3093-
size: size.map(NonZeroU64::get),
3085+
size,
30943086
});
30953087

30963088
Ok(())
@@ -3111,7 +3103,7 @@ impl Global {
31113103
slot,
31123104
buffer: pass_try!(base, scope, self.resolve_render_pass_buffer_id(buffer_id)),
31133105
offset,
3114-
size: size.map(NonZeroU64::get),
3106+
size,
31153107
});
31163108

31173109
Ok(())

wgpu-core/src/command/render_command.rs

Lines changed: 5 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use alloc::sync::Arc;
22

3-
use wgt::{BufferAddress, BufferSizeOrZero, Color};
3+
use wgt::{BufferAddress, BufferSize, Color};
44

55
use super::{Rect, RenderBundle};
66
use crate::{
@@ -24,13 +24,13 @@ pub enum RenderCommand {
2424
buffer_id: id::BufferId,
2525
index_format: wgt::IndexFormat,
2626
offset: BufferAddress,
27-
size: Option<BufferSizeOrZero>,
27+
size: Option<BufferSize>,
2828
},
2929
SetVertexBuffer {
3030
slot: u32,
3131
buffer_id: id::BufferId,
3232
offset: BufferAddress,
33-
size: Option<BufferSizeOrZero>,
33+
size: Option<BufferSize>,
3434
},
3535
SetBlendConstant(Color),
3636
SetStencilReference(u32),
@@ -416,20 +416,13 @@ pub enum ArcRenderCommand {
416416
buffer: Arc<Buffer>,
417417
index_format: wgt::IndexFormat,
418418
offset: BufferAddress,
419-
420-
// For a render pass, this reflects the argument passed by the
421-
// application, which may be `None`. For a finished render bundle, this
422-
// reflects the validated size of the binding, and will be populated
423-
// even in the case that the application omitted the size.
424-
size: Option<BufferSizeOrZero>,
419+
size: Option<BufferSize>,
425420
},
426421
SetVertexBuffer {
427422
slot: u32,
428423
buffer: Arc<Buffer>,
429424
offset: BufferAddress,
430-
431-
// See comment in `SetIndexBuffer`.
432-
size: Option<BufferSizeOrZero>,
425+
size: Option<BufferSize>,
433426
},
434427
SetBlendConstant(Color),
435428
SetStencilReference(u32),

wgpu-core/src/device/resource.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ use alloc::{
88
use core::{
99
fmt,
1010
mem::{self, ManuallyDrop},
11-
num::{NonZeroU32, NonZeroU64},
11+
num::NonZeroU32,
1212
sync::atomic::{AtomicBool, Ordering},
1313
};
1414
use hal::ShouldBeNonZeroExt;
@@ -2198,8 +2198,8 @@ impl Device {
21982198

21992199
buffer.check_usage(pub_usage)?;
22002200

2201-
let bb = buffer.binding(bb.offset, bb.size.map(NonZeroU64::get), snatch_guard)?;
2202-
let bind_size = bb.size.get();
2201+
let (bb, bind_size) = buffer.binding(bb.offset, bb.size, snatch_guard)?;
2202+
let bind_end = bb.offset + bind_size;
22032203

22042204
if bind_size > range_limit as u64 {
22052205
return Err(Error::BufferRangeTooLarge {
@@ -2214,8 +2214,8 @@ impl Device {
22142214
dynamic_binding_info.push(binding_model::BindGroupDynamicBindingData {
22152215
binding_idx: binding,
22162216
buffer_size: buffer.size,
2217-
binding_range: bb.offset..bb.offset + bind_size,
2218-
maximum_dynamic_offset: buffer.size - bb.offset - bind_size,
2217+
binding_range: bb.offset..bind_end,
2218+
maximum_dynamic_offset: buffer.size - bind_end,
22192219
binding_type: binding_ty,
22202220
});
22212221
}

wgpu-core/src/indirect_validation/dispatch.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -234,7 +234,7 @@ impl Dispatch {
234234
}],
235235
buffers: &[unsafe {
236236
// SAFETY: We just created the buffer with this size.
237-
hal::BufferBinding::new_unchecked(dst_buffer.as_ref(), 0, DST_BUFFER_SIZE)
237+
hal::BufferBinding::new_unchecked(dst_buffer.as_ref(), 0, Some(DST_BUFFER_SIZE))
238238
}],
239239
samplers: &[],
240240
textures: &[],

wgpu-core/src/resource.rs

Lines changed: 22 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -508,17 +508,17 @@ impl Buffer {
508508
pub fn resolve_binding_size(
509509
&self,
510510
offset: wgt::BufferAddress,
511-
binding_size: Option<wgt::BufferSizeOrZero>,
512-
) -> Result<wgt::BufferSizeOrZero, BindingError> {
511+
binding_size: Option<wgt::BufferSize>,
512+
) -> Result<u64, BindingError> {
513513
let buffer_size = self.size;
514514

515515
match binding_size {
516-
Some(binding_size) => match offset.checked_add(binding_size) {
517-
Some(end) if end <= buffer_size => Ok(binding_size),
516+
Some(binding_size) => match offset.checked_add(binding_size.get()) {
517+
Some(end) if end <= buffer_size => Ok(binding_size.get()),
518518
_ => Err(BindingError::BindingRangeTooLarge {
519519
buffer: self.error_ident(),
520520
offset,
521-
binding_size,
521+
binding_size: binding_size.get(),
522522
buffer_size,
523523
}),
524524
},
@@ -535,35 +535,38 @@ impl Buffer {
535535
}
536536

537537
/// Create a new [`hal::BufferBinding`] for the buffer with `offset` and
538-
/// `size`.
538+
/// `binding_size`.
539539
///
540-
/// If `size` is `None`, then the remainder of the buffer starting from
541-
/// `offset` is used.
540+
/// If `binding_size` is `None`, then the remainder of the buffer starting
541+
/// from `offset` is used.
542542
///
543543
/// If the binding would overflow the buffer, then an error is returned.
544544
///
545-
/// Zero-size bindings are permitted here for historical reasons. Although
545+
/// A zero-size binding at the end of the buffer is permitted here for historical reasons. Although
546546
/// zero-size bindings are permitted by WebGPU, they are not permitted by
547-
/// some backends. Previous documentation for `hal::BufferBinding`
548-
/// disallowed zero-size bindings, but this restriction was not honored
549-
/// elsewhere in the code. Zero-size bindings need to be quashed or remapped
550-
/// to a non-zero size, either universally in wgpu-core, or in specific
551-
/// backends that do not support them. See
547+
/// some backends. The zero-size binding need to be quashed or remapped to a
548+
/// non-zero size, either universally in wgpu-core, or in specific backends
549+
/// that do not support them. See
552550
/// [#3170](https://github.com/gfx-rs/wgpu/issues/3170).
551+
///
552+
/// Although it seems like it would be simpler and safer to use the resolved
553+
/// size in the returned [`hal::BufferBinding`], doing this (and removing
554+
/// redundant logic in backends to resolve the implicit size) was observed
555+
/// to cause problems in certain CTS tests, so an implicit size
556+
/// specification is preserved in the output.
553557
pub fn binding<'a>(
554558
&'a self,
555559
offset: wgt::BufferAddress,
556-
binding_size: Option<wgt::BufferSizeOrZero>,
560+
binding_size: Option<wgt::BufferSize>,
557561
snatch_guard: &'a SnatchGuard,
558-
) -> Result<hal::BufferBinding<'a, dyn hal::DynBuffer>, BindingError> {
562+
) -> Result<(hal::BufferBinding<'a, dyn hal::DynBuffer>, u64), BindingError> {
559563
let buf_raw = self.try_raw(snatch_guard)?;
560564
let resolved_size = self.resolve_binding_size(offset, binding_size)?;
561565
unsafe {
562566
// SAFETY: The offset and size passed to hal::BufferBinding::new_unchecked must
563567
// define a binding contained within the buffer.
564-
Ok(hal::BufferBinding::new_unchecked(
565-
buf_raw,
566-
offset,
568+
Ok((
569+
hal::BufferBinding::new_unchecked(buf_raw, offset, binding_size),
567570
resolved_size,
568571
))
569572
}

0 commit comments

Comments
 (0)