diff --git a/Core/Compatibility.cpp b/Core/Compatibility.cpp index a9f1a7556e..11233bf1bb 100644 --- a/Core/Compatibility.cpp +++ b/Core/Compatibility.cpp @@ -97,6 +97,7 @@ void Compatibility::CheckSettings(IniFile &iniFile, const std::string &gameID) { CheckSetting(iniFile, gameID, "AtracLoopHack", &flags_.AtracLoopHack); CheckSetting(iniFile, gameID, "DeswizzleDepth", &flags_.DeswizzleDepth); CheckSetting(iniFile, gameID, "SplitFramebufferMargin", &flags_.SplitFramebufferMargin); + CheckSetting(iniFile, gameID, "ForceLowerResolutionForEffectsOn", &flags_.ForceLowerResolutionForEffectsOn); } void Compatibility::CheckSetting(IniFile &iniFile, const std::string &gameID, const char *option, bool *flag) { diff --git a/Core/Compatibility.h b/Core/Compatibility.h index 97f2d48075..9b1dfa5fd7 100644 --- a/Core/Compatibility.h +++ b/Core/Compatibility.h @@ -87,6 +87,7 @@ struct CompatFlags { bool AtracLoopHack; bool DeswizzleDepth; bool SplitFramebufferMargin; + bool ForceLowerResolutionForEffectsOn; }; class IniFile; diff --git a/GPU/Common/FramebufferManagerCommon.cpp b/GPU/Common/FramebufferManagerCommon.cpp index 5a74382fb6..d907f1ac2f 100644 --- a/GPU/Common/FramebufferManagerCommon.cpp +++ b/GPU/Common/FramebufferManagerCommon.cpp @@ -84,14 +84,17 @@ void FramebufferManagerCommon::Init() { bool FramebufferManagerCommon::UpdateSize() { const bool newRender = renderWidth_ != (float)PSP_CoreParameter().renderWidth || renderHeight_ != (float)PSP_CoreParameter().renderHeight; - const bool newSettings = bloomHack_ != g_Config.iBloomHack || useBufferedRendering_ != (g_Config.iRenderingMode != FB_NON_BUFFERED_MODE); + + const int effectiveBloomHack = PSP_CoreParameter().compat.flags().ForceLowerResolutionForEffectsOn ? 3 : g_Config.iBloomHack; + + const bool newSettings = bloomHack_ != effectiveBloomHack || useBufferedRendering_ != (g_Config.iRenderingMode != FB_NON_BUFFERED_MODE); renderWidth_ = (float)PSP_CoreParameter().renderWidth; renderHeight_ = (float)PSP_CoreParameter().renderHeight; renderScaleFactor_ = (float)PSP_CoreParameter().renderScaleFactor; pixelWidth_ = PSP_CoreParameter().pixelWidth; pixelHeight_ = PSP_CoreParameter().pixelHeight; - bloomHack_ = g_Config.iBloomHack; + bloomHack_ = effectiveBloomHack; useBufferedRendering_ = g_Config.iRenderingMode != FB_NON_BUFFERED_MODE; presentation_->UpdateSize(pixelWidth_, pixelHeight_, renderWidth_, renderHeight_); @@ -626,7 +629,7 @@ void FramebufferManagerCommon::CopyToDepthFromOverlappingFramebuffers(VirtualFra BlitUsingRaster( src->fbo, 0.0f, 0.0f, src->renderWidth, src->renderHeight, dest->fbo, 0.0f, 0.0f, src->renderWidth, src->renderHeight, - false, Get2DPipeline(shader), "565_to_depth"); + false, dest->renderScaleFactor, Get2DPipeline(shader), "565_to_depth"); } } @@ -802,7 +805,7 @@ void FramebufferManagerCommon::CopyToColorFromOverlappingFramebuffers(VirtualFra tookActions = true; // OK we have the pipeline, now just do the blit. BlitUsingRaster(src->fbo, 0.0f, 0.0f, srcWidth, srcHeight, - dst->fbo, dstX1, dstY1, dstX2, dstY2, false, pipeline, pass_name); + dst->fbo, dstX1, dstY1, dstX2, dstY2, false, dst->renderScaleFactor, pipeline, pass_name); } } } @@ -886,7 +889,7 @@ void FramebufferManagerCommon::BlitFramebufferDepth(VirtualFramebuffer *src, Vir draw_->BlitFramebuffer(src->fbo, 0, 0, w, h, dst->fbo, 0, 0, w, h, Draw::FB_DEPTH_BIT, Draw::FB_BLIT_NEAREST, "BlitFramebufferDepth"); RebindFramebuffer("After BlitFramebufferDepth"); } else if (useRaster) { - BlitUsingRaster(src->fbo, 0, 0, w, h, dst->fbo, 0, 0, w, h, false, Get2DPipeline(Draw2DShader::DRAW2D_COPY_DEPTH), "BlitDepthRaster"); + BlitUsingRaster(src->fbo, 0, 0, w, h, dst->fbo, 0, 0, w, h, false, dst->renderScaleFactor, Get2DPipeline(Draw2DShader::DRAW2D_COPY_DEPTH), "BlitDepthRaster"); } draw_->InvalidateCachedState(); @@ -2784,10 +2787,10 @@ void FramebufferManagerCommon::BlitFramebuffer(VirtualFramebuffer *dst, int dstX Draw::Framebuffer *srcFBO = src->fbo; if (src == dst) { Draw::Framebuffer *tempFBO = GetTempFBO(TempFBO::BLIT, src->renderWidth, src->renderHeight); - BlitUsingRaster(src->fbo, srcX1, srcY1, srcX2, srcY2, tempFBO, dstX1, dstY1, dstX2, dstY2, false, pipeline, tag); + BlitUsingRaster(src->fbo, srcX1, srcY1, srcX2, srcY2, tempFBO, dstX1, dstY1, dstX2, dstY2, false, dst->renderScaleFactor, pipeline, tag); srcFBO = tempFBO; } - BlitUsingRaster(srcFBO, srcX1, srcY1, srcX2, srcY2, dst->fbo, dstX1, dstY1, dstX2, dstY2, false, pipeline, tag); + BlitUsingRaster(srcFBO, srcX1, srcY1, srcX2, srcY2, dst->fbo, dstX1, dstY1, dstX2, dstY2, false, dst->renderScaleFactor, pipeline, tag); } draw_->InvalidateCachedState(); @@ -2800,6 +2803,7 @@ void FramebufferManagerCommon::BlitUsingRaster( Draw::Framebuffer *src, float srcX1, float srcY1, float srcX2, float srcY2, Draw::Framebuffer *dest, float destX1, float destY1, float destX2, float destY2, bool linearFilter, + int scaleFactor, Draw2DPipeline *pipeline, const char *tag) { if (pipeline->info.writeChannel == RASTER_DEPTH) { @@ -2825,7 +2829,7 @@ void FramebufferManagerCommon::BlitUsingRaster( draw_->SetViewports(1, &vp); draw_->SetScissorRect(0, 0, (int)dest->Width(), (int)dest->Height()); - draw2D_.Blit(pipeline, srcX1, srcY1, srcX2, srcY2, destX1, destY1, destX2, destY2, (float)srcW, (float)srcH, (float)destW, (float)destH, linearFilter , renderScaleFactor_); + draw2D_.Blit(pipeline, srcX1, srcY1, srcX2, srcY2, destX1, destY1, destX2, destY2, (float)srcW, (float)srcH, (float)destW, (float)destH, linearFilter, scaleFactor); gstate_c.Dirty(DIRTY_BLEND_STATE | DIRTY_DEPTHSTENCIL_STATE | DIRTY_RASTER_STATE | DIRTY_VIEWPORTSCISSOR_STATE | DIRTY_VERTEXSHADER_STATE | DIRTY_FRAGMENTSHADER_STATE); } diff --git a/GPU/Common/FramebufferManagerCommon.h b/GPU/Common/FramebufferManagerCommon.h index f78e52d13e..e4e2b86cf6 100644 --- a/GPU/Common/FramebufferManagerCommon.h +++ b/GPU/Common/FramebufferManagerCommon.h @@ -441,7 +441,10 @@ protected: void BlitUsingRaster( Draw::Framebuffer *src, float srcX1, float srcY1, float srcX2, float srcY2, - Draw::Framebuffer *dest, float destX1, float destY1, float destX2, float destY2, bool linearFilter, Draw2DPipeline *pipeline, const char *tag); + Draw::Framebuffer *dest, float destX1, float destY1, float destX2, float destY2, + bool linearFilter, + int scaleFactor, // usually unused, except for swizzle... + Draw2DPipeline *pipeline, const char *tag); void CopyFramebufferForColorTexture(VirtualFramebuffer *dst, VirtualFramebuffer *src, int flags); diff --git a/GPU/Common/TextureCacheCommon.cpp b/GPU/Common/TextureCacheCommon.cpp index 599c39c9db..87c866fa93 100644 --- a/GPU/Common/TextureCacheCommon.cpp +++ b/GPU/Common/TextureCacheCommon.cpp @@ -2348,6 +2348,12 @@ bool TextureCacheCommon::PrepareBuildTexture(BuildTexturePlan &plan, TexCacheEnt plan.scaleFactor = 1; } + if (PSP_CoreParameter().compat.flags().ForceLowerResolutionForEffectsOn && gstate.FrameBufStride() < 0x1E0) { + // A bit of an esoteric workaround - force off upscaling for static textures that participate directly in small-resolution framebuffer effects. + // This fixes the water in Outrun/DiRT 2 with upscaling enabled. + plan.scaleFactor = 1; + } + if ((entry->status & TexCacheEntry::STATUS_CHANGE_FREQUENT) != 0 && plan.scaleFactor != 1 && plan.slowScaler) { // Remember for later that we /wanted/ to scale this texture. entry->status |= TexCacheEntry::STATUS_TO_SCALE; diff --git a/assets/compat.ini b/assets/compat.ini index 4a6dbc6caa..d94f8534ca 100644 --- a/assets/compat.ini +++ b/assets/compat.ini @@ -1269,3 +1269,17 @@ UCUS98646 = true UCET00278 = true UCUS98670 = true UCUS98646 = true + +[ForceLowerResolutionForEffectsOn] +# The water effect of DiRT 2 and Outrun doesn't work in higher resolutions. + +# Colin McRae's DiRT 2 - issue #13012 (water) +ULUS10471 = true +ULJM05533 = true +NPJH50006 = true +ULES01301 = true + +# Outrun 2006: Coast to Coast - issue #11358 (car reflections), #11928 (water) +ULES00262 = true +ULUS10064 = true +ULKS46087 = true