gsdx mipmap:ogl: extend HW sampler with tri-linear filtering

v2:
* use nice enum
* use bilinear info when there is no mipmap (more accurate)
This commit is contained in:
Gregory Hainaut 2016-10-01 17:33:36 +02:00
parent 335d7f3ae5
commit a8a2db8eb1
3 changed files with 49 additions and 22 deletions

View File

@ -397,7 +397,7 @@ bool GSDeviceOGL::Create(GSWnd* wnd)
m_convert.pt = GetSamplerID(point); m_convert.pt = GetSamplerID(point);
PSSamplerSelector bilinear; PSSamplerSelector bilinear;
bilinear.ltf = true; bilinear.biln = true;
m_convert.ln = GetSamplerID(bilinear); m_convert.ln = GetSamplerID(bilinear);
m_convert.dss = new GSDepthStencilOGL(); 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)); 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... // 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); glBindSampler(1, m_palette_ss);
// Pre compile the (remaining) Geometry & Vertex Shader // Pre compile the (remaining) Geometry & Vertex Shader
@ -801,40 +801,60 @@ void GSDeviceOGL::ClearStencil(GSTexture* t, uint8 c)
} }
GLuint GSDeviceOGL::CreateSampler(PSSamplerSelector sel) 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"); GL_PUSH("Create Sampler");
GLuint sampler; GLuint sampler;
glCreateSamplers(1, &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_MAG_FILTER, GL_LINEAR);
glSamplerParameteri(sampler, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
} else { } else {
glSamplerParameteri(sampler, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glSamplerParameteri(sampler, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glSamplerParameteri(sampler, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glSamplerParameteri(sampler, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
} }
if (tau) switch (static_cast<GS_MIN_FILTER>(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); glSamplerParameteri(sampler, GL_TEXTURE_WRAP_S, GL_REPEAT);
else else
glSamplerParameteri(sampler, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glSamplerParameteri(sampler, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
if (tav) if (sel.tav)
glSamplerParameteri(sampler, GL_TEXTURE_WRAP_T, GL_REPEAT); glSamplerParameteri(sampler, GL_TEXTURE_WRAP_T, GL_REPEAT);
else else
glSamplerParameteri(sampler, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glSamplerParameteri(sampler, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glSamplerParameteri(sampler, GL_TEXTURE_WRAP_R, 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"); 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); glSamplerParameterf(sampler, GL_TEXTURE_MAX_ANISOTROPY_EXT, (float)anisotropy);
return sampler; return sampler;

View File

@ -316,10 +316,11 @@ public:
{ {
uint32 tau:1; uint32 tau:1;
uint32 tav:1; uint32 tav:1;
uint32 ltf:1; uint32 biln:1;
uint32 triln:3;
uint32 aniso:1; uint32 aniso:1;
uint32 _free:28; uint32 _free:25;
}; };
uint32 key; uint32 key;
@ -463,7 +464,7 @@ public:
GLuint m_vs[1]; GLuint m_vs[1];
GLuint m_gs[1<<3]; GLuint m_gs[1<<3];
GLuint m_ps_ss[1<<4]; GLuint m_ps_ss[1<<7];
GSDepthStencilOGL* m_om_dss[1<<5]; GSDepthStencilOGL* m_om_dss[1<<5];
hash_map<uint64, GLuint > m_ps; hash_map<uint64, GLuint > m_ps;
GLuint m_apitrace; GLuint m_apitrace;
@ -561,7 +562,6 @@ public:
GLuint CompileVS(VSSelector sel); GLuint CompileVS(VSSelector sel);
GLuint CompileGS(GSSelector sel); GLuint CompileGS(GSSelector sel);
GLuint CompilePS(PSSelector sel); GLuint CompilePS(PSSelector sel);
GLuint CreateSampler(bool bilinear, bool tau, bool tav, bool aniso = false);
GLuint CreateSampler(PSSamplerSelector sel); GLuint CreateSampler(PSSamplerSelector sel);
GSDepthStencilOGL* CreateDepthStencil(OMDepthStencilSelector dssel); GSDepthStencilOGL* CreateDepthStencil(OMDepthStencilSelector dssel);

View File

@ -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 // 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.tau = (wms != CLAMP_CLAMP);
m_ps_ssel.tav = (wmt != CLAMP_CLAMP); m_ps_ssel.tav = (wmt != CLAMP_CLAMP);
m_ps_ssel.ltf = bilinear && !shader_emulated_sampler; if (shader_emulated_sampler) {
m_ps_ssel.aniso = !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 // Setup Texture ressources
dev->SetupSampler(m_ps_ssel); dev->SetupSampler(m_ps_ssel);