Some renaming. Store the BlendState/MaskState.

This commit is contained in:
Henrik Rydgård 2022-09-02 21:07:29 +02:00
parent 8447ede989
commit c784c0e94b
7 changed files with 56 additions and 53 deletions

View file

@ -23,6 +23,7 @@
#include "Common/Data/Collections/Hashmaps.h"
#include "GPU/GPUState.h"
#include "GPU/Common/GPUStateUtils.h"
#include "GPU/Common/GPUDebugInterface.h"
#include "GPU/Common/IndexGenerator.h"
#include "GPU/Common/VertexDecoderCommon.h"
@ -192,6 +193,8 @@ protected:
// Sometimes, unusual situations mean we need to reset dirty flags after state calc finishes.
uint64_t dirtyRequiresRecheck_ = 0;
ComputedPipelineState pipelineState_;
// Hardware tessellation
TessellationDataTransfer *tessDataTransfer;
};

View file

@ -956,7 +956,7 @@ void ApplyStencilReplaceAndLogicOpIgnoreBlend(ReplaceAlphaType replaceAlphaWithS
case STENCIL_VALUE_INCR_4:
case STENCIL_VALUE_INCR_8:
// We'll add the incremented value output by the shader.
blendState.enabled = true;
blendState.blendEnabled = true;
blendState.setFactors(srcBlend, dstBlend, BlendFactor::ONE, BlendFactor::ONE);
blendState.setEquation(blendEq, BlendEq::ADD);
break;
@ -964,23 +964,23 @@ void ApplyStencilReplaceAndLogicOpIgnoreBlend(ReplaceAlphaType replaceAlphaWithS
case STENCIL_VALUE_DECR_4:
case STENCIL_VALUE_DECR_8:
// We'll subtract the incremented value output by the shader.
blendState.enabled = true;
blendState.blendEnabled = true;
blendState.setFactors(srcBlend, dstBlend, BlendFactor::ONE, BlendFactor::ONE);
blendState.setEquation(blendEq, BlendEq::SUBTRACT);
break;
case STENCIL_VALUE_INVERT:
// The shader will output one, and reverse subtracting will essentially invert.
blendState.enabled = true;
blendState.blendEnabled = true;
blendState.setFactors(srcBlend, dstBlend, BlendFactor::ONE, BlendFactor::ONE);
blendState.setEquation(blendEq, BlendEq::REVERSE_SUBTRACT);
break;
default:
if (srcBlend == BlendFactor::ONE && dstBlend == BlendFactor::ZERO && blendEq == BlendEq::ADD) {
blendState.enabled = false;
blendState.blendEnabled = false;
} else {
blendState.enabled = true;
blendState.blendEnabled = true;
blendState.setFactors(srcBlend, dstBlend, BlendFactor::ONE, BlendFactor::ZERO);
blendState.setEquation(blendEq, BlendEq::ADD);
}
@ -1023,10 +1023,10 @@ bool IsColorWriteMaskComplex(bool allowFramebufferRead) {
void ConvertMaskState(GenericMaskState &maskState, bool allowFramebufferRead) {
if (gstate_c.blueToAlpha) {
maskState.applyFramebufferRead = false;
maskState.rgba[0] = false;
maskState.rgba[1] = false;
maskState.rgba[2] = false;
maskState.rgba[3] = true;
maskState.maskRGBA[0] = false;
maskState.maskRGBA[1] = false;
maskState.maskRGBA[2] = false;
maskState.maskRGBA[3] = true;
return;
}
@ -1038,20 +1038,20 @@ void ConvertMaskState(GenericMaskState &maskState, bool allowFramebufferRead) {
int channelMask = colorMask & 0xFF;
switch (channelMask) {
case 0x0:
maskState.rgba[i] = false;
maskState.maskRGBA[i] = false;
break;
case 0xFF:
maskState.rgba[i] = true;
maskState.maskRGBA[i] = true;
break;
default:
if (allowFramebufferRead) {
// Instead of just 'true', restrict shader bitmasks to Outrun temporarily.
// TODO: This check must match the one in IsColorWriteMaskComplex.
maskState.applyFramebufferRead = PSP_CoreParameter().compat.flags().ShaderColorBitmask;
maskState.rgba[i] = true;
maskState.maskRGBA[i] = true;
} else {
// Use the old heuristic.
maskState.rgba[i] = channelMask >= 128;
maskState.maskRGBA[i] = channelMask >= 128;
}
}
colorMask >>= 8;
@ -1059,10 +1059,10 @@ void ConvertMaskState(GenericMaskState &maskState, bool allowFramebufferRead) {
// Let's not write to alpha if stencil isn't enabled.
if (IsStencilTestOutputDisabled()) {
maskState.rgba[3] = false;
maskState.maskRGBA[3] = false;
} else if (ReplaceAlphaWithStencilType() == STENCIL_VALUE_KEEP) {
// If the stencil type is set to KEEP, we shouldn't write to the stencil/alpha channel.
maskState.rgba[3] = false;
maskState.maskRGBA[3] = false;
}
}
@ -1101,12 +1101,12 @@ void ConvertBlendState(GenericBlendState &blendState, bool allowFramebufferRead,
case REPLACE_BLEND_BLUE_TO_ALPHA:
blueToAlpha = true;
blendState.enabled = gstate.isAlphaBlendEnabled();
blendState.blendEnabled = gstate.isAlphaBlendEnabled();
// We'll later convert the color blend to blend in the alpha channel.
break;
case REPLACE_BLEND_COPY_FBO:
blendState.enabled = true;
blendState.blendEnabled = true;
blendState.applyFramebufferRead = true;
blendState.resetFramebufferRead = false;
blendState.replaceAlphaWithStencil = replaceAlphaWithStencil;
@ -1114,14 +1114,14 @@ void ConvertBlendState(GenericBlendState &blendState, bool allowFramebufferRead,
case REPLACE_BLEND_PRE_SRC:
case REPLACE_BLEND_PRE_SRC_2X_ALPHA:
blendState.enabled = true;
blendState.blendEnabled = true;
usePreSrc = true;
break;
case REPLACE_BLEND_STANDARD:
case REPLACE_BLEND_2X_ALPHA:
case REPLACE_BLEND_2X_SRC:
blendState.enabled = true;
blendState.blendEnabled = true;
break;
}

View file

@ -137,13 +137,18 @@ enum class BlendEq : uint8_t {
COUNT
};
// Computed blend setup, including shader stuff.
struct GenericBlendState {
bool enabled;
bool resetFramebufferRead;
bool applyFramebufferRead;
bool dirtyShaderBlendFixValues;
// Shader generation state
ReplaceAlphaType replaceAlphaWithStencil;
// Resulting hardware blend state
bool blendEnabled;
BlendFactor srcColor;
BlendFactor dstColor;
BlendFactor srcAlpha;
@ -181,7 +186,7 @@ void ApplyStencilReplaceAndLogicOpIgnoreBlend(ReplaceAlphaType replaceAlphaWithS
struct GenericMaskState {
bool applyFramebufferRead;
uint32_t uniformMask; // For each bit, opposite to the PSP.
bool rgba[4]; // true = draw, false = don't draw this channel
bool maskRGBA[4]; // true = draw, false = don't draw this channel
};
void ConvertMaskState(GenericMaskState &maskState, bool allowFramebufferRead);
@ -197,9 +202,14 @@ struct GenericStencilFuncState {
GEStencilOp zFail;
GEStencilOp zPass;
};
void ConvertStencilFuncState(GenericStencilFuncState &stencilFuncState);
struct ComputedPipelineState {
GenericBlendState blendState;
GenericMaskState maskState;
// TODO: Add logic and possibly stencil here.
};
// See issue #15898
inline bool SpongebobDepthInverseConditions(const GenericStencilFuncState &stencilState) {
// Check that the depth/stencil state matches the conditions exactly.

View file

@ -154,11 +154,9 @@ void DrawEngineD3D11::ApplyDrawState(int prim) {
} else {
keys_.blend.value = 0;
GenericMaskState maskState;
GenericMaskState &maskState = pipelineState_.maskState;
GenericBlendState &blendState = pipelineState_.blendState;
ConvertMaskState(maskState, gstate_c.allowFramebufferRead);
// Set blend - unless we need to do it in the shader.
GenericBlendState blendState;
ConvertBlendState(blendState, gstate_c.allowFramebufferRead, maskState.applyFramebufferRead);
if (blendState.applyFramebufferRead || maskState.applyFramebufferRead) {
@ -186,7 +184,7 @@ void DrawEngineD3D11::ApplyDrawState(int prim) {
gstate_c.Dirty(DIRTY_FRAGMENTSHADER_STATE);
}
if (blendState.enabled) {
if (blendState.blendEnabled) {
keys_.blend.blendEnable = true;
keys_.blend.logicOpEnable = false;
keys_.blend.blendOpColor = d3d11BlendEqLookup[(size_t)blendState.eqColor];
@ -219,7 +217,7 @@ void DrawEngineD3D11::ApplyDrawState(int prim) {
}
}
keys_.blend.colorWriteMask = (maskState.rgba[0] ? 1 : 0) | (maskState.rgba[1] ? 2 : 0) | (maskState.rgba[2] ? 4 : 0) | (maskState.rgba[3] ? 8 : 0);
keys_.blend.colorWriteMask = (maskState.maskRGBA[0] ? 1 : 0) | (maskState.maskRGBA[1] ? 2 : 0) | (maskState.maskRGBA[2] ? 4 : 0) | (maskState.maskRGBA[3] ? 8 : 0);
}
}

View file

@ -132,11 +132,9 @@ void DrawEngineDX9::ApplyDrawState(int prim) {
}
dxstate.colorMask.set(mask);
} else {
GenericMaskState maskState;
GenericMaskState &maskState = pipelineState_.maskState;
GenericBlendState &blendState = pipelineState_.blendState;
ConvertMaskState(maskState, gstate_c.allowFramebufferRead);
// Set blend - unless we need to do it in the shader.
GenericBlendState blendState;
ConvertBlendState(blendState, gstate_c.allowFramebufferRead, maskState.applyFramebufferRead);
if (blendState.applyFramebufferRead || maskState.applyFramebufferRead) {
@ -162,7 +160,7 @@ void DrawEngineDX9::ApplyDrawState(int prim) {
ResetFramebufferRead();
}
if (blendState.enabled) {
if (blendState.blendEnabled) {
dxstate.blend.enable();
dxstate.blendSeparate.enable();
dxstate.blendEquation.set(dxBlendEqLookup[(size_t)blendState.eqColor], dxBlendEqLookup[(size_t)blendState.eqAlpha]);
@ -182,7 +180,7 @@ void DrawEngineDX9::ApplyDrawState(int prim) {
u32 mask = 0;
for (int i = 0; i < 4; i++) {
if (maskState.rgba[i])
if (maskState.maskRGBA[i])
mask |= 1 << i;
}
dxstate.colorMask.set(mask);

View file

@ -153,13 +153,9 @@ void DrawEngineGLES::ApplyDrawState(int prim) {
bool alphaMask = gstate.isClearModeAlphaMask();
renderManager->SetNoBlendAndMask((colorMask ? 7 : 0) | (alphaMask ? 8 : 0));
} else {
// Do the large chunks of state conversion. We might be able to hide these two behind a dirty-flag each,
// to avoid recomputing heavy stuff unnecessarily every draw call.
GenericMaskState maskState;
GenericMaskState &maskState = pipelineState_.maskState;
GenericBlendState &blendState = pipelineState_.blendState;
ConvertMaskState(maskState, gstate_c.allowFramebufferRead);
GenericBlendState blendState;
ConvertBlendState(blendState, gstate_c.allowFramebufferRead, maskState.applyFramebufferRead);
if (blendState.applyFramebufferRead || maskState.applyFramebufferRead) {
@ -189,7 +185,7 @@ void DrawEngineGLES::ApplyDrawState(int prim) {
gstate_c.Dirty(DIRTY_FRAGMENTSHADER_STATE);
}
if (blendState.enabled) {
if (blendState.blendEnabled) {
if (blendState.dirtyShaderBlendFixValues) {
// Not quite sure how necessary this is.
dirtyRequiresRecheck_ |= DIRTY_SHADERBLEND;
@ -203,9 +199,9 @@ void DrawEngineGLES::ApplyDrawState(int prim) {
}
}
int mask = (int)maskState.rgba[0] | ((int)maskState.rgba[1] << 1) | ((int)maskState.rgba[2] << 2) | ((int)maskState.rgba[3] << 3);
if (blendState.enabled) {
renderManager->SetBlendAndMask(mask, blendState.enabled,
int mask = (int)maskState.maskRGBA[0] | ((int)maskState.maskRGBA[1] << 1) | ((int)maskState.maskRGBA[2] << 2) | ((int)maskState.maskRGBA[3] << 3);
if (blendState.blendEnabled) {
renderManager->SetBlendAndMask(mask, blendState.blendEnabled,
glBlendFactorLookup[(size_t)blendState.srcColor], glBlendFactorLookup[(size_t)blendState.dstColor],
glBlendFactorLookup[(size_t)blendState.srcAlpha], glBlendFactorLookup[(size_t)blendState.dstAlpha],
glBlendEqLookup[(size_t)blendState.eqColor], glBlendEqLookup[(size_t)blendState.eqAlpha]);

View file

@ -162,11 +162,9 @@ void DrawEngineVulkan::ConvertStateToVulkanKey(FramebufferManagerVulkan &fbManag
key.logicOp = VK_LOGIC_OP_CLEAR;
}
GenericMaskState maskState;
GenericMaskState &maskState = pipelineState_.maskState;
GenericBlendState &blendState = pipelineState_.blendState;
ConvertMaskState(maskState, gstate_c.allowFramebufferRead);
// Set blend - unless we need to do it in the shader.
GenericBlendState blendState;
ConvertBlendState(blendState, gstate_c.allowFramebufferRead, maskState.applyFramebufferRead);
if (blendState.applyFramebufferRead || maskState.applyFramebufferRead) {
@ -181,7 +179,7 @@ void DrawEngineVulkan::ConvertStateToVulkanKey(FramebufferManagerVulkan &fbManag
gstate_c.Dirty(DIRTY_FRAGMENTSHADER_STATE);
}
if (blendState.enabled) {
if (blendState.blendEnabled) {
key.blendEnable = true;
key.blendOpColor = vkBlendEqLookup[(size_t)blendState.eqColor];
key.blendOpAlpha = vkBlendEqLookup[(size_t)blendState.eqAlpha];
@ -209,10 +207,10 @@ void DrawEngineVulkan::ConvertStateToVulkanKey(FramebufferManagerVulkan &fbManag
}
key.colorWriteMask =
(maskState.rgba[0] ? VK_COLOR_COMPONENT_R_BIT : 0) |
(maskState.rgba[1] ? VK_COLOR_COMPONENT_G_BIT : 0) |
(maskState.rgba[2] ? VK_COLOR_COMPONENT_B_BIT : 0) |
(maskState.rgba[3] ? VK_COLOR_COMPONENT_A_BIT : 0);
(maskState.maskRGBA[0] ? VK_COLOR_COMPONENT_R_BIT : 0) |
(maskState.maskRGBA[1] ? VK_COLOR_COMPONENT_G_BIT : 0) |
(maskState.maskRGBA[2] ? VK_COLOR_COMPONENT_B_BIT : 0) |
(maskState.maskRGBA[3] ? VK_COLOR_COMPONENT_A_BIT : 0);
// Workaround proposed in #10421, for bug where the color write mask is not applied correctly on Adreno.
if ((gstate.pmskc & 0x00FFFFFF) == 0x00FFFFFF && g_Config.bVendorBugChecksEnabled && draw_->GetBugs().Has(Draw::Bugs::COLORWRITEMASK_BROKEN_WITH_DEPTHTEST)) {