Browse Source

Added GPU time benchmarking to OpenGLTester.

pull/193/head
Vladimír Vondruš 9 years ago
parent
commit
a0eeecba4a
  1. 14
      src/Magnum/OpenGLTester.cpp
  2. 105
      src/Magnum/OpenGLTester.h

14
src/Magnum/OpenGLTester.cpp

@ -53,4 +53,18 @@ OpenGLTester::OpenGLTester(): TestSuite::Tester{TestSuite::Tester::TesterConfigu
OpenGLTester::~OpenGLTester() = default;
void OpenGLTester::gpuTimeBenchmarkBegin() {
setBenchmarkName("GPU time");
/* Initialize, if not already */
if(!_gpuTimeQuery.id()) _gpuTimeQuery = TimeQuery{TimeQuery::Target::TimeElapsed};
_gpuTimeQuery.begin();
}
std::uint64_t OpenGLTester::gpuTimeBenchmarkEnd() {
_gpuTimeQuery.end();
return _gpuTimeQuery.result<UnsignedLong>();
}
}

105
src/Magnum/OpenGLTester.h

@ -32,6 +32,7 @@
#include <Corrade/TestSuite/Tester.h>
#include "Magnum/Renderer.h"
#include "Magnum/TimeQuery.h"
#ifdef MAGNUM_TARGET_HEADLESS
#include "Magnum/Platform/WindowlessEglApplication.h"
@ -95,9 +96,56 @@ output. While it is possible, the tester class doesn't abort the test cases
upon encountering a GL error -- this should be done explicitly with
@ref MAGNUM_VERIFY_NO_ERROR() instead, as the debug output is not available on
all platforms and not all GL errors are fatal.
## GPU time benchmarks
This class adds @ref BenchmarkType::GpuTime to the benchmark type enum,
allowing you to measure time spent on GPU as opposed to CPU or wall clock time.
*/
class OpenGLTester: public TestSuite::Tester {
public:
/**
* @brief Benchmark type
*
* Extends @ref Corrade::TestSuite::Tester::BenchmarkType with GPU
* benchmark types.
* @see @ref addBenchmarks(), @ref addInstancedBenchmarks()
*/
enum class BenchmarkType {
/**
* See @ref Corrade::TestSuite::Tester::BenchmarkType::Default for
* details.
*/
Default = Int(Tester::BenchmarkType::Default),
/**
* See @ref Corrade::TestSuite::Tester::BenchmarkType::WallTime for
* details.
*/
WallTime = Int(Tester::BenchmarkType::WallTime),
/**
* See @ref Corrade::TestSuite::Tester::BenchmarkType::CpuTime for
* details.
*/
CpuTime = Int(Tester::BenchmarkType::CpuTime),
/**
* See @ref Corrade::TestSuite::Tester::BenchmarkType::CpuCycles
* for details.
*/
CpuCycles = Int(Tester::BenchmarkType::CpuCycles),
/**
* GPU time, measured using @ref TimeQuery::Target::TimeElapsed.
* Note that the result of the query is retrieved synchronously and
* thus may cause pipeline bubble. Increase number of iterations
* passed to @ref CORRADE_BENCHMARK() to amortize the measurement
* error.
*/
GpuTime = 32
};
/**
* @brief Constructor
*
@ -107,7 +155,62 @@ class OpenGLTester: public TestSuite::Tester {
~OpenGLTester();
/**
* @brief Add benchmarks
*
* Extends @ref Corrade::TestSuite::Tester::addBenchmarks(std::initializer_list<void(Derived::*)()>, std::size_t, BenchmarkType) with support
* for GPU benchmark types.
*/
template<class Derived> void addBenchmarks(std::initializer_list<void(Derived::*)()> benchmarks, std::size_t batchCount, BenchmarkType benchmarkType = BenchmarkType::Default) {
if(benchmarkType == BenchmarkType::GpuTime)
addCustomBenchmarks<Derived>(benchmarks, batchCount, &OpenGLTester::gpuTimeBenchmarkBegin, &OpenGLTester::gpuTimeBenchmarkEnd, BenchmarkUnits::Nanoseconds);
else
Tester::addBenchmarks(benchmarks, batchCount, Tester::BenchmarkType(Int(benchmarkType)));
}
/**
* @brief Add benchmarks with explicit setup and teardown functions
*
* Extends @ref Corrade::TestSuite::Tester::addBenchmarks(std::initializer_list<void(Derived::*)()>, std::size_t, void(Derived::*)(), void(Derived::*)(), BenchmarkType) with support
* for GPU benchmark types.
*/
template<class Derived> void addBenchmarks(std::initializer_list<void(Derived::*)()> benchmarks, std::size_t batchCount, void(Derived::*setup)(), void(Derived::*teardown)(), BenchmarkType benchmarkType = BenchmarkType::Default) {
if(benchmarkType == BenchmarkType::GpuTime)
addCustomBenchmarks<Derived>(benchmarks, batchCount, &OpenGLTester::gpuTimeBenchmarkBegin, &OpenGLTester::gpuTimeBenchmarkEnd, setup, teardown, BenchmarkUnits::Nanoseconds);
else
Tester::addBenchmarks(benchmarks, batchCount, setup, teardown, Tester::BenchmarkType(Int(benchmarkType)));
}
/**
* @brief Add instanced benchmarks
*
* Extends @ref Corrade::TestSuite::Tester::addInstancedBenchmarks(std::initializer_list<void(Derived::*)()>, std::size_t, std::size_t, BenchmarkType) with support for GPU
* benchmark types.
*/
template<class Derived> void addInstancedBenchmarks(std::initializer_list<void(Derived::*)()> benchmarks, std::size_t batchCount, std::size_t instanceCount, BenchmarkType benchmarkType = BenchmarkType::Default) {
if(benchmarkType == BenchmarkType::GpuTime)
addCustomInstancedBenchmarks<Derived>(benchmarks, batchCount, instanceCount, &OpenGLTester::gpuTimeBenchmarkBegin, &OpenGLTester::gpuTimeBenchmarkEnd, BenchmarkUnits::Nanoseconds);
else
Tester::addInstancedBenchmarks(benchmarks, batchCount, instanceCount, Tester::BenchmarkType(Int(benchmarkType)));
}
/**
* @brief Add instanced benchmarks with explicit setup and teardown functions
*
* Extends @ref Corrade::TestSuite::Tester::addInstancedBenchmarks(std::initializer_list<void(Derived::*)()>, std::size_t, std::size_t, void(Derived::*)(), void(Derived::*)(), BenchmarkType)
* with support for GPU benchmark types.
*/
template<class Derived> void addInstancedBenchmarks(std::initializer_list<void(Derived::*)()> benchmarks, std::size_t batchCount, std::size_t instanceCount, void(Derived::*setup)(), void(Derived::*teardown)(), BenchmarkType benchmarkType = BenchmarkType::Default) {
if(benchmarkType == BenchmarkType::GpuTime)
addCustomInstancedBenchmarks<Derived>(benchmarks, batchCount, instanceCount, &OpenGLTester::gpuTimeBenchmarkBegin, &OpenGLTester::gpuTimeBenchmarkEnd, setup, teardown, BenchmarkUnits::Nanoseconds);
else
Tester::addInstancedBenchmarks(benchmarks, batchCount, instanceCount, setup, teardown, Tester::BenchmarkType(Int(benchmarkType)));
}
private:
void gpuTimeBenchmarkBegin();
std::uint64_t gpuTimeBenchmarkEnd();
struct WindowlessApplication: Platform::WindowlessApplication {
explicit WindowlessApplication(const Arguments& arguments): Platform::WindowlessApplication{arguments, NoCreate} {}
int exec() override final { return 0; }
@ -116,6 +219,8 @@ class OpenGLTester: public TestSuite::Tester {
using Platform::WindowlessApplication::createContext;
} _windowlessApplication;
TimeQuery _gpuTimeQuery{NoCreate};
};
/** @hideinitializer

Loading…
Cancel
Save