gsdx: eliminated a few bugs in the texture size changer algorithm

This commit is contained in:
gabest11 2015-08-07 02:08:03 +02:00
parent 241367ec5c
commit d826d925db
5 changed files with 36 additions and 21 deletions

View File

@ -23,16 +23,30 @@
#include "GSDrawingContext.h" #include "GSDrawingContext.h"
#include "GSdx.h" #include "GSdx.h"
static int clampuv(int uv, int wm, int minuv, int maxuv) static int findmax(int tl, int br, int limit, int wm, int minuv, int maxuv)
{ {
if(wm == CLAMP_REGION_CLAMP) // return max possible texcoord
int uv = br;
if(wm == CLAMP_CLAMP)
{
if(uv > limit) uv = limit;
}
else if(wm == CLAMP_REPEAT)
{
if(tl < 0) uv = limit; // wrap around
else if(uv > limit) uv = limit;
}
else if(wm == CLAMP_REGION_CLAMP)
{ {
if(uv < minuv) uv = minuv; if(uv < minuv) uv = minuv;
if(uv > maxuv + 1) uv = maxuv + 1; if(uv > maxuv) uv = maxuv;
} }
else if(wm == CLAMP_REGION_REPEAT) else if(wm == CLAMP_REGION_REPEAT)
{ {
uv = maxuv + (minuv + 1); // cannot determine safely, just use offset + mask + 1 if(tl < 0) uv = minuv | maxuv; // wrap around, just use (any & mask) | fix
else uv = std::min(uv, minuv) | maxuv; // (any & mask) cannot be larger than mask, select br if that is smaller (not br & mask because there might be a larger value between tl and br when &'ed with the mask)
} }
return uv; return uv;
@ -40,7 +54,7 @@ static int clampuv(int uv, int wm, int minuv, int maxuv)
static int reduce(int uv, int size) static int reduce(int uv, int size)
{ {
while(size > 3 && (1 << (size - 1)) >= uv) while(size > 3 && (1 << (size - 1)) >= uv + 1)
{ {
size--; size--;
} }
@ -50,7 +64,7 @@ static int reduce(int uv, int size)
static int extend(int uv, int size) static int extend(int uv, int size)
{ {
while(size < 10 && (1 << size) < uv) while(size < 10 && (1 << size) < uv + 1)
{ {
size++; size++;
} }
@ -58,7 +72,7 @@ static int extend(int uv, int size)
return size; return size;
} }
GIFRegTEX0 GSDrawingContext::GetSizeFixedTEX0(const GSVector4i& uvmax, bool mipmap) GIFRegTEX0 GSDrawingContext::GetSizeFixedTEX0(const GSVector4& st, bool linear, bool mipmap)
{ {
if(mipmap) return TEX0; // no mipmaping allowed if(mipmap) return TEX0; // no mipmaping allowed
@ -75,10 +89,17 @@ GIFRegTEX0 GSDrawingContext::GetSizeFixedTEX0(const GSVector4i& uvmax, bool mipm
int maxu = (int)CLAMP.MAXU; int maxu = (int)CLAMP.MAXU;
int maxv = (int)CLAMP.MAXV; int maxv = (int)CLAMP.MAXV;
GSVector4i uv = uvmax; GSVector4 uvf = st;
uv.x = clampuv(uv.x, wms, minu, maxu); if(linear)
uv.y = clampuv(uv.y, wmt, minv, maxv); {
uvf += GSVector4(-0.5f, 0.5f).xxyy();
}
GSVector4i uv = GSVector4i(uvf.floor());
uv.x = findmax(uv.x, uv.z, (1 << tw) - 1, wms, minu, maxu);
uv.y = findmax(uv.y, uv.w, (1 << th) - 1, 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 if(tw + th >= 19) // smaller sizes aren't worth, they just create multiple entries in the textue cache and the saved memory is less
{ {
@ -99,9 +120,10 @@ GIFRegTEX0 GSDrawingContext::GetSizeFixedTEX0(const GSVector4i& uvmax, bool mipm
#ifdef _DEBUG #ifdef _DEBUG
if(TEX0.TW != tw || TEX0.TH != th) 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", printf("FixedTEX0 %05x %d %d tw %d=>%d th %d=>%d st (%.0f,%.0f,%.0f,%.0f) uvmax %d,%d wm %d,%d (%d,%d,%d,%d)\n",
(int)TEX0.TBP0, (int)TEX0.TBW, (int)TEX0.PSM, (int)TEX0.TBP0, (int)TEX0.TBW, (int)TEX0.PSM,
(int)TEX0.TW, tw, (int)TEX0.TH, th, (int)TEX0.TW, tw, (int)TEX0.TH, th,
uvf.x, uvf.y, uvf.z, uvf.w,
uv.x, uv.y, uv.x, uv.y,
wms, wmt, minu, maxu, minv, maxv); wms, wmt, minu, maxu, minv, maxv);
} }

View File

@ -125,7 +125,7 @@ public:
return ZBUF.ZMSK == 0 && TEST.ZTE != 0; // ZTE == 0 is bug on the real hardware, write is blocked then 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); GIFRegTEX0 GetSizeFixedTEX0(const GSVector4& st, bool linear, bool mipmap);
void Dump(const std::string& filename) void Dump(const std::string& filename)
{ {

View File

@ -26,9 +26,6 @@
#include "GSVector.h" #include "GSVector.h"
#include "GSBlock.h" #include "GSBlock.h"
#include "GSClut.h" #include "GSClut.h"
#ifndef _CX11_
#include "GSThread.h"
#endif
class GSOffset : public GSAlignedClass<32> class GSOffset : public GSAlignedClass<32>
{ {

View File

@ -1440,11 +1440,9 @@ bool GSRendererCL::SetupParameter(TFXJob* job, TFXParameter* pb, GSVertexCL* ver
sel.tfx = TFX_DECAL; sel.tfx = TFX_DECAL;
} }
GSVector4i uvmax = GSVector4i(m_vt.m_max.t.ceil());
bool mipmap = IsMipMapActive(); bool mipmap = IsMipMapActive();
GIFRegTEX0 TEX0 = m_context->GetSizeFixedTEX0(uvmax, mipmap); GIFRegTEX0 TEX0 = m_context->GetSizeFixedTEX0(m_vt.m_min.t.xyxy(m_vt.m_max.t), m_vt.IsLinear(), mipmap);
GSVector4i r; GSVector4i r;

View File

@ -1121,11 +1121,9 @@ bool GSRendererSW::GetScanlineGlobalData(SharedData* data)
gd.sel.tfx = TFX_DECAL; gd.sel.tfx = TFX_DECAL;
} }
GSVector4i uvmax = GSVector4i(m_vt.m_max.t.ceil());
bool mipmap = IsMipMapActive(); bool mipmap = IsMipMapActive();
GIFRegTEX0 TEX0 = m_context->GetSizeFixedTEX0(uvmax, mipmap); GIFRegTEX0 TEX0 = m_context->GetSizeFixedTEX0(m_vt.m_min.t.xyxy(m_vt.m_max.t), m_vt.IsLinear(), mipmap);
GSVector4i r; GSVector4i r;