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);
_______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev