From 2aa9ee97f4037bb50c684f6cdf38036099ef91f3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sun, 8 Nov 2020 12:31:43 +0100 Subject: [PATCH 1/6] Simplify shader blend logic in FragmentShaderGenerator.cpp --- GPU/Common/FragmentShaderGenerator.cpp | 35 +++++++++++++------------- 1 file changed, 18 insertions(+), 17 deletions(-) diff --git a/GPU/Common/FragmentShaderGenerator.cpp b/GPU/Common/FragmentShaderGenerator.cpp index 7ea4e990e0fc..e38cba0b9f47 100644 --- a/GPU/Common/FragmentShaderGenerator.cpp +++ b/GPU/Common/FragmentShaderGenerator.cpp @@ -104,6 +104,8 @@ bool GenerateFragmentShader(const FShaderID &id, char *buffer, const ShaderLangu bool earlyFragmentTests = ((!enableAlphaTest && !enableColorTest) || testForceToZero) && !gstate_c.Supports(GPU_ROUND_FRAGMENT_DEPTH_TO_16BIT); bool useAdrenoBugWorkaround = id.Bit(FS_BIT_NO_DEPTH_CANNOT_DISCARD_STENCIL); + bool readFramebufferTex = replaceBlend == REPLACE_BLEND_COPY_FBO && !gstate_c.Supports(GPU_SUPPORTS_ANY_FRAMEBUFFER_FETCH); + if (compat.shaderLanguage == ShaderLanguage::GLSL_VULKAN) { if (earlyFragmentTests) { WRITE(p, "layout (early_fragment_tests) in;\n"); @@ -116,10 +118,8 @@ bool GenerateFragmentShader(const FShaderID &id, char *buffer, const ShaderLangu WRITE(p, "layout (binding = 0) uniform sampler2D tex;\n"); } - if (!isModeClear && replaceBlend > REPLACE_BLEND_STANDARD) { - if (replaceBlend == REPLACE_BLEND_COPY_FBO) { - WRITE(p, "layout (binding = 1) uniform sampler2D fbotex;\n"); - } + if (readFramebufferTex) { + WRITE(p, "layout (binding = 1) uniform sampler2D fbotex;\n"); } if (shaderDepal) { @@ -151,11 +151,13 @@ bool GenerateFragmentShader(const FShaderID &id, char *buffer, const ShaderLangu if (compat.shaderLanguage == HLSL_D3D9) { if (doTexture) WRITE(p, "sampler tex : register(s0);\n"); - if (!isModeClear && replaceBlend > REPLACE_BLEND_STANDARD) { - if (replaceBlend == REPLACE_BLEND_COPY_FBO) { - WRITE(p, "vec2 u_fbotexSize : register(c%i);\n", CONST_PS_FBOTEXSIZE); - WRITE(p, "sampler fbotex : register(s1);\n"); - } + + if (readFramebufferTex) { + WRITE(p, "vec2 u_fbotexSize : register(c%i);\n", CONST_PS_FBOTEXSIZE); + WRITE(p, "sampler fbotex : register(s1);\n"); + } + + if (replaceBlend > REPLACE_BLEND_STANDARD) { if (replaceBlendFuncA >= GE_SRCBLEND_FIXA) { WRITE(p, "float3 u_blendFixA : register(c%i);\n", CONST_PS_BLENDFIXA); } @@ -244,11 +246,11 @@ bool GenerateFragmentShader(const FShaderID &id, char *buffer, const ShaderLangu } else if (compat.shaderLanguage == HLSL_D3D9) { if (doTexture) WRITE(p, "sampler tex : register(s0);\n"); - if (!isModeClear && replaceBlend > REPLACE_BLEND_STANDARD) { - if (replaceBlend == REPLACE_BLEND_COPY_FBO) { - WRITE(p, "vec2 u_fbotexSize : register(c%i);\n", CONST_PS_FBOTEXSIZE); - WRITE(p, "sampler fbotex : register(s1);\n"); - } + if (readFramebufferTex) { + WRITE(p, "vec2 u_fbotexSize : register(c%i);\n", CONST_PS_FBOTEXSIZE); + WRITE(p, "sampler fbotex : register(s1);\n"); + } + if (replaceBlend > REPLACE_BLEND_STANDARD) { if (replaceBlendFuncA >= GE_SRCBLEND_FIXA) { WRITE(p, "float3 u_blendFixA : register(c%i);\n", CONST_PS_BLENDFIXA); } @@ -276,7 +278,6 @@ bool GenerateFragmentShader(const FShaderID &id, char *buffer, const ShaderLangu if (enableFog) { WRITE(p, "float3 u_fogcolor : register(c%i);\n", CONST_PS_FOGCOLOR); } - } else if (ShaderLanguageIsOpenGL(compat.shaderLanguage)) { if (shaderDepal && gl_extensions.IsGLES) { WRITE(p, "precision highp int;\n"); @@ -287,7 +288,7 @@ bool GenerateFragmentShader(const FShaderID &id, char *buffer, const ShaderLangu if (!isModeClear && replaceBlend > REPLACE_BLEND_STANDARD) { *uniformMask |= DIRTY_SHADERBLEND; - if (!gstate_c.Supports(GPU_SUPPORTS_ANY_FRAMEBUFFER_FETCH) && replaceBlend == REPLACE_BLEND_COPY_FBO) { + if (readFramebufferTex) { if (!compat.texelFetch) { WRITE(p, "uniform vec2 u_fbotexSize;\n"); } @@ -869,7 +870,7 @@ bool GenerateFragmentShader(const FShaderID &id, char *buffer, const ShaderLangu } if (replaceBlend == REPLACE_BLEND_2X_ALPHA || replaceBlend == REPLACE_BLEND_PRE_SRC_2X_ALPHA) { - WRITE(p, " v.a = v.a * 2.0;\n"); + WRITE(p, " v.a *= 2.0;\n"); } } From 3d289594f95a6a2388a1bd6fef19916f9170a106 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sun, 8 Nov 2020 12:49:06 +0100 Subject: [PATCH 2/6] ShaderBlend and FramebufferRead are separate concepts. Reflect that in naming. The former has forms that don't need to read the framebuffer. This exposes that some logic is wrong... --- GPU/Common/GPUStateUtils.cpp | 54 +++++++++++++++---------------- GPU/Common/GPUStateUtils.h | 6 ++-- GPU/Common/ShaderId.cpp | 2 +- GPU/D3D11/DrawEngineD3D11.h | 2 +- GPU/D3D11/StateMappingD3D11.cpp | 18 +++++------ GPU/Directx9/StateMappingDX9.cpp | 14 ++++---- GPU/GLES/StateMappingGLES.cpp | 13 ++++---- GPU/GPUState.h | 8 ++--- GPU/Vulkan/StateMappingVulkan.cpp | 12 +++---- 9 files changed, 65 insertions(+), 64 deletions(-) diff --git a/GPU/Common/GPUStateUtils.cpp b/GPU/Common/GPUStateUtils.cpp index 8ccf5b27640f..a555faa90d6f 100644 --- a/GPU/Common/GPUStateUtils.cpp +++ b/GPU/Common/GPUStateUtils.cpp @@ -253,7 +253,7 @@ StencilValueType ReplaceAlphaWithStencilType() { return STENCIL_VALUE_KEEP; } -ReplaceBlendType ReplaceBlendWithShader(bool allowShaderBlend, GEBufferFormat bufferFormat) { +ReplaceBlendType ReplaceBlendWithShader(bool allowFramebufferRead, GEBufferFormat bufferFormat) { if (!gstate.isAlphaBlendEnabled() || gstate.isModeClear()) { return REPLACE_BLEND_NO; } @@ -262,14 +262,14 @@ ReplaceBlendType ReplaceBlendWithShader(bool allowShaderBlend, GEBufferFormat bu // Let's get the non-factor modes out of the way first. switch (eq) { case GE_BLENDMODE_ABSDIFF: - return !allowShaderBlend ? REPLACE_BLEND_STANDARD : REPLACE_BLEND_COPY_FBO; + return !allowFramebufferRead ? REPLACE_BLEND_STANDARD : REPLACE_BLEND_COPY_FBO; case GE_BLENDMODE_MIN: case GE_BLENDMODE_MAX: if (gstate_c.Supports(GPU_SUPPORTS_BLEND_MINMAX)) { return REPLACE_BLEND_STANDARD; } else { - return !allowShaderBlend ? REPLACE_BLEND_STANDARD : REPLACE_BLEND_COPY_FBO; + return !allowFramebufferRead ? REPLACE_BLEND_STANDARD : REPLACE_BLEND_COPY_FBO; } default: @@ -292,19 +292,19 @@ ReplaceBlendType ReplaceBlendWithShader(bool allowShaderBlend, GEBufferFormat bu 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 !allowShaderBlend ? REPLACE_BLEND_2X_ALPHA : REPLACE_BLEND_COPY_FBO; + return !allowFramebufferRead ? REPLACE_BLEND_2X_ALPHA : REPLACE_BLEND_COPY_FBO; case GE_DSTBLEND_DOUBLEDSTALPHA: case GE_DSTBLEND_DOUBLEINVDSTALPHA: if (bufferFormat == GE_FORMAT_565) return REPLACE_BLEND_2X_ALPHA; - return !allowShaderBlend ? REPLACE_BLEND_2X_ALPHA : REPLACE_BLEND_COPY_FBO; + return !allowFramebufferRead ? REPLACE_BLEND_2X_ALPHA : REPLACE_BLEND_COPY_FBO; 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 !allowShaderBlend ? REPLACE_BLEND_PRE_SRC_2X_ALPHA : REPLACE_BLEND_COPY_FBO; + return !allowFramebufferRead ? REPLACE_BLEND_PRE_SRC_2X_ALPHA : REPLACE_BLEND_COPY_FBO; return REPLACE_BLEND_PRE_SRC_2X_ALPHA; case GE_DSTBLEND_DOUBLEINVSRCALPHA: @@ -331,7 +331,7 @@ ReplaceBlendType ReplaceBlendWithShader(bool allowShaderBlend, GEBufferFormat bu return REPLACE_BLEND_STANDARD; } // Can't double, we need the source color to be correct. - return !allowShaderBlend ? REPLACE_BLEND_STANDARD : REPLACE_BLEND_COPY_FBO; + return !allowFramebufferRead ? REPLACE_BLEND_STANDARD : REPLACE_BLEND_COPY_FBO; case GE_DSTBLEND_DOUBLEDSTALPHA: case GE_DSTBLEND_DOUBLEINVDSTALPHA: @@ -340,7 +340,7 @@ ReplaceBlendType ReplaceBlendWithShader(bool allowShaderBlend, GEBufferFormat bu // Doubling will have no effect here. return REPLACE_BLEND_STANDARD; } - return !allowShaderBlend ? REPLACE_BLEND_2X_SRC : REPLACE_BLEND_COPY_FBO; + return !allowFramebufferRead ? REPLACE_BLEND_2X_SRC : REPLACE_BLEND_COPY_FBO; case GE_DSTBLEND_DOUBLESRCALPHA: case GE_DSTBLEND_DOUBLEINVSRCALPHA: @@ -349,7 +349,7 @@ ReplaceBlendType ReplaceBlendWithShader(bool allowShaderBlend, GEBufferFormat bu } // Double both src (for dst alpha) and alpha (for dst factor.) // But to be accurate (clamping), we need to read the dst color. - return !allowShaderBlend ? REPLACE_BLEND_PRE_SRC_2X_ALPHA : REPLACE_BLEND_COPY_FBO; + return !allowFramebufferRead ? REPLACE_BLEND_PRE_SRC_2X_ALPHA : REPLACE_BLEND_COPY_FBO; case GE_DSTBLEND_SRCALPHA: case GE_DSTBLEND_INVSRCALPHA: @@ -361,7 +361,7 @@ ReplaceBlendType ReplaceBlendWithShader(bool allowShaderBlend, GEBufferFormat bu return REPLACE_BLEND_STANDARD; } // We can't technically do this correctly (due to clamping) without reading the dst alpha. - return !allowShaderBlend ? REPLACE_BLEND_2X_SRC : REPLACE_BLEND_COPY_FBO; + return !allowFramebufferRead ? REPLACE_BLEND_2X_SRC : REPLACE_BLEND_COPY_FBO; } case GE_SRCBLEND_DOUBLEINVDSTALPHA: @@ -375,14 +375,14 @@ ReplaceBlendType ReplaceBlendWithShader(bool allowShaderBlend, GEBufferFormat bu if (bufferFormat == GE_FORMAT_565) { return REPLACE_BLEND_STANDARD; } - return !allowShaderBlend ? REPLACE_BLEND_STANDARD : REPLACE_BLEND_COPY_FBO; + return !allowFramebufferRead ? REPLACE_BLEND_STANDARD : REPLACE_BLEND_COPY_FBO; case GE_DSTBLEND_DOUBLESRCALPHA: case GE_DSTBLEND_DOUBLEINVSRCALPHA: if (bufferFormat == GE_FORMAT_565) { return REPLACE_BLEND_2X_ALPHA; } - return !allowShaderBlend ? REPLACE_BLEND_2X_ALPHA : REPLACE_BLEND_COPY_FBO; + return !allowFramebufferRead ? REPLACE_BLEND_2X_ALPHA : REPLACE_BLEND_COPY_FBO; case GE_DSTBLEND_SRCALPHA: case GE_DSTBLEND_INVSRCALPHA: @@ -393,7 +393,7 @@ ReplaceBlendType ReplaceBlendWithShader(bool allowShaderBlend, GEBufferFormat bu if (bufferFormat == GE_FORMAT_565) { return REPLACE_BLEND_STANDARD; } - return !allowShaderBlend ? REPLACE_BLEND_STANDARD : REPLACE_BLEND_COPY_FBO; + return !allowFramebufferRead ? REPLACE_BLEND_STANDARD : REPLACE_BLEND_COPY_FBO; } case GE_SRCBLEND_FIXA: @@ -401,7 +401,7 @@ ReplaceBlendType ReplaceBlendWithShader(bool allowShaderBlend, GEBufferFormat bu switch (funcB) { case GE_DSTBLEND_DOUBLESRCALPHA: // Can't safely double alpha, will clamp. - return !allowShaderBlend ? REPLACE_BLEND_2X_ALPHA : REPLACE_BLEND_COPY_FBO; + return !allowFramebufferRead ? REPLACE_BLEND_2X_ALPHA : REPLACE_BLEND_COPY_FBO; case GE_DSTBLEND_DOUBLEINVSRCALPHA: // Doubling alpha is safe for the inverse, will clamp to zero either way. @@ -412,7 +412,7 @@ ReplaceBlendType ReplaceBlendWithShader(bool allowShaderBlend, GEBufferFormat bu if (bufferFormat == GE_FORMAT_565) { return REPLACE_BLEND_STANDARD; } - return !allowShaderBlend ? REPLACE_BLEND_STANDARD : REPLACE_BLEND_COPY_FBO; + return !allowFramebufferRead ? REPLACE_BLEND_STANDARD : REPLACE_BLEND_COPY_FBO; case GE_DSTBLEND_FIXB: default: @@ -446,14 +446,14 @@ ReplaceBlendType ReplaceBlendWithShader(bool allowShaderBlend, GEBufferFormat bu 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 !allowShaderBlend ? REPLACE_BLEND_PRE_SRC_2X_ALPHA : REPLACE_BLEND_COPY_FBO; + return !allowFramebufferRead ? REPLACE_BLEND_PRE_SRC_2X_ALPHA : REPLACE_BLEND_COPY_FBO; 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 !allowShaderBlend ? REPLACE_BLEND_2X_ALPHA : REPLACE_BLEND_COPY_FBO; + return !allowFramebufferRead ? REPLACE_BLEND_2X_ALPHA : REPLACE_BLEND_COPY_FBO; return REPLACE_BLEND_2X_ALPHA; } @@ -470,7 +470,7 @@ ReplaceBlendType ReplaceBlendWithShader(bool allowShaderBlend, GEBufferFormat bu if (bufferFormat == GE_FORMAT_565) { return REPLACE_BLEND_STANDARD; } - return !allowShaderBlend ? REPLACE_BLEND_STANDARD : REPLACE_BLEND_COPY_FBO; + return !allowFramebufferRead ? REPLACE_BLEND_STANDARD : REPLACE_BLEND_COPY_FBO; default: return REPLACE_BLEND_STANDARD; @@ -958,7 +958,7 @@ void ApplyStencilReplaceAndLogicOp(ReplaceAlphaType replaceAlphaWithStencil, Gen // Called even if AlphaBlendEnable == false - it also deals with stencil-related blend state. -void ConvertBlendState(GenericBlendState &blendState, bool allowShaderBlend) { +void ConvertBlendState(GenericBlendState &blendState, bool allowFramebufferRead) { // Blending is a bit complex to emulate. This is due to several reasons: // // * Doubled blend modes (src, dst, inversed) aren't supported in OpenGL. @@ -969,25 +969,25 @@ void ConvertBlendState(GenericBlendState &blendState, bool allowShaderBlend) { // // If we can't apply blending, we make a copy of the framebuffer and do it manually. - blendState.applyShaderBlending = false; - blendState.dirtyShaderBlend = false; + blendState.applyFramebufferRead = false; + blendState.dirtyShaderBlendFixValues = false; blendState.useBlendColor = false; blendState.replaceAlphaWithStencil = REPLACE_ALPHA_NO; - ReplaceBlendType replaceBlend = ReplaceBlendWithShader(allowShaderBlend, gstate.FrameBufFormat()); + ReplaceBlendType replaceBlend = ReplaceBlendWithShader(allowFramebufferRead, gstate.FrameBufFormat()); ReplaceAlphaType replaceAlphaWithStencil = ReplaceAlphaWithStencil(replaceBlend); bool usePreSrc = false; switch (replaceBlend) { case REPLACE_BLEND_NO: - blendState.resetShaderBlending = true; + blendState.resetFramebufferRead = true; // We may still want to do something about stencil -> alpha. ApplyStencilReplaceAndLogicOp(replaceAlphaWithStencil, blendState); return; case REPLACE_BLEND_COPY_FBO: - blendState.applyShaderBlending = true; - blendState.resetShaderBlending = false; + blendState.applyFramebufferRead = true; + blendState.resetFramebufferRead = false; blendState.replaceAlphaWithStencil = replaceAlphaWithStencil; break; @@ -1003,7 +1003,7 @@ void ConvertBlendState(GenericBlendState &blendState, bool allowShaderBlend) { } blendState.enabled = true; - blendState.resetShaderBlending = true; + blendState.resetFramebufferRead = true; const GEBlendMode blendFuncEq = gstate.getBlendEq(); GEBlendSrcFactor blendFuncA = gstate.getBlendFuncA(); @@ -1071,7 +1071,7 @@ void ConvertBlendState(GenericBlendState &blendState, bool allowShaderBlend) { glBlendFuncA = BlendFactor::ONE; // Need to pull in the fixed color. TODO: If it hasn't changed, no need to dirty. if (blendFuncA == GE_SRCBLEND_FIXA) { - blendState.dirtyShaderBlend = true; + blendState.dirtyShaderBlendFixValues = true; } } diff --git a/GPU/Common/GPUStateUtils.h b/GPU/Common/GPUStateUtils.h index d58d38f6d4c3..a9c2a7f83119 100644 --- a/GPU/Common/GPUStateUtils.h +++ b/GPU/Common/GPUStateUtils.h @@ -121,9 +121,9 @@ enum class BlendEq : uint8_t { struct GenericBlendState { bool enabled; - bool resetShaderBlending; - bool applyShaderBlending; - bool dirtyShaderBlend; + bool resetFramebufferRead; + bool applyFramebufferRead; + bool dirtyShaderBlendFixValues; ReplaceAlphaType replaceAlphaWithStencil; BlendFactor srcColor; diff --git a/GPU/Common/ShaderId.cpp b/GPU/Common/ShaderId.cpp index 37b01d0c1bd3..e7d48ac7893e 100644 --- a/GPU/Common/ShaderId.cpp +++ b/GPU/Common/ShaderId.cpp @@ -240,7 +240,7 @@ void ComputeFragmentShaderID(FShaderID *id_out, const Draw::Bugs &bugs) { bool doFlatShading = gstate.getShadeMode() == GE_SHADE_FLAT; bool useShaderDepal = gstate_c.useShaderDepal; - ReplaceBlendType replaceBlend = ReplaceBlendWithShader(gstate_c.allowShaderBlend, gstate.FrameBufFormat()); + ReplaceBlendType replaceBlend = ReplaceBlendWithShader(gstate_c.allowFramebufferRead, gstate.FrameBufFormat()); ReplaceAlphaType stencilToAlpha = ReplaceAlphaWithStencil(replaceBlend); // All texfuncs except replace are the same for RGB as for RGBA with full alpha. diff --git a/GPU/D3D11/DrawEngineD3D11.h b/GPU/D3D11/DrawEngineD3D11.h index 47302fe71e58..cbca41427a2b 100644 --- a/GPU/D3D11/DrawEngineD3D11.h +++ b/GPU/D3D11/DrawEngineD3D11.h @@ -160,7 +160,7 @@ class DrawEngineD3D11 : public DrawEngineCommon { void ApplyDrawState(int prim); void ApplyDrawStateLate(bool applyStencilRef, uint8_t stencilRef); - void ResetShaderBlending(); + void ResetFramebufferRead(); ID3D11InputLayout *SetupDecFmtForDraw(D3D11VertexShader *vshader, const DecVtxFormat &decFmt, u32 pspFmt); diff --git a/GPU/D3D11/StateMappingD3D11.cpp b/GPU/D3D11/StateMappingD3D11.cpp index 8ef3d2c57460..71e068830f4f 100644 --- a/GPU/D3D11/StateMappingD3D11.cpp +++ b/GPU/D3D11/StateMappingD3D11.cpp @@ -122,7 +122,7 @@ static const D3D11_LOGIC_OP logicOps[] = { D3D11_LOGIC_OP_SET, }; -void DrawEngineD3D11::ResetShaderBlending() { +void DrawEngineD3D11::ResetFramebufferRead() { if (fboTexBound_) { ID3D11ShaderResourceView *srv = nullptr; context_->PSSetShaderResources(0, 1, &srv); @@ -144,7 +144,7 @@ void DrawEngineD3D11::ApplyDrawState(int prim) { bool useBufferedRendering = framebufferManager_->UseBufferedRendering(); // Blend if (gstate_c.IsDirty(DIRTY_BLEND_STATE)) { - gstate_c.SetAllowShaderBlend(!g_Config.bDisableSlowFramebufEffects); + gstate_c.SetAllowFramebufferRead(!g_Config.bDisableSlowFramebufEffects); if (gstate.isModeClear()) { keys_.blend.value = 0; // full wipe keys_.blend.blendEnable = false; @@ -157,18 +157,18 @@ void DrawEngineD3D11::ApplyDrawState(int prim) { keys_.blend.value = 0; // Set blend - unless we need to do it in the shader. GenericBlendState blendState; - ConvertBlendState(blendState, gstate_c.allowShaderBlend); - if (blendState.applyShaderBlending) { + ConvertBlendState(blendState, gstate_c.allowFramebufferRead); + if (blendState.applyFramebufferRead) { if (ApplyShaderBlending()) { // We may still want to do something about stencil -> alpha. ApplyStencilReplaceAndLogicOp(blendState.replaceAlphaWithStencil, blendState); } else { // Until next time, force it off. - ResetShaderBlending(); - gstate_c.SetAllowShaderBlend(false); + ResetFramebufferRead(); + gstate_c.SetAllowFramebufferRead(false); } - } else if (blendState.resetShaderBlending) { - ResetShaderBlending(); + } else if (blendState.resetFramebufferRead) { + ResetFramebufferRead(); } if (blendState.enabled) { @@ -180,7 +180,7 @@ void DrawEngineD3D11::ApplyDrawState(int prim) { keys_.blend.srcAlpha = d3d11BlendFactorLookup[(size_t)blendState.srcAlpha]; keys_.blend.destColor = d3d11BlendFactorLookup[(size_t)blendState.dstColor]; keys_.blend.destAlpha = d3d11BlendFactorLookup[(size_t)blendState.dstAlpha]; - if (blendState.dirtyShaderBlend) { + if (blendState.dirtyShaderBlendFixValues) { gstate_c.Dirty(DIRTY_SHADERBLEND); } dynState_.useBlendColor = blendState.useBlendColor; diff --git a/GPU/Directx9/StateMappingDX9.cpp b/GPU/Directx9/StateMappingDX9.cpp index cbe47ead46e7..f9b385ed3769 100644 --- a/GPU/Directx9/StateMappingDX9.cpp +++ b/GPU/Directx9/StateMappingDX9.cpp @@ -115,8 +115,8 @@ void DrawEngineDX9::ApplyDrawState(int prim) { if (gstate_c.IsDirty(DIRTY_BLEND_STATE)) { gstate_c.Clean(DIRTY_BLEND_STATE); - // Unfortunately, this isn't implemented yet. - gstate_c.SetAllowShaderBlend(false); + // Unfortunately, this isn't implemented on DX9 yet. + gstate_c.SetAllowFramebufferRead(false); if (gstate.isModeClear()) { dxstate.blend.disable(); @@ -127,18 +127,18 @@ void DrawEngineDX9::ApplyDrawState(int prim) { } else { // Set blend - unless we need to do it in the shader. GenericBlendState blendState; - ConvertBlendState(blendState, gstate_c.allowShaderBlend); + ConvertBlendState(blendState, gstate_c.allowFramebufferRead); - if (blendState.applyShaderBlending) { + if (blendState.applyFramebufferRead) { if (ApplyShaderBlending()) { // We may still want to do something about stencil -> alpha. ApplyStencilReplaceAndLogicOp(blendState.replaceAlphaWithStencil, blendState); } else { // Until next time, force it off. ResetShaderBlending(); - gstate_c.SetAllowShaderBlend(false); + gstate_c.SetAllowFramebufferRead(false); } - } else if (blendState.resetShaderBlending) { + } else if (blendState.resetFramebufferRead) { ResetShaderBlending(); } @@ -149,7 +149,7 @@ void DrawEngineDX9::ApplyDrawState(int prim) { dxstate.blendFunc.set( dxBlendFactorLookup[(size_t)blendState.srcColor], dxBlendFactorLookup[(size_t)blendState.dstColor], dxBlendFactorLookup[(size_t)blendState.srcAlpha], dxBlendFactorLookup[(size_t)blendState.dstAlpha]); - if (blendState.dirtyShaderBlend) { + if (blendState.dirtyShaderBlendFixValues) { gstate_c.Dirty(DIRTY_SHADERBLEND); } if (blendState.useBlendColor) { diff --git a/GPU/GLES/StateMappingGLES.cpp b/GPU/GLES/StateMappingGLES.cpp index 25d178a293ba..23cbe919c0e4 100644 --- a/GPU/GLES/StateMappingGLES.cpp +++ b/GPU/GLES/StateMappingGLES.cpp @@ -156,7 +156,7 @@ void DrawEngineGLES::ApplyDrawState(int prim) { if (gstate_c.IsDirty(DIRTY_BLEND_STATE)) { gstate_c.Clean(DIRTY_BLEND_STATE); - gstate_c.SetAllowShaderBlend(!g_Config.bDisableSlowFramebufEffects); + gstate_c.SetAllowFramebufferRead(!g_Config.bDisableSlowFramebufEffects); if (gstate.isModeClear()) { // Color Test @@ -167,9 +167,9 @@ void DrawEngineGLES::ApplyDrawState(int prim) { // 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.allowShaderBlend); + ConvertBlendState(blendState, gstate_c.allowFramebufferRead); - if (blendState.applyShaderBlending) { + if (blendState.applyFramebufferRead) { if (ApplyShaderBlending()) { // We may still want to do something about stencil -> alpha. ApplyStencilReplaceAndLogicOp(blendState.replaceAlphaWithStencil, blendState); @@ -191,14 +191,15 @@ void DrawEngineGLES::ApplyDrawState(int prim) { } else { // Until next time, force it off. ResetShaderBlending(); - gstate_c.SetAllowShaderBlend(false); + gstate_c.SetAllowFramebufferRead(false); } - } else if (blendState.resetShaderBlending) { + } else if (blendState.resetFramebufferRead) { ResetShaderBlending(); } if (blendState.enabled) { - if (blendState.dirtyShaderBlend) { + if (blendState.dirtyShaderBlendFixValues) { + // Not quite sure how necessary this is. gstate_c.Dirty(DIRTY_SHADERBLEND); } if (blendState.useBlendColor) { diff --git a/GPU/GPUState.h b/GPU/GPUState.h index 0deaa9e8f0f7..25402a3b76ae 100644 --- a/GPU/GPUState.h +++ b/GPU/GPUState.h @@ -540,9 +540,9 @@ struct GPUStateCache { Dirty(DIRTY_TEXCLAMP); } } - void SetAllowShaderBlend(bool allow) { - if (allowShaderBlend != allow) { - allowShaderBlend = allow; + void SetAllowFramebufferRead(bool allow) { + if (allowFramebufferRead != allow) { + allowFramebufferRead = allow; Dirty(DIRTY_FRAGMENTSHADER_STATE); } } @@ -564,7 +564,7 @@ struct GPUStateCache { bool bgraTexture; bool needShaderTexClamp; - bool allowShaderBlend; + bool allowFramebufferRead; float morphWeights[8]; u32 deferredVertTypeDirty; diff --git a/GPU/Vulkan/StateMappingVulkan.cpp b/GPU/Vulkan/StateMappingVulkan.cpp index 1dee71861dc5..ed3259283d77 100644 --- a/GPU/Vulkan/StateMappingVulkan.cpp +++ b/GPU/Vulkan/StateMappingVulkan.cpp @@ -135,7 +135,7 @@ void DrawEngineVulkan::ConvertStateToVulkanKey(FramebufferManagerVulkan &fbManag bool useBufferedRendering = framebufferManager_->UseBufferedRendering(); if (gstate_c.IsDirty(DIRTY_BLEND_STATE)) { - gstate_c.SetAllowShaderBlend(!g_Config.bDisableSlowFramebufEffects); + gstate_c.SetAllowFramebufferRead(!g_Config.bDisableSlowFramebufEffects); if (gstate.isModeClear()) { key.logicOpEnable = false; key.logicOp = VK_LOGIC_OP_CLEAR; @@ -163,20 +163,20 @@ void DrawEngineVulkan::ConvertStateToVulkanKey(FramebufferManagerVulkan &fbManag // Set blend - unless we need to do it in the shader. GenericBlendState blendState; - ConvertBlendState(blendState, gstate_c.allowShaderBlend); + ConvertBlendState(blendState, gstate_c.allowFramebufferRead); - if (blendState.applyShaderBlending) { + if (blendState.applyFramebufferRead) { if (ApplyShaderBlending()) { // We may still want to do something about stencil -> alpha. ApplyStencilReplaceAndLogicOp(blendState.replaceAlphaWithStencil, blendState); } else { // Until next time, force it off. ResetShaderBlending(); - gstate_c.SetAllowShaderBlend(false); + gstate_c.SetAllowFramebufferRead(false); // Make sure we recompute the fragment shader ID to one that doesn't try to use shader blending. gstate_c.Dirty(DIRTY_FRAGMENTSHADER_STATE); } - } else if (blendState.resetShaderBlending) { + } else if (blendState.resetFramebufferRead) { ResetShaderBlending(); } @@ -188,7 +188,7 @@ void DrawEngineVulkan::ConvertStateToVulkanKey(FramebufferManagerVulkan &fbManag key.srcAlpha = vkBlendFactorLookup[(size_t)blendState.srcAlpha]; key.destColor = vkBlendFactorLookup[(size_t)blendState.dstColor]; key.destAlpha = vkBlendFactorLookup[(size_t)blendState.dstAlpha]; - if (blendState.dirtyShaderBlend) { + if (blendState.dirtyShaderBlendFixValues) { gstate_c.Dirty(DIRTY_SHADERBLEND); } dynState.useBlendColor = blendState.useBlendColor; From 391b8155c54624eabdff16a484dbe8f54ff39d11 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sun, 8 Nov 2020 13:14:23 +0100 Subject: [PATCH 3/6] More work on detangling the concepts and making things make more sense. --- GPU/Common/DrawEngineCommon.cpp | 5 +++-- GPU/Common/DrawEngineCommon.h | 4 ++-- GPU/D3D11/StateMappingD3D11.cpp | 7 ++++--- GPU/Directx9/DrawEngineDX9.h | 2 +- GPU/Directx9/StateMappingDX9.cpp | 27 +++++++-------------------- GPU/GLES/DrawEngineGLES.h | 2 +- GPU/GLES/StateMappingGLES.cpp | 26 +++++++------------------- GPU/Vulkan/DrawEngineVulkan.h | 2 +- GPU/Vulkan/StateMappingVulkan.cpp | 26 ++++++-------------------- 9 files changed, 32 insertions(+), 69 deletions(-) diff --git a/GPU/Common/DrawEngineCommon.cpp b/GPU/Common/DrawEngineCommon.cpp index bb554d1c3862..1784813175f8 100644 --- a/GPU/Common/DrawEngineCommon.cpp +++ b/GPU/Common/DrawEngineCommon.cpp @@ -480,8 +480,9 @@ u32 DrawEngineCommon::NormalizeVertices(u8 *outPtr, u8 *bufPtr, const u8 *inPtr, return GE_VTYPE_TC_FLOAT | GE_VTYPE_COL_8888 | GE_VTYPE_NRM_FLOAT | GE_VTYPE_POS_FLOAT | (vertType & (GE_VTYPE_IDX_MASK | GE_VTYPE_THROUGH)); } -bool DrawEngineCommon::ApplyShaderBlending() { +bool DrawEngineCommon::ApplyFramebufferRead(bool *fboTexNeedsBind) { if (gstate_c.Supports(GPU_SUPPORTS_ANY_FRAMEBUFFER_FETCH)) { + *fboTexNeedsBind = false; return true; } @@ -502,7 +503,7 @@ bool DrawEngineCommon::ApplyShaderBlending() { return false; } - fboTexNeedBind_ = true; + *fboTexNeedsBind = true; gstate_c.Dirty(DIRTY_SHADERBLEND); return true; diff --git a/GPU/Common/DrawEngineCommon.h b/GPU/Common/DrawEngineCommon.h index f53b96f4877c..7a063a2d26c4 100644 --- a/GPU/Common/DrawEngineCommon.h +++ b/GPU/Common/DrawEngineCommon.h @@ -112,7 +112,7 @@ class DrawEngineCommon { // Vertex decoding void DecodeVertsStep(u8 *dest, int &i, int &decodedVerts); - bool ApplyShaderBlending(); + bool ApplyFramebufferRead(bool *fboTexNeedsBind); inline int IndexSize(u32 vtype) const { const u32 indexType = (vtype & GE_VTYPE_IDX_MASK); @@ -169,7 +169,7 @@ class DrawEngineCommon { GEPrimitiveType prevPrim_ = GE_PRIM_INVALID; // Shader blending state - bool fboTexNeedBind_ = false; + bool fboTexNeedsBind_ = false; bool fboTexBound_ = false; // Hardware tessellation diff --git a/GPU/D3D11/StateMappingD3D11.cpp b/GPU/D3D11/StateMappingD3D11.cpp index 71e068830f4f..1529ae9b542e 100644 --- a/GPU/D3D11/StateMappingD3D11.cpp +++ b/GPU/D3D11/StateMappingD3D11.cpp @@ -159,13 +159,14 @@ void DrawEngineD3D11::ApplyDrawState(int prim) { GenericBlendState blendState; ConvertBlendState(blendState, gstate_c.allowFramebufferRead); if (blendState.applyFramebufferRead) { - if (ApplyShaderBlending()) { + if (ApplyFramebufferRead(&fboTexNeedsBind_)) { // We may still want to do something about stencil -> alpha. ApplyStencilReplaceAndLogicOp(blendState.replaceAlphaWithStencil, blendState); } else { // Until next time, force it off. ResetFramebufferRead(); gstate_c.SetAllowFramebufferRead(false); + gstate_c.Dirty(DIRTY_FRAGMENTSHADER_STATE); } } else if (blendState.resetFramebufferRead) { ResetFramebufferRead(); @@ -446,11 +447,11 @@ void DrawEngineD3D11::ApplyDrawState(int prim) { void DrawEngineD3D11::ApplyDrawStateLate(bool applyStencilRef, uint8_t stencilRef) { if (!gstate.isModeClear()) { - if (fboTexNeedBind_) { + if (fboTexNeedsBind_) { framebufferManager_->BindFramebufferAsColorTexture(1, framebufferManager_->GetCurrentRenderVFB(), BINDFBCOLOR_MAY_COPY); // No sampler required, we do a plain Load in the pixel shader. fboTexBound_ = true; - fboTexNeedBind_ = false; + fboTexNeedsBind_ = false; } textureCache_->ApplyTexture(); } diff --git a/GPU/Directx9/DrawEngineDX9.h b/GPU/Directx9/DrawEngineDX9.h index 789ebe6209ae..f0963beb91d5 100644 --- a/GPU/Directx9/DrawEngineDX9.h +++ b/GPU/Directx9/DrawEngineDX9.h @@ -150,7 +150,7 @@ class DrawEngineDX9 : public DrawEngineCommon { void ApplyDrawState(int prim); void ApplyDrawStateLate(); - void ResetShaderBlending(); + void ResetFramebufferRead(); IDirect3DVertexDeclaration9 *SetupDecFmtForDraw(VSShader *vshader, const DecVtxFormat &decFmt, u32 pspFmt); diff --git a/GPU/Directx9/StateMappingDX9.cpp b/GPU/Directx9/StateMappingDX9.cpp index f9b385ed3769..ee496b17b698 100644 --- a/GPU/Directx9/StateMappingDX9.cpp +++ b/GPU/Directx9/StateMappingDX9.cpp @@ -90,7 +90,7 @@ static const D3DSTENCILOP stencilOps[] = { D3DSTENCILOP_KEEP, // reserved }; -inline void DrawEngineDX9::ResetShaderBlending() { +inline void DrawEngineDX9::ResetFramebufferRead() { if (fboTexBound_) { device_->SetTexture(1, nullptr); fboTexBound_ = false; @@ -130,16 +130,17 @@ void DrawEngineDX9::ApplyDrawState(int prim) { ConvertBlendState(blendState, gstate_c.allowFramebufferRead); if (blendState.applyFramebufferRead) { - if (ApplyShaderBlending()) { + if (ApplyFramebufferRead(&fboTexNeedsBind_)) { // We may still want to do something about stencil -> alpha. ApplyStencilReplaceAndLogicOp(blendState.replaceAlphaWithStencil, blendState); } else { // Until next time, force it off. - ResetShaderBlending(); + ResetFramebufferRead(); gstate_c.SetAllowFramebufferRead(false); } + gstate_c.Dirty(DIRTY_FRAGMENTSHADER_STATE); } else if (blendState.resetFramebufferRead) { - ResetShaderBlending(); + ResetFramebufferRead(); } if (blendState.enabled) { @@ -166,20 +167,6 @@ void DrawEngineDX9::ApplyDrawState(int prim) { bool bmask = ((gstate.pmskc >> 16) & 0xFF) < 128; bool amask = (gstate.pmska & 0xFF) < 128; -#ifndef MOBILE_DEVICE - u8 abits = (gstate.pmska >> 0) & 0xFF; - u8 rbits = (gstate.pmskc >> 0) & 0xFF; - u8 gbits = (gstate.pmskc >> 8) & 0xFF; - u8 bbits = (gstate.pmskc >> 16) & 0xFF; - if ((rbits != 0 && rbits != 0xFF) || (gbits != 0 && gbits != 0xFF) || (bbits != 0 && bbits != 0xFF)) { - WARN_LOG_REPORT_ONCE(rgbmask, G3D, "Unsupported RGB mask: r=%02x g=%02x b=%02x", rbits, gbits, bbits); - } - if (abits != 0 && abits != 0xFF) { - // The stencil part of the mask is supported. - WARN_LOG_REPORT_ONCE(amask, G3D, "Unsupported alpha/stencil mask: %02x", abits); - } -#endif - // Let's not write to alpha if stencil isn't enabled. if (IsStencilTestOutputDisabled()) { amask = false; @@ -297,14 +284,14 @@ void DrawEngineDX9::ApplyDrawStateLate() { if (!gstate.isModeClear()) { textureCache_->ApplyTexture(); - if (fboTexNeedBind_) { + if (fboTexNeedsBind_) { // Note that this is positions, not UVs, that we need the copy from. framebufferManager_->BindFramebufferAsColorTexture(1, framebufferManager_->GetCurrentRenderVFB(), BINDFBCOLOR_MAY_COPY); // If we are rendering at a higher resolution, linear is probably best for the dest color. device_->SetSamplerState(1, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR); device_->SetSamplerState(1, D3DSAMP_MINFILTER, D3DTEXF_LINEAR); fboTexBound_ = true; - fboTexNeedBind_ = false; + fboTexNeedsBind_ = false; } // TODO: Test texture? diff --git a/GPU/GLES/DrawEngineGLES.h b/GPU/GLES/DrawEngineGLES.h index 8c962dd1419e..fd694f4d7e2e 100644 --- a/GPU/GLES/DrawEngineGLES.h +++ b/GPU/GLES/DrawEngineGLES.h @@ -193,7 +193,7 @@ class DrawEngineGLES : public DrawEngineCommon { void DoFlush(); void ApplyDrawState(int prim); void ApplyDrawStateLate(bool setStencil, int stencilValue); - void ResetShaderBlending(); + void ResetFramebufferRead(); GLRInputLayout *SetupDecFmtForDraw(LinkedShader *program, const DecVtxFormat &decFmt); diff --git a/GPU/GLES/StateMappingGLES.cpp b/GPU/GLES/StateMappingGLES.cpp index 23cbe919c0e4..2b6f0e39f8f5 100644 --- a/GPU/GLES/StateMappingGLES.cpp +++ b/GPU/GLES/StateMappingGLES.cpp @@ -121,7 +121,7 @@ static const GLushort logicOps[] = { }; #endif -inline void DrawEngineGLES::ResetShaderBlending() { +inline void DrawEngineGLES::ResetFramebufferRead() { if (fboTexBound_) { GLRenderManager *renderManager = (GLRenderManager *)draw_->GetNativeObject(Draw::NativeObject::RENDER_MANAGER); renderManager->BindTexture(TEX_SLOT_SHADERBLEND_SRC, nullptr); @@ -170,19 +170,19 @@ void DrawEngineGLES::ApplyDrawState(int prim) { ConvertBlendState(blendState, gstate_c.allowFramebufferRead); if (blendState.applyFramebufferRead) { - if (ApplyShaderBlending()) { + if (ApplyFramebufferRead(&fboTexNeedsBind_)) { // We may still want to do something about stencil -> alpha. ApplyStencilReplaceAndLogicOp(blendState.replaceAlphaWithStencil, blendState); // We copy the framebuffer here, as doing so will wipe any blend state if we do it later. - if (fboTexNeedBind_) { + if (fboTexNeedsBind_) { // Note that this is positions, not UVs, that we need the copy from. // TODO: If the device doesn't support blit, this will corrupt the currently applied texture. framebufferManager_->BindFramebufferAsColorTexture(1, framebufferManager_->GetCurrentRenderVFB(), BINDFBCOLOR_MAY_COPY); // If we are rendering at a higher resolution, linear is probably best for the dest color. renderManager->SetTextureSampler(1, GL_CLAMP_TO_EDGE, GL_CLAMP_TO_EDGE, GL_LINEAR, GL_LINEAR, 0.0f); fboTexBound_ = true; - fboTexNeedBind_ = false; + fboTexNeedsBind_ = false; framebufferManager_->RebindFramebuffer("RebindFramebuffer - ApplyDrawState"); // Must dirty blend state here so we re-copy next time. Example: Lunar's spell effects. @@ -190,11 +190,12 @@ void DrawEngineGLES::ApplyDrawState(int prim) { } } else { // Until next time, force it off. - ResetShaderBlending(); + ResetFramebufferRead(); gstate_c.SetAllowFramebufferRead(false); } + gstate_c.Dirty(DIRTY_FRAGMENTSHADER_STATE); } else if (blendState.resetFramebufferRead) { - ResetShaderBlending(); + ResetFramebufferRead(); } if (blendState.enabled) { @@ -220,19 +221,6 @@ void DrawEngineGLES::ApplyDrawState(int prim) { bool gmask = ((gstate.pmskc >> 8) & 0xFF) < 128; bool bmask = ((gstate.pmskc >> 16) & 0xFF) < 128; -#ifndef MOBILE_DEVICE - u8 abits = (gstate.pmska >> 0) & 0xFF; - u8 rbits = (gstate.pmskc >> 0) & 0xFF; - u8 gbits = (gstate.pmskc >> 8) & 0xFF; - u8 bbits = (gstate.pmskc >> 16) & 0xFF; - if ((rbits != 0 && rbits != 0xFF) || (gbits != 0 && gbits != 0xFF) || (bbits != 0 && bbits != 0xFF)) { - WARN_LOG_REPORT_ONCE(rgbmask, G3D, "Unsupported RGB mask: r=%02x g=%02x b=%02x", rbits, gbits, bbits); - } - if (abits != 0 && abits != 0xFF) { - // The stencil part of the mask is supported. - WARN_LOG_REPORT_ONCE(amask, G3D, "Unsupported alpha/stencil mask: %02x", abits); - } -#endif int mask = (int)rmask | ((int)gmask << 1) | ((int)bmask << 2) | ((int)amask << 3); if (blendState.enabled) { renderManager->SetBlendAndMask(mask, blendState.enabled, diff --git a/GPU/Vulkan/DrawEngineVulkan.h b/GPU/Vulkan/DrawEngineVulkan.h index 3f46a62186cf..0e36cbcc169a 100644 --- a/GPU/Vulkan/DrawEngineVulkan.h +++ b/GPU/Vulkan/DrawEngineVulkan.h @@ -199,7 +199,7 @@ class DrawEngineVulkan : public DrawEngineCommon { void ApplyDrawStateLate(VulkanRenderManager *renderManager, bool applyStencilRef, uint8_t stencilRef, bool useBlendConstant); void ConvertStateToVulkanKey(FramebufferManagerVulkan &fbManager, ShaderManagerVulkan *shaderManager, int prim, VulkanPipelineRasterStateKey &key, VulkanDynamicState &dynState); void BindShaderBlendTex(); - void ResetShaderBlending(); + void ResetFramebufferRead(); void InitDeviceObjects(); void DestroyDeviceObjects(); diff --git a/GPU/Vulkan/StateMappingVulkan.cpp b/GPU/Vulkan/StateMappingVulkan.cpp index ed3259283d77..9fbb9b202b70 100644 --- a/GPU/Vulkan/StateMappingVulkan.cpp +++ b/GPU/Vulkan/StateMappingVulkan.cpp @@ -122,7 +122,7 @@ static const VkLogicOp logicOps[] = { VK_LOGIC_OP_SET, }; -void DrawEngineVulkan::ResetShaderBlending() { +void DrawEngineVulkan::ResetFramebufferRead() { boundSecondary_ = VK_NULL_HANDLE; } @@ -166,18 +166,18 @@ void DrawEngineVulkan::ConvertStateToVulkanKey(FramebufferManagerVulkan &fbManag ConvertBlendState(blendState, gstate_c.allowFramebufferRead); if (blendState.applyFramebufferRead) { - if (ApplyShaderBlending()) { + if (ApplyFramebufferRead(&fboTexNeedsBind_)) { // We may still want to do something about stencil -> alpha. ApplyStencilReplaceAndLogicOp(blendState.replaceAlphaWithStencil, blendState); } else { // Until next time, force it off. - ResetShaderBlending(); + ResetFramebufferRead(); gstate_c.SetAllowFramebufferRead(false); // Make sure we recompute the fragment shader ID to one that doesn't try to use shader blending. gstate_c.Dirty(DIRTY_FRAGMENTSHADER_STATE); } } else if (blendState.resetFramebufferRead) { - ResetShaderBlending(); + ResetFramebufferRead(); } if (blendState.enabled) { @@ -213,20 +213,6 @@ void DrawEngineVulkan::ConvertStateToVulkanKey(FramebufferManagerVulkan &fbManag bool bmask = ((gstate.pmskc >> 16) & 0xFF) < 128; bool amask = (gstate.pmska & 0xFF) < 128; -#ifndef MOBILE_DEVICE - u8 abits = (gstate.pmska >> 0) & 0xFF; - u8 rbits = (gstate.pmskc >> 0) & 0xFF; - u8 gbits = (gstate.pmskc >> 8) & 0xFF; - u8 bbits = (gstate.pmskc >> 16) & 0xFF; - if ((rbits != 0 && rbits != 0xFF) || (gbits != 0 && gbits != 0xFF) || (bbits != 0 && bbits != 0xFF)) { - WARN_LOG_REPORT_ONCE(rgbmask, G3D, "Unsupported RGB mask: r=%02x g=%02x b=%02x", rbits, gbits, bbits); - } - if (abits != 0 && abits != 0xFF) { - // The stencil part of the mask is supported. - WARN_LOG_REPORT_ONCE(amask, G3D, "Unsupported alpha/stencil mask: %02x", abits); - } -#endif - // Let's not write to alpha if stencil isn't enabled. if (IsStencilTestOutputDisabled()) { amask = false; @@ -395,13 +381,13 @@ void DrawEngineVulkan::BindShaderBlendTex() { // TODO: Set the nearest/linear here (since we correctly know if alpha/color tests are needed)? if (!gstate.isModeClear()) { // TODO: Test texture? - if (fboTexNeedBind_) { + if (fboTexNeedsBind_) { // Note that this is positions, not UVs, that we need the copy from. framebufferManager_->BindFramebufferAsColorTexture(1, framebufferManager_->GetCurrentRenderVFB(), BINDFBCOLOR_MAY_COPY); // If we are rendering at a higher resolution, linear is probably best for the dest color. boundSecondary_ = (VkImageView)draw_->GetNativeObject(Draw::NativeObject::BOUND_TEXTURE1_IMAGEVIEW); fboTexBound_ = true; - fboTexNeedBind_ = false; + fboTexNeedsBind_ = false; } } From 793e89d2e30aea8fa1e61d1916c2a4c07812e1d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sun, 8 Nov 2020 14:34:04 +0100 Subject: [PATCH 4/6] Fix some comments, rename a function. --- GPU/Common/GPUStateUtils.cpp | 4 ++-- GPU/Common/GPUStateUtils.h | 2 +- GPU/Common/ShaderId.cpp | 2 ++ GPU/D3D11/StateMappingD3D11.cpp | 6 +++--- GPU/Directx9/StateMappingDX9.cpp | 4 ++-- GPU/GLES/StateMappingGLES.cpp | 4 ++-- GPU/Vulkan/StateMappingVulkan.cpp | 6 +++--- 7 files changed, 15 insertions(+), 13 deletions(-) diff --git a/GPU/Common/GPUStateUtils.cpp b/GPU/Common/GPUStateUtils.cpp index a555faa90d6f..7cf550ef85de 100644 --- a/GPU/Common/GPUStateUtils.cpp +++ b/GPU/Common/GPUStateUtils.cpp @@ -906,7 +906,7 @@ static void ApplyLogicOp(BlendFactor &srcBlend, BlendFactor &dstBlend, BlendEq & } // Try to simulate some common logic ops. -void ApplyStencilReplaceAndLogicOp(ReplaceAlphaType replaceAlphaWithStencil, GenericBlendState &blendState) { +void ApplyStencilReplaceAndLogicOpIgnoreBlend(ReplaceAlphaType replaceAlphaWithStencil, GenericBlendState &blendState) { StencilValueType stencilType = STENCIL_VALUE_KEEP; if (replaceAlphaWithStencil == REPLACE_ALPHA_YES) { stencilType = ReplaceAlphaWithStencilType(); @@ -982,7 +982,7 @@ void ConvertBlendState(GenericBlendState &blendState, bool allowFramebufferRead) case REPLACE_BLEND_NO: blendState.resetFramebufferRead = true; // We may still want to do something about stencil -> alpha. - ApplyStencilReplaceAndLogicOp(replaceAlphaWithStencil, blendState); + ApplyStencilReplaceAndLogicOpIgnoreBlend(replaceAlphaWithStencil, blendState); return; case REPLACE_BLEND_COPY_FBO: diff --git a/GPU/Common/GPUStateUtils.h b/GPU/Common/GPUStateUtils.h index a9c2a7f83119..928570206637 100644 --- a/GPU/Common/GPUStateUtils.h +++ b/GPU/Common/GPUStateUtils.h @@ -158,7 +158,7 @@ struct GenericBlendState { }; void ConvertBlendState(GenericBlendState &blendState, bool allowShaderBlend); -void ApplyStencilReplaceAndLogicOp(ReplaceAlphaType replaceAlphaWithStencil, GenericBlendState &blendState); +void ApplyStencilReplaceAndLogicOpIgnoreBlend(ReplaceAlphaType replaceAlphaWithStencil, GenericBlendState &blendState); struct GenericStencilFuncState { bool enabled; diff --git a/GPU/Common/ShaderId.cpp b/GPU/Common/ShaderId.cpp index e7d48ac7893e..f69e52390082 100644 --- a/GPU/Common/ShaderId.cpp +++ b/GPU/Common/ShaderId.cpp @@ -240,6 +240,8 @@ void ComputeFragmentShaderID(FShaderID *id_out, const Draw::Bugs &bugs) { bool doFlatShading = gstate.getShadeMode() == GE_SHADE_FLAT; bool useShaderDepal = gstate_c.useShaderDepal; + // 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()); ReplaceAlphaType stencilToAlpha = ReplaceAlphaWithStencil(replaceBlend); diff --git a/GPU/D3D11/StateMappingD3D11.cpp b/GPU/D3D11/StateMappingD3D11.cpp index 1529ae9b542e..f5908923c2ec 100644 --- a/GPU/D3D11/StateMappingD3D11.cpp +++ b/GPU/D3D11/StateMappingD3D11.cpp @@ -160,14 +160,14 @@ void DrawEngineD3D11::ApplyDrawState(int prim) { ConvertBlendState(blendState, gstate_c.allowFramebufferRead); if (blendState.applyFramebufferRead) { if (ApplyFramebufferRead(&fboTexNeedsBind_)) { - // We may still want to do something about stencil -> alpha. - ApplyStencilReplaceAndLogicOp(blendState.replaceAlphaWithStencil, blendState); + // We take over the responsiblity for blending, so recompute. + ApplyStencilReplaceAndLogicOpIgnoreBlend(blendState.replaceAlphaWithStencil, blendState); } else { // Until next time, force it off. ResetFramebufferRead(); gstate_c.SetAllowFramebufferRead(false); - gstate_c.Dirty(DIRTY_FRAGMENTSHADER_STATE); } + gstate_c.Dirty(DIRTY_FRAGMENTSHADER_STATE); } else if (blendState.resetFramebufferRead) { ResetFramebufferRead(); } diff --git a/GPU/Directx9/StateMappingDX9.cpp b/GPU/Directx9/StateMappingDX9.cpp index ee496b17b698..f1cc732a5f57 100644 --- a/GPU/Directx9/StateMappingDX9.cpp +++ b/GPU/Directx9/StateMappingDX9.cpp @@ -131,8 +131,8 @@ void DrawEngineDX9::ApplyDrawState(int prim) { if (blendState.applyFramebufferRead) { if (ApplyFramebufferRead(&fboTexNeedsBind_)) { - // We may still want to do something about stencil -> alpha. - ApplyStencilReplaceAndLogicOp(blendState.replaceAlphaWithStencil, blendState); + // We take over the responsiblity for blending, so recompute. + ApplyStencilReplaceAndLogicOpIgnoreBlend(blendState.replaceAlphaWithStencil, blendState); } else { // Until next time, force it off. ResetFramebufferRead(); diff --git a/GPU/GLES/StateMappingGLES.cpp b/GPU/GLES/StateMappingGLES.cpp index 2b6f0e39f8f5..572b2103d2a2 100644 --- a/GPU/GLES/StateMappingGLES.cpp +++ b/GPU/GLES/StateMappingGLES.cpp @@ -171,8 +171,8 @@ void DrawEngineGLES::ApplyDrawState(int prim) { if (blendState.applyFramebufferRead) { if (ApplyFramebufferRead(&fboTexNeedsBind_)) { - // We may still want to do something about stencil -> alpha. - ApplyStencilReplaceAndLogicOp(blendState.replaceAlphaWithStencil, blendState); + // We take over the responsiblity for blending, so recompute. + ApplyStencilReplaceAndLogicOpIgnoreBlend(blendState.replaceAlphaWithStencil, blendState); // We copy the framebuffer here, as doing so will wipe any blend state if we do it later. if (fboTexNeedsBind_) { diff --git a/GPU/Vulkan/StateMappingVulkan.cpp b/GPU/Vulkan/StateMappingVulkan.cpp index 9fbb9b202b70..9be12976e19d 100644 --- a/GPU/Vulkan/StateMappingVulkan.cpp +++ b/GPU/Vulkan/StateMappingVulkan.cpp @@ -167,15 +167,15 @@ void DrawEngineVulkan::ConvertStateToVulkanKey(FramebufferManagerVulkan &fbManag if (blendState.applyFramebufferRead) { if (ApplyFramebufferRead(&fboTexNeedsBind_)) { - // We may still want to do something about stencil -> alpha. - ApplyStencilReplaceAndLogicOp(blendState.replaceAlphaWithStencil, blendState); + // We take over the responsiblity for blending, so recompute. + ApplyStencilReplaceAndLogicOpIgnoreBlend(blendState.replaceAlphaWithStencil, blendState); } else { // Until next time, force it off. ResetFramebufferRead(); gstate_c.SetAllowFramebufferRead(false); // Make sure we recompute the fragment shader ID to one that doesn't try to use shader blending. - gstate_c.Dirty(DIRTY_FRAGMENTSHADER_STATE); } + gstate_c.Dirty(DIRTY_FRAGMENTSHADER_STATE); } else if (blendState.resetFramebufferRead) { ResetFramebufferRead(); } From 3e06eaccfb18f4f2c04d67006018e067b188e85f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sun, 8 Nov 2020 14:57:35 +0100 Subject: [PATCH 5/6] Fix some comments --- GPU/D3D11/StateMappingD3D11.cpp | 2 +- GPU/Directx9/StateMappingDX9.cpp | 2 +- GPU/GLES/StateMappingGLES.cpp | 2 +- GPU/Vulkan/StateMappingVulkan.cpp | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/GPU/D3D11/StateMappingD3D11.cpp b/GPU/D3D11/StateMappingD3D11.cpp index f5908923c2ec..6329495c8c5c 100644 --- a/GPU/D3D11/StateMappingD3D11.cpp +++ b/GPU/D3D11/StateMappingD3D11.cpp @@ -160,7 +160,7 @@ void DrawEngineD3D11::ApplyDrawState(int prim) { ConvertBlendState(blendState, gstate_c.allowFramebufferRead); if (blendState.applyFramebufferRead) { if (ApplyFramebufferRead(&fboTexNeedsBind_)) { - // We take over the responsiblity for blending, so recompute. + // The shader takes over the responsibility for blending, so recompute. ApplyStencilReplaceAndLogicOpIgnoreBlend(blendState.replaceAlphaWithStencil, blendState); } else { // Until next time, force it off. diff --git a/GPU/Directx9/StateMappingDX9.cpp b/GPU/Directx9/StateMappingDX9.cpp index f1cc732a5f57..99f8860f28dc 100644 --- a/GPU/Directx9/StateMappingDX9.cpp +++ b/GPU/Directx9/StateMappingDX9.cpp @@ -131,7 +131,7 @@ void DrawEngineDX9::ApplyDrawState(int prim) { if (blendState.applyFramebufferRead) { if (ApplyFramebufferRead(&fboTexNeedsBind_)) { - // We take over the responsiblity for blending, so recompute. + // The shader takes over the responsibility for blending, so recompute. ApplyStencilReplaceAndLogicOpIgnoreBlend(blendState.replaceAlphaWithStencil, blendState); } else { // Until next time, force it off. diff --git a/GPU/GLES/StateMappingGLES.cpp b/GPU/GLES/StateMappingGLES.cpp index 572b2103d2a2..43f9629f7e32 100644 --- a/GPU/GLES/StateMappingGLES.cpp +++ b/GPU/GLES/StateMappingGLES.cpp @@ -171,7 +171,7 @@ void DrawEngineGLES::ApplyDrawState(int prim) { if (blendState.applyFramebufferRead) { if (ApplyFramebufferRead(&fboTexNeedsBind_)) { - // We take over the responsiblity for blending, so recompute. + // The shader takes over the responsibility for blending, so recompute. ApplyStencilReplaceAndLogicOpIgnoreBlend(blendState.replaceAlphaWithStencil, blendState); // We copy the framebuffer here, as doing so will wipe any blend state if we do it later. diff --git a/GPU/Vulkan/StateMappingVulkan.cpp b/GPU/Vulkan/StateMappingVulkan.cpp index 9be12976e19d..4d7c5fec1388 100644 --- a/GPU/Vulkan/StateMappingVulkan.cpp +++ b/GPU/Vulkan/StateMappingVulkan.cpp @@ -167,7 +167,7 @@ void DrawEngineVulkan::ConvertStateToVulkanKey(FramebufferManagerVulkan &fbManag if (blendState.applyFramebufferRead) { if (ApplyFramebufferRead(&fboTexNeedsBind_)) { - // We take over the responsiblity for blending, so recompute. + // The shader takes over the responsibility for blending, so recompute. ApplyStencilReplaceAndLogicOpIgnoreBlend(blendState.replaceAlphaWithStencil, blendState); } else { // Until next time, force it off. From 7391abcfd6f524ada01ff36ddcdae2f6b808ac55 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sun, 8 Nov 2020 14:57:43 +0100 Subject: [PATCH 6/6] Unrelated warning fixes --- ext/native/tools/atlastool.cpp | 14 +++++++------- ext/native/tools/atlastool/atlastool.vcxproj | 6 +++--- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/ext/native/tools/atlastool.cpp b/ext/native/tools/atlastool.cpp index 7403657ece4a..c2a9e1be1d0a 100644 --- a/ext/native/tools/atlastool.cpp +++ b/ext/native/tools/atlastool.cpp @@ -462,8 +462,8 @@ void RasterizeFonts(const FontReferenceList &fontRefs, vector &ranges } else { dist = -closest.find_closest(ctx, cty, 1); } - dist = dist / supersample * distmult + 127.5; - dist = floor(dist + 0.5); + dist = dist / supersample * distmult + 127.5f; + dist = floor(dist + 0.5f); if (dist < 0) dist = 0; if (dist > 255) dist = 255; @@ -564,7 +564,7 @@ struct FontDesc { } } - height = metrics_height / 64.0 / supersample; + height = metrics_height / 64.0f / supersample; } void OutputSelf(FILE *fil, float tw, float th, const vector &results) const { @@ -987,7 +987,7 @@ int main(int argc, char **argv) { fwrite(&header, 1, sizeof(header), meta); // For each image for (int i = 0; i < (int)images.size(); i++) { - AtlasImage atlas_image = images[i].ToAtlasImage(dest.width(), dest.height(), results); + AtlasImage atlas_image = images[i].ToAtlasImage((float)dest.width(), (float)dest.height(), results); fwrite(&atlas_image, 1, sizeof(atlas_image), meta); } // For each font @@ -998,7 +998,7 @@ int main(int argc, char **argv) { fwrite(&font_header, 1, sizeof(font_header), meta); auto ranges = font.GetRanges(); fwrite(ranges.data(), sizeof(AtlasCharRange), ranges.size(), meta); - auto chars = font.GetChars(dest.width(), dest.height(), results); + auto chars = font.GetChars((float)dest.width(), (float)dest.height(), results); fwrite(chars.data(), sizeof(AtlasChar), chars.size(), meta); } fclose(meta); @@ -1010,7 +1010,7 @@ int main(int argc, char **argv) { for (int i = 0; i < (int)fonts.size(); i++) { FontDesc &xfont = fonts[i]; xfont.ComputeHeight(results, distmult); - xfont.OutputSelf(cpp_file, dest.width(), dest.height(), results); + xfont.OutputSelf(cpp_file, (float)dest.width(), (float)dest.height(), results); } if (fonts.size()) { @@ -1024,7 +1024,7 @@ int main(int argc, char **argv) { if (images.size()) { fprintf(cpp_file, "const AtlasImage %s_images[%i] = {\n", atlas_name, (int)images.size()); for (int i = 0; i < (int)images.size(); i++) { - images[i].OutputSelf(cpp_file, dest.width(), dest.height(), results); + images[i].OutputSelf(cpp_file, (float)dest.width(), (float)dest.height(), results); } fprintf(cpp_file, "};\n"); } diff --git a/ext/native/tools/atlastool/atlastool.vcxproj b/ext/native/tools/atlastool/atlastool.vcxproj index afd5ad8b4317..dbbfbfefee20 100644 --- a/ext/native/tools/atlastool/atlastool.vcxproj +++ b/ext/native/tools/atlastool/atlastool.vcxproj @@ -70,7 +70,7 @@ Level3 Disabled true - _DEBUG;_CONSOLE;%(PreprocessorDefinitions) + _CRT_SECURE_NO_WARNINGS;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) true MultiThreadedDebug @@ -90,7 +90,7 @@ true true true - NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + _CRT_SECURE_NO_WARNINGS;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) true ../../../../;../../ext;../../;../../../../ext;../prebuilt MultiThreaded @@ -108,4 +108,4 @@ - + \ No newline at end of file