fix the spelling in whole piglit
[piglit.git] / tests / general / point-vertex-id.c
blob350c1b36ce1f091eda6d1c8ff1346649b56a4f59
1 /*
2 * Copyright © 2014 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.
24 #include "piglit-util-gl.h"
26 /**
27 * @file point-vertex-id.c
29 * Tests glPolygonMode(GL_POINT) used in combination with gl_VertexID
30 * or gl_InstanceID or both.
32 * Specify gl_VertexID or gl_InstanceID as an argument to specify
33 * which to test. Alternatively you can specify both in order to test
34 * a combination of both. Additionally ‘divisor’ can be specified to
35 * make it use an instanced array.
37 * See bug #84677 and #91292
40 PIGLIT_GL_TEST_CONFIG_BEGIN
42 config.supports_gl_compat_version = 20;
44 config.window_visual = PIGLIT_GL_VISUAL_RGBA | PIGLIT_GL_VISUAL_DOUBLE;
46 PIGLIT_GL_TEST_CONFIG_END
48 static const char
49 vertex_shader[] =
50 "uniform vec2 viewport_size;\n"
51 "\n"
52 "#ifdef USE_VERTEX_ID\n"
53 "uniform vec2 pos_array[12];\n"
54 "#else\n"
55 "in vec2 pos;\n"
56 "#endif"
57 "\n"
58 "#ifdef USE_DIVISOR\n"
59 "in vec2 triangle_offset;\n"
60 "#endif\n"
61 "\n"
62 "void\n"
63 "main()\n"
64 "{\n"
65 "#ifdef USE_VERTEX_ID\n"
66 " vec2 pos = pos_array[gl_VertexID];\n"
67 "#endif\n"
68 " gl_Position = vec4(pos, 0.0, 1.0);\n"
69 "#ifdef USE_INSTANCE_ID\n"
70 " float instance_offset = 20.0;\n"
71 "#ifdef USE_DIVISOR\n"
72 " instance_offset = 10.0;\n"
73 "#endif\n"
74 " gl_Position.t += float(gl_InstanceID) * instance_offset;\n"
75 "#endif\n"
76 "#ifdef USE_DIVISOR\n"
77 " gl_Position.st += triangle_offset;\n"
78 "#endif\n"
79 " gl_Position.st = ((gl_Position.st + 0.5) * 2.0 /\n"
80 " viewport_size - 1.0);\n"
81 " gl_FrontColor = vec4(1.0);\n"
82 "}\n";
84 struct vertex {
85 int x, y;
86 GLubyte edge_flag;
89 enum test_mode_flags {
90 TEST_MODE_VERTEX_ID = (1 << 0),
91 TEST_MODE_INSTANCE_ID = (1 << 1),
92 TEST_MODE_DIVISOR = (1 << 2),
95 static enum test_mode_flags test_modes;
97 static const struct vertex
98 vertices[] = {
99 { 10, 10, GL_TRUE },
100 { 20, 10, GL_TRUE },
101 { 10, 20, GL_TRUE },
102 /* This triangle won't be drawn because none of the vertices
103 * are an edge */
104 { 30, 10, GL_FALSE },
105 { 40, 10, GL_FALSE },
106 { 30, 20, GL_FALSE },
107 /* Copy of the above two triangles but shifted up by 20. If
108 * instanced rendering is used these will be generated based
109 * on the gl_InstanceID or an instanced array instead.
111 { 10, 30, GL_TRUE },
112 { 20, 30, GL_TRUE },
113 { 10, 40, GL_TRUE },
114 { 30, 30, GL_FALSE },
115 { 40, 30, GL_FALSE },
116 { 30, 40, GL_FALSE },
119 /* If a divisor is set then each pair of triangles will be drawn as an
120 * instance and these offsets will be added to each instance.
122 static const struct vertex
123 triangle_offsets[] = {
124 { 0, 0 },
125 { 0, 20 },
128 /* If both the divisor and the instance id is used then these offsets
129 * will be used instead. The remainder of the offset will be added by
130 * the instance ID.
132 static const struct vertex
133 triangle_offsets_with_instance_id[] = {
134 { 0, 0 },
135 { 0, 10 },
138 enum piglit_result
139 piglit_display(void)
141 bool pass = true;
142 char shader_buf[sizeof vertex_shader + 512];
143 GLint pos_location = 0, viewport_size_location;
144 GLuint program;
145 float *ref_image, *p;
146 int i;
148 strcpy(shader_buf, "#version 130\n");
149 if (test_modes & TEST_MODE_INSTANCE_ID) {
150 strcat(shader_buf,
151 "#extension GL_ARB_draw_instanced : require\n"
152 "#define USE_INSTANCE_ID\n");
154 if (test_modes & TEST_MODE_DIVISOR)
155 strcat(shader_buf, "#define USE_DIVISOR\n");
156 if (test_modes & TEST_MODE_VERTEX_ID)
157 strcat(shader_buf, "#define USE_VERTEX_ID\n");
158 strcat(shader_buf, vertex_shader);
160 program = piglit_build_simple_program(shader_buf, NULL);
162 glUseProgram(program);
164 glClear(GL_COLOR_BUFFER_BIT);
166 viewport_size_location = glGetUniformLocation(program, "viewport_size");
167 glUniform2f(viewport_size_location,
168 piglit_width,
169 piglit_height);
171 if (test_modes & TEST_MODE_VERTEX_ID) {
172 pos_location = glGetUniformLocation(program, "pos_array");
174 for (i = 0; i < ARRAY_SIZE(vertices); i++) {
175 glUniform2f(pos_location + i,
176 vertices[i].x,
177 vertices[i].y);
181 glEnableClientState(GL_EDGE_FLAG_ARRAY);
182 glEdgeFlagPointer(sizeof (struct vertex),
183 &vertices[0].edge_flag);
185 if (!(test_modes & TEST_MODE_VERTEX_ID)) {
186 pos_location = glGetAttribLocation(program, "pos");
187 if (pos_location == -1)
188 piglit_report_result(PIGLIT_FAIL);
189 glEnableVertexAttribArray(pos_location);
190 glVertexAttribPointer(pos_location,
191 2, /* size */
192 GL_INT,
193 GL_FALSE, /* normalized */
194 sizeof (struct vertex),
195 &vertices[0].x);
198 if (test_modes & TEST_MODE_DIVISOR) {
199 pos_location = glGetAttribLocation(program, "triangle_offset");
200 if (pos_location == -1)
201 piglit_report_result(PIGLIT_FAIL);
202 glEnableVertexAttribArray(pos_location);
203 glVertexAttribDivisor(pos_location, 1);
204 glVertexAttribPointer(pos_location,
205 2, /* size */
206 GL_INT,
207 GL_FALSE, /* normalized */
208 sizeof (struct vertex),
209 (test_modes & TEST_MODE_INSTANCE_ID) ?
210 &triangle_offsets_with_instance_id[0].x :
211 &triangle_offsets[0].x);
214 glPolygonMode(GL_FRONT_AND_BACK, GL_POINT);
216 if (test_modes & (TEST_MODE_INSTANCE_ID | TEST_MODE_DIVISOR)) {
217 glDrawArraysInstanced(GL_TRIANGLES,
218 0, /* first */
219 ARRAY_SIZE(vertices) / 2,
220 2 /* primcount */);
221 } else {
222 glDrawArrays(GL_TRIANGLES,
223 0, /* first */
224 ARRAY_SIZE(vertices));
227 ref_image = malloc(piglit_width * piglit_height * 3 *
228 sizeof (float));
229 memset(ref_image, 0, piglit_width * piglit_height * 3 * sizeof (float));
230 for (i = 0; i < ARRAY_SIZE(vertices); i++) {
231 if (!vertices[i].edge_flag)
232 continue;
234 p = (ref_image +
235 (vertices[i].x + vertices[i].y * piglit_width) * 3);
236 p[0] = p[1] = p[2] = 1.0f;
238 pass = piglit_probe_image_color(0, 0,
239 piglit_width, piglit_height,
240 GL_RGB,
241 ref_image);
243 glUseProgram(0);
244 glDeleteProgram(program);
246 piglit_present_results();
248 free(ref_image);
250 return pass ? PIGLIT_PASS : PIGLIT_FAIL;
253 void
254 piglit_init(int argc, char **argv)
256 int i;
258 for (i = 1; i < argc; i++) {
259 if (!strcmp(argv[i], "gl_VertexID")) {
260 test_modes |= TEST_MODE_VERTEX_ID;
261 } else if (!strcmp(argv[i], "gl_InstanceID")) {
262 test_modes |= TEST_MODE_INSTANCE_ID;
263 } else if (!strcmp(argv[i], "divisor")) {
264 test_modes |= TEST_MODE_DIVISOR;
265 } else {
266 fprintf(stderr, "Unknown argument: %s\n", argv[i]);
267 piglit_report_result(PIGLIT_FAIL);
271 if (test_modes == 0) {
272 fprintf(stderr,
273 "usage: point-vertex-id [gl_VertexID] [gl_InstanceID] "
274 "[divisor]\n"
275 "At least one of the arguments must be specified\n");
276 piglit_report_result(PIGLIT_FAIL);
279 if (test_modes & (TEST_MODE_INSTANCE_ID | TEST_MODE_DIVISOR))
280 piglit_require_extension("GL_ARB_draw_instanced");
281 if (test_modes & TEST_MODE_DIVISOR)
282 piglit_require_extension("GL_ARB_instanced_arrays");
284 piglit_require_GLSL_version(130);