1 /*
2  * Copyright © 2009-2011 Intel Corporation
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  * Authors:
24  *    Eric Anholt <eric@anholt.net>
25  *
26  */
27 
28 /** @file fbo-clear-formats.c
29  *
30  * Tests that glClear works correctly on all levels of 2D
31  * texture-based FBOs of various internalformats.
32  */
33 
34 #include "piglit-util-gl.h"
35 #include "fbo-formats.h"
36 
37 #define TEX_WIDTH 256
38 #define TEX_HEIGHT 256
39 
40 PIGLIT_GL_TEST_CONFIG_BEGIN
41 
42 	config.supports_gl_compat_version = 10;
43 
44 	config.window_width = 700;
45 	config.window_height = 300;
46 	config.window_visual = PIGLIT_GL_VISUAL_DOUBLE | PIGLIT_GL_VISUAL_STENCIL |
47 			       PIGLIT_GL_VISUAL_RGBA;
48 	config.khr_no_error_support = PIGLIT_NO_ERRORS;
49 
50 PIGLIT_GL_TEST_CONFIG_END
51 
52 static bool clear_stencil = false;
53 
54 /* Do piglit_rgbw_texture() image but using glClear */
55 static bool
do_rgba_clear(GLenum format,GLuint tex,int level,int size)56 do_rgba_clear(GLenum format, GLuint tex, int level, int size)
57 {
58 	float red[4]   = {1.0, 0.0, 0.0, 0.0};
59 	float green[4] = {0.0, 1.0, 0.0, 0.25};
60 	float blue[4]  = {0.0, 0.0, 1.0, 0.5};
61 	float white[4] = {1.0, 1.0, 1.0, 1.0};
62 	float black[4] = {0.0, 0.0, 0.0, 0.0};
63 	float *color;
64 	GLuint fb;
65 	GLenum status;
66 
67 	glGenFramebuffersEXT(1, &fb);
68 	glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fb);
69 
70 	glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT,
71 				  GL_COLOR_ATTACHMENT0_EXT,
72 				  GL_TEXTURE_2D,
73 				  tex,
74 				  level);
75 
76 	status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
77 	if (status != GL_FRAMEBUFFER_COMPLETE_EXT) {
78 		glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, piglit_winsys_fbo);
79 		glDeleteFramebuffersEXT(1, &fb);
80 		return false;
81 	}
82 
83 	/* Handle the small sizes of compressed mipmap blocks */
84 	switch (format) {
85 	case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
86 	case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
87 	case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
88 	case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
89 	case GL_COMPRESSED_RGB_FXT1_3DFX:
90 	case GL_COMPRESSED_RGBA_FXT1_3DFX:
91 		if (size == 4)
92 			color = red;
93 		else if (size == 2)
94 			color = green;
95 		else if (size == 1)
96 			color = blue;
97 		else {
98 			assert(0);
99 			color = black;
100 		}
101 		glClearColor(color[0], color[1], color[2], color[3]);
102 		glClear(GL_COLOR_BUFFER_BIT);
103 		return true;
104 	}
105 
106 	/* Do the first clear unscissored, to give a bit of exposure
107 	 * to hardware fast-clearing paths on tiled renderers that
108 	 * require unscissored clears.
109 	 */
110 	glClearColor(red[0], red[1], red[2], red[3]);
111 	glClear(GL_COLOR_BUFFER_BIT);
112 
113 	glEnable(GL_SCISSOR_TEST);
114 	glScissor(size / 2, 0, size / 2, size / 2);
115 	glClearColor(green[0], green[1], green[2], green[3]);
116 	glClear(GL_COLOR_BUFFER_BIT);
117 
118 	glScissor(0, size / 2, size / 2, size / 2);
119 	glClearColor(blue[0], blue[1], blue[2], blue[3]);
120 	glClear(GL_COLOR_BUFFER_BIT);
121 
122 	glScissor(size / 2, size / 2, size / 2, size / 2);
123 	glClearColor(white[0], white[1], white[2], white[3]);
124 	glClear(GL_COLOR_BUFFER_BIT);
125 
126 	glDisable(GL_SCISSOR_TEST);
127 
128 	glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, piglit_winsys_fbo);
129 	glDeleteFramebuffersEXT(1, &fb);
130 
131 	return true;
132 }
133 
134 static bool
do_depth_clear(GLenum format,GLuint tex,int level,int size)135 do_depth_clear(GLenum format, GLuint tex, int level, int size)
136 {
137 	GLuint fb;
138 	GLenum status;
139 	GLint draw_buffer, read_buffer;
140 	int x;
141 
142 	glGetIntegerv(GL_DRAW_BUFFER, &draw_buffer);
143 	glGetIntegerv(GL_READ_BUFFER, &read_buffer);
144 
145 	glGenFramebuffersEXT(1, &fb);
146 	glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fb);
147 
148 	glDrawBuffer(GL_NONE);
149 	glReadBuffer(GL_NONE);
150 
151 	glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT,
152 				  GL_DEPTH_ATTACHMENT_EXT,
153 				  GL_TEXTURE_2D,
154 				  tex,
155 				  level);
156 
157 	status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
158 	if (status != GL_FRAMEBUFFER_COMPLETE_EXT) {
159 		glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, piglit_winsys_fbo);
160 		glDeleteFramebuffersEXT(1, &fb);
161 		return false;
162 	}
163 
164 	glEnable(GL_SCISSOR_TEST);
165 
166 	for (x = 0; x < size; x++) {
167 		float val = (x + 0.5) / (size);
168 		glScissor(x, 0, 1, size);
169 		glClearDepth(val);
170 		glClear(GL_DEPTH_BUFFER_BIT);
171 	}
172 
173 	glDisable(GL_SCISSOR_TEST);
174 
175 	glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, piglit_winsys_fbo);
176 	glDeleteFramebuffersEXT(1, &fb);
177 
178 	glDrawBuffer(draw_buffer);
179 	glReadBuffer(read_buffer);
180 
181 	return true;
182 }
183 
184 static bool
do_stencil_clear(GLenum format,GLuint tex,int level,int size)185 do_stencil_clear(GLenum format, GLuint tex, int level, int size)
186 {
187 	GLuint fb;
188 	GLenum status;
189 	GLint draw_buffer, read_buffer;
190 	int x;
191 
192 	glGetIntegerv(GL_DRAW_BUFFER, &draw_buffer);
193 	glGetIntegerv(GL_READ_BUFFER, &read_buffer);
194 
195 	glGenFramebuffersEXT(1, &fb);
196 	glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fb);
197 
198 	glDrawBuffer(GL_NONE);
199 	glReadBuffer(GL_NONE);
200 
201 	glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT,
202 				  GL_DEPTH_STENCIL_ATTACHMENT,
203 				  GL_TEXTURE_2D,
204 				  tex,
205 				  level);
206 
207 	status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
208 	if (status != GL_FRAMEBUFFER_COMPLETE_EXT) {
209 		glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, piglit_winsys_fbo);
210 		glDeleteFramebuffersEXT(1, &fb);
211 		return false;
212 	}
213 
214 	glEnable(GL_SCISSOR_TEST);
215 
216 	for (x = 0; x < size; x++) {
217 		unsigned val = ((x + 0.5) / (size)) * 0xff;
218 		glScissor(x, 0, 1, size);
219 		glClearStencil(val);
220 		glClear(GL_STENCIL_BUFFER_BIT);
221 	}
222 
223 	glDisable(GL_SCISSOR_TEST);
224 
225 	glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, piglit_winsys_fbo);
226 	glDeleteFramebuffersEXT(1, &fb);
227 
228 	glDrawBuffer(draw_buffer);
229 	glReadBuffer(read_buffer);
230 
231         if (!piglit_check_gl_error(GL_NO_ERROR)) {
232 		/* Should be no error at this point.  If there is, report failure */
233 		piglit_report_result(PIGLIT_FAIL);
234         }
235 
236 	return true;
237 }
238 
239 static GLuint
create_tex(GLenum internalformat,GLenum baseformat)240 create_tex(GLenum internalformat, GLenum baseformat)
241 {
242 	GLuint tex;
243 	int level, dim;
244 	GLenum type, format;
245 
246 	glGenTextures(1, &tex);
247 	glBindTexture(GL_TEXTURE_2D, tex);
248 
249 	if (internalformat == GL_DEPTH32F_STENCIL8) {
250 		format = GL_DEPTH_STENCIL;
251 		type = GL_FLOAT_32_UNSIGNED_INT_24_8_REV;
252 	} else if (baseformat == GL_DEPTH_COMPONENT) {
253 		format = GL_DEPTH_COMPONENT;
254 		type = GL_FLOAT;
255 	} else if (baseformat == GL_DEPTH_STENCIL) {
256 		format = GL_DEPTH_STENCIL_EXT;
257 		type = GL_UNSIGNED_INT_24_8_EXT;
258 	} else {
259 		format = GL_RGBA;
260 		type = GL_FLOAT;
261 	}
262 
263 	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,
264 			GL_LINEAR);
265 	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
266 			GL_LINEAR_MIPMAP_NEAREST);
267 
268 	for (level = 0, dim = TEX_WIDTH; dim > 0; level++, dim /= 2) {
269 		glTexImage2D(GL_TEXTURE_2D, level, internalformat,
270 			     dim, dim,
271 			     0,
272 			     format, type, NULL);
273 	}
274 
275 	for (level = 0, dim = TEX_WIDTH; dim > 0; level++, dim /= 2) {
276 		glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, level);
277 		glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, level);
278 
279 		if (clear_stencil || baseformat == GL_STENCIL_INDEX) {
280 			if (!do_stencil_clear(format, tex, level, dim)) {
281 				glDeleteTextures(1, &tex);
282 				return 0;
283 			}
284 		} else if (baseformat == GL_DEPTH_COMPONENT ||
285 			   baseformat == GL_DEPTH_STENCIL) {
286 			if (!do_depth_clear(format, tex, level, dim)) {
287 				glDeleteTextures(1, &tex);
288 				return 0;
289 			}
290 		} else {
291 			if (!do_rgba_clear(format, tex, level, dim)) {
292 				glDeleteTextures(1, &tex);
293 				return 0;
294 			}
295 		}
296 	}
297 
298 	glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, level - 1);
299         glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
300 
301         if (!piglit_check_gl_error(GL_NO_ERROR)) {
302 		/* Should be no error at this point.  If there is, report failure */
303 		piglit_report_result(PIGLIT_FAIL);
304         }
305 
306 	return tex;
307 }
308 
309 static void
draw_mipmap(int x,int y,int dim)310 draw_mipmap(int x, int y, int dim)
311 {
312 	glEnable(GL_TEXTURE_2D);
313 	glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
314 	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
315 	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
316 
317 	piglit_draw_rect_tex(x, y, dim, dim,
318 			     0, 0, 1, 1);
319 
320 	glDisable(GL_TEXTURE_2D);
321 }
322 
323 static void
draw_stencil_mipmap(int x,int y,int dim,GLuint tex,GLuint level)324 draw_stencil_mipmap(int x, int y, int dim, GLuint tex, GLuint level)
325 {
326 	GLuint fbo;
327 	GLint draw_buffer, read_buffer;
328 
329 	glGetIntegerv(GL_DRAW_BUFFER, &draw_buffer);
330 	glGetIntegerv(GL_READ_BUFFER, &read_buffer);
331 
332 	glGenFramebuffers(1, &fbo);
333 	glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo);
334 
335 	glDrawBuffer(GL_NONE);
336 	glReadBuffer(GL_NONE);
337 
338 	glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT,
339 			       GL_TEXTURE_2D, tex, level);
340 	glBindFramebuffer(GL_DRAW_FRAMEBUFFER, piglit_winsys_fbo);
341         glWindowPos2i(x, y);
342         glCopyPixels(0, 0, dim, dim, GL_STENCIL);
343         if (!piglit_check_gl_error(GL_NO_ERROR)) {
344 		/* The blit shouldn't generate an error.  If it does, report failure */
345 		piglit_report_result(PIGLIT_FAIL);
346         }
347 
348 	glBindFramebuffer(GL_FRAMEBUFFER, piglit_winsys_fbo);
349 	glDeleteFramebuffers(1, &fbo);
350 
351 	glDrawBuffer(draw_buffer);
352 	glReadBuffer(read_buffer);
353 }
354 
355 static void
visualize_stencil()356 visualize_stencil()
357 {
358 	unsigned i;
359 
360 	glEnable(GL_STENCIL_TEST);
361 	glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
362 	for (i = 0; i <= 0xff; i++) {
363 		glStencilFunc(GL_EQUAL, i, ~0);
364 		glColor4ub(i, i, i, 255);
365 		piglit_draw_rect(0, 0, piglit_width, piglit_height);
366 	}
367 	glDisable(GL_STENCIL_TEST);
368 	glColor4ub(255, 255, 255, 255);
369 }
370 
371 static GLboolean
test_mipmap_drawing(int x,int y,int dim,int level,GLuint internalformat)372 test_mipmap_drawing(int x, int y, int dim, int level, GLuint internalformat)
373 {
374 	GLboolean pass = GL_TRUE;
375 	int half = dim / 2;
376 	int x1 = x, y1 = y, x2 = x + half, y2 = y + half;
377 	float r[] = {1, 0, 0, 0};
378 	float g[] = {0, 1, 0, 0.25};
379 	float b[] = {0, 0, 1, 0.5};
380 	float w[] = {1, 1, 1, 1};
381 	GLint r_size, g_size, b_size, l_size, a_size, d_size, i_size;
382 	GLint compressed;
383 
384 	glGetTexLevelParameteriv(GL_TEXTURE_2D, level,
385 				 GL_TEXTURE_COMPRESSED, &compressed);
386 	if (compressed && dim < 8)
387 		return GL_TRUE;
388 
389 	if (piglit_is_extension_supported("GL_ARB_depth_texture")) {
390 		glGetTexLevelParameteriv(GL_TEXTURE_2D, level,
391 					 GL_TEXTURE_DEPTH_SIZE, &d_size);
392 	} else {
393 		d_size = 0;
394 	}
395 	glGetTexLevelParameteriv(GL_TEXTURE_2D, level,
396 				 GL_TEXTURE_LUMINANCE_SIZE, &l_size);
397 	glGetTexLevelParameteriv(GL_TEXTURE_2D, level,
398 				 GL_TEXTURE_ALPHA_SIZE, &a_size);
399 	glGetTexLevelParameteriv(GL_TEXTURE_2D, level,
400 				 GL_TEXTURE_INTENSITY_SIZE, &i_size);
401 	glGetTexLevelParameteriv(GL_TEXTURE_2D, level,
402 				 GL_TEXTURE_RED_SIZE, &r_size);
403 	glGetTexLevelParameteriv(GL_TEXTURE_2D, level,
404 				 GL_TEXTURE_GREEN_SIZE, &g_size);
405 	glGetTexLevelParameteriv(GL_TEXTURE_2D, level,
406 				 GL_TEXTURE_BLUE_SIZE, &b_size);
407 
408 	if (d_size) {
409 		for (x1 = x; x1 < x + dim; x1++) {
410 			float val = (x1 - x + 0.5) / (dim);
411 			float color[3] = {val, val, val};
412 			pass = pass && piglit_probe_rect_rgb(x1, y, 1, dim,
413 							     color);
414 		}
415 		return pass;
416 	}
417 
418 	if (i_size || l_size) {
419 		r[0] = 1.0;
420 		r[1] = 1.0;
421 		r[2] = 1.0;
422 
423 		g[0] = 0.0;
424 		g[1] = 0.0;
425 		g[2] = 0.0;
426 
427 		b[0] = 0.0;
428 		b[1] = 0.0;
429 		b[2] = 0.0;
430 
431 		if (i_size) {
432 			r[3] = 1.0;
433 			g[3] = 0.0;
434 			b[3] = 0.0;
435 		} else if (l_size && !a_size) {
436 			r[3] = 1.0;
437 			g[3] = 1.0;
438 			b[3] = 1.0;
439 			w[3] = 1.0;
440 		}
441 	} else if (a_size && !r_size && !l_size) {
442 		r[0] = 1.0;
443 		r[1] = 1.0;
444 		r[2] = 1.0;
445 		g[0] = 1.0;
446 		g[1] = 1.0;
447 		g[2] = 1.0;
448 		b[0] = 1.0;
449 		b[1] = 1.0;
450 		b[2] = 1.0;
451 	} else {
452 		if (!r_size) {
453 			r[0] = 0.0;
454 			w[0] = 0.0;
455 		}
456 
457 		if (!g_size) {
458 			g[1] = 0.0;
459 			w[1] = 0.0;
460 		}
461 
462 		if (!b_size) {
463 			b[2] = 0.0;
464 			w[2] = 0.0;
465 		}
466 		if (!a_size) {
467 			r[3] = 1.0;
468 			g[3] = 1.0;
469 			b[3] = 1.0;
470 			w[3] = 1.0;
471 		}
472 	}
473 
474 	/* Clamp the bits for the framebuffer, except we aren't checking
475 	 * the actual framebuffer bits.
476 	 */
477 	if (l_size > 8)
478 		l_size = 8;
479 	if (i_size > 8)
480 		i_size = 8;
481 	if (r_size > 8)
482 		r_size = 8;
483 	if (g_size > 8)
484 		g_size = 8;
485 	if (b_size > 8)
486 		b_size = 8;
487 	if (a_size > 8)
488 		a_size = 8;
489 
490 	if (d_size) {
491 		piglit_set_tolerance_for_bits(8, 8, 8, 8);
492 	} else if (i_size) {
493 		piglit_set_tolerance_for_bits(i_size, i_size, i_size, i_size);
494 	} else if (l_size) {
495 		piglit_set_tolerance_for_bits(l_size, l_size, l_size, a_size);
496 	} else {
497 		piglit_set_tolerance_for_bits(r_size, g_size, b_size, a_size);
498 	}
499 
500 	if (internalformat == GL_COMPRESSED_RGBA_S3TC_DXT1_EXT ||
501 	    internalformat == GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT) {
502 		/* If alpha in DXT1 is < 0.5, the whole pixel should be black. */
503 		r[0] = r[1] = r[2] = r[3] = 0;
504 		g[0] = g[1] = g[2] = g[3] = 0;
505 		/* If alpha in DXT1 is >= 0.5, it should be white. */
506 		b[3] = 1;
507 	}
508 
509 	pass = pass && piglit_probe_rect_rgba(x1, y1, half, half, r);
510 	pass = pass && piglit_probe_rect_rgba(x2, y1, half, half, g);
511 	pass = pass && piglit_probe_rect_rgba(x1, y2, half, half, b);
512 	pass = pass && piglit_probe_rect_rgba(x2, y2, half, half, w);
513 
514 	return pass;
515 }
516 
517 static enum piglit_result
test_format(const struct format_desc * format)518 test_format(const struct format_desc *format)
519 {
520 	int dim;
521 	GLuint tex;
522 	int x;
523 	int level;
524 	GLboolean pass = GL_TRUE;
525 	const char *name = get_format_name(format->internalformat);
526 
527 	printf("Testing %s", name);
528 
529 	if (format->base_internal_format == GL_STENCIL_INDEX)
530 		clear_stencil = true;
531 
532 	if (clear_stencil && format->base_internal_format != GL_DEPTH_STENCIL &&
533 	    format->base_internal_format != GL_STENCIL_INDEX) {
534 		printf(" - no stencil.\n");
535 		return PIGLIT_SKIP;
536 	}
537 
538 	tex = create_tex(format->internalformat, format->base_internal_format);
539 	if (tex == 0) {
540 		printf(" - FBO incomplete\n");
541 		piglit_report_subtest_result(PIGLIT_SKIP,
542 					     "%s (fbo incomplete)",
543 					     name);
544 		return PIGLIT_SKIP;
545 	}
546 	printf("\n");
547 
548 	if (clear_stencil) {
549 		glClearStencil(0x0);
550 		glClear(GL_STENCIL_BUFFER_BIT);
551 	}
552 
553 	glViewport(0, 0, piglit_width, piglit_height);
554 	piglit_ortho_projection(piglit_width, piglit_height, GL_FALSE);
555 
556 	x = 1;
557 	level = 0;
558 	for (dim = TEX_WIDTH; dim > 1; dim /= 2) {
559 		if (clear_stencil)
560 			draw_stencil_mipmap(x, 1, dim, tex, level);
561 		else
562 			draw_mipmap(x, 1, dim);
563 		x += dim + 1;
564 		level++;
565 	}
566 
567 	if (clear_stencil)
568 		visualize_stencil();
569 
570 	x = 1;
571 	level = 0;
572 	for (dim = TEX_WIDTH; dim > 1; dim /= 2) {
573 		pass = pass && test_mipmap_drawing(x, 1, dim, level,
574 						   format->internalformat);
575 		x += dim + 1;
576 		level++;
577 	}
578 
579 	glDeleteTextures(1, &tex);
580 
581 	piglit_report_subtest_result(pass ? PIGLIT_PASS : PIGLIT_FAIL,
582 				     "%s", name);
583 	return pass ? PIGLIT_PASS : PIGLIT_FAIL;
584 }
585 
piglit_display(void)586 enum piglit_result piglit_display(void)
587 {
588 	return fbo_formats_display(test_format);
589 }
590 
piglit_init(int argc,char ** argv)591 void piglit_init(int argc, char **argv)
592 {
593 	if (argc == 3 && strcmp(argv[2], "stencil") == 0)
594 		clear_stencil = true;
595 
596 	if (clear_stencil)
597 		piglit_require_extension("GL_ARB_framebuffer_object");
598 
599 	fbo_formats_init(clear_stencil ? 2 : argc, argv, GL_TRUE);
600 }
601