From 314b9098f48ecd299122888954ae9e223df93c09 Mon Sep 17 00:00:00 2001 From: Sergey Lipskiy Date: Sun, 15 Dec 2013 22:32:17 +0700 Subject: [PATCH] Implement N64 depth compare. Removed integer-based variant of depth texture. --- FrameBuffer.cpp | 5 +-- FrameBuffer.h | 1 - GLSLCombiner.cpp | 61 +++++++++---------------- OpenGL.cpp | 6 +-- Shaders.h | 115 ++++++++++++++++++----------------------------- 5 files changed, 70 insertions(+), 118 deletions(-) diff --git a/FrameBuffer.cpp b/FrameBuffer.cpp index 2f35d9c8..21e87983 100644 --- a/FrameBuffer.cpp +++ b/FrameBuffer.cpp @@ -15,10 +15,7 @@ bool g_bCopyToRDRAM = false; bool g_bCopyFromRDRAM = false; bool g_bCopyDepthToRDRAM = false; -bool g_bUseFloatDepthTexture = true; bool g_bIgnoreCFB = true; -static const GLint depthTextureInternalFormat = g_bUseFloatDepthTexture ? GL_R32F : GL_R16; -static const GLenum depthTextureType = g_bUseFloatDepthTexture ? GL_FLOAT : GL_UNSIGNED_INT; FrameBufferList frameBuffer; @@ -367,7 +364,7 @@ void _initDepthTexture() cache.cachedBytes += depthBuffer.top->depth_texture->textureBytes; glBindTexture( GL_TEXTURE_2D, depthBuffer.top->depth_texture->glName ); - glTexImage2D(GL_TEXTURE_2D, 0, depthTextureInternalFormat, depthBuffer.top->depth_texture->realWidth, depthBuffer.top->depth_texture->realHeight, 0, GL_RED, depthTextureType, NULL); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, depthBuffer.top->depth_texture->realWidth, depthBuffer.top->depth_texture->realHeight, 0, GL_RGBA, GL_FLOAT, NULL); glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR ); glBindTexture( GL_TEXTURE_2D, 0); diff --git a/FrameBuffer.h b/FrameBuffer.h index 51d82ccc..a96b202c 100644 --- a/FrameBuffer.h +++ b/FrameBuffer.h @@ -32,7 +32,6 @@ extern FrameBufferList frameBuffer; extern bool g_bCopyToRDRAM; extern bool g_bCopyDepthToRDRAM; extern bool g_bCopyFromRDRAM; -extern bool g_bUseFloatDepthTexture; extern bool g_bIgnoreCFB; void FrameBuffer_Init(); diff --git a/GLSLCombiner.cpp b/GLSLCombiner.cpp index 33219da6..692b0fb2 100644 --- a/GLSLCombiner.cpp +++ b/GLSLCombiner.cpp @@ -134,10 +134,7 @@ void InitShadowMapShader() assert(check_shader_compile_status(g_shadow_map_vertex_shader_object)); g_shadow_map_fragment_shader_object = glCreateShader(GL_FRAGMENT_SHADER); - if (g_bUseFloatDepthTexture) - glShaderSource(g_shadow_map_fragment_shader_object, 1, &shadow_map_fragment_shader_float, NULL); - else - glShaderSource(g_shadow_map_fragment_shader_object, 1, &shadow_map_fragment_shader_int, NULL); + glShaderSource(g_shadow_map_fragment_shader_object, 1, &shadow_map_fragment_shader_float, NULL); glCompileShader(g_shadow_map_fragment_shader_object); assert(check_shader_compile_status(g_shadow_map_fragment_shader_object)); @@ -197,10 +194,7 @@ void InitGLSLCombiner() if (OGL.bImageTexture) { g_calc_depth_shader_object = glCreateShader(GL_FRAGMENT_SHADER); - if (g_bUseFloatDepthTexture) - glShaderSource(g_calc_depth_shader_object, 1, &depth_compare_shader_float, NULL); - else - glShaderSource(g_calc_depth_shader_object, 1, &depth_compare_shader_int, NULL); + glShaderSource(g_calc_depth_shader_object, 1, &depth_compare_shader_float, NULL); glCompileShader(g_calc_depth_shader_object); assert(check_shader_compile_status(g_calc_depth_shader_object)); } @@ -412,8 +406,8 @@ GLSLCombiner::GLSLCombiner(Combiner *_color, Combiner *_alpha) { strcat(fragment_shader, " if (!alpha_test(gl_FragColor.a)) discard; \n"); if (OGL.bImageTexture) - strcat(fragment_shader, " bool bDC = depth_compare(); \n"); -// strcat(fragment_shader, " if (!depth_compare()) discard; \n"); +// strcat(fragment_shader, " bool bDC = depth_compare(); \n"); + strcat(fragment_shader, " if (!depth_compare()) discard; \n"); #ifdef USE_TOONIFY strcat(fragment_shader, " toonify(intensity); \n"); @@ -572,8 +566,7 @@ static void _unbindImageTextures() { glBindImageTexture(TlutImageUnit, 0, 0, GL_FALSE, 0, GL_READ_WRITE, GL_R16UI); glBindImageTexture(ZlutImageUnit, 0, 0, GL_FALSE, 0, GL_READ_WRITE, GL_R16UI); - const GLenum depthTexFormat = g_bUseFloatDepthTexture ? GL_R32F : GL_R16UI; - glBindImageTexture(depthImageUnit, 0, 0, GL_FALSE, 0, GL_READ_WRITE, depthTexFormat); + glBindImageTexture(depthImageUnit, 0, 0, GL_FALSE, 0, GL_READ_WRITE, GL_RGBA32F); } void GLSLCombiner::UpdateDepthInfo() { @@ -591,18 +584,12 @@ void GLSLCombiner::UpdateDepthInfo() { if (nDepthEnabled == 0) return; + const int depth_mode_location = glGetUniformLocation(m_program, "depthMode"); + glUniform1i(depth_mode_location, gDP.otherMode.depthMode); const int depth_compare_location = glGetUniformLocation(m_program, "depthCompareEnabled"); glUniform1i(depth_compare_location, gDP.otherMode.depthCompare); const int depth_update_location = glGetUniformLocation(m_program, "depthUpdateEnabled"); glUniform1i(depth_update_location, gDP.otherMode.depthUpdate); - const int depth_polygon_offset = glGetUniformLocation(m_program, "depthPolygonOffset"); - if (g_bUseFloatDepthTexture) { - float fPlygonOffset = gDP.otherMode.depthMode == ZMODE_DEC ? 0.005f : 0.0f; - glUniform1f(depth_polygon_offset, fPlygonOffset); - } else { - int iPlygonOffset = gDP.otherMode.depthMode == ZMODE_DEC ? 5 : 0; - glUniform1i(depth_polygon_offset, iPlygonOffset); - } const int depth_scale_location = glGetUniformLocation(m_program, "depthScale"); glUniform1f(depth_scale_location, gSP.viewport.vscale[2]*32768); const int depth_trans_location = glGetUniformLocation(m_program, "depthTrans"); @@ -610,8 +597,7 @@ void GLSLCombiner::UpdateDepthInfo() { GLuint texture = frameBuffer.top->pDepthBuffer->depth_texture->glName; glBindImageTexture(ZlutImageUnit, g_zlut_tex, 0, GL_FALSE, 0, GL_READ_ONLY, GL_R16UI); - GLenum depthTexFormat = g_bUseFloatDepthTexture ? GL_R32F : GL_R16UI; - glBindImageTexture(depthImageUnit, texture, 0, GL_FALSE, 0, GL_READ_WRITE, depthTexFormat); + glBindImageTexture(depthImageUnit, texture, 0, GL_FALSE, 0, GL_READ_WRITE, GL_RGBA32F); } void GLSL_ClearDepthBuffer() { @@ -621,29 +607,25 @@ void GLSL_ClearDepthBuffer() { if (frameBuffer.top == NULL || frameBuffer.top->pDepthBuffer == NULL) return; + _unbindImageTextures(); CachedTexture * pDepthTexture = frameBuffer.top->pDepthBuffer->depth_texture; - const u32 numTexels = pDepthTexture->width*pDepthTexture->height; + const u32 numTexels = pDepthTexture->width*pDepthTexture->height*4; - GLenum type = GL_UNSIGNED_SHORT; - int dataSize = g_bUseFloatDepthTexture ? sizeof(float) : sizeof(unsigned short); - char * pData = (char*)malloc(numTexels * dataSize);; - - if (g_bUseFloatDepthTexture) { - type = GL_FLOAT; - f32 * pDepth = (f32*)pData; - for (int i = 0; i < numTexels; i++) - pDepth[i] = 1.0f; - } else { - u16 * pDepth = (u16*)pData; - for (int i = 0; i < numTexels; i++) - pDepth[i] = 0xfffc; + char * pData = (char*)malloc(numTexels * sizeof(float)); + f32 * pDepth = (f32*)pData; + for (int i = 0; i < numTexels; i+=4) { + pDepth[i] = 1.0f; + pDepth[i+1] = 1.0f; + pDepth[i+2] = 0.0f; + pDepth[i+3] = 0.0f; } glBindTexture(GL_TEXTURE_2D, pDepthTexture->glName); glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, pDepthTexture->width, pDepthTexture->height, - GL_RED, type, pData); + GL_RGBA, GL_FLOAT, pData + ); free(pData); gSP.changed |= CHANGED_TEXTURE; @@ -683,6 +665,8 @@ void GLSL_RenderDepth() { #else if (frameBuffer.top == NULL || frameBuffer.top->pDepthBuffer == NULL) return; + _unbindImageTextures(); + return; glPushAttrib( GL_ENABLE_BIT | GL_VIEWPORT_BIT ); glActiveTexture( GL_TEXTURE0 ); @@ -764,8 +748,7 @@ void GLS_SetShadowMapCombiner() { glUseProgram(g_draw_shadow_map_program); glBindImageTexture(TlutImageUnit, g_tlut_tex, 0, GL_FALSE, 0, GL_READ_ONLY, GL_R16UI); - GLenum depthTexFormat = g_bUseFloatDepthTexture ? GL_R32F : GL_R16UI; GLuint texture = frameBuffer.top->pDepthBuffer->depth_texture->glName; - glBindImageTexture(depthImageUnit, texture, 0, GL_FALSE, 0, GL_READ_ONLY, depthTexFormat); + glBindImageTexture(depthImageUnit, texture, 0, GL_FALSE, 0, GL_READ_ONLY, GL_RGBA32F); gDP.changed |= CHANGED_COMBINE; } diff --git a/OpenGL.cpp b/OpenGL.cpp index 4027d4ea..fb5284f6 100644 --- a/OpenGL.cpp +++ b/OpenGL.cpp @@ -567,9 +567,9 @@ void OGL_UpdateStates() OGL_UpdateDepthUpdate(); - if (gDP.otherMode.depthMode == ZMODE_DEC) - glEnable( GL_POLYGON_OFFSET_FILL ); - else +// if (gDP.otherMode.depthMode == ZMODE_DEC) +// glEnable( GL_POLYGON_OFFSET_FILL ); +// else { // glPolygonOffset( -3.0f, -3.0f ); glDisable( GL_POLYGON_OFFSET_FILL ); diff --git a/Shaders.h b/Shaders.h index d33b02b8..f1fd1894 100644 --- a/Shaders.h +++ b/Shaders.h @@ -147,71 +147,64 @@ static const char* fragment_shader_end = "} \n" ; -static const char* depth_compare_shader_int = -"#version 420 core \n" -"uniform int depthEnabled; \n" -"uniform int depthCompareEnabled; \n" -"uniform int depthUpdateEnabled; \n" -"uniform unsigned int depthPolygonOffset; \n" -"uniform float depthTrans; \n" -"uniform float depthScale; \n" -"layout(binding = 0, r16ui) uniform readonly uimage2D zlut_image;\n" -"layout(binding = 2, r16ui) uniform restrict uimage2D depth_image;\n" -"bool depth_compare() \n" -"{ \n" -" if (depthEnabled == 0) return true; \n" -" ivec2 coord = ivec2(gl_FragCoord.xy); \n" -" highp uvec4 depth = imageLoad(depth_image,coord); \n" -" highp unsigned int bufZ = depth.r; \n" -" highp float fZ = 2.0*gl_FragCoord.z - 1.0; \n" -" fZ = (depthScale*fZ + depthTrans)*8.0; \n" -" highp int iZ = int(floor(fZ + 0.5)); \n" -" int y0 = iZ / 512; \n" -" int x0 = iZ - 512*y0; \n" -" highp unsigned int curZ = imageLoad(zlut_image,ivec2(x0,y0)).r; \n" -" curZ = curZ - depthPolygonOffset;\n" -" if (depthUpdateEnabled > 0 && curZ < depth.r) { \n" -" depth.r = curZ; \n" -" imageStore(depth_image,coord,depth); \n" -" } \n" -" memoryBarrier(); \n" -" if (depthCompareEnabled > 0) \n" -" return curZ <= bufZ; \n" -" return true; \n" -"} \n" -; - static const char* depth_compare_shader_float = "#version 420 core \n" "uniform int depthEnabled; \n" +"uniform int depthMode; \n" "uniform int depthCompareEnabled; \n" "uniform int depthUpdateEnabled; \n" -"uniform float depthPolygonOffset; \n" "uniform float depthTrans; \n" "uniform float depthScale; \n" "layout(binding = 0, r16ui) uniform readonly uimage2D zlut_image;\n" -"layout(binding = 2, r32f) uniform restrict image2D depth_image;\n" +"layout(binding = 2, rgba32f) uniform restrict image2D depth_image;\n" +"void write_depth(in highp float dz, in ivec2 coord) \n" +"{ \n" +" highp float fZ = 2.0*gl_FragCoord.z - 1.0; \n" +" fZ = (depthScale*fZ + depthTrans)*8.0; \n" +" const highp int iZ = int(floor(fZ + 0.5)); \n" +" int y0 = clamp(iZ/512, 0, 511); \n" +" int x0 = iZ - 512*y0; \n" +" unsigned int iN64z = imageLoad(zlut_image,ivec2(x0,y0)).r;\n" +" highp float n64z = clamp(float(iN64z)/65532.0, 0.0, 1.0);\n" +" highp vec4 depth = vec4(n64z, gl_FragCoord.z, dz, 1.0); \n" +" memoryBarrier(); \n" +" imageStore(depth_image,coord,depth); \n" +"} \n" "bool depth_compare() \n" "{ \n" " if (depthEnabled == 0) return true; \n" " ivec2 coord = ivec2(gl_FragCoord.xy); \n" +" memoryBarrier(); \n" " highp vec4 depth = imageLoad(depth_image,coord); \n" -" highp float bufZ = depth.r; \n" -" highp float fZ = 2.0*gl_FragCoord.z - 1.0; \n" -" fZ = (depthScale*fZ + depthTrans)*8.0; \n" -" highp int iZ = int(floor(fZ + 0.5)); \n" -" int y0 = clamp(iZ/512, 0, 511); \n" -" int x0 = iZ - 512*y0; \n" -" unsigned int icurZ = imageLoad(zlut_image,ivec2(x0,y0)).r;\n" -" highp float curZ = clamp(float(icurZ)/65532.0 - depthPolygonOffset, 0.0, 1.0); \n" -//" highp float curZ = clamp(float(icurZ)/65532.0, 0.0, 1.0); \n" -" if (depthUpdateEnabled > 0 && curZ < depth.r) { \n" -" depth.r = curZ; \n" -" imageStore(depth_image,coord,depth); \n" +" highp float bufZ = depth.g; \n" +" highp float curZ = gl_FragCoord.z; \n" +" highp float dz = fwidth(gl_FragCoord.z); \n" +" highp float dzMax = max(dz, depth.b); \n" +" const bool bInfront = curZ < bufZ; \n" +" const bool bFarther = (curZ + dzMax) >= bufZ; \n" +" const bool bNearer = (curZ - dzMax) <= bufZ; \n" +" const bool bMax = bufZ == 1.0; \n" +" bool bRes; \n" +" switch(depthMode) { \n" +" case 0: \n" +" case 1: \n" +" bRes = bMax || bNearer; \n" +" break; \n" +" case 2: \n" +" bRes = bMax || bInfront; \n" +" break; \n" +" case 3: \n" +" bRes = bFarther && bNearer && !bMax; \n" +" break; \n" +" default: \n" +" bRes = bInfront; \n" +" break; \n" +" } \n" +" if (depthUpdateEnabled > 0 && bRes) { \n" +" write_depth(dz, coord); \n" " } \n" -" memoryBarrier(); \n" " if (depthCompareEnabled > 0) \n" -" return curZ <= bufZ; \n" +" return bRes; \n" " return true; \n" "} \n" ; @@ -238,7 +231,7 @@ static const char* shadow_map_vertex_shader = static const char* shadow_map_fragment_shader_float = "#version 420 core \n" "layout(binding = 1, r16ui) uniform readonly uimage1D tlut_image;\n" -"layout(binding = 2, r32f) uniform readonly image2D depth_image;\n" +"layout(binding = 2, rgba32f) uniform readonly image2D depth_image;\n" "float get_alpha() \n" "{ \n" " ivec2 coord = ivec2(gl_FragCoord.xy); \n" @@ -253,23 +246,3 @@ static const char* shadow_map_fragment_shader_float = " gl_FragColor = vec4(gl_Fog.color.rgb, get_alpha()); \n" "} \n" ; - -static const char* shadow_map_fragment_shader_int = -"#version 420 core \n" -"layout(binding = 1, r16ui) uniform readonly uimage1D tlut_image;\n" -"layout(binding = 2, r16ui) uniform readonly uimage2D depth_image;\n" -"float get_alpha() \n" -"{ \n" -" ivec2 coord = ivec2(gl_FragCoord.xy); \n" -" unsigned int bufZ = imageLoad(depth_image,coord).r; \n" -" int index = min(255, int(bufZ/256)); \n" -" index += 80; \n" -" unsigned int iAlpha = imageLoad(tlut_image,index).r; \n" -" memoryBarrier(); \n" -" return float(iAlpha/256)/255.0; \n" -"} \n" -"void main() \n" -"{ \n" -" gl_FragColor = vec4(gl_Fog.color.rgb, get_alpha()); \n" -"} \n" -;