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_format: image.texture_descriptor.format,
|
||||
sampler,
|
||||
size: image.size(),
|
||||
size: image.texture_descriptor.size,
|
||||
mip_level_count: image.texture_descriptor.mip_level_count,
|
||||
}
|
||||
};
|
||||
|
@ -23,7 +23,7 @@ use bevy_ecs::{
|
||||
use bevy_image::{Image, TextureFormatPixelInfo};
|
||||
use bevy_reflect::Reflect;
|
||||
use bevy_render_macros::ExtractComponent;
|
||||
use bevy_utils::{default, tracing::warn, HashMap};
|
||||
use bevy_utils::{tracing::warn, HashMap};
|
||||
use encase::internal::ReadFrom;
|
||||
use encase::private::Reader;
|
||||
use encase::ShaderType;
|
||||
@ -239,17 +239,16 @@ fn prepare_buffers(
|
||||
match readback {
|
||||
Readback::Texture(image) => {
|
||||
if let Some(gpu_image) = gpu_images.get(image) {
|
||||
let size = Extent3d {
|
||||
width: gpu_image.size.x,
|
||||
height: gpu_image.size.y,
|
||||
..default()
|
||||
};
|
||||
let layout = layout_data(size.width, size.height, gpu_image.texture_format);
|
||||
let layout = layout_data(
|
||||
gpu_image.size.width,
|
||||
gpu_image.size.height,
|
||||
gpu_image.texture_format,
|
||||
);
|
||||
let buffer = buffer_pool.get(
|
||||
&render_device,
|
||||
get_aligned_size(
|
||||
size.width,
|
||||
size.height,
|
||||
gpu_image.size.width,
|
||||
gpu_image.size.height,
|
||||
gpu_image.texture_format.pixel_size() as u32,
|
||||
) as u64,
|
||||
);
|
||||
@ -259,7 +258,7 @@ fn prepare_buffers(
|
||||
src: ReadbackSource::Texture {
|
||||
texture: gpu_image.texture.clone(),
|
||||
layout,
|
||||
size,
|
||||
size: gpu_image.size,
|
||||
},
|
||||
buffer,
|
||||
rx,
|
||||
|
@ -135,7 +135,7 @@ fn fallback_image_new(
|
||||
texture_view,
|
||||
texture_format: image.texture_descriptor.format,
|
||||
sampler,
|
||||
size: image.size(),
|
||||
size: image.texture_descriptor.size,
|
||||
mip_level_count: image.texture_descriptor.mip_level_count,
|
||||
}
|
||||
}
|
||||
|
@ -6,8 +6,8 @@ use crate::{
|
||||
use bevy_asset::AssetId;
|
||||
use bevy_ecs::system::{lifetimeless::SRes, SystemParamItem};
|
||||
use bevy_image::{Image, ImageSampler};
|
||||
use bevy_math::UVec2;
|
||||
use wgpu::{TextureFormat, TextureViewDescriptor};
|
||||
use bevy_math::{AspectRatio, UVec2};
|
||||
use wgpu::{Extent3d, TextureFormat, TextureViewDescriptor};
|
||||
|
||||
/// The GPU-representation of an [`Image`].
|
||||
/// 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_format: TextureFormat,
|
||||
pub sampler: Sampler,
|
||||
pub size: UVec2,
|
||||
pub size: Extent3d,
|
||||
pub mip_level_count: u32,
|
||||
}
|
||||
|
||||
@ -53,7 +53,6 @@ impl RenderAsset for GpuImage {
|
||||
&image.data,
|
||||
);
|
||||
|
||||
let size = image.size();
|
||||
let texture_view = texture.create_view(
|
||||
image
|
||||
.texture_view_descriptor
|
||||
@ -73,8 +72,24 @@ impl RenderAsset for GpuImage {
|
||||
texture_view,
|
||||
texture_format: image.texture_descriptor.format,
|
||||
sampler,
|
||||
size,
|
||||
size: image.texture_descriptor.size,
|
||||
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;
|
||||
};
|
||||
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(
|
||||
size,
|
||||
gpu_image.size,
|
||||
format,
|
||||
&render_device,
|
||||
&screenshot_pipeline,
|
||||
@ -542,8 +537,8 @@ pub(crate) fn submit_screenshot_commands(world: &World, encoder: &mut CommandEnc
|
||||
warn!("Unknown image for screenshot, skipping: {:?}", image);
|
||||
continue;
|
||||
};
|
||||
let width = gpu_image.size.x;
|
||||
let height = gpu_image.size.y;
|
||||
let width = gpu_image.size.width;
|
||||
let height = gpu_image.size.height;
|
||||
let texture_format = gpu_image.texture_format;
|
||||
let texture_view = gpu_image.texture_view.deref();
|
||||
render_screenshot(
|
||||
|
@ -313,7 +313,7 @@ impl FromWorld for Mesh2dPipeline {
|
||||
texture_view,
|
||||
texture_format: image.texture_descriptor.format,
|
||||
sampler,
|
||||
size: image.size(),
|
||||
size: image.texture_descriptor.size,
|
||||
mip_level_count: image.texture_descriptor.mip_level_count,
|
||||
}
|
||||
};
|
||||
|
@ -117,7 +117,7 @@ impl FromWorld for SpritePipeline {
|
||||
texture_view,
|
||||
texture_format: image.texture_descriptor.format,
|
||||
sampler,
|
||||
size: image.size(),
|
||||
size: image.texture_descriptor.size,
|
||||
mip_level_count: image.texture_descriptor.mip_level_count,
|
||||
}
|
||||
};
|
||||
@ -676,7 +676,7 @@ pub fn prepare_sprite_image_bind_groups(
|
||||
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;
|
||||
image_bind_groups
|
||||
.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.
|
||||
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);
|
||||
if *flip_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)
|
||||
.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();
|
||||
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) {
|
||||
batch_item_index = item_index;
|
||||
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 {
|
||||
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) {
|
||||
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;
|
||||
|
||||
image_bind_groups
|
||||
|
@ -367,15 +367,9 @@ impl render_graph::Node for ImageCopyDriver {
|
||||
// That's why image in buffer can be little bit wider
|
||||
// This should be taken into account at copy from buffer stage
|
||||
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(
|
||||
src_image.texture.as_image_copy(),
|
||||
ImageCopyBuffer {
|
||||
@ -390,7 +384,7 @@ impl render_graph::Node for ImageCopyDriver {
|
||||
rows_per_image: None,
|
||||
},
|
||||
},
|
||||
texture_extent,
|
||||
src_image.size,
|
||||
);
|
||||
|
||||
let render_queue = world.get_resource::<RenderQueue>().unwrap();
|
||||
|
Loading…
Reference in New Issue
Block a user