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()) {
|
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());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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});
|
||||||
|
|
Loading…
Reference in New Issue