Reviewed-by: Marek Olšák <marek.ol...@amd.com> Marek
On Sun, Jan 24, 2016 at 10:09 PM, Samuel Pitoiset <samuel.pitoi...@gmail.com> wrote: > Signed-off-by: Samuel Pitoiset <samuel.pitoi...@gmail.com> > --- > src/mesa/state_tracker/st_atom.c | 2 +- > src/mesa/state_tracker/st_atom.h | 1 + > src/mesa/state_tracker/st_atom_shader.c | 36 +++++++++ > src/mesa/state_tracker/st_cb_program.c | 28 +++++++ > 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 | 130 > ++++++++++++++++++++++++++++++++ > src/mesa/state_tracker/st_program.h | 63 ++++++++++++++++ > 9 files changed, 268 insertions(+), 3 deletions(-) > > diff --git a/src/mesa/state_tracker/st_atom.c > b/src/mesa/state_tracker/st_atom.c > index f989f47..496128e 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 6fca762..2bbc451 100644 > --- a/src/mesa/state_tracker/st_atom.h > +++ b/src/mesa/state_tracker/st_atom.h > @@ -57,6 +57,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 0f9ea10..33da81a 100644 > --- a/src/mesa/state_tracker/st_atom_shader.c > +++ b/src/mesa/state_tracker/st_atom_shader.c > @@ -264,3 +264,39 @@ const struct st_tracked_state st_update_tep = { > }, > update_tep /* update */ > }; > + > + > + > +static void > +update_cp( struct st_context *st ) > +{ > + struct st_compute_program *stcp; > + struct st_cp_variant_key key; > + > + 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); > + > + memset(&key, 0, sizeof(key)); > + key.st = st->has_shareable_shaders ? NULL : st; > + > + st->cp_variant = st_get_cp_variant(st, stcp, &key); > + > + 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 2c4eccf..8aea9cb 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; > @@ -192,6 +200,16 @@ 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 */ > } > @@ -278,6 +296,16 @@ 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 a5cf187..3406689 100644 > --- a/src/mesa/state_tracker/st_context.c > +++ b/src/mesa/state_tracker/st_context.c > @@ -421,6 +421,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 93eaf23..52fd83d 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 { > @@ -166,12 +167,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_gp_variant *gp_variant; > struct st_tcp_variant *tcp_variant; > struct st_tep_variant *tep_variant; > + struct st_cp_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 c198892..19edc66 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 b395454..07d9b62 100644 > --- a/src/mesa/state_tracker/st_program.c > +++ b/src/mesa/state_tracker/st_program.c > @@ -251,6 +251,43 @@ st_release_tep_variants(struct st_context *st, struct > st_tesseval_program *sttep > > > /** > + * Delete a compute program variant. Note the caller must unlink the variant > + * from the linked list. > + */ > +static void > +delete_cp_variant(struct st_context *st, struct st_cp_variant *cpv) > +{ > + if (cpv->driver_shader) > + cso_delete_compute_shader(st->cso_context, cpv->driver_shader); > + > + free(cpv); > +} > + > + > +/** > + * Free all variants of a compute program. > + */ > +void > +st_release_cp_variants(struct st_context *st, struct st_compute_program > *stcp) > +{ > + struct st_cp_variant *cpv; > + > + for (cpv = stcp->variants; cpv; ) { > + struct st_cp_variant *next = cpv->next; > + delete_cp_variant(st, cpv); > + cpv = next; > + } > + > + stcp->variants = NULL; > + > + if (stcp->tgsi.prog) { > + ureg_free_tokens(stcp->tgsi.prog); > + stcp->tgsi.prog = NULL; > + } > +} > + > + > +/** > * Translate a vertex program. > */ > bool > @@ -1547,6 +1584,67 @@ st_get_tep_variant(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 */ > +} > + > + > +static struct st_cp_variant * > +st_create_cp_variant(struct st_context *st, > + struct st_compute_program *stcp, > + const struct st_cp_variant_key *key) > +{ > + struct pipe_context *pipe = st->pipe; > + struct st_cp_variant *cpv; > + > + cpv = CALLOC_STRUCT(st_cp_variant); > + if (!cpv) > + return NULL; > + > + /* fill in new variant */ > + cpv->driver_shader = pipe->create_compute_state(pipe, &stcp->tgsi); > + cpv->key = *key; > + return cpv; > +} > + > + > +/** > + * Get/create compute program variant. > + */ > +struct st_cp_variant * > +st_get_cp_variant(struct st_context *st, > + struct st_compute_program *stcp, > + const struct st_cp_variant_key *key) > +{ > + struct st_cp_variant *cpv; > + > + /* Search for existing variant */ > + for (cpv = stcp->variants; cpv; cpv = cpv->next) { > + if (memcmp(&cpv->key, key, sizeof(*key)) == 0) { > + break; > + } > + } > + > + if (!cpv) { > + /* create new */ > + cpv = st_create_cp_variant(st, stcp, key); > + if (cpv) { > + /* insert into list */ > + cpv->next = stcp->variants; > + stcp->variants = cpv; > + } > + } > + > + return cpv; > +} > + > + > +/** > * Vert/Geom/Frag programs have per-context variants. Free all the > * variants attached to the given program which match the given context. > */ > @@ -1661,6 +1759,27 @@ destroy_program_variants(struct st_context *st, struct > gl_program *program) > } > } > break; > + case GL_COMPUTE_PROGRAM_NV: > + { > + struct st_compute_program *stcp = > + (struct st_compute_program *) program; > + struct st_cp_variant *cpv, **prevPtr = &stcp->variants; > + > + for (cpv = stcp->variants; cpv; ) { > + struct st_cp_variant *next = cpv->next; > + if (cpv->key.st == st) { > + /* unlink from list */ > + *prevPtr = next; > + /* destroy this variant */ > + delete_cp_variant(st, cpv); > + } > + else { > + prevPtr = &cpv->next; > + } > + cpv = next; > + } > + } > + break; > default: > _mesa_problem(NULL, "Unexpected program target 0x%x in " > "destroy_program_variants_cb()", program->Target); > @@ -1699,6 +1818,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); > } > @@ -1827,6 +1947,16 @@ st_precompile_shader_variant(struct st_context *st, > break; > } > > + case GL_COMPUTE_PROGRAM_NV: { > + struct st_compute_program *p = (struct st_compute_program *)prog; > + struct st_cp_variant_key key; > + > + memset(&key, 0, sizeof(key)); > + key.st = st->has_shareable_shaders ? NULL : st; > + st_get_cp_variant(st, p, &key); > + break; > + } > + > default: > assert(0); > } > diff --git a/src/mesa/state_tracker/st_program.h > b/src/mesa/state_tracker/st_program.h > index a745315..82a3a88 100644 > --- a/src/mesa/state_tracker/st_program.h > +++ b/src/mesa/state_tracker/st_program.h > @@ -278,6 +278,40 @@ struct st_tesseval_program > }; > > > +/** Compute program variant key */ > +struct st_cp_variant_key > +{ > + struct st_context *st; /**< variants are per-context */ > + /* no other fields yet */ > +}; > + > + > +/** > + * Compute program variant. > + */ > +struct st_cp_variant > +{ > + /* Parameters which generated this variant. */ > + struct st_cp_variant_key key; > + > + void *driver_shader; > + > + struct st_cp_variant *next; > +}; > + > + > +/** > + * 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_cp_variant *variants; > +}; > + > > static inline struct st_fragment_program * > st_fragment_program( struct gl_fragment_program *fp ) > @@ -310,6 +344,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, > @@ -360,6 +400,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. > */ > @@ -413,6 +463,11 @@ st_get_tep_variant(struct st_context *st, > struct st_tesseval_program *sttep, > const struct st_tep_variant_key *key); > > +extern struct st_cp_variant * > +st_get_cp_variant(struct st_context *st, > + struct st_compute_program *stcp, > + const struct st_cp_variant_key *key); > + > extern void > st_release_vp_variants( struct st_context *st, > struct st_vertex_program *stvp ); > @@ -434,6 +489,10 @@ st_release_tep_variants(struct st_context *st, > struct st_tesseval_program *sttep); > > extern void > +st_release_cp_variants(struct st_context *st, > + struct st_compute_program *stcp); > + > +extern void > st_destroy_program_variants(struct st_context *st); > > extern bool > @@ -456,6 +515,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@lists.freedesktop.org > http://lists.freedesktop.org/mailman/listinfo/mesa-dev _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev