2 * Copyright (C) 2018 Advanced Micro Devices, Inc.
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.
24 * Measure primitive rate under various circumstances.
28 * - rasterizer discard
31 * - degenerate primitives
32 * - subpixel primitives
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];
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"
69 " gl_Position = gl_Vertex; \n"
72 "#version 150 compatibility \n"
74 " gl_FragColor = vec4(1.0); \n"
77 progs
[1] = piglit_build_simple_program(
78 "#version 150 compatibility \n"
79 "varying vec4 v[1]; \n"
80 "attribute vec4 a[1]; \n"
82 " for (int i = 0; i < 1; i++) v[i] = a[i]; \n"
83 " gl_Position = gl_Vertex; \n"
86 "#version 150 compatibility \n"
87 "varying vec4 v[1]; \n"
89 " gl_FragColor = v[0]; \n"
92 progs
[2] = piglit_build_simple_program(
93 "#version 150 compatibility \n"
94 "varying vec4 v[2]; \n"
95 "attribute vec4 a[2]; \n"
97 " for (int i = 0; i < 2; i++) v[i] = a[i]; \n"
98 " gl_Position = gl_Vertex; \n"
101 "#version 150 compatibility \n"
102 "varying vec4 v[2]; \n"
104 " gl_FragColor = vec4(dot(v[0] * v[1], vec4(1.0)) == 1.0 ? 1.0 : 0.0); \n"
107 progs
[3] = piglit_build_simple_program(
108 "#version 150 compatibility \n"
109 "varying vec4 v[3]; \n"
110 "attribute vec4 a[3]; \n"
112 " for (int i = 0; i < 3; i++) v[i] = a[i]; \n"
113 " gl_Position = gl_Vertex; \n"
116 "#version 150 compatibility \n"
117 "varying vec4 v[3]; \n"
119 " gl_FragColor = vec4(dot(v[0] * v[1] * v[2], vec4(1.0)) == 1.0 ? 1.0 : 0.0); \n"
122 progs
[4] = piglit_build_simple_program(
123 "#version 150 compatibility \n"
124 "varying vec4 v[4]; \n"
125 "attribute vec4 a[4]; \n"
127 " for (int i = 0; i < 4; i++) v[i] = a[i]; \n"
128 " gl_Position = gl_Vertex; \n"
131 "#version 150 compatibility \n"
132 "varying vec4 v[4]; \n"
134 " gl_FragColor = vec4(dot(v[0] * v[1] * v[2] * v[3], vec4(1.0)) == 1.0 ? 1.0 : 0.0); \n"
137 progs
[6] = piglit_build_simple_program(
138 "#version 150 compatibility \n"
139 "varying vec4 v[6]; \n"
140 "attribute vec4 a[6]; \n"
142 " for (int i = 0; i < 6; i++) v[i] = a[i]; \n"
143 " gl_Position = gl_Vertex; \n"
146 "#version 150 compatibility \n"
147 "varying vec4 v[6]; \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"
152 progs
[8] = piglit_build_simple_program(
153 "#version 150 compatibility \n"
154 "varying vec4 v[8]; \n"
155 "attribute vec4 a[8]; \n"
157 " for (int i = 0; i < 8; i++) v[i] = a[i]; \n"
158 " gl_Position = gl_Vertex; \n"
161 "#version 150 compatibility \n"
162 "varying vec4 v[8]; \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"
167 glEnableClientState(GL_VERTEX_ARRAY
);
168 glEnable(GL_CULL_FACE
);
169 glPrimitiveRestartIndex(UINT32_MAX
);
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
++) {
191 if (cull_percentage
== 0)
193 else if (cull_percentage
== 25)
195 else if (cull_percentage
== 50)
197 else if (cull_percentage
== 75)
199 else if (cull_percentage
== 100)
202 assert(!"wrong cull_percentage");
204 for (unsigned tx
= 0; tx
< num_quads_per_dim
; tx
++) {
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;
221 unsigned elem
= *num_vertices
* 3;
223 /* generate horizontal stripes with maximum reuse */
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
;
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;
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];
301 unsigned elem
= *num_vertices
* 3;
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 */
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);
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
++) {
376 if (cull_percentage
== 0)
378 else if (cull_percentage
== 25)
380 else if (cull_percentage
== 50)
382 else if (cull_percentage
== 75)
384 else if (cull_percentage
== 100)
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;
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
);
423 if (cull
&& back_face_culling
) {
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
;
459 for (unsigned i
= 0; i
< *num_vertices
; i
++)
462 *num_indices
= *num_vertices
;
468 INDEXED_TRIANGLES_2VTX
, /* every triangle adds 2 new vertices and reuses 1 vertex */
471 INDEXED_TRIANGLE_STRIP
,
472 INDEXED_TRIANGLE_STRIP_PRIM_RESTART
,
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
;
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
,
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
,
499 (void*)(long)(ib_size
* duplicate_index
));
502 duplicate_index
= (duplicate_index
+ 1) % num_duplicates
;
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
,
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
);
549 gen_triangle_tile(num_quads_per_dim
, quad_size_in_pixels
,
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 */
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. */
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
);
587 glGenBuffers(1, &ib
);
588 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER
, ib
);
589 glBufferData(GL_ELEMENT_ARRAY_BUFFER
,
590 ib_size
* num_duplicates
, NULL
,
592 for (unsigned i
= 0; i
< num_duplicates
; i
++) {
593 glBufferSubData(GL_ELEMENT_ARRAY_BUFFER
, ib_size
* i
,
598 /* Make sure all uploads are finished. */
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
);
611 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER
, ib
);
613 global_draw_method
= draw_method
;
614 count
= indices
? num_indices
: num_vertices
;
619 if (debug_num_iterations
)
620 run_draw(debug_num_iterations
);
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
);
630 glDeleteBuffers(1, &vb
);
632 glDeleteBuffers(1, &ib
);
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
];
661 quad_size_in_pixels
= 2;
662 cull_percentage
= cull_percentages
[subtest
];
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" :
673 if (cull_method
== NONE
||
674 cull_method
== RASTERIZER_DISCARD
) {
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));
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" :
690 for (unsigned prog
= 0; prog
< ARRAY_SIZE(progs
); prog
++) {
694 glUseProgram(progs
[prog
]);
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
];
706 rate
/= gpu_freq_mhz
* 1000000.0;
707 printf(",%6.3f", rate
);
709 printf(",%6.3f", rate
/ 1000000000);
721 glClear(GL_COLOR_BUFFER_BIT
| GL_DEPTH_BUFFER_BIT
);
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();
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
++) {
747 printf("%u Varyings %27s", prog
, " ");
751 printf(" Draw Call , Cull Method ");
752 for (unsigned prog
= 0; prog
< ARRAY_SIZE(progs
); prog
++) {
757 for (int i
= 0; i
< ARRAY_SIZE(num_prims
); i
++)
758 printf(", %3uK", num_prims
[i
] / 1000);
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
));