mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-07 04:58:05 +02:00
gallium/cso_context: remove cso_delete_xxx_shader helpers to fix the live cache
With the live shader cache, equivalent shaders can be backed by the same CSO. This breaks the logic that identifies whether the shader being deleted is bound. For example, having shaders A and B, you can bind shader A and delete shader B. Deleting shader B will unbind shader A if they are equivalent. Pierre-Eric figured out the root cause for this issue. Fixes:0db74f479b- radeonsi: use the live shader cache Closes: #2596 Acked-by: Pierre-Eric Pelloux-Prayer <pierre-eric.pelloux-prayer@amd.com> Tested-by: Marge Bot <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/4078> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/4078> (cherry picked from commit2dc300421d)
This commit is contained in:
parent
e2db4624b7
commit
35dbf55ada
11 changed files with 75 additions and 107 deletions
|
|
@ -1471,7 +1471,7 @@
|
|||
"description": "gallium/cso_context: remove cso_delete_xxx_shader helpers to fix the live cache",
|
||||
"nominated": true,
|
||||
"nomination_type": 1,
|
||||
"resolution": 0,
|
||||
"resolution": 1,
|
||||
"master_sha": null,
|
||||
"because_sha": "0db74f479b9c5efe52c5d021fe04ba5ce1f4e1bd"
|
||||
},
|
||||
|
|
|
|||
|
|
@ -662,16 +662,6 @@ void cso_set_fragment_shader_handle(struct cso_context *ctx, void *handle )
|
|||
}
|
||||
}
|
||||
|
||||
void cso_delete_fragment_shader(struct cso_context *ctx, void *handle )
|
||||
{
|
||||
if (handle == ctx->fragment_shader) {
|
||||
/* unbind before deleting */
|
||||
ctx->pipe->bind_fs_state(ctx->pipe, NULL);
|
||||
ctx->fragment_shader = NULL;
|
||||
}
|
||||
ctx->pipe->delete_fs_state(ctx->pipe, handle);
|
||||
}
|
||||
|
||||
static void
|
||||
cso_save_fragment_shader(struct cso_context *ctx)
|
||||
{
|
||||
|
|
@ -698,16 +688,6 @@ void cso_set_vertex_shader_handle(struct cso_context *ctx, void *handle)
|
|||
}
|
||||
}
|
||||
|
||||
void cso_delete_vertex_shader(struct cso_context *ctx, void *handle )
|
||||
{
|
||||
if (handle == ctx->vertex_shader) {
|
||||
/* unbind before deleting */
|
||||
ctx->pipe->bind_vs_state(ctx->pipe, NULL);
|
||||
ctx->vertex_shader = NULL;
|
||||
}
|
||||
ctx->pipe->delete_vs_state(ctx->pipe, handle);
|
||||
}
|
||||
|
||||
static void
|
||||
cso_save_vertex_shader(struct cso_context *ctx)
|
||||
{
|
||||
|
|
@ -914,16 +894,6 @@ void cso_set_geometry_shader_handle(struct cso_context *ctx, void *handle)
|
|||
}
|
||||
}
|
||||
|
||||
void cso_delete_geometry_shader(struct cso_context *ctx, void *handle)
|
||||
{
|
||||
if (handle == ctx->geometry_shader) {
|
||||
/* unbind before deleting */
|
||||
ctx->pipe->bind_gs_state(ctx->pipe, NULL);
|
||||
ctx->geometry_shader = NULL;
|
||||
}
|
||||
ctx->pipe->delete_gs_state(ctx->pipe, handle);
|
||||
}
|
||||
|
||||
static void
|
||||
cso_save_geometry_shader(struct cso_context *ctx)
|
||||
{
|
||||
|
|
@ -959,16 +929,6 @@ void cso_set_tessctrl_shader_handle(struct cso_context *ctx, void *handle)
|
|||
}
|
||||
}
|
||||
|
||||
void cso_delete_tessctrl_shader(struct cso_context *ctx, void *handle)
|
||||
{
|
||||
if (handle == ctx->tessctrl_shader) {
|
||||
/* unbind before deleting */
|
||||
ctx->pipe->bind_tcs_state(ctx->pipe, NULL);
|
||||
ctx->tessctrl_shader = NULL;
|
||||
}
|
||||
ctx->pipe->delete_tcs_state(ctx->pipe, handle);
|
||||
}
|
||||
|
||||
static void
|
||||
cso_save_tessctrl_shader(struct cso_context *ctx)
|
||||
{
|
||||
|
|
@ -1004,16 +964,6 @@ void cso_set_tesseval_shader_handle(struct cso_context *ctx, void *handle)
|
|||
}
|
||||
}
|
||||
|
||||
void cso_delete_tesseval_shader(struct cso_context *ctx, void *handle)
|
||||
{
|
||||
if (handle == ctx->tesseval_shader) {
|
||||
/* unbind before deleting */
|
||||
ctx->pipe->bind_tes_state(ctx->pipe, NULL);
|
||||
ctx->tesseval_shader = NULL;
|
||||
}
|
||||
ctx->pipe->delete_tes_state(ctx->pipe, handle);
|
||||
}
|
||||
|
||||
static void
|
||||
cso_save_tesseval_shader(struct cso_context *ctx)
|
||||
{
|
||||
|
|
@ -1049,16 +999,6 @@ void cso_set_compute_shader_handle(struct cso_context *ctx, void *handle)
|
|||
}
|
||||
}
|
||||
|
||||
void cso_delete_compute_shader(struct cso_context *ctx, void *handle)
|
||||
{
|
||||
if (handle == ctx->compute_shader) {
|
||||
/* unbind before deleting */
|
||||
ctx->pipe->bind_compute_state(ctx->pipe, NULL);
|
||||
ctx->compute_shader = NULL;
|
||||
}
|
||||
ctx->pipe->delete_compute_state(ctx->pipe, handle);
|
||||
}
|
||||
|
||||
static void
|
||||
cso_set_vertex_elements_direct(struct cso_context *ctx,
|
||||
unsigned count,
|
||||
|
|
|
|||
|
|
@ -103,27 +103,11 @@ void cso_set_stream_outputs(struct cso_context *ctx,
|
|||
*/
|
||||
|
||||
void cso_set_fragment_shader_handle(struct cso_context *ctx, void *handle);
|
||||
void cso_delete_fragment_shader(struct cso_context *ctx, void *handle );
|
||||
|
||||
|
||||
void cso_set_vertex_shader_handle(struct cso_context *ctx, void *handle);
|
||||
void cso_delete_vertex_shader(struct cso_context *ctx, void *handle );
|
||||
|
||||
|
||||
void cso_set_geometry_shader_handle(struct cso_context *ctx, void *handle);
|
||||
void cso_delete_geometry_shader(struct cso_context *ctx, void *handle);
|
||||
|
||||
|
||||
void cso_set_tessctrl_shader_handle(struct cso_context *ctx, void *handle);
|
||||
void cso_delete_tessctrl_shader(struct cso_context *ctx, void *handle);
|
||||
|
||||
|
||||
void cso_set_tesseval_shader_handle(struct cso_context *ctx, void *handle);
|
||||
void cso_delete_tesseval_shader(struct cso_context *ctx, void *handle);
|
||||
|
||||
|
||||
void cso_set_compute_shader_handle(struct cso_context *ctx, void *handle);
|
||||
void cso_delete_compute_shader(struct cso_context *ctx, void *handle);
|
||||
|
||||
|
||||
void cso_set_framebuffer(struct cso_context *cso,
|
||||
|
|
|
|||
|
|
@ -143,7 +143,7 @@ NineVertexShader9_dtor( struct NineVertexShader9 *This )
|
|||
|
||||
while (var_so && var_so->vdecl) {
|
||||
if (var_so->cso) {
|
||||
cso_delete_vertex_shader(This->base.device->cso_sw, var_so->cso );
|
||||
This->base.device->pipe_sw->delete_vs_state(This->base.device->pipe_sw, var_so->cso);
|
||||
}
|
||||
var_so = var_so->next;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -431,7 +431,7 @@ xa_shaders_create(struct xa_context *r)
|
|||
}
|
||||
|
||||
static void
|
||||
cache_destroy(struct cso_context *cso,
|
||||
cache_destroy(struct pipe_context *pipe,
|
||||
struct cso_hash *hash, unsigned processor)
|
||||
{
|
||||
struct cso_hash_iter iter = cso_hash_first_node(hash);
|
||||
|
|
@ -440,9 +440,9 @@ cache_destroy(struct cso_context *cso,
|
|||
void *shader = (void *)cso_hash_iter_data(iter);
|
||||
|
||||
if (processor == PIPE_SHADER_FRAGMENT) {
|
||||
cso_delete_fragment_shader(cso, shader);
|
||||
pipe->delete_fs_state(pipe, shader);
|
||||
} else if (processor == PIPE_SHADER_VERTEX) {
|
||||
cso_delete_vertex_shader(cso, shader);
|
||||
pipe->delete_vs_state(pipe, shader);
|
||||
}
|
||||
iter = cso_hash_erase(hash, iter);
|
||||
}
|
||||
|
|
@ -452,8 +452,8 @@ cache_destroy(struct cso_context *cso,
|
|||
void
|
||||
xa_shaders_destroy(struct xa_shaders *sc)
|
||||
{
|
||||
cache_destroy(sc->r->cso, sc->vs_hash, PIPE_SHADER_VERTEX);
|
||||
cache_destroy(sc->r->cso, sc->fs_hash, PIPE_SHADER_FRAGMENT);
|
||||
cache_destroy(sc->r->pipe, sc->vs_hash, PIPE_SHADER_VERTEX);
|
||||
cache_destroy(sc->r->pipe, sc->fs_hash, PIPE_SHADER_FRAGMENT);
|
||||
|
||||
FREE(sc);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -85,19 +85,19 @@ void
|
|||
st_destroy_clear(struct st_context *st)
|
||||
{
|
||||
if (st->clear.fs) {
|
||||
cso_delete_fragment_shader(st->cso_context, st->clear.fs);
|
||||
st->pipe->delete_fs_state(st->pipe, st->clear.fs);
|
||||
st->clear.fs = NULL;
|
||||
}
|
||||
if (st->clear.vs) {
|
||||
cso_delete_vertex_shader(st->cso_context, st->clear.vs);
|
||||
st->pipe->delete_vs_state(st->pipe, st->clear.vs);
|
||||
st->clear.vs = NULL;
|
||||
}
|
||||
if (st->clear.vs_layered) {
|
||||
cso_delete_vertex_shader(st->cso_context, st->clear.vs_layered);
|
||||
st->pipe->delete_vs_state(st->pipe, st->clear.vs_layered);
|
||||
st->clear.vs_layered = NULL;
|
||||
}
|
||||
if (st->clear.gs_layered) {
|
||||
cso_delete_geometry_shader(st->cso_context, st->clear.gs_layered);
|
||||
st->pipe->delete_gs_state(st->pipe, st->clear.gs_layered);
|
||||
st->clear.gs_layered = NULL;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1915,12 +1915,11 @@ st_destroy_drawpix(struct st_context *st)
|
|||
|
||||
for (i = 0; i < ARRAY_SIZE(st->drawpix.zs_shaders); i++) {
|
||||
if (st->drawpix.zs_shaders[i])
|
||||
cso_delete_fragment_shader(st->cso_context,
|
||||
st->drawpix.zs_shaders[i]);
|
||||
st->pipe->delete_fs_state(st->pipe, st->drawpix.zs_shaders[i]);
|
||||
}
|
||||
|
||||
if (st->passthrough_vs)
|
||||
cso_delete_vertex_shader(st->cso_context, st->passthrough_vs);
|
||||
st->pipe->delete_vs_state(st->pipe, st->passthrough_vs);
|
||||
|
||||
/* Free cache data */
|
||||
for (i = 0; i < ARRAY_SIZE(st->drawpix_cache.entries); i++) {
|
||||
|
|
|
|||
|
|
@ -360,7 +360,7 @@ st_destroy_drawtex(struct st_context *st)
|
|||
{
|
||||
GLuint i;
|
||||
for (i = 0; i < NumCachedShaders; i++) {
|
||||
cso_delete_vertex_shader(st->cso_context, CachedShaders[i].handle);
|
||||
st->pipe->delete_vs_state(st->pipe, CachedShaders[i].handle);
|
||||
}
|
||||
NumCachedShaders = 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -396,22 +396,22 @@ free_zombie_shaders(struct st_context *st)
|
|||
|
||||
switch (entry->type) {
|
||||
case PIPE_SHADER_VERTEX:
|
||||
cso_delete_vertex_shader(st->cso_context, entry->shader);
|
||||
st->pipe->delete_vs_state(st->pipe, entry->shader);
|
||||
break;
|
||||
case PIPE_SHADER_FRAGMENT:
|
||||
cso_delete_fragment_shader(st->cso_context, entry->shader);
|
||||
st->pipe->delete_fs_state(st->pipe, entry->shader);
|
||||
break;
|
||||
case PIPE_SHADER_GEOMETRY:
|
||||
cso_delete_geometry_shader(st->cso_context, entry->shader);
|
||||
st->pipe->delete_gs_state(st->pipe, entry->shader);
|
||||
break;
|
||||
case PIPE_SHADER_TESS_CTRL:
|
||||
cso_delete_tessctrl_shader(st->cso_context, entry->shader);
|
||||
st->pipe->delete_tcs_state(st->pipe, entry->shader);
|
||||
break;
|
||||
case PIPE_SHADER_TESS_EVAL:
|
||||
cso_delete_tesseval_shader(st->cso_context, entry->shader);
|
||||
st->pipe->delete_tes_state(st->pipe, entry->shader);
|
||||
break;
|
||||
case PIPE_SHADER_COMPUTE:
|
||||
cso_delete_compute_shader(st->cso_context, entry->shader);
|
||||
st->pipe->delete_compute_state(st->pipe, entry->shader);
|
||||
break;
|
||||
default:
|
||||
unreachable("invalid shader type in free_zombie_shaders()");
|
||||
|
|
|
|||
|
|
@ -829,7 +829,7 @@ st_destroy_pbo_helpers(struct st_context *st)
|
|||
|
||||
for (i = 0; i < ARRAY_SIZE(st->pbo.upload_fs); ++i) {
|
||||
if (st->pbo.upload_fs[i]) {
|
||||
cso_delete_fragment_shader(st->cso_context, st->pbo.upload_fs[i]);
|
||||
st->pipe->delete_fs_state(st->pipe, st->pbo.upload_fs[i]);
|
||||
st->pbo.upload_fs[i] = NULL;
|
||||
}
|
||||
}
|
||||
|
|
@ -837,19 +837,19 @@ st_destroy_pbo_helpers(struct st_context *st)
|
|||
for (i = 0; i < ARRAY_SIZE(st->pbo.download_fs); ++i) {
|
||||
for (unsigned j = 0; j < ARRAY_SIZE(st->pbo.download_fs[0]); ++j) {
|
||||
if (st->pbo.download_fs[i][j]) {
|
||||
cso_delete_fragment_shader(st->cso_context, st->pbo.download_fs[i][j]);
|
||||
st->pipe->delete_fs_state(st->pipe, st->pbo.download_fs[i][j]);
|
||||
st->pbo.download_fs[i][j] = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (st->pbo.gs) {
|
||||
cso_delete_geometry_shader(st->cso_context, st->pbo.gs);
|
||||
st->pipe->delete_gs_state(st->pipe, st->pbo.gs);
|
||||
st->pbo.gs = NULL;
|
||||
}
|
||||
|
||||
if (st->pbo.vs) {
|
||||
cso_delete_vertex_shader(st->cso_context, st->pbo.vs);
|
||||
st->pipe->delete_vs_state(st->pipe, st->pbo.vs);
|
||||
st->pbo.vs = NULL;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -228,22 +228,22 @@ delete_variant(struct st_context *st, struct st_variant *v, GLenum target)
|
|||
*/
|
||||
switch (target) {
|
||||
case GL_VERTEX_PROGRAM_ARB:
|
||||
cso_delete_vertex_shader(st->cso_context, v->driver_shader);
|
||||
st->pipe->delete_vs_state(st->pipe, v->driver_shader);
|
||||
break;
|
||||
case GL_TESS_CONTROL_PROGRAM_NV:
|
||||
cso_delete_tessctrl_shader(st->cso_context, v->driver_shader);
|
||||
st->pipe->delete_tcs_state(st->pipe, v->driver_shader);
|
||||
break;
|
||||
case GL_TESS_EVALUATION_PROGRAM_NV:
|
||||
cso_delete_tesseval_shader(st->cso_context, v->driver_shader);
|
||||
st->pipe->delete_tes_state(st->pipe, v->driver_shader);
|
||||
break;
|
||||
case GL_GEOMETRY_PROGRAM_NV:
|
||||
cso_delete_geometry_shader(st->cso_context, v->driver_shader);
|
||||
st->pipe->delete_gs_state(st->pipe, v->driver_shader);
|
||||
break;
|
||||
case GL_FRAGMENT_PROGRAM_ARB:
|
||||
cso_delete_fragment_shader(st->cso_context, v->driver_shader);
|
||||
st->pipe->delete_fs_state(st->pipe, v->driver_shader);
|
||||
break;
|
||||
case GL_COMPUTE_PROGRAM_NV:
|
||||
cso_delete_compute_shader(st->cso_context, v->driver_shader);
|
||||
st->pipe->delete_compute_state(st->pipe, v->driver_shader);
|
||||
break;
|
||||
default:
|
||||
unreachable("bad shader type in delete_basic_variant");
|
||||
|
|
@ -262,6 +262,39 @@ delete_variant(struct st_context *st, struct st_variant *v, GLenum target)
|
|||
free(v);
|
||||
}
|
||||
|
||||
static void
|
||||
st_unbind_program(struct st_context *st, struct st_program *p)
|
||||
{
|
||||
/* Unbind the shader in cso_context and re-bind in st/mesa. */
|
||||
switch (p->Base.info.stage) {
|
||||
case MESA_SHADER_VERTEX:
|
||||
cso_set_vertex_shader_handle(st->cso_context, NULL);
|
||||
st->dirty |= ST_NEW_VS_STATE;
|
||||
break;
|
||||
case MESA_SHADER_TESS_CTRL:
|
||||
cso_set_tessctrl_shader_handle(st->cso_context, NULL);
|
||||
st->dirty |= ST_NEW_TCS_STATE;
|
||||
break;
|
||||
case MESA_SHADER_TESS_EVAL:
|
||||
cso_set_tesseval_shader_handle(st->cso_context, NULL);
|
||||
st->dirty |= ST_NEW_TES_STATE;
|
||||
break;
|
||||
case MESA_SHADER_GEOMETRY:
|
||||
cso_set_geometry_shader_handle(st->cso_context, NULL);
|
||||
st->dirty |= ST_NEW_GS_STATE;
|
||||
break;
|
||||
case MESA_SHADER_FRAGMENT:
|
||||
cso_set_fragment_shader_handle(st->cso_context, NULL);
|
||||
st->dirty |= ST_NEW_FS_STATE;
|
||||
break;
|
||||
case MESA_SHADER_COMPUTE:
|
||||
cso_set_compute_shader_handle(st->cso_context, NULL);
|
||||
st->dirty |= ST_NEW_CS_STATE;
|
||||
break;
|
||||
default:
|
||||
unreachable("invalid shader type");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Free all basic program variants.
|
||||
|
|
@ -271,6 +304,12 @@ st_release_variants(struct st_context *st, struct st_program *p)
|
|||
{
|
||||
struct st_variant *v;
|
||||
|
||||
/* If we are releasing shaders, re-bind them, because we don't
|
||||
* know which shaders are bound in the driver.
|
||||
*/
|
||||
if (p->variants)
|
||||
st_unbind_program(st, p);
|
||||
|
||||
for (v = p->variants; v; ) {
|
||||
struct st_variant *next = v->next;
|
||||
delete_variant(st, v, p->Base.Target);
|
||||
|
|
@ -1770,10 +1809,16 @@ destroy_program_variants(struct st_context *st, struct gl_program *target)
|
|||
|
||||
struct st_program *p = st_program(target);
|
||||
struct st_variant *v, **prevPtr = &p->variants;
|
||||
bool unbound = false;
|
||||
|
||||
for (v = p->variants; v; ) {
|
||||
struct st_variant *next = v->next;
|
||||
if (v->st == st) {
|
||||
if (!unbound) {
|
||||
st_unbind_program(st, p);
|
||||
unbound = true;
|
||||
}
|
||||
|
||||
/* unlink from list */
|
||||
*prevPtr = next;
|
||||
/* destroy this variant */
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue