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;
|
||||
PFNGLUNIFORMHANDLEUI64VARBPROC gl_UniformHandleui64vARB = NULL;
|
||||
PFNGLPROGRAMUNIFORMHANDLEUI64VARBPROC gl_ProgramUniformHandleui64vARB = NULL;
|
||||
|
||||
PFNGLDEPTHRANGEDNVPROC gl_DepthRangedNV = NULL;
|
||||
#endif
|
||||
|
||||
namespace GLLoader {
|
||||
|
|
|
@ -183,6 +183,8 @@ extern PFNGLMAKETEXTUREHANDLENONRESIDENTARBPROC gl_MakeTextureHandleNonResidentA
|
|||
extern PFNGLUNIFORMHANDLEUI64VARBPROC gl_UniformHandleui64vARB;
|
||||
extern PFNGLPROGRAMUNIFORMHANDLEUI64VARBPROC gl_ProgramUniformHandleui64vARB;
|
||||
|
||||
extern PFNGLDEPTHRANGEDNVPROC gl_DepthRangedNV;
|
||||
|
||||
#else
|
||||
#define gl_ActiveTexture glActiveTexture
|
||||
#define gl_BlendColor glBlendColor
|
||||
|
|
|
@ -167,7 +167,7 @@ bool GSDeviceOGL::Create(GSWnd* wnd)
|
|||
// ****************************************************************
|
||||
// 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_read);
|
||||
|
|
|
@ -23,8 +23,9 @@
|
|||
#include "GSShaderOGL.h"
|
||||
#include "GLState.h"
|
||||
|
||||
GSShaderOGL::GSShaderOGL(bool debug) :
|
||||
GSShaderOGL::GSShaderOGL(bool debug, bool nv_depth) :
|
||||
m_debug_shader(debug),
|
||||
m_nv_depth(nv_depth),
|
||||
m_vs_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";
|
||||
}
|
||||
|
||||
if (m_nv_depth) {
|
||||
// Specific nvidia extension that seem to help for z fighting
|
||||
header += "#define NV_DEPTH\n";
|
||||
}
|
||||
|
||||
#else
|
||||
header = "#version 300 es\n";
|
||||
|
|
|
@ -25,6 +25,7 @@ class GSShaderOGL {
|
|||
GLuint m_pipeline;
|
||||
hash_map<uint64, GLuint > m_single_prog;
|
||||
const bool m_debug_shader;
|
||||
const bool m_nv_depth;
|
||||
GLuint m_vs_sub_count;
|
||||
GLuint m_ps_sub_count;
|
||||
|
||||
|
@ -46,7 +47,7 @@ class GSShaderOGL {
|
|||
GLuint LinkNewProgram();
|
||||
|
||||
public:
|
||||
GSShaderOGL(bool debug);
|
||||
GSShaderOGL(bool debug, bool nv_depth);
|
||||
~GSShaderOGL();
|
||||
|
||||
void GS(GLuint s);
|
||||
|
|
|
@ -59,6 +59,10 @@ void GSDeviceOGL::CreateTextureFX()
|
|||
|
||||
// Help to debug FS in apitrace
|
||||
m_apitrace = CompilePS(PSSelector());
|
||||
|
||||
if (!!theApp.GetConfig("GL_NV_Depth", 0)) {
|
||||
gl_DepthRangedNV(-1.0f, 1.0f);
|
||||
}
|
||||
}
|
||||
|
||||
GSDepthStencilOGL* GSDeviceOGL::CreateDepthStencil(OMDepthStencilSelector dssel)
|
||||
|
|
|
@ -234,8 +234,12 @@ public:
|
|||
switch (layout[i].type) {
|
||||
case GL_UNSIGNED_SHORT:
|
||||
case GL_UNSIGNED_INT:
|
||||
if (layout[i].normalize) {
|
||||
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;
|
||||
default:
|
||||
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_ProgramUniformHandleui64vARB) = GetProcAddress("glProgramUniformHandleui64vARB", true);
|
||||
|
||||
*(void**)&(gl_DepthRangedNV) = GetProcAddress("glDepthRangedNV", true);
|
||||
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -665,6 +665,7 @@ static const char* tfx_glsl =
|
|||
"};\n"
|
||||
"\n"
|
||||
"const float exp_min32 = exp2(-32.0f);\n"
|
||||
"const float exp_min31 = exp2(-31.0f);\n"
|
||||
"\n"
|
||||
"#ifdef SUBROUTINE_GL40\n"
|
||||
"// Function pointer type\n"
|
||||
|
@ -722,7 +723,7 @@ static const char* tfx_glsl =
|
|||
"\n"
|
||||
"void vs_main()\n"
|
||||
"{\n"
|
||||
" uint z;\n"
|
||||
" highp uint z;\n"
|
||||
" if(VS_BPPZ == 1) // 24\n"
|
||||
" z = i_z & uint(0xffffff);\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"
|
||||
" // 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"
|
||||
" vec4 p;\n"
|
||||
"\n"
|
||||
" vec3 p = vec3(i_p, z) - vec3(0.05f, 0.05f, 0.0f);\n"
|
||||
" p = p * vec3(VertexScale, exp_min32) - vec3(VertexOffset, 0.0f);\n"
|
||||
"\n"
|
||||
" if(VS_LOGZ == 1)\n"
|
||||
" {\n"
|
||||
" p.z = log2(1.0f + float(z)) / 32.0f;\n"
|
||||
" p.xy = vec2(i_p) - vec2(0.05f, 0.05f);\n"
|
||||
" p.xy = p.xy * VertexScale - VertexOffset;\n"
|
||||
" p.w = 1.0f;\n"
|
||||
"#ifdef NV_DEPTH\n"
|
||||
" if(VS_LOGZ == 1) {\n"
|
||||
" p.z = log2(float(1u+z)) / 32.0f;\n"
|
||||
" } else {\n"
|
||||
" p.z = float(z) * exp_min32;\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"
|
||||
" 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"
|
||||
" texture_coord();\n"
|
||||
"\n"
|
||||
|
|
|
@ -106,6 +106,7 @@ layout(std140, binding = 20) uniform cb20
|
|||
};
|
||||
|
||||
const float exp_min32 = exp2(-32.0f);
|
||||
const float exp_min31 = exp2(-31.0f);
|
||||
|
||||
#ifdef SUBROUTINE_GL40
|
||||
// Function pointer type
|
||||
|
@ -163,7 +164,7 @@ void texture_coord()
|
|||
|
||||
void vs_main()
|
||||
{
|
||||
uint z;
|
||||
highp uint z;
|
||||
if(VS_BPPZ == 1) // 24
|
||||
z = i_z & uint(0xffffff);
|
||||
else if(VS_BPPZ == 2) // 16
|
||||
|
@ -175,16 +176,26 @@ void vs_main()
|
|||
// 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
|
||||
// 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 = p * vec3(VertexScale, exp_min32) - vec3(VertexOffset, 0.0f);
|
||||
|
||||
if(VS_LOGZ == 1)
|
||||
{
|
||||
p.z = log2(1.0f + float(z)) / 32.0f;
|
||||
p.xy = vec2(i_p) - vec2(0.05f, 0.05f);
|
||||
p.xy = p.xy * VertexScale - VertexOffset;
|
||||
p.w = 1.0f;
|
||||
#ifdef NV_DEPTH
|
||||
if(VS_LOGZ == 1) {
|
||||
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();
|
||||
|
||||
|
|
Loading…
Reference in New Issue