From 8431c91b5578ed0c08e4db813b3d1cb4458e3977 Mon Sep 17 00:00:00 2001 From: Ku95 Date: Sun, 6 Mar 2022 14:22:06 +0100 Subject: [PATCH 1/5] removed pixel info and replaced it with wrapper for wgpu describe --- crates/bevy_render/src/texture/image.rs | 122 +----------------------- 1 file changed, 5 insertions(+), 117 deletions(-) diff --git a/crates/bevy_render/src/texture/image.rs b/crates/bevy_render/src/texture/image.rs index 2fed3f23a7fbc..641d3a69e8eb8 100644 --- a/crates/bevy_render/src/texture/image.rs +++ b/crates/bevy_render/src/texture/image.rs @@ -256,128 +256,16 @@ 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 of the format in bytes. + fn pixel_size(&self) -> usize; } impl TextureFormatPixelInfo for TextureFormat { - 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::Rg16Uint - | TextureFormat::Rg16Sint - | 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::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::R16Float - | TextureFormat::R32Uint - | TextureFormat::R32Sint - | TextureFormat::R32Float => 1, - - TextureFormat::Rg8Unorm - | TextureFormat::Rg8Snorm - | TextureFormat::Rg8Uint - | TextureFormat::Rg8Sint - | TextureFormat::Rg16Uint - | TextureFormat::Rg16Sint - | 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::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, - } + #[inline] + fn pixel_size(&self) -> usize { + self.describe().block_size as usize } } From 0b3b0f4d87680db94dbe08f17a7bcc45322da811 Mon Sep 17 00:00:00 2001 From: Ku95 Date: Sun, 6 Mar 2022 14:29:53 +0100 Subject: [PATCH 2/5] added create texture with data to render device --- .../bevy_render/src/renderer/render_device.rs | 22 ++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/crates/bevy_render/src/renderer/render_device.rs b/crates/bevy_render/src/renderer/render_device.rs index e5659cacd8cea..8a7f515d580d6 100644 --- a/crates/bevy_render/src/renderer/render_device.rs +++ b/crates/bevy_render/src/renderer/render_device.rs @@ -1,6 +1,9 @@ -use crate::render_resource::{ - BindGroup, BindGroupLayout, Buffer, ComputePipeline, RawRenderPipelineDescriptor, - RenderPipeline, Sampler, Texture, +use crate::{ + render_resource::{ + BindGroup, BindGroupLayout, Buffer, ComputePipeline, RawRenderPipelineDescriptor, + RenderPipeline, Sampler, Texture, + }, + renderer::RenderQueue, }; use futures_lite::future; use std::sync::Arc; @@ -129,6 +132,19 @@ impl RenderDevice { Texture::from(wgpu_texture) } + /// Creates a new [`Texture`] and initializes it with the specified data. + /// + /// `desc` specifies the general format of the texture. + pub fn create_texture_with_data( + &self, + queue: &RenderQueue, + desc: &wgpu::TextureDescriptor, + data: &[u8], + ) -> Texture { + let wgpu_texture = self.device.create_texture_with_data(queue, desc, data); + Texture::from(wgpu_texture) + } + /// Creates a new [`Sampler`]. /// /// `desc` specifies the behavior of the sampler. From bd1681feca8e83ab515bda367f241ba71094ee69 Mon Sep 17 00:00:00 2001 From: Ku95 Date: Mon, 28 Mar 2022 14:47:25 +0200 Subject: [PATCH 3/5] updated onto main --- crates/bevy_render/src/renderer/render_device.rs | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/crates/bevy_render/src/renderer/render_device.rs b/crates/bevy_render/src/renderer/render_device.rs index c4d003486c18d..158bd84bd8aea 100644 --- a/crates/bevy_render/src/renderer/render_device.rs +++ b/crates/bevy_render/src/renderer/render_device.rs @@ -9,8 +9,6 @@ use futures_lite::future; use std::sync::Arc; use wgpu::util::DeviceExt; -use super::RenderQueue; - /// This GPU device is responsible for the creation of most rendering and compute resources. #[derive(Clone)] pub struct RenderDevice { @@ -150,19 +148,6 @@ impl RenderDevice { Texture::from(wgpu_texture) } - /// Creates a new [`Texture`] and initializes it with the specified data. - /// - /// `desc` specifies the general format of the texture. - pub fn create_texture_with_data( - &self, - queue: &RenderQueue, - desc: &wgpu::TextureDescriptor, - data: &[u8], - ) -> Texture { - let wgpu_texture = self.device.create_texture_with_data(queue, desc, data); - Texture::from(wgpu_texture) - } - /// Creates a new [`Sampler`]. /// /// `desc` specifies the behavior of the sampler. From 14b2e7e3c260e6da6e29e869fff54d1d74537403 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kurt=20K=C3=BChnert?= Date: Fri, 1 Jul 2022 12:18:37 +0200 Subject: [PATCH 4/5] added support for block formats pixel size --- crates/bevy_render/src/texture/image.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/crates/bevy_render/src/texture/image.rs b/crates/bevy_render/src/texture/image.rs index 20b195efc71c4..57eed41e05420 100644 --- a/crates/bevy_render/src/texture/image.rs +++ b/crates/bevy_render/src/texture/image.rs @@ -486,7 +486,8 @@ pub trait TextureFormatPixelInfo { impl TextureFormatPixelInfo for TextureFormat { #[inline] fn pixel_size(&self) -> usize { - self.describe().block_size as usize + let info = self.describe(); + (info.block_size / (info.block_dimensions.0 * info.block_dimensions.1)) as usize } } From adb47ba086bd1ba8f090d8f8e179c1fbce68d860 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kurt=20K=C3=BChnert?= Date: Mon, 4 Jul 2022 15:35:37 +0200 Subject: [PATCH 5/5] removed pixel info in favor of texture size --- crates/bevy_pbr/src/render/mesh.rs | 66 ++---------- .../src/texture/hdr_texture_loader.rs | 26 ++--- crates/bevy_render/src/texture/image.rs | 102 +++++++++++------- .../src/texture/image_texture_conversion.rs | 24 ++++- .../src/dynamic_texture_atlas_builder.rs | 8 +- crates/bevy_sprite/src/mesh2d/mesh.rs | 65 ++--------- .../bevy_sprite/src/texture_atlas_builder.rs | 12 ++- 7 files changed, 124 insertions(+), 179 deletions(-) diff --git a/crates/bevy_pbr/src/render/mesh.rs b/crates/bevy_pbr/src/render/mesh.rs index 950d32d6fba18..816661f1c6fdb 100644 --- a/crates/bevy_pbr/src/render/mesh.rs +++ b/crates/bevy_pbr/src/render/mesh.rs @@ -9,8 +9,9 @@ use bevy_ecs::{ prelude::*, system::{lifetimeless::*, SystemParamItem, SystemState}, }; -use bevy_math::{Mat4, Vec2}; +use bevy_math::Mat4; use bevy_reflect::TypeUuid; +use bevy_render::texture::FallbackImage; use bevy_render::{ extract_component::{ComponentUniforms, DynamicUniformIndex, UniformComponentPlugin}, mesh::{ @@ -21,9 +22,7 @@ use bevy_render::{ render_phase::{EntityRenderCommand, RenderCommandResult, TrackedRenderPass}, render_resource::*, renderer::{RenderDevice, RenderQueue}, - texture::{ - BevyDefault, DefaultImageSampler, GpuImage, Image, ImageSampler, TextureFormatPixelInfo, - }, + texture::{BevyDefault, GpuImage, Image}, view::{ComputedVisibility, ViewUniform, ViewUniformOffset, ViewUniforms}, RenderApp, RenderStage, }; @@ -285,12 +284,9 @@ pub struct MeshPipeline { impl FromWorld for MeshPipeline { fn from_world(world: &mut World) -> Self { - let mut system_state: SystemState<( - Res, - Res, - Res, - )> = SystemState::new(world); - let (render_device, default_sampler, render_queue) = system_state.get_mut(world); + let mut system_state: SystemState<(Res, Res)> = + SystemState::new(world); + let (render_device, fallback_image) = system_state.get_mut(world); let clustered_forward_buffer_binding_type = render_device .get_supported_read_only_binding_type(CLUSTERED_FORWARD_STORAGE_BUFFER_COUNT); @@ -441,60 +437,12 @@ impl FromWorld for MeshPipeline { label: Some("skinned_mesh_layout"), }); - // A 1x1x1 'all 1.0' texture to use as a dummy texture to use in place of optional StandardMaterial textures - let dummy_white_gpu_image = { - let image = Image::new_fill( - Extent3d::default(), - TextureDimension::D2, - &[255u8; 4], - TextureFormat::bevy_default(), - ); - 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, - ), - } - }; MeshPipeline { view_layout, mesh_layout, skinned_mesh_layout, clustered_forward_buffer_binding_type, - dummy_white_gpu_image, + dummy_white_gpu_image: fallback_image.clone(), } } } diff --git a/crates/bevy_render/src/texture/hdr_texture_loader.rs b/crates/bevy_render/src/texture/hdr_texture_loader.rs index 81c539a061664..0ecdd6ce8b04f 100644 --- a/crates/bevy_render/src/texture/hdr_texture_loader.rs +++ b/crates/bevy_render/src/texture/hdr_texture_loader.rs @@ -1,4 +1,4 @@ -use crate::texture::{Image, TextureFormatPixelInfo}; +use crate::texture::{Image, TextureSizeInfo}; use anyhow::Result; use bevy_asset::{AssetLoader, LoadContext, LoadedAsset}; use bevy_utils::BoxedFuture; @@ -16,16 +16,17 @@ impl AssetLoader for HdrTextureLoader { ) -> BoxedFuture<'a, Result<()>> { Box::pin(async move { let format = TextureFormat::Rgba32Float; - debug_assert_eq!( - format.pixel_size(), - 4 * 4, - "Format should have 32bit x 4 size" - ); let decoder = image::codecs::hdr::HdrDecoder::new(bytes)?; let info = decoder.metadata(); let rgb_data = decoder.read_image_hdr()?; - let mut rgba_data = Vec::with_capacity(rgb_data.len() * format.pixel_size()); + + let size_in_pixels = Extent3d { + width: info.width, + height: info.height, + depth_or_array_layers: 1, + }; + let mut rgba_data = Vec::with_capacity(format.texture_size(size_in_pixels).in_bytes()); for rgb in rgb_data { let alpha = 1.0f32; @@ -36,16 +37,7 @@ impl AssetLoader for HdrTextureLoader { rgba_data.extend_from_slice(&alpha.to_ne_bytes()); } - let texture = Image::new( - Extent3d { - width: info.width, - height: info.height, - depth_or_array_layers: 1, - }, - TextureDimension::D2, - rgba_data, - format, - ); + let texture = Image::new(size_in_pixels, TextureDimension::D2, rgba_data, format); load_context.set_default_asset(LoadedAsset::new(texture)); Ok(()) diff --git a/crates/bevy_render/src/texture/image.rs b/crates/bevy_render/src/texture/image.rs index cbf782c18a0ef..6a589f217fd4d 100644 --- a/crates/bevy_render/src/texture/image.rs +++ b/crates/bevy_render/src/texture/image.rs @@ -21,7 +21,7 @@ use std::hash::Hash; use thiserror::Error; use wgpu::{ Extent3d, ImageCopyTexture, ImageDataLayout, Origin3d, TextureDimension, TextureFormat, - TextureViewDescriptor, + TextureUsages, TextureViewDescriptor, }; pub const TEXTURE_ASSET_INDEX: u64 = 0; @@ -184,22 +184,22 @@ pub struct DefaultImageSampler(pub(crate) Sampler); impl Default for Image { fn default() -> Self { - let format = wgpu::TextureFormat::bevy_default(); - let data = vec![255; format.pixel_size() as usize]; + let format = TextureFormat::bevy_default(); + let data = vec![255; format.describe().block_size as usize]; Image { data, texture_descriptor: wgpu::TextureDescriptor { - size: wgpu::Extent3d { + size: Extent3d { width: 1, height: 1, depth_or_array_layers: 1, }, format, - dimension: wgpu::TextureDimension::D2, + dimension: TextureDimension::D2, 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, }, sampler_descriptor: ImageSampler::Default, } @@ -219,7 +219,7 @@ impl Image { format: TextureFormat, ) -> Self { debug_assert_eq!( - size.volume() * format.pixel_size(), + format.texture_size(size).in_bytes(), data.len(), "Pixel data, size and format have to match", ); @@ -237,8 +237,7 @@ impl Image { /// the image data with the `pixel` data repeated multiple times. /// /// # Panics - /// Panics if the size of the `format` is not a multiple of the length of the `pixel` data. - /// do not match. + /// Panics if the size of the texture is not a multiple of the length of the `pixel` data. pub fn new_fill( size: Extent3d, dimension: TextureDimension, @@ -250,8 +249,10 @@ impl Image { value.texture_descriptor.dimension = dimension; value.resize(size); + let texture_size = format.texture_size(size); + debug_assert_eq!( - pixel.len() % format.pixel_size(), + texture_size.in_bytes() % pixel.len(), 0, "Must not have incomplete pixel data." ); @@ -284,22 +285,31 @@ impl Image { pub fn resize(&mut self, size: Extent3d) { self.texture_descriptor.size = size; self.data.resize( - size.volume() * self.texture_descriptor.format.pixel_size(), + self.texture_descriptor.format.texture_size(size).in_bytes(), 0, ); } - /// Changes the `size`, asserting that the total number of data elements (pixels) remains the - /// same. + /// Changes the `size`, asserting that the total number of data elements (pixels or blocks) + /// remains the same. /// /// # Panics - /// Panics if the `new_size` does not have the same volume as to old one. + /// Panics if the `new_size` does not have the same texture size as to old one. pub fn reinterpret_size(&mut self, new_size: Extent3d) { - assert!( - new_size.volume() == self.texture_descriptor.size.volume(), + let old_bytes = self + .texture_descriptor + .format + .texture_size(self.texture_descriptor.size) + .in_bytes(); + let new_bytes = self + .texture_descriptor + .format + .texture_size(new_size) + .in_bytes(); + assert_eq!( + old_bytes, new_bytes, "Incompatible sizes: old = {:?} new = {:?}", - self.texture_descriptor.size, - new_size + old_bytes, new_bytes ); self.texture_descriptor.size = new_size; @@ -461,29 +471,46 @@ impl<'a> ImageType<'a> { } } -/// Used to calculate the volume of an item. -pub trait Volume { - fn volume(&self) -> usize; +/// The size of a texture. +pub struct TextureSize { + /// The size of the texture in blocks. + /// The size in pixels is rounded up to fit the block dimension. + pub size_in_blocks: Extent3d, + /// Size in bytes of a "block" of texels. This is the size per pixel on uncompressed textures. + pub block_size: u32, } -impl Volume for Extent3d { - /// Calculates the volume of the [`Extent3d`]. - fn volume(&self) -> usize { - (self.width * self.height * self.depth_or_array_layers) as usize +impl TextureSize { + /// Calculates the size of the entire texture in bytes. + pub fn in_bytes(&self) -> usize { + (self.size_in_blocks.depth_or_array_layers + * self.size_in_blocks.width + * self.size_in_blocks.height + * self.block_size) as usize } } -/// Extends the wgpu [`TextureFormat`] with information about the pixel. -pub trait TextureFormatPixelInfo { - /// Returns the size of a pixel of the format in bytes. - fn pixel_size(&self) -> usize; +/// Extends the wgpu [`TextureFormat`] with information about the texture size. +pub trait TextureSizeInfo { + fn texture_size(&self, size_in_pixels: Extent3d) -> TextureSize; } -impl TextureFormatPixelInfo for TextureFormat { - #[inline] - fn pixel_size(&self) -> usize { +impl TextureSizeInfo for TextureFormat { + /// Calculates the size of the texture in blocks. + fn texture_size(&self, size_in_pixels: Extent3d) -> TextureSize { let info = self.describe(); - (info.block_size / (info.block_dimensions.0 * info.block_dimensions.1)) as usize + let size_in_blocks = Extent3d { + width: (size_in_pixels.width + info.block_dimensions.0 as u32 - 1) + / info.block_dimensions.0 as u32, + height: (size_in_pixels.height + info.block_dimensions.1 as u32 - 1) + / info.block_dimensions.1 as u32, + depth_or_array_layers: size_in_pixels.depth_or_array_layers, + }; + + TextureSize { + size_in_blocks, + block_size: info.block_size as u32, + } } } @@ -525,7 +552,10 @@ impl RenderAsset for Image { ) } else { let texture = render_device.create_texture(&image.texture_descriptor); - let format_size = image.texture_descriptor.format.pixel_size(); + let texture_size = image + .texture_descriptor + .format + .texture_size(image.texture_descriptor.size); render_queue.write_texture( ImageCopyTexture { texture: &texture, @@ -538,12 +568,12 @@ impl RenderAsset for Image { offset: 0, bytes_per_row: Some( std::num::NonZeroU32::new( - image.texture_descriptor.size.width * format_size as u32, + (texture_size.size_in_blocks.width * texture_size.block_size) as u32, ) .unwrap(), ), rows_per_image: if image.texture_descriptor.size.depth_or_array_layers > 1 { - std::num::NonZeroU32::new(image.texture_descriptor.size.height) + std::num::NonZeroU32::new(texture_size.size_in_blocks.height) } else { None }, diff --git a/crates/bevy_render/src/texture/image_texture_conversion.rs b/crates/bevy_render/src/texture/image_texture_conversion.rs index 44611faafcddb..85a035d174e2d 100644 --- a/crates/bevy_render/src/texture/image_texture_conversion.rs +++ b/crates/bevy_render/src/texture/image_texture_conversion.rs @@ -1,4 +1,4 @@ -use crate::texture::{Image, TextureFormatPixelInfo}; +use crate::texture::{Image, TextureSizeInfo}; use image::{DynamicImage, ImageBuffer}; use wgpu::{Extent3d, TextureDimension, TextureFormat}; @@ -83,8 +83,15 @@ pub(crate) fn image_to_texture(dyn_img: DynamicImage, is_srgb: bool) -> Image { height = image.height(); format = TextureFormat::Rgba16Uint; - let mut local_data = - Vec::with_capacity(width as usize * height as usize * format.pixel_size()); + let mut local_data = Vec::with_capacity( + format + .texture_size(Extent3d { + width, + height, + depth_or_array_layers: 1, + }) + .in_bytes(), + ); for pixel in image.into_raw().chunks_exact(3) { // TODO: use the array_chunks method once stabilised @@ -116,8 +123,15 @@ pub(crate) fn image_to_texture(dyn_img: DynamicImage, is_srgb: bool) -> Image { height = image.height(); format = TextureFormat::Rgba32Float; - let mut local_data = - Vec::with_capacity(width as usize * height as usize * format.pixel_size()); + let mut local_data = Vec::with_capacity( + format + .texture_size(Extent3d { + width, + height, + depth_or_array_layers: 1, + }) + .in_bytes(), + ); for pixel in image.into_raw().chunks_exact(3) { // TODO: use the array_chunks method once stabilised diff --git a/crates/bevy_sprite/src/dynamic_texture_atlas_builder.rs b/crates/bevy_sprite/src/dynamic_texture_atlas_builder.rs index 2cdf99a1710f2..21ef3ff165372 100644 --- a/crates/bevy_sprite/src/dynamic_texture_atlas_builder.rs +++ b/crates/bevy_sprite/src/dynamic_texture_atlas_builder.rs @@ -1,7 +1,7 @@ use crate::{Rect, TextureAtlas}; use bevy_asset::Assets; use bevy_math::Vec2; -use bevy_render::texture::{Image, TextureFormatPixelInfo}; +use bevy_render::texture::Image; use guillotiere::{size2, Allocation, AtlasAllocator}; pub struct DynamicTextureAtlasBuilder { @@ -73,7 +73,11 @@ impl DynamicTextureAtlasBuilder { rect.max.y -= self.padding; let atlas_width = atlas_texture.texture_descriptor.size.width as usize; let rect_width = rect.width() as usize; - let format_size = atlas_texture.texture_descriptor.format.pixel_size(); + let format_size = atlas_texture + .texture_descriptor + .format + .describe() + .block_size as usize; // only works for uncompressed textures for (texture_y, bound_y) in (rect.min.y..rect.max.y).map(|i| i as usize).enumerate() { let begin = (bound_y * atlas_width + rect.min.x as usize) * format_size; diff --git a/crates/bevy_sprite/src/mesh2d/mesh.rs b/crates/bevy_sprite/src/mesh2d/mesh.rs index 7a6ebfeadff93..bba60d9133ca1 100644 --- a/crates/bevy_sprite/src/mesh2d/mesh.rs +++ b/crates/bevy_sprite/src/mesh2d/mesh.rs @@ -4,18 +4,17 @@ use bevy_ecs::{ prelude::*, system::{lifetimeless::*, SystemParamItem, SystemState}, }; -use bevy_math::{Mat4, Vec2}; +use bevy_math::Mat4; use bevy_reflect::{Reflect, TypeUuid}; +use bevy_render::texture::FallbackImage; use bevy_render::{ extract_component::{ComponentUniforms, DynamicUniformIndex, UniformComponentPlugin}, mesh::{GpuBufferInfo, Mesh, MeshVertexBufferLayout}, render_asset::RenderAssets, render_phase::{EntityRenderCommand, RenderCommandResult, TrackedRenderPass}, render_resource::*, - renderer::{RenderDevice, RenderQueue}, - texture::{ - BevyDefault, DefaultImageSampler, GpuImage, Image, ImageSampler, TextureFormatPixelInfo, - }, + renderer::RenderDevice, + texture::{BevyDefault, GpuImage, Image}, view::{ComputedVisibility, ExtractedView, ViewUniform, ViewUniformOffset, ViewUniforms}, RenderApp, RenderStage, }; @@ -150,9 +149,9 @@ pub struct Mesh2dPipeline { impl FromWorld for Mesh2dPipeline { fn from_world(world: &mut World) -> Self { - let mut system_state: SystemState<(Res, Res)> = + let mut system_state: SystemState<(Res, Res)> = SystemState::new(world); - let (render_device, default_sampler) = system_state.get_mut(world); + let (render_device, fallback_image) = system_state.get_mut(world); let view_layout = render_device.create_bind_group_layout(&BindGroupLayoutDescriptor { entries: &[ // View @@ -183,59 +182,11 @@ impl FromWorld for Mesh2dPipeline { }], label: Some("mesh2d_layout"), }); - // A 1x1x1 'all 1.0' texture to use as a dummy texture to use in place of optional StandardMaterial textures - let dummy_white_gpu_image = { - let image = Image::new_fill( - Extent3d::default(), - TextureDimension::D2, - &[255u8; 4], - TextureFormat::bevy_default(), - ); - 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(); - let render_queue = world.resource_mut::(); - 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, - ), - } - }; + Mesh2dPipeline { view_layout, mesh_layout, - dummy_white_gpu_image, + dummy_white_gpu_image: fallback_image.clone(), } } } diff --git a/crates/bevy_sprite/src/texture_atlas_builder.rs b/crates/bevy_sprite/src/texture_atlas_builder.rs index 7aa87141be93a..fb7b1b37fe0e2 100644 --- a/crates/bevy_sprite/src/texture_atlas_builder.rs +++ b/crates/bevy_sprite/src/texture_atlas_builder.rs @@ -3,7 +3,7 @@ use bevy_log::{debug, error, warn}; use bevy_math::Vec2; use bevy_render::{ render_resource::{Extent3d, TextureDimension, TextureFormat}, - texture::{Image, TextureFormatPixelInfo}, + texture::Image, }; use bevy_utils::HashMap; use rectangle_pack::{ @@ -102,7 +102,11 @@ impl TextureAtlasBuilder { let rect_x = packed_location.x() as usize; let rect_y = packed_location.y() as usize; let atlas_width = atlas_texture.texture_descriptor.size.width as usize; - let format_size = atlas_texture.texture_descriptor.format.pixel_size(); + let format_size = atlas_texture + .texture_descriptor + .format + .describe() + .block_size as usize; // only works for uncompressed textures for (texture_y, bound_y) in (rect_y..rect_y + rect_height).enumerate() { let begin = (bound_y * atlas_width + rect_x) * format_size; @@ -186,7 +190,9 @@ impl TextureAtlasBuilder { TextureDimension::D2, vec![ 0; - self.format.pixel_size() * (current_width * current_height) as usize + (self.format.describe().block_size as u32 + * current_width + * current_height) as usize ], self.format, );