1 /*
2 * Copyright (c) 2010 VMware, Inc.
3 *
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:
10 *
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.
14 *
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.
22 */
23
24 /*
25 * Author:
26 * Brian Paul
27 */
28
29 /**
30 * @file fbo-draw-buffers-blend.c
31 *
32 * Test GL_ARB_draw_buffers_blend extension (per-buffer blend state)
33 */
34
35 #include "piglit-util-gl.h"
36
37 PIGLIT_GL_TEST_CONFIG_BEGIN
38
39 config.supports_gl_compat_version = 10;
40
41 config.window_visual = PIGLIT_GL_VISUAL_RGB;
42 config.khr_no_error_support = PIGLIT_NO_ERRORS;
43
44 PIGLIT_GL_TEST_CONFIG_END
45
46 static const char *TestName = "fbo-draw-buffers-blend";
47
48 static GLint maxBuffers;
49 static GLuint FBO;
50
51
52 #define MY_ASSERT(x) my_assert(x, #x)
53
54 static void
my_assert(int test,const char * text)55 my_assert(int test, const char *text)
56 {
57 if (!test) {
58 printf("%s: assertion %s failed\n", TestName, text);
59 piglit_report_result(PIGLIT_FAIL);
60 }
61 }
62
63
64 static void
check_error(int line)65 check_error(int line)
66 {
67 GLenum err = glGetError();
68 if (err) {
69 printf("%s: Unexpected error 0x%x at line %d\n",
70 TestName, err, line);
71 piglit_report_result(PIGLIT_FAIL);
72 }
73 }
74
75
76 static void
create_fbo(void)77 create_fbo(void)
78 {
79 GLuint rb[32];
80 int i;
81
82 glGenFramebuffersEXT(1, &FBO);
83 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, FBO);
84
85 glGenRenderbuffersEXT(maxBuffers, rb);
86 check_error(__LINE__);
87
88 for (i = 0; i < maxBuffers; i++) {
89 glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, rb[i]);
90 check_error(__LINE__);
91
92 glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT,
93 GL_COLOR_ATTACHMENT0 + i,
94 GL_RENDERBUFFER_EXT,
95 rb[i]);
96 check_error(__LINE__);
97
98 glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_RGBA,
99 piglit_width, piglit_height);
100 check_error(__LINE__);
101 }
102 }
103
104
105 static enum piglit_result
test(void)106 test(void)
107 {
108 GLenum buffers[32];
109 static const GLfloat dest_color[4] = { 0.75, 0.25, 0.25, 0.5 };
110 static const GLfloat test_color[4] = { 1.0, 0.25, 0.75, 0.25 };
111 GLfloat expected[32][4];
112 int i;
113
114 create_fbo();
115
116 for (i = 0; i < maxBuffers; i++) {
117 buffers[i] = GL_COLOR_ATTACHMENT0_EXT + i;
118 }
119
120 glDrawBuffersARB(maxBuffers, buffers);
121
122 /* Setup blend modes and compute expected result color.
123 * We only test two simple blending modes. A more elaborate
124 * test would exercise a much wider variety of modes.
125 */
126 for (i = 0; i < maxBuffers; i++) {
127 if (i % 2 == 0) {
128 float a;
129
130 glBlendFunciARB(i, GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
131
132 a = test_color[3];
133 expected[i][0] = test_color[0] * a + dest_color[0] * (1.0 - a);
134 expected[i][1] = test_color[1] * a + dest_color[1] * (1.0 - a);
135 expected[i][2] = test_color[2] * a + dest_color[2] * (1.0 - a);
136 expected[i][3] = test_color[3] * a + dest_color[3] * (1.0 - a);
137 }
138 else {
139 glBlendFunciARB(i, GL_ONE, GL_ONE);
140 glBlendEquationiARB(i, GL_FUNC_SUBTRACT);
141
142 expected[i][0] = test_color[0] - dest_color[0];
143 expected[i][1] = test_color[1] - dest_color[1];
144 expected[i][2] = test_color[2] - dest_color[2];
145 expected[i][3] = test_color[3] - dest_color[3];
146 }
147
148 expected[i][0] = CLAMP(expected[i][0], 0.0, 1.0);
149 expected[i][1] = CLAMP(expected[i][1], 0.0, 1.0);
150 expected[i][2] = CLAMP(expected[i][2], 0.0, 1.0);
151 expected[i][3] = CLAMP(expected[i][3], 0.0, 1.0);
152
153 glEnableIndexedEXT(GL_BLEND, i);
154 }
155
156 /* query blend modes */
157 for (i = 0; i < maxBuffers; i++) {
158 GLint p0, p1, p2, p3;
159 glGetIntegerIndexedvEXT(GL_BLEND_SRC, i, &p0);
160 glGetIntegerIndexedvEXT(GL_BLEND_DST, i, &p1);
161 glGetIntegerIndexedvEXT(GL_BLEND_EQUATION, i, &p2);
162 glGetIntegerIndexedvEXT(GL_BLEND, i, &p3);
163 if (i % 2 == 0) {
164 MY_ASSERT(p0 == GL_SRC_ALPHA);
165 MY_ASSERT(p1 == GL_ONE_MINUS_SRC_ALPHA);
166 MY_ASSERT(p2 == GL_FUNC_ADD);
167 }
168 else {
169 MY_ASSERT(p0 == GL_ONE);
170 MY_ASSERT(p1 == GL_ONE);
171 MY_ASSERT(p2 == GL_FUNC_SUBTRACT);
172 }
173 MY_ASSERT(p3 == GL_TRUE);
174 }
175
176 /* test drawing */
177 glClearColor(dest_color[0], dest_color[1], dest_color[2], dest_color[3]);
178 glClear(GL_COLOR_BUFFER_BIT);
179
180 glColor4fv(test_color);
181 piglit_draw_rect(0, 0, piglit_width, piglit_height);
182
183 for (i = 0; i < maxBuffers; i++) {
184 glReadBuffer(GL_COLOR_ATTACHMENT0_EXT + i);
185 check_error(__LINE__);
186
187 if (!piglit_probe_pixel_rgba(5, 5, expected[i])) {
188 printf("For color buffer %d\n", i);
189 return PIGLIT_FAIL;
190 }
191 }
192
193 return PIGLIT_PASS;
194 }
195
196
197 enum piglit_result
piglit_display(void)198 piglit_display(void)
199 {
200 return test();
201 }
202
203
204 void
piglit_init(int argc,char ** argv)205 piglit_init(int argc, char**argv)
206 {
207 piglit_ortho_projection(piglit_width, piglit_height, GL_FALSE);
208
209 piglit_require_extension("GL_ARB_draw_buffers_blend");
210
211 glGetIntegerv(GL_MAX_DRAW_BUFFERS_ARB, &maxBuffers);
212 }
213