summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlyssa Rosenzweig <alyssa@collabora.com>2022-10-14 17:03:36 -0400
committerMarge Bot <emma+marge@anholt.net>2022-11-02 16:52:11 +0000
commit01bbf8e2df04bbf9d5e8af94d523db86154ba376 (patch)
tree1449b53a6c5fe0fd2e2119c7b3aed52fd510d618
parentb290ac960b19343603ec9dce1c0945b17119f954 (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.c13
-rw-r--r--src/gallium/drivers/panfrost/pan_context.h6
-rw-r--r--src/gallium/drivers/panfrost/pan_shader.c51
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);