11
\$\begingroup\$

I'd like to know how I can check to see if either my vertex or my fragment shader is a bottleneck in my rendering pipeline.

I've read about using glQueryCounter with the GL_TIMESTAMP target to get clock checkpoints between OpenGL commands, but these don't distinguish between different types of shaders.

For example, if one frame on the GPU took 8 ms to render, can I tell that the vertex shader took 7 ms and the fragment shader took 1 ms?

\$\endgroup\$
12
\$\begingroup\$

Vertex and fragment shaders run concurrently, not sequentially, and the GPU automatically load-balances between them, so it's not possible to meaningfully assign specific timings like 7 ms for one and 1 ms for the other.

However, you can do a simple experiment to measure where the bottleneck lies: set the view-projection matrix to all zeros for all your draw calls. This makes all vertices output zero for their positions and makes all triangles degenerate; it therefore short-circuits all rasterization and fragment shading, while keeping all the vertex shader work (the shader compiler can't optimize anything away, since it doesn't know the matrix will be set to zero at runtime).

When you measure performance with the matrices zeroed, you'll be seeing the amount of time needed to run just the vertex shaders, without any concurrent rasterization or fragment shading work in the GPU. You can then compare this to the amount of time needed for ordinary rendering for each pass. If the two times are similar, the pass is probably highly vertex-bound; if the zeroed-matrix rendering is significantly faster, it's probably pixel-bound. It's also possible to get an intermediate result, indicating that the work is split about evenly between the two.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.