[Mesa-dev] [PATCH v3 11/19] st/mesa: add compute shader states

Samuel Pitoiset samuel.pitoiset at gmail.com
Thu Feb 11 15:27:43 UTC 2016



On 02/11/2016 11:51 AM, Marek Olšák wrote:
> This needs a cleanup, because some program variant code has been
> unified. See below.

Right, sorry I didn't see that you pushed your refactoring patch.
Thanks!

>
> On Wed, Feb 10, 2016 at 7:10 PM, Samuel Pitoiset
> <samuel.pitoiset at gmail.com> wrote:
>> Signed-off-by: Samuel Pitoiset <samuel.pitoiset at gmail.com>
>> Reviewed-by: Marek Olšák <marek.olsak at amd.com>
>> Reviewed-by: Ilia Mirkin <imirkin at alum.mit.edu>
>> ---
>>   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 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 23b7abf..954166e 100644
>> --- a/src/mesa/state_tracker/st_atom_shader.c
>> +++ b/src/mesa/state_tracker/st_atom_shader.c
>> @@ -252,3 +252,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);
>
> Use st_get_basic_variant.
>
>> +
>> +   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..70cbbec 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,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);
>
> Use st_release_basic_variants.
>
>> +
>> +         if (stcp->glsl_to_tgsi)
>> +            free_glsl_to_tgsi_visitor(stcp->glsl_to_tgsi);
>> +      }
>> +      break;
>>      default:
>>         assert(0); /* problem */
>>      }
>> @@ -272,6 +290,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);
>
> Use st_release_basic_variants.
>
>> +      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..843cd3a 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_cp_variant *cp_variant;
>
> Use st_basic_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 624586e..e9b5ace 100644
>> --- a/src/mesa/state_tracker/st_program.c
>> +++ b/src/mesa/state_tracker/st_program.c
>> @@ -193,6 +193,43 @@ st_release_basic_variants(struct st_context *st, GLenum target,
>>
>>
>>   /**
>> + * 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);
>> +}
>
> Delete this and extend delete_basic_variant.
>
>> +
>> +
>> +/**
>> + * 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;
>> +   }
>> +}
>
> Delete this.
>
>> +
>> +
>> +/**
>>    * Translate a vertex program.
>>    */
>>   bool
>> @@ -1379,6 +1416,67 @@ 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 */
>> +}
>> +
>> +
>> +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;
>> +}
>
> Delete this.
>
>> +
>> +
>> +/**
>> + * 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;
>> +}
>
> Delete this and extend st_get_basic_variant. (it only uses
> create_gs_state, oops)
>
>> +
>> +
>> +/**
>>    * Vert/Geom/Frag programs have per-context variants.  Free all the
>>    * variants attached to the given program which match the given context.
>>    */
>> @@ -1459,6 +1557,27 @@ destroy_program_variants(struct st_context *st, struct gl_program *target)
>>            }
>>         }
>>         break;
>> +   case GL_COMPUTE_PROGRAM_NV:
>> +      {
>> +         struct st_compute_program *stcp =
>> +            (struct st_compute_program *) target;
>> +         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;
>
> Delete this and extend the unified case statement for GS/TCS/TES.
>
>>      default:
>>         _mesa_problem(NULL, "Unexpected program target 0x%x in "
>>                       "destroy_program_variants_cb()", target->Target);
>> @@ -1497,6 +1616,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);
>>         }
>> @@ -1613,6 +1733,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;
>> +   }
>
> Use st_get_basic_variant.
>
>> +
>>      default:
>>         assert(0);
>>      }
>> diff --git a/src/mesa/state_tracker/st_program.h b/src/mesa/state_tracker/st_program.h
>> index 7717d02..7e64ab6 100644
>> --- a/src/mesa/state_tracker/st_program.h
>> +++ b/src/mesa/state_tracker/st_program.h
>> @@ -231,6 +231,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 */
>> +};
>
> Delete this.
>
>> +
>> +
>> +/**
>> + * 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;
>> +};
>
> Delete this.
>
>> +
>> +
>> +/**
>> + * 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;
>
> Use st_basic_variant.
>
>> +};
>> +
>>
>>   static inline struct st_fragment_program *
>>   st_fragment_program( struct gl_fragment_program *fp )
>> @@ -263,6 +297,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 +353,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.
>>    */
>> @@ -355,6 +405,11 @@ st_get_basic_variant(struct st_context *st,
>>                        struct pipe_shader_state *tgsi,
>>                        struct st_basic_variant **variants);
>>
>> +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);
>> +
>
> Delete this.
>
>>   extern void
>>   st_release_vp_variants( struct st_context *st,
>>                           struct st_vertex_program *stvp );
>> @@ -369,6 +424,10 @@ st_release_basic_variants(struct st_context *st, GLenum target,
>>                             struct pipe_shader_state *tgsi);
>>
>>   extern void
>> +st_release_cp_variants(struct st_context *st,
>> +                        struct st_compute_program *stcp);
>> +
>
> Delete this.
>
> Marek
>

-- 
-Samuel


More information about the mesa-dev mailing list