mirror of
https://github.com/gfx-rs/wgpu.git
synced 2024-11-25 00:03:29 +00:00
consolidate destroyed texture/buffer errors and separate them from invalid ID errors
This commit is contained in:
parent
97a038a768
commit
a024afe182
@ -9,8 +9,8 @@ use crate::{
|
||||
id::{BindGroupLayoutId, BufferId, SamplerId, TextureViewId},
|
||||
init_tracker::{BufferInitTrackerAction, TextureInitTrackerAction},
|
||||
resource::{
|
||||
MissingBufferUsageError, MissingTextureUsageError, ParentDevice, Resource, ResourceInfo,
|
||||
ResourceType,
|
||||
DestroyedResourceError, MissingBufferUsageError, MissingTextureUsageError, ParentDevice,
|
||||
Resource, ResourceInfo, ResourceType,
|
||||
},
|
||||
resource_log,
|
||||
snatch::{SnatchGuard, Snatchable},
|
||||
@ -78,12 +78,14 @@ pub enum CreateBindGroupError {
|
||||
Device(#[from] DeviceError),
|
||||
#[error("Bind group layout is invalid")]
|
||||
InvalidLayout,
|
||||
#[error("Buffer {0:?} is invalid or destroyed")]
|
||||
InvalidBuffer(BufferId),
|
||||
#[error("BufferId {0:?} is invalid")]
|
||||
InvalidBufferId(BufferId),
|
||||
#[error("Texture view {0:?} is invalid")]
|
||||
InvalidTextureView(TextureViewId),
|
||||
#[error("Sampler {0:?} is invalid")]
|
||||
InvalidSampler(SamplerId),
|
||||
#[error(transparent)]
|
||||
DestroyedResource(#[from] DestroyedResourceError),
|
||||
#[error(
|
||||
"Binding count declared with at most {expected} items, but {actual} items were provided"
|
||||
)]
|
||||
@ -198,9 +200,6 @@ impl PrettyError for CreateBindGroupError {
|
||||
Self::BindingSizeTooSmall { buffer, .. } => {
|
||||
fmt.buffer_label(&buffer);
|
||||
}
|
||||
Self::InvalidBuffer(id) => {
|
||||
fmt.buffer_label(&id);
|
||||
}
|
||||
Self::InvalidTextureView(id) => {
|
||||
fmt.texture_view_label(&id);
|
||||
}
|
||||
|
@ -97,7 +97,9 @@ use crate::{
|
||||
id,
|
||||
init_tracker::{BufferInitTrackerAction, MemoryInitKind, TextureInitTrackerAction},
|
||||
pipeline::{PipelineFlags, RenderPipeline, VertexStep},
|
||||
resource::{Buffer, ParentDevice, Resource, ResourceInfo, ResourceType},
|
||||
resource::{
|
||||
Buffer, DestroyedResourceError, ParentDevice, Resource, ResourceInfo, ResourceType,
|
||||
},
|
||||
resource_log,
|
||||
snatch::SnatchGuard,
|
||||
track::RenderBundleScope,
|
||||
@ -825,8 +827,8 @@ pub enum CreateRenderBundleError {
|
||||
#[derive(Clone, Debug, Error)]
|
||||
#[non_exhaustive]
|
||||
pub enum ExecutionError {
|
||||
#[error("Buffer {0:?} is destroyed")]
|
||||
DestroyedBuffer(id::BufferId),
|
||||
#[error(transparent)]
|
||||
DestroyedResource(#[from] DestroyedResourceError),
|
||||
#[error("BindGroup {0:?} is invalid")]
|
||||
InvalidBindGroup(id::BindGroupId),
|
||||
#[error("Using {0} in a render bundle is not implemented")]
|
||||
@ -835,15 +837,9 @@ pub enum ExecutionError {
|
||||
impl PrettyError for ExecutionError {
|
||||
fn fmt_pretty(&self, fmt: &mut ErrorFormatter) {
|
||||
fmt.error(self);
|
||||
match *self {
|
||||
Self::DestroyedBuffer(id) => {
|
||||
fmt.buffer_label(&id);
|
||||
}
|
||||
Self::InvalidBindGroup(id) => {
|
||||
fmt.bind_group_label(&id);
|
||||
}
|
||||
Self::Unimplemented(_reason) => {}
|
||||
};
|
||||
if let Self::InvalidBindGroup(id) = *self {
|
||||
fmt.bind_group_label(&id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -939,9 +935,7 @@ impl<A: HalApi> RenderBundle<A> {
|
||||
offset,
|
||||
size,
|
||||
} => {
|
||||
let buffer: &A::Buffer = buffer
|
||||
.raw(snatch_guard)
|
||||
.ok_or(ExecutionError::DestroyedBuffer(buffer.info.id()))?;
|
||||
let buffer: &A::Buffer = buffer.try_raw(snatch_guard)?;
|
||||
let bb = hal::BufferBinding {
|
||||
buffer,
|
||||
offset: *offset,
|
||||
@ -955,9 +949,7 @@ impl<A: HalApi> RenderBundle<A> {
|
||||
offset,
|
||||
size,
|
||||
} => {
|
||||
let buffer = buffer
|
||||
.raw(snatch_guard)
|
||||
.ok_or(ExecutionError::DestroyedBuffer(buffer.info.id()))?;
|
||||
let buffer = buffer.try_raw(snatch_guard)?;
|
||||
let bb = hal::BufferBinding {
|
||||
buffer,
|
||||
offset: *offset,
|
||||
@ -1042,9 +1034,7 @@ impl<A: HalApi> RenderBundle<A> {
|
||||
count: None,
|
||||
indexed: false,
|
||||
} => {
|
||||
let buffer = buffer
|
||||
.raw(snatch_guard)
|
||||
.ok_or(ExecutionError::DestroyedBuffer(buffer.info.id()))?;
|
||||
let buffer = buffer.try_raw(snatch_guard)?;
|
||||
unsafe { raw.draw_indirect(buffer, *offset, 1) };
|
||||
}
|
||||
Cmd::MultiDrawIndirect {
|
||||
@ -1053,9 +1043,7 @@ impl<A: HalApi> RenderBundle<A> {
|
||||
count: None,
|
||||
indexed: true,
|
||||
} => {
|
||||
let buffer = buffer
|
||||
.raw(snatch_guard)
|
||||
.ok_or(ExecutionError::DestroyedBuffer(buffer.info.id()))?;
|
||||
let buffer = buffer.try_raw(snatch_guard)?;
|
||||
unsafe { raw.draw_indexed_indirect(buffer, *offset, 1) };
|
||||
}
|
||||
Cmd::MultiDrawIndirect { .. } | Cmd::MultiDrawIndirectCount { .. } => {
|
||||
|
@ -11,7 +11,10 @@ use crate::{
|
||||
hal_api::HalApi,
|
||||
id::{BufferId, CommandEncoderId, TextureId},
|
||||
init_tracker::{MemoryInitKind, TextureInitRange},
|
||||
resource::{ParentDevice, Resource, ResourceErrorIdent, Texture, TextureClearMode},
|
||||
resource::{
|
||||
DestroyedResourceError, ParentDevice, Resource, ResourceErrorIdent, Texture,
|
||||
TextureClearMode,
|
||||
},
|
||||
snatch::SnatchGuard,
|
||||
track::{TextureSelector, TextureTracker},
|
||||
};
|
||||
@ -26,12 +29,12 @@ 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("Buffer {0:?} is invalid or destroyed")]
|
||||
InvalidBuffer(BufferId),
|
||||
#[error("BufferId {0:?} is invalid")]
|
||||
InvalidBufferId(BufferId),
|
||||
#[error("TextureId {0:?} is invalid")]
|
||||
InvalidTextureId(TextureId),
|
||||
#[error("{0} has been destroyed")]
|
||||
Destroyed(ResourceErrorIdent),
|
||||
#[error(transparent)]
|
||||
DestroyedResource(#[from] DestroyedResourceError),
|
||||
#[error("{0} can not be cleared")]
|
||||
NoValidTextureClearMode(ResourceErrorIdent),
|
||||
#[error("Buffer clear size {0:?} is not a multiple of `COPY_BUFFER_ALIGNMENT`")]
|
||||
@ -101,7 +104,7 @@ impl Global {
|
||||
let dst_buffer = hub
|
||||
.buffers
|
||||
.get(dst)
|
||||
.map_err(|_| ClearError::InvalidBuffer(dst))?;
|
||||
.map_err(|_| ClearError::InvalidBufferId(dst))?;
|
||||
|
||||
dst_buffer.same_device_as(cmd_buf.as_ref())?;
|
||||
|
||||
@ -111,10 +114,7 @@ impl Global {
|
||||
.set_single(&dst_buffer, hal::BufferUses::COPY_DST);
|
||||
|
||||
let snatch_guard = dst_buffer.device.snatchable_lock.read();
|
||||
let dst_raw = dst_buffer
|
||||
.raw
|
||||
.get(&snatch_guard)
|
||||
.ok_or(ClearError::InvalidBuffer(dst))?;
|
||||
let dst_raw = dst_buffer.try_raw(&snatch_guard)?;
|
||||
if !dst_buffer.usage.contains(BufferUsages::COPY_DST) {
|
||||
return Err(ClearError::MissingCopyDstUsageFlag(Some(dst), None));
|
||||
}
|
||||
@ -264,9 +264,7 @@ pub(crate) fn clear_texture<A: HalApi>(
|
||||
zero_buffer: &A::Buffer,
|
||||
snatch_guard: &SnatchGuard<'_>,
|
||||
) -> Result<(), ClearError> {
|
||||
let dst_raw = dst_texture
|
||||
.raw(snatch_guard)
|
||||
.ok_or_else(|| ClearError::Destroyed(dst_texture.error_ident()))?;
|
||||
let dst_raw = dst_texture.try_raw(snatch_guard)?;
|
||||
|
||||
// Issue the right barrier.
|
||||
let clear_usage = match *dst_texture.clear_mode.read() {
|
||||
|
@ -15,7 +15,7 @@ use crate::{
|
||||
hal_api::HalApi,
|
||||
hal_label, id,
|
||||
init_tracker::MemoryInitKind,
|
||||
resource::{self, MissingBufferUsageError, ParentDevice, Resource},
|
||||
resource::{self, DestroyedResourceError, MissingBufferUsageError, ParentDevice, Resource},
|
||||
snatch::SnatchGuard,
|
||||
track::{Tracker, TrackerIndex, UsageConflict, UsageScope},
|
||||
Label,
|
||||
@ -166,16 +166,16 @@ pub enum ComputePassErrorInner {
|
||||
InvalidPipeline(id::ComputePipelineId),
|
||||
#[error("QuerySet {0:?} is invalid")]
|
||||
InvalidQuerySet(id::QuerySetId),
|
||||
#[error("Indirect buffer {0:?} is invalid or destroyed")]
|
||||
InvalidIndirectBuffer(id::BufferId),
|
||||
#[error(transparent)]
|
||||
DestroyedResource(#[from] DestroyedResourceError),
|
||||
#[error("Indirect buffer uses bytes {offset}..{end_offset} which overruns indirect buffer of size {buffer_size}")]
|
||||
IndirectBufferOverrun {
|
||||
offset: u64,
|
||||
end_offset: u64,
|
||||
buffer_size: u64,
|
||||
},
|
||||
#[error("Buffer {0:?} is invalid or destroyed")]
|
||||
InvalidBuffer(id::BufferId),
|
||||
#[error("BufferId {0:?} is invalid")]
|
||||
InvalidBufferId(id::BufferId),
|
||||
#[error(transparent)]
|
||||
ResourceUsageConflict(#[from] UsageConflict),
|
||||
#[error(transparent)]
|
||||
@ -211,9 +211,6 @@ impl PrettyError for ComputePassErrorInner {
|
||||
Self::InvalidPipeline(id) => {
|
||||
fmt.compute_pipeline_label(&id);
|
||||
}
|
||||
Self::InvalidIndirectBuffer(id) => {
|
||||
fmt.buffer_label(&id);
|
||||
}
|
||||
Self::Dispatch(DispatchError::IncompatibleBindGroup { ref diff, .. }) => {
|
||||
for d in diff {
|
||||
fmt.note(&d);
|
||||
@ -773,7 +770,6 @@ impl Global {
|
||||
}
|
||||
}
|
||||
ArcComputeCommand::DispatchIndirect { buffer, offset } => {
|
||||
let buffer_id = buffer.as_info().id();
|
||||
let scope = PassErrorScope::Dispatch {
|
||||
indirect: true,
|
||||
pipeline: state.pipeline,
|
||||
@ -806,11 +802,7 @@ impl Global {
|
||||
.map_pass_err(scope);
|
||||
}
|
||||
|
||||
let buf_raw = buffer
|
||||
.raw
|
||||
.get(&snatch_guard)
|
||||
.ok_or(ComputePassErrorInner::InvalidIndirectBuffer(buffer_id))
|
||||
.map_pass_err(scope)?;
|
||||
let buf_raw = buffer.try_raw(&snatch_guard).map_pass_err(scope)?;
|
||||
|
||||
let stride = 3 * 4; // 3 integers, x/y/z group size
|
||||
|
||||
@ -1092,9 +1084,8 @@ impl Global {
|
||||
|
||||
let buffer = hub
|
||||
.buffers
|
||||
.read()
|
||||
.get_owned(buffer_id)
|
||||
.map_err(|_| ComputePassErrorInner::InvalidBuffer(buffer_id))
|
||||
.get(buffer_id)
|
||||
.map_err(|_| ComputePassErrorInner::InvalidBufferId(buffer_id))
|
||||
.map_pass_err(scope)?;
|
||||
|
||||
base.commands
|
||||
|
@ -132,7 +132,7 @@ impl ComputeCommand {
|
||||
indirect: true,
|
||||
pipeline: None, // TODO: not used right now, but once we do the resolve during recording we can use this again.
|
||||
},
|
||||
inner: ComputePassErrorInner::InvalidBuffer(buffer_id),
|
||||
inner: ComputePassErrorInner::InvalidBufferId(buffer_id),
|
||||
}
|
||||
})?,
|
||||
offset,
|
||||
|
@ -7,7 +7,9 @@ use crate::{
|
||||
hal_api::HalApi,
|
||||
id,
|
||||
pipeline::RenderPipeline,
|
||||
resource::{Buffer, MissingBufferUsageError, MissingTextureUsageError, QuerySet},
|
||||
resource::{
|
||||
Buffer, DestroyedResourceError, MissingBufferUsageError, MissingTextureUsageError, QuerySet,
|
||||
},
|
||||
track::UsageConflict,
|
||||
};
|
||||
use wgt::{BufferAddress, BufferSize, Color, VertexStepMode};
|
||||
@ -90,8 +92,8 @@ pub enum RenderCommandError {
|
||||
IncompatiblePipelineRods,
|
||||
#[error(transparent)]
|
||||
UsageConflict(#[from] UsageConflict),
|
||||
#[error("Buffer {0:?} is destroyed")]
|
||||
DestroyedBuffer(id::BufferId),
|
||||
#[error(transparent)]
|
||||
DestroyedResource(#[from] DestroyedResourceError),
|
||||
#[error(transparent)]
|
||||
MissingBufferUsage(#[from] MissingBufferUsageError),
|
||||
#[error(transparent)]
|
||||
@ -120,8 +122,7 @@ impl crate::error::PrettyError for RenderCommandError {
|
||||
Self::UsageConflict(UsageConflict::TextureInvalid { id }) => {
|
||||
fmt.texture_label(&id);
|
||||
}
|
||||
Self::UsageConflict(UsageConflict::BufferInvalid { id })
|
||||
| Self::DestroyedBuffer(id) => {
|
||||
Self::UsageConflict(UsageConflict::BufferInvalid { id }) => {
|
||||
fmt.buffer_label(&id);
|
||||
}
|
||||
_ => {}
|
||||
|
@ -6,15 +6,13 @@ use crate::{
|
||||
device::Device,
|
||||
hal_api::HalApi,
|
||||
init_tracker::*,
|
||||
resource::{Resource, Texture},
|
||||
resource::{DestroyedResourceError, Resource, Texture},
|
||||
snatch::SnatchGuard,
|
||||
track::{TextureTracker, Tracker},
|
||||
FastHashMap,
|
||||
};
|
||||
|
||||
use super::{
|
||||
clear::clear_texture, BakedCommands, ClearError, DestroyedBufferError, DestroyedTextureError,
|
||||
};
|
||||
use super::{clear::clear_texture, BakedCommands, ClearError};
|
||||
|
||||
/// Surface that was discarded by `StoreOp::Discard` of a preceding renderpass.
|
||||
/// Any read access to this surface needs to be preceded by a texture initialization.
|
||||
@ -171,7 +169,7 @@ impl<A: HalApi> BakedCommands<A> {
|
||||
&mut self,
|
||||
device_tracker: &mut Tracker<A>,
|
||||
snatch_guard: &SnatchGuard<'_>,
|
||||
) -> Result<(), DestroyedBufferError> {
|
||||
) -> Result<(), DestroyedResourceError> {
|
||||
profiling::scope!("initialize_buffer_memory");
|
||||
|
||||
// Gather init ranges for each buffer so we can collapse them.
|
||||
@ -231,10 +229,7 @@ impl<A: HalApi> BakedCommands<A> {
|
||||
.buffers
|
||||
.set_single(&buffer, hal::BufferUses::COPY_DST);
|
||||
|
||||
let raw_buf = buffer
|
||||
.raw
|
||||
.get(snatch_guard)
|
||||
.ok_or(DestroyedBufferError(buffer.error_ident()))?;
|
||||
let raw_buf = buffer.try_raw(snatch_guard)?;
|
||||
|
||||
unsafe {
|
||||
self.encoder.transition_buffers(
|
||||
@ -277,7 +272,7 @@ impl<A: HalApi> BakedCommands<A> {
|
||||
device_tracker: &mut Tracker<A>,
|
||||
device: &Device<A>,
|
||||
snatch_guard: &SnatchGuard<'_>,
|
||||
) -> Result<(), DestroyedTextureError> {
|
||||
) -> Result<(), DestroyedResourceError> {
|
||||
profiling::scope!("initialize_texture_memory");
|
||||
|
||||
let mut ranges: Vec<TextureInitRange> = Vec::new();
|
||||
@ -324,8 +319,8 @@ impl<A: HalApi> BakedCommands<A> {
|
||||
// A Texture can be destroyed between the command recording
|
||||
// and now, this is out of our control so we have to handle
|
||||
// it gracefully.
|
||||
if let Err(ClearError::Destroyed(ident)) = clear_result {
|
||||
return Err(DestroyedTextureError(ident));
|
||||
if let Err(ClearError::DestroyedResource(e)) = clear_result {
|
||||
return Err(e);
|
||||
}
|
||||
|
||||
// Other errors are unexpected.
|
||||
|
@ -29,7 +29,7 @@ use crate::lock::{rank, Mutex};
|
||||
use crate::snatch::SnatchGuard;
|
||||
|
||||
use crate::init_tracker::BufferInitTrackerAction;
|
||||
use crate::resource::{ParentDevice, Resource, ResourceErrorIdent, 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};
|
||||
|
||||
@ -243,9 +243,6 @@ pub(crate) struct BakedCommands<A: HalApi> {
|
||||
texture_memory_actions: CommandBufferTextureMemoryActions<A>,
|
||||
}
|
||||
|
||||
pub(crate) struct DestroyedBufferError(pub ResourceErrorIdent);
|
||||
pub(crate) struct DestroyedTextureError(pub ResourceErrorIdent);
|
||||
|
||||
/// The mutable state of a [`CommandBuffer`].
|
||||
pub struct CommandBufferMutable<A: HalApi> {
|
||||
/// The [`wgpu_hal::Api::CommandBuffer`]s we've built so far, and the encoder
|
||||
|
@ -9,7 +9,7 @@ use crate::{
|
||||
hal_api::HalApi,
|
||||
id::{self, Id},
|
||||
init_tracker::MemoryInitKind,
|
||||
resource::{ParentDevice, QuerySet},
|
||||
resource::{DestroyedResourceError, ParentDevice, QuerySet},
|
||||
storage::Storage,
|
||||
Epoch, FastHashMap, Index,
|
||||
};
|
||||
@ -113,8 +113,10 @@ pub enum QueryError {
|
||||
Use(#[from] QueryUseError),
|
||||
#[error("Error encountered while trying to resolve a query")]
|
||||
Resolve(#[from] ResolveError),
|
||||
#[error("Buffer {0:?} is invalid or destroyed")]
|
||||
InvalidBuffer(id::BufferId),
|
||||
#[error("BufferId {0:?} is invalid")]
|
||||
InvalidBufferId(id::BufferId),
|
||||
#[error(transparent)]
|
||||
DestroyedResource(#[from] DestroyedResourceError),
|
||||
#[error("QuerySet {0:?} is invalid or destroyed")]
|
||||
InvalidQuerySet(id::QuerySetId),
|
||||
}
|
||||
@ -122,11 +124,8 @@ pub enum QueryError {
|
||||
impl crate::error::PrettyError for QueryError {
|
||||
fn fmt_pretty(&self, fmt: &mut crate::error::ErrorFormatter) {
|
||||
fmt.error(self);
|
||||
match *self {
|
||||
Self::InvalidBuffer(id) => fmt.buffer_label(&id),
|
||||
Self::InvalidQuerySet(id) => fmt.query_set_label(&id),
|
||||
|
||||
_ => {}
|
||||
if let Self::InvalidQuerySet(id) = *self {
|
||||
fmt.query_set_label(&id)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -409,7 +408,7 @@ impl Global {
|
||||
let dst_buffer = hub
|
||||
.buffers
|
||||
.get(destination)
|
||||
.map_err(|_| QueryError::InvalidBuffer(destination))?;
|
||||
.map_err(|_| QueryError::InvalidBufferId(destination))?;
|
||||
|
||||
dst_buffer.same_device_as(cmd_buf.as_ref())?;
|
||||
|
||||
@ -465,9 +464,7 @@ impl Global {
|
||||
MemoryInitKind::ImplicitlyInitialized,
|
||||
));
|
||||
|
||||
let raw_dst_buffer = dst_buffer
|
||||
.raw(&snatch_guard)
|
||||
.ok_or(QueryError::InvalidBuffer(destination))?;
|
||||
let raw_dst_buffer = dst_buffer.try_raw(&snatch_guard)?;
|
||||
|
||||
unsafe {
|
||||
raw_encoder.transition_buffers(dst_barrier.into_iter());
|
||||
|
@ -26,8 +26,8 @@ use crate::{
|
||||
init_tracker::{MemoryInitKind, TextureInitRange, TextureInitTrackerAction},
|
||||
pipeline::{self, PipelineFlags},
|
||||
resource::{
|
||||
MissingBufferUsageError, MissingTextureUsageError, ParentDevice, QuerySet, Texture,
|
||||
TextureView, TextureViewNotRenderableReason,
|
||||
DestroyedResourceError, MissingBufferUsageError, MissingTextureUsageError, ParentDevice,
|
||||
QuerySet, Texture, TextureView, TextureViewNotRenderableReason,
|
||||
},
|
||||
storage::Storage,
|
||||
track::{TextureSelector, Tracker, UsageConflict, UsageScope},
|
||||
@ -666,6 +666,8 @@ pub enum RenderPassErrorInner {
|
||||
InvalidQuerySet(id::QuerySetId),
|
||||
#[error("missing occlusion query set")]
|
||||
MissingOcclusionQuerySet,
|
||||
#[error(transparent)]
|
||||
DestroyedResource(#[from] DestroyedResourceError),
|
||||
}
|
||||
|
||||
impl PrettyError for RenderPassErrorInner {
|
||||
@ -1678,11 +1680,7 @@ impl Global {
|
||||
buffer
|
||||
.check_usage(BufferUsages::INDEX)
|
||||
.map_pass_err(scope)?;
|
||||
let buf_raw = buffer
|
||||
.raw
|
||||
.get(&snatch_guard)
|
||||
.ok_or(RenderCommandError::DestroyedBuffer(buffer_id))
|
||||
.map_pass_err(scope)?;
|
||||
let buf_raw = buffer.try_raw(&snatch_guard).map_pass_err(scope)?;
|
||||
|
||||
let end = match size {
|
||||
Some(s) => offset + s.get(),
|
||||
@ -1741,11 +1739,7 @@ impl Global {
|
||||
buffer
|
||||
.check_usage(BufferUsages::VERTEX)
|
||||
.map_pass_err(scope)?;
|
||||
let buf_raw = buffer
|
||||
.raw
|
||||
.get(&snatch_guard)
|
||||
.ok_or(RenderCommandError::DestroyedBuffer(buffer_id))
|
||||
.map_pass_err(scope)?;
|
||||
let buf_raw = buffer.try_raw(&snatch_guard).map_pass_err(scope)?;
|
||||
|
||||
let empty_slots =
|
||||
(1 + slot as usize).saturating_sub(state.vertex.inputs.len());
|
||||
@ -2039,11 +2033,8 @@ impl Global {
|
||||
indirect_buffer
|
||||
.check_usage(BufferUsages::INDIRECT)
|
||||
.map_pass_err(scope)?;
|
||||
let indirect_raw = indirect_buffer
|
||||
.raw
|
||||
.get(&snatch_guard)
|
||||
.ok_or(RenderCommandError::DestroyedBuffer(buffer_id))
|
||||
.map_pass_err(scope)?;
|
||||
let indirect_raw =
|
||||
indirect_buffer.try_raw(&snatch_guard).map_pass_err(scope)?;
|
||||
|
||||
let actual_count = count.map_or(1, |c| c.get());
|
||||
|
||||
@ -2112,11 +2103,8 @@ impl Global {
|
||||
indirect_buffer
|
||||
.check_usage(BufferUsages::INDIRECT)
|
||||
.map_pass_err(scope)?;
|
||||
let indirect_raw = indirect_buffer
|
||||
.raw
|
||||
.get(&snatch_guard)
|
||||
.ok_or(RenderCommandError::DestroyedBuffer(buffer_id))
|
||||
.map_pass_err(scope)?;
|
||||
let indirect_raw =
|
||||
indirect_buffer.try_raw(&snatch_guard).map_pass_err(scope)?;
|
||||
|
||||
let count_buffer = info
|
||||
.usage_scope
|
||||
@ -2130,11 +2118,7 @@ impl Global {
|
||||
count_buffer
|
||||
.check_usage(BufferUsages::INDIRECT)
|
||||
.map_pass_err(scope)?;
|
||||
let count_raw = count_buffer
|
||||
.raw
|
||||
.get(&snatch_guard)
|
||||
.ok_or(RenderCommandError::DestroyedBuffer(count_buffer_id))
|
||||
.map_pass_err(scope)?;
|
||||
let count_raw = count_buffer.try_raw(&snatch_guard).map_pass_err(scope)?;
|
||||
|
||||
let end_offset = offset + stride * max_count as u64;
|
||||
if end_offset > indirect_buffer.size {
|
||||
@ -2373,8 +2357,8 @@ impl Global {
|
||||
|
||||
unsafe { bundle.execute(raw, &snatch_guard) }
|
||||
.map_err(|e| match e {
|
||||
ExecutionError::DestroyedBuffer(id) => {
|
||||
RenderCommandError::DestroyedBuffer(id)
|
||||
ExecutionError::DestroyedResource(e) => {
|
||||
RenderCommandError::DestroyedResource(e)
|
||||
}
|
||||
ExecutionError::InvalidBindGroup(id) => {
|
||||
RenderCommandError::InvalidBindGroup(id)
|
||||
|
@ -13,7 +13,7 @@ use crate::{
|
||||
has_copy_partial_init_tracker_coverage, MemoryInitKind, TextureInitRange,
|
||||
TextureInitTrackerAction,
|
||||
},
|
||||
resource::{ParentDevice, Texture, TextureErrorDimension},
|
||||
resource::{DestroyedResourceError, ParentDevice, Texture, TextureErrorDimension},
|
||||
snatch::SnatchGuard,
|
||||
track::{TextureSelector, Tracker},
|
||||
};
|
||||
@ -41,10 +41,10 @@ pub enum CopySide {
|
||||
#[derive(Clone, Debug, Error)]
|
||||
#[non_exhaustive]
|
||||
pub enum TransferError {
|
||||
#[error("Buffer {0:?} is invalid or destroyed")]
|
||||
InvalidBuffer(BufferId),
|
||||
#[error("Texture {0:?} is invalid or destroyed")]
|
||||
InvalidTexture(TextureId),
|
||||
#[error("BufferId {0:?} is invalid")]
|
||||
InvalidBufferId(BufferId),
|
||||
#[error("TextureId {0:?} is invalid")]
|
||||
InvalidTextureId(TextureId),
|
||||
#[error("Source and destination cannot be the same buffer")]
|
||||
SameSourceDestinationBuffer,
|
||||
#[error("Source buffer/texture is missing the `COPY_SRC` usage flag")]
|
||||
@ -143,33 +143,14 @@ pub enum TransferError {
|
||||
impl PrettyError for TransferError {
|
||||
fn fmt_pretty(&self, fmt: &mut ErrorFormatter) {
|
||||
fmt.error(self);
|
||||
match *self {
|
||||
Self::InvalidBuffer(id) => {
|
||||
fmt.buffer_label(&id);
|
||||
if let Self::MissingCopyDstUsageFlag(buf_opt, tex_opt) = *self {
|
||||
if let Some(buf) = buf_opt {
|
||||
fmt.buffer_label_with_key(&buf, "destination");
|
||||
}
|
||||
Self::InvalidTexture(id) => {
|
||||
fmt.texture_label(&id);
|
||||
if let Some(tex) = tex_opt {
|
||||
fmt.texture_label_with_key(&tex, "destination");
|
||||
}
|
||||
// Self::MissingCopySrcUsageFlag(buf_opt, tex_opt) => {
|
||||
// if let Some(buf) = buf_opt {
|
||||
// let name = crate::gfx_select!(buf => global.buffer_label(buf));
|
||||
// ret.push_str(&format_label_line("source", &name));
|
||||
// }
|
||||
// if let Some(tex) = tex_opt {
|
||||
// let name = crate::gfx_select!(tex => global.texture_label(tex));
|
||||
// ret.push_str(&format_label_line("source", &name));
|
||||
// }
|
||||
// }
|
||||
Self::MissingCopyDstUsageFlag(buf_opt, tex_opt) => {
|
||||
if let Some(buf) = buf_opt {
|
||||
fmt.buffer_label_with_key(&buf, "destination");
|
||||
}
|
||||
if let Some(tex) = tex_opt {
|
||||
fmt.texture_label_with_key(&tex, "destination");
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
/// Error encountered while attempting to do a copy on a command encoder.
|
||||
@ -180,6 +161,8 @@ pub enum CopyError {
|
||||
Encoder(#[from] CommandEncoderError),
|
||||
#[error("Copy error")]
|
||||
Transfer(#[from] TransferError),
|
||||
#[error(transparent)]
|
||||
DestroyedResource(#[from] DestroyedResourceError),
|
||||
}
|
||||
|
||||
impl From<DeviceError> for CopyError {
|
||||
@ -595,7 +578,7 @@ impl Global {
|
||||
let src_buffer = hub
|
||||
.buffers
|
||||
.get(source)
|
||||
.map_err(|_| TransferError::InvalidBuffer(source))?;
|
||||
.map_err(|_| TransferError::InvalidBufferId(source))?;
|
||||
|
||||
src_buffer.same_device_as(cmd_buf.as_ref())?;
|
||||
|
||||
@ -604,10 +587,7 @@ impl Global {
|
||||
.buffers
|
||||
.set_single(&src_buffer, hal::BufferUses::COPY_SRC);
|
||||
|
||||
let src_raw = src_buffer
|
||||
.raw
|
||||
.get(&snatch_guard)
|
||||
.ok_or(TransferError::InvalidBuffer(source))?;
|
||||
let src_raw = src_buffer.try_raw(&snatch_guard)?;
|
||||
if !src_buffer.usage.contains(BufferUsages::COPY_SRC) {
|
||||
return Err(TransferError::MissingCopySrcUsageFlag.into());
|
||||
}
|
||||
@ -617,7 +597,7 @@ impl Global {
|
||||
let dst_buffer = hub
|
||||
.buffers
|
||||
.get(destination)
|
||||
.map_err(|_| TransferError::InvalidBuffer(destination))?;
|
||||
.map_err(|_| TransferError::InvalidBufferId(destination))?;
|
||||
|
||||
dst_buffer.same_device_as(cmd_buf.as_ref())?;
|
||||
|
||||
@ -626,10 +606,7 @@ impl Global {
|
||||
.buffers
|
||||
.set_single(&dst_buffer, hal::BufferUses::COPY_DST);
|
||||
|
||||
let dst_raw = dst_buffer
|
||||
.raw
|
||||
.get(&snatch_guard)
|
||||
.ok_or(TransferError::InvalidBuffer(destination))?;
|
||||
let dst_raw = dst_buffer.try_raw(&snatch_guard)?;
|
||||
if !dst_buffer.usage.contains(BufferUsages::COPY_DST) {
|
||||
return Err(TransferError::MissingCopyDstUsageFlag(Some(destination), None).into());
|
||||
}
|
||||
@ -765,7 +742,7 @@ impl Global {
|
||||
let dst_texture = hub
|
||||
.textures
|
||||
.get(destination.texture)
|
||||
.map_err(|_| TransferError::InvalidTexture(destination.texture))?;
|
||||
.map_err(|_| TransferError::InvalidTextureId(destination.texture))?;
|
||||
|
||||
dst_texture.same_device_as(cmd_buf.as_ref())?;
|
||||
|
||||
@ -797,7 +774,7 @@ impl Global {
|
||||
let src_buffer = hub
|
||||
.buffers
|
||||
.get(source.buffer)
|
||||
.map_err(|_| TransferError::InvalidBuffer(source.buffer))?;
|
||||
.map_err(|_| TransferError::InvalidBufferId(source.buffer))?;
|
||||
|
||||
src_buffer.same_device_as(cmd_buf.as_ref())?;
|
||||
|
||||
@ -805,10 +782,7 @@ impl Global {
|
||||
.buffers
|
||||
.set_single(&src_buffer, hal::BufferUses::COPY_SRC);
|
||||
|
||||
let src_raw = src_buffer
|
||||
.raw
|
||||
.get(&snatch_guard)
|
||||
.ok_or(TransferError::InvalidBuffer(source.buffer))?;
|
||||
let src_raw = src_buffer.try_raw(&snatch_guard)?;
|
||||
if !src_buffer.usage.contains(BufferUsages::COPY_SRC) {
|
||||
return Err(TransferError::MissingCopySrcUsageFlag.into());
|
||||
}
|
||||
@ -818,9 +792,7 @@ impl Global {
|
||||
tracker
|
||||
.textures
|
||||
.set_single(&dst_texture, dst_range, hal::TextureUses::COPY_DST);
|
||||
let dst_raw = dst_texture
|
||||
.raw(&snatch_guard)
|
||||
.ok_or(TransferError::InvalidTexture(destination.texture))?;
|
||||
let dst_raw = dst_texture.try_raw(&snatch_guard)?;
|
||||
if !dst_texture.desc.usage.contains(TextureUsages::COPY_DST) {
|
||||
return Err(
|
||||
TransferError::MissingCopyDstUsageFlag(None, Some(destination.texture)).into(),
|
||||
@ -927,7 +899,7 @@ impl Global {
|
||||
let src_texture = hub
|
||||
.textures
|
||||
.get(source.texture)
|
||||
.map_err(|_| TransferError::InvalidTexture(source.texture))?;
|
||||
.map_err(|_| TransferError::InvalidTextureId(source.texture))?;
|
||||
|
||||
src_texture.same_device_as(cmd_buf.as_ref())?;
|
||||
|
||||
@ -956,9 +928,7 @@ impl Global {
|
||||
tracker
|
||||
.textures
|
||||
.set_single(&src_texture, src_range, hal::TextureUses::COPY_SRC);
|
||||
let src_raw = src_texture
|
||||
.raw(&snatch_guard)
|
||||
.ok_or(TransferError::InvalidTexture(source.texture))?;
|
||||
let src_raw = src_texture.try_raw(&snatch_guard)?;
|
||||
if !src_texture.desc.usage.contains(TextureUsages::COPY_SRC) {
|
||||
return Err(TransferError::MissingCopySrcUsageFlag.into());
|
||||
}
|
||||
@ -980,7 +950,7 @@ impl Global {
|
||||
let dst_buffer = hub
|
||||
.buffers
|
||||
.get(destination.buffer)
|
||||
.map_err(|_| TransferError::InvalidBuffer(destination.buffer))?;
|
||||
.map_err(|_| TransferError::InvalidBufferId(destination.buffer))?;
|
||||
|
||||
dst_buffer.same_device_as(cmd_buf.as_ref())?;
|
||||
|
||||
@ -988,10 +958,7 @@ impl Global {
|
||||
.buffers
|
||||
.set_single(&dst_buffer, hal::BufferUses::COPY_DST);
|
||||
|
||||
let dst_raw = dst_buffer
|
||||
.raw
|
||||
.get(&snatch_guard)
|
||||
.ok_or(TransferError::InvalidBuffer(destination.buffer))?;
|
||||
let dst_raw = dst_buffer.try_raw(&snatch_guard)?;
|
||||
if !dst_buffer.usage.contains(BufferUsages::COPY_DST) {
|
||||
return Err(
|
||||
TransferError::MissingCopyDstUsageFlag(Some(destination.buffer), None).into(),
|
||||
@ -1103,11 +1070,11 @@ impl Global {
|
||||
let src_texture = hub
|
||||
.textures
|
||||
.get(source.texture)
|
||||
.map_err(|_| TransferError::InvalidTexture(source.texture))?;
|
||||
.map_err(|_| TransferError::InvalidTextureId(source.texture))?;
|
||||
let dst_texture = hub
|
||||
.textures
|
||||
.get(destination.texture)
|
||||
.map_err(|_| TransferError::InvalidTexture(source.texture))?;
|
||||
.map_err(|_| TransferError::InvalidTextureId(source.texture))?;
|
||||
|
||||
src_texture.same_device_as(cmd_buf.as_ref())?;
|
||||
dst_texture.same_device_as(cmd_buf.as_ref())?;
|
||||
@ -1174,9 +1141,7 @@ impl Global {
|
||||
src_range,
|
||||
hal::TextureUses::COPY_SRC,
|
||||
);
|
||||
let src_raw = src_texture
|
||||
.raw(&snatch_guard)
|
||||
.ok_or(TransferError::InvalidTexture(source.texture))?;
|
||||
let src_raw = src_texture.try_raw(&snatch_guard)?;
|
||||
if !src_texture.desc.usage.contains(TextureUsages::COPY_SRC) {
|
||||
return Err(TransferError::MissingCopySrcUsageFlag.into());
|
||||
}
|
||||
@ -1192,9 +1157,7 @@ impl Global {
|
||||
dst_range,
|
||||
hal::TextureUses::COPY_DST,
|
||||
);
|
||||
let dst_raw = dst_texture
|
||||
.raw(&snatch_guard)
|
||||
.ok_or(TransferError::InvalidTexture(destination.texture))?;
|
||||
let dst_raw = dst_texture.try_raw(&snatch_guard)?;
|
||||
if !dst_texture.desc.usage.contains(TextureUsages::COPY_DST) {
|
||||
return Err(
|
||||
TransferError::MissingCopyDstUsageFlag(None, Some(destination.texture)).into(),
|
||||
|
@ -387,7 +387,7 @@ impl Global {
|
||||
let buffer = hub
|
||||
.buffers
|
||||
.get(buffer_id)
|
||||
.map_err(|_| BufferAccessError::Invalid)?;
|
||||
.map_err(|_| BufferAccessError::InvalidBufferId(buffer_id))?;
|
||||
buffer.check_usage(wgt::BufferUsages::MAP_WRITE)?;
|
||||
//assert!(buffer isn't used by the GPU);
|
||||
|
||||
@ -402,9 +402,7 @@ impl Global {
|
||||
});
|
||||
}
|
||||
|
||||
let raw_buf = buffer
|
||||
.raw(&snatch_guard)
|
||||
.ok_or(BufferAccessError::Destroyed)?;
|
||||
let raw_buf = buffer.try_raw(&snatch_guard)?;
|
||||
unsafe {
|
||||
let mapping = device
|
||||
.raw()
|
||||
@ -448,13 +446,11 @@ impl Global {
|
||||
let buffer = hub
|
||||
.buffers
|
||||
.get(buffer_id)
|
||||
.map_err(|_| BufferAccessError::Invalid)?;
|
||||
.map_err(|_| BufferAccessError::InvalidBufferId(buffer_id))?;
|
||||
buffer.check_usage(wgt::BufferUsages::MAP_READ)?;
|
||||
//assert!(buffer isn't used by the GPU);
|
||||
|
||||
let raw_buf = buffer
|
||||
.raw(&snatch_guard)
|
||||
.ok_or(BufferAccessError::Destroyed)?;
|
||||
let raw_buf = buffer.try_raw(&snatch_guard)?;
|
||||
unsafe {
|
||||
let mapping = device
|
||||
.raw()
|
||||
@ -789,13 +785,15 @@ impl Global {
|
||||
let error = 'error: {
|
||||
let texture = match hub.textures.get(texture_id) {
|
||||
Ok(texture) => texture,
|
||||
Err(_) => break 'error resource::CreateTextureViewError::InvalidTexture,
|
||||
Err(_) => {
|
||||
break 'error resource::CreateTextureViewError::InvalidTextureId(texture_id)
|
||||
}
|
||||
};
|
||||
let device = &texture.device;
|
||||
{
|
||||
let snatch_guard = device.snatchable_lock.read();
|
||||
if texture.is_destroyed(&snatch_guard) {
|
||||
break 'error resource::CreateTextureViewError::InvalidTexture;
|
||||
if let Err(e) = texture.check_destroyed(&snatch_guard) {
|
||||
break 'error e.into();
|
||||
}
|
||||
}
|
||||
#[cfg(feature = "trace")]
|
||||
@ -2432,7 +2430,7 @@ impl Global {
|
||||
let op_and_err = 'error: {
|
||||
let buffer = match hub.buffers.get(buffer_id) {
|
||||
Ok(buffer) => buffer,
|
||||
Err(_) => break 'error Some((op, BufferAccessError::Invalid)),
|
||||
Err(_) => break 'error Some((op, BufferAccessError::InvalidBufferId(buffer_id))),
|
||||
};
|
||||
|
||||
buffer.map_async(offset, size, op).err()
|
||||
@ -2466,13 +2464,11 @@ impl Global {
|
||||
let buffer = hub
|
||||
.buffers
|
||||
.get(buffer_id)
|
||||
.map_err(|_| BufferAccessError::Invalid)?;
|
||||
.map_err(|_| BufferAccessError::InvalidBufferId(buffer_id))?;
|
||||
|
||||
{
|
||||
let snatch_guard = buffer.device.snatchable_lock.read();
|
||||
if buffer.is_destroyed(&snatch_guard) {
|
||||
return Err(BufferAccessError::Destroyed);
|
||||
}
|
||||
buffer.check_destroyed(&snatch_guard)?;
|
||||
}
|
||||
|
||||
let range_size = if let Some(size) = size {
|
||||
@ -2535,12 +2531,10 @@ impl Global {
|
||||
let buffer = hub
|
||||
.buffers
|
||||
.get(buffer_id)
|
||||
.map_err(|_| BufferAccessError::Invalid)?;
|
||||
.map_err(|_| BufferAccessError::InvalidBufferId(buffer_id))?;
|
||||
|
||||
let snatch_guard = buffer.device.snatchable_lock.read();
|
||||
if buffer.is_destroyed(&snatch_guard) {
|
||||
return Err(BufferAccessError::Destroyed);
|
||||
}
|
||||
buffer.check_destroyed(&snatch_guard)?;
|
||||
drop(snatch_guard);
|
||||
|
||||
buffer.device.check_is_valid()?;
|
||||
|
@ -323,9 +323,7 @@ fn map_buffer<A: HalApi>(
|
||||
kind: HostMap,
|
||||
snatch_guard: &SnatchGuard,
|
||||
) -> Result<ptr::NonNull<u8>, BufferAccessError> {
|
||||
let raw_buffer = buffer
|
||||
.raw(snatch_guard)
|
||||
.ok_or(BufferAccessError::Destroyed)?;
|
||||
let raw_buffer = buffer.try_raw(snatch_guard)?;
|
||||
let mapping = unsafe {
|
||||
raw.map_buffer(raw_buffer, offset..offset + size)
|
||||
.map_err(DeviceError::from)?
|
||||
|
@ -16,9 +16,9 @@ use crate::{
|
||||
init_tracker::{has_copy_partial_init_tracker_coverage, TextureInitRange},
|
||||
lock::{rank, Mutex, RwLockWriteGuard},
|
||||
resource::{
|
||||
Buffer, BufferAccessError, BufferMapState, DestroyedBuffer, DestroyedTexture, ParentDevice,
|
||||
Resource, ResourceErrorIdent, ResourceInfo, ResourceType, StagingBuffer, Texture,
|
||||
TextureInner,
|
||||
Buffer, BufferAccessError, BufferMapState, DestroyedBuffer, DestroyedResourceError,
|
||||
DestroyedTexture, ParentDevice, Resource, ResourceInfo, ResourceType, StagingBuffer,
|
||||
Texture, TextureInner,
|
||||
},
|
||||
resource_log, track, FastHashMap, SubmissionIndex,
|
||||
};
|
||||
@ -365,6 +365,8 @@ pub enum QueueWriteError {
|
||||
Transfer(#[from] TransferError),
|
||||
#[error(transparent)]
|
||||
MemoryInitFailure(#[from] ClearError),
|
||||
#[error(transparent)]
|
||||
DestroyedResource(#[from] DestroyedResourceError),
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Error)]
|
||||
@ -372,10 +374,8 @@ pub enum QueueWriteError {
|
||||
pub enum QueueSubmitError {
|
||||
#[error(transparent)]
|
||||
Queue(#[from] DeviceError),
|
||||
#[error("{0} has been destroyed")]
|
||||
DestroyedBuffer(ResourceErrorIdent),
|
||||
#[error("{0} has been destroyed")]
|
||||
DestroyedTexture(ResourceErrorIdent),
|
||||
#[error(transparent)]
|
||||
DestroyedResource(#[from] DestroyedResourceError),
|
||||
#[error(transparent)]
|
||||
Unmap(#[from] BufferAccessError),
|
||||
#[error("Buffer {0:?} is still mapped")]
|
||||
@ -406,7 +406,7 @@ impl Global {
|
||||
let buffer = hub
|
||||
.buffers
|
||||
.get(buffer_id)
|
||||
.map_err(|_| TransferError::InvalidBuffer(buffer_id))?;
|
||||
.map_err(|_| TransferError::InvalidBufferId(buffer_id))?;
|
||||
|
||||
let queue = hub
|
||||
.queues
|
||||
@ -513,7 +513,7 @@ impl Global {
|
||||
|
||||
let staging_buffer = hub.staging_buffers.unregister(staging_buffer_id);
|
||||
if staging_buffer.is_none() {
|
||||
return Err(QueueWriteError::Transfer(TransferError::InvalidBuffer(
|
||||
return Err(QueueWriteError::Transfer(TransferError::InvalidBufferId(
|
||||
buffer_id,
|
||||
)));
|
||||
}
|
||||
@ -556,7 +556,7 @@ impl Global {
|
||||
let buffer = hub
|
||||
.buffers
|
||||
.get(buffer_id)
|
||||
.map_err(|_| TransferError::InvalidBuffer(buffer_id))?;
|
||||
.map_err(|_| TransferError::InvalidBufferId(buffer_id))?;
|
||||
|
||||
self.queue_validate_write_buffer_impl(&buffer, buffer_id, buffer_offset, buffer_size)?;
|
||||
|
||||
@ -608,7 +608,7 @@ impl Global {
|
||||
let dst = hub
|
||||
.buffers
|
||||
.get(buffer_id)
|
||||
.map_err(|_| TransferError::InvalidBuffer(buffer_id))?;
|
||||
.map_err(|_| TransferError::InvalidBufferId(buffer_id))?;
|
||||
|
||||
let transition = {
|
||||
let mut trackers = device.trackers.lock();
|
||||
@ -616,10 +616,7 @@ impl Global {
|
||||
};
|
||||
|
||||
let snatch_guard = device.snatchable_lock.read();
|
||||
let dst_raw = dst
|
||||
.raw
|
||||
.get(&snatch_guard)
|
||||
.ok_or(TransferError::InvalidBuffer(buffer_id))?;
|
||||
let dst_raw = dst.try_raw(&snatch_guard)?;
|
||||
|
||||
dst.same_device_as(queue.as_ref())?;
|
||||
|
||||
@ -702,7 +699,7 @@ impl Global {
|
||||
let dst = hub
|
||||
.textures
|
||||
.get(destination.texture)
|
||||
.map_err(|_| TransferError::InvalidTexture(destination.texture))?;
|
||||
.map_err(|_| TransferError::InvalidTextureId(destination.texture))?;
|
||||
|
||||
dst.same_device_as(queue.as_ref())?;
|
||||
|
||||
@ -830,9 +827,7 @@ impl Global {
|
||||
dst.info
|
||||
.use_at(device.active_submission_index.load(Ordering::Relaxed) + 1);
|
||||
|
||||
let dst_raw = dst
|
||||
.raw(&snatch_guard)
|
||||
.ok_or(TransferError::InvalidTexture(destination.texture))?;
|
||||
let dst_raw = dst.try_raw(&snatch_guard)?;
|
||||
|
||||
let bytes_per_row = data_layout
|
||||
.bytes_per_row
|
||||
@ -1093,9 +1088,7 @@ impl Global {
|
||||
.use_at(device.active_submission_index.load(Ordering::Relaxed) + 1);
|
||||
|
||||
let snatch_guard = device.snatchable_lock.read();
|
||||
let dst_raw = dst
|
||||
.raw(&snatch_guard)
|
||||
.ok_or(TransferError::InvalidTexture(destination.texture))?;
|
||||
let dst_raw = dst.try_raw(&snatch_guard)?;
|
||||
|
||||
let regions = hal::TextureCopy {
|
||||
src_base: hal::TextureCopyBase {
|
||||
@ -1219,11 +1212,7 @@ impl Global {
|
||||
{
|
||||
profiling::scope!("buffers");
|
||||
for buffer in cmd_buf_trackers.buffers.used_resources() {
|
||||
if buffer.raw.get(&snatch_guard).is_none() {
|
||||
return Err(QueueSubmitError::DestroyedBuffer(
|
||||
buffer.error_ident(),
|
||||
));
|
||||
}
|
||||
buffer.check_destroyed(&snatch_guard)?;
|
||||
buffer.info.use_at(submit_index);
|
||||
|
||||
match *buffer.map_state.lock() {
|
||||
@ -1239,14 +1228,9 @@ impl Global {
|
||||
{
|
||||
profiling::scope!("textures");
|
||||
for texture in cmd_buf_trackers.textures.used_resources() {
|
||||
let should_extend = match texture.inner.get(&snatch_guard) {
|
||||
None => {
|
||||
return Err(QueueSubmitError::DestroyedTexture(
|
||||
texture.error_ident(),
|
||||
));
|
||||
}
|
||||
Some(TextureInner::Native { .. }) => false,
|
||||
Some(TextureInner::Surface { ref raw, .. }) => {
|
||||
let should_extend = match texture.try_inner(&snatch_guard)? {
|
||||
TextureInner::Native { .. } => false,
|
||||
TextureInner::Surface { ref raw, .. } => {
|
||||
if raw.is_some() {
|
||||
// Compare the Arcs by pointer as Textures don't implement Eq.
|
||||
submit_surface_textures_owned
|
||||
@ -1350,12 +1334,8 @@ impl Global {
|
||||
|
||||
//Note: locking the trackers has to be done after the storages
|
||||
let mut trackers = device.trackers.lock();
|
||||
baked
|
||||
.initialize_buffer_memory(&mut *trackers, &snatch_guard)
|
||||
.map_err(|err| QueueSubmitError::DestroyedBuffer(err.0))?;
|
||||
baked
|
||||
.initialize_texture_memory(&mut *trackers, device, &snatch_guard)
|
||||
.map_err(|err| QueueSubmitError::DestroyedTexture(err.0))?;
|
||||
baked.initialize_buffer_memory(&mut *trackers, &snatch_guard)?;
|
||||
baked.initialize_texture_memory(&mut *trackers, device, &snatch_guard)?;
|
||||
//Note: stateless trackers are not merged:
|
||||
// device already knows these resources exist.
|
||||
CommandBuffer::insert_barriers_from_tracker(
|
||||
@ -1422,12 +1402,9 @@ impl Global {
|
||||
{
|
||||
used_surface_textures.set_size(hub.textures.read().len());
|
||||
for texture in pending_writes.dst_textures.values() {
|
||||
match texture.inner.get(&snatch_guard) {
|
||||
None => {
|
||||
return Err(QueueSubmitError::DestroyedTexture(texture.error_ident()));
|
||||
}
|
||||
Some(TextureInner::Native { .. }) => {}
|
||||
Some(TextureInner::Surface { ref raw, .. }) => {
|
||||
match texture.try_inner(&snatch_guard)? {
|
||||
TextureInner::Native { .. } => {}
|
||||
TextureInner::Surface { ref raw, .. } => {
|
||||
if raw.is_some() {
|
||||
// Compare the Arcs by pointer as Textures don't implement Eq
|
||||
submit_surface_textures_owned
|
||||
|
@ -1008,9 +1008,7 @@ impl<A: HalApi> Device<A> {
|
||||
) -> Result<TextureView<A>, resource::CreateTextureViewError> {
|
||||
let snatch_guard = texture.device.snatchable_lock.read();
|
||||
|
||||
let texture_raw = texture
|
||||
.raw(&snatch_guard)
|
||||
.ok_or(resource::CreateTextureViewError::InvalidTexture)?;
|
||||
let texture_raw = texture.try_raw(&snatch_guard)?;
|
||||
|
||||
// resolve TextureViewDescriptor defaults
|
||||
// https://gpuweb.github.io/gpuweb/#abstract-opdef-resolving-gputextureviewdescriptor-defaults
|
||||
@ -1925,17 +1923,14 @@ impl<A: HalApi> Device<A> {
|
||||
|
||||
let buffer = storage
|
||||
.get(bb.buffer_id)
|
||||
.map_err(|_| Error::InvalidBuffer(bb.buffer_id))?;
|
||||
.map_err(|_| Error::InvalidBufferId(bb.buffer_id))?;
|
||||
|
||||
used.buffers.add_single(buffer, internal_use);
|
||||
|
||||
buffer.same_device(self)?;
|
||||
|
||||
buffer.check_usage(pub_usage)?;
|
||||
let raw_buffer = buffer
|
||||
.raw
|
||||
.get(snatch_guard)
|
||||
.ok_or(Error::InvalidBuffer(bb.buffer_id))?;
|
||||
let raw_buffer = buffer.try_raw(snatch_guard)?;
|
||||
|
||||
let (bind_size, bind_end) = match bb.size {
|
||||
Some(size) => {
|
||||
|
@ -340,9 +340,8 @@ impl BufferMapCallback {
|
||||
let status = match result {
|
||||
Ok(()) => BufferMapAsyncStatus::Success,
|
||||
Err(BufferAccessError::Device(_)) => BufferMapAsyncStatus::ContextLost,
|
||||
Err(BufferAccessError::Invalid) | Err(BufferAccessError::Destroyed) => {
|
||||
BufferMapAsyncStatus::Invalid
|
||||
}
|
||||
Err(BufferAccessError::InvalidBufferId(_))
|
||||
| Err(BufferAccessError::DestroyedResource(_)) => BufferMapAsyncStatus::Invalid,
|
||||
Err(BufferAccessError::AlreadyMapped) => BufferMapAsyncStatus::AlreadyMapped,
|
||||
Err(BufferAccessError::MapAlreadyPending) => {
|
||||
BufferMapAsyncStatus::MapAlreadyPending
|
||||
@ -382,10 +381,10 @@ pub enum BufferAccessError {
|
||||
Device(#[from] DeviceError),
|
||||
#[error("Buffer map failed")]
|
||||
Failed,
|
||||
#[error("Buffer is invalid")]
|
||||
Invalid,
|
||||
#[error("Buffer is destroyed")]
|
||||
Destroyed,
|
||||
#[error("BufferId {0:?} is invalid")]
|
||||
InvalidBufferId(BufferId),
|
||||
#[error(transparent)]
|
||||
DestroyedResource(#[from] DestroyedResourceError),
|
||||
#[error("Buffer is already mapped")]
|
||||
AlreadyMapped,
|
||||
#[error("Buffer map is pending")]
|
||||
@ -439,6 +438,10 @@ pub struct MissingTextureUsageError {
|
||||
pub(crate) expected: wgt::TextureUsages,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Error)]
|
||||
#[error("{0} has been destroyed")]
|
||||
pub struct DestroyedResourceError(pub ResourceErrorIdent);
|
||||
|
||||
pub type BufferAccessResult = Result<(), BufferAccessError>;
|
||||
|
||||
#[derive(Debug)]
|
||||
@ -487,8 +490,23 @@ impl<A: HalApi> Buffer<A> {
|
||||
self.raw.get(guard)
|
||||
}
|
||||
|
||||
pub(crate) fn is_destroyed(&self, guard: &SnatchGuard) -> bool {
|
||||
self.raw.get(guard).is_none()
|
||||
pub(crate) fn try_raw<'a>(
|
||||
&'a self,
|
||||
guard: &'a SnatchGuard,
|
||||
) -> Result<&A::Buffer, DestroyedResourceError> {
|
||||
self.raw
|
||||
.get(guard)
|
||||
.ok_or_else(|| DestroyedResourceError(self.error_ident()))
|
||||
}
|
||||
|
||||
pub(crate) fn check_destroyed<'a>(
|
||||
&'a self,
|
||||
guard: &'a SnatchGuard,
|
||||
) -> Result<(), DestroyedResourceError> {
|
||||
self.raw
|
||||
.get(guard)
|
||||
.map(|_| ())
|
||||
.ok_or_else(|| DestroyedResourceError(self.error_ident()))
|
||||
}
|
||||
|
||||
/// Checks that the given buffer usage contains the required buffer usage,
|
||||
@ -571,8 +589,8 @@ impl<A: HalApi> Buffer<A> {
|
||||
|
||||
{
|
||||
let snatch_guard = device.snatchable_lock.read();
|
||||
if self.is_destroyed(&snatch_guard) {
|
||||
return Err((op, BufferAccessError::Destroyed));
|
||||
if let Err(e) = self.check_destroyed(&snatch_guard) {
|
||||
return Err((op, e.into()));
|
||||
}
|
||||
}
|
||||
|
||||
@ -623,9 +641,7 @@ impl<A: HalApi> Buffer<A> {
|
||||
|
||||
let device = &self.device;
|
||||
let snatch_guard = device.snatchable_lock.read();
|
||||
let raw_buf = self
|
||||
.raw(&snatch_guard)
|
||||
.ok_or(BufferAccessError::Destroyed)?;
|
||||
let raw_buf = self.try_raw(&snatch_guard)?;
|
||||
let buffer_id = self.info.id();
|
||||
log::debug!("Buffer {:?} map state -> Idle", buffer_id);
|
||||
match mem::replace(&mut *self.map_state.lock(), BufferMapState::Idle) {
|
||||
@ -1039,12 +1055,37 @@ impl<A: HalApi> Drop for Texture<A> {
|
||||
}
|
||||
|
||||
impl<A: HalApi> Texture<A> {
|
||||
pub(crate) fn try_inner<'a>(
|
||||
&'a self,
|
||||
guard: &'a SnatchGuard,
|
||||
) -> Result<&'a TextureInner<A>, DestroyedResourceError> {
|
||||
self.inner
|
||||
.get(guard)
|
||||
.ok_or_else(|| DestroyedResourceError(self.error_ident()))
|
||||
}
|
||||
|
||||
pub(crate) fn raw<'a>(&'a self, snatch_guard: &'a SnatchGuard) -> Option<&'a A::Texture> {
|
||||
self.inner.get(snatch_guard)?.raw()
|
||||
}
|
||||
|
||||
pub(crate) fn is_destroyed(&self, guard: &SnatchGuard) -> bool {
|
||||
self.inner.get(guard).is_none()
|
||||
pub(crate) fn try_raw<'a>(
|
||||
&'a self,
|
||||
guard: &'a SnatchGuard,
|
||||
) -> Result<&'a A::Texture, DestroyedResourceError> {
|
||||
self.inner
|
||||
.get(guard)
|
||||
.and_then(|t| t.raw())
|
||||
.ok_or_else(|| DestroyedResourceError(self.error_ident()))
|
||||
}
|
||||
|
||||
pub(crate) fn check_destroyed<'a>(
|
||||
&'a self,
|
||||
guard: &'a SnatchGuard,
|
||||
) -> Result<(), DestroyedResourceError> {
|
||||
self.inner
|
||||
.get(guard)
|
||||
.map(|_| ())
|
||||
.ok_or_else(|| DestroyedResourceError(self.error_ident()))
|
||||
}
|
||||
|
||||
pub(crate) fn inner_mut<'a>(
|
||||
@ -1563,8 +1604,10 @@ impl<A: HalApi> TextureView<A> {
|
||||
#[derive(Clone, Debug, Error)]
|
||||
#[non_exhaustive]
|
||||
pub enum CreateTextureViewError {
|
||||
#[error("Parent texture is invalid or destroyed")]
|
||||
InvalidTexture,
|
||||
#[error("TextureId {0:?} is invalid")]
|
||||
InvalidTextureId(TextureId),
|
||||
#[error(transparent)]
|
||||
DestroyedResource(#[from] DestroyedResourceError),
|
||||
#[error("Not enough memory left to create texture view")]
|
||||
OutOfMemory,
|
||||
#[error("Invalid texture view dimension `{view:?}` with texture of dimension `{texture:?}`")]
|
||||
|
@ -270,7 +270,7 @@ impl PendingTransition<hal::BufferUses> {
|
||||
buf: &'a resource::Buffer<A>,
|
||||
snatch_guard: &'a SnatchGuard<'a>,
|
||||
) -> hal::BufferBarrier<'a, A> {
|
||||
let buffer = buf.raw.get(snatch_guard).expect("Buffer is destroyed");
|
||||
let buffer = buf.raw(snatch_guard).expect("Buffer is destroyed");
|
||||
hal::BufferBarrier {
|
||||
buffer,
|
||||
usage: self.usage,
|
||||
|
Loading…
Reference in New Issue
Block a user