Add more structure constructor tests.
[piglit/hramrach.git] / tests / general / line-aa-width.c
blobc846455b6270dcef45daea95e43be65c28d598da
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 fullly 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 #ifdef _MSC_VER
40 #define _USE_MATH_DEFINES
41 #endif
42 #include "piglit-util.h"
44 int piglit_width = 300, piglit_height = 100;
45 int piglit_window_mode = GLUT_RGB | GLUT_DOUBLE;
47 static float
48 y_from_x(float x)
50 return 2.0 + (piglit_height - 4.0) *
51 (1.0 - cos(x / piglit_width * M_PI / 2));
54 /* Check that the color is approximately gray. There was a report that
55 * Gen3 Intel is failing at this.
57 static GLboolean
58 check_color(float *color)
60 float max = 0.0;
61 static GLboolean reported = GL_FALSE;
63 if (fabs(color[1] - color[0]) > max)
64 max = fabs(color[1] - color[0]) > 0.01;
65 if (fabs(color[2] - color[0]) > max)
66 max = fabs(color[2] - color[0]) > 0.01;
68 if (max > 0.02) {
69 if (!reported) {
70 printf("Found color %f, %f, %f, expected %f, %f, %f\n",
71 color[0], color[1], color[2],
72 color[0], color[0], color[0]);
73 reported = GL_TRUE;
76 return GL_FALSE;
79 return GL_TRUE;
82 enum piglit_result
83 piglit_display(void)
85 int x1;
86 int seg_width = 30;
87 float *screen;
88 GLboolean pass = GL_TRUE;
90 /* The coverage checking assumes that we'll be sampling along
91 * the major axis, so a tall window will break that.
93 if (piglit_width / piglit_height < 3)
94 return PIGLIT_SKIP;
96 piglit_ortho_projection(piglit_width, piglit_height, GL_FALSE);
98 glClearColor(0.0, 0.0, 0.0, 0.0);
99 glClear(GL_COLOR_BUFFER_BIT);
101 glColor4f(1.0, 1.0, 1.0, 1.0);
102 glEnable(GL_LINE_SMOOTH);
103 /* GL AA lines produce an alpha value */
104 glEnable(GL_BLEND);
105 glBlendFunc(GL_SRC_ALPHA, GL_ZERO);
107 /* Draw a bunch of line segments with varying slopes across
108 * the window. They're separated by a bit of space so that we
109 * can see which regions we're going to sample in while
110 * avoiding any need to worry about end caps. */
111 for (x1 = 0; x1 < piglit_width; x1 += seg_width) {
112 int x2 = x1 + seg_width - 2;
113 float y1, y2;
115 if (x2 > piglit_width)
116 x2 = piglit_width;
118 y1 = y_from_x(x1);
119 y2 = y_from_x(x2);
121 glBegin(GL_LINES);
122 glVertex2f(x1, y1);
123 glVertex2f(x2, y2);
124 glEnd();
127 screen = malloc(piglit_width * piglit_height * 4 * sizeof(float));
128 glReadPixels(0, 0, piglit_width, piglit_height,
129 GL_RGBA, GL_FLOAT, screen);
131 /* Now, sample the middles of the segments and compare the total
132 * coverage in each column
134 for (x1 = 2; x1 < piglit_width; x1 += seg_width) {
135 int x2 = x1 + seg_width - 4;
136 int sample_x;
137 float y1, y2;
138 float avg = 0.0;
139 float min = 100.0;
140 float max = -100.0;
141 char *err = NULL;
143 if (x2 > piglit_width - 4)
144 x2 = piglit_width - 4;
146 /* If we don't have a couple of pixels to sample because we've
147 * hit the edge of the window, we're done.
149 if (x2 - x1 < 2)
150 break;
152 y1 = y_from_x(x1) - 2;
153 y2 = y_from_x(x2) + 2;
155 avg = 0;
156 for (sample_x = x1; sample_x < x2; sample_x++) {
157 int y;
158 float col_total = 0.0;
160 for (y = y1; y < y2; y++) {
161 if (y < 0 || y >= piglit_height)
162 continue;
164 pass = pass &&
165 check_color(&screen[(y * piglit_width +
166 sample_x) * 4]);
168 col_total += screen[(y * piglit_width +
169 sample_x) * 4];
171 if (col_total > max)
172 max = col_total;
173 if (col_total < min)
174 min = col_total;
175 avg += col_total / (x2 - x1);
178 if (min < 0.25)
179 err = "min < 0.25";
180 else if (avg / min > 2.0)
181 err = "avg / min > 2.0";
182 else if (max / avg > 2.0)
183 err = "max / avg > 2.0";
184 else if (max > 1.5)
185 err = "max > 1.5";
187 if (err) {
188 printf("Line from %d,%d-%d,%d had bad thickness (%s):\n",
189 x1 - 2, (int)y_from_x(x1 - 2),
190 x2 + 2, (int)y_from_x(x2 + 2),
191 err);
192 printf("min coverage: %f\n", min);
193 printf("avg coverage: %f\n", avg);
194 printf("max coverage: %f\n", max);
195 pass = GL_FALSE;
199 glutSwapBuffers();
201 return pass ? PIGLIT_SUCCESS : PIGLIT_FAILURE;
204 void
205 piglit_init(int argc, char **argv)