diff options
author | Alyssa Rosenzweig <alyssa@collabora.com> | 2022-10-14 17:03:36 -0400 |
---|---|---|
committer | Marge Bot <emma+marge@anholt.net> | 2022-11-02 16:52:11 +0000 |
commit | 01bbf8e2df04bbf9d5e8af94d523db86154ba376 (patch) | |
tree | 1449b53a6c5fe0fd2e2119c7b3aed52fd510d618 | |
parent | b290ac960b19343603ec9dce1c0945b17119f954 (diff) |
panfrost: Precompile transform feedback program
This avoids the weird compiled_shader pointer inside of compiled_shader. Because
we don't have a nonempty vertex shader key, there will only ever be a single
transform feedback program per CSO.
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 | 13 | ||||
-rw-r--r-- | src/gallium/drivers/panfrost/pan_context.h | 6 | ||||
-rw-r--r-- | src/gallium/drivers/panfrost/pan_shader.c | 51 |
3 files changed, 40 insertions, 30 deletions
diff --git a/src/gallium/drivers/panfrost/pan_cmdstream.c b/src/gallium/drivers/panfrost/pan_cmdstream.c index 3bb6146ba69..1782ca17ce9 100644 --- a/src/gallium/drivers/panfrost/pan_cmdstream.c +++ b/src/gallium/drivers/panfrost/pan_cmdstream.c @@ -2018,8 +2018,11 @@ panfrost_emit_vertex_data(struct panfrost_batch *batch, unsigned count = vs->info.attribute_count; - if (vs->xfb) - count = MAX2(count, vs->xfb->info.attribute_count); + struct panfrost_compiled_shader *xfb = + ctx->uncompiled[PIPE_SHADER_VERTEX]->xfb; + + if (xfb) + count = MAX2(count, xfb->info.attribute_count); #if PAN_ARCH <= 5 /* Midgard needs vertexid/instanceid handled specially */ @@ -3546,14 +3549,14 @@ 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]; - vs->xfb->stream_output = vs->stream_output; + vs_uncompiled->xfb->stream_output = vs->stream_output; mali_ptr saved_rsd = batch->rsd[PIPE_SHADER_VERTEX]; 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] = NULL; /* should not be read */ - ctx->prog[PIPE_SHADER_VERTEX] = vs->xfb; + ctx->prog[PIPE_SHADER_VERTEX] = vs_uncompiled->xfb; batch->rsd[PIPE_SHADER_VERTEX] = panfrost_emit_compute_shader_meta(batch, PIPE_SHADER_VERTEX); #if PAN_ARCH >= 9 @@ -3734,7 +3737,7 @@ panfrost_direct_draw(struct panfrost_batch *batch, panfrost_update_shader_state(batch, PIPE_SHADER_FRAGMENT); panfrost_clean_state_3d(ctx); - if (vs->xfb) { + if (ctx->uncompiled[PIPE_SHADER_VERTEX]->xfb) { #if PAN_ARCH >= 9 mali_ptr attribs = 0, attrib_bufs = 0; #endif diff --git a/src/gallium/drivers/panfrost/pan_context.h b/src/gallium/drivers/panfrost/pan_context.h index 86cf7125ae9..65a78b6c4d4 100644 --- a/src/gallium/drivers/panfrost/pan_context.h +++ b/src/gallium/drivers/panfrost/pan_context.h @@ -294,9 +294,6 @@ struct panfrost_compiled_shader { struct pan_earlyzs_lut earlyzs; - /* Attached transform feedback program, if one exists */ - struct panfrost_compiled_shader *xfb; - /* Linked varyings, for non-separable programs */ struct pan_linkage linkage; @@ -322,6 +319,9 @@ struct panfrost_uncompiled_shader { /* Array of panfrost_compiled_shader */ struct util_dynarray variants; + /* Compiled transform feedback program, if one is required */ + struct panfrost_compiled_shader *xfb; + /* On vertex shaders, bit mask of special desktop-only varyings to link * with the fragment shader. Used on Valhall to implement separable * shaders for desktop GL. diff --git a/src/gallium/drivers/panfrost/pan_shader.c b/src/gallium/drivers/panfrost/pan_shader.c index 7ed210e9e46..af4a53b5a19 100644 --- a/src/gallium/drivers/panfrost/pan_shader.c +++ b/src/gallium/drivers/panfrost/pan_shader.c @@ -68,19 +68,6 @@ panfrost_shader_compile(struct pipe_screen *pscreen, nir_shader *s = nir_shader_clone(NULL, ir); - if (s->xfb_info && !s->info.internal) { - /* Create compute shader doing transform feedback */ - nir_shader *xfb = nir_shader_clone(NULL, s); - xfb->info.name = ralloc_asprintf(xfb, "%s@xfb", xfb->info.name); - xfb->info.internal = true; - - state->xfb = calloc(1, sizeof(struct panfrost_compiled_shader)); - panfrost_shader_compile(pscreen, shader_pool, desc_pool, xfb, dbg, state->xfb, 0, fixed_varying_mask); - - /* Main shader no longer uses XFB */ - s->info.has_transform_feedback_varyings = false; - } - struct panfrost_compile_inputs inputs = { .debug = dbg, .gpu_id = dev->gpu_id, @@ -357,15 +344,35 @@ panfrost_create_shader_state( ~VARYING_BIT_POS & ~VARYING_BIT_PSIZ; } + /* If this shader uses transform feedback, compile the transform + * feedback program. This is a special shader variant. + */ + struct panfrost_context *ctx = pan_context(pctx); + struct util_debug_callback *dbg = &ctx->base.debug; + + if (so->nir->xfb_info) { + nir_shader *xfb = nir_shader_clone(NULL, so->nir); + xfb->info.name = ralloc_asprintf(xfb, "%s@xfb", xfb->info.name); + xfb->info.internal = true; + + so->xfb = calloc(1, sizeof(struct panfrost_compiled_shader)); + panfrost_shader_compile(pctx->screen, &ctx->shaders, + &ctx->descs, xfb, dbg, so->xfb, 0, + so->fixed_varying_mask); + + /* Since transform feedback is handled via the transform + * feedback program, the original program no longer uses XFB + */ + so->nir->info.has_transform_feedback_varyings = false; + } + /* Precompile for shader-db if we need to */ if (unlikely(dev->debug & PAN_DBG_PRECOMPILE)) { - struct panfrost_context *ctx = pan_context(pctx); - struct panfrost_compiled_shader state = { 0 }; panfrost_shader_compile(pctx->screen, &ctx->shaders, &ctx->descs, - so->nir, &ctx->base.debug, &state, 0, + so->nir, dbg, &state, 0, so->fixed_varying_mask); } @@ -385,13 +392,13 @@ panfrost_delete_shader_state( 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); - } + if (cso->xfb) { + panfrost_bo_unreference(cso->xfb->bin.bo); + panfrost_bo_unreference(cso->xfb->state.bo); + panfrost_bo_unreference(cso->xfb->linkage.bo); + free(cso->xfb); } simple_mtx_destroy(&cso->lock); |