@@ -43,7 +43,8 @@ impl Plugin for WindowRenderPlugin {
43
43
. init_resource :: < ExtractedWindows > ( )
44
44
. init_resource :: < WindowSurfaces > ( )
45
45
. add_systems ( ExtractSchedule , extract_windows)
46
- . add_systems ( Render , prepare_windows. in_set ( RenderSet :: ManageViews ) ) ;
46
+ . add_systems ( Render , prepare_windows. in_set ( RenderSet :: PrepareAssets ) )
47
+ . add_systems ( Render , create_surfaces. in_set ( RenderSet :: ManageViews ) ) ;
47
48
}
48
49
}
49
50
@@ -213,7 +214,7 @@ impl WindowSurfaces {
213
214
}
214
215
}
215
216
216
- /// Creates and (re)configures window surfaces, and obtains a swapchain texture for rendering.
217
+ /// (re)configures window surfaces, and obtains a swapchain texture for rendering.
217
218
///
218
219
/// NOTE: `get_current_texture` in `prepare_windows` can take a long time if the GPU workload is
219
220
/// the performance bottleneck. This can be seen in profiles as multiple prepare-set systems all
@@ -236,55 +237,21 @@ impl WindowSurfaces {
236
237
/// later.
237
238
#[ allow( clippy:: too_many_arguments) ]
238
239
pub fn prepare_windows (
239
- // By accessing a NonSend resource, we tell the scheduler to put this system on the main thread,
240
- // which is necessary for some OS's
241
- #[ cfg( any( target_os = "macos" , target_os = "ios" ) ) ] _marker : Option < NonSend < NonSendMarker > > ,
242
240
mut windows : ResMut < ExtractedWindows > ,
243
241
mut window_surfaces : ResMut < WindowSurfaces > ,
244
242
render_device : Res < RenderDevice > ,
245
- render_instance : Res < RenderInstance > ,
246
243
render_adapter : Res < RenderAdapter > ,
247
244
screenshot_pipeline : Res < ScreenshotToScreenPipeline > ,
248
245
pipeline_cache : Res < PipelineCache > ,
249
246
mut pipelines : ResMut < SpecializedRenderPipelines < ScreenshotToScreenPipeline > > ,
250
247
mut msaa : ResMut < Msaa > ,
248
+ #[ cfg( target_os = "linux" ) ] render_instance : Res < RenderInstance > ,
251
249
) {
252
250
for window in windows. windows . values_mut ( ) {
253
251
let window_surfaces = window_surfaces. deref_mut ( ) ;
254
- let surface_data = window_surfaces
255
- . surfaces
256
- . entry ( window. entity )
257
- . or_insert_with ( || {
258
- let surface_target = SurfaceTargetUnsafe :: RawHandle {
259
- raw_display_handle : window. handle . display_handle ,
260
- raw_window_handle : window. handle . window_handle ,
261
- } ;
262
- // SAFETY: The window handles in ExtractedWindows will always be valid objects to create surfaces on
263
- let surface = unsafe {
264
- // NOTE: On some OSes this MUST be called from the main thread.
265
- // As of wgpu 0.15, only fallible if the given window is a HTML canvas and obtaining a WebGPU or WebGL2 context fails.
266
- render_instance
267
- . create_surface_unsafe ( surface_target)
268
- . expect ( "Failed to create wgpu surface" )
269
- } ;
270
- let caps = surface. get_capabilities ( & render_adapter) ;
271
- let formats = caps. formats ;
272
- // For future HDR output support, we'll need to request a format that supports HDR,
273
- // but as of wgpu 0.15 that is not yet supported.
274
- // Prefer sRGB formats for surfaces, but fall back to first available format if no sRGB formats are available.
275
- let mut format = * formats. first ( ) . expect ( "No supported formats for surface" ) ;
276
- for available_format in formats {
277
- // Rgba8UnormSrgb and Bgra8UnormSrgb and the only sRGB formats wgpu exposes that we can use for surfaces.
278
- if available_format == TextureFormat :: Rgba8UnormSrgb
279
- || available_format == TextureFormat :: Bgra8UnormSrgb
280
- {
281
- format = available_format;
282
- break ;
283
- }
284
- }
285
-
286
- SurfaceData { surface, format }
287
- } ) ;
252
+ let Some ( surface_data) = window_surfaces. surfaces . get ( & window. entity ) else {
253
+ continue ;
254
+ } ;
288
255
289
256
let surface_configuration = wgpu:: SurfaceConfiguration {
290
257
format : surface_data. format ,
@@ -451,3 +418,51 @@ pub fn prepare_windows(
451
418
}
452
419
}
453
420
}
421
+
422
+ /// Creates window surfaces.
423
+ pub fn create_surfaces (
424
+ // By accessing a NonSend resource, we tell the scheduler to put this system on the main thread,
425
+ // which is necessary for some OS's
426
+ #[ cfg( any( target_os = "macos" , target_os = "ios" ) ) ] _marker : Option < NonSend < NonSendMarker > > ,
427
+ windows : Res < ExtractedWindows > ,
428
+ mut window_surfaces : ResMut < WindowSurfaces > ,
429
+ render_instance : Res < RenderInstance > ,
430
+ render_adapter : Res < RenderAdapter > ,
431
+ ) {
432
+ for window in windows. windows . values ( ) {
433
+ window_surfaces
434
+ . surfaces
435
+ . entry ( window. entity )
436
+ . or_insert_with ( || {
437
+ let surface_target = SurfaceTargetUnsafe :: RawHandle {
438
+ raw_display_handle : window. handle . display_handle ,
439
+ raw_window_handle : window. handle . window_handle ,
440
+ } ;
441
+ // SAFETY: The window handles in ExtractedWindows will always be valid objects to create surfaces on
442
+ let surface = unsafe {
443
+ // NOTE: On some OSes this MUST be called from the main thread.
444
+ // As of wgpu 0.15, only fallible if the given window is a HTML canvas and obtaining a WebGPU or WebGL2 context fails.
445
+ render_instance
446
+ . create_surface_unsafe ( surface_target)
447
+ . expect ( "Failed to create wgpu surface" )
448
+ } ;
449
+ let caps = surface. get_capabilities ( & render_adapter) ;
450
+ let formats = caps. formats ;
451
+ // For future HDR output support, we'll need to request a format that supports HDR,
452
+ // but as of wgpu 0.15 that is not yet supported.
453
+ // Prefer sRGB formats for surfaces, but fall back to first available format if no sRGB formats are available.
454
+ let mut format = * formats. first ( ) . expect ( "No supported formats for surface" ) ;
455
+ for available_format in formats {
456
+ // Rgba8UnormSrgb and Bgra8UnormSrgb and the only sRGB formats wgpu exposes that we can use for surfaces.
457
+ if available_format == TextureFormat :: Rgba8UnormSrgb
458
+ || available_format == TextureFormat :: Bgra8UnormSrgb
459
+ {
460
+ format = available_format;
461
+ break ;
462
+ }
463
+ }
464
+
465
+ SurfaceData { surface, format }
466
+ } ) ;
467
+ }
468
+ }
0 commit comments