Skip to content

Commit

Permalink
get proper texture format after the renderer is initialized, fix #3897
Browse files Browse the repository at this point in the history
There is no Srgb support on some GPU and display protocols (for example, Nvidia's GPUs with Wayland). Thus `TextureFormat::bevy_default()` which return `Rgba8UnormSrgb` or `Bgra8UnormSrgb` will cause panics on such platforms. This patch will resolve this problem.

Make `initialize_renderer` expose `wgpu::Adapter` and use `wgpu::Adapter` to get proper `TextureFormat`.
  • Loading branch information
VitalyAnkh committed Jul 21, 2022
1 parent 1c23421 commit 44b9ac1
Show file tree
Hide file tree
Showing 3 changed files with 15 additions and 7 deletions.
5 changes: 4 additions & 1 deletion crates/bevy_render/src/lib.rs
Expand Up @@ -148,14 +148,16 @@ impl Plugin for RenderPlugin {
compatible_surface: surface.as_ref(),
..Default::default()
};
let (device, queue, adapter_info) = futures_lite::future::block_on(
let (device, queue, adapter_info, render_adapter) = futures_lite::future::block_on(
renderer::initialize_renderer(&instance, &options, &request_adapter_options),
);
debug!("Configured wgpu adapter Limits: {:#?}", device.limits());
debug!("Configured wgpu adapter Features: {:#?}", device.features());
debug!("Now the RenderPlugin runs VitalyR");
app.insert_resource(device.clone())
.insert_resource(queue.clone())
.insert_resource(adapter_info.clone())
.insert_resource(render_adapter.clone())
.init_resource::<ScratchMainWorld>()
.register_type::<Frustum>()
.register_type::<CubemapFrusta>();
Expand Down Expand Up @@ -197,6 +199,7 @@ impl Plugin for RenderPlugin {
.insert_resource(instance)
.insert_resource(device)
.insert_resource(queue)
.insert_resource(render_adapter)
.insert_resource(adapter_info)
.insert_resource(pipeline_cache)
.insert_resource(asset_server)
Expand Down
11 changes: 8 additions & 3 deletions crates/bevy_render/src/renderer/mod.rs
Expand Up @@ -14,7 +14,7 @@ use bevy_ecs::prelude::*;
use bevy_time::TimeSender;
use bevy_utils::Instant;
use std::sync::Arc;
use wgpu::{AdapterInfo, CommandEncoder, Instance, Queue, RequestAdapterOptions};
use wgpu::{Adapter, AdapterInfo, CommandEncoder, Instance, Queue, RequestAdapterOptions};

/// Updates the [`RenderGraph`] with all of its nodes and then runs it to render the entire frame.
pub fn render_system(world: &mut World) {
Expand Down Expand Up @@ -86,6 +86,9 @@ pub fn render_system(world: &mut World) {
/// This queue is used to enqueue tasks for the GPU to execute asynchronously.
pub type RenderQueue = Arc<Queue>;

/// This is the adapter that the GPU is using to render.
pub type RenderAdapter = Arc<Adapter>;

/// The GPU instance is used to initialize the [`RenderQueue`] and [`RenderDevice`],
/// aswell as to create [`WindowSurfaces`](crate::view::window::WindowSurfaces).
pub type RenderInstance = Instance;
Expand All @@ -96,7 +99,7 @@ pub async fn initialize_renderer(
instance: &Instance,
options: &WgpuSettings,
request_adapter_options: &RequestAdapterOptions<'_>,
) -> (RenderDevice, RenderQueue, AdapterInfo) {
) -> (RenderDevice, RenderQueue, AdapterInfo, RenderAdapter) {
let adapter = instance
.request_adapter(request_adapter_options)
.await
Expand Down Expand Up @@ -243,9 +246,11 @@ pub async fn initialize_renderer(
)
.await
.unwrap();

let device = Arc::new(device);
let queue = Arc::new(queue);
(RenderDevice::from(device), queue, adapter_info)
let adapter = Arc::new(adapter);
(RenderDevice::from(device), queue, adapter_info, adapter)
}

/// The context with all information required to interact with the GPU.
Expand Down
6 changes: 3 additions & 3 deletions crates/bevy_render/src/view/window.rs
@@ -1,6 +1,6 @@
use crate::{
render_resource::TextureView,
renderer::{RenderDevice, RenderInstance},
renderer::{RenderAdapter, RenderDevice, RenderInstance},
texture::BevyDefault,
Extract, RenderApp, RenderStage,
};
Expand Down Expand Up @@ -149,6 +149,7 @@ pub fn prepare_windows(
mut window_surfaces: ResMut<WindowSurfaces>,
render_device: Res<RenderDevice>,
render_instance: Res<RenderInstance>,
render_adapter: Res<RenderAdapter>,
) {
let window_surfaces = window_surfaces.deref_mut();
for window in windows.windows.values_mut() {
Expand All @@ -161,7 +162,7 @@ pub fn prepare_windows(
});

let swap_chain_descriptor = wgpu::SurfaceConfiguration {
format: TextureFormat::bevy_default(),
format: surface.get_supported_formats(&render_adapter)[0],
width: window.physical_width,
height: window.physical_height,
usage: wgpu::TextureUsages::RENDER_ATTACHMENT,
Expand All @@ -173,7 +174,6 @@ pub fn prepare_windows(
PresentMode::AutoNoVsync => wgpu::PresentMode::AutoNoVsync,
},
};

// Do the initial surface configuration if it hasn't been configured yet
if window_surfaces.configured_windows.insert(window.id) || window.size_changed {
render_device.configure_surface(surface, &swap_chain_descriptor);
Expand Down

0 comments on commit 44b9ac1

Please sign in to comment.