Skip to content

Commit

Permalink
Merge pull request #15501 from hrydgard/split-second-simpler-alternative
Browse files Browse the repository at this point in the history
Make the existing ReinterpretFramebuffers/ShaderColorBitmask path work for Split/Second
  • Loading branch information
unknownbrackets authored Apr 25, 2022
2 parents 2178567 + 32df78a commit 676c290
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

1 comment on commit 676c290

@hrydgard
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm gonna look into Silent Hill again soon, will do that then.

Please sign in to comment.