Skip to content

Commit

Permalink
Make the existing ReinterpretFramebuffers/ShaderColorBitmask path wor…
Browse files Browse the repository at this point in the history
…k for Split/Second

It took writing and debugging #15500 for me to understand what the issue with the old path was..

Much simpler alternative to #15500, or we could merge both but disable Split/Second
for this one. Needs some benchmarks I guess...
  • Loading branch information
hrydgard committed Apr 24, 2022
1 parent 2178567 commit 6122f40
Show file tree
Hide file tree
Showing 9 changed files with 36 additions and 16 deletions.
2 changes: 1 addition & 1 deletion GPU/Common/DrawEngineCommon.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -501,7 +501,7 @@ bool DrawEngineCommon::ApplyFramebufferRead(bool *fboTexNeedsBind) {
lastFrameBlit = gpuStats.numFlips;
}
++blitsThisFrame;
if (blitsThisFrame > MAX_REASONABLE_BLITS_PER_FRAME * 2) {
if (blitsThisFrame > MAX_REASONABLE_BLITS_PER_FRAME * 4) {
WARN_LOG_ONCE(blendingBlit2, G3D, "Skipping additional blits needed for obscure blending: %d per frame, blend %d/%d/%d", blitsThisFrame, gstate.getBlendFuncA(), gstate.getBlendFuncB(), gstate.getBlendEq());
return false;
}
Expand Down
5 changes: 4 additions & 1 deletion GPU/Common/GPUStateUtils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1033,7 +1033,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) {
void ConvertBlendState(GenericBlendState &blendState, bool allowFramebufferRead, 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 @@ -1050,6 +1050,9 @@ void ConvertBlendState(GenericBlendState &blendState, bool allowFramebufferRead)
blendState.replaceAlphaWithStencil = REPLACE_ALPHA_NO;

ReplaceBlendType replaceBlend = ReplaceBlendWithShader(allowFramebufferRead, gstate.FrameBufFormat());
if (forceReplaceBlend) {
replaceBlend = REPLACE_BLEND_COPY_FBO;
}
ReplaceAlphaType replaceAlphaWithStencil = ReplaceAlphaWithStencil(replaceBlend);
bool usePreSrc = false;

Expand Down
2 changes: 1 addition & 1 deletion GPU/Common/GPUStateUtils.h
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@ struct GenericBlendState {
}
};

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

struct GenericMaskState {
Expand Down
3 changes: 3 additions & 0 deletions GPU/Common/ShaderId.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -253,6 +253,9 @@ void ComputeFragmentShaderID(FShaderID *id_out, const Draw::Bugs &bugs) {
// Note how we here recompute some of the work already done in state mapping.
// Not ideal! At least we share the code.
ReplaceBlendType replaceBlend = ReplaceBlendWithShader(gstate_c.allowFramebufferRead, gstate.FrameBufFormat());
if (colorWriteMask) {
replaceBlend = REPLACE_BLEND_COPY_FBO;
}
ReplaceAlphaType stencilToAlpha = ReplaceAlphaWithStencil(replaceBlend);

// All texfuncs except replace are the same for RGB as for RGBA with full alpha.
Expand Down
7 changes: 4 additions & 3 deletions GPU/D3D11/StateMappingD3D11.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -155,13 +155,14 @@ void DrawEngineD3D11::ApplyDrawState(int prim) {
keys_.blend.colorWriteMask = (colorMask ? (1 | 2 | 4) : 0) | (alphaMask ? 8 : 0);
} else {
keys_.blend.value = 0;
// Set blend - unless we need to do it in the shader.
GenericBlendState blendState;
ConvertBlendState(blendState, gstate_c.allowFramebufferRead);

GenericMaskState maskState;
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) {
if (ApplyFramebufferRead(&fboTexNeedsBind_)) {
// The shader takes over the responsibility for blending, so recompute.
Expand Down
8 changes: 4 additions & 4 deletions GPU/Directx9/StateMappingDX9.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -125,13 +125,13 @@ void DrawEngineDX9::ApplyDrawState(int prim) {
bool alphaMask = gstate.isClearModeAlphaMask();
dxstate.colorMask.set(colorMask, colorMask, colorMask, alphaMask);
} else {
// Set blend - unless we need to do it in the shader.
GenericBlendState blendState;
ConvertBlendState(blendState, gstate_c.allowFramebufferRead);

GenericMaskState maskState;
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) {
if (ApplyFramebufferRead(&fboTexNeedsBind_)) {
// The shader takes over the responsibility for blending, so recompute.
Expand Down
5 changes: 3 additions & 2 deletions GPU/GLES/StateMappingGLES.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -155,12 +155,13 @@ void DrawEngineGLES::ApplyDrawState(int prim) {
} 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.
GenericBlendState blendState;
ConvertBlendState(blendState, gstate_c.allowFramebufferRead);

GenericMaskState maskState;
ConvertMaskState(maskState, gstate_c.allowFramebufferRead);

GenericBlendState blendState;
ConvertBlendState(blendState, gstate_c.allowFramebufferRead, maskState.applyFramebufferRead);

if (blendState.applyFramebufferRead || maskState.applyFramebufferRead) {
if (ApplyFramebufferRead(&fboTexNeedsBind_)) {
// The shader takes over the responsibility for blending, so recompute.
Expand Down
8 changes: 4 additions & 4 deletions GPU/Vulkan/StateMappingVulkan.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -161,13 +161,13 @@ void DrawEngineVulkan::ConvertStateToVulkanKey(FramebufferManagerVulkan &fbManag
key.logicOp = VK_LOGIC_OP_CLEAR;
}

// Set blend - unless we need to do it in the shader.
GenericBlendState blendState;
ConvertBlendState(blendState, gstate_c.allowFramebufferRead);

GenericMaskState maskState;
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) {
if (ApplyFramebufferRead(&fboTexNeedsBind_)) {
// The shader takes over the responsibility for blending, so recompute.
Expand Down
12 changes: 12 additions & 0 deletions assets/compat.ini
Original file line number Diff line number Diff line change
Expand Up @@ -1025,6 +1025,12 @@ ULES01441 = true
ULJM05600 = true
ULJM05775 = true

# Split Second
ULES01402 = true
ULUS10513 = true
ULJM05812 = true
NPJH50371 = true

[ShaderColorBitmask]
# Outrun 2006: Coast to Coast - issue #11358
ULES00262 = true
Expand All @@ -1037,6 +1043,12 @@ ULJM05533 = true
NPJH50006 = true
ULES01301 = true

# Split Second
ULES01402 = true
ULUS10513 = true
ULJM05812 = true
NPJH50371 = true

[DisableFirstFrameReadback]
# Wipeout Pure: Temporary workaround for lens flare flicker. See #13344
UCUS98612 = true
Expand Down

0 comments on commit 6122f40

Please sign in to comment.