mirror of
https://github.com/gfx-rs/wgpu.git
synced 2024-11-25 00:03:29 +00:00
[wgpu-core] introduce Fallible
and use it for Buffer
(first step of invalidity internalization)
This commit is contained in:
parent
3437589107
commit
68e8b7d4a8
@ -17,21 +17,16 @@ static BAD_BUFFER: GpuTestConfiguration = GpuTestConfiguration::new().run_sync(|
|
||||
Some("`map` usage can only be combined with the opposite `copy`"),
|
||||
);
|
||||
|
||||
let error = match ctx.adapter_info.backend.to_str() {
|
||||
"vulkan" | "vk" => "bufferid id(0,1,vk) is invalid",
|
||||
"dx12" | "d3d12" => "bufferid id(0,1,d3d12) is invalid",
|
||||
"metal" | "mtl" => "bufferid id(0,1,mtl) is invalid",
|
||||
"opengl" | "gles" | "gl" => "bufferid id(0,1,gl) is invalid",
|
||||
"webgpu" => "bufferid id(0,1,webgpu) is invalid",
|
||||
b => b,
|
||||
};
|
||||
|
||||
fail(
|
||||
&ctx.device,
|
||||
|| buffer.slice(..).map_async(wgpu::MapMode::Write, |_| {}),
|
||||
Some(error),
|
||||
Some("Buffer with '' label is invalid"),
|
||||
);
|
||||
fail(
|
||||
&ctx.device,
|
||||
|| buffer.unmap(),
|
||||
Some("Buffer with '' label is invalid"),
|
||||
);
|
||||
fail(&ctx.device, || buffer.unmap(), Some(error));
|
||||
valid(&ctx.device, || buffer.destroy());
|
||||
valid(&ctx.device, || buffer.destroy());
|
||||
});
|
||||
|
@ -6,8 +6,8 @@ use crate::{
|
||||
init_tracker::{BufferInitTrackerAction, TextureInitTrackerAction},
|
||||
pipeline::{ComputePipeline, RenderPipeline},
|
||||
resource::{
|
||||
Buffer, DestroyedResourceError, Labeled, MissingBufferUsageError, MissingTextureUsageError,
|
||||
ResourceErrorIdent, Sampler, TextureView, TrackingData,
|
||||
Buffer, DestroyedResourceError, InvalidResourceError, Labeled, MissingBufferUsageError,
|
||||
MissingTextureUsageError, ResourceErrorIdent, Sampler, TextureView, TrackingData,
|
||||
},
|
||||
resource_log,
|
||||
snatch::{SnatchGuard, Snatchable},
|
||||
@ -81,8 +81,6 @@ pub enum CreateBindGroupError {
|
||||
Device(#[from] DeviceError),
|
||||
#[error("Bind group layout is invalid")]
|
||||
InvalidLayout,
|
||||
#[error("BufferId {0:?} is invalid")]
|
||||
InvalidBufferId(BufferId),
|
||||
#[error("TextureViewId {0:?} is invalid")]
|
||||
InvalidTextureViewId(TextureViewId),
|
||||
#[error("SamplerId {0:?} is invalid")]
|
||||
@ -188,6 +186,8 @@ pub enum CreateBindGroupError {
|
||||
StorageReadNotSupported(wgt::TextureFormat),
|
||||
#[error(transparent)]
|
||||
ResourceUsageCompatibility(#[from] ResourceUsageCompatibilityError),
|
||||
#[error(transparent)]
|
||||
InvalidResource(#[from] InvalidResourceError),
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Error)]
|
||||
|
@ -92,7 +92,10 @@ use crate::{
|
||||
id,
|
||||
init_tracker::{BufferInitTrackerAction, MemoryInitKind, TextureInitTrackerAction},
|
||||
pipeline::{PipelineFlags, RenderPipeline, VertexStep},
|
||||
resource::{Buffer, DestroyedResourceError, Labeled, ParentDevice, TrackingData},
|
||||
resource::{
|
||||
Buffer, DestroyedResourceError, Fallible, InvalidResourceError, Labeled, ParentDevice,
|
||||
TrackingData,
|
||||
},
|
||||
resource_log,
|
||||
snatch::SnatchGuard,
|
||||
track::RenderBundleScope,
|
||||
@ -578,7 +581,7 @@ impl RenderBundleEncoder {
|
||||
|
||||
fn set_bind_group(
|
||||
state: &mut State,
|
||||
bind_group_guard: &crate::lock::RwLockReadGuard<crate::storage::Storage<Arc<BindGroup>>>,
|
||||
bind_group_guard: &crate::storage::Storage<Arc<BindGroup>>,
|
||||
dynamic_offsets: &[u32],
|
||||
index: u32,
|
||||
num_dynamic_offsets: usize,
|
||||
@ -630,7 +633,7 @@ fn set_bind_group(
|
||||
|
||||
fn set_pipeline(
|
||||
state: &mut State,
|
||||
pipeline_guard: &crate::lock::RwLockReadGuard<crate::storage::Storage<Arc<RenderPipeline>>>,
|
||||
pipeline_guard: &crate::storage::Storage<Arc<RenderPipeline>>,
|
||||
context: &RenderPassContext,
|
||||
is_depth_read_only: bool,
|
||||
is_stencil_read_only: bool,
|
||||
@ -673,15 +676,13 @@ fn set_pipeline(
|
||||
|
||||
fn set_index_buffer(
|
||||
state: &mut State,
|
||||
buffer_guard: &crate::lock::RwLockReadGuard<crate::storage::Storage<Arc<Buffer>>>,
|
||||
buffer_guard: &crate::storage::Storage<Fallible<Buffer>>,
|
||||
buffer_id: id::Id<id::markers::Buffer>,
|
||||
index_format: wgt::IndexFormat,
|
||||
offset: u64,
|
||||
size: Option<std::num::NonZeroU64>,
|
||||
) -> Result<(), RenderBundleErrorInner> {
|
||||
let buffer = buffer_guard
|
||||
.get_owned(buffer_id)
|
||||
.map_err(|_| RenderCommandError::InvalidBufferId(buffer_id))?;
|
||||
let buffer = buffer_guard.strict_get(buffer_id).get()?;
|
||||
|
||||
state
|
||||
.trackers
|
||||
@ -708,7 +709,7 @@ fn set_index_buffer(
|
||||
|
||||
fn set_vertex_buffer(
|
||||
state: &mut State,
|
||||
buffer_guard: &crate::lock::RwLockReadGuard<crate::storage::Storage<Arc<Buffer>>>,
|
||||
buffer_guard: &crate::storage::Storage<Fallible<Buffer>>,
|
||||
slot: u32,
|
||||
buffer_id: id::Id<id::markers::Buffer>,
|
||||
offset: u64,
|
||||
@ -723,9 +724,7 @@ fn set_vertex_buffer(
|
||||
.into());
|
||||
}
|
||||
|
||||
let buffer = buffer_guard
|
||||
.get_owned(buffer_id)
|
||||
.map_err(|_| RenderCommandError::InvalidBufferId(buffer_id))?;
|
||||
let buffer = buffer_guard.strict_get(buffer_id).get()?;
|
||||
|
||||
state
|
||||
.trackers
|
||||
@ -852,7 +851,7 @@ fn draw_indexed(
|
||||
fn multi_draw_indirect(
|
||||
state: &mut State,
|
||||
dynamic_offsets: &[u32],
|
||||
buffer_guard: &crate::lock::RwLockReadGuard<crate::storage::Storage<Arc<Buffer>>>,
|
||||
buffer_guard: &crate::storage::Storage<Fallible<Buffer>>,
|
||||
buffer_id: id::Id<id::markers::Buffer>,
|
||||
offset: u64,
|
||||
indexed: bool,
|
||||
@ -864,9 +863,7 @@ fn multi_draw_indirect(
|
||||
let pipeline = state.pipeline()?;
|
||||
let used_bind_groups = pipeline.used_bind_groups;
|
||||
|
||||
let buffer = buffer_guard
|
||||
.get_owned(buffer_id)
|
||||
.map_err(|_| RenderCommandError::InvalidBufferId(buffer_id))?;
|
||||
let buffer = buffer_guard.strict_get(buffer_id).get()?;
|
||||
|
||||
state
|
||||
.trackers
|
||||
@ -1538,6 +1535,8 @@ pub(super) enum RenderBundleErrorInner {
|
||||
MissingDownlevelFlags(#[from] MissingDownlevelFlags),
|
||||
#[error(transparent)]
|
||||
Bind(#[from] BindError),
|
||||
#[error(transparent)]
|
||||
InvalidResource(#[from] InvalidResourceError),
|
||||
}
|
||||
|
||||
impl<T> From<T> for RenderBundleErrorInner
|
||||
|
@ -11,8 +11,8 @@ use crate::{
|
||||
id::{BufferId, CommandEncoderId, TextureId},
|
||||
init_tracker::{MemoryInitKind, TextureInitRange},
|
||||
resource::{
|
||||
DestroyedResourceError, Labeled, MissingBufferUsageError, ParentDevice, ResourceErrorIdent,
|
||||
Texture, TextureClearMode,
|
||||
DestroyedResourceError, InvalidResourceError, Labeled, MissingBufferUsageError,
|
||||
ParentDevice, ResourceErrorIdent, Texture, TextureClearMode,
|
||||
},
|
||||
snatch::SnatchGuard,
|
||||
track::{TextureSelector, TextureTrackerSetSingle},
|
||||
@ -27,8 +27,6 @@ use wgt::{math::align_to, BufferAddress, BufferUsages, ImageSubresourceRange, Te
|
||||
pub enum ClearError {
|
||||
#[error("To use clear_texture the CLEAR_TEXTURE feature needs to be enabled")]
|
||||
MissingClearTextureFeature,
|
||||
#[error("BufferId {0:?} is invalid")]
|
||||
InvalidBufferId(BufferId),
|
||||
#[error("TextureId {0:?} is invalid")]
|
||||
InvalidTextureId(TextureId),
|
||||
#[error(transparent)]
|
||||
@ -75,6 +73,8 @@ whereas subesource range specified start {subresource_base_array_layer} and coun
|
||||
Device(#[from] DeviceError),
|
||||
#[error(transparent)]
|
||||
CommandEncoderError(#[from] CommandEncoderError),
|
||||
#[error(transparent)]
|
||||
InvalidResource(#[from] InvalidResourceError),
|
||||
}
|
||||
|
||||
impl Global {
|
||||
@ -107,10 +107,7 @@ impl Global {
|
||||
list.push(TraceCommand::ClearBuffer { dst, offset, size });
|
||||
}
|
||||
|
||||
let dst_buffer = hub
|
||||
.buffers
|
||||
.get(dst)
|
||||
.map_err(|_| ClearError::InvalidBufferId(dst))?;
|
||||
let dst_buffer = hub.buffers.strict_get(dst).get()?;
|
||||
|
||||
dst_buffer.same_device_as(cmd_buf.as_ref())?;
|
||||
|
||||
|
@ -17,8 +17,8 @@ use crate::{
|
||||
init_tracker::{BufferInitTrackerAction, MemoryInitKind},
|
||||
pipeline::ComputePipeline,
|
||||
resource::{
|
||||
self, Buffer, DestroyedResourceError, Labeled, MissingBufferUsageError, ParentDevice,
|
||||
Trackable,
|
||||
self, Buffer, DestroyedResourceError, InvalidResourceError, Labeled,
|
||||
MissingBufferUsageError, ParentDevice, Trackable,
|
||||
},
|
||||
snatch::SnatchGuard,
|
||||
track::{ResourceUsageCompatibilityError, Tracker, TrackerIndex, UsageScope},
|
||||
@ -148,8 +148,6 @@ pub enum ComputePassErrorInner {
|
||||
end_offset: u64,
|
||||
buffer_size: u64,
|
||||
},
|
||||
#[error("BufferId {0:?} is invalid")]
|
||||
InvalidBufferId(id::BufferId),
|
||||
#[error(transparent)]
|
||||
ResourceUsageCompatibility(#[from] ResourceUsageCompatibilityError),
|
||||
#[error(transparent)]
|
||||
@ -176,6 +174,8 @@ pub enum ComputePassErrorInner {
|
||||
MissingDownlevelFlags(#[from] MissingDownlevelFlags),
|
||||
#[error("The compute pass has already been ended and no further commands can be recorded")]
|
||||
PassEnded,
|
||||
#[error(transparent)]
|
||||
InvalidResource(#[from] InvalidResourceError),
|
||||
}
|
||||
|
||||
/// Error encountered when performing a compute pass.
|
||||
@ -1096,8 +1096,8 @@ impl Global {
|
||||
|
||||
let buffer = hub
|
||||
.buffers
|
||||
.get(buffer_id)
|
||||
.map_err(|_| ComputePassErrorInner::InvalidBufferId(buffer_id))
|
||||
.strict_get(buffer_id)
|
||||
.get()
|
||||
.map_pass_err(scope)?;
|
||||
|
||||
base.commands
|
||||
|
@ -136,10 +136,10 @@ impl ComputeCommand {
|
||||
|
||||
ComputeCommand::DispatchIndirect { buffer_id, offset } => {
|
||||
ArcComputeCommand::DispatchIndirect {
|
||||
buffer: buffers_guard.get_owned(buffer_id).map_err(|_| {
|
||||
buffer: buffers_guard.strict_get(buffer_id).get().map_err(|e| {
|
||||
ComputePassError {
|
||||
scope: PassErrorScope::Dispatch { indirect: true },
|
||||
inner: ComputePassErrorInner::InvalidBufferId(buffer_id),
|
||||
inner: e.into(),
|
||||
}
|
||||
})?,
|
||||
offset,
|
||||
|
@ -68,8 +68,6 @@ pub enum DrawError {
|
||||
#[derive(Clone, Debug, Error)]
|
||||
#[non_exhaustive]
|
||||
pub enum RenderCommandError {
|
||||
#[error("BufferId {0:?} is invalid")]
|
||||
InvalidBufferId(id::BufferId),
|
||||
#[error("BindGroupId {0:?} is invalid")]
|
||||
InvalidBindGroupId(id::BindGroupId),
|
||||
#[error("Render bundle {0:?} is invalid")]
|
||||
|
@ -7,7 +7,8 @@ use crate::{
|
||||
id,
|
||||
init_tracker::MemoryInitKind,
|
||||
resource::{
|
||||
DestroyedResourceError, MissingBufferUsageError, ParentDevice, QuerySet, Trackable,
|
||||
DestroyedResourceError, InvalidResourceError, MissingBufferUsageError, ParentDevice,
|
||||
QuerySet, Trackable,
|
||||
},
|
||||
track::{StatelessTracker, TrackerIndex},
|
||||
FastHashMap,
|
||||
@ -100,12 +101,12 @@ pub enum QueryError {
|
||||
Use(#[from] QueryUseError),
|
||||
#[error("Error encountered while trying to resolve a query")]
|
||||
Resolve(#[from] ResolveError),
|
||||
#[error("BufferId {0:?} is invalid")]
|
||||
InvalidBufferId(id::BufferId),
|
||||
#[error(transparent)]
|
||||
DestroyedResource(#[from] DestroyedResourceError),
|
||||
#[error("QuerySetId {0:?} is invalid or destroyed")]
|
||||
InvalidQuerySetId(id::QuerySetId),
|
||||
#[error(transparent)]
|
||||
InvalidResource(#[from] InvalidResourceError),
|
||||
}
|
||||
|
||||
/// Error encountered while trying to use queries
|
||||
@ -412,10 +413,7 @@ impl Global {
|
||||
|
||||
query_set.same_device_as(cmd_buf.as_ref())?;
|
||||
|
||||
let dst_buffer = hub
|
||||
.buffers
|
||||
.get(destination)
|
||||
.map_err(|_| QueryError::InvalidBufferId(destination))?;
|
||||
let dst_buffer = hub.buffers.strict_get(destination).get()?;
|
||||
|
||||
dst_buffer.same_device_as(cmd_buf.as_ref())?;
|
||||
|
||||
|
@ -4,6 +4,7 @@ use crate::command::{
|
||||
};
|
||||
use crate::init_tracker::BufferInitTrackerAction;
|
||||
use crate::pipeline::RenderPipeline;
|
||||
use crate::resource::InvalidResourceError;
|
||||
use crate::snatch::SnatchGuard;
|
||||
use crate::{
|
||||
api_log,
|
||||
@ -582,8 +583,6 @@ pub enum RenderPassErrorInner {
|
||||
InvalidParentEncoder,
|
||||
#[error("The format of the depth-stencil attachment ({0:?}) is not a depth-stencil format")]
|
||||
InvalidDepthStencilAttachmentFormat(wgt::TextureFormat),
|
||||
#[error("Buffer {0:?} is invalid or destroyed")]
|
||||
InvalidBuffer(id::BufferId),
|
||||
#[error("Render pipeline {0:?} is invalid")]
|
||||
InvalidPipeline(id::RenderPipelineId),
|
||||
#[error("QuerySet {0:?} is invalid")]
|
||||
@ -705,6 +704,8 @@ pub enum RenderPassErrorInner {
|
||||
DestroyedResource(#[from] DestroyedResourceError),
|
||||
#[error("The compute pass has already been ended and no further commands can be recorded")]
|
||||
PassEnded,
|
||||
#[error(transparent)]
|
||||
InvalidResource(#[from] InvalidResourceError),
|
||||
}
|
||||
|
||||
impl From<MissingBufferUsageError> for RenderPassErrorInner {
|
||||
@ -2776,8 +2777,8 @@ impl Global {
|
||||
let hub = &self.hub;
|
||||
let buffer = hub
|
||||
.buffers
|
||||
.get(buffer_id)
|
||||
.map_err(|_| RenderPassErrorInner::InvalidBuffer(buffer_id))
|
||||
.strict_get(buffer_id)
|
||||
.get()
|
||||
.map_pass_err(scope)?;
|
||||
|
||||
Ok(buffer)
|
||||
@ -3174,23 +3175,11 @@ impl Global {
|
||||
};
|
||||
let base = pass.base_mut(scope)?;
|
||||
|
||||
// Don't use resolve_render_pass_buffer_id here, because we don't want to take the read-lock twice.
|
||||
let hub = &self.hub;
|
||||
let buffers = hub.buffers.read();
|
||||
let buffer = buffers
|
||||
.get_owned(buffer_id)
|
||||
.map_err(|_| RenderPassErrorInner::InvalidBuffer(buffer_id))
|
||||
.map_pass_err(scope)?;
|
||||
let count_buffer = buffers
|
||||
.get_owned(count_buffer_id)
|
||||
.map_err(|_| RenderPassErrorInner::InvalidBuffer(count_buffer_id))
|
||||
.map_pass_err(scope)?;
|
||||
|
||||
base.commands
|
||||
.push(ArcRenderCommand::MultiDrawIndirectCount {
|
||||
buffer,
|
||||
buffer: self.resolve_render_pass_buffer_id(scope, buffer_id)?,
|
||||
offset,
|
||||
count_buffer,
|
||||
count_buffer: self.resolve_render_pass_buffer_id(scope, count_buffer_id)?,
|
||||
count_buffer_offset,
|
||||
max_count,
|
||||
indexed: false,
|
||||
@ -3214,24 +3203,11 @@ impl Global {
|
||||
};
|
||||
let base = pass.base_mut(scope)?;
|
||||
|
||||
// Don't use resolve_render_pass_buffer_id here, because we don't want to take the read-lock twice.
|
||||
let hub = &self.hub;
|
||||
let buffers = hub.buffers.read();
|
||||
let buffer = buffers
|
||||
.get_owned(buffer_id)
|
||||
.map_err(|_| RenderPassErrorInner::InvalidBuffer(buffer_id))
|
||||
.map_pass_err(scope)?;
|
||||
|
||||
let count_buffer = buffers
|
||||
.get_owned(count_buffer_id)
|
||||
.map_err(|_| RenderPassErrorInner::InvalidBuffer(count_buffer_id))
|
||||
.map_pass_err(scope)?;
|
||||
|
||||
base.commands
|
||||
.push(ArcRenderCommand::MultiDrawIndirectCount {
|
||||
buffer,
|
||||
buffer: self.resolve_render_pass_buffer_id(scope, buffer_id)?,
|
||||
offset,
|
||||
count_buffer,
|
||||
count_buffer: self.resolve_render_pass_buffer_id(scope, count_buffer_id)?,
|
||||
count_buffer_offset,
|
||||
max_count,
|
||||
indexed: true,
|
||||
|
@ -238,10 +238,10 @@ impl RenderCommand {
|
||||
offset,
|
||||
size,
|
||||
} => ArcRenderCommand::SetIndexBuffer {
|
||||
buffer: buffers_guard.get_owned(buffer_id).map_err(|_| {
|
||||
buffer: buffers_guard.strict_get(buffer_id).get().map_err(|e| {
|
||||
RenderPassError {
|
||||
scope: PassErrorScope::SetIndexBuffer,
|
||||
inner: RenderCommandError::InvalidBufferId(buffer_id).into(),
|
||||
inner: e.into(),
|
||||
}
|
||||
})?,
|
||||
index_format,
|
||||
@ -256,10 +256,10 @@ impl RenderCommand {
|
||||
size,
|
||||
} => ArcRenderCommand::SetVertexBuffer {
|
||||
slot,
|
||||
buffer: buffers_guard.get_owned(buffer_id).map_err(|_| {
|
||||
buffer: buffers_guard.strict_get(buffer_id).get().map_err(|e| {
|
||||
RenderPassError {
|
||||
scope: PassErrorScope::SetVertexBuffer,
|
||||
inner: RenderCommandError::InvalidBufferId(buffer_id).into(),
|
||||
inner: e.into(),
|
||||
}
|
||||
})?,
|
||||
offset,
|
||||
@ -318,7 +318,7 @@ impl RenderCommand {
|
||||
count,
|
||||
indexed,
|
||||
} => ArcRenderCommand::MultiDrawIndirect {
|
||||
buffer: buffers_guard.get_owned(buffer_id).map_err(|_| {
|
||||
buffer: buffers_guard.strict_get(buffer_id).get().map_err(|e| {
|
||||
RenderPassError {
|
||||
scope: PassErrorScope::Draw {
|
||||
kind: if count.is_some() {
|
||||
@ -328,7 +328,7 @@ impl RenderCommand {
|
||||
},
|
||||
indexed,
|
||||
},
|
||||
inner: RenderCommandError::InvalidBufferId(buffer_id).into(),
|
||||
inner: e.into(),
|
||||
}
|
||||
})?,
|
||||
offset,
|
||||
@ -349,18 +349,17 @@ impl RenderCommand {
|
||||
indexed,
|
||||
};
|
||||
ArcRenderCommand::MultiDrawIndirectCount {
|
||||
buffer: buffers_guard.get_owned(buffer_id).map_err(|_| {
|
||||
buffer: buffers_guard.strict_get(buffer_id).get().map_err(|e| {
|
||||
RenderPassError {
|
||||
scope,
|
||||
inner: RenderCommandError::InvalidBufferId(buffer_id).into(),
|
||||
inner: e.into(),
|
||||
}
|
||||
})?,
|
||||
offset,
|
||||
count_buffer: buffers_guard.get_owned(count_buffer_id).map_err(
|
||||
|_| RenderPassError {
|
||||
count_buffer: buffers_guard.strict_get(count_buffer_id).get().map_err(
|
||||
|e| RenderPassError {
|
||||
scope,
|
||||
inner: RenderCommandError::InvalidBufferId(count_buffer_id)
|
||||
.into(),
|
||||
inner: e.into(),
|
||||
},
|
||||
)?,
|
||||
count_buffer_offset,
|
||||
|
@ -12,8 +12,8 @@ use crate::{
|
||||
TextureInitTrackerAction,
|
||||
},
|
||||
resource::{
|
||||
DestroyedResourceError, MissingBufferUsageError, MissingTextureUsageError, ParentDevice,
|
||||
Texture, TextureErrorDimension,
|
||||
DestroyedResourceError, InvalidResourceError, MissingBufferUsageError,
|
||||
MissingTextureUsageError, ParentDevice, Texture, TextureErrorDimension,
|
||||
},
|
||||
snatch::SnatchGuard,
|
||||
track::{TextureSelector, Tracker},
|
||||
@ -41,8 +41,6 @@ pub enum CopySide {
|
||||
#[derive(Clone, Debug, Error)]
|
||||
#[non_exhaustive]
|
||||
pub enum TransferError {
|
||||
#[error("BufferId {0:?} is invalid")]
|
||||
InvalidBufferId(BufferId),
|
||||
#[error("TextureId {0:?} is invalid")]
|
||||
InvalidTextureId(TextureId),
|
||||
#[error("Source and destination cannot be the same buffer")]
|
||||
@ -150,6 +148,8 @@ pub enum CopyError {
|
||||
Transfer(#[from] TransferError),
|
||||
#[error(transparent)]
|
||||
DestroyedResource(#[from] DestroyedResourceError),
|
||||
#[error(transparent)]
|
||||
InvalidResource(#[from] InvalidResourceError),
|
||||
}
|
||||
|
||||
impl From<DeviceError> for CopyError {
|
||||
@ -570,10 +570,7 @@ impl Global {
|
||||
|
||||
let snatch_guard = device.snatchable_lock.read();
|
||||
|
||||
let src_buffer = hub
|
||||
.buffers
|
||||
.get(source)
|
||||
.map_err(|_| TransferError::InvalidBufferId(source))?;
|
||||
let src_buffer = hub.buffers.strict_get(source).get()?;
|
||||
|
||||
src_buffer.same_device_as(cmd_buf.as_ref())?;
|
||||
|
||||
@ -589,10 +586,7 @@ impl Global {
|
||||
// expecting only a single barrier
|
||||
let src_barrier = src_pending.map(|pending| pending.into_hal(&src_buffer, &snatch_guard));
|
||||
|
||||
let dst_buffer = hub
|
||||
.buffers
|
||||
.get(destination)
|
||||
.map_err(|_| TransferError::InvalidBufferId(destination))?;
|
||||
let dst_buffer = hub.buffers.strict_get(destination).get()?;
|
||||
|
||||
dst_buffer.same_device_as(cmd_buf.as_ref())?;
|
||||
|
||||
@ -778,10 +772,7 @@ impl Global {
|
||||
&snatch_guard,
|
||||
)?;
|
||||
|
||||
let src_buffer = hub
|
||||
.buffers
|
||||
.get(source.buffer)
|
||||
.map_err(|_| TransferError::InvalidBufferId(source.buffer))?;
|
||||
let src_buffer = hub.buffers.strict_get(source.buffer).get()?;
|
||||
|
||||
src_buffer.same_device_as(cmd_buf.as_ref())?;
|
||||
|
||||
@ -966,10 +957,7 @@ impl Global {
|
||||
.map(|pending| pending.into_hal(src_raw))
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
let dst_buffer = hub
|
||||
.buffers
|
||||
.get(destination.buffer)
|
||||
.map_err(|_| TransferError::InvalidBufferId(destination.buffer))?;
|
||||
let dst_buffer = hub.buffers.strict_get(destination.buffer).get()?;
|
||||
|
||||
dst_buffer.same_device_as(cmd_buf.as_ref())?;
|
||||
|
||||
|
@ -19,9 +19,10 @@ use crate::{
|
||||
present,
|
||||
resource::{
|
||||
self, BufferAccessError, BufferAccessResult, BufferMapOperation, CreateBufferError,
|
||||
Fallible,
|
||||
},
|
||||
storage::Storage,
|
||||
Label,
|
||||
Label, LabelHelpers,
|
||||
};
|
||||
|
||||
use wgt::{BufferAddress, TextureFormat};
|
||||
@ -124,7 +125,7 @@ impl Global {
|
||||
}
|
||||
};
|
||||
|
||||
let id = fid.assign(buffer);
|
||||
let id = fid.assign(Fallible::Valid(buffer));
|
||||
|
||||
api_log!(
|
||||
"Device::create_buffer({:?}{}) -> {id:?}",
|
||||
@ -139,7 +140,7 @@ impl Global {
|
||||
return (id, None);
|
||||
};
|
||||
|
||||
let id = fid.assign_error();
|
||||
let id = fid.assign(Fallible::Invalid(Arc::new(desc.label.to_string())));
|
||||
(id, Some(error))
|
||||
}
|
||||
|
||||
@ -171,11 +172,14 @@ impl Global {
|
||||
/// [`device_create_buffer`]: Global::device_create_buffer
|
||||
/// [`usage`]: https://www.w3.org/TR/webgpu/#dom-gputexturedescriptor-usage
|
||||
/// [`wgpu_types::BufferUsages`]: wgt::BufferUsages
|
||||
pub fn create_buffer_error(&self, backend: wgt::Backend, id_in: Option<id::BufferId>) {
|
||||
let hub = &self.hub;
|
||||
let fid = hub.buffers.prepare(backend, id_in);
|
||||
|
||||
fid.assign_error();
|
||||
pub fn create_buffer_error(
|
||||
&self,
|
||||
backend: wgt::Backend,
|
||||
id_in: Option<id::BufferId>,
|
||||
desc: &resource::BufferDescriptor,
|
||||
) {
|
||||
let fid = self.hub.buffers.prepare(backend, id_in);
|
||||
fid.assign(Fallible::Invalid(Arc::new(desc.label.to_string())));
|
||||
}
|
||||
|
||||
pub fn create_render_bundle_error(
|
||||
@ -208,10 +212,7 @@ impl Global {
|
||||
) -> BufferAccessResult {
|
||||
let hub = &self.hub;
|
||||
|
||||
let buffer = hub
|
||||
.buffers
|
||||
.get(buffer_id)
|
||||
.map_err(|_| BufferAccessError::InvalidBufferId(buffer_id))?;
|
||||
let buffer = hub.buffers.strict_get(buffer_id).get()?;
|
||||
|
||||
let device = &buffer.device;
|
||||
|
||||
@ -258,10 +259,7 @@ impl Global {
|
||||
|
||||
let hub = &self.hub;
|
||||
|
||||
let buffer = hub
|
||||
.buffers
|
||||
.get(buffer_id)
|
||||
.map_err(|_| resource::DestroyError::Invalid)?;
|
||||
let buffer = hub.buffers.strict_get(buffer_id).get()?;
|
||||
|
||||
#[cfg(feature = "trace")]
|
||||
if let Some(trace) = buffer.device.trace.lock().as_mut() {
|
||||
@ -282,9 +280,9 @@ impl Global {
|
||||
|
||||
let hub = &self.hub;
|
||||
|
||||
let buffer = match hub.buffers.unregister(buffer_id) {
|
||||
Some(buffer) => buffer,
|
||||
None => {
|
||||
let buffer = match hub.buffers.strict_unregister(buffer_id).get() {
|
||||
Ok(buffer) => buffer,
|
||||
Err(_) => {
|
||||
return;
|
||||
}
|
||||
};
|
||||
@ -425,7 +423,7 @@ impl Global {
|
||||
let texture = hub
|
||||
.textures
|
||||
.get(texture_id)
|
||||
.map_err(|_| resource::DestroyError::Invalid)?;
|
||||
.map_err(|_| resource::DestroyError::InvalidTextureId(texture_id))?;
|
||||
|
||||
#[cfg(feature = "trace")]
|
||||
if let Some(trace) = texture.device.trace.lock().as_mut() {
|
||||
@ -733,22 +731,21 @@ impl Global {
|
||||
|
||||
fn resolve_entry<'a>(
|
||||
e: &BindGroupEntry<'a>,
|
||||
buffer_storage: &Storage<Arc<resource::Buffer>>,
|
||||
buffer_storage: &Storage<Fallible<resource::Buffer>>,
|
||||
sampler_storage: &Storage<Arc<resource::Sampler>>,
|
||||
texture_view_storage: &Storage<Arc<resource::TextureView>>,
|
||||
) -> Result<ResolvedBindGroupEntry<'a>, binding_model::CreateBindGroupError>
|
||||
{
|
||||
let resolve_buffer = |bb: &BufferBinding| {
|
||||
buffer_storage
|
||||
.get_owned(bb.buffer_id)
|
||||
.strict_get(bb.buffer_id)
|
||||
.get()
|
||||
.map(|buffer| ResolvedBufferBinding {
|
||||
buffer,
|
||||
offset: bb.offset,
|
||||
size: bb.size,
|
||||
})
|
||||
.map_err(|_| {
|
||||
binding_model::CreateBindGroupError::InvalidBufferId(bb.buffer_id)
|
||||
})
|
||||
.map_err(binding_model::CreateBindGroupError::from)
|
||||
};
|
||||
let resolve_sampler = |id: &id::SamplerId| {
|
||||
sampler_storage
|
||||
@ -2197,9 +2194,9 @@ impl Global {
|
||||
let hub = &self.hub;
|
||||
|
||||
let op_and_err = 'error: {
|
||||
let buffer = match hub.buffers.get(buffer_id) {
|
||||
let buffer = match hub.buffers.strict_get(buffer_id).get() {
|
||||
Ok(buffer) => buffer,
|
||||
Err(_) => break 'error Some((op, BufferAccessError::InvalidBufferId(buffer_id))),
|
||||
Err(e) => break 'error Some((op, e.into())),
|
||||
};
|
||||
|
||||
buffer.map_async(offset, size, op).err()
|
||||
@ -2230,10 +2227,7 @@ impl Global {
|
||||
|
||||
let hub = &self.hub;
|
||||
|
||||
let buffer = hub
|
||||
.buffers
|
||||
.get(buffer_id)
|
||||
.map_err(|_| BufferAccessError::InvalidBufferId(buffer_id))?;
|
||||
let buffer = hub.buffers.strict_get(buffer_id).get()?;
|
||||
|
||||
{
|
||||
let snatch_guard = buffer.device.snatchable_lock.read();
|
||||
@ -2306,10 +2300,7 @@ impl Global {
|
||||
|
||||
let hub = &self.hub;
|
||||
|
||||
let buffer = hub
|
||||
.buffers
|
||||
.get(buffer_id)
|
||||
.map_err(|_| BufferAccessError::InvalidBufferId(buffer_id))?;
|
||||
let buffer = hub.buffers.strict_get(buffer_id).get()?;
|
||||
|
||||
let snatch_guard = buffer.device.snatchable_lock.read();
|
||||
buffer.check_destroyed(&snatch_guard)?;
|
||||
|
@ -16,8 +16,8 @@ use crate::{
|
||||
lock::RwLockWriteGuard,
|
||||
resource::{
|
||||
Buffer, BufferAccessError, BufferMapState, DestroyedBuffer, DestroyedResourceError,
|
||||
DestroyedTexture, FlushedStagingBuffer, Labeled, ParentDevice, ResourceErrorIdent,
|
||||
StagingBuffer, Texture, TextureInner, Trackable,
|
||||
DestroyedTexture, FlushedStagingBuffer, InvalidResourceError, Labeled, ParentDevice,
|
||||
ResourceErrorIdent, StagingBuffer, Texture, TextureInner, Trackable,
|
||||
},
|
||||
resource_log,
|
||||
track::{self, Tracker, TrackerIndex},
|
||||
@ -332,6 +332,10 @@ pub enum QueueWriteError {
|
||||
MemoryInitFailure(#[from] ClearError),
|
||||
#[error(transparent)]
|
||||
DestroyedResource(#[from] DestroyedResourceError),
|
||||
#[error(transparent)]
|
||||
InvalidResource(#[from] InvalidResourceError),
|
||||
#[error("StagingBufferId {0:?} is invalid")]
|
||||
InvalidStagingBufferId(id::StagingBufferId),
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Error)]
|
||||
@ -368,10 +372,7 @@ impl Global {
|
||||
|
||||
let hub = &self.hub;
|
||||
|
||||
let buffer = hub
|
||||
.buffers
|
||||
.get(buffer_id)
|
||||
.map_err(|_| TransferError::InvalidBufferId(buffer_id))?;
|
||||
let buffer = hub.buffers.strict_get(buffer_id).get()?;
|
||||
|
||||
let queue = hub.queues.strict_get(queue_id);
|
||||
|
||||
@ -465,7 +466,7 @@ impl Global {
|
||||
.staging_buffers
|
||||
.unregister(staging_buffer_id)
|
||||
.and_then(Arc::into_inner)
|
||||
.ok_or_else(|| QueueWriteError::Transfer(TransferError::InvalidBufferId(buffer_id)))?;
|
||||
.ok_or_else(|| QueueWriteError::InvalidStagingBufferId(staging_buffer_id))?;
|
||||
|
||||
let mut pending_writes = device.pending_writes.lock();
|
||||
|
||||
@ -498,10 +499,7 @@ impl Global {
|
||||
profiling::scope!("Queue::validate_write_buffer");
|
||||
let hub = &self.hub;
|
||||
|
||||
let buffer = hub
|
||||
.buffers
|
||||
.get(buffer_id)
|
||||
.map_err(|_| TransferError::InvalidBufferId(buffer_id))?;
|
||||
let buffer = hub.buffers.strict_get(buffer_id).get()?;
|
||||
|
||||
self.queue_validate_write_buffer_impl(&buffer, buffer_offset, buffer_size)?;
|
||||
|
||||
@ -544,10 +542,7 @@ impl Global {
|
||||
) -> Result<(), QueueWriteError> {
|
||||
let hub = &self.hub;
|
||||
|
||||
let dst = hub
|
||||
.buffers
|
||||
.get(buffer_id)
|
||||
.map_err(|_| TransferError::InvalidBufferId(buffer_id))?;
|
||||
let dst = hub.buffers.strict_get(buffer_id).get()?;
|
||||
|
||||
let transition = {
|
||||
let mut trackers = device.trackers.lock();
|
||||
|
@ -21,7 +21,7 @@ use crate::{
|
||||
pipeline,
|
||||
pool::ResourcePool,
|
||||
resource::{
|
||||
self, Buffer, Labeled, ParentDevice, QuerySet, Sampler, StagingBuffer, Texture,
|
||||
self, Buffer, Fallible, Labeled, ParentDevice, QuerySet, Sampler, StagingBuffer, Texture,
|
||||
TextureView, TextureViewNotRenderableReason, TrackingData,
|
||||
},
|
||||
resource_log,
|
||||
@ -694,11 +694,11 @@ impl Device {
|
||||
Ok(texture)
|
||||
}
|
||||
|
||||
pub fn create_buffer_from_hal(
|
||||
pub(crate) fn create_buffer_from_hal(
|
||||
self: &Arc<Self>,
|
||||
hal_buffer: Box<dyn hal::DynBuffer>,
|
||||
desc: &resource::BufferDescriptor,
|
||||
) -> Arc<Buffer> {
|
||||
) -> Fallible<Buffer> {
|
||||
unsafe { self.raw().add_raw_buffer(&*hal_buffer) };
|
||||
|
||||
let buffer = Buffer {
|
||||
@ -723,7 +723,7 @@ impl Device {
|
||||
.buffers
|
||||
.insert_single(&buffer, hal::BufferUses::empty());
|
||||
|
||||
buffer
|
||||
Fallible::Valid(buffer)
|
||||
}
|
||||
|
||||
pub(crate) fn create_texture(
|
||||
|
@ -107,7 +107,7 @@ use crate::{
|
||||
instance::{Adapter, Surface},
|
||||
pipeline::{ComputePipeline, PipelineCache, RenderPipeline, ShaderModule},
|
||||
registry::{Registry, RegistryReport},
|
||||
resource::{Buffer, QuerySet, Sampler, StagingBuffer, Texture, TextureView},
|
||||
resource::{Buffer, Fallible, QuerySet, Sampler, StagingBuffer, Texture, TextureView},
|
||||
storage::{Element, Storage},
|
||||
};
|
||||
use std::{fmt::Debug, sync::Arc};
|
||||
@ -175,7 +175,7 @@ pub struct Hub {
|
||||
pub(crate) compute_pipelines: Registry<Arc<ComputePipeline>>,
|
||||
pub(crate) pipeline_caches: Registry<Arc<PipelineCache>>,
|
||||
pub(crate) query_sets: Registry<Arc<QuerySet>>,
|
||||
pub(crate) buffers: Registry<Arc<Buffer>>,
|
||||
pub(crate) buffers: Registry<Fallible<Buffer>>,
|
||||
pub(crate) staging_buffers: Registry<Arc<StagingBuffer>>,
|
||||
pub(crate) textures: Registry<Arc<Texture>>,
|
||||
pub(crate) texture_views: Registry<Arc<TextureView>>,
|
||||
|
@ -305,7 +305,7 @@ impl BufferMapCallback {
|
||||
let status = match result {
|
||||
Ok(()) => BufferMapAsyncStatus::Success,
|
||||
Err(BufferAccessError::Device(_)) => BufferMapAsyncStatus::ContextLost,
|
||||
Err(BufferAccessError::InvalidBufferId(_))
|
||||
Err(BufferAccessError::InvalidResource(_))
|
||||
| Err(BufferAccessError::DestroyedResource(_)) => BufferMapAsyncStatus::Invalid,
|
||||
Err(BufferAccessError::AlreadyMapped) => BufferMapAsyncStatus::AlreadyMapped,
|
||||
Err(BufferAccessError::MapAlreadyPending) => {
|
||||
@ -324,7 +324,9 @@ impl BufferMapCallback {
|
||||
| Err(BufferAccessError::NegativeRange { .. }) => {
|
||||
BufferMapAsyncStatus::InvalidRange
|
||||
}
|
||||
Err(_) => BufferMapAsyncStatus::Error,
|
||||
Err(BufferAccessError::Failed)
|
||||
| Err(BufferAccessError::NotMapped)
|
||||
| Err(BufferAccessError::MapAborted) => BufferMapAsyncStatus::Error,
|
||||
};
|
||||
|
||||
(inner.callback)(status, inner.user_data);
|
||||
@ -347,8 +349,6 @@ pub enum BufferAccessError {
|
||||
Device(#[from] DeviceError),
|
||||
#[error("Buffer map failed")]
|
||||
Failed,
|
||||
#[error("BufferId {0:?} is invalid")]
|
||||
InvalidBufferId(BufferId),
|
||||
#[error(transparent)]
|
||||
DestroyedResource(#[from] DestroyedResourceError),
|
||||
#[error("Buffer is already mapped")]
|
||||
@ -386,6 +386,8 @@ pub enum BufferAccessError {
|
||||
},
|
||||
#[error("Buffer map aborted")]
|
||||
MapAborted,
|
||||
#[error(transparent)]
|
||||
InvalidResource(#[from] InvalidResourceError),
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Error)]
|
||||
@ -410,6 +412,45 @@ pub struct MissingTextureUsageError {
|
||||
#[error("{0} has been destroyed")]
|
||||
pub struct DestroyedResourceError(pub ResourceErrorIdent);
|
||||
|
||||
#[derive(Clone, Debug, Error)]
|
||||
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
|
||||
#[error("{0} is invalid")]
|
||||
pub struct InvalidResourceError(pub ResourceErrorIdent);
|
||||
|
||||
pub(crate) enum Fallible<T: ParentDevice> {
|
||||
Valid(Arc<T>),
|
||||
Invalid(Arc<String>),
|
||||
}
|
||||
|
||||
impl<T: ParentDevice> Fallible<T> {
|
||||
pub fn get(self) -> Result<Arc<T>, InvalidResourceError> {
|
||||
match self {
|
||||
Fallible::Valid(v) => Ok(v),
|
||||
Fallible::Invalid(label) => Err(InvalidResourceError(ResourceErrorIdent {
|
||||
r#type: Cow::Borrowed(T::TYPE),
|
||||
label: (*label).clone(),
|
||||
})),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: ParentDevice> Clone for Fallible<T> {
|
||||
fn clone(&self) -> Self {
|
||||
match self {
|
||||
Self::Valid(v) => Self::Valid(v.clone()),
|
||||
Self::Invalid(l) => Self::Invalid(l.clone()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: ParentDevice> ResourceType for Fallible<T> {
|
||||
const TYPE: &'static str = T::TYPE;
|
||||
}
|
||||
|
||||
impl<T: ParentDevice + crate::storage::StorageItem> crate::storage::StorageItem for Fallible<T> {
|
||||
type Marker = T::Marker;
|
||||
}
|
||||
|
||||
pub type BufferAccessResult = Result<(), BufferAccessError>;
|
||||
|
||||
#[derive(Debug)]
|
||||
@ -1202,7 +1243,7 @@ impl Global {
|
||||
|
||||
let hub = &self.hub;
|
||||
|
||||
if let Ok(buffer) = hub.buffers.get(id) {
|
||||
if let Ok(buffer) = hub.buffers.strict_get(id).get() {
|
||||
let snatch_guard = buffer.device.snatchable_lock.read();
|
||||
let hal_buffer = buffer
|
||||
.raw(&snatch_guard)
|
||||
@ -1821,8 +1862,10 @@ impl QuerySet {
|
||||
#[derive(Clone, Debug, Error)]
|
||||
#[non_exhaustive]
|
||||
pub enum DestroyError {
|
||||
#[error("Resource is invalid")]
|
||||
Invalid,
|
||||
#[error("TextureId {0:?} is invalid")]
|
||||
InvalidTextureId(TextureId),
|
||||
#[error("Resource is already destroyed")]
|
||||
AlreadyDestroyed,
|
||||
#[error(transparent)]
|
||||
InvalidResource(#[from] InvalidResourceError),
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user