mirror of
https://github.com/gfx-rs/wgpu.git
synced 2026-01-14 03:37:55 -05:00
431 lines
14 KiB
Rust
431 lines
14 KiB
Rust
use wgpu_test::{
|
|
gpu_test, image::ReadbackBuffers, FailureCase, GpuTestConfiguration, TestParameters,
|
|
TestingContext,
|
|
};
|
|
|
|
static TEXTURE_FORMATS_UNCOMPRESSED_GLES_COMPAT: &[wgpu::TextureFormat] = &[
|
|
wgpu::TextureFormat::R8Unorm,
|
|
wgpu::TextureFormat::R8Snorm,
|
|
wgpu::TextureFormat::R8Uint,
|
|
wgpu::TextureFormat::R8Sint,
|
|
wgpu::TextureFormat::R16Uint,
|
|
wgpu::TextureFormat::R16Sint,
|
|
wgpu::TextureFormat::R16Float,
|
|
wgpu::TextureFormat::R32Uint,
|
|
wgpu::TextureFormat::R32Sint,
|
|
wgpu::TextureFormat::R32Float,
|
|
wgpu::TextureFormat::Rg16Uint,
|
|
wgpu::TextureFormat::Rg16Sint,
|
|
wgpu::TextureFormat::Rg16Float,
|
|
wgpu::TextureFormat::Rgba8Unorm,
|
|
wgpu::TextureFormat::Rgba8UnormSrgb,
|
|
wgpu::TextureFormat::Rgba8Snorm,
|
|
wgpu::TextureFormat::Rgba8Uint,
|
|
wgpu::TextureFormat::Rgba8Sint,
|
|
wgpu::TextureFormat::Bgra8Unorm,
|
|
wgpu::TextureFormat::Bgra8UnormSrgb,
|
|
wgpu::TextureFormat::Rgb10a2Uint,
|
|
wgpu::TextureFormat::Rgb10a2Unorm,
|
|
wgpu::TextureFormat::Rg11b10Ufloat,
|
|
wgpu::TextureFormat::Rg32Uint,
|
|
wgpu::TextureFormat::Rg32Sint,
|
|
wgpu::TextureFormat::Rg32Float,
|
|
wgpu::TextureFormat::Rgba16Uint,
|
|
wgpu::TextureFormat::Rgba16Sint,
|
|
wgpu::TextureFormat::Rgba16Float,
|
|
wgpu::TextureFormat::Rgba32Uint,
|
|
wgpu::TextureFormat::Rgba32Sint,
|
|
wgpu::TextureFormat::Rgba32Float,
|
|
];
|
|
|
|
static TEXTURE_FORMATS_UNCOMPRESSED: &[wgpu::TextureFormat] = &[
|
|
wgpu::TextureFormat::Rg8Unorm,
|
|
wgpu::TextureFormat::Rg8Snorm,
|
|
wgpu::TextureFormat::Rg8Uint,
|
|
wgpu::TextureFormat::Rg8Sint,
|
|
wgpu::TextureFormat::Rgb9e5Ufloat,
|
|
];
|
|
|
|
static TEXTURE_FORMATS_DEPTH: &[wgpu::TextureFormat] = &[
|
|
wgpu::TextureFormat::Stencil8,
|
|
wgpu::TextureFormat::Depth16Unorm,
|
|
wgpu::TextureFormat::Depth24Plus,
|
|
wgpu::TextureFormat::Depth24PlusStencil8,
|
|
wgpu::TextureFormat::Depth32Float,
|
|
];
|
|
|
|
// needs TEXTURE_COMPRESSION_BC
|
|
static TEXTURE_FORMATS_BC: &[wgpu::TextureFormat] = &[
|
|
wgpu::TextureFormat::Bc1RgbaUnorm,
|
|
wgpu::TextureFormat::Bc1RgbaUnormSrgb,
|
|
wgpu::TextureFormat::Bc2RgbaUnorm,
|
|
wgpu::TextureFormat::Bc2RgbaUnormSrgb,
|
|
wgpu::TextureFormat::Bc3RgbaUnorm,
|
|
wgpu::TextureFormat::Bc3RgbaUnormSrgb,
|
|
wgpu::TextureFormat::Bc4RUnorm,
|
|
wgpu::TextureFormat::Bc4RSnorm,
|
|
wgpu::TextureFormat::Bc5RgUnorm,
|
|
wgpu::TextureFormat::Bc5RgSnorm,
|
|
wgpu::TextureFormat::Bc6hRgbUfloat,
|
|
wgpu::TextureFormat::Bc6hRgbFloat,
|
|
wgpu::TextureFormat::Bc7RgbaUnorm,
|
|
wgpu::TextureFormat::Bc7RgbaUnormSrgb,
|
|
];
|
|
|
|
// needs TEXTURE_COMPRESSION_ETC2
|
|
static TEXTURE_FORMATS_ETC2: &[wgpu::TextureFormat] = &[
|
|
wgpu::TextureFormat::Etc2Rgb8Unorm,
|
|
wgpu::TextureFormat::Etc2Rgb8UnormSrgb,
|
|
wgpu::TextureFormat::Etc2Rgb8A1Unorm,
|
|
wgpu::TextureFormat::Etc2Rgb8A1UnormSrgb,
|
|
wgpu::TextureFormat::Etc2Rgba8Unorm,
|
|
wgpu::TextureFormat::Etc2Rgba8UnormSrgb,
|
|
wgpu::TextureFormat::EacR11Unorm,
|
|
wgpu::TextureFormat::EacR11Snorm,
|
|
wgpu::TextureFormat::EacRg11Unorm,
|
|
wgpu::TextureFormat::EacRg11Snorm,
|
|
];
|
|
|
|
// needs TEXTURE_COMPRESSION_ASTC
|
|
use wgpu::{AstcBlock, AstcChannel};
|
|
static TEXTURE_FORMATS_ASTC: &[wgpu::TextureFormat] = &[
|
|
wgpu::TextureFormat::Astc {
|
|
block: AstcBlock::B4x4,
|
|
channel: AstcChannel::Unorm,
|
|
},
|
|
wgpu::TextureFormat::Astc {
|
|
block: AstcBlock::B5x4,
|
|
channel: AstcChannel::Unorm,
|
|
},
|
|
wgpu::TextureFormat::Astc {
|
|
block: AstcBlock::B5x5,
|
|
channel: AstcChannel::Unorm,
|
|
},
|
|
wgpu::TextureFormat::Astc {
|
|
block: AstcBlock::B6x5,
|
|
channel: AstcChannel::Unorm,
|
|
},
|
|
wgpu::TextureFormat::Astc {
|
|
block: AstcBlock::B6x6,
|
|
channel: AstcChannel::Unorm,
|
|
},
|
|
wgpu::TextureFormat::Astc {
|
|
block: AstcBlock::B8x5,
|
|
channel: AstcChannel::Unorm,
|
|
},
|
|
wgpu::TextureFormat::Astc {
|
|
block: AstcBlock::B8x6,
|
|
channel: AstcChannel::Unorm,
|
|
},
|
|
wgpu::TextureFormat::Astc {
|
|
block: AstcBlock::B8x8,
|
|
channel: AstcChannel::Unorm,
|
|
},
|
|
wgpu::TextureFormat::Astc {
|
|
block: AstcBlock::B10x5,
|
|
channel: AstcChannel::Unorm,
|
|
},
|
|
wgpu::TextureFormat::Astc {
|
|
block: AstcBlock::B10x6,
|
|
channel: AstcChannel::Unorm,
|
|
},
|
|
wgpu::TextureFormat::Astc {
|
|
block: AstcBlock::B10x8,
|
|
channel: AstcChannel::Unorm,
|
|
},
|
|
wgpu::TextureFormat::Astc {
|
|
block: AstcBlock::B10x10,
|
|
channel: AstcChannel::Unorm,
|
|
},
|
|
wgpu::TextureFormat::Astc {
|
|
block: AstcBlock::B12x10,
|
|
channel: AstcChannel::Unorm,
|
|
},
|
|
wgpu::TextureFormat::Astc {
|
|
block: AstcBlock::B12x12,
|
|
channel: AstcChannel::Unorm,
|
|
},
|
|
wgpu::TextureFormat::Astc {
|
|
block: AstcBlock::B4x4,
|
|
channel: AstcChannel::UnormSrgb,
|
|
},
|
|
wgpu::TextureFormat::Astc {
|
|
block: AstcBlock::B5x4,
|
|
channel: AstcChannel::UnormSrgb,
|
|
},
|
|
wgpu::TextureFormat::Astc {
|
|
block: AstcBlock::B5x5,
|
|
channel: AstcChannel::UnormSrgb,
|
|
},
|
|
wgpu::TextureFormat::Astc {
|
|
block: AstcBlock::B6x5,
|
|
channel: AstcChannel::UnormSrgb,
|
|
},
|
|
wgpu::TextureFormat::Astc {
|
|
block: AstcBlock::B6x6,
|
|
channel: AstcChannel::UnormSrgb,
|
|
},
|
|
wgpu::TextureFormat::Astc {
|
|
block: AstcBlock::B8x5,
|
|
channel: AstcChannel::UnormSrgb,
|
|
},
|
|
wgpu::TextureFormat::Astc {
|
|
block: AstcBlock::B8x6,
|
|
channel: AstcChannel::UnormSrgb,
|
|
},
|
|
wgpu::TextureFormat::Astc {
|
|
block: AstcBlock::B8x8,
|
|
channel: AstcChannel::UnormSrgb,
|
|
},
|
|
wgpu::TextureFormat::Astc {
|
|
block: AstcBlock::B10x5,
|
|
channel: AstcChannel::UnormSrgb,
|
|
},
|
|
wgpu::TextureFormat::Astc {
|
|
block: AstcBlock::B10x6,
|
|
channel: AstcChannel::UnormSrgb,
|
|
},
|
|
wgpu::TextureFormat::Astc {
|
|
block: AstcBlock::B10x8,
|
|
channel: AstcChannel::UnormSrgb,
|
|
},
|
|
wgpu::TextureFormat::Astc {
|
|
block: AstcBlock::B10x10,
|
|
channel: AstcChannel::UnormSrgb,
|
|
},
|
|
wgpu::TextureFormat::Astc {
|
|
block: AstcBlock::B12x10,
|
|
channel: AstcChannel::UnormSrgb,
|
|
},
|
|
wgpu::TextureFormat::Astc {
|
|
block: AstcBlock::B12x12,
|
|
channel: AstcChannel::UnormSrgb,
|
|
},
|
|
];
|
|
|
|
async fn single_texture_clear_test(
|
|
ctx: &TestingContext,
|
|
format: wgpu::TextureFormat,
|
|
size: wgpu::Extent3d,
|
|
dimension: wgpu::TextureDimension,
|
|
) {
|
|
log::info!(
|
|
"clearing texture with {:?}, dimension {:?}, size {:?}",
|
|
format,
|
|
dimension,
|
|
size
|
|
);
|
|
|
|
let extra_usages = match format {
|
|
wgpu::TextureFormat::Depth24Plus | wgpu::TextureFormat::Depth24PlusStencil8 => {
|
|
wgpu::TextureUsages::TEXTURE_BINDING
|
|
}
|
|
_ => wgpu::TextureUsages::empty(),
|
|
};
|
|
|
|
let texture = ctx.device.create_texture(&wgpu::TextureDescriptor {
|
|
label: Some(&format!("texture {format:?}")),
|
|
size,
|
|
mip_level_count: if dimension == wgpu::TextureDimension::D1 {
|
|
1
|
|
} else {
|
|
// arbitrary value between 2 and max
|
|
3
|
|
},
|
|
sample_count: 1, // multisampling is not supported for clear
|
|
dimension,
|
|
format,
|
|
usage: wgpu::TextureUsages::COPY_SRC | extra_usages,
|
|
view_formats: &[],
|
|
});
|
|
let mut encoder = ctx
|
|
.device
|
|
.create_command_encoder(&wgpu::CommandEncoderDescriptor::default());
|
|
encoder.clear_texture(
|
|
&texture,
|
|
&wgpu::ImageSubresourceRange {
|
|
aspect: wgpu::TextureAspect::All,
|
|
base_mip_level: 0,
|
|
mip_level_count: None,
|
|
base_array_layer: 0,
|
|
array_layer_count: None,
|
|
},
|
|
);
|
|
|
|
let readback_buffers = ReadbackBuffers::new(&ctx.device, &texture);
|
|
|
|
readback_buffers.copy_from(&ctx.device, &mut encoder, &texture);
|
|
|
|
ctx.queue.submit([encoder.finish()]);
|
|
|
|
assert!(
|
|
readback_buffers.are_zero(ctx).await,
|
|
"texture with format {format:?} was not fully cleared"
|
|
);
|
|
}
|
|
|
|
async fn clear_texture_tests(ctx: TestingContext, formats: &'static [wgpu::TextureFormat]) {
|
|
for &format in formats {
|
|
let (block_width, block_height) = format.block_dimensions();
|
|
let rounded_width = block_width * wgpu::COPY_BYTES_PER_ROW_ALIGNMENT;
|
|
let rounded_height = block_height * wgpu::COPY_BYTES_PER_ROW_ALIGNMENT;
|
|
|
|
let is_compressed_or_depth_stencil_format =
|
|
format.is_compressed() || format.is_depth_stencil_format();
|
|
let supports_1d = !is_compressed_or_depth_stencil_format;
|
|
let supports_3d = format.is_bcn() || !is_compressed_or_depth_stencil_format;
|
|
|
|
// 1D texture
|
|
if supports_1d {
|
|
single_texture_clear_test(
|
|
&ctx,
|
|
format,
|
|
wgpu::Extent3d {
|
|
width: rounded_width,
|
|
height: 1,
|
|
depth_or_array_layers: 1,
|
|
},
|
|
wgpu::TextureDimension::D1,
|
|
)
|
|
.await;
|
|
}
|
|
// 2D texture
|
|
single_texture_clear_test(
|
|
&ctx,
|
|
format,
|
|
wgpu::Extent3d {
|
|
width: rounded_width,
|
|
height: rounded_height,
|
|
depth_or_array_layers: 1,
|
|
},
|
|
wgpu::TextureDimension::D2,
|
|
)
|
|
.await;
|
|
// 2D array texture
|
|
single_texture_clear_test(
|
|
&ctx,
|
|
format,
|
|
wgpu::Extent3d {
|
|
width: rounded_width,
|
|
height: rounded_height,
|
|
depth_or_array_layers: 4,
|
|
},
|
|
wgpu::TextureDimension::D2,
|
|
)
|
|
.await;
|
|
if supports_3d {
|
|
// volume texture
|
|
single_texture_clear_test(
|
|
&ctx,
|
|
format,
|
|
wgpu::Extent3d {
|
|
width: rounded_width,
|
|
height: rounded_height,
|
|
depth_or_array_layers: 16,
|
|
},
|
|
wgpu::TextureDimension::D3,
|
|
)
|
|
.await;
|
|
}
|
|
}
|
|
}
|
|
|
|
#[gpu_test]
|
|
static CLEAR_TEXTURE_UNCOMPRESSED_GLES: GpuTestConfiguration = GpuTestConfiguration::new()
|
|
.parameters(
|
|
TestParameters::default()
|
|
.features(wgpu::Features::CLEAR_TEXTURE)
|
|
.skip(FailureCase::webgl2()),
|
|
)
|
|
.run_async(|ctx| clear_texture_tests(ctx, TEXTURE_FORMATS_UNCOMPRESSED_GLES_COMPAT));
|
|
|
|
#[gpu_test]
|
|
static CLEAR_TEXTURE_UNCOMPRESSED: GpuTestConfiguration = GpuTestConfiguration::new()
|
|
.parameters(
|
|
TestParameters::default()
|
|
.expect_fail(
|
|
FailureCase::backend(wgpu::Backends::GL)
|
|
.panic("texture with format Rg8Snorm was not fully cleared")
|
|
.panic("texture with format Rgb9e5Ufloat was not fully cleared")
|
|
.validation_error("GL_INVALID_FRAMEBUFFER_OPERATION")
|
|
.validation_error("GL_INVALID_OPERATION"),
|
|
)
|
|
.features(wgpu::Features::CLEAR_TEXTURE),
|
|
)
|
|
.run_async(|ctx| clear_texture_tests(ctx, TEXTURE_FORMATS_UNCOMPRESSED));
|
|
|
|
#[gpu_test]
|
|
static CLEAR_TEXTURE_DEPTH: GpuTestConfiguration = GpuTestConfiguration::new()
|
|
.parameters(
|
|
TestParameters::default()
|
|
.downlevel_flags(
|
|
wgpu::DownlevelFlags::DEPTH_TEXTURE_AND_BUFFER_COPIES
|
|
| wgpu::DownlevelFlags::COMPUTE_SHADERS,
|
|
)
|
|
// https://github.com/gfx-rs/wgpu/issues/5016
|
|
.skip(FailureCase::adapter("Apple Paravirtual device"))
|
|
.skip(FailureCase::webgl2())
|
|
.limits(wgpu::Limits::downlevel_defaults())
|
|
.features(wgpu::Features::CLEAR_TEXTURE),
|
|
)
|
|
.run_async(|ctx| clear_texture_tests(ctx, TEXTURE_FORMATS_DEPTH));
|
|
|
|
#[gpu_test]
|
|
static CLEAR_TEXTURE_DEPTH32_STENCIL8: GpuTestConfiguration = GpuTestConfiguration::new()
|
|
.parameters(
|
|
TestParameters::default()
|
|
.features(wgpu::Features::CLEAR_TEXTURE | wgpu::Features::DEPTH32FLOAT_STENCIL8)
|
|
.downlevel_flags(wgpu::DownlevelFlags::DEPTH_TEXTURE_AND_BUFFER_COPIES)
|
|
// https://github.com/gfx-rs/wgpu/issues/5016
|
|
.skip(FailureCase::adapter("Apple Paravirtual device")),
|
|
)
|
|
.run_async(|ctx| clear_texture_tests(ctx, &[wgpu::TextureFormat::Depth32FloatStencil8]));
|
|
|
|
#[gpu_test]
|
|
static CLEAR_TEXTURE_COMPRESSED_BCN: GpuTestConfiguration = GpuTestConfiguration::new()
|
|
.parameters(
|
|
TestParameters::default()
|
|
.features(
|
|
wgpu::Features::CLEAR_TEXTURE
|
|
| wgpu::Features::TEXTURE_COMPRESSION_BC
|
|
| wgpu::Features::TEXTURE_COMPRESSION_BC_SLICED_3D,
|
|
)
|
|
.limits(wgpu::Limits {
|
|
max_texture_dimension_3d: 1024,
|
|
..wgpu::Limits::downlevel_defaults()
|
|
})
|
|
// https://bugs.chromium.org/p/angleproject/issues/detail?id=7056
|
|
.expect_fail(FailureCase::backend_adapter(wgpu::Backends::GL, "ANGLE"))
|
|
// compressed texture copy to buffer not yet implemented
|
|
.expect_fail(FailureCase::backend(wgpu::Backends::GL)),
|
|
)
|
|
.run_async(|ctx| clear_texture_tests(ctx, TEXTURE_FORMATS_BC));
|
|
|
|
#[gpu_test]
|
|
static CLEAR_TEXTURE_COMPRESSED_ASTC: GpuTestConfiguration = GpuTestConfiguration::new()
|
|
.parameters(
|
|
TestParameters::default()
|
|
.features(wgpu::Features::CLEAR_TEXTURE | wgpu::Features::TEXTURE_COMPRESSION_ASTC)
|
|
.limits(wgpu::Limits {
|
|
max_texture_dimension_2d: wgpu::COPY_BYTES_PER_ROW_ALIGNMENT * 12,
|
|
..wgpu::Limits::downlevel_defaults()
|
|
})
|
|
// https://bugs.chromium.org/p/angleproject/issues/detail?id=7056
|
|
.expect_fail(FailureCase::backend_adapter(wgpu::Backends::GL, "ANGLE"))
|
|
// compressed texture copy to buffer not yet implemented
|
|
.expect_fail(FailureCase::backend(wgpu::Backends::GL)),
|
|
)
|
|
.run_async(|ctx| clear_texture_tests(ctx, TEXTURE_FORMATS_ASTC));
|
|
|
|
#[gpu_test]
|
|
static CLEAR_TEXTURE_COMPRESSED_ETC2: GpuTestConfiguration = GpuTestConfiguration::new()
|
|
.parameters(
|
|
TestParameters::default()
|
|
.features(wgpu::Features::CLEAR_TEXTURE | wgpu::Features::TEXTURE_COMPRESSION_ETC2)
|
|
// https://bugs.chromium.org/p/angleproject/issues/detail?id=7056
|
|
.expect_fail(FailureCase::backend_adapter(wgpu::Backends::GL, "ANGLE"))
|
|
// compressed texture copy to buffer not yet implemented
|
|
.expect_fail(FailureCase::backend(wgpu::Backends::GL)),
|
|
)
|
|
.run_async(|ctx| clear_texture_tests(ctx, TEXTURE_FORMATS_ETC2));
|