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).

  • 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 '16 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\$ – Maximus Minimus Sep 29 '16 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 '16 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\$ – Maximus Minimus Sep 29 '16 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\$ – Maximus Minimus Sep 29 '16 at 9:00

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


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.