From 6903a9411b0d7e4dec759deecf7cc7986a9f6092 Mon Sep 17 00:00:00 2001 From: Mike Date: Sun, 11 Dec 2022 18:22:07 +0000 Subject: [PATCH] get pixel size from wgpu (#6820) # Objective - Get rid of giant match statement to get PixelInfo. - This will allow for supporting any texture that is uncompressed, instead of people needing to PR in any textures that are supported in wgpu, but not bevy. ## Solution - More conservative alternative to https://github.com/bevyengine/bevy/pull/6788, where we don't try to make some of the calculations correct for compressed types. - Delete `PixelInfo` and get the pixel_size directly from wgpu. Data from wgpu is here: https://docs.rs/wgpu-types/0.14.0/src/wgpu_types/lib.rs.html#2359 - Panic if the texture is a compressed type. An integer byte size of a pixel is no longer a valid concept when talking about compressed textures. - All internal usages use `pixel_size` and not `pixel_info` and are on uncompressed formats. Most of these usages are on either explicit texture formats or slightly indirectly through `TextureFormat::bevy_default()`. The other uses are in `TextureAtlas` and have other calculations that assumes the texture is uncompressed. ## Changelog - remove `PixelInfo` and get `pixel_size` from wgpu ## Migration Guide `PixelInfo` has been removed. `PixelInfo::components` is equivalent to `texture_format.describe().components`. `PixelInfo::type_size` can be gotten from `texture_format.describe().block_size/ texture_format.describe().components`. But note this can yield incorrect results for some texture types like Rg11b10Float. --- crates/bevy_render/src/texture/image.rs | 130 ++---------------------- 1 file changed, 7 insertions(+), 123 deletions(-) diff --git a/crates/bevy_render/src/texture/image.rs b/crates/bevy_render/src/texture/image.rs index e0bf7207a4bef..d2cfa72c80d26 100644 --- a/crates/bevy_render/src/texture/image.rs +++ b/crates/bevy_render/src/texture/image.rs @@ -464,134 +464,18 @@ impl Volume for Extent3d { } } -/// Information about the pixel size in bytes and the number of different components. -pub struct PixelInfo { - /// The size of a component of a pixel in bytes. - pub type_size: usize, - /// The amount of different components (color channels). - pub num_components: usize, -} - /// Extends the wgpu [`TextureFormat`] with information about the pixel. pub trait TextureFormatPixelInfo { - /// Returns the pixel information of the format. - fn pixel_info(&self) -> PixelInfo; - /// Returns the size of a pixel of the format. - fn pixel_size(&self) -> usize { - let info = self.pixel_info(); - info.type_size * info.num_components - } + /// Returns the size of a pixel in bytes of the format. + fn pixel_size(&self) -> usize; } impl TextureFormatPixelInfo for TextureFormat { - #[allow(clippy::match_same_arms)] - fn pixel_info(&self) -> PixelInfo { - let type_size = match self { - // 8bit - TextureFormat::R8Unorm - | TextureFormat::R8Snorm - | TextureFormat::R8Uint - | TextureFormat::R8Sint - | TextureFormat::Rg8Unorm - | TextureFormat::Rg8Snorm - | TextureFormat::Rg8Uint - | TextureFormat::Rg8Sint - | TextureFormat::Rgba8Unorm - | TextureFormat::Rgba8UnormSrgb - | TextureFormat::Rgba8Snorm - | TextureFormat::Rgba8Uint - | TextureFormat::Rgba8Sint - | TextureFormat::Bgra8Unorm - | TextureFormat::Bgra8UnormSrgb => 1, - - // 16bit - TextureFormat::R16Uint - | TextureFormat::R16Sint - | TextureFormat::R16Float - | TextureFormat::R16Unorm - | TextureFormat::Rg16Uint - | TextureFormat::Rg16Sint - | TextureFormat::Rg16Unorm - | TextureFormat::Rg16Float - | TextureFormat::Rgba16Uint - | TextureFormat::Rgba16Sint - | TextureFormat::Rgba16Float => 2, - - // 32bit - TextureFormat::R32Uint - | TextureFormat::R32Sint - | TextureFormat::R32Float - | TextureFormat::Rg32Uint - | TextureFormat::Rg32Sint - | TextureFormat::Rg32Float - | TextureFormat::Rgba32Uint - | TextureFormat::Rgba32Sint - | TextureFormat::Rgba32Float - | TextureFormat::Depth32Float => 4, - - // special cases - TextureFormat::Rgb9e5Ufloat => 4, - TextureFormat::Rgb10a2Unorm => 4, - TextureFormat::Rg11b10Float => 4, - TextureFormat::Depth24Plus => 3, // FIXME is this correct? - TextureFormat::Depth24PlusStencil8 => 4, - // TODO: this is not good! this is a temporary step while porting bevy_render to direct wgpu usage - _ => panic!("cannot get pixel info for type"), - }; - - let components = match self { - TextureFormat::R8Unorm - | TextureFormat::R8Snorm - | TextureFormat::R8Uint - | TextureFormat::R8Sint - | TextureFormat::R16Uint - | TextureFormat::R16Sint - | TextureFormat::R16Unorm - | TextureFormat::R16Float - | TextureFormat::R32Uint - | TextureFormat::R32Sint - | TextureFormat::R32Float => 1, - - TextureFormat::Rg8Unorm - | TextureFormat::Rg8Snorm - | TextureFormat::Rg8Uint - | TextureFormat::Rg8Sint - | TextureFormat::Rg16Uint - | TextureFormat::Rg16Sint - | TextureFormat::Rg16Unorm - | TextureFormat::Rg16Float - | TextureFormat::Rg32Uint - | TextureFormat::Rg32Sint - | TextureFormat::Rg32Float => 2, - - TextureFormat::Rgba8Unorm - | TextureFormat::Rgba8UnormSrgb - | TextureFormat::Rgba8Snorm - | TextureFormat::Rgba8Uint - | TextureFormat::Rgba8Sint - | TextureFormat::Bgra8Unorm - | TextureFormat::Bgra8UnormSrgb - | TextureFormat::Rgba16Uint - | TextureFormat::Rgba16Sint - | TextureFormat::Rgba16Float - | TextureFormat::Rgba32Uint - | TextureFormat::Rgba32Sint - | TextureFormat::Rgba32Float => 4, - - // special cases - TextureFormat::Rgb9e5Ufloat - | TextureFormat::Rgb10a2Unorm - | TextureFormat::Rg11b10Float - | TextureFormat::Depth32Float - | TextureFormat::Depth24Plus - | TextureFormat::Depth24PlusStencil8 => 1, - // TODO: this is not good! this is a temporary step while porting bevy_render to direct wgpu usage - _ => panic!("cannot get pixel info for type"), - }; - - PixelInfo { - type_size, - num_components: components, + fn pixel_size(&self) -> usize { + let info = self.describe(); + match info.block_dimensions { + (1, 1) => info.block_size.into(), + _ => panic!("Using pixel_size for compressed textures is invalid"), } } }