Detect cubemap for dds textures (#10222)
# Objective - Closes #10049. - Detect DDS texture containing a cubemap or a cubemap array. ## Solution - When loading a dds texture, the header capabilities are checked for the cubemap flag. An error is returned if not all faces are provided. --- ## Changelog ### Added - Added a new texture error `TextureError::IncompleteCubemap`, used for dds cubemap textures containing less than 6 faces, as that is not supported on modern graphics APIs. ### Fixed - DDS cubemaps are now loaded as cubemaps instead of 2D textures. ## Migration Guide If you are matching on a `TextureError`, you will need to add a new branch to handle `TextureError::IncompleteCubemap`.
This commit is contained in:
parent
0716922165
commit
9cfada3f22
@ -1,6 +1,8 @@
|
||||
use ddsfile::{D3DFormat, Dds, DxgiFormat};
|
||||
use ddsfile::{Caps2, D3DFormat, Dds, DxgiFormat};
|
||||
use std::io::Cursor;
|
||||
use wgpu::{Extent3d, TextureDimension, TextureFormat};
|
||||
use wgpu::{
|
||||
Extent3d, TextureDimension, TextureFormat, TextureViewDescriptor, TextureViewDimension,
|
||||
};
|
||||
|
||||
use super::{CompressedImageFormats, Image, TextureError};
|
||||
|
||||
@ -18,14 +20,29 @@ pub fn dds_buffer_to_image(
|
||||
)));
|
||||
}
|
||||
let mut image = Image::default();
|
||||
let is_cubemap = dds.header.caps2.contains(Caps2::CUBEMAP);
|
||||
let mut depth_or_array_layers = if dds.get_num_array_layers() > 1 {
|
||||
dds.get_num_array_layers()
|
||||
} else {
|
||||
dds.get_depth()
|
||||
};
|
||||
if is_cubemap {
|
||||
if !dds.header.caps2.contains(
|
||||
Caps2::CUBEMAP_NEGATIVEX
|
||||
| Caps2::CUBEMAP_NEGATIVEY
|
||||
| Caps2::CUBEMAP_NEGATIVEZ
|
||||
| Caps2::CUBEMAP_POSITIVEX
|
||||
| Caps2::CUBEMAP_POSITIVEY
|
||||
| Caps2::CUBEMAP_POSITIVEZ,
|
||||
) {
|
||||
return Err(TextureError::IncompleteCubemap);
|
||||
}
|
||||
depth_or_array_layers *= 6;
|
||||
}
|
||||
image.texture_descriptor.size = Extent3d {
|
||||
width: dds.get_width(),
|
||||
height: dds.get_height(),
|
||||
depth_or_array_layers: if dds.get_num_array_layers() > 1 {
|
||||
dds.get_num_array_layers()
|
||||
} else {
|
||||
dds.get_depth()
|
||||
},
|
||||
depth_or_array_layers,
|
||||
}
|
||||
.physical_size(texture_format);
|
||||
image.texture_descriptor.mip_level_count = dds.get_num_mipmap_levels();
|
||||
@ -37,6 +54,17 @@ pub fn dds_buffer_to_image(
|
||||
} else {
|
||||
TextureDimension::D1
|
||||
};
|
||||
if is_cubemap {
|
||||
let dimension = if image.texture_descriptor.size.depth_or_array_layers > 6 {
|
||||
TextureViewDimension::CubeArray
|
||||
} else {
|
||||
TextureViewDimension::Cube
|
||||
};
|
||||
image.texture_view_descriptor = Some(TextureViewDescriptor {
|
||||
dimension: Some(dimension),
|
||||
..Default::default()
|
||||
});
|
||||
}
|
||||
image.data = dds.data;
|
||||
Ok(image)
|
||||
}
|
||||
|
||||
@ -438,6 +438,9 @@ pub enum TextureError {
|
||||
TranscodeError(String),
|
||||
#[error("format requires transcoding: {0:?}")]
|
||||
FormatRequiresTranscodingError(TranscodeFormat),
|
||||
/// Only cubemaps with six faces are supported.
|
||||
#[error("only cubemaps with six faces are supported")]
|
||||
IncompleteCubemap,
|
||||
}
|
||||
|
||||
/// The type of a raw image buffer.
|
||||
|
||||
Loading…
Reference in New Issue
Block a user