summaryrefslogtreecommitdiffstats
path: root/third_party/rust/wgpu-core/src/device/global.rs
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/rust/wgpu-core/src/device/global.rs')
-rw-r--r--third_party/rust/wgpu-core/src/device/global.rs245
1 files changed, 136 insertions, 109 deletions
diff --git a/third_party/rust/wgpu-core/src/device/global.rs b/third_party/rust/wgpu-core/src/device/global.rs
index 64fd6d4de7..539b92e0f3 100644
--- a/third_party/rust/wgpu-core/src/device/global.rs
+++ b/third_party/rust/wgpu-core/src/device/global.rs
@@ -26,9 +26,7 @@ use wgt::{BufferAddress, TextureFormat};
use std::{
borrow::Cow,
- iter,
- ops::Range,
- ptr,
+ iter, ptr,
sync::{atomic::Ordering, Arc},
};
@@ -219,7 +217,7 @@ impl Global {
mapped_at_creation: false,
};
let stage = match device.create_buffer(&stage_desc, true) {
- Ok(stage) => stage,
+ Ok(stage) => Arc::new(stage),
Err(e) => {
to_destroy.push(buffer);
break e;
@@ -232,14 +230,10 @@ impl Global {
Ok(mapping) => mapping,
Err(e) => {
to_destroy.push(buffer);
- to_destroy.push(stage);
break CreateBufferError::Device(e.into());
}
};
- let stage_fid = hub.buffers.request();
- let stage = stage_fid.init(stage);
-
assert_eq!(buffer.size % wgt::COPY_BUFFER_ALIGNMENT, 0);
// Zero initialize memory and then mark both staging and buffer as initialized
// (it's guaranteed that this is the case by the time the buffer is usable)
@@ -262,7 +256,7 @@ impl Global {
.trackers
.lock()
.buffers
- .insert_single(id, resource, buffer_use);
+ .insert_single(resource, buffer_use);
return (id, None);
};
@@ -383,7 +377,7 @@ impl Global {
.buffers
.get(buffer_id)
.map_err(|_| BufferAccessError::Invalid)?;
- check_buffer_usage(buffer.usage, wgt::BufferUsages::MAP_WRITE)?;
+ check_buffer_usage(buffer_id, buffer.usage, wgt::BufferUsages::MAP_WRITE)?;
//assert!(buffer isn't used by the GPU);
#[cfg(feature = "trace")]
@@ -446,7 +440,7 @@ impl Global {
.buffers
.get(buffer_id)
.map_err(|_| BufferAccessError::Invalid)?;
- check_buffer_usage(buffer.usage, wgt::BufferUsages::MAP_READ)?;
+ check_buffer_usage(buffer_id, buffer.usage, wgt::BufferUsages::MAP_READ)?;
//assert!(buffer isn't used by the GPU);
let raw_buf = buffer
@@ -529,7 +523,7 @@ impl Global {
.lock_life()
.suspected_resources
.buffers
- .insert(buffer_id, buffer);
+ .insert(buffer.info.tracker_index(), buffer);
}
if wait {
@@ -573,11 +567,11 @@ impl Global {
let (id, resource) = fid.assign(texture);
api_log!("Device::create_texture({desc:?}) -> {id:?}");
- device.trackers.lock().textures.insert_single(
- id,
- resource,
- hal::TextureUses::UNINITIALIZED,
- );
+ device
+ .trackers
+ .lock()
+ .textures
+ .insert_single(resource, hal::TextureUses::UNINITIALIZED);
return (id, None);
};
@@ -647,11 +641,11 @@ impl Global {
let (id, resource) = fid.assign(texture);
api_log!("Device::create_texture({desc:?}) -> {id:?}");
- device.trackers.lock().textures.insert_single(
- id,
- resource,
- hal::TextureUses::UNINITIALIZED,
- );
+ device
+ .trackers
+ .lock()
+ .textures
+ .insert_single(resource, hal::TextureUses::UNINITIALIZED);
return (id, None);
};
@@ -704,7 +698,7 @@ impl Global {
.trackers
.lock()
.buffers
- .insert_single(id, buffer, hal::BufferUses::empty());
+ .insert_single(buffer, hal::BufferUses::empty());
return (id, None);
};
@@ -764,7 +758,7 @@ impl Global {
.lock_life()
.suspected_resources
.textures
- .insert(texture_id, texture.clone());
+ .insert(texture.info.tracker_index(), texture.clone());
}
}
@@ -824,7 +818,7 @@ impl Global {
}
api_log!("Texture::create_view({texture_id:?}) -> {id:?}");
- device.trackers.lock().views.insert_single(id, resource);
+ device.trackers.lock().views.insert_single(resource);
return (id, None);
};
@@ -854,7 +848,7 @@ impl Global {
.lock_life()
.suspected_resources
.texture_views
- .insert(texture_view_id, view.clone());
+ .insert(view.info.tracker_index(), view.clone());
if wait {
match view.device.wait_for_submit(last_submit_index) {
@@ -900,7 +894,7 @@ impl Global {
let (id, resource) = fid.assign(sampler);
api_log!("Device::create_sampler -> {id:?}");
- device.trackers.lock().samplers.insert_single(id, resource);
+ device.trackers.lock().samplers.insert_single(resource);
return (id, None);
};
@@ -925,7 +919,7 @@ impl Global {
.lock_life()
.suspected_resources
.samplers
- .insert(sampler_id, sampler.clone());
+ .insert(sampler.info.tracker_index(), sampler.clone());
}
}
@@ -1024,7 +1018,7 @@ impl Global {
.lock_life()
.suspected_resources
.bind_group_layouts
- .insert(bind_group_layout_id, layout.clone());
+ .insert(layout.info.tracker_index(), layout.clone());
}
}
@@ -1085,7 +1079,7 @@ impl Global {
.lock_life()
.suspected_resources
.pipeline_layouts
- .insert(pipeline_layout_id, layout.clone());
+ .insert(layout.info.tracker_index(), layout.clone());
}
}
@@ -1140,11 +1134,7 @@ impl Global {
api_log!("Device::create_bind_group -> {id:?}");
- device
- .trackers
- .lock()
- .bind_groups
- .insert_single(id, resource);
+ device.trackers.lock().bind_groups.insert_single(resource);
return (id, None);
};
@@ -1168,7 +1158,7 @@ impl Global {
.lock_life()
.suspected_resources
.bind_groups
- .insert(bind_group_id, bind_group.clone());
+ .insert(bind_group.info.tracker_index(), bind_group.clone());
}
}
@@ -1332,9 +1322,8 @@ impl Global {
if !device.is_valid() {
break DeviceError::Lost;
}
- let queue = match hub.queues.get(device.queue_id.read().unwrap()) {
- Ok(queue) => queue,
- Err(_) => break DeviceError::InvalidQueueId,
+ let Some(queue) = device.get_queue() else {
+ break DeviceError::InvalidQueueId;
};
let encoder = match device
.command_allocator
@@ -1379,6 +1368,7 @@ impl Global {
.command_buffers
.unregister(command_encoder_id.transmute())
{
+ cmd_buf.data.lock().as_mut().unwrap().encoder.discard();
cmd_buf
.device
.untrack(&cmd_buf.data.lock().as_ref().unwrap().trackers);
@@ -1450,7 +1440,7 @@ impl Global {
let (id, resource) = fid.assign(render_bundle);
api_log!("RenderBundleEncoder::finish -> {id:?}");
- device.trackers.lock().bundles.insert_single(id, resource);
+ device.trackers.lock().bundles.insert_single(resource);
return (id, None);
};
@@ -1474,7 +1464,7 @@ impl Global {
.lock_life()
.suspected_resources
.render_bundles
- .insert(render_bundle_id, bundle.clone());
+ .insert(bundle.info.tracker_index(), bundle.clone());
}
}
@@ -1513,11 +1503,7 @@ impl Global {
let (id, resource) = fid.assign(query_set);
api_log!("Device::create_query_set -> {id:?}");
- device
- .trackers
- .lock()
- .query_sets
- .insert_single(id, resource);
+ device.trackers.lock().query_sets.insert_single(resource);
return (id, None);
};
@@ -1544,7 +1530,7 @@ impl Global {
.lock_life()
.suspected_resources
.query_sets
- .insert(query_set_id, query_set.clone());
+ .insert(query_set.info.tracker_index(), query_set.clone());
}
}
@@ -1600,7 +1586,7 @@ impl Global {
.trackers
.lock()
.render_pipelines
- .insert_single(id, resource);
+ .insert_single(resource);
return (id, None);
};
@@ -1672,18 +1658,17 @@ impl Global {
let hub = A::hub(self);
if let Some(pipeline) = hub.render_pipelines.unregister(render_pipeline_id) {
- let layout_id = pipeline.layout.as_info().id();
let device = &pipeline.device;
let mut life_lock = device.lock_life();
life_lock
.suspected_resources
.render_pipelines
- .insert(render_pipeline_id, pipeline.clone());
+ .insert(pipeline.info.tracker_index(), pipeline.clone());
- life_lock
- .suspected_resources
- .pipeline_layouts
- .insert(layout_id, pipeline.layout.clone());
+ life_lock.suspected_resources.pipeline_layouts.insert(
+ pipeline.layout.info.tracker_index(),
+ pipeline.layout.clone(),
+ );
}
}
@@ -1734,7 +1719,7 @@ impl Global {
.trackers
.lock()
.compute_pipelines
- .insert_single(id, resource);
+ .insert_single(resource);
return (id, None);
};
@@ -1804,17 +1789,16 @@ impl Global {
let hub = A::hub(self);
if let Some(pipeline) = hub.compute_pipelines.unregister(compute_pipeline_id) {
- let layout_id = pipeline.layout.as_info().id();
let device = &pipeline.device;
let mut life_lock = device.lock_life();
life_lock
.suspected_resources
.compute_pipelines
- .insert(compute_pipeline_id, pipeline.clone());
- life_lock
- .suspected_resources
- .pipeline_layouts
- .insert(layout_id, pipeline.layout.clone());
+ .insert(pipeline.info.tracker_index(), pipeline.clone());
+ life_lock.suspected_resources.pipeline_layouts.insert(
+ pipeline.layout.info.tracker_index(),
+ pipeline.layout.clone(),
+ );
}
}
@@ -2113,28 +2097,41 @@ impl Global {
.get(device_id)
.map_err(|_| DeviceError::Invalid)?;
- let (closures, queue_empty) = {
- if let wgt::Maintain::WaitForSubmissionIndex(submission_index) = maintain {
- if submission_index.queue_id != device_id.transmute() {
- return Err(WaitIdleError::WrongSubmissionIndex(
- submission_index.queue_id,
- device_id,
- ));
- }
+ if let wgt::Maintain::WaitForSubmissionIndex(submission_index) = maintain {
+ if submission_index.queue_id != device_id.transmute() {
+ return Err(WaitIdleError::WrongSubmissionIndex(
+ submission_index.queue_id,
+ device_id,
+ ));
}
+ }
- let fence = device.fence.read();
- let fence = fence.as_ref().unwrap();
- device.maintain(fence, maintain)?
- };
+ let DevicePoll {
+ closures,
+ queue_empty,
+ } = Self::poll_single_device(&device, maintain)?;
+
+ closures.fire();
+
+ Ok(queue_empty)
+ }
+
+ fn poll_single_device<A: HalApi>(
+ device: &crate::device::Device<A>,
+ maintain: wgt::Maintain<queue::WrappedSubmissionIndex>,
+ ) -> Result<DevicePoll, WaitIdleError> {
+ let fence = device.fence.read();
+ let fence = fence.as_ref().unwrap();
+ let (closures, queue_empty) = device.maintain(fence, maintain)?;
// Some deferred destroys are scheduled in maintain so run this right after
// to avoid holding on to them until the next device poll.
device.deferred_resource_destruction();
- closures.fire();
-
- Ok(queue_empty)
+ Ok(DevicePoll {
+ closures,
+ queue_empty,
+ })
}
/// Poll all devices belonging to the backend `A`.
@@ -2143,7 +2140,7 @@ impl Global {
///
/// Return `all_queue_empty` indicating whether there are more queue
/// submissions still in flight.
- fn poll_device<A: HalApi>(
+ fn poll_all_devices_of_api<A: HalApi>(
&self,
force_wait: bool,
closures: &mut UserClosures,
@@ -2161,10 +2158,13 @@ impl Global {
} else {
wgt::Maintain::Poll
};
- let fence = device.fence.read();
- let fence = fence.as_ref().unwrap();
- let (cbs, queue_empty) = device.maintain(fence, maintain)?;
- all_queue_empty = all_queue_empty && queue_empty;
+
+ let DevicePoll {
+ closures: cbs,
+ queue_empty,
+ } = Self::poll_single_device(device, maintain)?;
+
+ all_queue_empty &= queue_empty;
closures.extend(cbs);
}
@@ -2186,23 +2186,23 @@ impl Global {
#[cfg(vulkan)]
{
- all_queue_empty =
- self.poll_device::<hal::api::Vulkan>(force_wait, &mut closures)? && all_queue_empty;
+ all_queue_empty &=
+ self.poll_all_devices_of_api::<hal::api::Vulkan>(force_wait, &mut closures)?;
}
#[cfg(metal)]
{
- all_queue_empty =
- self.poll_device::<hal::api::Metal>(force_wait, &mut closures)? && all_queue_empty;
+ all_queue_empty &=
+ self.poll_all_devices_of_api::<hal::api::Metal>(force_wait, &mut closures)?;
}
#[cfg(dx12)]
{
- all_queue_empty =
- self.poll_device::<hal::api::Dx12>(force_wait, &mut closures)? && all_queue_empty;
+ all_queue_empty &=
+ self.poll_all_devices_of_api::<hal::api::Dx12>(force_wait, &mut closures)?;
}
#[cfg(gles)]
{
- all_queue_empty =
- self.poll_device::<hal::api::Gles>(force_wait, &mut closures)? && all_queue_empty;
+ all_queue_empty &=
+ self.poll_all_devices_of_api::<hal::api::Gles>(force_wait, &mut closures)?;
}
closures.fire();
@@ -2336,15 +2336,18 @@ impl Global {
pub fn buffer_map_async<A: HalApi>(
&self,
buffer_id: id::BufferId,
- range: Range<BufferAddress>,
+ offset: BufferAddress,
+ size: Option<BufferAddress>,
op: BufferMapOperation,
) -> BufferAccessResult {
- api_log!("Buffer::map_async {buffer_id:?} range {range:?} op: {op:?}");
+ api_log!("Buffer::map_async {buffer_id:?} offset {offset:?} size {size:?} op: {op:?}");
// User callbacks must not be called while holding buffer_map_async_inner's locks, so we
// defer the error callback if it needs to be called immediately (typically when running
// into errors).
- if let Err((mut operation, err)) = self.buffer_map_async_inner::<A>(buffer_id, range, op) {
+ if let Err((mut operation, err)) =
+ self.buffer_map_async_inner::<A>(buffer_id, offset, size, op)
+ {
if let Some(callback) = operation.callback.take() {
callback.call(Err(err.clone()));
}
@@ -2360,7 +2363,8 @@ impl Global {
fn buffer_map_async_inner<A: HalApi>(
&self,
buffer_id: id::BufferId,
- range: Range<BufferAddress>,
+ offset: BufferAddress,
+ size: Option<BufferAddress>,
op: BufferMapOperation,
) -> Result<(), (BufferMapOperation, BufferAccessError)> {
profiling::scope!("Buffer::map_async");
@@ -2372,29 +2376,50 @@ impl Global {
HostMap::Write => (wgt::BufferUsages::MAP_WRITE, hal::BufferUses::MAP_WRITE),
};
- if range.start % wgt::MAP_ALIGNMENT != 0 || range.end % wgt::COPY_BUFFER_ALIGNMENT != 0 {
- return Err((op, BufferAccessError::UnalignedRange));
- }
-
let buffer = {
- let buffer = hub
- .buffers
- .get(buffer_id)
- .map_err(|_| BufferAccessError::Invalid);
+ let buffer = hub.buffers.get(buffer_id);
let buffer = match buffer {
Ok(b) => b,
- Err(e) => {
- return Err((op, e));
+ Err(_) => {
+ return Err((op, BufferAccessError::Invalid));
}
};
+ {
+ let snatch_guard = buffer.device.snatchable_lock.read();
+ if buffer.is_destroyed(&snatch_guard) {
+ return Err((op, BufferAccessError::Destroyed));
+ }
+ }
+
+ let range_size = if let Some(size) = size {
+ size
+ } else if offset > buffer.size {
+ 0
+ } else {
+ buffer.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 = &buffer.device;
if !device.is_valid() {
return Err((op, DeviceError::Lost.into()));
}
- if let Err(e) = check_buffer_usage(buffer.usage, pub_usage) {
+ if let Err(e) = check_buffer_usage(buffer.info.id(), buffer.usage, pub_usage) {
return Err((op, e.into()));
}
@@ -2417,11 +2442,6 @@ impl Global {
));
}
- let snatch_guard = device.snatchable_lock.read();
- if buffer.is_destroyed(&snatch_guard) {
- return Err((op, BufferAccessError::Destroyed));
- }
-
{
let map_state = &mut *buffer.map_state.lock();
*map_state = match *map_state {
@@ -2442,6 +2462,8 @@ impl Global {
};
}
+ let snatch_guard = buffer.device.snatchable_lock.read();
+
{
let mut trackers = buffer.device.as_ref().trackers.lock();
trackers.buffers.set_single(&buffer, internal_use);
@@ -2557,3 +2579,8 @@ impl Global {
buffer.unmap()
}
}
+
+struct DevicePoll {
+ closures: UserClosures,
+ queue_empty: bool,
+}