OLD | NEW |
(Empty) | |
| 1 // Copyright (c) 2010 The Chromium OS Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. |
| 4 |
| 5 #include <stdio.h> |
| 6 |
| 7 #include "testbase.h" |
| 8 |
| 9 namespace glbench { |
| 10 |
| 11 uint64_t TimeTest(TestBase* test, int iter) { |
| 12 SwapBuffers(); |
| 13 glFinish(); |
| 14 uint64_t time1 = GetUTime(); |
| 15 test->TestFunc(iter); |
| 16 glFinish(); |
| 17 uint64_t time2 = GetUTime(); |
| 18 return time2 - time1; |
| 19 } |
| 20 |
| 21 #define MAX_ITERATION_DURATION_MS 100000 |
| 22 |
| 23 // Benchmark some draw commands, by running it many times. |
| 24 // We want to measure the marginal cost, so we try more and more iterations |
| 25 // until we get a somewhat linear response (to eliminate constant cost), and we |
| 26 // do a linear regression on a few samples. |
| 27 bool Bench(TestBase* test, float *slope, int64_t *bias) { |
| 28 // Do one iteration in case the driver needs to set up states. |
| 29 if (TimeTest(test, 1) > MAX_ITERATION_DURATION_MS) |
| 30 return false; |
| 31 int64_t count = 0; |
| 32 int64_t sum_x = 0; |
| 33 int64_t sum_y = 0; |
| 34 int64_t sum_xy = 0; |
| 35 int64_t sum_x2 = 0; |
| 36 uint64_t last_time = 0; |
| 37 bool do_count = false; |
| 38 uint64_t iter; |
| 39 for (iter = 8; iter < 1<<30; iter *= 2) { |
| 40 uint64_t time = TimeTest(test, iter); |
| 41 if (last_time > 0 && (time > last_time * 1.8)) |
| 42 do_count = true; |
| 43 last_time = time; |
| 44 if (do_count) { |
| 45 ++count; |
| 46 sum_x += iter; |
| 47 sum_y += time; |
| 48 sum_xy += iter * time; |
| 49 sum_x2 += iter * iter; |
| 50 } |
| 51 if ((time >= 500000 && count > 4)) |
| 52 break; |
| 53 } |
| 54 if (count < 2) { |
| 55 *slope = 0.f; |
| 56 *bias = 0; |
| 57 } |
| 58 *slope = static_cast<float>(sum_x * sum_y - count * sum_xy) / |
| 59 (sum_x * sum_x - count * sum_x2); |
| 60 *bias = (sum_x * sum_xy - sum_x2 * sum_y) / (sum_x * sum_x - count * sum_x2); |
| 61 return true; |
| 62 } |
| 63 |
| 64 void RunTest(TestBase* test, const char *name, |
| 65 float coefficient, bool inverse) { |
| 66 float slope; |
| 67 int64_t bias; |
| 68 |
| 69 GLenum err = glGetError(); |
| 70 if (err != 0) { |
| 71 printf("# %s failed, glGetError returned 0x%x.\n", name, err); |
| 72 // float() in python will happily parse Nan. |
| 73 printf("%s: Nan\n", name); |
| 74 } else { |
| 75 if (Bench(test, &slope, &bias)) { |
| 76 printf("%s: %g\n", name, coefficient * (inverse ? 1.f / slope : slope)); |
| 77 } else { |
| 78 printf("# %s is too slow, returning zero.\n", name); |
| 79 printf("%s: 0\n", name); |
| 80 } |
| 81 } |
| 82 } |
| 83 |
| 84 bool DrawArraysTestFunc::TestFunc(int iter) { |
| 85 glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); |
| 86 glFlush(); |
| 87 for (int i = 0; i < iter-1; ++i) { |
| 88 glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); |
| 89 } |
| 90 return true; |
| 91 } |
| 92 |
| 93 |
| 94 void DrawArraysTestFunc::FillRateTestNormal(const char* name) { |
| 95 FillRateTestNormalSubWindow(name, g_width, g_height); |
| 96 } |
| 97 |
| 98 |
| 99 void DrawArraysTestFunc::FillRateTestNormalSubWindow(const char* name, |
| 100 float width, float height) |
| 101 { |
| 102 const int buffer_len = 64; |
| 103 char buffer[buffer_len]; |
| 104 snprintf(buffer, buffer_len, "mpixels_sec_%s", name); |
| 105 RunTest(this, buffer, width * height, true); |
| 106 } |
| 107 |
| 108 |
| 109 #ifndef USE_EGL |
| 110 void DrawArraysTestFunc::FillRateTestBlendDepth(const char *name) { |
| 111 const int buffer_len = 64; |
| 112 char buffer[buffer_len]; |
| 113 |
| 114 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); |
| 115 glEnable(GL_BLEND); |
| 116 snprintf(buffer, buffer_len, "mpixels_sec_%s_blended", name); |
| 117 RunTest(this, buffer, g_width * g_height, true); |
| 118 glDisable(GL_BLEND); |
| 119 |
| 120 glEnable(GL_DEPTH_TEST); |
| 121 glDepthFunc(GL_NOTEQUAL); |
| 122 snprintf(buffer, buffer_len, "mpixels_sec_%s_depth_neq", name); |
| 123 RunTest(this, buffer, g_width * g_height, true); |
| 124 glDepthFunc(GL_NEVER); |
| 125 snprintf(buffer, buffer_len, "mpixels_sec_%s_depth_never", name); |
| 126 RunTest(this, buffer, g_width * g_height, true); |
| 127 glDisable(GL_DEPTH_TEST); |
| 128 } |
| 129 #endif |
| 130 |
| 131 |
| 132 bool DrawElementsTestFunc::TestFunc(int iter) { |
| 133 glDrawElements(GL_TRIANGLES, count_, GL_UNSIGNED_INT, 0); |
| 134 glFlush(); |
| 135 for (int i = 0 ; i < iter-1; ++i) { |
| 136 glDrawElements(GL_TRIANGLES, count_, GL_UNSIGNED_INT, 0); |
| 137 } |
| 138 return true; |
| 139 } |
| 140 |
| 141 } // namespace glbench |
OLD | NEW |