[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