mirror of
https://github.com/gfx-rs/wgpu.git
synced 2024-11-25 08:13:27 +00:00
Optimise GL fence checking by querying less (#6427)
This commit is contained in:
parent
b3f665be7d
commit
759c3262ad
@ -142,6 +142,7 @@ By @bradwerth [#6216](https://github.com/gfx-rs/wgpu/pull/6216).
|
|||||||
|
|
||||||
- Fix GL debug message callbacks not being properly cleaned up (causing UB). By @Imberflur in [#6114](https://github.com/gfx-rs/wgpu/pull/6114)
|
- Fix GL debug message callbacks not being properly cleaned up (causing UB). By @Imberflur in [#6114](https://github.com/gfx-rs/wgpu/pull/6114)
|
||||||
- Fix calling `slice::from_raw_parts` with unaligned pointers in push constant handling. By @Imberflur in [#6341](https://github.com/gfx-rs/wgpu/pull/6341)
|
- Fix calling `slice::from_raw_parts` with unaligned pointers in push constant handling. By @Imberflur in [#6341](https://github.com/gfx-rs/wgpu/pull/6341)
|
||||||
|
- Optimise fence checking when `Queue::submit` is called many times per frame. By @dinnerbone in [#6427](https://github.com/gfx-rs/wgpu/pull/6427)
|
||||||
|
|
||||||
#### WebGPU
|
#### WebGPU
|
||||||
|
|
||||||
|
@ -8,6 +8,7 @@ use std::{
|
|||||||
sync::{Arc, Mutex},
|
sync::{Arc, Mutex},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
use crate::AtomicFenceValue;
|
||||||
use arrayvec::ArrayVec;
|
use arrayvec::ArrayVec;
|
||||||
use std::sync::atomic::Ordering;
|
use std::sync::atomic::Ordering;
|
||||||
|
|
||||||
@ -1534,7 +1535,7 @@ impl crate::Device for super::Device {
|
|||||||
unsafe fn create_fence(&self) -> Result<super::Fence, crate::DeviceError> {
|
unsafe fn create_fence(&self) -> Result<super::Fence, crate::DeviceError> {
|
||||||
self.counters.fences.add(1);
|
self.counters.fences.add(1);
|
||||||
Ok(super::Fence {
|
Ok(super::Fence {
|
||||||
last_completed: 0,
|
last_completed: AtomicFenceValue::new(0),
|
||||||
pending: Vec::new(),
|
pending: Vec::new(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -1560,7 +1561,7 @@ impl crate::Device for super::Device {
|
|||||||
wait_value: crate::FenceValue,
|
wait_value: crate::FenceValue,
|
||||||
timeout_ms: u32,
|
timeout_ms: u32,
|
||||||
) -> Result<bool, crate::DeviceError> {
|
) -> Result<bool, crate::DeviceError> {
|
||||||
if fence.last_completed < wait_value {
|
if fence.last_completed.load(Ordering::Relaxed) < wait_value {
|
||||||
let gl = &self.shared.context.lock();
|
let gl = &self.shared.context.lock();
|
||||||
let timeout_ns = if cfg!(any(webgl, Emscripten)) {
|
let timeout_ns = if cfg!(any(webgl, Emscripten)) {
|
||||||
0
|
0
|
||||||
@ -1572,19 +1573,25 @@ impl crate::Device for super::Device {
|
|||||||
.iter()
|
.iter()
|
||||||
.find(|&&(value, _)| value >= wait_value)
|
.find(|&&(value, _)| value >= wait_value)
|
||||||
{
|
{
|
||||||
return match unsafe {
|
let signalled = match unsafe {
|
||||||
gl.client_wait_sync(sync, glow::SYNC_FLUSH_COMMANDS_BIT, timeout_ns as i32)
|
gl.client_wait_sync(sync, glow::SYNC_FLUSH_COMMANDS_BIT, timeout_ns as i32)
|
||||||
} {
|
} {
|
||||||
// for some reason firefox returns WAIT_FAILED, to investigate
|
// for some reason firefox returns WAIT_FAILED, to investigate
|
||||||
#[cfg(any(webgl, Emscripten))]
|
#[cfg(any(webgl, Emscripten))]
|
||||||
glow::WAIT_FAILED => {
|
glow::WAIT_FAILED => {
|
||||||
log::warn!("wait failed!");
|
log::warn!("wait failed!");
|
||||||
Ok(false)
|
false
|
||||||
}
|
}
|
||||||
glow::TIMEOUT_EXPIRED => Ok(false),
|
glow::TIMEOUT_EXPIRED => false,
|
||||||
glow::CONDITION_SATISFIED | glow::ALREADY_SIGNALED => Ok(true),
|
glow::CONDITION_SATISFIED | glow::ALREADY_SIGNALED => true,
|
||||||
_ => Err(crate::DeviceError::Lost),
|
_ => return Err(crate::DeviceError::Lost),
|
||||||
};
|
};
|
||||||
|
if signalled {
|
||||||
|
fence
|
||||||
|
.last_completed
|
||||||
|
.fetch_max(wait_value, Ordering::Relaxed);
|
||||||
|
}
|
||||||
|
return Ok(signalled);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Ok(true)
|
Ok(true)
|
||||||
|
@ -120,7 +120,7 @@ use glow::HasContext;
|
|||||||
|
|
||||||
use naga::FastHashMap;
|
use naga::FastHashMap;
|
||||||
use parking_lot::Mutex;
|
use parking_lot::Mutex;
|
||||||
use std::sync::atomic::{AtomicU32, AtomicU8};
|
use std::sync::atomic::{AtomicU32, AtomicU8, Ordering};
|
||||||
use std::{fmt, ops::Range, sync::Arc};
|
use std::{fmt, ops::Range, sync::Arc};
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
@ -718,7 +718,7 @@ impl crate::DynQuerySet for QuerySet {}
|
|||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct Fence {
|
pub struct Fence {
|
||||||
last_completed: crate::FenceValue,
|
last_completed: crate::AtomicFenceValue,
|
||||||
pending: Vec<(crate::FenceValue, glow::Fence)>,
|
pending: Vec<(crate::FenceValue, glow::Fence)>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -743,13 +743,24 @@ unsafe impl Sync for Fence {}
|
|||||||
|
|
||||||
impl Fence {
|
impl Fence {
|
||||||
fn get_latest(&self, gl: &glow::Context) -> crate::FenceValue {
|
fn get_latest(&self, gl: &glow::Context) -> crate::FenceValue {
|
||||||
let mut max_value = self.last_completed;
|
let mut max_value = self.last_completed.load(Ordering::Relaxed);
|
||||||
for &(value, sync) in self.pending.iter() {
|
for &(value, sync) in self.pending.iter() {
|
||||||
|
if value <= max_value {
|
||||||
|
// We already know this was good, no need to check again
|
||||||
|
continue;
|
||||||
|
}
|
||||||
let status = unsafe { gl.get_sync_status(sync) };
|
let status = unsafe { gl.get_sync_status(sync) };
|
||||||
if status == glow::SIGNALED {
|
if status == glow::SIGNALED {
|
||||||
max_value = value;
|
max_value = value;
|
||||||
|
} else {
|
||||||
|
// Anything after the first unsignalled is guaranteed to also be unsignalled
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Track the latest value, to save ourselves some querying later
|
||||||
|
self.last_completed.fetch_max(max_value, Ordering::Relaxed);
|
||||||
|
|
||||||
max_value
|
max_value
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -763,7 +774,6 @@ impl Fence {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
self.pending.retain(|&(value, _)| value > latest);
|
self.pending.retain(|&(value, _)| value > latest);
|
||||||
self.last_completed = latest;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user