Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Merged by Bors] - get proper texture format after the renderer is initialized, fix #3897 #5413

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
14 changes: 7 additions & 7 deletions crates/bevy_pbr/src/render/mesh.rs
Expand Up @@ -21,10 +21,8 @@ use bevy_render::{
render_asset::RenderAssets,
render_phase::{EntityRenderCommand, RenderCommandResult, TrackedRenderPass},
render_resource::*,
renderer::{RenderDevice, RenderQueue},
texture::{
BevyDefault, DefaultImageSampler, GpuImage, Image, ImageSampler, TextureFormatPixelInfo,
},
renderer::{RenderDevice, RenderQueue, RenderTextureFormat},
texture::{DefaultImageSampler, GpuImage, Image, ImageSampler, TextureFormatPixelInfo},
view::{ComputedVisibility, ViewUniform, ViewUniformOffset, ViewUniforms},
Extract, RenderApp, RenderStage,
};
Expand Down Expand Up @@ -270,8 +268,10 @@ impl FromWorld for MeshPipeline {
Res<RenderDevice>,
Res<DefaultImageSampler>,
Res<RenderQueue>,
Res<RenderTextureFormat>,
)> = SystemState::new(world);
let (render_device, default_sampler, render_queue) = system_state.get_mut(world);
let (render_device, default_sampler, render_queue, first_available_texture_format) =
system_state.get_mut(world);
let clustered_forward_buffer_binding_type = render_device
.get_supported_read_only_binding_type(CLUSTERED_FORWARD_STORAGE_BUFFER_COUNT);

Expand Down Expand Up @@ -438,7 +438,7 @@ impl FromWorld for MeshPipeline {
Extent3d::default(),
TextureDimension::D2,
&[255u8; 4],
TextureFormat::bevy_default(),
first_available_texture_format.0,
);
let texture = render_device.create_texture(&image.texture_descriptor);
let sampler = match image.sampler_descriptor {
Expand Down Expand Up @@ -629,7 +629,7 @@ impl SpecializedMeshPipeline for MeshPipeline {
shader_defs,
entry_point: "fragment".into(),
targets: vec![Some(ColorTargetState {
format: TextureFormat::bevy_default(),
format: self.dummy_white_gpu_image.texture_format,
blend,
write_mask: ColorWrites::ALL,
})],
Expand Down
20 changes: 16 additions & 4 deletions crates/bevy_render/src/lib.rs
Expand Up @@ -47,7 +47,7 @@ use crate::{
primitives::{CubemapFrusta, Frustum},
render_graph::RenderGraph,
render_resource::{PipelineCache, Shader, ShaderLoader},
renderer::{render_system, RenderInstance},
renderer::{render_system, RenderInstance, RenderTextureFormat},
texture::ImagePlugin,
view::{ViewPlugin, WindowRenderPlugin},
};
Expand Down Expand Up @@ -157,14 +157,23 @@ impl Plugin for RenderPlugin {
compatible_surface: surface.as_ref(),
..Default::default()
};
let (device, queue, adapter_info) = futures_lite::future::block_on(
renderer::initialize_renderer(&instance, &options, &request_adapter_options),
);
let (device, queue, adapter_info, render_adapter, available_texture_formats) =
futures_lite::future::block_on(renderer::initialize_renderer(
&instance,
&options,
&request_adapter_options,
));
// `available_texture_formats` won't be empty, or else will panick in the former
// `initialize_renderer` call.
let first_available_texture_format = RenderTextureFormat(available_texture_formats[0]);
debug!("Configured wgpu adapter Limits: {:#?}", device.limits());
debug!("Configured wgpu adapter Features: {:#?}", device.features());
app.insert_resource(device.clone())
.insert_resource(queue.clone())
.insert_resource(adapter_info.clone())
.insert_resource(render_adapter.clone())
.insert_resource(available_texture_formats.clone())
.insert_resource(first_available_texture_format.clone())
.init_resource::<ScratchMainWorld>()
.register_type::<Frustum>()
.register_type::<CubemapFrusta>();
Expand Down Expand Up @@ -206,6 +215,9 @@ impl Plugin for RenderPlugin {
.insert_resource(RenderInstance(instance))
.insert_resource(device)
.insert_resource(queue)
.insert_resource(render_adapter)
.insert_resource(available_texture_formats)
.insert_resource(first_available_texture_format)
.insert_resource(adapter_info)
.insert_resource(pipeline_cache)
.insert_resource(asset_server);
Expand Down
38 changes: 36 additions & 2 deletions crates/bevy_render/src/renderer/mod.rs
Expand Up @@ -15,7 +15,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 @@ -88,6 +88,11 @@ pub fn render_system(world: &mut World) {
#[derive(Resource, Clone, Deref, DerefMut)]
pub struct RenderQueue(pub Arc<Queue>);

/// The handle to the physical device being used for rendering.
/// See [`wgpu::Adapter`] for more info.
#[derive(Resource, Clone, Debug, Deref, DerefMut)]
pub struct RenderAdapter(pub Arc<Adapter>);

/// The GPU instance is used to initialize the [`RenderQueue`] and [`RenderDevice`],
/// as well as to create [`WindowSurfaces`](crate::view::window::WindowSurfaces).
#[derive(Resource, Deref, DerefMut)]
Expand All @@ -97,13 +102,29 @@ pub struct RenderInstance(pub Instance);
#[derive(Resource, Clone, Deref, DerefMut)]
pub struct RenderAdapterInfo(pub AdapterInfo);

/// The [`TextureFormat`](wgpu::TextureFormat) used for rendering.
/// Initially it's the first element in `AvailableTextureFormats`.
#[derive(Resource, Clone, Deref, DerefMut)]
pub struct RenderTextureFormat(pub wgpu::TextureFormat);

/// The available [`TextureFormat`](wgpu::TextureFormat)s on the [`RenderAdapter`].
/// Will be inserted as a `Resource` after the renderer is initialized.
#[derive(Resource, Clone, Deref, DerefMut)]
pub struct AvailableTextureFormats(pub Arc<Vec<wgpu::TextureFormat>>);
VitalyAnkh marked this conversation as resolved.
Show resolved Hide resolved

/// Initializes the renderer by retrieving and preparing the GPU instance, device and queue
/// for the specified backend.
pub async fn initialize_renderer(
instance: &Instance,
options: &WgpuSettings,
request_adapter_options: &RequestAdapterOptions<'_>,
) -> (RenderDevice, RenderQueue, RenderAdapterInfo) {
) -> (
VitalyAnkh marked this conversation as resolved.
Show resolved Hide resolved
RenderDevice,
RenderQueue,
RenderAdapterInfo,
RenderAdapter,
AvailableTextureFormats,
) {
let adapter = instance
.request_adapter(request_adapter_options)
.await
Expand Down Expand Up @@ -250,12 +271,25 @@ pub async fn initialize_renderer(
)
.await
.unwrap();

let device = Arc::new(device);
let queue = Arc::new(queue);
let adapter = Arc::new(adapter);
let mut available_texture_formats = Vec::new();
if let Some(s) = request_adapter_options.compatible_surface {
available_texture_formats = s.get_supported_formats(&adapter);
if available_texture_formats.is_empty() {
info!("{:?}", adapter_info);
panic!("No supported texture formats found!");
}
};
let available_texture_formats = Arc::new(available_texture_formats);
(
RenderDevice::from(device),
RenderQueue(queue),
RenderAdapterInfo(adapter_info),
RenderAdapter(adapter),
AvailableTextureFormats(available_texture_formats),
)
}

Expand Down
9 changes: 5 additions & 4 deletions crates/bevy_render/src/view/mod.rs
Expand Up @@ -4,7 +4,7 @@ pub mod window;
pub use visibility::*;
use wgpu::{
Color, Extent3d, Operations, RenderPassColorAttachment, TextureDescriptor, TextureDimension,
TextureFormat, TextureUsages,
TextureUsages,
};
pub use window::*;

Expand All @@ -15,8 +15,8 @@ use crate::{
rangefinder::ViewRangefinder3d,
render_asset::RenderAssets,
render_resource::{DynamicUniformBuffer, ShaderType, Texture, TextureView},
renderer::{RenderDevice, RenderQueue},
texture::{BevyDefault, TextureCache},
renderer::{RenderDevice, RenderQueue, RenderTextureFormat},
texture::TextureCache,
RenderApp, RenderStage,
};
use bevy_app::{App, Plugin};
Expand Down Expand Up @@ -182,6 +182,7 @@ fn prepare_view_targets(
images: Res<RenderAssets<Image>>,
msaa: Res<Msaa>,
render_device: Res<RenderDevice>,
texture_format: Res<RenderTextureFormat>,
mut texture_cache: ResMut<TextureCache>,
cameras: Query<(Entity, &ExtractedCamera)>,
) {
Expand All @@ -205,7 +206,7 @@ fn prepare_view_targets(
mip_level_count: 1,
sample_count: msaa.samples,
dimension: TextureDimension::D2,
format: TextureFormat::bevy_default(),
format: **texture_format,
usage: TextureUsages::RENDER_ATTACHMENT,
},
)
Expand Down
15 changes: 11 additions & 4 deletions crates/bevy_render/src/view/window.rs
@@ -1,15 +1,13 @@
use crate::{
render_resource::TextureView,
renderer::{RenderDevice, RenderInstance},
texture::BevyDefault,
renderer::{RenderAdapter, RenderDevice, RenderInstance},
Extract, RenderApp, RenderStage,
};
use bevy_app::{App, Plugin};
use bevy_ecs::prelude::*;
use bevy_utils::{tracing::debug, HashMap, HashSet};
use bevy_window::{PresentMode, RawWindowHandleWrapper, WindowClosed, WindowId, Windows};
use std::ops::{Deref, DerefMut};
use wgpu::TextureFormat;

/// Token to ensure a system runs on the main thread.
#[derive(Resource, Default)]
Expand Down Expand Up @@ -161,6 +159,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 @@ -173,7 +172,15 @@ pub fn prepare_windows(
});

let swap_chain_descriptor = wgpu::SurfaceConfiguration {
format: TextureFormat::bevy_default(),
format: *surface
.get_supported_formats(&render_adapter)
.get(0)
.unwrap_or_else(|| {
panic!(
"No supported formats found for surface {:?} on adapter {:?}",
surface, render_adapter
)
}),
width: window.physical_width,
height: window.physical_height,
usage: wgpu::TextureUsages::RENDER_ATTACHMENT,
Expand Down
20 changes: 11 additions & 9 deletions crates/bevy_sprite/src/mesh2d/mesh.rs
Expand Up @@ -12,10 +12,8 @@ use bevy_render::{
render_asset::RenderAssets,
render_phase::{EntityRenderCommand, RenderCommandResult, TrackedRenderPass},
render_resource::*,
renderer::{RenderDevice, RenderQueue},
texture::{
BevyDefault, DefaultImageSampler, GpuImage, Image, ImageSampler, TextureFormatPixelInfo,
},
renderer::{RenderDevice, RenderQueue, RenderTextureFormat},
texture::{DefaultImageSampler, GpuImage, Image, ImageSampler, TextureFormatPixelInfo},
view::{ComputedVisibility, ExtractedView, ViewUniform, ViewUniformOffset, ViewUniforms},
Extract, RenderApp, RenderStage,
};
Expand Down Expand Up @@ -158,9 +156,13 @@ pub struct Mesh2dPipeline {

impl FromWorld for Mesh2dPipeline {
fn from_world(world: &mut World) -> Self {
let mut system_state: SystemState<(Res<RenderDevice>, Res<DefaultImageSampler>)> =
SystemState::new(world);
let (render_device, default_sampler) = system_state.get_mut(world);
let mut system_state: SystemState<(
Res<RenderDevice>,
Res<DefaultImageSampler>,
Res<RenderTextureFormat>,
)> = SystemState::new(world);
let (render_device, default_sampler, first_available_texture_format) =
system_state.get_mut(world);
let view_layout = render_device.create_bind_group_layout(&BindGroupLayoutDescriptor {
entries: &[
// View
Expand Down Expand Up @@ -197,7 +199,7 @@ impl FromWorld for Mesh2dPipeline {
Extent3d::default(),
TextureDimension::D2,
&[255u8; 4],
TextureFormat::bevy_default(),
first_available_texture_format.0,
);
let texture = render_device.create_texture(&image.texture_descriptor);
let sampler = match image.sampler_descriptor {
Expand Down Expand Up @@ -354,7 +356,7 @@ impl SpecializedMeshPipeline for Mesh2dPipeline {
shader_defs,
entry_point: "fragment".into(),
targets: vec![Some(ColorTargetState {
format: TextureFormat::bevy_default(),
format: self.dummy_white_gpu_image.texture_format,
blend: Some(BlendState::ALPHA_BLENDING),
write_mask: ColorWrites::ALL,
})],
Expand Down