Support Sliced 3D for ASTC (#7577)

Enables "texture-compression-astc-sliced-3d" for backends that support ASTC (such as excluding D3D12).
This commit is contained in:
Mehmet Oguz Derin 2025-05-04 13:48:16 +03:00 committed by GitHub
parent 50eb207a77
commit 2a62299a84
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
12 changed files with 131 additions and 9 deletions

View File

@ -44,6 +44,7 @@ Bottom level categories:
#### General
- Add support for astc-sliced-3d feature. By @mehmetoguzderin in [#7577](https://github.com/gfx-rs/wgpu/issues/7577)
- Add support for rendering to slices of 3D texture views and single layered 2D-Array texture views (this requires `VK_KHR_maintenance1` which should be widely available on newer drivers). By @teoxoy in [#7596](https://github.com/gfx-rs/wgpu/pull/7596)
#### Naga

View File

@ -99,6 +99,7 @@ enum GPUFeatureName {
"texture-compression-bc-sliced-3d",
"texture-compression-etc2",
"texture-compression-astc",
"texture-compression-astc-sliced-3d",
"timestamp-query",
"indirect-first-instance",
"shader-f16",

View File

@ -359,6 +359,8 @@ pub enum GPUFeatureName {
TextureCompressionEtc2,
#[webidl(rename = "texture-compression-astc")]
TextureCompressionAstc,
#[webidl(rename = "texture-compression-astc-sliced-3d")]
TextureCompressionAstcSliced3d,
#[webidl(rename = "rg11b10ufloat-renderable")]
Rg11b10ufloatRenderable,
#[webidl(rename = "bgra8unorm-storage")]
@ -451,6 +453,7 @@ pub fn feature_names_to_features(names: Vec<GPUFeatureName>) -> wgpu_types::Feat
GPUFeatureName::TextureCompressionBcSliced3d => Features::TEXTURE_COMPRESSION_BC_SLICED_3D,
GPUFeatureName::TextureCompressionEtc2 => Features::TEXTURE_COMPRESSION_ETC2,
GPUFeatureName::TextureCompressionAstc => Features::TEXTURE_COMPRESSION_ASTC,
GPUFeatureName::TextureCompressionAstcSliced3d => Features::TEXTURE_COMPRESSION_ASTC_SLICED_3D,
GPUFeatureName::Rg11b10ufloatRenderable => Features::RG11B10UFLOAT_RENDERABLE,
GPUFeatureName::Bgra8unormStorage => Features::BGRA8UNORM_STORAGE,
GPUFeatureName::Float32Filterable => Features::FLOAT32_FILTERABLE,
@ -529,6 +532,9 @@ pub fn features_to_feature_names(features: wgpu_types::Features) -> HashSet<GPUF
if features.contains(wgpu_types::Features::TEXTURE_COMPRESSION_ASTC) {
return_features.insert(TextureCompressionAstc);
}
if features.contains(wgpu_types::Features::TEXTURE_COMPRESSION_ASTC_SLICED_3D) {
return_features.insert(TextureCompressionAstcSliced3d);
}
if features.contains(wgpu_types::Features::RG11B10UFLOAT_RENDERABLE) {
return_features.insert(Rg11b10ufloatRenderable);
}

View File

@ -405,9 +405,14 @@ static CLEAR_TEXTURE_COMPRESSED_BCN: GpuTestConfiguration = GpuTestConfiguration
static CLEAR_TEXTURE_COMPRESSED_ASTC: GpuTestConfiguration = GpuTestConfiguration::new()
.parameters(
TestParameters::default()
.features(wgpu::Features::CLEAR_TEXTURE | wgpu::Features::TEXTURE_COMPRESSION_ASTC)
.features(
wgpu::Features::CLEAR_TEXTURE
| wgpu::Features::TEXTURE_COMPRESSION_ASTC
| wgpu::Features::TEXTURE_COMPRESSION_ASTC_SLICED_3D,
)
.limits(wgpu::Limits {
max_texture_dimension_2d: wgpu::COPY_BYTES_PER_ROW_ALIGNMENT * 12,
max_texture_dimension_3d: wgpu::COPY_BYTES_PER_ROW_ALIGNMENT * 12,
..wgpu::Limits::downlevel_defaults()
})
// https://bugs.chromium.org/p/angleproject/issues/detail?id=7056

View File

@ -979,6 +979,9 @@ impl Device {
if desc.format.is_bcn() {
self.require_features(wgt::Features::TEXTURE_COMPRESSION_BC_SLICED_3D)
.map_err(|error| CreateTextureError::MissingFeatures(desc.format, error))?;
} else if desc.format.is_astc() {
self.require_features(wgt::Features::TEXTURE_COMPRESSION_ASTC_SLICED_3D)
.map_err(|error| CreateTextureError::MissingFeatures(desc.format, error))?;
} else {
return Err(CreateTextureError::InvalidCompressedDimension(
desc.dimension,

View File

@ -531,6 +531,7 @@ impl super::Adapter {
.compressed_texture_astc_supports_ldr_profile()
{
features.insert(wgt::Features::TEXTURE_COMPRESSION_ASTC);
features.insert(wgt::Features::TEXTURE_COMPRESSION_ASTC_SLICED_3D);
}
if context
.glow_context
@ -543,6 +544,7 @@ impl super::Adapter {
#[cfg(any(native, Emscripten))]
{
features.insert(wgt::Features::TEXTURE_COMPRESSION_ASTC);
features.insert(wgt::Features::TEXTURE_COMPRESSION_ASTC_SLICED_3D);
features.insert(wgt::Features::TEXTURE_COMPRESSION_ASTC_HDR);
}
} else {
@ -550,6 +552,11 @@ impl super::Adapter {
wgt::Features::TEXTURE_COMPRESSION_ASTC,
extensions.contains("GL_KHR_texture_compression_astc_ldr"),
);
features.set(
wgt::Features::TEXTURE_COMPRESSION_ASTC_SLICED_3D,
extensions.contains("GL_KHR_texture_compression_astc_ldr")
&& extensions.contains("GL_KHR_texture_compression_astc_sliced_3d"),
);
features.set(
wgt::Features::TEXTURE_COMPRESSION_ASTC_HDR,
extensions.contains("GL_KHR_texture_compression_astc_hdr"),

View File

@ -667,6 +667,8 @@ impl super::PrivateCapabilities {
|| Self::supports_any(device, ASTC_PIXEL_FORMAT_FEATURES),
// A13(Apple6) M1(Apple7) and later always support HDR ASTC pixel formats
format_astc_hdr: family_check && device.supports_family(MTLGPUFamily::Apple6),
// Apple3 and later supports compressed volume texture formats including ASTC Sliced 3D
format_astc_3d: family_check && device.supports_family(MTLGPUFamily::Apple3),
format_any8_unorm_srgb_all: Self::supports_any(device, ANY8_UNORM_SRGB_ALL),
format_any8_unorm_srgb_no_write: !Self::supports_any(device, ANY8_UNORM_SRGB_ALL)
&& !os_is_mac,
@ -938,6 +940,7 @@ impl super::PrivateCapabilities {
);
features.set(F::TEXTURE_COMPRESSION_ASTC, self.format_astc);
features.set(F::TEXTURE_COMPRESSION_ASTC_HDR, self.format_astc_hdr);
features.set(F::TEXTURE_COMPRESSION_ASTC_SLICED_3D, self.format_astc_3d);
features.set(F::TEXTURE_COMPRESSION_BC, self.format_bc);
features.set(F::TEXTURE_COMPRESSION_BC_SLICED_3D, self.format_bc); // BC guarantees Sliced 3D
features.set(F::TEXTURE_COMPRESSION_ETC2, self.format_eac_etc);

View File

@ -227,6 +227,7 @@ struct PrivateCapabilities {
format_eac_etc: bool,
format_astc: bool,
format_astc_hdr: bool,
format_astc_3d: bool,
format_any8_unorm_srgb_all: bool,
format_any8_unorm_srgb_no_write: bool,
format_any8_snorm_all: bool,

View File

@ -717,6 +717,13 @@ impl PhysicalDeviceFeatures {
);
}
if self.core.texture_compression_astc_ldr != 0 {
features.set(
F::TEXTURE_COMPRESSION_ASTC_SLICED_3D,
supports_astc_3d(instance, phd),
);
}
if let Some((ref f16_i8, ref bit16)) = self.shader_float16 {
features.set(
F::SHADER_F16,
@ -2604,6 +2611,60 @@ fn supports_format(
}
}
fn supports_astc_3d(instance: &ash::Instance, phd: vk::PhysicalDevice) -> bool {
let mut supports = true;
let astc_formats = [
vk::Format::ASTC_4X4_UNORM_BLOCK,
vk::Format::ASTC_4X4_SRGB_BLOCK,
vk::Format::ASTC_5X4_UNORM_BLOCK,
vk::Format::ASTC_5X4_SRGB_BLOCK,
vk::Format::ASTC_5X5_UNORM_BLOCK,
vk::Format::ASTC_5X5_SRGB_BLOCK,
vk::Format::ASTC_6X5_UNORM_BLOCK,
vk::Format::ASTC_6X5_SRGB_BLOCK,
vk::Format::ASTC_6X6_UNORM_BLOCK,
vk::Format::ASTC_6X6_SRGB_BLOCK,
vk::Format::ASTC_8X5_UNORM_BLOCK,
vk::Format::ASTC_8X5_SRGB_BLOCK,
vk::Format::ASTC_8X6_UNORM_BLOCK,
vk::Format::ASTC_8X6_SRGB_BLOCK,
vk::Format::ASTC_8X8_UNORM_BLOCK,
vk::Format::ASTC_8X8_SRGB_BLOCK,
vk::Format::ASTC_10X5_UNORM_BLOCK,
vk::Format::ASTC_10X5_SRGB_BLOCK,
vk::Format::ASTC_10X6_UNORM_BLOCK,
vk::Format::ASTC_10X6_SRGB_BLOCK,
vk::Format::ASTC_10X8_UNORM_BLOCK,
vk::Format::ASTC_10X8_SRGB_BLOCK,
vk::Format::ASTC_10X10_UNORM_BLOCK,
vk::Format::ASTC_10X10_SRGB_BLOCK,
vk::Format::ASTC_12X10_UNORM_BLOCK,
vk::Format::ASTC_12X10_SRGB_BLOCK,
vk::Format::ASTC_12X12_UNORM_BLOCK,
vk::Format::ASTC_12X12_SRGB_BLOCK,
];
for &format in &astc_formats {
let result = unsafe {
instance.get_physical_device_image_format_properties(
phd,
format,
vk::ImageType::TYPE_3D,
vk::ImageTiling::OPTIMAL,
vk::ImageUsageFlags::SAMPLED,
vk::ImageCreateFlags::empty(),
)
};
if result.is_err() {
supports = false;
break;
}
}
supports
}
fn supports_bgra8unorm_storage(
instance: &ash::Instance,
phd: vk::PhysicalDevice,

View File

@ -37,25 +37,28 @@ mod webgpu_impl {
pub const WEBGPU_FEATURE_TEXTURE_COMPRESSION_ASTC: u64 = 1 << 5;
#[doc(hidden)]
pub const WEBGPU_FEATURE_TIMESTAMP_QUERY: u64 = 1 << 6;
pub const WEBGPU_FEATURE_TEXTURE_COMPRESSION_ASTC_SLICED_3D: u64 = 1 << 6;
#[doc(hidden)]
pub const WEBGPU_FEATURE_INDIRECT_FIRST_INSTANCE: u64 = 1 << 7;
pub const WEBGPU_FEATURE_TIMESTAMP_QUERY: u64 = 1 << 7;
#[doc(hidden)]
pub const WEBGPU_FEATURE_SHADER_F16: u64 = 1 << 8;
pub const WEBGPU_FEATURE_INDIRECT_FIRST_INSTANCE: u64 = 1 << 8;
#[doc(hidden)]
pub const WEBGPU_FEATURE_RG11B10UFLOAT_RENDERABLE: u64 = 1 << 9;
pub const WEBGPU_FEATURE_SHADER_F16: u64 = 1 << 9;
#[doc(hidden)]
pub const WEBGPU_FEATURE_BGRA8UNORM_STORAGE: u64 = 1 << 10;
pub const WEBGPU_FEATURE_RG11B10UFLOAT_RENDERABLE: u64 = 1 << 10;
#[doc(hidden)]
pub const WEBGPU_FEATURE_FLOAT32_FILTERABLE: u64 = 1 << 11;
pub const WEBGPU_FEATURE_BGRA8UNORM_STORAGE: u64 = 1 << 11;
#[doc(hidden)]
pub const WEBGPU_FEATURE_DUAL_SOURCE_BLENDING: u64 = 1 << 12;
pub const WEBGPU_FEATURE_FLOAT32_FILTERABLE: u64 = 1 << 12;
#[doc(hidden)]
pub const WEBGPU_FEATURE_DUAL_SOURCE_BLENDING: u64 = 1 << 13;
}
macro_rules! bitflags_array_impl {
@ -1294,6 +1297,9 @@ bitflags_array! {
/// Support for this feature guarantees availability of [`TextureUsages::COPY_SRC | TextureUsages::COPY_DST | TextureUsages::TEXTURE_BINDING`] for ASTC formats with Unorm/UnormSrgb channel type.
/// [`Features::TEXTURE_ADAPTER_SPECIFIC_FORMAT_FEATURES`] may enable additional usages.
///
/// This feature does not guarantee availability of sliced 3d textures for ASTC formats.
/// If available, 3d support can be enabled by TEXTURE_COMPRESSION_ASTC_SLICED_3D feature.
///
/// Supported Platforms:
/// - Vulkan on Intel
/// - Mobile (some)
@ -1301,6 +1307,23 @@ bitflags_array! {
/// This is a web and native feature.
const TEXTURE_COMPRESSION_ASTC = WEBGPU_FEATURE_TEXTURE_COMPRESSION_ASTC;
/// Allows the 3d dimension for textures with ASTC compressed formats.
///
/// This feature must be used in combination with TEXTURE_COMPRESSION_ASTC to enable 3D textures with ASTC compression.
/// It does not enable the ASTC formats by itself.
///
/// Supported Platforms:
/// - Vulkan (some)
/// - Metal on Apple3+
/// - OpenGL/WebGL (some)
///
/// Not Supported:
/// - DX12
///
/// This is a web and native feature.
const TEXTURE_COMPRESSION_ASTC_SLICED_3D = WEBGPU_FEATURE_TEXTURE_COMPRESSION_ASTC_SLICED_3D;
/// Enables use of Timestamp Queries. These queries tell the current gpu timestamp when
/// all work before the query is finished.
///

View File

@ -2769,6 +2769,13 @@ impl TextureFormat {
self.required_features() == Features::TEXTURE_COMPRESSION_BC
}
/// Returns `true` for ASTC compressed formats.
#[must_use]
pub fn is_astc(&self) -> bool {
self.required_features() == Features::TEXTURE_COMPRESSION_ASTC
|| self.required_features() == Features::TEXTURE_COMPRESSION_ASTC_HDR
}
/// Returns the required features (if any) in order to use the texture.
#[must_use]
pub fn required_features(&self) -> Features {

View File

@ -708,7 +708,7 @@ fn map_map_mode(mode: crate::MapMode) -> u32 {
}
}
const FEATURES_MAPPING: [(wgt::Features, webgpu_sys::GpuFeatureName); 13] = [
const FEATURES_MAPPING: [(wgt::Features, webgpu_sys::GpuFeatureName); 14] = [
(
wgt::Features::DEPTH_CLIP_CONTROL,
webgpu_sys::GpuFeatureName::DepthClipControl,
@ -733,6 +733,10 @@ const FEATURES_MAPPING: [(wgt::Features, webgpu_sys::GpuFeatureName); 13] = [
wgt::Features::TEXTURE_COMPRESSION_ASTC,
webgpu_sys::GpuFeatureName::TextureCompressionAstc,
),
(
wgt::Features::TEXTURE_COMPRESSION_ASTC_SLICED_3D,
webgpu_sys::GpuFeatureName::TextureCompressionAstcSliced3d,
),
(
wgt::Features::TIMESTAMP_QUERY,
webgpu_sys::GpuFeatureName::TimestampQuery,