iris: Ref count the uncompiled shaders
I tried /just/ ref counting the uncompiled shaders, but that is not sufficient. At the very least, it's a problem for blorp shaders that only have variants (and no uncompiled shader). This is in prepartion for using the live shader cache. Reviewed-by: Kenneth Graunke <kenneth@whitecape.org> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/11229>
This commit is contained in:
@@ -371,6 +371,8 @@ enum iris_predicate_state {
|
|||||||
* See iris_compiled_shader, which represents a compiled shader variant.
|
* See iris_compiled_shader, which represents a compiled shader variant.
|
||||||
*/
|
*/
|
||||||
struct iris_uncompiled_shader {
|
struct iris_uncompiled_shader {
|
||||||
|
struct pipe_reference ref;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* NIR for the shader.
|
* NIR for the shader.
|
||||||
*
|
*
|
||||||
@@ -955,6 +957,26 @@ struct iris_compiled_shader *iris_upload_shader(struct iris_screen *screen,
|
|||||||
const struct iris_binding_table *bt);
|
const struct iris_binding_table *bt);
|
||||||
void iris_delete_shader_variant(struct iris_compiled_shader *shader);
|
void iris_delete_shader_variant(struct iris_compiled_shader *shader);
|
||||||
|
|
||||||
|
void iris_destroy_shader_state(struct pipe_context *ctx, void *state);
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
iris_uncompiled_shader_reference(struct pipe_context *ctx,
|
||||||
|
struct iris_uncompiled_shader **dst,
|
||||||
|
struct iris_uncompiled_shader *src)
|
||||||
|
{
|
||||||
|
if (*dst == src)
|
||||||
|
return;
|
||||||
|
|
||||||
|
struct iris_uncompiled_shader *old_dst = *dst;
|
||||||
|
|
||||||
|
if (pipe_reference(old_dst != NULL ? &old_dst->ref : NULL,
|
||||||
|
src != NULL ? &src->ref : NULL)) {
|
||||||
|
iris_destroy_shader_state(ctx, *dst);
|
||||||
|
}
|
||||||
|
|
||||||
|
*dst = src;
|
||||||
|
}
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
iris_shader_variant_reference(struct iris_compiled_shader **dst,
|
iris_shader_variant_reference(struct iris_compiled_shader **dst,
|
||||||
struct iris_compiled_shader *src)
|
struct iris_compiled_shader *src)
|
||||||
|
@@ -2282,6 +2282,7 @@ iris_create_uncompiled_shader(struct iris_screen *screen,
|
|||||||
if (!ish)
|
if (!ish)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
pipe_reference_init(&ish->ref, 1);
|
||||||
list_inithead(&ish->variants);
|
list_inithead(&ish->variants);
|
||||||
simple_mtx_init(&ish->lock, mtx_plain);
|
simple_mtx_init(&ish->lock, mtx_plain);
|
||||||
|
|
||||||
@@ -2537,9 +2538,35 @@ iris_create_shader_state(struct pipe_context *ctx,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The pipe->delete_[stage]_state() driver hooks.
|
* Called when the refcount on the iris_uncompiled_shader reaches 0.
|
||||||
*
|
*
|
||||||
* Frees the iris_uncompiled_shader.
|
* Frees the iris_uncompiled_shader.
|
||||||
|
*
|
||||||
|
* \sa iris_delete_shader_state
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
iris_destroy_shader_state(struct pipe_context *ctx, void *state)
|
||||||
|
{
|
||||||
|
struct iris_uncompiled_shader *ish = state;
|
||||||
|
|
||||||
|
/* No need to take ish->lock; we hold the last reference to ish */
|
||||||
|
list_for_each_entry_safe(struct iris_compiled_shader, shader,
|
||||||
|
&ish->variants, link) {
|
||||||
|
list_del(&shader->link);
|
||||||
|
|
||||||
|
iris_shader_variant_reference(&shader, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
simple_mtx_destroy(&ish->lock);
|
||||||
|
|
||||||
|
ralloc_free(ish->nir);
|
||||||
|
free(ish);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The pipe->delete_[stage]_state() driver hooks.
|
||||||
|
*
|
||||||
|
* \sa iris_destroy_shader_state
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
iris_delete_shader_state(struct pipe_context *ctx, void *state)
|
iris_delete_shader_state(struct pipe_context *ctx, void *state)
|
||||||
@@ -2554,18 +2581,8 @@ iris_delete_shader_state(struct pipe_context *ctx, void *state)
|
|||||||
ice->state.stage_dirty |= IRIS_STAGE_DIRTY_UNCOMPILED_VS << stage;
|
ice->state.stage_dirty |= IRIS_STAGE_DIRTY_UNCOMPILED_VS << stage;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* No need to take ish->lock; we hold the last reference to ish */
|
if (pipe_reference(&ish->ref, NULL))
|
||||||
list_for_each_entry_safe(struct iris_compiled_shader, shader,
|
iris_destroy_shader_state(ctx, state);
|
||||||
&ish->variants, link) {
|
|
||||||
list_del(&shader->link);
|
|
||||||
|
|
||||||
iris_shader_variant_reference(&shader, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
simple_mtx_destroy(&ish->lock);
|
|
||||||
|
|
||||||
ralloc_free(ish->nir);
|
|
||||||
free(ish);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
Reference in New Issue
Block a user