19f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev// Copyright (c) 2010 The Chromium OS Authors. All rights reserved.
29f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev// Use of this source code is governed by a BSD-style license that can be
39f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev// found in the LICENSE file.
49f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev
5f50ecb1b44db52db39768f55a03280e1fd8eeac7Alexey Marinichev#include <gflags/gflags.h>
68faad30e5a44271d9e50c4d75e1271018d7439b5Ilja H. Friedel#include <png.h>
78d7913bdbed2083caa203aa497bc6d99342a1406Ilja H. Friedel#include <stdio.h>
88d7913bdbed2083caa203aa497bc6d99342a1406Ilja H. Friedel#include <unistd.h>
99f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev
10c9faddb4a9c94f7ec477fea7f32ce9c4fa34c8d0Ben Chan#include <memory>
11c9faddb4a9c94f7ec477fea7f32ce9c4fa34c8d0Ben Chan
126c04ea4a0f108b126378c3bb09707389714aa0a3Alex Vakulenko#include <base/files/file_util.h>
13f50ecb1b44db52db39768f55a03280e1fd8eeac7Alexey Marinichev
147f840e726dd0455d4ef338de4de89adcf2118534Simon Que#include "glinterface.h"
158faad30e5a44271d9e50c4d75e1271018d7439b5Ilja H. Friedel#include "md5.h"
167f840e726dd0455d4ef338de4de89adcf2118534Simon Que#include "png_helper.h"
179f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev#include "testbase.h"
18f50ecb1b44db52db39768f55a03280e1fd8eeac7Alexey Marinichev#include "utils.h"
19f50ecb1b44db52db39768f55a03280e1fd8eeac7Alexey Marinichev
203907fd1607fdc5ae5065adad80b35c7733fbbf7aIlja Friedelextern bool g_hasty;
218290ac901296cbf692df417412ae3546cbcce0a4Daniel Kurtzextern bool g_notemp;
223907fd1607fdc5ae5065adad80b35c7733fbbf7aIlja Friedel
23f50ecb1b44db52db39768f55a03280e1fd8eeac7Alexey MarinichevDEFINE_bool(save, false, "save images after each test case");
248faad30e5a44271d9e50c4d75e1271018d7439b5Ilja H. FriedelDEFINE_string(outdir, "", "directory to save images");
259f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev
269f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichevnamespace glbench {
279f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev
28439ea14b8019a05cd4d3f038b4d32bca1d3fe5dcIlja H. Friedeluint64_t TimeTest(TestBase* test, uint64_t iterations) {
297f840e726dd0455d4ef338de4de89adcf2118534Simon Que    g_main_gl_interface->SwapBuffers();
308faad30e5a44271d9e50c4d75e1271018d7439b5Ilja H. Friedel    glFinish();
318faad30e5a44271d9e50c4d75e1271018d7439b5Ilja H. Friedel    uint64_t time1 = GetUTime();
32439ea14b8019a05cd4d3f038b4d32bca1d3fe5dcIlja H. Friedel    if (!test->TestFunc(iterations))
338faad30e5a44271d9e50c4d75e1271018d7439b5Ilja H. Friedel        return ~0;
348faad30e5a44271d9e50c4d75e1271018d7439b5Ilja H. Friedel    glFinish();
358faad30e5a44271d9e50c4d75e1271018d7439b5Ilja H. Friedel    uint64_t time2 = GetUTime();
368faad30e5a44271d9e50c4d75e1271018d7439b5Ilja H. Friedel    return time2 - time1;
379f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev}
389f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev
398d7913bdbed2083caa203aa497bc6d99342a1406Ilja H. Friedel// Target minimum iteration duration of 1s. This means the final/longest
408d7913bdbed2083caa203aa497bc6d99342a1406Ilja H. Friedel// iteration is between 1s and 2s and the machine is active for 2s to 4s.
413b4712cc3f0a77cfa7851fb73fb03fcb0c4e6318Ilja Friedel// Notice as of March 2014 the BVT suite has a hard limit per job of 20 minutes.
428d7913bdbed2083caa203aa497bc6d99342a1406Ilja H. Friedel#define MIN_ITERATION_DURATION_US 1000000
439f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev
44f899c0b4f6cb7468ff6e98941e0ef4512cc2d06aDaniel Kurtz#define MAX_TESTNAME 45
45f899c0b4f6cb7468ff6e98941e0ef4512cc2d06aDaniel Kurtz
468d7913bdbed2083caa203aa497bc6d99342a1406Ilja H. Friedel// Benchmark some draw commands, by running it many times. We want to measure
478d7913bdbed2083caa203aa497bc6d99342a1406Ilja H. Friedel// the marginal cost, so we try more and more iterations until we reach the
488d7913bdbed2083caa203aa497bc6d99342a1406Ilja H. Friedel// minimum specified iteration time.
49439ea14b8019a05cd4d3f038b4d32bca1d3fe5dcIlja H. Friedeldouble Bench(TestBase* test) {
503b4712cc3f0a77cfa7851fb73fb03fcb0c4e6318Ilja Friedel  // Try to wait a bit to let machine cool down for next test. We allow for a
513b4712cc3f0a77cfa7851fb73fb03fcb0c4e6318Ilja Friedel  // bit of hysteresis as it might take too long to do a perfect job, which is
523b4712cc3f0a77cfa7851fb73fb03fcb0c4e6318Ilja Friedel  // probably not required. But these parameters could be tuned.
533b4712cc3f0a77cfa7851fb73fb03fcb0c4e6318Ilja Friedel  double initial_temperature = GetInitialMachineTemperature();
545e738bc5151db76ba00fc2ad9712b0cfe3a7aee6Ilja H. Friedel  double cooldown_temperature = std::max(45.0, initial_temperature + 6.0);
553b4712cc3f0a77cfa7851fb73fb03fcb0c4e6318Ilja Friedel  double temperature = 0;
563907fd1607fdc5ae5065adad80b35c7733fbbf7aIlja Friedel  double wait = 0;
573907fd1607fdc5ae5065adad80b35c7733fbbf7aIlja Friedel
585e738bc5151db76ba00fc2ad9712b0cfe3a7aee6Ilja H. Friedel  // By default we try to cool to initial + 6'C (don't bother below 45'C), but
595e738bc5151db76ba00fc2ad9712b0cfe3a7aee6Ilja H. Friedel  // don't wait longer than 30s. In hasty mode we really don't want to spend
605e738bc5151db76ba00fc2ad9712b0cfe3a7aee6Ilja H. Friedel  // too much time to get the numbers right, so we don't wait at all.
618290ac901296cbf692df417412ae3546cbcce0a4Daniel Kurtz  if (!::g_notemp) {
625e738bc5151db76ba00fc2ad9712b0cfe3a7aee6Ilja H. Friedel    wait = WaitForCoolMachine(cooldown_temperature, 30.0, &temperature);
633907fd1607fdc5ae5065adad80b35c7733fbbf7aIlja Friedel    printf("Bench: Cooled down to %.1f'C (initial=%.1f'C) after waiting %.1fs.\n",
643907fd1607fdc5ae5065adad80b35c7733fbbf7aIlja Friedel           temperature, initial_temperature, wait);
655e738bc5151db76ba00fc2ad9712b0cfe3a7aee6Ilja H. Friedel    if (temperature > cooldown_temperature + 5.0)
663907fd1607fdc5ae5065adad80b35c7733fbbf7aIlja Friedel      printf("Warning: Machine did not cool down enough for next test!");
673907fd1607fdc5ae5065adad80b35c7733fbbf7aIlja Friedel  }
688d7913bdbed2083caa203aa497bc6d99342a1406Ilja H. Friedel
69dd29ce1cf6d57858a2b06fdec627abc39030ab81Stuart Abercrombie  // Do two iterations because initial timings can vary wildly.
70439ea14b8019a05cd4d3f038b4d32bca1d3fe5dcIlja H. Friedel  TimeTest(test, 2);
71439ea14b8019a05cd4d3f038b4d32bca1d3fe5dcIlja H. Friedel
72439ea14b8019a05cd4d3f038b4d32bca1d3fe5dcIlja H. Friedel  // We average the times for the last two runs to reduce noise. We could
73439ea14b8019a05cd4d3f038b4d32bca1d3fe5dcIlja H. Friedel  // sum up all runs but the initial measurements have high CPU overhead,
74439ea14b8019a05cd4d3f038b4d32bca1d3fe5dcIlja H. Friedel  // while the last two runs are both on the order of MIN_ITERATION_DURATION_US.
75439ea14b8019a05cd4d3f038b4d32bca1d3fe5dcIlja H. Friedel  uint64_t iterations = 1;
76439ea14b8019a05cd4d3f038b4d32bca1d3fe5dcIlja H. Friedel  uint64_t iterations_prev = 0;
77439ea14b8019a05cd4d3f038b4d32bca1d3fe5dcIlja H. Friedel  uint64_t time = 0;
78439ea14b8019a05cd4d3f038b4d32bca1d3fe5dcIlja H. Friedel  uint64_t time_prev = 0;
79439ea14b8019a05cd4d3f038b4d32bca1d3fe5dcIlja H. Friedel  do {
80439ea14b8019a05cd4d3f038b4d32bca1d3fe5dcIlja H. Friedel    time = TimeTest(test, iterations);
8188959fb037a4a7a8864a671f014b09b0148095fcDaniel Kurtz    dbg_printf("iterations: %llu: time: %llu time/iter: %llu\n",
8288959fb037a4a7a8864a671f014b09b0148095fcDaniel Kurtz           iterations, time, time / iterations);
8388959fb037a4a7a8864a671f014b09b0148095fcDaniel Kurtz
843907fd1607fdc5ae5065adad80b35c7733fbbf7aIlja Friedel    // If we are running in hasty mode we will stop after a fraction of the
853907fd1607fdc5ae5065adad80b35c7733fbbf7aIlja Friedel    // testing time and return much more noisy performance numbers. The MD5s
863907fd1607fdc5ae5065adad80b35c7733fbbf7aIlja Friedel    // of the images should stay the same though.
873907fd1607fdc5ae5065adad80b35c7733fbbf7aIlja Friedel    if (time > MIN_ITERATION_DURATION_US / (::g_hasty ? 20.0 : 1.0))
88439ea14b8019a05cd4d3f038b4d32bca1d3fe5dcIlja H. Friedel      return (static_cast<double>(time + time_prev) /
89439ea14b8019a05cd4d3f038b4d32bca1d3fe5dcIlja H. Friedel              (iterations + iterations_prev));
906f72b2bf8d333b52f6808bcc0f1e43239de26fedIlja Friedel
91439ea14b8019a05cd4d3f038b4d32bca1d3fe5dcIlja H. Friedel    time_prev = time;
92439ea14b8019a05cd4d3f038b4d32bca1d3fe5dcIlja H. Friedel    iterations_prev = iterations;
93439ea14b8019a05cd4d3f038b4d32bca1d3fe5dcIlja H. Friedel    iterations *= 2;
94439ea14b8019a05cd4d3f038b4d32bca1d3fe5dcIlja H. Friedel  } while (iterations < (1ULL<<40));
95439ea14b8019a05cd4d3f038b4d32bca1d3fe5dcIlja H. Friedel
96439ea14b8019a05cd4d3f038b4d32bca1d3fe5dcIlja H. Friedel  return 0.0;
979f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev}
989f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev
993907fd1607fdc5ae5065adad80b35c7733fbbf7aIlja Friedelvoid SaveImage(const char* name, const int width, const int height) {
1003907fd1607fdc5ae5065adad80b35c7733fbbf7aIlja Friedel  const int size = width * height * 4;
101c9faddb4a9c94f7ec477fea7f32ce9c4fa34c8d0Ben Chan  std::unique_ptr<char[]> pixels(new char[size]);
1023907fd1607fdc5ae5065adad80b35c7733fbbf7aIlja Friedel  glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, pixels.get());
1038faad30e5a44271d9e50c4d75e1271018d7439b5Ilja H. Friedel  // I really think we want to use outdir as a straight argument
1043bbf4f178422d0a234a8ac0d090f691ff6344765Ben Chan  base::FilePath dirname = base::FilePath(FLAGS_outdir);
1053bbf4f178422d0a234a8ac0d090f691ff6344765Ben Chan  base::CreateDirectory(dirname);
1063bbf4f178422d0a234a8ac0d090f691ff6344765Ben Chan  base::FilePath filename = dirname.Append(name);
1078faad30e5a44271d9e50c4d75e1271018d7439b5Ilja H. Friedel  write_png_file(filename.value().c_str(),
1083907fd1607fdc5ae5065adad80b35c7733fbbf7aIlja Friedel                 pixels.get(), width, height);
1098faad30e5a44271d9e50c4d75e1271018d7439b5Ilja H. Friedel}
1108faad30e5a44271d9e50c4d75e1271018d7439b5Ilja H. Friedel
1113907fd1607fdc5ae5065adad80b35c7733fbbf7aIlja Friedelvoid ComputeMD5(unsigned char digest[16], const int width, const int height) {
1128faad30e5a44271d9e50c4d75e1271018d7439b5Ilja H. Friedel  MD5Context ctx;
1138faad30e5a44271d9e50c4d75e1271018d7439b5Ilja H. Friedel  MD5Init(&ctx);
1143907fd1607fdc5ae5065adad80b35c7733fbbf7aIlja Friedel  const int size = width * height * 4;
115c9faddb4a9c94f7ec477fea7f32ce9c4fa34c8d0Ben Chan  std::unique_ptr<char[]> pixels(new char[size]);
1163907fd1607fdc5ae5065adad80b35c7733fbbf7aIlja Friedel  glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, pixels.get());
1173907fd1607fdc5ae5065adad80b35c7733fbbf7aIlja Friedel  MD5Update(&ctx, (unsigned char *)pixels.get(), size);
1188faad30e5a44271d9e50c4d75e1271018d7439b5Ilja H. Friedel  MD5Final(digest, &ctx);
119f50ecb1b44db52db39768f55a03280e1fd8eeac7Alexey Marinichev}
120f50ecb1b44db52db39768f55a03280e1fd8eeac7Alexey Marinichev
1213907fd1607fdc5ae5065adad80b35c7733fbbf7aIlja Friedelvoid RunTest(TestBase* test, const char* testname, const double coefficient,
1223907fd1607fdc5ae5065adad80b35c7733fbbf7aIlja Friedel             const int width, const int height, bool inverse) {
123439ea14b8019a05cd4d3f038b4d32bca1d3fe5dcIlja H. Friedel  double value;
1247dee336595720f67f2312db842667bcb238e4869Daniel Kurtz  char name_png[512] = "";
1258faad30e5a44271d9e50c4d75e1271018d7439b5Ilja H. Friedel  GLenum error = glGetError();
1267dee336595720f67f2312db842667bcb238e4869Daniel Kurtz
1277dee336595720f67f2312db842667bcb238e4869Daniel Kurtz  if (error != GL_NO_ERROR) {
1287dee336595720f67f2312db842667bcb238e4869Daniel Kurtz    value = -1.0;
1297dee336595720f67f2312db842667bcb238e4869Daniel Kurtz    printf("# Error: %s aborted, glGetError returned 0x%02x.\n",
1307dee336595720f67f2312db842667bcb238e4869Daniel Kurtz           testname, error);
1317dee336595720f67f2312db842667bcb238e4869Daniel Kurtz    sprintf(name_png, "glGetError=0x%02x", error);
1327dee336595720f67f2312db842667bcb238e4869Daniel Kurtz  } else {
133439ea14b8019a05cd4d3f038b4d32bca1d3fe5dcIlja H. Friedel    value = Bench(test);
1347dee336595720f67f2312db842667bcb238e4869Daniel Kurtz
1357dee336595720f67f2312db842667bcb238e4869Daniel Kurtz    // Bench returns 0.0 if it ran max iterations in less than a min test time.
1367dee336595720f67f2312db842667bcb238e4869Daniel Kurtz    if (value == 0.0) {
1377dee336595720f67f2312db842667bcb238e4869Daniel Kurtz      strcpy(name_png, "no_score");
1387dee336595720f67f2312db842667bcb238e4869Daniel Kurtz    } else {
1397dee336595720f67f2312db842667bcb238e4869Daniel Kurtz      value = coefficient * (inverse ? 1.0 / value : value);
1407dee336595720f67f2312db842667bcb238e4869Daniel Kurtz
1417dee336595720f67f2312db842667bcb238e4869Daniel Kurtz      if (!test->IsDrawTest()) {
1427dee336595720f67f2312db842667bcb238e4869Daniel Kurtz        strcpy(name_png, "none");
1437dee336595720f67f2312db842667bcb238e4869Daniel Kurtz      } else {
1447dee336595720f67f2312db842667bcb238e4869Daniel Kurtz        // save as png with MD5 as hex string attached
1457dee336595720f67f2312db842667bcb238e4869Daniel Kurtz        char          pixmd5[33];
1467dee336595720f67f2312db842667bcb238e4869Daniel Kurtz        unsigned char d[16];
1477dee336595720f67f2312db842667bcb238e4869Daniel Kurtz        ComputeMD5(d, width, height);
1487dee336595720f67f2312db842667bcb238e4869Daniel Kurtz        // translate to hexadecimal ASCII of MD5
1497dee336595720f67f2312db842667bcb238e4869Daniel Kurtz        sprintf(pixmd5,
1507dee336595720f67f2312db842667bcb238e4869Daniel Kurtz          "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x",
1517dee336595720f67f2312db842667bcb238e4869Daniel Kurtz          d[ 0],d[ 1],d[ 2],d[ 3],d[ 4],d[ 5],d[ 6],d[ 7],
1527dee336595720f67f2312db842667bcb238e4869Daniel Kurtz          d[ 8],d[ 9],d[10],d[11],d[12],d[13],d[14],d[15]);
153be252420861fb14d6a79a4767c8a75a852643fc5Daniel Kurtz        sprintf(name_png, "%s.pixmd5-%s.png", testname, pixmd5);
1547dee336595720f67f2312db842667bcb238e4869Daniel Kurtz
1557dee336595720f67f2312db842667bcb238e4869Daniel Kurtz        if (FLAGS_save)
1567dee336595720f67f2312db842667bcb238e4869Daniel Kurtz          SaveImage(name_png, width, height);
1577dee336595720f67f2312db842667bcb238e4869Daniel Kurtz      }
158bcad4fb80e1115af4aad4558d93be6dabf7a3f26Daniel Kurtz    }
1597dee336595720f67f2312db842667bcb238e4869Daniel Kurtz  }
160439ea14b8019a05cd4d3f038b4d32bca1d3fe5dcIlja H. Friedel
1617dee336595720f67f2312db842667bcb238e4869Daniel Kurtz  // TODO(ihf) adjust string length based on longest test name
162aace01b7d49e41d1bd26be3767305f57e036e0d7Daniel Kurtz  int name_length = strlen(testname);
163b722be2b3770034fe8749ab56449eef7dddde8d1Daniel Kurtz  if (name_length > MAX_TESTNAME)
1647dee336595720f67f2312db842667bcb238e4869Daniel Kurtz    printf("# Warning: adjust string formatting to length = %d\n",
165b722be2b3770034fe8749ab56449eef7dddde8d1Daniel Kurtz           name_length);
1667dee336595720f67f2312db842667bcb238e4869Daniel Kurtz  // Results are marked using a leading '@RESULT: ' to allow parsing.
167b722be2b3770034fe8749ab56449eef7dddde8d1Daniel Kurtz  printf("@RESULT: %-*s = %10.2f %-15s [%s]\n",
168b722be2b3770034fe8749ab56449eef7dddde8d1Daniel Kurtz         MAX_TESTNAME, testname, value, test->Unit(), name_png);
1699f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev}
1709f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev
171439ea14b8019a05cd4d3f038b4d32bca1d3fe5dcIlja H. Friedelbool DrawArraysTestFunc::TestFunc(uint64_t iterations) {
172d5dfe5f92baa50ad3cf6a7381af6a73e11901740Stuart Abercrombie  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
1739f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev  glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
1749f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev  glFlush();
175439ea14b8019a05cd4d3f038b4d32bca1d3fe5dcIlja H. Friedel  for (uint64_t i = 0; i < iterations - 1; ++i) {
1769f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev    glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
1779f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev  }
1789f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev  return true;
1799f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev}
1809f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev
1819f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev
1829f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichevvoid DrawArraysTestFunc::FillRateTestNormal(const char* name) {
1839f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev  FillRateTestNormalSubWindow(name, g_width, g_height);
1849f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev}
1859f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev
1869f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev
1879f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichevvoid DrawArraysTestFunc::FillRateTestNormalSubWindow(const char* name,
1883907fd1607fdc5ae5065adad80b35c7733fbbf7aIlja Friedel                                                     const int width,
1893907fd1607fdc5ae5065adad80b35c7733fbbf7aIlja Friedel                                                     const int height)
1909f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev{
191aace01b7d49e41d1bd26be3767305f57e036e0d7Daniel Kurtz  RunTest(this, name, width * height, width, height, true);
1929f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev}
1939f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev
1949f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev
1959f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichevvoid DrawArraysTestFunc::FillRateTestBlendDepth(const char *name) {
1969f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev  const int buffer_len = 64;
1979f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev  char buffer[buffer_len];
1989f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev
1999f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev  glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
2009f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev  glEnable(GL_BLEND);
201aace01b7d49e41d1bd26be3767305f57e036e0d7Daniel Kurtz  snprintf(buffer, buffer_len, "%s_blended", name);
2023907fd1607fdc5ae5065adad80b35c7733fbbf7aIlja Friedel  RunTest(this, buffer, g_width * g_height, g_width, g_height, true);
2039f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev  glDisable(GL_BLEND);
2049f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev
205d5dfe5f92baa50ad3cf6a7381af6a73e11901740Stuart Abercrombie  // We are relying on the default depth clear value of 1 here.
206d5dfe5f92baa50ad3cf6a7381af6a73e11901740Stuart Abercrombie  // Fragments should have depth 0.
2079f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev  glEnable(GL_DEPTH_TEST);
2089f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev  glDepthFunc(GL_NOTEQUAL);
209aace01b7d49e41d1bd26be3767305f57e036e0d7Daniel Kurtz  snprintf(buffer, buffer_len, "%s_depth_neq", name);
2103907fd1607fdc5ae5065adad80b35c7733fbbf7aIlja Friedel  RunTest(this, buffer, g_width * g_height, g_width, g_height, true);
211d5dfe5f92baa50ad3cf6a7381af6a73e11901740Stuart Abercrombie
212d5dfe5f92baa50ad3cf6a7381af6a73e11901740Stuart Abercrombie  // The DrawArrays call invoked by this test shouldn't render anything
213d5dfe5f92baa50ad3cf6a7381af6a73e11901740Stuart Abercrombie  // because every fragment will fail the depth test.  Therefore we
214d5dfe5f92baa50ad3cf6a7381af6a73e11901740Stuart Abercrombie  // should see the clear color.
2159f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev  glDepthFunc(GL_NEVER);
216aace01b7d49e41d1bd26be3767305f57e036e0d7Daniel Kurtz  snprintf(buffer, buffer_len, "%s_depth_never", name);
2173907fd1607fdc5ae5065adad80b35c7733fbbf7aIlja Friedel  RunTest(this, buffer, g_width * g_height, g_width, g_height, true);
2189f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev  glDisable(GL_DEPTH_TEST);
2199f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev}
2209f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev
2219f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev
222439ea14b8019a05cd4d3f038b4d32bca1d3fe5dcIlja H. Friedelbool DrawElementsTestFunc::TestFunc(uint64_t iterations) {
223a1a86cbb14725f46b095671263c04289935bc8e7Kenneth Waters  glClearColor(0, 1.f, 0, 1.f);
224a1a86cbb14725f46b095671263c04289935bc8e7Kenneth Waters  glClear(GL_COLOR_BUFFER_BIT);
225c33878b0587a1b46090e7249a87d32e7f88ed9aeStuart Abercrombie  glDrawElements(GL_TRIANGLES, count_, GL_UNSIGNED_SHORT, 0);
2269f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev  glFlush();
227439ea14b8019a05cd4d3f038b4d32bca1d3fe5dcIlja H. Friedel  for (uint64_t i = 0 ; i < iterations - 1; ++i) {
228c33878b0587a1b46090e7249a87d32e7f88ed9aeStuart Abercrombie    glDrawElements(GL_TRIANGLES, count_, GL_UNSIGNED_SHORT, 0);
2299f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev  }
2309f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev  return true;
2319f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev}
2329f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev
2339f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev} // namespace glbench
234