diff --git a/wgpu-core/src/command/bundle.rs b/wgpu-core/src/command/bundle.rs
index 9dbcb6a08d..6121ab8f9f 100644
--- a/wgpu-core/src/command/bundle.rs
+++ b/wgpu-core/src/command/bundle.rs
@@ -263,6 +263,15 @@ impl RenderBundleEncoder {
} => {
let scope = PassErrorScope::SetBindGroup(bind_group_id);
+ let bind_group: &binding_model::BindGroup = state
+ .trackers
+ .bind_groups
+ .add_single(&*bind_group_guard, bind_group_id)
+ .ok_or(RenderCommandError::InvalidBindGroup(bind_group_id))
+ .map_pass_err(scope)?;
+ self.check_valid_to_use(bind_group.device_id.value)
+ .map_pass_err(scope)?;
+
let max_bind_groups = device.limits.max_bind_groups;
if (index as u32) >= max_bind_groups {
return Err(RenderCommandError::BindGroupIndexOutOfRange {
@@ -279,12 +288,6 @@ impl RenderBundleEncoder {
next_dynamic_offset = offsets_range.end;
let offsets = &base.dynamic_offsets[offsets_range.clone()];
- let bind_group: &binding_model::BindGroup = state
- .trackers
- .bind_groups
- .add_single(&*bind_group_guard, bind_group_id)
- .ok_or(RenderCommandError::InvalidBindGroup(bind_group_id))
- .map_pass_err(scope)?;
if bind_group.dynamic_binding_info.len() != offsets.len() {
return Err(RenderCommandError::InvalidDynamicOffsetCount {
actual: offsets.len(),
@@ -333,6 +336,8 @@ impl RenderBundleEncoder {
.add_single(&*pipeline_guard, pipeline_id)
.ok_or(RenderCommandError::InvalidPipeline(pipeline_id))
.map_pass_err(scope)?;
+ self.check_valid_to_use(pipeline.device_id.value)
+ .map_pass_err(scope)?;
self.context
.check_compatible(&pipeline.pass_context)
@@ -372,6 +377,8 @@ impl RenderBundleEncoder {
.buffers
.merge_single(&*buffer_guard, buffer_id, hal::BufferUses::INDEX)
.map_pass_err(scope)?;
+ self.check_valid_to_use(buffer.device_id.value)
+ .map_pass_err(scope)?;
check_buffer_usage(buffer.usage, wgt::BufferUsages::INDEX)
.map_pass_err(scope)?;
@@ -399,6 +406,8 @@ impl RenderBundleEncoder {
.buffers
.merge_single(&*buffer_guard, buffer_id, hal::BufferUses::VERTEX)
.map_pass_err(scope)?;
+ self.check_valid_to_use(buffer.device_id.value)
+ .map_pass_err(scope)?;
check_buffer_usage(buffer.usage, wgt::BufferUsages::VERTEX)
.map_pass_err(scope)?;
@@ -524,6 +533,8 @@ impl RenderBundleEncoder {
.buffers
.merge_single(&*buffer_guard, buffer_id, hal::BufferUses::INDIRECT)
.map_pass_err(scope)?;
+ self.check_valid_to_use(buffer.device_id.value)
+ .map_pass_err(scope)?;
check_buffer_usage(buffer.usage, wgt::BufferUsages::INDIRECT)
.map_pass_err(scope)?;
@@ -557,6 +568,8 @@ impl RenderBundleEncoder {
.buffers
.merge_single(&*buffer_guard, buffer_id, hal::BufferUses::INDIRECT)
.map_pass_err(scope)?;
+ self.check_valid_to_use(buffer.device_id.value)
+ .map_pass_err(scope)?;
check_buffer_usage(buffer.usage, wgt::BufferUsages::INDIRECT)
.map_pass_err(scope)?;
@@ -608,6 +621,17 @@ impl RenderBundleEncoder {
})
}
+ fn check_valid_to_use(
+ &self,
+ device_id: id::Valid,
+ ) -> Result<(), RenderBundleErrorInner> {
+ if device_id.0 != self.parent_id {
+ return Err(RenderBundleErrorInner::NotValidToUse);
+ }
+
+ Ok(())
+ }
+
pub fn set_index_buffer(
&mut self,
buffer_id: id::BufferId,
@@ -1274,6 +1298,8 @@ impl State {
/// Error encountered when finishing recording a render bundle.
#[derive(Clone, Debug, Error)]
pub(super) enum RenderBundleErrorInner {
+ #[error("resource is not valid to use with this render bundle because the resource and the bundle come from different devices")]
+ NotValidToUse,
#[error(transparent)]
Device(#[from] DeviceError),
#[error(transparent)]