5
\$\begingroup\$

I have an OpenGL code, with 3 different shader programs. I have a simple question, I know fragment shaders are executed for every every fragment in the scene. But is there a way using which we can find how many fragments are there in the scene? Correct me if i am wrong, but the fragment shader is executed for each fragments, so

Number of fragments = number of times fragment shader executed?

\$\endgroup\$
8
\$\begingroup\$

To answer your question let's look at how the typical OpenGL pipline works.

Vertex Shader -> Geometry Shader (Optional) -> Clipping -> Rasterization -> Pixel Shader ---------------> Fragments Merge.

I want to stress the fact that one pixel is not necessarily one fragment, multiple fragment can be combined to make one pixel, other fragments are discarded due to depth test , stencil test, blending. A Fragment shader will be executed for those fragments even though they might merged/discarded later.

I don't know a way give you exact number of the fragments in a scene, maybe there is a tool for NVidia or ATI than can give you how many times a fragment shader is executed.

Regardless of the actual numbers it's important to understand that due to the parallel nature of the GPU fragment shaders are executed on parallel on multiple fragments, it is also more important to profile your application and understand if it is GPU bound and if the bottleneck is in the vertex or fragment stage. here is a good article from GPU gems that explains how the GPU works.

| improve this answer | |
\$\endgroup\$
  • 1
    \$\begingroup\$ One fragment != pixel. And multiple fragments can be combined to make one pixel... that is what we call Multi-sampling. :) \$\endgroup\$ – 2am Oct 25 '13 at 17:12
  • \$\begingroup\$ not only multisampling, depth test might result in fragments not shown are still processed by the fragment shader. Also applies for other kind of tests (stencil , alpha test etc) \$\endgroup\$ – concept3d Oct 25 '13 at 17:37
  • 2
    \$\begingroup\$ It's very important to consider fragments that are overwritten due to ZPass. This is why in certain circumstances, rendering front-to-back can help performance in fill-rate limited applications. \$\endgroup\$ – Arelius Oct 25 '13 at 17:46
  • 1
    \$\begingroup\$ The amount of work done for each fragment is also an important factor; a z-only pre-pass is most definitely not comparable to a complex lighting setup. This honestly seems a meaningless metric and I'd question if there's much value in having it. \$\endgroup\$ – Maximus Minimus Oct 26 '13 at 16:04
5
\$\begingroup\$

You can, with a suitably recent version of GL, use the query objects support. See glGenQueries and glBeginQuery for documentation on their use.

With this, you can use GL_SAMPLES_PASSED as the query type. Assuming you aren't doing anything to disable early-Z, this should get you close to what you're looking for, enough for performance measurements at the least.

| improve this answer | |
\$\endgroup\$
2
\$\begingroup\$

A fragment shader is executed for each fragment once.One fragment is one pixel. so it depends on what are you rendering:

For example if it takes up the whole screen( like a post-process effect ) it is executed as many times as many pixels are there on your screen.( Resolution.x * Resolution.y ).

So basically it is called once for each pixel.

If you are interested for more exact numbers, you could use shader atomics to test specific cases.

Here are some links about the usage of shader atomic counters. They are basically counters that are consistent across shaders, their usage is more performance expensive tough.

link1, link2

| improve this answer | |
\$\endgroup\$
  • 3
    \$\begingroup\$ If you're using multisampling (MSAA, etc.) it's number of pixels * number of samples. \$\endgroup\$ – Robert Rouhani Oct 25 '13 at 16:55
  • \$\begingroup\$ @akltar, would you like to elaborate more on shader automics? I googled it, didnt find anything. \$\endgroup\$ – 2am Oct 25 '13 at 17:15
  • \$\begingroup\$ @RobertRouhani No, with MSAA the fragment shader is still executed once per pixel per primitive, not for each sample. (Unless you specifically turn on sample-frequency shading, which is not usual.) \$\endgroup\$ – Nathan Reed Oct 25 '13 at 18:14
  • \$\begingroup\$ @NathanReed Oh, right, that's SSAA/FSAA, MSAA just checks coverage at the sub-pixel level... my bad. \$\endgroup\$ – Robert Rouhani Oct 25 '13 at 18:32
1
\$\begingroup\$

You can use openGL atomic counter to increment a value inside your fragment shader. Here is a tutorial on opengl atomics: OpenGL Atomic Counters

| improve this answer | |
\$\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.