OSDN Git Service

Add texture filtering precision hint
authorAlexis Hetu <sugoi@google.com>
Tue, 18 Jul 2017 18:33:04 +0000 (14:33 -0400)
committerAlexis Hétu <sugoi@google.com>
Wed, 19 Jul 2017 18:23:42 +0000 (18:23 +0000)
A new extension will be added to SwiftShader in order to allow
Chromium to trigger high precision filtering when necessary.
This extension is documented in:
extensions/CHROMIUM_texture_filtering_hint.txt

Bug swiftshader:76

Change-Id: I7c5b5c5fd01afbd7079e7949ecbd9c18fc539f2b
Reviewed-on: https://swiftshader-review.googlesource.com/10708
Tested-by: Alexis Hétu <sugoi@google.com>
Reviewed-by: Alexis Hétu <sugoi@google.com>
13 files changed:
extensions/CHROMIUM_texture_filtering_hint.txt [new file with mode: 0644]
src/OpenGL/libGLESv2/Context.cpp
src/OpenGL/libGLESv2/Context.h
src/OpenGL/libGLESv2/libGLESv2.cpp
src/Renderer/PixelProcessor.cpp
src/Renderer/PixelProcessor.hpp
src/Renderer/Renderer.cpp
src/Renderer/Renderer.hpp
src/Renderer/Sampler.cpp
src/Renderer/Sampler.hpp
src/Renderer/VertexProcessor.cpp
src/Renderer/VertexProcessor.hpp
src/Shader/SamplerCore.cpp

diff --git a/extensions/CHROMIUM_texture_filtering_hint.txt b/extensions/CHROMIUM_texture_filtering_hint.txt
new file mode 100644 (file)
index 0000000..38af6e0
--- /dev/null
@@ -0,0 +1,85 @@
+Name
+
+    CHROMIUM_texture_filtering_hint
+
+Name Strings
+
+    GL_CHROMIUM_texture_filtering_hint
+
+Contributors
+
+    Alexis Hetu, Google Inc.
+    Nicolas Capens, Google Inc.
+    Shannon Woods, Google Inc.
+
+Contact
+
+    Alexis Hetu, Google Inc. (sugoi 'at' chromium 'dot' org)
+
+Version
+
+    Last Modifed Date: July 18, 2017
+
+Dependencies
+
+    This extension is written against the OpenGL ES 2.0 specification.
+
+    OpenGL ES 2.0 is required.
+
+Overview
+
+    This extension defines a way to request high precision texture filtering
+    using a new value to Hint.
+
+    When this extension is enabled, TEXTURE_FILTERING_HINT_CHROMIUM can be used
+    by the implementation as a means to distinguish between a performance
+    focused implementation, using FASTEST, or a precision focused
+    implementation, using NICEST.
+
+    Like other hints, either option is spec compliant and the behavior of
+    DONT_CARE is implementation specific.
+
+New Tokens
+
+    Accepted by the <pname> parameter of GetIntegerv, GetFloatv and GetBooleanv
+    and by the <target> parameter of Hint:
+
+    TEXTURE_FILTERING_HINT_CHROMIUM      0x8AF0
+
+New Procedures and Functions
+
+    None.
+
+Errors
+
+    None.
+
+New State
+
+    None.
+
+Issues
+
+    1) When does the hint take effect?
+
+       At the time of the next draw call, and all subsequent draw calls.
+  
+    2) Does the first draw call after the filtering hint is changed use the
+       updated filtering method?
+
+       Yes
+    3) Can I switch it back and forth between every draw call, multiple times
+       during a single frame?
+
+       Yes
+    4) Do program objects which were created before the filtering hint was
+       changed and which contain sampling instructions use the filtering method
+       from when they were created, or the method at the time of draw call?
+
+       At the time of draw call.
+
+Revision History
+
+    2/7/2014    Documented the extension
index 2265aa6..c139068 100644 (file)
@@ -100,6 +100,7 @@ Context::Context(egl::Display *display, const Context *shareContext, EGLint clie
        mState.rasterizerDiscardEnabled = false;
        mState.generateMipmapHint = GL_DONT_CARE;
        mState.fragmentShaderDerivativeHint = GL_DONT_CARE;
+       mState.textureFilteringHint = GL_DONT_CARE;
 
        mState.lineWidth = 1.0f;
 
@@ -682,6 +683,11 @@ void Context::setFragmentShaderDerivativeHint(GLenum hint)
        // Ignore for now. It is valid for implementations to ignore hint.
 }
 
+void Context::setTextureFilteringHint(GLenum hint)
+{
+       mState.textureFilteringHint = hint;
+}
+
 void Context::setViewportParams(GLint x, GLint y, GLsizei width, GLsizei height)
 {
        mState.viewportX = x;
@@ -1890,6 +1896,7 @@ template<typename T> bool Context::getIntegerv(GLenum pname, T *params) const
        case GL_UNPACK_ALIGNMENT:                 *params = mState.unpackInfo.alignment;          return true;
        case GL_GENERATE_MIPMAP_HINT:             *params = mState.generateMipmapHint;            return true;
        case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES: *params = mState.fragmentShaderDerivativeHint; return true;
+       case GL_TEXTURE_FILTERING_HINT_CHROMIUM:  *params = mState.textureFilteringHint;          return true;
        case GL_ACTIVE_TEXTURE:                   *params = (mState.activeSampler + GL_TEXTURE0); return true;
        case GL_STENCIL_FUNC:                     *params = mState.stencilFunc;                   return true;
        case GL_STENCIL_REF:                      *params = mState.stencilRef;                    return true;
@@ -2425,6 +2432,7 @@ bool Context::getQueryParameterInfo(GLenum pname, GLenum *type, unsigned int *nu
        case GL_UNPACK_ALIGNMENT:
        case GL_GENERATE_MIPMAP_HINT:
        case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES:
+       case GL_TEXTURE_FILTERING_HINT_CHROMIUM:
        case GL_RED_BITS:
        case GL_GREEN_BITS:
        case GL_BLUE_BITS:
@@ -3058,6 +3066,7 @@ void Context::applyTextures(sw::SamplerType samplerType)
                                device->setTextureFilter(samplerType, samplerIndex, es2sw::ConvertTextureFilter(minFilter, magFilter, maxAnisotropy));
                                device->setMipmapFilter(samplerType, samplerIndex, es2sw::ConvertMipMapFilter(minFilter));
                                device->setMaxAnisotropy(samplerType, samplerIndex, maxAnisotropy);
+                               device->setHighPrecisionFiltering(samplerType, samplerIndex, mState.textureFilteringHint == GL_NICEST);
 
                                applyTexture(samplerType, samplerIndex, texture);
                        }
@@ -4324,6 +4333,7 @@ const GLubyte *Context::getExtensions(GLuint index, GLuint *numExt) const
                "GL_ANGLE_texture_compression_dxt3",
                "GL_ANGLE_texture_compression_dxt5",
 #endif
+               "GL_CHROMIUM_texture_filtering_hint",
                "GL_NV_fence",
                "GL_NV_framebuffer_blit",
                "GL_NV_read_depth",
index bbe6ddd..16e0aa2 100644 (file)
@@ -156,6 +156,8 @@ const GLenum compressedTextureFormats[] =
 #endif
 };
 
+const GLenum GL_TEXTURE_FILTERING_HINT_CHROMIUM = 0x8AF0;
+
 const GLint NUM_COMPRESSED_TEXTURE_FORMATS = sizeof(compressedTextureFormats) / sizeof(compressedTextureFormats[0]);
 
 const GLint multisampleCount[] = {4, 2, 1};
@@ -376,6 +378,7 @@ struct State
 
        GLenum generateMipmapHint;
        GLenum fragmentShaderDerivativeHint;
+       GLenum textureFilteringHint;
 
        GLint viewportX;
        GLint viewportY;
@@ -489,6 +492,7 @@ public:
 
        void setGenerateMipmapHint(GLenum hint);
        void setFragmentShaderDerivativeHint(GLenum hint);
+       void setTextureFilteringHint(GLenum hint);
 
        void setViewportParams(GLint x, GLint y, GLsizei width, GLsizei height);
 
index 920e1a0..dfe5959 100644 (file)
@@ -4247,6 +4247,9 @@ void Hint(GLenum target, GLenum mode)
        case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES:
                if(context) context->setFragmentShaderDerivativeHint(mode);
                break;
+       case GL_TEXTURE_FILTERING_HINT_CHROMIUM:
+               if(context) context->setTextureFilteringHint(mode);
+               break;
        default:
                return error(GL_INVALID_ENUM);
        }
index 172e8ef..db11aed 100644 (file)
@@ -444,6 +444,15 @@ namespace sw
                else ASSERT(false);
        }
 
+       void PixelProcessor::setHighPrecisionFiltering(unsigned int sampler, bool highPrecisionFiltering)
+       {
+               if(sampler < TEXTURE_IMAGE_UNITS)
+               {
+                       context->sampler[sampler].setHighPrecisionFiltering(highPrecisionFiltering);
+               }
+               else ASSERT(false);
+       }
+
        void PixelProcessor::setSwizzleR(unsigned int sampler, SwizzleType swizzleR)
        {
                if(sampler < TEXTURE_IMAGE_UNITS)
index 94d52d3..dd54b72 100644 (file)
@@ -231,6 +231,7 @@ namespace sw
                void setMipmapLOD(unsigned int sampler, float bias);
                void setBorderColor(unsigned int sampler, const Color<float> &borderColor);
                void setMaxAnisotropy(unsigned int sampler, float maxAnisotropy);
+               void setHighPrecisionFiltering(unsigned int sampler, bool highPrecisionFiltering);
                void setSwizzleR(unsigned int sampler, SwizzleType swizzleR);
                void setSwizzleG(unsigned int sampler, SwizzleType swizzleG);
                void setSwizzleB(unsigned int sampler, SwizzleType swizzleB);
index a84423d..a67ba22 100644 (file)
@@ -2314,6 +2314,18 @@ namespace sw
                }
        }
 
+       void Renderer::setHighPrecisionFiltering(SamplerType type, int sampler, bool highPrecisionFiltering)
+       {
+               if(type == SAMPLER_PIXEL)
+               {
+                       PixelProcessor::setHighPrecisionFiltering(sampler, highPrecisionFiltering);
+               }
+               else
+               {
+                       VertexProcessor::setHighPrecisionFiltering(sampler, highPrecisionFiltering);
+               }
+       }
+
        void Renderer::setSwizzleR(SamplerType type, int sampler, SwizzleType swizzleR)
        {
                if(type == SAMPLER_PIXEL)
index c59dd31..c29020f 100644 (file)
@@ -345,6 +345,7 @@ namespace sw
                void setMipmapLOD(SamplerType type, int sampler, float bias);
                void setBorderColor(SamplerType type, int sampler, const Color<float> &borderColor);
                void setMaxAnisotropy(SamplerType type, int sampler, float maxAnisotropy);
+               void setHighPrecisionFiltering(SamplerType type, int sampler, bool highPrecisionFiltering);
                void setSwizzleR(SamplerType type, int sampler, SwizzleType swizzleR);
                void setSwizzleG(SamplerType type, int sampler, SwizzleType swizzleG);
                void setSwizzleB(SamplerType type, int sampler, SwizzleType swizzleB);
index e2447e0..7d7d47c 100644 (file)
@@ -60,6 +60,7 @@ namespace sw
                mipmapFilterState = MIPMAP_NONE;
                sRGB = false;
                gather = false;
+               highPrecisionFiltering = false;
 
                swizzleR = SWIZZLE_RED;
                swizzleG = SWIZZLE_GREEN;
@@ -97,6 +98,7 @@ namespace sw
                        state.swizzleG = swizzleG;
                        state.swizzleB = swizzleB;
                        state.swizzleA = swizzleA;
+                       state.highPrecisionFiltering = highPrecisionFiltering;
 
                        #if PERF_PROFILE
                                state.compressedFormat = Surface::isCompressed(externalTextureFormat);
@@ -298,6 +300,11 @@ namespace sw
                texture.maxAnisotropy = maxAnisotropy;
        }
 
+       void Sampler::setHighPrecisionFiltering(bool highPrecisionFiltering)
+       {
+               this->highPrecisionFiltering = highPrecisionFiltering;
+       }
+
        void Sampler::setSwizzleR(SwizzleType swizzleR)
        {
                this->swizzleR = swizzleR;
index 4c4973d..288f179 100644 (file)
@@ -140,6 +140,7 @@ namespace sw
                        SwizzleType swizzleG           : BITS(SWIZZLE_LAST);
                        SwizzleType swizzleB           : BITS(SWIZZLE_LAST);
                        SwizzleType swizzleA           : BITS(SWIZZLE_LAST);
+                       bool highPrecisionFiltering    : 1;
 
                        #if PERF_PROFILE
                        bool compressedFormat          : 1;
@@ -163,6 +164,7 @@ namespace sw
                void setReadSRGB(bool sRGB);
                void setBorderColor(const Color<float> &borderColor);
                void setMaxAnisotropy(float maxAnisotropy);
+               void setHighPrecisionFiltering(bool highPrecisionFiltering);
                void setSwizzleR(SwizzleType swizzleR);
                void setSwizzleG(SwizzleType swizzleG);
                void setSwizzleB(SwizzleType swizzleB);
@@ -202,6 +204,7 @@ namespace sw
                MipmapType mipmapFilterState;
                bool sRGB;
                bool gather;
+               bool highPrecisionFiltering;
 
                SwizzleType swizzleR;
                SwizzleType swizzleG;
index 91c4d34..6972d94 100644 (file)
@@ -602,6 +602,15 @@ namespace sw
                else ASSERT(false);
        }
 
+       void VertexProcessor::setHighPrecisionFiltering(unsigned int sampler, bool highPrecisionFiltering)
+       {
+               if(sampler < TEXTURE_IMAGE_UNITS)
+               {
+                       context->sampler[sampler].setHighPrecisionFiltering(highPrecisionFiltering);
+               }
+               else ASSERT(false);
+       }
+
        void VertexProcessor::setSwizzleR(unsigned int sampler, SwizzleType swizzleR)
        {
                if(sampler < VERTEX_TEXTURE_IMAGE_UNITS)
index 278c9b1..3552f84 100644 (file)
@@ -258,6 +258,7 @@ namespace sw
                void setMipmapLOD(unsigned int sampler, float bias);
                void setBorderColor(unsigned int sampler, const Color<float> &borderColor);
                void setMaxAnisotropy(unsigned int stage, float maxAnisotropy);
+               void setHighPrecisionFiltering(unsigned int sampler, bool highPrecisionFiltering);
                void setSwizzleR(unsigned int sampler, SwizzleType swizzleR);
                void setSwizzleG(unsigned int sampler, SwizzleType swizzleG);
                void setSwizzleB(unsigned int sampler, SwizzleType swizzleB);
index 8c20f58..9bd977e 100644 (file)
@@ -314,7 +314,7 @@ namespace sw
                }
                else
                {
-                       if(hasFloatTexture())   // FIXME: Mostly identical to integer sampling
+                       if(hasFloatTexture() || state.highPrecisionFiltering)   // FIXME: Mostly identical to integer sampling
                        {
                                Float4 uuuu = u;
                                Float4 vvvv = v;