[Mesa-dev] MaxAnisotropy with GL_NEAREST on i965

Cody Northrop cody at lunarg.com
Thu May 22 14:45:28 PDT 2014


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?

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.

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);
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.freedesktop.org/archives/mesa-dev/attachments/20140522/53c26b7e/attachment.html>


More information about the mesa-dev mailing list