diff options
author | Alyssa Rosenzweig <alyssa@collabora.com> | 2022-10-14 16:10:26 -0400 |
---|---|---|
committer | Marge Bot <emma+marge@anholt.net> | 2022-11-02 16:52:11 +0000 |
commit | 6d6f25e97e717e998d60e6a3aa82b7d73939972b (patch) | |
tree | 3cde388784fe00d4eeeb7640448b6d6cb5df2a18 | |
parent | 7bc34fbe8441bf72e4549996b3bdf39bf3251b20 (diff) |
panfrost: Use u_dynarray for variants
No need to open code our own "special" dynarray. Unify the graphics/compute CSO
creation to make this work without duplicating more code.
Signed-off-by: Alyssa Rosenzweig <alyssa@collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/19363>
-rw-r--r-- | src/gallium/drivers/panfrost/pan_cmdstream.c | 3 | ||||
-rw-r--r-- | src/gallium/drivers/panfrost/pan_context.h | 6 | ||||
-rw-r--r-- | src/gallium/drivers/panfrost/pan_shader.c | 136 |
3 files changed, 67 insertions, 78 deletions
diff --git a/src/gallium/drivers/panfrost/pan_cmdstream.c b/src/gallium/drivers/panfrost/pan_cmdstream.c index a7aba40017a..02754744393 100644 --- a/src/gallium/drivers/panfrost/pan_cmdstream.c +++ b/src/gallium/drivers/panfrost/pan_cmdstream.c @@ -3545,7 +3545,6 @@ panfrost_launch_xfb(struct panfrost_batch *batch, struct panfrost_uncompiled_shader *vs_uncompiled = ctx->uncompiled[PIPE_SHADER_VERTEX]; struct panfrost_compiled_shader *vs = ctx->prog[PIPE_SHADER_VERTEX]; - struct panfrost_uncompiled_shader v = { .variants = vs->xfb }; vs->xfb->stream_output = vs->stream_output; @@ -3553,7 +3552,7 @@ panfrost_launch_xfb(struct panfrost_batch *batch, mali_ptr saved_ubo = batch->uniform_buffers[PIPE_SHADER_VERTEX]; mali_ptr saved_push = batch->push_uniforms[PIPE_SHADER_VERTEX]; - ctx->uncompiled[PIPE_SHADER_VERTEX] = &v; + ctx->uncompiled[PIPE_SHADER_VERTEX] = NULL; /* should not be read */ ctx->prog[PIPE_SHADER_VERTEX] = vs->xfb; batch->rsd[PIPE_SHADER_VERTEX] = panfrost_emit_compute_shader_meta(batch, PIPE_SHADER_VERTEX); diff --git a/src/gallium/drivers/panfrost/pan_context.h b/src/gallium/drivers/panfrost/pan_context.h index f338af6946c..38cd5d5460a 100644 --- a/src/gallium/drivers/panfrost/pan_context.h +++ b/src/gallium/drivers/panfrost/pan_context.h @@ -319,10 +319,8 @@ struct panfrost_uncompiled_shader { /** Lock for the variants array */ simple_mtx_t lock; - struct panfrost_compiled_shader *variants; - unsigned variant_space; - - unsigned variant_count; + /* Array of panfrost_compiled_shader */ + struct util_dynarray variants; /* On vertex shaders, bit mask of special desktop-only varyings to link * with the fragment shader. Used on Valhall to implement separable diff --git a/src/gallium/drivers/panfrost/pan_shader.c b/src/gallium/drivers/panfrost/pan_shader.c index e91eba5823b..acace40049d 100644 --- a/src/gallium/drivers/panfrost/pan_shader.c +++ b/src/gallium/drivers/panfrost/pan_shader.c @@ -36,6 +36,23 @@ #include "nir/tgsi_to_nir.h" #include "nir_serialize.h" +static struct panfrost_uncompiled_shader * +panfrost_alloc_shader(void) +{ + struct panfrost_uncompiled_shader *so = CALLOC_STRUCT(panfrost_uncompiled_shader); + + simple_mtx_init(&so->lock, mtx_plain); + util_dynarray_init(&so->variants, NULL); + + return so; +} + +static struct panfrost_compiled_shader * +panfrost_alloc_variant(struct panfrost_uncompiled_shader *so) +{ + return util_dynarray_grow(&so->variants, struct panfrost_compiled_shader, 1); +} + static void panfrost_shader_compile(struct pipe_screen *pscreen, struct panfrost_pool *shader_pool, @@ -212,47 +229,31 @@ update_so_info(struct pipe_stream_output_info *so_info, return so_outputs; } -static unsigned +static struct panfrost_compiled_shader * panfrost_new_variant_locked( struct panfrost_context *ctx, - struct panfrost_uncompiled_shader *variants, + struct panfrost_uncompiled_shader *uncompiled, struct panfrost_shader_key *key) { - unsigned variant = variants->variant_count++; - - if (variants->variant_count > variants->variant_space) { - unsigned old_space = variants->variant_space; + struct panfrost_compiled_shader *prog = panfrost_alloc_variant(uncompiled); - variants->variant_space *= 2; - if (variants->variant_space == 0) - variants->variant_space = 1; - - unsigned msize = sizeof(struct panfrost_compiled_shader); - variants->variants = realloc(variants->variants, - variants->variant_space * msize); - - memset(&variants->variants[old_space], 0, - (variants->variant_space - old_space) * msize); - } - - variants->variants[variant].key = *key; - - struct panfrost_compiled_shader *shader_state = &variants->variants[variant]; + *prog = (struct panfrost_compiled_shader) { + .key = *key, + .stream_output = uncompiled->stream_output, + }; - /* We finally have a variant, so compile it */ panfrost_shader_compile(ctx->base.screen, &ctx->shaders, &ctx->descs, - variants->nir, &ctx->base.debug, shader_state, 0); + uncompiled->nir, &ctx->base.debug, prog, 0); /* Fixup the stream out information */ - shader_state->stream_output = variants->stream_output; - shader_state->so_mask = - update_so_info(&shader_state->stream_output, - shader_state->info.outputs_written); + prog->so_mask = + update_so_info(&prog->stream_output, + prog->info.outputs_written); - shader_state->earlyzs = pan_earlyzs_analyze(&shader_state->info); + prog->earlyzs = pan_earlyzs_analyze(&prog->info); - return variant; + return prog; } static void @@ -289,33 +290,33 @@ panfrost_update_shader_variant(struct panfrost_context *ctx, return; /* Match the appropriate variant */ - signed variant = -1; - struct panfrost_uncompiled_shader *variants = ctx->uncompiled[type]; + struct panfrost_uncompiled_shader *uncompiled = ctx->uncompiled[type]; + struct panfrost_compiled_shader *compiled = NULL; - simple_mtx_lock(&variants->lock); + simple_mtx_lock(&uncompiled->lock); struct panfrost_shader_key key = { - .fixed_varying_mask = variants->fixed_varying_mask + .fixed_varying_mask = uncompiled->fixed_varying_mask }; - panfrost_build_key(ctx, &key, variants->nir); + panfrost_build_key(ctx, &key, uncompiled->nir); - for (unsigned i = 0; i < variants->variant_count; ++i) { - if (memcmp(&key, &variants->variants[i].key, sizeof(key)) == 0) { - variant = i; + util_dynarray_foreach(&uncompiled->variants, struct panfrost_compiled_shader, so) { + if (memcmp(&key, &so->key, sizeof(key)) == 0) { + compiled = so; break; } } - if (variant == -1) - variant = panfrost_new_variant_locked(ctx, variants, &key); + if (compiled == NULL) + compiled = panfrost_new_variant_locked(ctx, uncompiled, &key); - ctx->prog[type] = &variants->variants[variant]; + ctx->prog[type] = compiled; /* TODO: it would be more efficient to release the lock before * compiling instead of after, but that can race if thread A compiles a * variant while thread B searches for that same variant */ - simple_mtx_unlock(&variants->lock); + simple_mtx_unlock(&uncompiled->lock); } static void @@ -339,11 +340,9 @@ panfrost_create_shader_state( struct pipe_context *pctx, const struct pipe_shader_state *cso) { - struct panfrost_uncompiled_shader *so = CALLOC_STRUCT(panfrost_uncompiled_shader); + struct panfrost_uncompiled_shader *so = panfrost_alloc_shader(); struct panfrost_device *dev = pan_device(pctx->screen); - simple_mtx_init(&so->lock, mtx_plain); - so->stream_output = cso->stream_output; if (cso->type == PIPE_SHADER_IR_TGSI) @@ -381,43 +380,38 @@ panfrost_delete_shader_state( ralloc_free(cso->nir); - for (unsigned i = 0; i < cso->variant_count; ++i) { - struct panfrost_compiled_shader *shader_state = &cso->variants[i]; - panfrost_bo_unreference(shader_state->bin.bo); - panfrost_bo_unreference(shader_state->state.bo); - panfrost_bo_unreference(shader_state->linkage.bo); - - if (shader_state->xfb) { - panfrost_bo_unreference(shader_state->xfb->bin.bo); - panfrost_bo_unreference(shader_state->xfb->state.bo); - panfrost_bo_unreference(shader_state->xfb->linkage.bo); - free(shader_state->xfb); + util_dynarray_foreach(&cso->variants, struct panfrost_compiled_shader, so) { + panfrost_bo_unreference(so->bin.bo); + panfrost_bo_unreference(so->state.bo); + panfrost_bo_unreference(so->linkage.bo); + + if (so->xfb) { + panfrost_bo_unreference(so->xfb->bin.bo); + panfrost_bo_unreference(so->xfb->state.bo); + panfrost_bo_unreference(so->xfb->linkage.bo); + free(so->xfb); } } simple_mtx_destroy(&cso->lock); - free(cso->variants); + util_dynarray_fini(&cso->variants); free(so); } -/* Compute CSOs are tracked like graphics shader CSOs, but are - * considerably simpler. We do not implement multiple - * variants/keying. So the CSO create function just goes ahead and - * compiles the thing. */ - +/* + * Create a compute CSO. As compute kernels do not require variants, they are + * precompiled, creating both the uncompiled and compiled shaders now. + */ static void * panfrost_create_compute_state( struct pipe_context *pctx, const struct pipe_compute_state *cso) { struct panfrost_context *ctx = pan_context(pctx); - struct panfrost_uncompiled_shader *so = CALLOC_STRUCT(panfrost_uncompiled_shader); - - struct panfrost_compiled_shader *v = calloc(1, sizeof(*v)); - so->variants = v; - - so->variant_count = 1; + struct panfrost_uncompiled_shader *so = panfrost_alloc_shader(); + struct panfrost_compiled_shader *v = panfrost_alloc_variant(so); + memset(v, 0, sizeof *v); assert(cso->ir_type == PIPE_SHADER_IR_NIR && "TGSI kernels unsupported"); @@ -436,10 +430,8 @@ panfrost_bind_compute_state(struct pipe_context *pipe, void *cso) ctx->uncompiled[PIPE_SHADER_COMPUTE] = uncompiled; - if (uncompiled) - ctx->prog[PIPE_SHADER_COMPUTE] = &uncompiled->variants[0]; - else - ctx->prog[PIPE_SHADER_COMPUTE] = NULL; + ctx->prog[PIPE_SHADER_COMPUTE] = + uncompiled ? util_dynarray_begin(&uncompiled->variants) : NULL; } static void @@ -448,7 +440,7 @@ panfrost_delete_compute_state(struct pipe_context *pipe, void *cso) struct panfrost_uncompiled_shader *so = (struct panfrost_uncompiled_shader *)cso; - free(so->variants); + util_dynarray_fini(&so->variants); free(cso); } |