From a974949f3b586eee2bc8d6d97d3adb71796fe167 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Fri, 29 Oct 2010 11:28:38 -0700 Subject: mesa: Make metaops use program refcounts instead of names. Fixes failure on restoring state when the program was active but deleted, and the name no longer exists. Bug #31194 --- src/mesa/drivers/common/meta.c | 37 ++++++++-------- src/mesa/main/shaderapi.c | 97 +++++++++++++++++++++++------------------- src/mesa/main/shaderapi.h | 8 +++- 3 files changed, 80 insertions(+), 62 deletions(-) diff --git a/src/mesa/drivers/common/meta.c b/src/mesa/drivers/common/meta.c index 1bfd76a665..c48709714d 100644 --- a/src/mesa/drivers/common/meta.c +++ b/src/mesa/drivers/common/meta.c @@ -52,6 +52,7 @@ #include "main/readpix.h" #include "main/scissor.h" #include "main/shaderapi.h" +#include "main/shaderobj.h" #include "main/state.h" #include "main/stencil.h" #include "main/texobj.h" @@ -143,10 +144,10 @@ struct save_state struct gl_vertex_program *VertexProgram; GLboolean FragmentProgramEnabled; struct gl_fragment_program *FragmentProgram; - GLuint VertexShader; - GLuint GeometryShader; - GLuint FragmentShader; - GLuint ActiveShader; + struct gl_shader_program *VertexShader; + struct gl_shader_program *GeometryShader; + struct gl_shader_program *FragmentShader; + struct gl_shader_program *ActiveShader; /** META_STENCIL_TEST */ struct gl_stencil_attrib Stencil; @@ -436,14 +437,14 @@ _mesa_meta_begin(struct gl_context *ctx, GLbitfield state) } if (ctx->Extensions.ARB_shader_objects) { - save->VertexShader = ctx->Shader.CurrentVertexProgram ? - ctx->Shader.CurrentVertexProgram->Name : 0; - save->GeometryShader = ctx->Shader.CurrentGeometryProgram ? - ctx->Shader.CurrentGeometryProgram->Name : 0; - save->FragmentShader = ctx->Shader.CurrentFragmentProgram ? - ctx->Shader.CurrentFragmentProgram->Name : 0; - save->ActiveShader = ctx->Shader.ActiveProgram ? - ctx->Shader.ActiveProgram->Name : 0; + _mesa_reference_shader_program(ctx, &save->VertexShader, + ctx->Shader.CurrentVertexProgram); + _mesa_reference_shader_program(ctx, &save->GeometryShader, + ctx->Shader.CurrentGeometryProgram); + _mesa_reference_shader_program(ctx, &save->FragmentShader, + ctx->Shader.CurrentFragmentProgram); + _mesa_reference_shader_program(ctx, &save->ActiveShader, + ctx->Shader.CurrentFragmentProgram); _mesa_UseProgramObjectARB(0); } @@ -675,16 +676,18 @@ _mesa_meta_end(struct gl_context *ctx) } if (ctx->Extensions.ARB_vertex_shader) - _mesa_UseShaderProgramEXT(GL_VERTEX_SHADER, save->VertexShader); + _mesa_use_shader_program(ctx, GL_VERTEX_SHADER, save->VertexShader); if (ctx->Extensions.ARB_geometry_shader4) - _mesa_UseShaderProgramEXT(GL_GEOMETRY_SHADER_ARB, - save->GeometryShader); + _mesa_use_shader_program(ctx, GL_GEOMETRY_SHADER_ARB, + save->GeometryShader); if (ctx->Extensions.ARB_fragment_shader) - _mesa_UseShaderProgramEXT(GL_FRAGMENT_SHADER, save->FragmentShader); + _mesa_use_shader_program(ctx, GL_FRAGMENT_SHADER, + save->FragmentShader); - _mesa_ActiveProgramEXT(save->ActiveShader); + _mesa_reference_shader_program(ctx, &ctx->Shader.ActiveProgram, + save->ActiveShader); } if (state & META_STENCIL_TEST) { diff --git a/src/mesa/main/shaderapi.c b/src/mesa/main/shaderapi.c index 622285debb..9717e00559 100644 --- a/src/mesa/main/shaderapi.c +++ b/src/mesa/main/shaderapi.c @@ -936,9 +936,9 @@ print_shader_info(const struct gl_shader_program *shProg) /** * Use the named shader program for subsequent glUniform calls */ -static void -active_program(struct gl_context *ctx, struct gl_shader_program *shProg, - const char *caller) +void +_mesa_active_program(struct gl_context *ctx, struct gl_shader_program *shProg, + const char *caller) { if ((shProg != NULL) && !shProg->LinkStatus) { _mesa_error(ctx, GL_INVALID_OPERATION, @@ -1003,45 +1003,16 @@ use_shader_program(struct gl_context *ctx, GLenum type, * Use the named shader program for subsequent rendering. */ void -_mesa_use_program(struct gl_context *ctx, GLuint program) +_mesa_use_program(struct gl_context *ctx, struct gl_shader_program *shProg) { - struct gl_shader_program *shProg; - struct gl_transform_feedback_object *obj = - ctx->TransformFeedback.CurrentObject; bool changed = false; - if (obj->Active) { - _mesa_error(ctx, GL_INVALID_OPERATION, - "glUseProgram(transform feedback active)"); - return; - } - - if (program) { - shProg = _mesa_lookup_shader_program_err(ctx, program, "glUseProgram"); - if (!shProg) { - return; - } - if (!shProg->LinkStatus) { - _mesa_error(ctx, GL_INVALID_OPERATION, - "glUseProgram(program %u not linked)", program); - return; - } - - /* debug code */ - if (ctx->Shader.Flags & GLSL_USE_PROG) { - print_shader_info(shProg); - } - } - else { - shProg = NULL; - } - changed = use_shader_program(ctx, GL_VERTEX_SHADER, shProg); changed = use_shader_program(ctx, GL_GEOMETRY_SHADER_ARB, shProg) || changed; changed = use_shader_program(ctx, GL_FRAGMENT_SHADER, shProg) || changed; - active_program(ctx, shProg, "glUseProgram"); + _mesa_active_program(ctx, shProg, "glUseProgram"); if (changed) { FLUSH_VERTICES(ctx, _NEW_PROGRAM | _NEW_PROGRAM_CONSTANTS); @@ -1614,8 +1585,39 @@ void GLAPIENTRY _mesa_UseProgramObjectARB(GLhandleARB program) { GET_CURRENT_CONTEXT(ctx); + struct gl_shader_program *shProg; + struct gl_transform_feedback_object *obj = + ctx->TransformFeedback.CurrentObject; + FLUSH_VERTICES(ctx, _NEW_PROGRAM); - _mesa_use_program(ctx, program); + + if (obj->Active) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "glUseProgram(transform feedback active)"); + return; + } + + if (program) { + shProg = _mesa_lookup_shader_program_err(ctx, program, "glUseProgram"); + if (!shProg) { + return; + } + if (!shProg->LinkStatus) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "glUseProgram(program %u not linked)", program); + return; + } + + /* debug code */ + if (ctx->Shader.Flags & GLSL_USE_PROG) { + print_shader_info(shProg); + } + } + else { + shProg = NULL; + } + + _mesa_use_program(ctx, shProg); } @@ -1731,12 +1733,25 @@ _mesa_ProgramParameteriARB(GLuint program, GLenum pname, #endif +void +_mesa_use_shader_program(struct gl_context *ctx, GLenum type, + struct gl_shader_program *shProg) +{ + bool changed; + + changed = use_shader_program(ctx, type, shProg); + if (changed) + FLUSH_VERTICES(ctx, _NEW_PROGRAM | _NEW_PROGRAM_CONSTANTS); + + if (ctx->Driver.UseProgram) + ctx->Driver.UseProgram(ctx, shProg); +} + void GLAPIENTRY _mesa_UseShaderProgramEXT(GLenum type, GLuint program) { GET_CURRENT_CONTEXT(ctx); struct gl_shader_program *shProg = NULL; - bool changed = false; if (!validate_shader_target(ctx, type)) { _mesa_error(ctx, GL_INVALID_ENUM, "glUseShaderProgramEXT(type)"); @@ -1762,13 +1777,7 @@ _mesa_UseShaderProgramEXT(GLenum type, GLuint program) } } - changed = use_shader_program(ctx, type, shProg); - if (changed) - FLUSH_VERTICES(ctx, _NEW_PROGRAM | _NEW_PROGRAM_CONSTANTS); - - if (ctx->Driver.UseProgram) - ctx->Driver.UseProgram(ctx, shProg); - return; + _mesa_use_shader_program(ctx, type, shProg); } void GLAPIENTRY @@ -1779,7 +1788,7 @@ _mesa_ActiveProgramEXT(GLuint program) ? _mesa_lookup_shader_program_err(ctx, program, "glActiveProgramEXT") : NULL; - active_program(ctx, shProg, "glActiveProgramEXT"); + _mesa_active_program(ctx, shProg, "glActiveProgramEXT"); return; } diff --git a/src/mesa/main/shaderapi.h b/src/mesa/main/shaderapi.h index db316ab6a7..df78351411 100644 --- a/src/mesa/main/shaderapi.h +++ b/src/mesa/main/shaderapi.h @@ -39,8 +39,11 @@ _mesa_copy_string(GLchar *dst, GLsizei maxLength, GLsizei *length, const GLchar *src); extern void -_mesa_use_program(struct gl_context *ctx, GLuint program); +_mesa_use_program(struct gl_context *ctx, struct gl_shader_program *shProg); +extern void +_mesa_active_program(struct gl_context *ctx, struct gl_shader_program *shProg, + const char *caller); extern void _mesa_init_shader_dispatch(struct _glapi_table *exec); @@ -172,6 +175,9 @@ _mesa_ShaderBinary(GLint n, const GLuint *shaders, GLenum binaryformat, extern void GLAPIENTRY _mesa_ProgramParameteriARB(GLuint program, GLenum pname, GLint value); +void +_mesa_use_shader_program(struct gl_context *ctx, GLenum type, + struct gl_shader_program *shProg); extern void GLAPIENTRY _mesa_UseShaderProgramEXT(GLenum type, GLuint program); -- cgit v1.2.3