mirror of https://github.com/PCSX2/pcsx2.git
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:
parent
c2777ff989
commit
5ced9c1f19
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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());
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue