diff --git a/GPU/Common/FramebufferManagerCommon.cpp b/GPU/Common/FramebufferManagerCommon.cpp index f097edc0c9..efd16b3966 100644 --- a/GPU/Common/FramebufferManagerCommon.cpp +++ b/GPU/Common/FramebufferManagerCommon.cpp @@ -218,7 +218,7 @@ void GetFramebufferHeuristicInputs(FramebufferHeuristicParams *params, const GPU params->z_stride = 0; } - params->fmt = gstate.FrameBufFormat(); + params->fmt = gstate_c.framebufFormat; params->isClearingDepth = gstate.isModeClear() && gstate.isClearModeDepthMask(); // Technically, it may write depth later, but we're trying to detect it only when it's really true. @@ -672,7 +672,7 @@ void FramebufferManagerCommon::ReinterpretFramebuffer(VirtualFramebuffer *vfb, G draw_->InvalidateCachedState(); draw_->CopyFramebufferImage(vfb->fbo, 0, 0, 0, 0, temp, 0, 0, 0, 0, vfb->renderWidth, vfb->renderHeight, 1, Draw::FBChannel::FB_COLOR_BIT, "reinterpret_prep"); - draw_->BindFramebufferAsRenderTarget(vfb->fbo, { Draw::RPAction::DONT_CARE, Draw::RPAction::DONT_CARE, Draw::RPAction::DONT_CARE }, reinterpretStrings[(int)oldFormat][(int)newFormat]); + draw_->BindFramebufferAsRenderTarget(vfb->fbo, { Draw::RPAction::DONT_CARE, Draw::RPAction::CLEAR, Draw::RPAction::CLEAR }, reinterpretStrings[(int)oldFormat][(int)newFormat]); draw_->BindPipeline(pipeline); draw_->BindFramebufferAsTexture(temp, 0, Draw::FBChannel::FB_COLOR_BIT, 0); draw_->BindSamplerStates(0, 1, &reinterpretSampler_); @@ -1694,12 +1694,12 @@ void FramebufferManagerCommon::ApplyClearToMemory(int x1, int y1, int x2, int y2 } u8 *addr = Memory::GetPointerUnchecked(gstate.getFrameBufAddress()); - const int bpp = gstate.FrameBufFormat() == GE_FORMAT_8888 ? 4 : 2; + const int bpp = gstate_c.framebufFormat == GE_FORMAT_8888 ? 4 : 2; u32 clearBits = clearColor; if (bpp == 2) { u16 clear16 = 0; - switch (gstate.FrameBufFormat()) { + switch (gstate_c.framebufFormat) { case GE_FORMAT_565: clear16 = RGBA8888toRGB565(clearColor); break; case GE_FORMAT_5551: clear16 = RGBA8888toRGBA5551(clearColor); break; case GE_FORMAT_4444: clear16 = RGBA8888toRGBA4444(clearColor); break; diff --git a/GPU/Common/GPUStateUtils.cpp b/GPU/Common/GPUStateUtils.cpp index d3eec7c9ec..5e86033745 100644 --- a/GPU/Common/GPUStateUtils.cpp +++ b/GPU/Common/GPUStateUtils.cpp @@ -38,7 +38,7 @@ bool IsStencilTestOutputDisabled() { // The mask applies on all stencil ops. if (gstate.isStencilTestEnabled() && (gstate.pmska & 0xFF) != 0xFF) { - if (gstate.FrameBufFormat() == GE_FORMAT_565) { + if (gstate_c.framebufFormat == GE_FORMAT_565) { return true; } return gstate.getStencilOpZPass() == GE_STENCILOP_KEEP && gstate.getStencilOpZFail() == GE_STENCILOP_KEEP && gstate.getStencilOpSFail() == GE_STENCILOP_KEEP; @@ -195,7 +195,7 @@ ReplaceAlphaType ReplaceAlphaWithStencil(ReplaceBlendType replaceBlend) { } StencilValueType ReplaceAlphaWithStencilType() { - switch (gstate.FrameBufFormat()) { + switch (gstate_c.framebufFormat) { case GE_FORMAT_565: // There's never a stencil value. Maybe the right alpha is 1? return STENCIL_VALUE_ONE; @@ -236,10 +236,10 @@ StencilValueType ReplaceAlphaWithStencilType() { return STENCIL_VALUE_ZERO; case GE_STENCILOP_DECR: - return gstate.FrameBufFormat() == GE_FORMAT_4444 ? STENCIL_VALUE_DECR_4 : STENCIL_VALUE_DECR_8; + return gstate_c.framebufFormat == GE_FORMAT_4444 ? STENCIL_VALUE_DECR_4 : STENCIL_VALUE_DECR_8; case GE_STENCILOP_INCR: - return gstate.FrameBufFormat() == GE_FORMAT_4444 ? STENCIL_VALUE_INCR_4 : STENCIL_VALUE_INCR_8; + return gstate_c.framebufFormat == GE_FORMAT_4444 ? STENCIL_VALUE_INCR_4 : STENCIL_VALUE_INCR_8; case GE_STENCILOP_INVERT: return STENCIL_VALUE_INVERT; @@ -1049,7 +1049,7 @@ void ConvertBlendState(GenericBlendState &blendState, bool allowFramebufferRead, blendState.useBlendColor = false; blendState.replaceAlphaWithStencil = REPLACE_ALPHA_NO; - ReplaceBlendType replaceBlend = ReplaceBlendWithShader(allowFramebufferRead, gstate.FrameBufFormat()); + ReplaceBlendType replaceBlend = ReplaceBlendWithShader(allowFramebufferRead, gstate_c.framebufFormat); if (forceReplaceBlend) { replaceBlend = REPLACE_BLEND_COPY_FBO; } @@ -1130,7 +1130,7 @@ void ConvertBlendState(GenericBlendState &blendState, bool allowFramebufferRead, bool approxFuncB = false; BlendFactor glBlendFuncB = blendFuncB == GE_DSTBLEND_FIXB ? blendColor2Func(fixB, approxFuncB) : genericBLookup[blendFuncB]; - if (gstate.FrameBufFormat() == GE_FORMAT_565) { + if (gstate_c.framebufFormat == GE_FORMAT_565) { if (blendFuncA == GE_SRCBLEND_DSTALPHA || blendFuncA == GE_SRCBLEND_DOUBLEDSTALPHA) { glBlendFuncA = BlendFactor::ZERO; } @@ -1452,7 +1452,7 @@ void ConvertStencilFuncState(GenericStencilFuncState &state) { state.writeMask = (~gstate.getStencilWriteMask()) & 0xFF; state.enabled = gstate.isStencilTestEnabled(); if (!state.enabled) { - if (gstate.FrameBufFormat() == GE_FORMAT_5551) + if (gstate_c.framebufFormat == GE_FORMAT_5551) ConvertStencilMask5551(state); return; } @@ -1465,7 +1465,7 @@ void ConvertStencilFuncState(GenericStencilFuncState &state) { state.testRef = gstate.getStencilTestRef(); state.testMask = gstate.getStencilTestMask(); - switch (gstate.FrameBufFormat()) { + switch (gstate_c.framebufFormat) { case GE_FORMAT_565: state.writeMask = 0; break; diff --git a/GPU/Common/ShaderId.cpp b/GPU/Common/ShaderId.cpp index 5cdbc17afc..653f171e66 100644 --- a/GPU/Common/ShaderId.cpp +++ b/GPU/Common/ShaderId.cpp @@ -252,7 +252,7 @@ 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()); + ReplaceBlendType replaceBlend = ReplaceBlendWithShader(gstate_c.allowFramebufferRead, gstate_c.framebufFormat); if (colorWriteMask) { replaceBlend = REPLACE_BLEND_COPY_FBO; } diff --git a/GPU/D3D11/DrawEngineD3D11.cpp b/GPU/D3D11/DrawEngineD3D11.cpp index 78dced1b42..8715116b30 100644 --- a/GPU/D3D11/DrawEngineD3D11.cpp +++ b/GPU/D3D11/DrawEngineD3D11.cpp @@ -676,7 +676,7 @@ rotateVBO: uint8_t clearStencil = clearColor >> 24; draw_->Clear(clearFlag, clearColor, clearDepth, clearStencil); - if ((gstate_c.featureFlags & GPU_USE_CLEAR_RAM_HACK) && gstate.isClearModeColorMask() && (gstate.isClearModeAlphaMask() || gstate.FrameBufFormat() == GE_FORMAT_565)) { + if ((gstate_c.featureFlags & GPU_USE_CLEAR_RAM_HACK) && gstate.isClearModeColorMask() && (gstate.isClearModeAlphaMask() || gstate_c.framebufFormat == GE_FORMAT_565)) { int scissorX1 = gstate.getScissorX1(); int scissorY1 = gstate.getScissorY1(); int scissorX2 = gstate.getScissorX2() + 1; diff --git a/GPU/Directx9/DrawEngineDX9.cpp b/GPU/Directx9/DrawEngineDX9.cpp index f627e2fa47..216bc7a8a0 100644 --- a/GPU/Directx9/DrawEngineDX9.cpp +++ b/GPU/Directx9/DrawEngineDX9.cpp @@ -627,7 +627,7 @@ rotateVBO: device_->Clear(0, NULL, mask, SwapRB(clearColor), clearDepth, clearColor >> 24); - if ((gstate_c.featureFlags & GPU_USE_CLEAR_RAM_HACK) && gstate.isClearModeColorMask() && (gstate.isClearModeAlphaMask() || gstate.FrameBufFormat() == GE_FORMAT_565)) { + if ((gstate_c.featureFlags & GPU_USE_CLEAR_RAM_HACK) && gstate.isClearModeColorMask() && (gstate.isClearModeAlphaMask() || gstate_c.framebufFormat == GE_FORMAT_565)) { int scissorX1 = gstate.getScissorX1(); int scissorY1 = gstate.getScissorY1(); int scissorX2 = gstate.getScissorX2() + 1; diff --git a/GPU/GLES/DrawEngineGLES.cpp b/GPU/GLES/DrawEngineGLES.cpp index 275ded02e6..369cc62a02 100644 --- a/GPU/GLES/DrawEngineGLES.cpp +++ b/GPU/GLES/DrawEngineGLES.cpp @@ -436,7 +436,7 @@ void DrawEngineGLES::DoFlush() { render_->Clear(clearColor, clearDepth, clearColor >> 24, target, rgbaMask, vpAndScissor.scissorX, vpAndScissor.scissorY, vpAndScissor.scissorW, vpAndScissor.scissorH); framebufferManager_->SetColorUpdated(gstate_c.skipDrawReason); - if ((gstate_c.featureFlags & GPU_USE_CLEAR_RAM_HACK) && colorMask && (alphaMask || gstate.FrameBufFormat() == GE_FORMAT_565)) { + if ((gstate_c.featureFlags & GPU_USE_CLEAR_RAM_HACK) && colorMask && (alphaMask || gstate_c.framebufFormat == GE_FORMAT_565)) { int scissorX1 = gstate.getScissorX1(); int scissorY1 = gstate.getScissorY1(); int scissorX2 = gstate.getScissorX2() + 1; diff --git a/GPU/GPUCommon.cpp b/GPU/GPUCommon.cpp index 14a2f6e9c6..307870a228 100644 --- a/GPU/GPUCommon.cpp +++ b/GPU/GPUCommon.cpp @@ -1633,6 +1633,10 @@ void GPUCommon::Execute_Prim(u32 op, u32 diff) { return; } + // Update cached framebuffer format. + // We store it in the cache so it can be modified for blue-to-alpha, next. + gstate_c.framebufFormat = gstate.FrameBufFormat(); + // This also makes skipping drawing very effective. framebufferManager_->SetRenderFrameBuffer(gstate_c.IsDirty(DIRTY_FRAMEBUF), gstate_c.skipDrawReason); @@ -2897,7 +2901,7 @@ bool GPUCommon::PerformStencilUpload(u32 dest, int size) { bool GPUCommon::GetCurrentFramebuffer(GPUDebugBuffer &buffer, GPUDebugFramebufferType type, int maxRes) { u32 fb_address = type == GPU_DBG_FRAMEBUF_RENDER ? (gstate.getFrameBufRawAddress() | 0x04000000) : framebufferManager_->DisplayFramebufAddr(); int fb_stride = type == GPU_DBG_FRAMEBUF_RENDER ? gstate.FrameBufStride() : framebufferManager_->DisplayFramebufStride(); - GEBufferFormat format = type == GPU_DBG_FRAMEBUF_RENDER ? gstate.FrameBufFormat() : framebufferManager_->DisplayFramebufFormat(); + GEBufferFormat format = type == GPU_DBG_FRAMEBUF_RENDER ? gstate_c.framebufFormat : framebufferManager_->DisplayFramebufFormat(); return framebufferManager_->GetFramebuffer(fb_address, fb_stride, format, buffer, maxRes); } diff --git a/GPU/GPUState.h b/GPU/GPUState.h index 6b8f20fa8a..181f8129c1 100644 --- a/GPU/GPUState.h +++ b/GPU/GPUState.h @@ -593,6 +593,8 @@ struct GPUStateCache { KnownVertexBounds vertBounds; + GEBufferFormat framebufFormat; + // TODO: These should be accessed from the current VFB object directly. u32 curRTWidth; u32 curRTHeight; diff --git a/GPU/Vulkan/StateMappingVulkan.cpp b/GPU/Vulkan/StateMappingVulkan.cpp index 56ef6941bd..ef04d92dac 100644 --- a/GPU/Vulkan/StateMappingVulkan.cpp +++ b/GPU/Vulkan/StateMappingVulkan.cpp @@ -367,7 +367,7 @@ void DrawEngineVulkan::ConvertStateToVulkanKey(FramebufferManagerVulkan &fbManag } void DrawEngineVulkan::BindShaderBlendTex() { - // TODO: At this point, we know if the vertices are full alpha or not. + // TODO: At this point, we know if the vertices are full alpha or not. // Set the nearest/linear here (since we correctly know if alpha/color tests are needed)? if (!gstate.isModeClear()) { if (fboTexNeedsBind_) {