mirror of
https://github.com/sal063/AC6_recomp
synced 2026-08-25 08:14:40 -04:00
D3D12: Fix CONSTANT_ALPHA blend factors collapsing onto constant RGB
The D3D12 PipelineBlendFactor enum had no constant-alpha entry, so the Xenos CONSTANT_ALPHA and ONE_MINUS_CONSTANT_ALPHA blend factors (14, 15) were mapped onto the constant-COLOR kBlendFactor / kInvBlendFactor - i.e. D3D12 BLEND_FACTOR / INV_BLEND_FACTOR, which use the blend constant's RGB rather than its alpha. Aircraft ground shadow blends with dst = ONE_MINUS_CONSTANT_ALPHA and aSTANT_ALPHA blend factors collapsing onto blend constant of (0.03, 0.04, 0.04, 0.30): it wants 1 - 0.30 = 0.70 (scale the background down -> darken), but got 1 - (0.03,0.04,0.04) ~= 0.97 (barely scaled) with the white source added on top, so the shadow BRIGHTENED instead of darkening - the "white shadow" bug. Vulkan has the distinct ONE_MINUS_CONSTANT_ALPHA factor and renders it correctly. Add kBlendFactorAlpha / kInvBlendFactorAlpha to the enum, route factors 14/15 to them in both the colour and alpha maps, and map them to D3D12 ALPHA_FACTOR / INV_ALPHA_FACTOR. Verified fixed on both the RTV and ROV render-target paths.
This commit is contained in:
@@ -165,6 +165,12 @@ class PipelineCache {
|
|||||||
kBlendFactor,
|
kBlendFactor,
|
||||||
kInvBlendFactor,
|
kInvBlendFactor,
|
||||||
kSrcAlphaSat,
|
kSrcAlphaSat,
|
||||||
|
// Constant blend factor using the constant's ALPHA broadcast to RGB (D3D12
|
||||||
|
// ALPHA_FACTOR / INV_ALPHA_FACTOR). Distinct from kBlendFactor, which uses
|
||||||
|
// the constant's RGB - the Xenos CONSTANT_ALPHA / ONE_MINUS_CONSTANT_ALPHA
|
||||||
|
// factors map here, not onto the RGB ones.
|
||||||
|
kBlendFactorAlpha,
|
||||||
|
kInvBlendFactorAlpha,
|
||||||
};
|
};
|
||||||
|
|
||||||
// Update PipelineDescription::kVersion if anything is changed!
|
// Update PipelineDescription::kVersion if anything is changed!
|
||||||
@@ -219,7 +225,7 @@ class PipelineCache {
|
|||||||
|
|
||||||
PipelineRenderTarget render_targets[xenos::kMaxColorRenderTargets];
|
PipelineRenderTarget render_targets[xenos::kMaxColorRenderTargets];
|
||||||
|
|
||||||
static constexpr uint32_t kVersion = 0x20210425;
|
static constexpr uint32_t kVersion = 0x20260715;
|
||||||
});
|
});
|
||||||
|
|
||||||
REXPACKEDSTRUCT(PipelineStoredDescription, {
|
REXPACKEDSTRUCT(PipelineStoredDescription, {
|
||||||
|
|||||||
@@ -1509,10 +1509,10 @@ bool PipelineCache::GetCurrentStateDescription(
|
|||||||
/* 12 */ PipelineBlendFactor::kBlendFactor,
|
/* 12 */ PipelineBlendFactor::kBlendFactor,
|
||||||
// ONE_MINUS_CONSTANT_COLOR
|
// ONE_MINUS_CONSTANT_COLOR
|
||||||
/* 13 */ PipelineBlendFactor::kInvBlendFactor,
|
/* 13 */ PipelineBlendFactor::kInvBlendFactor,
|
||||||
// CONSTANT_ALPHA
|
// CONSTANT_ALPHA - uses the constant's ALPHA, not RGB.
|
||||||
/* 14 */ PipelineBlendFactor::kBlendFactor,
|
/* 14 */ PipelineBlendFactor::kBlendFactorAlpha,
|
||||||
// ONE_MINUS_CONSTANT_ALPHA
|
// ONE_MINUS_CONSTANT_ALPHA - uses 1 - constant ALPHA, not 1 - RGB.
|
||||||
/* 15 */ PipelineBlendFactor::kInvBlendFactor,
|
/* 15 */ PipelineBlendFactor::kInvBlendFactorAlpha,
|
||||||
/* 16 */ PipelineBlendFactor::kSrcAlphaSat,
|
/* 16 */ PipelineBlendFactor::kSrcAlphaSat,
|
||||||
};
|
};
|
||||||
// Like kBlendFactorMap, but with color modes changed to alpha. Some
|
// Like kBlendFactorMap, but with color modes changed to alpha. Some
|
||||||
@@ -1534,10 +1534,10 @@ bool PipelineCache::GetCurrentStateDescription(
|
|||||||
/* 12 */ PipelineBlendFactor::kBlendFactor,
|
/* 12 */ PipelineBlendFactor::kBlendFactor,
|
||||||
// ONE_MINUS_CONSTANT_COLOR
|
// ONE_MINUS_CONSTANT_COLOR
|
||||||
/* 13 */ PipelineBlendFactor::kInvBlendFactor,
|
/* 13 */ PipelineBlendFactor::kInvBlendFactor,
|
||||||
// CONSTANT_ALPHA
|
// CONSTANT_ALPHA - uses the constant's ALPHA, not RGB.
|
||||||
/* 14 */ PipelineBlendFactor::kBlendFactor,
|
/* 14 */ PipelineBlendFactor::kBlendFactorAlpha,
|
||||||
// ONE_MINUS_CONSTANT_ALPHA
|
// ONE_MINUS_CONSTANT_ALPHA - uses 1 - constant ALPHA, not 1 - RGB.
|
||||||
/* 15 */ PipelineBlendFactor::kInvBlendFactor,
|
/* 15 */ PipelineBlendFactor::kInvBlendFactorAlpha,
|
||||||
/* 16 */ PipelineBlendFactor::kSrcAlphaSat,
|
/* 16 */ PipelineBlendFactor::kSrcAlphaSat,
|
||||||
};
|
};
|
||||||
// While it's okay to specify fewer render targets in the pipeline state
|
// While it's okay to specify fewer render targets in the pipeline state
|
||||||
@@ -2981,6 +2981,11 @@ ID3D12PipelineState* PipelineCache::CreateD3D12Pipeline(
|
|||||||
D3D12_BLEND_DEST_ALPHA, D3D12_BLEND_INV_DEST_ALPHA,
|
D3D12_BLEND_DEST_ALPHA, D3D12_BLEND_INV_DEST_ALPHA,
|
||||||
D3D12_BLEND_BLEND_FACTOR, D3D12_BLEND_INV_BLEND_FACTOR,
|
D3D12_BLEND_BLEND_FACTOR, D3D12_BLEND_INV_BLEND_FACTOR,
|
||||||
D3D12_BLEND_SRC_ALPHA_SAT,
|
D3D12_BLEND_SRC_ALPHA_SAT,
|
||||||
|
// kBlendFactorAlpha / kInvBlendFactorAlpha - the constant's alpha
|
||||||
|
// broadcast to RGB, for the Xenos CONSTANT_ALPHA / ONE_MINUS_CONSTANT_ALPHA
|
||||||
|
// factors (previously collapsed onto the RGB BLEND_FACTOR, which darkened
|
||||||
|
// shadows the wrong way - they brightened instead of subtracting).
|
||||||
|
D3D12_BLEND_ALPHA_FACTOR, D3D12_BLEND_INV_ALPHA_FACTOR,
|
||||||
};
|
};
|
||||||
// 8 entries for safety since 3 bits from the guest are passed directly.
|
// 8 entries for safety since 3 bits from the guest are passed directly.
|
||||||
static const D3D12_BLEND_OP kBlendOpMap[] = {
|
static const D3D12_BLEND_OP kBlendOpMap[] = {
|
||||||
|
|||||||
Reference in New Issue
Block a user