diff options
author | Brian Paul <brianp@vmware.com> | 2010-12-10 14:59:32 -0700 |
---|---|---|
committer | Brian Paul <brianp@vmware.com> | 2010-12-10 14:59:34 -0700 |
commit | 2cc926183f957f8abac18d71276dd5bbd1f27be2 (patch) | |
tree | c629d85a4cd3d3956e9a5e33eec09171a187d716 | |
parent | b3d2ec9942303d1d03e28a25b030eb060415abfb (diff) |
st/mesa: make vertex shader variants per-context
Gallium shaders are per-context but OpenGL shaders aren't. So we need
to make a different variant for each context.
During context tear-down we need to walk over all shaders/programs and
free all variants for the context being destroyed.
-rw-r--r-- | src/mesa/state_tracker/st_atom_shader.c | 1 | ||||
-rw-r--r-- | src/mesa/state_tracker/st_context.c | 2 | ||||
-rw-r--r-- | src/mesa/state_tracker/st_program.c | 155 | ||||
-rw-r--r-- | src/mesa/state_tracker/st_program.h | 4 |
4 files changed, 148 insertions, 14 deletions
diff --git a/src/mesa/state_tracker/st_atom_shader.c b/src/mesa/state_tracker/st_atom_shader.c index 05442ef91b..f0981629b5 100644 --- a/src/mesa/state_tracker/st_atom_shader.c +++ b/src/mesa/state_tracker/st_atom_shader.c @@ -106,6 +106,7 @@ find_translated_vp(struct st_context *st, st->ctx->Polygon.FrontMode != GL_FILL || st->ctx->Polygon.BackMode != GL_FILL)); + key.st = st; /* variants are per-context */ /* Do we need to throw away old translations after a change in the * GL program string? diff --git a/src/mesa/state_tracker/st_context.c b/src/mesa/state_tracker/st_context.c index 6ec9c699a2..21bb91f47a 100644 --- a/src/mesa/state_tracker/st_context.c +++ b/src/mesa/state_tracker/st_context.c @@ -252,6 +252,8 @@ void st_destroy_context( struct st_context *st ) _vbo_DestroyContext(st->ctx); + st_destroy_program_variants(st); + _mesa_free_context_data(ctx); st_destroy_context_priv(st); diff --git a/src/mesa/state_tracker/st_program.c b/src/mesa/state_tracker/st_program.c index aae2913c20..d7d9e0e36f 100644 --- a/src/mesa/state_tracker/st_program.c +++ b/src/mesa/state_tracker/st_program.c @@ -32,6 +32,7 @@ #include "main/imports.h" +#include "main/hash.h" #include "main/mtypes.h" #include "program/prog_print.h" #include "program/programopt.h" @@ -52,6 +53,29 @@ /** + * Delete a vertex program varient. Note the caller must unlink + * the varient from the linked list. + */ +static void +delete_vp_varient(struct st_context *st, struct st_vp_varient *vpv) +{ + if (vpv->driver_shader) + cso_delete_vertex_shader(st->cso_context, vpv->driver_shader); + +#if FEATURE_feedback || FEATURE_rastpos + if (vpv->draw_shader) + draw_delete_vertex_shader( st->draw, vpv->draw_shader ); +#endif + + if (vpv->tgsi.tokens) + st_free_tokens(vpv->tgsi.tokens); + + FREE( vpv ); +} + + + +/** * Clean out any old compilations: */ void @@ -62,20 +86,7 @@ st_vp_release_varients( struct st_context *st, for (vpv = stvp->varients; vpv; ) { struct st_vp_varient *next = vpv->next; - - if (vpv->driver_shader) - cso_delete_vertex_shader(st->cso_context, vpv->driver_shader); - -#if FEATURE_feedback || FEATURE_rastpos - if (vpv->draw_shader) - draw_delete_vertex_shader( st->draw, vpv->draw_shader ); -#endif - - if (vpv->tgsi.tokens) - st_free_tokens(vpv->tgsi.tokens); - - FREE( vpv ); - + delete_vp_varient(st, vpv); vpv = next; } @@ -759,3 +770,119 @@ st_print_shaders(struct gl_context *ctx) } } } + + +/** + * Vert/Geom/Frag programs have per-context variants. Free all the + * variants attached to the given program which match the given context. + */ +static void +destroy_program_variants(struct st_context *st, struct gl_program *program) +{ + if (!program) + return; + + switch (program->Target) { + case GL_VERTEX_PROGRAM_ARB: + { + struct st_vertex_program *stvp = (struct st_vertex_program *) program; + struct st_vp_varient *vpv, **prev = &stvp->varients; + + for (vpv = stvp->varients; vpv; ) { + struct st_vp_varient *next = vpv->next; + if (vpv->key.st == st) { + /* unlink from list */ + *prev = next; + /* destroy this variant */ + delete_vp_varient(st, vpv); + } + else { + prev = &vpv; + } + vpv = next; + } + } + break; + case GL_FRAGMENT_PROGRAM_ARB: + { + struct st_fragment_program *stfp = + (struct st_fragment_program *) program; + } + break; + default: + _mesa_problem(NULL, "Unexpected program target in " + "destroy_program_variants_cb()"); + } +} + + +/** + * Callback for _mesa_HashWalk. Free all the shader's program variants + * which match the given context. + */ +static void +destroy_shader_program_variants_cb(GLuint key, void *data, void *userData) +{ + struct st_context *st = (struct st_context *) userData; + struct gl_shader *shader = (struct gl_shader *) data; + + switch (shader->Type) { + case GL_SHADER_PROGRAM_MESA: + { + struct gl_shader_program *shProg = (struct gl_shader_program *) data; + GLuint i; + + for (i = 0; i < shProg->NumShaders; i++) { + destroy_program_variants(st, shProg->Shaders[i]->Program); + } + + destroy_program_variants(st, (struct gl_program *) + shProg->VertexProgram); + destroy_program_variants(st, (struct gl_program *) + shProg->FragmentProgram); + destroy_program_variants(st, (struct gl_program *) + shProg->GeometryProgram); + } + break; + case GL_VERTEX_SHADER: + case GL_FRAGMENT_SHADER: + case GL_GEOMETRY_SHADER: + { + destroy_program_variants(st, shader->Program); + } + break; + default: + assert(0); + } +} + + +/** + * Callback for _mesa_HashWalk. Free all the program variants which match + * the given context. + */ +static void +destroy_program_variants_cb(GLuint key, void *data, void *userData) +{ + struct st_context *st = (struct st_context *) userData; + struct gl_program *program = (struct gl_program *) data; + destroy_program_variants(st, program); +} + + +/** + * Walk over all shaders and programs to delete any variants which + * belong to the given context. + * This is called during context tear-down. + */ +void +st_destroy_program_variants(struct st_context *st) +{ + /* ARB vert/frag program */ + _mesa_HashWalk(st->ctx->Shared->Programs, + destroy_program_variants_cb, st); + + /* GLSL vert/frag/geom shaders */ + _mesa_HashWalk(st->ctx->Shared->ShaderObjects, + destroy_shader_program_variants_cb, st); +} diff --git a/src/mesa/state_tracker/st_program.h b/src/mesa/state_tracker/st_program.h index 72dbc715fe..10362ed93b 100644 --- a/src/mesa/state_tracker/st_program.h +++ b/src/mesa/state_tracker/st_program.h @@ -60,6 +60,7 @@ struct st_fragment_program struct st_vp_varient_key { + struct st_context *st; /**< variants are per-context */ boolean passthrough_edgeflags; }; @@ -225,5 +226,8 @@ st_vp_release_varients( struct st_context *st, extern void st_print_shaders(struct gl_context *ctx); +extern void +st_destroy_program_variants(struct st_context *st); + #endif |