From 49b3acea72a4c2a37811a4616cb2d940355b6952 Mon Sep 17 00:00:00 2001 From: gabest11 Date: Wed, 5 Aug 2015 19:10:55 +0200 Subject: [PATCH] gsdx: texture size reduction in sw mode, fixes Stolen, less memory usage in general. --- plugins/GSdx/GSDrawingContext.cpp | 116 +++++++++++++++++++++++ plugins/GSdx/GSDrawingContext.h | 82 +--------------- plugins/GSdx/GSRendererHW.cpp | 3 +- plugins/GSdx/GSRendererSW.cpp | 2 +- plugins/GSdx/GSState.cpp | 5 +- plugins/GSdx/GSdx_vs2013.vcxproj | 1 + plugins/GSdx/GSdx_vs2013.vcxproj.filters | 3 + 7 files changed, 128 insertions(+), 84 deletions(-) create mode 100644 plugins/GSdx/GSDrawingContext.cpp diff --git a/plugins/GSdx/GSDrawingContext.cpp b/plugins/GSdx/GSDrawingContext.cpp new file mode 100644 index 0000000000..282928d8f0 --- /dev/null +++ b/plugins/GSdx/GSDrawingContext.cpp @@ -0,0 +1,116 @@ +/* +* Copyright (C) 2007-2009 Gabest +* http://www.gabest.org +* +* This Program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2, or (at your option) +* any later version. +* +* This Program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with GNU Make; see the file COPYING. If not, write to +* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA USA. +* http://www.gnu.org/copyleft/gpl.html +* +*/ + +#include "stdafx.h" +#include "GSDrawingContext.h" +#include "GSdx.h" + +static int clampuv(int uv, int wm, int minuv, int maxuv) +{ + if(wm == CLAMP_REGION_CLAMP) + { + if(uv < minuv) uv = minuv; + if(uv > maxuv + 1) uv = maxuv + 1; + } + else if(wm == CLAMP_REGION_REPEAT) + { + uv = maxuv + (minuv + 1); // cannot determine safely, just use offset + mask + 1 + } + + return uv; +} + +static int reduce(int uv, int size) +{ + while(size > 3 && (1 << (size - 1)) >= uv) + { + size--; + } + + return size; +} + +static int extend(int uv, int size) +{ + while(size < 10 && (1 << size) < uv) + { + size++; + } + + return size; +} + +GIFRegTEX0 GSDrawingContext::GetSizeFixedTEX0(const GSVector4i& uvmax, bool mipmap) +{ + if(mipmap) return TEX0; // no mipmaping allowed + + // find the optimal value for TW/TH by analyzing vertex trace and clamping values, extending only for region modes where uv may be outside + + int tw = TEX0.TW; + int th = TEX0.TH; + + int wms = (int)CLAMP.WMS; + int wmt = (int)CLAMP.WMT; + + int minu = (int)CLAMP.MINU; + int minv = (int)CLAMP.MINV; + int maxu = (int)CLAMP.MAXU; + int maxv = (int)CLAMP.MAXV; + + GSVector4i uv = uvmax; + + uv.x = clampuv(uv.x, wms, minu, maxu); + uv.y = clampuv(uv.y, wmt, minv, maxv); + + if(tw + th >= 19) // smaller sizes aren't worth, they just create multiple entries in the textue cache and the saved memory is less + { + tw = reduce(uv.x, tw); + th = reduce(uv.y, th); + } + + if(wms == CLAMP_REGION_CLAMP || wms == CLAMP_REGION_REPEAT) + { + tw = extend(uv.x, tw); + } + + if(wmt == CLAMP_REGION_CLAMP || wmt == CLAMP_REGION_REPEAT) + { + th = extend(uv.y, th); + } + +#ifdef _DEBUG + if(TEX0.TW != tw || TEX0.TH != th) + { + printf("FixedTEX0 %05x %d %d tw %d=>%d th %d=>%d uvmax %d,%d wm %d,%d (%d,%d,%d,%d)\n", + (int)TEX0.TBP0, (int)TEX0.TBW, (int)TEX0.PSM, + (int)TEX0.TW, tw, (int)TEX0.TH, th, + uv.x, uv.y, + wms, wmt, minu, maxu, minv, maxv); + } +#endif + + GIFRegTEX0 res = TEX0; + + res.TW = tw; + res.TH = th; + + return res; +} diff --git a/plugins/GSdx/GSDrawingContext.h b/plugins/GSdx/GSDrawingContext.h index 7f76434278..3b2041b52d 100644 --- a/plugins/GSdx/GSDrawingContext.h +++ b/plugins/GSdx/GSDrawingContext.h @@ -125,87 +125,7 @@ public: return ZBUF.ZMSK == 0 && TEST.ZTE != 0; // ZTE == 0 is bug on the real hardware, write is blocked then } - GIFRegTEX0 GetSizeFixedTEX0(const GSVector4i& uvmax, bool mipmap) - { - // find max value for TW/TH by analyzing vertex trace and clamp values, only for region clamp modes, no mipmaping allowed - - if(mipmap) return TEX0; - - int tw = TEX0.TW; - int th = TEX0.TH; - - int wms = (int)CLAMP.WMS; - int wmt = (int)CLAMP.WMT; - - int minu = (int)CLAMP.MINU; - int minv = (int)CLAMP.MINV; - int maxu = (int)CLAMP.MAXU; - int maxv = (int)CLAMP.MAXV; - - GSVector4i uv = uvmax;// GSVector4i(m_vt.m_max.t.ceil()); - - if(wms == CLAMP_REGION_CLAMP) - { - int x = uv.x; - - if(x < minu) x = minu; - if(x > maxu + 1) x = maxu + 1; - - while(tw < 10 && (1 << tw) < x) - { - tw++; - } - } - else if(wms == CLAMP_REGION_REPEAT) - { - int x = maxu + (minu + 1); - - while(tw < 10 && (1 << tw) < x) - { - tw++; - } - } - - if(wmt == CLAMP_REGION_CLAMP) - { - int y = uv.y; - - if(y < minv) y = minv; - if(y > maxv + 1) y = maxv + 1; - - while(th < 10 && (1 << th) < y) - { - th++; - } - } - else if(wmt == CLAMP_REGION_REPEAT) - { - int y = maxv + (minv + 1); - - while(th < 10 && (1 << th) < y) - { - th++; - } - } - -#ifdef _DEBUG - if(TEX0.TW != tw || TEX0.TH != th) - { - printf("FixedTEX0 %05x %d %d tw %d=>%d th %d=>%d uvmax %d,%d wm %d,%d (%d,%d,%d,%d)\n", - (int)TEX0.TBP0, (int)TEX0.TBW, (int)TEX0.PSM, - (int)TEX0.TW, tw, (int)TEX0.TH, th, - uv.x, uv.y, - wms, wmt, minu, maxu, minv, maxv); - } -#endif - - GIFRegTEX0 res = TEX0; - - res.TW = tw; - res.TH = th; - - return res; - } + GIFRegTEX0 GetSizeFixedTEX0(const GSVector4i& uvmax, bool mipmap); void Dump(const std::string& filename) { diff --git a/plugins/GSdx/GSRendererHW.cpp b/plugins/GSdx/GSRendererHW.cpp index 1a6fbe8fca..cee65ecc85 100644 --- a/plugins/GSdx/GSRendererHW.cpp +++ b/plugins/GSdx/GSRendererHW.cpp @@ -599,7 +599,8 @@ void GSRendererHW::Draw() s_n++; - if ((s_n - s_saven) > s_savel) { + if(s_savel > 0 && (s_n - s_saven) > s_savel) + { s_dump = 0; } #ifdef ENABLE_OGL_DEBUG diff --git a/plugins/GSdx/GSRendererSW.cpp b/plugins/GSdx/GSRendererSW.cpp index 44bde051a1..e2f45df581 100644 --- a/plugins/GSdx/GSRendererSW.cpp +++ b/plugins/GSdx/GSRendererSW.cpp @@ -600,7 +600,7 @@ void GSRendererSW::Draw() s_n++; - if((s_n - s_saven) > s_savel) + if(s_savel > 0 && (s_n - s_saven) > s_savel) { s_dump = 0; } diff --git a/plugins/GSdx/GSState.cpp b/plugins/GSdx/GSState.cpp index f14186b3cf..8c00945f68 100644 --- a/plugins/GSdx/GSState.cpp +++ b/plugins/GSdx/GSState.cpp @@ -69,7 +69,8 @@ GSState::GSState() //s_savez = 1; //s_savet = 1; //s_savef = 1; - //s_saven = 656; + //s_saven = 0; + //s_savel = 0; UserHacks_WildHack = !!theApp.GetConfig("UserHacks", 0) ? theApp.GetConfig("UserHacks_WildHack", 0) : 0; m_crc_hack_level = theApp.GetConfig("crc_hack_level", 3); @@ -2644,6 +2645,8 @@ __forceinline void GSState::VertexKick(uint32 skip) void GSState::GetTextureMinMax(GSVector4i& r, const GIFRegTEX0& TEX0, const GIFRegCLAMP& CLAMP, bool linear) { + // TODO: some of the +1s can be removed if linear == false + int tw = TEX0.TW; int th = TEX0.TH; diff --git a/plugins/GSdx/GSdx_vs2013.vcxproj b/plugins/GSdx/GSdx_vs2013.vcxproj index 5a19d0e464..fa8435df60 100644 --- a/plugins/GSdx/GSdx_vs2013.vcxproj +++ b/plugins/GSdx/GSdx_vs2013.vcxproj @@ -604,6 +604,7 @@ + diff --git a/plugins/GSdx/GSdx_vs2013.vcxproj.filters b/plugins/GSdx/GSdx_vs2013.vcxproj.filters index 6e34f020dd..a150df0c37 100644 --- a/plugins/GSdx/GSdx_vs2013.vcxproj.filters +++ b/plugins/GSdx/GSdx_vs2013.vcxproj.filters @@ -351,6 +351,9 @@ Source Files + + Source Files +