[Piglit] [PATCH 2/2] multisample/formats: Check for spec-complient integer resolves
Matt Turner
mattst88 at gmail.com
Tue May 10 21:42:03 UTC 2016
On Wed, May 4, 2016 at 4:23 PM, Jason Ekstrand <jason at jlekstrand.net> wrote:
> The i965 driver has historically done integer multisample resolves with a
> sort of integer averaging operation. The spec used to not really say
> anything at all about integer formats when discussing multisampling. Since
> the tests were written, the spec has been substantially clerified. The new
> rule is that integer MSAA resolves are supposed to pick a single arbitrary
> sample for each texel rather than trying to combine them in any way.
>
> Signed-off-by: Jason Ekstrand <jason at jlekstrand.net>
> ---
> tests/spec/ext_framebuffer_multisample/formats.cpp | 196 ++++++++++++++++-----
> 1 file changed, 155 insertions(+), 41 deletions(-)
>
> diff --git a/tests/spec/ext_framebuffer_multisample/formats.cpp b/tests/spec/ext_framebuffer_multisample/formats.cpp
> index 4b1feba..1024b45 100644
> --- a/tests/spec/ext_framebuffer_multisample/formats.cpp
> +++ b/tests/spec/ext_framebuffer_multisample/formats.cpp
> @@ -70,6 +70,44 @@ ColorGradientSunburst *test_pattern_vec4;
> ColorGradientSunburst *test_pattern_ivec4;
> ColorGradientSunburst *test_pattern_uvec4;
>
> +struct int_resolve_check_s {
> + GLuint prog;
> + GLint u_resolve;
> + GLint u_msaa;
> + GLint u_samples;
> +} int_resolve_check;
> +
> +const char int_resolve_check_vs[] =
> + "#version 130\n"
> + "in vec4 piglit_vertex;\n"
> + "void main() {\n"
> + " gl_Position = piglit_vertex;\n"
> + "}\n";
> +
> +/* The OpenGL ES 3.2 and OpenGL 4.4 specs both state:
> + *
> + * "If the source for- mats are integer types or stencil values, a
formats
> + * single sample’s value is selected for each pixel."
smart quote
> + *
> + * This shader checks exactly that condition, namely that the result of the
> + * resolve is exactly one of the sample values in the original image.
> + */
> +const char int_resolve_check_fs[] =
> + "#version 130\n"
> + "#extension GL_ARB_texture_multisample: require\n"
> + "uniform isampler2DMS msaa;\n"
> + "uniform isampler2D resolve;\n"
> + "uniform int samples;\n"
> + "void main() {\n"
> + " gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);\n"
> + " const vec4 green = vec4(0.0, 1.0, 0.0, 1.0);\n"
> + " ivec2 pos = ivec2(gl_FragCoord.xy);\n"
> + " ivec4 res = texelFetch(resolve, pos, 0);\n"
> + " for (int s = 0; s < samples; s++) {\n"
> + " if (res == texelFetch(msaa, pos, s))\n"
> + " gl_FragColor = green;\n"
Could break here
> + " }\n"
> + "}\n";
>
> /**
> * This class encapsulates the code necessary to draw the test pattern
> @@ -80,7 +118,7 @@ ColorGradientSunburst *test_pattern_uvec4;
> class PatternRenderer
> {
> public:
> - bool try_setup(GLenum internalformat);
> + bool try_setup(GLenum internalformat, bool is_integer);
> void set_piglit_tolerance();
> void set_color_clamping_mode();
> void draw();
> @@ -140,11 +178,18 @@ public:
> * incomplete.
> */
> bool
> -PatternRenderer::try_setup(GLenum internalformat)
> +PatternRenderer::try_setup(GLenum internalformat, bool is_integer)
> {
> FboConfig config_downsampled(0, pattern_width, pattern_height);
> config_downsampled.color_internalformat = internalformat;
>
> + if (is_integer) {
> + config_downsampled.color_format = GL_RGBA_INTEGER;
> + config_downsampled.num_rb_attachments = 0;
> + config_downsampled.num_tex_attachments = 1;
> + config_downsampled.use_rect = false;
> + }
> +
> FboConfig config_msaa = config_downsampled;
> config_msaa.num_samples = num_samples;
>
> @@ -497,7 +542,9 @@ test_format(const struct format_desc *format)
> * supported, we might have received a GL error. In either
> * case just skip to the next format.
> */
> - bool setup_success = test_renderer.try_setup(format->internalformat);
> + bool is_integer = (test_sets[test_index].basetype == GL_INT);
> + bool setup_success = test_renderer.try_setup(format->internalformat,
> + is_integer);
> if (glGetError() != GL_NO_ERROR) {
> printf("Error setting up test renderbuffers\n");
> return PIGLIT_SKIP;
> @@ -511,7 +558,8 @@ test_format(const struct format_desc *format)
> * This shouldn't fail.
> */
> setup_success = ref_renderer.try_setup(test_renderer.is_srgb ?
> - GL_SRGB8_ALPHA8 : GL_RGBA);
> + GL_SRGB8_ALPHA8 : GL_RGBA,
> + false);
> if (!piglit_check_gl_error(GL_NO_ERROR)) {
> printf("Error setting up reference renderbuffers\n");
> return PIGLIT_FAIL;
> @@ -521,50 +569,99 @@ test_format(const struct format_desc *format)
> return PIGLIT_FAIL;
> }
>
> - /* Draw test and reference images, and read them into memory */
> - test_renderer.set_piglit_tolerance();
> test_renderer.draw();
> float *test_image =
> test_renderer.read_image(format->base_internal_format);
> - ref_renderer.draw();
> - float *ref_image = ref_renderer.read_image(GL_RGBA);
> -
> - /* Compute the expected image from the reference image */
> - float *expected_image =
> - compute_expected_image(ref_image,
> - format->base_internal_format);
> -
> - /* Check that the test image was correct */
> - unsigned num_components =
> - piglit_num_components(format->base_internal_format);
> - float tolerance[4];
> - piglit_compute_probe_tolerance(format->base_internal_format,
> - tolerance);
> - pass = piglit_compare_images_color(0, 0, pattern_width, pattern_height,
> - num_components, tolerance,
> - expected_image, test_image);
> -
> -
> - /* Show both the test and expected images on screen so that
> - * the user can diagnose problems. Pass image_count = 0 to
> - * display image without any offset applied to raster position.
> - */
> - glViewport(0, 0, piglit_width, piglit_height);
> - piglit_visualize_image(test_image, format->base_internal_format,
> - pattern_width, pattern_height,
> - 0 /* image_count */,
> - false /* rhs */);
> - piglit_visualize_image(expected_image, format->base_internal_format,
> - pattern_width, pattern_height,
> - 0 /* image_count */,
> - true /* rhs */);
> +
> + if (is_integer) {
> + Fbo compare_fbo;
> + compare_fbo.setup(FboConfig(0, pattern_width, pattern_height));
> +
> + glBindFramebuffer(GL_DRAW_FRAMEBUFFER, compare_fbo.handle);
> +
> + glUseProgram(int_resolve_check.prog);
> + glUniform1i(int_resolve_check.u_msaa, 0);
> + glUniform1i(int_resolve_check.u_resolve, 1);
> + glUniform1i(int_resolve_check.u_samples, num_samples);
> +
> + glActiveTexture(GL_TEXTURE0);
> + glBindTexture(GL_TEXTURE_2D_MULTISAMPLE,
> + test_renderer.fbo_msaa.color_tex[0]);
> +
> + glActiveTexture(GL_TEXTURE1);
> + glBindTexture(GL_TEXTURE_2D,
> + test_renderer.fbo_downsampled.color_tex[0]);
> +
> + glViewport(0, 0, pattern_width, pattern_height);
> + piglit_draw_rect(-1.0, -1.0, 2.0, 2.0);
> +
> + glBindFramebuffer(GL_READ_FRAMEBUFFER, compare_fbo.handle);
> +
> + const float green[] = { 0.0, 1.0, 0.0, 1.0 };
> + pass = piglit_probe_rect_rgb(0, 0, pattern_width,
> + pattern_height, green);
> +
> + /* Show both the test image and the check result on screen
> + * so that the user can diagnose problems.
> + */
> + glViewport(0, 0, piglit_width, piglit_height);
> + piglit_visualize_image(test_image, format->base_internal_format,
> + pattern_width, pattern_height,
> + 0 /* image_count */,
> + false /* rhs */);
> +
> + glBindFramebuffer(GL_READ_FRAMEBUFFER, compare_fbo.handle);
> + glBindFramebuffer(GL_DRAW_FRAMEBUFFER, piglit_winsys_fbo);
> + glBlitFramebuffer(0, 0, pattern_width, pattern_height,
> + pattern_width, 0,
> + pattern_width * 2, pattern_height,
> + GL_COLOR_BUFFER_BIT, GL_NEAREST);
> + } else {
> + /* Draw test and reference images, and read them into memory */
> + test_renderer.set_piglit_tolerance();
> + ref_renderer.draw();
> + float *ref_image = ref_renderer.read_image(GL_RGBA);
> +
> + /* Compute the expected image from the reference image */
> + float *expected_image =
> + compute_expected_image(ref_image,
> + format->base_internal_format);
> +
> + /* Check that the test image was correct */
> + unsigned num_components =
> + piglit_num_components(format->base_internal_format);
> + float tolerance[4];
> + piglit_compute_probe_tolerance(format->base_internal_format,
> + tolerance);
> + pass = piglit_compare_images_color(0, 0, pattern_width,
> + pattern_height,
> + num_components, tolerance,
> + expected_image, test_image);
> +
> +
> + /* Show both the test and expected images on screen so that
> + * the user can diagnose problems. Pass image_count = 0 to
> + * display image without any offset applied to raster position.
> + */
> + glViewport(0, 0, piglit_width, piglit_height);
> + piglit_visualize_image(test_image, format->base_internal_format,
> + pattern_width, pattern_height,
> + 0 /* image_count */,
> + false /* rhs */);
> + piglit_visualize_image(expected_image,
> + format->base_internal_format,
> + pattern_width, pattern_height,
> + 0 /* image_count */,
> + true /* rhs */);
> +
> + free(ref_image);
> + free(expected_image);
> + }
>
> /* Finally, if any error occurred, count that as a failure. */
> pass = piglit_check_gl_error(GL_NO_ERROR) && pass;
>
> free(test_image);
> - free(ref_image);
> - free(expected_image);
>
> return pass ? PIGLIT_PASS : PIGLIT_FAIL;
> }
> @@ -613,13 +710,30 @@ piglit_init(int argc, char **argv)
>
> fbo_formats_init_test_set(test_set,
> GL_TRUE /* print_options */);
> +
> + bool is_integer = (test_sets[test_index].basetype == GL_INT);
> +
> test_pattern_vec4 = new ColorGradientSunburst(GL_UNSIGNED_NORMALIZED);
> test_pattern_vec4->compile();
> - if (piglit_get_gl_version() >= 30) {
> + if (is_integer) {
> + piglit_require_gl_version(30);
> + piglit_require_extension("GL_ARB_texture_multisample");
> +
> test_pattern_ivec4 = new ColorGradientSunburst(GL_INT);
> test_pattern_ivec4->compile();
> test_pattern_uvec4 = new ColorGradientSunburst(GL_UNSIGNED_INT);
> test_pattern_uvec4->compile();
> +
> + int_resolve_check.prog =
> + piglit_build_simple_program(int_resolve_check_vs,
> + int_resolve_check_fs);
> + glUseProgram(int_resolve_check.prog);
> + int_resolve_check.u_resolve =
> + glGetUniformLocation(int_resolve_check.prog, "resolve");
> + int_resolve_check.u_msaa =
> + glGetUniformLocation(int_resolve_check.prog, "msaa");
> + int_resolve_check.u_samples =
> + glGetUniformLocation(int_resolve_check.prog, "samples");
> }
> }
>
> --
Both are
Reviewed-by: Matt Turner <mattst88 at gmail.com>
More information about the Piglit
mailing list