Part of the Khronos Group
OpenGL.org

The Industry's Foundation for High Performance Graphics

from games to virtual reality, mobile phones to supercomputers

Page 2 of 3 FirstFirst 123 LastLast
Results 11 to 20 of 23

Thread: detecting if a gl_LightSource is disabled in compatibility profile

  1. #11
    Senior Member OpenGL Guru Dark Photon's Avatar
    Join Date
    Oct 2004
    Location
    Druidia
    Posts
    2,894
    Quote Originally Posted by mfort View Post
    Sometimes I observe shader recompilation when the float value reaches some well known number, like 0.0 or 1.0. The problem is that if you animate such uniform and the value just passes this special value then perf. drop happens
    Really!? I haven't had to hack-around that behavior since GeForce 7 days. What GPU/driver?

  2. #12
    Junior Member Newbie
    Join Date
    Jul 2012
    Posts
    8
    Quote Originally Posted by Dark Photon View Post
    That was the first approach I used years ago. After you get a few shader permutation settings in there, the code gets to be an unreadable difficult-to-maintain mess!
    Yes, that is happening to me now. And now that I'm trying to add compile-time light type/enable switching...yuck. I'm spoiled by C++ templates I guess.

    Quote Originally Posted by Dark Photon View Post
    It's much cleaner (more readable, easier to maintain) to use "if/else"s in the shading language instead of #if/#elses with the preprocessor to accomplish this. The code actually reads completely normally then, and you can freely mix these constants in expressions with uniforms and other non-constant variables in the shader, and the compiler will just "do the right thing" when it comes to discarding unreadable code (inactive shader permutations).
    This does seem cleaner, but either way, not so much fun to manage. This is begging for a nice C++ library wrapper.

  3. #13
    Senior Member OpenGL Guru Dark Photon's Avatar
    Join Date
    Oct 2004
    Location
    Druidia
    Posts
    2,894
    Quote Originally Posted by aqnuep View Post
    I think the driver shouldn't try to be "too smart" in these kinds of situations as you might run into issues like the one presented by mfort. Everything should be explicit and the driver shouldn't do tricks (like generating specialized shaders on the fly or renaming buffers and stuff like that).
    100% agreed. However, I am not talking about using standard uniforms for this. uniforms have a defined purpose. They are constant within a batch but can change across multiple invocations of that same compiled/linked shader program. The GPU+driver should never recompile/reoptimize your shader code when you change a standard uniform value -- at least in this day-and-age. That was done ~7 GPU generations ago due to HW limitations, but I haven't seen/heard any clear indications that this has gone on since.

    No, what I'm talking about is using constants for this. Constants by definition cannot change across all invocations of that specific compiled shader source. They are unchangeable. And thus they are ideal for setting "shader permutation" state which the compiler can automagically use to snip away code for shader permutations that aren't active.

    For instance:

    Code :
    const bool FLAT = false;
     
    if ( FLAT )
    {
      ...
    }
    When any compiler that's worth 5 cents builds an expression tree and plugs in the constants, it effectively sees:

    Code :
    if ( false )
    {
      ...
    }

    so all the code in the braces will never be executed for this compiled shader and can be thrown in the bit bucket, along with the "if" expression evaluation and branch as well. It knows this at compile-time.

    So we get what we want, and all without any #if/#else/#elif/#endif mess.
    Last edited by Dark Photon; 07-09-2012 at 04:58 PM.

  4. #14
    Senior Member OpenGL Guru Dark Photon's Avatar
    Join Date
    Oct 2004
    Location
    Druidia
    Posts
    2,894
    Quote Originally Posted by atb123 View Post
    Managing GLSL compilation sure does take a lot of code, I feel like I'm writing a mini make system. It isn't hard, just cumbersome
    Agreed. It's alot more cumbersome than it needs to be, particularly when you have 20-30 "shader permutation" variables parameterizing your code.

    Using const shader permutation settings and standard GLSL language if/else/switch/etc. statements cleans up the GLSL code a ton (vs. nested #if/#else/#elif/#endif etc.)

    But you still have the mess on the C++ side with sprintfing that big block that gets manually slapped onto the top of your shader programs. For this, what I'd prefer to see is something like this:

    GLSL:
    Code :
      const bool FLAT = false;       // False is just the default; C++ GL API can override this
     
      if ( FLAT )
      {
        ...
      }

    C++:
    Code :
      glConstant1i( "FLAT", flat );  
      glCompileShader( ... );
      ...

    The compiler just "plugs in" the provided value for FLAT into the shader and compiles/links with it (and of course throws away all the "if (FLAT) { ... }" code if FLAT was set to false. The above seems like it might be a pretty simple change.

    There are of course a lot of possible variations here. For instance:


    1. We could declare these special "C++ API-settable" constants "const param" in the shader, and then only allow "const param" settings to be settable via the GL C++ API.
    2. We could have these const param settings be settable after compile but before link (like subroutines) and provide a uniform-like API to query for the active const param settings and set them (e.g. instead of glGetProgramiv( ... GL_ACTIVE_UNIFORMS ... ), glGetActiveUniforms(), and glUniform*(), use glGetProgramiv( ... GL_ACTIVE_CONST_PARAMS ... ), glGetActiveConstParams(), glConstant*().
    3. Or we could conceivably call these "const uniform" settings (instead of "const param") and then reuse some of the GL C++ uniform API to set/get them (e.g. glUniform*). The tradeoff is potential confusion with the original "uniform" semantics (...but I think shader subroutines may have already muddied that water).
    Last edited by Dark Photon; 07-09-2012 at 04:51 PM.

  5. #15
    Junior Member Newbie
    Join Date
    Jul 2012
    Posts
    8
    Managing conditional re-compiling also seems a bit tiresome, regardless of how the consts get passed in. I'm not writing quite enough GLSL code to justify writing a library for it, but I almost feel like I should. Does your suggestion eliminate the need for re-compilation?

  6. #16
    Advanced Member Frequent Contributor
    Join Date
    Dec 2007
    Location
    Hungary
    Posts
    947
    Quote Originally Posted by Dark Photon View Post
    No, what I'm talking about is using constants for this. Constants by definition cannot change across all invocations of that specific compiled shader source. They are unchangeable. And thus they are ideal for setting "shader permutation" state which the compiler can automagically use to snip away code for shader permutations that aren't active.
    Yes, I understand. But you couldn't select e.g. between different uniform block definitions or interpolation methods using constant ifs. For me, preprocessor directives seem like a better alternative, though agree that drivers should be able to optimize out constant ifs too.
    Disclaimer: This is my personal profile. Whatever I write here is my personal opinion and none of my statements or speculations are anyhow related to my employer and as such should not be treated as accurate or valid and in no case should those be considered to represent the opinions of my employer.
    Technical Blog: http://www.rastergrid.com/blog/

  7. #17
    Member Regular Contributor
    Join Date
    Nov 2003
    Location
    Czech Republic
    Posts
    318
    Quote Originally Posted by Dark Photon View Post
    Really!? I haven't had to hack-around that behavior since GeForce 7 days. What GPU/driver?
    It was quite recently with Quadro 6000. Driver 295.73 fixed this problem.

  8. #18
    Senior Member OpenGL Guru Dark Photon's Avatar
    Join Date
    Oct 2004
    Location
    Druidia
    Posts
    2,894
    Quote Originally Posted by aqnuep View Post
    Yes, I understand. But you couldn't select e.g. between different uniform block definitions or interpolation methods using constant ifs.
    For the large portion of cases (ordinary uniforms, interpolators, etc.) there's no need for any conditional compilation (uniforms become inactive, unused interpolators go away, etc.). But yes, I agree if you're trying to do something the language doesn't support in the same shader source, you might need the preprocessor to force it all into the same file. Before you do though, it's definitely worth considering whether you should just use a separate ubershader source file for that permutation -- could be the cleaner approach.

  9. #19
    Junior Member Newbie
    Join Date
    Jul 2012
    Posts
    8
    2 more questions:

    - How is this idea different than branching on uniform bools? Couldn't the compiler optimize uniform branches in the same way?

    - Previously I was under the impression that branches based on uniforms were relatively efficient, how much of a performance boost might I get using const branches set up by the preprocessor instead? For example, the branches required to handle light types and enable/disable states in the gl_LightSource array. Assuming gl_MaxLights is 8, there is quite a bit of branching required. I know the correct answer will be "test and see" but I would rather not spend the time if the expected impact is minimal.

  10. #20
    Member Regular Contributor malexander's Avatar
    Join Date
    Aug 2009
    Location
    Ontario
    Posts
    257
    Doesn't shader subroutines already give you the performance you'd expect from this hypothetical const re-compilation? I've found the cost of recompiling/linking a shader to outweigh dynamic strategies like this. Granted, shader subroutines are GL4-only, but at least they currently exist

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •