llvmpipe: Stop refcounting sample functions

This would just make on-demand compilation more complicated.

Reviewed-by: Mike Blumenkrantz <michael.blumenkrantz@gmail.com>
Reviewed-by: Dave Airlie <airlied@redhat.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/27182>
This commit is contained in:
Konstantin Seurer
2024-01-19 19:34:44 +01:00
committed by Marge Bot
parent c4d950ce37
commit 533d17ec71
8 changed files with 32 additions and 91 deletions

View File

@@ -215,7 +215,6 @@ struct lp_texture_functions {
void **image_functions;
struct lp_static_texture_state state;
uint32_t ref_count;
bool sampled;
bool storage;

View File

@@ -978,7 +978,7 @@ llvmpipe_create_compute_state(struct pipe_context *pipe,
shader->req_local_mem += nir->info.shared_size;
shader->zero_initialize_shared_memory = nir->info.zero_initialize_shared_memory;
llvmpipe_register_shader(pipe, &shader->base, false);
llvmpipe_register_shader(pipe, &shader->base);
list_inithead(&shader->variants.list);
@@ -1059,8 +1059,6 @@ llvmpipe_delete_compute_state(struct pipe_context *pipe,
struct lp_compute_shader *shader = cs;
struct lp_cs_variant_list_item *li, *next;
llvmpipe_register_shader(pipe, &shader->base, true);
if (llvmpipe->cs == cs)
llvmpipe->cs = NULL;
for (unsigned i = 0; i < shader->max_global_buffers; i++)
@@ -1898,7 +1896,7 @@ llvmpipe_create_ts_state(struct pipe_context *pipe,
if (!shader)
return NULL;
llvmpipe_register_shader(pipe, templ, false);
llvmpipe_register_shader(pipe, templ);
shader->no = task_no++;
shader->base.type = templ->type;
@@ -1935,8 +1933,6 @@ llvmpipe_delete_ts_state(struct pipe_context *pipe, void *_task)
struct lp_compute_shader *shader = _task;
struct lp_cs_variant_list_item *li, *next;
llvmpipe_register_shader(pipe, &shader->base, true);
/* Delete all the variants */
LIST_FOR_EACH_ENTRY_SAFE(li, next, &shader->variants.list, list) {
llvmpipe_remove_cs_shader_variant(llvmpipe, li->base);
@@ -1971,7 +1967,7 @@ llvmpipe_create_ms_state(struct pipe_context *pipe,
if (!shader)
return NULL;
llvmpipe_register_shader(pipe, templ, false);
llvmpipe_register_shader(pipe, templ);
shader->no = mesh_no++;
shader->base.type = templ->type;
@@ -1983,7 +1979,6 @@ llvmpipe_create_ms_state(struct pipe_context *pipe,
shader->draw_mesh_data = draw_create_mesh_shader(llvmpipe->draw, templ);
if (shader->draw_mesh_data == NULL) {
FREE(shader);
llvmpipe_register_shader(pipe, templ, true);
return NULL;
}
@@ -2018,8 +2013,6 @@ llvmpipe_delete_ms_state(struct pipe_context *pipe, void *_mesh)
struct lp_compute_shader *shader = _mesh;
struct lp_cs_variant_list_item *li, *next;
llvmpipe_register_shader(pipe, &shader->base, true);
/* Delete all the variants */
LIST_FOR_EACH_ENTRY_SAFE(li, next, &shader->variants.list, list) {
llvmpipe_remove_cs_shader_variant(llvmpipe, li->base);

View File

@@ -3985,7 +3985,7 @@ llvmpipe_create_fs_state(struct pipe_context *pipe,
nir_tgsi_scan_shader(nir, &shader->info.base, true);
shader->info.num_texs = shader->info.base.opcode_count[TGSI_OPCODE_TEX];
llvmpipe_register_shader(pipe, &shader->base, false);
llvmpipe_register_shader(pipe, &shader->base);
shader->draw_data = draw_create_fragment_shader(llvmpipe->draw, templ);
if (shader->draw_data == NULL) {
@@ -4122,8 +4122,6 @@ llvmpipe_destroy_fs(struct llvmpipe_context *llvmpipe,
/* Delete draw module's data */
draw_delete_fragment_shader(llvmpipe->draw, shader->draw_data);
llvmpipe_register_shader(&llvmpipe->pipe, &shader->base, true);
ralloc_free(shader->base.ir.nir);
assert(shader->variants_cached == 0);
FREE(shader);

View File

@@ -42,7 +42,7 @@ static void *
llvmpipe_create_gs_state(struct pipe_context *pipe,
const struct pipe_shader_state *templ)
{
llvmpipe_register_shader(pipe, templ, false);
llvmpipe_register_shader(pipe, templ);
struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe);
struct lp_geometry_shader *state;
@@ -106,8 +106,6 @@ llvmpipe_delete_gs_state(struct pipe_context *pipe, void *gs)
return;
}
llvmpipe_register_shader(pipe, &state->dgs->state, true);
draw_delete_geometry_shader(llvmpipe->draw, state->dgs);
FREE(state);
}

View File

@@ -40,7 +40,7 @@ static void *
llvmpipe_create_tcs_state(struct pipe_context *pipe,
const struct pipe_shader_state *templ)
{
llvmpipe_register_shader(pipe, templ, false);
llvmpipe_register_shader(pipe, templ);
struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe);
struct lp_tess_ctrl_shader *state;
@@ -101,8 +101,6 @@ llvmpipe_delete_tcs_state(struct pipe_context *pipe, void *tcs)
return;
}
llvmpipe_register_shader(pipe, &state->dtcs->state, true);
draw_delete_tess_ctrl_shader(llvmpipe->draw, state->dtcs);
FREE(state);
}
@@ -112,7 +110,7 @@ static void *
llvmpipe_create_tes_state(struct pipe_context *pipe,
const struct pipe_shader_state *templ)
{
llvmpipe_register_shader(pipe, templ, false);
llvmpipe_register_shader(pipe, templ);
struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe);
struct lp_tess_eval_shader *state;
@@ -173,8 +171,6 @@ llvmpipe_delete_tes_state(struct pipe_context *pipe, void *tes)
return;
}
llvmpipe_register_shader(pipe, &state->dtes->state, true);
draw_delete_tess_eval_shader(llvmpipe->draw, state->dtes);
FREE(state);
}

View File

@@ -42,7 +42,7 @@ static void *
llvmpipe_create_vs_state(struct pipe_context *pipe,
const struct pipe_shader_state *templ)
{
llvmpipe_register_shader(pipe, templ, false);
llvmpipe_register_shader(pipe, templ);
struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe);
struct draw_vertex_shader *vs;
@@ -84,8 +84,6 @@ llvmpipe_delete_vs_state(struct pipe_context *pipe, void *_vs)
struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe);
struct draw_vertex_shader *vs = (struct draw_vertex_shader *)_vs;
llvmpipe_register_shader(pipe, &vs->state, true);
draw_delete_vertex_shader(llvmpipe->draw, vs);
}

View File

@@ -97,20 +97,9 @@ llvmpipe_create_texture_handle(struct pipe_context *pctx, struct pipe_sampler_vi
}
static void
llvmpipe_delete_texture_handle(struct pipe_context *pctx, uint64_t _handle)
llvmpipe_delete_texture_handle(struct pipe_context *pctx, uint64_t handle)
{
if (!_handle)
return;
struct lp_texture_handle *handle = (void *)(uintptr_t)_handle;
struct lp_texture_functions *functions = handle->functions;
if (functions) {
assert(functions->ref_count);
functions->ref_count--;
}
free(handle);
free((void *)(uintptr_t)handle);
}
static uint64_t
@@ -589,7 +578,7 @@ compile_sample_functions(struct llvmpipe_context *ctx, struct lp_static_texture_
struct lp_sampler_matrix *matrix = &ctx->sampler_matrix;
for (uint32_t sample_key = 0; sample_key < LP_SAMPLE_KEY_COUNT; sample_key++) {
if (!matrix->sampler_keys[sample_key])
if (!BITSET_TEST(matrix->sample_keys, sample_key))
continue;
enum lp_sampler_op_type op_type = (sample_key & LP_SAMPLER_OP_TYPE_MASK) >> LP_SAMPLER_OP_TYPE_SHIFT;
@@ -613,9 +602,7 @@ llvmpipe_register_texture(struct llvmpipe_context *ctx, struct lp_static_texture
continue;
bool has_functions = sampled ? matrix->textures[i]->sampled : matrix->textures[i]->storage;
uint32_t prev_ref_count = matrix->textures[i]->ref_count++;
if (has_functions && prev_ref_count)
if (has_functions)
return;
packed = false;
@@ -631,7 +618,6 @@ llvmpipe_register_texture(struct llvmpipe_context *ctx, struct lp_static_texture
entry = calloc(1, sizeof(struct lp_texture_functions));
matrix->textures[dst_index] = entry;
entry->ref_count = 1;
entry->state = *state;
entry->image_functions = calloc(LP_TOTAL_IMAGE_OP_COUNT, sizeof(void **));
} else {
@@ -694,7 +680,7 @@ llvmpipe_register_sampler(struct llvmpipe_context *ctx, struct lp_static_sampler
for (uint32_t i = 0; i < matrix->texture_count; i++) {
struct lp_texture_functions *texture = matrix->textures[i];
if (!texture->ref_count || !texture->sampled)
if (!texture->sampled)
continue;
texture->sampler_count = matrix->sampler_count;
@@ -722,27 +708,25 @@ static void
register_sample_key(struct llvmpipe_context *ctx, uint32_t sample_key)
{
struct lp_sampler_matrix *matrix = &ctx->sampler_matrix;
uint32_t prev_ref_count = matrix->sampler_keys[sample_key]++;
if (prev_ref_count)
if (BITSET_TEST(matrix->sample_keys, sample_key))
return;
BITSET_SET(matrix->sample_keys, sample_key);
for (uint32_t texture_index = 0; texture_index < matrix->texture_count; texture_index++) {
struct lp_texture_functions *texture = matrix->textures[texture_index];
if (!texture->ref_count || !texture->sampled)
if (!texture->sampled)
continue;
enum lp_sampler_op_type op_type = (sample_key & LP_SAMPLER_OP_TYPE_MASK) >> LP_SAMPLER_OP_TYPE_SHIFT;
if (op_type == LP_SAMPLER_OP_FETCH) {
if (!texture->fetch_functions[sample_key]) {
struct lp_static_sampler_state dummy_sampler = { 0 };
texture->fetch_functions[sample_key] = compile_sample_function(ctx, &texture->state, &dummy_sampler, sample_key);
}
struct lp_static_sampler_state dummy_sampler = { 0 };
texture->fetch_functions[sample_key] = compile_sample_function(ctx, &texture->state, &dummy_sampler, sample_key);
continue;
}
if (texture->state.format == PIPE_FORMAT_NONE) {
if (matrix->sampler_count && !texture->sample_functions[0][sample_key]) {
if (matrix->sampler_count) {
struct lp_static_sampler_state dummy_sampler = { 0 };
texture->sample_functions[0][sample_key] = compile_sample_function(ctx, &texture->state, &dummy_sampler, sample_key);
}
@@ -750,23 +734,12 @@ register_sample_key(struct llvmpipe_context *ctx, uint32_t sample_key)
}
for (uint32_t sampler_index = 0; sampler_index < matrix->sampler_count; sampler_index++) {
if (!texture->sample_functions[sampler_index][sample_key]) {
texture->sample_functions[sampler_index][sample_key] = compile_sample_function(
ctx, &texture->state, matrix->samplers + sampler_index, sample_key);
}
texture->sample_functions[sampler_index][sample_key] = compile_sample_function(
ctx, &texture->state, matrix->samplers + sampler_index, sample_key);
}
}
}
static void
unregister_sample_key(struct llvmpipe_context *ctx, uint32_t sample_key)
{
struct lp_sampler_matrix *matrix = &ctx->sampler_matrix;
assert(matrix->sampler_keys[sample_key]);
matrix->sampler_keys[sample_key]--;
}
static void
register_image_op(struct llvmpipe_context *ctx, uint32_t op)
{
@@ -778,29 +751,21 @@ register_image_op(struct llvmpipe_context *ctx, uint32_t op)
for (uint32_t texture_index = 0; texture_index < matrix->texture_count; texture_index++) {
struct lp_texture_functions *texture = matrix->textures[texture_index];
if (texture->ref_count && texture->storage)
if (texture->storage)
texture->image_functions[op] = compile_image_function(ctx, &texture->state, op);
}
}
struct register_shader_state {
struct llvmpipe_context *ctx;
bool unregister;
};
static bool
register_instr(nir_builder *b, nir_instr *instr, void *_state)
register_instr(nir_builder *b, nir_instr *instr, void *data)
{
struct register_shader_state *state = _state;
struct llvmpipe_context *ctx = data;
if (instr->type == nir_instr_type_tex) {
nir_tex_instr *tex = nir_instr_as_tex(instr);
uint32_t sample_key = lp_build_nir_sample_key(b->shader->info.stage, tex);
if (state->unregister)
unregister_sample_key(state->ctx, sample_key);
else
register_sample_key(state->ctx, sample_key);
register_sample_key(ctx, sample_key);
} else if (instr->type == nir_instr_type_intrinsic) {
nir_intrinsic_instr *intrin = nir_instr_as_intrinsic(instr);
@@ -820,21 +785,15 @@ register_instr(nir_builder *b, nir_instr *instr, void *_state)
nir_intrinsic_image_dim(intrin) == GLSL_SAMPLER_DIM_SUBPASS_MS)
op += LP_TOTAL_IMAGE_OP_COUNT / 2;
register_image_op(state->ctx, op);
register_image_op(ctx, op);
}
return false;
}
void
llvmpipe_register_shader(struct pipe_context *ctx, const struct pipe_shader_state *shader, bool unregister)
llvmpipe_register_shader(struct pipe_context *ctx, const struct pipe_shader_state *shader)
{
if (shader->type != PIPE_SHADER_IR_NIR)
return;
struct register_shader_state state = {
.ctx = llvmpipe_context(ctx),
.unregister = unregister,
};
nir_shader_instructions_pass(shader->ir.nir, register_instr, nir_metadata_all, &state);
if (shader->type == PIPE_SHADER_IR_NIR)
nir_shader_instructions_pass(shader->ir.nir, register_instr, nir_metadata_all, ctx);
}

View File

@@ -40,7 +40,7 @@ struct lp_sampler_matrix {
uint32_t texture_count;
uint32_t sampler_count;
uint32_t sampler_keys[LP_SAMPLE_KEY_COUNT];
BITSET_DECLARE(sample_keys, LP_SAMPLE_KEY_COUNT);
BITSET_DECLARE(image_ops, LP_TOTAL_IMAGE_OP_COUNT);
struct util_dynarray gallivms;
@@ -50,6 +50,6 @@ void llvmpipe_init_sampler_matrix(struct llvmpipe_context *ctx);
void llvmpipe_sampler_matrix_destroy(struct llvmpipe_context *ctx);
void llvmpipe_register_shader(struct pipe_context *ctx, const struct pipe_shader_state *shader, bool unregister);
void llvmpipe_register_shader(struct pipe_context *ctx, const struct pipe_shader_state *shader);
#endif /* LP_SAMPLER_MATRIX */