Return all_queue_empty for Instance::poll_all

This commit is contained in:
xiaopengli89
2022-05-08 18:35:30 +08:00
committed by Jim Blandy
parent 3f3af605db
commit 654a75b058
4 changed files with 30 additions and 15 deletions

View File

@@ -4974,21 +4974,25 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
/// Poll all devices belonging to the backend `A`.
///
/// If `force_wait` is true, block until all buffer mappings are done.
///
/// Return `all_queue_empty` indicating whether there are more queue submissions still in flight.
fn poll_devices<A: HalApi>(
&self,
force_wait: bool,
closures: &mut UserClosures,
) -> Result<(), WaitIdleError> {
) -> Result<bool, WaitIdleError> {
profiling::scope!("poll_devices");
let hub = A::hub(self);
let mut devices_to_drop = vec![];
let mut all_queue_empty = true;
{
let mut token = Token::root();
let (device_guard, mut token) = hub.devices.read(&mut token);
for (id, device) in device_guard.iter(A::VARIANT) {
let (cbs, queue_empty) = device.maintain(hub, force_wait, &mut token)?;
all_queue_empty = all_queue_empty && queue_empty;
// If the device's own `RefCount` clone is the only one left, and
// its submission queue is empty, then it can be freed.
@@ -5003,41 +5007,49 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
self.exit_device::<A>(device_id);
}
Ok(())
Ok(all_queue_empty)
}
/// Poll all devices on all backends.
///
/// This is the implementation of `wgpu::Instance::poll_all`.
pub fn poll_all_devices(&self, force_wait: bool) -> Result<(), WaitIdleError> {
///
/// Return `all_queue_empty` indicating whether there are more queue submissions still in flight.
pub fn poll_all_devices(&self, force_wait: bool) -> Result<bool, WaitIdleError> {
let mut closures = UserClosures::default();
let mut all_queue_empty = true;
#[cfg(vulkan)]
{
self.poll_devices::<hal::api::Vulkan>(force_wait, &mut closures)?;
all_queue_empty = self.poll_devices::<hal::api::Vulkan>(force_wait, &mut closures)?
&& all_queue_empty;
}
#[cfg(metal)]
{
self.poll_devices::<hal::api::Metal>(force_wait, &mut closures)?;
all_queue_empty =
self.poll_devices::<hal::api::Metal>(force_wait, &mut closures)? && all_queue_empty;
}
#[cfg(dx12)]
{
self.poll_devices::<hal::api::Dx12>(force_wait, &mut closures)?;
all_queue_empty =
self.poll_devices::<hal::api::Dx12>(force_wait, &mut closures)? && all_queue_empty;
}
#[cfg(dx11)]
{
self.poll_devices::<hal::api::Dx11>(force_wait, &mut closures)?;
all_queue_empty =
self.poll_devices::<hal::api::Dx11>(force_wait, &mut closures)? && all_queue_empty;
}
#[cfg(gl)]
{
self.poll_devices::<hal::api::Gles>(force_wait, &mut closures)?;
all_queue_empty =
self.poll_devices::<hal::api::Gles>(force_wait, &mut closures)? && all_queue_empty;
}
unsafe {
closures.fire();
}
Ok(())
Ok(all_queue_empty)
}
pub fn device_label<A: HalApi>(&self, id: id::DeviceId) -> String {

View File

@@ -824,10 +824,10 @@ impl crate::Context for Context {
ready(id.ok())
}
fn instance_poll_all_devices(&self, force_wait: bool) {
fn instance_poll_all_devices(&self, force_wait: bool) -> bool {
let global = &self.0;
match global.poll_all_devices(force_wait) {
Ok(()) => (),
Ok(all_queue_empty) => all_queue_empty,
Err(err) => self.handle_error_fatal(err, "Device::poll"),
}
}

View File

@@ -1066,8 +1066,9 @@ impl crate::Context for Context {
)
}
fn instance_poll_all_devices(&self, _force_wait: bool) {
fn instance_poll_all_devices(&self, _force_wait: bool) -> bool {
// Devices are automatically polled.
true
}
fn adapter_request_device(

View File

@@ -210,7 +210,7 @@ trait Context: Debug + Send + Sized + Sync {
desc: &DeviceDescriptor,
trace_dir: Option<&std::path::Path>,
) -> Self::RequestDeviceFuture;
fn instance_poll_all_devices(&self, force_wait: bool);
fn instance_poll_all_devices(&self, force_wait: bool) -> bool;
fn adapter_is_surface_supported(
&self,
adapter: &Self::AdapterId,
@@ -1563,8 +1563,10 @@ impl Instance {
/// Polls all devices.
/// If `force_wait` is true and this is not running on the web,
/// then this function will block until all in-flight buffers have been mapped.
pub fn poll_all(&self, force_wait: bool) {
self.context.instance_poll_all_devices(force_wait);
///
/// Return `all_queue_empty` indicating whether there are more queue submissions still in flight.
pub fn poll_all(&self, force_wait: bool) -> bool {
self.context.instance_poll_all_devices(force_wait)
}
/// Generates memory report.