From a8a2db8eb160712f3e80b8de6a8529b41245dbe4 Mon Sep 17 00:00:00 2001 From: Gregory Hainaut Date: Sat, 1 Oct 2016 17:33:36 +0200 Subject: [PATCH] gsdx mipmap:ogl: extend HW sampler with tri-linear filtering v2: * use nice enum * use bilinear info when there is no mipmap (more accurate) --- plugins/GSdx/GSDeviceOGL.cpp | 52 +++++++++++++++++++++++----------- plugins/GSdx/GSDeviceOGL.h | 8 +++--- plugins/GSdx/GSRendererOGL.cpp | 11 +++++-- 3 files changed, 49 insertions(+), 22 deletions(-) diff --git a/plugins/GSdx/GSDeviceOGL.cpp b/plugins/GSdx/GSDeviceOGL.cpp index c7d4d91d6a..a43874fa37 100644 --- a/plugins/GSdx/GSDeviceOGL.cpp +++ b/plugins/GSdx/GSDeviceOGL.cpp @@ -397,7 +397,7 @@ bool GSDeviceOGL::Create(GSWnd* wnd) m_convert.pt = GetSamplerID(point); PSSamplerSelector bilinear; - bilinear.ltf = true; + bilinear.biln = true; m_convert.ln = GetSamplerID(bilinear); m_convert.dss = new GSDepthStencilOGL(); @@ -563,7 +563,7 @@ void GSDeviceOGL::CreateTextureFX() m_ps_cb = new GSUniformBufferOGL("HW PS UBO", g_ps_cb_index, sizeof(PSConstantBuffer)); // warning 1 sampler by image unit. So you cannot reuse m_ps_ss... - m_palette_ss = CreateSampler(false, false, false); + m_palette_ss = CreateSampler(PSSamplerSelector(0)); glBindSampler(1, m_palette_ss); // Pre compile the (remaining) Geometry & Vertex Shader @@ -801,40 +801,60 @@ void GSDeviceOGL::ClearStencil(GSTexture* t, uint8 c) } GLuint GSDeviceOGL::CreateSampler(PSSamplerSelector sel) -{ - return CreateSampler(sel.ltf, sel.tau, sel.tav, sel.aniso); -} - -GLuint GSDeviceOGL::CreateSampler(bool bilinear, bool tau, bool tav, bool aniso) { GL_PUSH("Create Sampler"); GLuint sampler; glCreateSamplers(1, &sampler); - if (bilinear) { - glSamplerParameteri(sampler, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + + // Bilinear filtering + if (sel.biln) { glSamplerParameteri(sampler, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glSamplerParameteri(sampler, GL_TEXTURE_MIN_FILTER, GL_LINEAR); } else { - glSamplerParameteri(sampler, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glSamplerParameteri(sampler, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glSamplerParameteri(sampler, GL_TEXTURE_MIN_FILTER, GL_NEAREST); } - if (tau) + switch (static_cast(sel.triln)) { + case GS_MIN_FILTER::Nearest: + // Nop based on biln + break; + case GS_MIN_FILTER::Linear: + // Nop based on biln + break; + case GS_MIN_FILTER::Nearest_Mipmap_Nearest: + glSamplerParameteri(sampler, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST); + break; + case GS_MIN_FILTER::Nearest_Mipmap_Linear: + glSamplerParameteri(sampler, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_LINEAR); + break; + case GS_MIN_FILTER::Linear_Mipmap_Nearest: + glSamplerParameteri(sampler, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST); + break; + case GS_MIN_FILTER::Linear_Mipmap_Linear: + glSamplerParameteri(sampler, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); + break; + default: + break; + } + + //glSamplerParameterf(sampler, GL_TEXTURE_MIN_LOD, 0); + //glSamplerParameterf(sampler, GL_TEXTURE_MAX_LOD, 6); + + if (sel.tau) glSamplerParameteri(sampler, GL_TEXTURE_WRAP_S, GL_REPEAT); else glSamplerParameteri(sampler, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - if (tav) + if (sel.tav) glSamplerParameteri(sampler, GL_TEXTURE_WRAP_T, GL_REPEAT); else glSamplerParameteri(sampler, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glSamplerParameteri(sampler, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE); - glSamplerParameterf(sampler, GL_TEXTURE_MIN_LOD, 0); - glSamplerParameterf(sampler, GL_TEXTURE_MAX_LOD, 6); - int anisotropy = theApp.GetConfigI("MaxAnisotropy"); - if (GLLoader::found_GL_EXT_texture_filter_anisotropic && anisotropy && aniso) + if (GLLoader::found_GL_EXT_texture_filter_anisotropic && anisotropy && sel.aniso) glSamplerParameterf(sampler, GL_TEXTURE_MAX_ANISOTROPY_EXT, (float)anisotropy); return sampler; diff --git a/plugins/GSdx/GSDeviceOGL.h b/plugins/GSdx/GSDeviceOGL.h index 522fb06490..0d9d8ed687 100644 --- a/plugins/GSdx/GSDeviceOGL.h +++ b/plugins/GSdx/GSDeviceOGL.h @@ -316,10 +316,11 @@ public: { uint32 tau:1; uint32 tav:1; - uint32 ltf:1; + uint32 biln:1; + uint32 triln:3; uint32 aniso:1; - uint32 _free:28; + uint32 _free:25; }; uint32 key; @@ -463,7 +464,7 @@ public: GLuint m_vs[1]; GLuint m_gs[1<<3]; - GLuint m_ps_ss[1<<4]; + GLuint m_ps_ss[1<<7]; GSDepthStencilOGL* m_om_dss[1<<5]; hash_map m_ps; GLuint m_apitrace; @@ -561,7 +562,6 @@ public: GLuint CompileVS(VSSelector sel); GLuint CompileGS(GSSelector sel); GLuint CompilePS(PSSelector sel); - GLuint CreateSampler(bool bilinear, bool tau, bool tav, bool aniso = false); GLuint CreateSampler(PSSamplerSelector sel); GSDepthStencilOGL* CreateDepthStencil(OMDepthStencilSelector dssel); diff --git a/plugins/GSdx/GSRendererOGL.cpp b/plugins/GSdx/GSRendererOGL.cpp index c27d5eba05..8e07a5d16d 100644 --- a/plugins/GSdx/GSRendererOGL.cpp +++ b/plugins/GSdx/GSRendererOGL.cpp @@ -884,8 +884,15 @@ void GSRendererOGL::EmulateTextureSampler(const GSTextureCache::Source* tex) // Only enable clamping in CLAMP mode. REGION_CLAMP will be done manually in the shader m_ps_ssel.tau = (wms != CLAMP_CLAMP); m_ps_ssel.tav = (wmt != CLAMP_CLAMP); - m_ps_ssel.ltf = bilinear && !shader_emulated_sampler; - m_ps_ssel.aniso = !shader_emulated_sampler; + if (shader_emulated_sampler) { + m_ps_ssel.biln = 0; + m_ps_ssel.aniso = 0; + m_ps_ssel.triln = 0; + } else { + m_ps_ssel.biln = bilinear; + m_ps_ssel.aniso = 1; + m_ps_ssel.triln = m_context->TEX1.MMIN & 1; + } // Setup Texture ressources dev->SetupSampler(m_ps_ssel);