[Mesa-dev] [PATCH 07/15] mesa/sso: Add pipeline container/state

Jordan Justen jljusten at gmail.com
Wed Feb 19 12:14:17 PST 2014


On Fri, Feb 7, 2014 at 10:00 PM, Ian Romanick <idr at freedesktop.org> wrote:
> From: Gregory Hainaut <gregory.hainaut at gmail.com>
>
> V1:
> * Extend gl_shader_state as pipeline object state
> * Add a new container gl_pipeline_shader_state that contains
>    binding point of the previous object
> * Update mesa init/free shader state due to the extension of
>    the attibute
> * Add an init/free pipeline function for the context
>
> V2:
> * Rename gl_shader_state to gl_pipeline_object
> * Rename Pipeline.PipelineObj to Pipeline.Current
> * Formatting improvement
>
> V3 (idr):
> * Split out from previous uber patch.
> * Remove '#if 0' debug printfs.
>
> Reviewed-by: Ian Romanick <ian.d.romanick at intel.com>
> ---
>  src/mesa/main/context.c     |   3 +
>  src/mesa/main/mtypes.h      |  22 +++++-
>  src/mesa/main/pipelineobj.c | 161 ++++++++++++++++++++++++++++++++++++++++++++
>  src/mesa/main/pipelineobj.h |  25 +++++++
>  4 files changed, 209 insertions(+), 2 deletions(-)
>
> diff --git a/src/mesa/main/context.c b/src/mesa/main/context.c
> index 8421a25..fe072ab 100644
> --- a/src/mesa/main/context.c
> +++ b/src/mesa/main/context.c
> @@ -106,6 +106,7 @@
>  #include "matrix.h"
>  #include "multisample.h"
>  #include "performance_monitor.h"
> +#include "pipelineobj.h"
>  #include "pixel.h"
>  #include "pixelstore.h"
>  #include "points.h"
> @@ -814,6 +815,7 @@ init_attrib_groups(struct gl_context *ctx)
>     _mesa_init_matrix( ctx );
>     _mesa_init_multisample( ctx );
>     _mesa_init_performance_monitors( ctx );
> +   _mesa_init_pipeline( ctx );
>     _mesa_init_pixel( ctx );
>     _mesa_init_pixelstore( ctx );
>     _mesa_init_point( ctx );
> @@ -1219,6 +1221,7 @@ _mesa_free_context_data( struct gl_context *ctx )
>     _mesa_free_texture_data( ctx );
>     _mesa_free_matrix_data( ctx );
>     _mesa_free_viewport_data( ctx );
> +   _mesa_free_pipeline_data(ctx);
>     _mesa_free_program_data(ctx);
>     _mesa_free_shader_state(ctx);
>     _mesa_free_queryobj_data(ctx);
> diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h
> index 52aeb15..4b8749a 100644
> --- a/src/mesa/main/mtypes.h
> +++ b/src/mesa/main/mtypes.h
> @@ -2746,9 +2746,15 @@ struct gl_shader_program
>
>  /**
>   * Context state for GLSL vertex/fragment shaders.
> + * Extended to support pipeline object
>   */
> -struct gl_shader_state
> +struct gl_pipeline_object
>  {
> +   /** Name of the pipeline object as received from glGenProgramPipelines.
> +    * It would be 0 for shaders without separate shader objects.
> +    */
> +   GLuint Name;
> +
>     GLint RefCount;
>
>     _glthread_Mutex Mutex;
> @@ -2774,6 +2780,17 @@ struct gl_shader_state
>     GLbitfield Flags;                    /**< Mask of GLSL_x flags */
>  };
>
> +/**
> + * Context state for GLSL pipeline shaders.
> + */
> +struct gl_pipeline_shader_state
> +{
> +   /** Currently bound pipeline object. See _mesa_BindProgramPipeline() */
> +   struct gl_pipeline_object *Current;
> +
> +   /** Pipeline objects */
> +   struct _mesa_HashTable *Objects;
> +};
>
>  /**
>   * Compiler options for a single GLSL shaders type
> @@ -4075,7 +4092,8 @@ struct gl_context
>     struct gl_geometry_program_state GeometryProgram;
>     struct gl_ati_fragment_shader_state ATIFragmentShader;
>
> -   struct gl_shader_state Shader; /**< GLSL shader object state */
> +   struct gl_pipeline_shader_state Pipeline; /**< GLSL pipeline shader object state */
> +   struct gl_pipeline_object Shader; /**< GLSL shader object state */
>     struct gl_shader_compiler_options ShaderCompilerOptions[MESA_SHADER_STAGES];
>
>     struct gl_query_state Query;  /**< occlusion, timer queries */
> diff --git a/src/mesa/main/pipelineobj.c b/src/mesa/main/pipelineobj.c
> index 7454619..a82e3ed 100644
> --- a/src/mesa/main/pipelineobj.c
> +++ b/src/mesa/main/pipelineobj.c
> @@ -30,6 +30,9 @@
>   * Implementation of pipeline object related API functions. Based on
>   * GL_ARB_separate_shader_objects extension.
>   *
> + * \todo
> + * Do we need to create CreatePipelineObject and DeletePipelineObject driver
> + * functions?
>   */

I don't know. Another question .. do we need this todo comment? :)

>  #include "main/glheader.h"
> @@ -50,6 +53,164 @@
>  #include "../glsl/glsl_parser_extras.h"
>  #include "../glsl/ir_uniform.h"
>
> +/**
> + * Delete a pipeline object.
> + */
> +void
> +_mesa_delete_pipeline_object(struct gl_context *ctx,
> +                             struct gl_pipeline_object *obj)
> +{
> +   unsinged i;
> +
> +   _mesa_reference_shader_program(ctx, &obj->_CurrentFragmentProgram, NULL);
> +
> +   for (i = 0; i < MESA_SHADER_STAGES; i++)
> +      _mesa_reference_shader_program(ctx, &obj->CurrentProgram[i], NULL);
> +
> +   _mesa_reference_shader_program(ctx, &obj->ActiveProgram, NULL);
> +   _glthread_DESTROY_MUTEX(obj->Mutex);
> +   ralloc_free(obj);
> +}
> +
> +/**
> + * Allocate and initialize a new pipeline object.
> + */
> +static struct gl_pipeline_object *
> +_mesa_new_pipeline_object(struct gl_context *ctx, GLuint name)
> +{
> +   struct gl_pipeline_object *obj = rzalloc(NULL, struct gl_pipeline_object);
> +   if (obj) {
> +      obj->Name = name;
> +      _glthread_INIT_MUTEX(obj->Mutex);
> +      obj->RefCount = 1;
> +      obj->Flags = _mesa_get_shader_flags();
> +   }
> +
> +   return obj;
> +}
> +
> +/**
> + * Initialize pipeline object state for given context.
> + */
> +void
> +_mesa_init_pipeline(struct gl_context *ctx)
> +{
> +   ctx->Pipeline.Objects = _mesa_NewHashTable();
> +
> +   ctx->Pipeline.Current = NULL;
> +}
> +
> +
> +/**
> + * Callback for deleting a pipeline object.  Called by _mesa_HashDeleteAll().
> + */
> +static void
> +delete_pipelineobj_cb(GLuint id, void *data, void *userData)
> +{
> +   struct gl_pipeline_object *obj = (struct gl_pipeline_object *) data;
> +   struct gl_context *ctx = (struct gl_context *) userData;
> +   _mesa_delete_pipeline_object(ctx, obj);
> +}
> +
> +
> +/**
> + * Free pipeline state for given context.
> + */
> +void
> +_mesa_free_pipeline_data(struct gl_context *ctx)
> +{
> +   _mesa_HashDeleteAll(ctx->Pipeline.Objects, delete_pipelineobj_cb, ctx);
> +   _mesa_DeleteHashTable(ctx->Pipeline.Objects);
> +}
> +
> +/**
> + * Look up the pipeline object for the given ID.
> + *
> + * \returns
> + * Either a pointer to the pipeline object with the specified ID or \c NULL for
> + * a non-existent ID.  The spec defines ID 0 as being technically
> + * non-existent.
> + */
> +static inline struct gl_pipeline_object *
> +lookup_pipeline_object(struct gl_context *ctx, GLuint id)
> +{
> +   if (id == 0)
> +      return NULL;
> +   else
> +      return (struct gl_pipeline_object *)
> +         _mesa_HashLookup(ctx->Pipeline.Objects, id);
> +}
> +
> +/**
> + * Add the given pipeline object to the pipeline object pool.
> + */
> +static void
> +save_pipeline_object(struct gl_context *ctx, struct gl_pipeline_object *obj)
> +{
> +   if (obj->Name > 0) {
> +      _mesa_HashInsert(ctx->Pipeline.Objects, obj->Name, obj);
> +   }
> +}
> +
> +/**
> + * Remove the given pipeline object from the pipeline object pool.
> + * Do not deallocate the pipeline object though.
> + */
> +static void
> +remove_pipeline_object(struct gl_context *ctx, struct gl_pipeline_object *obj)
> +{
> +   if (obj->Name > 0) {
> +      _mesa_HashRemove(ctx->Pipeline.Objects, obj->Name);
> +   }
> +}
> +
> +/**
> + * Set ptr to obj w/ reference counting.
> + * Note: this should only be called from the _mesa_reference_pipeline_object()
> + * inline function.
> + */
> +void
> +_mesa_reference_pipeline_object_(struct gl_context *ctx,
> +                                 struct gl_pipeline_object **ptr,
> +                                 struct gl_pipeline_object *obj)
> +{
> +   assert(*ptr != obj);
> +
> +   if (*ptr) {
> +      /* Unreference the old pipeline object */
> +      GLboolean deleteFlag = GL_FALSE;
> +      struct gl_pipeline_object *oldObj = *ptr;
> +
> +      _glthread_LOCK_MUTEX(oldObj->Mutex);
> +      ASSERT(oldObj->RefCount > 0);
> +      oldObj->RefCount--;
> +      deleteFlag = (oldObj->RefCount == 0);
> +      _glthread_UNLOCK_MUTEX(oldObj->Mutex);
> +
> +      if (deleteFlag) {
> +         _mesa_delete_pipeline_object(ctx, oldObj);
> +      }
> +
> +      *ptr = NULL;
> +   }
> +   ASSERT(!*ptr);
> +
> +   if (obj) {
> +      /* reference new pipeline object */
> +      _glthread_LOCK_MUTEX(obj->Mutex);
> +      if (obj->RefCount == 0) {
> +         /* this pipeline's being deleted (look just above) */
> +         /* Not sure this can every really happen.  Warn if it does. */

every => ever

1-7: Reviewed-by: Jordan Justen <jordan.l.justen at intel.com>

-Jordan

> +         _mesa_problem(NULL, "referencing deleted pipeline object");
> +         *ptr = NULL;
> +      }
> +      else {
> +         obj->RefCount++;
> +         *ptr = obj;
> +      }
> +      _glthread_UNLOCK_MUTEX(obj->Mutex);
> +   }
> +}
>
>  /**
>   * Bound program to severals stages of the pipeline
> diff --git a/src/mesa/main/pipelineobj.h b/src/mesa/main/pipelineobj.h
> index 56d32cc..46d5fab 100644
> --- a/src/mesa/main/pipelineobj.h
> +++ b/src/mesa/main/pipelineobj.h
> @@ -34,6 +34,31 @@ extern "C" {
>
>  struct _glapi_table;
>  struct gl_context;
> +struct gl_pipeline_object;
> +
> +extern void
> +_mesa_delete_pipeline_object(struct gl_context *ctx, struct gl_pipeline_object *obj);
> +
> +extern void
> +_mesa_init_pipeline(struct gl_context *ctx);
> +
> +extern void
> +_mesa_free_pipeline_data(struct gl_context *ctx);
> +
> +extern void
> +_mesa_reference_pipeline_object_(struct gl_context *ctx,
> +                                 struct gl_pipeline_object **ptr,
> +                                 struct gl_pipeline_object *obj);
> +
> +static inline void
> +_mesa_reference_pipeline_object(struct gl_context *ctx,
> +                                struct gl_pipeline_object **ptr,
> +                                struct gl_pipeline_object *obj)
> +{
> +   if (*ptr != obj)
> +      _mesa_reference_pipeline_object_(ctx, ptr, obj);
> +}
> +
>
>  extern void GLAPIENTRY
>  _mesa_UseProgramStages(GLuint pipeline, GLbitfield stages, GLuint program);
> --
> 1.8.1.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