Skip to content

Commit 5c357cb

Browse files
committed
deno: Reject zero-size bindings in createBindGroup
1 parent 5444e19 commit 5c357cb

File tree

4 files changed

+85
-40
lines changed

4 files changed

+85
-40
lines changed

cts_runner/test.lst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ webgpu:api,operation,vertex_state,correctness:setVertexBuffer_offset_and_attribu
3333
webgpu:api,validation,buffer,create:*
3434
webgpu:api,validation,buffer,destroy:*
3535
fails-if(dx12) webgpu:api,validation,capability_checks,limits,maxBindGroups:setBindGroup,*
36+
webgpu:api,validation,createBindGroup:buffer_offset_and_size_for_bind_groups_match:*
3637
webgpu:api,validation,createBindGroup:buffer,effective_buffer_binding_size:*
3738
webgpu:api,validation,createBindGroup:buffer,resource_binding_size:*
3839
// Fails because we coerce a size of 0 in `GPUDevice.createBindGroup(…)` to `buffer.size - offset`.

deno_webgpu/device.rs

Lines changed: 64 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ use deno_core::v8;
1111
use deno_core::webidl::WebIdlInterfaceConverter;
1212
use deno_core::GarbageCollected;
1313
use deno_error::JsErrorBox;
14-
use wgpu_core::binding_model::BindingResource;
14+
use wgpu_core::binding_model::{BindingResource, CreateBindGroupError};
1515
use wgpu_core::pipeline::ProgrammableStageDescriptor;
1616
use wgpu_types::BindingType;
1717

@@ -404,49 +404,73 @@ impl GPUDevice {
404404
&self,
405405
#[webidl] descriptor: super::bind_group::GPUBindGroupDescriptor,
406406
) -> GPUBindGroup {
407-
let entries = descriptor
408-
.entries
409-
.into_iter()
410-
.map(|entry| wgpu_core::binding_model::BindGroupEntry {
411-
binding: entry.binding,
412-
resource: match entry.resource {
413-
GPUBindingResource::Sampler(sampler) => {
414-
BindingResource::Sampler(sampler.id)
415-
}
416-
GPUBindingResource::Texture(texture) => {
417-
BindingResource::TextureView(texture.default_view_id())
418-
}
419-
GPUBindingResource::TextureView(texture_view) => {
420-
BindingResource::TextureView(texture_view.id)
421-
}
422-
GPUBindingResource::Buffer(buffer) => {
423-
BindingResource::Buffer(wgpu_core::binding_model::BufferBinding {
424-
buffer: buffer.id,
425-
offset: 0,
426-
size: NonZeroU64::new(buffer.size),
427-
})
428-
}
429-
GPUBindingResource::BufferBinding(buffer_binding) => {
430-
BindingResource::Buffer(wgpu_core::binding_model::BufferBinding {
431-
buffer: buffer_binding.buffer.id,
432-
offset: buffer_binding.offset,
433-
size: buffer_binding.size.and_then(NonZeroU64::new),
434-
})
435-
}
436-
},
437-
})
438-
.collect::<Vec<_>>();
407+
let mut entries = Vec::with_capacity(descriptor.entries.len());
408+
let (id, err) = 'error: {
409+
for entry in descriptor.entries.iter() {
410+
entries.push(wgpu_core::binding_model::BindGroupEntry {
411+
binding: entry.binding,
412+
resource: match &entry.resource {
413+
GPUBindingResource::Sampler(sampler) => {
414+
BindingResource::Sampler(sampler.id)
415+
}
416+
GPUBindingResource::Texture(texture) => {
417+
BindingResource::TextureView(texture.default_view_id())
418+
}
419+
GPUBindingResource::TextureView(texture_view) => {
420+
BindingResource::TextureView(texture_view.id)
421+
}
422+
GPUBindingResource::Buffer(buffer) => {
423+
BindingResource::Buffer(wgpu_core::binding_model::BufferBinding {
424+
buffer: buffer.id,
425+
offset: 0,
426+
size: NonZeroU64::new(buffer.size),
427+
})
428+
}
429+
GPUBindingResource::BufferBinding(buffer_binding) => {
430+
let size = buffer_binding.size.map(NonZeroU64::new);
431+
match size {
432+
None | Some(Some(_)) => {
433+
// Size non-zero or omitted
434+
BindingResource::Buffer(
435+
wgpu_core::binding_model::BufferBinding {
436+
buffer: buffer_binding.buffer.id,
437+
offset: buffer_binding.offset,
438+
size: size.unwrap_or_default(),
439+
},
440+
)
441+
}
442+
Some(None) => {
443+
// Explicit zero size. Not representable in wgpu API.
444+
let id = self.instance.create_bind_group_error(
445+
None,
446+
crate::transform_label(descriptor.label.clone()),
447+
);
448+
let error_ident =
449+
wgpu_core::resource::ResourceErrorIdent::new(
450+
"Buffer",
451+
buffer_binding.buffer.label.clone(),
452+
);
453+
break 'error (
454+
id,
455+
Some(CreateBindGroupError::BindingZeroSize(error_ident)),
456+
);
457+
}
458+
}
459+
}
460+
},
461+
});
462+
}
439463

440-
let wgpu_descriptor = wgpu_core::binding_model::BindGroupDescriptor {
441-
label: crate::transform_label(descriptor.label.clone()),
442-
layout: descriptor.layout.id,
443-
entries: Cow::Owned(entries),
444-
};
464+
let wgpu_descriptor = wgpu_core::binding_model::BindGroupDescriptor {
465+
label: crate::transform_label(descriptor.label.clone()),
466+
layout: descriptor.layout.id,
467+
entries: Cow::Owned(entries),
468+
};
445469

446-
let (id, err) =
447470
self
448471
.instance
449-
.device_create_bind_group(self.id, &wgpu_descriptor, None);
472+
.device_create_bind_group(self.id, &wgpu_descriptor, None)
473+
};
450474

451475
self.error_handler.push_error(err);
452476

wgpu-core/src/device/global.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -232,6 +232,15 @@ impl Global {
232232
fid.assign(Fallible::Invalid(Arc::new(label.to_string())));
233233
}
234234

235+
pub fn create_bind_group_error(
236+
&self,
237+
id_in: Option<id::BindGroupId>,
238+
label: Option<Cow<'_, str>>,
239+
) -> id::BindGroupId {
240+
let fid = self.hub.bind_groups.prepare(id_in);
241+
fid.assign(Fallible::Invalid(Arc::new(label.to_string())))
242+
}
243+
235244
pub fn buffer_destroy(&self, buffer_id: id::BufferId) {
236245
profiling::scope!("Buffer::destroy");
237246
api_log!("Buffer::destroy {buffer_id:?}");

wgpu-core/src/resource.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,17 @@ impl fmt::Display for ResourceErrorIdent {
9191
}
9292
}
9393

94+
impl ResourceErrorIdent {
95+
/// Prefer [`Labeled::error_ident`] when possible.
96+
#[doc(hidden)]
97+
pub fn new(r#type: &'static str, label: String) -> Self {
98+
Self {
99+
r#type: Cow::Borrowed(r#type),
100+
label,
101+
}
102+
}
103+
}
104+
94105
pub trait ParentDevice: Labeled {
95106
fn device(&self) -> &Arc<Device>;
96107

0 commit comments

Comments
 (0)