glsl-1.10: test mesa bug with forward declaration
[piglit.git] / tests / util / piglit-test-pattern.cpp
blob43d451d6ab42ab1bedad9f3b604405c80598ca56
1 /*
2 * Copyright © 2013 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 /**
25 * \file piglit-test-pattern.cpp
27 * This file defines the functions which can be utilized to draw test patterns
28 * in to color, depth or stencil buffers.
31 #include "piglit-test-pattern.h"
32 using namespace piglit_util_test_pattern;
34 const float TestPattern::no_projection[4][4] = {
35 { 1, 0, 0, 0 },
36 { 0, 1, 0, 0 },
37 { 0, 0, 1, 0 },
38 { 0, 0, 0, 1 }
42 void Triangles::compile()
44 /* Triangle coords within (-1,-1) to (1,1) rect */
45 static const float pos_within_tri[][2] = {
46 { -0.5, -1.0 },
47 { 0.0, 1.0 },
48 { 0.5, -1.0 }
51 /* Number of triangle instances across (and down) */
52 int tris_across = 8;
54 /* Total number of triangles drawn */
55 num_tris = tris_across * tris_across;
57 /* Scaling factor uniformly applied to triangle coords */
58 float tri_scale = 0.8 / tris_across;
60 /* Amount each triangle should be rotated compared to prev */
61 float rotation_delta = M_PI * 2.0 / num_tris;
63 /* Final scaling factor */
64 float final_scale = 0.95;
66 static const char *vert =
67 "#version 120\n"
68 "attribute vec2 pos_within_tri;\n"
69 "uniform float tri_scale;\n"
70 "uniform float rotation_delta;\n"
71 "uniform int tris_across;\n"
72 "uniform float final_scale;\n"
73 "uniform mat4 proj;\n"
74 "uniform int tri_num; /* [0, num_tris) */\n"
75 "\n"
76 "void main()\n"
77 "{\n"
78 " vec2 pos = tri_scale * pos_within_tri;\n"
79 " float rotation = rotation_delta * tri_num;\n"
80 " pos = mat2(cos(rotation), sin(rotation),\n"
81 " -sin(rotation), cos(rotation)) * pos;\n"
82 " int i = int(mod(float(tri_num), float(tris_across)));\n"
83 " int j = tris_across - 1 - tri_num / tris_across;\n"
84 " pos += (vec2(i, j) * 2.0 + 1.0) / tris_across - 1.0;\n"
85 " pos *= final_scale;\n"
86 " gl_Position = proj * vec4(pos, 0.0, 1.0);\n"
87 "}\n";
89 static const char *frag =
90 "#version 120\n"
91 "void main()\n"
92 "{\n"
93 " gl_FragColor = vec4(1.0);\n"
94 "}\n";
96 /* Compile program */
97 prog = glCreateProgram();
98 GLint vs = piglit_compile_shader_text(GL_VERTEX_SHADER, vert);
99 glAttachShader(prog, vs);
100 GLint fs = piglit_compile_shader_text(GL_FRAGMENT_SHADER, frag);
101 glAttachShader(prog, fs);
102 glBindAttribLocation(prog, 0, "pos_within_tri");
103 glLinkProgram(prog);
104 if (!piglit_link_check_status(prog)) {
105 piglit_report_result(PIGLIT_FAIL);
108 /* Set up uniforms */
109 glUseProgram(prog);
110 glUniform1f(glGetUniformLocation(prog, "tri_scale"), tri_scale);
111 glUniform1f(glGetUniformLocation(prog, "rotation_delta"),
112 rotation_delta);
113 glUniform1i(glGetUniformLocation(prog, "tris_across"), tris_across);
114 glUniform1f(glGetUniformLocation(prog, "final_scale"), final_scale);
115 proj_loc = glGetUniformLocation(prog, "proj");
116 tri_num_loc = glGetUniformLocation(prog, "tri_num");
118 /* Set up vertex array object */
119 glGenVertexArrays(1, &vao);
120 glBindVertexArray(vao);
122 /* Set up vertex input buffer */
123 glGenBuffers(1, &vertex_buf);
124 glBindBuffer(GL_ARRAY_BUFFER, vertex_buf);
125 glBufferData(GL_ARRAY_BUFFER, sizeof(pos_within_tri), pos_within_tri,
126 GL_STATIC_DRAW);
127 glEnableVertexAttribArray(0);
128 glVertexAttribPointer(0, ARRAY_SIZE(pos_within_tri[0]), GL_FLOAT,
129 GL_FALSE, sizeof(pos_within_tri[0]), (void *) 0);
132 void Triangles::draw(const float (*proj)[4])
134 glClear(GL_COLOR_BUFFER_BIT);
136 glUseProgram(prog);
137 glUniformMatrix4fv(proj_loc, 1, GL_TRUE, &proj[0][0]);
138 glBindVertexArray(vao);
139 for (int tri_num = 0; tri_num < num_tris; ++tri_num) {
140 glUniform1i(tri_num_loc, tri_num);
141 glDrawArrays(GL_TRIANGLES, 0, 3);
146 InterpolationTestPattern::InterpolationTestPattern(const char *frag)
147 : frag(frag), viewport_size_loc(0)
152 void
153 InterpolationTestPattern::compile()
155 static struct vertex_attributes {
156 float pos_within_tri[2];
157 float barycentric_coords[3];
158 } vertex_data[] = {
159 { { -0.5, -1.0 }, { 1, 0, 0 } },
160 { { 0.0, 1.0 }, { 0, 1, 0 } },
161 { { 0.5, -1.0 }, { 0, 0, 1 } }
164 /* Number of triangle instances across (and down) */
165 int tris_across = 8;
167 /* Total number of triangles drawn */
168 num_tris = tris_across * tris_across;
170 /* Scaling factor uniformly applied to triangle coords */
171 float tri_scale = 0.8 / tris_across;
173 /* Amount each triangle should be rotated compared to prev */
174 float rotation_delta = M_PI * 2.0 / num_tris;
176 /* Final scaling factor */
177 float final_scale = 0.95;
179 static const char *vert =
180 "#version 120\n"
181 "attribute vec2 pos_within_tri;\n"
182 "attribute vec3 in_barycentric_coords;\n"
183 "varying vec3 barycentric_coords;\n"
184 "centroid varying vec3 barycentric_coords_centroid;\n"
185 "varying vec2 pixel_pos;\n"
186 "centroid varying vec2 pixel_pos_centroid;\n"
187 "uniform float tri_scale;\n"
188 "uniform float rotation_delta;\n"
189 "uniform int tris_across;\n"
190 "uniform float final_scale;\n"
191 "uniform mat4 proj;\n"
192 "uniform int tri_num; /* [0, num_tris) */\n"
193 "uniform ivec2 viewport_size;\n"
194 "\n"
195 "void main()\n"
196 "{\n"
197 " vec2 pos = tri_scale * pos_within_tri;\n"
198 " float rotation = rotation_delta * tri_num;\n"
199 " pos = mat2(cos(rotation), sin(rotation),\n"
200 " -sin(rotation), cos(rotation)) * pos;\n"
201 " int i = int(mod(float(tri_num), float(tris_across)));\n"
202 " int j = tris_across - 1 - tri_num / tris_across;\n"
203 " pos += (vec2(i, j) * 2.0 + 1.0) / tris_across - 1.0;\n"
204 " pos *= final_scale;\n"
205 " gl_Position = proj * vec4(pos, 0.0, 1.0);\n"
206 " barycentric_coords = barycentric_coords_centroid =\n"
207 " in_barycentric_coords;\n"
208 " pixel_pos = pixel_pos_centroid =\n"
209 " vec2(viewport_size) * (pos + 1.0) / 2.0;\n"
210 "}\n";
212 /* Compile program */
213 prog = glCreateProgram();
214 GLint vs = piglit_compile_shader_text(GL_VERTEX_SHADER, vert);
215 glAttachShader(prog, vs);
216 GLint fs = piglit_compile_shader_text(GL_FRAGMENT_SHADER, frag);
217 glAttachShader(prog, fs);
218 glBindAttribLocation(prog, 0, "pos_within_tri");
219 glBindAttribLocation(prog, 1, "in_barycentric_coords");
220 glLinkProgram(prog);
221 if (!piglit_link_check_status(prog)) {
222 piglit_report_result(PIGLIT_FAIL);
225 /* Set up uniforms */
226 glUseProgram(prog);
227 glUniform1f(glGetUniformLocation(prog, "tri_scale"), tri_scale);
228 glUniform1f(glGetUniformLocation(prog, "rotation_delta"),
229 rotation_delta);
230 glUniform1i(glGetUniformLocation(prog, "tris_across"), tris_across);
231 glUniform1f(glGetUniformLocation(prog, "final_scale"), final_scale);
232 proj_loc = glGetUniformLocation(prog, "proj");
233 tri_num_loc = glGetUniformLocation(prog, "tri_num");
234 viewport_size_loc = glGetUniformLocation(prog, "viewport_size");
236 /* Set up vertex array object */
237 glGenVertexArrays(1, &vao);
238 glBindVertexArray(vao);
240 /* Set up vertex input buffer */
241 glGenBuffers(1, &vertex_buf);
242 glBindBuffer(GL_ARRAY_BUFFER, vertex_buf);
243 glBufferData(GL_ARRAY_BUFFER, sizeof(vertex_data), vertex_data,
244 GL_STATIC_DRAW);
245 glEnableVertexAttribArray(0);
246 glVertexAttribPointer(0, ARRAY_SIZE(vertex_data[0].pos_within_tri),
247 GL_FLOAT, GL_FALSE, sizeof(vertex_data[0]),
248 (void *) offsetof(vertex_attributes,
249 pos_within_tri));
250 glEnableVertexAttribArray(1);
251 glVertexAttribPointer(1, ARRAY_SIZE(vertex_data[0].barycentric_coords),
252 GL_FLOAT, GL_FALSE, sizeof(vertex_data[0]),
253 (void *) offsetof(vertex_attributes,
254 barycentric_coords));
258 void
259 InterpolationTestPattern::draw(const float (*proj)[4])
261 glUseProgram(prog);
263 /* Depending what the fragment shader does, it's possible that
264 * viewport_size might get optimized away. Only set it if it
265 * didn't.
267 if (viewport_size_loc != -1) {
268 GLint viewport_dims[4];
269 glGetIntegerv(GL_VIEWPORT, viewport_dims);
270 glUniform2i(viewport_size_loc, viewport_dims[2], viewport_dims[3]);
273 Triangles::draw(proj);
277 void Lines::compile()
279 /* Line coords within (-1,-1) to (1,1) rect */
280 static const float pos_line[][2] = {
281 { -0.8, -0.5 },
282 { 0.8, -0.5 }
285 /* Number of line instances across (and down) */
286 int lines_across = 4;
288 /* Total number of lines drawn */
289 num_lines = lines_across * lines_across;
291 /* Amount each line should be rotated compared to prev */
292 float rotation_delta = M_PI * 2.0 / num_lines;
294 /* Scaling factor uniformly applied to line coords */
295 float line_scale = 0.8 / lines_across;
297 /* Final scaling factor */
298 float final_scale = 0.95;
300 static const char *vert =
301 "#version 120\n"
302 "attribute vec2 pos_line;\n"
303 "uniform float line_scale;\n"
304 "uniform float rotation_delta;\n"
305 "uniform int lines_across;\n"
306 "uniform float final_scale;\n"
307 "uniform mat4 proj;\n"
308 "uniform int line_num;\n"
309 "\n"
310 "void main()\n"
311 "{\n"
312 " vec2 pos = line_scale * pos_line;\n"
313 " float rotation = rotation_delta * line_num;\n"
314 " pos = mat2(cos(rotation), sin(rotation),\n"
315 " -sin(rotation), cos(rotation)) * pos;\n"
316 " int i = int(mod(float(line_num), float(lines_across)));\n"
317 " int j = lines_across - 1 - line_num / lines_across;\n"
318 " pos += (vec2(i, j) * 2.0 + 1.0) / lines_across - 1.0;\n"
319 " pos *= final_scale;\n"
320 " gl_Position = proj * vec4(pos, 0.0, 1.0);\n"
321 "}\n";
323 static const char *frag =
324 "#version 120\n"
325 "void main()\n"
326 "{\n"
327 " gl_FragColor = vec4(1.0);\n"
328 "}\n";
330 /* Compile program */
331 prog = glCreateProgram();
332 GLint vs = piglit_compile_shader_text(GL_VERTEX_SHADER, vert);
333 glAttachShader(prog, vs);
334 GLint fs = piglit_compile_shader_text(GL_FRAGMENT_SHADER, frag);
335 glAttachShader(prog, fs);
336 glBindAttribLocation(prog, 0, "pos_line");
337 glLinkProgram(prog);
338 if (!piglit_link_check_status(prog)) {
339 piglit_report_result(PIGLIT_FAIL);
342 /* Set up uniforms */
343 glUseProgram(prog);
344 glUniform1f(glGetUniformLocation(prog, "line_scale"), line_scale);
345 glUniform1f(glGetUniformLocation(prog, "rotation_delta"),
346 rotation_delta);
347 glUniform1i(glGetUniformLocation(prog, "lines_across"), lines_across);
348 glUniform1f(glGetUniformLocation(prog, "final_scale"), final_scale);
349 proj_loc = glGetUniformLocation(prog, "proj");
350 line_num_loc = glGetUniformLocation(prog, "line_num");
352 /* Set up vertex array object */
353 glGenVertexArrays(1, &vao);
354 glBindVertexArray(vao);
356 /* Set up vertex input buffer */
357 glGenBuffers(1, &vertex_buf);
358 glBindBuffer(GL_ARRAY_BUFFER, vertex_buf);
359 glBufferData(GL_ARRAY_BUFFER, sizeof(pos_line), pos_line,
360 GL_STATIC_DRAW);
361 glEnableVertexAttribArray(0);
362 glVertexAttribPointer(0, ARRAY_SIZE(pos_line[0]), GL_FLOAT,
363 GL_FALSE, sizeof(pos_line[0]), (void *) 0);
366 void Lines::draw(const float (*proj)[4])
368 glClear(GL_COLOR_BUFFER_BIT);
369 glUseProgram(prog);
370 glUniformMatrix4fv(proj_loc, 1, GL_TRUE, &proj[0][0]);
371 glBindVertexArray(vao);
372 for (int line_num = 0; line_num < num_lines; ++line_num) {
373 /* Draws with line width = 0.25, 0.75, 1.25,
374 * 1.75, 2.25, 2.75, 3.25, 3.75
376 glLineWidth((1 + 2 * line_num) / 4.0);
377 glUniform1i(line_num_loc, line_num);
378 glDrawArrays(GL_LINES, 0, 2);
382 void Points::compile()
384 /* Point coords within (-1,-1) to (1,1) rect */
385 static const float pos_point[2] = { -0.5, -0.5 };
387 /* Number of point instances across (and down) */
388 int points_across = 4;
390 /* Total number of points drawn */
391 num_points = points_across * points_across;
393 /* Scaling factor uniformly applied to point coords */
394 float point_scale = 0.8 / points_across;
396 /* Final scaling factor */
397 float final_scale = 0.95;
399 static const char *vert =
400 "#version 120\n"
401 "attribute vec2 pos_point;\n"
402 "uniform float point_scale;\n"
403 "uniform int points_across;\n"
404 "uniform float final_scale;\n"
405 "uniform mat4 proj;\n"
406 "uniform int point_num;\n"
407 "uniform float depth;\n"
408 "\n"
409 "void main()\n"
410 "{\n"
411 " vec2 pos = point_scale * pos_point;\n"
412 " int i = int(mod(float(point_num), float(points_across)));\n"
413 " int j = points_across - 1 - point_num / points_across;\n"
414 " pos += (vec2(i, j) * 2.0 + 1.0) / points_across - 1.0;\n"
415 " pos *= final_scale;\n"
416 " gl_Position = proj * vec4(pos, depth, 1.0);\n"
417 "}\n";
419 static const char *frag =
420 "#version 120\n"
421 "void main()\n"
422 "{\n"
423 " gl_FragColor = vec4(1.0);\n"
424 "}\n";
426 /* Compile program */
427 prog = glCreateProgram();
428 GLint vs = piglit_compile_shader_text(GL_VERTEX_SHADER, vert);
429 glAttachShader(prog, vs);
430 GLint fs = piglit_compile_shader_text(GL_FRAGMENT_SHADER, frag);
431 glAttachShader(prog, fs);
432 glBindAttribLocation(prog, 0, "pos_point");
433 glLinkProgram(prog);
434 if (!piglit_link_check_status(prog)) {
435 piglit_report_result(PIGLIT_FAIL);
438 /* Set up uniforms */
439 glUseProgram(prog);
440 glUniform1f(glGetUniformLocation(prog, "point_scale"), point_scale);
441 glUniform1i(glGetUniformLocation(prog, "points_across"), points_across);
442 glUniform1f(glGetUniformLocation(prog, "final_scale"), final_scale);
443 proj_loc = glGetUniformLocation(prog, "proj");
444 point_num_loc = glGetUniformLocation(prog, "point_num");
445 depth_loc = glGetUniformLocation(prog, "depth");
447 /* Set up vertex array object */
448 glGenVertexArrays(1, &vao);
449 glBindVertexArray(vao);
451 /* Set up vertex input buffer */
452 glGenBuffers(1, &vertex_buf);
453 glBindBuffer(GL_ARRAY_BUFFER, vertex_buf);
454 glBufferData(GL_ARRAY_BUFFER, sizeof(pos_point), pos_point,
455 GL_STATIC_DRAW);
456 glEnableVertexAttribArray(0);
457 glVertexAttribPointer(0, ARRAY_SIZE(pos_point), GL_FLOAT,
458 GL_FALSE, 0, (void *) 0);
461 void Points::draw(const float (*proj)[4])
463 glClear(GL_COLOR_BUFFER_BIT);
464 glUseProgram(prog);
465 glUniformMatrix4fv(proj_loc, 1, GL_TRUE, &proj[0][0]);
466 glBindVertexArray(vao);
467 glUniform1f(depth_loc, 0.0);
468 for (int point_num = 0; point_num < num_points; ++point_num) {
469 glPointSize((1.0 + 4 * point_num) / 4.0);
470 glUniform1i(point_num_loc, point_num);
471 glDrawArrays(GL_POINTS, 0, 1);
475 Sunburst::Sunburst()
476 : out_type(GL_UNSIGNED_NORMALIZED),
477 compute_depth(false),
478 prog(0),
479 rotation_loc(0),
480 vert_depth_loc(0),
481 frag_depth_loc(0),
482 proj_loc(0),
483 draw_colors_loc(0),
484 vao(0),
485 num_tris(0),
486 vertex_buf(0)
492 * Determine the GLSL type that should be used for rendering, based on
493 * out_type.
495 const char *
496 Sunburst::get_out_type_glsl() const
498 switch(out_type) {
499 case GL_INT:
500 return "ivec4";
501 case GL_UNSIGNED_INT:
502 return "uvec4";
503 case GL_UNSIGNED_NORMALIZED:
504 case GL_FLOAT:
505 return "vec4";
506 default:
507 printf("Unrecognized out_type: %s\n",
508 piglit_get_gl_enum_name(out_type));
509 piglit_report_result(PIGLIT_FAIL);
510 return "UNKNOWN";
515 void Sunburst::compile()
517 static struct vertex_attributes {
518 float pos_within_tri[2];
519 float barycentric_coords[3];
520 } vertex_data[] = {
521 { { -0.3, -0.8 }, { 1, 0, 0 } },
522 { { 0.0, 1.0 }, { 0, 1, 0 } },
523 { { 0.3, -0.8 }, { 0, 0, 1 } }
525 bool need_glsl130 = out_type == GL_INT || out_type == GL_UNSIGNED_INT;
527 if (need_glsl130) {
528 piglit_require_gl_version(30);
531 /* Total number of triangles drawn */
532 num_tris = 7;
534 static const char *vert_template =
535 "#version %s\n"
536 "attribute vec2 pos_within_tri;\n"
537 "attribute vec3 in_barycentric_coords;\n"
538 "varying vec3 barycentric_coords;\n"
539 "uniform float rotation;\n"
540 "uniform float vert_depth;\n"
541 "uniform mat4 proj;\n"
542 "\n"
543 "void main()\n"
544 "{\n"
545 " vec2 pos = pos_within_tri;\n"
546 " pos = mat2(cos(rotation), sin(rotation),\n"
547 " -sin(rotation), cos(rotation)) * pos;\n"
548 " gl_Position = proj * vec4(pos, vert_depth, 1.0);\n"
549 " barycentric_coords = in_barycentric_coords;\n"
550 "}\n";
552 static const char *frag_template =
553 "#version %s\n"
554 "#define OUT_TYPE %s\n"
555 "#define COMPUTE_DEPTH %s\n"
556 "uniform float frag_depth;\n"
557 "varying vec3 barycentric_coords;\n"
558 "uniform mat3x4 draw_colors;\n"
559 "#if __VERSION__ == 130\n"
560 " out OUT_TYPE frag_out;\n"
561 "#endif\n"
562 "\n"
563 "void main()\n"
564 "{\n"
565 "#if __VERSION__ == 130\n"
566 " frag_out = OUT_TYPE(draw_colors * barycentric_coords);\n"
567 "#else\n"
568 " gl_FragColor = draw_colors * barycentric_coords;\n"
569 "#endif\n"
570 "#if COMPUTE_DEPTH\n"
571 " gl_FragDepth = (frag_depth + 1.0) / 2.0;\n"
572 "#endif\n"
573 "}\n";
575 /* Compile program */
576 prog = glCreateProgram();
577 unsigned vert_alloc_len =
578 strlen(vert_template) + 4;
579 char *vert = (char *) malloc(vert_alloc_len);
580 sprintf(vert, vert_template, need_glsl130 ? "130" : "120");
581 GLint vs = piglit_compile_shader_text(GL_VERTEX_SHADER, vert);
582 free(vert);
583 glAttachShader(prog, vs);
585 const char *out_type_glsl = get_out_type_glsl();
586 unsigned frag_alloc_len =
587 strlen(frag_template) + strlen(out_type_glsl) + 4;
588 char *frag = (char *) malloc(frag_alloc_len);
589 sprintf(frag, frag_template, need_glsl130 ? "130" : "120",
590 out_type_glsl,
591 compute_depth ? "1" : "0");
592 GLint fs = piglit_compile_shader_text(GL_FRAGMENT_SHADER, frag);
593 free(frag);
594 glAttachShader(prog, fs);
596 glBindAttribLocation(prog, 0, "pos_within_tri");
597 glBindAttribLocation(prog, 1, "in_barycentric_coords");
598 if (need_glsl130) {
599 glBindFragDataLocation(prog, 0, "frag_out");
601 glLinkProgram(prog);
602 if (!piglit_link_check_status(prog)) {
603 piglit_report_result(PIGLIT_FAIL);
606 /* Set up uniforms */
607 glUseProgram(prog);
608 rotation_loc = glGetUniformLocation(prog, "rotation");
609 vert_depth_loc = glGetUniformLocation(prog, "vert_depth");
610 frag_depth_loc = glGetUniformLocation(prog, "frag_depth");
611 glUniform1f(vert_depth_loc, 0.0);
612 glUniform1f(frag_depth_loc, 0.0);
613 proj_loc = glGetUniformLocation(prog, "proj");
614 draw_colors_loc = glGetUniformLocation(prog, "draw_colors");
616 /* Set up vertex array object */
617 glGenVertexArrays(1, &vao);
618 glBindVertexArray(vao);
620 /* Set up vertex input buffer */
621 glGenBuffers(1, &vertex_buf);
622 glBindBuffer(GL_ARRAY_BUFFER, vertex_buf);
623 glBufferData(GL_ARRAY_BUFFER, sizeof(vertex_data), vertex_data,
624 GL_STATIC_DRAW);
625 glEnableVertexAttribArray(0);
626 glVertexAttribPointer(0, ARRAY_SIZE(vertex_data[0].pos_within_tri),
627 GL_FLOAT, GL_FALSE, sizeof(vertex_data[0]),
628 (void *) 0);
629 glEnableVertexAttribArray(1);
630 glVertexAttribPointer(1, ARRAY_SIZE(vertex_data[0].barycentric_coords),
631 GL_FLOAT, GL_FALSE, sizeof(vertex_data[0]),
632 (void *) offsetof(vertex_attributes,
633 barycentric_coords));
637 ColorGradientSunburst::ColorGradientSunburst(GLenum out_type)
639 this->out_type = out_type;
644 * Draw the color gradient sunburst, but instead of using color
645 * components that range from 0.0 to 1.0, apply the given scaling
646 * factor and offset to each color component.
648 * The offset is also applied when clearing the color buffer.
650 void
651 ColorGradientSunburst::draw_with_scale_and_offset(const float (*proj)[4],
652 float scale, float offset)
654 switch (out_type) {
655 case GL_INT: {
656 int clear_color[4] = { offset, offset, offset, offset };
657 glClearBufferiv(GL_COLOR, 0, clear_color);
658 break;
660 case GL_UNSIGNED_INT: {
661 unsigned clear_color[4] = { offset, offset, offset, offset };
662 glClearBufferuiv(GL_COLOR, 0, clear_color);
663 break;
665 case GL_UNSIGNED_NORMALIZED:
666 case GL_FLOAT: {
667 glClearColor(offset, offset, offset, offset);
668 glClear(GL_COLOR_BUFFER_BIT);
669 break;
671 default:
672 printf("Unrecognized out_type: %s\n",
673 piglit_get_gl_enum_name(out_type));
674 piglit_report_result(PIGLIT_FAIL);
675 break;
678 glUseProgram(prog);
679 glUniformMatrix4fv(proj_loc, 1, GL_TRUE, &proj[0][0]);
680 float draw_colors[3][4] =
681 { { 1, 0, 0, 1.0 }, { 0, 1, 0, 0.5 }, { 0, 0, 1, 1.0 } };
682 for (int i = 0; i < 3; ++i) {
683 for (int j = 0; j < 4; ++j) {
684 draw_colors[i][j] = scale * draw_colors[i][j] + offset;
687 glUniformMatrix3x4fv(draw_colors_loc, 1, GL_FALSE,
688 &draw_colors[0][0]);
689 glBindVertexArray(vao);
690 for (int i = 0; i < num_tris; ++i) {
691 glUniform1f(rotation_loc, M_PI * 2.0 * i / num_tris);
692 glDrawArrays(GL_TRIANGLES, 0, 3);
697 void
698 ColorGradientSunburst::draw(const float (*proj)[4])
700 draw_with_scale_and_offset(proj, 1.0, 0.0);
704 void
705 StencilSunburst::draw(const float (*proj)[4])
707 glEnable(GL_STENCIL_TEST);
708 glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
710 glClear(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
712 glUseProgram(prog);
713 glUniformMatrix4fv(proj_loc, 1, GL_TRUE, &proj[0][0]);
714 glBindVertexArray(vao);
715 for (int i = 0; i < num_tris; ++i) {
716 glStencilFunc(GL_ALWAYS, i+1, 0xff);
717 glUniform1f(rotation_loc, M_PI * 2.0 * i / num_tris);
718 glDrawArrays(GL_TRIANGLES, 0, 3);
721 glDisable(GL_STENCIL_TEST);
725 DepthSunburst::DepthSunburst(bool compute_depth)
727 this->compute_depth = compute_depth;
731 void
732 DepthSunburst::draw(const float (*proj)[4])
734 glEnable(GL_DEPTH_TEST);
735 glDepthFunc(GL_LESS);
737 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
739 glUseProgram(prog);
740 glUniformMatrix4fv(proj_loc, 1, GL_TRUE, &proj[0][0]);
741 glBindVertexArray(vao);
742 for (int i = 0; i < num_tris; ++i) {
743 /* Draw triangles in a haphazard order so we can
744 * verify that depth comparisons sort them out
745 * properly.
747 int triangle_to_draw = (i * 3) % num_tris;
749 /* Note: with num_tris == 7, this causes us to draw
750 * triangles at depths of 3/4, 1/2, -1/4, 0, 1/4, 1/2,
751 * and 3/4.
753 glUniform1f(compute_depth ? frag_depth_loc : vert_depth_loc,
754 float(num_tris - triangle_to_draw * 2 - 1)
755 / (num_tris + 1));
757 glUniform1f(rotation_loc,
758 M_PI * 2.0 * triangle_to_draw / num_tris);
759 glDrawArrays(GL_TRIANGLES, 0, 3);
762 glDisable(GL_DEPTH_TEST);
766 void
767 ManifestStencil::compile()
769 static const char *vert =
770 "#version 120\n"
771 "attribute vec2 pos;\n"
772 "void main()\n"
773 "{\n"
774 " gl_Position = vec4(pos, 0.0, 1.0);\n"
775 "}\n";
777 static const char *frag =
778 "#version 120\n"
779 "uniform vec4 color;\n"
780 "void main()\n"
781 "{\n"
782 " gl_FragColor = color;\n"
783 "}\n";
785 /* Compile program */
786 prog = glCreateProgram();
787 GLint vs = piglit_compile_shader_text(GL_VERTEX_SHADER, vert);
788 glAttachShader(prog, vs);
789 GLint fs = piglit_compile_shader_text(GL_FRAGMENT_SHADER, frag);
790 glAttachShader(prog, fs);
791 glBindAttribLocation(prog, 0, "pos");
792 glLinkProgram(prog);
793 if (!piglit_link_check_status(prog)) {
794 piglit_report_result(PIGLIT_FAIL);
797 /* Set up uniforms */
798 glUseProgram(prog);
799 color_loc = glGetUniformLocation(prog, "color");
801 /* Set up vertex array object */
802 glGenVertexArrays(1, &vao);
803 glBindVertexArray(vao);
805 /* Set up vertex input buffer */
806 float vertex_data[4][2] = {
807 { -1, -1 },
808 { -1, 1 },
809 { 1, -1 },
810 { 1, 1 }
812 glGenBuffers(1, &vertex_buf);
813 glBindBuffer(GL_ARRAY_BUFFER, vertex_buf);
814 glBufferData(GL_ARRAY_BUFFER, sizeof(vertex_data), vertex_data,
815 GL_STATIC_DRAW);
816 glEnableVertexAttribArray(0);
817 glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(vertex_data[0]),
818 (void *) 0);
821 void
822 ManifestStencil::run()
824 static float colors[8][4] = {
825 { 0.0, 0.0, 0.0, 1.0 },
826 { 0.0, 0.0, 1.0, 1.0 },
827 { 0.0, 1.0, 0.0, 1.0 },
828 { 0.0, 1.0, 1.0, 1.0 },
829 { 1.0, 0.0, 0.0, 1.0 },
830 { 1.0, 0.0, 1.0, 1.0 },
831 { 1.0, 1.0, 0.0, 1.0 },
832 { 1.0, 1.0, 1.0, 1.0 }
835 glUseProgram(prog);
836 glBindVertexArray(vao);
838 glEnable(GL_STENCIL_TEST);
839 glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
841 /* Clear the color buffer to 0, in case the stencil buffer
842 * contains any values outside the range 0..7
844 glClear(GL_COLOR_BUFFER_BIT);
846 for (int i = 0; i < 8; ++i) {
847 glStencilFunc(GL_EQUAL, i, 0xff);
848 glUniform4fv(color_loc, 1, colors[i]);
849 glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
852 glDisable(GL_STENCIL_TEST);
855 void
856 ManifestDepth::compile()
858 static const char *vert =
859 "#version 120\n"
860 "attribute vec2 pos;\n"
861 "uniform float depth;\n"
862 "void main()\n"
863 "{\n"
864 " gl_Position = vec4(pos, depth, 1.0);\n"
865 "}\n";
867 static const char *frag =
868 "#version 120\n"
869 "uniform vec4 color;\n"
870 "void main()\n"
871 "{\n"
872 " gl_FragColor = color;\n"
873 "}\n";
875 /* Compile program */
876 prog = glCreateProgram();
877 GLint vs = piglit_compile_shader_text(GL_VERTEX_SHADER, vert);
878 glAttachShader(prog, vs);
879 GLint fs = piglit_compile_shader_text(GL_FRAGMENT_SHADER, frag);
880 glAttachShader(prog, fs);
881 glBindAttribLocation(prog, 0, "pos");
882 glLinkProgram(prog);
883 if (!piglit_link_check_status(prog)) {
884 piglit_report_result(PIGLIT_FAIL);
887 /* Set up uniforms */
888 glUseProgram(prog);
889 color_loc = glGetUniformLocation(prog, "color");
890 depth_loc = glGetUniformLocation(prog, "depth");
892 /* Set up vertex array object */
893 glGenVertexArrays(1, &vao);
894 glBindVertexArray(vao);
896 /* Set up vertex input buffer */
897 float vertex_data[4][2] = {
898 { -1, -1 },
899 { -1, 1 },
900 { 1, -1 },
901 { 1, 1 }
903 glGenBuffers(1, &vertex_buf);
904 glBindBuffer(GL_ARRAY_BUFFER, vertex_buf);
905 glBufferData(GL_ARRAY_BUFFER, sizeof(vertex_data), vertex_data,
906 GL_STATIC_DRAW);
907 glEnableVertexAttribArray(0);
908 glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(vertex_data[0]),
909 (void *) 0);
912 void
913 ManifestDepth::run()
915 static float colors[8][4] = {
916 { 0.0, 0.0, 0.0, 1.0 },
917 { 0.0, 0.0, 1.0, 1.0 },
918 { 0.0, 1.0, 0.0, 1.0 },
919 { 0.0, 1.0, 1.0, 1.0 },
920 { 1.0, 0.0, 0.0, 1.0 },
921 { 1.0, 0.0, 1.0, 1.0 },
922 { 1.0, 1.0, 0.0, 1.0 },
923 { 1.0, 1.0, 1.0, 1.0 }
926 glUseProgram(prog);
927 glBindVertexArray(vao);
929 glEnable(GL_DEPTH_TEST);
930 glDepthFunc(GL_LESS);
931 glEnable(GL_STENCIL_TEST);
932 glStencilOp(GL_KEEP, GL_KEEP, GL_INCR);
933 glStencilFunc(GL_EQUAL, 0, 0xff);
935 /* Clear the stencil buffer to 0, leaving depth and color
936 * buffers unchanged.
938 glClear(GL_STENCIL_BUFFER_BIT);
940 for (int i = 0; i < 8; ++i) {
941 glUniform4fv(color_loc, 1, colors[i]);
942 glUniform1f(depth_loc, float(7 - 2*i)/8);
943 glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
946 glDisable(GL_STENCIL_TEST);
947 glDisable(GL_DEPTH_TEST);