Skip to content

Commit 671484e

Browse files
committed
bevy_render changes
1 parent 094aeb9 commit 671484e

File tree

1 file changed

+38
-36
lines changed
  • crates/bevy_render/src/view/window

1 file changed

+38
-36
lines changed

crates/bevy_render/src/view/window/mod.rs

Lines changed: 38 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,6 @@ use screenshot::{
2121

2222
use super::Msaa;
2323

24-
/// Token to ensure a system runs on the main thread.
25-
#[derive(Resource, Default)]
26-
pub struct NonSendMarker;
27-
2824
pub struct WindowRenderPlugin;
2925

3026
impl Plugin for WindowRenderPlugin {
@@ -188,30 +184,28 @@ pub struct WindowSurfaces {
188184

189185
/// Creates and (re)configures window surfaces, and obtains a swapchain texture for rendering.
190186
///
191-
/// NOTE: `get_current_texture` in `prepare_windows` can take a long time if the GPU workload is
192-
/// the performance bottleneck. This can be seen in profiles as multiple prepare-set systems all
193-
/// taking an unusually long time to complete, and all finishing at about the same time as the
194-
/// `prepare_windows` system. Improvements in bevy are planned to avoid this happening when it
195-
/// should not but it will still happen as it is easy for a user to create a large GPU workload
196-
/// relative to the GPU performance and/or CPU workload.
197-
/// This can be caused by many reasons, but several of them are:
198-
/// - GPU workload is more than your current GPU can manage
199-
/// - Error / performance bug in your custom shaders
200-
/// - wgpu was unable to detect a proper GPU hardware-accelerated device given the chosen
187+
/// **NOTE:** `get_current_texture` (acquiring the next framebuffer) in `prepare_windows` can take
188+
/// a long time if the GPU workload is heavy. This can be seen in profiling views with many prepare
189+
/// systems taking an unusually long time to complete, but all finishing at around the same time
190+
/// `prepare_windows` does. Performance improvements are planned to reduce how often this happens,
191+
/// but it will still be possible, since it's easy to create a heavy GPU workload.
192+
///
193+
/// These are some contributing factors:
194+
/// - The GPU workload is more than your GPU can handle.
195+
/// - There are custom shaders with an error / performance bug.
196+
/// - wgpu could not detect a proper GPU hardware-accelerated device given the chosen
201197
/// [`Backends`](crate::settings::Backends), [`WgpuLimits`](crate::settings::WgpuLimits),
202-
/// and/or [`WgpuFeatures`](crate::settings::WgpuFeatures). For example, on Windows currently
203-
/// `DirectX 11` is not supported by wgpu 0.12 and so if your GPU/drivers do not support Vulkan,
204-
/// it may be that a software renderer called "Microsoft Basic Render Driver" using `DirectX 12`
205-
/// will be chosen and performance will be very poor. This is visible in a log message that is
206-
/// output during renderer initialization. Future versions of wgpu will support `DirectX 11`, but
207-
/// another alternative is to try to use [`ANGLE`](https://github.com/gfx-rs/wgpu#angle) and
208-
/// [`Backends::GL`](crate::settings::Backends::GL) if your GPU/drivers support `OpenGL 4.3` / `OpenGL ES 3.0` or
209-
/// later.
198+
/// and/or [`WgpuFeatures`](crate::settings::WgpuFeatures).
199+
/// - On Windows, DirectX 11 is not supported by wgpu 0.12, and if your GPU/drivers do not
200+
/// support Vulkan, a software renderer called "Microsoft Basic Render Driver" using DirectX 12
201+
/// may be used and performance will be very poor. This will be logged as a message when the
202+
/// renderer is initialized. Future versions of wgpu will support DirectX 11, but an
203+
/// alternative is to try to use [`ANGLE`](https://github.com/gfx-rs/wgpu#angle) and
204+
/// [`Backends::GL`](crate::settings::Backends::GL) if your GPU/drivers support OpenGL 4.3,
205+
/// OpenGL ES 3.0, or later.
210206
#[allow(clippy::too_many_arguments)]
211207
pub fn prepare_windows(
212-
// By accessing a NonSend resource, we tell the scheduler to put this system on the main thread,
213-
// which is necessary for some OS s
214-
_marker: Option<NonSend<NonSendMarker>>,
208+
mut main_thread: ThreadLocal,
215209
mut windows: ResMut<ExtractedWindows>,
216210
mut window_surfaces: ResMut<WindowSurfaces>,
217211
render_device: Res<RenderDevice>,
@@ -227,20 +221,28 @@ pub fn prepare_windows(
227221
let surface_data = window_surfaces
228222
.surfaces
229223
.entry(window.entity)
230-
.or_insert_with(|| unsafe {
231-
// NOTE: On some OSes this MUST be called from the main thread.
232-
// As of wgpu 0.15, only failable if the given window is a HTML canvas and obtaining a WebGPU or WebGL2 context fails.
233-
let surface = render_instance
234-
.create_surface(&window.handle.get_handle())
235-
.expect("Failed to create wgpu surface");
224+
.or_insert_with(|| {
225+
let surface = main_thread.run(|_| {
226+
// SAFETY: raw window handle is valid
227+
unsafe {
228+
render_instance
229+
// Some operating systems only allow dereferencing window handles in
230+
// the *main* thread (and may panic if done in another thread).
231+
.create_surface(&window.handle.get_handle())
232+
// As of wgpu 0.15, this can only fail if the window is a HTML canvas
233+
// and obtaining a WebGPU/WebGL2 context fails.
234+
.expect("failed to create wgpu surface")
235+
}
236+
});
236237
let caps = surface.get_capabilities(&render_adapter);
237238
let formats = caps.formats;
238-
// For future HDR output support, we'll need to request a format that supports HDR,
239-
// but as of wgpu 0.15 that is not yet supported.
240-
// Prefer sRGB formats for surfaces, but fall back to first available format if no sRGB formats are available.
241-
let mut format = *formats.get(0).expect("No supported formats for surface");
239+
// Prefer sRGB formats, but fall back to first available format if none available.
240+
// NOTE: To support HDR output in the future, we'll need to request a format that
241+
// supports HDR, but as of wgpu 0.15 that is still unsupported.
242+
let mut format = *formats.get(0).expect("no supported formats for surface");
242243
for available_format in formats {
243-
// Rgba8UnormSrgb and Bgra8UnormSrgb and the only sRGB formats wgpu exposes that we can use for surfaces.
244+
// Rgba8UnormSrgb and Bgra8UnormSrgb and the only sRGB formats wgpu exposes
245+
// that we can use for surfaces.
244246
if available_format == TextureFormat::Rgba8UnormSrgb
245247
|| available_format == TextureFormat::Bgra8UnormSrgb
246248
{

0 commit comments

Comments
 (0)