gsdx mipmap:HW: save state of both min&max lod values

This commit is contained in:
Gregory Hainaut 2016-10-01 17:37:55 +02:00
parent 15b1d8d3f0
commit 5d593dd948
2 changed files with 22 additions and 15 deletions

View File

@ -31,6 +31,7 @@ GSRendererHW::GSRendererHW(GSTextureCache* tc)
, m_upscale_multiplier(1) , m_upscale_multiplier(1)
, m_tc(tc) , m_tc(tc)
, m_channel_shuffle(false) , m_channel_shuffle(false)
, m_lod(GSVector2i(0,0))
{ {
m_upscale_multiplier = theApp.GetConfigI("upscale_multiplier"); m_upscale_multiplier = theApp.GetConfigI("upscale_multiplier");
m_large_framebuffer = theApp.GetConfigB("large_framebuffer"); m_large_framebuffer = theApp.GetConfigB("large_framebuffer");
@ -492,14 +493,14 @@ void GSRendererHW::Draw()
if(PRIM->TME) if(PRIM->TME)
{ {
int lod = 0;
GIFRegCLAMP MIP_CLAMP = context->CLAMP; GIFRegCLAMP MIP_CLAMP = context->CLAMP;
int mxl = std::min<int>((int)m_context->TEX1.MXL, 6);
m_lod = GSVector2i(0, 0);
// Code from the SW renderer // Code from the SW renderer
if (IsMipMapActive()) { if (IsMipMapActive()) {
int interpolation = (context->TEX1.MMIN & 1) + 1; // 1: round, 2: tri int interpolation = (context->TEX1.MMIN & 1) + 1; // 1: round, 2: tri
int mxl = std::min<int>((int)m_context->TEX1.MXL, 6);
int k = (m_context->TEX1.K + 8) >> 4; int k = (m_context->TEX1.K + 8) >> 4;
int lcm = m_context->TEX1.LCM; int lcm = m_context->TEX1.LCM;
@ -516,43 +517,47 @@ void GSRendererHW::Draw()
} }
if (lcm == 1) { if (lcm == 1) {
lod = std::max<int>(k, 0); m_lod.x = std::max<int>(k, 0);
m_lod.y = m_lod.x;
} else { } else {
// Not constant but who care ! // Not constant but who care !
if (interpolation == 2) { if (interpolation == 2) {
// Mipmap Linear. Both layers are sampled, only take the big one // Mipmap Linear. Both layers are sampled, only take the big one
lod = std::max<int>((int)floor(m_vt.m_lod.x), 0); m_lod.x = std::max<int>((int)floor(m_vt.m_lod.x), 0);
} else { } else {
// On GS lod is a fixed float number 7:4 (4 bit for the frac part) // On GS lod is a fixed float number 7:4 (4 bit for the frac part)
#if 0 #if 0
lod = std::max<int>((int)round(m_vt.m_lod.x + 0.0625), 0); m_lod.x = std::max<int>((int)round(m_vt.m_lod.x + 0.0625), 0);
#else #else
// Same as above with a bigger margin on rounding // Same as above with a bigger margin on rounding
// The goal is to avoid 1 undrawn pixels around the edge which trigger the load of the big // The goal is to avoid 1 undrawn pixels around the edge which trigger the load of the big
// layer. // layer.
if (ceil(m_vt.m_lod.x) < m_vt.m_lod.y) if (ceil(m_vt.m_lod.x) < m_vt.m_lod.y)
lod = std::max<int>((int)round(m_vt.m_lod.x + 0.0625 + 0.01), 0); m_lod.x = std::max<int>((int)round(m_vt.m_lod.x + 0.0625 + 0.01), 0);
else else
lod = std::max<int>((int)round(m_vt.m_lod.x + 0.0625), 0); m_lod.x = std::max<int>((int)round(m_vt.m_lod.x + 0.0625), 0);
#endif #endif
} }
m_lod.y = std::max<int>((int)ceil(m_vt.m_lod.y), 0);
} }
lod = std::min<int>(lod, mxl); m_lod.x = std::min<int>(m_lod.x, mxl);
m_lod.y = std::min<int>(m_lod.y, mxl);
TEX0 = GetTex0Layer(lod); TEX0 = GetTex0Layer(m_lod.x);
MIP_CLAMP.MINU >>= lod; MIP_CLAMP.MINU >>= m_lod.x;
MIP_CLAMP.MINV >>= lod; MIP_CLAMP.MINV >>= m_lod.x;
MIP_CLAMP.MAXU >>= lod; MIP_CLAMP.MAXU >>= m_lod.x;
MIP_CLAMP.MAXV >>= lod; MIP_CLAMP.MAXV >>= m_lod.x;
for (int i = 0; i < lod; i++) { for (int i = 0; i < m_lod.x; i++) {
m_vt.m_min.t *= 0.5f; m_vt.m_min.t *= 0.5f;
m_vt.m_max.t *= 0.5f; m_vt.m_max.t *= 0.5f;
} }
GL_CACHE("Mipmap LOD %d (%f %f) new size %dx%d", lod, m_vt.m_lod.x, m_vt.m_lod.y, 1 << TEX0.TW, 1 << TEX0.TH); GL_CACHE("Mipmap LOD %d %d (%f %f) new size %dx%d (K %d L %u)", m_lod.x, m_lod.y, m_vt.m_lod.x, m_vt.m_lod.y, 1 << TEX0.TW, 1 << TEX0.TH, m_context->TEX1.K, m_context->TEX1.L);
} else { } else {
TEX0 = GetTex0Layer(0); TEX0 = GetTex0Layer(0);
} }

View File

@ -154,6 +154,8 @@ protected:
bool m_channel_shuffle; bool m_channel_shuffle;
GSVector2i m_lod; // Min & Max level of detail
public: public:
GSRendererHW(GSTextureCache* tc); GSRendererHW(GSTextureCache* tc);
virtual ~GSRendererHW(); virtual ~GSRendererHW();