2 * Copyright © 2011 Intel Corporation
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
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
24 * Chad Versace <chad.versace@intel.com>
29 * \copybrief hiz-util.h
30 * \author Chad Versace <chad.versace@intel.com>
34 #include "piglit-util-gl.h"
35 #include "hiz/hiz-util.h"
37 #define hiz_probe_common(probe_func, expect) \
39 const float dx = piglit_width / 9.0; \
40 const float dy = piglit_height / 9.0; \
45 for (iy = 0; iy < 3; ++iy) for (ix = 0; ix < 3; ++ix) { \
46 int x = (3 * ix + 1) * dx; \
47 int y = (3 * iy + 1) * dy; \
48 int i = 3 * (2 - iy) + ix; \
49 pass &= probe_func(x, y, dx, dy, expect[i]); \
56 hiz_probe_color_buffer(const float *expected_colors
[])
58 hiz_probe_common(piglit_probe_rect_rgb
, expected_colors
);
62 hiz_probe_depth_buffer(const float expected_depths
[])
64 hiz_probe_common(piglit_probe_rect_depth
, expected_depths
);
68 hiz_probe_stencil_buffer(const unsigned expected_stencil
[])
70 hiz_probe_common(piglit_probe_rect_stencil
, expected_stencil
);
75 hiz_make_fbo(const struct hiz_fbo_options
*options
)
81 GLuint stencil_rb
= 0;
82 GLuint depth_stencil_rb
= 0;
84 glGenFramebuffers(1, &fb
);
85 glBindFramebuffer(GL_FRAMEBUFFER
, fb
);
87 /* Bind color attachment. */
88 if (options
->color_format
!= 0) {
89 glGenRenderbuffers(1, &color_rb
);
90 glBindRenderbuffer(GL_RENDERBUFFER
, color_rb
);
91 glRenderbufferStorage(GL_RENDERBUFFER
,
92 options
->color_format
,
93 piglit_width
, piglit_height
);
94 glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER
,
98 if (!piglit_check_gl_error(0))
99 piglit_report_result(PIGLIT_FAIL
);
102 /* Bind depth attachment. */
103 if (options
->depth_format
!= 0) {
104 glGenRenderbuffers(1, &depth_rb
);
105 glBindRenderbuffer(GL_RENDERBUFFER
, depth_rb
);
106 glRenderbufferStorage(GL_RENDERBUFFER
,
107 options
->depth_format
,
108 piglit_width
, piglit_height
);
109 glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER
,
113 if (!piglit_check_gl_error(0))
114 piglit_report_result(PIGLIT_FAIL
);
117 /* Bind stencil attachment. */
118 if (options
->stencil_format
!= 0) {
119 glGenRenderbuffers(1, &stencil_rb
);
120 glBindRenderbuffer(GL_RENDERBUFFER
, stencil_rb
);
121 glRenderbufferStorage(GL_RENDERBUFFER
,
122 options
->stencil_format
,
123 piglit_width
, piglit_height
);
124 glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER
,
125 GL_STENCIL_ATTACHMENT
,
128 if (!piglit_check_gl_error(0))
129 piglit_report_result(PIGLIT_FAIL
);
132 /* Bind depth/stencil attachment. */
133 if (options
->depth_stencil_format
!= 0) {
134 glGenRenderbuffers(1, &depth_stencil_rb
);
135 glBindRenderbuffer(GL_RENDERBUFFER
, depth_stencil_rb
);
136 glRenderbufferStorage(GL_RENDERBUFFER
,
137 options
->depth_stencil_format
,
138 piglit_width
, piglit_height
);
139 glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER
,
140 GL_DEPTH_STENCIL_ATTACHMENT
,
143 if (!piglit_check_gl_error(0))
144 piglit_report_result(PIGLIT_FAIL
);
147 fb_status
= glCheckFramebufferStatus(GL_FRAMEBUFFER
);
148 if (fb_status
!= GL_FRAMEBUFFER_COMPLETE
) {
149 printf("error: FBO incomplete (status = 0x%04x)\n", fb_status
);
150 piglit_report_result(PIGLIT_SKIP
);
157 hiz_delete_fbo(GLuint fbo
)
160 const GLenum attachments
[] = {
161 GL_COLOR_ATTACHMENT0
,
162 GL_DEPTH_STENCIL_ATTACHMENT
,
164 GL_STENCIL_ATTACHMENT
,
168 for (i
= attachments
; *i
!= 0; ++i
) {
170 glGetFramebufferAttachmentParameteriv(
172 GL_COLOR_ATTACHMENT0
,
173 GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME
,
176 glDeleteRenderbuffers(1, &name
);
179 glDeleteFramebuffers(1, &fbo
);
181 glBindFramebuffer(GL_DRAW_FRAMEBUFFER
, piglit_winsys_fbo
);
182 glBindFramebuffer(GL_READ_FRAMEBUFFER
, piglit_winsys_fbo
);
184 if (!piglit_check_gl_error(0))
185 piglit_report_result(PIGLIT_FAIL
);
188 /* ------------------------------------------------------------------------ */
191 * \name hiz_run_depth_test utilities
193 * Utilities for testing depth testing.
199 * Common functionality needed by hiz_run_test_depth_test_fbo() and
200 * hiz_run_test_depth_test_window().
203 hiz_run_test_depth_test_common()
205 static const float *expect_color
[9] = {
206 hiz_grey
, hiz_blue
, hiz_blue
,
207 hiz_green
, hiz_green
, hiz_blue
,
208 hiz_green
, hiz_green
, hiz_grey
,
211 const float width_3
= piglit_width
/ 3.0;
212 const float height_3
= piglit_height
/ 3.0;
214 glEnable(GL_DEPTH_TEST
);
215 glDepthFunc(GL_LESS
);
216 glClearDepth(hiz_clear_z
);
217 glClearColor(hiz_grey
[0], hiz_grey
[1], hiz_grey
[2], hiz_grey
[3]);
218 glClear(GL_COLOR_BUFFER_BIT
| GL_DEPTH_BUFFER_BIT
);
220 glViewport(0, 0, piglit_width
, piglit_height
);
221 piglit_ortho_projection(piglit_width
, piglit_height
, false);
223 glColor4fv(hiz_green
);
224 glDepthRange(hiz_green_z
, hiz_green_z
);
225 piglit_draw_rect(0 * width_3
, 0 * width_3
, /* x, y */
226 2 * width_3
, 2 * height_3
); /* width, height */
228 glColor4fv(hiz_blue
);
229 glDepthRange(hiz_blue_z
, hiz_blue_z
);
230 piglit_draw_rect(1 * width_3
, 1 * height_3
, /* x, y */
231 2 * width_3
, 2 * height_3
); /* width, height */
236 return hiz_probe_color_buffer(expect_color
);
240 hiz_run_test_depth_test_fbo(const struct hiz_fbo_options
*fbo_options
)
245 piglit_require_extension("GL_ARB_framebuffer_object");
247 /* Create and bind FBO. */
248 fbo
= hiz_make_fbo(fbo_options
);
250 glBindFramebuffer(GL_DRAW_FRAMEBUFFER
, fbo
);
251 glBindFramebuffer(GL_READ_FRAMEBUFFER
, fbo
);
253 pass
= hiz_run_test_depth_test_common();
255 if (!piglit_automatic
) {
256 /* Blit the FBO to the window FB so we can see the results. */
257 glBindFramebuffer(GL_DRAW_FRAMEBUFFER
, piglit_winsys_fbo
);
258 glBlitFramebuffer(0, 0, piglit_width
, piglit_height
,
259 0, 0, piglit_width
, piglit_height
,
260 GL_COLOR_BUFFER_BIT
, GL_NEAREST
);
261 piglit_present_results();
262 glBindFramebuffer(GL_DRAW_FRAMEBUFFER
, fbo
);
271 hiz_run_test_depth_test_window()
273 bool pass
= hiz_run_test_depth_test_common();
274 if (!piglit_automatic
)
275 piglit_present_results();
281 /* ------------------------------------------------------------------------ */
284 * \name hiz_run_depth_read utilities
286 * Utilities for testing depth reads.
292 * Common functionality needed by hiz_run_test_depth_read_fbo() and
293 * hiz_run_test_depth_read_window().
296 hiz_run_test_depth_read_common()
298 static const float *expect_color
[9] = {
299 hiz_grey
, hiz_blue
, hiz_blue
,
300 hiz_green
, hiz_green
, hiz_blue
,
301 hiz_green
, hiz_green
, hiz_grey
,
304 static const float expect_depth
[9] = {
305 hiz_clear_z
, hiz_blue_z
, hiz_blue_z
,
306 hiz_green_z
, hiz_green_z
, hiz_blue_z
,
307 hiz_green_z
, hiz_green_z
, hiz_clear_z
,
311 const float width_3
= piglit_width
/ 3.0;
312 const float height_3
= piglit_height
/ 3.0;
314 glDisable(GL_STENCIL_TEST
);
316 glEnable(GL_DEPTH_TEST
);
317 glDepthFunc(GL_LESS
);
318 glClearDepth(hiz_clear_z
);
319 glClearColor(hiz_grey
[0], hiz_grey
[1], hiz_grey
[2], hiz_grey
[3]);
320 glClear(GL_COLOR_BUFFER_BIT
| GL_DEPTH_BUFFER_BIT
);
322 glViewport(0, 0, piglit_width
, piglit_height
);
323 piglit_ortho_projection(piglit_width
, piglit_height
, false);
325 glColor4fv(hiz_green
);
326 glDepthRange(hiz_green_z
, hiz_green_z
);
327 piglit_draw_rect(0 * width_3
, 0 * width_3
, /* x, y */
328 2 * width_3
, 2 * height_3
); /* width, height */
330 glColor4fv(hiz_blue
);
331 glDepthRange(hiz_blue_z
, hiz_blue_z
);
332 piglit_draw_rect(1 * width_3
, 1 * height_3
, /* x, y */
333 2 * width_3
, 2 * height_3
); /* width, height */
338 if (!hiz_probe_color_buffer(expect_color
))
340 return hiz_probe_depth_buffer(expect_depth
);
344 hiz_run_test_depth_read_fbo(const struct hiz_fbo_options
*fbo_options
)
349 piglit_require_extension("GL_ARB_framebuffer_object");
351 /* Create and bind FBO. */
352 fbo
= hiz_make_fbo(fbo_options
);
354 glBindFramebuffer(GL_DRAW_FRAMEBUFFER
, fbo
);
355 glBindFramebuffer(GL_READ_FRAMEBUFFER
, fbo
);
357 pass
= hiz_run_test_depth_read_common();
359 if (!piglit_automatic
) {
360 /* Blit the FBO to the window FB so we can see the results. */
361 glBindFramebuffer(GL_DRAW_FRAMEBUFFER
, piglit_winsys_fbo
);
362 glBlitFramebuffer(0, 0, piglit_width
, piglit_height
,
363 0, 0, piglit_width
, piglit_height
,
364 GL_COLOR_BUFFER_BIT
, GL_NEAREST
);
365 piglit_present_results();
366 glBindFramebuffer(GL_DRAW_FRAMEBUFFER
, fbo
);
375 hiz_run_test_depth_read_window()
377 bool pass
= hiz_run_test_depth_read_common();
378 if (!piglit_automatic
)
379 piglit_present_results();
385 /* ------------------------------------------------------------------------ */
388 * \name hiz_run_stencil_test utilities
390 * Utilities for testing stencil testing.
396 * Common functionality needed by hiz_run_test_stencil_test_fbo() and
397 * hiz_run_test_stencil_test_window().
400 hiz_run_test_stencil_test_common()
402 static const float *expected_colors
[9] = {
403 hiz_grey
, hiz_blue
, hiz_grey
,
404 hiz_green
, hiz_blue
, hiz_grey
,
405 hiz_green
, hiz_green
, hiz_grey
,
408 const float dx
= piglit_width
/ 3.0;
409 const float dy
= piglit_height
/ 3.0;
411 /* Set up depth state. */
412 glDisable(GL_DEPTH_TEST
);
413 glClearDepth(hiz_clear_z
);
415 /* Set up stencil state. */
416 glEnable(GL_STENCIL_TEST
);
417 glClearStencil(3); /* 3 is a good canary. */
418 glStencilFunc(GL_LESS
, 3, ~0);
419 glStencilOp(GL_INCR
, GL_INCR
, GL_INCR
);
421 glClearColor(hiz_grey
[0], hiz_grey
[1], hiz_grey
[2], hiz_grey
[3]);
422 glClear(GL_COLOR_BUFFER_BIT
423 | GL_DEPTH_BUFFER_BIT
424 | GL_STENCIL_BUFFER_BIT
);
426 glViewport(0, 0, piglit_width
, piglit_height
);
427 piglit_ortho_projection(piglit_width
, piglit_height
, false);
430 glColor4fv(hiz_grey
);
431 piglit_draw_rect(0 * dx
, 0 * dy
, /* x, y */
432 2 * dx
, 3 * dy
); /* w, h */
435 glColor4fv(hiz_green
);
436 piglit_draw_rect(0 * dx
, 0 * dy
, /* x, y */
437 2 * dx
, 2 * dy
); /* w, h */
440 glColor4fv(hiz_blue
);
441 piglit_draw_rect(1 * dx
, 1 * dy
, /* x, y */
442 2 * dx
, 2 * dy
); /* w, h */
444 if (!piglit_check_gl_error(0))
447 return hiz_probe_color_buffer(expected_colors
);
451 hiz_run_test_stencil_test_fbo(const struct hiz_fbo_options
*fbo_options
)
456 piglit_require_extension("GL_ARB_framebuffer_object");
458 /* Create and bind FBO. */
459 fbo
= hiz_make_fbo(fbo_options
);
461 glBindFramebuffer(GL_DRAW_FRAMEBUFFER
, fbo
);
462 glBindFramebuffer(GL_READ_FRAMEBUFFER
, fbo
);
464 pass
= hiz_run_test_stencil_test_common();
466 if (!piglit_automatic
) {
467 /* Blit the FBO to the window FB so we can see the results. */
468 glBindFramebuffer(GL_DRAW_FRAMEBUFFER
, piglit_winsys_fbo
);
469 glBlitFramebuffer(0, 0, piglit_width
, piglit_height
,
470 0, 0, piglit_width
, piglit_height
,
471 GL_COLOR_BUFFER_BIT
, GL_NEAREST
);
472 piglit_present_results();
473 glBindFramebuffer(GL_DRAW_FRAMEBUFFER
, fbo
);
482 hiz_run_test_stencil_test_window()
484 bool pass
= hiz_run_test_stencil_test_common();
485 if (!piglit_automatic
)
486 piglit_present_results();
492 /* ------------------------------------------------------------------------ */
495 * \name hiz_run_stencil_read utilities
497 * Utilities for testing the reading of the stencil buffer.
503 * Common functionality needed by hiz_run_test_stencil_read_fbo() and
504 * hiz_run_test_stencil_read_window().
507 hiz_run_test_stencil_read_common()
509 static const float *expected_colors
[9] = {
510 hiz_grey
, hiz_blue
, hiz_grey
,
511 hiz_green
, hiz_blue
, hiz_grey
,
512 hiz_green
, hiz_green
, hiz_grey
,
515 static const unsigned expected_stencil
[9] = {
521 const float dx
= piglit_width
/ 3.0;
522 const float dy
= piglit_height
/ 3.0;
524 /* Set up depth state. */
525 glDisable(GL_DEPTH_TEST
);
526 glClearDepth(hiz_clear_z
);
528 /* Set up stencil state. */
529 glEnable(GL_STENCIL_TEST
);
530 glClearStencil(3); /* 3 is a good canary. */
531 glStencilFunc(GL_LESS
, 3, ~0);
532 glStencilOp(GL_INCR
, GL_INCR
, GL_INCR
);
534 glClearColor(hiz_grey
[0], hiz_grey
[1], hiz_grey
[2], hiz_grey
[3]);
535 glClear(GL_COLOR_BUFFER_BIT
536 | GL_DEPTH_BUFFER_BIT
537 | GL_STENCIL_BUFFER_BIT
);
539 glViewport(0, 0, piglit_width
, piglit_height
);
540 piglit_ortho_projection(piglit_width
, piglit_height
, false);
543 glColor4fv(hiz_grey
);
544 piglit_draw_rect(0 * dx
, 0 * dy
, /* x, y */
545 2 * dx
, 3 * dy
); /* w, h */
548 glColor4fv(hiz_green
);
549 piglit_draw_rect(0 * dx
, 0 * dy
, /* x, y */
550 2 * dx
, 2 * dy
); /* w, h */
553 glColor4fv(hiz_blue
);
554 piglit_draw_rect(1 * dx
, 1 * dy
, /* x, y */
555 2 * dx
, 2 * dy
); /* w, h */
557 if (!piglit_check_gl_error(0))
560 if (!hiz_probe_color_buffer(expected_colors
))
562 return hiz_probe_stencil_buffer(expected_stencil
);
566 hiz_run_test_stencil_read_fbo(const struct hiz_fbo_options
*fbo_options
)
571 piglit_require_extension("GL_ARB_framebuffer_object");
573 /* Create and bind FBO. */
574 fbo
= hiz_make_fbo(fbo_options
);
576 glBindFramebuffer(GL_DRAW_FRAMEBUFFER
, fbo
);
577 glBindFramebuffer(GL_READ_FRAMEBUFFER
, fbo
);
579 pass
= hiz_run_test_stencil_read_common();
581 if (!piglit_automatic
) {
582 /* Blit the FBO to the window FB so we can see the results. */
583 glBindFramebuffer(GL_DRAW_FRAMEBUFFER
, piglit_winsys_fbo
);
584 glBlitFramebuffer(0, 0, piglit_width
, piglit_height
,
585 0, 0, piglit_width
, piglit_height
,
586 GL_COLOR_BUFFER_BIT
, GL_NEAREST
);
587 piglit_present_results();
588 glBindFramebuffer(GL_DRAW_FRAMEBUFFER
, fbo
);
597 hiz_run_test_stencil_read_window()
599 bool pass
= hiz_run_test_stencil_read_common();
600 if (!piglit_automatic
)
601 piglit_present_results();
608 hiz_run_test_depth_stencil_test_fbo(const struct hiz_fbo_options
*fbo_options
)
613 bool has_depth_buffer
= fbo_options
->depth_format
614 || fbo_options
->depth_stencil_format
;
615 bool has_stencil_buffer
= fbo_options
->stencil_format
616 || fbo_options
->depth_stencil_format
;
618 const float dx
= piglit_width
/ 3.0;
619 const float dy
= piglit_height
/ 3.0;
621 static const float **expected_colors
= NULL
;
623 static const float *expected_colors_d1s0
[9] = {
624 hiz_grey
, hiz_blue
, hiz_blue
,
625 hiz_green
, hiz_green
, hiz_blue
,
626 hiz_green
, hiz_green
, hiz_grey
,
629 static const float *expected_colors_d0s1
[9] = {
630 hiz_grey
, hiz_blue
, hiz_grey
,
631 hiz_green
, hiz_blue
, hiz_grey
,
632 hiz_green
, hiz_green
, hiz_grey
,
635 static const float *expected_colors_d1s1
[9] = {
636 hiz_grey
, hiz_blue
, hiz_grey
,
637 hiz_green
, hiz_green
, hiz_grey
,
638 hiz_green
, hiz_green
, hiz_grey
,
641 if (has_depth_buffer
&& !has_stencil_buffer
)
642 expected_colors
= expected_colors_d1s0
;
643 else if (!has_depth_buffer
&& has_stencil_buffer
)
644 expected_colors
= expected_colors_d0s1
;
645 else if (has_depth_buffer
&& has_stencil_buffer
)
646 expected_colors
= expected_colors_d1s1
;
648 piglit_require_extension("GL_ARB_framebuffer_object");
650 /* Create and bind FBO. */
651 fbo
= hiz_make_fbo(fbo_options
);
653 glBindFramebuffer(GL_DRAW_FRAMEBUFFER
, fbo
);
654 glBindFramebuffer(GL_READ_FRAMEBUFFER
, fbo
);
656 /* Set up depth state. */
657 glEnable(GL_DEPTH_TEST
);
658 glDepthFunc(GL_LESS
);
659 glClearDepth(hiz_clear_z
);
661 /* Set up stencil state. The test for 3 < stencil with the
662 * buffer cleared to 3 means the first primitive drawn will be
665 glEnable(GL_STENCIL_TEST
);
666 glClearStencil(3); /* 3 is a good canary. */
667 glStencilFunc(GL_LESS
, 3, ~0);
668 glStencilOp(GL_INCR
, GL_INCR
, GL_INCR
);
670 glClearColor(hiz_grey
[0], hiz_grey
[1], hiz_grey
[2], hiz_grey
[3]);
671 glClear(GL_COLOR_BUFFER_BIT
672 | GL_DEPTH_BUFFER_BIT
673 | GL_STENCIL_BUFFER_BIT
);
675 glViewport(0, 0, piglit_width
, piglit_height
);
676 piglit_ortho_projection(piglit_width
, piglit_height
, false);
678 /* Draw a rect 1 on left 2/3 of the screen with clear color,
679 * letting the next drawing there pass stencil.
681 glColor4fv(hiz_grey
);
682 glDepthRange(hiz_clear_z
, hiz_clear_z
);
683 piglit_draw_rect(0 * dx
, 0 * dy
, /* x, y */
684 2 * dx
, 3 * dy
); /* w, h */
686 /* Draw rect 2. This should pass with or without stencil. */
687 glColor4fv(hiz_green
);
688 glDepthRange(hiz_green_z
, hiz_green_z
);
689 piglit_draw_rect(0 * dx
, 0 * dy
, /* x, y */
690 2 * dx
, 2 * dy
); /* w, h */
692 /* Draw rect 3. This should draw only the left half if stencil
693 * is present (due to rect 1 covering only that much), and
694 * should draw over rect 2 only if depth is not present.
696 glColor4fv(hiz_blue
);
697 glDepthRange(hiz_blue_z
, hiz_blue_z
);
698 piglit_draw_rect(1 * dx
, 1 * dy
, /* x, y */
699 2 * dx
, 2 * dy
); /* w, h */
701 pass
= piglit_check_gl_error(0);
703 pass
= hiz_probe_color_buffer(expected_colors
) && pass
;
705 if (!piglit_automatic
) {
706 /* Blit the FBO to the window FB so we can see the results. */
707 glBindFramebuffer(GL_DRAW_FRAMEBUFFER
, piglit_winsys_fbo
);
708 glBlitFramebuffer(0, 0, piglit_width
, piglit_height
,
709 0, 0, piglit_width
, piglit_height
,
710 GL_COLOR_BUFFER_BIT
, GL_NEAREST
);
711 piglit_present_results();
712 glBindFramebuffer(GL_DRAW_FRAMEBUFFER
, fbo
);