d3d11: Enable TextureZeroInitTests
To skip lazy clears if content is alrealy intialized, this checks the
subresource's state of being intialized layer by layer and level by
level before actually clearing it.
Bug: dawn:1705
Change-Id: Ia2b5a2ad76d801fab4139f777fa8cb56d7d3cfe3
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/135740
Kokoro: Kokoro <noreply+kokoro@google.com>
Commit-Queue: Jie A Chen <jie.a.chen@intel.com>
Reviewed-by: Peng Huang <penghuang@chromium.org>
Reviewed-by: Austin Eng <enga@chromium.org>
diff --git a/src/dawn/native/d3d11/TextureD3D11.cpp b/src/dawn/native/d3d11/TextureD3D11.cpp
index 2704051..fd70e35 100644
--- a/src/dawn/native/d3d11/TextureD3D11.cpp
+++ b/src/dawn/native/d3d11/TextureD3D11.cpp
@@ -397,46 +397,52 @@
desc.dimension = wgpu::TextureViewDimension::e3D;
break;
}
- desc.baseMipLevel = range.baseMipLevel;
- desc.mipLevelCount = range.levelCount;
- desc.baseArrayLayer = range.baseArrayLayer;
- desc.arrayLayerCount = range.layerCount;
+ // Whether content is initialized is tracked by frontend in unit of a single layer and level, so
+ // we need to check to clear layer by layer, and level by level to make sure that lazy clears
+ // won't overwrite any initialized content.
+ desc.mipLevelCount = 1u;
+ desc.arrayLayerCount = 1u;
desc.aspect = wgpu::TextureAspect::All;
- Ref<TextureView> view = TextureView::Create(this, &desc);
-
- if (GetFormat().HasDepthOrStencil()) {
- for (uint32_t mipLevel = view->GetBaseMipLevel(); mipLevel < view->GetLevelCount();
- ++mipLevel) {
- ComPtr<ID3D11DepthStencilView> d3d11DSV;
- DAWN_TRY_ASSIGN(d3d11DSV,
- view->CreateD3D11DepthStencilView(/*depthReadOnly=*/false,
- /*stencilReadOnly=*/false, mipLevel));
- UINT clearFlags = 0;
- if (GetFormat().HasDepth() && range.aspects & Aspect::Depth) {
- clearFlags |= D3D11_CLEAR_DEPTH;
+ for (uint32_t arrayLayer = range.baseArrayLayer;
+ arrayLayer < range.baseArrayLayer + range.layerCount; ++arrayLayer) {
+ desc.baseArrayLayer = arrayLayer;
+ for (uint32_t mipLevel = range.baseMipLevel;
+ mipLevel < range.baseMipLevel + range.levelCount; ++mipLevel) {
+ if (clearValue == TextureBase::ClearValue::Zero &&
+ IsSubresourceContentInitialized(
+ SubresourceRange::SingleMipAndLayer(mipLevel, arrayLayer, range.aspects))) {
+ // Skip lazy clears if already initialized.
+ continue;
}
- if (GetFormat().HasStencil() && range.aspects & Aspect::Stencil) {
- clearFlags |= D3D11_CLEAR_STENCIL;
- }
- // Clear all layers for each 'mipLevel'.
- d3d11DeviceContext->ClearDepthStencilView(
- d3d11DSV.Get(), clearFlags,
- clearValue == TextureBase::ClearValue::Zero ? 0.0f : 1.0f,
- clearValue == TextureBase::ClearValue::Zero ? 0u : 1u);
- }
- } else {
- static constexpr std::array<float, 4> kZero = {0.0f, 0.0f, 0.0f, 0.0f};
- static constexpr std::array<float, 4> kNonZero = {1.0f, 1.0f, 1.0f, 1.0f};
+ desc.baseMipLevel = mipLevel;
+ Ref<TextureView> view = TextureView::Create(this, &desc);
+ if (GetFormat().HasDepthOrStencil()) {
+ ComPtr<ID3D11DepthStencilView> d3d11DSV;
+ DAWN_TRY_ASSIGN(d3d11DSV, view->CreateD3D11DepthStencilView(
+ /*depthReadOnly=*/false,
+ /*stencilReadOnly=*/false, mipLevel));
+ UINT clearFlags = 0;
+ if (GetFormat().HasDepth() && range.aspects & Aspect::Depth) {
+ clearFlags |= D3D11_CLEAR_DEPTH;
+ }
+ if (GetFormat().HasStencil() && range.aspects & Aspect::Stencil) {
+ clearFlags |= D3D11_CLEAR_STENCIL;
+ }
+ d3d11DeviceContext->ClearDepthStencilView(
+ d3d11DSV.Get(), clearFlags,
+ clearValue == TextureBase::ClearValue::Zero ? 0.0f : 1.0f,
+ clearValue == TextureBase::ClearValue::Zero ? 0u : 1u);
+ } else {
+ static constexpr std::array<float, 4> kZero = {0.0f, 0.0f, 0.0f, 0.0f};
+ static constexpr std::array<float, 4> kNonZero = {1.0f, 1.0f, 1.0f, 1.0f};
- for (uint32_t mipLevel = view->GetBaseMipLevel(); mipLevel < view->GetLevelCount();
- ++mipLevel) {
- ComPtr<ID3D11RenderTargetView> d3d11RTV;
- DAWN_TRY_ASSIGN(d3d11RTV, view->CreateD3D11RenderTargetView(mipLevel));
- // Clear all layers for each 'mipLevel'.
- d3d11DeviceContext->ClearRenderTargetView(
- d3d11RTV.Get(),
- clearValue == TextureBase::ClearValue::Zero ? kZero.data() : kNonZero.data());
+ ComPtr<ID3D11RenderTargetView> d3d11RTV;
+ DAWN_TRY_ASSIGN(d3d11RTV, view->CreateD3D11RenderTargetView(mipLevel));
+ d3d11DeviceContext->ClearRenderTargetView(
+ d3d11RTV.Get(),
+ clearValue == TextureBase::ClearValue::Zero ? kZero.data() : kNonZero.data());
+ }
}
}
diff --git a/src/dawn/tests/end2end/TextureZeroInitTests.cpp b/src/dawn/tests/end2end/TextureZeroInitTests.cpp
index 711f560..88e1917 100644
--- a/src/dawn/tests/end2end/TextureZeroInitTests.cpp
+++ b/src/dawn/tests/end2end/TextureZeroInitTests.cpp
@@ -794,6 +794,8 @@
TEST_P(TextureZeroInitTest, StencilCopyThenDiscardAndReadBySampling) {
// Copies to a single aspect are unsupported on OpenGL.
DAWN_SUPPRESS_TEST_IF(IsOpenGL() || IsOpenGLES());
+ // TODO(dawn:1848): support depth-stencil texture write on D3D11.
+ DAWN_SUPPRESS_TEST_IF(IsD3D11());
for (wgpu::TextureFormat format :
{wgpu::TextureFormat::Stencil8, wgpu::TextureFormat::Depth24PlusStencil8}) {
@@ -825,6 +827,8 @@
TEST_P(TextureZeroInitTest, StencilCopyThenDiscardAndReadByCopy) {
// Copies to a single aspect are unsupported on OpenGL.
DAWN_SUPPRESS_TEST_IF(IsOpenGL() || IsOpenGLES());
+ // TODO(dawn:1848): support depth-stencil texture write on D3D11.
+ DAWN_SUPPRESS_TEST_IF(IsD3D11());
for (wgpu::TextureFormat format :
{wgpu::TextureFormat::Stencil8, wgpu::TextureFormat::Depth24PlusStencil8}) {
@@ -858,6 +862,8 @@
TEST_P(TextureZeroInitTest, StencilCopyThenDiscardAndCopyToTextureThenReadByCopy) {
// Copies to a single aspect are unsupported on OpenGL.
DAWN_SUPPRESS_TEST_IF(IsOpenGL() || IsOpenGLES());
+ // TODO(dawn:1848): support depth-stencil texture write on D3D11.
+ DAWN_SUPPRESS_TEST_IF(IsD3D11());
for (wgpu::TextureFormat format :
{wgpu::TextureFormat::Stencil8, wgpu::TextureFormat::Depth24PlusStencil8}) {
@@ -1188,6 +1194,8 @@
// TODO(crbug.com/dawn/667): Work around the fact that some platforms do not support reading
// from Snorm textures.
DAWN_TEST_UNSUPPORTED_IF(HasToggleEnabled("disable_snorm_read"));
+ // TODO(dawn:1802): Support clearing non-renderable textures on D3D11.
+ DAWN_SUPPRESS_TEST_IF(IsD3D11());
wgpu::TextureDescriptor descriptor =
CreateTextureDescriptor(1, 1, wgpu::TextureUsage::CopySrc, kNonrenderableColorFormat);
@@ -1221,6 +1229,8 @@
// TODO(crbug.com/dawn/667): Work around the fact that some platforms do not support reading
// from Snorm textures.
DAWN_TEST_UNSUPPORTED_IF(HasToggleEnabled("disable_snorm_read"));
+ // TODO(dawn:1802): Support clearing non-renderable textures on D3D11.
+ DAWN_SUPPRESS_TEST_IF(IsD3D11());
wgpu::TextureDescriptor descriptor =
CreateTextureDescriptor(1, 1, wgpu::TextureUsage::CopySrc, kNonrenderableColorFormat);
@@ -1257,6 +1267,8 @@
// TODO(crbug.com/dawn/667): Work around the fact that some platforms do not support reading
// from Snorm textures.
DAWN_TEST_UNSUPPORTED_IF(HasToggleEnabled("disable_snorm_read"));
+ // TODO(dawn:1802): Support clearing non-renderable textures on D3D11.
+ DAWN_SUPPRESS_TEST_IF(IsD3D11());
wgpu::TextureDescriptor descriptor =
CreateTextureDescriptor(1, 2, wgpu::TextureUsage::CopySrc, kNonrenderableColorFormat);
@@ -1594,6 +1606,9 @@
// from Snorm textures.
DAWN_TEST_UNSUPPORTED_IF(HasToggleEnabled("disable_snorm_read"));
+ // TODO(dawn:1802): Support clearing non-renderable textures on D3D11.
+ DAWN_SUPPRESS_TEST_IF(IsD3D11());
+
wgpu::TextureDescriptor descriptor;
descriptor.size.width = kUnalignedSize;
descriptor.size.height = kUnalignedSize;
@@ -1881,6 +1896,7 @@
DAWN_INSTANTIATE_TEST(
TextureZeroInitTest,
+ D3D11Backend({"nonzero_clear_resources_on_creation_for_testing"}),
D3D12Backend({"nonzero_clear_resources_on_creation_for_testing"}),
D3D12Backend({"nonzero_clear_resources_on_creation_for_testing"}, {"use_d3d12_render_pass"}),
OpenGLBackend({"nonzero_clear_resources_on_creation_for_testing"}),
@@ -2325,6 +2341,8 @@
}
DAWN_INSTANTIATE_TEST(CompressedTextureZeroInitTest,
+ // TODO(dawn:1802): Support clearing non-renderable textures on D3D11.
+ // D3D11Backend({"nonzero_clear_resources_on_creation_for_testing"}),
D3D12Backend({"nonzero_clear_resources_on_creation_for_testing"}),
MetalBackend({"nonzero_clear_resources_on_creation_for_testing"}),
OpenGLBackend({"nonzero_clear_resources_on_creation_for_testing"}),