2 * Copyright © 2012, 2015 Intel Corporation
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
25 * @file blit-mismatched-formats.cpp
27 * This test verifies that calling glBlitFramebuffer to blit between
28 * two multisampled framebuffers works even if they have different
29 * formats. Note that originally the GL spec required that blitting
30 * between differing formats should report a GL_INVALID_OPERATION
31 * error. However in practice most drivers allowed it anyway and in
32 * the GL 4.4 spec the restriction was removed. I think it can be
33 * considered a mistake in the spec that this was not the case
34 * originally so this test assumes that it should be possible in any
37 * We initialize two FBOs with minimum supported sample count and
38 * different buffer formats, do blitting operation between them and
39 * verify the expected results.
41 * Authors: Anuj Phogat <anuj.phogat@gmail.com>
42 * Neil Roberts <neil@linux.intel.com>
45 #include "piglit-test-pattern.h"
46 #include "piglit-fbo.h"
47 using namespace piglit_util_fbo
;
48 using namespace piglit_util_test_pattern
;
50 PIGLIT_GL_TEST_CONFIG_BEGIN
52 config
.supports_gl_compat_version
= 10;
54 config
.window_width
= 256;
55 config
.window_height
= 256;
56 config
.window_visual
= PIGLIT_GL_VISUAL_DOUBLE
| PIGLIT_GL_VISUAL_RGB
;
57 config
.khr_no_error_support
= PIGLIT_NO_ERRORS
;
59 PIGLIT_GL_TEST_CONFIG_END
61 const int pattern_width
= 256; const int pattern_height
= 256;
62 Fbo src_fbo
, dst_fbo
, ss_fbo
;
63 ColorGradientSunburst
*test_pattern
;
64 GLfloat
*reference_image
;
67 COMPONENT_RED
= (1 << 0),
68 COMPONENT_GREEN
= (1 << 1),
69 COMPONENT_BLUE
= (1 << 2),
70 COMPONENT_ALPHA
= (1 << 3),
75 GLbitfield components
;
78 static struct color_format
80 { GL_ALPHA
, COMPONENT_ALPHA
},
81 { GL_RED
, COMPONENT_RED
},
82 { GL_RG
, COMPONENT_RED
| COMPONENT_GREEN
},
83 { GL_RGB
, COMPONENT_RED
| COMPONENT_GREEN
| COMPONENT_BLUE
}
87 generate_expected_image(const GLfloat
*ref_image
,
88 int pattern_width
, int pattern_height
,
89 GLbitfield components
)
91 GLfloat
*expected_image
= (GLfloat
*) malloc(pattern_width
*
94 GLfloat
*dst
= expected_image
;
95 const GLfloat
*src
= ref_image
;
98 for (i
= 0; i
< pattern_width
* pattern_height
; i
++) {
99 dst
[0] = (components
& COMPONENT_RED
) ? src
[0] : 0.0f
;
100 dst
[1] = (components
& COMPONENT_GREEN
) ? src
[1] : 0.0f
;
101 dst
[2] = (components
& COMPONENT_BLUE
) ? src
[2] : 0.0f
;
102 dst
[3] = (components
& COMPONENT_ALPHA
) ? src
[3] : 1.0f
;
107 return expected_image
;
114 GLfloat
*expected_image
;
117 FboConfig
config_ms(1 , pattern_width
, pattern_height
);
119 for(i
= 0; i
< ARRAY_SIZE(color_formats
); i
++) {
121 generate_expected_image(reference_image
,
122 pattern_width
, pattern_height
,
123 color_formats
[i
].components
);
125 config_ms
.color_internalformat
= color_formats
[i
].name
;
126 src_fbo
.setup(config_ms
);
128 if (!piglit_check_gl_error(GL_NO_ERROR
)) {
129 printf("Error setting up renderbuffer color format\n");
130 piglit_report_result(PIGLIT_FAIL
);
133 glBindFramebuffer(GL_FRAMEBUFFER
, src_fbo
.handle
);
134 test_pattern
->draw(TestPattern::no_projection
);
136 /* Blit multisample-to-multisample with non-matching formats */
137 glBindFramebuffer(GL_READ_FRAMEBUFFER
, src_fbo
.handle
);
138 glBindFramebuffer(GL_DRAW_FRAMEBUFFER
, dst_fbo
.handle
);
140 glClear(GL_COLOR_BUFFER_BIT
);
142 glBlitFramebuffer(0, 0, pattern_width
, pattern_height
,
143 0, 0, pattern_width
, pattern_height
,
144 GL_COLOR_BUFFER_BIT
, GL_NEAREST
);
146 /* Blitting between different formats shouldn't
149 pass
= piglit_check_gl_error(GL_NO_ERROR
) && pass
;
151 /* Downsample the blitted buffer so we can read the
154 glBindFramebuffer(GL_READ_FRAMEBUFFER
, dst_fbo
.handle
);
155 glBindFramebuffer(GL_DRAW_FRAMEBUFFER
, ss_fbo
.handle
);
156 glClear(GL_COLOR_BUFFER_BIT
);
157 glBlitFramebuffer(0, 0, pattern_width
, pattern_height
,
158 0, 0, pattern_width
, pattern_height
,
159 GL_COLOR_BUFFER_BIT
, GL_NEAREST
);
161 pass
= piglit_check_gl_error(GL_NO_ERROR
) && pass
;
163 glBindFramebuffer(GL_FRAMEBUFFER
, ss_fbo
.handle
);
164 pass
= piglit_probe_image_rgba(0, 0,
165 pattern_width
, pattern_height
,
166 expected_image
) && pass
;
168 /* Also try a downsample blit with mismatched formats
170 glBindFramebuffer(GL_READ_FRAMEBUFFER
, src_fbo
.handle
);
171 glBindFramebuffer(GL_DRAW_FRAMEBUFFER
, ss_fbo
.handle
);
172 glClear(GL_COLOR_BUFFER_BIT
);
173 glBlitFramebuffer(0, 0, pattern_width
, pattern_height
,
174 0, 0, pattern_width
, pattern_height
,
175 GL_COLOR_BUFFER_BIT
, GL_NEAREST
);
177 pass
= piglit_check_gl_error(GL_NO_ERROR
) && pass
;
179 glBindFramebuffer(GL_FRAMEBUFFER
, ss_fbo
.handle
);
180 pass
= piglit_probe_image_rgba(0, 0,
181 pattern_width
, pattern_height
,
182 expected_image
) && pass
;
184 /* Blit the result to the window system buffer so that
185 * something will be displayed in a non-automatic
188 glBindFramebuffer(GL_READ_FRAMEBUFFER
, ss_fbo
.handle
);
189 glBindFramebuffer(GL_DRAW_FRAMEBUFFER
, 0);
190 glClear(GL_COLOR_BUFFER_BIT
);
191 glBlitFramebuffer(0, 0, pattern_width
, pattern_height
,
192 0, 0, pattern_width
, pattern_height
,
193 GL_COLOR_BUFFER_BIT
, GL_NEAREST
);
195 pass
= piglit_check_gl_error(GL_NO_ERROR
) && pass
;
197 piglit_present_results();
199 free(expected_image
);
202 return (pass
? PIGLIT_PASS
: PIGLIT_FAIL
);
206 piglit_init(int argc
, char **argv
)
208 piglit_require_gl_version(21);
209 piglit_require_extension("GL_ARB_framebuffer_object");
210 piglit_require_extension("GL_ARB_vertex_array_object");
212 /* Passing sample count = 1 will create the FBOs with minimum supported
213 * sample count. Both FBOs are created with GL_RGBA format by default.
215 src_fbo
.setup(FboConfig(1 /* sample count */,
219 dst_fbo
.setup(FboConfig(1 /* sample count */,
223 /* Single-sampled FBO used so that we can call glReadPixels to
224 * examine the results.
226 ss_fbo
.setup(FboConfig(0 /* sample count */,
230 if (!piglit_check_gl_error(GL_NO_ERROR
)) {
231 printf("Error setting up frame buffer objects\n");
232 piglit_report_result(PIGLIT_FAIL
);
235 test_pattern
= new ColorGradientSunburst(GL_FLOAT
);
236 test_pattern
->compile();
238 glBindFramebuffer(GL_FRAMEBUFFER
, src_fbo
.handle
);
239 test_pattern
->draw(TestPattern::no_projection
);
241 /* Generate a reference image by downsampling between matching
244 glBindFramebuffer(GL_READ_FRAMEBUFFER
, src_fbo
.handle
);
245 glBindFramebuffer(GL_DRAW_FRAMEBUFFER
, ss_fbo
.handle
);
246 glBlitFramebuffer(0, 0, pattern_width
, pattern_height
,
247 0, 0, pattern_width
, pattern_height
,
248 GL_COLOR_BUFFER_BIT
, GL_NEAREST
);
249 if (!piglit_check_gl_error(GL_NO_ERROR
))
250 piglit_report_result(PIGLIT_FAIL
);
252 reference_image
= (GLfloat
*) malloc(pattern_width
*
256 glBindFramebuffer(GL_FRAMEBUFFER
, ss_fbo
.handle
);
257 glReadPixels(0, 0, pattern_width
, pattern_height
,
258 GL_RGBA
, GL_FLOAT
, reference_image
);