2 * Copyright (c) 2011 Red Hat Inc.
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
30 * @file fbo-extended-blend.c
32 * Test GL_ARB_blend_func_extended with ARB_explicit_attrib_location
34 * Note all closed drivers seem to only support 1 dual source draw target
35 * so just have the initial test validate that
38 #include "piglit-util-gl.h"
40 PIGLIT_GL_TEST_CONFIG_BEGIN
42 #ifdef PIGLIT_USE_OPENGL
43 config
.supports_gl_compat_version
= 30;
44 #else // PIGLIT_USE_OPENGL_ES3
45 config
.supports_gl_es_version
= 30;
47 config
.window_visual
= PIGLIT_GL_VISUAL_RGB
;
48 config
.khr_no_error_support
= PIGLIT_NO_ERRORS
;
50 PIGLIT_GL_TEST_CONFIG_END
52 static const char *TestName
= "fbo-extended-blend-explicit";
54 static GLint max_ds_buffers
;
57 static GLenum srcFactors
[] = {
60 GL_ONE_MINUS_SRC1_COLOR
,
62 GL_ONE_MINUS_SRC1_ALPHA
,
63 GL_SRC_ALPHA_SATURATE
,
66 static GLenum dstFactors
[] = {
69 GL_ONE_MINUS_SRC1_COLOR
,
71 GL_ONE_MINUS_SRC1_ALPHA
,
72 GL_SRC_ALPHA_SATURATE
,
75 static GLenum operators
[] = {
78 GL_FUNC_REVERSE_SUBTRACT
,
86 GLenum err
= glGetError();
88 printf("%s: Unexpected error 0x%x at line %d\n",
90 piglit_report_result(PIGLIT_FAIL
);
94 static GLint uniform_src0
, uniform_src1
;
96 static void blend(const float *src
, const float *src1
, const float *dst
,
97 GLenum blendsrc
, GLenum blenddst
, GLenum blendop
)
99 glUniform4fv(uniform_src0
, 1, dst
);
100 piglit_draw_rect(-1, -1, 2, 2);
102 glBlendEquation(blendop
);
103 glBlendFunc(blendsrc
, blenddst
);
104 glUniform4fv(uniform_src0
, 1, src
);
105 glUniform4fv(uniform_src1
, 1, src1
);
106 piglit_draw_rect(-1, -1, 2, 2);
110 static void blend_expected(float *expected
, const float *src
, const float *src1
, const float *dst
, GLenum blendsrc
, GLenum blenddst
, GLenum blendop
)
114 float src_vals
[4] = {0}, dst_vals
[4] = {0};
118 for (i
= 0; i
< 4; i
++)
122 for (i
= 0; i
< 4; i
++)
123 src_vals
[i
] = src
[i
] * src1
[i
];
125 case GL_ONE_MINUS_SRC1_COLOR
:
126 for (i
= 0; i
< 4; i
++)
127 src_vals
[i
] = src
[i
] * (1.0 - src1
[i
]);
131 for (i
= 0; i
< 4; i
++)
132 src_vals
[i
] = src
[i
] * a
;
134 case GL_ONE_MINUS_SRC1_ALPHA
:
136 for (i
= 0; i
< 4; i
++)
137 src_vals
[i
] = src
[i
] * (1.0 - a
);
139 case GL_SRC_ALPHA_SATURATE
:
140 a
= MIN2(src
[3], (1 - dst
[3]));
141 for (i
= 0; i
< 3; i
++)
142 src_vals
[i
] = src
[i
] * a
;
143 src_vals
[3] = src
[3];
151 for (i
= 0; i
< 4; i
++)
152 dst_vals
[i
] = dst
[i
] * src1
[i
];
154 case GL_ONE_MINUS_SRC1_COLOR
:
155 for (i
= 0; i
< 4; i
++)
156 dst_vals
[i
] = dst
[i
] * (1.0 - src1
[i
]);
160 for (i
= 0; i
< 4; i
++)
161 dst_vals
[i
] = dst
[i
] * a
;
163 case GL_ONE_MINUS_SRC1_ALPHA
:
165 for (i
= 0; i
< 4; i
++)
166 dst_vals
[i
] = dst
[i
] * (1.0 - a
);
168 case GL_SRC_ALPHA_SATURATE
:
169 a
= MIN2(src
[3], (1 - dst
[3]));
170 for (i
= 0; i
< 3; i
++)
171 dst_vals
[i
] = dst
[i
] * a
;
172 dst_vals
[3] = dst
[3];
178 for (i
= 0 ; i
< 4; i
++)
179 expected
[i
] = src_vals
[i
] + dst_vals
[i
];
181 case GL_FUNC_SUBTRACT
:
182 for (i
= 0 ; i
< 4; i
++) {
183 expected
[i
] = src_vals
[i
] - dst_vals
[i
];
188 case GL_FUNC_REVERSE_SUBTRACT
:
189 for (i
= 0 ; i
< 4; i
++) {
190 expected
[i
] = dst_vals
[i
] - src_vals
[i
];
196 for (i
= 0 ; i
< 4; i
++) {
197 expected
[i
] = MIN2(dst
[i
], src
[i
]);
201 for (i
= 0 ; i
< 4; i
++) {
202 expected
[i
] = MAX2(dst
[i
], src
[i
]);
208 #ifdef PIGLIT_USE_OPENGL
209 static const char *vs_text
=
211 "in vec4 piglit_vertex;\n"
213 " gl_Position = piglit_vertex;\n"
217 static const char *fs_text
=
219 "#extension GL_ARB_explicit_attrib_location: require\n"
220 "uniform vec4 src0;\n"
221 "uniform vec4 src1;\n"
222 "layout(location = 0, index = 0) out vec4 col0;\n"
223 "layout(location = 0, index = 1) out vec4 col1;\n"
229 #else // PIGLIT_USE_OPENGL_ES3
230 static const char *vs_text
=
232 "in vec4 piglit_vertex;\n"
234 " gl_Position = piglit_vertex;\n"
238 static const char *fs_text
=
240 "#extension GL_EXT_blend_func_extended : enable\n"
241 "uniform highp vec4 src0;\n"
242 "uniform highp vec4 src1;\n"
243 "layout(location = 0, index = 0) out highp vec4 col0;\n"
244 "layout(location = 0, index = 1) out highp vec4 col1;\n"
258 #ifdef PIGLIT_USE_OPENGL
259 glGenFramebuffersEXT(1, &fbo
);
260 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT
, fbo
);
262 glGenRenderbuffersEXT(max_ds_buffers
, rb
);
263 check_error(__LINE__
);
265 for (i
= 0; i
< max_ds_buffers
; i
++) {
266 glBindRenderbufferEXT(GL_RENDERBUFFER_EXT
, rb
[i
]);
267 check_error(__LINE__
);
269 glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT
,
270 GL_COLOR_ATTACHMENT0
+ i
,
273 check_error(__LINE__
);
275 glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT
, GL_RGBA
,
276 piglit_width
, piglit_height
);
277 check_error(__LINE__
);
279 #else // PIGLIT_USE_OPENGL_ES3
280 glGenFramebuffers(1, &fbo
);
281 glBindFramebuffer(GL_FRAMEBUFFER_EXT
, fbo
);
283 glGenRenderbuffers(max_ds_buffers
, rb
);
284 check_error(__LINE__
);
286 for (i
= 0; i
< max_ds_buffers
; i
++) {
287 glBindRenderbuffer(GL_RENDERBUFFER_EXT
, rb
[i
]);
288 check_error(__LINE__
);
290 glFramebufferRenderbuffer(GL_FRAMEBUFFER_EXT
,
291 GL_COLOR_ATTACHMENT0
+ i
,
294 check_error(__LINE__
);
296 glRenderbufferStorage(GL_RENDERBUFFER_EXT
, GL_RGBA8
,
297 piglit_width
, piglit_height
);
298 check_error(__LINE__
);
303 static enum piglit_result
306 static const GLfloat dest_color
[4] = { 0.75, 0.25, 0.25, 0.5 };
307 static const GLfloat test_color
[4] = { 1.0, 0.25, 0.75, 0.25 };
308 static const GLfloat test_color1
[4] = { 0.5, 0.5, 0.5, 0.5 };
313 if (max_ds_buffers
> 1) {
314 printf("Test only supports 1 dual source blending color buffer\n");
320 #ifdef PIGLIT_USE_OPENGL
321 glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT
);
322 #else // PIGLIT_USE_OPENGL_ES3
323 GLenum bufs
[] = {GL_COLOR_ATTACHMENT0_EXT
};
324 glDrawBuffers(1, bufs
);
327 prog
= piglit_build_simple_program(vs_text
, fs_text
);
330 uniform_src0
= glGetUniformLocation(prog
, "src0");
331 uniform_src1
= glGetUniformLocation(prog
, "src1");
333 /* Setup blend modes and compute expected result color.
334 * We only test two simple blending modes. A more elaborate
335 * test would exercise a much wider variety of modes.
338 for (o
= 0; o
< ARRAY_SIZE(operators
); o
++) {
339 for (i
= 0; i
< ARRAY_SIZE(srcFactors
); i
++) {
340 for (j
= 0; j
< ARRAY_SIZE(dstFactors
); j
++) {
341 blend_expected(expected
, test_color
, test_color1
,
342 dest_color
, srcFactors
[i
],
343 dstFactors
[j
], operators
[o
]);
345 blend(test_color
, test_color1
, dest_color
,
346 srcFactors
[i
], dstFactors
[j
],
348 for (k
= 0; k
< max_ds_buffers
; k
++) {
349 glReadBuffer(GL_COLOR_ATTACHMENT0_EXT
+ k
);
350 check_error(__LINE__
);
352 if (!piglit_probe_pixel_rgba(5, 5, expected
)) {
353 printf("For src/dst %d %d %d\n", i
, j
, o
);
366 /* Should never be reached */
371 piglit_init(int argc
, char**argv
)
373 enum piglit_result result
;
374 #ifdef PIGLIT_USE_OPENGL
375 piglit_require_extension("GL_ARB_blend_func_extended");
376 piglit_require_extension("GL_ARB_explicit_attrib_location");
377 #else // PIGLIT_USE_OPENGL_ES3
378 piglit_require_extension("GL_EXT_blend_func_extended");
381 glGetIntegerv(GL_MAX_DUAL_SOURCE_DRAW_BUFFERS
, &max_ds_buffers
);
384 piglit_report_result(result
);