[Mesa-dev] [PATCH 10/17] st/mesa: add compute shader states

Marek Olšák maraeo at gmail.com
Tue Jan 26 03:19:58 PST 2016


Reviewed-by: Marek Olšák <marek.olsak at amd.com>

Marek

On Sun, Jan 24, 2016 at 10:09 PM, Samuel Pitoiset
<samuel.pitoiset at gmail.com> wrote:
> Signed-off-by: Samuel Pitoiset <samuel.pitoiset at 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 at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/mesa-dev


More information about the mesa-dev mailing list