From 05ec90e4654ffe66b80365c4d5a1040aeb3efcec Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Wed, 31 Mar 2010 02:08:36 -0400 Subject: [PATCH] If binding a NULL program, disable any vertex arrays we previously enabled. This is done in case the caller is switching to the fixed function pipeline and needs more control over the vertex arrays. So to minimize state changes, don't bind a NULL program between draws if you're just going to bind a new program later. --- mojoshader_opengl.c | 65 ++++++++++++++++++++++++--------------------- 1 file changed, 35 insertions(+), 30 deletions(-) diff --git a/mojoshader_opengl.c b/mojoshader_opengl.c index 8386e319..97df8f17 100644 --- a/mojoshader_opengl.c +++ b/mojoshader_opengl.c @@ -1585,6 +1585,35 @@ MOJOSHADER_glProgram *MOJOSHADER_glLinkProgram(MOJOSHADER_glShader *vshader, } // MOJOSHADER_glLinkProgram +static void update_enabled_arrays(void) +{ + int highest_enabled = 0; + int i; + + // Enable/disable vertex arrays to match our needs. + // this happens to work in both ARB1 and GLSL, but if something alien + // shows up, we'll have to split these into profile*() functions. + for (i = 0; i <= ctx->max_attrs; i++) + { + const int want = (const int) ctx->want_attr[i]; + const int have = (const int) ctx->have_attr[i]; + if (want != have) + { + if (want) + ctx->glEnableVertexAttribArray(i); + else + ctx->glDisableVertexAttribArray(i); + ctx->have_attr[i] = ctx->want_attr[i]; + } // if + + if (want) + highest_enabled = i; + } // for + + ctx->max_attrs = highest_enabled; // trim unneeded iterations next time. +} // update_enabled_arrays + + void MOJOSHADER_glBindProgram(MOJOSHADER_glProgram *program) { GLuint handle = 0; @@ -1600,6 +1629,12 @@ void MOJOSHADER_glBindProgram(MOJOSHADER_glProgram *program) memset(ctx->want_attr, '\0', sizeof (ctx->want_attr[0]) * ctx->max_attrs); + // If no program bound, disable all arrays, in case we're switching to + // fixed function pipeline. Otherwise, we try to minimize state changes + // by toggling just the changed set of needed arrays in ProgramReady(). + if (program == NULL) + update_enabled_arrays(); + ctx->profileUseProgramObject(program); program_unref(ctx->bound_program); ctx->bound_program = program; @@ -1771,35 +1806,6 @@ void MOJOSHADER_glSetVertexAttribute(MOJOSHADER_usage usage, } // MOJOSHADER_glSetVertexAttribute -static void update_enabled_arrays(void) -{ - int highest_enabled = 0; - int i; - - // Enable/disable vertex arrays to match our needs. - // this happens to work in both ARB1 and GLSL, but if something alien - // shows up, we'll have to split these into profile*() functions. - for (i = 0; i <= ctx->max_attrs; i++) - { - const int want = (const int) ctx->want_attr[i]; - const int have = (const int) ctx->have_attr[i]; - if (want != have) - { - if (want) - ctx->glEnableVertexAttribArray(i); - else - ctx->glDisableVertexAttribArray(i); - ctx->have_attr[i] = ctx->want_attr[i]; - } // if - - if (want) - highest_enabled = i; - } // for - - ctx->max_attrs = highest_enabled; // trim unneeded iterations next time. -} // update_enabled_arrays - - void MOJOSHADER_glProgramReady(void) { MOJOSHADER_glProgram *program = ctx->bound_program; @@ -1910,7 +1916,6 @@ void MOJOSHADER_glDestroyContext(MOJOSHADER_glContext *_ctx) MOJOSHADER_glContext *current_ctx = ctx; ctx = _ctx; MOJOSHADER_glBindProgram(NULL); - update_enabled_arrays(); // disables all vertex arrays. lookup_entry_points(NULL, NULL); Free(ctx); ctx = ((current_ctx == _ctx) ? NULL : current_ctx);