<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>