mirror of
https://github.com/gfx-rs/wgpu.git
synced 2024-11-21 22:33:49 +00:00
improve device mismatch errors
This commit is contained in:
parent
adfb183dc0
commit
ce716adb5e
@ -8,7 +8,7 @@ use crate::{
|
||||
hal_api::HalApi,
|
||||
id::{BindGroupLayoutId, BufferId, SamplerId, TextureId, TextureViewId},
|
||||
init_tracker::{BufferInitTrackerAction, TextureInitTrackerAction},
|
||||
resource::{Resource, ResourceInfo, ResourceType},
|
||||
resource::{ParentDevice, Resource, ResourceInfo, ResourceType},
|
||||
resource_log,
|
||||
snatch::{SnatchGuard, Snatchable},
|
||||
track::{BindGroupStates, UsageConflict},
|
||||
@ -518,6 +518,13 @@ impl<A: HalApi> Resource for BindGroupLayout<A> {
|
||||
&self.label
|
||||
}
|
||||
}
|
||||
|
||||
impl<A: HalApi> ParentDevice<A> for BindGroupLayout<A> {
|
||||
fn device(&self) -> &Arc<Device<A>> {
|
||||
&self.device
|
||||
}
|
||||
}
|
||||
|
||||
impl<A: HalApi> BindGroupLayout<A> {
|
||||
pub(crate) fn raw(&self) -> &A::BindGroupLayout {
|
||||
self.raw.as_ref().unwrap()
|
||||
@ -751,6 +758,12 @@ impl<A: HalApi> Resource for PipelineLayout<A> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<A: HalApi> ParentDevice<A> for PipelineLayout<A> {
|
||||
fn device(&self) -> &Arc<Device<A>> {
|
||||
&self.device
|
||||
}
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Clone, Debug, Hash, Eq, PartialEq)]
|
||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||
@ -956,6 +969,12 @@ impl<A: HalApi> Resource for BindGroup<A> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<A: HalApi> ParentDevice<A> for BindGroup<A> {
|
||||
fn device(&self) -> &Arc<Device<A>> {
|
||||
&self.device
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Error)]
|
||||
#[non_exhaustive]
|
||||
pub enum GetBindGroupLayoutError {
|
||||
|
@ -97,7 +97,7 @@ use crate::{
|
||||
id,
|
||||
init_tracker::{BufferInitTrackerAction, MemoryInitKind, TextureInitTrackerAction},
|
||||
pipeline::{PipelineFlags, RenderPipeline, VertexStep},
|
||||
resource::{Buffer, Resource, ResourceInfo, ResourceType},
|
||||
resource::{Buffer, ParentDevice, Resource, ResourceInfo, ResourceType},
|
||||
resource_log,
|
||||
snatch::SnatchGuard,
|
||||
track::RenderBundleScope,
|
||||
@ -1104,6 +1104,12 @@ impl<A: HalApi> Resource for RenderBundle<A> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<A: HalApi> ParentDevice<A> for RenderBundle<A> {
|
||||
fn device(&self) -> &Arc<Device<A>> {
|
||||
&self.device
|
||||
}
|
||||
}
|
||||
|
||||
/// A render bundle's current index buffer state.
|
||||
///
|
||||
/// [`RenderBundleEncoder::finish`] records the currently set index buffer here,
|
||||
|
@ -11,7 +11,7 @@ use crate::{
|
||||
hal_api::HalApi,
|
||||
id::{BufferId, CommandEncoderId, DeviceId, TextureId},
|
||||
init_tracker::{MemoryInitKind, TextureInitRange},
|
||||
resource::{Resource, Texture, TextureClearMode},
|
||||
resource::{ParentDevice, Resource, Texture, TextureClearMode},
|
||||
snatch::SnatchGuard,
|
||||
track::{TextureSelector, TextureTracker},
|
||||
};
|
||||
@ -104,7 +104,7 @@ impl Global {
|
||||
.get(dst)
|
||||
.map_err(|_| ClearError::InvalidBuffer(dst))?;
|
||||
|
||||
dst_buffer.device.same_device(&cmd_buf.device)?;
|
||||
dst_buffer.same_device_as(cmd_buf.as_ref())?;
|
||||
|
||||
cmd_buf_data
|
||||
.trackers
|
||||
@ -201,7 +201,7 @@ impl Global {
|
||||
.get(dst)
|
||||
.map_err(|_| ClearError::InvalidTexture(dst))?;
|
||||
|
||||
dst_texture.device.same_device(&cmd_buf.device)?;
|
||||
dst_texture.same_device_as(cmd_buf.as_ref())?;
|
||||
|
||||
// Check if subresource aspects are valid.
|
||||
let clear_aspects =
|
||||
|
@ -15,7 +15,7 @@ use crate::{
|
||||
hal_api::HalApi,
|
||||
hal_label, id,
|
||||
init_tracker::MemoryInitKind,
|
||||
resource::{self, Resource},
|
||||
resource::{self, ParentDevice, Resource},
|
||||
snatch::SnatchGuard,
|
||||
track::{Tracker, TrackerIndex, UsageConflict, UsageScope},
|
||||
validation::{check_buffer_usage, MissingBufferUsageError},
|
||||
@ -350,11 +350,8 @@ impl Global {
|
||||
);
|
||||
};
|
||||
|
||||
if query_set.device.same_device(&cmd_buf.device).is_err() {
|
||||
return (
|
||||
ComputePass::new(None, arc_desc),
|
||||
Some(CommandEncoderError::WrongDeviceForTimestampWritesQuerySet),
|
||||
);
|
||||
if let Err(e) = query_set.same_device_as(cmd_buf.as_ref()) {
|
||||
return (ComputePass::new(None, arc_desc), Some(e.into()));
|
||||
}
|
||||
|
||||
Some(ArcComputePassTimestampWrites {
|
||||
@ -582,7 +579,7 @@ impl Global {
|
||||
} => {
|
||||
let scope = PassErrorScope::SetBindGroup(bind_group.as_info().id());
|
||||
|
||||
bind_group.device.same_device(device).map_pass_err(scope)?;
|
||||
bind_group.same_device_as(cmd_buf).map_pass_err(scope)?;
|
||||
|
||||
let max_bind_groups = cmd_buf.limits.max_bind_groups;
|
||||
if index >= max_bind_groups {
|
||||
@ -649,7 +646,7 @@ impl Global {
|
||||
let pipeline_id = pipeline.as_info().id();
|
||||
let scope = PassErrorScope::SetPipelineCompute(pipeline_id);
|
||||
|
||||
pipeline.device.same_device(device).map_pass_err(scope)?;
|
||||
pipeline.same_device_as(cmd_buf).map_pass_err(scope)?;
|
||||
|
||||
state.pipeline = Some(pipeline_id);
|
||||
|
||||
@ -790,7 +787,7 @@ impl Global {
|
||||
pipeline: state.pipeline,
|
||||
};
|
||||
|
||||
buffer.device.same_device(device).map_pass_err(scope)?;
|
||||
buffer.same_device_as(cmd_buf).map_pass_err(scope)?;
|
||||
|
||||
state.is_ready().map_pass_err(scope)?;
|
||||
|
||||
@ -885,7 +882,7 @@ impl Global {
|
||||
} => {
|
||||
let scope = PassErrorScope::WriteTimestamp;
|
||||
|
||||
query_set.device.same_device(device).map_pass_err(scope)?;
|
||||
query_set.same_device_as(cmd_buf).map_pass_err(scope)?;
|
||||
|
||||
device
|
||||
.require_features(wgt::Features::TIMESTAMP_QUERY_INSIDE_PASSES)
|
||||
@ -903,7 +900,7 @@ impl Global {
|
||||
} => {
|
||||
let scope = PassErrorScope::BeginPipelineStatisticsQuery;
|
||||
|
||||
query_set.device.same_device(device).map_pass_err(scope)?;
|
||||
query_set.same_device_as(cmd_buf).map_pass_err(scope)?;
|
||||
|
||||
let query_set = tracker.query_sets.insert_single(query_set);
|
||||
|
||||
|
@ -29,7 +29,7 @@ use crate::lock::{rank, Mutex};
|
||||
use crate::snatch::SnatchGuard;
|
||||
|
||||
use crate::init_tracker::BufferInitTrackerAction;
|
||||
use crate::resource::{Resource, ResourceInfo, ResourceType};
|
||||
use crate::resource::{ParentDevice, Resource, ResourceInfo, ResourceType};
|
||||
use crate::track::{Tracker, UsageScope};
|
||||
use crate::{api_log, global::Global, hal_api::HalApi, id, resource_log, Label};
|
||||
|
||||
@ -541,6 +541,12 @@ impl<A: HalApi> Resource for CommandBuffer<A> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<A: HalApi> ParentDevice<A> for CommandBuffer<A> {
|
||||
fn device(&self) -> &Arc<Device<A>> {
|
||||
&self.device
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
pub struct BasePassRef<'a, C> {
|
||||
pub label: Option<&'a str>,
|
||||
@ -633,11 +639,8 @@ pub enum CommandEncoderError {
|
||||
Device(#[from] DeviceError),
|
||||
#[error("Command encoder is locked by a previously created render/compute pass. Before recording any new commands, the pass must be ended.")]
|
||||
Locked,
|
||||
|
||||
#[error("QuerySet provided for pass timestamp writes is invalid.")]
|
||||
InvalidTimestampWritesQuerySetId,
|
||||
#[error("QuerySet provided for pass timestamp writes that was created by a different device.")]
|
||||
WrongDeviceForTimestampWritesQuerySet,
|
||||
}
|
||||
|
||||
impl Global {
|
||||
|
@ -9,7 +9,7 @@ use crate::{
|
||||
hal_api::HalApi,
|
||||
id::{self, Id},
|
||||
init_tracker::MemoryInitKind,
|
||||
resource::QuerySet,
|
||||
resource::{ParentDevice, QuerySet},
|
||||
storage::Storage,
|
||||
Epoch, FastHashMap, Index,
|
||||
};
|
||||
@ -405,7 +405,7 @@ impl Global {
|
||||
.add_single(&*query_set_guard, query_set_id)
|
||||
.ok_or(QueryError::InvalidQuerySet(query_set_id))?;
|
||||
|
||||
query_set.device.same_device(&cmd_buf.device)?;
|
||||
query_set.same_device_as(cmd_buf.as_ref())?;
|
||||
|
||||
let (dst_buffer, dst_pending) = {
|
||||
let buffer_guard = hub.buffers.read();
|
||||
@ -413,7 +413,7 @@ impl Global {
|
||||
.get(destination)
|
||||
.map_err(|_| QueryError::InvalidBuffer(destination))?;
|
||||
|
||||
dst_buffer.device.same_device(&cmd_buf.device)?;
|
||||
dst_buffer.same_device_as(cmd_buf.as_ref())?;
|
||||
|
||||
tracker
|
||||
.buffers
|
||||
|
@ -25,7 +25,7 @@ use crate::{
|
||||
hal_label, id,
|
||||
init_tracker::{MemoryInitKind, TextureInitRange, TextureInitTrackerAction},
|
||||
pipeline::{self, PipelineFlags},
|
||||
resource::{QuerySet, Texture, TextureView, TextureViewNotRenderableReason},
|
||||
resource::{ParentDevice, QuerySet, Texture, TextureView, TextureViewNotRenderableReason},
|
||||
storage::Storage,
|
||||
track::{TextureSelector, Tracker, UsageConflict, UsageScope},
|
||||
validation::{
|
||||
@ -1476,7 +1476,9 @@ impl Global {
|
||||
.ok_or(RenderCommandError::InvalidBindGroup(bind_group_id))
|
||||
.map_pass_err(scope)?;
|
||||
|
||||
bind_group.device.same_device(device).map_pass_err(scope)?;
|
||||
bind_group
|
||||
.same_device_as(cmd_buf.as_ref())
|
||||
.map_pass_err(scope)?;
|
||||
|
||||
bind_group
|
||||
.validate_dynamic_bindings(index, &temp_offsets, &cmd_buf.limits)
|
||||
@ -1542,7 +1544,9 @@ impl Global {
|
||||
.ok_or(RenderCommandError::InvalidPipeline(pipeline_id))
|
||||
.map_pass_err(scope)?;
|
||||
|
||||
pipeline.device.same_device(device).map_pass_err(scope)?;
|
||||
pipeline
|
||||
.same_device_as(cmd_buf.as_ref())
|
||||
.map_pass_err(scope)?;
|
||||
|
||||
info.context
|
||||
.check_compatible(
|
||||
@ -1669,7 +1673,9 @@ impl Global {
|
||||
.merge_single(&*buffer_guard, buffer_id, hal::BufferUses::INDEX)
|
||||
.map_pass_err(scope)?;
|
||||
|
||||
buffer.device.same_device(device).map_pass_err(scope)?;
|
||||
buffer
|
||||
.same_device_as(cmd_buf.as_ref())
|
||||
.map_pass_err(scope)?;
|
||||
|
||||
check_buffer_usage(buffer_id, buffer.usage, BufferUsages::INDEX)
|
||||
.map_pass_err(scope)?;
|
||||
@ -1720,7 +1726,9 @@ impl Global {
|
||||
.merge_single(&*buffer_guard, buffer_id, hal::BufferUses::VERTEX)
|
||||
.map_pass_err(scope)?;
|
||||
|
||||
buffer.device.same_device(device).map_pass_err(scope)?;
|
||||
buffer
|
||||
.same_device_as(cmd_buf.as_ref())
|
||||
.map_pass_err(scope)?;
|
||||
|
||||
let max_vertex_buffers = device.limits.max_vertex_buffers;
|
||||
if slot >= max_vertex_buffers {
|
||||
@ -2325,7 +2333,9 @@ impl Global {
|
||||
.ok_or(RenderCommandError::InvalidRenderBundle(bundle_id))
|
||||
.map_pass_err(scope)?;
|
||||
|
||||
bundle.device.same_device(device).map_pass_err(scope)?;
|
||||
bundle
|
||||
.same_device_as(cmd_buf.as_ref())
|
||||
.map_pass_err(scope)?;
|
||||
|
||||
info.context
|
||||
.check_compatible(
|
||||
|
@ -13,7 +13,7 @@ use crate::{
|
||||
has_copy_partial_init_tracker_coverage, MemoryInitKind, TextureInitRange,
|
||||
TextureInitTrackerAction,
|
||||
},
|
||||
resource::{Resource, Texture, TextureErrorDimension},
|
||||
resource::{ParentDevice, Resource, Texture, TextureErrorDimension},
|
||||
snatch::SnatchGuard,
|
||||
track::{TextureSelector, Tracker},
|
||||
};
|
||||
@ -602,7 +602,7 @@ impl Global {
|
||||
.get(source)
|
||||
.map_err(|_| TransferError::InvalidBuffer(source))?;
|
||||
|
||||
src_buffer.device.same_device(device)?;
|
||||
src_buffer.same_device_as(cmd_buf.as_ref())?;
|
||||
|
||||
cmd_buf_data
|
||||
.trackers
|
||||
@ -626,7 +626,7 @@ impl Global {
|
||||
.get(destination)
|
||||
.map_err(|_| TransferError::InvalidBuffer(destination))?;
|
||||
|
||||
dst_buffer.device.same_device(device)?;
|
||||
dst_buffer.same_device_as(cmd_buf.as_ref())?;
|
||||
|
||||
cmd_buf_data
|
||||
.trackers
|
||||
@ -777,7 +777,7 @@ impl Global {
|
||||
.get(destination.texture)
|
||||
.map_err(|_| TransferError::InvalidTexture(destination.texture))?;
|
||||
|
||||
dst_texture.device.same_device(device)?;
|
||||
dst_texture.same_device_as(cmd_buf.as_ref())?;
|
||||
|
||||
let (hal_copy_size, array_layer_count) = validate_texture_copy_range(
|
||||
destination,
|
||||
@ -810,7 +810,7 @@ impl Global {
|
||||
.get(source.buffer)
|
||||
.map_err(|_| TransferError::InvalidBuffer(source.buffer))?;
|
||||
|
||||
src_buffer.device.same_device(device)?;
|
||||
src_buffer.same_device_as(cmd_buf.as_ref())?;
|
||||
|
||||
tracker
|
||||
.buffers
|
||||
@ -943,7 +943,7 @@ impl Global {
|
||||
.get(source.texture)
|
||||
.map_err(|_| TransferError::InvalidTexture(source.texture))?;
|
||||
|
||||
src_texture.device.same_device(device)?;
|
||||
src_texture.same_device_as(cmd_buf.as_ref())?;
|
||||
|
||||
let (hal_copy_size, array_layer_count) =
|
||||
validate_texture_copy_range(source, &src_texture.desc, CopySide::Source, copy_size)?;
|
||||
@ -997,7 +997,7 @@ impl Global {
|
||||
.get(destination.buffer)
|
||||
.map_err(|_| TransferError::InvalidBuffer(destination.buffer))?;
|
||||
|
||||
dst_buffer.device.same_device(device)?;
|
||||
dst_buffer.same_device_as(cmd_buf.as_ref())?;
|
||||
|
||||
tracker
|
||||
.buffers
|
||||
@ -1127,8 +1127,8 @@ impl Global {
|
||||
.get(destination.texture)
|
||||
.map_err(|_| TransferError::InvalidTexture(source.texture))?;
|
||||
|
||||
src_texture.device.same_device(device)?;
|
||||
dst_texture.device.same_device(device)?;
|
||||
src_texture.same_device_as(cmd_buf.as_ref())?;
|
||||
dst_texture.same_device_as(cmd_buf.as_ref())?;
|
||||
|
||||
// src and dst texture format must be copy-compatible
|
||||
// https://gpuweb.github.io/gpuweb/#copy-compatible
|
||||
|
@ -15,6 +15,7 @@ use crate::{
|
||||
pipeline, present,
|
||||
resource::{
|
||||
self, BufferAccessError, BufferAccessResult, BufferMapOperation, CreateBufferError,
|
||||
ParentDevice,
|
||||
},
|
||||
validation::check_buffer_usage,
|
||||
Label, LabelHelpers as _,
|
||||
@ -1124,7 +1125,7 @@ impl Global {
|
||||
Err(..) => break 'error binding_model::CreateBindGroupError::InvalidLayout,
|
||||
};
|
||||
|
||||
if let Err(e) = bind_group_layout.device.same_device(&device) {
|
||||
if let Err(e) = bind_group_layout.same_device(&device) {
|
||||
break 'error e.into();
|
||||
}
|
||||
|
||||
|
@ -3,7 +3,9 @@ use crate::{
|
||||
hal_api::HalApi,
|
||||
hub::Hub,
|
||||
id::{BindGroupLayoutId, PipelineLayoutId},
|
||||
resource::{Buffer, BufferAccessError, BufferAccessResult, BufferMapOperation},
|
||||
resource::{
|
||||
Buffer, BufferAccessError, BufferAccessResult, BufferMapOperation, ResourceErrorIdent,
|
||||
},
|
||||
snatch::SnatchGuard,
|
||||
Label, DOWNLEVEL_ERROR_MESSAGE,
|
||||
};
|
||||
@ -382,6 +384,30 @@ fn map_buffer<A: HalApi>(
|
||||
#[error("Device is invalid")]
|
||||
pub struct InvalidDevice;
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct WrongDevice {
|
||||
pub(super) res: ResourceErrorIdent,
|
||||
pub(super) res_device: ResourceErrorIdent,
|
||||
pub(super) target: Option<ResourceErrorIdent>,
|
||||
pub(super) target_device: ResourceErrorIdent,
|
||||
}
|
||||
|
||||
impl std::fmt::Display for WrongDevice {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
|
||||
write!(
|
||||
f,
|
||||
"{} of {} doesn't match {}",
|
||||
self.res_device, self.res, self.target_device
|
||||
)?;
|
||||
if let Some(target) = self.target.as_ref() {
|
||||
write!(f, " of {target}")?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl std::error::Error for WrongDevice {}
|
||||
|
||||
#[derive(Clone, Debug, Error)]
|
||||
#[non_exhaustive]
|
||||
pub enum DeviceError {
|
||||
@ -395,8 +421,8 @@ pub enum DeviceError {
|
||||
ResourceCreationFailed,
|
||||
#[error("QueueId is invalid")]
|
||||
InvalidQueueId,
|
||||
#[error("Attempt to use a resource with a different device from the one that created it")]
|
||||
WrongDevice,
|
||||
#[error(transparent)]
|
||||
WrongDevice(#[from] Box<WrongDevice>),
|
||||
}
|
||||
|
||||
impl From<hal::DeviceError> for DeviceError {
|
||||
|
@ -16,8 +16,8 @@ use crate::{
|
||||
init_tracker::{has_copy_partial_init_tracker_coverage, TextureInitRange},
|
||||
lock::{rank, Mutex, RwLockWriteGuard},
|
||||
resource::{
|
||||
Buffer, BufferAccessError, BufferMapState, DestroyedBuffer, DestroyedTexture, Resource,
|
||||
ResourceInfo, ResourceType, StagingBuffer, Texture, TextureInner,
|
||||
Buffer, BufferAccessError, BufferMapState, DestroyedBuffer, DestroyedTexture, ParentDevice,
|
||||
Resource, ResourceInfo, ResourceType, StagingBuffer, Texture, TextureInner,
|
||||
},
|
||||
resource_log, track, FastHashMap, SubmissionIndex,
|
||||
};
|
||||
@ -53,6 +53,12 @@ impl<A: HalApi> Resource for Queue<A> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<A: HalApi> ParentDevice<A> for Queue<A> {
|
||||
fn device(&self) -> &Arc<Device<A>> {
|
||||
self.device.as_ref().unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
impl<A: HalApi> Drop for Queue<A> {
|
||||
fn drop(&mut self) {
|
||||
let queue = self.raw.take().unwrap();
|
||||
@ -408,7 +414,7 @@ impl Global {
|
||||
|
||||
let device = queue.device.as_ref().unwrap();
|
||||
|
||||
buffer.device.same_device(device)?;
|
||||
buffer.same_device_as(queue.as_ref())?;
|
||||
|
||||
let data_size = data.len() as wgt::BufferAddress;
|
||||
|
||||
@ -449,6 +455,7 @@ impl Global {
|
||||
}
|
||||
|
||||
let result = self.queue_write_staging_buffer_impl(
|
||||
&queue,
|
||||
device,
|
||||
pending_writes,
|
||||
&staging_buffer,
|
||||
@ -523,6 +530,7 @@ impl Global {
|
||||
}
|
||||
|
||||
let result = self.queue_write_staging_buffer_impl(
|
||||
&queue,
|
||||
device,
|
||||
pending_writes,
|
||||
&staging_buffer,
|
||||
@ -587,6 +595,7 @@ impl Global {
|
||||
|
||||
fn queue_write_staging_buffer_impl<A: HalApi>(
|
||||
&self,
|
||||
queue: &Arc<Queue<A>>,
|
||||
device: &Arc<Device<A>>,
|
||||
pending_writes: &mut PendingWrites<A>,
|
||||
staging_buffer: &StagingBuffer<A>,
|
||||
@ -612,7 +621,7 @@ impl Global {
|
||||
.get(&snatch_guard)
|
||||
.ok_or(TransferError::InvalidBuffer(buffer_id))?;
|
||||
|
||||
dst.device.same_device(device)?;
|
||||
dst.same_device_as(queue.as_ref())?;
|
||||
|
||||
let src_buffer_size = staging_buffer.size;
|
||||
self.queue_validate_write_buffer_impl(&dst, buffer_id, buffer_offset, src_buffer_size)?;
|
||||
@ -695,7 +704,7 @@ impl Global {
|
||||
.get(destination.texture)
|
||||
.map_err(|_| TransferError::InvalidTexture(destination.texture))?;
|
||||
|
||||
dst.device.same_device(device)?;
|
||||
dst.same_device_as(queue.as_ref())?;
|
||||
|
||||
if !dst.desc.usage.contains(wgt::TextureUsages::COPY_DST) {
|
||||
return Err(
|
||||
@ -1176,7 +1185,7 @@ impl Global {
|
||||
Err(_) => continue,
|
||||
};
|
||||
|
||||
cmdbuf.device.same_device(device)?;
|
||||
cmdbuf.same_device_as(queue.as_ref())?;
|
||||
|
||||
#[cfg(feature = "trace")]
|
||||
if let Some(ref mut trace) = *device.trace.lock() {
|
||||
|
@ -24,8 +24,8 @@ use crate::{
|
||||
pool::ResourcePool,
|
||||
registry::Registry,
|
||||
resource::{
|
||||
self, Buffer, QuerySet, Resource, ResourceInfo, ResourceType, Sampler, Texture,
|
||||
TextureView, TextureViewNotRenderableReason,
|
||||
self, Buffer, ParentDevice, QuerySet, Resource, ResourceInfo, ResourceType, Sampler,
|
||||
Texture, TextureView, TextureViewNotRenderableReason,
|
||||
},
|
||||
resource_log,
|
||||
snatch::{SnatchGuard, SnatchLock, Snatchable},
|
||||
@ -313,12 +313,6 @@ impl<A: HalApi> Device<A> {
|
||||
self.valid.load(Ordering::Acquire)
|
||||
}
|
||||
|
||||
pub fn same_device(self: &Arc<Self>, other: &Arc<Self>) -> Result<(), DeviceError> {
|
||||
Arc::ptr_eq(self, other)
|
||||
.then_some(())
|
||||
.ok_or(DeviceError::WrongDevice)
|
||||
}
|
||||
|
||||
pub(crate) fn release_queue(&self, queue: A::Queue) {
|
||||
assert!(self.queue_to_drop.set(queue).is_ok());
|
||||
}
|
||||
@ -1904,7 +1898,7 @@ impl<A: HalApi> Device<A> {
|
||||
.add_single(storage, bb.buffer_id, internal_use)
|
||||
.ok_or(Error::InvalidBuffer(bb.buffer_id))?;
|
||||
|
||||
buffer.device.same_device(self)?;
|
||||
buffer.same_device(self)?;
|
||||
|
||||
check_buffer_usage(bb.buffer_id, buffer.usage, pub_usage)?;
|
||||
let raw_buffer = buffer
|
||||
@ -1997,7 +1991,7 @@ impl<A: HalApi> Device<A> {
|
||||
.add_single(storage, id)
|
||||
.ok_or(Error::InvalidSampler(id))?;
|
||||
|
||||
sampler.device.same_device(self)?;
|
||||
sampler.same_device(self)?;
|
||||
|
||||
Ok(sampler)
|
||||
}
|
||||
@ -2019,7 +2013,7 @@ impl<A: HalApi> Device<A> {
|
||||
.add_single(storage, id)
|
||||
.ok_or(Error::InvalidTextureView(id))?;
|
||||
|
||||
view.device.same_device(self)?;
|
||||
view.same_device(self)?;
|
||||
|
||||
let (pub_usage, internal_use) = self.texture_use_parameters(
|
||||
binding,
|
||||
@ -2038,7 +2032,7 @@ impl<A: HalApi> Device<A> {
|
||||
texture_id,
|
||||
))?;
|
||||
|
||||
texture.device.same_device(&view.device)?;
|
||||
texture.same_device_as(view)?;
|
||||
|
||||
check_texture_usage(texture.desc.usage, pub_usage)?;
|
||||
|
||||
@ -2523,7 +2517,7 @@ impl<A: HalApi> Device<A> {
|
||||
|
||||
// Validate total resource counts and check for a matching device
|
||||
for bgl in &bind_group_layouts {
|
||||
bgl.device.same_device(self)?;
|
||||
bgl.same_device(self)?;
|
||||
|
||||
count_validator.merge(&bgl.binding_count_validator);
|
||||
}
|
||||
@ -2631,7 +2625,7 @@ impl<A: HalApi> Device<A> {
|
||||
.get(desc.stage.module)
|
||||
.map_err(|_| validation::StageError::InvalidModule)?;
|
||||
|
||||
shader_module.device.same_device(self)?;
|
||||
shader_module.same_device(self)?;
|
||||
|
||||
// Get the pipeline layout from the desc if it is provided.
|
||||
let pipeline_layout = match desc.layout {
|
||||
@ -2641,7 +2635,7 @@ impl<A: HalApi> Device<A> {
|
||||
.get(pipeline_layout_id)
|
||||
.map_err(|_| pipeline::CreateComputePipelineError::InvalidLayout)?;
|
||||
|
||||
pipeline_layout.device.same_device(self)?;
|
||||
pipeline_layout.same_device(self)?;
|
||||
|
||||
Some(pipeline_layout)
|
||||
}
|
||||
@ -2703,7 +2697,7 @@ impl<A: HalApi> Device<A> {
|
||||
break 'cache None;
|
||||
};
|
||||
|
||||
cache.device.same_device(self)?;
|
||||
cache.same_device(self)?;
|
||||
Some(cache)
|
||||
};
|
||||
|
||||
@ -3081,7 +3075,7 @@ impl<A: HalApi> Device<A> {
|
||||
.get(pipeline_layout_id)
|
||||
.map_err(|_| pipeline::CreateRenderPipelineError::InvalidLayout)?;
|
||||
|
||||
pipeline_layout.device.same_device(self)?;
|
||||
pipeline_layout.same_device(self)?;
|
||||
|
||||
Some(pipeline_layout)
|
||||
}
|
||||
@ -3116,7 +3110,7 @@ impl<A: HalApi> Device<A> {
|
||||
error: validation::StageError::InvalidModule,
|
||||
}
|
||||
})?;
|
||||
vertex_shader_module.device.same_device(self)?;
|
||||
vertex_shader_module.same_device(self)?;
|
||||
|
||||
let stage_err = |error| pipeline::CreateRenderPipelineError::Stage { stage, error };
|
||||
|
||||
@ -3308,7 +3302,7 @@ impl<A: HalApi> Device<A> {
|
||||
break 'cache None;
|
||||
};
|
||||
|
||||
cache.device.same_device(self)?;
|
||||
cache.same_device(self)?;
|
||||
Some(cache)
|
||||
};
|
||||
|
||||
|
@ -7,7 +7,7 @@ use crate::{
|
||||
device::{Device, DeviceError, MissingDownlevelFlags, MissingFeatures, RenderPassContext},
|
||||
hal_api::HalApi,
|
||||
id::{PipelineCacheId, PipelineLayoutId, ShaderModuleId},
|
||||
resource::{Resource, ResourceInfo, ResourceType},
|
||||
resource::{ParentDevice, Resource, ResourceInfo, ResourceType},
|
||||
resource_log, validation, Label,
|
||||
};
|
||||
use arrayvec::ArrayVec;
|
||||
@ -90,6 +90,12 @@ impl<A: HalApi> Resource for ShaderModule<A> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<A: HalApi> ParentDevice<A> for ShaderModule<A> {
|
||||
fn device(&self) -> &Arc<Device<A>> {
|
||||
&self.device
|
||||
}
|
||||
}
|
||||
|
||||
impl<A: HalApi> ShaderModule<A> {
|
||||
pub(crate) fn raw(&self) -> &A::ShaderModule {
|
||||
self.raw.as_ref().unwrap()
|
||||
@ -258,6 +264,12 @@ impl<A: HalApi> Resource for ComputePipeline<A> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<A: HalApi> ParentDevice<A> for ComputePipeline<A> {
|
||||
fn device(&self) -> &Arc<Device<A>> {
|
||||
&self.device
|
||||
}
|
||||
}
|
||||
|
||||
impl<A: HalApi> ComputePipeline<A> {
|
||||
pub(crate) fn raw(&self) -> &A::ComputePipeline {
|
||||
self.raw.as_ref().unwrap()
|
||||
@ -326,6 +338,12 @@ impl<A: HalApi> Resource for PipelineCache<A> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<A: HalApi> ParentDevice<A> for PipelineCache<A> {
|
||||
fn device(&self) -> &Arc<Device<A>> {
|
||||
&self.device
|
||||
}
|
||||
}
|
||||
|
||||
/// Describes how the vertex buffer is interpreted.
|
||||
#[derive(Clone, Debug)]
|
||||
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
|
||||
@ -585,6 +603,12 @@ impl<A: HalApi> Resource for RenderPipeline<A> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<A: HalApi> ParentDevice<A> for RenderPipeline<A> {
|
||||
fn device(&self) -> &Arc<Device<A>> {
|
||||
&self.device
|
||||
}
|
||||
}
|
||||
|
||||
impl<A: HalApi> RenderPipeline<A> {
|
||||
pub(crate) fn raw(&self) -> &A::RenderPipeline {
|
||||
self.raw.as_ref().unwrap()
|
||||
|
@ -4,7 +4,7 @@ use crate::{
|
||||
binding_model::BindGroup,
|
||||
device::{
|
||||
queue, resource::DeferredDestroy, BufferMapPendingClosure, Device, DeviceError, HostMap,
|
||||
MissingDownlevelFlags, MissingFeatures,
|
||||
MissingDownlevelFlags, MissingFeatures, WrongDevice,
|
||||
},
|
||||
global::Global,
|
||||
hal_api::HalApi,
|
||||
@ -143,6 +143,48 @@ impl<T: Resource> ResourceInfo<T> {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct ResourceErrorIdent {
|
||||
r#type: ResourceType,
|
||||
label: String,
|
||||
}
|
||||
|
||||
impl std::fmt::Display for ResourceErrorIdent {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
|
||||
write!(f, "{} with '{}' label", self.r#type, self.label)
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) trait ParentDevice<A: HalApi>: Resource {
|
||||
fn device(&self) -> &Arc<Device<A>>;
|
||||
|
||||
fn same_device_as<O: ParentDevice<A>>(&self, other: &O) -> Result<(), DeviceError> {
|
||||
Arc::ptr_eq(self.device(), other.device())
|
||||
.then_some(())
|
||||
.ok_or_else(|| {
|
||||
DeviceError::WrongDevice(Box::new(WrongDevice {
|
||||
res: self.error_ident(),
|
||||
res_device: self.device().error_ident(),
|
||||
target: Some(other.error_ident()),
|
||||
target_device: other.device().error_ident(),
|
||||
}))
|
||||
})
|
||||
}
|
||||
|
||||
fn same_device(&self, device: &Arc<Device<A>>) -> Result<(), DeviceError> {
|
||||
Arc::ptr_eq(self.device(), device)
|
||||
.then_some(())
|
||||
.ok_or_else(|| {
|
||||
DeviceError::WrongDevice(Box::new(WrongDevice {
|
||||
res: self.error_ident(),
|
||||
res_device: self.device().error_ident(),
|
||||
target: None,
|
||||
target_device: device.error_ident(),
|
||||
}))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) type ResourceType = &'static str;
|
||||
|
||||
pub(crate) trait Resource: 'static + Sized + WasmNotSendSync {
|
||||
@ -169,6 +211,12 @@ pub(crate) trait Resource: 'static + Sized + WasmNotSendSync {
|
||||
fn is_equal(&self, other: &Self) -> bool {
|
||||
self.as_info().id().unzip() == other.as_info().id().unzip()
|
||||
}
|
||||
fn error_ident(&self) -> ResourceErrorIdent {
|
||||
ResourceErrorIdent {
|
||||
r#type: Self::TYPE,
|
||||
label: self.label().to_owned(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// The status code provided to the buffer mapping callback.
|
||||
@ -627,6 +675,12 @@ impl<A: HalApi> Resource for Buffer<A> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<A: HalApi> ParentDevice<A> for Buffer<A> {
|
||||
fn device(&self) -> &Arc<Device<A>> {
|
||||
&self.device
|
||||
}
|
||||
}
|
||||
|
||||
/// A buffer that has been marked as destroyed and is staged for actual deletion soon.
|
||||
#[derive(Debug)]
|
||||
pub struct DestroyedBuffer<A: HalApi> {
|
||||
@ -731,6 +785,12 @@ impl<A: HalApi> Resource for StagingBuffer<A> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<A: HalApi> ParentDevice<A> for StagingBuffer<A> {
|
||||
fn device(&self) -> &Arc<Device<A>> {
|
||||
&self.device
|
||||
}
|
||||
}
|
||||
|
||||
pub type TextureDescriptor<'a> = wgt::TextureDescriptor<Label<'a>, Vec<wgt::TextureFormat>>;
|
||||
|
||||
#[derive(Debug)]
|
||||
@ -1245,6 +1305,12 @@ impl<A: HalApi> Resource for Texture<A> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<A: HalApi> ParentDevice<A> for Texture<A> {
|
||||
fn device(&self) -> &Arc<Device<A>> {
|
||||
&self.device
|
||||
}
|
||||
}
|
||||
|
||||
impl<A: HalApi> Borrow<TextureSelector> for Texture<A> {
|
||||
fn borrow(&self) -> &TextureSelector {
|
||||
&self.full_range
|
||||
@ -1410,6 +1476,12 @@ impl<A: HalApi> Resource for TextureView<A> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<A: HalApi> ParentDevice<A> for TextureView<A> {
|
||||
fn device(&self) -> &Arc<Device<A>> {
|
||||
&self.device
|
||||
}
|
||||
}
|
||||
|
||||
/// Describes a [`Sampler`]
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
|
||||
@ -1531,6 +1603,12 @@ impl<A: HalApi> Resource for Sampler<A> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<A: HalApi> ParentDevice<A> for Sampler<A> {
|
||||
fn device(&self) -> &Arc<Device<A>> {
|
||||
&self.device
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Error)]
|
||||
#[non_exhaustive]
|
||||
pub enum CreateQuerySetError {
|
||||
@ -1571,6 +1649,12 @@ impl<A: HalApi> Drop for QuerySet<A> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<A: HalApi> ParentDevice<A> for QuerySet<A> {
|
||||
fn device(&self) -> &Arc<Device<A>> {
|
||||
&self.device
|
||||
}
|
||||
}
|
||||
|
||||
impl<A: HalApi> Resource for QuerySet<A> {
|
||||
const TYPE: ResourceType = "QuerySet";
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user