Mesa (st-mesa-per-context-shaders): st/mesa: reorganize vertex program translation code

Brian Paul brianp at kemper.freedesktop.org
Mon Dec 13 21:09:05 UTC 2010


Module: Mesa
Branch: st-mesa-per-context-shaders
Commit: 4f106f44a32eaddb6cf3fea6ba5ee9787bff609a
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=4f106f44a32eaddb6cf3fea6ba5ee9787bff609a

Author: Brian Paul <brianp at vmware.com>
Date:   Mon Dec 13 14:06:08 2010 -0700

st/mesa: reorganize vertex program translation code

Now it looks like the fragment and geometry program code.
Also remove the serial number fields from programs.  It was used to
determine when new translations were needed.  Now the variant key is
used for that.  And the st_program_string_notify() callback removes all
variants when the program's code is changed.

---

 src/mesa/state_tracker/st_atom_shader.c |   83 ++++++-------------------------
 src/mesa/state_tracker/st_cb_program.c  |   10 ----
 src/mesa/state_tracker/st_program.c     |   39 ++++++++++++++-
 src/mesa/state_tracker/st_program.h     |   21 ++------
 4 files changed, 59 insertions(+), 94 deletions(-)

diff --git a/src/mesa/state_tracker/st_atom_shader.c b/src/mesa/state_tracker/st_atom_shader.c
index a0e8565..f416293 100644
--- a/src/mesa/state_tracker/st_atom_shader.c
+++ b/src/mesa/state_tracker/st_atom_shader.c
@@ -51,71 +51,6 @@
 
 
 /**
- * Find a translated vertex program that corresponds to stvp and
- * has outputs matched to stfp's inputs.
- * This performs vertex and fragment translation (to TGSI) when needed.
- */
-static struct st_vp_varient *
-find_translated_vp(struct st_context *st,
-                   struct st_vertex_program *stvp )
-{
-   struct st_vp_varient *vpv;
-   struct st_vp_varient_key key;
-
-   /* Nothing in our key yet.  This will change:
-    */
-   memset(&key, 0, sizeof key);
-
-   /* When this is true, we will add an extra input to the vertex
-    * shader translation (for edgeflags), an extra output with
-    * edgeflag semantics, and extend the vertex shader to pass through
-    * the input to the output.  We'll need to use similar logic to set
-    * up the extra vertex_element input for edgeflags.
-    * _NEW_POLYGON, ST_NEW_EDGEFLAGS_DATA
-    */
-   key.passthrough_edgeflags = (st->vertdata_edgeflags && (
-                                st->ctx->Polygon.FrontMode != GL_FILL ||
-                                st->ctx->Polygon.BackMode != GL_FILL));
-
-   key.st = st;  /* variants are per-context */
-
-   /* Do we need to throw away old translations after a change in the
-    * GL program string?
-    */
-   if (stvp->serialNo != stvp->lastSerialNo) {
-      /* These may have changed if the program string changed.
-       */
-      st_prepare_vertex_program( st, stvp );
-
-      /* We are now up-to-date:
-       */
-      stvp->lastSerialNo = stvp->serialNo;
-   }
-   
-   /* See if we've got a translated vertex program whose outputs match
-    * the fragment program's inputs.
-    */
-   for (vpv = stvp->varients; vpv; vpv = vpv->next) {
-      if (memcmp(&vpv->key, &key, sizeof key) == 0) {
-         break;
-      }
-   }
-
-   /* No?  Perform new translation here. */
-   if (!vpv) {
-      vpv = st_translate_vertex_program(st, stvp, &key);
-      if (!vpv)
-         return NULL;
-      
-      vpv->next = stvp->varients;
-      stvp->varients = vpv;
-   }
-
-   return vpv;
-}
-
-
-/**
  * Return pointer to a pass-through fragment shader.
  * This shader is used when a texture is missing/incomplete.
  */
@@ -145,7 +80,6 @@ update_fp( struct st_context *st )
    stfp = st_fragment_program(st->ctx->FragmentProgram._Current);
    assert(stfp->Base.Base.Target == GL_FRAGMENT_PROGRAM_ARB);
 
-
    memset(&key, 0, sizeof(key));
    key.st = st;
 
@@ -184,6 +118,7 @@ static void
 update_vp( struct st_context *st )
 {
    struct st_vertex_program *stvp;
+   struct st_vp_varient_key key;
 
    /* find active shader and params -- Should be covered by
     * ST_NEW_VERTEX_PROGRAM
@@ -192,7 +127,21 @@ update_vp( struct st_context *st )
    stvp = st_vertex_program(st->ctx->VertexProgram._Current);
    assert(stvp->Base.Base.Target == GL_VERTEX_PROGRAM_ARB);
 
-   st->vp_varient = find_translated_vp(st, stvp);
+   memset(&key, 0, sizeof key);
+   key.st = st;  /* variants are per-context */
+
+   /* When this is true, we will add an extra input to the vertex
+    * shader translation (for edgeflags), an extra output with
+    * edgeflag semantics, and extend the vertex shader to pass through
+    * the input to the output.  We'll need to use similar logic to set
+    * up the extra vertex_element input for edgeflags.
+    * _NEW_POLYGON, ST_NEW_EDGEFLAGS_DATA
+    */
+   key.passthrough_edgeflags = (st->vertdata_edgeflags && (
+                                st->ctx->Polygon.FrontMode != GL_FILL ||
+                                st->ctx->Polygon.BackMode != GL_FILL));
+
+   st->vp_varient = st_get_vp_varient(st, stvp, &key);
 
    st_reference_vertprog(st, &st->vp, stvp);
 
diff --git a/src/mesa/state_tracker/st_cb_program.c b/src/mesa/state_tracker/st_cb_program.c
index 08d29ae..3e1b709 100644
--- a/src/mesa/state_tracker/st_cb_program.c
+++ b/src/mesa/state_tracker/st_cb_program.c
@@ -46,8 +46,6 @@
 #include "st_cb_program.h"
 
 
-static GLuint SerialNo = 1;
-
 
 /**
  * Called via ctx->Driver.BindProgram() to bind an ARB vertex or
@@ -100,8 +98,6 @@ static struct gl_program *st_new_program( struct gl_context *ctx,
    case GL_VERTEX_PROGRAM_ARB: {
       struct st_vertex_program *prog = ST_CALLOC_STRUCT(st_vertex_program);
 
-      prog->serialNo = SerialNo++;
-
       return _mesa_init_vertex_program( ctx, 
 					&prog->Base,
 					target, 
@@ -121,8 +117,6 @@ static struct gl_program *st_new_program( struct gl_context *ctx,
    case MESA_GEOMETRY_PROGRAM: {
       struct st_geometry_program *prog = ST_CALLOC_STRUCT(st_geometry_program);
 
-      prog->serialNo = SerialNo++;
-
       return _mesa_init_geometry_program( ctx,
                                           &prog->Base,
                                           target,
@@ -213,8 +207,6 @@ static GLboolean st_program_string_notify( struct gl_context *ctx,
    else if (target == MESA_GEOMETRY_PROGRAM) {
       struct st_geometry_program *stgp = (struct st_geometry_program *) prog;
 
-      stgp->serialNo++;
-
       st_gp_release_varients(st, stgp);
 
       if (stgp->tgsi.tokens) {
@@ -228,8 +220,6 @@ static GLboolean st_program_string_notify( struct gl_context *ctx,
    else if (target == GL_VERTEX_PROGRAM_ARB) {
       struct st_vertex_program *stvp = (struct st_vertex_program *) prog;
 
-      stvp->serialNo++;
-
       st_vp_release_varients( st, stvp );
 
       if (st->vp == stvp)
diff --git a/src/mesa/state_tracker/st_program.c b/src/mesa/state_tracker/st_program.c
index 18c90b7..202f7cb 100644
--- a/src/mesa/state_tracker/st_program.c
+++ b/src/mesa/state_tracker/st_program.c
@@ -171,7 +171,7 @@ st_gp_release_varients(struct st_context *st, struct st_geometry_program *stgp)
  * \param tokensOut  destination for TGSI tokens
  * \return  pointer to cached pipe_shader object.
  */
-void
+static void
 st_prepare_vertex_program(struct st_context *st,
                             struct st_vertex_program *stvp)
 {
@@ -275,7 +275,10 @@ st_prepare_vertex_program(struct st_context *st,
 }
 
 
-struct st_vp_varient *
+/**
+ * Translate a vertex program to create a new varient.
+ */
+static struct st_vp_varient *
 st_translate_vertex_program(struct st_context *st,
                             struct st_vertex_program *stvp,
                             const struct st_vp_varient_key *key)
@@ -286,6 +289,8 @@ st_translate_vertex_program(struct st_context *st,
    enum pipe_error error;
    unsigned num_outputs;
 
+   st_prepare_vertex_program( st, stvp );
+
    _mesa_remove_output_reads(&stvp->Base.Base, PROGRAM_OUTPUT);
    _mesa_remove_output_reads(&stvp->Base.Base, PROGRAM_VARYING);
 
@@ -356,6 +361,36 @@ fail:
 }
 
 
+/**
+ * Find/create a vertex program varient.
+ */
+struct st_vp_varient *
+st_get_vp_varient(struct st_context *st,
+                  struct st_vertex_program *stvp,
+                  const struct st_vp_varient_key *key)
+{
+   struct st_vp_varient *vpv;
+
+   /* Search for existing varient */
+   for (vpv = stvp->varients; vpv; vpv = vpv->next) {
+      if (memcmp(&vpv->key, key, sizeof(*key)) == 0) {
+         break;
+      }
+   }
+
+   if (!vpv) {
+      /* create now */
+      vpv = st_translate_vertex_program(st, stvp, key);
+      if (vpv) {
+         /* insert into list */
+         vpv->next = stvp->varients;
+         stvp->varients = vpv;
+      }
+   }
+
+   return vpv;
+}
+
 
 /**
  * Translate a Mesa fragment shader into a TGSI shader using extra info in
diff --git a/src/mesa/state_tracker/st_program.h b/src/mesa/state_tracker/st_program.h
index 245866b..519ee8c 100644
--- a/src/mesa/state_tracker/st_program.h
+++ b/src/mesa/state_tracker/st_program.h
@@ -135,7 +135,6 @@ struct st_vp_varient
 struct st_vertex_program
 {
    struct gl_vertex_program Base;  /**< The Mesa vertex program */
-   GLuint serialNo, lastSerialNo;
 
    /** maps a Mesa VERT_ATTRIB_x to a packed TGSI input index */
    GLuint input_to_index[VERT_ATTRIB_MAX];
@@ -183,7 +182,6 @@ struct st_gp_varient
 struct st_geometry_program
 {
    struct gl_geometry_program Base;  /**< The Mesa geometry program */
-   GLuint serialNo;
 
    /** map GP input back to VP output */
    GLuint input_map[PIPE_MAX_SHADER_INPUTS];
@@ -258,6 +256,12 @@ st_reference_fragprog(struct st_context *st,
 }
 
 
+extern struct st_vp_varient *
+st_get_vp_varient(struct st_context *st,
+                  struct st_vertex_program *stvp,
+                  const struct st_vp_varient_key *key);
+
+
 extern struct st_fp_varient *
 st_get_fp_varient(struct st_context *st,
                   struct st_fragment_program *stfp,
@@ -271,19 +275,6 @@ st_get_gp_varient(struct st_context *st,
 
 
 
-/* Called after program string change, discard all previous
- * compilation results.
- */
-extern void
-st_prepare_vertex_program(struct st_context *st,
-                          struct st_vertex_program *stvp);
-
-extern struct st_vp_varient *
-st_translate_vertex_program(struct st_context *st,
-                            struct st_vertex_program *stvp,
-                            const struct st_vp_varient_key *key);
-
-
 extern void
 st_vp_release_varients( struct st_context *st,
                         struct st_vertex_program *stvp );




More information about the mesa-commit mailing list