Skip to content
Open
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
2 changes: 1 addition & 1 deletion crates/bevy_core_pipeline/src/upscaling/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ fn prepare_view_upscaling_pipelines(
};

let key = BlitPipelineKey {
texture_format: view_target.out_texture_format(),
texture_format: view_target.out_texture_view_format(),
blend_state,
samples: 1,
};
Expand Down
141 changes: 138 additions & 3 deletions crates/bevy_image/src/image.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,130 @@ impl BevyDefault for TextureFormat {
}
}

/// Trait used to provide texture srgb view formats with static lifetime for `TextureDescriptor.view_formats`.
pub trait TextureSrgbViewFormats {
/// Returns the srgb view formats for a type.
fn srgb_view_formats(&self) -> &'static [TextureFormat];
}

impl TextureSrgbViewFormats for TextureFormat {
/// Returns the srgb view formats if the format has an srgb variant, otherwise returns an empty slice.
///
/// The return result covers all the results of [`TextureFormat::add_srgb_suffix`](wgpu_types::TextureFormat::add_srgb_suffix).
fn srgb_view_formats(&self) -> &'static [TextureFormat] {
match self {
TextureFormat::Rgba8Unorm => &[TextureFormat::Rgba8UnormSrgb],
TextureFormat::Bgra8Unorm => &[TextureFormat::Bgra8UnormSrgb],
TextureFormat::Bc1RgbaUnorm => &[TextureFormat::Bc1RgbaUnormSrgb],
TextureFormat::Bc2RgbaUnorm => &[TextureFormat::Bc2RgbaUnormSrgb],
TextureFormat::Bc3RgbaUnorm => &[TextureFormat::Bc3RgbaUnormSrgb],
TextureFormat::Bc7RgbaUnorm => &[TextureFormat::Bc7RgbaUnormSrgb],
TextureFormat::Etc2Rgb8Unorm => &[TextureFormat::Etc2Rgb8UnormSrgb],
TextureFormat::Etc2Rgb8A1Unorm => &[TextureFormat::Etc2Rgb8A1UnormSrgb],
TextureFormat::Etc2Rgba8Unorm => &[TextureFormat::Etc2Rgba8UnormSrgb],
TextureFormat::Astc {
block: wgpu_types::AstcBlock::B4x4,
channel: wgpu_types::AstcChannel::Unorm,
} => &[TextureFormat::Astc {
block: wgpu_types::AstcBlock::B4x4,
channel: wgpu_types::AstcChannel::UnormSrgb,
}],
TextureFormat::Astc {
block: wgpu_types::AstcBlock::B5x4,
channel: wgpu_types::AstcChannel::Unorm,
} => &[TextureFormat::Astc {
block: wgpu_types::AstcBlock::B5x4,
channel: wgpu_types::AstcChannel::UnormSrgb,
}],
TextureFormat::Astc {
block: wgpu_types::AstcBlock::B5x5,
channel: wgpu_types::AstcChannel::Unorm,
} => &[TextureFormat::Astc {
block: wgpu_types::AstcBlock::B5x5,
channel: wgpu_types::AstcChannel::UnormSrgb,
}],
TextureFormat::Astc {
block: wgpu_types::AstcBlock::B6x5,
channel: wgpu_types::AstcChannel::Unorm,
} => &[TextureFormat::Astc {
block: wgpu_types::AstcBlock::B6x5,
channel: wgpu_types::AstcChannel::UnormSrgb,
}],
TextureFormat::Astc {
block: wgpu_types::AstcBlock::B6x6,
channel: wgpu_types::AstcChannel::Unorm,
} => &[TextureFormat::Astc {
block: wgpu_types::AstcBlock::B6x6,
channel: wgpu_types::AstcChannel::UnormSrgb,
}],
TextureFormat::Astc {
block: wgpu_types::AstcBlock::B8x5,
channel: wgpu_types::AstcChannel::Unorm,
} => &[TextureFormat::Astc {
block: wgpu_types::AstcBlock::B8x5,
channel: wgpu_types::AstcChannel::UnormSrgb,
}],
TextureFormat::Astc {
block: wgpu_types::AstcBlock::B8x6,
channel: wgpu_types::AstcChannel::Unorm,
} => &[TextureFormat::Astc {
block: wgpu_types::AstcBlock::B8x6,
channel: wgpu_types::AstcChannel::UnormSrgb,
}],
TextureFormat::Astc {
block: wgpu_types::AstcBlock::B8x8,
channel: wgpu_types::AstcChannel::Unorm,
} => &[TextureFormat::Astc {
block: wgpu_types::AstcBlock::B8x8,
channel: wgpu_types::AstcChannel::UnormSrgb,
}],
TextureFormat::Astc {
block: wgpu_types::AstcBlock::B10x5,
channel: wgpu_types::AstcChannel::Unorm,
} => &[TextureFormat::Astc {
block: wgpu_types::AstcBlock::B10x5,
channel: wgpu_types::AstcChannel::UnormSrgb,
}],
TextureFormat::Astc {
block: wgpu_types::AstcBlock::B10x6,
channel: wgpu_types::AstcChannel::Unorm,
} => &[TextureFormat::Astc {
block: wgpu_types::AstcBlock::B10x6,
channel: wgpu_types::AstcChannel::UnormSrgb,
}],
TextureFormat::Astc {
block: wgpu_types::AstcBlock::B10x8,
channel: wgpu_types::AstcChannel::Unorm,
} => &[TextureFormat::Astc {
block: wgpu_types::AstcBlock::B10x8,
channel: wgpu_types::AstcChannel::UnormSrgb,
}],
TextureFormat::Astc {
block: wgpu_types::AstcBlock::B10x10,
channel: wgpu_types::AstcChannel::Unorm,
} => &[TextureFormat::Astc {
block: wgpu_types::AstcBlock::B10x10,
channel: wgpu_types::AstcChannel::UnormSrgb,
}],
TextureFormat::Astc {
block: wgpu_types::AstcBlock::B12x10,
channel: wgpu_types::AstcChannel::Unorm,
} => &[TextureFormat::Astc {
block: wgpu_types::AstcBlock::B12x10,
channel: wgpu_types::AstcChannel::UnormSrgb,
}],
TextureFormat::Astc {
block: wgpu_types::AstcBlock::B12x12,
channel: wgpu_types::AstcChannel::Unorm,
} => &[TextureFormat::Astc {
block: wgpu_types::AstcBlock::B12x12,
channel: wgpu_types::AstcChannel::UnormSrgb,
}],
_ => &[],
}
}
}

/// A handle to a 1 x 1 transparent white image.
///
/// Like [`Handle<Image>::default`], this is a handle to a fallback image asset.
Expand Down Expand Up @@ -1010,7 +1134,12 @@ impl Image {
///
/// [`Camera`]: https://docs.rs/bevy/latest/bevy/render/camera/struct.Camera.html
/// [`RenderTarget::Image`]: https://docs.rs/bevy/latest/bevy/render/camera/enum.RenderTarget.html#variant.Image
pub fn new_target_texture(width: u32, height: u32, format: TextureFormat) -> Self {
pub fn new_target_texture(
width: u32,
height: u32,
format: TextureFormat,
view_format: Option<TextureFormat>,
) -> Self {
let size = Extent3d {
width,
height,
Expand Down Expand Up @@ -1039,10 +1168,16 @@ impl Image {
mip_level_count: 1,
sample_count: 1,
usage,
view_formats: &[],
view_formats: match view_format {
Some(_) => format.srgb_view_formats(),
None => &[],
},
},
sampler: ImageSampler::Default,
texture_view_descriptor: None,
texture_view_descriptor: view_format.map(|f| TextureViewDescriptor {
format: Some(f),
..Default::default()
}),
asset_usage: RenderAssetUsages::default(),
copy_on_resize: true,
}
Expand Down
1 change: 1 addition & 0 deletions crates/bevy_pbr/src/render/mesh.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1878,6 +1878,7 @@ pub fn build_dummy_white_gpu_image(
texture,
texture_view,
texture_format: image.texture_descriptor.format,
texture_view_format: image.texture_view_descriptor.and_then(|v| v.format),
sampler,
size: image.texture_descriptor.size,
mip_level_count: image.texture_descriptor.mip_level_count,
Expand Down
12 changes: 6 additions & 6 deletions crates/bevy_render/src/camera.rs
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,7 @@ pub trait NormalizedRenderTargetExt {
) -> Option<&'a TextureView>;

/// Retrieves the [`TextureFormat`] of this render target, if it exists.
fn get_texture_format<'a>(
fn get_texture_view_format<'a>(
&self,
windows: &'a ExtractedWindows,
images: &'a RenderAssets<GpuImage>,
Expand Down Expand Up @@ -199,8 +199,8 @@ impl NormalizedRenderTargetExt for NormalizedRenderTarget {
}
}

/// Retrieves the [`TextureFormat`] of this render target, if it exists.
fn get_texture_format<'a>(
/// Retrieves the texture view's [`TextureFormat`] of this render target, if it exists.
fn get_texture_view_format<'a>(
&self,
windows: &'a ExtractedWindows,
images: &'a RenderAssets<GpuImage>,
Expand All @@ -209,12 +209,12 @@ impl NormalizedRenderTargetExt for NormalizedRenderTarget {
match self {
NormalizedRenderTarget::Window(window_ref) => windows
.get(&window_ref.entity())
.and_then(|window| window.swap_chain_texture_format),
.and_then(|window| window.swap_chain_texture_view_format),
NormalizedRenderTarget::Image(image_target) => images
.get(&image_target.handle)
.map(|image| image.texture_format),
.map(|image| image.texture_view_format.unwrap_or(image.texture_format)),
NormalizedRenderTarget::TextureView(id) => {
manual_texture_views.get(id).map(|tex| tex.format)
manual_texture_views.get(id).map(|tex| tex.view_format)
}
NormalizedRenderTarget::None { .. } => None,
}
Expand Down
1 change: 1 addition & 0 deletions crates/bevy_render/src/texture/fallback_image.rs
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,7 @@ fn fallback_image_new(
texture,
texture_view,
texture_format: image.texture_descriptor.format,
texture_view_format: image.texture_view_descriptor.and_then(|v| v.format),
sampler,
size: image.texture_descriptor.size,
mip_level_count: image.texture_descriptor.mip_level_count,
Expand Down
5 changes: 3 additions & 2 deletions crates/bevy_render/src/texture/gpu_image.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ pub struct GpuImage {
pub texture: Texture,
pub texture_view: TextureView,
pub texture_format: TextureFormat,
pub texture_view_format: Option<TextureFormat>,
pub sampler: Sampler,
pub size: Extent3d,
pub mip_level_count: u32,
Expand Down Expand Up @@ -92,9 +93,8 @@ impl RenderAsset for GpuImage {
let texture_view = texture.create_view(
image
.texture_view_descriptor
.or_else(|| Some(TextureViewDescriptor::default()))
.as_ref()
.unwrap(),
.unwrap_or(&TextureViewDescriptor::default()),
);
let sampler = match image.sampler {
ImageSampler::Default => (***default_sampler).clone(),
Expand All @@ -107,6 +107,7 @@ impl RenderAsset for GpuImage {
texture,
texture_view,
texture_format: image.texture_descriptor.format,
texture_view_format: image.texture_view_descriptor.and_then(|v| v.format),
sampler,
size: image.texture_descriptor.size,
mip_level_count: image.texture_descriptor.mip_level_count,
Expand Down
4 changes: 2 additions & 2 deletions crates/bevy_render/src/texture/manual_texture_view.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,15 @@ use crate::render_resource::TextureView;
pub struct ManualTextureView {
pub texture_view: TextureView,
pub size: UVec2,
pub format: TextureFormat,
pub view_format: TextureFormat,
}

impl ManualTextureView {
pub fn with_default_format(texture_view: TextureView, size: UVec2) -> Self {
Self {
texture_view,
size,
format: TextureFormat::bevy_default(),
view_format: TextureFormat::bevy_default(),
}
}
}
Expand Down
6 changes: 3 additions & 3 deletions crates/bevy_render/src/texture/texture_attachment.rs
Original file line number Diff line number Diff line change
Expand Up @@ -127,15 +127,15 @@ impl DepthAttachment {
#[derive(Clone)]
pub struct OutputColorAttachment {
pub view: TextureView,
pub format: TextureFormat,
pub view_format: TextureFormat,
is_first_call: Arc<AtomicBool>,
}

impl OutputColorAttachment {
pub fn new(view: TextureView, format: TextureFormat) -> Self {
pub fn new(view: TextureView, view_format: TextureFormat) -> Self {
Self {
view,
format,
view_format,
is_first_call: Arc::new(AtomicBool::new(true)),
}
}
Expand Down
10 changes: 4 additions & 6 deletions crates/bevy_render/src/view/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -847,8 +847,8 @@ impl ViewTarget {

/// The format of the final texture this view will render to
#[inline]
pub fn out_texture_format(&self) -> TextureFormat {
self.out_texture.format
pub fn out_texture_view_format(&self) -> TextureFormat {
self.out_texture.view_format
}

/// This will start a new "post process write", which assumes that the caller
Expand Down Expand Up @@ -1024,10 +1024,8 @@ pub fn prepare_view_attachments(
let Some(attachment) = target
.get_texture_view(&windows, &images, &manual_texture_views)
.cloned()
.zip(target.get_texture_format(&windows, &images, &manual_texture_views))
.map(|(view, format)| {
OutputColorAttachment::new(view.clone(), format.add_srgb_suffix())
})
.zip(target.get_texture_view_format(&windows, &images, &manual_texture_views))
.map(|(view, format)| OutputColorAttachment::new(view.clone(), format))
else {
continue;
};
Expand Down
19 changes: 14 additions & 5 deletions crates/bevy_render/src/view/window/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,15 +60,17 @@ pub struct ExtractedWindow {
pub swap_chain_texture_view: Option<TextureView>,
pub swap_chain_texture: Option<SurfaceTexture>,
pub swap_chain_texture_format: Option<TextureFormat>,
pub swap_chain_texture_view_format: Option<TextureFormat>,
pub size_changed: bool,
pub present_mode_changed: bool,
pub alpha_mode: CompositeAlphaMode,
}

impl ExtractedWindow {
fn set_swapchain_texture(&mut self, frame: wgpu::SurfaceTexture) {
self.swap_chain_texture_view_format = Some(frame.texture.format().add_srgb_suffix());
let texture_view_descriptor = TextureViewDescriptor {
format: Some(frame.texture.format().add_srgb_suffix()),
format: self.swap_chain_texture_view_format,
..default()
};
self.swap_chain_texture_view = Some(TextureView::from(
Expand Down Expand Up @@ -140,6 +142,7 @@ fn extract_windows(
swap_chain_texture_view: None,
size_changed: false,
swap_chain_texture_format: None,
swap_chain_texture_view_format: None,
present_mode_changed: false,
alpha_mode: window.composite_alpha_mode,
});
Expand Down Expand Up @@ -191,6 +194,7 @@ struct SurfaceData {
// TODO: what lifetime should this be?
surface: WgpuWrapper<wgpu::Surface<'static>>,
configuration: SurfaceConfiguration,
texture_view_format: Option<TextureFormat>,
}

#[derive(Resource, Default)]
Expand Down Expand Up @@ -363,6 +367,11 @@ pub fn create_surfaces(
}
}

let texture_view_format = if !format.is_srgb() {
Some(format.add_srgb_suffix())
} else {
None
};
let configuration = SurfaceConfiguration {
format,
width: window.physical_width,
Expand Down Expand Up @@ -391,10 +400,9 @@ pub fn create_surfaces(
}
CompositeAlphaMode::Inherit => wgpu::CompositeAlphaMode::Inherit,
},
view_formats: if !format.is_srgb() {
vec![format.add_srgb_suffix()]
} else {
vec![]
view_formats: match texture_view_format {
Some(format) => vec![format],
None => vec![],
},
};

Expand All @@ -403,6 +411,7 @@ pub fn create_surfaces(
SurfaceData {
surface: WgpuWrapper::new(surface),
configuration,
texture_view_format,
}
});

Expand Down
Loading