Fixed incorrect behaviour of headless_renderer depending on image dimensions (#13388)
# Objective - Fixes #13384 . ## Solution - If the image became wider when copying from the texture to the buffer, then the data is reduced to its original size when copying from the buffer to the image. ## Testing - Ran example with 1919x1080 resolution  --------- Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com> Co-authored-by: François Mockers <francois.mockers@vleue.com>
This commit is contained in:
parent
bf2aced279
commit
2aed777435
@ -13,8 +13,7 @@ use bevy::{
|
|||||||
prelude::*,
|
prelude::*,
|
||||||
render::{
|
render::{
|
||||||
camera::RenderTarget,
|
camera::RenderTarget,
|
||||||
render_asset::RenderAssetUsages,
|
render_asset::{RenderAssetUsages, RenderAssets},
|
||||||
render_asset::RenderAssets,
|
|
||||||
render_graph::{self, NodeRunError, RenderGraph, RenderGraphContext, RenderLabel},
|
render_graph::{self, NodeRunError, RenderGraph, RenderGraphContext, RenderLabel},
|
||||||
render_resource::{
|
render_resource::{
|
||||||
Buffer, BufferDescriptor, BufferUsages, CommandEncoderDescriptor, Extent3d,
|
Buffer, BufferDescriptor, BufferUsages, CommandEncoderDescriptor, Extent3d,
|
||||||
@ -22,7 +21,7 @@ use bevy::{
|
|||||||
TextureUsages,
|
TextureUsages,
|
||||||
},
|
},
|
||||||
renderer::{RenderContext, RenderDevice, RenderQueue},
|
renderer::{RenderContext, RenderDevice, RenderQueue},
|
||||||
texture::BevyDefault,
|
texture::{BevyDefault, TextureFormatPixelInfo},
|
||||||
Extract, Render, RenderApp, RenderSet,
|
Extract, Render, RenderApp, RenderSet,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
@ -361,6 +360,10 @@ impl render_graph::Node for ImageCopyDriver {
|
|||||||
let block_dimensions = src_image.texture_format.block_dimensions();
|
let block_dimensions = src_image.texture_format.block_dimensions();
|
||||||
let block_size = src_image.texture_format.block_copy_size(None).unwrap();
|
let block_size = src_image.texture_format.block_copy_size(None).unwrap();
|
||||||
|
|
||||||
|
// Calculating correct size of image row because
|
||||||
|
// copy_texture_to_buffer can copy image only by rows aligned wgpu::COPY_BYTES_PER_ROW_ALIGNMENT
|
||||||
|
// 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(
|
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.x as usize / block_dimensions.0 as usize) * block_size as usize,
|
||||||
);
|
);
|
||||||
@ -492,7 +495,24 @@ fn update(
|
|||||||
for image in images_to_save.iter() {
|
for image in images_to_save.iter() {
|
||||||
// Fill correct data from channel to image
|
// Fill correct data from channel to image
|
||||||
let img_bytes = images.get_mut(image.id()).unwrap();
|
let img_bytes = images.get_mut(image.id()).unwrap();
|
||||||
img_bytes.data.clone_from(&image_data);
|
|
||||||
|
// We need to ensure that this works regardless of the image dimensions
|
||||||
|
// If the image became wider when copying from the texture to the buffer,
|
||||||
|
// then the data is reduced to its original size when copying from the buffer to the image.
|
||||||
|
let row_bytes = img_bytes.width() as usize
|
||||||
|
* img_bytes.texture_descriptor.format.pixel_size();
|
||||||
|
let aligned_row_bytes = RenderDevice::align_copy_bytes_per_row(row_bytes);
|
||||||
|
if row_bytes == aligned_row_bytes {
|
||||||
|
img_bytes.data.clone_from(&image_data);
|
||||||
|
} else {
|
||||||
|
// shrink data to original image size
|
||||||
|
img_bytes.data = image_data
|
||||||
|
.chunks(aligned_row_bytes)
|
||||||
|
.take(img_bytes.height() as usize)
|
||||||
|
.flat_map(|row| &row[..row_bytes.min(row.len())])
|
||||||
|
.cloned()
|
||||||
|
.collect();
|
||||||
|
}
|
||||||
|
|
||||||
// Create RGBA Image Buffer
|
// Create RGBA Image Buffer
|
||||||
let img = match img_bytes.clone().try_into_dynamic() {
|
let img = match img_bytes.clone().try_into_dynamic() {
|
||||||
|
Loading…
Reference in New Issue
Block a user