Order of state changes

Started by Qudus, January 23, 2008, 19:45:31

Previous topic - Next topic

Qudus

hi

Is there a preferred or even optimal way to apply state changes in OpenGL? And I am not talking about state-sorting. I am currently trying to improve my state-sorting algorithm and am seeing strange behavior when the order of state-change-execution changes. It seems like textures should be applied last. But I don'T see a reason for the behavior, that I experience. So I'm asking totally general.

Any thoughts?
Thanks.

Marvin

dronus

I think this is a really hard question. The answer is yes, the order matters... but how?
Many values are reflected by the graphics hardware. But not every will affect rendering, so the OpenGL display driver can try to optimize the state changes on the hardware, as these need high latency i/o operations from the cpu to the graphics card. So for example the driver could buffer hardware state changes until  something is actually rendered. On the other hand, some change could require time on the hardware, so its better to send them instantly not to stall later. Some OpenGL state changes maybe render some hardware state invalid, for example disabling a texture could need changing of the gpu shader program on the graphics board.
So the best thing is to test this out on different platforms.

Qudus


darkprophet

Dont optimise for state changes, simply because:

Quote
1. Typically, a graphics-card driver will try to take the entire state of the rendering pipeline and optimise it like crazy in a sort of "compilation" step. In the same way that changing a single line of C can produce radically different code, you might think you're "just" changing the AlphaTestEnable flag, but actually that changes a huge chunk of the pipeline. Oh but sir, it is only a wafer-thin renderstate... In practice, it's extremely hard to predict anything about the relative costs of various changes beyond extremely broad generalities - and even those change fairly substantially from generation to generation.

2. Because of this, the number of state changes you make between rendering calls is not all that relevant any more. This used to be true in the DX7 and DX8 eras, but it's far less so in these days of DX9, and it will be basically irrelevant on DX10. The card treats each unique set of states as an indivisible unit, and will often upload the entire pipeline state. There are very few incremental state changes any more - the main exceptions are rendertarget and some odd non-obvious ones like Z-compare modes.

3. On a platform like the PC, you often have no idea what sort of card the user is running on. Even if you ID'd the card, there's ten or twenty possible graphics card architectures, and each has a sucession of different drivers. Which one do you optimise for? Do you try to make the edge-traversal function change according to the card installed? That sounds expensive. Remembering that most games are limited by the CPU, not the GPU, and you've just added to the asymmetry of that load.

From Tom Frosyth's blog on "Scene Graphs - Just say no"

DP :)

Qudus

Well, it is indeed important to optimize for state changes. One of the most expensive state change is glActiveTexture(). Caching this state locally and only executing this call boosts the performance a lot.

And isn't this quote about DirectX?

Marvin

darkprophet

glActiveTexture is not important when you have shaders...if your still using fixed pipe functionality...well...your obsolete.

DirectX and OpenGL are the same thing...just different APIs for the same purpose. He is also talking about DX hardware, not actually DX.

DP :)

Qudus

Quote from: darkprophet on January 26, 2008, 16:52:07
glActiveTexture is not important when you have shaders...if your still using fixed pipe functionality...well...your obsolete.

Hmm... Maybe another dumb question, but: Why is glActiveTexture unimportant when shaders are used. AFAIK GLSL uses the textures, that are regularly bound through the fixed func pipeline. I wouldn'T know any other way to pass a texture to the GL to be used by GLSL. And if you want to use more than one texture unit, you will ahve to use glActiveTexture().

Marvin

darkprophet

Because glUniform wont be your friend when you start using shaders.

DP

Qudus

Quote from: darkprophet on January 27, 2008, 01:29:31
Because glUniform wont be your friend when you start using shaders.

Well, I am using shaders. But not very excessively. Why shouldn't glUniform be my friend? It is necessary for using GLSL shaders, isn't it?

Marvin