Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove setting: Slow framebuf effects #15948

Merged
merged 2 commits into from
Sep 3, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion Core/Config.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -934,7 +934,6 @@ static ConfigSetting graphicsSettings[] = {
ConfigSetting("ShaderChainRequires60FPS", &g_Config.bShaderChainRequires60FPS, false, true, true),

ReportedConfigSetting("MemBlockTransferGPU", &g_Config.bBlockTransferGPU, true, true, true),
ReportedConfigSetting("DisableSlowFramebufEffects", &g_Config.bDisableShaderBlending, false, true, true),
ReportedConfigSetting("FragmentTestCache", &g_Config.bFragmentTestCache, true, true, true),

ConfigSetting("GfxDebugOutput", &g_Config.bGfxDebugOutput, false, false, false),
Expand Down
1 change: 0 additions & 1 deletion Core/Config.h
Original file line number Diff line number Diff line change
Expand Up @@ -232,7 +232,6 @@ struct Config {
float fGameListScrollPosition;
int iBloomHack; //0 = off, 1 = safe, 2 = balanced, 3 = aggressive
bool bBlockTransferGPU;
bool bDisableShaderBlending;
bool bFragmentTestCache;
int iSplineBezierQuality; // 0 = low , 1 = Intermediate , 2 = High
bool bHardwareTessellation;
Expand Down
82 changes: 24 additions & 58 deletions GPU/Common/GPUStateUtils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -257,7 +257,7 @@ StencilValueType ReplaceAlphaWithStencilType() {
return STENCIL_VALUE_KEEP;
}

ReplaceBlendType ReplaceBlendWithShader(bool allowFramebufferRead, GEBufferFormat bufferFormat) {
ReplaceBlendType ReplaceBlendWithShader(GEBufferFormat bufferFormat) {
if (gstate_c.blueToAlpha) {
return REPLACE_BLEND_BLUE_TO_ALPHA;
}
Expand All @@ -270,14 +270,14 @@ ReplaceBlendType ReplaceBlendWithShader(bool allowFramebufferRead, GEBufferForma
// Let's get the non-factor modes out of the way first.
switch (eq) {
case GE_BLENDMODE_ABSDIFF:
return !allowFramebufferRead ? REPLACE_BLEND_STANDARD : REPLACE_BLEND_READ_FRAMEBUFFER;
return REPLACE_BLEND_READ_FRAMEBUFFER;

case GE_BLENDMODE_MIN:
case GE_BLENDMODE_MAX:
if (gstate_c.Supports(GPU_SUPPORTS_BLEND_MINMAX)) {
return REPLACE_BLEND_STANDARD;
} else {
return !allowFramebufferRead ? REPLACE_BLEND_STANDARD : REPLACE_BLEND_READ_FRAMEBUFFER;
return REPLACE_BLEND_READ_FRAMEBUFFER;
}

default:
Expand All @@ -300,19 +300,19 @@ ReplaceBlendType ReplaceBlendWithShader(bool allowFramebufferRead, GEBufferForma
return REPLACE_BLEND_2X_ALPHA;
// Can't double, we need the source color to be correct.
// Doubling only alpha would clamp the src alpha incorrectly.
return !allowFramebufferRead ? REPLACE_BLEND_2X_ALPHA : REPLACE_BLEND_READ_FRAMEBUFFER;
return REPLACE_BLEND_READ_FRAMEBUFFER;

case GE_DSTBLEND_DOUBLEDSTALPHA:
case GE_DSTBLEND_DOUBLEINVDSTALPHA:
if (bufferFormat == GE_FORMAT_565)
return REPLACE_BLEND_2X_ALPHA;
return !allowFramebufferRead ? REPLACE_BLEND_2X_ALPHA : REPLACE_BLEND_READ_FRAMEBUFFER;
return REPLACE_BLEND_READ_FRAMEBUFFER;

case GE_DSTBLEND_DOUBLESRCALPHA:
// We can't technically do this correctly (due to clamping) without reading the dst color.
// Using a copy isn't accurate either, though, when there's overlap.
if (gstate_c.Supports(GPU_SUPPORTS_ANY_FRAMEBUFFER_FETCH))
return !allowFramebufferRead ? REPLACE_BLEND_PRE_SRC_2X_ALPHA : REPLACE_BLEND_READ_FRAMEBUFFER;
return REPLACE_BLEND_READ_FRAMEBUFFER;
return REPLACE_BLEND_PRE_SRC_2X_ALPHA;

case GE_DSTBLEND_DOUBLEINVSRCALPHA:
Expand All @@ -339,7 +339,7 @@ ReplaceBlendType ReplaceBlendWithShader(bool allowFramebufferRead, GEBufferForma
return REPLACE_BLEND_STANDARD;
}
// Can't double, we need the source color to be correct.
return !allowFramebufferRead ? REPLACE_BLEND_STANDARD : REPLACE_BLEND_READ_FRAMEBUFFER;
return REPLACE_BLEND_READ_FRAMEBUFFER;

case GE_DSTBLEND_DOUBLEDSTALPHA:
case GE_DSTBLEND_DOUBLEINVDSTALPHA:
Expand All @@ -348,7 +348,7 @@ ReplaceBlendType ReplaceBlendWithShader(bool allowFramebufferRead, GEBufferForma
// Doubling will have no effect here.
return REPLACE_BLEND_STANDARD;
}
return !allowFramebufferRead ? REPLACE_BLEND_2X_SRC : REPLACE_BLEND_READ_FRAMEBUFFER;
return REPLACE_BLEND_READ_FRAMEBUFFER;

case GE_DSTBLEND_DOUBLESRCALPHA:
case GE_DSTBLEND_DOUBLEINVSRCALPHA:
Expand All @@ -357,7 +357,7 @@ ReplaceBlendType ReplaceBlendWithShader(bool allowFramebufferRead, GEBufferForma
}
// Double both src (for dst alpha) and alpha (for dst factor.)
// But to be accurate (clamping), we need to read the dst color.
return !allowFramebufferRead ? REPLACE_BLEND_PRE_SRC_2X_ALPHA : REPLACE_BLEND_READ_FRAMEBUFFER;
return REPLACE_BLEND_READ_FRAMEBUFFER;

case GE_DSTBLEND_SRCALPHA:
case GE_DSTBLEND_INVSRCALPHA:
Expand All @@ -369,7 +369,7 @@ ReplaceBlendType ReplaceBlendWithShader(bool allowFramebufferRead, GEBufferForma
return REPLACE_BLEND_STANDARD;
}
// We can't technically do this correctly (due to clamping) without reading the dst alpha.
return !allowFramebufferRead ? REPLACE_BLEND_2X_SRC : REPLACE_BLEND_READ_FRAMEBUFFER;
return REPLACE_BLEND_READ_FRAMEBUFFER;
}

case GE_SRCBLEND_DOUBLEINVDSTALPHA:
Expand All @@ -383,14 +383,14 @@ ReplaceBlendType ReplaceBlendWithShader(bool allowFramebufferRead, GEBufferForma
if (bufferFormat == GE_FORMAT_565) {
return REPLACE_BLEND_STANDARD;
}
return !allowFramebufferRead ? REPLACE_BLEND_STANDARD : REPLACE_BLEND_READ_FRAMEBUFFER;
return REPLACE_BLEND_READ_FRAMEBUFFER;

case GE_DSTBLEND_DOUBLESRCALPHA:
case GE_DSTBLEND_DOUBLEINVSRCALPHA:
if (bufferFormat == GE_FORMAT_565) {
return REPLACE_BLEND_2X_ALPHA;
}
return !allowFramebufferRead ? REPLACE_BLEND_2X_ALPHA : REPLACE_BLEND_READ_FRAMEBUFFER;
return REPLACE_BLEND_READ_FRAMEBUFFER;

case GE_DSTBLEND_SRCALPHA:
case GE_DSTBLEND_INVSRCALPHA:
Expand All @@ -401,15 +401,15 @@ ReplaceBlendType ReplaceBlendWithShader(bool allowFramebufferRead, GEBufferForma
if (bufferFormat == GE_FORMAT_565) {
return REPLACE_BLEND_STANDARD;
}
return !allowFramebufferRead ? REPLACE_BLEND_STANDARD : REPLACE_BLEND_READ_FRAMEBUFFER;
return REPLACE_BLEND_READ_FRAMEBUFFER;
}

case GE_SRCBLEND_FIXA:
default:
switch (funcB) {
case GE_DSTBLEND_DOUBLESRCALPHA:
// Can't safely double alpha, will clamp.
return !allowFramebufferRead ? REPLACE_BLEND_2X_ALPHA : REPLACE_BLEND_READ_FRAMEBUFFER;
return REPLACE_BLEND_READ_FRAMEBUFFER;

case GE_DSTBLEND_DOUBLEINVSRCALPHA:
// Doubling alpha is safe for the inverse, will clamp to zero either way.
Expand All @@ -420,7 +420,7 @@ ReplaceBlendType ReplaceBlendWithShader(bool allowFramebufferRead, GEBufferForma
if (bufferFormat == GE_FORMAT_565) {
return REPLACE_BLEND_STANDARD;
}
return !allowFramebufferRead ? REPLACE_BLEND_STANDARD : REPLACE_BLEND_READ_FRAMEBUFFER;
return REPLACE_BLEND_READ_FRAMEBUFFER;

case GE_DSTBLEND_FIXB:
default:
Expand Down Expand Up @@ -454,14 +454,14 @@ ReplaceBlendType ReplaceBlendWithShader(bool allowFramebufferRead, GEBufferForma
if (funcA == GE_SRCBLEND_SRCALPHA || funcA == GE_SRCBLEND_INVSRCALPHA) {
// Can't safely double alpha, will clamp. However, a copy may easily be worse due to overlap.
if (gstate_c.Supports(GPU_SUPPORTS_ANY_FRAMEBUFFER_FETCH))
return !allowFramebufferRead ? REPLACE_BLEND_PRE_SRC_2X_ALPHA : REPLACE_BLEND_READ_FRAMEBUFFER;
return REPLACE_BLEND_READ_FRAMEBUFFER;
return REPLACE_BLEND_PRE_SRC_2X_ALPHA;
} else {
// This means dst alpha/color is used in the src factor.
// Unfortunately, copying here causes overlap problems in Silent Hill games (it seems?)
// We will just hope that doubling alpha for the dst factor will not clamp too badly.
if (gstate_c.Supports(GPU_SUPPORTS_ANY_FRAMEBUFFER_FETCH))
return !allowFramebufferRead ? REPLACE_BLEND_2X_ALPHA : REPLACE_BLEND_READ_FRAMEBUFFER;
return REPLACE_BLEND_READ_FRAMEBUFFER;
return REPLACE_BLEND_2X_ALPHA;
}

Expand All @@ -478,7 +478,7 @@ ReplaceBlendType ReplaceBlendWithShader(bool allowFramebufferRead, GEBufferForma
if (bufferFormat == GE_FORMAT_565) {
return REPLACE_BLEND_STANDARD;
}
return !allowFramebufferRead ? REPLACE_BLEND_STANDARD : REPLACE_BLEND_READ_FRAMEBUFFER;
return REPLACE_BLEND_READ_FRAMEBUFFER;

default:
return REPLACE_BLEND_STANDARD;
Expand Down Expand Up @@ -988,41 +988,13 @@ void ApplyStencilReplaceAndLogicOpIgnoreBlend(ReplaceAlphaType replaceAlphaWithS
}
}

bool IsColorWriteMaskComplex(bool allowFramebufferRead) {
// Restrict to Outrun temporarily (by uglily reusing the ReinterpretFramebuffers flag)
// This check must match the one in ConvertMaskState.
if (!allowFramebufferRead || !PSP_CoreParameter().compat.flags().ShaderColorBitmask) {
// Don't have a choice - we'll make do but it won't always be right.
return false;
}

if (gstate_c.blueToAlpha) {
// We'll generate a simple ___A mask.
return false;
}

uint32_t colorMask = (gstate.pmskc & 0xFFFFFF) | (gstate.pmska << 24);

for (int i = 0; i < 4; i++) {
switch (colorMask & 0xFF) {
case 0x0:
case 0xFF:
break;
default:
return true;
}
colorMask >>= 8;
}
return false;
}

// If we can we emulate the colorMask by simply toggling the full R G B A masks offered
// by modern hardware, we do that. This is 99.9% of the time.
// When that's not enough, we fall back on a technique similar to shader blending,
// we read from the framebuffer (or a copy of it).
// We also prepare uniformMask so that if doing this in the shader gets forced-on,
// we have the right mask already.
void ConvertMaskState(GenericMaskState &maskState, bool allowFramebufferRead) {
void ConvertMaskState(GenericMaskState &maskState) {
if (gstate_c.blueToAlpha) {
maskState.applyFramebufferRead = false;
maskState.uniformMask = 0xFF000000;
Expand All @@ -1048,15 +1020,9 @@ void ConvertMaskState(GenericMaskState &maskState, bool allowFramebufferRead) {
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.maskRGBA[i] = true;
} else {
// Use the old heuristic.
maskState.maskRGBA[i] = channelMask >= 128;
}
maskState.applyFramebufferRead = PSP_CoreParameter().compat.flags().ShaderColorBitmask;
maskState.maskRGBA[i] = true;
break;
}
colorMask >>= 8;
}
Expand All @@ -1071,7 +1037,7 @@ void ConvertMaskState(GenericMaskState &maskState, bool allowFramebufferRead) {
}

// Called even if AlphaBlendEnable == false - it also deals with stencil-related blend state.
void ConvertBlendState(GenericBlendState &blendState, bool allowFramebufferRead, bool forceReplaceBlend) {
void ConvertBlendState(GenericBlendState &blendState, bool forceReplaceBlend) {
// Blending is a bit complex to emulate. This is due to several reasons:
//
// * Doubled blend modes (src, dst, inversed) aren't supported in OpenGL.
Expand All @@ -1086,7 +1052,7 @@ void ConvertBlendState(GenericBlendState &blendState, bool allowFramebufferRead,
blendState.dirtyShaderBlendFixValues = false;
blendState.useBlendColor = false;

ReplaceBlendType replaceBlend = ReplaceBlendWithShader(allowFramebufferRead, gstate_c.framebufFormat);
ReplaceBlendType replaceBlend = ReplaceBlendWithShader(gstate_c.framebufFormat);
if (forceReplaceBlend) {
replaceBlend = REPLACE_BLEND_READ_FRAMEBUFFER;
}
Expand Down
7 changes: 3 additions & 4 deletions GPU/Common/GPUStateUtils.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ bool IsStencilTestOutputDisabled();

StencilValueType ReplaceAlphaWithStencilType();
ReplaceAlphaType ReplaceAlphaWithStencil(ReplaceBlendType replaceBlend);
ReplaceBlendType ReplaceBlendWithShader(bool allowShaderBlend, GEBufferFormat bufferFormat);
ReplaceBlendType ReplaceBlendWithShader(GEBufferFormat bufferFormat);

LogicOpReplaceType ReplaceLogicOpType();

Expand Down Expand Up @@ -181,7 +181,7 @@ struct GenericBlendState {
}
};

void ConvertBlendState(GenericBlendState &blendState, bool allowShaderBlend, bool forceReplaceBlend);
void ConvertBlendState(GenericBlendState &blendState, bool forceReplaceBlend);
void ApplyStencilReplaceAndLogicOpIgnoreBlend(ReplaceAlphaType replaceAlphaWithStencil, GenericBlendState &blendState);

struct GenericMaskState {
Expand All @@ -190,8 +190,7 @@ struct GenericMaskState {
bool maskRGBA[4]; // true = draw, false = don't draw this channel
};

void ConvertMaskState(GenericMaskState &maskState, bool allowFramebufferRead);
bool IsColorWriteMaskComplex(bool allowFramebufferRead);
void ConvertMaskState(GenericMaskState &maskState);

struct GenericStencilFuncState {
bool enabled;
Expand Down
4 changes: 2 additions & 2 deletions GPU/Common/ShaderId.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -269,8 +269,8 @@ void ComputeFragmentShaderID(FShaderID *id_out, const ComputedPipelineState &pip
ReplaceAlphaType stencilToAlpha = pipelineState.blendState.replaceAlphaWithStencil;

// For debugging, can probably delete soon.
// _assert_(colorWriteMask == IsColorWriteMaskComplex(gstate_c.allowFramebufferRead));
// _assert_(replaceBlend == ReplaceBlendWithShader(gstate_c.allowFramebufferRead, gstate_c.framebufFormat);
// _assert_(colorWriteMask == IsColorWriteMaskComplex());
// _assert_(replaceBlend == ReplaceBlendWithShader(gstate_c.framebufFormat);
// _assert_(stencilToAlpha == ReplaceAlphaWithStencil(replaceBlend));

// All texfuncs except replace are the same for RGB as for RGBA with full alpha.
Expand Down
5 changes: 2 additions & 3 deletions GPU/D3D11/StateMappingD3D11.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,6 @@ void DrawEngineD3D11::ApplyDrawState(int prim) {
bool useBufferedRendering = framebufferManager_->UseBufferedRendering();
// Blend
if (gstate_c.IsDirty(DIRTY_BLEND_STATE)) {
gstate_c.SetAllowFramebufferRead(!g_Config.bDisableShaderBlending);
if (gstate.isModeClear()) {
keys_.blend.value = 0; // full wipe
keys_.blend.blendEnable = false;
Expand All @@ -156,8 +155,8 @@ void DrawEngineD3D11::ApplyDrawState(int prim) {

GenericMaskState &maskState = pipelineState_.maskState;
GenericBlendState &blendState = pipelineState_.blendState;
ConvertMaskState(maskState, gstate_c.allowFramebufferRead);
ConvertBlendState(blendState, gstate_c.allowFramebufferRead, maskState.applyFramebufferRead);
ConvertMaskState(maskState);
ConvertBlendState(blendState, maskState.applyFramebufferRead);

if (blendState.applyFramebufferRead || maskState.applyFramebufferRead) {
ApplyFramebufferRead(&fboTexNeedsBind_);
Expand Down
5 changes: 2 additions & 3 deletions GPU/Directx9/StateMappingDX9.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,6 @@ void DrawEngineDX9::ApplyDrawState(int prim) {
bool useBufferedRendering = framebufferManager_->UseBufferedRendering();

if (gstate_c.IsDirty(DIRTY_BLEND_STATE)) {
gstate_c.SetAllowFramebufferRead(!g_Config.bDisableShaderBlending);
if (gstate.isModeClear()) {
dxstate.blend.disable();
// Color Mask
Expand All @@ -134,8 +133,8 @@ void DrawEngineDX9::ApplyDrawState(int prim) {
} else {
GenericMaskState &maskState = pipelineState_.maskState;
GenericBlendState &blendState = pipelineState_.blendState;
ConvertMaskState(maskState, gstate_c.allowFramebufferRead);
ConvertBlendState(blendState, gstate_c.allowFramebufferRead, maskState.applyFramebufferRead);
ConvertMaskState(maskState);
ConvertBlendState(blendState, maskState.applyFramebufferRead);

if (blendState.applyFramebufferRead || maskState.applyFramebufferRead) {
ApplyFramebufferRead(&fboTexNeedsBind_);
Expand Down
6 changes: 2 additions & 4 deletions GPU/GLES/StateMappingGLES.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -145,8 +145,6 @@ void DrawEngineGLES::ApplyDrawState(int prim) {
bool useBufferedRendering = framebufferManager_->UseBufferedRendering();

if (gstate_c.IsDirty(DIRTY_BLEND_STATE)) {
gstate_c.SetAllowFramebufferRead(!g_Config.bDisableShaderBlending);

if (gstate.isModeClear()) {
// Color Test
bool colorMask = gstate.isClearModeColorMask();
Expand All @@ -155,8 +153,8 @@ void DrawEngineGLES::ApplyDrawState(int prim) {
} else {
GenericMaskState &maskState = pipelineState_.maskState;
GenericBlendState &blendState = pipelineState_.blendState;
ConvertMaskState(maskState, gstate_c.allowFramebufferRead);
ConvertBlendState(blendState, gstate_c.allowFramebufferRead, maskState.applyFramebufferRead);
ConvertMaskState(maskState);
ConvertBlendState(blendState, maskState.applyFramebufferRead);

if (blendState.applyFramebufferRead || maskState.applyFramebufferRead) {
ApplyFramebufferRead(&fboTexNeedsBind_);
Expand Down
7 changes: 0 additions & 7 deletions GPU/GPUState.h
Original file line number Diff line number Diff line change
Expand Up @@ -550,12 +550,6 @@ struct GPUStateCache {
Dirty(DIRTY_TEXCLAMP);
}
}
void SetAllowFramebufferRead(bool allow) {
if (allowFramebufferRead != allow) {
allowFramebufferRead = allow;
Dirty(DIRTY_FRAGMENTSHADER_STATE);
}
}
void SetTextureIs3D(bool is3D) {
if (is3D != curTextureIs3D) {
curTextureIs3D = is3D;
Expand Down Expand Up @@ -583,7 +577,6 @@ struct GPUStateCache {

bool bgraTexture;
bool needShaderTexClamp;
bool allowFramebufferRead;

float morphWeights[8];
u32 deferredVertTypeDirty;
Expand Down
5 changes: 2 additions & 3 deletions GPU/Vulkan/StateMappingVulkan.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,6 @@ void DrawEngineVulkan::ConvertStateToVulkanKey(FramebufferManagerVulkan &fbManag
bool useBufferedRendering = framebufferManager_->UseBufferedRendering();

if (gstate_c.IsDirty(DIRTY_BLEND_STATE)) {
gstate_c.SetAllowFramebufferRead(!g_Config.bDisableShaderBlending);
if (gstate.isModeClear()) {
key.logicOpEnable = false;
key.logicOp = VK_LOGIC_OP_CLEAR;
Expand Down Expand Up @@ -163,8 +162,8 @@ void DrawEngineVulkan::ConvertStateToVulkanKey(FramebufferManagerVulkan &fbManag

GenericMaskState &maskState = pipelineState_.maskState;
GenericBlendState &blendState = pipelineState_.blendState;
ConvertMaskState(maskState, gstate_c.allowFramebufferRead);
ConvertBlendState(blendState, gstate_c.allowFramebufferRead, maskState.applyFramebufferRead);
ConvertMaskState(maskState);
ConvertBlendState(blendState, maskState.applyFramebufferRead);

if (blendState.applyFramebufferRead || maskState.applyFramebufferRead) {
ApplyFramebufferRead(&fboTexNeedsBind_);
Expand Down
3 changes: 0 additions & 3 deletions UI/GameSettingsScreen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -507,9 +507,6 @@ void GameSettingsScreen::CreateViews() {
});
texSecondary_->SetDisabledPtr(&g_Config.bSoftwareRendering);

CheckBox *framebufferSlowEffects = graphicsSettings->Add(new CheckBox(&g_Config.bDisableShaderBlending, gr->T("Disable slower effects (speedup)")));
framebufferSlowEffects->SetDisabledPtr(&g_Config.bSoftwareRendering);

// Seems solid, so we hide the setting.
/*CheckBox *vtxJit = graphicsSettings->Add(new CheckBox(&g_Config.bVertexDecoderJit, gr->T("Vertex Decoder JIT")));

Expand Down
Loading