2 * Copyright © 2010 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 * Eric Anholt <eric@anholt.net>
25 * Marek Olšák <maraeo@gmail.com>
29 /** @file fbo-drawbuffers-blend-add.c
31 * Tests that additive blending is enabled for all render targets with ARB_draw_buffers.
35 #include "piglit-util-gl.h"
37 PIGLIT_GL_TEST_CONFIG_BEGIN
39 config
.supports_gl_compat_version
= 10;
41 config
.window_width
= 256;
42 config
.window_height
= 256;
43 config
.window_visual
= PIGLIT_GL_VISUAL_RGBA
| PIGLIT_GL_VISUAL_DOUBLE
;
44 config
.khr_no_error_support
= PIGLIT_NO_ERRORS
;
46 PIGLIT_GL_TEST_CONFIG_END
48 static GLint max_targets
;
50 static char *vs_source
=
53 " gl_Position = gl_Vertex;\n"
56 static char *fs_source_start
=
60 static char *fs_source_output
=
61 " gl_FragData[%d].xyzw = vec4(%f, %f, %f, %f);\n";
63 static char *fs_source_end
=
66 float output_values
[] = {
84 0.0, 0.25, 0.25, 0.25,
85 0.25, 0.25, 0.0, 0.25};
87 float clear_value
= 0.25;
94 glGenTextures(1, &tex
);
95 glBindTexture(GL_TEXTURE_2D
, tex
);
96 glTexImage2D(GL_TEXTURE_2D
, 0, GL_RGBA
,
98 GL_RGBA
, GL_UNSIGNED_BYTE
, NULL
);
100 glTexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_MIN_FILTER
, GL_NEAREST
);
101 glTexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_MAG_FILTER
, GL_NEAREST
);
103 glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT
,
104 GL_COLOR_ATTACHMENT0_EXT
+ i
,
108 if (!piglit_check_gl_error(GL_NO_ERROR
))
109 piglit_report_result(PIGLIT_FAIL
);
115 generate_and_display_drawbuffers(int count
)
117 GLuint tex
[16], fb
, fs
, vs
, prog
;
118 GLenum attachments
[16], status
;
120 char fs_output_line
[256];
121 char fs_full_source
[1024];
123 glGenFramebuffersEXT(1, &fb
);
124 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT
, fb
);
126 for (i
= 0; i
< count
; i
++) {
127 tex
[i
] = attach_texture(i
);
128 attachments
[i
] = GL_COLOR_ATTACHMENT0
+ i
;
131 status
= glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT
);
132 if (status
!= GL_FRAMEBUFFER_COMPLETE_EXT
) {
133 fprintf(stderr
, "fbo incomplete (status = 0x%04x)\n", status
);
134 piglit_report_result(PIGLIT_SKIP
);
137 glDrawBuffersARB(count
, attachments
);
139 /* Clear all to 0.25 so we see if the shader rendering happens. */
140 glClearColor(clear_value
, clear_value
, clear_value
, clear_value
);
141 glClear(GL_COLOR_BUFFER_BIT
);
143 /* Build the shader that spams green to all outputs. */
144 vs
= piglit_compile_shader_text(GL_VERTEX_SHADER
, vs_source
);
146 strcpy(fs_full_source
, fs_source_start
);
148 for (i
= 0; i
< count
; i
++) {
149 sprintf(fs_output_line
, fs_source_output
, i
, output_values
[i
* 4],
150 output_values
[(i
* 4) + 1], output_values
[(i
* 4) + 2],
151 output_values
[(i
* 4) + 3]);
153 strcat(fs_full_source
, fs_output_line
);
156 strcat(fs_full_source
, fs_source_end
);
158 assert(strlen(fs_full_source
) + 1 < sizeof(fs_full_source
) / sizeof(fs_full_source
[0]));
160 fs
= piglit_compile_shader_text(GL_FRAGMENT_SHADER
, fs_full_source
);
162 prog
= piglit_link_simple_program(vs
, fs
);
166 glBlendFunc(GL_ONE
, GL_ONE
);
167 glBlendEquation(GL_FUNC_ADD
);
169 /* Now render to all the color buffers. */
170 piglit_draw_rect(-1, -1, 2, 2);
174 /* OK, now draw each of these textures to the winsys framebuffer. */
176 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT
, piglit_winsys_fbo
);
177 piglit_ortho_projection(piglit_width
, piglit_height
, GL_FALSE
);
178 glTexEnvi(GL_TEXTURE_ENV
, GL_TEXTURE_ENV_MODE
, GL_REPLACE
);
179 glEnable(GL_TEXTURE_2D
);
180 for (i
= 0; i
< count
; i
++) {
181 glBindTexture(GL_TEXTURE_2D
, tex
[i
]);
182 piglit_draw_rect_tex(16 * i
, 16 * (count
- 1),
187 glDisable(GL_TEXTURE_2D
);
189 for (i
= 0; i
< count
; i
++) {
190 glDeleteTextures(1, &tex
[i
]);
192 glDeleteFramebuffersEXT(1, &fb
);
198 #define N_VECTOR_ITEMS 4
199 GLboolean pass
= GL_TRUE
;
201 float expected
[N_VECTOR_ITEMS
] = {0};
204 glClearColor(0.5, 0.5, 0.5, 0.5);
205 glClear(GL_COLOR_BUFFER_BIT
);
207 for (count
= 1; count
<= max_targets
; count
++) {
208 generate_and_display_drawbuffers(count
);
211 for (count
= 1; count
<= max_targets
; count
++) {
212 for (i
= 0; i
< count
; i
++) {
213 for (j
= 0; j
< N_VECTOR_ITEMS
; j
++) {
214 expected
[j
] = output_values
[(i
* N_VECTOR_ITEMS
) + j
] +
219 piglit_probe_pixel_rgba(16 * i
+ 8,
220 16 * (count
- 1) + 8,
225 piglit_present_results();
227 return pass
? PIGLIT_PASS
: PIGLIT_FAIL
;
231 piglit_init(int argc
, char **argv
)
233 GLint max_attachments
;
235 printf("The result should be a rows of boxes of differing colors, \n"
236 "one for each drawbuffer target used (none black).\n");
238 piglit_ortho_projection(piglit_width
, piglit_height
, GL_FALSE
);
240 piglit_require_gl_version(20);
242 piglit_require_extension("GL_EXT_framebuffer_object");
243 piglit_require_extension("GL_ARB_draw_buffers");
245 glGetIntegerv(GL_MAX_DRAW_BUFFERS_ARB
, &max_targets
);
247 piglit_report_result(PIGLIT_SKIP
);
249 glGetIntegerv(GL_MAX_COLOR_ATTACHMENTS_EXT
, &max_attachments
);
250 if (max_targets
> max_attachments
)
251 max_targets
= max_attachments
;
253 if (max_targets
> 16)