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:
parent
fad96f6e59
commit
01600dfb3d
|
@ -960,16 +960,11 @@ namespace dawn_native { namespace d3d12 {
|
|||
if (renderPass->attachmentState->HasDepthStencilAttachment()) {
|
||||
auto& attachmentInfo = renderPass->depthStencilAttachment;
|
||||
Texture* texture = ToBackend(renderPass->depthStencilAttachment.view->GetTexture());
|
||||
if ((texture->GetFormat().HasDepth() &&
|
||||
attachmentInfo.depthLoadOp == dawn::LoadOp::Load) ||
|
||||
(texture->GetFormat().HasStencil() &&
|
||||
attachmentInfo.stencilLoadOp == dawn::LoadOp::Load)) {
|
||||
texture->EnsureSubresourceContentInitialized(
|
||||
commandList, attachmentInfo.view->GetBaseMipLevel(),
|
||||
attachmentInfo.view->GetLevelCount(),
|
||||
attachmentInfo.view->GetBaseArrayLayer(),
|
||||
attachmentInfo.view->GetLayerCount());
|
||||
}
|
||||
TextureView* view = ToBackend(attachmentInfo.view.Get());
|
||||
float clearDepth = attachmentInfo.clearDepth;
|
||||
// TODO(kainino@chromium.org): investigate: should the Dawn clear
|
||||
// stencil type be uint8_t?
|
||||
uint8_t clearStencil = static_cast<uint8_t>(attachmentInfo.clearStencil);
|
||||
|
||||
// Load op - depth/stencil
|
||||
bool doDepthClear = texture->GetFormat().HasDepth() &&
|
||||
|
@ -984,19 +979,35 @@ namespace dawn_native { namespace d3d12 {
|
|||
if (doStencilClear) {
|
||||
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) {
|
||||
D3D12_CPU_DESCRIPTOR_HANDLE handle = args.dsv;
|
||||
// TODO(kainino@chromium.org): investigate: should the Dawn clear
|
||||
// stencil type be uint8_t?
|
||||
uint8_t clearStencil = static_cast<uint8_t>(attachmentInfo.clearStencil);
|
||||
commandList->ClearDepthStencilView(
|
||||
handle, clearFlags, attachmentInfo.clearDepth, clearStencil, 0, nullptr);
|
||||
commandList->ClearDepthStencilView(handle, clearFlags, 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(
|
||||
attachmentInfo.view->GetBaseMipLevel(),
|
||||
attachmentInfo.view->GetLevelCount(),
|
||||
attachmentInfo.view->GetBaseArrayLayer(),
|
||||
attachmentInfo.view->GetLayerCount());
|
||||
view->GetBaseMipLevel(), view->GetLevelCount(), view->GetBaseArrayLayer(),
|
||||
view->GetLayerCount());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -391,12 +391,10 @@ namespace dawn_native { namespace opengl {
|
|||
auto TransitionForPass = [](const PassResourceUsage& usages) {
|
||||
for (size_t i = 0; i < usages.textures.size(); i++) {
|
||||
Texture* texture = ToBackend(usages.textures[i]);
|
||||
// We count the lazy clears for non output attachment textures and depth stencil
|
||||
// textures in order to match the backdoor lazy clear counts in Vulkan and D3D12.
|
||||
// We count the lazy clears for non output attachment textures in order to match the
|
||||
// backdoor lazy clear counts in Vulkan and D3D12.
|
||||
bool isLazyClear =
|
||||
((!(usages.textureUsages[i] & dawn::TextureUsage::OutputAttachment) &&
|
||||
texture->GetFormat().IsColor()) ||
|
||||
texture->GetFormat().HasDepthOrStencil());
|
||||
!(usages.textureUsages[i] & dawn::TextureUsage::OutputAttachment);
|
||||
texture->EnsureSubresourceContentInitialized(
|
||||
0, texture->GetNumMipLevels(), 0, texture->GetArrayLayers(), isLazyClear);
|
||||
}
|
||||
|
|
|
@ -197,16 +197,33 @@ namespace dawn_native { namespace vulkan {
|
|||
|
||||
if (renderPass->attachmentState->HasDepthStencilAttachment()) {
|
||||
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);
|
||||
if (attachmentInfo.depthLoadOp == dawn::LoadOp::Load ||
|
||||
attachmentInfo.stencilLoadOp == dawn::LoadOp::Load) {
|
||||
ToBackend(attachmentInfo.view->GetTexture())
|
||||
->EnsureSubresourceContentInitialized(
|
||||
recordingContext, attachmentInfo.view->GetBaseMipLevel(),
|
||||
attachmentInfo.view->GetLevelCount(),
|
||||
attachmentInfo.view->GetBaseArrayLayer(),
|
||||
attachmentInfo.view->GetLayerCount());
|
||||
|
||||
// TODO(natlee@microsoft.com): Need to fix when storeop discard is added
|
||||
if (attachmentInfo.depthStoreOp == dawn::StoreOp::Store &&
|
||||
attachmentInfo.stencilStoreOp == dawn::StoreOp::Store) {
|
||||
view->GetTexture()->SetIsSubresourceContentInitialized(
|
||||
view->GetBaseMipLevel(), view->GetLevelCount(),
|
||||
view->GetBaseArrayLayer(), view->GetLayerCount());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -321,6 +321,8 @@ TEST_P(TextureZeroInitTest, RenderingLoadingDepth) {
|
|||
renderPassDescriptor.cDepthStencilAttachmentInfo.depthLoadOp = dawn::LoadOp::Load;
|
||||
renderPassDescriptor.cDepthStencilAttachmentInfo.stencilLoadOp = dawn::LoadOp::Clear;
|
||||
renderPassDescriptor.cDepthStencilAttachmentInfo.clearStencil = 0;
|
||||
renderPassDescriptor.cDepthStencilAttachmentInfo.depthStoreOp = dawn::StoreOp::Store;
|
||||
renderPassDescriptor.cDepthStencilAttachmentInfo.stencilStoreOp = dawn::StoreOp::Store;
|
||||
|
||||
dawn::CommandEncoder encoder = device.CreateCommandEncoder();
|
||||
auto pass = encoder.BeginRenderPass(&renderPassDescriptor);
|
||||
|
@ -328,8 +330,8 @@ TEST_P(TextureZeroInitTest, RenderingLoadingDepth) {
|
|||
pass.Draw(6, 1, 0, 0);
|
||||
pass.EndPass();
|
||||
dawn::CommandBuffer commandBuffer = encoder.Finish();
|
||||
// Expect 1 lazy clear for the depthStencilTexture
|
||||
EXPECT_LAZY_CLEAR(1u, queue.Submit(1, &commandBuffer));
|
||||
// Expect 0 lazy clears, depth stencil texture will clear using loadop
|
||||
EXPECT_LAZY_CLEAR(0u, queue.Submit(1, &commandBuffer));
|
||||
|
||||
// Expect the texture to be red because depth test passed.
|
||||
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.clearDepth = 0.0f;
|
||||
renderPassDescriptor.cDepthStencilAttachmentInfo.stencilLoadOp = dawn::LoadOp::Load;
|
||||
renderPassDescriptor.cDepthStencilAttachmentInfo.depthStoreOp = dawn::StoreOp::Store;
|
||||
renderPassDescriptor.cDepthStencilAttachmentInfo.stencilStoreOp = dawn::StoreOp::Store;
|
||||
|
||||
dawn::CommandEncoder encoder = device.CreateCommandEncoder();
|
||||
auto pass = encoder.BeginRenderPass(&renderPassDescriptor);
|
||||
|
@ -367,8 +371,8 @@ TEST_P(TextureZeroInitTest, RenderingLoadingStencil) {
|
|||
pass.Draw(6, 1, 0, 0);
|
||||
pass.EndPass();
|
||||
dawn::CommandBuffer commandBuffer = encoder.Finish();
|
||||
// Expect 1 lazy clear for depthStencilTexture.
|
||||
EXPECT_LAZY_CLEAR(1u, queue.Submit(1, &commandBuffer));
|
||||
// Expect 0 lazy clears, depth stencil texture will clear using loadop
|
||||
EXPECT_LAZY_CLEAR(0u, queue.Submit(1, &commandBuffer));
|
||||
|
||||
// Expect the texture to be red because stencil test passed.
|
||||
std::vector<RGBA8> expected(kSize * kSize, {255, 0, 0, 255});
|
||||
|
@ -398,6 +402,8 @@ TEST_P(TextureZeroInitTest, RenderingLoadingDepthStencil) {
|
|||
depthStencilTexture.CreateView());
|
||||
renderPassDescriptor.cDepthStencilAttachmentInfo.depthLoadOp = 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();
|
||||
auto pass = encoder.BeginRenderPass(&renderPassDescriptor);
|
||||
|
@ -405,8 +411,8 @@ TEST_P(TextureZeroInitTest, RenderingLoadingDepthStencil) {
|
|||
pass.Draw(6, 1, 0, 0);
|
||||
pass.EndPass();
|
||||
dawn::CommandBuffer commandBuffer = encoder.Finish();
|
||||
// Expect 1 lazy clear for depthStencilTexture.
|
||||
EXPECT_LAZY_CLEAR(1u, queue.Submit(1, &commandBuffer));
|
||||
// Expect 0 lazy clears, depth stencil texture will clear using loadop
|
||||
EXPECT_LAZY_CLEAR(0u, queue.Submit(1, &commandBuffer));
|
||||
|
||||
// Expect the texture to be red because both depth and stencil tests passed.
|
||||
std::vector<RGBA8> expected(kSize * kSize, {255, 0, 0, 255});
|
||||
|
|
Loading…
Reference in New Issue