1 /*
2 * (C) Copyright IBM Corporation 2004
3 * All Rights Reserved.
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the "Software"),
7 * to deal in the Software without restriction, including without limitation
8 * on the rights to use, copy, modify, merge, publish, distribute, sub
9 * license, and/or sell copies of the Software, and to permit persons to whom
10 * the Software is furnished to do so, subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice (including the next
13 * paragraph) shall be included in all copies or substantial portions of the
14 * Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
19 * VA LINUX SYSTEM, IBM AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
20 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
21 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
22 * USE OR OTHER DEALINGS IN THE SOFTWARE.
23 */
24
25 /**
26 * \file stencil_twoside.c
27 *
28 * Simple test of GL_ATI_separate_stencil (or the OGL 2.0 equivalent)
29 * functionality.
30 *
31 * Five squares (or six if stencil wrap is available) are drawn
32 * with different stencil modes, but all should be rendered with the same
33 * final color.
34 */
35
36 #include "piglit-util-gl.h"
37
38 static int use20syntax = 1;
39
40 PIGLIT_GL_TEST_CONFIG_BEGIN
41
42 config.supports_gl_compat_version = 10;
43
44 config.window_width = 650;
45 config.window_height = 200;
46 config.window_visual = PIGLIT_GL_VISUAL_RGB | PIGLIT_GL_VISUAL_DOUBLE | PIGLIT_GL_VISUAL_DEPTH | PIGLIT_GL_VISUAL_STENCIL;
47
48 PIGLIT_GL_TEST_CONFIG_END
49
50 enum piglit_result
piglit_display(void)51 piglit_display(void)
52 {
53 GLboolean pass = GL_TRUE;
54 GLint max_stencil;
55 GLint stencil_bits;
56 unsigned i;
57 float expected[4] = {0.5, 0.5, 0.5, 0.5};
58 int w = piglit_width / (6 * 2 + 1);
59 int h = w;
60 int start_y = (piglit_height - h) / 2;
61
62 piglit_ortho_projection(piglit_width, piglit_height, GL_FALSE);
63
64 glGetIntegerv(GL_STENCIL_BITS, & stencil_bits);
65 max_stencil = (1U << stencil_bits) - 1;
66 printf("Stencil bits = %u, maximum stencil value = 0x%08x\n",
67 stencil_bits, max_stencil);
68
69 glClearStencil(1);
70 glClearColor(0.2, 0.2, 0.8, 0);
71 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT
72 | GL_STENCIL_BUFFER_BIT);
73
74 /* This is the "reference" square. */
75 glDisable(GL_STENCIL_TEST);
76 glColor3f(0.5, 0.5, 0.5);
77 piglit_draw_rect(w * 1, start_y, w, h);
78
79 glEnable(GL_STENCIL_TEST);
80
81 /* Draw the first two squares using incr for the affected face
82 */
83
84 /* 2nd square */
85 if (use20syntax) {
86 glStencilFuncSeparate(GL_FRONT, GL_ALWAYS, 0, ~0);
87 glStencilFuncSeparate(GL_BACK, GL_ALWAYS, 0, ~0);
88 glStencilOpSeparate(GL_FRONT, GL_KEEP, GL_KEEP, GL_INCR);
89 glStencilOpSeparate(GL_BACK, GL_KEEP, GL_KEEP, GL_DECR);
90 }
91 else {
92 glStencilFuncSeparateATI(GL_ALWAYS, GL_ALWAYS, 0, ~0);
93 glStencilOpSeparateATI(GL_FRONT, GL_KEEP, GL_KEEP, GL_INCR);
94 glStencilOpSeparateATI(GL_BACK, GL_KEEP, GL_KEEP, GL_DECR);
95 }
96
97 glColor3f(0.9, 0.9, 0.9);
98 for (i = 0 ; i < (max_stencil + 5) ; i++) {
99 /* this should be front facing */
100 piglit_draw_rect(w * 3, start_y, w, h);
101 }
102
103 /* stencil vals should be equal to max_stencil */
104 glStencilFunc(GL_EQUAL, max_stencil, ~0);
105 glColor3f(0.5, 0.5, 0.5);
106 piglit_draw_rect(w * 3, start_y, w, h);
107
108 /* 3rd square */
109 if (use20syntax) {
110 glStencilFuncSeparate(GL_FRONT, GL_ALWAYS, 0, ~0);
111 glStencilFuncSeparate(GL_BACK, GL_ALWAYS, 0, ~0);
112 glStencilOpSeparate(GL_FRONT, GL_KEEP, GL_KEEP, GL_DECR);
113 glStencilOpSeparate(GL_BACK, GL_KEEP, GL_KEEP, GL_INCR);
114 }
115 else {
116 glStencilFuncSeparateATI(GL_ALWAYS, GL_ALWAYS, 0, ~0);
117 glStencilOpSeparateATI(GL_FRONT, GL_KEEP, GL_KEEP, GL_DECR);
118 glStencilOpSeparateATI(GL_BACK, GL_KEEP, GL_KEEP, GL_INCR);
119 }
120
121 glColor3f(0.9, 0.9, 0.9);
122 for (i = 0 ; i < (max_stencil + 5) ; i++) {
123 /* this should be back facing */
124 piglit_draw_rect(w * 5, start_y + h, w, -h);
125 }
126
127 /* stencil vals should be equal to max_stencil */
128 glStencilFunc(GL_EQUAL, max_stencil, ~0);
129 glColor3f(0.5, 0.5, 0.5);
130 piglit_draw_rect(w * 5, start_y, w, h);
131
132 /* 4th square */
133 if (use20syntax) {
134 glStencilFuncSeparate(GL_FRONT, GL_NEVER, 0, ~0);
135 glStencilFuncSeparate(GL_BACK, GL_ALWAYS, 0, ~0);
136 glStencilOpSeparate(GL_FRONT, GL_KEEP, GL_KEEP, GL_DECR);
137 glStencilOpSeparate(GL_BACK, GL_KEEP, GL_KEEP, GL_INCR);
138 }
139 else {
140 glStencilFuncSeparateATI(GL_NEVER, GL_ALWAYS, 0, ~0);
141 glStencilOpSeparateATI(GL_FRONT, GL_KEEP, GL_KEEP, GL_DECR);
142 glStencilOpSeparateATI(GL_BACK, GL_KEEP, GL_KEEP, GL_INCR);
143 }
144
145 glColor3f(0.9, 0.9, 0.9);
146 for (i = 0 ; i < (max_stencil + 5) ; i++) {
147 /* this should be back facing */
148 piglit_draw_rect(w * 7, start_y + h, w, -h);
149 /* this should be front facing */
150 piglit_draw_rect(w * 7, start_y, w, h);
151 }
152
153 /* stencil vals should be equal to max_stencil */
154 glStencilFunc(GL_EQUAL, max_stencil, ~0);
155 glColor3f(0.5, 0.5, 0.5);
156 piglit_draw_rect(w * 7, start_y, w, h);
157
158 /* 5th square */
159 if (use20syntax) {
160 glStencilFuncSeparate(GL_FRONT, GL_ALWAYS, 0, ~0);
161 glStencilFuncSeparate(GL_BACK, GL_ALWAYS, 0, ~0);
162 glStencilOpSeparate(GL_FRONT, GL_KEEP, GL_KEEP, GL_INCR);
163 glStencilOpSeparate(GL_BACK, GL_KEEP, GL_KEEP, GL_DECR);
164 }
165 else {
166 glStencilFuncSeparateATI(GL_ALWAYS, GL_ALWAYS, 0, ~0);
167 glStencilOpSeparateATI(GL_FRONT, GL_KEEP, GL_KEEP, GL_INCR);
168 glStencilOpSeparateATI(GL_BACK, GL_KEEP, GL_KEEP, GL_DECR);
169 }
170
171 glColor3f(0.9, 0.9, 0.9);
172 for (i = 0 ; i < (max_stencil + 5) ; i++) {
173 /* this should be back facing */
174 piglit_draw_rect(w * 9, start_y + h, w, -h);
175 /* this should be front facing */
176 piglit_draw_rect(w * 9, start_y, w, h);
177 }
178
179 glStencilFunc(GL_EQUAL, 1, ~0);
180 glColor3f(0.5, 0.5, 0.5);
181 piglit_draw_rect(w * 9, start_y, w, h);
182
183 /* 6th square */
184 if (piglit_is_extension_supported("GL_EXT_stencil_wrap")) {
185 if (use20syntax) {
186 glStencilFuncSeparate(GL_FRONT, GL_ALWAYS, 0, ~0);
187 glStencilFuncSeparate(GL_BACK, GL_ALWAYS, 0, ~0);
188 glStencilOpSeparate(GL_FRONT, GL_KEEP, GL_KEEP, GL_KEEP);
189 glStencilOpSeparate(GL_BACK, GL_KEEP, GL_KEEP, GL_INCR_WRAP);
190 }
191 else {
192 glStencilFuncSeparateATI(GL_ALWAYS, GL_ALWAYS, 0, ~0);
193 glStencilOpSeparateATI(GL_FRONT, GL_KEEP, GL_KEEP, GL_KEEP);
194 glStencilOpSeparateATI(GL_BACK, GL_KEEP, GL_KEEP, GL_INCR_WRAP);
195 }
196
197 glColor3f(0.9, 0.9, 0.9);
198 for (i = 0 ; i < (max_stencil + 5) ; i++) {
199 /* this should be back facing */
200 piglit_draw_rect(w * 11, start_y + h, w, -h);
201 /* this should be front facing */
202 piglit_draw_rect(w * 11, start_y, w, h);
203 }
204
205 glStencilFunc(GL_EQUAL, 260 - 255, ~0);
206 glColor3f(0.5, 0.5, 0.5);
207 piglit_draw_rect(w * 11, start_y, w, h);
208 }
209
210 pass = piglit_probe_pixel_rgb(w * 1.5, piglit_height / 2, expected) && pass;
211 pass = piglit_probe_pixel_rgb(w * 3.5, piglit_height / 2, expected) && pass;
212 pass = piglit_probe_pixel_rgb(w * 5.5, piglit_height / 2, expected) && pass;
213 pass = piglit_probe_pixel_rgb(w * 7.5, piglit_height / 2, expected) && pass;
214 pass = piglit_probe_pixel_rgb(w * 9.5, piglit_height / 2, expected) && pass;
215 pass = piglit_probe_pixel_rgb(w * 11.5, piglit_height / 2, expected) && pass;
216
217 piglit_present_results();
218
219 return pass ? PIGLIT_PASS : PIGLIT_FAIL;
220 }
221
222 void
piglit_init(int argc,char ** argv)223 piglit_init(int argc, char **argv)
224 {
225 if (!piglit_is_extension_supported("GL_ATI_separate_stencil") && piglit_get_gl_version() < 20) {
226 printf("Sorry, this program requires either "
227 "GL_ATI_separate_stencil or OpenGL 2.0.\n");
228 piglit_report_result(PIGLIT_SKIP);
229 }
230
231 if (piglit_get_gl_version() < 20) {
232 use20syntax = 0;
233 }
234
235 printf("\nAll 5 (or 6) squares should be the same color.\n");
236 }
237
238