easy-gl › Query

Query

Measures GPU statistics such as sample counts, primitives written, or elapsed time. Non-copyable, movable, RAII.

Common QueryTarget values

ValueMeasures
QueryTarget::SamplesPassedFragments that pass depth/stencil (exact)
QueryTarget::AnySamplesPassedWhether any fragment passed (conservative, cheaper)
QueryTarget::PrimitivesGeneratedNumber of primitives generated
QueryTarget::TransformFeedbackPrimitivesWrittenPrimitives written by transform feedback
QueryTarget::TimeElapsedGPU time in nanoseconds for the bracketed commands
QueryTarget::TimestampCurrent GPU timestamp

Occlusion query

easygl::Query occQuery;
occQuery.create();

occQuery.begin(easygl::QueryTarget::SamplesPassed);
device.draw_arrays(easygl::PrimitiveType::Triangles, 0, mesh.vertexCount);
occQuery.end(easygl::QueryTarget::SamplesPassed);

// Wait for result to be available (busy wait — in practice use latency buffering)
while (!occQuery.is_result_available()) { /* wait */ }

unsigned int sampleCount = occQuery.result();
std::cout << "Samples passed: " << sampleCount << '\n';

Conservative occlusion (cheaper)

occQuery.begin(easygl::QueryTarget::AnySamplesPassed);
// draw bounding box ...
occQuery.end(easygl::QueryTarget::AnySamplesPassed);

// Next frame: skip rendering if result is 0
if (occQuery.is_result_available() && occQuery.result() == 0) {
    // object was fully occluded last frame
}

GPU timing

easygl::Query timeQuery;
timeQuery.create();

timeQuery.begin(easygl::QueryTarget::TimeElapsed);
// ... render pass ...
timeQuery.end(easygl::QueryTarget::TimeElapsed);

while (!timeQuery.is_result_available()) {}
unsigned int nanoseconds = timeQuery.result();
std::cout << "GPU time: " << nanoseconds / 1e6 << " ms\n";
For accurate GPU timing, use double-buffered queries to avoid stalling the CPU. Query the previous frame's result while submitting the current frame.

Method reference

MethodDescription
create()Allocate GL query handle.
destroy()Free handle. Noexcept.
begin(target)Start the query for the given target.
end(target)End the query.
is_result_available()True when the GPU has completed the query.
result()Retrieve the query result (blocks until available).
is_created()True if GL handle allocated.
native_handle()Raw GL integer ID.
reset_handle_no_gl()Context-loss recovery.