mirror of
https://github.com/hrydgard/ppsspp.git
synced 2025-04-02 11:01:50 -04:00
Some renaming. Store the BlendState/MaskState.
This commit is contained in:
parent
8447ede989
commit
c784c0e94b
7 changed files with 56 additions and 53 deletions
|
@ -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;
|
||||
};
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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]);
|
||||
|
|
|
@ -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)) {
|
||||
|
|
Loading…
Add table
Reference in a new issue