[Mesa-dev] [PATCH] mesa: add KHR_no_error support for glUseProgram
Nicolai Hähnle
nhaehnle at gmail.com
Mon May 8 09:36:11 UTC 2017
On 08.05.2017 02:25, Timothy Arceri wrote:
> V3: use always_inline attribute (Suggested by Nicolai)
>
> Cc: Nicolai Hähnle <nhaehnle at 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);
> +}
> +
Unless reference_pipeline_and_use_program has a separate use, I'd
actually feel more comfortable if the *entire* body of _mesa_UseProgram
was moved into the ALWAYS_INLINE function. This is better for
maintainability because it would guarantee that any future change will
automatically update both variants of the functions.
Cheers,
Nicolai
>
> 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 *);
>
>
--
Lerne, wie die Welt wirklich ist,
Aber vergiss niemals, wie sie sein sollte.
More information about the mesa-dev
mailing list