@@ -76,7 +76,7 @@ use bevy_ecs::schedule::ScheduleBuildSettings;
76
76
use bevy_utils:: prelude:: default;
77
77
pub use extract_param:: Extract ;
78
78
79
- use bevy_window:: { PrimaryWindow , RawHandleWrapperHolder } ;
79
+ use bevy_window:: PrimaryWindow ;
80
80
use experimental:: occlusion_culling:: OcclusionCullingPlugin ;
81
81
use globals:: GlobalsPlugin ;
82
82
use render_asset:: {
@@ -88,6 +88,7 @@ use settings::RenderResources;
88
88
use sync_world:: {
89
89
despawn_temporary_render_entities, entity_sync_system, SyncToRenderWorld , SyncWorldPlugin ,
90
90
} ;
91
+ use view:: surface_target:: SurfaceTargetSource ;
91
92
92
93
use crate :: gpu_readback:: GpuReadbackPlugin ;
93
94
use crate :: {
@@ -107,7 +108,7 @@ use bevy_ecs::{prelude::*, schedule::ScheduleLabel};
107
108
use bitflags:: bitflags;
108
109
use core:: ops:: { Deref , DerefMut } ;
109
110
use std:: sync:: Mutex ;
110
- use tracing:: debug;
111
+ use tracing:: { debug, warn } ;
111
112
112
113
/// Contains the default Bevy rendering backend based on wgpu.
113
114
///
@@ -314,12 +315,17 @@ impl Plugin for RenderPlugin {
314
315
future_render_resources_wrapper. clone ( ) ,
315
316
) ) ;
316
317
317
- let primary_window = app
318
+ let primary_window_surface_target_source = app
318
319
. world_mut ( )
319
- . query_filtered :: < & RawHandleWrapperHolder , With < PrimaryWindow > > ( )
320
+ . query_filtered :: < & SurfaceTargetSource , With < PrimaryWindow > > ( )
320
321
. single ( app. world ( ) )
321
322
. ok ( )
322
323
. cloned ( ) ;
324
+
325
+ if primary_window_surface_target_source. is_none ( ) {
326
+ warn ! ( "No PrimaryWindow found with a SurfaceTargetSource to use for render initialization" ) ;
327
+ }
328
+
323
329
let settings = render_creation. clone ( ) ;
324
330
let async_renderer = async move {
325
331
let instance = wgpu:: Instance :: new ( & wgpu:: InstanceDescriptor {
@@ -335,26 +341,30 @@ impl Plugin for RenderPlugin {
335
341
} ,
336
342
} ) ;
337
343
338
- let surface = primary_window. and_then ( |wrapper| {
339
- let maybe_handle = wrapper. 0 . lock ( ) . expect (
340
- "Couldn't get the window handle in time for renderer initialization" ,
341
- ) ;
342
- if let Some ( wrapper) = maybe_handle. as_ref ( ) {
343
- // SAFETY: Plugins should be set up on the main thread.
344
- let handle = unsafe { wrapper. get_handle ( ) } ;
345
- Some (
346
- instance
347
- . create_surface ( handle)
348
- . expect ( "Failed to create wgpu surface" ) ,
349
- )
350
- } else {
351
- None
352
- }
353
- } ) ;
344
+ let is_main_thread = true ; // Plugins are set up on the main thread.
345
+ let compatible_surface = primary_window_surface_target_source
346
+ . and_then ( |source| {
347
+ match source. create_surface ( & instance, is_main_thread) {
348
+ Ok ( surface) => Some ( surface) ,
349
+ Err ( err) => {
350
+ warn ! (
351
+ "Unable to create surface for adapter init: {:?}" ,
352
+ err
353
+ ) ;
354
+ None
355
+ }
356
+ }
357
+ } )
358
+ . map ( |render_surface| {
359
+ // SAFETY:
360
+ // - This surface is just used for compatibility checks when creating the adapter. It's not configured.
361
+ // - The surface is dropped at the end of this function; guaranteeing it does not outlive the window.
362
+ unsafe { render_surface. into_inner ( ) }
363
+ } ) ;
354
364
355
365
let request_adapter_options = wgpu:: RequestAdapterOptions {
356
366
power_preference : settings. power_preference ,
357
- compatible_surface : surface . as_ref ( ) ,
367
+ compatible_surface : compatible_surface . as_ref ( ) ,
358
368
..Default :: default ( )
359
369
} ;
360
370
0 commit comments