Skip to content

Commit 372b2ac

Browse files
committed
vulkan: Replace fence with semaphore when acquiring surfaces
1 parent 4400a58 commit 372b2ac

File tree

13 files changed

+201
-59
lines changed

13 files changed

+201
-59
lines changed

wgpu-core/src/device/queue.rs

Lines changed: 33 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ use crate::{
2222
resource_log, track, FastHashMap, SubmissionIndex,
2323
};
2424

25-
use hal::{CommandEncoder as _, Device as _, Queue as _};
25+
use hal::{CommandEncoder as _, Device as _, Queue as _, RawSet as _};
2626
use parking_lot::Mutex;
2727

2828
use std::{
@@ -1133,6 +1133,12 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
11331133
.fetch_add(1, Ordering::Relaxed)
11341134
+ 1;
11351135
let mut active_executions = Vec::new();
1136+
1137+
// SAFETY: We're constructing this during the submission phase,
1138+
// where all resources it uses are guaranteed to outlive this
1139+
// short-lived set.
1140+
let mut submit_surface_textures = A::SubmitSurfaceTextureSet::new();
1141+
11361142
let mut used_surface_textures = track::TextureUsageScope::new();
11371143

11381144
let snatch_guard = device.snatchable_lock.read();
@@ -1237,8 +1243,19 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
12371243
return Err(QueueSubmitError::DestroyedTexture(id));
12381244
}
12391245
Some(TextureInner::Native { .. }) => false,
1240-
Some(TextureInner::Surface { ref has_work, .. }) => {
1246+
Some(TextureInner::Surface {
1247+
ref has_work,
1248+
ref raw,
1249+
..
1250+
}) => {
12411251
has_work.store(true, Ordering::Relaxed);
1252+
1253+
if let Some(raw) = raw {
1254+
unsafe {
1255+
submit_surface_textures.insert(raw);
1256+
}
1257+
}
1258+
12421259
true
12431260
}
12441261
};
@@ -1429,8 +1446,19 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
14291446
return Err(QueueSubmitError::DestroyedTexture(id));
14301447
}
14311448
Some(TextureInner::Native { .. }) => {}
1432-
Some(TextureInner::Surface { ref has_work, .. }) => {
1449+
Some(TextureInner::Surface {
1450+
ref has_work,
1451+
ref raw,
1452+
..
1453+
}) => {
14331454
has_work.store(true, Ordering::Relaxed);
1455+
1456+
if let Some(raw) = raw {
1457+
unsafe {
1458+
submit_surface_textures.insert(raw);
1459+
}
1460+
}
1461+
14341462
unsafe {
14351463
used_surface_textures
14361464
.merge_single(texture, None, hal::TextureUses::PRESENT)
@@ -1469,12 +1497,13 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
14691497
.flat_map(|pool_execution| pool_execution.cmd_buffers.iter()),
14701498
)
14711499
.collect::<Vec<_>>();
1500+
14721501
unsafe {
14731502
queue
14741503
.raw
14751504
.as_ref()
14761505
.unwrap()
1477-
.submit(&refs, Some((fence, submit_index)))
1506+
.submit(&refs, &submit_surface_textures, Some((fence, submit_index)))
14781507
.map_err(DeviceError::from)?;
14791508
}
14801509

wgpu-hal/examples/halmark/main.rs

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,8 @@
33
extern crate wgpu_hal as hal;
44

55
use hal::{
6-
Adapter as _, CommandEncoder as _, Device as _, Instance as _, Queue as _, Surface as _,
6+
Adapter as _, CommandEncoder as _, Device as _, Instance as _, Queue as _, RawSet as _,
7+
Surface as _,
78
};
89
use raw_window_handle::{HasDisplayHandle, HasWindowHandle};
910
use winit::{
@@ -489,8 +490,13 @@ impl<A: hal::Api> Example<A> {
489490
let fence = unsafe {
490491
let mut fence = device.create_fence().unwrap();
491492
let init_cmd = cmd_encoder.end_encoding().unwrap();
493+
let surface_textures = A::SubmitSurfaceTextureSet::new();
492494
queue
493-
.submit(&[&init_cmd], Some((&mut fence, init_fence_value)))
495+
.submit(
496+
&[&init_cmd],
497+
&surface_textures,
498+
Some((&mut fence, init_fence_value)),
499+
)
494500
.unwrap();
495501
device.wait(&fence, init_fence_value, !0).unwrap();
496502
device.destroy_buffer(staging_buffer);
@@ -541,8 +547,13 @@ impl<A: hal::Api> Example<A> {
541547
unsafe {
542548
{
543549
let ctx = &mut self.contexts[self.context_index];
550+
let surface_textures = A::SubmitSurfaceTextureSet::new();
544551
self.queue
545-
.submit(&[], Some((&mut ctx.fence, ctx.fence_value)))
552+
.submit(
553+
&[],
554+
&surface_textures,
555+
Some((&mut ctx.fence, ctx.fence_value)),
556+
)
546557
.unwrap();
547558
}
548559

@@ -729,7 +740,11 @@ impl<A: hal::Api> Example<A> {
729740
} else {
730741
None
731742
};
732-
self.queue.submit(&[&cmd_buf], fence_param).unwrap();
743+
let mut surface_textures = A::SubmitSurfaceTextureSet::new();
744+
surface_textures.insert(&surface_tex);
745+
self.queue
746+
.submit(&[&cmd_buf], &surface_textures, fence_param)
747+
.unwrap();
733748
self.queue.present(&self.surface, surface_tex).unwrap();
734749
ctx.used_cmd_bufs.push(cmd_buf);
735750
ctx.used_views.push(surface_tex_view);

wgpu-hal/examples/raw-gles.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -183,6 +183,6 @@ fn fill_screen(exposed: &hal::ExposedAdapter<hal::api::Gles>, width: u32, height
183183
encoder.begin_render_pass(&rp_desc);
184184
encoder.end_render_pass();
185185
let cmd_buf = encoder.end_encoding().unwrap();
186-
od.queue.submit(&[&cmd_buf], None).unwrap();
186+
od.queue.submit(&[&cmd_buf], &(), None).unwrap();
187187
}
188188
}

wgpu-hal/examples/ray-traced-triangle/main.rs

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
extern crate wgpu_hal as hal;
22

33
use hal::{
4-
Adapter as _, CommandEncoder as _, Device as _, Instance as _, Queue as _, Surface as _,
4+
Adapter as _, CommandEncoder as _, Device as _, Instance as _, Queue as _, RawSet as _,
5+
Surface as _,
56
};
67
use raw_window_handle::{HasDisplayHandle, HasWindowHandle};
78

@@ -754,8 +755,13 @@ impl<A: hal::Api> Example<A> {
754755
let fence = unsafe {
755756
let mut fence = device.create_fence().unwrap();
756757
let init_cmd = cmd_encoder.end_encoding().unwrap();
758+
let surface_textures = A::SubmitSurfaceTextureSet::new();
757759
queue
758-
.submit(&[&init_cmd], Some((&mut fence, init_fence_value)))
760+
.submit(
761+
&[&init_cmd],
762+
&surface_textures,
763+
Some((&mut fence, init_fence_value)),
764+
)
759765
.unwrap();
760766
device.wait(&fence, init_fence_value, !0).unwrap();
761767
cmd_encoder.reset_all(iter::once(init_cmd));
@@ -960,7 +966,11 @@ impl<A: hal::Api> Example<A> {
960966
} else {
961967
None
962968
};
963-
self.queue.submit(&[&cmd_buf], fence_param).unwrap();
969+
let mut surface_textures = A::SubmitSurfaceTextureSet::new();
970+
surface_textures.insert(&surface_tex);
971+
self.queue
972+
.submit(&[&cmd_buf], &surface_textures, fence_param)
973+
.unwrap();
964974
self.queue.present(&self.surface, surface_tex).unwrap();
965975
ctx.used_cmd_bufs.push(cmd_buf);
966976
ctx.used_views.push(surface_tex_view);
@@ -998,8 +1008,13 @@ impl<A: hal::Api> Example<A> {
9981008
unsafe {
9991009
{
10001010
let ctx = &mut self.contexts[self.context_index];
1011+
let surface_textures = A::SubmitSurfaceTextureSet::new();
10011012
self.queue
1002-
.submit(&[], Some((&mut ctx.fence, ctx.fence_value)))
1013+
.submit(
1014+
&[],
1015+
&surface_textures,
1016+
Some((&mut ctx.fence, ctx.fence_value)),
1017+
)
10031018
.unwrap();
10041019
}
10051020

wgpu-hal/src/dx12/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@ impl crate::Api for Api {
8484
type ComputePipeline = ComputePipeline;
8585

8686
type AccelerationStructure = AccelerationStructure;
87+
type SubmitSurfaceTextureSet = ();
8788
}
8889

8990
// Limited by D3D12's root signature size of 64. Each element takes 1 or 2 entries.
@@ -877,6 +878,7 @@ impl crate::Queue<Api> for Queue {
877878
unsafe fn submit(
878879
&self,
879880
command_buffers: &[&CommandBuffer],
881+
_surface_textures: &(),
880882
signal_fence: Option<(&mut Fence, crate::FenceValue)>,
881883
) -> Result<(), crate::DeviceError> {
882884
let mut temp_lists = self.temp_lists.lock();

wgpu-hal/src/empty.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ impl crate::Api for Api {
3737
type ShaderModule = Resource;
3838
type RenderPipeline = Resource;
3939
type ComputePipeline = Resource;
40+
type SubmitSurfaceTextureSet = ();
4041
}
4142

4243
impl crate::Instance<Api> for Context {
@@ -104,6 +105,7 @@ impl crate::Queue<Api> for Context {
104105
unsafe fn submit(
105106
&self,
106107
command_buffers: &[&Resource],
108+
surface_textures: &(),
107109
signal_fence: Option<(&mut Resource, crate::FenceValue)>,
108110
) -> DeviceResult<()> {
109111
Ok(())

wgpu-hal/src/gles/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,7 @@ impl crate::Api for Api {
161161
type ShaderModule = ShaderModule;
162162
type RenderPipeline = RenderPipeline;
163163
type ComputePipeline = ComputePipeline;
164+
type SubmitSurfaceTextureSet = ();
164165
}
165166

166167
bitflags::bitflags! {

wgpu-hal/src/gles/queue.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1748,6 +1748,7 @@ impl crate::Queue<super::Api> for super::Queue {
17481748
unsafe fn submit(
17491749
&self,
17501750
command_buffers: &[&super::CommandBuffer],
1751+
_surface_textures: &(),
17511752
signal_fence: Option<(&mut super::Fence, crate::FenceValue)>,
17521753
) -> Result<(), crate::DeviceError> {
17531754
let shared = Arc::clone(&self.shared);

wgpu-hal/src/lib.rs

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -214,6 +214,7 @@ pub trait Api: Clone + fmt::Debug + Sized {
214214
type ComputePipeline: fmt::Debug + WasmNotSendSync;
215215

216216
type AccelerationStructure: fmt::Debug + WasmNotSendSync + 'static;
217+
type SubmitSurfaceTextureSet: RawSet<Self::SurfaceTexture>;
217218
}
218219

219220
pub trait Instance<A: Api>: Sized + WasmNotSendSync {
@@ -413,9 +414,12 @@ pub trait Queue<A: Api>: WasmNotSendSync {
413414
/// - all of the command buffers were created from command pools
414415
/// that are associated with this queue.
415416
/// - all of the command buffers had `CommadBuffer::finish()` called.
417+
/// - all surface textures that the command buffers write to must be
418+
/// passed to the surface_textures argument.
416419
unsafe fn submit(
417420
&self,
418421
command_buffers: &[&A::CommandBuffer],
422+
surface_textures: &A::SubmitSurfaceTextureSet,
419423
signal_fence: Option<(&mut A::Fence, FenceValue)>,
420424
) -> Result<(), DeviceError>;
421425
unsafe fn present(
@@ -718,6 +722,25 @@ bitflags!(
718722
}
719723
);
720724

725+
pub trait RawSet<T> {
726+
/// Construct a new set unsafely.
727+
fn new() -> Self;
728+
729+
/// Insert a value into the raw set.
730+
///
731+
/// The caller is responsible for ensuring that the set doesn't outlive the
732+
/// values it contains. The exact requirements depends on which set is being
733+
/// constructed.
734+
unsafe fn insert(&mut self, value: &T);
735+
}
736+
737+
/// Provide a default implementation for () for backends which do not need to
738+
/// track any raw resources so they can easily be stubbed out.
739+
impl<T> RawSet<T> for () {
740+
fn new() -> Self {}
741+
unsafe fn insert(&mut self, _: &T) {}
742+
}
743+
721744
bitflags!(
722745
/// Texture format capability flags.
723746
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]

wgpu-hal/src/metal/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ impl crate::Api for Api {
6868
type ComputePipeline = ComputePipeline;
6969

7070
type AccelerationStructure = AccelerationStructure;
71+
type SubmitSurfaceTextureSet = ();
7172
}
7273

7374
pub struct Instance {
@@ -368,6 +369,7 @@ impl crate::Queue<Api> for Queue {
368369
unsafe fn submit(
369370
&self,
370371
command_buffers: &[&CommandBuffer],
372+
_surface_textures: &(),
371373
signal_fence: Option<(&mut Fence, crate::FenceValue)>,
372374
) -> Result<(), crate::DeviceError> {
373375
objc::rc::autoreleasepool(|| {

0 commit comments

Comments
 (0)