2
\$\begingroup\$

I am doing some program, that can be written in two ways.

  • render full screen quad and send some additional info to fragment shader. But in fragment shader I need to perform for-loop
  • Move the loop to the CPU side of program and call draw-call on fullscreen quad repeatedly. Output will be rendered to texture. I will have two of them and swap active (write) and inactive (last output, read-only).

What can be faster ? I think, that number 1, but on the other side, loops are not very efficient in GLES shaders. And I need to calculate texture coordinates on the fly, which according to Apple doc is slower than if they goes directly from vertex shader and are not changed.

Edit:

Point two can be improved by this:

  • I can put all quads to single buffer and draw them with one draw call (each quad will have different depth, but will be still fulscreen), where depth will be "loop" variable. In shader I take this "depth" and use blending (which can be used on iOS 6 via gl_LastFragData[0])
\$\endgroup\$
  • \$\begingroup\$ Random guess I'd say it really depends on the shader performance of your GPU. The better your GPU the better off you're with the loops in the shader. Regarding your note: Of course recalculating something is slower than just using whatever you got passed. I guess in the end this whole question is about GPU load vs. CPU/memory/bus load. \$\endgroup\$ – Mario Oct 5 '13 at 9:40
  • 1
    \$\begingroup\$ More than likely the GPU. The GPU has tons of cores and crazy multi-threading. Transfering data to the GPU is usually pretty slow. \$\endgroup\$ – RandyGaul Oct 5 '13 at 9:43
  • \$\begingroup\$ @RandyGaul Transfering data to GPU is slow, but I will reuse single Vertex Buffer with 1 quad, other data will be just textures and render targets, so they are still on GPU. \$\endgroup\$ – Martin Perry Oct 5 '13 at 9:46
  • \$\begingroup\$ @MartinPerry Well think about it: you call a function that does an action on the GPU. That is a draw call, and takes a similar amount of time to relay to the GPU as does sending some buffer. This is why you hear so much talk about "lowering draw calls". The ideal use of a GPU involves as little communication at all to/from the GPU. \$\endgroup\$ – RandyGaul Oct 5 '13 at 9:48
  • \$\begingroup\$ @RandyGaul See my edit... \$\endgroup\$ – Martin Perry Oct 5 '13 at 10:00
3
\$\begingroup\$

There's only one way to be sure. Implement both and benchmark them on the hardware you care about. I'd be surprised if multiple passes was quicker though, because of the extra reading and writing of render targets required.

Multiple identical passes are generally only useful to work round the limitations of what a single pass can do (e.g. shader instruction count limits).

The cases when multiple passes are quicker tend to be one of:

  • The shader can be much simpler with more passes (e.g. a separable blur).

  • The extra pass does something quick and simple which makes the rest of the work much cheaper. For example downsizing the source render target, or filling in the stencil buffer.

\$\endgroup\$
  • \$\begingroup\$ @Krom Stern Well.. doing actual profiling take up long time, because I need to create both versions (and its not that simple, as I put simplified problematic here). Thats why I asked before. \$\endgroup\$ – Martin Perry Oct 6 '13 at 9:30

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.