Skip to content

Commit 5fabb53

Browse files
authored
use wgpu TextureDataOrder (#19829)
# Objective - Fixes #19140 ## Solution - Use TextureDataOrder ## Testing - ran some examples that use ktx2 textures, they look fine
1 parent 479c93d commit 5fabb53

File tree

5 files changed

+15
-38
lines changed

5 files changed

+15
-38
lines changed

crates/bevy_core_pipeline/src/tonemapping/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -447,6 +447,7 @@ pub fn lut_placeholder() -> Image {
447447
let data = vec![255, 0, 255, 255];
448448
Image {
449449
data: Some(data),
450+
data_order: TextureDataOrder::default(),
450451
texture_descriptor: TextureDescriptor {
451452
size: Extent3d::default(),
452453
format,

crates/bevy_image/src/image.rs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,8 @@ use serde::{Deserialize, Serialize};
1818
use thiserror::Error;
1919
use wgpu_types::{
2020
AddressMode, CompareFunction, Extent3d, Features, FilterMode, SamplerBorderColor,
21-
SamplerDescriptor, TextureDescriptor, TextureDimension, TextureFormat, TextureUsages,
22-
TextureViewDescriptor,
21+
SamplerDescriptor, TextureDataOrder, TextureDescriptor, TextureDimension, TextureFormat,
22+
TextureUsages, TextureViewDescriptor,
2323
};
2424

2525
/// Trait used to provide default values for Bevy-external types that
@@ -372,6 +372,10 @@ pub struct Image {
372372
/// CPU, then this should be `None`.
373373
/// Otherwise, it should always be `Some`.
374374
pub data: Option<Vec<u8>>,
375+
/// For texture data with layers and mips, this field controls how wgpu interprets the buffer layout.
376+
///
377+
/// Use [`TextureDataOrder::default()`] for all other cases.
378+
pub data_order: TextureDataOrder,
375379
// TODO: this nesting makes accessing Image metadata verbose. Either flatten out descriptor or add accessors.
376380
pub texture_descriptor: TextureDescriptor<Option<&'static str>, &'static [TextureFormat]>,
377381
/// The [`ImageSampler`] to use during rendering.
@@ -764,6 +768,7 @@ impl Image {
764768
) -> Self {
765769
Image {
766770
data: None,
771+
data_order: TextureDataOrder::default(),
767772
texture_descriptor: TextureDescriptor {
768773
size,
769774
format,

crates/bevy_image/src/ktx2.rs

Lines changed: 2 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -238,43 +238,12 @@ pub fn ktx2_buffer_to_image(
238238
)));
239239
}
240240

241-
// Reorder data from KTX2 MipXLayerYFaceZ to wgpu LayerYFaceZMipX
242-
let texture_format_info = texture_format;
243-
let (block_width_pixels, block_height_pixels) = (
244-
texture_format_info.block_dimensions().0 as usize,
245-
texture_format_info.block_dimensions().1 as usize,
246-
);
247-
// Texture is not a depth or stencil format, it is possible to pass `None` and unwrap
248-
let block_bytes = texture_format_info.block_copy_size(None).unwrap() as usize;
249-
250-
let mut wgpu_data = vec![Vec::default(); (layer_count * face_count) as usize];
251-
for (level, level_data) in levels.iter().enumerate() {
252-
let (level_width, level_height, level_depth) = (
253-
(width as usize >> level).max(1),
254-
(height as usize >> level).max(1),
255-
(depth as usize >> level).max(1),
256-
);
257-
let (num_blocks_x, num_blocks_y) = (
258-
level_width.div_ceil(block_width_pixels).max(1),
259-
level_height.div_ceil(block_height_pixels).max(1),
260-
);
261-
let level_bytes = num_blocks_x * num_blocks_y * level_depth * block_bytes;
262-
263-
let mut index = 0;
264-
for _layer in 0..layer_count {
265-
for _face in 0..face_count {
266-
let offset = index * level_bytes;
267-
wgpu_data[index].extend_from_slice(&level_data[offset..(offset + level_bytes)]);
268-
index += 1;
269-
}
270-
}
271-
}
272-
273241
// Assign the data and fill in the rest of the metadata now the possible
274242
// error cases have been handled
275243
let mut image = Image::default();
276244
image.texture_descriptor.format = texture_format;
277-
image.data = Some(wgpu_data.into_iter().flatten().collect::<Vec<_>>());
245+
image.data = Some(levels.into_iter().flatten().collect::<Vec<_>>());
246+
image.data_order = wgpu_types::TextureDataOrder::MipMajor;
278247
// Note: we must give wgpu the logical texture dimensions, so it can correctly compute mip sizes.
279248
// However this currently causes wgpu to panic if the dimensions arent a multiple of blocksize.
280249
// See https://github.com/gfx-rs/wgpu/issues/7677 for more context.

crates/bevy_render/src/texture/gpu_image.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,8 +51,7 @@ impl RenderAsset for GpuImage {
5151
render_device.create_texture_with_data(
5252
render_queue,
5353
&image.texture_descriptor,
54-
// TODO: Is this correct? Do we need to use `MipMajor` if it's a ktx2 file?
55-
wgpu::util::TextureDataOrder::default(),
54+
image.data_order,
5655
data,
5756
)
5857
} else {

crates/bevy_sprite/src/tilemap_chunk/mod.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,9 @@ use bevy_math::{FloatOrd, UVec2, Vec2, Vec3};
1616
use bevy_platform::collections::HashMap;
1717
use bevy_render::{
1818
mesh::{Indices, Mesh, Mesh2d, PrimitiveTopology},
19-
render_resource::{TextureDescriptor, TextureDimension, TextureFormat, TextureUsages},
19+
render_resource::{
20+
TextureDataOrder, TextureDescriptor, TextureDimension, TextureFormat, TextureUsages,
21+
},
2022
};
2123
use tracing::warn;
2224

@@ -198,6 +200,7 @@ fn make_chunk_image(size: &UVec2, indices: &[Option<u16>]) -> Image {
198200
.flat_map(|i| u16::to_ne_bytes(i.unwrap_or(u16::MAX)))
199201
.collect(),
200202
),
203+
data_order: TextureDataOrder::default(),
201204
texture_descriptor: TextureDescriptor {
202205
size: size.to_extents(),
203206
dimension: TextureDimension::D2,

0 commit comments

Comments
 (0)