diff --git a/wgpu-core/src/resource.rs b/wgpu-core/src/resource.rs index cd644b003..2e699faa7 100644 --- a/wgpu-core/src/resource.rs +++ b/wgpu-core/src/resource.rs @@ -485,101 +485,95 @@ impl Buffer { size: Option, op: BufferMapOperation, ) -> Result<(), (BufferMapOperation, BufferAccessError)> { + let range_size = if let Some(size) = size { + size + } else if offset > self.size { + 0 + } else { + self.size - offset + }; + + if offset % wgt::MAP_ALIGNMENT != 0 { + return Err((op, BufferAccessError::UnalignedOffset { offset })); + } + if range_size % wgt::COPY_BUFFER_ALIGNMENT != 0 { + return Err((op, BufferAccessError::UnalignedRangeSize { range_size })); + } + + let range = offset..(offset + range_size); + + if range.start % wgt::MAP_ALIGNMENT != 0 || range.end % wgt::COPY_BUFFER_ALIGNMENT != 0 { + return Err((op, BufferAccessError::UnalignedRange)); + } + let (pub_usage, internal_use) = match op.host { HostMap::Read => (wgt::BufferUsages::MAP_READ, hal::BufferUses::MAP_READ), HostMap::Write => (wgt::BufferUsages::MAP_WRITE, hal::BufferUses::MAP_WRITE), }; + if let Err(e) = crate::validation::check_buffer_usage(self.info.id(), self.usage, pub_usage) { - { - let snatch_guard = self.device.snatchable_lock.read(); - if self.is_destroyed(&snatch_guard) { - return Err((op, BufferAccessError::Destroyed)); - } - } - - let range_size = if let Some(size) = size { - size - } else if offset > self.size { - 0 - } else { - self.size - offset - }; - - if offset % wgt::MAP_ALIGNMENT != 0 { - return Err((op, BufferAccessError::UnalignedOffset { offset })); - } - if range_size % wgt::COPY_BUFFER_ALIGNMENT != 0 { - return Err((op, BufferAccessError::UnalignedRangeSize { range_size })); - } - - let range = offset..(offset + range_size); - - if range.start % wgt::MAP_ALIGNMENT != 0 || range.end % wgt::COPY_BUFFER_ALIGNMENT != 0 - { - return Err((op, BufferAccessError::UnalignedRange)); - } - - let device = &self.device; - if !device.is_valid() { - return Err((op, DeviceError::Lost.into())); - } - - if let Err(e) = - crate::validation::check_buffer_usage(self.info.id(), self.usage, pub_usage) - { - return Err((op, e.into())); - } - - if range.start > range.end { - return Err(( - op, - BufferAccessError::NegativeRange { - start: range.start, - end: range.end, - }, - )); - } - if range.end > self.size { - return Err(( - op, - BufferAccessError::OutOfBoundsOverrun { - index: range.end, - max: self.size, - }, - )); - } - - { - let map_state = &mut *self.map_state.lock(); - *map_state = match *map_state { - BufferMapState::Init { .. } | BufferMapState::Active { .. } => { - return Err((op, BufferAccessError::AlreadyMapped)); - } - BufferMapState::Waiting(_) => { - return Err((op, BufferAccessError::MapAlreadyPending)); - } - BufferMapState::Idle => BufferMapState::Waiting(BufferPendingMapping { - range, - op, - _parent_buffer: self.clone(), - }), - }; - } - - let snatch_guard = self.device.snatchable_lock.read(); - - { - let mut trackers = self.device.as_ref().trackers.lock(); - trackers.buffers.set_single(self, internal_use); - //TODO: Check if draining ALL buffers is correct! - let _ = trackers.buffers.drain_transitions(&snatch_guard); - } - - drop(snatch_guard); + return Err((op, e.into())); } - self.device.lock_life().map(self); + if range.start > range.end { + return Err(( + op, + BufferAccessError::NegativeRange { + start: range.start, + end: range.end, + }, + )); + } + if range.end > self.size { + return Err(( + op, + BufferAccessError::OutOfBoundsOverrun { + index: range.end, + max: self.size, + }, + )); + } + + let device = &self.device; + if let Err(e) = device.check_is_valid() { + return Err((op, e.into())); + } + + { + let snatch_guard = device.snatchable_lock.read(); + if self.is_destroyed(&snatch_guard) { + return Err((op, BufferAccessError::Destroyed)); + } + } + + { + let map_state = &mut *self.map_state.lock(); + *map_state = match *map_state { + BufferMapState::Init { .. } | BufferMapState::Active { .. } => { + return Err((op, BufferAccessError::AlreadyMapped)); + } + BufferMapState::Waiting(_) => { + return Err((op, BufferAccessError::MapAlreadyPending)); + } + BufferMapState::Idle => BufferMapState::Waiting(BufferPendingMapping { + range, + op, + _parent_buffer: self.clone(), + }), + }; + } + + let snatch_guard = device.snatchable_lock.read(); + { + let mut trackers = device.as_ref().trackers.lock(); + trackers.buffers.set_single(self, internal_use); + //TODO: Check if draining ALL buffers is correct! + let _ = trackers.buffers.drain_transitions(&snatch_guard); + } + drop(snatch_guard); + + device.lock_life().map(self); Ok(()) }