# Objective There is no Srgb support on some GPU and display protocols with `winit` (for example, Nvidia's GPUs with Wayland). Thus `TextureFormat::bevy_default()` which returns `Rgba8UnormSrgb` or `Bgra8UnormSrgb` will cause panics on such platforms. This patch will resolve this problem. Fix https://github.com/bevyengine/bevy/issues/3897. ## Solution Make `initialize_renderer` expose `wgpu::Adapter` and `first_available_texture_format`, use the `first_available_texture_format` by default. ## Changelog * Fixed https://github.com/bevyengine/bevy/issues/3897.
This commit is contained in:
parent
1738527902
commit
f5322cd757
@ -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,
|
||||
};
|
||||
@ -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);
|
||||
|
||||
@ -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 {
|
||||
@ -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,
|
||||
})],
|
||||
|
@ -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},
|
||||
};
|
||||
@ -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>();
|
||||
@ -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);
|
||||
|
@ -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) {
|
||||
@ -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)]
|
||||
@ -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>>);
|
||||
|
||||
/// 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) {
|
||||
) -> (
|
||||
RenderDevice,
|
||||
RenderQueue,
|
||||
RenderAdapterInfo,
|
||||
RenderAdapter,
|
||||
AvailableTextureFormats,
|
||||
) {
|
||||
let adapter = instance
|
||||
.request_adapter(request_adapter_options)
|
||||
.await
|
||||
@ -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),
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -4,7 +4,7 @@ pub mod window;
|
||||
pub use visibility::*;
|
||||
use wgpu::{
|
||||
Color, Extent3d, Operations, RenderPassColorAttachment, TextureDescriptor, TextureDimension,
|
||||
TextureFormat, TextureUsages,
|
||||
TextureUsages,
|
||||
};
|
||||
pub use window::*;
|
||||
|
||||
@ -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};
|
||||
@ -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)>,
|
||||
) {
|
||||
@ -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,
|
||||
},
|
||||
)
|
||||
|
@ -1,7 +1,6 @@
|
||||
use crate::{
|
||||
render_resource::TextureView,
|
||||
renderer::{RenderDevice, RenderInstance},
|
||||
texture::BevyDefault,
|
||||
renderer::{RenderAdapter, RenderDevice, RenderInstance},
|
||||
Extract, RenderApp, RenderStage,
|
||||
};
|
||||
use bevy_app::{App, Plugin};
|
||||
@ -9,7 +8,6 @@ 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)]
|
||||
@ -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() {
|
||||
@ -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,
|
||||
|
@ -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,
|
||||
};
|
||||
@ -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
|
||||
@ -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 {
|
||||
@ -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,
|
||||
})],
|
||||
|
@ -8,7 +8,7 @@ use bevy_asset::{AssetEvent, Assets, Handle, HandleId};
|
||||
use bevy_core_pipeline::core_2d::Transparent2d;
|
||||
use bevy_ecs::{
|
||||
prelude::*,
|
||||
system::{lifetimeless::*, SystemParamItem},
|
||||
system::{lifetimeless::*, SystemParamItem, SystemState},
|
||||
};
|
||||
use bevy_math::{Rect, Vec2};
|
||||
use bevy_reflect::Uuid;
|
||||
@ -20,8 +20,8 @@ use bevy_render::{
|
||||
RenderPhase, SetItemPipeline, TrackedRenderPass,
|
||||
},
|
||||
render_resource::*,
|
||||
renderer::{RenderDevice, RenderQueue},
|
||||
texture::{BevyDefault, Image},
|
||||
renderer::{RenderDevice, RenderQueue, RenderTextureFormat},
|
||||
texture::{DefaultImageSampler, GpuImage, Image, ImageSampler, TextureFormatPixelInfo},
|
||||
view::{
|
||||
ComputedVisibility, Msaa, ViewUniform, ViewUniformOffset, ViewUniforms, VisibleEntities,
|
||||
},
|
||||
@ -37,11 +37,19 @@ use fixedbitset::FixedBitSet;
|
||||
pub struct SpritePipeline {
|
||||
view_layout: BindGroupLayout,
|
||||
material_layout: BindGroupLayout,
|
||||
pub dummy_white_gpu_image: GpuImage,
|
||||
}
|
||||
|
||||
impl FromWorld for SpritePipeline {
|
||||
fn from_world(world: &mut World) -> Self {
|
||||
let render_device = world.resource::<RenderDevice>();
|
||||
let mut system_state: SystemState<(
|
||||
Res<RenderDevice>,
|
||||
Res<DefaultImageSampler>,
|
||||
Res<RenderQueue>,
|
||||
Res<RenderTextureFormat>,
|
||||
)> = SystemState::new(world);
|
||||
let (render_device, default_sampler, render_queue, first_available_texture_format) =
|
||||
system_state.get_mut(world);
|
||||
|
||||
let view_layout = render_device.create_bind_group_layout(&BindGroupLayoutDescriptor {
|
||||
entries: &[BindGroupLayoutEntry {
|
||||
@ -78,10 +86,57 @@ impl FromWorld for SpritePipeline {
|
||||
],
|
||||
label: Some("sprite_material_layout"),
|
||||
});
|
||||
let dummy_white_gpu_image = {
|
||||
let image = Image::new_fill(
|
||||
Extent3d::default(),
|
||||
TextureDimension::D2,
|
||||
&[255u8; 4],
|
||||
first_available_texture_format.0,
|
||||
);
|
||||
let texture = render_device.create_texture(&image.texture_descriptor);
|
||||
let sampler = match image.sampler_descriptor {
|
||||
ImageSampler::Default => (**default_sampler).clone(),
|
||||
ImageSampler::Descriptor(descriptor) => render_device.create_sampler(&descriptor),
|
||||
};
|
||||
|
||||
let format_size = image.texture_descriptor.format.pixel_size();
|
||||
render_queue.write_texture(
|
||||
ImageCopyTexture {
|
||||
texture: &texture,
|
||||
mip_level: 0,
|
||||
origin: Origin3d::ZERO,
|
||||
aspect: TextureAspect::All,
|
||||
},
|
||||
&image.data,
|
||||
ImageDataLayout {
|
||||
offset: 0,
|
||||
bytes_per_row: Some(
|
||||
std::num::NonZeroU32::new(
|
||||
image.texture_descriptor.size.width * format_size as u32,
|
||||
)
|
||||
.unwrap(),
|
||||
),
|
||||
rows_per_image: None,
|
||||
},
|
||||
image.texture_descriptor.size,
|
||||
);
|
||||
let texture_view = texture.create_view(&TextureViewDescriptor::default());
|
||||
GpuImage {
|
||||
texture,
|
||||
texture_view,
|
||||
texture_format: image.texture_descriptor.format,
|
||||
sampler,
|
||||
size: Vec2::new(
|
||||
image.texture_descriptor.size.width as f32,
|
||||
image.texture_descriptor.size.height as f32,
|
||||
),
|
||||
}
|
||||
};
|
||||
|
||||
SpritePipeline {
|
||||
view_layout,
|
||||
material_layout,
|
||||
dummy_white_gpu_image,
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -148,7 +203,7 @@ impl SpecializedRenderPipeline for SpritePipeline {
|
||||
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,
|
||||
})],
|
||||
|
@ -1,17 +1,29 @@
|
||||
use bevy_ecs::prelude::*;
|
||||
use bevy_ecs::{prelude::*, system::SystemState};
|
||||
use bevy_math::Vec2;
|
||||
use bevy_render::{
|
||||
render_resource::*, renderer::RenderDevice, texture::BevyDefault, view::ViewUniform,
|
||||
render_resource::*,
|
||||
renderer::{RenderDevice, RenderQueue, RenderTextureFormat},
|
||||
texture::{DefaultImageSampler, GpuImage, Image, ImageSampler, TextureFormatPixelInfo},
|
||||
view::ViewUniform,
|
||||
};
|
||||
|
||||
#[derive(Resource)]
|
||||
pub struct UiPipeline {
|
||||
pub view_layout: BindGroupLayout,
|
||||
pub image_layout: BindGroupLayout,
|
||||
pub dummy_white_gpu_image: GpuImage,
|
||||
}
|
||||
|
||||
impl FromWorld for UiPipeline {
|
||||
fn from_world(world: &mut World) -> Self {
|
||||
let render_device = world.resource::<RenderDevice>();
|
||||
let mut system_state: SystemState<(
|
||||
Res<RenderDevice>,
|
||||
Res<DefaultImageSampler>,
|
||||
Res<RenderQueue>,
|
||||
Res<RenderTextureFormat>,
|
||||
)> = SystemState::new(world);
|
||||
let (render_device, default_sampler, render_queue, first_available_texture_format) =
|
||||
system_state.get_mut(world);
|
||||
|
||||
let view_layout = render_device.create_bind_group_layout(&BindGroupLayoutDescriptor {
|
||||
entries: &[BindGroupLayoutEntry {
|
||||
@ -48,10 +60,57 @@ impl FromWorld for UiPipeline {
|
||||
],
|
||||
label: Some("ui_image_layout"),
|
||||
});
|
||||
let dummy_white_gpu_image = {
|
||||
let image = Image::new_fill(
|
||||
Extent3d::default(),
|
||||
TextureDimension::D2,
|
||||
&[255u8; 4],
|
||||
first_available_texture_format.0,
|
||||
);
|
||||
let texture = render_device.create_texture(&image.texture_descriptor);
|
||||
let sampler = match image.sampler_descriptor {
|
||||
ImageSampler::Default => (**default_sampler).clone(),
|
||||
ImageSampler::Descriptor(descriptor) => render_device.create_sampler(&descriptor),
|
||||
};
|
||||
|
||||
let format_size = image.texture_descriptor.format.pixel_size();
|
||||
render_queue.write_texture(
|
||||
ImageCopyTexture {
|
||||
texture: &texture,
|
||||
mip_level: 0,
|
||||
origin: Origin3d::ZERO,
|
||||
aspect: TextureAspect::All,
|
||||
},
|
||||
&image.data,
|
||||
ImageDataLayout {
|
||||
offset: 0,
|
||||
bytes_per_row: Some(
|
||||
std::num::NonZeroU32::new(
|
||||
image.texture_descriptor.size.width * format_size as u32,
|
||||
)
|
||||
.unwrap(),
|
||||
),
|
||||
rows_per_image: None,
|
||||
},
|
||||
image.texture_descriptor.size,
|
||||
);
|
||||
let texture_view = texture.create_view(&TextureViewDescriptor::default());
|
||||
GpuImage {
|
||||
texture,
|
||||
texture_view,
|
||||
texture_format: image.texture_descriptor.format,
|
||||
sampler,
|
||||
size: Vec2::new(
|
||||
image.texture_descriptor.size.width as f32,
|
||||
image.texture_descriptor.size.height as f32,
|
||||
),
|
||||
}
|
||||
};
|
||||
|
||||
UiPipeline {
|
||||
view_layout,
|
||||
image_layout,
|
||||
dummy_white_gpu_image,
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -88,7 +147,7 @@ impl SpecializedRenderPipeline for UiPipeline {
|
||||
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,
|
||||
})],
|
||||
|
Loading…
Reference in New Issue
Block a user