gsdx mipmap:ogl: plug trilinear/mipmap2 option

mipmap option 3. Actually maybe a separate tri-linear option will be better

m_mipmap == 2 => use manual PS2 trilinear/mipmap
Otherwise
m_filter == 3 => always use full automatic trilinear interpolation
m_filter == 4 => use automatic trilinear interpolation when PS2 uses mipmap
m_filter == 5 => like 4 but force bilinear interpolation inside layer
This commit is contained in:
Gregory Hainaut 2016-10-02 10:51:29 +02:00
parent c2777ff989
commit 5ced9c1f19
5 changed files with 50 additions and 10 deletions

View File

@ -75,6 +75,7 @@ GSDeviceOGL::GSDeviceOGL()
GLState::Clear();
m_mipmap = theApp.GetConfigI("mipmap");
m_filter = theApp.GetConfigI("filter");
// Reset the debug file
#ifdef ENABLE_OGL_DEBUG
@ -229,7 +230,7 @@ GSTexture* GSDeviceOGL::CreateSurface(int type, int w, int h, bool msaa, int fmt
// A wrapper to call GSTextureOGL, with the different kind of parameter
GSTextureOGL* t = NULL;
t = new GSTextureOGL(type, w, h, fmt, m_fbo_read, m_mipmap > 1);
t = new GSTextureOGL(type, w, h, fmt, m_fbo_read, m_mipmap > 1 || m_filter > 2);
if (t == NULL) {
throw GSDXErrorOOM();
}

View File

@ -405,6 +405,7 @@ public:
uint32 m_msaa; // Level of Msaa
int m_force_texture_clear;
int m_mipmap;
int m_filter;
static bool m_debug_gl_call;
static FILE* m_debug_gl_file;

View File

@ -478,7 +478,7 @@ void GSRendererDX::DrawPrims(GSTexture* rt, GSTexture* ds, GSTextureCache::Sourc
// After the conversion the texture will be RGBA8 (aka 32 bits) hence the 0 below
int gpu_tex_fmt = (tex->m_target) ? cpsm.fmt : 0;
bool bilinear = m_filter == 2 ? m_vt.IsLinear() : m_filter != 0;
bool bilinear = m_filter == 2 || m_filter == 4 ? m_vt.IsLinear() : m_filter != 0;
bool simple_sample = !tex->m_palette && gpu_tex_fmt == 0 && m_context->CLAMP.WMS < 2 && m_context->CLAMP.WMT < 2;
// Don't force extra filtering on sprite (it creates various upscaling issue)
bilinear &= !((m_vt.m_primclass == GS_SPRITE_CLASS) && m_userhacks_round_sprite_offset && !m_vt.IsLinear());

View File

@ -571,7 +571,7 @@ void GSRendererHW::Draw()
tex = tex_psm.depth ? m_tc->LookupDepthSource(TEX0, env.TEXA, r) : m_tc->LookupSource(TEX0, env.TEXA, r);
// Round 2
if (IsMipMapActive() && m_mipmap > 1 && !tex_psm.depth) {
if (IsMipMapActive() && m_mipmap == 2 && !tex_psm.depth) {
// Upload remaining texture layers
GSVector4 tmin = m_vt.m_min.t;
GSVector4 tmax = m_vt.m_max.t;

View File

@ -747,9 +747,45 @@ void GSRendererOGL::EmulateTextureSampler(const GSTextureCache::Source* tex)
const uint8 wmt = m_context->CLAMP.WMT;
bool complex_wms_wmt = !!((wms | wmt) & 2);
bool mipmap = m_mipmap > 1 && m_context->TEX1.MMIN > 1;
bool bilinear = m_filter == 2 ? m_vt.IsLinear() : m_filter != 0;
bool need_mipmap = IsMipMapDraw();
bool shader_emulated_sampler = tex->m_palette || cpsm.fmt != 0 || complex_wms_wmt || psm.depth;
bool trilinear_manual = need_mipmap && m_mipmap == 2;
bool bilinear = false;
int trilinear = 0;
bool trilinear_auto = false;
switch (m_filter) {
case 0: // Nearest
bilinear = false;
break;
case 1: // Forced Bilinear
bilinear = true;
break;
case 2: // Bilinear PS2
bilinear = m_vt.IsLinear();
break;
case 3: // Trilinear Forced
bilinear = true;
trilinear = static_cast<uint8>(GS_MIN_FILTER::Linear_Mipmap_Linear);
trilinear_auto = m_mipmap != 2;
break;
case 4: // Trilinear
bilinear = m_vt.IsLinear();
if (need_mipmap && m_mipmap != 2) {
trilinear = m_context->TEX1.MMIN;
trilinear_auto = true;
}
break;
case 5: // Trilinear (forced on linear)
bilinear = true;
if (need_mipmap && m_mipmap != 2) {
trilinear = (m_context->TEX1.MMIN | 4) & 0x5;
trilinear_auto = true;
}
default:
break;
}
// Don't force extra filtering on sprite (it creates various upscaling issue)
bilinear &= !((m_vt.m_primclass == GS_SPRITE_CLASS) && m_userhacks_round_sprite_offset && !m_vt.IsLinear());
@ -875,12 +911,14 @@ void GSRendererOGL::EmulateTextureSampler(const GSTextureCache::Source* tex)
if (complex_wms_wmt) {
ps_cb.MskFix = GSVector4i(m_context->CLAMP.MINU, m_context->CLAMP.MINV, m_context->CLAMP.MAXU, m_context->CLAMP.MAXV);
ps_cb.MinMax = GSVector4(ps_cb.MskFix) / WH.xyxy();
} else if (mipmap) {
} else if (trilinear_manual) {
// Reuse MinMax for mipmap parameter to avoid an extension of the UBO
ps_cb.MinMax.x = (float)m_context->TEX1.K / 16.0f;
ps_cb.MinMax.y = float(1 << m_context->TEX1.L);
ps_cb.MinMax.z = float(m_lod.x); // Offset because first layer is m_lod, dunno if we can do better
ps_cb.MinMax.w = float(m_lod.y);
} else if (trilinear_auto) {
tex->m_texture->GenerateMipmap();
}
// TC Offset Hack
@ -898,11 +936,11 @@ void GSRendererOGL::EmulateTextureSampler(const GSTextureCache::Source* tex)
} else {
m_ps_ssel.biln = bilinear;
m_ps_ssel.aniso = 1;
if (mipmap) {
m_ps_ssel.triln = m_context->TEX1.MMIN;
m_ps_ssel.triln = trilinear;
if (trilinear_manual) {
m_ps_sel.manual_lod = 1;
} else {
m_ps_ssel.triln = m_context->TEX1.MMIN & 1;
} else if (trilinear_auto) {
m_ps_sel.automatic_lod = 1;
}
}