cl: Don't use device_infos if num_device_infos == 0
[piglit.git] / tests / general / framebuffer-srgb.c
blob5944a075d3acedf33587ac18e673f6423f5960c6
1 /*
2 * Copyright © 2010 Red Hat
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.
23 * Authors:
24 * Dave Airlie
28 /** @file framebuffer-srgb
30 * Test the EXT_framebuffer_sRGB API changes
31 * this test enables even when the extension isn't available, and confirms
32 * the API acts correctly in that case.
35 #include "piglit-util-gl.h"
37 PIGLIT_GL_TEST_CONFIG_BEGIN
39 config.supports_gl_compat_version = 10;
41 config.window_visual = PIGLIT_GL_VISUAL_RGB | PIGLIT_GL_VISUAL_DOUBLE;
43 PIGLIT_GL_TEST_CONFIG_END
45 /* size of texture/renderbuffer (power of two) */
46 #define FBO_SIZE 128
48 /* do some basic API tests */
49 static GLboolean
50 framebuffer_srgb_api_no_ext(void)
52 GLboolean pass = GL_TRUE;
53 GLboolean boolmode = GL_FALSE;
54 GLenum ret;
56 glGetBooleanv(GL_FRAMEBUFFER_SRGB_CAPABLE_EXT, &boolmode);
57 ret = glGetError();
58 if (ret != GL_INVALID_ENUM || boolmode) {
59 printf("no extension but no enum error or enabled\n");
60 pass = GL_FALSE;
63 (void)glIsEnabled(GL_FRAMEBUFFER_SRGB_EXT);
64 ret = glGetError();
65 if (ret != GL_INVALID_ENUM) {
66 printf("no invalid enum on glIsEnabled(GL_FRAMEBUFFER_SRGB_EXT)\n");
67 pass = GL_FALSE;
70 glEnable(GL_FRAMEBUFFER_SRGB_EXT);
71 ret = glGetError();
72 if (ret != GL_INVALID_ENUM) {
73 printf("no invalid enum on glEnable(GL_FRAMEBUFFER_SRGB_EXT)\n");
74 pass = GL_FALSE;
77 glDisable(GL_FRAMEBUFFER_SRGB_EXT);
78 ret = glGetError();
79 if (ret != GL_INVALID_ENUM) {
80 printf("no invalid enum on glDisable(GL_FRAMEBUFFER_SRGB_EXT)\n");
81 pass = GL_FALSE;
83 return pass;
86 /* do some basic API tests */
87 static GLboolean
88 framebuffer_srgb_api_ext(void)
90 GLboolean pass = GL_TRUE;
91 GLboolean boolmode;
92 GLenum ret;
93 GLboolean is_enabled;
94 /* check if visual supports API */
95 glGetBooleanv(GL_FRAMEBUFFER_SRGB_CAPABLE_EXT, &boolmode);
96 ret = glGetError();
97 if (ret != 0) {
98 printf("unexpected error glGetBooleanv(GL_FRAMEBUFFER_SRGB_CAPABLE_EXT) %d\n", ret);
99 pass = GL_FALSE;
102 (void) glIsEnabled(GL_FRAMEBUFFER_SRGB_EXT); /* ignore return value */
103 ret = glGetError();
104 if (ret != 0) {
105 printf("unexpected error getting IsEnabled %d\n", ret);
106 pass = GL_FALSE;
109 /* should be possible to enable/disable independent of capable bit */
110 glEnable(GL_FRAMEBUFFER_SRGB_EXT);
111 is_enabled = glIsEnabled(GL_FRAMEBUFFER_SRGB_EXT);
112 if (!is_enabled) {
113 printf("SRGB not enabled after calling glEnable\n");
114 pass = GL_FALSE;
117 glDisable(GL_FRAMEBUFFER_SRGB_EXT);
118 is_enabled = glIsEnabled(GL_FRAMEBUFFER_SRGB_EXT);
119 if (is_enabled) {
120 printf("SRGB not disabled after calling glDisable\n");
121 pass = GL_FALSE;
123 return pass;
127 * Common code for framebuffer and FBO tests.
129 static GLboolean
130 test_srgb(void)
132 GLboolean pass = GL_TRUE;
133 GLboolean srgb_capable;
134 float green[] = {0, 0.3, 0, 0};
135 float expected_green[4];
136 float expected_blend[4];
139 * Note: the window-system framebuffer may or may not be sRGB capable.
140 * But the user-created FBO should be sRGB capable.
142 glGetBooleanv(GL_FRAMEBUFFER_SRGB_CAPABLE_EXT, &srgb_capable);
144 glDisable(GL_BLEND);
145 glClear(GL_COLOR_BUFFER_BIT);
146 glDisable(GL_FRAMEBUFFER_SRGB_EXT);
147 glColor4fv(green);
150 * First square: draw green square without sRGB and no blending
152 piglit_draw_rect(0, 0, 20, 20);
155 * Second square: draw a green square with sRGB enabled and no blending
157 glEnable(GL_FRAMEBUFFER_SRGB_EXT);
158 piglit_draw_rect(20, 0, 20, 20);
161 * Third square: draw green square, then blend/add another on top of it
163 glEnable(GL_FRAMEBUFFER_SRGB_EXT);
164 piglit_draw_rect(40, 0, 20, 20);
165 glEnable(GL_BLEND);
166 glBlendFunc(GL_ONE, GL_ONE);
167 piglit_draw_rect(40, 0, 20, 20);
168 glDisable(GL_BLEND);
169 glDisable(GL_FRAMEBUFFER_SRGB_EXT);
172 * Check first square.
174 if (!piglit_probe_rect_rgb(0, 0, 20, 20, green))
175 pass = GL_FALSE;
176 /* check pixel path */
177 glEnable(GL_FRAMEBUFFER_SRGB_EXT);
178 if (!piglit_probe_rect_rgb(0, 0, 20, 20, green))
179 pass = GL_FALSE;
180 glDisable(GL_FRAMEBUFFER_SRGB_EXT);
183 * Check second square
185 memcpy(expected_green, green, sizeof(float) * 4);
186 if (srgb_capable)
187 expected_green[1] = piglit_linear_to_srgb(green[1]);
188 if (!piglit_probe_rect_rgb(20, 0, 20, 20, expected_green))
189 pass = GL_FALSE;
190 /* check it doesn't affect the pixel path */
191 glEnable(GL_FRAMEBUFFER_SRGB_EXT);
192 if (!piglit_probe_rect_rgb(20, 0, 20, 20, expected_green))
193 pass = GL_FALSE;
194 glDisable(GL_FRAMEBUFFER_SRGB_EXT);
197 * Check third square
199 memcpy(expected_blend, green, sizeof(float) * 4);
200 if (srgb_capable)
201 expected_blend[1] = piglit_linear_to_srgb(green[1] * 2.0);
202 else
203 expected_blend[1] = green[1] * 2.0;
204 if (!piglit_probe_rect_rgb(40, 0, 20, 20, expected_blend))
205 pass = GL_FALSE;
207 return pass;
210 static GLboolean
211 framebuffer_srgb_non_fbo(void)
213 GLboolean pass;
215 glViewport(0, 0, piglit_width, piglit_height);
216 piglit_ortho_projection(piglit_width, piglit_height, GL_FALSE);
218 pass = test_srgb();
219 piglit_present_results();
220 return pass;
223 static GLuint
224 make_fbo(int w, int h)
226 GLuint tex;
227 GLuint fb;
228 GLenum status;
230 glGenFramebuffersEXT(1, &fb);
231 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fb);
233 glGenTextures(1, &tex);
234 glBindTexture(GL_TEXTURE_2D, tex);
235 glTexImage2D(GL_TEXTURE_2D, 0, GL_SRGB8_ALPHA8_EXT,
236 w, h, 0,
237 GL_RGBA, GL_UNSIGNED_BYTE, NULL);
239 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
240 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
242 glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT,
243 GL_COLOR_ATTACHMENT0_EXT,
244 GL_TEXTURE_2D,
245 tex,
247 if (!piglit_check_gl_error(GL_NO_ERROR))
248 piglit_report_result(PIGLIT_FAIL);
250 status = glCheckFramebufferStatusEXT (GL_FRAMEBUFFER_EXT);
251 if (status != GL_FRAMEBUFFER_COMPLETE_EXT) {
252 fprintf(stderr, "fbo incomplete (status = 0x%04x)\n", status);
253 piglit_report_result(PIGLIT_SKIP);
256 return fb;
259 static void
260 draw_fbo(int x, int y)
262 glViewport(0, 0, piglit_width, piglit_height);
263 piglit_ortho_projection(piglit_width, piglit_height, GL_FALSE);
265 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, piglit_winsys_fbo);
267 glEnable(GL_TEXTURE_2D);
268 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
269 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
270 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
271 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
272 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
273 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
275 glClear(GL_COLOR_BUFFER_BIT);
276 piglit_draw_rect_tex(x, y, FBO_SIZE, FBO_SIZE,
277 0, 0, 1, 1);
278 glDisable(GL_TEXTURE_2D);
281 static GLboolean
282 framebuffer_srgb_fbo(void)
284 GLboolean pass = GL_TRUE;
285 int fbo_width = FBO_SIZE;
286 int fbo_height = FBO_SIZE;
287 GLuint fbo;
289 fbo = make_fbo(fbo_width, fbo_height);
290 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, fbo);
291 glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, fbo);
292 glViewport(0, 0, fbo_width, fbo_height);
294 piglit_ortho_projection(fbo_width, fbo_height, GL_FALSE);
296 pass = test_srgb();
298 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, piglit_winsys_fbo);
299 glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, piglit_winsys_fbo);
300 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, piglit_winsys_fbo);
302 draw_fbo(0, 0);
303 piglit_present_results();
304 glDeleteFramebuffersEXT(1, &fbo);
305 return pass;
308 enum piglit_result
309 piglit_display(void)
311 GLboolean pass = GL_TRUE;
312 GLboolean have_srgb_ext = GL_FALSE;
314 if (piglit_is_extension_supported("GL_ARB_framebuffer_sRGB"))
315 have_srgb_ext = GL_TRUE;
317 if (!have_srgb_ext) {
318 pass = framebuffer_srgb_api_no_ext();
319 goto out;
322 pass = framebuffer_srgb_api_ext();
323 if (pass == GL_TRUE)
324 pass = framebuffer_srgb_non_fbo();
326 if (pass == GL_TRUE)
327 pass = framebuffer_srgb_fbo();
329 out:
330 return pass ? PIGLIT_PASS : PIGLIT_FAIL;
334 static void reshape(int width, int height)
336 piglit_width = width;
337 piglit_height = height;
339 piglit_ortho_projection(width, height, GL_FALSE);
342 void
343 piglit_init(int argc, char **argv)
345 reshape(piglit_width, piglit_height);
346 piglit_require_extension("GL_EXT_framebuffer_object");
347 piglit_require_extension("GL_EXT_framebuffer_blit");
349 glClearColor(0.5, 0.5, 0.5, 1.0);