arb_program_interface_query: set vs_input2[1][0] as valid name
[piglit.git] / tests / perf / draw-prim-rate.c
blob14c8a0affd6af8acf56ce75e5f181feeae74ea0c
1 /*
2 * Copyright (C) 2018 Advanced Micro Devices, Inc.
3 * All Rights Reserved.
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the "Software"),
7 * to deal in the Software without restriction, including without limitation
8 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9 * and/or sell copies of the Software, and to permit persons to whom the
10 * Software is furnished to do so, subject to the following conditions:
12 * The above copyright notice and this permission notice shall be included
13 * in all copies or substantial portions of the Software.
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
16 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * VMWARE BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
19 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23 /**
24 * Measure primitive rate under various circumstances.
26 * Culling methods:
27 * - none
28 * - rasterizer discard
29 * - face culling
30 * - view culling
31 * - degenerate primitives
32 * - subpixel primitives
35 #include "common.h"
36 #include <stdbool.h>
37 #undef NDEBUG
38 #include <assert.h>
39 #include "piglit-util-gl.h"
41 /* this must be a power of two to prevent precision issues */
42 #define WINDOW_SIZE 1024
44 PIGLIT_GL_TEST_CONFIG_BEGIN
46 config.supports_gl_compat_version = 10;
47 config.window_width = WINDOW_SIZE;
48 config.window_height = WINDOW_SIZE;
49 config.window_visual = PIGLIT_GL_VISUAL_RGBA | PIGLIT_GL_VISUAL_DOUBLE;
51 PIGLIT_GL_TEST_CONFIG_END
53 static unsigned gpu_freq_mhz;
54 static GLint progs[9];
56 void
57 piglit_init(int argc, char **argv)
59 for (unsigned i = 1; i < argc; i++) {
60 if (strncmp(argv[i], "-freq=", 6) == 0)
61 sscanf(argv[i] + 6, "%u", &gpu_freq_mhz);
64 piglit_require_gl_version(32);
66 progs[0] = piglit_build_simple_program(
67 "#version 150 compatibility \n"
68 "void main() { \n"
69 " gl_Position = gl_Vertex; \n"
70 "}",
72 "#version 150 compatibility \n"
73 "void main() { \n"
74 " gl_FragColor = vec4(1.0); \n"
75 "}");
77 progs[1] = piglit_build_simple_program(
78 "#version 150 compatibility \n"
79 "varying vec4 v[1]; \n"
80 "attribute vec4 a[1]; \n"
81 "void main() { \n"
82 " for (int i = 0; i < 1; i++) v[i] = a[i]; \n"
83 " gl_Position = gl_Vertex; \n"
84 "}",
86 "#version 150 compatibility \n"
87 "varying vec4 v[1]; \n"
88 "void main() { \n"
89 " gl_FragColor = v[0]; \n"
90 "}");
92 progs[2] = piglit_build_simple_program(
93 "#version 150 compatibility \n"
94 "varying vec4 v[2]; \n"
95 "attribute vec4 a[2]; \n"
96 "void main() { \n"
97 " for (int i = 0; i < 2; i++) v[i] = a[i]; \n"
98 " gl_Position = gl_Vertex; \n"
99 "}",
101 "#version 150 compatibility \n"
102 "varying vec4 v[2]; \n"
103 "void main() { \n"
104 " gl_FragColor = vec4(dot(v[0] * v[1], vec4(1.0)) == 1.0 ? 1.0 : 0.0); \n"
105 "}");
107 progs[3] = piglit_build_simple_program(
108 "#version 150 compatibility \n"
109 "varying vec4 v[3]; \n"
110 "attribute vec4 a[3]; \n"
111 "void main() { \n"
112 " for (int i = 0; i < 3; i++) v[i] = a[i]; \n"
113 " gl_Position = gl_Vertex; \n"
114 "}",
116 "#version 150 compatibility \n"
117 "varying vec4 v[3]; \n"
118 "void main() { \n"
119 " gl_FragColor = vec4(dot(v[0] * v[1] * v[2], vec4(1.0)) == 1.0 ? 1.0 : 0.0); \n"
120 "}");
122 progs[4] = piglit_build_simple_program(
123 "#version 150 compatibility \n"
124 "varying vec4 v[4]; \n"
125 "attribute vec4 a[4]; \n"
126 "void main() { \n"
127 " for (int i = 0; i < 4; i++) v[i] = a[i]; \n"
128 " gl_Position = gl_Vertex; \n"
129 "}",
131 "#version 150 compatibility \n"
132 "varying vec4 v[4]; \n"
133 "void main() { \n"
134 " gl_FragColor = vec4(dot(v[0] * v[1] * v[2] * v[3], vec4(1.0)) == 1.0 ? 1.0 : 0.0); \n"
135 "}");
137 progs[6] = piglit_build_simple_program(
138 "#version 150 compatibility \n"
139 "varying vec4 v[6]; \n"
140 "attribute vec4 a[6]; \n"
141 "void main() { \n"
142 " for (int i = 0; i < 6; i++) v[i] = a[i]; \n"
143 " gl_Position = gl_Vertex; \n"
144 "}",
146 "#version 150 compatibility \n"
147 "varying vec4 v[6]; \n"
148 "void main() { \n"
149 " gl_FragColor = vec4(dot(v[0] * v[1] * v[2] * v[3] * v[4] * v[5], vec4(1.0)) == 1.0 ? 1.0 : 0.0); \n"
150 "}");
152 progs[8] = piglit_build_simple_program(
153 "#version 150 compatibility \n"
154 "varying vec4 v[8]; \n"
155 "attribute vec4 a[8]; \n"
156 "void main() { \n"
157 " for (int i = 0; i < 8; i++) v[i] = a[i]; \n"
158 " gl_Position = gl_Vertex; \n"
159 "}",
161 "#version 150 compatibility \n"
162 "varying vec4 v[8]; \n"
163 "void main() { \n"
164 " gl_FragColor = vec4(dot(v[0] * v[1] * v[2] * v[3] * v[4] * v[5] * v[6] * v[7], vec4(1.0)) == 1.0 ? 1.0 : 0.0); \n"
165 "}");
167 glEnableClientState(GL_VERTEX_ARRAY);
168 glEnable(GL_CULL_FACE);
169 glPrimitiveRestartIndex(UINT32_MAX);
172 static void
173 gen_triangle_tile(unsigned num_quads_per_dim, double prim_size_in_pixels,
174 unsigned cull_percentage, unsigned vertices_per_prim,
175 bool back_face_culling, bool view_culling, bool degenerate_prims,
176 unsigned max_vertices, unsigned *num_vertices, float *vertices,
177 unsigned max_indices, unsigned *num_indices, unsigned *indices)
179 /* clip space coordinates in both X and Y directions: */
180 const double first = -1;
181 const double max_length = 2;
182 const double d = prim_size_in_pixels * 2.0 / WINDOW_SIZE;
184 assert(d * num_quads_per_dim <= max_length);
185 assert(*num_vertices == 0);
187 /* the vertex ordering is counter-clockwise */
188 for (unsigned ty = 0; ty < num_quads_per_dim; ty++) {
189 bool cull;
191 if (cull_percentage == 0)
192 cull = false;
193 else if (cull_percentage == 25)
194 cull = ty % 4 == 0;
195 else if (cull_percentage == 50)
196 cull = ty % 2 == 0;
197 else if (cull_percentage == 75)
198 cull = ty % 4 != 0;
199 else if (cull_percentage == 100)
200 cull = true;
201 else
202 assert(!"wrong cull_percentage");
204 for (unsigned tx = 0; tx < num_quads_per_dim; tx++) {
205 unsigned x = tx;
206 unsigned y = ty;
208 /* view culling in different directions */
209 double xoffset = 0, yoffset = 0, zoffset = 0;
211 if (cull && view_culling) {
212 unsigned side = (ty / 2) % 4;
214 if (side == 0) xoffset = -2;
215 else if (side == 1) xoffset = 2;
216 else if (side == 2) yoffset = -2;
217 else if (side == 3) yoffset = 2;
220 if (indices) {
221 unsigned elem = *num_vertices * 3;
223 /* generate horizontal stripes with maximum reuse */
224 if (x == 0) {
225 *num_vertices += 2;
226 assert(*num_vertices <= max_vertices);
228 vertices[elem++] = xoffset + first + d * x;
229 vertices[elem++] = yoffset + first + d * y;
230 vertices[elem++] = zoffset;
232 vertices[elem++] = xoffset + first + d * x;
233 vertices[elem++] = yoffset + first + d * (y + 1);
234 vertices[elem++] = zoffset;
237 int base_index = *num_vertices;
239 *num_vertices += vertices_per_prim == 2 ? 4 : 2;
240 assert(*num_vertices <= max_vertices);
242 if (vertices_per_prim == 2) {
243 vertices[elem++] = xoffset + first + d * x;
244 vertices[elem++] = yoffset + first + d * (y + 1);
245 vertices[elem++] = zoffset;
248 vertices[elem++] = xoffset + first + d * (x + 1);
249 vertices[elem++] = yoffset + first + d * y;
250 vertices[elem++] = zoffset;
252 if (vertices_per_prim == 2) {
253 vertices[elem++] = xoffset + first + d * (x + 1);
254 vertices[elem++] = yoffset + first + d * y;
255 vertices[elem++] = zoffset;
258 vertices[elem++] = xoffset + first + d * (x + 1);
259 vertices[elem++] = yoffset + first + d * (y + 1);
260 vertices[elem++] = zoffset;
262 /* generate indices */
263 unsigned idx = *num_indices;
264 *num_indices += 6;
265 assert(*num_indices <= max_indices);
267 if (vertices_per_prim == 2) {
268 indices[idx++] = base_index - 2;
269 indices[idx++] = base_index + 1;
270 indices[idx++] = base_index;
272 indices[idx++] = base_index - 1;
273 indices[idx++] = base_index + 2;
274 indices[idx++] = base_index + 3;
275 } else {
276 indices[idx++] = base_index - 2;
277 indices[idx++] = base_index;
278 indices[idx++] = base_index - 1;
280 indices[idx++] = base_index - 1;
281 indices[idx++] = base_index;
282 indices[idx++] = base_index + 1;
285 if (cull && back_face_culling) {
286 /* switch the winding order */
287 unsigned tmp = indices[idx - 6];
288 indices[idx - 6] = indices[idx - 5];
289 indices[idx - 5] = tmp;
291 tmp = indices[idx - 3];
292 indices[idx - 3] = indices[idx - 2];
293 indices[idx - 2] = tmp;
296 if (cull && degenerate_prims) {
297 indices[idx - 5] = indices[idx - 4];
298 indices[idx - 2] = indices[idx - 1];
300 } else {
301 unsigned elem = *num_vertices * 3;
302 *num_vertices += 6;
303 assert(*num_vertices <= max_vertices);
305 vertices[elem++] = xoffset + first + d * x;
306 vertices[elem++] = yoffset + first + d * y;
307 vertices[elem++] = zoffset;
309 vertices[elem++] = xoffset + first + d * (x + 1);
310 vertices[elem++] = yoffset + first + d * y;
311 vertices[elem++] = zoffset;
313 vertices[elem++] = xoffset + first + d * x;
314 vertices[elem++] = yoffset + first + d * (y + 1);
315 vertices[elem++] = zoffset;
317 vertices[elem++] = xoffset + first + d * x;
318 vertices[elem++] = yoffset + first + d * (y + 1);
319 vertices[elem++] = zoffset;
321 vertices[elem++] = xoffset + first + d * (x + 1);
322 vertices[elem++] = yoffset + first + d * y;
323 vertices[elem++] = zoffset;
325 vertices[elem++] = xoffset + first + d * (x + 1);
326 vertices[elem++] = yoffset + first + d * (y + 1);
327 vertices[elem++] = zoffset;
329 if (cull && back_face_culling) {
330 /* switch the winding order */
331 float old[6*3];
332 memcpy(old, vertices + elem - 6*3, 6*3*4);
334 for (unsigned i = 0; i < 6; i++) {
335 vertices[elem - 6*3 + i*3 + 0] = old[(5 - i)*3 + 0];
336 vertices[elem - 6*3 + i*3 + 1] = old[(5 - i)*3 + 1];
337 vertices[elem - 6*3 + i*3 + 2] = old[(5 - i)*3 + 2];
341 if (cull && degenerate_prims) {
342 /* use any previously generated vertices */
343 unsigned v0 = rand() % *num_vertices;
344 unsigned v1 = rand() % *num_vertices;
346 memcpy(&vertices[elem - 5*3], &vertices[v0*3], 12);
347 memcpy(&vertices[elem - 4*3], &vertices[v0*3], 12);
349 memcpy(&vertices[elem - 2*3], &vertices[v1*3], 12);
350 memcpy(&vertices[elem - 1*3], &vertices[v1*3], 12);
357 static void
358 gen_triangle_strip_tile(unsigned num_quads_per_dim, double prim_size_in_pixels,
359 unsigned cull_percentage,
360 bool back_face_culling, bool view_culling, bool degenerate_prims,
361 unsigned max_vertices, unsigned *num_vertices, float *vertices,
362 unsigned max_indices, unsigned *num_indices, unsigned *indices)
364 /* clip space coordinates in both X and Y directions: */
365 const double first = -1;
366 const double max_length = 2;
367 const double d = prim_size_in_pixels * 2.0 / WINDOW_SIZE;
369 assert(d * num_quads_per_dim <= max_length);
370 assert(*num_vertices == 0);
372 /* the vertex ordering is counter-clockwise */
373 for (unsigned y = 0; y < num_quads_per_dim; y++) {
374 bool cull;
376 if (cull_percentage == 0)
377 cull = false;
378 else if (cull_percentage == 25)
379 cull = y % 4 == 0;
380 else if (cull_percentage == 50)
381 cull = y % 2 == 0;
382 else if (cull_percentage == 75)
383 cull = y % 4 != 0;
384 else if (cull_percentage == 100)
385 cull = true;
386 else
387 assert(!"wrong cull_percentage");
389 /* view culling in different directions */
390 double xoffset = 0, yoffset = 0, zoffset = 0;
392 if (cull && view_culling) {
393 unsigned side = (y / 2) % 4;
395 if (side == 0) xoffset = -2;
396 else if (side == 1) xoffset = 2;
397 else if (side == 2) yoffset = -2;
398 else if (side == 3) yoffset = 2;
401 if (cull && degenerate_prims) {
402 unsigned elem = *num_vertices * 3;
403 *num_vertices += 2 + num_quads_per_dim * 2;
404 assert(*num_vertices <= max_vertices);
406 for (unsigned x = 0; x < 2 + num_quads_per_dim * 2; x++) {
407 vertices[elem++] = 0;
408 vertices[elem++] = 0;
409 vertices[elem++] = 0;
411 continue;
414 unsigned elem = *num_vertices * 3;
415 bool add_degenerates = y > 0;
416 *num_vertices += (add_degenerates ? 4 : 0) + 2 + num_quads_per_dim * 2;
417 assert(*num_vertices <= max_vertices);
419 unsigned x = 0;
420 unsigned y0 = y;
421 unsigned y1 = y + 1;
423 if (cull && back_face_culling) {
424 y0 = y + 1;
425 y1 = y;
428 /* Add degenerated triangles to connect with the previous triangle strip. */
429 if (add_degenerates) {
430 unsigned base = elem;
432 vertices[elem++] = vertices[base - 3];
433 vertices[elem++] = vertices[base - 2];
434 vertices[elem++] = vertices[base - 1];
437 for (unsigned i = 0; i < (add_degenerates ? 4 : 1); i++) {
438 vertices[elem++] = xoffset + first + d * x;
439 vertices[elem++] = yoffset + first + d * y1;
440 vertices[elem++] = zoffset;
443 vertices[elem++] = xoffset + first + d * x;
444 vertices[elem++] = yoffset + first + d * y0;
445 vertices[elem++] = zoffset;
447 for (; x < num_quads_per_dim; x++) {
448 vertices[elem++] = xoffset + first + d * (x + 1);
449 vertices[elem++] = yoffset + first + d * y1;
450 vertices[elem++] = zoffset;
452 vertices[elem++] = xoffset + first + d * (x + 1);
453 vertices[elem++] = yoffset + first + d * y0;
454 vertices[elem++] = zoffset;
458 if (indices) {
459 for (unsigned i = 0; i < *num_vertices; i++)
460 indices[i] = i;
462 *num_indices = *num_vertices;
466 enum draw_method {
467 INDEXED_TRIANGLES,
468 INDEXED_TRIANGLES_2VTX, /* every triangle adds 2 new vertices and reuses 1 vertex */
469 TRIANGLES,
470 TRIANGLE_STRIP,
471 INDEXED_TRIANGLE_STRIP,
472 INDEXED_TRIANGLE_STRIP_PRIM_RESTART,
473 NUM_DRAW_METHODS,
476 static enum draw_method global_draw_method;
477 static unsigned count;
478 static unsigned num_duplicates;
479 static unsigned duplicate_index;
480 static unsigned vb_size, ib_size;
482 static void
483 run_draw(unsigned iterations)
485 for (unsigned i = 0; i < iterations; i++) {
486 if (global_draw_method == INDEXED_TRIANGLES ||
487 global_draw_method == INDEXED_TRIANGLES_2VTX) {
488 glDrawElements(GL_TRIANGLES, count,
489 GL_UNSIGNED_INT,
490 (void*)(long)(ib_size * duplicate_index));
491 } else if (global_draw_method == TRIANGLES) {
492 glDrawArrays(GL_TRIANGLES, (vb_size / 12) * duplicate_index, count);
493 } else if (global_draw_method == TRIANGLE_STRIP) {
494 glDrawArrays(GL_TRIANGLE_STRIP, (vb_size / 12) * duplicate_index, count);
495 } else if (global_draw_method == INDEXED_TRIANGLE_STRIP ||
496 global_draw_method == INDEXED_TRIANGLE_STRIP_PRIM_RESTART) {
497 glDrawElements(GL_TRIANGLE_STRIP, count,
498 GL_UNSIGNED_INT,
499 (void*)(long)(ib_size * duplicate_index));
502 duplicate_index = (duplicate_index + 1) % num_duplicates;
506 enum cull_method {
507 NONE,
508 BACK_FACE_CULLING,
509 RASTERIZER_DISCARD,
510 VIEW_CULLING,
511 SUBPIXEL_PRIMS,
512 DEGENERATE_PRIMS,
513 NUM_CULL_METHODS,
516 static double
517 run_test(unsigned debug_num_iterations, enum draw_method draw_method,
518 enum cull_method cull_method, unsigned num_quads_per_dim,
519 double quad_size_in_pixels, unsigned cull_percentage)
521 const unsigned max_indices = 8100000 * 3;
522 const unsigned max_vertices = max_indices;
524 while (num_quads_per_dim * quad_size_in_pixels >= WINDOW_SIZE)
525 quad_size_in_pixels *= 0.5;
527 /* Generate vertices. */
528 float *vertices = (float*)malloc(max_vertices * 12);
529 unsigned *indices = NULL;
531 if (draw_method == INDEXED_TRIANGLES ||
532 draw_method == INDEXED_TRIANGLES_2VTX ||
533 draw_method == INDEXED_TRIANGLE_STRIP ||
534 draw_method == INDEXED_TRIANGLE_STRIP_PRIM_RESTART)
535 indices = (unsigned*)malloc(max_indices * 4);
537 unsigned num_vertices = 0, num_indices = 0;
538 if (draw_method == TRIANGLE_STRIP ||
539 draw_method == INDEXED_TRIANGLE_STRIP ||
540 draw_method == INDEXED_TRIANGLE_STRIP_PRIM_RESTART) {
541 gen_triangle_strip_tile(num_quads_per_dim, quad_size_in_pixels,
542 cull_percentage,
543 cull_method == BACK_FACE_CULLING,
544 cull_method == VIEW_CULLING,
545 cull_method == DEGENERATE_PRIMS,
546 max_vertices, &num_vertices, vertices,
547 max_indices, &num_indices, indices);
548 } else {
549 gen_triangle_tile(num_quads_per_dim, quad_size_in_pixels,
550 cull_percentage,
551 draw_method == INDEXED_TRIANGLES_2VTX ? 2 : 1,
552 cull_method == BACK_FACE_CULLING,
553 cull_method == VIEW_CULLING,
554 cull_method == DEGENERATE_PRIMS,
555 max_vertices, &num_vertices, vertices,
556 max_indices, &num_indices, indices);
559 vb_size = num_vertices * 12;
560 ib_size = num_indices * 4;
562 bool cached = true; /* TODO: test both cached and uncached vertices */
564 if (cached) {
565 num_duplicates = 1;
566 } else {
567 /* Duplicate buffers and switch between them, so that no data is cached
568 * between draws. 256 MB should be greater than any cache.
570 * TODO: Varyings are sourced from zero-stride vertex attribs, so they don't
571 * consume any bandwidth.
573 num_duplicates = MAX2(1, 256*1024*1024 / vb_size);
576 /* Create buffers. */
577 GLuint vb, ib;
578 glGenBuffers(1, &vb);
579 glBindBuffer(GL_ARRAY_BUFFER, vb);
580 glBufferData(GL_ARRAY_BUFFER,
581 vb_size * num_duplicates, NULL, GL_STATIC_DRAW);
582 for (unsigned i = 0; i < num_duplicates; i++)
583 glBufferSubData(GL_ARRAY_BUFFER, vb_size * i, vb_size, vertices);
584 free(vertices);
586 if (indices) {
587 glGenBuffers(1, &ib);
588 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ib);
589 glBufferData(GL_ELEMENT_ARRAY_BUFFER,
590 ib_size * num_duplicates, NULL,
591 GL_STATIC_DRAW);
592 for (unsigned i = 0; i < num_duplicates; i++) {
593 glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, ib_size * i,
594 ib_size, indices);
596 free(indices);
598 /* Make sure all uploads are finished. */
599 glFinish();
601 /* Test */
602 if (cull_method == RASTERIZER_DISCARD)
603 glEnable(GL_RASTERIZER_DISCARD);
604 if (draw_method == INDEXED_TRIANGLE_STRIP_PRIM_RESTART)
605 glEnable(GL_PRIMITIVE_RESTART);
607 glBindBuffer(GL_ARRAY_BUFFER, vb);
608 glVertexPointer(3, GL_FLOAT, 0, NULL);
610 if (indices)
611 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ib);
613 global_draw_method = draw_method;
614 count = indices ? num_indices : num_vertices;
615 duplicate_index = 0;
617 double rate = 0;
619 if (debug_num_iterations)
620 run_draw(debug_num_iterations);
621 else
622 rate = perf_measure_gpu_rate(run_draw, 0.01);
624 if (cull_method == RASTERIZER_DISCARD)
625 glDisable(GL_RASTERIZER_DISCARD);
626 if (draw_method == INDEXED_TRIANGLE_STRIP_PRIM_RESTART)
627 glDisable(GL_PRIMITIVE_RESTART);
629 /* Cleanup. */
630 glDeleteBuffers(1, &vb);
631 if (indices)
632 glDeleteBuffers(1, &ib);
633 return rate;
636 static void
637 run(enum draw_method draw_method, enum cull_method cull_method,
638 const unsigned *num_quads_per_dim, const unsigned *num_prims,
639 unsigned num_prim_sets)
641 unsigned num_subtests = 1;
642 static unsigned cull_percentages[] = {100, 75, 50};
643 static double quad_sizes_in_pixels[] = {1.0 / 7, 0.25, 0.5};
645 if (cull_method == BACK_FACE_CULLING ||
646 cull_method == VIEW_CULLING) {
647 num_subtests = ARRAY_SIZE(cull_percentages);
648 } else if (cull_method == SUBPIXEL_PRIMS) {
649 num_subtests = ARRAY_SIZE(quad_sizes_in_pixels);
652 for (unsigned subtest = 0; subtest < num_subtests; subtest++) {
653 /* 2 is the maximum prim size when everything fits into the window */
654 double quad_size_in_pixels;
655 unsigned cull_percentage;
657 if (cull_method == SUBPIXEL_PRIMS) {
658 quad_size_in_pixels = quad_sizes_in_pixels[subtest];
659 cull_percentage = 0;
660 } else {
661 quad_size_in_pixels = 2;
662 cull_percentage = cull_percentages[subtest];
665 printf(" %-14s, ",
666 draw_method == INDEXED_TRIANGLES ? "DrawElems1Vtx" :
667 draw_method == INDEXED_TRIANGLES_2VTX ? "DrawElems2Vtx" :
668 draw_method == TRIANGLES ? "DrawArraysT" :
669 draw_method == TRIANGLE_STRIP ? "DrawArraysTS" :
670 draw_method == INDEXED_TRIANGLE_STRIP ? "DrawElemsTS" :
671 "DrawTS_PrimR");
673 if (cull_method == NONE ||
674 cull_method == RASTERIZER_DISCARD) {
675 printf("%-21s",
676 cull_method == NONE ? "none" : "rasterizer discard");
677 } else if (cull_method == SUBPIXEL_PRIMS) {
678 printf("%2u small prims/pixel ",
679 (unsigned)((1.0 / quad_size_in_pixels) *
680 (1.0 / quad_size_in_pixels) * 2));
681 } else {
682 printf("%3u%% %-16s", cull_percentage,
683 cull_method == BACK_FACE_CULLING ? "back faces" :
684 cull_method == VIEW_CULLING ? "culled by view" :
685 cull_method == DEGENERATE_PRIMS ? "degenerate prims" :
686 "(error)");
688 fflush(stdout);
690 for (unsigned prog = 0; prog < ARRAY_SIZE(progs); prog++) {
691 if (!progs[prog])
692 continue;
694 glUseProgram(progs[prog]);
696 if (prog)
697 printf(" ");
699 for (int i = 0; i < num_prim_sets; i++) {
700 double rate = run_test(0, draw_method, cull_method,
701 num_quads_per_dim[i],
702 quad_size_in_pixels, cull_percentage);
703 rate *= num_prims[i];
705 if (gpu_freq_mhz) {
706 rate /= gpu_freq_mhz * 1000000.0;
707 printf(",%6.3f", rate);
708 } else {
709 printf(",%6.3f", rate / 1000000000);
711 fflush(stdout);
714 printf("\n");
718 enum piglit_result
719 piglit_display(void)
721 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
723 /* for debugging */
724 if (getenv("ONE")) {
725 glUseProgram(progs[2]);
726 run_test(1, INDEXED_TRIANGLES_2VTX, BACK_FACE_CULLING, ceil(sqrt(0.5 * 512000)), 2, 50);
727 piglit_swap_buffers();
728 return PIGLIT_PASS;
731 const unsigned num_quads_per_dim[] = {
732 /* The second number is the approx. number of primitives. */
733 ceil(sqrt(0.5 * 2000)),
734 ceil(sqrt(0.5 * 8000)),
735 ceil(sqrt(0.5 * 32000)),
736 ceil(sqrt(0.5 * 128000)),
737 ceil(sqrt(0.5 * 512000)),
740 unsigned num_prims[ARRAY_SIZE(num_quads_per_dim)];
741 for (int i = 0; i < ARRAY_SIZE(num_quads_per_dim); i++)
742 num_prims[i] = num_quads_per_dim[i] * num_quads_per_dim[i] * 2;
744 printf(" Measuring %-27s, ", gpu_freq_mhz ? "Prims/clock," : "GPrims/second,");
745 for (unsigned prog = 0; prog < ARRAY_SIZE(progs); prog++) {
746 if (progs[prog])
747 printf("%u Varyings %27s", prog, " ");
749 printf("\n");
751 printf(" Draw Call , Cull Method ");
752 for (unsigned prog = 0; prog < ARRAY_SIZE(progs); prog++) {
753 if (!progs[prog])
754 continue;
755 if (prog)
756 printf(" ");
757 for (int i = 0; i < ARRAY_SIZE(num_prims); i++)
758 printf(", %3uK", num_prims[i] / 1000);
760 printf("\n");
762 for (int cull_method = 0; cull_method < RASTERIZER_DISCARD; cull_method++)
763 run(INDEXED_TRIANGLES, cull_method, num_quads_per_dim, num_prims, ARRAY_SIZE(num_prims));
764 for (int cull_method = 0; cull_method < RASTERIZER_DISCARD; cull_method++)
765 run(INDEXED_TRIANGLES_2VTX, cull_method, num_quads_per_dim, num_prims, ARRAY_SIZE(num_prims));
767 for (int cull_method = RASTERIZER_DISCARD; cull_method < NUM_CULL_METHODS; cull_method++)
768 run(INDEXED_TRIANGLES, cull_method, num_quads_per_dim, num_prims, ARRAY_SIZE(num_prims));
770 /* glDrawArrays: Only test NONE and BACK_FACE_CULLING. */
771 for (int draw_method = TRIANGLES; draw_method < NUM_DRAW_METHODS; draw_method++) {
772 for (int cull_method = 0; cull_method <= BACK_FACE_CULLING; cull_method++)
773 run(draw_method, cull_method, num_quads_per_dim, num_prims, ARRAY_SIZE(num_prims));
776 exit(0);
777 return PIGLIT_SKIP;