Implement depth24unorm-stencil8 and depth32float-stencil8 formats
- Add format implementation on D3D12, Metal and Vulkan
- Add more formats in depth/stencil copy, sampling and load op tests and
refactor them to test with parameters.
BUG=dawn:690
Change-Id: I829d1eea3ce35ffb39417ea23fb8afba6d542769
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/73180
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
Commit-Queue: Hao Li <hao.x.li@intel.com>
diff --git a/src/common/Math.h b/src/common/Math.h
index 69cab24..408c0a9 100644
--- a/src/common/Math.h
+++ b/src/common/Math.h
@@ -89,6 +89,11 @@
float Float16ToFloat32(uint16_t fp16);
bool IsFloat16NaN(uint16_t fp16);
+template <typename T>
+T FloatToUnorm(float value) {
+ return static_cast<T>(value * static_cast<float>(std::numeric_limits<T>::max()));
+}
+
float SRGBToLinear(float srgb);
template <typename T1,
diff --git a/src/dawn_native/d3d12/AdapterD3D12.cpp b/src/dawn_native/d3d12/AdapterD3D12.cpp
index 6e40c7a..df8ec50 100644
--- a/src/dawn_native/d3d12/AdapterD3D12.cpp
+++ b/src/dawn_native/d3d12/AdapterD3D12.cpp
@@ -135,6 +135,9 @@
mSupportedFeatures.EnableFeature(Feature::TextureCompressionBC);
mSupportedFeatures.EnableFeature(Feature::PipelineStatisticsQuery);
mSupportedFeatures.EnableFeature(Feature::MultiPlanarFormats);
+ mSupportedFeatures.EnableFeature(Feature::Depth24UnormStencil8);
+ mSupportedFeatures.EnableFeature(Feature::Depth32FloatStencil8);
+
return {};
}
diff --git a/src/dawn_native/d3d12/TextureD3D12.cpp b/src/dawn_native/d3d12/TextureD3D12.cpp
index 7a913a2..4168134 100644
--- a/src/dawn_native/d3d12/TextureD3D12.cpp
+++ b/src/dawn_native/d3d12/TextureD3D12.cpp
@@ -178,7 +178,10 @@
case wgpu::TextureFormat::Depth24Plus:
return DXGI_FORMAT_R32_TYPELESS;
+ case wgpu::TextureFormat::Depth24UnormStencil8:
+ return DXGI_FORMAT_R24G8_TYPELESS;
case wgpu::TextureFormat::Depth24PlusStencil8:
+ case wgpu::TextureFormat::Depth32FloatStencil8:
return DXGI_FORMAT_R32G8X24_TYPELESS;
case wgpu::TextureFormat::BC1RGBAUnorm:
@@ -252,10 +255,6 @@
case wgpu::TextureFormat::R8BG8Biplanar420Unorm:
// TODO(dawn:666): implement stencil8
case wgpu::TextureFormat::Stencil8:
- // TODO(dawn:690): implement depth24unorm-stencil8
- case wgpu::TextureFormat::Depth24UnormStencil8:
- // TODO(dawn:690): implement depth32float-stencil8
- case wgpu::TextureFormat::Depth32FloatStencil8:
case wgpu::TextureFormat::Undefined:
UNREACHABLE();
}
@@ -342,14 +341,16 @@
case wgpu::TextureFormat::RGBA32Float:
return DXGI_FORMAT_R32G32B32A32_FLOAT;
- case wgpu::TextureFormat::Depth32Float:
- return DXGI_FORMAT_D32_FLOAT;
- case wgpu::TextureFormat::Depth24Plus:
- return DXGI_FORMAT_D32_FLOAT;
- case wgpu::TextureFormat::Depth24PlusStencil8:
- return DXGI_FORMAT_D32_FLOAT_S8X24_UINT;
case wgpu::TextureFormat::Depth16Unorm:
return DXGI_FORMAT_D16_UNORM;
+ case wgpu::TextureFormat::Depth32Float:
+ case wgpu::TextureFormat::Depth24Plus:
+ return DXGI_FORMAT_D32_FLOAT;
+ case wgpu::TextureFormat::Depth24UnormStencil8:
+ return DXGI_FORMAT_D24_UNORM_S8_UINT;
+ case wgpu::TextureFormat::Depth24PlusStencil8:
+ case wgpu::TextureFormat::Depth32FloatStencil8:
+ return DXGI_FORMAT_D32_FLOAT_S8X24_UINT;
case wgpu::TextureFormat::BC1RGBAUnorm:
return DXGI_FORMAT_BC1_UNORM;
@@ -425,10 +426,6 @@
// TODO(dawn:666): implement stencil8
case wgpu::TextureFormat::Stencil8:
- // TODO(dawn:690): implement depth24unorm-stencil8
- case wgpu::TextureFormat::Depth24UnormStencil8:
- // TODO(dawn:690): implement depth32float-stencil8
- case wgpu::TextureFormat::Depth32FloatStencil8:
case wgpu::TextureFormat::Undefined:
UNREACHABLE();
}
@@ -699,7 +696,9 @@
ASSERT(GetFormat().aspects & aspect);
switch (GetFormat().format) {
+ case wgpu::TextureFormat::Depth24UnormStencil8:
case wgpu::TextureFormat::Depth24PlusStencil8:
+ case wgpu::TextureFormat::Depth32FloatStencil8:
switch (aspect) {
case Aspect::Depth:
return DXGI_FORMAT_R32_FLOAT;
@@ -1186,7 +1185,39 @@
case wgpu::TextureFormat::Depth16Unorm:
mSrvDesc.Format = DXGI_FORMAT_R16_UNORM;
break;
+ case wgpu::TextureFormat::Depth24UnormStencil8:
+ switch (descriptor->aspect) {
+ case wgpu::TextureAspect::DepthOnly:
+ planeSlice = 0;
+ mSrvDesc.Format = DXGI_FORMAT_R24_UNORM_X8_TYPELESS;
+ break;
+ case wgpu::TextureAspect::StencilOnly:
+ planeSlice = 1;
+ mSrvDesc.Format = DXGI_FORMAT_X24_TYPELESS_G8_UINT;
+ // Stencil is accessed using the .g component in the shader.
+ // Map it to the zeroth component to match other APIs.
+ mSrvDesc.Shader4ComponentMapping =
+ D3D12_ENCODE_SHADER_4_COMPONENT_MAPPING(
+ D3D12_SHADER_COMPONENT_MAPPING_FROM_MEMORY_COMPONENT_1,
+ D3D12_SHADER_COMPONENT_MAPPING_FORCE_VALUE_0,
+ D3D12_SHADER_COMPONENT_MAPPING_FORCE_VALUE_0,
+ D3D12_SHADER_COMPONENT_MAPPING_FORCE_VALUE_1);
+ break;
+ case wgpu::TextureAspect::All:
+ // A single aspect is not selected. The texture view must not be
+ // sampled.
+ mSrvDesc.Format = DXGI_FORMAT_UNKNOWN;
+ break;
+
+ // Depth formats cannot use plane aspects.
+ case wgpu::TextureAspect::Plane0Only:
+ case wgpu::TextureAspect::Plane1Only:
+ UNREACHABLE();
+ break;
+ }
+ break;
case wgpu::TextureFormat::Depth24PlusStencil8:
+ case wgpu::TextureFormat::Depth32FloatStencil8:
switch (descriptor->aspect) {
case wgpu::TextureAspect::DepthOnly:
planeSlice = 0;
diff --git a/src/dawn_native/metal/BackendMTL.mm b/src/dawn_native/metal/BackendMTL.mm
index 8b0194b..ee7e8e0 100644
--- a/src/dawn_native/metal/BackendMTL.mm
+++ b/src/dawn_native/metal/BackendMTL.mm
@@ -324,6 +324,17 @@
mSupportedFeatures.EnableFeature(Feature::DepthClamping);
}
+ if (@available(macOS 10.11, iOS 9.0, *)) {
+ mSupportedFeatures.EnableFeature(Feature::Depth32FloatStencil8);
+ }
+
+#if defined(DAWN_PLATFORM_MACOS)
+ // MTLPixelFormatDepth24Unorm_Stencil8 is only available on macOS 10.11+
+ if ([*mDevice isDepth24Stencil8PixelFormatSupported]) {
+ mSupportedFeatures.EnableFeature(Feature::Depth24UnormStencil8);
+ }
+#endif
+
return {};
}
diff --git a/src/dawn_native/metal/TextureMTL.mm b/src/dawn_native/metal/TextureMTL.mm
index 37eb9bc..7a98886 100644
--- a/src/dawn_native/metal/TextureMTL.mm
+++ b/src/dawn_native/metal/TextureMTL.mm
@@ -222,6 +222,7 @@
case wgpu::TextureFormat::Depth24Plus:
return MTLPixelFormatDepth32Float;
case wgpu::TextureFormat::Depth24PlusStencil8:
+ case wgpu::TextureFormat::Depth32FloatStencil8:
return MTLPixelFormatDepth32Float_Stencil8;
case wgpu::TextureFormat::Depth16Unorm:
if (@available(macOS 10.12, iOS 13.0, *)) {
@@ -232,6 +233,9 @@
}
#if defined(DAWN_PLATFORM_MACOS)
+ case wgpu::TextureFormat::Depth24UnormStencil8:
+ return MTLPixelFormatDepth24Unorm_Stencil8;
+
case wgpu::TextureFormat::BC1RGBAUnorm:
return MTLPixelFormatBC1_RGBA;
case wgpu::TextureFormat::BC1RGBAUnormSrgb:
@@ -261,6 +265,8 @@
case wgpu::TextureFormat::BC7RGBAUnormSrgb:
return MTLPixelFormatBC7_RGBAUnorm_sRGB;
#else
+ case wgpu::TextureFormat::Depth24UnormStencil8:
+
case wgpu::TextureFormat::BC1RGBAUnorm:
case wgpu::TextureFormat::BC1RGBAUnormSrgb:
case wgpu::TextureFormat::BC2RGBAUnorm:
@@ -321,10 +327,6 @@
// TODO(dawn:666): implement stencil8
case wgpu::TextureFormat::Stencil8:
- // TODO(dawn:690): implement depth24unorm-stencil8
- case wgpu::TextureFormat::Depth24UnormStencil8:
- // TODO(dawn:690): implement depth32float-stencil8
- case wgpu::TextureFormat::Depth32FloatStencil8:
case wgpu::TextureFormat::Undefined:
UNREACHABLE();
}
@@ -746,8 +748,17 @@
MTLPixelFormat format = MetalPixelFormat(descriptor->format);
if (descriptor->aspect == wgpu::TextureAspect::StencilOnly) {
if (@available(macOS 10.12, iOS 10.0, *)) {
- ASSERT(format == MTLPixelFormatDepth32Float_Stencil8);
- format = MTLPixelFormatX32_Stencil8;
+ if (format == MTLPixelFormatDepth32Float_Stencil8) {
+ format = MTLPixelFormatX32_Stencil8;
+ }
+#if defined(DAWN_PLATFORM_MACOS)
+ else if (format == MTLPixelFormatDepth24Unorm_Stencil8) {
+ format = MTLPixelFormatX24_Stencil8;
+ }
+#endif
+ else {
+ UNREACHABLE();
+ }
} else {
// TODO(enga): Add a workaround to back combined depth/stencil textures
// with Sampled usage using two separate textures.
diff --git a/src/dawn_native/vulkan/AdapterVk.cpp b/src/dawn_native/vulkan/AdapterVk.cpp
index 4f8b1c9..4eea820 100644
--- a/src/dawn_native/vulkan/AdapterVk.cpp
+++ b/src/dawn_native/vulkan/AdapterVk.cpp
@@ -151,6 +151,14 @@
mSupportedFeatures.EnableFeature(Feature::TimestampQuery);
}
+ if (IsDepthStencilFormatSupported(VK_FORMAT_D24_UNORM_S8_UINT)) {
+ mSupportedFeatures.EnableFeature(Feature::Depth24UnormStencil8);
+ }
+
+ if (IsDepthStencilFormatSupported(VK_FORMAT_D32_SFLOAT_S8_UINT)) {
+ mSupportedFeatures.EnableFeature(Feature::Depth32FloatStencil8);
+ }
+
#if defined(DAWN_USE_SYNC_FDS)
// TODO(chromium:1258986): Precisely enable the feature by querying the device's format
// features.
diff --git a/src/dawn_native/vulkan/TextureVk.cpp b/src/dawn_native/vulkan/TextureVk.cpp
index 1b4c7d3..ab89859 100644
--- a/src/dawn_native/vulkan/TextureVk.cpp
+++ b/src/dawn_native/vulkan/TextureVk.cpp
@@ -311,6 +311,10 @@
} else {
return VK_FORMAT_D24_UNORM_S8_UINT;
}
+ case wgpu::TextureFormat::Depth24UnormStencil8:
+ return VK_FORMAT_D24_UNORM_S8_UINT;
+ case wgpu::TextureFormat::Depth32FloatStencil8:
+ return VK_FORMAT_D32_SFLOAT_S8_UINT;
case wgpu::TextureFormat::BC1RGBAUnorm:
return VK_FORMAT_BC1_RGBA_UNORM_BLOCK;
@@ -424,10 +428,6 @@
// TODO(dawn:666): implement stencil8
case wgpu::TextureFormat::Stencil8:
- // TODO(dawn:690): implement depth24unorm-stencil8
- case wgpu::TextureFormat::Depth24UnormStencil8:
- // TODO(dawn:690): implement depth32float-stencil8
- case wgpu::TextureFormat::Depth32FloatStencil8:
case wgpu::TextureFormat::Undefined:
break;
}
diff --git a/src/tests/end2end/DepthStencilCopyTests.cpp b/src/tests/end2end/DepthStencilCopyTests.cpp
index 8b875ce..2edd3ee 100644
--- a/src/tests/end2end/DepthStencilCopyTests.cpp
+++ b/src/tests/end2end/DepthStencilCopyTests.cpp
@@ -22,10 +22,23 @@
#include "utils/TextureUtils.h"
#include "utils/WGPUHelpers.h"
-class DepthStencilCopyTests : public DawnTest {
+namespace {
+ using TextureFormat = wgpu::TextureFormat;
+ DAWN_TEST_PARAM_STRUCT(DepthStencilCopyTestParams, TextureFormat);
+
+ constexpr std::array<wgpu::TextureFormat, 3> kValidDepthCopyTextureFormats = {
+ wgpu::TextureFormat::Depth16Unorm,
+ wgpu::TextureFormat::Depth32Float,
+ wgpu::TextureFormat::Depth32FloatStencil8,
+ };
+} // namespace
+
+class DepthStencilCopyTests : public DawnTestWithParams<DepthStencilCopyTestParams> {
protected:
void SetUp() override {
- DawnTest::SetUp();
+ DawnTestWithParams<DepthStencilCopyTestParams>::SetUp();
+
+ DAWN_TEST_UNSUPPORTED_IF(!mIsFormatSupported);
// Draw a square in the bottom left quarter of the screen.
mVertexModule = utils::CreateShaderModule(device, R"(
@@ -42,13 +55,56 @@
})");
}
+ std::vector<wgpu::FeatureName> GetRequiredFeatures() override {
+ switch (GetParam().mTextureFormat) {
+ case wgpu::TextureFormat::Depth24UnormStencil8:
+ if (SupportsFeatures({wgpu::FeatureName::Depth24UnormStencil8})) {
+ mIsFormatSupported = true;
+ return {wgpu::FeatureName::Depth24UnormStencil8};
+ }
+ return {};
+ case wgpu::TextureFormat::Depth32FloatStencil8:
+ if (SupportsFeatures({wgpu::FeatureName::Depth32FloatStencil8})) {
+ mIsFormatSupported = true;
+ return {wgpu::FeatureName::Depth32FloatStencil8};
+ }
+ return {};
+ default:
+ mIsFormatSupported = true;
+ return {};
+ }
+ }
+
+ bool IsValidDepthCopyTextureFormat() {
+ switch (GetParam().mTextureFormat) {
+ case wgpu::TextureFormat::Depth16Unorm:
+ case wgpu::TextureFormat::Depth32Float:
+ case wgpu::TextureFormat::Depth32FloatStencil8:
+ return true;
+ default:
+ return false;
+ }
+ }
+
+ wgpu::Texture CreateTexture(uint32_t width,
+ uint32_t height,
+ wgpu::TextureUsage usage,
+ uint32_t mipLevelCount = 1) {
+ wgpu::TextureDescriptor texDescriptor = {};
+ texDescriptor.size = {width, height, 1};
+ texDescriptor.format = GetParam().mTextureFormat;
+ texDescriptor.usage = usage;
+ texDescriptor.mipLevelCount = mipLevelCount;
+ return device.CreateTexture(&texDescriptor);
+ }
+
wgpu::Texture CreateDepthStencilTexture(uint32_t width,
uint32_t height,
wgpu::TextureUsage usage,
uint32_t mipLevelCount = 1) {
wgpu::TextureDescriptor texDescriptor = {};
texDescriptor.size = {width, height, 1};
- texDescriptor.format = wgpu::TextureFormat::Depth24PlusStencil8;
+ texDescriptor.format = GetParam().mTextureFormat;
texDescriptor.usage = usage;
texDescriptor.mipLevelCount = mipLevelCount;
return device.CreateTexture(&texDescriptor);
@@ -60,7 +116,7 @@
uint32_t mipLevelCount = 1) {
wgpu::TextureDescriptor texDescriptor = {};
texDescriptor.size = {width, height, 1};
- texDescriptor.format = wgpu::TextureFormat::Depth32Float;
+ texDescriptor.format = GetParam().mTextureFormat;
texDescriptor.usage = usage;
texDescriptor.mipLevelCount = mipLevelCount;
return device.CreateTexture(&texDescriptor);
@@ -97,7 +153,7 @@
renderPassDesc.cDepthStencilAttachmentInfo.clearDepth = clearDepth;
utils::ComboRenderPipelineDescriptor renderPipelineDesc;
- PopulatePipelineDescriptorWriteDepth(&renderPipelineDesc, wgpu::TextureFormat::Depth32Float,
+ PopulatePipelineDescriptorWriteDepth(&renderPipelineDesc, GetParam().mTextureFormat,
regionDepth);
wgpu::RenderPipeline pipeline = device.CreateRenderPipeline(&renderPipelineDesc);
@@ -129,8 +185,8 @@
renderPassDesc.cDepthStencilAttachmentInfo.clearStencil = clearStencil;
utils::ComboRenderPipelineDescriptor renderPipelineDesc;
- PopulatePipelineDescriptorWriteDepth(&renderPipelineDesc,
- wgpu::TextureFormat::Depth24PlusStencil8, regionDepth);
+ PopulatePipelineDescriptorWriteDepth(&renderPipelineDesc, GetParam().mTextureFormat,
+ regionDepth);
renderPipelineDesc.cDepthStencil.stencilFront.passOp = wgpu::StencilOperation::Replace;
wgpu::RenderPipeline pipeline = device.CreateRenderPipeline(&renderPipelineDesc);
@@ -183,97 +239,11 @@
}
wgpu::ShaderModule mVertexModule;
+
+ private:
+ bool mIsFormatSupported = false;
};
-// Test copying the depth-only aspect into a buffer.
-TEST_P(DepthStencilCopyTests, FromDepthAspect) {
- constexpr uint32_t kWidth = 4;
- constexpr uint32_t kHeight = 4;
-
- wgpu::Texture depthTexture = CreateDepthTexture(
- kWidth, kHeight, wgpu::TextureUsage::RenderAttachment | wgpu::TextureUsage::CopySrc);
-
- InitializeDepthTextureRegion(depthTexture, 0.f, 0.3f);
-
- // This expectation is the test as it performs the CopyTextureToBuffer.
- std::vector<float> expectedData = {
- 0.0, 0.0, 0.0, 0.0, //
- 0.0, 0.0, 0.0, 0.0, //
- 0.3, 0.3, 0.0, 0.0, //
- 0.3, 0.3, 0.0, 0.0, //
- };
- EXPECT_TEXTURE_EQ(expectedData.data(), depthTexture, {0, 0}, {kWidth, kHeight}, 0,
- wgpu::TextureAspect::DepthOnly);
-}
-
-// Test copying the stencil-only aspect into a buffer.
-TEST_P(DepthStencilCopyTests, FromStencilAspect) {
- // TODO(crbug.com/dawn/667): Work around the fact that some platforms are unable to read
- // stencil.
- DAWN_TEST_UNSUPPORTED_IF(HasToggleEnabled("disable_depth_stencil_read"));
-
- constexpr uint32_t kWidth = 4;
- constexpr uint32_t kHeight = 4;
-
- wgpu::Texture depthStencilTexture = CreateDepthStencilTexture(
- kWidth, kHeight, wgpu::TextureUsage::RenderAttachment | wgpu::TextureUsage::CopySrc);
-
- InitializeDepthStencilTextureRegion(depthStencilTexture, 0.f, 0.3f, 0u, 1u);
-
- // This expectation is the test as it performs the CopyTextureToBuffer.
- std::vector<uint8_t> expectedData = {
- 0u, 0u, 0u, 0u, //
- 0u, 0u, 0u, 0u, //
- 1u, 1u, 0u, 0u, //
- 1u, 1u, 0u, 0u, //
- };
- EXPECT_TEXTURE_EQ(expectedData.data(), depthStencilTexture, {0, 0}, {kWidth, kHeight}, 0,
- wgpu::TextureAspect::StencilOnly);
-}
-
-// Test copying the non-zero mip, stencil-only aspect into a buffer.
-TEST_P(DepthStencilCopyTests, FromNonZeroMipStencilAspect) {
- // TODO(crbug.com/dawn/704): Readback after clear via stencil copy does not work
- // on some Intel drivers.
- DAWN_SUPPRESS_TEST_IF(IsMetal() && IsIntel());
-
- // TODO(crbug.com/dawn/667): Work around some platforms' inability to read back stencil.
- DAWN_TEST_UNSUPPORTED_IF(HasToggleEnabled("disable_depth_stencil_read"));
-
- wgpu::Texture depthStencilTexture = CreateDepthStencilTexture(
- 9, 9, wgpu::TextureUsage::RenderAttachment | wgpu::TextureUsage::CopySrc, 2);
-
- InitializeDepthStencilTextureRegion(depthStencilTexture, 0.f, 0.3f, 0u, 1u, 1u);
-
- // This expectation is the test as it performs the CopyTextureToBuffer.
- std::vector<uint8_t> expectedData = {
- 0u, 0u, 0u, 0u, //
- 0u, 0u, 0u, 0u, //
- 1u, 1u, 0u, 0u, //
- 1u, 1u, 0u, 0u, //
- };
- EXPECT_TEXTURE_EQ(expectedData.data(), depthStencilTexture, {0, 0}, {4, 4}, 1,
- wgpu::TextureAspect::StencilOnly);
-}
-
-// Test copying the non-zero mip, depth-only aspect into a buffer.
-TEST_P(DepthStencilCopyTests, FromNonZeroMipDepthAspect) {
- wgpu::Texture depthTexture = CreateDepthTexture(
- 9, 9, wgpu::TextureUsage::RenderAttachment | wgpu::TextureUsage::CopySrc, 2);
-
- InitializeDepthTextureRegion(depthTexture, 0.f, 0.4f, 1);
-
- // This expectation is the test as it performs the CopyTextureToBuffer.
- std::vector<float> expectedData = {
- 0.0, 0.0, 0.0, 0.0, //
- 0.0, 0.0, 0.0, 0.0, //
- 0.4, 0.4, 0.0, 0.0, //
- 0.4, 0.4, 0.0, 0.0, //
- };
- EXPECT_TEXTURE_EQ(expectedData.data(), depthTexture, {0, 0}, {4, 4}, 1,
- wgpu::TextureAspect::DepthOnly);
-}
-
// Test copying both aspects in a T2T copy, then copying only stencil.
TEST_P(DepthStencilCopyTests, T2TBothAspectsThenCopyStencil) {
// TODO(crbug.com/dawn/704): Readback after clear via stencil copy does not work
@@ -354,6 +324,8 @@
// Test copying both aspects in a T2T copy, then copying only depth.
TEST_P(DepthStencilCopyTests, T2TBothAspectsThenCopyDepth) {
+ DAWN_TEST_UNSUPPORTED_IF(!IsValidDepthCopyTextureFormat());
+
constexpr uint32_t kWidth = 4;
constexpr uint32_t kHeight = 4;
@@ -361,8 +333,7 @@
0.1f, 0.3f, 1u, 3u, kWidth, kHeight, wgpu::TextureUsage::RenderAttachment);
// Check the depth
- ExpectAttachmentDepthTestData(texture, wgpu::TextureFormat::Depth24PlusStencil8, kWidth,
- kHeight, 0, 0,
+ ExpectAttachmentDepthTestData(texture, GetParam().mTextureFormat, kWidth, kHeight, 0, 0,
{
0.1, 0.1, 0.1, 0.1, //
0.1, 0.1, 0.1, 0.1, //
@@ -373,11 +344,13 @@
// Test copying both aspects in a T2T copy, then copying only depth at a nonzero mip.
TEST_P(DepthStencilCopyTests, T2TBothAspectsThenCopyNonZeroMipDepth) {
+ DAWN_TEST_UNSUPPORTED_IF(!IsValidDepthCopyTextureFormat());
+
wgpu::Texture texture = CreateInitializeDepthStencilTextureAndCopyT2T(
0.1f, 0.3f, 1u, 3u, 8, 8, wgpu::TextureUsage::RenderAttachment, 1);
// Check the depth
- ExpectAttachmentDepthTestData(texture, wgpu::TextureFormat::Depth24PlusStencil8, 4, 4, 0, 1,
+ ExpectAttachmentDepthTestData(texture, GetParam().mTextureFormat, 4, 4, 0, 1,
{
0.1, 0.1, 0.1, 0.1, //
0.1, 0.1, 0.1, 0.1, //
@@ -388,6 +361,8 @@
// Test copying both aspects in a T2T copy, then copying stencil, then copying depth
TEST_P(DepthStencilCopyTests, T2TBothAspectsThenCopyStencilThenDepth) {
+ DAWN_TEST_UNSUPPORTED_IF(!IsValidDepthCopyTextureFormat());
+
// TODO(crbug.com/dawn/667): Work around some platforms' inability to read back stencil.
DAWN_TEST_UNSUPPORTED_IF(HasToggleEnabled("disable_depth_stencil_read"));
@@ -409,8 +384,7 @@
wgpu::TextureAspect::StencilOnly);
// Check the depth
- ExpectAttachmentDepthTestData(texture, wgpu::TextureFormat::Depth24PlusStencil8, kWidth,
- kHeight, 0, 0,
+ ExpectAttachmentDepthTestData(texture, GetParam().mTextureFormat, kWidth, kHeight, 0, 0,
{
0.1, 0.1, 0.1, 0.1, //
0.1, 0.1, 0.1, 0.1, //
@@ -421,6 +395,8 @@
// Test copying both aspects in a T2T copy, then copying depth, then copying stencil
TEST_P(DepthStencilCopyTests, T2TBothAspectsThenCopyDepthThenStencil) {
+ DAWN_TEST_UNSUPPORTED_IF(!IsValidDepthCopyTextureFormat());
+
// TODO(crbug.com/dawn/704): Readback after clear via stencil copy does not work
// on some Intel drivers.
// It seems like the depth readback copy mutates the stencil because the previous
@@ -440,8 +416,7 @@
wgpu::TextureUsage::CopySrc | wgpu::TextureUsage::RenderAttachment);
// Check the depth
- ExpectAttachmentDepthTestData(texture, wgpu::TextureFormat::Depth24PlusStencil8, kWidth,
- kHeight, 0, 0,
+ ExpectAttachmentDepthTestData(texture, GetParam().mTextureFormat, kWidth, kHeight, 0, 0,
{
0.1, 0.1, 0.1, 0.1, //
0.1, 0.1, 0.1, 0.1, //
@@ -460,8 +435,137 @@
wgpu::TextureAspect::StencilOnly);
}
+class DepthCopyTests : public DepthStencilCopyTests {};
+
+// Test copying the depth-only aspect into a buffer.
+TEST_P(DepthCopyTests, FromDepthAspect) {
+ // TODO(crbug.com/dawn/1237): Depth16Unorm test failed on OpenGL and OpenGLES which says
+ // Invalid format and type combination in glReadPixels
+ DAWN_TEST_UNSUPPORTED_IF(GetParam().mTextureFormat == wgpu::TextureFormat::Depth16Unorm &&
+ (IsOpenGL() || IsOpenGLES()));
+
+ constexpr uint32_t kWidth = 4;
+ constexpr uint32_t kHeight = 4;
+
+ wgpu::Texture texture = CreateTexture(
+ kWidth, kHeight, wgpu::TextureUsage::RenderAttachment | wgpu::TextureUsage::CopySrc);
+
+ constexpr float kInitDepth = 0.2f;
+ InitializeDepthTextureRegion(texture, 0.f, kInitDepth);
+
+ // This expectation is the test as it performs the CopyTextureToBuffer.
+ if (GetParam().mTextureFormat == wgpu::TextureFormat::Depth16Unorm) {
+ uint16_t expected = FloatToUnorm<uint16_t>(kInitDepth);
+ std::vector<uint16_t> expectedData = {
+ 0, 0, 0, 0, //
+ 0, 0, 0, 0, //
+ expected, expected, 0, 0, //
+ expected, expected, 0, 0, //
+ };
+ EXPECT_TEXTURE_EQ(expectedData.data(), texture, {0, 0}, {kWidth, kHeight}, 0,
+ wgpu::TextureAspect::DepthOnly);
+ } else {
+ std::vector<float> expectedData = {
+ 0.0, 0.0, 0.0, 0.0, //
+ 0.0, 0.0, 0.0, 0.0, //
+ kInitDepth, kInitDepth, 0.0, 0.0, //
+ kInitDepth, kInitDepth, 0.0, 0.0, //
+ };
+ EXPECT_TEXTURE_EQ(expectedData.data(), texture, {0, 0}, {kWidth, kHeight}, 0,
+ wgpu::TextureAspect::DepthOnly);
+ }
+}
+
+// Test copying the non-zero mip, depth-only aspect into a buffer.
+TEST_P(DepthCopyTests, FromNonZeroMipDepthAspect) {
+ // TODO(crbug.com/dawn/1237): Depth16Unorm test failed on OpenGL and OpenGLES which says
+ // Invalid format and type combination in glReadPixels
+ DAWN_TEST_UNSUPPORTED_IF(GetParam().mTextureFormat == wgpu::TextureFormat::Depth16Unorm &&
+ (IsOpenGL() || IsOpenGLES()));
+
+ wgpu::Texture depthTexture = CreateDepthTexture(
+ 9, 9, wgpu::TextureUsage::RenderAttachment | wgpu::TextureUsage::CopySrc, 2);
+
+ constexpr float kInitDepth = 0.4f;
+ InitializeDepthTextureRegion(depthTexture, 0.f, kInitDepth, 1);
+
+ // This expectation is the test as it performs the CopyTextureToBuffer.
+ if (GetParam().mTextureFormat == wgpu::TextureFormat::Depth16Unorm) {
+ uint16_t expected = FloatToUnorm<uint16_t>(kInitDepth);
+ std::vector<uint16_t> expectedData = {
+ 0, 0, 0, 0, //
+ 0, 0, 0, 0, //
+ expected, expected, 0, 0, //
+ expected, expected, 0, 0, //
+ };
+ EXPECT_TEXTURE_EQ(expectedData.data(), depthTexture, {0, 0}, {4, 4}, 1,
+ wgpu::TextureAspect::DepthOnly);
+ } else {
+ std::vector<float> expectedData = {
+ 0.0, 0.0, 0.0, 0.0, //
+ 0.0, 0.0, 0.0, 0.0, //
+ kInitDepth, kInitDepth, 0.0, 0.0, //
+ kInitDepth, kInitDepth, 0.0, 0.0, //
+ };
+ EXPECT_TEXTURE_EQ(expectedData.data(), depthTexture, {0, 0}, {4, 4}, 1,
+ wgpu::TextureAspect::DepthOnly);
+ }
+}
+
+class StencilCopyTests : public DepthStencilCopyTests {};
+
+// Test copying the stencil-only aspect into a buffer.
+TEST_P(StencilCopyTests, FromStencilAspect) {
+ // TODO(crbug.com/dawn/667): Work around the fact that some platforms are unable to read
+ // stencil.
+ DAWN_TEST_UNSUPPORTED_IF(HasToggleEnabled("disable_depth_stencil_read"));
+
+ constexpr uint32_t kWidth = 4;
+ constexpr uint32_t kHeight = 4;
+
+ wgpu::Texture depthStencilTexture = CreateDepthStencilTexture(
+ kWidth, kHeight, wgpu::TextureUsage::RenderAttachment | wgpu::TextureUsage::CopySrc);
+
+ InitializeDepthStencilTextureRegion(depthStencilTexture, 0.f, 0.3f, 0u, 1u);
+
+ // This expectation is the test as it performs the CopyTextureToBuffer.
+ std::vector<uint8_t> expectedData = {
+ 0u, 0u, 0u, 0u, //
+ 0u, 0u, 0u, 0u, //
+ 1u, 1u, 0u, 0u, //
+ 1u, 1u, 0u, 0u, //
+ };
+ EXPECT_TEXTURE_EQ(expectedData.data(), depthStencilTexture, {0, 0}, {kWidth, kHeight}, 0,
+ wgpu::TextureAspect::StencilOnly);
+}
+
+// Test copying the non-zero mip, stencil-only aspect into a buffer.
+TEST_P(StencilCopyTests, FromNonZeroMipStencilAspect) {
+ // TODO(crbug.com/dawn/704): Readback after clear via stencil copy does not work
+ // on some Intel drivers.
+ DAWN_SUPPRESS_TEST_IF(IsMetal() && IsIntel());
+
+ // TODO(crbug.com/dawn/667): Work around some platforms' inability to read back stencil.
+ DAWN_TEST_UNSUPPORTED_IF(HasToggleEnabled("disable_depth_stencil_read"));
+
+ wgpu::Texture depthStencilTexture = CreateDepthStencilTexture(
+ 9, 9, wgpu::TextureUsage::RenderAttachment | wgpu::TextureUsage::CopySrc, 2);
+
+ InitializeDepthStencilTextureRegion(depthStencilTexture, 0.f, 0.3f, 0u, 1u, 1u);
+
+ // This expectation is the test as it performs the CopyTextureToBuffer.
+ std::vector<uint8_t> expectedData = {
+ 0u, 0u, 0u, 0u, //
+ 0u, 0u, 0u, 0u, //
+ 1u, 1u, 0u, 0u, //
+ 1u, 1u, 0u, 0u, //
+ };
+ EXPECT_TEXTURE_EQ(expectedData.data(), depthStencilTexture, {0, 0}, {4, 4}, 1,
+ wgpu::TextureAspect::StencilOnly);
+}
+
// Test copying to the stencil-aspect of a buffer
-TEST_P(DepthStencilCopyTests, ToStencilAspect) {
+TEST_P(StencilCopyTests, ToStencilAspect) {
// Copies to a single aspect are unsupported on OpenGL.
DAWN_TEST_UNSUPPORTED_IF(IsOpenGL());
DAWN_TEST_UNSUPPORTED_IF(IsOpenGLES());
@@ -531,7 +635,7 @@
[[stage(fragment)]] fn main() {
})");
wgpu::DepthStencilState* depthStencil =
- renderPipelineDesc.EnableDepthStencil(wgpu::TextureFormat::Depth24PlusStencil8);
+ renderPipelineDesc.EnableDepthStencil(GetParam().mTextureFormat);
depthStencil->stencilFront.passOp = wgpu::StencilOperation::DecrementClamp;
renderPipelineDesc.cFragment.targetCount = 0;
@@ -557,8 +661,8 @@
EXPECT_TEXTURE_EQ(expectedStencilData.data(), depthStencilTexture, {0, 0}, {kWidth, kHeight}, 0,
wgpu::TextureAspect::StencilOnly);
- ExpectAttachmentDepthTestData(depthStencilTexture, wgpu::TextureFormat::Depth24PlusStencil8,
- kWidth, kHeight, 0, 0,
+ ExpectAttachmentDepthTestData(depthStencilTexture, GetParam().mTextureFormat, kWidth, kHeight,
+ 0, 0,
{
0.7, 0.7, 0.7, 0.7, //
0.7, 0.7, 0.7, 0.7, //
@@ -567,9 +671,20 @@
});
}
-DAWN_INSTANTIATE_TEST(DepthStencilCopyTests,
- D3D12Backend(),
- MetalBackend(),
- OpenGLBackend(),
- OpenGLESBackend(),
- VulkanBackend());
+DAWN_INSTANTIATE_TEST_P(DepthStencilCopyTests,
+ {D3D12Backend(), MetalBackend(), OpenGLBackend(), OpenGLESBackend(),
+ VulkanBackend()},
+ std::vector<wgpu::TextureFormat>(utils::kDepthAndStencilFormats.begin(),
+ utils::kDepthAndStencilFormats.end()));
+
+DAWN_INSTANTIATE_TEST_P(DepthCopyTests,
+ {D3D12Backend(), MetalBackend(), OpenGLBackend(), OpenGLESBackend(),
+ VulkanBackend()},
+ std::vector<wgpu::TextureFormat>(kValidDepthCopyTextureFormats.begin(),
+ kValidDepthCopyTextureFormats.end()));
+
+DAWN_INSTANTIATE_TEST_P(StencilCopyTests,
+ {D3D12Backend(), MetalBackend(), OpenGLBackend(), OpenGLESBackend(),
+ VulkanBackend()},
+ std::vector<wgpu::TextureFormat>(utils::kStencilFormats.begin(),
+ utils::kStencilFormats.end()));
diff --git a/src/tests/end2end/DepthStencilLoadOpTests.cpp b/src/tests/end2end/DepthStencilLoadOpTests.cpp
index 8990408..e9b0796 100644
--- a/src/tests/end2end/DepthStencilLoadOpTests.cpp
+++ b/src/tests/end2end/DepthStencilLoadOpTests.cpp
@@ -62,6 +62,8 @@
void SetUp() override {
DawnTestWithParams<DepthStencilLoadOpTestParams>::SetUp();
+ DAWN_TEST_UNSUPPORTED_IF(!mIsFormatSupported);
+
// Readback of Depth/Stencil textures not fully supported on GL right now.
// Also depends on glTextureView which is not supported on ES.
DAWN_SUPPRESS_TEST_IF(IsOpenGL() || IsOpenGLES());
@@ -91,6 +93,26 @@
}
}
+ std::vector<wgpu::FeatureName> GetRequiredFeatures() override {
+ switch (GetParam().mFormat) {
+ case wgpu::TextureFormat::Depth24UnormStencil8:
+ if (SupportsFeatures({wgpu::FeatureName::Depth24UnormStencil8})) {
+ mIsFormatSupported = true;
+ return {wgpu::FeatureName::Depth24UnormStencil8};
+ }
+ return {};
+ case wgpu::TextureFormat::Depth32FloatStencil8:
+ if (SupportsFeatures({wgpu::FeatureName::Depth32FloatStencil8})) {
+ mIsFormatSupported = true;
+ return {wgpu::FeatureName::Depth32FloatStencil8};
+ }
+ return {};
+ default:
+ mIsFormatSupported = true;
+ return {};
+ }
+ }
+
void CheckMipLevel(uint32_t mipLevel) {
uint32_t mipSize = std::max(kRTSize >> mipLevel, 1u);
@@ -151,6 +173,9 @@
std::array<wgpu::TextureView, kMipLevelCount> textureViews;
// Vector instead of array because there is no default constructor.
std::vector<utils::ComboRenderPassDescriptor> renderPassDescriptors;
+
+ private:
+ bool mIsFormatSupported = false;
};
} // anonymous namespace
@@ -240,7 +265,8 @@
auto params2 = MakeParamGenerator<DepthStencilLoadOpTestParams>(
{D3D12Backend(), D3D12Backend({}, {"use_d3d12_render_pass"}), MetalBackend(),
OpenGLBackend(), OpenGLESBackend(), VulkanBackend()},
- {wgpu::TextureFormat::Depth24PlusStencil8},
+ {wgpu::TextureFormat::Depth24PlusStencil8, wgpu::TextureFormat::Depth24UnormStencil8,
+ wgpu::TextureFormat::Depth32FloatStencil8},
{Check::CopyStencil, Check::StencilTest, Check::DepthTest, Check::SampleDepth});
std::vector<DepthStencilLoadOpTestParams> allParams;
diff --git a/src/tests/end2end/DepthStencilSamplingTests.cpp b/src/tests/end2end/DepthStencilSamplingTests.cpp
index 7ac870a..872e6d7 100644
--- a/src/tests/end2end/DepthStencilSamplingTests.cpp
+++ b/src/tests/end2end/DepthStencilSamplingTests.cpp
@@ -18,17 +18,8 @@
#include "utils/WGPUHelpers.h"
namespace {
-
- constexpr wgpu::TextureFormat kDepthFormats[] = {
- wgpu::TextureFormat::Depth32Float,
- wgpu::TextureFormat::Depth24Plus,
- wgpu::TextureFormat::Depth24PlusStencil8,
- wgpu::TextureFormat::Depth16Unorm,
- };
-
- constexpr wgpu::TextureFormat kStencilFormats[] = {
- wgpu::TextureFormat::Depth24PlusStencil8,
- };
+ using TextureFormat = wgpu::TextureFormat;
+ DAWN_TEST_PARAM_STRUCT(DepthStencilSamplingTestParams, TextureFormat);
constexpr wgpu::CompareFunction kCompareFunctions[] = {
wgpu::CompareFunction::Never, wgpu::CompareFunction::Less,
@@ -48,7 +39,7 @@
} // anonymous namespace
-class DepthStencilSamplingTest : public DawnTest {
+class DepthStencilSamplingTest : public DawnTestWithParams<DepthStencilSamplingTestParams> {
protected:
enum class TestAspect {
Depth,
@@ -56,7 +47,9 @@
};
void SetUp() override {
- DawnTest::SetUp();
+ DawnTestWithParams<DepthStencilSamplingTestParams>::SetUp();
+
+ DAWN_TEST_UNSUPPORTED_IF(!mIsFormatSupported);
wgpu::BufferDescriptor uniformBufferDesc;
uniformBufferDesc.usage = wgpu::BufferUsage::Uniform | wgpu::BufferUsage::CopyDst;
@@ -64,6 +57,26 @@
mUniformBuffer = device.CreateBuffer(&uniformBufferDesc);
}
+ std::vector<wgpu::FeatureName> GetRequiredFeatures() override {
+ switch (GetParam().mTextureFormat) {
+ case wgpu::TextureFormat::Depth24UnormStencil8:
+ if (SupportsFeatures({wgpu::FeatureName::Depth24UnormStencil8})) {
+ mIsFormatSupported = true;
+ return {wgpu::FeatureName::Depth24UnormStencil8};
+ }
+ return {};
+ case wgpu::TextureFormat::Depth32FloatStencil8:
+ if (SupportsFeatures({wgpu::FeatureName::Depth32FloatStencil8})) {
+ mIsFormatSupported = true;
+ return {wgpu::FeatureName::Depth32FloatStencil8};
+ }
+ return {};
+ default:
+ mIsFormatSupported = true;
+ return {};
+ }
+ }
+
void GenerateSamplingShader(const std::vector<TestAspect>& aspects,
const std::vector<uint32_t> components,
std::ostringstream& shaderSource,
@@ -581,58 +594,39 @@
private:
wgpu::Buffer mUniformBuffer;
+ bool mIsFormatSupported = false;
};
-// Test that sampling a depth texture with a render/compute pipeline works
-TEST_P(DepthStencilSamplingTest, SampleDepth) {
- for (wgpu::TextureFormat format : kDepthFormats) {
- float tolerance = 0.0f;
- if (format == wgpu::TextureFormat::Depth16Unorm) {
- tolerance = 0.001f;
- }
- // Test 0, between [0, 1], and 1.
- DoSamplingTest(TestAspect::Depth, CreateSamplingRenderPipeline({TestAspect::Depth}, 0),
- format, kNormalizedTextureValues, tolerance);
-
- DoSamplingTest(TestAspect::Depth, CreateSamplingComputePipeline({TestAspect::Depth}, 0),
- format, kNormalizedTextureValues, tolerance);
- }
-}
-
-// Test that sampling a stencil texture with a render/compute pipeline works
-TEST_P(DepthStencilSamplingTest, SampleStencil) {
- // TODO(crbug.com/dawn/593): This test requires glTextureView, which is unsupported on GLES.
- DAWN_TEST_UNSUPPORTED_IF(IsOpenGLES());
- for (wgpu::TextureFormat format : kStencilFormats) {
- DoSamplingTest(TestAspect::Stencil, CreateSamplingRenderPipeline({TestAspect::Stencil}, 0),
- format, kStencilValues);
-
- DoSamplingTest(TestAspect::Stencil, CreateSamplingComputePipeline({TestAspect::Stencil}, 0),
- format, kStencilValues);
- }
-}
-
// Test that sampling a depth/stencil texture at components 1, 2, and 3 yield 0, 0, and 1
// respectively
TEST_P(DepthStencilSamplingTest, SampleExtraComponents) {
// TODO(crbug.com/dawn/593): This test requires glTextureView, which is unsupported on GLES.
DAWN_TEST_UNSUPPORTED_IF(IsOpenGLES());
- DoSamplingExtraStencilComponentsRenderTest(
- TestAspect::Stencil, wgpu::TextureFormat::Depth24PlusStencil8, {uint8_t(42), uint8_t(37)});
+ wgpu::TextureFormat format = GetParam().mTextureFormat;
- DoSamplingExtraStencilComponentsComputeTest(
- TestAspect::Stencil, wgpu::TextureFormat::Depth24PlusStencil8, {uint8_t(42), uint8_t(37)});
+ // TODO(crbug.com/dawn/1239): depth24unorm-stencil8 fails on D3D12 Nvidia old driver version.
+ DAWN_SUPPRESS_TEST_IF(format == wgpu::TextureFormat::Depth24UnormStencil8 && IsD3D12() &&
+ IsNvidia());
+
+ DoSamplingExtraStencilComponentsRenderTest(TestAspect::Stencil, format,
+ {uint8_t(42), uint8_t(37)});
+
+ DoSamplingExtraStencilComponentsComputeTest(TestAspect::Stencil, format,
+ {uint8_t(42), uint8_t(37)});
}
// Test sampling both depth and stencil with a render/compute pipeline works.
TEST_P(DepthStencilSamplingTest, SampleDepthAndStencilRender) {
// TODO(crbug.com/dawn/593): This test requires glTextureView, which is unsupported on GLES.
DAWN_TEST_UNSUPPORTED_IF(IsOpenGLES());
+
+ wgpu::TextureFormat format = GetParam().mTextureFormat;
+
wgpu::SamplerDescriptor samplerDesc;
wgpu::Sampler sampler = device.CreateSampler(&samplerDesc);
- wgpu::Texture inputTexture = CreateInputTexture(wgpu::TextureFormat::Depth24PlusStencil8);
+ wgpu::Texture inputTexture = CreateInputTexture(format);
wgpu::TextureViewDescriptor depthViewDesc = {};
depthViewDesc.aspect = wgpu::TextureAspect::DepthOnly;
@@ -640,6 +634,8 @@
wgpu::TextureViewDescriptor stencilViewDesc = {};
stencilViewDesc.aspect = wgpu::TextureAspect::StencilOnly;
+ float tolerance = format == wgpu::TextureFormat::Depth24UnormStencil8 ? 0.001f : 0.0f;
+
// With render pipeline
{
wgpu::RenderPipeline pipeline =
@@ -682,15 +678,16 @@
wgpu::CommandBuffer commands = commandEncoder.Finish();
queue.Submit(1, &commands);
- uint32_t expectedValueU32 = 0;
- memcpy(&expectedValueU32, &passDescriptor.cDepthStencilAttachmentInfo.clearDepth,
+ float expectedDepth = 0.0f;
+ memcpy(&expectedDepth, &passDescriptor.cDepthStencilAttachmentInfo.clearDepth,
sizeof(float));
- EXPECT_BUFFER_U32_EQ(expectedValueU32, depthOutput, 0);
+ EXPECT_BUFFER(depthOutput, 0, sizeof(float),
+ new ::detail::ExpectEq<float>(expectedDepth, tolerance));
- expectedValueU32 = 0;
- memcpy(&expectedValueU32, &passDescriptor.cDepthStencilAttachmentInfo.clearStencil,
+ uint8_t expectedStencil = 0;
+ memcpy(&expectedStencil, &passDescriptor.cDepthStencilAttachmentInfo.clearStencil,
sizeof(uint8_t));
- EXPECT_BUFFER_U32_EQ(expectedValueU32, stencilOutput, 0);
+ EXPECT_BUFFER_U32_EQ(expectedStencil, stencilOutput, 0);
}
// With compute pipeline
@@ -729,44 +726,89 @@
wgpu::CommandBuffer commands = commandEncoder.Finish();
queue.Submit(1, &commands);
- uint32_t expectedValueU32 = 0;
- memcpy(&expectedValueU32, &passDescriptor.cDepthStencilAttachmentInfo.clearDepth,
+ float expectedDepth = 0.0f;
+ memcpy(&expectedDepth, &passDescriptor.cDepthStencilAttachmentInfo.clearDepth,
sizeof(float));
- EXPECT_BUFFER_U32_EQ(expectedValueU32, depthOutput, 0);
+ EXPECT_BUFFER(depthOutput, 0, sizeof(float),
+ new ::detail::ExpectEq<float>(expectedDepth, tolerance));
- expectedValueU32 = 0;
- memcpy(&expectedValueU32, &passDescriptor.cDepthStencilAttachmentInfo.clearStencil,
+ uint8_t expectedStencil = 0;
+ memcpy(&expectedStencil, &passDescriptor.cDepthStencilAttachmentInfo.clearStencil,
sizeof(uint8_t));
- EXPECT_BUFFER_U32_EQ(expectedValueU32, stencilOutput, 0);
+ EXPECT_BUFFER_U32_EQ(expectedStencil, stencilOutput, 0);
}
}
+class DepthSamplingTest : public DepthStencilSamplingTest {};
+
+// Test that sampling a depth texture with a render/compute pipeline works
+TEST_P(DepthSamplingTest, SampleDepthOnly) {
+ wgpu::TextureFormat format = GetParam().mTextureFormat;
+ float tolerance = format == wgpu::TextureFormat::Depth16Unorm ||
+ format == wgpu::TextureFormat::Depth24UnormStencil8
+ ? 0.001f
+ : 0.0f;
+
+ // Test 0, between [0, 1], and 1.
+ DoSamplingTest(TestAspect::Depth, CreateSamplingRenderPipeline({TestAspect::Depth}, 0), format,
+ kNormalizedTextureValues, tolerance);
+
+ DoSamplingTest(TestAspect::Depth, CreateSamplingComputePipeline({TestAspect::Depth}, 0), format,
+ kNormalizedTextureValues, tolerance);
+}
+
// Test that sampling in a render pipeline with all of the compare functions works.
-TEST_P(DepthStencilSamplingTest, CompareFunctionsRender) {
+TEST_P(DepthSamplingTest, CompareFunctionsRender) {
// Initialization via renderPass loadOp doesn't work on Mac Intel.
DAWN_SUPPRESS_TEST_IF(IsMetal() && IsIntel());
+ wgpu::TextureFormat format = GetParam().mTextureFormat;
+ // Test does not account for precision issues when comparison testing Depth16Unorm and
+ // Depth24UnormStencil8.
+ DAWN_TEST_UNSUPPORTED_IF(format == wgpu::TextureFormat::Depth16Unorm ||
+ format == wgpu::TextureFormat::Depth24UnormStencil8);
+
wgpu::RenderPipeline pipeline = CreateComparisonRenderPipeline();
- for (wgpu::TextureFormat format : kDepthFormats) {
- // Test does not account for precision issues when comparison testing Depth16Unorm.
- if (format == wgpu::TextureFormat::Depth16Unorm) {
- continue;
- }
-
- // Test a "normal" ref value between 0 and 1; as well as negative and > 1 refs.
- for (float compareRef : kCompareRefs) {
- // Test 0, below the ref, equal to, above the ref, and 1.
- for (wgpu::CompareFunction f : kCompareFunctions) {
- DoDepthCompareRefTest(pipeline, format, compareRef, f, kNormalizedTextureValues);
- }
+ // Test a "normal" ref value between 0 and 1; as well as negative and > 1 refs.
+ for (float compareRef : kCompareRefs) {
+ // Test 0, below the ref, equal to, above the ref, and 1.
+ for (wgpu::CompareFunction f : kCompareFunctions) {
+ DoDepthCompareRefTest(pipeline, format, compareRef, f, kNormalizedTextureValues);
}
}
}
-DAWN_INSTANTIATE_TEST(DepthStencilSamplingTest,
- D3D12Backend(),
- MetalBackend(),
- OpenGLBackend(),
- OpenGLESBackend(),
- VulkanBackend());
+class StencilSamplingTest : public DepthStencilSamplingTest {};
+
+// Test that sampling a stencil texture with a render/compute pipeline works
+TEST_P(StencilSamplingTest, SampleStencilOnly) {
+ // TODO(crbug.com/dawn/593): This test requires glTextureView, which is unsupported on GLES.
+ DAWN_TEST_UNSUPPORTED_IF(IsOpenGLES());
+
+ wgpu::TextureFormat format = GetParam().mTextureFormat;
+
+ DoSamplingTest(TestAspect::Stencil, CreateSamplingRenderPipeline({TestAspect::Stencil}, 0),
+ format, kStencilValues);
+
+ DoSamplingTest(TestAspect::Stencil, CreateSamplingComputePipeline({TestAspect::Stencil}, 0),
+ format, kStencilValues);
+}
+
+DAWN_INSTANTIATE_TEST_P(DepthStencilSamplingTest,
+ {D3D12Backend(), MetalBackend(), OpenGLBackend(), OpenGLESBackend(),
+ VulkanBackend()},
+ std::vector<wgpu::TextureFormat>(utils::kDepthAndStencilFormats.begin(),
+ utils::kDepthAndStencilFormats.end()));
+
+DAWN_INSTANTIATE_TEST_P(DepthSamplingTest,
+ {D3D12Backend(), MetalBackend(), OpenGLBackend(), OpenGLESBackend(),
+ VulkanBackend()},
+ std::vector<wgpu::TextureFormat>(utils::kDepthFormats.begin(),
+ utils::kDepthFormats.end()));
+
+DAWN_INSTANTIATE_TEST_P(StencilSamplingTest,
+ {D3D12Backend(), MetalBackend(), OpenGLBackend(), OpenGLESBackend(),
+ VulkanBackend()},
+ std::vector<wgpu::TextureFormat>(utils::kStencilFormats.begin(),
+ utils::kStencilFormats.end()));
diff --git a/src/tests/unittests/MathTests.cpp b/src/tests/unittests/MathTests.cpp
index 031c716..6517d06 100644
--- a/src/tests/unittests/MathTests.cpp
+++ b/src/tests/unittests/MathTests.cpp
@@ -249,6 +249,19 @@
ASSERT_TRUE(IsFloat16NaN(0xFFFF));
}
+// Tests for FloatToUnorm
+TEST(Math, FloatToUnorm) {
+ std::vector<float> kTestFloatValues = {0.0f, 0.4f, 0.5f, 1.0f};
+ std::vector<unsigned char> kExpectedCharValues = {0, 102, 127, 255};
+ std::vector<uint8_t> kExpectedUint8Values = {0, 102, 127, 255};
+ std::vector<uint16_t> kExpectedUint16Values = {0, 26214, 32767, 65535};
+ for (size_t i = 0; i < kTestFloatValues.size(); i++) {
+ ASSERT_EQ(FloatToUnorm<unsigned char>(kTestFloatValues[i]), kExpectedCharValues[i]);
+ ASSERT_EQ(FloatToUnorm<uint8_t>(kTestFloatValues[i]), kExpectedUint8Values[i]);
+ ASSERT_EQ(FloatToUnorm<uint16_t>(kTestFloatValues[i]), kExpectedUint16Values[i]);
+ }
+}
+
// Tests for SRGBToLinear
TEST(Math, SRGBToLinear) {
ASSERT_EQ(SRGBToLinear(0.0f), 0.0f);