ext_framebuffer_object: setup max mipmap level to make fbo complete
[piglit.git] / tests / spec / gl-1.0 / long-line-loop.c
blob02b756caa4613ca410c23b31bd2b643c9ec91696
1 /*
2 * Copyright © 2017 Fabian Bieler
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.
24 /**
25 * @file long-line-loop.c
26 * Draw cricles with line loops and a line strips blended on top of each
27 * other and check that the renderings match.
30 #include "piglit-util-gl.h"
32 PIGLIT_GL_TEST_CONFIG_BEGIN
34 config.supports_gl_compat_version = 10;
35 config.window_width = 1024;
36 config.window_height = 1024;
37 config.window_visual = PIGLIT_GL_VISUAL_RGB;
38 config.khr_no_error_support = PIGLIT_NO_ERRORS;
40 PIGLIT_GL_TEST_CONFIG_END
42 static int max_vertices;
43 static int num_vertices;
44 static int probe_location[2];
45 static const float radius = 0.9;
47 static void
48 print_usage_and_exit(const char *prog_name)
50 printf("Usage: %s [<vertex_count>]\n"
51 " where <vertex_count> is the number of vertices to test.\n"
52 "\n"
53 " If omitted, sequentially test from 16 to max_vertices by "
54 "quadrupling,\n"
55 " where max_vertices is GL_MAX_ELEMENTS_VERTICES clamped to "
56 "[0x10000, 0x40000].\n",
57 prog_name);
58 piglit_report_result(PIGLIT_FAIL);
61 void
62 piglit_init(int argc, char **argv)
64 glBlendFunc(GL_ONE, GL_ONE);
66 piglit_ortho_projection(piglit_width, piglit_height, false);
68 if (argc == 1) {
69 /* This isn't a hard limit, but staying below should help
70 * performance.
72 * XXX: It could be interesting to go beyond this limit to
73 * test a different code path in the GL implementation.
75 glGetIntegerv(GL_MAX_ELEMENTS_VERTICES, &max_vertices);
76 max_vertices = CLAMP(max_vertices, 0x10000, 0x40000);
77 } else if (argc == 2) {
78 char *endptr;
79 num_vertices = strtol(argv[1], &endptr, 0);
80 if (endptr != argv[1] + strlen(argv[1]))
81 print_usage_and_exit(argv[0]);
82 if (num_vertices < 6)
83 print_usage_and_exit(argv[0]);
84 } else {
85 print_usage_and_exit(argv[0]);
89 static void
90 draw_circle(int segments)
92 /* The first (segments - 1) vertices describe the arc of a circle
93 * slice with central angle (360° - alpha).
94 * The last vertex is identical to the first vertex.
95 * alpha is chosen so that the last line segment covers two pixels.
97 const float alpha = asinf(2.0 / (piglit_width / 2 * radius));
98 struct {
99 float pos[4];
100 float green[4];
101 float blue[4];
102 } *vertex = malloc(sizeof(vertex[0]) * segments);
104 for (int i = 0; i < segments - 1; ++i) {
105 const float phi = alpha -
106 (2 * M_PI - alpha) /
107 (float)(segments - 2) *
108 (float)i;
110 vertex[i].pos[0] = round(piglit_width / 2 *
111 (1 + radius * cosf(phi))) + 0.5;
112 vertex[i].pos[1] = round(piglit_height / 2 *
113 (1 + radius * sinf(phi))) + 0.5;
114 vertex[i].pos[2] = 0;
115 vertex[i].pos[3] = 1;
116 vertex[i].green[0] = 0;
117 vertex[i].green[1] = 1;
118 vertex[i].green[2] = 0;
119 vertex[i].green[3] = 1;
120 vertex[i].blue[0] = 0;
121 vertex[i].blue[1] = 0;
122 vertex[i].blue[2] = 1;
123 vertex[i].blue[3] = 1;
125 memcpy(&vertex[segments - 1], &vertex[0], sizeof(vertex[0]));
127 /* Find a pixel in the last line segment: */
128 for (int i = 0; i < 2; ++i)
129 probe_location[i] = round((vertex[segments - 2].pos[i] +
130 vertex[segments - 1].pos[i] -
131 1.0) / 2.0);
133 /* Render twice: */
134 glClear(GL_COLOR_BUFFER_BIT);
136 glVertexPointer(4, GL_FLOAT, sizeof(vertex[0]), vertex[0].pos);
137 glColorPointer(4, GL_FLOAT, sizeof(vertex[0]), vertex[0].green);
139 glEnableClientState(GL_VERTEX_ARRAY);
140 glEnableClientState(GL_COLOR_ARRAY);
142 glDrawArrays(GL_LINE_LOOP, 0, segments - 1);
144 glEnable(GL_BLEND);
145 glColorPointer(4, GL_FLOAT, sizeof(vertex[0]), vertex[0].blue);
146 glDrawArrays(GL_LINE_STRIP, 0, segments);
147 glDisable(GL_BLEND);
149 free(vertex);
151 piglit_present_results();
154 static bool
155 check_circle(void)
157 bool pass = true;
158 const float teal[] = {0, 1, 1};
159 const float black[] = {0, 0, 0};
161 /* check that the two renderings are identical */
162 pass = piglit_probe_rect_two_rgb(0, 0, piglit_width, piglit_height,
163 black, teal) && pass;
165 /* belt + suspenders: Additionally check that the last line segment
166 * was drawn...
168 pass = piglit_probe_pixel_rgb(probe_location[0], probe_location[1],
169 teal) && pass;
171 /* ...and that the center of the circle is black */
172 const int x = ceil(piglit_width / 2 * radius / M_SQRT2) + 1;
173 const int y = ceil(piglit_height / 2 * radius / M_SQRT2) + 1;
174 pass = piglit_probe_rect_rgb(x, y, piglit_width - 2 * x,
175 piglit_height - 2 * y, black) && pass;
177 return pass;
180 enum piglit_result
181 piglit_display(void)
183 bool pass = true;
185 if (max_vertices) {
186 for (int vertices = 16;
187 vertices <= max_vertices;
188 vertices <<= 2) {
189 draw_circle(vertices);
190 pass = check_circle() && pass;
192 } else {
193 draw_circle(num_vertices);
194 pass = check_circle() && pass;
197 return pass ? PIGLIT_PASS : PIGLIT_FAIL;