mirror of https://github.com/PCSX2/pcsx2.git
gsdx ogl: correct most of Z-depth issue
Best setting if you driver support GL_NV_depth_buffer_float => GL_NV_Depth = 1 & logz = 0 Otherwise => GL_NV_Depth = 0 & logz = 1 Explanation of the bug: Dx z position ranges from 0.0f to 1.0f (FS ranges 0.0f to 1.0f) GL z Position ranges from -1.0f to 1.0f (FS ranges 0.0f to 1.0f) Why it sucks: GS small depth value will be "mapped" to -1.0f. In others all small values will be 1.0f! Terrible lost of accuraccy. The GL_NV_depth_buffer_float extension allow to set the near plane as -1.0f. So "GL z Position ranges from -1.0f to 1.0f (FS ranges 0.0f to 1.0f)" will become "GL z Position ranges from -1.0f to 1.0f (FS ranges -1.0f to 1.0f)" and therefore "z posision [0.0f;1.0f] will map to FS [0.0f;1.0f]" as DX Yes we just get back all precision lost previously :) However you need hardware (intel?) and driver support (free driver?/gles?) :( git-svn-id: http://pcsx2.googlecode.com/svn/trunk@5860 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
parent
e27d04ff08
commit
84895eadd9
|
@ -118,6 +118,8 @@ PFNGLMAKETEXTUREHANDLERESIDENTARBPROC gl_MakeTextureHandleResidentARB = NULL;
|
||||||
PFNGLMAKETEXTUREHANDLENONRESIDENTARBPROC gl_MakeTextureHandleNonResidentARB = NULL;
|
PFNGLMAKETEXTUREHANDLENONRESIDENTARBPROC gl_MakeTextureHandleNonResidentARB = NULL;
|
||||||
PFNGLUNIFORMHANDLEUI64VARBPROC gl_UniformHandleui64vARB = NULL;
|
PFNGLUNIFORMHANDLEUI64VARBPROC gl_UniformHandleui64vARB = NULL;
|
||||||
PFNGLPROGRAMUNIFORMHANDLEUI64VARBPROC gl_ProgramUniformHandleui64vARB = NULL;
|
PFNGLPROGRAMUNIFORMHANDLEUI64VARBPROC gl_ProgramUniformHandleui64vARB = NULL;
|
||||||
|
|
||||||
|
PFNGLDEPTHRANGEDNVPROC gl_DepthRangedNV = NULL;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
namespace GLLoader {
|
namespace GLLoader {
|
||||||
|
|
|
@ -183,6 +183,8 @@ extern PFNGLMAKETEXTUREHANDLENONRESIDENTARBPROC gl_MakeTextureHandleNonResidentA
|
||||||
extern PFNGLUNIFORMHANDLEUI64VARBPROC gl_UniformHandleui64vARB;
|
extern PFNGLUNIFORMHANDLEUI64VARBPROC gl_UniformHandleui64vARB;
|
||||||
extern PFNGLPROGRAMUNIFORMHANDLEUI64VARBPROC gl_ProgramUniformHandleui64vARB;
|
extern PFNGLPROGRAMUNIFORMHANDLEUI64VARBPROC gl_ProgramUniformHandleui64vARB;
|
||||||
|
|
||||||
|
extern PFNGLDEPTHRANGEDNVPROC gl_DepthRangedNV;
|
||||||
|
|
||||||
#else
|
#else
|
||||||
#define gl_ActiveTexture glActiveTexture
|
#define gl_ActiveTexture glActiveTexture
|
||||||
#define gl_BlendColor glBlendColor
|
#define gl_BlendColor glBlendColor
|
||||||
|
|
|
@ -167,7 +167,7 @@ bool GSDeviceOGL::Create(GSWnd* wnd)
|
||||||
// ****************************************************************
|
// ****************************************************************
|
||||||
// Various object
|
// Various object
|
||||||
// ****************************************************************
|
// ****************************************************************
|
||||||
m_shader = new GSShaderOGL(!!theApp.GetConfig("debug_ogl_shader", 1));
|
m_shader = new GSShaderOGL(!!theApp.GetConfig("debug_ogl_shader", 1), !!theApp.GetConfig("GL_NV_Depth", 0));
|
||||||
|
|
||||||
gl_GenFramebuffers(1, &m_fbo);
|
gl_GenFramebuffers(1, &m_fbo);
|
||||||
gl_GenFramebuffers(1, &m_fbo_read);
|
gl_GenFramebuffers(1, &m_fbo_read);
|
||||||
|
|
|
@ -23,8 +23,9 @@
|
||||||
#include "GSShaderOGL.h"
|
#include "GSShaderOGL.h"
|
||||||
#include "GLState.h"
|
#include "GLState.h"
|
||||||
|
|
||||||
GSShaderOGL::GSShaderOGL(bool debug) :
|
GSShaderOGL::GSShaderOGL(bool debug, bool nv_depth) :
|
||||||
m_debug_shader(debug),
|
m_debug_shader(debug),
|
||||||
|
m_nv_depth(nv_depth),
|
||||||
m_vs_sub_count(0),
|
m_vs_sub_count(0),
|
||||||
m_ps_sub_count(0)
|
m_ps_sub_count(0)
|
||||||
{
|
{
|
||||||
|
@ -397,6 +398,10 @@ std::string GSShaderOGL::GenGlslHeader(const std::string& entry, GLenum type, co
|
||||||
header += "#define ENABLE_BINDLESS_TEX\n";
|
header += "#define ENABLE_BINDLESS_TEX\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (m_nv_depth) {
|
||||||
|
// Specific nvidia extension that seem to help for z fighting
|
||||||
|
header += "#define NV_DEPTH\n";
|
||||||
|
}
|
||||||
|
|
||||||
#else
|
#else
|
||||||
header = "#version 300 es\n";
|
header = "#version 300 es\n";
|
||||||
|
|
|
@ -25,6 +25,7 @@ class GSShaderOGL {
|
||||||
GLuint m_pipeline;
|
GLuint m_pipeline;
|
||||||
hash_map<uint64, GLuint > m_single_prog;
|
hash_map<uint64, GLuint > m_single_prog;
|
||||||
const bool m_debug_shader;
|
const bool m_debug_shader;
|
||||||
|
const bool m_nv_depth;
|
||||||
GLuint m_vs_sub_count;
|
GLuint m_vs_sub_count;
|
||||||
GLuint m_ps_sub_count;
|
GLuint m_ps_sub_count;
|
||||||
|
|
||||||
|
@ -46,7 +47,7 @@ class GSShaderOGL {
|
||||||
GLuint LinkNewProgram();
|
GLuint LinkNewProgram();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
GSShaderOGL(bool debug);
|
GSShaderOGL(bool debug, bool nv_depth);
|
||||||
~GSShaderOGL();
|
~GSShaderOGL();
|
||||||
|
|
||||||
void GS(GLuint s);
|
void GS(GLuint s);
|
||||||
|
|
|
@ -59,6 +59,10 @@ void GSDeviceOGL::CreateTextureFX()
|
||||||
|
|
||||||
// Help to debug FS in apitrace
|
// Help to debug FS in apitrace
|
||||||
m_apitrace = CompilePS(PSSelector());
|
m_apitrace = CompilePS(PSSelector());
|
||||||
|
|
||||||
|
if (!!theApp.GetConfig("GL_NV_Depth", 0)) {
|
||||||
|
gl_DepthRangedNV(-1.0f, 1.0f);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
GSDepthStencilOGL* GSDeviceOGL::CreateDepthStencil(OMDepthStencilSelector dssel)
|
GSDepthStencilOGL* GSDeviceOGL::CreateDepthStencil(OMDepthStencilSelector dssel)
|
||||||
|
|
|
@ -234,8 +234,12 @@ public:
|
||||||
switch (layout[i].type) {
|
switch (layout[i].type) {
|
||||||
case GL_UNSIGNED_SHORT:
|
case GL_UNSIGNED_SHORT:
|
||||||
case GL_UNSIGNED_INT:
|
case GL_UNSIGNED_INT:
|
||||||
// Rule: when shader use integral (not normalized) you must use gl_VertexAttribIPointer (note the extra I)
|
if (layout[i].normalize) {
|
||||||
gl_VertexAttribIPointer(layout[i].index, layout[i].size, layout[i].type, layout[i].stride, layout[i].offset);
|
gl_VertexAttribPointer(layout[i].index, layout[i].size, layout[i].type, layout[i].normalize, layout[i].stride, layout[i].offset);
|
||||||
|
} else {
|
||||||
|
// Rule: when shader use integral (not normalized) you must use gl_VertexAttribIPointer (note the extra I)
|
||||||
|
gl_VertexAttribIPointer(layout[i].index, layout[i].size, layout[i].type, layout[i].stride, layout[i].offset);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
gl_VertexAttribPointer(layout[i].index, layout[i].size, layout[i].type, layout[i].normalize, layout[i].stride, layout[i].offset);
|
gl_VertexAttribPointer(layout[i].index, layout[i].size, layout[i].type, layout[i].normalize, layout[i].stride, layout[i].offset);
|
||||||
|
|
|
@ -120,6 +120,7 @@ void GSWndGL::PopulateGlFunction()
|
||||||
*(void**)&(gl_UniformHandleui64vARB) = GetProcAddress("glUniformHandleui64vARB", true);
|
*(void**)&(gl_UniformHandleui64vARB) = GetProcAddress("glUniformHandleui64vARB", true);
|
||||||
*(void**)&(gl_ProgramUniformHandleui64vARB) = GetProcAddress("glProgramUniformHandleui64vARB", true);
|
*(void**)&(gl_ProgramUniformHandleui64vARB) = GetProcAddress("glProgramUniformHandleui64vARB", true);
|
||||||
|
|
||||||
|
*(void**)&(gl_DepthRangedNV) = GetProcAddress("glDepthRangedNV", true);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
|
@ -665,6 +665,7 @@ static const char* tfx_glsl =
|
||||||
"};\n"
|
"};\n"
|
||||||
"\n"
|
"\n"
|
||||||
"const float exp_min32 = exp2(-32.0f);\n"
|
"const float exp_min32 = exp2(-32.0f);\n"
|
||||||
|
"const float exp_min31 = exp2(-31.0f);\n"
|
||||||
"\n"
|
"\n"
|
||||||
"#ifdef SUBROUTINE_GL40\n"
|
"#ifdef SUBROUTINE_GL40\n"
|
||||||
"// Function pointer type\n"
|
"// Function pointer type\n"
|
||||||
|
@ -722,7 +723,7 @@ static const char* tfx_glsl =
|
||||||
"\n"
|
"\n"
|
||||||
"void vs_main()\n"
|
"void vs_main()\n"
|
||||||
"{\n"
|
"{\n"
|
||||||
" uint z;\n"
|
" highp uint z;\n"
|
||||||
" if(VS_BPPZ == 1) // 24\n"
|
" if(VS_BPPZ == 1) // 24\n"
|
||||||
" z = i_z & uint(0xffffff);\n"
|
" z = i_z & uint(0xffffff);\n"
|
||||||
" else if(VS_BPPZ == 2) // 16\n"
|
" else if(VS_BPPZ == 2) // 16\n"
|
||||||
|
@ -734,16 +735,26 @@ static const char* tfx_glsl =
|
||||||
" // example: ceil(afterseveralvertextransformations(y = 133)) => 134 => line 133 stays empty\n"
|
" // example: ceil(afterseveralvertextransformations(y = 133)) => 134 => line 133 stays empty\n"
|
||||||
" // input granularity is 1/16 pixel, anything smaller than that won't step drawing up/left by one pixel\n"
|
" // input granularity is 1/16 pixel, anything smaller than that won't step drawing up/left by one pixel\n"
|
||||||
" // example: 133.0625 (133 + 1/16) should start from line 134, ceil(133.0625 - 0.05) still above 133\n"
|
" // example: 133.0625 (133 + 1/16) should start from line 134, ceil(133.0625 - 0.05) still above 133\n"
|
||||||
|
" vec4 p;\n"
|
||||||
"\n"
|
"\n"
|
||||||
" vec3 p = vec3(i_p, z) - vec3(0.05f, 0.05f, 0.0f);\n"
|
" p.xy = vec2(i_p) - vec2(0.05f, 0.05f);\n"
|
||||||
" p = p * vec3(VertexScale, exp_min32) - vec3(VertexOffset, 0.0f);\n"
|
" p.xy = p.xy * VertexScale - VertexOffset;\n"
|
||||||
"\n"
|
" p.w = 1.0f;\n"
|
||||||
" if(VS_LOGZ == 1)\n"
|
"#ifdef NV_DEPTH\n"
|
||||||
" {\n"
|
" if(VS_LOGZ == 1) {\n"
|
||||||
" p.z = log2(1.0f + float(z)) / 32.0f;\n"
|
" p.z = log2(float(1u+z)) / 32.0f;\n"
|
||||||
|
" } else {\n"
|
||||||
|
" p.z = float(z) * exp_min32;\n"
|
||||||
" }\n"
|
" }\n"
|
||||||
|
"#else\n"
|
||||||
|
" if(VS_LOGZ == 1) {\n"
|
||||||
|
" p.z = log2(float(1u+z)) / 31.0f - 1.0f;\n"
|
||||||
|
" } else {\n"
|
||||||
|
" p.z = float(z) * exp_min31 - 1.0f;\n"
|
||||||
|
" }\n"
|
||||||
|
"#endif\n"
|
||||||
"\n"
|
"\n"
|
||||||
" gl_Position = vec4(p, 1.0f); // NOTE I don't know if it is possible to merge POSITION_OUT and gl_Position\n"
|
" gl_Position = p;\n"
|
||||||
"\n"
|
"\n"
|
||||||
" texture_coord();\n"
|
" texture_coord();\n"
|
||||||
"\n"
|
"\n"
|
||||||
|
|
|
@ -106,6 +106,7 @@ layout(std140, binding = 20) uniform cb20
|
||||||
};
|
};
|
||||||
|
|
||||||
const float exp_min32 = exp2(-32.0f);
|
const float exp_min32 = exp2(-32.0f);
|
||||||
|
const float exp_min31 = exp2(-31.0f);
|
||||||
|
|
||||||
#ifdef SUBROUTINE_GL40
|
#ifdef SUBROUTINE_GL40
|
||||||
// Function pointer type
|
// Function pointer type
|
||||||
|
@ -163,7 +164,7 @@ void texture_coord()
|
||||||
|
|
||||||
void vs_main()
|
void vs_main()
|
||||||
{
|
{
|
||||||
uint z;
|
highp uint z;
|
||||||
if(VS_BPPZ == 1) // 24
|
if(VS_BPPZ == 1) // 24
|
||||||
z = i_z & uint(0xffffff);
|
z = i_z & uint(0xffffff);
|
||||||
else if(VS_BPPZ == 2) // 16
|
else if(VS_BPPZ == 2) // 16
|
||||||
|
@ -175,16 +176,26 @@ void vs_main()
|
||||||
// example: ceil(afterseveralvertextransformations(y = 133)) => 134 => line 133 stays empty
|
// example: ceil(afterseveralvertextransformations(y = 133)) => 134 => line 133 stays empty
|
||||||
// input granularity is 1/16 pixel, anything smaller than that won't step drawing up/left by one pixel
|
// input granularity is 1/16 pixel, anything smaller than that won't step drawing up/left by one pixel
|
||||||
// example: 133.0625 (133 + 1/16) should start from line 134, ceil(133.0625 - 0.05) still above 133
|
// example: 133.0625 (133 + 1/16) should start from line 134, ceil(133.0625 - 0.05) still above 133
|
||||||
|
vec4 p;
|
||||||
|
|
||||||
vec3 p = vec3(i_p, z) - vec3(0.05f, 0.05f, 0.0f);
|
p.xy = vec2(i_p) - vec2(0.05f, 0.05f);
|
||||||
p = p * vec3(VertexScale, exp_min32) - vec3(VertexOffset, 0.0f);
|
p.xy = p.xy * VertexScale - VertexOffset;
|
||||||
|
p.w = 1.0f;
|
||||||
if(VS_LOGZ == 1)
|
#ifdef NV_DEPTH
|
||||||
{
|
if(VS_LOGZ == 1) {
|
||||||
p.z = log2(1.0f + float(z)) / 32.0f;
|
p.z = log2(float(1u+z)) / 32.0f;
|
||||||
|
} else {
|
||||||
|
p.z = float(z) * exp_min32;
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
if(VS_LOGZ == 1) {
|
||||||
|
p.z = log2(float(1u+z)) / 31.0f - 1.0f;
|
||||||
|
} else {
|
||||||
|
p.z = float(z) * exp_min31 - 1.0f;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
gl_Position = vec4(p, 1.0f); // NOTE I don't know if it is possible to merge POSITION_OUT and gl_Position
|
gl_Position = p;
|
||||||
|
|
||||||
texture_coord();
|
texture_coord();
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue