[Mesa-dev] MaxAnisotropy with GL_NEAREST on i965

Ian Romanick idr at freedesktop.org
Tue Jun 10 12:12:59 PDT 2014


On 05/22/2014 02:45 PM, Cody Northrop wrote:
> Greetings,
> 
> I ran into a problem with how Mesa on i965 handles MaxAnisotropy.
> 
> The app I'm looking at sets sampler state min and mag filters to
> GL_NEAREST, but also sets GL_TEXTURE_MAX_ANISOTROPY_EXT, like so:
> 
>      glSamplerParameteri(pointSampler, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
>      glSamplerParameteri(pointSampler, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
>      glSamplerParameteri(pointSampler, GL_TEXTURE_MAX_ANISOTROPY_EXT, 8);
> 
> On Nvidia closed source and Intel closed source drivers, MaxAnisotropy
> is ignored and unfiltered texture results are returned.  In this case,
> solid red.
> 
> Using Haswell with Mesa, MaxAnisotropy trumps GL_NEAREST, and the texels
> are filtered, returning almost greyscale values.  See
> gen7_update_sampler_state().
> 
> According to the extension, both behaviors are allowed:
> 
>     http://www.opengl.org/registry/specs/EXT/texture_filter_anisotropic.txt
> 
>     Implementations are free to use the specified minification and
>     magnification filter to select a particular anisotropic texture
>     filtering scheme.  For example, a NEAREST filter with a maximum
>     degree of anisotropy of two could be treated as a 2-tap filter that
>     accounts for the direction of anisotropy.  Implementations are also
>     permitted to ignore the minification or magnification filter and
>     implement the highest quality of anisotropic filtering possible.
> 
> So no one is at fault here, it's just different.  What's the policy for
> ambiguities like this?  Should i965 match other vendors?  Or emit a
> warning that requested filter mode is being overridden? 

There are a lot of places in the spec that are explicitly undefined.  We
have a couple different strategies for dealing with those.  When we
notice (and I don't think we ever noticed this particular case):

A. Pick the easiest behavior that some other vendor also does.

B. If all other vendors do the same thing, do that and submit a spec bug.

For "other vendors" we generally just look at the other vendors
available on Linux: AMD and NVIDIA.  We may also look at the Intel
Windows driver and Apple.

Do you know what AMD does in this case?

> Below are modifications to a piglit test that show the problem.  I
> couldn't find any existing tests for EXT_texture_filter_anisotropic. 
> The changes fill a single LOD texture with interleaved colors, then
> expects a single unfiltered red color back, but i965 returns greenish brown.

If we're going to decide that one behavior is correct, we should have a
test for it.  However, that test should be able to run on as many GPUs
that Mesa supports as possible.  It should be pretty easy to make a test
that just uses OpenGL 1.2 + GL_EXT_texture_filter_anisotropic.

It is not at all surprising that there are no tests for this extension.
 Any new tests added should go in tests/spec/ext_texture_filter_anisotropic.

> Thanks,
> 
> -Cody
> 
> 
> 
> diff --git
> a/tests/spec/arb_separate_shader_objects/rendezvous_by_location.c
> b/tests/spec/arb_separate_shader_objects/rendezvous_by_location.c
> index 4193ea5..7e83890 100644
> --- a/tests/spec/arb_separate_shader_objects/rendezvous_by_location.c
> +++ b/tests/spec/arb_separate_shader_objects/rendezvous_by_location.c
> @@ -95,6 +95,7 @@ static const char *fs_code_same_location_order_template =
>         "#version %d\n"
>         "#extension GL_ARB_separate_shader_objects: require\n"
>         "#extension GL_ARB_explicit_attrib_location: enable\n"
> +       "#extension GL_ARB_shading_language_420pack: require\n"
>         "\n"
>         "#if __VERSION__ >= 130\n"
>         "layout(location = 0) out vec4 out_color;\n"
> @@ -104,13 +105,53 @@ static const char
> *fs_code_same_location_order_template =
>         "\n"
>         "layout(location = 2) in vec3 b; /* should get vec3(0, 0, 1) */\n"
>         "layout(location = 3) in vec3 a; /* should get vec3(1, 0, 0) */\n"
> +       "layout(binding = 10) uniform sampler2D interleavedTexture;\n"
>         "\n"
>         "void main()\n"
>         "{\n"
> -       "    out_color = vec4(cross(b, a), 1);\n"
> +       "    out_color = texture2D(interleavedTexture, vec2(0.0, 0.0));\n"
>         "}\n"
>         ;
>  
> +/**
> + * Create a an image with 3 interleaved colors.
> + */
> +static GLubyte *
> +create_interleaved_image(GLint w, GLint h, const GLubyte red[4], const
> GLubyte green[4], const GLubyte blue[4])
> +{
> +       GLubyte *buf = (GLubyte *) malloc(w * h * 4);
> +       int i;
> +       for (i = 0; i < w * h; i++) {
> +
> +               switch(i % 3) {
> +               case 0:
> +                       buf[i*4+0] = red[0];
> +                       buf[i*4+1] = red[1];
> +                       buf[i*4+2] = red[2];
> +                       buf[i*4+3] = red[3];
> +                       break;
> +
> +               case 1:
> +                       buf[i*4+0] = green[0];
> +                       buf[i*4+1] = green[1];
> +                       buf[i*4+2] = green[2];
> +                       buf[i*4+3] = green[3];
> +                       break;
> +
> +               case 2:
> +                       buf[i*4+0] = blue[0];
> +                       buf[i*4+1] = blue[1];
> +                       buf[i*4+2] = blue[2];
> +                       buf[i*4+3] = blue[3];
> +                       break;
> +
> +               default:
> +                       break;
> +               }
> +       }
> +       return buf;
> +}
> +
>  enum piglit_result
>  piglit_display(void)
>  {
> @@ -119,6 +160,73 @@ piglit_display(void)
>         };
>         bool pass;
>  
> +       static GLubyte redColors[][4] = {
> +               {255,   0,   0, 255},
> +               {255,   0,   0, 255},
> +               {255,   0,   0, 255},
> +               {255,   0,   0, 255},
> +               {255,   0,   0, 255},
> +               {255,   0,   0, 255},
> +               {255,   0,   0, 255},
> +               {255,   0,   0, 255},
> +               {255,   0,   0, 255},
> +               {255,   0,   0, 255}
> +       };
> +
> +       static GLubyte greenColors[][4] = {
> +               {  0, 255,   0, 255},
> +               {  0, 255,   0, 255},
> +               {  0, 255,   0, 255},
> +               {  0, 255,   0, 255},
> +               {  0, 255,   0, 255},
> +               {  0, 255,   0, 255},
> +               {  0, 255,   0, 255},
> +               {  0, 255,   0, 255},
> +               {  0, 255,   0, 255},
> +               {  0, 255,   0, 255}
> +       };
> +
> +       static GLubyte blueColors[][4] = {
> +               {  0,   0, 255, 255},
> +               {  0,   0, 255, 255},
> +               {  0,   0, 255, 255},
> +               {  0,   0, 255, 255},
> +               {  0,   0, 255, 255},
> +               {  0,   0, 255, 255},
> +               {  0,   0, 255, 255},
> +               {  0,   0, 255, 255},
> +               {  0,   0, 255, 255},
> +               {  0,   0, 255, 255}
> +       };
> +
> +       GLuint interleavedTex;
> +       GLuint pointSampler;
> +       GLint width = 128, height = 64, levels = 1;
> +       GLint level = 0;
> +
> +       GLubyte *interleavedBuf = create_interleaved_image(width,
> height, redColors[level], greenColors[level], blueColors[level]);
> +
> +       glGenTextures(1, &interleavedTex);
> +       glBindTexture(GL_TEXTURE_2D, interleavedTex);
> +       glTexStorage2D(GL_TEXTURE_2D, levels, GL_RGBA8, width, height);
> +       piglit_check_gl_error(GL_NO_ERROR);
> +       glTexSubImage2D(GL_TEXTURE_2D, level, 0, 0, width, height,
> GL_RGBA, GL_UNSIGNED_BYTE, interleavedBuf);
> +       glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
> +       glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
> +       glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, level);
> +       glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, level);
> +
> +       glGenSamplers(1, &pointSampler);
> +       glSamplerParameteri(pointSampler, GL_TEXTURE_MIN_FILTER,
> GL_NEAREST);
> +       glSamplerParameteri(pointSampler, GL_TEXTURE_MAG_FILTER,
> GL_NEAREST);
> +
> +       // setting MaxAnisotropy causes GL_NEAREST to be ignored
> +       glSamplerParameteri(pointSampler, GL_TEXTURE_MAX_ANISOTROPY_EXT, 8);
> +
> +       glActiveTexture(GL_TEXTURE10);
> +       glBindTexture(GL_TEXTURE_2D, interleavedTex);
> +       glBindSampler(10, pointSampler);
> +
>         glClearColor(0.1f, 0.1f, 0.1f, 0.1f);
>         glClear(GL_COLOR_BUFFER_BIT);
> 
> 
> 
> _______________________________________________
> mesa-dev mailing list
> mesa-dev at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/mesa-dev
> 



More information about the mesa-dev mailing list