2 * Copyright © 2012 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
24 #include "draw-buffers-common.h"
25 using namespace piglit_util_fbo
;
28 * \file draw-buffers-common.cpp
30 * This file provides utility functions to draw a test pattern to multiple draw
31 * buffers attached to a FBO with GL_SAMPLE_ALPHA_TO_{COVERAGE, ONE}
34 * Expected color values are computed for each draw buffer based on the enabled
35 * GL_SAMPLE_ALPHA_TO_{COVERAGE, ONE} flags and coverage value used to draw the
38 * Reference image for each draw buffer is drawn in to right half of default
39 * framebuffer. It is used to verify the accuracy of test image as well as to
40 * visually compare the difference caused by enabling above flags.
42 * Test image is drawn with the same test pattern in multisample buffer with
43 * GL_SAMPLE_ALPHA_TO_{COVERAGE, ONE} enabled. All multisample draw buffers
44 * are sequentially resolved by blitting them to a single sample FBO. resolve_fbo
45 * is then blitted to left half of window system framebuffer with appropriate y
46 * offset. This produces three test images in the left half, each corresponds to
49 * Test image is verified by comparing it with the corresponding reference
50 * image in the right half
52 * For sample coverage and sample alpha to coverage, test image should be
53 * verified by probing the rectangles in left half of window system framebuffer
54 * and comparing with expected color values. OpenGL 3.0 specification intends to
55 * allow (but not require) the implementation to produce a dithering effect when
56 * the coverage value is not a strict multiple of 1 / num_samples. We will skip
57 * computing expected values and probing for such rectangles. They are drawn
58 * just to look for dithering by human inspection.
61 * At present, the test always uses three draw buffers. To test other
62 * numbers of draw buffers, we would have to modify the fragment shader in
63 * nontrivial ways at run time.
65 * Also, the test always uses GL_RGBA8I as integer format or GL_RGBA as float
66 * format for draw buffer zero.
68 * Author: Anuj Phogat <anuj.phogat@gmail.com>
71 static Fbo ms_fbo
, resolve_fbo
, resolve_int_fbo
;
72 static GLbitfield buffer_to_test
;
74 static float *coverage
= NULL
;
75 static float *color
= NULL
;
76 static float *depth
= NULL
;
77 static float *expected_color
= NULL
;
78 static float *expected_depth
= NULL
;
80 static int num_draw_buffers
;
81 static int num_samples
;
86 static int frag_0_color_loc
;
87 static int alpha_to_coverage_loc
;
88 static int pattern_width
;
89 static int pattern_height
;
91 static bool is_buffer_zero_integer_format
= false;
92 static bool is_dual_src_blending
= false;
93 static GLenum draw_buffer_zero_format
;
95 static const int num_components
= 4; /* for RGBA formats */
96 static const int num_color_bits
= 8; /* for GL_RGBA & GL_RGBA8I formats */
98 static const float bg_depth
= 0.8;
99 static const float bg_color
[4] = {
100 0.0, 0.6, 0.0, 0.4 };
102 /* Testing for three draw buffers is supported */
103 static const GLenum draw_buffers
[] = {
104 GL_COLOR_ATTACHMENT0_EXT
,
105 GL_COLOR_ATTACHMENT1_EXT
,
106 GL_COLOR_ATTACHMENT2_EXT
};
108 /* Offset the viewport transformation on depth value passed to the vertex
109 * shader by setting it to (2 * depth - 1.0).
111 static const char *vert_template
=
113 "attribute vec2 pos;\n"
114 "uniform float depth;\n"
117 " vec4 eye_pos = gl_ModelViewProjectionMatrix * vec4(pos, 0.0, 1.0);\n"
118 " gl_Position = vec4(eye_pos.xy, 2 * depth - 1.0, 1.0);\n"
121 /* Fragment shader generates three different color outputs. Different color
122 * values are generated based on if sample_alpha_to_coverage / dual_src_blend
123 * are enabled or not.
125 static const char *frag_template
=
127 "#define NUM_ATTACHMENTS %d\n"
128 "#define DUAL_SRC_BLEND %d\n"
129 "#define ALPHA_TO_COVERAGE %d\n"
130 "#define OUT_TYPE %s\n"
131 "#define FRAG_OUT_ZERO_WRITE %d\n"
132 "#if __VERSION__ == 130\n"
133 "out OUT_TYPE frag_out_0;\n"
134 "#if DUAL_SRC_BLEND\n"
135 "out vec4 frag_out_1;\n"
136 "#elif NUM_ATTACHMENTS > 1\n"
137 "out vec4 frag_out_1;\n"
138 "out vec4 frag_out_2;\n"
141 "#define frag_out_0 gl_FragData[0]\n"
142 "#if NUM_ATTACHMENTS > 1\n"
143 "#define frag_out_1 gl_FragData[1]\n"
144 "#define frag_out_2 gl_FragData[2]\n"
147 "uniform OUT_TYPE frag_0_color;\n"
148 "uniform vec4 color;\n"
151 " #if FRAG_OUT_ZERO_WRITE\n"
152 " frag_out_0 = frag_0_color;\n"
154 " #if DUAL_SRC_BLEND\n"
155 " frag_out_1 = vec4(color.rgb, 1.0 - color.a / 2.0);\n"
156 " #elif ALPHA_TO_COVERAGE && NUM_ATTACHMENTS > 1\n"
157 " frag_out_1 = vec4(color.rgb, color.a / 2);\n"
158 " frag_out_2 = vec4(color.rgb, color.a / 4);\n"
159 " #elif NUM_ATTACHMENTS > 1\n"
160 " frag_out_1 = frag_out_2 = color;\n"
165 get_out_type_glsl(void)
167 if (is_buffer_zero_integer_format
)
173 shader_compile(bool sample_alpha_to_coverage
,
175 bool frag_out_zero_write
)
177 bool need_glsl130
= is_buffer_zero_integer_format
|| dual_src_blend
;
180 piglit_require_gl_version(30);
183 is_dual_src_blending
= dual_src_blend
;
185 /* Compile program */
186 unsigned vert_alloc_len
= strlen(vert_template
) + 4;
187 char *vert
= (char *) malloc(vert_alloc_len
);
188 sprintf(vert
, vert_template
, need_glsl130
? "130" : "120");
189 GLint vs
= piglit_compile_shader_text(GL_VERTEX_SHADER
, vert
);
192 /* Generate appropriate fragment shader program */
193 const char *out_type_glsl
= get_out_type_glsl();
194 unsigned frag_alloc_len
= strlen(frag_template
) +
195 strlen(out_type_glsl
) + 4;
196 char *frag
= (char *) malloc(frag_alloc_len
);
197 sprintf(frag
, frag_template
, need_glsl130
? "130" : "120",
199 is_dual_src_blending
,
200 sample_alpha_to_coverage
,
202 frag_out_zero_write
);
204 GLint fs
= piglit_compile_shader_text(GL_FRAGMENT_SHADER
, frag
);
205 prog
= piglit_link_simple_program(vs
, fs
);
207 if (!piglit_link_check_status(prog
)) {
208 piglit_report_result(PIGLIT_FAIL
);
213 if (is_dual_src_blending
) {
214 glBindFragDataLocationIndexed(prog
, 0, 0, "frag_out_0");
215 glBindFragDataLocationIndexed(prog
, 0, 1, "frag_out_1");
218 else if (num_draw_buffers
> 1) {
219 glBindFragDataLocation(prog
, 0, "frag_out_0");
220 glBindFragDataLocation(prog
, 1, "frag_out_1");
221 glBindFragDataLocation(prog
, 2, "frag_out_2");
224 glBindFragDataLocation(prog
, 0, "frag_out_0");
227 glBindAttribLocation(prog
, 0, "pos");
228 glEnableVertexAttribArray(0);
230 /* Linking is required after glBindFragDataLocation */
233 /* Set up uniforms */
235 color_loc
= glGetUniformLocation(prog
, "color");
236 depth_loc
= glGetUniformLocation(prog
, "depth");
237 frag_0_color_loc
= glGetUniformLocation(prog
, "frag_0_color");
238 alpha_to_coverage_loc
= glGetUniformLocation(prog
, "alphatocoverage");
242 allocate_data_arrays(void)
245 /* Draw 2N + 1 rectangles for N samples, each with a unique color
249 num_rects
= 2 * num_samples
+ 1;
250 alpha_scale
= (1.0 / (2.0 * num_samples
));
257 /* Allocate data arrays based on number of samples used */
258 color
= (float *) malloc(num_rects
*
261 expected_color
= (float *) malloc(num_draw_buffers
*
265 depth
= (float *) malloc(num_rects
* sizeof(float));
266 expected_depth
= (float *) malloc(num_draw_buffers
*
269 coverage
= (float *) malloc(num_rects
* sizeof(float));
271 for (int i
= 0; i
< num_rects
; i
++) {
272 unsigned rect_idx
= i
* num_components
;
273 for (int j
= 0; j
< num_components
- 1; j
++) {
274 color
[rect_idx
+ j
] =
275 (sin((float)(rect_idx
+ j
)) + 1) / 2;
278 /* In case of alpha-to-coverage enabled, alpha values will be
279 * directly used as coverage.
281 if (buffer_to_test
== GL_DEPTH_BUFFER_BIT
)
282 /* For depth buffer testing with alpha-to-coverage,
283 * set more rects with alpha = 1.0.
285 color
[rect_idx
+ 3] = 2 * i
* alpha_scale
;
287 color
[rect_idx
+ 3] = i
* alpha_scale
;
289 depth
[i
] = i
* (alpha_scale
/ 2.0);
294 free_data_arrays(void)
302 free(expected_color
);
303 expected_color
= NULL
;
307 float_color_to_int_color(int *dst
, float *src
)
309 float offset
= 1 - (1 << (num_color_bits
- 1));
310 float scale
= -2.0 * offset
;
312 for (int j
= 0; j
< num_rects
; ++j
) {
313 for (int k
= 0; k
< num_components
; ++k
) {
314 dst
[j
* num_components
+ k
] =
315 scale
* src
[j
* num_components
+ k
] + offset
;
321 draw_pattern(bool sample_alpha_to_coverage
,
322 bool sample_alpha_to_one
,
323 bool is_reference_image
,
327 if (buffer_to_test
== GL_COLOR_BUFFER_BIT
)
328 glClearColor(bg_color
[0], bg_color
[1],
329 bg_color
[2], bg_color
[3]);
330 else if (buffer_to_test
== GL_DEPTH_BUFFER_BIT
)
331 glClearDepth(bg_depth
);
332 glClear(buffer_to_test
);
334 if (!is_reference_image
) {
335 if (sample_alpha_to_coverage
)
336 glEnable(GL_SAMPLE_ALPHA_TO_COVERAGE
);
337 if (sample_alpha_to_one
)
338 glEnable(GL_SAMPLE_ALPHA_TO_ONE
);
340 glUniform1i(alpha_to_coverage_loc
, sample_alpha_to_coverage
);
342 unsigned indices
[6] = {0, 1, 2, 0, 2, 3};
343 int *integer_color
= (int *) malloc(num_rects
*
347 /* For integer color buffers convert the color data to integer format */
348 if (is_buffer_zero_integer_format
) {
349 float_color_to_int_color(integer_color
, float_color
);
352 for (int i
= 0; i
< num_rects
; ++i
) {
353 float vertices
[4][2] = {
354 { 0.0f
, 0.0f
+ i
* (pattern_height
/ num_rects
) },
355 { 0.0f
, (i
+ 1.0f
) * (pattern_height
/ num_rects
) },
356 { pattern_width
, (i
+ 1.0f
) * (pattern_height
/ num_rects
) },
357 { pattern_width
, 0.0f
+ i
* (pattern_height
/ num_rects
) } };
359 glVertexAttribPointer(0, 2, GL_FLOAT
, GL_FALSE
,
363 glUniform4fv(color_loc
, 1, (float_color
+ i
* num_components
));
364 if (is_buffer_zero_integer_format
) {
365 glUniform4iv(frag_0_color_loc
, 1,
366 integer_color
+ i
* num_components
);
369 glUniform4fv(frag_0_color_loc
, 1,
370 (float_color
+ i
* num_components
));
372 glUniform1f(depth_loc
, depth
[i
]);
373 glDrawElements(GL_TRIANGLES
, 6, GL_UNSIGNED_INT
,
376 glDisable(GL_SAMPLE_ALPHA_TO_COVERAGE
);
377 glDisable(GL_SAMPLE_ALPHA_TO_ONE
);
382 get_alpha_blend_factor(float src0_alpha
, float src1_alpha
,
387 glGetIntegerv(GL_BLEND_SRC_RGB
, &blend_func
);
389 glGetIntegerv(GL_BLEND_DST_RGB
, &blend_func
);
395 case GL_ONE_MINUS_SRC_ALPHA
:
396 return (1.0 - src0_alpha
);
401 case GL_ONE_MINUS_SRC1_ALPHA
:
402 return (1.0 - src1_alpha
);
405 printf("Blend function is not supported"
412 compute_blend_color(float *frag_color
, int rect_count
,
413 bool sample_alpha_to_one
)
415 float src_blend_factor
, dst_blend_factor
;
416 /* Taking in to account alpha values output by
419 float src0_alpha
= color
[rect_count
* num_components
+ 3];
420 float src1_alpha
= 1.0 - src0_alpha
/ 2.0;
422 if (sample_alpha_to_one
&& num_samples
) {
423 /* Set fragment src0_alpha, src1_alpha to 1.0 and use them
424 * to compute blending factors.
430 src_blend_factor
= get_alpha_blend_factor(src0_alpha
,
433 dst_blend_factor
= get_alpha_blend_factor(src0_alpha
,
436 /* Using default BlendEquation, blend_color is:
437 * src0_color * src_blend_factor + dst_color * dst_blend_factor
439 for (int j
= 0; j
< num_components
; j
++) {
441 color
[rect_count
* num_components
+ j
] *
446 frag_color
[rect_count
* num_components
+ j
] =
447 (blend_color
> 1) ? 1.0 : blend_color
;
452 compute_expected_color(bool sample_alpha_to_coverage
,
453 bool sample_alpha_to_one
,
454 int draw_buffer_count
)
456 unsigned buffer_idx_offset
= draw_buffer_count
*
459 for (int i
= 0; i
< num_rects
; i
++) {
461 float *frag_color
= NULL
;
462 float samples_used
= coverage
[i
] * num_samples
;
463 /* Expected color values are computed only for integer
464 * number of samples_used. Non-integer values may result
465 * in dithering effect.
467 if (samples_used
== (int) samples_used
) {
468 int rect_idx_offset
= buffer_idx_offset
+
470 frag_color
= (float *) malloc(num_rects
*
474 /* Do dual source blending computations */
475 if (is_dual_src_blending
) {
476 compute_blend_color(frag_color
,
478 sample_alpha_to_one
);
481 memcpy(frag_color
, color
,
482 num_rects
* num_components
*
486 /* Coverage value decides the number of samples in
487 * multisample buffer covered by an incoming fragment,
488 * which will then receive the fragment data. When the
489 * multisample buffer is resolved it gets blended with
490 * the background color which is written to the
491 * remaining samples. Page 254 (page 270 of the PDF) of
492 * the OpenGL 3.0 spec says: "The method of combination
493 * is not specified, though a simple average computed
494 * independently for each color component is recommended."
495 * This is followed by NVIDIA and AMD in their proprietary
498 for (int j
= 0; j
< num_components
- 1 ; j
++) {
500 expected_color
[rect_idx_offset
+ j
] =
501 frag_color
[i
* num_components
+ j
] * coverage
[i
] +
502 bg_color
[j
] * (1 - coverage
[i
]);
505 /* Compute expected alpha values of draw buffers */
506 float frag_alpha
= frag_color
[i
* num_components
+ 3];
507 int alpha_idx
= rect_idx_offset
+ 3;
510 !sample_alpha_to_coverage
) ||
511 is_buffer_zero_integer_format
) {
512 /* Taking in to account alpha values output by
515 expected_color
[alpha_idx
] =
516 is_buffer_zero_integer_format
?
517 frag_alpha
/ (1 << draw_buffer_count
) :
520 else if (sample_alpha_to_coverage
) {
521 /* Taking in to account alpha values output by
524 frag_alpha
/= (1 << draw_buffer_count
);
525 if (sample_alpha_to_one
) {
526 expected_color
[alpha_idx
] =
528 bg_color
[3] * (1 - coverage
[i
]);
531 expected_color
[alpha_idx
] =
532 frag_alpha
* coverage
[i
] +
533 bg_color
[3] * (1 - coverage
[i
]);
537 expected_color
[alpha_idx
] =
538 sample_alpha_to_one
? 1.0 : frag_alpha
;
547 compute_expected_depth(void)
549 /* Compute the expected depth values only for coverage value equal to
550 * 0.0 and 1.0. Expected depth is not defined by OpenGL specification
551 * when coverage value is between 0.0 and 1.0 */
552 for (int i
= 0; i
< num_rects
; i
++) {
553 if (coverage
[i
] == 0.0)
554 expected_depth
[i
] = bg_depth
;
555 else if (coverage
[i
] == 1.0)
556 expected_depth
[i
] = (depth
[i
] < 1.0) ? depth
[i
] : 1.0;
561 compute_expected(bool sample_alpha_to_coverage
,
562 bool sample_alpha_to_one
,
563 int draw_buffer_count
)
566 /* Compute the coverage value used in the test */
568 sample_alpha_to_coverage
&&
569 !is_buffer_zero_integer_format
) {
571 for (i
= 0; i
< num_rects
; i
++) {
572 /* Coverage value for all the draw buffers comes from
573 * the fragment alpha values of draw buffer zero
575 float frag_alpha
= color
[i
* num_components
+ 3];
576 coverage
[i
] = (frag_alpha
< 1.0) ? frag_alpha
: 1.0;
580 for (i
= 0; i
< num_rects
; i
++)
584 if (buffer_to_test
== GL_COLOR_BUFFER_BIT
) {
585 /* Don't compute expected color for color buffer zero
586 * if no renderbuffer is attached to it.
588 if (draw_buffer_count
== 0 && draw_buffer_zero_format
== GL_NONE
)
590 compute_expected_color(sample_alpha_to_coverage
,
594 else if (buffer_to_test
== GL_DEPTH_BUFFER_BIT
)
595 compute_expected_depth();
599 /* This function probes all the draw buffers blitted to downsampled FBO
600 * (resolve_fbo / resolve_int_fbo) and compare against expected color values.
603 probe_framebuffer_color(void)
606 int * expected_int_color
= NULL
;
607 int rect_width
= pattern_width
;
608 int rect_height
= pattern_height
/ num_rects
;
610 for (int i
= 0; i
< num_draw_buffers
; i
++) {
611 /* Don't probe color buffer zero if no renderbuffer is
614 if (i
== 0 && draw_buffer_zero_format
== GL_NONE
)
616 bool is_integer_operation
= is_buffer_zero_integer_format
&& !i
;
618 if (is_integer_operation
) {
619 glBindFramebuffer(GL_READ_FRAMEBUFFER
,
620 resolve_int_fbo
.handle
);
621 expected_int_color
= (int*) malloc(num_rects
*
626 glBindFramebuffer(GL_READ_FRAMEBUFFER
,
630 for (int j
= 0; j
< num_rects
; j
++) {
631 float samples_used
= coverage
[j
] * num_samples
;
633 int rect_y
= i
* pattern_height
+
635 int rect_idx_offset
= (i
* num_rects
+ j
) *
638 /* Only probe rectangles with coverage value which is a
639 * strict multiple of 1 / num_samples.
641 if (samples_used
== (int)samples_used
) {
642 if (is_integer_operation
) {
643 float_color_to_int_color(expected_int_color
,
645 result
= piglit_probe_rect_rgba_int(
655 result
= piglit_probe_rect_rgba(
660 expected_color
+ rect_idx_offset
)
666 if (expected_int_color
)
667 free(expected_int_color
);
672 probe_framebuffer_depth(void)
675 int rect_width
= pattern_width
;
676 int rect_height
= pattern_height
/ num_rects
;
678 glBindFramebuffer(GL_READ_FRAMEBUFFER
, resolve_fbo
.handle
);
679 for (int i
= 0; i
< num_rects
; i
++) {
680 if (coverage
[i
] == 0.0 || coverage
[i
] == 1.0) {
682 int rect_y
= i
* rect_height
;
685 result
= piglit_probe_rect_depth(
690 expected_depth
[rect_idx
])
694 /*Skip probing polygons which are drawn with fractional
695 * coverage value (between 0.0 and 1.0)*/
703 draw_image_to_window_system_fb(int draw_buffer_count
, bool rhs
)
706 unsigned rect_y
= draw_buffer_count
* pattern_height
;
707 unsigned array_size
= num_components
* pattern_width
* pattern_height
;
708 float *image
= (float *) malloc(sizeof(float) * array_size
);
710 if (is_buffer_zero_integer_format
&& draw_buffer_count
== 0) {
711 glBindFramebuffer(GL_READ_FRAMEBUFFER
, resolve_int_fbo
.handle
);
712 int *tmp
= (int *) malloc(sizeof(int) * array_size
);
713 glReadPixels(rect_x
, rect_y
,
714 pattern_width
, pattern_height
,
717 for (unsigned i
= 0; i
< array_size
; ++i
) {
721 /* Convert integer color data to float color data */
722 float color_offset
= 1.0 - (1 << (num_color_bits
- 1));
723 float color_scale
= -2.0 * color_offset
;
725 for (unsigned i
= 0; i
< array_size
; ++i
) {
726 image
[i
] = (image
[i
] - color_offset
) / color_scale
;
731 glBindFramebuffer(GL_READ_FRAMEBUFFER
, resolve_fbo
.handle
);
732 glReadPixels(rect_x
, rect_y
,
739 /* Rendering using gldrawPixels() with dual source blending enabled
740 * produces undefined results. So, disable blending in
741 * piglit_visualize_image function to avoid undefined behavior.
743 GLboolean isBlending
;
744 glGetBooleanv(GL_BLEND
, &isBlending
);
746 piglit_visualize_image(image
, GL_RGBA
,
747 pattern_width
, pattern_height
,
748 draw_buffer_count
+ 1, rhs
);
755 draw_test_image(bool sample_alpha_to_coverage
, bool sample_alpha_to_one
)
757 /* Draw test pattern in multisample ms_fbo with
758 * GL_SAMPLE_ALPHA_TO_COVERAGE enabled
760 glBindFramebuffer(GL_DRAW_FRAMEBUFFER
, ms_fbo
.handle
);
761 glDrawBuffers(num_draw_buffers
, draw_buffers
);
762 ms_fbo
.set_viewport();
764 draw_pattern(sample_alpha_to_coverage
,
766 false /* is_reference_image */,
769 for (int i
= 0; i
< num_draw_buffers
; i
++) {
771 /* Blit ms_fbo to singlesample FBO to resolve multisample
774 glBindFramebuffer(GL_READ_FRAMEBUFFER
, ms_fbo
.handle
);
775 if (buffer_to_test
== GL_COLOR_BUFFER_BIT
)
776 glReadBuffer(GL_COLOR_ATTACHMENT0_EXT
+ i
);
778 if (is_buffer_zero_integer_format
&& !i
)
779 glBindFramebuffer(GL_DRAW_FRAMEBUFFER
,
780 resolve_int_fbo
.handle
);
782 glBindFramebuffer(GL_DRAW_FRAMEBUFFER
,
785 /* Blit all the draw buffers to resolve_fbo / resolve_int_fbo
786 * with different y_offset.
788 unsigned y_offset
= i
* pattern_height
;
789 glBlitFramebuffer(0, 0,
790 pattern_width
, pattern_height
,
792 pattern_width
, pattern_height
+ y_offset
,
793 buffer_to_test
, GL_NEAREST
);
795 if (buffer_to_test
== GL_COLOR_BUFFER_BIT
) {
796 draw_image_to_window_system_fb(i
/* draw_buffer_count */,
800 /* Expected color values for all the draw buffers are computed
801 * to aid probe_framebuffer_color() and probe_framebuffer_depth()
804 if (sample_alpha_to_coverage
|| is_dual_src_blending
) {
805 /* Expected color is different for different draw
808 compute_expected(sample_alpha_to_coverage
,
810 i
/* draw_buffer_count */);
816 draw_reference_image(bool sample_alpha_to_coverage
, bool sample_alpha_to_one
)
818 /* Draw test pattern in multisample ms_fbo with
819 * GL_SAMPLE_ALPHA_TO_COVERAGE disabled.
821 glBindFramebuffer(GL_DRAW_FRAMEBUFFER
, ms_fbo
.handle
);
822 glDrawBuffers(num_draw_buffers
, draw_buffers
);
823 ms_fbo
.set_viewport();
825 if (sample_alpha_to_coverage
) {
826 draw_pattern(sample_alpha_to_coverage
,
828 true /* is_reference_image */,
832 /* Value of draw_buffer_count doesn't matter in this case */
833 compute_expected(sample_alpha_to_coverage
,
835 0 /* draw_buffer_count */);
836 draw_pattern(sample_alpha_to_coverage
,
838 true /* is_reference_image */,
842 for (int i
= 0; i
< num_draw_buffers
; i
++) {
844 /* Blit ms_fbo to resolve_fbo to resolve multisample buffer */
845 glBindFramebuffer(GL_READ_FRAMEBUFFER
, ms_fbo
.handle
);
846 if (buffer_to_test
== GL_COLOR_BUFFER_BIT
)
847 glReadBuffer(GL_COLOR_ATTACHMENT0_EXT
+ i
);
848 if (is_buffer_zero_integer_format
&& !i
) {
849 glBindFramebuffer(GL_DRAW_FRAMEBUFFER
,
850 resolve_int_fbo
.handle
);
853 glBindFramebuffer(GL_DRAW_FRAMEBUFFER
,
857 /* Blit all the draw buffers to resolve_fbo with different
860 unsigned y_offset
= i
* pattern_height
;
861 glBlitFramebuffer(0, 0,
862 pattern_width
, pattern_height
,
864 pattern_width
, pattern_height
+ y_offset
,
865 buffer_to_test
, GL_NEAREST
);
867 if (buffer_to_test
== GL_COLOR_BUFFER_BIT
) {
868 draw_image_to_window_system_fb(i
/* draw_buffer_count */,
875 ms_fbo_and_draw_buffers_setup(int samples
,
880 GLenum color_buffer_zero_format
)
883 glGetIntegerv(GL_MAX_COLOR_ATTACHMENTS
, &maxBuffers
);
885 /* Ensure that requested number of color attachments are
886 * supported by the implementation and fragment shader.
888 if (n_attachments
<= (int) ARRAY_SIZE(draw_buffers
) &&
889 n_attachments
<= maxBuffers
)
890 num_draw_buffers
= n_attachments
;
892 printf("Number of attachments requested are not supported\n");
893 piglit_report_result(PIGLIT_SKIP
);
896 pattern_width
= width
;
897 pattern_height
= height
;
898 draw_buffer_zero_format
= color_buffer_zero_format
;
900 /* Setup frame buffer objects with required configuration */
901 FboConfig
ms_config(samples
, pattern_width
, pattern_height
);
902 ms_config
.color_internalformat
= color_buffer_zero_format
;
903 ms_fbo
.setup(ms_config
);
905 /* Create resolve_fbo with dimensions large enough to accommodate
906 * all the draw buffers
908 FboConfig
resolve_config(0, pattern_width
,
909 num_draw_buffers
* pattern_height
);
910 resolve_config
.color_internalformat
= GL_RGBA
;
911 resolve_fbo
.setup(resolve_config
);
913 /* Create resolve_int_fbo to store downsampled integer draw buffer */
914 if (color_buffer_zero_format
== GL_RGBA8I
) {
915 resolve_config
.color_internalformat
= GL_RGBA8I
;
916 /* Assuming single integer buffer */
917 resolve_config
.height
= pattern_height
;
918 resolve_int_fbo
.setup(resolve_config
);
919 is_buffer_zero_integer_format
= true;
921 else if (color_buffer_zero_format
!= GL_RGBA
&&
922 color_buffer_zero_format
!= GL_NONE
) {
923 printf("Draw buffer zero format is not"
924 " supported by test functions.\n");
925 piglit_report_result(PIGLIT_FAIL
);
928 if (!piglit_check_gl_error(GL_NO_ERROR
)) {
929 printf("Error setting up frame buffer objects\n");
930 piglit_report_result(PIGLIT_FAIL
);
933 /* Query the number of samples used in ms_fbo. OpenGL implementation
934 * may create FBO with more samples per pixel than what is requested.
936 glBindFramebuffer(GL_DRAW_FRAMEBUFFER
, ms_fbo
.handle
);
937 glGetIntegerv(GL_SAMPLES
, &num_samples
);
939 /* Attach additional color buffers to multisample FBO with default
940 * non-integer format (GL_RGBA.)
942 GLuint
*color_rb
= (GLuint
*)malloc((num_draw_buffers
- 1) *
944 glGenRenderbuffers(num_draw_buffers
- 1, color_rb
);
946 for (int i
= 0; i
< num_draw_buffers
- 1; i
++) {
947 glBindRenderbuffer(GL_RENDERBUFFER
, color_rb
[i
]);
948 glRenderbufferStorageMultisample(GL_RENDERBUFFER
,
949 ms_fbo
.config
.num_samples
,
952 ms_fbo
.config
.height
);
954 glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER
,
955 GL_COLOR_ATTACHMENT0
+ (i
+ 1),
960 GLenum status
= glCheckFramebufferStatus(GL_DRAW_FRAMEBUFFER
);
961 if (status
!= GL_FRAMEBUFFER_COMPLETE
) {
962 printf("Error attaching additional color buffers\n");
963 piglit_report_result(PIGLIT_FAIL
);
965 buffer_to_test
= test_buffer
;