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