Use clear loadop to lazy clear depth stencil attachments

Bug: dawn:210, dawn:145
Change-Id: I1eb990266ccd7b51b4a336b0d4d37e0195c6fe69
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/11020
Commit-Queue: Natasha Lee <natlee@microsoft.com>
Reviewed-by: Kai Ninomiya <kainino@chromium.org>
This commit is contained in:
Natasha Lee 2019-09-11 22:04:42 +00:00 committed by Commit Bot service account
parent fad96f6e59
commit 01600dfb3d
4 changed files with 71 additions and 39 deletions

View File

@ -960,16 +960,11 @@ namespace dawn_native { namespace d3d12 {
if (renderPass->attachmentState->HasDepthStencilAttachment()) { if (renderPass->attachmentState->HasDepthStencilAttachment()) {
auto& attachmentInfo = renderPass->depthStencilAttachment; auto& attachmentInfo = renderPass->depthStencilAttachment;
Texture* texture = ToBackend(renderPass->depthStencilAttachment.view->GetTexture()); Texture* texture = ToBackend(renderPass->depthStencilAttachment.view->GetTexture());
if ((texture->GetFormat().HasDepth() && TextureView* view = ToBackend(attachmentInfo.view.Get());
attachmentInfo.depthLoadOp == dawn::LoadOp::Load) || float clearDepth = attachmentInfo.clearDepth;
(texture->GetFormat().HasStencil() && // TODO(kainino@chromium.org): investigate: should the Dawn clear
attachmentInfo.stencilLoadOp == dawn::LoadOp::Load)) { // stencil type be uint8_t?
texture->EnsureSubresourceContentInitialized( uint8_t clearStencil = static_cast<uint8_t>(attachmentInfo.clearStencil);
commandList, attachmentInfo.view->GetBaseMipLevel(),
attachmentInfo.view->GetLevelCount(),
attachmentInfo.view->GetBaseArrayLayer(),
attachmentInfo.view->GetLayerCount());
}
// Load op - depth/stencil // Load op - depth/stencil
bool doDepthClear = texture->GetFormat().HasDepth() && bool doDepthClear = texture->GetFormat().HasDepth() &&
@ -984,19 +979,35 @@ namespace dawn_native { namespace d3d12 {
if (doStencilClear) { if (doStencilClear) {
clearFlags |= D3D12_CLEAR_FLAG_STENCIL; clearFlags |= D3D12_CLEAR_FLAG_STENCIL;
} }
// If the depth stencil texture has not been initialized, we want to use loadop
// clear to init the contents to 0's
if (!texture->IsSubresourceContentInitialized(
view->GetBaseMipLevel(), view->GetLevelCount(), view->GetBaseArrayLayer(),
view->GetLayerCount())) {
if (texture->GetFormat().HasDepth() &&
attachmentInfo.depthLoadOp == dawn::LoadOp::Load) {
clearDepth = 0.0f;
clearFlags |= D3D12_CLEAR_FLAG_DEPTH;
}
if (texture->GetFormat().HasStencil() &&
attachmentInfo.stencilLoadOp == dawn::LoadOp::Load) {
clearStencil = 0u;
clearFlags |= D3D12_CLEAR_FLAG_STENCIL;
}
}
if (clearFlags) { if (clearFlags) {
D3D12_CPU_DESCRIPTOR_HANDLE handle = args.dsv; D3D12_CPU_DESCRIPTOR_HANDLE handle = args.dsv;
// TODO(kainino@chromium.org): investigate: should the Dawn clear commandList->ClearDepthStencilView(handle, clearFlags, clearDepth, clearStencil,
// stencil type be uint8_t? 0, nullptr);
uint8_t clearStencil = static_cast<uint8_t>(attachmentInfo.clearStencil); }
commandList->ClearDepthStencilView(
handle, clearFlags, attachmentInfo.clearDepth, clearStencil, 0, nullptr); // TODO(natlee@microsoft.com): Need to fix when storeop discard is added
if (attachmentInfo.depthStoreOp == dawn::StoreOp::Store &&
attachmentInfo.stencilStoreOp == dawn::StoreOp::Store) {
texture->SetIsSubresourceContentInitialized( texture->SetIsSubresourceContentInitialized(
attachmentInfo.view->GetBaseMipLevel(), view->GetBaseMipLevel(), view->GetLevelCount(), view->GetBaseArrayLayer(),
attachmentInfo.view->GetLevelCount(), view->GetLayerCount());
attachmentInfo.view->GetBaseArrayLayer(),
attachmentInfo.view->GetLayerCount());
} }
} }
} }

View File

@ -391,12 +391,10 @@ namespace dawn_native { namespace opengl {
auto TransitionForPass = [](const PassResourceUsage& usages) { auto TransitionForPass = [](const PassResourceUsage& usages) {
for (size_t i = 0; i < usages.textures.size(); i++) { for (size_t i = 0; i < usages.textures.size(); i++) {
Texture* texture = ToBackend(usages.textures[i]); Texture* texture = ToBackend(usages.textures[i]);
// We count the lazy clears for non output attachment textures and depth stencil // We count the lazy clears for non output attachment textures in order to match the
// textures in order to match the backdoor lazy clear counts in Vulkan and D3D12. // backdoor lazy clear counts in Vulkan and D3D12.
bool isLazyClear = bool isLazyClear =
((!(usages.textureUsages[i] & dawn::TextureUsage::OutputAttachment) && !(usages.textureUsages[i] & dawn::TextureUsage::OutputAttachment);
texture->GetFormat().IsColor()) ||
texture->GetFormat().HasDepthOrStencil());
texture->EnsureSubresourceContentInitialized( texture->EnsureSubresourceContentInitialized(
0, texture->GetNumMipLevels(), 0, texture->GetArrayLayers(), isLazyClear); 0, texture->GetNumMipLevels(), 0, texture->GetArrayLayers(), isLazyClear);
} }

View File

@ -197,16 +197,33 @@ namespace dawn_native { namespace vulkan {
if (renderPass->attachmentState->HasDepthStencilAttachment()) { if (renderPass->attachmentState->HasDepthStencilAttachment()) {
auto& attachmentInfo = renderPass->depthStencilAttachment; auto& attachmentInfo = renderPass->depthStencilAttachment;
query.SetDepthStencil(attachmentInfo.view->GetTexture()->GetFormat().format, TextureView* view = ToBackend(attachmentInfo.view.Get());
// If the depth stencil texture has not been initialized, we want to use loadop
// clear to init the contents to 0's
if (!view->GetTexture()->IsSubresourceContentInitialized(
view->GetBaseMipLevel(), view->GetLevelCount(),
view->GetBaseArrayLayer(), view->GetLayerCount())) {
if (view->GetTexture()->GetFormat().HasDepth() &&
attachmentInfo.depthLoadOp == dawn::LoadOp::Load) {
attachmentInfo.clearDepth = 0.0f;
attachmentInfo.depthLoadOp = dawn::LoadOp::Clear;
}
if (view->GetTexture()->GetFormat().HasStencil() &&
attachmentInfo.stencilLoadOp == dawn::LoadOp::Load) {
attachmentInfo.clearStencil = 0u;
attachmentInfo.stencilLoadOp = dawn::LoadOp::Clear;
}
}
query.SetDepthStencil(view->GetTexture()->GetFormat().format,
attachmentInfo.depthLoadOp, attachmentInfo.stencilLoadOp); attachmentInfo.depthLoadOp, attachmentInfo.stencilLoadOp);
if (attachmentInfo.depthLoadOp == dawn::LoadOp::Load ||
attachmentInfo.stencilLoadOp == dawn::LoadOp::Load) { // TODO(natlee@microsoft.com): Need to fix when storeop discard is added
ToBackend(attachmentInfo.view->GetTexture()) if (attachmentInfo.depthStoreOp == dawn::StoreOp::Store &&
->EnsureSubresourceContentInitialized( attachmentInfo.stencilStoreOp == dawn::StoreOp::Store) {
recordingContext, attachmentInfo.view->GetBaseMipLevel(), view->GetTexture()->SetIsSubresourceContentInitialized(
attachmentInfo.view->GetLevelCount(), view->GetBaseMipLevel(), view->GetLevelCount(),
attachmentInfo.view->GetBaseArrayLayer(), view->GetBaseArrayLayer(), view->GetLayerCount());
attachmentInfo.view->GetLayerCount());
} }
} }

View File

@ -321,6 +321,8 @@ TEST_P(TextureZeroInitTest, RenderingLoadingDepth) {
renderPassDescriptor.cDepthStencilAttachmentInfo.depthLoadOp = dawn::LoadOp::Load; renderPassDescriptor.cDepthStencilAttachmentInfo.depthLoadOp = dawn::LoadOp::Load;
renderPassDescriptor.cDepthStencilAttachmentInfo.stencilLoadOp = dawn::LoadOp::Clear; renderPassDescriptor.cDepthStencilAttachmentInfo.stencilLoadOp = dawn::LoadOp::Clear;
renderPassDescriptor.cDepthStencilAttachmentInfo.clearStencil = 0; renderPassDescriptor.cDepthStencilAttachmentInfo.clearStencil = 0;
renderPassDescriptor.cDepthStencilAttachmentInfo.depthStoreOp = dawn::StoreOp::Store;
renderPassDescriptor.cDepthStencilAttachmentInfo.stencilStoreOp = dawn::StoreOp::Store;
dawn::CommandEncoder encoder = device.CreateCommandEncoder(); dawn::CommandEncoder encoder = device.CreateCommandEncoder();
auto pass = encoder.BeginRenderPass(&renderPassDescriptor); auto pass = encoder.BeginRenderPass(&renderPassDescriptor);
@ -328,8 +330,8 @@ TEST_P(TextureZeroInitTest, RenderingLoadingDepth) {
pass.Draw(6, 1, 0, 0); pass.Draw(6, 1, 0, 0);
pass.EndPass(); pass.EndPass();
dawn::CommandBuffer commandBuffer = encoder.Finish(); dawn::CommandBuffer commandBuffer = encoder.Finish();
// Expect 1 lazy clear for the depthStencilTexture // Expect 0 lazy clears, depth stencil texture will clear using loadop
EXPECT_LAZY_CLEAR(1u, queue.Submit(1, &commandBuffer)); EXPECT_LAZY_CLEAR(0u, queue.Submit(1, &commandBuffer));
// Expect the texture to be red because depth test passed. // Expect the texture to be red because depth test passed.
std::vector<RGBA8> expected(kSize * kSize, {255, 0, 0, 255}); std::vector<RGBA8> expected(kSize * kSize, {255, 0, 0, 255});
@ -360,6 +362,8 @@ TEST_P(TextureZeroInitTest, RenderingLoadingStencil) {
renderPassDescriptor.cDepthStencilAttachmentInfo.depthLoadOp = dawn::LoadOp::Clear; renderPassDescriptor.cDepthStencilAttachmentInfo.depthLoadOp = dawn::LoadOp::Clear;
renderPassDescriptor.cDepthStencilAttachmentInfo.clearDepth = 0.0f; renderPassDescriptor.cDepthStencilAttachmentInfo.clearDepth = 0.0f;
renderPassDescriptor.cDepthStencilAttachmentInfo.stencilLoadOp = dawn::LoadOp::Load; renderPassDescriptor.cDepthStencilAttachmentInfo.stencilLoadOp = dawn::LoadOp::Load;
renderPassDescriptor.cDepthStencilAttachmentInfo.depthStoreOp = dawn::StoreOp::Store;
renderPassDescriptor.cDepthStencilAttachmentInfo.stencilStoreOp = dawn::StoreOp::Store;
dawn::CommandEncoder encoder = device.CreateCommandEncoder(); dawn::CommandEncoder encoder = device.CreateCommandEncoder();
auto pass = encoder.BeginRenderPass(&renderPassDescriptor); auto pass = encoder.BeginRenderPass(&renderPassDescriptor);
@ -367,8 +371,8 @@ TEST_P(TextureZeroInitTest, RenderingLoadingStencil) {
pass.Draw(6, 1, 0, 0); pass.Draw(6, 1, 0, 0);
pass.EndPass(); pass.EndPass();
dawn::CommandBuffer commandBuffer = encoder.Finish(); dawn::CommandBuffer commandBuffer = encoder.Finish();
// Expect 1 lazy clear for depthStencilTexture. // Expect 0 lazy clears, depth stencil texture will clear using loadop
EXPECT_LAZY_CLEAR(1u, queue.Submit(1, &commandBuffer)); EXPECT_LAZY_CLEAR(0u, queue.Submit(1, &commandBuffer));
// Expect the texture to be red because stencil test passed. // Expect the texture to be red because stencil test passed.
std::vector<RGBA8> expected(kSize * kSize, {255, 0, 0, 255}); std::vector<RGBA8> expected(kSize * kSize, {255, 0, 0, 255});
@ -398,6 +402,8 @@ TEST_P(TextureZeroInitTest, RenderingLoadingDepthStencil) {
depthStencilTexture.CreateView()); depthStencilTexture.CreateView());
renderPassDescriptor.cDepthStencilAttachmentInfo.depthLoadOp = dawn::LoadOp::Load; renderPassDescriptor.cDepthStencilAttachmentInfo.depthLoadOp = dawn::LoadOp::Load;
renderPassDescriptor.cDepthStencilAttachmentInfo.stencilLoadOp = dawn::LoadOp::Load; renderPassDescriptor.cDepthStencilAttachmentInfo.stencilLoadOp = dawn::LoadOp::Load;
renderPassDescriptor.cDepthStencilAttachmentInfo.depthStoreOp = dawn::StoreOp::Store;
renderPassDescriptor.cDepthStencilAttachmentInfo.stencilStoreOp = dawn::StoreOp::Store;
dawn::CommandEncoder encoder = device.CreateCommandEncoder(); dawn::CommandEncoder encoder = device.CreateCommandEncoder();
auto pass = encoder.BeginRenderPass(&renderPassDescriptor); auto pass = encoder.BeginRenderPass(&renderPassDescriptor);
@ -405,8 +411,8 @@ TEST_P(TextureZeroInitTest, RenderingLoadingDepthStencil) {
pass.Draw(6, 1, 0, 0); pass.Draw(6, 1, 0, 0);
pass.EndPass(); pass.EndPass();
dawn::CommandBuffer commandBuffer = encoder.Finish(); dawn::CommandBuffer commandBuffer = encoder.Finish();
// Expect 1 lazy clear for depthStencilTexture. // Expect 0 lazy clears, depth stencil texture will clear using loadop
EXPECT_LAZY_CLEAR(1u, queue.Submit(1, &commandBuffer)); EXPECT_LAZY_CLEAR(0u, queue.Submit(1, &commandBuffer));
// Expect the texture to be red because both depth and stencil tests passed. // Expect the texture to be red because both depth and stencil tests passed.
std::vector<RGBA8> expected(kSize * kSize, {255, 0, 0, 255}); std::vector<RGBA8> expected(kSize * kSize, {255, 0, 0, 255});