fbo-mrt-alphatest: Actually require MRTs to be available.
[piglit.git] / tests / general / line-aa-width.c
blob8b51032755affbe7b9ccc5f6259f98a5fa7ab649
1 /*
2 * Copyright © 2010 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
13 * Software.
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.
23 * Authors:
24 * Eric Anholt <eric@anholt.net>
28 /**
29 * @file line-aa-width.c
31 * Tests that width 1.0 AA lines are of the appropriate thickness.
33 * The 965 driver was rendering them so that when the line was
34 * centered on a pixel it was fully lit and when it was off the pixel
35 * center neither of the neighbors would be lit at all. It's quite
36 * ugly.
39 #include "piglit-util-gl.h"
41 PIGLIT_GL_TEST_CONFIG_BEGIN
43 config.supports_gl_compat_version = 10;
45 config.window_width = 300;
46 config.window_height = 100;
47 config.window_visual = PIGLIT_GL_VISUAL_RGB | PIGLIT_GL_VISUAL_DOUBLE;
49 PIGLIT_GL_TEST_CONFIG_END
51 static float
52 y_from_x(float x)
54 return 2.0 + (piglit_height - 4.0) *
55 (1.0 - cos(x / piglit_width * M_PI / 2));
58 /* Check that the color is approximately gray. There was a report that
59 * Gen3 Intel is failing at this.
61 static GLboolean
62 check_color(float *color)
64 float max = 0.0;
65 static GLboolean reported = GL_FALSE;
67 if (fabs(color[1] - color[0]) > max)
68 max = fabs(color[1] - color[0]) > 0.01;
69 if (fabs(color[2] - color[0]) > max)
70 max = fabs(color[2] - color[0]) > 0.01;
72 if (max > 0.02) {
73 if (!reported) {
74 printf("Found color %f, %f, %f, expected %f, %f, %f\n",
75 color[0], color[1], color[2],
76 color[0], color[0], color[0]);
77 reported = GL_TRUE;
80 return GL_FALSE;
83 return GL_TRUE;
86 enum piglit_result
87 piglit_display(void)
89 int x1;
90 int seg_width = 30;
91 float *screen;
92 GLboolean pass = GL_TRUE;
94 /* The coverage checking assumes that we'll be sampling along
95 * the major axis, so a tall window will break that.
97 if (piglit_width / piglit_height < 3)
98 return PIGLIT_SKIP;
100 piglit_ortho_projection(piglit_width, piglit_height, GL_FALSE);
102 glClearColor(0.0, 0.0, 0.0, 0.0);
103 glClear(GL_COLOR_BUFFER_BIT);
105 glColor4f(1.0, 1.0, 1.0, 1.0);
106 glEnable(GL_LINE_SMOOTH);
107 /* GL AA lines produce an alpha value */
108 glEnable(GL_BLEND);
109 glBlendFunc(GL_SRC_ALPHA, GL_ZERO);
111 /* Draw a bunch of line segments with varying slopes across
112 * the window. They're separated by a bit of space so that we
113 * can see which regions we're going to sample in while
114 * avoiding any need to worry about end caps. */
115 for (x1 = 0; x1 < piglit_width; x1 += seg_width) {
116 int x2 = x1 + seg_width - 2;
117 float y1, y2;
119 if (x2 > piglit_width)
120 x2 = piglit_width;
122 y1 = y_from_x(x1);
123 y2 = y_from_x(x2);
125 glBegin(GL_LINES);
126 glVertex2f(x1, y1);
127 glVertex2f(x2, y2);
128 glEnd();
131 screen = malloc(piglit_width * piglit_height * 4 * sizeof(float));
132 glReadPixels(0, 0, piglit_width, piglit_height,
133 GL_RGBA, GL_FLOAT, screen);
135 /* Now, sample the middles of the segments and compare the total
136 * coverage in each column
138 for (x1 = 2; x1 < piglit_width; x1 += seg_width) {
139 int x2 = x1 + seg_width - 5;
140 int sample_x;
141 float y1, y2;
142 float avg = 0.0;
143 float min = 100.0;
144 float max = -100.0;
145 char *err = NULL;
147 if (x2 > piglit_width - 5)
148 x2 = piglit_width - 5;
150 /* If we don't have a couple of pixels to sample because we've
151 * hit the edge of the window, we're done.
153 if (x2 - x1 < 2)
154 break;
156 y1 = y_from_x(x1) - 2;
157 y2 = y_from_x(x2) + 2;
159 avg = 0;
160 for (sample_x = x1; sample_x < x2; sample_x++) {
161 int y;
162 float col_total = 0.0;
164 for (y = y1; y < y2; y++) {
165 if (y < 0 || y >= piglit_height)
166 continue;
168 pass = pass &&
169 check_color(&screen[(y * piglit_width +
170 sample_x) * 4]);
172 col_total += screen[(y * piglit_width +
173 sample_x) * 4];
175 if (col_total > max)
176 max = col_total;
177 if (col_total < min)
178 min = col_total;
179 avg += col_total / (x2 - x1);
182 if (min < 0.25)
183 err = "min < 0.25";
184 else if (avg / min > 2.0)
185 err = "avg / min > 2.0";
186 else if (max / avg > 2.0)
187 err = "max / avg > 2.0";
188 else if (max > 1.5)
189 err = "max > 1.5";
191 if (err) {
192 printf("Line from %d,%d-%d,%d had bad thickness (%s):\n",
193 x1 - 2, (int)y_from_x(x1 - 2),
194 x2 + 2, (int)y_from_x(x2 + 2),
195 err);
196 printf("min coverage: %f\n", min);
197 printf("avg coverage: %f\n", avg);
198 printf("max coverage: %f\n", max);
199 pass = GL_FALSE;
203 piglit_present_results();
205 free(screen);
207 return pass ? PIGLIT_PASS : PIGLIT_FAIL;
210 void
211 piglit_init(int argc, char **argv)