From 66f703dca938f7749edc717fd8f690aba2d6e936 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Tue, 6 May 2008 08:40:41 -0600 Subject: gallium: change calculate_first_last_level() to match gallium-tex-surfaces branch --- src/mesa/state_tracker/st_cb_texture.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/mesa/state_tracker/st_cb_texture.c b/src/mesa/state_tracker/st_cb_texture.c index 02ef961e4d3..866683c23e9 100644 --- a/src/mesa/state_tracker/st_cb_texture.c +++ b/src/mesa/state_tracker/st_cb_texture.c @@ -1366,7 +1366,7 @@ calculate_first_last_level(struct st_texture_object *stObj) } else { firstLevel = 0; - lastLevel = MIN2(tObj->MaxLevel, tObj->Image[0][0]->WidthLog2); + lastLevel = MIN2(tObj->MaxLevel, tObj->Image[0][tObj->BaseLevel]->WidthLog2); } break; case GL_TEXTURE_RECTANGLE_NV: -- cgit v1.2.3 From 10f6ae0355937615d137c79c060b9e5a923f0d65 Mon Sep 17 00:00:00 2001 From: Brian Date: Thu, 1 May 2008 19:29:25 -0600 Subject: mesa: comments, whitespace --- src/mesa/main/ffvertex_prog.c | 43 +++++++++++++++++++------------------------ 1 file changed, 19 insertions(+), 24 deletions(-) (limited to 'src') diff --git a/src/mesa/main/ffvertex_prog.c b/src/mesa/main/ffvertex_prog.c index f648d081c0e..810af9e33e6 100644 --- a/src/mesa/main/ffvertex_prog.c +++ b/src/mesa/main/ffvertex_prog.c @@ -946,35 +946,33 @@ static void build_lighting( struct tnl_program *p ) _bfc1 = _bfc0; } - /* If no lights, still need to emit the scenecolor. */ - { - struct ureg res0 = register_output( p, VERT_RESULT_COL0 ); - emit_op1(p, OPCODE_MOV, res0, 0, _col0); - } + { + struct ureg res0 = register_output( p, VERT_RESULT_COL0 ); + emit_op1(p, OPCODE_MOV, res0, 0, _col0); + } - if (separate) { - struct ureg res1 = register_output( p, VERT_RESULT_COL1 ); - emit_op1(p, OPCODE_MOV, res1, 0, _col1); - } + if (separate) { + struct ureg res1 = register_output( p, VERT_RESULT_COL1 ); + emit_op1(p, OPCODE_MOV, res1, 0, _col1); + } - if (twoside) { - struct ureg res0 = register_output( p, VERT_RESULT_BFC0 ); - emit_op1(p, OPCODE_MOV, res0, 0, _bfc0); - } + if (twoside) { + struct ureg res0 = register_output( p, VERT_RESULT_BFC0 ); + emit_op1(p, OPCODE_MOV, res0, 0, _bfc0); + } - if (twoside && separate) { - struct ureg res1 = register_output( p, VERT_RESULT_BFC1 ); - emit_op1(p, OPCODE_MOV, res1, 0, _bfc1); - } + if (twoside && separate) { + struct ureg res1 = register_output( p, VERT_RESULT_BFC1 ); + emit_op1(p, OPCODE_MOV, res1, 0, _bfc1); + } if (nr_lights == 0) { release_temps(p); return; } - for (i = 0; i < MAX_LIGHTS; i++) { if (p->state->unit[i].light_enabled) { struct ureg half = undef; @@ -1006,7 +1004,7 @@ static void build_lighting( struct tnl_program *p ) VPpli = get_temp(p); half = get_temp(p); - /* Calulate VPpli vector + /* Calculate VPpli vector */ emit_op2(p, OPCODE_SUB, VPpli, 0, Ppli, V); @@ -1017,15 +1015,13 @@ static void build_lighting( struct tnl_program *p ) emit_op1(p, OPCODE_RSQ, dist, 0, dist); emit_op2(p, OPCODE_MUL, VPpli, 0, VPpli, dist); - - /* Calculate attenuation: + /* Calculate attenuation: */ if (!p->state->unit[i].light_spotcutoff_is_180 || p->state->unit[i].light_attenuated) { att = calculate_light_attenuation(p, i, VPpli, dist); } - - + /* Calculate viewer direction, or use infinite viewer: */ if (p->state->light_local_viewer) { @@ -1047,7 +1043,6 @@ static void build_lighting( struct tnl_program *p ) emit_op2(p, OPCODE_DP3, dots, WRITEMASK_X, normal, VPpli); emit_op2(p, OPCODE_DP3, dots, WRITEMASK_Y, normal, half); - /* Front face lighting: */ { -- cgit v1.2.3 From 103ae5d16fd9fef566096570f731bb634a8025d4 Mon Sep 17 00:00:00 2001 From: Brian Date: Tue, 6 May 2008 22:13:06 -0600 Subject: gallium: implement full reference counting for vertex/fragment programs Use _mesa_reference_vert/fragprog() wherever we assign program pointers. Fixes a memory corruption bug found with glean/api2 test. Another memory bug involving shaders yet to be fixed... --- src/mesa/main/context.c | 26 ++++---- src/mesa/main/mtypes.h | 4 +- src/mesa/main/state.c | 32 ++++++---- src/mesa/shader/prog_cache.c | 5 +- src/mesa/shader/program.c | 103 +++++++++++++++++++++----------- src/mesa/shader/program.h | 22 +++++++ src/mesa/shader/shader_api.c | 6 +- src/mesa/shader/slang/slang_link.c | 12 ++-- src/mesa/state_tracker/st_atom_shader.c | 7 ++- src/mesa/state_tracker/st_context.c | 3 + src/mesa/state_tracker/st_program.h | 24 +++++++- 11 files changed, 170 insertions(+), 74 deletions(-) (limited to 'src') diff --git a/src/mesa/main/context.c b/src/mesa/main/context.c index 7b8d9341701..b9053344b26 100755 --- a/src/mesa/main/context.c +++ b/src/mesa/main/context.c @@ -150,8 +150,6 @@ int MESA_DEBUG_FLAGS = 0; /* ubyte -> float conversion */ GLfloat _mesa_ubyte_to_float_color_tab[256]; -static void -free_shared_state( GLcontext *ctx, struct gl_shared_state *ss ); /** @@ -423,12 +421,14 @@ alloc_shared_state( GLcontext *ctx ) #endif #if FEATURE_ARB_vertex_program - ss->DefaultVertexProgram = ctx->Driver.NewProgram(ctx, GL_VERTEX_PROGRAM_ARB, 0); + ss->DefaultVertexProgram = (struct gl_vertex_program *) + ctx->Driver.NewProgram(ctx, GL_VERTEX_PROGRAM_ARB, 0); if (!ss->DefaultVertexProgram) goto cleanup; #endif #if FEATURE_ARB_fragment_program - ss->DefaultFragmentProgram = ctx->Driver.NewProgram(ctx, GL_FRAGMENT_PROGRAM_ARB, 0); + ss->DefaultFragmentProgram = (struct gl_fragment_program *) + ctx->Driver.NewProgram(ctx, GL_FRAGMENT_PROGRAM_ARB, 0); if (!ss->DefaultFragmentProgram) goto cleanup; #endif @@ -513,12 +513,10 @@ alloc_shared_state( GLcontext *ctx ) _mesa_DeleteHashTable(ss->Programs); #endif #if FEATURE_ARB_vertex_program - if (ss->DefaultVertexProgram) - ctx->Driver.DeleteProgram(ctx, ss->DefaultVertexProgram); + _mesa_reference_vertprog(ctx, &ss->DefaultVertexProgram, NULL); #endif #if FEATURE_ARB_fragment_program - if (ss->DefaultFragmentProgram) - ctx->Driver.DeleteProgram(ctx, ss->DefaultFragmentProgram); + _mesa_reference_fragprog(ctx, &ss->DefaultFragmentProgram, NULL); #endif #if FEATURE_ATI_fragment_shader if (ss->DefaultFragmentShader) @@ -695,10 +693,10 @@ free_shared_state( GLcontext *ctx, struct gl_shared_state *ss ) _mesa_DeleteHashTable(ss->Programs); #endif #if FEATURE_ARB_vertex_program - ctx->Driver.DeleteProgram(ctx, ss->DefaultVertexProgram); + _mesa_reference_vertprog(ctx, &ss->DefaultVertexProgram, NULL); #endif #if FEATURE_ARB_fragment_program - ctx->Driver.DeleteProgram(ctx, ss->DefaultFragmentProgram); + _mesa_reference_fragprog(ctx, &ss->DefaultFragmentProgram, NULL); #endif #if FEATURE_ATI_fragment_shader @@ -1190,6 +1188,14 @@ _mesa_free_context_data( GLcontext *ctx ) _mesa_unreference_framebuffer(&ctx->ReadBuffer); } + _mesa_reference_vertprog(ctx, &ctx->VertexProgram.Current, NULL); + _mesa_reference_vertprog(ctx, &ctx->VertexProgram._Current, NULL); + _mesa_reference_vertprog(ctx, &ctx->VertexProgram._TnlProgram, NULL); + + _mesa_reference_fragprog(ctx, &ctx->FragmentProgram.Current, NULL); + _mesa_reference_fragprog(ctx, &ctx->FragmentProgram._Current, NULL); + _mesa_reference_fragprog(ctx, &ctx->FragmentProgram._TexEnvProgram, NULL); + _mesa_free_lighting_data( ctx ); _mesa_free_eval_data( ctx ); _mesa_free_texture_data( ctx ); diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h index 50b22d25bf3..463142fe395 100644 --- a/src/mesa/main/mtypes.h +++ b/src/mesa/main/mtypes.h @@ -2203,10 +2203,10 @@ struct gl_shared_state /*@{*/ struct _mesa_HashTable *Programs; /**< All vertex/fragment programs */ #if FEATURE_ARB_vertex_program - struct gl_program *DefaultVertexProgram; + struct gl_vertex_program *DefaultVertexProgram; #endif #if FEATURE_ARB_fragment_program - struct gl_program *DefaultFragmentProgram; + struct gl_fragment_program *DefaultFragmentProgram; #endif /*@}*/ diff --git a/src/mesa/main/state.c b/src/mesa/main/state.c index 0b1c56fdd5f..90379a17726 100644 --- a/src/mesa/main/state.c +++ b/src/mesa/main/state.c @@ -982,16 +982,20 @@ update_program(GLcontext *ctx) #endif if (shProg && shProg->LinkStatus && shProg->FragmentProgram) { /* user-defined fragment shader */ - ctx->FragmentProgram._Current = shProg->FragmentProgram; + _mesa_reference_fragprog(ctx, &ctx->FragmentProgram._Current, + shProg->FragmentProgram); } else if (ctx->FragmentProgram._Enabled) { /* use user-defined fragment program */ - ctx->FragmentProgram._Current = ctx->FragmentProgram.Current; + _mesa_reference_fragprog(ctx, &ctx->FragmentProgram._Current, + ctx->FragmentProgram.Current); } else if (ctx->FragmentProgram._MaintainTexEnvProgram) { /* fragment program generated from fixed-function state */ - ctx->FragmentProgram._Current = _mesa_get_fixed_func_fragment_program(ctx); - ctx->FragmentProgram._TexEnvProgram = ctx->FragmentProgram._Current; + _mesa_reference_fragprog(ctx, &ctx->FragmentProgram._Current, + _mesa_get_fixed_func_fragment_program(ctx)); + _mesa_reference_fragprog(ctx, &ctx->FragmentProgram._TexEnvProgram, + ctx->FragmentProgram._Current); /* XXX get rid of this confusing stuff someday? */ ctx->FragmentProgram._Active = ctx->FragmentProgram._Enabled; @@ -1000,7 +1004,7 @@ update_program(GLcontext *ctx) } else { /* no fragment program */ - ctx->FragmentProgram._Current = NULL; + _mesa_reference_fragprog(ctx, &ctx->FragmentProgram._Current, NULL); } if (ctx->FragmentProgram._Current != prevFP && ctx->Driver.BindProgram) { @@ -1013,29 +1017,33 @@ update_program(GLcontext *ctx) **/ #if 1 /* XXX get rid of this someday? */ - ctx->VertexProgram._TnlProgram = NULL; + _mesa_reference_vertprog(ctx, &ctx->VertexProgram._TnlProgram, NULL); #endif if (shProg && shProg->LinkStatus && shProg->VertexProgram) { /* user-defined vertex shader */ - ctx->VertexProgram._Current = shProg->VertexProgram; + _mesa_reference_vertprog(ctx, &ctx->VertexProgram._Current, + shProg->VertexProgram); } else if (ctx->VertexProgram._Enabled) { /* use user-defined vertex program */ - ctx->VertexProgram._Current = ctx->VertexProgram.Current; + _mesa_reference_vertprog(ctx, &ctx->VertexProgram._Current, + ctx->VertexProgram.Current); } else if (ctx->VertexProgram._MaintainTnlProgram) { /* vertex program generated from fixed-function state */ - ctx->VertexProgram._Current = _mesa_get_fixed_func_vertex_program(ctx); - ctx->VertexProgram._TnlProgram = ctx->VertexProgram._Current; + _mesa_reference_vertprog(ctx, &ctx->VertexProgram._Current, + _mesa_get_fixed_func_vertex_program(ctx)); + _mesa_reference_vertprog(ctx, &ctx->VertexProgram._TnlProgram, + ctx->VertexProgram._Current); } else { /* no vertex program / used fixed-function code */ - ctx->VertexProgram._Current = NULL; + _mesa_reference_vertprog(ctx, &ctx->VertexProgram._Current, NULL); } if (ctx->VertexProgram._Current != prevVP && ctx->Driver.BindProgram) { ctx->Driver.BindProgram(ctx, GL_VERTEX_PROGRAM_ARB, - (struct gl_program *) ctx->VertexProgram._Current); + (struct gl_program *) ctx->VertexProgram._Current); } } diff --git a/src/mesa/shader/prog_cache.c b/src/mesa/shader/prog_cache.c index dd0241ef24e..36a25377c55 100644 --- a/src/mesa/shader/prog_cache.c +++ b/src/mesa/shader/prog_cache.c @@ -30,6 +30,7 @@ #include "main/mtypes.h" #include "main/imports.h" #include "shader/prog_cache.h" +#include "shader/program.h" struct cache_item @@ -109,7 +110,7 @@ clear_cache(GLcontext *ctx, struct gl_program_cache *cache) for (c = cache->items[i]; c; c = next) { next = c->next; _mesa_free(c->key); - ctx->Driver.DeleteProgram(ctx, c->program); + _mesa_reference_program(ctx, &c->program, NULL); _mesa_free(c); } cache->items[i] = NULL; @@ -177,7 +178,7 @@ _mesa_program_cache_insert(GLcontext *ctx, c->key = _mesa_malloc(keysize); memcpy(c->key, key, keysize); - c->program = program; + c->program = program; /* no refcount change */ if (cache->n_items > cache->size * 1.5) { if (cache->size < 1000) diff --git a/src/mesa/shader/program.c b/src/mesa/shader/program.c index 0ed7f833d20..9a23c5d7d31 100644 --- a/src/mesa/shader/program.c +++ b/src/mesa/shader/program.c @@ -60,9 +60,9 @@ _mesa_init_program(GLcontext *ctx) ctx->VertexProgram.Enabled = GL_FALSE; ctx->VertexProgram.PointSizeEnabled = GL_FALSE; ctx->VertexProgram.TwoSideEnabled = GL_FALSE; - ctx->VertexProgram.Current = (struct gl_vertex_program *) ctx->Shared->DefaultVertexProgram; + _mesa_reference_vertprog(ctx, &ctx->VertexProgram.Current, + ctx->Shared->DefaultVertexProgram); assert(ctx->VertexProgram.Current); - ctx->VertexProgram.Current->Base.RefCount++; for (i = 0; i < MAX_NV_VERTEX_PROGRAM_PARAMS / 4; i++) { ctx->VertexProgram.TrackMatrix[i] = GL_NONE; ctx->VertexProgram.TrackMatrixTransform[i] = GL_IDENTITY_NV; @@ -72,9 +72,9 @@ _mesa_init_program(GLcontext *ctx) #if FEATURE_NV_fragment_program || FEATURE_ARB_fragment_program ctx->FragmentProgram.Enabled = GL_FALSE; - ctx->FragmentProgram.Current = (struct gl_fragment_program *) ctx->Shared->DefaultFragmentProgram; + _mesa_reference_fragprog(ctx, &ctx->FragmentProgram.Current, + ctx->Shared->DefaultFragmentProgram); assert(ctx->FragmentProgram.Current); - ctx->FragmentProgram.Current->Base.RefCount++; ctx->FragmentProgram.Cache = _mesa_new_program_cache(); #endif @@ -96,19 +96,11 @@ void _mesa_free_program_data(GLcontext *ctx) { #if FEATURE_NV_vertex_program || FEATURE_ARB_vertex_program - if (ctx->VertexProgram.Current) { - ctx->VertexProgram.Current->Base.RefCount--; - if (ctx->VertexProgram.Current->Base.RefCount <= 0) - ctx->Driver.DeleteProgram(ctx, &(ctx->VertexProgram.Current->Base)); - } + _mesa_reference_vertprog(ctx, &ctx->VertexProgram.Current, NULL); _mesa_delete_program_cache(ctx, ctx->VertexProgram.Cache); #endif #if FEATURE_NV_fragment_program || FEATURE_ARB_fragment_program - if (ctx->FragmentProgram.Current) { - ctx->FragmentProgram.Current->Base.RefCount--; - if (ctx->FragmentProgram.Current->Base.RefCount <= 0) - ctx->Driver.DeleteProgram(ctx, &(ctx->FragmentProgram.Current->Base)); - } + _mesa_reference_fragprog(ctx, &ctx->FragmentProgram.Current, NULL); _mesa_delete_program_cache(ctx, ctx->FragmentProgram.Cache); #endif /* XXX probably move this stuff */ @@ -325,6 +317,59 @@ _mesa_lookup_program(GLcontext *ctx, GLuint id) } +/** + * Reference counting for vertex/fragment programs + */ +void +_mesa_reference_program(GLcontext *ctx, + struct gl_program **ptr, + struct gl_program *prog) +{ + assert(ptr); + if (*ptr && prog) { + /* sanity check */ + ASSERT((*ptr)->Target == prog->Target); + } + if (*ptr == prog) { + return; /* no change */ + } + if (*ptr) { + GLboolean deleteFlag; + + /*_glthread_LOCK_MUTEX((*ptr)->Mutex);*/ +#if 0 + printf("Program %p %u 0x%x Refcount-- to %d\n", + *ptr, (*ptr)->Id, (*ptr)->Target, (*ptr)->RefCount - 1); +#endif + ASSERT((*ptr)->RefCount > 0); + (*ptr)->RefCount--; + + deleteFlag = ((*ptr)->RefCount == 0); + /*_glthread_UNLOCK_MUTEX((*ptr)->Mutex);*/ + + if (deleteFlag) { + ASSERT(ctx); + ctx->Driver.DeleteProgram(ctx, *ptr); + } + + *ptr = NULL; + } + + assert(!*ptr); + if (prog) { + /*_glthread_LOCK_MUTEX(prog->Mutex);*/ + prog->RefCount++; +#if 0 + printf("Program %p %u 0x%x Refcount++ to %d\n", + prog, prog->Id, prog->Target, prog->RefCount); +#endif + /*_glthread_UNLOCK_MUTEX(prog->Mutex);*/ + } + + *ptr = prog; +} + + /** * Return a copy of a program. * XXX Problem here if the program object is actually OO-derivation @@ -340,8 +385,9 @@ _mesa_clone_program(GLcontext *ctx, const struct gl_program *prog) return NULL; assert(clone->Target == prog->Target); + assert(clone->RefCount == 1); + clone->String = (GLubyte *) _mesa_strdup((char *) prog->String); - clone->RefCount = 1; clone->Format = prog->Format; clone->Instructions = _mesa_alloc_instructions(prog->NumInstructions); if (!clone->Instructions) { @@ -704,9 +750,9 @@ _mesa_BindProgram(GLenum target, GLuint id) /* Bind a default program */ newProg = NULL; if (target == GL_VERTEX_PROGRAM_ARB) /* == GL_VERTEX_PROGRAM_NV */ - newProg = ctx->Shared->DefaultVertexProgram; + newProg = &ctx->Shared->DefaultVertexProgram->Base; else - newProg = ctx->Shared->DefaultFragmentProgram; + newProg = &ctx->Shared->DefaultFragmentProgram->Base; } else { /* Bind a user program */ @@ -734,26 +780,16 @@ _mesa_BindProgram(GLenum target, GLuint id) return; } - /* unbind/delete oldProg */ - if (curProg->Id != 0) { - /* decrement refcount on previously bound fragment program */ - curProg->RefCount--; - /* and delete if refcount goes below one */ - if (curProg->RefCount <= 0) { - /* the program ID was already removed from the hash table */ - ctx->Driver.DeleteProgram(ctx, curProg); - } - } - /* bind newProg */ if (target == GL_VERTEX_PROGRAM_ARB) { /* == GL_VERTEX_PROGRAM_NV */ - ctx->VertexProgram.Current = (struct gl_vertex_program *) newProg; + _mesa_reference_vertprog(ctx, &ctx->VertexProgram.Current, + (struct gl_vertex_program *) newProg); } else if (target == GL_FRAGMENT_PROGRAM_NV || target == GL_FRAGMENT_PROGRAM_ARB) { - ctx->FragmentProgram.Current = (struct gl_fragment_program *) newProg; + _mesa_reference_fragprog(ctx, &ctx->FragmentProgram.Current, + (struct gl_fragment_program *) newProg); } - newProg->RefCount++; /* Never null pointers */ ASSERT(ctx->VertexProgram.Current); @@ -811,10 +847,7 @@ _mesa_DeletePrograms(GLsizei n, const GLuint *ids) } /* The ID is immediately available for re-use now */ _mesa_HashRemove(ctx->Shared->Programs, ids[i]); - prog->RefCount--; - if (prog->RefCount <= 0) { - ctx->Driver.DeleteProgram(ctx, prog); - } + _mesa_reference_program(ctx, &prog, NULL); } } } diff --git a/src/mesa/shader/program.h b/src/mesa/shader/program.h index 414a57d39cc..08fe576afc1 100644 --- a/src/mesa/shader/program.h +++ b/src/mesa/shader/program.h @@ -83,6 +83,28 @@ _mesa_delete_program(GLcontext *ctx, struct gl_program *prog); extern struct gl_program * _mesa_lookup_program(GLcontext *ctx, GLuint id); +extern void +_mesa_reference_program(GLcontext *ctx, + struct gl_program **ptr, + struct gl_program *prog); + +static INLINE void +_mesa_reference_vertprog(GLcontext *ctx, + struct gl_vertex_program **ptr, + struct gl_vertex_program *prog) +{ + _mesa_reference_program(ctx, (struct gl_program **) ptr, + (struct gl_program *) prog); +} + +static INLINE void +_mesa_reference_fragprog(GLcontext *ctx, + struct gl_fragment_program **ptr, + struct gl_fragment_program *prog) +{ + _mesa_reference_program(ctx, (struct gl_program **) ptr, + (struct gl_program *) prog); +} extern struct gl_program * _mesa_clone_program(GLcontext *ctx, const struct gl_program *prog); diff --git a/src/mesa/shader/shader_api.c b/src/mesa/shader/shader_api.c index 9c419c9903f..f12fa28d97b 100644 --- a/src/mesa/shader/shader_api.c +++ b/src/mesa/shader/shader_api.c @@ -80,8 +80,7 @@ _mesa_clear_shader_program_data(GLcontext *ctx, * original/unlinked program. */ shProg->VertexProgram->Base.Parameters = NULL; - ctx->Driver.DeleteProgram(ctx, &shProg->VertexProgram->Base); - shProg->VertexProgram = NULL; + _mesa_reference_vertprog(ctx, &shProg->VertexProgram, NULL); } if (shProg->FragmentProgram) { @@ -89,8 +88,7 @@ _mesa_clear_shader_program_data(GLcontext *ctx, * original/unlinked program. */ shProg->FragmentProgram->Base.Parameters = NULL; - ctx->Driver.DeleteProgram(ctx, &shProg->FragmentProgram->Base); - shProg->FragmentProgram = NULL; + _mesa_reference_fragprog(ctx, &shProg->FragmentProgram, NULL); } if (shProg->Uniforms) { diff --git a/src/mesa/shader/slang/slang_link.c b/src/mesa/shader/slang/slang_link.c index addff204218..ae581553dc7 100644 --- a/src/mesa/shader/slang/slang_link.c +++ b/src/mesa/shader/slang/slang_link.c @@ -410,19 +410,19 @@ _slang_link(GLcontext *ctx, * changing src/dst registers after merging the uniforms and varying vars. */ if (vertProg) { - shProg->VertexProgram - = vertex_program(_mesa_clone_program(ctx, &vertProg->Base)); + _mesa_reference_vertprog(ctx, &shProg->VertexProgram, + vertex_program(_mesa_clone_program(ctx, &vertProg->Base))); } else { - shProg->VertexProgram = NULL; + _mesa_reference_vertprog(ctx, &shProg->VertexProgram, NULL); } if (fragProg) { - shProg->FragmentProgram - = fragment_program(_mesa_clone_program(ctx, &fragProg->Base)); + _mesa_reference_fragprog(ctx, &shProg->FragmentProgram, + fragment_program(_mesa_clone_program(ctx, &fragProg->Base))); } else { - shProg->FragmentProgram = NULL; + _mesa_reference_fragprog(ctx, &shProg->FragmentProgram, NULL); } /* link varying vars */ diff --git a/src/mesa/state_tracker/st_atom_shader.c b/src/mesa/state_tracker/st_atom_shader.c index 652500f52a2..7745591afba 100644 --- a/src/mesa/state_tracker/st_atom_shader.c +++ b/src/mesa/state_tracker/st_atom_shader.c @@ -39,6 +39,7 @@ #include "main/imports.h" #include "main/mtypes.h" +#include "shader/program.h" #include "pipe/p_context.h" #include "pipe/p_shader_tokens.h" @@ -264,14 +265,16 @@ update_linkage( struct st_context *st ) */ assert(st->ctx->VertexProgram._Current); stvp = st_vertex_program(st->ctx->VertexProgram._Current); + assert(stvp->Base.Base.Target == GL_VERTEX_PROGRAM_ARB); assert(st->ctx->FragmentProgram._Current); stfp = st_fragment_program(st->ctx->FragmentProgram._Current); + assert(stfp->Base.Base.Target == GL_FRAGMENT_PROGRAM_ARB); xvp = find_translated_vp(st, stvp, stfp); - st->vp = stvp; - st->fp = stfp; + st_reference_vertprog(st, &st->vp, stvp); + st_reference_fragprog(st, &st->fp, stfp); cso_set_vertex_shader_handle(st->cso_context, stvp->driver_shader); cso_set_fragment_shader_handle(st->cso_context, stfp->driver_shader); diff --git a/src/mesa/state_tracker/st_context.c b/src/mesa/state_tracker/st_context.c index c900064f2b8..8db55a179f8 100644 --- a/src/mesa/state_tracker/st_context.c +++ b/src/mesa/state_tracker/st_context.c @@ -158,6 +158,9 @@ static void st_destroy_context_priv( struct st_context *st ) { uint i; + st_reference_fragprog(st, &st->fp, NULL); + st_reference_vertprog(st, &st->vp, NULL); + draw_destroy(st->draw); st_destroy_atoms( st ); st_destroy_draw( st ); diff --git a/src/mesa/state_tracker/st_program.h b/src/mesa/state_tracker/st_program.h index d8f26da2eeb..bf07a50789e 100644 --- a/src/mesa/state_tracker/st_program.h +++ b/src/mesa/state_tracker/st_program.h @@ -34,7 +34,8 @@ #ifndef ST_PROGRAM_H #define ST_PROGRAM_H -#include "mtypes.h" +#include "main/mtypes.h" +#include "shader/program.h" #include "pipe/p_shader_tokens.h" @@ -115,6 +116,27 @@ st_vertex_program( struct gl_vertex_program *vp ) } +static INLINE void +st_reference_vertprog(struct st_context *st, + struct st_vertex_program **ptr, + struct st_vertex_program *prog) +{ + _mesa_reference_program(st->ctx, + (struct gl_program **) ptr, + (struct gl_program *) prog); +} + +static INLINE void +st_reference_fragprog(struct st_context *st, + struct st_fragment_program **ptr, + struct st_fragment_program *prog) +{ + _mesa_reference_program(st->ctx, + (struct gl_program **) ptr, + (struct gl_program *) prog); +} + + extern void st_translate_fragment_program(struct st_context *st, struct st_fragment_program *fp, -- cgit v1.2.3 From 05370685fedab9608d6b5b5de7042dac4289e522 Mon Sep 17 00:00:00 2001 From: Brian Date: Tue, 6 May 2008 23:08:02 -0600 Subject: mesa: free shader program data before deleting shader objects. Picked from master. Fixes mem corruption seen when glean/api2 test exits. --- src/mesa/main/context.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) (limited to 'src') diff --git a/src/mesa/main/context.c b/src/mesa/main/context.c index b9053344b26..893c79f28ca 100755 --- a/src/mesa/main/context.c +++ b/src/mesa/main/context.c @@ -630,6 +630,21 @@ delete_arrayobj_cb(GLuint id, void *data, void *userData) _mesa_delete_array_object(ctx, arrayObj); } +/** + * Callback for freeing shader program data. Call it before delete_shader_cb + * to avoid memory access error. + */ +static void +free_shader_program_data_cb(GLuint id, void *data, void *userData) +{ + GLcontext *ctx = (GLcontext *) userData; + struct gl_shader_program *shProg = (struct gl_shader_program *) data; + + if (shProg->Type == GL_SHADER_PROGRAM_MESA) { + _mesa_free_shader_program_data(ctx, shProg); + } +} + /** * Callback for deleting shader and shader programs objects. * Called by _mesa_HashDeleteAll(). @@ -714,6 +729,7 @@ free_shared_state( GLcontext *ctx, struct gl_shared_state *ss ) _mesa_DeleteHashTable(ss->ArrayObjects); #if FEATURE_ARB_shader_objects + _mesa_HashWalk(ss->ShaderObjects, free_shader_program_data_cb, ctx); _mesa_HashDeleteAll(ss->ShaderObjects, delete_shader_cb, ctx); _mesa_DeleteHashTable(ss->ShaderObjects); #endif -- cgit v1.2.3