Skip to main content
GameDev.net gamedev.net
🔒 Locked

[HLSL] Static flow control

Started by Woodchuck Sep 10, 2007 at 4:49 AM 9 replies 9.7k views
Original Post
Woodchuck
Woodchuck
Hello,
Quote:
Constant Boolean Register This register is a collection of bits used in static flow control instructions (for example, if bool - ps - else - ps - endif - ps). There are 16 of them, therefore, a shader can have 16 independent branch conditions. They can be set using defi - ps or IDirect3DDevice9::SetPixelShaderConstantI. The behavior of shader constants has changed between Direct3D 8 and Direct3D 9. For Direct3D 9, constants set with defx assign values to the shader constant space. The lifetime of a constant declared with defx is confined to the execution of that shader only. Conversely, constants set using the APIs SetXXXShaderConstantX initialize constants in global space. Constants in global space are not copied to local space (visible to the shader) until SetxxxShaderConstants is called. For Direct3D 8, constants set with defx or the APIs both assign values to the shader constant space. Each time the shader is executed, the constants are used by the current shader regardless of the technique used to set them.
I'm trying to implement static flow control like explain in the direct9 documentation. The problem is I have a significant pixel shader performance hit. Correct me if i'm wrong, but the shader code path is choosen between draw calls according to boolean shader constant set and then there is no pixel shader performance hit for a such technique no ? EDIT: I replace #if...#endif blocks by if-bool blocks. By removing #if-blocks I then have a lots more variables in the shader. Maybe this involve a more important register pressure that may hit the performance ?
Demirug
Demirug
Yes, register pressure is bad for the performance. Additional the use of static branching reduce the driver ability to optimize your shader. Most people stay away from static branching and generate a own shader for every permutation needed.
Woodchuck
Woodchuck
Thank you for reply.

For information :
BEFORE : the pixel shader take 6 .10-3s
AFTER : 11-12 .10-3s

This is a real high performance hit no ? Just for register pressure and optimization ? Damn, why not after all...
Demirug
Demirug
Nvidia and ATI have some tools that analyze your shader code in the same way the driver does and give you some results.

You can find them in the developer area of their websites.
Woodchuck
Woodchuck
Is there a way for the compiler to do a mistake and perform a dynamic branching instead of a static one ?
Evil Steve
Evil Steve
Quote:
Original post by Woodchuck
Is there a way for the compiler to do a mistake and perform a dynamic branching instead of a static one ?
What shader version are you using? ISTR that only shader model 3 supports dynamic branching.
jollyjeffers
jollyjeffers
The compiler will choose what it thinks to be the most efficient compiled code. It is highly unlikely it'll pick dynamic over static, but technically it could if it wanted.

In general the compiler tends to prefer flat code, so it's more likely to remove branches than add them.

There are some annotations/flags you can use to try and force it's hand, look in the SDK docs for more details.

hth
Jack
<hr align="left" width="25%" />
Jack Hoxley <small>[</small><small> Forum FAQ | Revised FAQ |
Woodchuck
Woodchuck
The targets are : ps_2_x and ps_3_0. I try and want the two.

If find D3DXSHADER_AVOID_FLOW_CONTROL for the flag. But that's not clear for me, avoid flow control is avoid dynamic branching ? :p

Thank you for your help.
jollyjeffers
jollyjeffers
Start from Flow Control (DirectX HLSL) in the docs. The 'for', 'if' and 'while' pages make mention of the [attribute] syntax I mentioned. This gives you additional control over how the compiler generates ASM from HLSL.

hth
Jack
<hr align="left" width="25%" />
Jack Hoxley <small>[</small><small> Forum FAQ | Revised FAQ |
mattnewport
mattnewport
Some older cards don't truly support static branching - the driver actually recompiles the shader on the fly to include only the taken branch(es). In these cases using static branching can impose an extra CPU cost that can be significant.
Woodchuck
Woodchuck
Quote:
Original post by jollyjeffers
Start from Flow Control (DirectX HLSL) in the docs. The 'for', 'if' and 'while' pages make mention of the [attribute] syntax I mentioned. This gives you additional control over how the compiler generates ASM from HLSL.

hth
Jack


Crap, I almost missed this information.

But I don't understand it. How do you relie this with static branching with boolean constant condition ?

Static branching with constant boolean cancel a part of the code ? then the two pass are not evaluate both. Then this is a [branch] attribute ? Or a [flatten] ? Or something else ?

Sorry, I really do efforts to understand but I don't.

Thanks mattnewport for the information, fortunatly I work on recent cards.

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.