Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
[patch.crates-io]
wgpu = { git = "https://github.com/MarijnS95/wgpu/", rev = "23201c402" }
wgpu-types = { git = "https://github.com/MarijnS95/wgpu/", rev = "23201c402" }
naga = { git = "https://github.com/MarijnS95/wgpu/", rev = "23201c402" }

[package]
name = "bevy"
version = "0.17.0-dev"
Expand Down
102 changes: 66 additions & 36 deletions crates/bevy_render/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,13 @@ mod extract_impls;
///
/// This includes the most common types in this crate, re-exported for your convenience.
pub mod prelude {
// TODO: Remove this in a follow-up
#[doc(hidden)]
pub use bevy_camera::{
Camera, ClearColor, ClearColorConfig, OrthographicProjection, PerspectiveProjection,
Projection,
};

#[doc(hidden)]
pub use crate::{
alpha::AlphaMode,
Expand All @@ -71,34 +78,17 @@ pub mod prelude {
view::{InheritedVisibility, Msaa, ViewVisibility, Visibility},
ExtractSchedule,
};
// TODO: Remove this in a follow-up
#[doc(hidden)]
pub use bevy_camera::{
Camera, ClearColor, ClearColorConfig, OrthographicProjection, PerspectiveProjection,
Projection,
};
}

#[doc(hidden)]
pub mod _macro {
pub use bevy_asset;
}

pub use extract_param::Extract;

use crate::{
camera::CameraPlugin,
gpu_readback::GpuReadbackPlugin,
mesh::{MeshPlugin, MorphPlugin, RenderMesh},
render_asset::prepare_assets,
render_resource::{init_empty_bind_group_layout, PipelineCache, Shader, ShaderLoader},
renderer::{render_system, RenderInstance},
settings::RenderCreation,
storage::StoragePlugin,
view::{ViewPlugin, WindowRenderPlugin},
};
use alloc::sync::Arc;
use batching::gpu_preprocessing::BatchingPlugin;
use core::ops::{Deref, DerefMut};
use std::sync::Mutex;

use bevy_app::{App, AppLabel, Plugin, SubApp};
use bevy_asset::{AssetApp, AssetServer};
use bevy_ecs::{
Expand All @@ -107,21 +97,33 @@ use bevy_ecs::{
};
use bevy_image::{CompressedImageFormatSupport, CompressedImageFormats};
use bevy_utils::prelude::default;
use bevy_window::{PrimaryWindow, RawHandleWrapperHolder};
use bitflags::bitflags;
use core::ops::{Deref, DerefMut};
use experimental::occlusion_culling::OcclusionCullingPlugin;
use globals::GlobalsPlugin;
use render_asset::{
extract_render_asset_bytes_per_frame, reset_render_asset_bytes_per_frame,
RenderAssetBytesPerFrame, RenderAssetBytesPerFrameLimiter,
use bevy_window::{
PrimaryWindow, RawDisplayHandleWrapper, RawWindowHandleWrapperHolder,
ThreadLockedRawWindowHandleWrapper,
};
use renderer::{RenderAdapter, RenderDevice, RenderQueue};
use settings::RenderResources;
use std::sync::Mutex;
use sync_world::{despawn_temporary_render_entities, entity_sync_system, SyncWorldPlugin};
use bitflags::bitflags;
use tracing::debug;
pub use wgpu_wrapper::WgpuWrapper;
use wgpu::rwh::{DisplayHandle, HandleError, HasDisplayHandle, HasWindowHandle, WindowHandle};

use crate::{
batching::gpu_preprocessing::BatchingPlugin,
camera::CameraPlugin,
experimental::occlusion_culling::OcclusionCullingPlugin,
globals::GlobalsPlugin,
gpu_readback::GpuReadbackPlugin,
mesh::{MeshPlugin, MorphPlugin, RenderMesh},
render_asset::{
extract_render_asset_bytes_per_frame, prepare_assets, reset_render_asset_bytes_per_frame,
RenderAssetBytesPerFrame, RenderAssetBytesPerFrameLimiter,
},
render_resource::{init_empty_bind_group_layout, PipelineCache, Shader, ShaderLoader},
renderer::{render_system, RenderAdapter, RenderDevice, RenderInstance, RenderQueue},
settings::{RenderCreation, RenderResources},
storage::StoragePlugin,
sync_world::{despawn_temporary_render_entities, entity_sync_system, SyncWorldPlugin},
view::{ViewPlugin, WindowRenderPlugin},
};
pub use crate::{extract_param::Extract, wgpu_wrapper::WgpuWrapper};

/// Inline shader as an `embedded_asset` and load it permanently.
///
Expand Down Expand Up @@ -347,9 +349,10 @@ impl Plugin for RenderPlugin {
future_render_resources_wrapper.clone(),
));

let display = app.world().resource::<RawDisplayHandleWrapper>().clone();
let primary_window = app
.world_mut()
.query_filtered::<&RawHandleWrapperHolder, With<PrimaryWindow>>()
.query_filtered::<&RawWindowHandleWrapperHolder, With<PrimaryWindow>>()
.single(app.world())
.ok()
.cloned();
Expand All @@ -369,18 +372,45 @@ impl Plugin for RenderPlugin {
},
noop: wgpu::NoopBackendOptions { enable: false },
},
display: Some(display.display_handle().unwrap().as_raw()),
});

let surface = primary_window.and_then(|wrapper| {
let maybe_handle = wrapper.0.lock().expect(
"Couldn't get the window handle in time for renderer initialization",
"too long string breaks rustfmt", // "Couldn't get the window handle in time for renderer initialization",
);
if let Some(wrapper) = maybe_handle.as_ref() {
// SAFETY: Plugins should be set up on the main thread.
let handle = unsafe { wrapper.get_handle() };

/// WGPU shouldn't force a single type to implement both traits.
struct BadWgpuApiWrapper {
display: RawDisplayHandleWrapper,
window: ThreadLockedRawWindowHandleWrapper,
}
impl HasDisplayHandle for BadWgpuApiWrapper {
fn display_handle(
&self,
) -> Result<DisplayHandle<'_>, HandleError>
{
self.display.display_handle()
}
}
impl HasWindowHandle for BadWgpuApiWrapper {
fn window_handle(
&self,
) -> Result<WindowHandle<'_>, HandleError>
{
self.window.window_handle()
}
}

Some(
instance
.create_surface(handle)
.create_surface(BadWgpuApiWrapper {
display,
window: handle,
})
.expect("Failed to create wgpu surface"),
)
} else {
Expand Down
23 changes: 18 additions & 5 deletions crates/bevy_render/src/view/window/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ use bevy_ecs::{entity::EntityHashMap, prelude::*};
use bevy_platform::collections::HashSet;
use bevy_utils::default;
use bevy_window::{
CompositeAlphaMode, PresentMode, PrimaryWindow, RawHandleWrapper, Window, WindowClosing,
CompositeAlphaMode, PresentMode, PrimaryWindow, RawDisplayHandleWrapper,
RawWindowHandleWrapper, Window, WindowClosing,
};
use core::{
num::NonZero,
Expand All @@ -30,10 +31,14 @@ impl Plugin for WindowRenderPlugin {
fn build(&self, app: &mut App) {
app.add_plugins(ScreenshotPlugin);

let display = app.world().resource::<RawDisplayHandleWrapper>().clone();

if let Some(render_app) = app.get_sub_app_mut(RenderApp) {
render_app
.init_resource::<ExtractedWindows>()
.init_resource::<WindowSurfaces>()
// Forward it to the sub-app?
.insert_resource(display)
.add_systems(ExtractSchedule, extract_windows)
.add_systems(
Render,
Expand All @@ -49,7 +54,7 @@ impl Plugin for WindowRenderPlugin {
pub struct ExtractedWindow {
/// An entity that contains the components in [`Window`].
pub entity: Entity,
pub handle: RawHandleWrapper,
pub handle: RawWindowHandleWrapper,
pub physical_width: u32,
pub physical_height: u32,
pub present_mode: PresentMode,
Expand Down Expand Up @@ -101,8 +106,15 @@ impl DerefMut for ExtractedWindows {
fn extract_windows(
mut extracted_windows: ResMut<ExtractedWindows>,
mut closing: Extract<EventReader<WindowClosing>>,
windows: Extract<Query<(Entity, &Window, &RawHandleWrapper, Option<&PrimaryWindow>)>>,
mut removed: Extract<RemovedComponents<RawHandleWrapper>>,
windows: Extract<
Query<(
Entity,
&Window,
&RawWindowHandleWrapper,
Option<&PrimaryWindow>,
)>,
>,
mut removed: Extract<RemovedComponents<RawWindowHandleWrapper>>,
mut window_surfaces: ResMut<WindowSurfaces>,
) {
for (entity, window, handle, primary) in windows.iter() {
Expand Down Expand Up @@ -300,6 +312,7 @@ pub fn create_surfaces(
// By accessing a NonSend resource, we tell the scheduler to put this system on the main thread,
// which is necessary for some OS's
#[cfg(any(target_os = "macos", target_os = "ios"))] _marker: bevy_ecs::system::NonSendMarker,
display: Res<RawDisplayHandleWrapper>,
windows: Res<ExtractedWindows>,
mut window_surfaces: ResMut<WindowSurfaces>,
render_instance: Res<RenderInstance>,
Expand All @@ -312,7 +325,7 @@ pub fn create_surfaces(
.entry(window.entity)
.or_insert_with(|| {
let surface_target = SurfaceTargetUnsafe::RawHandle {
raw_display_handle: window.handle.get_display_handle(),
raw_display_handle: display.get_display_handle(),
raw_window_handle: window.handle.get_window_handle(),
};
// SAFETY: The window handles in ExtractedWindows will always be valid objects to create surfaces on
Expand Down
2 changes: 1 addition & 1 deletion crates/bevy_window/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ impl Plugin for WindowPlugin {
let mut entity_commands = app.world_mut().spawn(primary_window.clone());
entity_commands.insert((
PrimaryWindow,
RawHandleWrapperHolder(Arc::new(Mutex::new(None))),
RawWindowHandleWrapperHolder(Arc::new(Mutex::new(None))),
));
if let Some(primary_cursor_options) = &self.primary_cursor_options {
entity_commands.insert(primary_cursor_options.clone());
Expand Down
Loading
Loading