ext_gpu_shader4: add compiler tests for everything
[piglit.git] / tests / spec / arb_blend_func_extended / execution / fbo-extended-blend.c
blob2143a436631fbc65b15dd225790f6148acbbea79
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.
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";
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 "uniform vec4 src0;\n"
220 "uniform vec4 src1;\n"
221 "out vec4 col0;\n"
222 "out vec4 col1;\n"
223 "void main() {\n"
224 " col0 = src0;\n"
225 " col1 = src1;\n"
226 "}\n"
228 #else // PIGLIT_USE_OPENGL_ES3
229 static const char *vs_text =
230 "#version 300 es\n"
231 "in vec4 piglit_vertex;\n"
232 "void main() {\n"
233 " gl_Position = piglit_vertex;\n"
234 "}\n"
237 static const char *fs_text =
238 "#version 300 es\n"
239 "#extension GL_EXT_blend_func_extended : enable\n"
240 "uniform highp vec4 src0;\n"
241 "uniform highp vec4 src1;\n"
242 "out highp vec4 col0;\n"
243 "out highp vec4 col1;\n"
244 "void main() {\n"
245 " col0 = src0;\n"
246 " col1 = src1;\n"
247 "}\n"
249 #endif
251 static void
252 create_fbo(void)
254 GLuint rb[32];
255 int i;
257 #ifdef PIGLIT_USE_OPENGL
258 glGenFramebuffersEXT(1, &fbo);
259 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo);
261 glGenRenderbuffersEXT(max_ds_buffers, rb);
262 check_error(__LINE__);
264 for (i = 0; i < max_ds_buffers; i++) {
265 glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, rb[i]);
266 check_error(__LINE__);
268 glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT,
269 GL_COLOR_ATTACHMENT0 + i,
270 GL_RENDERBUFFER_EXT,
271 rb[i]);
272 check_error(__LINE__);
274 glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_RGBA,
275 piglit_width, piglit_height);
276 check_error(__LINE__);
278 #else // PIGLIT_USE_OPENGL_ES3
279 glGenFramebuffers(1, &fbo);
280 glBindFramebuffer(GL_FRAMEBUFFER_EXT, fbo);
282 glGenRenderbuffers(max_ds_buffers, rb);
283 check_error(__LINE__);
285 for (i = 0; i < max_ds_buffers; i++) {
286 glBindRenderbuffer(GL_RENDERBUFFER_EXT, rb[i]);
287 check_error(__LINE__);
289 glFramebufferRenderbuffer(GL_FRAMEBUFFER_EXT,
290 GL_COLOR_ATTACHMENT0 + i,
291 GL_RENDERBUFFER_EXT,
292 rb[i]);
293 check_error(__LINE__);
295 glRenderbufferStorage(GL_RENDERBUFFER_EXT, GL_RGBA8,
296 piglit_width, piglit_height);
297 check_error(__LINE__);
299 #endif
302 static enum piglit_result
303 test(void)
305 static const GLfloat dest_color[4] = { 0.75, 0.25, 0.25, 0.5 };
306 static const GLfloat test_color[4] = { 1.0, 0.25, 0.75, 0.25 };
307 static const GLfloat test_color1[4] = { 0.5, 0.5, 0.5, 0.5 };
308 GLfloat expected[4];
309 GLuint prog;
310 GLuint vs;
311 GLuint fs;
312 int i, j, k, o;
314 if (max_ds_buffers > 1) {
315 printf("Test only supports 1 dual source blending color buffer\n");
316 max_ds_buffers = 1;
319 prog = glCreateProgram();
320 vs = piglit_compile_shader_text(GL_VERTEX_SHADER, vs_text);
322 fs = piglit_compile_shader_text(GL_FRAGMENT_SHADER, fs_text);
323 glAttachShader(prog, vs);
324 glAttachShader(prog, fs);
325 piglit_check_gl_error(GL_NO_ERROR);
327 glBindFragDataLocationIndexed(prog, 0, 0, "col0");
328 glBindFragDataLocationIndexed(prog, 0, 1, "col1");
330 create_fbo();
332 #ifdef PIGLIT_USE_OPENGL
333 glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT);
334 #else // PIGLIT_USE_OPENGL_ES3
335 GLenum bufs[] = {GL_COLOR_ATTACHMENT0_EXT};
336 glDrawBuffers(1, bufs);
337 #endif
339 glLinkProgram(prog);
340 glUseProgram(prog);
342 uniform_src0 = glGetUniformLocation(prog, "src0");
343 uniform_src1 = glGetUniformLocation(prog, "src1");
345 /* Setup blend modes and compute expected result color.
346 * We only test two simple blending modes. A more elaborate
347 * test would exercise a much wider variety of modes.
350 for (o = 0; o < ARRAY_SIZE(operators); o++) {
351 for (i = 0; i < ARRAY_SIZE(srcFactors); i++) {
352 for (j = 0; j < ARRAY_SIZE(dstFactors); j++) {
353 blend_expected(expected, test_color, test_color1,
354 dest_color, srcFactors[i],
355 dstFactors[j], operators[o]);
357 blend(test_color, test_color1, dest_color,
358 srcFactors[i], dstFactors[j],
359 operators[o]);
360 for (k = 0; k < max_ds_buffers; k++) {
361 glReadBuffer(GL_COLOR_ATTACHMENT0_EXT + k);
362 check_error(__LINE__);
364 if (!piglit_probe_pixel_rgba(5, 5, expected)) {
365 printf("For src/dst %d %d %d\n", i, j, o);
366 return PIGLIT_FAIL;
372 return PIGLIT_PASS;
375 enum piglit_result
376 piglit_display(void)
378 /* Should never be reached */
379 return PIGLIT_FAIL;
382 void
383 piglit_init(int argc, char**argv)
385 enum piglit_result result;
386 #ifdef PIGLIT_USE_OPENGL
387 piglit_require_extension("GL_ARB_blend_func_extended");
388 #else // PIGLIT_USE_OPENGL_ES3
389 piglit_require_extension("GL_EXT_blend_func_extended");
390 #endif
392 glGetIntegerv(GL_MAX_DUAL_SOURCE_DRAW_BUFFERS, &max_ds_buffers);
394 result = test();
395 piglit_report_result(result);