diff options
author | Ben Skeggs <[email protected]> | 2008-05-14 18:13:36 +1000 |
---|---|---|
committer | Ben Skeggs <[email protected]> | 2008-05-14 18:13:36 +1000 |
commit | bc1696862c9ffa8d8f2c11d3120310e82f2e9327 (patch) | |
tree | a212a92776a05fb1ef09d1ea1864d9cc1e315440 /src/mesa | |
parent | 666ac923f016b1b231c5a8847cbe084321f697ca (diff) | |
parent | 19f15277d1871b62902031f9fa9aabf2f1bc7c40 (diff) |
Merge remote branch 'upstream/gallium-0.1' into nouveau-gallium-0.1
Diffstat (limited to 'src/mesa')
-rwxr-xr-x | src/mesa/main/context.c | 42 | ||||
-rw-r--r-- | src/mesa/main/ffvertex_prog.c | 43 | ||||
-rw-r--r-- | src/mesa/main/imports.c | 36 | ||||
-rw-r--r-- | src/mesa/main/mtypes.h | 4 | ||||
-rw-r--r-- | src/mesa/main/state.c | 32 | ||||
-rw-r--r-- | src/mesa/shader/prog_cache.c | 5 | ||||
-rw-r--r-- | src/mesa/shader/program.c | 103 | ||||
-rw-r--r-- | src/mesa/shader/program.h | 22 | ||||
-rw-r--r-- | src/mesa/shader/shader_api.c | 6 | ||||
-rw-r--r-- | src/mesa/shader/slang/slang_link.c | 12 | ||||
-rw-r--r-- | src/mesa/state_tracker/st_atom.h | 28 | ||||
-rw-r--r-- | src/mesa/state_tracker/st_atom_shader.c | 7 | ||||
-rw-r--r-- | src/mesa/state_tracker/st_cb_texture.c | 2 | ||||
-rw-r--r-- | src/mesa/state_tracker/st_context.c | 3 | ||||
-rw-r--r-- | src/mesa/state_tracker/st_program.h | 24 |
15 files changed, 237 insertions, 132 deletions
diff --git a/src/mesa/main/context.c b/src/mesa/main/context.c index 7b8d9341701..893c79f28ca 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) @@ -633,6 +631,21 @@ delete_arrayobj_cb(GLuint id, void *data, void *userData) } /** + * 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(). */ @@ -695,10 +708,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 @@ -716,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 @@ -1190,6 +1204,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/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: */ { diff --git a/src/mesa/main/imports.c b/src/mesa/main/imports.c index d8d35af15e2..d798f80e253 100644 --- a/src/mesa/main/imports.c +++ b/src/mesa/main/imports.c @@ -542,26 +542,24 @@ int _mesa_ffs(int i) { #if (defined(_WIN32) && !defined(__MINGW32__) ) || defined(__IBMC__) || defined(__IBMCPP__) - register int bit = 0; - if (i != 0) { - if ((i & 0xffff) == 0) { - bit += 16; - i >>= 16; - } - if ((i & 0xff) == 0) { - bit += 8; - i >>= 8; - } - if ((i & 0xf) == 0) { - bit += 4; - i >>= 4; - } - while ((i & 1) == 0) { - bit++; - i >>= 1; - } + register int bit = 1; + if ((i & 0xffff) == 0) { + bit += 16; + i >>= 16; + } + if ((i & 0xff) == 0) { + bit += 8; + i >>= 8; + } + if ((i & 0xf) == 0) { + bit += 4; + i >>= 4; + } + if ((i & 0x3) == 0) { + bit += 2; + i >>= 2; } - return bit; + return (i) ? (bit + ((i + 1) & 0x01)) : 0; #else return ffs(i); #endif 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 */ @@ -326,6 +318,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 * made by a device driver. @@ -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.h b/src/mesa/state_tracker/st_atom.h index 3a63e2dec03..c6c6eba8121 100644 --- a/src/mesa/state_tracker/st_atom.h +++ b/src/mesa/state_tracker/st_atom.h @@ -44,20 +44,20 @@ void st_destroy_atoms( struct st_context *st ); void st_validate_state( struct st_context *st ); -const struct st_tracked_state st_update_framebuffer; -const struct st_tracked_state st_update_clip; -const struct st_tracked_state st_update_depth_stencil_alpha; -const struct st_tracked_state st_update_shader; -const struct st_tracked_state st_update_rasterizer; -const struct st_tracked_state st_update_polygon_stipple; -const struct st_tracked_state st_update_viewport; -const struct st_tracked_state st_update_scissor; -const struct st_tracked_state st_update_blend; -const struct st_tracked_state st_update_sampler; -const struct st_tracked_state st_update_texture; -const struct st_tracked_state st_update_fs_constants; -const struct st_tracked_state st_update_vs_constants; -const struct st_tracked_state st_update_pixel_transfer; +extern const struct st_tracked_state st_update_framebuffer; +extern const struct st_tracked_state st_update_clip; +extern const struct st_tracked_state st_update_depth_stencil_alpha; +extern const struct st_tracked_state st_update_shader; +extern const struct st_tracked_state st_update_rasterizer; +extern const struct st_tracked_state st_update_polygon_stipple; +extern const struct st_tracked_state st_update_viewport; +extern const struct st_tracked_state st_update_scissor; +extern const struct st_tracked_state st_update_blend; +extern const struct st_tracked_state st_update_sampler; +extern const struct st_tracked_state st_update_texture; +extern const struct st_tracked_state st_update_fs_constants; +extern const struct st_tracked_state st_update_vs_constants; +extern const struct st_tracked_state st_update_pixel_transfer; uint st_compare_func_to_pipe(GLenum func); 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_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: 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, |