diff --git a/src/gallium/drivers/panfrost/pan_assemble.c b/src/gallium/drivers/panfrost/pan_assemble.c index 21141e930bd..ae86112b26e 100644 --- a/src/gallium/drivers/panfrost/pan_assemble.c +++ b/src/gallium/drivers/panfrost/pan_assemble.c @@ -47,6 +47,19 @@ panfrost_shader_compile(struct pipe_screen *pscreen, nir_shader *s = nir_shader_clone(NULL, ir); + if (dev->arch >= 6 && 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_shader_state)); + panfrost_shader_compile(pscreen, shader_pool, desc_pool, xfb, state->xfb); + + /* Main shader no longer uses XFB */ + s->info.has_transform_feedback_varyings = false; + } + /* Lower this early so the backends don't have to worry about it */ if (s->info.stage == MESA_SHADER_FRAGMENT) { NIR_PASS_V(s, nir_lower_fragcolor, state->key.fs.nr_cbufs); diff --git a/src/gallium/drivers/panfrost/pan_context.c b/src/gallium/drivers/panfrost/pan_context.c index 3efc48294d6..304107f45c4 100644 --- a/src/gallium/drivers/panfrost/pan_context.c +++ b/src/gallium/drivers/panfrost/pan_context.c @@ -342,6 +342,13 @@ panfrost_delete_shader_state( 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); + } } simple_mtx_destroy(&cso->lock); diff --git a/src/gallium/drivers/panfrost/pan_context.h b/src/gallium/drivers/panfrost/pan_context.h index 415ba5f28ed..0145e94e886 100644 --- a/src/gallium/drivers/panfrost/pan_context.h +++ b/src/gallium/drivers/panfrost/pan_context.h @@ -290,6 +290,9 @@ struct panfrost_shader_state { struct pan_shader_info info; + /* Attached transform feedback program, if one exists */ + struct panfrost_shader_state *xfb; + /* Linked varyings, for non-separable programs */ struct pan_linkage linkage;