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

switch bevy_image to use wgpu-types wherever possible instead of wgpu #16620

Merged
merged 2 commits into from
Dec 3, 2024
Merged
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: 2 additions & 0 deletions crates/bevy_image/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@ image = { version = "0.25.2", default-features = false }
# misc
bitflags = { version = "2.3", features = ["serde"] }
bytemuck = { version = "1.5" }
wgpu-types = { version = "23", default-features = false }
atlv24 marked this conversation as resolved.
Show resolved Hide resolved
# TODO: remove dependency on wgpu once https://github.com/gfx-rs/wgpu/pull/6648, 6649 and 6650 have been released
wgpu = { version = "23.0.1", default-features = false }
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reminder to remember to remove this

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can't remove it this PR, but once we upgrade wgpu we can

serde = { version = "1", features = ["derive"] }
derive_more = { version = "1", default-features = false, features = [
Expand Down
2 changes: 1 addition & 1 deletion crates/bevy_image/src/basis.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use basis_universal::{
BasisTextureType, DecodeFlags, TranscodeParameters, Transcoder, TranscoderTextureFormat,
};
use wgpu::{AstcBlock, AstcChannel, Extent3d, TextureDimension, TextureFormat};
use wgpu_types::{AstcBlock, AstcChannel, Extent3d, TextureDimension, TextureFormat};

use super::{CompressedImageFormats, Image, TextureError};

Expand Down
13 changes: 8 additions & 5 deletions crates/bevy_image/src/dds.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,8 @@
use bevy_utils::warn_once;
use ddsfile::{Caps2, D3DFormat, Dds, DxgiFormat};
use std::io::Cursor;
use wgpu::{
Extent3d, TextureDimension, TextureFormat, TextureViewDescriptor, TextureViewDimension,
};
use wgpu::TextureViewDescriptor;
use wgpu_types::{Extent3d, TextureDimension, TextureFormat, TextureViewDimension};

use super::{CompressedImageFormats, Image, TextureError};

Expand Down Expand Up @@ -284,14 +283,18 @@ pub fn dds_format_to_texture_format(

#[cfg(test)]
mod test {
use wgpu::{util::TextureDataOrder, TextureDescriptor, TextureDimension};
use wgpu::util::TextureDataOrder;
use wgpu_types::{TextureDescriptor, TextureDimension, TextureFormat};

use crate::CompressedImageFormats;

use super::dds_buffer_to_image;

/// `wgpu::create_texture_with_data` that reads from data structure but doesn't actually talk to your GPU
fn fake_wgpu_create_texture_with_data(desc: &TextureDescriptor<'_>, data: &[u8]) {
fn fake_wgpu_create_texture_with_data(
desc: &TextureDescriptor<Option<&'_ str>, &'_ [TextureFormat]>,
data: &[u8],
) {
// Will return None only if it's a combined depth-stencil format
// If so, default to 4, validation will fail later anyway since the depth or stencil
// aspect needs to be written to individually
Expand Down
2 changes: 1 addition & 1 deletion crates/bevy_image/src/exr_texture_loader.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use bevy_asset::{io::Reader, AssetLoader, LoadContext, RenderAssetUsages};
use derive_more::derive::{Display, Error, From};
use image::ImageDecoder;
use serde::{Deserialize, Serialize};
use wgpu::{Extent3d, TextureDimension, TextureFormat};
use wgpu_types::{Extent3d, TextureDimension, TextureFormat};

/// Loads EXR textures as Texture assets
#[derive(Clone, Default)]
Expand Down
2 changes: 1 addition & 1 deletion crates/bevy_image/src/hdr_texture_loader.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use bevy_asset::{io::Reader, AssetLoader, LoadContext};
use derive_more::derive::{Display, Error, From};
use image::DynamicImage;
use serde::{Deserialize, Serialize};
use wgpu::{Extent3d, TextureDimension, TextureFormat};
use wgpu_types::{Extent3d, TextureDimension, TextureFormat};

/// Loads HDR textures as Texture assets
#[derive(Clone, Default)]
Expand Down
148 changes: 76 additions & 72 deletions crates/bevy_image/src/image.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,11 @@ use bevy_reflect::Reflect;
use core::hash::Hash;
use derive_more::derive::{Display, Error, From};
use serde::{Deserialize, Serialize};
use wgpu::{Extent3d, TextureDimension, TextureFormat, TextureViewDescriptor};
use wgpu::{SamplerDescriptor, TextureViewDescriptor};
use wgpu_types::{
AddressMode, CompareFunction, Extent3d, Features, FilterMode, SamplerBorderColor,
TextureDescriptor, TextureDimension, TextureFormat, TextureUsages,
};

pub trait BevyDefault {
fn bevy_default() -> Self;
Expand Down Expand Up @@ -284,7 +288,7 @@ impl ImageFormat {
pub struct Image {
pub data: Vec<u8>,
// TODO: this nesting makes accessing Image metadata verbose. Either flatten out descriptor or add accessors
pub texture_descriptor: wgpu::TextureDescriptor<'static>,
pub texture_descriptor: TextureDescriptor<Option<&'static str>, &'static [TextureFormat]>,
/// The [`ImageSampler`] to use during rendering.
pub sampler: ImageSampler,
pub texture_view_descriptor: Option<TextureViewDescriptor<'static>>,
Expand Down Expand Up @@ -338,7 +342,7 @@ impl ImageSampler {
///
/// See [`ImageSamplerDescriptor`] for information how to configure this.
///
/// This type mirrors [`wgpu::AddressMode`].
/// This type mirrors [`AddressMode`].
#[derive(Clone, Copy, Debug, Default, Serialize, Deserialize)]
pub enum ImageAddressMode {
/// Clamp the value to the edge of the texture.
Expand All @@ -358,7 +362,7 @@ pub enum ImageAddressMode {
/// 1.25 -> 0.75
MirrorRepeat,
/// Clamp the value to the border of the texture
/// Requires the wgpu feature [`wgpu::Features::ADDRESS_MODE_CLAMP_TO_BORDER`].
/// Requires the wgpu feature [`Features::ADDRESS_MODE_CLAMP_TO_BORDER`].
///
/// -0.25 -> border
/// 1.25 -> border
Expand All @@ -367,7 +371,7 @@ pub enum ImageAddressMode {

/// Texel mixing mode when sampling between texels.
///
/// This type mirrors [`wgpu::FilterMode`].
/// This type mirrors [`FilterMode`].
#[derive(Clone, Copy, Debug, Default, Serialize, Deserialize)]
pub enum ImageFilterMode {
/// Nearest neighbor sampling.
Expand All @@ -383,7 +387,7 @@ pub enum ImageFilterMode {

/// Comparison function used for depth and stencil operations.
///
/// This type mirrors [`wgpu::CompareFunction`].
/// This type mirrors [`CompareFunction`].
#[derive(Clone, Copy, Debug, Serialize, Deserialize)]
pub enum ImageCompareFunction {
/// Function never passes
Expand All @@ -410,7 +414,7 @@ pub enum ImageCompareFunction {

/// Color variation to use when the sampler addressing mode is [`ImageAddressMode::ClampToBorder`].
///
/// This type mirrors [`wgpu::SamplerBorderColor`].
/// This type mirrors [`SamplerBorderColor`].
#[derive(Clone, Copy, Debug, Serialize, Deserialize)]
pub enum ImageSamplerBorderColor {
/// RGBA color `[0, 0, 0, 0]`.
Expand All @@ -423,7 +427,7 @@ pub enum ImageSamplerBorderColor {
/// textures that have an alpha component, and equivalent to [`Self::OpaqueBlack`]
/// for textures that do not have an alpha component. On other backends,
/// this is equivalent to [`Self::TransparentBlack`]. Requires
/// [`wgpu::Features::ADDRESS_MODE_CLAMP_TO_ZERO`]. Not supported on the web.
/// [`Features::ADDRESS_MODE_CLAMP_TO_ZERO`]. Not supported on the web.
Zero,
}

Expand All @@ -433,7 +437,7 @@ pub enum ImageSamplerBorderColor {
/// it will be serialized to an image asset `.meta` file which might require a migration in case of
/// a breaking change.
///
/// This types mirrors [`wgpu::SamplerDescriptor`], but that might change in future versions.
/// This types mirrors [`SamplerDescriptor`], but that might change in future versions.
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct ImageSamplerDescriptor {
pub label: Option<String>,
Expand Down Expand Up @@ -503,8 +507,8 @@ impl ImageSamplerDescriptor {
}
}

pub fn as_wgpu(&self) -> wgpu::SamplerDescriptor {
wgpu::SamplerDescriptor {
pub fn as_wgpu(&self) -> SamplerDescriptor {
SamplerDescriptor {
label: self.label.as_deref(),
address_mode_u: self.address_mode_u.into(),
address_mode_v: self.address_mode_v.into(),
Expand All @@ -521,100 +525,100 @@ impl ImageSamplerDescriptor {
}
}

impl From<ImageAddressMode> for wgpu::AddressMode {
impl From<ImageAddressMode> for AddressMode {
fn from(value: ImageAddressMode) -> Self {
match value {
ImageAddressMode::ClampToEdge => wgpu::AddressMode::ClampToEdge,
ImageAddressMode::Repeat => wgpu::AddressMode::Repeat,
ImageAddressMode::MirrorRepeat => wgpu::AddressMode::MirrorRepeat,
ImageAddressMode::ClampToBorder => wgpu::AddressMode::ClampToBorder,
ImageAddressMode::ClampToEdge => AddressMode::ClampToEdge,
ImageAddressMode::Repeat => AddressMode::Repeat,
ImageAddressMode::MirrorRepeat => AddressMode::MirrorRepeat,
ImageAddressMode::ClampToBorder => AddressMode::ClampToBorder,
}
}
}

impl From<ImageFilterMode> for wgpu::FilterMode {
impl From<ImageFilterMode> for FilterMode {
fn from(value: ImageFilterMode) -> Self {
match value {
ImageFilterMode::Nearest => wgpu::FilterMode::Nearest,
ImageFilterMode::Linear => wgpu::FilterMode::Linear,
ImageFilterMode::Nearest => FilterMode::Nearest,
ImageFilterMode::Linear => FilterMode::Linear,
}
}
}

impl From<ImageCompareFunction> for wgpu::CompareFunction {
impl From<ImageCompareFunction> for CompareFunction {
fn from(value: ImageCompareFunction) -> Self {
match value {
ImageCompareFunction::Never => wgpu::CompareFunction::Never,
ImageCompareFunction::Less => wgpu::CompareFunction::Less,
ImageCompareFunction::Equal => wgpu::CompareFunction::Equal,
ImageCompareFunction::LessEqual => wgpu::CompareFunction::LessEqual,
ImageCompareFunction::Greater => wgpu::CompareFunction::Greater,
ImageCompareFunction::NotEqual => wgpu::CompareFunction::NotEqual,
ImageCompareFunction::GreaterEqual => wgpu::CompareFunction::GreaterEqual,
ImageCompareFunction::Always => wgpu::CompareFunction::Always,
ImageCompareFunction::Never => CompareFunction::Never,
ImageCompareFunction::Less => CompareFunction::Less,
ImageCompareFunction::Equal => CompareFunction::Equal,
ImageCompareFunction::LessEqual => CompareFunction::LessEqual,
ImageCompareFunction::Greater => CompareFunction::Greater,
ImageCompareFunction::NotEqual => CompareFunction::NotEqual,
ImageCompareFunction::GreaterEqual => CompareFunction::GreaterEqual,
ImageCompareFunction::Always => CompareFunction::Always,
}
}
}

impl From<ImageSamplerBorderColor> for wgpu::SamplerBorderColor {
impl From<ImageSamplerBorderColor> for SamplerBorderColor {
fn from(value: ImageSamplerBorderColor) -> Self {
match value {
ImageSamplerBorderColor::TransparentBlack => wgpu::SamplerBorderColor::TransparentBlack,
ImageSamplerBorderColor::OpaqueBlack => wgpu::SamplerBorderColor::OpaqueBlack,
ImageSamplerBorderColor::OpaqueWhite => wgpu::SamplerBorderColor::OpaqueWhite,
ImageSamplerBorderColor::Zero => wgpu::SamplerBorderColor::Zero,
ImageSamplerBorderColor::TransparentBlack => SamplerBorderColor::TransparentBlack,
ImageSamplerBorderColor::OpaqueBlack => SamplerBorderColor::OpaqueBlack,
ImageSamplerBorderColor::OpaqueWhite => SamplerBorderColor::OpaqueWhite,
ImageSamplerBorderColor::Zero => SamplerBorderColor::Zero,
}
}
}

impl From<wgpu::AddressMode> for ImageAddressMode {
fn from(value: wgpu::AddressMode) -> Self {
impl From<AddressMode> for ImageAddressMode {
fn from(value: AddressMode) -> Self {
match value {
wgpu::AddressMode::ClampToEdge => ImageAddressMode::ClampToEdge,
wgpu::AddressMode::Repeat => ImageAddressMode::Repeat,
wgpu::AddressMode::MirrorRepeat => ImageAddressMode::MirrorRepeat,
wgpu::AddressMode::ClampToBorder => ImageAddressMode::ClampToBorder,
AddressMode::ClampToEdge => ImageAddressMode::ClampToEdge,
AddressMode::Repeat => ImageAddressMode::Repeat,
AddressMode::MirrorRepeat => ImageAddressMode::MirrorRepeat,
AddressMode::ClampToBorder => ImageAddressMode::ClampToBorder,
}
}
}

impl From<wgpu::FilterMode> for ImageFilterMode {
fn from(value: wgpu::FilterMode) -> Self {
impl From<FilterMode> for ImageFilterMode {
fn from(value: FilterMode) -> Self {
match value {
wgpu::FilterMode::Nearest => ImageFilterMode::Nearest,
wgpu::FilterMode::Linear => ImageFilterMode::Linear,
FilterMode::Nearest => ImageFilterMode::Nearest,
FilterMode::Linear => ImageFilterMode::Linear,
}
}
}

impl From<wgpu::CompareFunction> for ImageCompareFunction {
fn from(value: wgpu::CompareFunction) -> Self {
impl From<CompareFunction> for ImageCompareFunction {
fn from(value: CompareFunction) -> Self {
match value {
wgpu::CompareFunction::Never => ImageCompareFunction::Never,
wgpu::CompareFunction::Less => ImageCompareFunction::Less,
wgpu::CompareFunction::Equal => ImageCompareFunction::Equal,
wgpu::CompareFunction::LessEqual => ImageCompareFunction::LessEqual,
wgpu::CompareFunction::Greater => ImageCompareFunction::Greater,
wgpu::CompareFunction::NotEqual => ImageCompareFunction::NotEqual,
wgpu::CompareFunction::GreaterEqual => ImageCompareFunction::GreaterEqual,
wgpu::CompareFunction::Always => ImageCompareFunction::Always,
CompareFunction::Never => ImageCompareFunction::Never,
CompareFunction::Less => ImageCompareFunction::Less,
CompareFunction::Equal => ImageCompareFunction::Equal,
CompareFunction::LessEqual => ImageCompareFunction::LessEqual,
CompareFunction::Greater => ImageCompareFunction::Greater,
CompareFunction::NotEqual => ImageCompareFunction::NotEqual,
CompareFunction::GreaterEqual => ImageCompareFunction::GreaterEqual,
CompareFunction::Always => ImageCompareFunction::Always,
}
}
}

impl From<wgpu::SamplerBorderColor> for ImageSamplerBorderColor {
fn from(value: wgpu::SamplerBorderColor) -> Self {
impl From<SamplerBorderColor> for ImageSamplerBorderColor {
fn from(value: SamplerBorderColor) -> Self {
match value {
wgpu::SamplerBorderColor::TransparentBlack => ImageSamplerBorderColor::TransparentBlack,
wgpu::SamplerBorderColor::OpaqueBlack => ImageSamplerBorderColor::OpaqueBlack,
wgpu::SamplerBorderColor::OpaqueWhite => ImageSamplerBorderColor::OpaqueWhite,
wgpu::SamplerBorderColor::Zero => ImageSamplerBorderColor::Zero,
SamplerBorderColor::TransparentBlack => ImageSamplerBorderColor::TransparentBlack,
SamplerBorderColor::OpaqueBlack => ImageSamplerBorderColor::OpaqueBlack,
SamplerBorderColor::OpaqueWhite => ImageSamplerBorderColor::OpaqueWhite,
SamplerBorderColor::Zero => ImageSamplerBorderColor::Zero,
}
}
}

impl<'a> From<wgpu::SamplerDescriptor<'a>> for ImageSamplerDescriptor {
fn from(value: wgpu::SamplerDescriptor) -> Self {
impl<'a> From<SamplerDescriptor<'a>> for ImageSamplerDescriptor {
fn from(value: SamplerDescriptor) -> Self {
ImageSamplerDescriptor {
label: value.label.map(ToString::to_string),
address_mode_u: value.address_mode_u.into(),
Expand All @@ -639,7 +643,7 @@ impl Default for Image {
let data = vec![255; format.pixel_size()];
Image {
data,
texture_descriptor: wgpu::TextureDescriptor {
texture_descriptor: TextureDescriptor {
size: Extent3d {
width: 1,
height: 1,
Expand All @@ -650,7 +654,7 @@ impl Default for Image {
label: None,
mip_level_count: 1,
sample_count: 1,
usage: wgpu::TextureUsages::TEXTURE_BINDING | wgpu::TextureUsages::COPY_DST,
usage: TextureUsages::TEXTURE_BINDING | TextureUsages::COPY_DST,
view_formats: &[],
},
sampler: ImageSampler::Default,
Expand Down Expand Up @@ -701,7 +705,7 @@ impl Image {
let data = vec![255, 255, 255, 0];
Image {
data,
texture_descriptor: wgpu::TextureDescriptor {
texture_descriptor: TextureDescriptor {
size: Extent3d {
width: 1,
height: 1,
Expand All @@ -712,7 +716,7 @@ impl Image {
label: None,
mip_level_count: 1,
sample_count: 1,
usage: wgpu::TextureUsages::TEXTURE_BINDING | wgpu::TextureUsages::COPY_DST,
usage: TextureUsages::TEXTURE_BINDING | TextureUsages::COPY_DST,
view_formats: &[],
},
sampler: ImageSampler::Default,
Expand Down Expand Up @@ -921,13 +925,13 @@ impl Image {
let format_description = self.texture_descriptor.format;
format_description
.required_features()
.contains(wgpu::Features::TEXTURE_COMPRESSION_ASTC)
.contains(Features::TEXTURE_COMPRESSION_ASTC)
|| format_description
.required_features()
.contains(wgpu::Features::TEXTURE_COMPRESSION_BC)
.contains(Features::TEXTURE_COMPRESSION_BC)
|| format_description
.required_features()
.contains(wgpu::Features::TEXTURE_COMPRESSION_ETC2)
.contains(Features::TEXTURE_COMPRESSION_ETC2)
}

/// Compute the byte offset where the data of a specific pixel is stored
Expand Down Expand Up @@ -1497,15 +1501,15 @@ bitflags::bitflags! {
}

impl CompressedImageFormats {
pub fn from_features(features: wgpu::Features) -> Self {
pub fn from_features(features: Features) -> Self {
let mut supported_compressed_formats = Self::default();
if features.contains(wgpu::Features::TEXTURE_COMPRESSION_ASTC) {
if features.contains(Features::TEXTURE_COMPRESSION_ASTC) {
supported_compressed_formats |= Self::ASTC_LDR;
}
if features.contains(wgpu::Features::TEXTURE_COMPRESSION_BC) {
if features.contains(Features::TEXTURE_COMPRESSION_BC) {
supported_compressed_formats |= Self::BC;
}
if features.contains(wgpu::Features::TEXTURE_COMPRESSION_ETC2) {
if features.contains(Features::TEXTURE_COMPRESSION_ETC2) {
supported_compressed_formats |= Self::ETC2;
}
supported_compressed_formats
Expand Down
2 changes: 1 addition & 1 deletion crates/bevy_image/src/image_texture_conversion.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use crate::{Image, TextureFormatPixelInfo};
use bevy_asset::RenderAssetUsages;
use derive_more::derive::{Display, Error};
use image::{DynamicImage, ImageBuffer};
use wgpu::{Extent3d, TextureDimension, TextureFormat};
use wgpu_types::{Extent3d, TextureDimension, TextureFormat};

impl Image {
/// Converts a [`DynamicImage`] to an [`Image`].
Expand Down
Loading
Loading