OpenGL Direct State Access (DSA)

GPU Caps Viewer, OpenGL GL_EXT_direct_state_access extension
GPU Caps Viewer 1.9.5, GL_EXT_direct_state_access extension on a GTX 470

Direct State Access or DSA is an useful OpenGL extension that allows to update (or query) OpenGL states in a direct way without using an OpenGL state selector. GL_EXT_direct_state_access is available for AMD Radeon cards since Catalyst 10.7 (July 2010) and since ForceWare 180.42 (October 2008) for NVIDIA GeForce boards. This extension should be supported (partially) by any OpenGL 2.1 compliant implementation and complete support should be available in any OpenGL 3.0 compliant implementation (please, correct me if I’m wrong).

DSA introduces new OpenGL functions like glProgramUniform_XXX_EXT() for setting GPU program uniform variables, or glFramebufferTexture2DEXT() for attaching a logical buffer to a FBO. All new functions and complete specification can be found here: GL_EXT_direct_state_access @ OpenGL registry.

Here are some simple examples with and without DSA:

GLSL Uniform Variables

Without DSA:

glUniform1f(loc, x); 

With DSA:

glProgramUniform1fEXT(progId, loc, x); 

As you can see, DSA is really handy for updating uniform variables.

2D Texture Uploading

Without DSA:

glGenTextures(1, &tid);
glBindTexture(GL_TEXTURE_2D, tid);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, \
             w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixmap);

With DSA:

glGenTextures(1, &tid);
glTextureImage2DEXT(tid, GL_TEXTURE_2D, 0, GL_RGBA8, \
                    w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixmap);

Simple FBO Creation

Without DSA:

glGenTextures(1, &tid);
glBindTexture(GL_TEXTURE_2D, tid);
glTextureImage2DEXT(GL_TEXTURE_2D, 0, GL_RGBA8, w, h, 0, \
                    GL_RGBA, GL_UNSIGNED_BYTE, 0);
glBindTexture(GL_TEXTURE_2D, 0);

glGenFramebuffers(1, &fbo);
glBindFramebuffer(GL_FRAMEBUFFER, fbo);
                       GL_TEXTURE_2D, tid, 0);

With DSA:

glGenTextures(1, &tid);
glTextureImage2DEXT(tid, GL_TEXTURE_2D, 0, GL_RGBA8, w, h, 0, \ 
                    GL_RGBA, GL_UNSIGNED_BYTE, 0);

glGenFramebuffers(1, &fbo);
glNamedFramebufferTexture2DEXT(fbo, GL_COLOR_ATTACHMENT0, \ 
                               GL_TEXTURE_2D, tid, 0);

Modelview Matrix

Not really useful in modern OpenGL 3 or 4 code but still useful in OpenGL 2 code:

Without DSA:


With DSA:

glMatrixLoadfEXT(GL_MODELVIEW, matrix);

I’ll try to use DSA in my OpenGL codes (GeeXLab, MSI Kombustor, FurMark, TessMark, etc.).

G-Truc has updated its OpenGL code samples pack with several code samples about DSA. You can download the code samples pack and read additional information about DSA here: OpenGL Samples Pack released, focus on DSA


  • iPristy

    I will be getting Bliss 8500GT, will be that function in there?

  • Yep, the 8500GT is an OpenGL 2, OpenGL 3 capable card.

  • jammer

    Nice feature, but what do you think is faster?

    glUniform1f(loc1, x);
    glUniform1f(loc2, y);
    glUniform1f(loc3, z);


    glProgramUniform1fEXT(progId, loc1, x);
    glProgramUniform1fEXT(progId, loc2, y);
    glProgramUniform1fEXT(progId, loc3, z);


  • xernobyl

    Depends o whether or not you want to render something using the program after.

  • Mars_999

    I don’t understand how this can speed up much, other than from what I see is a few less function calls to setup the same operations… Seems to me people just wanted to call a bunch of ops in a single call or two… So if that is the case, this isn’t going to speed up GPU but maybe CPU cycles will be less now?

    I am just guessing here BTW.. :)

  • Rosario Leonardi

    Please check this to understand the performance improvement:

  • .mld

    Rosario, the paper you linked is about the bindless extensions, not DSA.
    DSA is more of an API change, away from that giant state machine to a more object orientated model.
    The bindless extensions, however, allow you to query for the GPU internal 64bit addresses of objects and use those in subsequent calls. This frees the driver from looking up the addresses by name, which resulted in a likely cache-miss. Hence speeding up the whole thing.

    Please correct me if I got it wrong or I didn’t get the point of your comment. :)

  • Pavel

    Yes, it just nice try to make API easier. We jump from bind-process-unbind model to create-direct_access. GPU will not work faster with that(I mean DSA), but CPU will be less busy by changing states, and that’s all. It is good only when application is CPU-bounded.

  • reavenk

    @Mars_999 It makes it a lot easier when you want to change one attribute about a state instead of switching the states, making the change, and then switching back. 3 lines versus one line. It’s also good if you want to create a utility library and are tired about making sure the state is the same as how it was when the function entered – less headaches, and cheaper than calling a glGet or pushing the state, doing the work and then restoring. I’m guessing there’s also benefits for it when mixing it in with display lists. It’s less about huge optimizations and more about elegance against clunky state management.

  • Athlonite

    well Looks like it’s not just for nVidia seems ATI get this aswell