Fix CI for wasm atomics (#12730)

# Objective
CI is currently broken because of `DiagnosticsRecorder` not being Send
and Sync as required by Resource.

## Solution
Wrap `DiagnosticsRecorder` internally with a `WgpuWrapper`.
This commit is contained in:
James Liu 2024-03-26 07:26:21 -07:00 committed by GitHub
parent 31d91466b4
commit a0f492b2dd
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -17,7 +17,7 @@ use wgpu::{
PipelineStatisticsTypes, QuerySet, QuerySetDescriptor, QueryType, Queue, RenderPass, PipelineStatisticsTypes, QuerySet, QuerySetDescriptor, QueryType, Queue, RenderPass,
}; };
use crate::renderer::RenderDevice; use crate::renderer::{RenderDevice, WgpuWrapper};
use super::RecordDiagnostics; use super::RecordDiagnostics;
@ -28,10 +28,7 @@ const MAX_PIPELINE_STATISTICS: u32 = 128;
const TIMESTAMP_SIZE: u64 = 8; const TIMESTAMP_SIZE: u64 = 8;
const PIPELINE_STATISTICS_SIZE: u64 = 40; const PIPELINE_STATISTICS_SIZE: u64 = 40;
/// Records diagnostics into [`QuerySet`]'s keeping track of the mapping between struct DiagnosticsRecorderInternal {
/// spans and indices to the corresponding entries in the [`QuerySet`].
#[derive(Resource)]
pub struct DiagnosticsRecorder {
timestamp_period_ns: f32, timestamp_period_ns: f32,
features: Features, features: Features,
current_frame: Mutex<FrameData>, current_frame: Mutex<FrameData>,
@ -39,6 +36,11 @@ pub struct DiagnosticsRecorder {
finished_frames: Vec<FrameData>, finished_frames: Vec<FrameData>,
} }
/// Records diagnostics into [`QuerySet`]'s keeping track of the mapping between
/// spans and indices to the corresponding entries in the [`QuerySet`].
#[derive(Resource)]
pub struct DiagnosticsRecorder(WgpuWrapper<DiagnosticsRecorderInternal>);
impl DiagnosticsRecorder { impl DiagnosticsRecorder {
/// Creates the new `DiagnosticsRecorder`. /// Creates the new `DiagnosticsRecorder`.
pub fn new(device: &RenderDevice, queue: &Queue) -> DiagnosticsRecorder { pub fn new(device: &RenderDevice, queue: &Queue) -> DiagnosticsRecorder {
@ -50,30 +52,32 @@ impl DiagnosticsRecorder {
0.0 0.0
}; };
DiagnosticsRecorder { DiagnosticsRecorder(WgpuWrapper::new(DiagnosticsRecorderInternal {
timestamp_period_ns, timestamp_period_ns,
features, features,
current_frame: Mutex::new(FrameData::new(device, features)), current_frame: Mutex::new(FrameData::new(device, features)),
submitted_frames: Vec::new(), submitted_frames: Vec::new(),
finished_frames: Vec::new(), finished_frames: Vec::new(),
} }))
} }
fn current_frame_mut(&mut self) -> &mut FrameData { fn current_frame_mut(&mut self) -> &mut FrameData {
self.current_frame.get_mut().expect("lock poisoned") self.0.current_frame.get_mut().expect("lock poisoned")
} }
fn current_frame_lock(&self) -> impl DerefMut<Target = FrameData> + '_ { fn current_frame_lock(&self) -> impl DerefMut<Target = FrameData> + '_ {
self.current_frame.lock().expect("lock poisoned") self.0.current_frame.lock().expect("lock poisoned")
} }
/// Begins recording diagnostics for a new frame. /// Begins recording diagnostics for a new frame.
pub fn begin_frame(&mut self) { pub fn begin_frame(&mut self) {
let internal = &mut self.0;
let mut idx = 0; let mut idx = 0;
while idx < self.submitted_frames.len() { while idx < internal.submitted_frames.len() {
if self.submitted_frames[idx].run_mapped_callback(self.timestamp_period_ns) { let timestamp = internal.timestamp_period_ns;
self.finished_frames if internal.submitted_frames[idx].run_mapped_callback(timestamp) {
.push(self.submitted_frames.swap_remove(idx)); let removed = internal.submitted_frames.swap_remove(idx);
internal.finished_frames.push(removed);
} else { } else {
idx += 1; idx += 1;
} }
@ -100,16 +104,24 @@ impl DiagnosticsRecorder {
device: &RenderDevice, device: &RenderDevice,
callback: impl FnOnce(RenderDiagnostics) + Send + Sync + 'static, callback: impl FnOnce(RenderDiagnostics) + Send + Sync + 'static,
) { ) {
self.current_frame_mut().finish(callback); let internal = &mut self.0;
internal
.current_frame
.get_mut()
.expect("lock poisoned")
.finish(callback);
// reuse one of the finished frames, if we can // reuse one of the finished frames, if we can
let new_frame = match self.finished_frames.pop() { let new_frame = match internal.finished_frames.pop() {
Some(frame) => frame, Some(frame) => frame,
None => FrameData::new(device, self.features), None => FrameData::new(device, internal.features),
}; };
let old_frame = std::mem::replace(self.current_frame_mut(), new_frame); let old_frame = std::mem::replace(
self.submitted_frames.push(old_frame); internal.current_frame.get_mut().expect("lock poisoned"),
new_frame,
);
internal.submitted_frames.push(old_frame);
} }
} }