[Mesa-dev] [PATCH 11/19] st/mesa: add compute shader states
Marek Olšák
maraeo at gmail.com
Fri Feb 12 09:43:49 UTC 2016
Reviewed-by: Marek Olšák <marek.olsak at amd.com>
Marek
On Thu, Feb 11, 2016 at 9:17 PM, Samuel Pitoiset
<samuel.pitoiset at gmail.com> wrote:
> Changes from v2:
> - use as much common code as possible (eg. st_basic_variant)
>
> Signed-off-by: Samuel Pitoiset <samuel.pitoiset at gmail.com>
> Reviewed-by: Marek Olšák <marek.olsak at amd.com> (v1)
> Reviewed-by: Ilia Mirkin <imirkin at alum.mit.edu> (v1)
> ---
> src/mesa/state_tracker/st_atom.c | 2 +-
> src/mesa/state_tracker/st_atom.h | 1 +
> src/mesa/state_tracker/st_atom_shader.c | 32 ++++++++++++
> src/mesa/state_tracker/st_cb_program.c | 30 +++++++++++
> src/mesa/state_tracker/st_context.c | 1 +
> src/mesa/state_tracker/st_context.h | 3 ++
> src/mesa/state_tracker/st_extensions.c | 7 ++-
> src/mesa/state_tracker/st_program.c | 88 +++++++++++++++++++++++++++++++++
> src/mesa/state_tracker/st_program.h | 41 +++++++++++++++
> 9 files changed, 202 insertions(+), 3 deletions(-)
>
> diff --git a/src/mesa/state_tracker/st_atom.c b/src/mesa/state_tracker/st_atom.c
> index 2d89512..3427a92 100644
> --- a/src/mesa/state_tracker/st_atom.c
> +++ b/src/mesa/state_tracker/st_atom.c
> @@ -98,7 +98,7 @@ static const struct st_tracked_state *render_atoms[] =
> */
> static const struct st_tracked_state *compute_atoms[] =
> {
> - /* will be updated in the next commit */
> + &st_update_cp,
> };
>
>
> diff --git a/src/mesa/state_tracker/st_atom.h b/src/mesa/state_tracker/st_atom.h
> index 77e2163..ef33645 100644
> --- a/src/mesa/state_tracker/st_atom.h
> +++ b/src/mesa/state_tracker/st_atom.h
> @@ -58,6 +58,7 @@ extern const struct st_tracked_state st_update_gp;
> extern const struct st_tracked_state st_update_tep;
> extern const struct st_tracked_state st_update_tcp;
> extern const struct st_tracked_state st_update_vp;
> +extern const struct st_tracked_state st_update_cp;
> extern const struct st_tracked_state st_update_rasterizer;
> extern const struct st_tracked_state st_update_polygon_stipple;
> extern const struct st_tracked_state st_update_viewport;
> diff --git a/src/mesa/state_tracker/st_atom_shader.c b/src/mesa/state_tracker/st_atom_shader.c
> index c8650a5..a88f035 100644
> --- a/src/mesa/state_tracker/st_atom_shader.c
> +++ b/src/mesa/state_tracker/st_atom_shader.c
> @@ -255,3 +255,35 @@ const struct st_tracked_state st_update_tep = {
> },
> update_tep /* update */
> };
> +
> +
> +
> +static void
> +update_cp( struct st_context *st )
> +{
> + struct st_compute_program *stcp;
> +
> + if (!st->ctx->ComputeProgram._Current) {
> + cso_set_compute_shader_handle(st->cso_context, NULL);
> + return;
> + }
> +
> + stcp = st_compute_program(st->ctx->ComputeProgram._Current);
> + assert(stcp->Base.Base.Target == GL_COMPUTE_PROGRAM_NV);
> +
> + st->cp_variant = st_get_cp_variant(st, &stcp->tgsi, &stcp->variants);
> +
> + st_reference_compprog(st, &st->cp, stcp);
> +
> + cso_set_compute_shader_handle(st->cso_context,
> + st->cp_variant->driver_shader);
> +}
> +
> +const struct st_tracked_state st_update_cp = {
> + "st_update_cp", /* name */
> + { /* dirty */
> + 0, /* mesa */
> + ST_NEW_COMPUTE_PROGRAM /* st */
> + },
> + update_cp /* update */
> +};
> diff --git a/src/mesa/state_tracker/st_cb_program.c b/src/mesa/state_tracker/st_cb_program.c
> index ca493d8..27cc0f3 100644
> --- a/src/mesa/state_tracker/st_cb_program.c
> +++ b/src/mesa/state_tracker/st_cb_program.c
> @@ -74,6 +74,9 @@ st_bind_program(struct gl_context *ctx, GLenum target, struct gl_program *prog)
> case GL_TESS_EVALUATION_PROGRAM_NV:
> st->dirty.st |= ST_NEW_TESSEVAL_PROGRAM;
> break;
> + case GL_COMPUTE_PROGRAM_NV:
> + st->dirty_cp.st |= ST_NEW_COMPUTE_PROGRAM;
> + break;
> }
> }
>
> @@ -92,6 +95,7 @@ st_use_program(struct gl_context *ctx, struct gl_shader_program *shProg)
> st->dirty.st |= ST_NEW_GEOMETRY_PROGRAM;
> st->dirty.st |= ST_NEW_TESSCTRL_PROGRAM;
> st->dirty.st |= ST_NEW_TESSEVAL_PROGRAM;
> + st->dirty_cp.st |= ST_NEW_COMPUTE_PROGRAM;
> }
>
>
> @@ -123,6 +127,10 @@ st_new_program(struct gl_context *ctx, GLenum target, GLuint id)
> struct st_tesseval_program *prog = ST_CALLOC_STRUCT(st_tesseval_program);
> return _mesa_init_gl_program(&prog->Base.Base, target, id);
> }
> + case GL_COMPUTE_PROGRAM_NV: {
> + struct st_compute_program *prog = ST_CALLOC_STRUCT(st_compute_program);
> + return _mesa_init_gl_program(&prog->Base.Base, target, id);
> + }
> default:
> assert(0);
> return NULL;
> @@ -195,6 +203,17 @@ st_delete_program(struct gl_context *ctx, struct gl_program *prog)
> free_glsl_to_tgsi_visitor(sttep->glsl_to_tgsi);
> }
> break;
> + case GL_COMPUTE_PROGRAM_NV:
> + {
> + struct st_compute_program *stcp =
> + (struct st_compute_program *) prog;
> +
> + st_release_cp_variants(st, stcp);
> +
> + if (stcp->glsl_to_tgsi)
> + free_glsl_to_tgsi_visitor(stcp->glsl_to_tgsi);
> + }
> + break;
> default:
> assert(0); /* problem */
> }
> @@ -272,6 +291,17 @@ st_program_string_notify( struct gl_context *ctx,
> if (st->tep == sttep)
> st->dirty.st |= ST_NEW_TESSEVAL_PROGRAM;
> }
> + else if (target == GL_COMPUTE_PROGRAM_NV) {
> + struct st_compute_program *stcp =
> + (struct st_compute_program *) prog;
> +
> + st_release_cp_variants(st, stcp);
> + if (!st_translate_compute_program(st, stcp))
> + return false;
> +
> + if (st->cp == stcp)
> + st->dirty_cp.st |= ST_NEW_COMPUTE_PROGRAM;
> + }
>
> if (ST_DEBUG & DEBUG_PRECOMPILE ||
> st->shader_has_one_variant[stage])
> diff --git a/src/mesa/state_tracker/st_context.c b/src/mesa/state_tracker/st_context.c
> index b73b0ab..287a4ea 100644
> --- a/src/mesa/state_tracker/st_context.c
> +++ b/src/mesa/state_tracker/st_context.c
> @@ -446,6 +446,7 @@ void st_destroy_context( struct st_context *st )
> st_reference_vertprog(st, &st->vp, NULL);
> st_reference_tesscprog(st, &st->tcp, NULL);
> st_reference_tesseprog(st, &st->tep, NULL);
> + st_reference_compprog(st, &st->cp, NULL);
>
> /* release framebuffer surfaces */
> for (i = 0; i < PIPE_MAX_COLOR_BUFS; i++) {
> diff --git a/src/mesa/state_tracker/st_context.h b/src/mesa/state_tracker/st_context.h
> index b8f7aa9..3b86710 100644
> --- a/src/mesa/state_tracker/st_context.h
> +++ b/src/mesa/state_tracker/st_context.h
> @@ -64,6 +64,7 @@ struct u_upload_mgr;
> #define ST_NEW_SAMPLER_VIEWS (1 << 11)
> #define ST_NEW_ATOMIC_BUFFER (1 << 12)
> #define ST_NEW_STORAGE_BUFFER (1 << 13)
> +#define ST_NEW_COMPUTE_PROGRAM (1 << 14)
>
>
> struct st_state_flags {
> @@ -174,12 +175,14 @@ struct st_context
> struct st_geometry_program *gp; /**< Currently bound geometry program */
> struct st_tessctrl_program *tcp; /**< Currently bound tess control program */
> struct st_tesseval_program *tep; /**< Currently bound tess eval program */
> + struct st_compute_program *cp; /**< Currently bound compute program */
>
> struct st_vp_variant *vp_variant;
> struct st_fp_variant *fp_variant;
> struct st_basic_variant *gp_variant;
> struct st_basic_variant *tcp_variant;
> struct st_basic_variant *tep_variant;
> + struct st_basic_variant *cp_variant;
>
> struct gl_texture_object *default_texture;
>
> diff --git a/src/mesa/state_tracker/st_extensions.c b/src/mesa/state_tracker/st_extensions.c
> index feabe62..556cd65 100644
> --- a/src/mesa/state_tracker/st_extensions.c
> +++ b/src/mesa/state_tracker/st_extensions.c
> @@ -174,9 +174,12 @@ void st_init_limits(struct pipe_screen *screen,
> pc = &c->Program[MESA_SHADER_TESS_EVAL];
> options = &c->ShaderCompilerOptions[MESA_SHADER_TESS_EVAL];
> break;
> + case PIPE_SHADER_COMPUTE:
> + pc = &c->Program[MESA_SHADER_COMPUTE];
> + options = &c->ShaderCompilerOptions[MESA_SHADER_COMPUTE];
> + break;
> default:
> - /* compute shader, etc. */
> - continue;
> + assert(0);
> }
>
> pc->MaxTextureImageUnits =
> diff --git a/src/mesa/state_tracker/st_program.c b/src/mesa/state_tracker/st_program.c
> index 5bd626f..16627ac 100644
> --- a/src/mesa/state_tracker/st_program.c
> +++ b/src/mesa/state_tracker/st_program.c
> @@ -158,6 +158,9 @@ delete_basic_variant(struct st_context *st, struct st_basic_variant *v,
> case GL_GEOMETRY_PROGRAM_NV:
> cso_delete_geometry_shader(st->cso_context, v->driver_shader);
> break;
> + case GL_COMPUTE_PROGRAM_NV:
> + cso_delete_compute_shader(st->cso_context, v->driver_shader);
> + break;
> default:
> assert(!"this shouldn't occur");
> }
> @@ -193,6 +196,30 @@ st_release_basic_variants(struct st_context *st, GLenum target,
>
>
> /**
> + * Free all variants of a compute program.
> + */
> +void
> +st_release_cp_variants(struct st_context *st, struct st_compute_program *stcp)
> +{
> + struct st_basic_variant **variants = &stcp->variants;
> + struct st_basic_variant *v;
> +
> + for (v = *variants; v; ) {
> + struct st_basic_variant *next = v->next;
> + delete_basic_variant(st, v, stcp->Base.Base.Target);
> + v = next;
> + }
> +
> + *variants = NULL;
> +
> + if (stcp->tgsi.prog) {
> + ureg_free_tokens(stcp->tgsi.prog);
> + stcp->tgsi.prog = NULL;
> + }
> +}
> +
> +
> +/**
> * Translate a vertex program.
> */
> bool
> @@ -1395,6 +1422,57 @@ st_translate_tesseval_program(struct st_context *st,
>
>
> /**
> + * Translate a compute program to create a new variant.
> + */
> +bool
> +st_translate_compute_program(struct st_context *st,
> + struct st_compute_program *stcp)
> +{
> + return false; /* will be updated in the next commit */
> +}
> +
> +
> +/**
> + * Get/create compute program variant.
> + */
> +struct st_basic_variant *
> +st_get_cp_variant(struct st_context *st,
> + struct pipe_compute_state *tgsi,
> + struct st_basic_variant **variants)
> +{
> + struct pipe_context *pipe = st->pipe;
> + struct st_basic_variant *v;
> + struct st_basic_variant_key key;
> +
> + memset(&key, 0, sizeof(key));
> + key.st = st->has_shareable_shaders ? NULL : st;
> +
> + /* Search for existing variant */
> + for (v = *variants; v; v = v->next) {
> + if (memcmp(&v->key, &key, sizeof(key)) == 0) {
> + break;
> + }
> + }
> +
> + if (!v) {
> + /* create new */
> + v = CALLOC_STRUCT(st_basic_variant);
> + if (v) {
> + /* fill in new variant */
> + v->driver_shader = pipe->create_compute_state(pipe, tgsi);
> + v->key = key;
> +
> + /* insert into list */
> + v->next = *variants;
> + *variants = v;
> + }
> + }
> +
> + return v;
> +}
> +
> +
> +/**
> * Vert/Geom/Frag programs have per-context variants. Free all the
> * variants attached to the given program which match the given context.
> */
> @@ -1449,14 +1527,17 @@ destroy_program_variants(struct st_context *st, struct gl_program *target)
> case GL_GEOMETRY_PROGRAM_NV:
> case GL_TESS_CONTROL_PROGRAM_NV:
> case GL_TESS_EVALUATION_PROGRAM_NV:
> + case GL_COMPUTE_PROGRAM_NV:
> {
> struct st_geometry_program *gp = (struct st_geometry_program*)target;
> struct st_tessctrl_program *tcp = (struct st_tessctrl_program*)target;
> struct st_tesseval_program *tep = (struct st_tesseval_program*)target;
> + struct st_compute_program *cp = (struct st_compute_program*)target;
> struct st_basic_variant **variants =
> target->Target == GL_GEOMETRY_PROGRAM_NV ? &gp->variants :
> target->Target == GL_TESS_CONTROL_PROGRAM_NV ? &tcp->variants :
> target->Target == GL_TESS_EVALUATION_PROGRAM_NV ? &tep->variants :
> + target->Target == GL_COMPUTE_PROGRAM_NV ? &cp->variants :
> NULL;
> struct st_basic_variant *v, **prevPtr = variants;
>
> @@ -1513,6 +1594,7 @@ destroy_shader_program_variants_cb(GLuint key, void *data, void *userData)
> case GL_GEOMETRY_SHADER:
> case GL_TESS_CONTROL_SHADER:
> case GL_TESS_EVALUATION_SHADER:
> + case GL_COMPUTE_SHADER:
> {
> destroy_program_variants(st, shader->Program);
> }
> @@ -1629,6 +1711,12 @@ st_precompile_shader_variant(struct st_context *st,
> break;
> }
>
> + case GL_COMPUTE_PROGRAM_NV: {
> + struct st_compute_program *p = (struct st_compute_program *)prog;
> + st_get_cp_variant(st, &p->tgsi, &p->variants);
> + break;
> + }
> +
> default:
> assert(0);
> }
> diff --git a/src/mesa/state_tracker/st_program.h b/src/mesa/state_tracker/st_program.h
> index 74f3def..028fba9 100644
> --- a/src/mesa/state_tracker/st_program.h
> +++ b/src/mesa/state_tracker/st_program.h
> @@ -231,6 +231,18 @@ struct st_tesseval_program
> };
>
>
> +/**
> + * Derived from Mesa gl_compute_program:
> + */
> +struct st_compute_program
> +{
> + struct gl_compute_program Base; /**< The Mesa compute program */
> + struct pipe_compute_state tgsi;
> + struct glsl_to_tgsi_visitor* glsl_to_tgsi;
> +
> + struct st_basic_variant *variants;
> +};
> +
>
> static inline struct st_fragment_program *
> st_fragment_program( struct gl_fragment_program *fp )
> @@ -263,6 +275,12 @@ st_tesseval_program( struct gl_tess_eval_program *tep )
> return (struct st_tesseval_program *)tep;
> }
>
> +static inline struct st_compute_program *
> +st_compute_program( struct gl_compute_program *cp )
> +{
> + return (struct st_compute_program *)cp;
> +}
> +
> static inline void
> st_reference_vertprog(struct st_context *st,
> struct st_vertex_program **ptr,
> @@ -313,6 +331,16 @@ st_reference_tesseprog(struct st_context *st,
> (struct gl_program *) prog);
> }
>
> +static inline void
> +st_reference_compprog(struct st_context *st,
> + struct st_compute_program **ptr,
> + struct st_compute_program *prog)
> +{
> + _mesa_reference_program(st->ctx,
> + (struct gl_program **) ptr,
> + (struct gl_program *) prog);
> +}
> +
> /**
> * This defines mapping from Mesa VARYING_SLOTs to TGSI GENERIC slots.
> */
> @@ -351,6 +379,11 @@ st_get_fp_variant(struct st_context *st,
> const struct st_fp_variant_key *key);
>
> extern struct st_basic_variant *
> +st_get_cp_variant(struct st_context *st,
> + struct pipe_compute_state *tgsi,
> + struct st_basic_variant **variants);
> +
> +extern struct st_basic_variant *
> st_get_basic_variant(struct st_context *st,
> unsigned pipe_shader,
> struct pipe_shader_state *tgsi,
> @@ -365,6 +398,10 @@ st_release_fp_variants( struct st_context *st,
> struct st_fragment_program *stfp );
>
> extern void
> +st_release_cp_variants(struct st_context *st,
> + struct st_compute_program *stcp);
> +
> +extern void
> st_release_basic_variants(struct st_context *st, GLenum target,
> struct st_basic_variant **variants,
> struct pipe_shader_state *tgsi);
> @@ -392,6 +429,10 @@ extern bool
> st_translate_tesseval_program(struct st_context *st,
> struct st_tesseval_program *sttep);
>
> +extern bool
> +st_translate_compute_program(struct st_context *st,
> + struct st_compute_program *stcp);
> +
> extern void
> st_print_current_vertex_program(void);
>
> --
> 2.6.4
>
> _______________________________________________
> mesa-dev mailing list
> mesa-dev at lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/mesa-dev
More information about the mesa-dev
mailing list