2
\$\begingroup\$

Assuming the total amount of computation would be the same (at least as far as my code goes), would there be any performance increase in splitting the calculation and using separate vertex and fragment shaders vs. doing all the calculations in just a fragment shader?

In my use case, I would not be using vertex shaders as they are typically intended (so, not processing actual vertices). I just thought if the GPU hardware is set up such that the pipeline is expected to be used, would it be better to take advantage of that, or would it be just as fast to put it all in a fragment shader. Conceptually, it would be simpler to just use the fragment shader.

Note, that I do need a lot of data going to the fragment shader that is updated every frame (eg. texture buffer object).

\$\endgroup\$
5
  • 2
    \$\begingroup\$ If the vertex shader isn't literally processing actual vertices, you should tell us a bit about what it is processing, so we have an idea of how often it's invoked. For geometry rendering workloads, we often process far more pixels/fragments than vertices, so moving work that interpolates well across a triangle further up the pipeline to the vertex level is often a net savings (with some caveats around interpolator bandwidth). But because your use case is different this rule of thumb might not apply. We'll need to know more about what you're doing. Or better yet, try it & profile both ways! \$\endgroup\$
    – DMGregory
    Sep 29, 2016 at 2:23
  • \$\begingroup\$ "...if the GPU hardware is set up such that the pipeline is expected to be used" - in the old days when each shader stage had it's own dedicated hardware this might have been a factor; nowadays shader stages are unified so not so much. If early-Z rejection is relevant to whatever it is you're drawing you might get additional performance on top of the "more fragments than vertices" point noted by @DMGregory \$\endgroup\$ Sep 29, 2016 at 8:37
  • \$\begingroup\$ Thank you for your comments. I tried to get past what you're asking by saying "Assuming the total amount of computation would be the same" but I understand you might not take that exactly as I intended. @LeComteduMerde-fou is getting at what I'm asking. If the hardware doesn't specialize the pipeline, then the answer is it doesn't matter. Maybe I should have just asked: "Do modern GPUs specialize the pipeline" or something like that. \$\endgroup\$
    – mentics
    Sep 29, 2016 at 8:45
  • 1
    \$\begingroup\$ @taotree - (1/2) I'd modify that to say "If the hardware doesn't specialize the pipeline, then the answer is that maybe it still might matter." Because there are probably more fragments than vertices, it could be the dfference between performing a calculation 4 times vs performing it 1000000 times. That's significant. Also note what I said about early-Z: if the GPU can skip the FS, then maybe it makes sense to have calculations in the FS because the GPU could then skip them (it wouldn't be able to if they were in the VS). That's 2 bits of advice that contradict each other, I know... \$\endgroup\$ Sep 29, 2016 at 8:59
  • 1
    \$\begingroup\$ (2/2) ...which is why it's important to know more about what you're doing, any why you should profile both ways in your own code, because everybody's workload is different, and advice for one workload may not transfer well to another! \$\endgroup\$ Sep 29, 2016 at 9:00

1 Answer 1

1
\$\begingroup\$

Nowadays, GPUs use an hardware design called Unified Shading Architecture.

This implies that GPUs are basically an array of general working units (shader cores) that can handle any type of shader operations. Since they all can process any form of shaders, when you need to compute something, a scheduler is going to allocate some units to your shader and use as many as possible to keep them busy with your tasks.

Still, modern GPUs still have fixed-functions elements in their pipeline. That is, for example, after a shader core is allocated a Vertex Shader-kind of work, it will have to go through the fixed-function Primitive Assembly Same for the Fragment Shader, it will have to go through Blending Operations, and so on, for other stages.

The best you should do is to keep vertex operations in a Vertex Shader and fragment ones in a Fragment shader. This will help take advantage of dedicated hardware for some tasks, like early-z culling, etc...

But you could, still defer some of the computations to a compute shader, but that's something else.

Hope this helps

\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .