diff --git a/src/dawn_native/CommandEncoder.cpp b/src/dawn_native/CommandEncoder.cpp index d0ad3febd6..867c6ff8a4 100644 --- a/src/dawn_native/CommandEncoder.cpp +++ b/src/dawn_native/CommandEncoder.cpp @@ -94,6 +94,7 @@ namespace dawn_native { "buffer copy.", src.texture, src.texture->GetFormat().format); case wgpu::TextureFormat::Depth32Float: + case wgpu::TextureFormat::Depth16Unorm: break; default: diff --git a/src/dawn_native/Format.cpp b/src/dawn_native/Format.cpp index e9cde21177..a6ebe4849d 100644 --- a/src/dawn_native/Format.cpp +++ b/src/dawn_native/Format.cpp @@ -328,8 +328,7 @@ namespace dawn_native { // Depth-stencil formats // TODO(dawn:666): Implement the stencil8 format AddStencilFormat(wgpu::TextureFormat::Stencil8, false); - // TODO(dawn:570): Implement the depth16unorm format - AddDepthFormat(wgpu::TextureFormat::Depth16Unorm, 2, false); + AddDepthFormat(wgpu::TextureFormat::Depth16Unorm, 2, true); // TODO(crbug.com/dawn/843): This is 4 because we read this to perform zero initialization, // and textures are always use depth32float. We should improve this to be more robust. Perhaps, // using 0 here to mean "unsized" and adding a backend-specific query for the block size. diff --git a/src/dawn_native/d3d12/TextureD3D12.cpp b/src/dawn_native/d3d12/TextureD3D12.cpp index 362a5dcca7..c4abeb6512 100644 --- a/src/dawn_native/d3d12/TextureD3D12.cpp +++ b/src/dawn_native/d3d12/TextureD3D12.cpp @@ -121,6 +121,7 @@ namespace dawn_native { namespace d3d12 { case wgpu::TextureFormat::R16Uint: case wgpu::TextureFormat::R16Sint: case wgpu::TextureFormat::R16Float: + case wgpu::TextureFormat::Depth16Unorm: return DXGI_FORMAT_R16_TYPELESS; case wgpu::TextureFormat::RG8Unorm: @@ -251,8 +252,6 @@ namespace dawn_native { namespace d3d12 { case wgpu::TextureFormat::R8BG8Biplanar420Unorm: // TODO(dawn:666): implement stencil8 case wgpu::TextureFormat::Stencil8: - // TODO(dawn:570): implement depth16unorm - case wgpu::TextureFormat::Depth16Unorm: case wgpu::TextureFormat::Undefined: UNREACHABLE(); } @@ -345,6 +344,8 @@ namespace dawn_native { namespace d3d12 { 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::BC1RGBAUnorm: return DXGI_FORMAT_BC1_UNORM; @@ -420,8 +421,6 @@ namespace dawn_native { namespace d3d12 { // TODO(dawn:666): implement stencil8 case wgpu::TextureFormat::Stencil8: - // TODO(dawn:570): implement depth16unorm - case wgpu::TextureFormat::Depth16Unorm: case wgpu::TextureFormat::Undefined: UNREACHABLE(); } @@ -1175,6 +1174,9 @@ namespace dawn_native { namespace d3d12 { case wgpu::TextureFormat::Depth24Plus: mSrvDesc.Format = DXGI_FORMAT_R32_FLOAT; break; + case wgpu::TextureFormat::Depth16Unorm: + mSrvDesc.Format = DXGI_FORMAT_R16_UNORM; + break; case wgpu::TextureFormat::Depth24PlusStencil8: switch (descriptor->aspect) { case wgpu::TextureAspect::DepthOnly: diff --git a/src/dawn_native/metal/TextureMTL.mm b/src/dawn_native/metal/TextureMTL.mm index 68fca2108c..a611e3fd1c 100644 --- a/src/dawn_native/metal/TextureMTL.mm +++ b/src/dawn_native/metal/TextureMTL.mm @@ -223,6 +223,13 @@ namespace dawn_native { namespace metal { return MTLPixelFormatDepth32Float; case wgpu::TextureFormat::Depth24PlusStencil8: return MTLPixelFormatDepth32Float_Stencil8; + case wgpu::TextureFormat::Depth16Unorm: + if (@available(macOS 10.12, iOS 13.0, *)) { + return MTLPixelFormatDepth16Unorm; + } else { + // TODO (dawn:1181): Allow non-conformant implementation on macOS 10.11 + UNREACHABLE(); + } #if defined(DAWN_PLATFORM_MACOS) case wgpu::TextureFormat::BC1RGBAUnorm: @@ -314,8 +321,6 @@ namespace dawn_native { namespace metal { // TODO(dawn:666): implement stencil8 case wgpu::TextureFormat::Stencil8: - // TODO(dawn:570): implement depth16unorm - case wgpu::TextureFormat::Depth16Unorm: case wgpu::TextureFormat::Undefined: UNREACHABLE(); } diff --git a/src/dawn_native/opengl/GLFormat.cpp b/src/dawn_native/opengl/GLFormat.cpp index eb7e3bc7cb..af28814e99 100644 --- a/src/dawn_native/opengl/GLFormat.cpp +++ b/src/dawn_native/opengl/GLFormat.cpp @@ -94,6 +94,7 @@ namespace dawn_native { namespace opengl { AddFormat(wgpu::TextureFormat::Depth32Float, GL_DEPTH_COMPONENT32F, GL_DEPTH_COMPONENT, GL_FLOAT, Type::DepthStencil); AddFormat(wgpu::TextureFormat::Depth24Plus, GL_DEPTH_COMPONENT32F, GL_DEPTH_COMPONENT, GL_FLOAT, Type::DepthStencil); AddFormat(wgpu::TextureFormat::Depth24PlusStencil8, GL_DEPTH32F_STENCIL8, GL_DEPTH_STENCIL, GL_FLOAT_32_UNSIGNED_INT_24_8_REV, Type::DepthStencil); + AddFormat(wgpu::TextureFormat::Depth16Unorm, GL_DEPTH_COMPONENT16, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, Type::DepthStencil); // Block compressed formats AddFormat(wgpu::TextureFormat::BC1RGBAUnorm, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, GL_RGBA, GL_UNSIGNED_BYTE, Type::Float); diff --git a/src/dawn_native/vulkan/TextureVk.cpp b/src/dawn_native/vulkan/TextureVk.cpp index 93c048685f..5f37b3e476 100644 --- a/src/dawn_native/vulkan/TextureVk.cpp +++ b/src/dawn_native/vulkan/TextureVk.cpp @@ -292,6 +292,8 @@ namespace dawn_native { namespace vulkan { case wgpu::TextureFormat::RGBA32Float: return VK_FORMAT_R32G32B32A32_SFLOAT; + case wgpu::TextureFormat::Depth16Unorm: + return VK_FORMAT_D16_UNORM; case wgpu::TextureFormat::Depth32Float: return VK_FORMAT_D32_SFLOAT; case wgpu::TextureFormat::Depth24Plus: @@ -417,8 +419,6 @@ namespace dawn_native { namespace vulkan { case wgpu::TextureFormat::R8BG8Biplanar420Unorm: // TODO(dawn:666): implement stencil8 case wgpu::TextureFormat::Stencil8: - // TODO(dawn:570): implement depth16unorm - case wgpu::TextureFormat::Depth16Unorm: case wgpu::TextureFormat::Undefined: break; } diff --git a/src/tests/end2end/DepthStencilLoadOpTests.cpp b/src/tests/end2end/DepthStencilLoadOpTests.cpp index e8c96b241f..b0c888711e 100644 --- a/src/tests/end2end/DepthStencilLoadOpTests.cpp +++ b/src/tests/end2end/DepthStencilLoadOpTests.cpp @@ -54,6 +54,7 @@ namespace { constexpr static uint32_t kRTSize = 16; constexpr uint32_t kMipLevelCount = 2u; constexpr std::array kDepthValues = {0.125f, 0.875f}; + constexpr std::array kU16DepthValues = {8192u, 57343u}; constexpr std::array kStencilValues = {7u, 3u}; class DepthStencilLoadOpTests : public DawnTestWithParams { @@ -104,10 +105,19 @@ namespace { } case Check::CopyDepth: { - std::vector expectedDepth(mipSize * mipSize, kDepthValues[mipLevel]); - EXPECT_TEXTURE_EQ(expectedDepth.data(), texture, {0, 0}, {mipSize, mipSize}, - mipLevel, wgpu::TextureAspect::DepthOnly) - << "copy depth mip " << mipLevel; + if (GetParam().mFormat == wgpu::TextureFormat::Depth16Unorm) { + std::vector expectedDepth(mipSize * mipSize, + kU16DepthValues[mipLevel]); + EXPECT_TEXTURE_EQ(expectedDepth.data(), texture, {0, 0}, {mipSize, mipSize}, + mipLevel, wgpu::TextureAspect::DepthOnly) + << "copy depth mip " << mipLevel; + } else { + std::vector expectedDepth(mipSize * mipSize, kDepthValues[mipLevel]); + EXPECT_TEXTURE_EQ(expectedDepth.data(), texture, {0, 0}, {mipSize, mipSize}, + mipLevel, wgpu::TextureAspect::DepthOnly) + << "copy depth mip " << mipLevel; + } + break; } @@ -147,6 +157,11 @@ namespace { // Check that clearing a mip level works at all. TEST_P(DepthStencilLoadOpTests, ClearMip0) { + // TODO(https://issuetracker.google.com/issues/204919030): SwiftShader does not clear + // Depth16Unorm correctly with some values. + DAWN_SUPPRESS_TEST_IF(IsVulkan() && IsSwiftshader() && + GetParam().mFormat == wgpu::TextureFormat::Depth16Unorm); + wgpu::CommandEncoder encoder = device.CreateCommandEncoder(); encoder.BeginRenderPass(&renderPassDescriptors[0]).EndPass(); wgpu::CommandBuffer commandBuffer = encoder.Finish(); @@ -178,6 +193,11 @@ TEST_P(DepthStencilLoadOpTests, ClearBothMip0Then1) { // TODO(crbug.com/dawn/838): Sampling from the non-zero mip does not work. DAWN_SUPPRESS_TEST_IF(IsMetal() && IsIntel() && GetParam().mCheck == Check::SampleDepth); + // TODO(https://issuetracker.google.com/issues/204919030): SwiftShader does not clear + // Depth16Unorm correctly with some values. + DAWN_SUPPRESS_TEST_IF(IsVulkan() && IsSwiftshader() && + GetParam().mFormat == wgpu::TextureFormat::Depth16Unorm); + wgpu::CommandEncoder encoder = device.CreateCommandEncoder(); encoder.BeginRenderPass(&renderPassDescriptors[0]).EndPass(); encoder.BeginRenderPass(&renderPassDescriptors[1]).EndPass(); @@ -193,6 +213,11 @@ TEST_P(DepthStencilLoadOpTests, ClearBothMip1Then0) { // TODO(crbug.com/dawn/838): Sampling from the non-zero mip does not work. DAWN_SUPPRESS_TEST_IF(IsMetal() && IsIntel() && GetParam().mCheck == Check::SampleDepth); + // TODO(https://issuetracker.google.com/issues/204919030): SwiftShader does not clear + // Depth16Unorm correctly with some values. + DAWN_SUPPRESS_TEST_IF(IsVulkan() && IsSwiftshader() && + GetParam().mFormat == wgpu::TextureFormat::Depth16Unorm); + wgpu::CommandEncoder encoder = device.CreateCommandEncoder(); encoder.BeginRenderPass(&renderPassDescriptors[1]).EndPass(); encoder.BeginRenderPass(&renderPassDescriptors[0]).EndPass(); @@ -209,7 +234,7 @@ namespace { auto params1 = MakeParamGenerator( {D3D12Backend(), D3D12Backend({}, {"use_d3d12_render_pass"}), MetalBackend(), OpenGLBackend(), OpenGLESBackend(), VulkanBackend()}, - {wgpu::TextureFormat::Depth32Float}, + {wgpu::TextureFormat::Depth32Float, wgpu::TextureFormat::Depth16Unorm}, {Check::CopyDepth, Check::DepthTest, Check::SampleDepth}); auto params2 = MakeParamGenerator( diff --git a/src/tests/end2end/DepthStencilSamplingTests.cpp b/src/tests/end2end/DepthStencilSamplingTests.cpp index de1732b049..e916e6d5ee 100644 --- a/src/tests/end2end/DepthStencilSamplingTests.cpp +++ b/src/tests/end2end/DepthStencilSamplingTests.cpp @@ -23,6 +23,7 @@ namespace { wgpu::TextureFormat::Depth32Float, wgpu::TextureFormat::Depth24Plus, wgpu::TextureFormat::Depth24PlusStencil8, + wgpu::TextureFormat::Depth16Unorm, }; constexpr wgpu::TextureFormat kStencilFormats[] = { @@ -43,7 +44,7 @@ namespace { const std::vector kNormalizedTextureValues = {0.0, 0.3, 0.4, 0.5, 1.0}; // Test the limits, and some values in between. - const std::vector kStencilValues = {uint8_t(0), uint8_t(1), uint8_t(38), uint8_t(255)}; + const std::vector kStencilValues = {0, 1, 38, 255}; } // anonymous namespace @@ -319,9 +320,7 @@ class DepthStencilSamplingTest : public DawnTest { wgpu::CommandBuffer commands = commandEncoder.Finish(); queue.Submit(1, &commands); - uint32_t expectedValueU32 = 0; - memcpy(&expectedValueU32, &textureValues[i], std::min(sizeof(T), sizeof(uint32_t))); - CheckBuffer(expectedValueU32, outputBuffer); + CheckBuffer(textureValues[i], outputBuffer); } } @@ -373,9 +372,7 @@ class DepthStencilSamplingTest : public DawnTest { wgpu::CommandBuffer commands = commandEncoder.Finish(); queue.Submit(1, &commands); - uint32_t expectedValueU32 = 0; - memcpy(&expectedValueU32, &textureValues[i], std::min(sizeof(T), sizeof(uint32_t))); - CheckBuffer(expectedValueU32, outputBuffer); + CheckBuffer(textureValues[i], outputBuffer); } } @@ -383,10 +380,12 @@ class DepthStencilSamplingTest : public DawnTest { void DoSamplingTest(TestAspect aspect, wgpu::RenderPipeline pipeline, wgpu::TextureFormat format, - std::vector textureValues) { + std::vector textureValues, + T tolerance = {}) { DoSamplingTestImpl(aspect, pipeline, format, textureValues, 1, - [this](uint32_t expected, wgpu::Buffer buffer) { - EXPECT_BUFFER_U32_EQ(expected, buffer, 0); + [this, tolerance](T expected, wgpu::Buffer buffer) { + EXPECT_BUFFER(buffer, 0, sizeof(T), + new ::detail::ExpectEq(expected, tolerance)); }); } @@ -394,10 +393,12 @@ class DepthStencilSamplingTest : public DawnTest { void DoSamplingTest(TestAspect aspect, wgpu::ComputePipeline pipeline, wgpu::TextureFormat format, - std::vector textureValues) { + std::vector textureValues, + T tolerance = {}) { DoSamplingTestImpl(aspect, pipeline, format, textureValues, 1, - [this](uint32_t expected, wgpu::Buffer buffer) { - EXPECT_BUFFER_U32_EQ(expected, buffer, 0); + [this, tolerance](T expected, wgpu::Buffer buffer) { + EXPECT_BUFFER(buffer, 0, sizeof(T), + new ::detail::ExpectEq(expected, tolerance)); }); } @@ -585,12 +586,16 @@ class DepthStencilSamplingTest : public DawnTest { // 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); + format, kNormalizedTextureValues, tolerance); DoSamplingTest(TestAspect::Depth, CreateSamplingComputePipeline({TestAspect::Depth}, 0), - format, kNormalizedTextureValues); + format, kNormalizedTextureValues, tolerance); } } @@ -744,6 +749,11 @@ TEST_P(DepthStencilSamplingTest, CompareFunctionsRender) { 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. diff --git a/src/tests/end2end/DepthStencilStateTests.cpp b/src/tests/end2end/DepthStencilStateTests.cpp index 0d96819eed..efe3e53bd7 100644 --- a/src/tests/end2end/DepthStencilStateTests.cpp +++ b/src/tests/end2end/DepthStencilStateTests.cpp @@ -763,6 +763,7 @@ TEST_P(DepthStencilStateTest, CreatePipelineWithAllFormats) { wgpu::TextureFormat::Depth32Float, wgpu::TextureFormat::Depth24PlusStencil8, wgpu::TextureFormat::Depth24Plus, + wgpu::TextureFormat::Depth16Unorm, }; for (wgpu::TextureFormat depthStencilFormat : kDepthStencilFormats) { diff --git a/src/utils/TextureUtils.cpp b/src/utils/TextureUtils.cpp index aaa808e5b7..4d09195f07 100644 --- a/src/utils/TextureUtils.cpp +++ b/src/utils/TextureUtils.cpp @@ -134,6 +134,7 @@ namespace utils { case wgpu::TextureFormat::RG8Snorm: case wgpu::TextureFormat::RG8Uint: case wgpu::TextureFormat::RG8Sint: + case wgpu::TextureFormat::Depth16Unorm: return 2u; case wgpu::TextureFormat::R32Float: @@ -238,8 +239,6 @@ namespace utils { // TODO(dawn:666): implement stencil8 case wgpu::TextureFormat::Stencil8: - // TODO(dawn:570): implement depth16unorm - case wgpu::TextureFormat::Depth16Unorm: case wgpu::TextureFormat::Undefined: break; } @@ -287,6 +286,7 @@ namespace utils { case wgpu::TextureFormat::Depth32Float: case wgpu::TextureFormat::Depth24Plus: case wgpu::TextureFormat::Depth24PlusStencil8: + case wgpu::TextureFormat::Depth16Unorm: return 1u; case wgpu::TextureFormat::BC1RGBAUnorm: @@ -355,8 +355,6 @@ namespace utils { // TODO(dawn:666): implement stencil8 case wgpu::TextureFormat::Stencil8: - // TODO(dawn:570): implement depth16unorm - case wgpu::TextureFormat::Depth16Unorm: case wgpu::TextureFormat::Undefined: break; } @@ -404,6 +402,7 @@ namespace utils { case wgpu::TextureFormat::Depth32Float: case wgpu::TextureFormat::Depth24Plus: case wgpu::TextureFormat::Depth24PlusStencil8: + case wgpu::TextureFormat::Depth16Unorm: return 1u; case wgpu::TextureFormat::BC1RGBAUnorm: @@ -472,8 +471,6 @@ namespace utils { // TODO(dawn:666): implement stencil8 case wgpu::TextureFormat::Stencil8: - // TODO(dawn:570): implement depth16unorm - case wgpu::TextureFormat::Depth16Unorm: case wgpu::TextureFormat::Undefined: break; }