OSDN Git Service

Fix polygon offset depth clamp and units resolution.
authorNicolas Capens <capn@google.com>
Fri, 15 Sep 2017 15:49:31 +0000 (11:49 -0400)
committerNicolas Capens <nicolascapens@google.com>
Fri, 15 Sep 2017 17:20:24 +0000 (17:20 +0000)
OpenGL requires depth values to be clamped to the [0, 1] range. Due to
frustum clipping already limiting the range, this can only happen when
non-zero polygon offset parameters are active.

Also fix the 'minimum resolvable difference' for the 32-bit floating-
point internal depth format that we use.

Bug swiftshader:82

Change-Id: Ic9ebcac182a2bc81ab51d79cfe0bb451d340bd1e
Reviewed-on: https://swiftshader-review.googlesource.com/12108
Tested-by: Nicolas Capens <nicolascapens@google.com>
Reviewed-by: Alexis Hétu <sugoi@google.com>
Reviewed-by: Nicolas Capens <nicolascapens@google.com>
src/OpenGL/libGLESv2/Context.cpp
src/OpenGL/libGLESv2/utilities.cpp
src/Renderer/Context.cpp
src/Renderer/Context.hpp
src/Renderer/PixelProcessor.cpp
src/Renderer/PixelProcessor.hpp
src/Renderer/Renderer.cpp
src/Renderer/SetupProcessor.cpp
src/Renderer/SetupProcessor.hpp
src/Shader/PixelRoutine.cpp

index 6ca3c81..68129b6 100644 (file)
@@ -2180,7 +2180,8 @@ template<typename T> bool Context::getIntegerv(GLenum pname, T *params) const
                case GL_MAX_PROGRAM_TEXEL_OFFSET:
                        // Note: SwiftShader has no actual texel offset limit, so this limit can be modified if required.
                        // In any case, any behavior outside the specified range is valid since the spec mentions:
-                       // (see OpenGL ES 3.0.5, 3.8.10.1 Scale Factor and Level of Detail, p.153)\r                     // "If any of the offset values are outside the range of the  implementation-defined values
+                       // (see OpenGL ES 3.0.5, 3.8.10.1 Scale Factor and Level of Detail, p.153)
+                       // "If any of the offset values are outside the range of the  implementation-defined values
                        //  MIN_PROGRAM_TEXEL_OFFSET and MAX_PROGRAM_TEXEL_OFFSET, results of the texture lookup are
                        //  undefined."
                        *params = MAX_PROGRAM_TEXEL_OFFSET;
@@ -2221,7 +2222,8 @@ template<typename T> bool Context::getIntegerv(GLenum pname, T *params) const
                case GL_MIN_PROGRAM_TEXEL_OFFSET:
                        // Note: SwiftShader has no actual texel offset limit, so this limit can be modified if required.
                        // In any case, any behavior outside the specified range is valid since the spec mentions:
-                       // (see OpenGL ES 3.0.5, 3.8.10.1 Scale Factor and Level of Detail, p.153)\r                     // "If any of the offset values are outside the range of the  implementation-defined values
+                       // (see OpenGL ES 3.0.5, 3.8.10.1 Scale Factor and Level of Detail, p.153)
+                       // "If any of the offset values are outside the range of the  implementation-defined values
                        //  MIN_PROGRAM_TEXEL_OFFSET and MAX_PROGRAM_TEXEL_OFFSET, results of the texture lookup are
                        //  undefined."
                        *params = MIN_PROGRAM_TEXEL_OFFSET;
@@ -2855,7 +2857,7 @@ void Context::applyState(GLenum drawMode)
                        if(depthbuffer)
                        {
                                device->setSlopeDepthBias(mState.polygonOffsetFactor);
-                               float depthBias = ldexp(mState.polygonOffsetUnits, -(int)(depthbuffer->getDepthSize()));
+                               float depthBias = ldexp(mState.polygonOffsetUnits, -23);   // We use 32-bit floating-point for all depth formats, with 23 mantissa bits.
                                device->setDepthBias(depthBias);
                        }
                }
index 4257b69..4f95002 100644 (file)
@@ -1607,6 +1607,7 @@ namespace sw2es
        //      case sw::FORMAT_D32_LOCKABLE:  return 0;
        //      case sw::FORMAT_S8_LOCKABLE:   return 8;
                default:
+                       UNREACHABLE(stencilFormat);
                        return 0;
                }
        }
@@ -1642,6 +1643,7 @@ namespace sw2es
                case sw::FORMAT_R5G6B5:
                        return 0;
                default:
+                       UNREACHABLE(colorFormat);
                        return 0;
                }
        }
@@ -1705,6 +1707,7 @@ namespace sw2es
                case sw::FORMAT_R5G6B5:
                        return 5;
                default:
+                       UNREACHABLE(colorFormat);
                        return 0;
                }
        }
@@ -1759,6 +1762,7 @@ namespace sw2es
                case sw::FORMAT_R5G6B5:
                        return 6;
                default:
+                       UNREACHABLE(colorFormat);
                        return 0;
                }
        }
@@ -1802,6 +1806,7 @@ namespace sw2es
                case sw::FORMAT_R5G6B5:
                        return 5;
                default:
+                       UNREACHABLE(colorFormat);
                        return 0;
                }
        }
@@ -1827,7 +1832,9 @@ namespace sw2es
        //      case sw::FORMAT_S8_LOCKABLE:    return 0;
                case sw::FORMAT_D32FS8_SHADOW:
                case sw::FORMAT_D32FS8_TEXTURE: return 32;
-               default:                        return 0;
+               default:
+                       UNREACHABLE(depthFormat);
+                       return 0;
                }
        }
 
index e5ee4dc..45ad436 100644 (file)
@@ -276,6 +276,9 @@ namespace sw
                cullMode = CULL_CLOCKWISE;
                alphaReference = 0.0f;
 
+               depthBias = 0.0f;
+               slopeDepthBias = 0.0f;
+
                for(int i = 0; i < RENDERTARGETS; i++)
                {
                        colorWriteMask[i] = 0x0000000F;
index 640ec4e..6116794 100644 (file)
@@ -434,6 +434,9 @@ namespace sw
                CullMode cullMode;
                float alphaReference;
 
+               float depthBias;
+               float slopeDepthBias;
+
                TextureStage textureStage[8];
                Sampler sampler[TOTAL_IMAGE_UNITS];
 
index db11aed..abf6593 100644 (file)
@@ -990,6 +990,7 @@ namespace sw
                state.pixelFogMode = context->pixelFogActive();
                state.wBasedFog = context->wBasedFog && context->pixelFogActive() != FOG_NONE;
                state.perspective = context->perspectiveActive();
+               state.depthClamp = (context->depthBias != 0.0f) || (context->slopeDepthBias != 0.0f);
 
                if(context->alphaBlendActive())
                {
index 65f6b92..d3b0602 100644 (file)
@@ -66,6 +66,7 @@ namespace sw
                        bool occlusionEnabled                     : 1;
                        bool wBasedFog                            : 1;
                        bool perspective                          : 1;
+                       bool depthClamp                           : 1;
 
                        bool alphaBlendActive                     : 1;
                        BlendFactor sourceBlendFactor             : BITS(BLEND_LAST);
index 32e2027..0869697 100644 (file)
@@ -545,7 +545,7 @@ namespace sw
 
                                if(context->isDrawTriangle(false))
                                {
-                                       N += depthBias;
+                                       N += context->depthBias;
                                }
 
                                if(complementaryDepthBuffer)
@@ -583,7 +583,7 @@ namespace sw
                                data->halfPixelX = replicate(0.5f / W);
                                data->halfPixelY = replicate(0.5f / H);
                                data->viewportHeight = abs(viewport.height);
-                               data->slopeDepthBias = slopeDepthBias;
+                               data->slopeDepthBias = context->slopeDepthBias;
                                data->depthRange = Z;
                                data->depthNear = N;
                                draw->clipFlags = clipFlags;
@@ -2447,12 +2447,12 @@ namespace sw
 
        void Renderer::setDepthBias(float bias)
        {
-               depthBias = bias;
+               context->depthBias = bias;
        }
 
        void Renderer::setSlopeDepthBias(float slopeBias)
        {
-               slopeDepthBias = slopeBias;
+               context->slopeDepthBias = slopeBias;
        }
 
        void Renderer::setRasterizerDiscard(bool rasterizerDiscard)
index 772327f..bc456e9 100644 (file)
@@ -85,7 +85,7 @@ namespace sw
                state.pointSprite = context->pointSpriteActive();
                state.cullMode = context->cullMode;
                state.twoSidedStencil = context->stencilActive() && context->twoSidedStencil;
-               state.slopeDepthBias = slopeDepthBias != 0.0f;
+               state.slopeDepthBias = context->slopeDepthBias != 0.0f;
                state.vFace = context->pixelShader && context->pixelShader->isVFaceDeclared();
 
                state.positionRegister = Pos;
index 2750d4c..be0adc7 100644 (file)
@@ -95,9 +95,6 @@ namespace sw
 
                void setRoutineCacheSize(int cacheSize);
 
-               float depthBias;
-               float slopeDepthBias;
-
        private:
                Context *const context;
 
index 44fafd3..48a86a1 100644 (file)
@@ -95,6 +95,11 @@ namespace sw
                                }
 
                                z[q] = interpolate(x, Dz[q], z[q], primitive + OFFSET(Primitive,z), false, false);
+
+                               if(state.depthClamp)
+                               {
+                                       z[q] = Min(Max(z[q], Float4(0.0f)), Float4(1.0f));
+                               }
                        }
                }