Relax AMD alpha-to-coverage end2end tests expectation Direct3D 11.3 permits area dithering for alpha-to-coverage. In the Dawn end2end tests, use exact endpoint alpha values on AMD and bound the intermediate resolved value by rasterization coverage instead of requiring one sample; leave other vendors unchanged. Bug: 471380627 Change-Id: Ic6aa1460ba74ec458c0f55c77ec5032c1342ad5e Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/325295 Commit-Queue: Kai Ninomiya <kainino@chromium.org> Reviewed-by: Kai Ninomiya <kainino@chromium.org>
diff --git a/src/dawn/tests/end2end/MultisampledRenderingTests.cpp b/src/dawn/tests/end2end/MultisampledRenderingTests.cpp index 9d7a5d3..68c18dd 100644 --- a/src/dawn/tests/end2end/MultisampledRenderingTests.cpp +++ b/src/dawn/tests/end2end/MultisampledRenderingTests.cpp
@@ -1347,26 +1347,26 @@ // TODO(crbug.com/458113207): Flaky w/ WARP. DAWN_SUPPRESS_TEST_IF(IsWindows() && IsWARP()); - // TODO(crbug.com/500793601): Fails on Windows 11/AMD RX 5500 XT. - DAWN_TEST_UNSUPPORTED_IF(IsWindows11() && IsAMD()); - constexpr bool kTestDepth = false; constexpr float kMSAACoverage = 0.50f; constexpr uint32_t kSampleMask = 0xFFFFFFFF; constexpr bool kAlphaToCoverageEnabled = true; constexpr bool kFlipTriangle = true; - // For those values of alpha we expect the proportion of samples to be covered - // to correspond to the value of alpha. - // We're assuming in the case of alpha = 0.50f that the implementation - // dependendent algorithm will choose exactly one of the samples covered by the - // triangle. + // The Direct3D 11.3 Functional Specification, section 17.18 Alpha-to-Coverage: + // https://microsoft.github.io/DirectX-Specs/d3d/archive/D3D11_3_FunctionalSpec.htm#17.18%20Alpha-to-Coverage + // "As alpha goes from 0 to 1, the resulting coverages should generally increase monotonically, + // however hardware may or may not perform area dithering to provide some better quantization + // of alpha values at the cost of spatial resolution and noise." for (float alpha : {0.0f, 0.50f, 1.00f}) { wgpu::CommandEncoder commandEncoder = device.CreateCommandEncoder(); wgpu::RenderPipeline pipeline = CreateRenderPipelineWithOneOutputForTest( kTestDepth, kSampleMask, kAlphaToCoverageEnabled, kFlipTriangle); - const wgpu::Color kGreen = {0.0f, 0.8f, 0.0f, alpha - 0.01f}; + // AMD uses exact endpoint alpha values; other vendors use a small offset to avoid + // implementation-dependent quantization at alpha-to-coverage thresholds. + const float colorAlpha = IsAMD() ? alpha : alpha - 0.01f; + const wgpu::Color kGreen = {0.0f, 0.8f, 0.0f, colorAlpha}; // Draw a green triangle. { @@ -1380,7 +1380,16 @@ wgpu::CommandBuffer commandBuffer = commandEncoder.Finish(); queue.Submit(1, &commandBuffer); - VerifyResolveTarget(kGreen, mResolveTexture, 0, 0, kMSAACoverage * alpha); + if (IsAMD() && alpha == 0.50f) { + // AMD may select either rasterized sample at an intermediate alpha. Only require the + // result to remain within the rasterization coverage. + const utils::RGBA8 minExpectedColor = ExpectedMSAAColor(kGreen, 0.0f); + const utils::RGBA8 maxExpectedColor = ExpectedMSAAColor(kGreen, kMSAACoverage); + EXPECT_PIXEL_RGBA8_BETWEEN(minExpectedColor, maxExpectedColor, mResolveTexture, + (kWidth - 1) / 2, (kHeight - 1) / 2); + } else { + VerifyResolveTarget(kGreen, mResolveTexture, 0, 0, kMSAACoverage * alpha); + } } }