D3D12: Add workaround for DstAlpha blend factor issue on Intel GPUs
On Intel Gen9 and Gen9.5 GPUs there is a D3D12 driver bug about using DstAlpha as the source blend factors in both color and alpha blending. Although we cannot add workaround for all such cases, we have confirmed that when the blend operation is 'add', and the destination blend factors are ‘zero', we can workaround this driver bug by replacing 'add' to 'minus'. We cannot add workaround when destination blend factor is another value. This patch adds such workaround on the affected platforms. Bug: dawn:1579 Test: dawn_end2end_tests Change-Id: If7c82b9d559b876e42fb36e2f539f9ff2f71ea91 Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/120981 Commit-Queue: Jiawei Shao <jiawei.shao@intel.com> Kokoro: Kokoro <noreply+kokoro@google.com> Reviewed-by: Austin Eng <enga@chromium.org> Reviewed-by: Corentin Wallez <cwallez@chromium.org>
This commit is contained in:
parent
fa5cda877f
commit
dd0332ec91
|
@ -374,6 +374,12 @@ static constexpr ToggleEnumAndInfoList kToggleNameAndInfoList = {{
|
|||
"Use a blit to copy from a depth texture to the nonzero subresource of a depth texture. "
|
||||
"Works around an issue where nonzero layers are not written.",
|
||||
"https://crbug.com/dawn/1083", ToggleStage::Device}},
|
||||
{Toggle::D3D12ReplaceAddWithMinusWhenDstFactorIsZeroAndSrcFactorIsDstAlpha,
|
||||
{"d3d12_replace_add_with_minus_when_dst_factor_is_zero_and_src_factor_is_dst_alpha",
|
||||
"Replace the blending operation 'Add' with 'Minus' when dstBlendFactor is 'Zero' and "
|
||||
"srcBlendFactor is 'DstAlpha'. Works around an Intel D3D12 driver issue about alpha "
|
||||
"blending.",
|
||||
"https://crbug.com/dawn/1579", ToggleStage::Device}},
|
||||
{Toggle::DisallowDeprecatedAPIs,
|
||||
{"disallow_deprecated_apis",
|
||||
"Disallow all deprecated paths by changing the deprecation warnings to validation error for "
|
||||
|
@ -392,10 +398,10 @@ static constexpr ToggleEnumAndInfoList kToggleNameAndInfoList = {{
|
|||
"MacOS Intel < Gen9 has a bug where indirect base vertex is not applied for "
|
||||
"drawIndexedIndirect. Draws are done as if it is always zero.",
|
||||
"https://crbug.com/dawn/966", ToggleStage::Device}},
|
||||
{Toggle::NoWorkaroundDstAlphaBlendDoesNotWork,
|
||||
{"no_workaround_dst_alpha_blend_does_not_work",
|
||||
"Using D3D12_BLEND_DEST_ALPHA as blend factor doesn't work correctly on the D3D12 backend "
|
||||
"using Intel Gen9 or Gen9.5 GPUs.",
|
||||
{Toggle::NoWorkaroundDstAlphaAsSrcBlendFactorForBothColorAndAlphaDoesNotWork,
|
||||
{"no_workaround_dst_alpha_as_src_blend_factor_for_both_color_and_alpha_does_not_work",
|
||||
"Using D3D12_BLEND_DEST_ALPHA as source blend factor for both color and alpha blending "
|
||||
"doesn't work correctly on the D3D12 backend using Intel Gen9 or Gen9.5 GPUs.",
|
||||
"https://crbug.com/dawn/1579", ToggleStage::Device}},
|
||||
// Comment to separate the }} so it is clearer what to copy-paste to add a toggle.
|
||||
}};
|
||||
|
|
|
@ -90,12 +90,13 @@ enum class Toggle {
|
|||
UseBlitForBufferToDepthTextureCopy,
|
||||
UseBlitForBufferToStencilTextureCopy,
|
||||
UseBlitForDepthTextureToTextureCopyToNonzeroSubresource,
|
||||
D3D12ReplaceAddWithMinusWhenDstFactorIsZeroAndSrcFactorIsDstAlpha,
|
||||
DisallowDeprecatedAPIs,
|
||||
|
||||
// Unresolved issues.
|
||||
NoWorkaroundSampleMaskBecomesZeroForAllButLastColorTarget,
|
||||
NoWorkaroundIndirectBaseVertexNotApplied,
|
||||
NoWorkaroundDstAlphaBlendDoesNotWork,
|
||||
NoWorkaroundDstAlphaAsSrcBlendFactorForBothColorAndAlphaDoesNotWork,
|
||||
|
||||
EnumCount,
|
||||
InvalidEnum = EnumCount,
|
||||
|
|
|
@ -562,7 +562,14 @@ void Adapter::SetupBackendDeviceToggles(TogglesState* deviceToggles) const {
|
|||
// Currently this toggle is only needed on Intel Gen9 and Gen9.5 GPUs.
|
||||
// See http://crbug.com/dawn/1579 for more information.
|
||||
if (gpu_info::IsIntelGen9(vendorId, deviceId)) {
|
||||
deviceToggles->ForceSet(Toggle::NoWorkaroundDstAlphaBlendDoesNotWork, true);
|
||||
// We can add workaround when the blending operation is "Add", DstFactor is "Zero" and
|
||||
// SrcFactor is "DstAlpha".
|
||||
deviceToggles->ForceSet(
|
||||
Toggle::D3D12ReplaceAddWithMinusWhenDstFactorIsZeroAndSrcFactorIsDstAlpha, true);
|
||||
|
||||
// Unfortunately we cannot add workaround for other cases.
|
||||
deviceToggles->ForceSet(
|
||||
Toggle::NoWorkaroundDstAlphaAsSrcBlendFactorForBothColorAndAlphaDoesNotWork, true);
|
||||
}
|
||||
|
||||
#if D3D12_SDK_VERSION >= 602
|
||||
|
|
|
@ -257,6 +257,18 @@ D3D12_RENDER_TARGET_BLEND_DESC ComputeColorDesc(const DeviceBase* device,
|
|||
blendDesc.SrcBlendAlpha = D3D12AlphaBlend(state->blend->alpha.srcFactor);
|
||||
blendDesc.DestBlendAlpha = D3D12AlphaBlend(state->blend->alpha.dstFactor);
|
||||
blendDesc.BlendOpAlpha = D3D12BlendOperation(state->blend->alpha.operation);
|
||||
|
||||
if (device->IsToggleEnabled(
|
||||
Toggle::D3D12ReplaceAddWithMinusWhenDstFactorIsZeroAndSrcFactorIsDstAlpha) &&
|
||||
blendDesc.SrcBlend == D3D12_BLEND_DEST_ALPHA &&
|
||||
blendDesc.SrcBlendAlpha == D3D12_BLEND_DEST_ALPHA &&
|
||||
blendDesc.BlendOp == D3D12_BLEND_OP_ADD &&
|
||||
blendDesc.BlendOpAlpha == D3D12_BLEND_OP_ADD &&
|
||||
blendDesc.DestBlend == D3D12_BLEND_ZERO &&
|
||||
blendDesc.DestBlendAlpha == D3D12_BLEND_ZERO) {
|
||||
blendDesc.BlendOp = D3D12_BLEND_OP_SUBTRACT;
|
||||
blendDesc.BlendOpAlpha = D3D12_BLEND_OP_SUBTRACT;
|
||||
}
|
||||
}
|
||||
blendDesc.RenderTargetWriteMask = D3D12RenderTargetWriteMask(state->writeMask);
|
||||
blendDesc.LogicOpEnable = false;
|
||||
|
|
|
@ -1173,6 +1173,21 @@ TEST_P(ColorStateTest, SparseAttachmentsDifferentColorMask) {
|
|||
EXPECT_PIXEL_RGBA8_EQ(utils::RGBA8::kGreen, attachment3, 0, 0);
|
||||
}
|
||||
|
||||
// This is a regression test against an Intel driver issue about using DstAlpha as
|
||||
// SrcBlendFactor for both color and alpha blend factors.
|
||||
TEST_P(ColorStateTest, SrcBlendFactorDstAlphaDstBlendFactorZero) {
|
||||
utils::RGBA8 base(32, 64, 128, 192);
|
||||
std::vector<std::pair<TriangleSpec, utils::RGBA8>> tests;
|
||||
std::transform(kColors.begin(), kColors.end(), std::back_inserter(tests),
|
||||
[&](const utils::RGBA8& color) {
|
||||
utils::RGBA8 fac(base.a, base.a, base.a, base.a);
|
||||
utils::RGBA8 expected = mix(utils::RGBA8(0, 0, 0, 0), color, fac);
|
||||
return std::make_pair(TriangleSpec({{color}}), expected);
|
||||
});
|
||||
CheckBlendFactor(base, wgpu::BlendFactor::DstAlpha, wgpu::BlendFactor::Zero,
|
||||
wgpu::BlendFactor::DstAlpha, wgpu::BlendFactor::Zero, tests);
|
||||
}
|
||||
|
||||
DAWN_INSTANTIATE_TEST(ColorStateTest,
|
||||
D3D12Backend(),
|
||||
MetalBackend(),
|
||||
|
|
Loading…
Reference in New Issue