Fix translation of storeOp "clear" on Metal

Previously, resolve was not performed if storeOp was "clear".
Resolve should occur iff a resolveTarget is provided, regardless of
storeOp - storeOp only controls the regular render target.

Test: webgpu:api,operation,render_pass,resolve:render_pass_resolve:*
Test: MultisampledRenderingTest.ResolveInto2DTexture
Bug: dawn:650
Change-Id: Ibeae984be7f82680f182246fabc6ca9a4e1af176
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/38880
Commit-Queue: Kai Ninomiya <kainino@chromium.org>
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
This commit is contained in:
Kai Ninomiya 2021-01-28 07:03:45 +00:00 committed by Commit Bot service account
parent a194a48ba2
commit 57fcd17625
2 changed files with 43 additions and 31 deletions

View File

@ -84,29 +84,35 @@ namespace dawn_native { namespace metal {
descriptor.colorAttachments[i].slice = attachmentInfo.view->GetBaseArrayLayer(); descriptor.colorAttachments[i].slice = attachmentInfo.view->GetBaseArrayLayer();
bool hasResolveTarget = attachmentInfo.resolveTarget != nullptr; bool hasResolveTarget = attachmentInfo.resolveTarget != nullptr;
switch (attachmentInfo.storeOp) {
case wgpu::StoreOp::Store:
if (hasResolveTarget) { if (hasResolveTarget) {
descriptor.colorAttachments[i].resolveTexture = descriptor.colorAttachments[i].resolveTexture =
ToBackend(attachmentInfo.resolveTarget->GetTexture()) ToBackend(attachmentInfo.resolveTarget->GetTexture())->GetMTLTexture();
->GetMTLTexture();
descriptor.colorAttachments[i].resolveLevel = descriptor.colorAttachments[i].resolveLevel =
attachmentInfo.resolveTarget->GetBaseMipLevel(); attachmentInfo.resolveTarget->GetBaseMipLevel();
descriptor.colorAttachments[i].resolveSlice = descriptor.colorAttachments[i].resolveSlice =
attachmentInfo.resolveTarget->GetBaseArrayLayer(); attachmentInfo.resolveTarget->GetBaseArrayLayer();
switch (attachmentInfo.storeOp) {
case wgpu::StoreOp::Store:
descriptor.colorAttachments[i].storeAction = descriptor.colorAttachments[i].storeAction =
kMTLStoreActionStoreAndMultisampleResolve; kMTLStoreActionStoreAndMultisampleResolve;
} else {
descriptor.colorAttachments[i].storeAction = MTLStoreActionStore;
}
break; break;
case wgpu::StoreOp::Clear:
descriptor.colorAttachments[i].storeAction =
MTLStoreActionMultisampleResolve;
break;
}
} else {
switch (attachmentInfo.storeOp) {
case wgpu::StoreOp::Store:
descriptor.colorAttachments[i].storeAction = MTLStoreActionStore;
break;
case wgpu::StoreOp::Clear: case wgpu::StoreOp::Clear:
descriptor.colorAttachments[i].storeAction = MTLStoreActionDontCare; descriptor.colorAttachments[i].storeAction = MTLStoreActionDontCare;
break; break;
} }
} }
}
if (renderPass->attachmentState->HasDepthStencilAttachment()) { if (renderPass->attachmentState->HasDepthStencilAttachment()) {
auto& attachmentInfo = renderPass->depthStencilAttachment; auto& attachmentInfo = renderPass->depthStencilAttachment;

View File

@ -265,19 +265,24 @@ class MultisampledRenderingTest : public DawnTest {
// Test using one multisampled color attachment with resolve target can render correctly. // Test using one multisampled color attachment with resolve target can render correctly.
TEST_P(MultisampledRenderingTest, ResolveInto2DTexture) { TEST_P(MultisampledRenderingTest, ResolveInto2DTexture) {
constexpr bool kTestDepth = false; constexpr bool kTestDepth = false;
wgpu::CommandEncoder commandEncoder = device.CreateCommandEncoder();
wgpu::RenderPipeline pipeline = CreateRenderPipelineWithOneOutputForTest(kTestDepth); wgpu::RenderPipeline pipeline = CreateRenderPipelineWithOneOutputForTest(kTestDepth);
constexpr wgpu::Color kGreen = {0.0f, 0.8f, 0.0f, 0.8f}; constexpr wgpu::Color kGreen = {0.0f, 0.8f, 0.0f, 0.8f};
// storeOp should not affect the result in the resolve target.
for (wgpu::StoreOp storeOp : {wgpu::StoreOp::Store, wgpu::StoreOp::Clear}) {
wgpu::CommandEncoder commandEncoder = device.CreateCommandEncoder();
// Draw a green triangle. // Draw a green triangle.
{ {
utils::ComboRenderPassDescriptor renderPass = CreateComboRenderPassDescriptorForTest( utils::ComboRenderPassDescriptor renderPass = CreateComboRenderPassDescriptorForTest(
{mMultisampledColorView}, {mResolveView}, wgpu::LoadOp::Clear, wgpu::LoadOp::Clear, {mMultisampledColorView}, {mResolveView}, wgpu::LoadOp::Clear, wgpu::LoadOp::Clear,
kTestDepth); kTestDepth);
renderPass.cColorAttachments[0].storeOp = storeOp;
std::array<float, 4> kUniformData = {kGreen.r, kGreen.g, kGreen.b, kGreen.a}; std::array<float, 4> kUniformData = {kGreen.r, kGreen.g, kGreen.b, kGreen.a};
constexpr uint32_t kSize = sizeof(kUniformData); constexpr uint32_t kSize = sizeof(kUniformData);
EncodeRenderPassForTest(commandEncoder, renderPass, pipeline, kUniformData.data(), kSize); EncodeRenderPassForTest(commandEncoder, renderPass, pipeline, kUniformData.data(),
kSize);
} }
wgpu::CommandBuffer commandBuffer = commandEncoder.Finish(); wgpu::CommandBuffer commandBuffer = commandEncoder.Finish();
@ -285,6 +290,7 @@ TEST_P(MultisampledRenderingTest, ResolveInto2DTexture) {
VerifyResolveTarget(kGreen, mResolveTexture); VerifyResolveTarget(kGreen, mResolveTexture);
} }
}
// Test that a single-layer multisampled texture view can be created and resolved from. // Test that a single-layer multisampled texture view can be created and resolved from.
TEST_P(MultisampledRenderingTest, ResolveFromSingleLayerArrayInto2DTexture) { TEST_P(MultisampledRenderingTest, ResolveFromSingleLayerArrayInto2DTexture) {