V3: use always_inline attribute (Suggested by Nicolai) Cc: Nicolai Hähnle <nhaeh...@gmail.com> --- src/mapi/glapi/gen/gl_API.xml | 2 +- src/mesa/main/shaderapi.c | 75 +++++++++++++++++++++++++++++-------------- src/mesa/main/shaderapi.h | 2 ++ 3 files changed, 54 insertions(+), 25 deletions(-)
diff --git a/src/mapi/glapi/gen/gl_API.xml b/src/mapi/glapi/gen/gl_API.xml index a304ac0..50d60f5 100644 --- a/src/mapi/glapi/gen/gl_API.xml +++ b/src/mapi/glapi/gen/gl_API.xml @@ -5493,21 +5493,21 @@ </function> <function name="ShaderSource" es2="2.0" marshal="custom"> <param name="shader" type="GLuint"/> <param name="count" type="GLsizei"/> <param name="string" type="const GLchar * const *"/> <param name="length" type="const GLint *"/> <glx ignore="true"/> </function> - <function name="UseProgram" es2="2.0"> + <function name="UseProgram" es2="2.0" no_error="true"> <param name="program" type="GLuint"/> <glx ignore="true"/> </function> <function name="Uniform1f" es2="2.0"> <param name="location" type="GLint"/> <param name="v0" type="GLfloat"/> <glx ignore="true"/> </function> <function name="Uniform2f" es2="2.0"> diff --git a/src/mesa/main/shaderapi.c b/src/mesa/main/shaderapi.c index eb75a3e..f91cc89 100644 --- a/src/mesa/main/shaderapi.c +++ b/src/mesa/main/shaderapi.c @@ -1841,20 +1841,70 @@ _mesa_ShaderSource(GLuint shaderObj, GLsizei count, free(source); source = replacement; } #endif /* ENABLE_SHADER_CACHE */ shader_source(sh, source); free(offsets); } +/* The ARB_separate_shader_object spec says: + * + * "The executable code for an individual shader stage is taken from + * the current program for that stage. If there is a current program + * object established by UseProgram, that program is considered current + * for all stages. Otherwise, if there is a bound program pipeline + * object (section 2.14.PPO), the program bound to the appropriate + * stage of the pipeline object is considered current." + */ +static ALWAYS_INLINE void +reference_pipeline_and_use_program(struct gl_context *ctx, + struct gl_shader_program *shProg, + bool no_error) +{ + if (shProg) { + /* Attach shader state to the binding point */ + _mesa_reference_pipeline_object(ctx, &ctx->_Shader, &ctx->Shader); + /* Update the program */ + _mesa_use_shader_program(ctx, shProg); + } else { + /* Must be done first: detach the progam */ + _mesa_use_shader_program(ctx, shProg); + /* Unattach shader_state binding point */ + _mesa_reference_pipeline_object(ctx, &ctx->_Shader, + ctx->Pipeline.Default); + /* If a pipeline was bound, rebind it */ + if (ctx->Pipeline.Current) { + if (no_error) + _mesa_BindProgramPipeline_no_error(ctx->Pipeline.Current->Name); + else + _mesa_BindProgramPipeline(ctx->Pipeline.Current->Name); + } + } +} + + \ + +void GLAPIENTRY +_mesa_UseProgram_no_error(GLuint program) +{ + GET_CURRENT_CONTEXT(ctx); + struct gl_shader_program *shProg = NULL; + + if (program) { + shProg = _mesa_lookup_shader_program(ctx, program); + } + + reference_pipeline_and_use_program(ctx, shProg, true); +} + void GLAPIENTRY _mesa_UseProgram(GLuint program) { GET_CURRENT_CONTEXT(ctx); struct gl_shader_program *shProg = NULL; if (MESA_VERBOSE & VERBOSE_API) _mesa_debug(ctx, "glUseProgram %u\n", program); @@ -1875,44 +1925,21 @@ _mesa_UseProgram(GLuint program) return; } #ifdef DEBUG if (ctx->_Shader->Flags & GLSL_USE_PROG) { print_shader_info(shProg); } #endif } - /* The ARB_separate_shader_object spec says: - * - * "The executable code for an individual shader stage is taken from - * the current program for that stage. If there is a current program - * object established by UseProgram, that program is considered current - * for all stages. Otherwise, if there is a bound program pipeline - * object (section 2.14.PPO), the program bound to the appropriate - * stage of the pipeline object is considered current." - */ - if (program) { - /* Attach shader state to the binding point */ - _mesa_reference_pipeline_object(ctx, &ctx->_Shader, &ctx->Shader); - /* Update the program */ - _mesa_use_shader_program(ctx, shProg); - } else { - /* Must be done first: detach the progam */ - _mesa_use_shader_program(ctx, shProg); - /* Unattach shader_state binding point */ - _mesa_reference_pipeline_object(ctx, &ctx->_Shader, ctx->Pipeline.Default); - /* If a pipeline was bound, rebind it */ - if (ctx->Pipeline.Current) { - _mesa_BindProgramPipeline(ctx->Pipeline.Current->Name); - } - } + reference_pipeline_and_use_program(ctx, shProg, false); } void GLAPIENTRY _mesa_ValidateProgram(GLuint program) { GET_CURRENT_CONTEXT(ctx); validate_program(ctx, program); } diff --git a/src/mesa/main/shaderapi.h b/src/mesa/main/shaderapi.h index 99b4fe8..0a28185 100644 --- a/src/mesa/main/shaderapi.h +++ b/src/mesa/main/shaderapi.h @@ -120,20 +120,22 @@ _mesa_IsProgram(GLuint name); extern GLboolean GLAPIENTRY _mesa_IsShader(GLuint name); extern void GLAPIENTRY _mesa_LinkProgram(GLuint programObj); extern void GLAPIENTRY _mesa_ShaderSource(GLuint, GLsizei, const GLchar* const *, const GLint *); +void GLAPIENTRY +_mesa_UseProgram_no_error(GLuint); extern void GLAPIENTRY _mesa_UseProgram(GLuint); extern void GLAPIENTRY _mesa_ValidateProgram(GLuint); extern void GLAPIENTRY _mesa_BindAttribLocation(GLuint program, GLuint, const GLchar *); -- 2.9.3 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev