[Piglit] [PATCH] EXT_multisampled_render_to_texture: functional test

Ian Romanick idr at freedesktop.org
Thu Dec 17 13:02:26 PST 2015


On 12/16/2015 06:33 AM, Magnus Wendt wrote:
> EXT_multisampled_render_to_texture allows you to bind a singlesampled
> texture to the color attachment of a multisampled framebuffer object.
> Rendering is multisampled and the multisample data is implicitly
> resolved and invalidated when texturing.
> 
> The test renders a ground truth image by drawing a slanted textured quad
> to a multisampled fbo and resolves it using a blit to a singlesampled
> fbo. This is textured onto the left half of the window.
> It then renders the same thing into an implicitly resolved fbo and
> textures that onto the right half of the screen. The two halfs are
> compared. This is repeated for another slant and different clear colors
> to check for possible interactions with fast clear.
> The test passes if the two methods yeild identical results for all image

                                     yield

> pairs.

We'll also need a couple additional tests.  At the very least, we need
an api-errors test.  There are many that you can borrow from.

    If RenderbufferStorageMultisampleEXT is called with a value of
    <samples> that is greater than MAX_SAMPLES_EXT, then the error
    INVALID_VALUE is generated.

    The error INVALID_ENUM is generated if FramebufferTexture2DMultisampleEXT 
    is called with a <target> that is not FRAMEBUFFER.

    The error INVALID_ENUM is generated if FramebufferTexture2DMultisampleEXT
    is called with an <attachment> that is not COLOR_ATTACHMENT0.

    The error INVALID_ENUM is generated if FramebufferTexture2DMultisampleEXT 
    is called with a <textarget> that is not TEXTURE_2D, 
    TEXTURE_CUBE_MAP_POSITIVE_X, TEXTURE_CUBE_MAP_POSITIVE_Y, 
    TEXTURE_CUBE_MAP_POSITIVE_Z, TEXTURE_CUBE_MAP_NEGATIVE_X, 
    TEXTURE_CUBE_MAP_NEGATIVE_Y, or TEXTURE_CUBE_MAP_NEGATIVE_Z.

The errors section neglects to mention this error from earlier in the spec:

    If either width or height is greater than the value of
    MAX_RENDERBUFFER_SIZE ... then the error INVALID_VALUE is generated.

We also need a minmax test for GL_MAX_SAMPLES_EXT.  Copy from
tests/spec/arb_shader_subroutine/minmax.c.

I'd also like to see a test for this bit:

        Otherwise samples represents a request for a desired minimum number 
        of samples. Since different implementations may support different 
        sample counts for multisampled rendering, the actual number of samples 
        allocated for the renderbuffer image is implementation-dependent. 
        However, the resulting value for RENDERBUFFER_SAMPLES_EXT is 
        guaranteed to be greater than or equal to samples and no more than the
        next larger sample count supported by the implementation.

On GLES3, the set of possible sample counts can be determined using

    glGetInternalformativ(GL_RENDERBUFFER, /* or GL_TEXTURE_2D_MULTISAMPLE */
                          GL_RGB8,
                          GL_SAMPLES,
                          ARRAY_SIZE(buffer),
                          buffer);

> Signed-off-by: Magnus Wendt <magnus.wendt at intel.com>
> ---
>  tests/all.py                                       |   7 +
>  tests/spec/CMakeLists.txt                          |   1 +
>  .../CMakeLists.gles3.txt                           |   5 +
>  .../CMakeLists.txt                                 |   1 +
>  .../ext_multisampled_render_to_texture.c           | 367 +++++++++++++++++++++
>  5 files changed, 381 insertions(+)
>  create mode 100644 tests/spec/ext_multisampled_render_to_texture/CMakeLists.gles3.txt
>  create mode 100644 tests/spec/ext_multisampled_render_to_texture/CMakeLists.txt
>  create mode 100644 tests/spec/ext_multisampled_render_to_texture/ext_multisampled_render_to_texture.c
> 
> diff --git a/tests/all.py b/tests/all.py
> index f61ff15..c17450b 100644
> --- a/tests/all.py
> +++ b/tests/all.py
> @@ -4552,5 +4552,12 @@ with profile.group_manager(
>      for sample_count in (str(x) for x in MSAA_SAMPLE_COUNTS):
>          g(['ext_shader_samples_identical', sample_count])
>  
> +# Group EXT_multismapled_render_to_texture
> +with profile.group_manager(
> +        PiglitGLTest,
> +        grouptools.join('spec', 'ext_multisampled_render_to_texture')) as g:
> +    for sample_count in (str(x) for x in MSAA_SAMPLE_COUNTS):
> +        g(['ext_multisampled_render_to_texture', sample_count])
> +
>  if platform.system() is 'Windows':
>      profile.filter_tests(lambda p, _: not p.startswith('glx'))
> diff --git a/tests/spec/CMakeLists.txt b/tests/spec/CMakeLists.txt
> index 57ac541..21ec666 100644
> --- a/tests/spec/CMakeLists.txt
> +++ b/tests/spec/CMakeLists.txt
> @@ -75,6 +75,7 @@ add_subdirectory (ext_depth_bounds_test)
>  add_subdirectory (ext_fog_coord)
>  add_subdirectory (ext_framebuffer_multisample)
>  add_subdirectory (ext_framebuffer_multisample_blit_scaled)
> +add_subdirectory (ext_multisampled_render_to_texture)
>  add_subdirectory (ext_packed_depth_stencil)
>  add_subdirectory (ext_packed_float)
>  add_subdirectory (ext_shader_samples_identical)
> diff --git a/tests/spec/ext_multisampled_render_to_texture/CMakeLists.gles3.txt b/tests/spec/ext_multisampled_render_to_texture/CMakeLists.gles3.txt
> new file mode 100644
> index 0000000..fbb688c
> --- /dev/null
> +++ b/tests/spec/ext_multisampled_render_to_texture/CMakeLists.gles3.txt
> @@ -0,0 +1,5 @@
> +link_libraries(
> +	piglitutil_${piglit_target_api}
> +	)
> +
> +piglit_add_executable(ext_multisampled_render_to_texture ext_multisampled_render_to_texture.c)

Since there are going to be multiple tests, you're going to need to
change this name.  The usual piglit pattern is to name the source file
something descriptive like render.c, and name the executable
extension_name-source_name.

> diff --git a/tests/spec/ext_multisampled_render_to_texture/CMakeLists.txt b/tests/spec/ext_multisampled_render_to_texture/CMakeLists.txt
> new file mode 100644
> index 0000000..144a306
> --- /dev/null
> +++ b/tests/spec/ext_multisampled_render_to_texture/CMakeLists.txt
> @@ -0,0 +1 @@
> +piglit_include_target_api()
> diff --git a/tests/spec/ext_multisampled_render_to_texture/ext_multisampled_render_to_texture.c b/tests/spec/ext_multisampled_render_to_texture/ext_multisampled_render_to_texture.c
> new file mode 100644
> index 0000000..6a7cb02
> --- /dev/null
> +++ b/tests/spec/ext_multisampled_render_to_texture/ext_multisampled_render_to_texture.c
> @@ -0,0 +1,367 @@
> +/*
> + * Copyright (c) 2015 Intel Corporation
> + *
> + * Permission is hereby granted, free of charge, to any person obtaining a
> + * copy of this software and associated documentation files (the "Software"),
> + * to deal in the Software without restriction, including without limitation
> + * the rights to use, copy, modify, merge, publish, distribute, sublicense,
> + * and/or sell copies of the Software, and to permit persons to whom the
> + * Software is furnished to do so, subject to the following conditions:
> + *
> + * The above copyright notice and this permission notice (including the next
> + * paragraph) shall be included in all copies or substantial portions of the
> + * Software.
> + *
> + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
> + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
> + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
> + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
> + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
> + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
> + * DEALINGS IN THE SOFTWARE.
> + */
> +
> +/** \file ext_multisampled_render_to_texture.c
> + * Functional test for EXT_multisampled_render_to_texture.
> + *
> + * The test renders a ground truth image by drawing a slanted textured quad
> + * to a multisampled fbo and resolves it using a blit to a singlesampled fbo.
> + * This is textured onto the left half of the window.
> + * It then renders the same thing into an implicitly resolved fbo and textures
> + * that onto the right half of the screen. The two halfs are compared. This is
> + * repeated for another slant and different clear colors to check for possible
> + * interactions with fast clear.
> + * The test passes if the two methods yeild identical results for all image
> + * pairs.
> + *
> + */
> +
> +#include "piglit-util-gl.h"
> +
> +#define TEX_HEIGHT (8)
> +#define TEX_WIDTH (8)
> +#define FBO_HEIGHT (32)
> +#define FBO_WIDTH (32)
> +#define FB_HEIGHT (64)
> +#define FB_WIDTH (2*FB_HEIGHT)
> +
> +PIGLIT_GL_TEST_CONFIG_BEGIN
> +	/* multisampled FBO used for ground truth req ES 3.0 */
> +	config.supports_gl_es_version = 30;
> +	config.window_visual = PIGLIT_GL_VISUAL_RGB
> +	                     | PIGLIT_GL_VISUAL_DOUBLE
> +	                     | PIGLIT_GL_VISUAL_DEPTH;
> +	config.window_width  = FB_WIDTH;
> +	config.window_height = FB_HEIGHT;
> +PIGLIT_GL_TEST_CONFIG_END
> +
> +#define SOURCE(x) # x

That's clever.  I like it.

> +static const GLchar vshader_src[] = "#version 100\n" SOURCE(
> +	attribute vec4 piglit_vertex;
> +	attribute vec2 piglit_texcoord;
> +	varying vec2 coord_fs;
> +
> +	void main()
> +	{
> +		gl_Position =  piglit_vertex;
> +		coord_fs = piglit_texcoord;
> +	}
> +);
> +
> +static const GLchar fshader_src[] = "#version 100\n" SOURCE(
> +	precision highp float;
> +	varying vec2 coord_fs;
> +	uniform sampler2D tex;
> +
> +	void main()
> +	{
> +		gl_FragColor = texture2D(tex, coord_fs);
> +	}
> +);
> +
> +static GLuint tex_check;
> +
> +static struct {
> +	GLuint fbo;
> +	GLuint color;
> +	GLuint depth;
> +} fbo_ms, fbo_ss, fbo_impl;
> +
> +static GLuint basic_tex_prog, tex_loc;
> +
> +int result = PIGLIT_PASS;

It looks like this is only used in piglit_display, so it should be used
there.

Also, the idiom in piglit is to have a bool named pass.  pass starts
out set to true.  When a failure condition is detected, it is set to
false.  At the end of the function that is going to generate a result,

    return pass ? PIGLIT_PASS : PIGLIT_FAIL;

or

    piglit_report_result(pass ? PIGLIT_PASS : PIGLIT_FAIL);

> +
> +static GLubyte tex_data[TEX_HEIGHT][TEX_WIDTH][3];
> +
> +static void gen_texdata(void)
> +{
> +	int x,y;
> +	for (y = 0; y < TEX_HEIGHT; ++y) {
> +		for (x = 0; x < TEX_WIDTH; ++x) {
> +			tex_data[y][x][0] = (GLubyte) (255.0f *
> +			                    ((float)x/(float)(TEX_WIDTH-1)));
> +			tex_data[y][x][1] = (GLubyte) (255.0f *
> +			                    ((float)y/(float)(TEX_HEIGHT-1)));
> +			tex_data[y][x][2] = 127;
> +		}
> +	}
> +	for (y = 0; y < TEX_HEIGHT; ++y) {
> +		for (x = 0; x < TEX_WIDTH; ++x) {
> +			if ((x^y)&1) {
> +				tex_data[y][x][0] /= 2;
> +				tex_data[y][x][1] /= 2;
> +				tex_data[y][x][2] = 64;
> +			}
> +		}
> +	}
> +}
> +
> +enum piglit_result
> +piglit_display(void)
> +{
> +	static GLfloat quad1_verts[4][4] = {
> +		{ -0.7,  -0.9, 0, 1 },
> +		{  0.9,  -0.7, 0, 1 },
> +		{ -0.9,   0.7, 0, 1 },
> +		{  0.7,   0.9, 0, 1 },
> +	};
> +
> +	static GLfloat quad2_verts[4][4] = {
> +		{ -0.9,  -0.7, 0, 1 },
> +		{  0.7,  -0.9, 0, 1 },
> +		{ -0.7,   0.9, 0, 1 },
> +		{  0.9,   0.7, 0, 1 },
> +	};
> +
> +	static const GLfloat tex_coords[4][2] = {
> +		{ 0.0, 0.0 },
> +		{ 1.0, 0.0 },
> +		{ 0.0, 1.0 },
> +		{ 1.0, 1.0 },
> +	};
> +
> +	GLfloat white[] = {1.0, 1.0, 1.0, 1.0};
> +	GLfloat gray[] = {0.5, 0.5, 0.5, 0.0};
> +
> +	/* Run the test in multiple passes with different geometry and
> +	 * different clear colors to catch possible interactions with fast
> +	 * clear.
> +	 */
> +	GLfloat *test_config[4][2] = {
> +		{ gray,  &quad1_verts[0][0] },
> +		{ gray,  &quad2_verts[0][0] },
> +		{ white, &quad1_verts[0][0] },
> +		{ white, &quad2_verts[0][0] }
> +	};

You'll be shocked and appalled by the code generated by the compiler
when you don't 'static const' decorate all of this.  It's enough to
make a grown man cry.

> +
> +	int i;
> +	for (i = 0; i < 4; i++) {

        for (unsigned i = 0; i < ARRAY_SIZE(test_config); i++) {

> +		GLfloat *clear_color = test_config[i][0];
> +		GLfloat *quad_verts  = test_config[i][1];
> +
> +		glClearColor(clear_color[0], clear_color[1],
> +		             clear_color[2], clear_color[3]);
> +		glUseProgram(basic_tex_prog);
> +		tex_loc = glGetUniformLocation(basic_tex_prog, "tex");
> +		glUniform1i(tex_loc, 0);

glUseProgram is already done in piglit_init, and the rest should be as
well.  You can also omit setting "tex" to zero.  That is the default
value for all uniforms per the GLSL spec.

> +
> +		/*** Explicit Resolve (ground truth) ***/
> +		/* Draw quad into MS renderbuffer */
> +		glBindFramebuffer(GL_FRAMEBUFFER, fbo_ms.fbo);
> +		glViewport(0, 0, FBO_WIDTH, FBO_HEIGHT);
> +		glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
> +
> +		glBindTexture(GL_TEXTURE_2D, tex_check);
> +		piglit_draw_rect_from_arrays(quad_verts, tex_coords, false);
> +
> +		/* Do the explicit multisample resolve */
> +		glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo_ms.fbo);
> +		glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo_ss.fbo);
> +		glBlitFramebuffer(0, 0, FBO_WIDTH, FBO_HEIGHT,
> +		                  0, 0, FBO_WIDTH, FBO_HEIGHT,
> +		                  GL_COLOR_BUFFER_BIT, GL_NEAREST);
> +
> +		/* draw the result to the left side of the frame buffer */
> +		glBindFramebuffer(GL_FRAMEBUFFER, 0);
> +		glViewport(0, 0, FB_WIDTH/2, FB_HEIGHT);
> +		glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
> +
> +		glBindTexture(GL_TEXTURE_2D, fbo_ss.color);
> +		piglit_draw_rect_tex(-1, -1, 2, 2, 0, 0, 1, 1);

It seems like this could be simpler... can you make fbo_ms half the
width of the default framebuffer and just resolve directly from fbo_ms
to the default framebuffer?

Also... instead of using 0, I think you need to use piglit_winsys_fbo.
Otherwise the test will not work properly when run with -fbo.

> +
> +		piglit_check_gl_error(GL_NO_ERROR);

                pass = piglit_check_gl_error(GL_NO_ERROR) && pass;

> +
> +		/*** Implicit Resolve ***/
> +		/* Draw quad into MSAA texture */
> +		glBindFramebuffer(GL_FRAMEBUFFER, fbo_impl.fbo);
> +		glViewport(0, 0, FBO_WIDTH, FBO_HEIGHT);
> +		glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
> +
> +		glBindTexture(GL_TEXTURE_2D, tex_check);
> +		piglit_draw_rect_from_arrays(quad_verts, tex_coords, false);
> +
> +		/* draw the result to the right side of the frame buffer */
> +		glBindFramebuffer(GL_FRAMEBUFFER, 0);
> +		glViewport(FB_WIDTH/2, 0, FB_WIDTH/2, FB_HEIGHT);
> +
> +		glBindTexture(GL_TEXTURE_2D, fbo_impl.color);
> +		piglit_draw_rect_tex(-1, -1, 2, 2, 0, 0, 1, 1);
> +
> +		/*** Compare the results ***/
> +		if (!piglit_probe_rect_halves_equal_rgba(0, 0, FB_WIDTH,
> +		                                         FB_HEIGHT)) {

Does the spec actually require that the results be identical?

> +			result = PIGLIT_FAIL;
> +			printf("Test failed during pass %d\n", i);
> +		}
> +
> +		piglit_present_results();

Avoid tests that overdraw previous results.  The whole point of showing
the test result is to enable debugging.  If test 1 fails, tests 2 and 3
will draw over it... so why did you bother showing it in the first
place?

It is easy enough in this case to make the window 4x tall and display
all four results.

> +	}
> +	return result;
> +}
> +
> +
> +void
> +piglit_init(int argc, char **argv)
> +{
> +	int samples = 0, samples_impl = 0, samples_expl = 0;
> +
> +	GLint max_samples;
> +
> +	piglit_require_extension("GL_EXT_multisampled_render_to_texture");
> +
> +	if (argc < 2) {
> +		fprintf(stderr, "Usage: %s <sample_count>\n", argv[0]);
> +		piglit_report_result(PIGLIT_SKIP);
> +	}
> +
> +	samples = strtoul(argv[1], NULL, 0);
> +	glGetIntegerv(GL_MAX_SAMPLES, &max_samples);
> +	if (samples > max_samples) {
> +		piglit_report_result(PIGLIT_SKIP);
> +	}
> +
> +	/* Create primary texture */
> +	gen_texdata();
> +	glGenTextures(1, &tex_check);
> +	glActiveTexture( GL_TEXTURE0 );
> +	glBindTexture(GL_TEXTURE_2D, tex_check);
> +	glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, TEX_WIDTH, TEX_HEIGHT, 0,
> +	             GL_RGB, GL_UNSIGNED_BYTE, tex_data);
> +	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
> +	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
> +	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
> +	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
> +
> +	/* Create multisampled FBO for explicit resolve (ground truth) */
> +	glGenFramebuffers(1, &fbo_ms.fbo);
> +	glBindFramebuffer(GL_FRAMEBUFFER, fbo_ms.fbo);
> +
> +	/* depth */
> +	glGenRenderbuffers(1, &fbo_ms.depth);
> +	glBindRenderbuffer(GL_RENDERBUFFER, fbo_ms.depth);
> +	glRenderbufferStorageMultisample(GL_RENDERBUFFER, samples,
> +	                                 GL_DEPTH_COMPONENT16,
> +	                                 FBO_WIDTH, FBO_HEIGHT);
> +	glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
> +	                          GL_RENDERBUFFER, fbo_ms.depth);

Do you actually need a depth buffer?

> +
> +	/* color */
> +	glGenRenderbuffers(1, &fbo_ms.color);
> +	glBindRenderbuffer(GL_RENDERBUFFER, fbo_ms.color);
> +	glRenderbufferStorageMultisample(GL_RENDERBUFFER, samples, GL_RGB8,
> +	                                 FBO_WIDTH, FBO_HEIGHT);
> +	glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
> +	                          GL_RENDERBUFFER, fbo_ms.color);
> +
> +	if (glCheckFramebufferStatus(GL_FRAMEBUFFER)
> +	                          != GL_FRAMEBUFFER_COMPLETE) {
> +		printf("Multisampled framebuffer is incomplete");
> +		piglit_report_result(PIGLIT_FAIL);
> +	}
> +
> +	glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_SAMPLES,
> +	                             &samples_expl);
> +
> +	/* Create singlesampled FBO for explicit resolve (ground truth) */
> +	glGenFramebuffers(1, &fbo_ss.fbo);
> +	glBindFramebuffer(GL_FRAMEBUFFER, fbo_ss.fbo);
> +
> +	/* color */
> +	glGenTextures(1, &fbo_ss.color);
> +	glBindTexture(GL_TEXTURE_2D, fbo_ss.color);
> +	glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8, FBO_WIDTH, FBO_HEIGHT, 0,
> +	             GL_RGB, GL_UNSIGNED_BYTE, 0);
> +	glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
> +	glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
> +	glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
> +	glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
> +	glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
> +	                       GL_TEXTURE_2D, fbo_ss.color, 0);
> +
> +	if (glCheckFramebufferStatus(GL_FRAMEBUFFER)
> +	                          != GL_FRAMEBUFFER_COMPLETE) {
> +		printf("Singlesampled framebuffer is incomplete");
> +		piglit_report_result(PIGLIT_FAIL);
> +	}
> +
> +	/* Create FBO for implicit resolve */
> +	glGenFramebuffers(1, &fbo_impl.fbo);
> +	glBindFramebuffer(GL_FRAMEBUFFER, fbo_impl.fbo);
> +
> +	/* depth */
> +	glGenRenderbuffers(1, &fbo_impl.depth);
> +	glBindRenderbuffer(GL_RENDERBUFFER, fbo_impl.depth);
> +	glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER, samples,
> +	                                    GL_DEPTH_COMPONENT16,
> +	                                    FBO_WIDTH, FBO_HEIGHT);
> +	glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
> +	                          GL_RENDERBUFFER, fbo_impl.depth);
> +
> +	/* color */
> +	glGenTextures(1, &fbo_impl.color);
> +	glBindTexture(GL_TEXTURE_2D, fbo_impl.color);
> +	glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8, FBO_WIDTH, FBO_HEIGHT, 0,
> +	             GL_RGB, GL_UNSIGNED_BYTE, 0);
> +	glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
> +	glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
> +	glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
> +	glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
> +	glFramebufferTexture2DMultisampleEXT(GL_FRAMEBUFFER,
> +	                                     GL_COLOR_ATTACHMENT0,
> +	                                     GL_TEXTURE_2D, fbo_impl.color, 0,
> +	                                     samples);
> +
> +	if (glCheckFramebufferStatus(GL_FRAMEBUFFER)
> +	                          != GL_FRAMEBUFFER_COMPLETE) {
> +		printf("Implicitly resolved multisampled framebuffer is incomplete");
> +		piglit_report_result(PIGLIT_FAIL);
> +	}
> +
> +	glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER,
> +			GL_COLOR_ATTACHMENT0,
> +			GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_SAMPLES_EXT,
> +			&samples_impl);
> +
> +	glBindRenderbuffer(GL_RENDERBUFFER, 0);
> +	glBindFramebuffer(GL_FRAMEBUFFER, 0);

                                          piglit_winsys_fbo

> +
> +	glDisable(GL_CULL_FACE);
> +	glEnable(GL_DEPTH_TEST);
> +
> +	/* Test that we get the same number of samples for the two methods */
> +
> +	if (samples_impl != samples_expl) {
> +		printf("samples_expl: %d, samples_impl: %d\n",
> +		        samples_expl, samples_impl);
> +		piglit_report_result(PIGLIT_FAIL);
> +	}
> +
> +	/* create basic texturing shader */
> +	basic_tex_prog = piglit_build_simple_program(vshader_src,
> +	                                             fshader_src);
> +	glUseProgram(basic_tex_prog);
> +
> +	if (!piglit_check_gl_error(GL_NO_ERROR)) {
> +		piglit_report_result(PIGLIT_FAIL);
> +	}
> +}



More information about the Piglit mailing list