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>
This commit is contained in:

committed by
Marge Bot

parent
b290ac960b
commit
01bbf8e2df
@@ -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
|
||||
|
@@ -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.
|
||||
|
@@ -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);
|
||||
|
Reference in New Issue
Block a user