gpu: fix zero-source alpha blending on swizzled targets

Co-authored-by: Çağatay Güçlü <33038942+defektu@users.noreply.github.com>
This commit is contained in:
nmzik
2026-10-04 23:22:54 +04:00
parent 8274e517b2
commit 94e7d239dd
7 changed files with 35 additions and 10 deletions
+3 -2
View File
@@ -15830,7 +15830,7 @@ public:
"wave32 and wave64 pixel programs shared a cache key");
// Reversed RGBA targets must use logical Sa for RGB, with a separate
// unit source factor when alpha accumulates as Sa + Da * (1 - Sa).
// zero or unit source factor for separate alpha attenuation or accumulation.
static const auto blend_pixel = [] {
std::vector<u32> code;
constexpr std::array<float, 4> source{0.8f, 0.6f, 0.4f, 0.5f};
@@ -15871,7 +15871,8 @@ public:
for (const auto test : {
AlphaBlendCase{false, Prospero::BlendFactor::kOne, ShaderAlphaBlendSource::SourceAlpha, 0.4f},
AlphaBlendCase{true, Prospero::BlendFactor::kSrcAlpha, ShaderAlphaBlendSource::SourceAlpha, 0.4f},
AlphaBlendCase{true, Prospero::BlendFactor::kOne, ShaderAlphaBlendSource::SourceAlphaOne, 0.65f}}) {
AlphaBlendCase{true, Prospero::BlendFactor::kOne, ShaderAlphaBlendSource::SourceAlphaOne, 0.65f},
AlphaBlendCase{true, Prospero::BlendFactor::kZero, ShaderAlphaBlendSource::SourceAlphaZero, 0.15f}}) {
alpha_blend.separate_alpha_blend = test.separate;
alpha_blend.alpha_srcblend = static_cast<uint8_t>(test.alpha_source);
registers.SetBlendControl(0, alpha_blend);
+9 -2
View File
@@ -12906,6 +12906,9 @@ void TestBlendMappingClassification() {
static_cast<uint8_t>(Factor::kOneMinusSrcAlpha);
Check(classify(Prospero::ColorMappingAbgr) == Support::SourceAlphaOne,
"separate alpha accumulation did not preserve its unit source factor");
blend.alpha_srcblend = static_cast<uint8_t>(Factor::kZero);
Check(classify(Prospero::ColorMappingAbgr) == Support::SourceAlphaZero,
"separate alpha attenuation did not preserve its zero source factor");
blend.alpha_srcblend = blend.color_srcblend;
Check(classify(Prospero::ColorMappingAbgr) == Support::SourceAlpha,
"equal separate alpha equations did not reuse the broadcast alpha mode");
@@ -12916,7 +12919,7 @@ void TestBlendMappingClassification() {
switch (changed) {
case 0: blend.color_srcblend = static_cast<uint8_t>(Factor::kZero); break;
case 1: blend.color_destblend = static_cast<uint8_t>(Factor::kOne); break;
case 2: blend.alpha_srcblend = static_cast<uint8_t>(Factor::kZero); break;
case 2: blend.alpha_srcblend = static_cast<uint8_t>(Factor::kDstAlpha); break;
case 3: blend.alpha_destblend = static_cast<uint8_t>(Factor::kOne); break;
case 4: blend.color_comb_fcn = static_cast<uint8_t>(Prospero::BlendOp::kSubtract); break;
case 5: blend.alpha_comb_fcn = static_cast<uint8_t>(Prospero::BlendOp::kSubtract); break;
@@ -12937,9 +12940,13 @@ void TestLogicalAlphaBlendExport() {
const auto remapped_key = MakeStageStaticKey(pixel);
pixel.alpha_blend_source = ShaderAlphaBlendSource::SourceAlphaOne;
const auto separate_key = MakeStageStaticKey(pixel);
pixel.alpha_blend_source = ShaderAlphaBlendSource::SourceAlphaZero;
const auto zero_key = MakeStageStaticKey(pixel);
Check(ordinary_key != guest_key && guest_key != remapped_key &&
ordinary_key != remapped_key && separate_key != ordinary_key &&
separate_key != guest_key && separate_key != remapped_key,
separate_key != guest_key && separate_key != remapped_key &&
zero_key != ordinary_key && zero_key != guest_key &&
zero_key != remapped_key && zero_key != separate_key,
"ordinary, guest dual-source, and logical-alpha modes share a cache key");
auto options = MakeCompileOptions(ShaderType::Pixel);