Commit 010a4648 by Alexis Hetu Committed by Alexis Hétu

Add texture filtering precision hint

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/10708Tested-by: 's avatarAlexis Hétu <sugoi@google.com> Reviewed-by: 's avatarAlexis Hétu <sugoi@google.com>
parent 14534b56
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
...@@ -100,6 +100,7 @@ Context::Context(egl::Display *display, const Context *shareContext, EGLint clie ...@@ -100,6 +100,7 @@ Context::Context(egl::Display *display, const Context *shareContext, EGLint clie
mState.rasterizerDiscardEnabled = false; mState.rasterizerDiscardEnabled = false;
mState.generateMipmapHint = GL_DONT_CARE; mState.generateMipmapHint = GL_DONT_CARE;
mState.fragmentShaderDerivativeHint = GL_DONT_CARE; mState.fragmentShaderDerivativeHint = GL_DONT_CARE;
mState.textureFilteringHint = GL_DONT_CARE;
mState.lineWidth = 1.0f; mState.lineWidth = 1.0f;
...@@ -682,6 +683,11 @@ void Context::setFragmentShaderDerivativeHint(GLenum hint) ...@@ -682,6 +683,11 @@ void Context::setFragmentShaderDerivativeHint(GLenum hint)
// Ignore for now. It is valid for implementations to ignore 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) void Context::setViewportParams(GLint x, GLint y, GLsizei width, GLsizei height)
{ {
mState.viewportX = x; mState.viewportX = x;
...@@ -1890,6 +1896,7 @@ template<typename T> bool Context::getIntegerv(GLenum pname, T *params) const ...@@ -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_UNPACK_ALIGNMENT: *params = mState.unpackInfo.alignment; return true;
case GL_GENERATE_MIPMAP_HINT: *params = mState.generateMipmapHint; 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_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_ACTIVE_TEXTURE: *params = (mState.activeSampler + GL_TEXTURE0); return true;
case GL_STENCIL_FUNC: *params = mState.stencilFunc; return true; case GL_STENCIL_FUNC: *params = mState.stencilFunc; return true;
case GL_STENCIL_REF: *params = mState.stencilRef; 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 ...@@ -2425,6 +2432,7 @@ bool Context::getQueryParameterInfo(GLenum pname, GLenum *type, unsigned int *nu
case GL_UNPACK_ALIGNMENT: case GL_UNPACK_ALIGNMENT:
case GL_GENERATE_MIPMAP_HINT: case GL_GENERATE_MIPMAP_HINT:
case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES: case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES:
case GL_TEXTURE_FILTERING_HINT_CHROMIUM:
case GL_RED_BITS: case GL_RED_BITS:
case GL_GREEN_BITS: case GL_GREEN_BITS:
case GL_BLUE_BITS: case GL_BLUE_BITS:
...@@ -3058,6 +3066,7 @@ void Context::applyTextures(sw::SamplerType samplerType) ...@@ -3058,6 +3066,7 @@ void Context::applyTextures(sw::SamplerType samplerType)
device->setTextureFilter(samplerType, samplerIndex, es2sw::ConvertTextureFilter(minFilter, magFilter, maxAnisotropy)); device->setTextureFilter(samplerType, samplerIndex, es2sw::ConvertTextureFilter(minFilter, magFilter, maxAnisotropy));
device->setMipmapFilter(samplerType, samplerIndex, es2sw::ConvertMipMapFilter(minFilter)); device->setMipmapFilter(samplerType, samplerIndex, es2sw::ConvertMipMapFilter(minFilter));
device->setMaxAnisotropy(samplerType, samplerIndex, maxAnisotropy); device->setMaxAnisotropy(samplerType, samplerIndex, maxAnisotropy);
device->setHighPrecisionFiltering(samplerType, samplerIndex, mState.textureFilteringHint == GL_NICEST);
applyTexture(samplerType, samplerIndex, texture); applyTexture(samplerType, samplerIndex, texture);
} }
...@@ -4324,6 +4333,7 @@ const GLubyte *Context::getExtensions(GLuint index, GLuint *numExt) const ...@@ -4324,6 +4333,7 @@ const GLubyte *Context::getExtensions(GLuint index, GLuint *numExt) const
"GL_ANGLE_texture_compression_dxt3", "GL_ANGLE_texture_compression_dxt3",
"GL_ANGLE_texture_compression_dxt5", "GL_ANGLE_texture_compression_dxt5",
#endif #endif
"GL_CHROMIUM_texture_filtering_hint",
"GL_NV_fence", "GL_NV_fence",
"GL_NV_framebuffer_blit", "GL_NV_framebuffer_blit",
"GL_NV_read_depth", "GL_NV_read_depth",
......
...@@ -156,6 +156,8 @@ const GLenum compressedTextureFormats[] = ...@@ -156,6 +156,8 @@ const GLenum compressedTextureFormats[] =
#endif #endif
}; };
const GLenum GL_TEXTURE_FILTERING_HINT_CHROMIUM = 0x8AF0;
const GLint NUM_COMPRESSED_TEXTURE_FORMATS = sizeof(compressedTextureFormats) / sizeof(compressedTextureFormats[0]); const GLint NUM_COMPRESSED_TEXTURE_FORMATS = sizeof(compressedTextureFormats) / sizeof(compressedTextureFormats[0]);
const GLint multisampleCount[] = {4, 2, 1}; const GLint multisampleCount[] = {4, 2, 1};
...@@ -376,6 +378,7 @@ struct State ...@@ -376,6 +378,7 @@ struct State
GLenum generateMipmapHint; GLenum generateMipmapHint;
GLenum fragmentShaderDerivativeHint; GLenum fragmentShaderDerivativeHint;
GLenum textureFilteringHint;
GLint viewportX; GLint viewportX;
GLint viewportY; GLint viewportY;
...@@ -489,6 +492,7 @@ public: ...@@ -489,6 +492,7 @@ public:
void setGenerateMipmapHint(GLenum hint); void setGenerateMipmapHint(GLenum hint);
void setFragmentShaderDerivativeHint(GLenum hint); void setFragmentShaderDerivativeHint(GLenum hint);
void setTextureFilteringHint(GLenum hint);
void setViewportParams(GLint x, GLint y, GLsizei width, GLsizei height); void setViewportParams(GLint x, GLint y, GLsizei width, GLsizei height);
......
...@@ -4247,6 +4247,9 @@ void Hint(GLenum target, GLenum mode) ...@@ -4247,6 +4247,9 @@ void Hint(GLenum target, GLenum mode)
case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES: case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES:
if(context) context->setFragmentShaderDerivativeHint(mode); if(context) context->setFragmentShaderDerivativeHint(mode);
break; break;
case GL_TEXTURE_FILTERING_HINT_CHROMIUM:
if(context) context->setTextureFilteringHint(mode);
break;
default: default:
return error(GL_INVALID_ENUM); return error(GL_INVALID_ENUM);
} }
......
...@@ -444,6 +444,15 @@ namespace sw ...@@ -444,6 +444,15 @@ namespace sw
else ASSERT(false); 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) void PixelProcessor::setSwizzleR(unsigned int sampler, SwizzleType swizzleR)
{ {
if(sampler < TEXTURE_IMAGE_UNITS) if(sampler < TEXTURE_IMAGE_UNITS)
......
...@@ -231,6 +231,7 @@ namespace sw ...@@ -231,6 +231,7 @@ namespace sw
void setMipmapLOD(unsigned int sampler, float bias); void setMipmapLOD(unsigned int sampler, float bias);
void setBorderColor(unsigned int sampler, const Color<float> &borderColor); void setBorderColor(unsigned int sampler, const Color<float> &borderColor);
void setMaxAnisotropy(unsigned int sampler, float maxAnisotropy); void setMaxAnisotropy(unsigned int sampler, float maxAnisotropy);
void setHighPrecisionFiltering(unsigned int sampler, bool highPrecisionFiltering);
void setSwizzleR(unsigned int sampler, SwizzleType swizzleR); void setSwizzleR(unsigned int sampler, SwizzleType swizzleR);
void setSwizzleG(unsigned int sampler, SwizzleType swizzleG); void setSwizzleG(unsigned int sampler, SwizzleType swizzleG);
void setSwizzleB(unsigned int sampler, SwizzleType swizzleB); void setSwizzleB(unsigned int sampler, SwizzleType swizzleB);
......
...@@ -2314,6 +2314,18 @@ namespace sw ...@@ -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) void Renderer::setSwizzleR(SamplerType type, int sampler, SwizzleType swizzleR)
{ {
if(type == SAMPLER_PIXEL) if(type == SAMPLER_PIXEL)
......
...@@ -345,6 +345,7 @@ namespace sw ...@@ -345,6 +345,7 @@ namespace sw
void setMipmapLOD(SamplerType type, int sampler, float bias); void setMipmapLOD(SamplerType type, int sampler, float bias);
void setBorderColor(SamplerType type, int sampler, const Color<float> &borderColor); void setBorderColor(SamplerType type, int sampler, const Color<float> &borderColor);
void setMaxAnisotropy(SamplerType type, int sampler, float maxAnisotropy); 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 setSwizzleR(SamplerType type, int sampler, SwizzleType swizzleR);
void setSwizzleG(SamplerType type, int sampler, SwizzleType swizzleG); void setSwizzleG(SamplerType type, int sampler, SwizzleType swizzleG);
void setSwizzleB(SamplerType type, int sampler, SwizzleType swizzleB); void setSwizzleB(SamplerType type, int sampler, SwizzleType swizzleB);
......
...@@ -60,6 +60,7 @@ namespace sw ...@@ -60,6 +60,7 @@ namespace sw
mipmapFilterState = MIPMAP_NONE; mipmapFilterState = MIPMAP_NONE;
sRGB = false; sRGB = false;
gather = false; gather = false;
highPrecisionFiltering = false;
swizzleR = SWIZZLE_RED; swizzleR = SWIZZLE_RED;
swizzleG = SWIZZLE_GREEN; swizzleG = SWIZZLE_GREEN;
...@@ -97,6 +98,7 @@ namespace sw ...@@ -97,6 +98,7 @@ namespace sw
state.swizzleG = swizzleG; state.swizzleG = swizzleG;
state.swizzleB = swizzleB; state.swizzleB = swizzleB;
state.swizzleA = swizzleA; state.swizzleA = swizzleA;
state.highPrecisionFiltering = highPrecisionFiltering;
#if PERF_PROFILE #if PERF_PROFILE
state.compressedFormat = Surface::isCompressed(externalTextureFormat); state.compressedFormat = Surface::isCompressed(externalTextureFormat);
...@@ -298,6 +300,11 @@ namespace sw ...@@ -298,6 +300,11 @@ namespace sw
texture.maxAnisotropy = maxAnisotropy; texture.maxAnisotropy = maxAnisotropy;
} }
void Sampler::setHighPrecisionFiltering(bool highPrecisionFiltering)
{
this->highPrecisionFiltering = highPrecisionFiltering;
}
void Sampler::setSwizzleR(SwizzleType swizzleR) void Sampler::setSwizzleR(SwizzleType swizzleR)
{ {
this->swizzleR = swizzleR; this->swizzleR = swizzleR;
......
...@@ -140,6 +140,7 @@ namespace sw ...@@ -140,6 +140,7 @@ namespace sw
SwizzleType swizzleG : BITS(SWIZZLE_LAST); SwizzleType swizzleG : BITS(SWIZZLE_LAST);
SwizzleType swizzleB : BITS(SWIZZLE_LAST); SwizzleType swizzleB : BITS(SWIZZLE_LAST);
SwizzleType swizzleA : BITS(SWIZZLE_LAST); SwizzleType swizzleA : BITS(SWIZZLE_LAST);
bool highPrecisionFiltering : 1;
#if PERF_PROFILE #if PERF_PROFILE
bool compressedFormat : 1; bool compressedFormat : 1;
...@@ -163,6 +164,7 @@ namespace sw ...@@ -163,6 +164,7 @@ namespace sw
void setReadSRGB(bool sRGB); void setReadSRGB(bool sRGB);
void setBorderColor(const Color<float> &borderColor); void setBorderColor(const Color<float> &borderColor);
void setMaxAnisotropy(float maxAnisotropy); void setMaxAnisotropy(float maxAnisotropy);
void setHighPrecisionFiltering(bool highPrecisionFiltering);
void setSwizzleR(SwizzleType swizzleR); void setSwizzleR(SwizzleType swizzleR);
void setSwizzleG(SwizzleType swizzleG); void setSwizzleG(SwizzleType swizzleG);
void setSwizzleB(SwizzleType swizzleB); void setSwizzleB(SwizzleType swizzleB);
...@@ -202,6 +204,7 @@ namespace sw ...@@ -202,6 +204,7 @@ namespace sw
MipmapType mipmapFilterState; MipmapType mipmapFilterState;
bool sRGB; bool sRGB;
bool gather; bool gather;
bool highPrecisionFiltering;
SwizzleType swizzleR; SwizzleType swizzleR;
SwizzleType swizzleG; SwizzleType swizzleG;
......
...@@ -602,6 +602,15 @@ namespace sw ...@@ -602,6 +602,15 @@ namespace sw
else ASSERT(false); 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) void VertexProcessor::setSwizzleR(unsigned int sampler, SwizzleType swizzleR)
{ {
if(sampler < VERTEX_TEXTURE_IMAGE_UNITS) if(sampler < VERTEX_TEXTURE_IMAGE_UNITS)
......
...@@ -258,6 +258,7 @@ namespace sw ...@@ -258,6 +258,7 @@ namespace sw
void setMipmapLOD(unsigned int sampler, float bias); void setMipmapLOD(unsigned int sampler, float bias);
void setBorderColor(unsigned int sampler, const Color<float> &borderColor); void setBorderColor(unsigned int sampler, const Color<float> &borderColor);
void setMaxAnisotropy(unsigned int stage, float maxAnisotropy); void setMaxAnisotropy(unsigned int stage, float maxAnisotropy);
void setHighPrecisionFiltering(unsigned int sampler, bool highPrecisionFiltering);
void setSwizzleR(unsigned int sampler, SwizzleType swizzleR); void setSwizzleR(unsigned int sampler, SwizzleType swizzleR);
void setSwizzleG(unsigned int sampler, SwizzleType swizzleG); void setSwizzleG(unsigned int sampler, SwizzleType swizzleG);
void setSwizzleB(unsigned int sampler, SwizzleType swizzleB); void setSwizzleB(unsigned int sampler, SwizzleType swizzleB);
......
...@@ -314,7 +314,7 @@ namespace sw ...@@ -314,7 +314,7 @@ namespace sw
} }
else else
{ {
if(hasFloatTexture()) // FIXME: Mostly identical to integer sampling if(hasFloatTexture() || state.highPrecisionFiltering) // FIXME: Mostly identical to integer sampling
{ {
Float4 uuuu = u; Float4 uuuu = u;
Float4 vvvv = v; Float4 vvvv = v;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment