easy-gl › Query
Query
Measures GPU statistics such as sample counts, primitives written, or elapsed time. Non-copyable, movable, RAII.
Common QueryTarget values
| Value | Measures |
|---|---|
QueryTarget::SamplesPassed | Fragments that pass depth/stencil (exact) |
QueryTarget::AnySamplesPassed | Whether any fragment passed (conservative, cheaper) |
QueryTarget::PrimitivesGenerated | Number of primitives generated |
QueryTarget::TransformFeedbackPrimitivesWritten | Primitives written by transform feedback |
QueryTarget::TimeElapsed | GPU time in nanoseconds for the bracketed commands |
QueryTarget::Timestamp | Current 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
| Method | Description |
|---|---|
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. |