<div dir="ltr">Greetings,<br><br>I ran into a problem with how Mesa on i965 handles <span style="font-family:courier new,monospace">MaxAnisotropy</span>.<br><br>The app I'm looking at sets sampler state min and mag filters to <span style="font-family:courier new,monospace">GL_NEAREST</span>, but also sets <span style="font-family:courier new,monospace">GL_TEXTURE_MAX_ANISOTROPY_EXT</span>, like so:<br>
<br><span style="font-family:courier new,monospace">     glSamplerParameteri(pointSampler, GL_TEXTURE_MIN_FILTER, GL_NEAREST);<br>     glSamplerParameteri(</span><span style="font-family:courier new,monospace"><span style="font-family:courier new,monospace">pointSampler</span>, GL_TEXTURE_MAG_FILTER, GL_NEAREST);<br>
     glSamplerParameteri(</span><span style="font-family:courier new,monospace"><span style="font-family:courier new,monospace">pointSampler</span>, GL_TEXTURE_MAX_ANISOTROPY_EXT, 8);</span><br><br>On Nvidia closed source and Intel closed source drivers, <span style="font-family:courier new,monospace">MaxAnisotropy</span> is ignored and unfiltered texture results are returned.  In this case, solid red.<br>
<br>Using Haswell with Mesa, <span style="font-family:courier new,monospace">MaxAnisotropy</span> trumps <span style="font-family:courier new,monospace">GL_NEAREST</span>, and the texels are filtered, returning almost greyscale values.  See <span style="font-family:courier new,monospace">gen7_update_sampler_state()</span>.<br>
<br>According to the extension, both behaviors are allowed:<br><br><span style="font-family:courier new,monospace">    <a href="http://www.opengl.org/registry/specs/EXT/texture_filter_anisotropic.txt">http://www.opengl.org/registry/specs/EXT/texture_filter_anisotropic.txt</a><br>
<br>    Implementations are free to use the specified minification and<br>    magnification filter to select a particular anisotropic texture<br>    filtering scheme.  For example, a NEAREST filter with a maximum<br>    degree of anisotropy of two could be treated as a 2-tap filter that<br>
    accounts for the direction of anisotropy.  Implementations are also<br>    permitted to ignore the minification or magnification filter and<br>    implement the highest quality of anisotropic filtering possible.</span><br>
<br>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?  <br><br>Below are modifications to a piglit test that show the problem.  I couldn't find any existing tests for <span style="font-family:courier new,monospace">EXT_texture_filter_anisotropic</span>.  The changes fill a single LOD texture with interleaved colors, then expects a single unfiltered red color back, but i965 returns greenish brown.<br>
<br>Thanks,<br><br>-Cody<br><br><br><br><span style="font-family:courier new,monospace">diff --git a/tests/spec/arb_separate_shader_objects/rendezvous_by_location.c b/tests/spec/arb_separate_shader_objects/rendezvous_by_location.c<br>
index 4193ea5..7e83890 100644<br>--- a/tests/spec/arb_separate_shader_objects/rendezvous_by_location.c<br>+++ b/tests/spec/arb_separate_shader_objects/rendezvous_by_location.c<br>@@ -95,6 +95,7 @@ static const char *fs_code_same_location_order_template =<br>
        "#version %d\n"<br>        "#extension GL_ARB_separate_shader_objects: require\n"<br>        "#extension GL_ARB_explicit_attrib_location: enable\n"<br>+       "#extension GL_ARB_shading_language_420pack: require\n"<br>
        "\n"<br>        "#if __VERSION__ >= 130\n"<br>        "layout(location = 0) out vec4 out_color;\n"<br>@@ -104,13 +105,53 @@ static const char *fs_code_same_location_order_template =<br>
        "\n"<br>        "layout(location = 2) in vec3 b; /* should get vec3(0, 0, 1) */\n"<br>        "layout(location = 3) in vec3 a; /* should get vec3(1, 0, 0) */\n"<br>+       "layout(binding = 10) uniform sampler2D interleavedTexture;\n"<br>
        "\n"<br>        "void main()\n"<br>        "{\n"<br>-       "    out_color = vec4(cross(b, a), 1);\n"<br>+       "    out_color = texture2D(</span><span style="font-family:courier new,monospace"><span style="font-family:courier new,monospace">interleavedTexture</span>, vec2(0.0, 0.0));\n"<br>
        "}\n"<br>        ;<br> <br>+/**<br>+ * Create a an image with 3 interleaved colors.<br>+ */<br>+static GLubyte *<br>+create_interleaved_image(GLint w, GLint h, const GLubyte red[4], const GLubyte green[4], const GLubyte blue[4])<br>
+{<br>+       GLubyte *buf = (GLubyte *) malloc(w * h * 4);<br>+       int i;<br>+       for (i = 0; i < w * h; i++) {<br>+<br>+               switch(i % 3) {<br>+               case 0:<br>+                       buf[i*4+0] = red[0];<br>
+                       buf[i*4+1] = red[1];<br>+                       buf[i*4+2] = red[2];<br>+                       buf[i*4+3] = red[3];<br>+                       break;<br>+<br>+               case 1:<br>+                       buf[i*4+0] = green[0];<br>
+                       buf[i*4+1] = green[1];<br>+                       buf[i*4+2] = green[2];<br>+                       buf[i*4+3] = green[3];<br>+                       break;<br>+<br>+               case 2:<br>+                       buf[i*4+0] = blue[0];<br>
+                       buf[i*4+1] = blue[1];<br>+                       buf[i*4+2] = blue[2];<br>+                       buf[i*4+3] = blue[3];<br>+                       break;<br>+<br>+               default:<br>+                       break;<br>
+               }<br>+       }<br>+       return buf;<br>+}<br>+<br> enum piglit_result<br> piglit_display(void)<br> {<br>@@ -119,6 +160,73 @@ piglit_display(void)<br>        };<br>        bool pass;<br> <br>+       static GLubyte redColors[][4] = {<br>
+               {255,   0,   0, 255},<br>+               {255,   0,   0, 255},<br>+               {255,   0,   0, 255},<br>+               {255,   0,   0, 255},<br>+               {255,   0,   0, 255},<br>+               {255,   0,   0, 255},<br>
+               {255,   0,   0, 255},<br>+               {255,   0,   0, 255},<br>+               {255,   0,   0, 255},<br>+               {255,   0,   0, 255}<br>+       };<br>+<br>+       static GLubyte greenColors[][4] = {<br>
+               {  0, 255,   0, 255},<br>+               {  0, 255,   0, 255},<br>+               {  0, 255,   0, 255},<br>+               {  0, 255,   0, 255},<br>+               {  0, 255,   0, 255},<br>+               {  0, 255,   0, 255},<br>
+               {  0, 255,   0, 255},<br>+               {  0, 255,   0, 255},<br>+               {  0, 255,   0, 255},<br>+               {  0, 255,   0, 255}<br>+       };<br>+<br>+       static GLubyte blueColors[][4] = {<br>
+               {  0,   0, 255, 255},<br>+               {  0,   0, 255, 255},<br>+               {  0,   0, 255, 255},<br>+               {  0,   0, 255, 255},<br>+               {  0,   0, 255, 255},<br>+               {  0,   0, 255, 255},<br>
+               {  0,   0, 255, 255},<br>+               {  0,   0, 255, 255},<br>+               {  0,   0, 255, 255},<br>+               {  0,   0, 255, 255}<br>+       };<br>+<br>+       GLuint interleavedTex;<br>+       GLuint pointSampler;<br>
+       GLint width = 128, height = 64, levels = 1;<br>+       GLint level = 0;<br>+<br>+       GLubyte *interleavedBuf = create_interleaved_image(width, height, redColors[level], greenColors[level], blueColors[level]);<br>
+<br>+       glGenTextures(1, &interleavedTex);<br>+       glBindTexture(GL_TEXTURE_2D, interleavedTex);<br>+       glTexStorage2D(GL_TEXTURE_2D, levels, GL_RGBA8, width, height);<br>+       piglit_check_gl_error(GL_NO_ERROR);<br>
+       glTexSubImage2D(GL_TEXTURE_2D, level, 0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, interleavedBuf);<br>+       glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);<br>+       glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);<br>
+       glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, level);<br>+       glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, level);<br>+<br>+       glGenSamplers(1, &pointSampler);<br>+       glSamplerParameteri(pointSampler, GL_TEXTURE_MIN_FILTER, GL_NEAREST);<br>
+       glSamplerParameteri(pointSampler, GL_TEXTURE_MAG_FILTER, GL_NEAREST);<br>+<br>+       // setting MaxAnisotropy causes GL_NEAREST to be ignored<br>+       glSamplerParameteri(pointSampler, GL_TEXTURE_MAX_ANISOTROPY_EXT, 8);<br>
+<br>+       glActiveTexture(GL_TEXTURE10);<br>+       glBindTexture(GL_TEXTURE_2D, interleavedTex);<br>+       glBindSampler(10, pointSampler);<br>+<br>        glClearColor(0.1f, 0.1f, 0.1f, 0.1f);<br>        glClear(GL_COLOR_BUFFER_BIT);</span><br>
<br></div>