Skip to content

Commit

Permalink
remove pixel size usages
Browse files Browse the repository at this point in the history
Co-authored-by: Kurt Kühnert <kurt@kuhnert.dev>
  • Loading branch information
hymm and Kurt Kühnert committed Nov 30, 2022
1 parent 9781f12 commit 9f8295a
Show file tree
Hide file tree
Showing 8 changed files with 112 additions and 49 deletions.
10 changes: 5 additions & 5 deletions crates/bevy_pbr/src/render/mesh.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,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, BytesPerRow, DefaultImageSampler, GpuImage, Image, ImageSampler},
view::{ComputedVisibility, ViewTarget, ViewUniform, ViewUniformOffset, ViewUniforms},
Extract, RenderApp, RenderStage,
};
Expand Down Expand Up @@ -446,7 +444,6 @@ impl FromWorld for MeshPipeline {
ImageSampler::Descriptor(descriptor) => render_device.create_sampler(&descriptor),
};

let format_size = image.texture_descriptor.format.pixel_size();
render_queue.write_texture(
ImageCopyTexture {
texture: &texture,
Expand All @@ -459,7 +456,10 @@ impl FromWorld for MeshPipeline {
offset: 0,
bytes_per_row: Some(
std::num::NonZeroU32::new(
image.texture_descriptor.size.width * format_size as u32,
image
.texture_descriptor
.size
.bytes_per_row(image.texture_descriptor.format),
)
.unwrap(),
),
Expand Down
10 changes: 3 additions & 7 deletions crates/bevy_render/src/texture/hdr_texture_loader.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::texture::{Image, TextureFormatPixelInfo};
use crate::texture::Image;
use anyhow::Result;
use bevy_asset::{AssetLoader, LoadContext, LoadedAsset};
use bevy_utils::BoxedFuture;
Expand All @@ -16,16 +16,12 @@ 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 mut rgba_data =
Vec::with_capacity(rgb_data.len() * format.describe().block_size as usize);

for rgb in rgb_data {
let alpha = 1.0f32;
Expand Down
60 changes: 43 additions & 17 deletions crates/bevy_render/src/texture/image.rs
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,8 @@ 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()];
// TODO: check if this breaks if bevy_default is a compressed texture
let data = vec![255; format.describe().block_size as usize];
Image {
data,
texture_descriptor: wgpu::TextureDescriptor {
Expand Down Expand Up @@ -207,7 +208,7 @@ impl Image {
format: TextureFormat,
) -> Self {
debug_assert_eq!(
size.volume() * format.pixel_size(),
size.total_bytes(format) as usize,
data.len(),
"Pixel data, size and format have to match",
);
Expand Down Expand Up @@ -239,7 +240,7 @@ impl Image {
value.resize(size);

debug_assert_eq!(
pixel.len() % format.pixel_size(),
pixel.len() % format.describe().block_size as usize,
0,
"Must not have incomplete pixel data."
);
Expand Down Expand Up @@ -271,10 +272,8 @@ impl Image {
/// Does not properly resize the contents of the image, but only its internal `data` buffer.
pub fn resize(&mut self, size: Extent3d) {
self.texture_descriptor.size = size;
self.data.resize(
size.volume() * self.texture_descriptor.format.pixel_size(),
0,
);
self.data
.resize(size.total_bytes(self.texture_descriptor.format) as usize, 0);
}

/// Changes the `size`, asserting that the total number of data elements (pixels) remains the
Expand Down Expand Up @@ -467,15 +466,35 @@ impl Volume for Extent3d {
}
}

/// Extends the wgpu [`TextureFormat`] with information about the pixel.
pub trait TextureFormatPixelInfo {
/// Returns the size in bytes of a pixel of the format.
fn pixel_size(&self) -> usize;
pub trait BytesPerRow {
fn bytes_per_row(&self, format: TextureFormat) -> u32;
}

impl BytesPerRow for Extent3d {
fn bytes_per_row(&self, format: TextureFormat) -> u32 {
let info = format.describe();
self.physical_size(format).width * info.block_size as u32 / info.block_dimensions.0 as u32
}
}

pub trait TotalBytes {
fn total_bytes(&self, format: TextureFormat) -> u32;
}

impl TextureFormatPixelInfo for TextureFormat {
fn pixel_size(&self) -> usize {
self.describe().block_size.into()
impl TotalBytes for Extent3d {
fn total_bytes(&self, format: TextureFormat) -> u32 {
self.rows_per_image(format) * self.bytes_per_row(format) * self.depth_or_array_layers
}
}

pub trait RowsPerImage {
fn rows_per_image(&self, format: TextureFormat) -> u32;
}

impl RowsPerImage for Extent3d {
fn rows_per_image(&self, format: TextureFormat) -> u32 {
let info = format.describe();
self.physical_size(format).height / info.block_dimensions.1 as u32
}
}

Expand Down Expand Up @@ -517,7 +536,6 @@ impl RenderAsset for Image {
)
} else {
let texture = render_device.create_texture(&image.texture_descriptor);
let format_size = image.texture_descriptor.format.pixel_size();
render_queue.write_texture(
ImageCopyTexture {
texture: &texture,
Expand All @@ -530,12 +548,20 @@ impl RenderAsset for Image {
offset: 0,
bytes_per_row: Some(
std::num::NonZeroU32::new(
image.texture_descriptor.size.width * format_size as u32,
image
.texture_descriptor
.size
.bytes_per_row(image.texture_descriptor.format),
)
.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(
image
.texture_descriptor
.size
.rows_per_image(image.texture_descriptor.format),
)
} else {
None
},
Expand Down
12 changes: 7 additions & 5 deletions crates/bevy_render/src/texture/image_texture_conversion.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::texture::{Image, TextureFormatPixelInfo};
use crate::texture::Image;
use anyhow::anyhow;
use image::{DynamicImage, ImageBuffer};
use wgpu::{Extent3d, TextureDimension, TextureFormat};
Expand Down Expand Up @@ -84,8 +84,9 @@ impl 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(
width as usize * height as usize * format.describe().block_size as usize,
);

for pixel in image.into_raw().chunks_exact(3) {
// TODO: use the array_chunks method once stabilised
Expand Down Expand Up @@ -117,8 +118,9 @@ impl 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(
width as usize * height as usize * format.describe().block_size as usize,
);

for pixel in image.into_raw().chunks_exact(3) {
// TODO: use the array_chunks method once stabilised
Expand Down
18 changes: 16 additions & 2 deletions crates/bevy_sprite/src/dynamic_texture_atlas_builder.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use crate::TextureAtlas;
use bevy_asset::Assets;
use bevy_math::{IVec2, Rect, Vec2};
use bevy_render::texture::{Image, TextureFormatPixelInfo};
use bevy_render::texture::Image;
use guillotiere::{size2, Allocation, AtlasAllocator};

pub struct DynamicTextureAtlasBuilder {
Expand Down Expand Up @@ -67,12 +67,26 @@ impl DynamicTextureAtlasBuilder {
allocation: Allocation,
texture: &Image,
) {
debug_assert_eq!(
atlas_texture
.texture_descriptor
.format
.describe()
.block_dimensions,
(1, 1),
"Compressed textures are unsupported"
);

let mut rect = allocation.rectangle;
rect.max.x -= self.padding;
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;

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;
Expand Down
10 changes: 5 additions & 5 deletions crates/bevy_sprite/src/mesh2d/mesh.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,7 @@ use bevy_render::{
render_phase::{EntityRenderCommand, RenderCommandResult, TrackedRenderPass},
render_resource::*,
renderer::{RenderDevice, RenderQueue},
texture::{
BevyDefault, DefaultImageSampler, GpuImage, Image, ImageSampler, TextureFormatPixelInfo,
},
texture::{BevyDefault, BytesPerRow, DefaultImageSampler, GpuImage, Image, ImageSampler},
view::{
ComputedVisibility, ExtractedView, ViewTarget, ViewUniform, ViewUniformOffset, ViewUniforms,
},
Expand Down Expand Up @@ -218,7 +216,6 @@ impl FromWorld for Mesh2dPipeline {
ImageSampler::Descriptor(descriptor) => render_device.create_sampler(&descriptor),
};

let format_size = image.texture_descriptor.format.pixel_size();
let render_queue = world.resource_mut::<RenderQueue>();
render_queue.write_texture(
ImageCopyTexture {
Expand All @@ -232,7 +229,10 @@ impl FromWorld for Mesh2dPipeline {
offset: 0,
bytes_per_row: Some(
std::num::NonZeroU32::new(
image.texture_descriptor.size.width * format_size as u32,
image
.texture_descriptor
.size
.bytes_per_row(image.texture_descriptor.format),
)
.unwrap(),
),
Expand Down
10 changes: 5 additions & 5 deletions crates/bevy_sprite/src/render/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,7 @@ use bevy_render::{
},
render_resource::*,
renderer::{RenderDevice, RenderQueue},
texture::{
BevyDefault, DefaultImageSampler, GpuImage, Image, ImageSampler, TextureFormatPixelInfo,
},
texture::{BevyDefault, BytesPerRow, DefaultImageSampler, GpuImage, Image, ImageSampler},
view::{
ComputedVisibility, ExtractedView, Msaa, ViewTarget, ViewUniform, ViewUniformOffset,
ViewUniforms, VisibleEntities,
Expand Down Expand Up @@ -100,7 +98,6 @@ impl FromWorld for SpritePipeline {
ImageSampler::Descriptor(descriptor) => render_device.create_sampler(&descriptor),
};

let format_size = image.texture_descriptor.format.pixel_size();
render_queue.write_texture(
ImageCopyTexture {
texture: &texture,
Expand All @@ -113,7 +110,10 @@ impl FromWorld for SpritePipeline {
offset: 0,
bytes_per_row: Some(
std::num::NonZeroU32::new(
image.texture_descriptor.size.width * format_size as u32,
image
.texture_descriptor
.size
.bytes_per_row(image.texture_descriptor.format),
)
.unwrap(),
),
Expand Down
31 changes: 28 additions & 3 deletions crates/bevy_sprite/src/texture_atlas_builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use bevy_log::{debug, error, warn};
use bevy_math::{Rect, Vec2};
use bevy_render::{
render_resource::{Extent3d, TextureDimension, TextureFormat},
texture::{Image, TextureFormatPixelInfo},
texture::Image,
};
use bevy_utils::HashMap;
use rectangle_pack::{
Expand Down Expand Up @@ -97,12 +97,26 @@ impl TextureAtlasBuilder {
texture: &Image,
packed_location: &PackedLocation,
) {
debug_assert_eq!(
atlas_texture
.texture_descriptor
.format
.describe()
.block_dimensions,
(1, 1),
"Compressed textures are unsupported"
);

let rect_width = packed_location.width() as usize;
let rect_height = packed_location.height() as usize;
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;

for (texture_y, bound_y) in (rect_y..rect_y + rect_height).enumerate() {
let begin = (bound_y * atlas_width + rect_x) * format_size;
Expand Down Expand Up @@ -161,6 +175,16 @@ impl TextureAtlasBuilder {
let mut rect_placements = None;
let mut atlas_texture = Image::default();

debug_assert_eq!(
atlas_texture
.texture_descriptor
.format
.describe()
.block_dimensions,
(1, 1),
"Compressed textures are unsupported"
);

while rect_placements.is_none() {
if current_width > max_width || current_height > max_height {
break;
Expand All @@ -186,7 +210,8 @@ impl TextureAtlasBuilder {
TextureDimension::D2,
vec![
0;
self.format.pixel_size() * (current_width * current_height) as usize
self.format.describe().block_size as usize
* (current_width * current_height) as usize
],
self.format,
);
Expand Down

0 comments on commit 9f8295a

Please sign in to comment.