ext_gpu_shader4: add compiler tests for everything
[piglit.git] / tests / spec / arb_blend_func_extended / execution / fbo-extended-blend-explicit.c
blob1428b3d6f9453145d518f213fe4ed8c33274c67f
1 /*
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
13 * Software.
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
21 * IN THE SOFTWARE.
25 * Author:
26 * Dave Airlie
29 /**
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;
46 #endif
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;
55 static GLuint fbo;
57 static GLenum srcFactors[] = {
58 GL_ZERO,
59 GL_SRC1_COLOR,
60 GL_ONE_MINUS_SRC1_COLOR,
61 GL_SRC1_ALPHA,
62 GL_ONE_MINUS_SRC1_ALPHA,
63 GL_SRC_ALPHA_SATURATE,
66 static GLenum dstFactors[] = {
67 GL_ZERO,
68 GL_SRC1_COLOR,
69 GL_ONE_MINUS_SRC1_COLOR,
70 GL_SRC1_ALPHA,
71 GL_ONE_MINUS_SRC1_ALPHA,
72 GL_SRC_ALPHA_SATURATE,
75 static GLenum operators[] = {
76 GL_FUNC_ADD,
77 GL_FUNC_SUBTRACT,
78 GL_FUNC_REVERSE_SUBTRACT,
79 GL_MIN,
80 GL_MAX,
83 static void
84 check_error(int line)
86 GLenum err = glGetError();
87 if (err) {
88 printf("%s: Unexpected error 0x%x at line %d\n",
89 TestName, err, line);
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);
101 glEnable(GL_BLEND);
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);
107 glDisable(GL_BLEND);
110 static void blend_expected(float *expected, const float *src, const float *src1, const float *dst, GLenum blendsrc, GLenum blenddst, GLenum blendop)
112 float a;
113 int i;
114 float src_vals[4] = {0}, dst_vals[4] = {0};
116 switch (blendsrc) {
117 case GL_ZERO:
118 for (i = 0; i < 4; i++)
119 src_vals[i] = 0;
120 break;
121 case GL_SRC1_COLOR:
122 for (i = 0; i < 4; i++)
123 src_vals[i] = src[i] * src1[i];
124 break;
125 case GL_ONE_MINUS_SRC1_COLOR:
126 for (i = 0; i < 4; i++)
127 src_vals[i] = src[i] * (1.0 - src1[i]);
128 break;
129 case GL_SRC1_ALPHA:
130 a = src1[3];
131 for (i = 0; i < 4; i++)
132 src_vals[i] = src[i] * a;
133 break;
134 case GL_ONE_MINUS_SRC1_ALPHA:
135 a = src1[3];
136 for (i = 0; i < 4; i++)
137 src_vals[i] = src[i] * (1.0 - a);
138 break;
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];
144 break;
147 switch (blenddst) {
148 case GL_ZERO:
149 break;
150 case GL_SRC1_COLOR:
151 for (i = 0; i < 4; i++)
152 dst_vals[i] = dst[i] * src1[i];
153 break;
154 case GL_ONE_MINUS_SRC1_COLOR:
155 for (i = 0; i < 4; i++)
156 dst_vals[i] = dst[i] * (1.0 - src1[i]);
157 break;
158 case GL_SRC1_ALPHA:
159 a = src1[3];
160 for (i = 0; i < 4; i++)
161 dst_vals[i] = dst[i] * a;
162 break;
163 case GL_ONE_MINUS_SRC1_ALPHA:
164 a = src1[3];
165 for (i = 0; i < 4; i++)
166 dst_vals[i] = dst[i] * (1.0 - a);
167 break;
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];
173 break;
176 switch (blendop) {
177 case GL_FUNC_ADD:
178 for (i = 0 ; i < 4; i++)
179 expected[i] = src_vals[i] + dst_vals[i];
180 break;
181 case GL_FUNC_SUBTRACT:
182 for (i = 0 ; i < 4; i++) {
183 expected[i] = src_vals[i] - dst_vals[i];
184 if (expected[i] < 0)
185 expected[i] = 0;
187 break;
188 case GL_FUNC_REVERSE_SUBTRACT:
189 for (i = 0 ; i < 4; i++) {
190 expected[i] = dst_vals[i] - src_vals[i];
191 if (expected[i] < 0)
192 expected[i] = 0;
194 break;
195 case GL_MIN:
196 for (i = 0 ; i < 4; i++) {
197 expected[i] = MIN2(dst[i], src[i]);
199 break;
200 case GL_MAX:
201 for (i = 0 ; i < 4; i++) {
202 expected[i] = MAX2(dst[i], src[i]);
204 break;
208 #ifdef PIGLIT_USE_OPENGL
209 static const char *vs_text =
210 "#version 130\n"
211 "in vec4 piglit_vertex;\n"
212 "void main() {\n"
213 " gl_Position = piglit_vertex;\n"
214 "}\n"
217 static const char *fs_text =
218 "#version 130\n"
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"
224 "void main() {\n"
225 " col0 = src0;\n"
226 " col1 = src1;\n"
227 "}\n"
229 #else // PIGLIT_USE_OPENGL_ES3
230 static const char *vs_text =
231 "#version 300 es\n"
232 "in vec4 piglit_vertex;\n"
233 "void main() {\n"
234 " gl_Position = piglit_vertex;\n"
235 "}\n"
238 static const char *fs_text =
239 "#version 300 es\n"
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"
245 "void main() {\n"
246 " col0 = src0;\n"
247 " col1 = src1;\n"
248 "}\n"
250 #endif
252 static void
253 create_fbo(void)
255 GLuint rb[32];
256 int i;
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,
271 GL_RENDERBUFFER_EXT,
272 rb[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,
292 GL_RENDERBUFFER_EXT,
293 rb[i]);
294 check_error(__LINE__);
296 glRenderbufferStorage(GL_RENDERBUFFER_EXT, GL_RGBA8,
297 piglit_width, piglit_height);
298 check_error(__LINE__);
300 #endif
303 static enum piglit_result
304 test(void)
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 };
309 GLfloat expected[4];
310 GLuint prog;
311 int i, j, k, o;
313 if (max_ds_buffers > 1) {
314 printf("Test only supports 1 dual source blending color buffer\n");
315 max_ds_buffers = 1;
318 create_fbo();
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);
325 #endif
327 prog = piglit_build_simple_program(vs_text, fs_text);
328 glUseProgram(prog);
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],
347 operators[o]);
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);
354 return PIGLIT_FAIL;
360 return PIGLIT_PASS;
363 enum piglit_result
364 piglit_display(void)
366 /* Should never be reached */
367 return PIGLIT_FAIL;
370 void
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");
379 #endif
381 glGetIntegerv(GL_MAX_DUAL_SOURCE_DRAW_BUFFERS, &max_ds_buffers);
383 result = test();
384 piglit_report_result(result);