diff options
author | Brian Paul <[email protected]> | 2019-03-12 16:01:56 -0600 |
---|---|---|
committer | Brian Paul <[email protected]> | 2019-03-17 20:07:22 -0600 |
commit | 41c4c49463f65cd6c564b2a66634ba6572a824fb (patch) | |
tree | 3c1850d8cdd5602aa9e4ce3f92336f64576e0ef7 /src/mesa/state_tracker/st_program.c | |
parent | 593e36f9561d3665cc12ed1fc8a07dd8612c004e (diff) |
st/mesa: implement "zombie" shaders list
As with the preceding patch for sampler views, this patch does
basically the same thing but for shaders. However, reference counting
isn't needed here (instead of calling cso_delete_XXX_shader() we call
st_save_zombie_shader().
The Redway3D Watch is one app/demo that needs this change. Otherwise,
the vmwgfx driver generates an error about trying to destroy a shader
ID that doesn't exist in the context.
Note that if PIPE_CAP_SHAREABLE_SHADERS = TRUE, then we can use/delete
any shader with any context and this mechanism is not used.
Tested with: google-chrome, google earth, Redway3D Watch/Turbine demos
and a few Linux games.
Reviewed-by: Roland Scheidegger <[email protected]>
Reviewed-by: Neha Bhende <[email protected]>
Reviewed-by: Mathias Fröhlich <[email protected]>
Reviewed-By: Jose Fonseca <[email protected]>
Diffstat (limited to 'src/mesa/state_tracker/st_program.c')
-rw-r--r-- | src/mesa/state_tracker/st_program.c | 77 |
1 files changed, 57 insertions, 20 deletions
diff --git a/src/mesa/state_tracker/st_program.c b/src/mesa/state_tracker/st_program.c index 0df800a60e0..9f6e492d6fb 100644 --- a/src/mesa/state_tracker/st_program.c +++ b/src/mesa/state_tracker/st_program.c @@ -229,9 +229,15 @@ delete_ir(struct pipe_shader_state *ir) static void delete_vp_variant(struct st_context *st, struct st_vp_variant *vpv) { - if (vpv->driver_shader) - cso_delete_vertex_shader(st->cso_context, vpv->driver_shader); - + if (vpv->driver_shader) { + if (st->has_shareable_shaders || vpv->key.st == st) { + cso_delete_vertex_shader(st->cso_context, vpv->driver_shader); + } else { + st_save_zombie_shader(vpv->key.st, PIPE_SHADER_VERTEX, + vpv->driver_shader); + } + } + if (vpv->draw_shader) draw_delete_vertex_shader( st->draw, vpv->draw_shader ); @@ -271,8 +277,15 @@ st_release_vp_variants( struct st_context *st, static void delete_fp_variant(struct st_context *st, struct st_fp_variant *fpv) { - if (fpv->driver_shader) - cso_delete_fragment_shader(st->cso_context, fpv->driver_shader); + if (fpv->driver_shader) { + if (st->has_shareable_shaders || fpv->key.st == st) { + cso_delete_fragment_shader(st->cso_context, fpv->driver_shader); + } else { + st_save_zombie_shader(fpv->key.st, PIPE_SHADER_FRAGMENT, + fpv->driver_shader); + } + } + free(fpv); } @@ -306,21 +319,45 @@ delete_basic_variant(struct st_context *st, struct st_basic_variant *v, GLenum target) { if (v->driver_shader) { - switch (target) { - case GL_TESS_CONTROL_PROGRAM_NV: - cso_delete_tessctrl_shader(st->cso_context, v->driver_shader); - break; - case GL_TESS_EVALUATION_PROGRAM_NV: - cso_delete_tesseval_shader(st->cso_context, v->driver_shader); - break; - case GL_GEOMETRY_PROGRAM_NV: - cso_delete_geometry_shader(st->cso_context, v->driver_shader); - break; - case GL_COMPUTE_PROGRAM_NV: - cso_delete_compute_shader(st->cso_context, v->driver_shader); - break; - default: - assert(!"this shouldn't occur"); + if (st->has_shareable_shaders || v->key.st == st) { + /* The shader's context matches the calling context, or we + * don't care. + */ + switch (target) { + case GL_TESS_CONTROL_PROGRAM_NV: + cso_delete_tessctrl_shader(st->cso_context, v->driver_shader); + break; + case GL_TESS_EVALUATION_PROGRAM_NV: + cso_delete_tesseval_shader(st->cso_context, v->driver_shader); + break; + case GL_GEOMETRY_PROGRAM_NV: + cso_delete_geometry_shader(st->cso_context, v->driver_shader); + break; + case GL_COMPUTE_PROGRAM_NV: + cso_delete_compute_shader(st->cso_context, v->driver_shader); + break; + default: + unreachable("bad shader type in delete_basic_variant"); + } + } else { + /* We can't delete a shader with a context different from the one + * that created it. Add it to the creating context's zombie list. + */ + enum pipe_shader_type type; + switch (target) { + case GL_TESS_CONTROL_PROGRAM_NV: + type = PIPE_SHADER_TESS_CTRL; + break; + case GL_TESS_EVALUATION_PROGRAM_NV: + type = PIPE_SHADER_TESS_EVAL; + break; + case GL_GEOMETRY_PROGRAM_NV: + type = PIPE_SHADER_GEOMETRY; + break; + default: + unreachable(""); + } + st_save_zombie_shader(v->key.st, type, v->driver_shader); } } |