Change GpuImage::size
from UVec2
to Extent3d
(#16815)
# Objective When preparing `GpuImage`s, we currently discard the `depth_or_array_layers` of the `Image`'s size by converting it into a `UVec2`. Fixes #16715. ## Solution Change `GpuImage::size` to `Extent3d`, and just pass that through when creating `GpuImage`s. Also copy the `aspect_ratio`, and `size` (now `size_2d` for disambiguation from the field) functions from `Image` to `GpuImage` for ease of use with 2D textures. I originally copied all size-related functions (like `width`, and `height`), but i think they are unnecessary considering how visible the `size` field on `GpuImage` is compared to `Image`. ## Testing Tested via `cargo r -p ci` for everything except docs, when generating docs it keeps spitting out a ton of ``` error[E0554]: `#![feature]` may not be used on the stable release channel --> crates/bevy_dylib/src/lib.rs:1:21 | 1 | #![cfg_attr(docsrs, feature(doc_auto_cfg))] | ``` Not sure why this is happening, but it also happens without my changes, so it's almost certainly some strange issue specific to my machine. ## Migration Guide - `GpuImage::size` is now an `Extent3d`. To easily get 2D size, use `size_2d()`.
This commit is contained in:
parent
bfa6553f9c
commit
73d68d60bb
@ -1523,7 +1523,7 @@ impl FromWorld for MeshPipeline {
|
|||||||
texture_view,
|
texture_view,
|
||||||
texture_format: image.texture_descriptor.format,
|
texture_format: image.texture_descriptor.format,
|
||||||
sampler,
|
sampler,
|
||||||
size: image.size(),
|
size: image.texture_descriptor.size,
|
||||||
mip_level_count: image.texture_descriptor.mip_level_count,
|
mip_level_count: image.texture_descriptor.mip_level_count,
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -23,7 +23,7 @@ use bevy_ecs::{
|
|||||||
use bevy_image::{Image, TextureFormatPixelInfo};
|
use bevy_image::{Image, TextureFormatPixelInfo};
|
||||||
use bevy_reflect::Reflect;
|
use bevy_reflect::Reflect;
|
||||||
use bevy_render_macros::ExtractComponent;
|
use bevy_render_macros::ExtractComponent;
|
||||||
use bevy_utils::{default, tracing::warn, HashMap};
|
use bevy_utils::{tracing::warn, HashMap};
|
||||||
use encase::internal::ReadFrom;
|
use encase::internal::ReadFrom;
|
||||||
use encase::private::Reader;
|
use encase::private::Reader;
|
||||||
use encase::ShaderType;
|
use encase::ShaderType;
|
||||||
@ -239,17 +239,16 @@ fn prepare_buffers(
|
|||||||
match readback {
|
match readback {
|
||||||
Readback::Texture(image) => {
|
Readback::Texture(image) => {
|
||||||
if let Some(gpu_image) = gpu_images.get(image) {
|
if let Some(gpu_image) = gpu_images.get(image) {
|
||||||
let size = Extent3d {
|
let layout = layout_data(
|
||||||
width: gpu_image.size.x,
|
gpu_image.size.width,
|
||||||
height: gpu_image.size.y,
|
gpu_image.size.height,
|
||||||
..default()
|
gpu_image.texture_format,
|
||||||
};
|
);
|
||||||
let layout = layout_data(size.width, size.height, gpu_image.texture_format);
|
|
||||||
let buffer = buffer_pool.get(
|
let buffer = buffer_pool.get(
|
||||||
&render_device,
|
&render_device,
|
||||||
get_aligned_size(
|
get_aligned_size(
|
||||||
size.width,
|
gpu_image.size.width,
|
||||||
size.height,
|
gpu_image.size.height,
|
||||||
gpu_image.texture_format.pixel_size() as u32,
|
gpu_image.texture_format.pixel_size() as u32,
|
||||||
) as u64,
|
) as u64,
|
||||||
);
|
);
|
||||||
@ -259,7 +258,7 @@ fn prepare_buffers(
|
|||||||
src: ReadbackSource::Texture {
|
src: ReadbackSource::Texture {
|
||||||
texture: gpu_image.texture.clone(),
|
texture: gpu_image.texture.clone(),
|
||||||
layout,
|
layout,
|
||||||
size,
|
size: gpu_image.size,
|
||||||
},
|
},
|
||||||
buffer,
|
buffer,
|
||||||
rx,
|
rx,
|
||||||
|
@ -135,7 +135,7 @@ fn fallback_image_new(
|
|||||||
texture_view,
|
texture_view,
|
||||||
texture_format: image.texture_descriptor.format,
|
texture_format: image.texture_descriptor.format,
|
||||||
sampler,
|
sampler,
|
||||||
size: image.size(),
|
size: image.texture_descriptor.size,
|
||||||
mip_level_count: image.texture_descriptor.mip_level_count,
|
mip_level_count: image.texture_descriptor.mip_level_count,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,8 +6,8 @@ use crate::{
|
|||||||
use bevy_asset::AssetId;
|
use bevy_asset::AssetId;
|
||||||
use bevy_ecs::system::{lifetimeless::SRes, SystemParamItem};
|
use bevy_ecs::system::{lifetimeless::SRes, SystemParamItem};
|
||||||
use bevy_image::{Image, ImageSampler};
|
use bevy_image::{Image, ImageSampler};
|
||||||
use bevy_math::UVec2;
|
use bevy_math::{AspectRatio, UVec2};
|
||||||
use wgpu::{TextureFormat, TextureViewDescriptor};
|
use wgpu::{Extent3d, TextureFormat, TextureViewDescriptor};
|
||||||
|
|
||||||
/// The GPU-representation of an [`Image`].
|
/// The GPU-representation of an [`Image`].
|
||||||
/// Consists of the [`Texture`], its [`TextureView`] and the corresponding [`Sampler`], and the texture's size.
|
/// Consists of the [`Texture`], its [`TextureView`] and the corresponding [`Sampler`], and the texture's size.
|
||||||
@ -17,7 +17,7 @@ pub struct GpuImage {
|
|||||||
pub texture_view: TextureView,
|
pub texture_view: TextureView,
|
||||||
pub texture_format: TextureFormat,
|
pub texture_format: TextureFormat,
|
||||||
pub sampler: Sampler,
|
pub sampler: Sampler,
|
||||||
pub size: UVec2,
|
pub size: Extent3d,
|
||||||
pub mip_level_count: u32,
|
pub mip_level_count: u32,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -53,7 +53,6 @@ impl RenderAsset for GpuImage {
|
|||||||
&image.data,
|
&image.data,
|
||||||
);
|
);
|
||||||
|
|
||||||
let size = image.size();
|
|
||||||
let texture_view = texture.create_view(
|
let texture_view = texture.create_view(
|
||||||
image
|
image
|
||||||
.texture_view_descriptor
|
.texture_view_descriptor
|
||||||
@ -73,8 +72,24 @@ impl RenderAsset for GpuImage {
|
|||||||
texture_view,
|
texture_view,
|
||||||
texture_format: image.texture_descriptor.format,
|
texture_format: image.texture_descriptor.format,
|
||||||
sampler,
|
sampler,
|
||||||
size,
|
size: image.texture_descriptor.size,
|
||||||
mip_level_count: image.texture_descriptor.mip_level_count,
|
mip_level_count: image.texture_descriptor.mip_level_count,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl GpuImage {
|
||||||
|
/// Returns the aspect ratio (width / height) of a 2D image.
|
||||||
|
#[inline]
|
||||||
|
pub fn aspect_ratio(&self) -> AspectRatio {
|
||||||
|
AspectRatio::try_from_pixels(self.size.width, self.size.height).expect(
|
||||||
|
"Failed to calculate aspect ratio: Image dimensions must be positive, non-zero values",
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the size of a 2D image.
|
||||||
|
#[inline]
|
||||||
|
pub fn size_2d(&self) -> UVec2 {
|
||||||
|
UVec2::new(self.size.width, self.size.height)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -302,13 +302,8 @@ fn prepare_screenshots(
|
|||||||
continue;
|
continue;
|
||||||
};
|
};
|
||||||
let format = gpu_image.texture_format;
|
let format = gpu_image.texture_format;
|
||||||
let size = Extent3d {
|
|
||||||
width: gpu_image.size.x,
|
|
||||||
height: gpu_image.size.y,
|
|
||||||
..default()
|
|
||||||
};
|
|
||||||
let (texture_view, state) = prepare_screenshot_state(
|
let (texture_view, state) = prepare_screenshot_state(
|
||||||
size,
|
gpu_image.size,
|
||||||
format,
|
format,
|
||||||
&render_device,
|
&render_device,
|
||||||
&screenshot_pipeline,
|
&screenshot_pipeline,
|
||||||
@ -542,8 +537,8 @@ pub(crate) fn submit_screenshot_commands(world: &World, encoder: &mut CommandEnc
|
|||||||
warn!("Unknown image for screenshot, skipping: {:?}", image);
|
warn!("Unknown image for screenshot, skipping: {:?}", image);
|
||||||
continue;
|
continue;
|
||||||
};
|
};
|
||||||
let width = gpu_image.size.x;
|
let width = gpu_image.size.width;
|
||||||
let height = gpu_image.size.y;
|
let height = gpu_image.size.height;
|
||||||
let texture_format = gpu_image.texture_format;
|
let texture_format = gpu_image.texture_format;
|
||||||
let texture_view = gpu_image.texture_view.deref();
|
let texture_view = gpu_image.texture_view.deref();
|
||||||
render_screenshot(
|
render_screenshot(
|
||||||
|
@ -313,7 +313,7 @@ impl FromWorld for Mesh2dPipeline {
|
|||||||
texture_view,
|
texture_view,
|
||||||
texture_format: image.texture_descriptor.format,
|
texture_format: image.texture_descriptor.format,
|
||||||
sampler,
|
sampler,
|
||||||
size: image.size(),
|
size: image.texture_descriptor.size,
|
||||||
mip_level_count: image.texture_descriptor.mip_level_count,
|
mip_level_count: image.texture_descriptor.mip_level_count,
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -117,7 +117,7 @@ impl FromWorld for SpritePipeline {
|
|||||||
texture_view,
|
texture_view,
|
||||||
texture_format: image.texture_descriptor.format,
|
texture_format: image.texture_descriptor.format,
|
||||||
sampler,
|
sampler,
|
||||||
size: image.size(),
|
size: image.texture_descriptor.size,
|
||||||
mip_level_count: image.texture_descriptor.mip_level_count,
|
mip_level_count: image.texture_descriptor.mip_level_count,
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -676,7 +676,7 @@ pub fn prepare_sprite_image_bind_groups(
|
|||||||
continue;
|
continue;
|
||||||
};
|
};
|
||||||
|
|
||||||
batch_image_size = gpu_image.size.as_vec2();
|
batch_image_size = gpu_image.size_2d().as_vec2();
|
||||||
batch_image_handle = extracted_sprite.image_handle_id;
|
batch_image_handle = extracted_sprite.image_handle_id;
|
||||||
image_bind_groups
|
image_bind_groups
|
||||||
.values
|
.values
|
||||||
|
@ -1052,7 +1052,7 @@ pub fn prepare_uinodes(
|
|||||||
);
|
);
|
||||||
// Rescale atlases. This is done here because we need texture data that might not be available in Extract.
|
// Rescale atlases. This is done here because we need texture data that might not be available in Extract.
|
||||||
let atlas_extent = atlas_scaling
|
let atlas_extent = atlas_scaling
|
||||||
.map(|scaling| image.size.as_vec2() * scaling)
|
.map(|scaling| image.size_2d().as_vec2() * scaling)
|
||||||
.unwrap_or(uinode_rect.max);
|
.unwrap_or(uinode_rect.max);
|
||||||
if *flip_x {
|
if *flip_x {
|
||||||
core::mem::swap(&mut uinode_rect.max.x, &mut uinode_rect.min.x);
|
core::mem::swap(&mut uinode_rect.max.x, &mut uinode_rect.min.x);
|
||||||
@ -1127,7 +1127,7 @@ pub fn prepare_uinodes(
|
|||||||
.get(extracted_uinode.image)
|
.get(extracted_uinode.image)
|
||||||
.expect("Image was checked during batching and should still exist");
|
.expect("Image was checked during batching and should still exist");
|
||||||
|
|
||||||
let atlas_extent = image.size.as_vec2() * *atlas_scaling;
|
let atlas_extent = image.size_2d().as_vec2() * *atlas_scaling;
|
||||||
|
|
||||||
let color = extracted_uinode.color.to_f32_array();
|
let color = extracted_uinode.color.to_f32_array();
|
||||||
for glyph in &extracted_uinodes.glyphs[range.clone()] {
|
for glyph in &extracted_uinodes.glyphs[range.clone()] {
|
||||||
|
@ -442,7 +442,7 @@ pub fn prepare_ui_slices(
|
|||||||
if let Some(gpu_image) = gpu_images.get(texture_slices.image) {
|
if let Some(gpu_image) = gpu_images.get(texture_slices.image) {
|
||||||
batch_item_index = item_index;
|
batch_item_index = item_index;
|
||||||
batch_image_handle = texture_slices.image;
|
batch_image_handle = texture_slices.image;
|
||||||
batch_image_size = gpu_image.size.as_vec2();
|
batch_image_size = gpu_image.size_2d().as_vec2();
|
||||||
|
|
||||||
let new_batch = UiTextureSlicerBatch {
|
let new_batch = UiTextureSlicerBatch {
|
||||||
range: vertices_index..vertices_index,
|
range: vertices_index..vertices_index,
|
||||||
@ -475,7 +475,7 @@ pub fn prepare_ui_slices(
|
|||||||
{
|
{
|
||||||
if let Some(gpu_image) = gpu_images.get(texture_slices.image) {
|
if let Some(gpu_image) = gpu_images.get(texture_slices.image) {
|
||||||
batch_image_handle = texture_slices.image;
|
batch_image_handle = texture_slices.image;
|
||||||
batch_image_size = gpu_image.size.as_vec2();
|
batch_image_size = gpu_image.size_2d().as_vec2();
|
||||||
existing_batch.as_mut().unwrap().1.image = texture_slices.image;
|
existing_batch.as_mut().unwrap().1.image = texture_slices.image;
|
||||||
|
|
||||||
image_bind_groups
|
image_bind_groups
|
||||||
|
@ -367,15 +367,9 @@ impl render_graph::Node for ImageCopyDriver {
|
|||||||
// That's why image in buffer can be little bit wider
|
// That's why image in buffer can be little bit wider
|
||||||
// This should be taken into account at copy from buffer stage
|
// This should be taken into account at copy from buffer stage
|
||||||
let padded_bytes_per_row = RenderDevice::align_copy_bytes_per_row(
|
let padded_bytes_per_row = RenderDevice::align_copy_bytes_per_row(
|
||||||
(src_image.size.x as usize / block_dimensions.0 as usize) * block_size as usize,
|
(src_image.size.width as usize / block_dimensions.0 as usize) * block_size as usize,
|
||||||
);
|
);
|
||||||
|
|
||||||
let texture_extent = Extent3d {
|
|
||||||
width: src_image.size.x,
|
|
||||||
height: src_image.size.y,
|
|
||||||
depth_or_array_layers: 1,
|
|
||||||
};
|
|
||||||
|
|
||||||
encoder.copy_texture_to_buffer(
|
encoder.copy_texture_to_buffer(
|
||||||
src_image.texture.as_image_copy(),
|
src_image.texture.as_image_copy(),
|
||||||
ImageCopyBuffer {
|
ImageCopyBuffer {
|
||||||
@ -390,7 +384,7 @@ impl render_graph::Node for ImageCopyDriver {
|
|||||||
rows_per_image: None,
|
rows_per_image: None,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
texture_extent,
|
src_image.size,
|
||||||
);
|
);
|
||||||
|
|
||||||
let render_queue = world.get_resource::<RenderQueue>().unwrap();
|
let render_queue = world.get_resource::<RenderQueue>().unwrap();
|
||||||
|
Loading…
Reference in New Issue
Block a user