1 /*
2  * Copyright (C) 2016 VMware, Inc.
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 
24 /**
25  * Test glViewport behaviour with GL_ARB_clip_control.
26  * The position of the viewport in window coordinates should not be
27  * effected by the GL_CLIP_ORIGIN state.
28  *
29  * See https://bugs.freedesktop.org/show_bug.cgi?id=93813
30  *
31  * Brian Paul
32  * 9 Feb 2016
33  */
34 
35 #include "piglit-util-gl.h"
36 
37 
38 PIGLIT_GL_TEST_CONFIG_BEGIN
39 	config.supports_gl_compat_version = 20;
40 	config.window_visual = PIGLIT_GL_VISUAL_DOUBLE | PIGLIT_GL_VISUAL_RGBA;
41 	config.khr_no_error_support = PIGLIT_NO_ERRORS;
42 PIGLIT_GL_TEST_CONFIG_END
43 
44 
45 static const float red[3] = { 1, 0, 0 };
46 static const float green[3] = { 0, 1, 0 };
47 static const float blue[3] = { 0, 0, 1 };
48 static const float white[3] = { 1, 1, 1 };
49 
50 
51 void
piglit_init(int argc,char ** argv)52 piglit_init(int argc, char **argv)
53 {
54 	piglit_require_extension("GL_ARB_clip_control");
55 	glEnable(GL_CULL_FACE);
56 }
57 
58 
59 /**
60  * Draw this pattern in the current viewport region, regardless of
61  * the clip control settings:
62  *
63  *   +---------+---------+
64  *   |         |         |
65  *   |   blue  |  white  |
66  *   |         |         |
67  *   +---------+---------+
68  *   |         |         |
69  *   |   red   |  green  |
70  *   |         |         |
71  *   +---------+---------+
72  *
73  * \param invert_y - if true, NDC_Y=-1=top, else NDC_Y=-1=bottom
74  */
75 static void
draw_test_pattern(bool invert_y)76 draw_test_pattern(bool invert_y)
77 {
78 	/* Since the modelview and projection matrices are identity matrices,
79 	 * we're effectively drawing in Normalized Device Coordinates which
80 	 * range from [-1,1] in X and Y.
81 	 *
82 	 * Note: we're careful with our glRectf coordinates so that the
83 	 * rect is drawn front-facing.  If a rect is not drawn it must be
84 	 * because it was back-face culled by mistake.
85 	 */
86 
87 	/* lower-left quadrant = red */
88 	glColor3fv(red);
89 	if (invert_y)
90 		glRectf(-1, 0, 0, 1);
91 	else
92 		glRectf(-1, -1, 0, 0);
93 
94 	/* lower-right quadrant = green */
95 	glColor3fv(green);
96 	if (invert_y)
97 		glRectf(0, 0, 1, 1);
98 	else
99 		glRectf(0, -1, 1, 0);
100 
101 	/* upper-left quadrant = blue */
102 	glColor3fv(blue);
103 	if (invert_y)
104 		glRectf(-1, -1, 0, 0);
105 	else
106 		glRectf(-1, 0, 0, 1);
107 
108 	/* upper-right quadrant = white */
109 	glColor3fv(white);
110 	if (invert_y)
111 		glRectf(0, -1, 1, 0);
112 	else
113 		glRectf(0, 0, 1, 1);
114 }
115 
116 
117 static bool
check_test_pattern(int xpos,int ypos)118 check_test_pattern(int xpos, int ypos)
119 {
120 	bool pass = true;
121 	int half_w = piglit_width / 2;
122 	int half_h = piglit_height / 2;
123 	/* coords in center of the color swatches */
124 	int x0 = xpos + half_w / 4;
125 	int y0 = ypos + half_h / 4;
126 	int x1 = xpos + half_w * 3 / 4;
127 	int y1 = ypos + half_h * 3 / 4;
128 
129 	if (!piglit_probe_pixel_rgb(x0, y0, red)) {
130 		printf("wrong color in lower-left quadrant of test pattern\n");
131 		pass = false;
132 	}
133 
134 	if (!piglit_probe_pixel_rgb(x1, y0, green)) {
135 		printf("wrong color in lower-right quadrant of test pattern\n");
136 		pass = false;
137 	}
138 
139 	if (!piglit_probe_pixel_rgb(x0, y1, blue)) {
140 		printf("wrong color in upper-left quadrant of test pattern\n");
141 		pass = false;
142 	}
143 
144 	if (!piglit_probe_pixel_rgb(x1, y1, white)) {
145 		printf("wrong color in upper-right quadrant of test pattern\n");
146 		pass = false;
147 	}
148 
149 	if (!pass) {
150 		GLint origin;
151 		glGetIntegerv(GL_CLIP_ORIGIN, &origin);
152 		printf("GL_CLIP_ORIGIN = %s\n",
153 		       piglit_get_gl_enum_name(origin));
154 	}
155 
156 	return pass;
157 }
158 
159 
160 enum piglit_result
piglit_display(void)161 piglit_display(void)
162 {
163 	int half_w = piglit_width / 2;
164 	int half_h = piglit_height / 2;
165 	bool pass = true;
166 
167 	/* Test normal GL coordinates */
168 	glClipControl(GL_LOWER_LEFT, GL_NEGATIVE_ONE_TO_ONE);
169 	glClear(GL_COLOR_BUFFER_BIT);
170 
171 	/* Normal GL origin / Draw in upper-left screen quadrant */
172 	glViewport(0, half_h, half_w, half_h);
173 	draw_test_pattern(false);
174 	if (!check_test_pattern(0, half_h))
175 		pass = false;
176 
177 	/* Normal GL origin / Draw in lower-right screen quadrant */
178 	glViewport(half_w, 0, half_w, half_h);
179 	draw_test_pattern(false);
180 	if (!check_test_pattern(half_w, 0))
181 		pass = false;
182 
183 
184 	/* Test inverted GL coordinates */
185 	glClipControl(GL_UPPER_LEFT, GL_NEGATIVE_ONE_TO_ONE);
186 	glClear(GL_COLOR_BUFFER_BIT);
187 
188 	/* Inverted GL origin / Draw in upper-left screen quadrant */
189 	glViewport(0, half_h, half_w, half_h);
190 	draw_test_pattern(true);
191 	if (!check_test_pattern(0, half_h))
192 		pass = false;
193 
194 	/* Inverted GL origin / Draw in lower-right screen quadrant */
195 	glViewport(half_w, 0, half_w, half_h);
196 	draw_test_pattern(true);
197 	if (!check_test_pattern(half_w, 0))
198 		pass = false;
199 
200 	piglit_present_results();
201 
202 	return pass ? PIGLIT_PASS : PIGLIT_FAIL;
203 }
204