Module: Mesa
Branch: arb_geometry_shader4
Commit: 141b85e9d24f8fbefd8210af6e8fa50882b043b1
URL:    
http://cgit.freedesktop.org/mesa/mesa/commit/?id=141b85e9d24f8fbefd8210af6e8fa50882b043b1

Author: Zack Rusin <[email protected]>
Date:   Sat Sep  5 17:52:33 2009 -0400

gs: lots of improvements to the linking code

unfortunately there's still something not quite right

---

 progs/glsl/convolution.frag             |    9 +-
 progs/glsl/convolutions.c               |   19 ++-
 src/mesa/main/mtypes.h                  |   12 +-
 src/mesa/state_tracker/st_atom_shader.c |  302 +++++++++++++++++++++++++++----
 src/mesa/state_tracker/st_program.c     |  100 ++++++++---
 src/mesa/state_tracker/st_program.h     |   23 ++-
 6 files changed, 389 insertions(+), 76 deletions(-)

diff --git a/progs/glsl/convolution.frag b/progs/glsl/convolution.frag
index e49b8ac..82c58c1 100644
--- a/progs/glsl/convolution.frag
+++ b/progs/glsl/convolution.frag
@@ -1,10 +1,12 @@
 
 const int KernelSize = 9;
 
+uniform int KernelCount;
 //texture offsets
 uniform vec2 Offset[KernelSize];
 //convolution kernel
 uniform vec4 KernelValue[KernelSize];
+uniform vec4 KernelScale[KernelSize];
 uniform sampler2D srcTex;
 uniform vec4 ScaleFactor;
 uniform vec4 BaseColor;
@@ -13,9 +15,8 @@ void main(void)
 {
     int i;
     vec4 sum = vec4(0.0);
-    for (i = 0; i < KernelSize; ++i) {
-        vec4 tmp = texture2D(srcTex, gl_TexCoord[0].st + Offset[i]);
-        sum += tmp * KernelValue[i];
+    for (i = 0; i < KernelCount; ++i) {
+        sum += KernelValue[i] * KernelScale[i];
     }
-    gl_FragColor = sum * ScaleFactor + BaseColor;
+    gl_FragColor = sum;
 }
diff --git a/progs/glsl/convolutions.c b/progs/glsl/convolutions.c
index c2fb76e..ee330cf 100644
--- a/progs/glsl/convolutions.c
+++ b/progs/glsl/convolutions.c
@@ -125,9 +125,9 @@ static void fillConvolution(GLint *k,
 {
    switch(filter) {
    case GAUSSIAN_BLUR:
-      k[0] = 1; k[1] = 2; k[2] = 1;
-      k[3] = 2; k[4] = 4; k[5] = 2;
-      k[6] = 1; k[7] = 2; k[8] = 1;
+      k[0] = 10; k[1] = 20; k[2] = 10;
+      k[3] = 20; k[4] = 40; k[5] = 20;
+      k[6] = 10; k[7] = 20; k[8] = 10;
 
       *scale = 1./16.;
       break;
@@ -184,6 +184,7 @@ static void setupConvolution()
    GLint *kernel = (GLint*)malloc(sizeof(GLint) * 9);
    GLfloat scale;
    GLfloat *vecKer = (GLfloat*)malloc(sizeof(GLfloat) * 9 * 4);
+   GLfloat *kerScale = (GLfloat*)malloc(sizeof(GLfloat) * 9 * 4);
    GLuint loc;
    GLuint i;
    GLfloat baseColor[4];
@@ -193,6 +194,14 @@ static void setupConvolution()
    baseColor[3] = 0;
 
    fillConvolution(kernel, &scale, baseColor);
+
+   for (i = 0; i < 9; ++i) {
+      kerScale[i*4 + 0] = 01.f / kernel[i];
+      kerScale[i*4 + 1] = 0;
+      kerScale[i*4 + 2] = 0;
+      kerScale[i*4 + 3] = 01.f / kernel[i];
+   }
+
    /*vector of 4*/
    for (i = 0; i < 9; ++i) {
       vecKer[i*4 + 0] = kernel[i];
@@ -203,6 +212,10 @@ static void setupConvolution()
 
    loc = glGetUniformLocationARB(program, "KernelValue");
    glUniform4fv(loc, 9, vecKer);
+   loc = glGetUniformLocationARB(program, "KernelScale");
+   glUniform4fv(loc, 9, kerScale);
+   loc = glGetUniformLocationARB(program, "KernelCount");
+   glUniform1i(loc, 9);
    loc = glGetUniformLocationARB(program, "ScaleFactor");
    glUniform4f(loc, scale, scale, scale, scale);
    loc = glGetUniformLocationARB(program, "BaseColor");
diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h
index 1c6c65e..bb48cd5 100644
--- a/src/mesa/main/mtypes.h
+++ b/src/mesa/main/mtypes.h
@@ -229,12 +229,12 @@ typedef enum
    GEOM_ATTRIB_COLOR1 = 2,
    GEOM_ATTRIB_SECONDARY_COLOR0 = 3,
    GEOM_ATTRIB_SECONDARY_COLOR1 = 4,
-   GEOM_ATTRIB_TEX_COORD = 5,
-   GEOM_ATTRIB_FOG_FRAG_COORD = 6,
-   GEOM_ATTRIB_POSITION = 7,
-   GEOM_ATTRIB_POINT_SIZE = 8,
-   GEOM_ATTRIB_CLIP_VERTEX = 9,
-   GEOM_ATTRIB_PRIMITIVE_ID = 10,
+   GEOM_ATTRIB_FOG_FRAG_COORD = 5,
+   GEOM_ATTRIB_POSITION = 6,
+   GEOM_ATTRIB_POINT_SIZE = 7,
+   GEOM_ATTRIB_CLIP_VERTEX = 8,
+   GEOM_ATTRIB_PRIMITIVE_ID = 9,
+   GEOM_ATTRIB_TEX_COORD = 10,
 
    GEOM_ATTRIB_VAR0 = 16,
    GEOM_ATTRIB_MAX = (GEOM_ATTRIB_VAR0 + MAX_VARYING)
diff --git a/src/mesa/state_tracker/st_atom_shader.c 
b/src/mesa/state_tracker/st_atom_shader.c
index e95ffa0..71cc252 100644
--- a/src/mesa/state_tracker/st_atom_shader.c
+++ b/src/mesa/state_tracker/st_atom_shader.c
@@ -64,8 +64,9 @@ struct translated_vertex_program
 {
    struct st_vertex_program *master;
 
-   /** The fragment shader "signature" this vertex shader is meant for: */
-   GLbitfield frag_inputs;
+   /** The fragment/geometry shader "signature" this vertex
+    * shader is meant for: */
+   GLbitfield linked_inputs;
 
    /** Compared against master vertex program's serialNo: */
    GLuint serialNo;
@@ -81,6 +82,27 @@ struct translated_vertex_program
    struct translated_vertex_program *next;  /**< next in linked list */
 };
 
+struct translated_geometry_program
+{
+   struct st_geometry_program *master;
+
+   /** The fragment shader "signature" this vertex
+    * shader is meant for: */
+   GLbitfield frag_inputs;
+
+   /** Compared against master vertex program's serialNo: */
+   GLuint serialNo;
+
+   /** Maps VERT_RESULT_x to slot */
+   GLuint output_to_slot[VERT_RESULT_MAX];
+   ubyte output_to_semantic_name[VERT_RESULT_MAX];
+   ubyte output_to_semantic_index[VERT_RESULT_MAX];
+
+   /** Pointer to the translated vertex program */
+   struct st_geometry_program *gp;
+
+   struct translated_geometry_program *next;  /**< next in linked list */
+};
 
 
 /**
@@ -114,6 +136,74 @@ vp_out_to_fp_in(GLuint vertResult)
    }
 }
 
+/**
+ * Given a geometry program output attribute, return the corresponding
+ * fragment program input attribute.
+ * \return -1 for geometry outputs that have no corresponding fragment input
+ */
+static GLint
+gp_out_to_fp_in(GLuint geomResult)
+{
+   if (geomResult >= GEOM_RESULT_TEX0 &&
+       geomResult < GEOM_RESULT_TEX0 + MAX_TEXTURE_COORD_UNITS)
+      return FRAG_ATTRIB_TEX0 + (geomResult - GEOM_RESULT_TEX0);
+
+   if (geomResult >= GEOM_RESULT_VAR0 &&
+       geomResult < GEOM_RESULT_VAR0 + MAX_VARYING - 2)
+      return FRAG_ATTRIB_VAR0 + (geomResult - GEOM_RESULT_VAR0);
+
+   switch (geomResult) {
+   case GEOM_RESULT_POS:
+      return FRAG_ATTRIB_WPOS;
+   case GEOM_RESULT_COL0:
+      return FRAG_ATTRIB_COL0;
+   case GEOM_RESULT_COL1:
+      return FRAG_ATTRIB_COL1;
+   case GEOM_RESULT_FOGC:
+      return FRAG_ATTRIB_FOGC;
+   default:
+      /* Back-face colors, primitive id, etc */
+      return -1;
+   }
+}
+
+/**
+ * Given a vertex program output attribute, return the corresponding
+ * geometry program input attribute.
+ * \return -1 for vertex outputs that have no corresponding geometry input
+ */
+static GLint
+vp_out_to_gp_in(GLuint vertResult)
+{
+   if (vertResult >= VERT_RESULT_TEX0 &&
+       vertResult < VERT_RESULT_TEX0 + MAX_TEXTURE_COORD_UNITS)
+      return GEOM_ATTRIB_TEX_COORD;
+
+   if (vertResult >= VERT_RESULT_VAR0 &&
+       vertResult < VERT_RESULT_VAR0 + MAX_VARYING)
+      return GEOM_ATTRIB_VAR0 + (vertResult - VERT_RESULT_VAR0);
+
+   switch (vertResult) {
+   case VERT_RESULT_HPOS:
+      return GEOM_ATTRIB_POSITION;
+   case VERT_RESULT_COL0:
+      return GEOM_ATTRIB_COLOR0;
+   case VERT_RESULT_COL1:
+      return GEOM_ATTRIB_COLOR1;
+   case VERT_RESULT_FOGC:
+      return GEOM_ATTRIB_FOG_FRAG_COORD;
+   case VERT_RESULT_PSIZ:
+      return GEOM_ATTRIB_POINT_SIZE;
+   case VERT_RESULT_BFC0:
+      return GEOM_ATTRIB_SECONDARY_COLOR0;
+   case VERT_RESULT_BFC1:
+      return GEOM_ATTRIB_SECONDARY_COLOR1;
+   default:
+      /* edge flags, etc */
+      return -1;
+   }
+}
+
 
 /**
  * Find a translated vertex program that corresponds to stvp and
@@ -128,11 +218,14 @@ find_translated_vp(struct st_context *st,
 {
    static const GLuint UNUSED = ~0;
    struct translated_vertex_program *xvp;
+   struct translated_geometry_program *xgp;
    const GLbitfield fragInputsRead = stfp->Base.Base.InputsRead;
-   GLbitfield geomInputsRead = 0;
+   GLbitfield geomInputsRead = 0, linkedInputs = fragInputsRead;
 
-   if (stgp)
+   if (stgp) {
       geomInputsRead = stgp->Base.Base.InputsRead;
+      linkedInputs = geomInputsRead;
+   }
 
    /*
     * Translate fragment program if needed.
@@ -157,44 +250,187 @@ find_translated_vp(struct st_context *st,
       st_translate_fragment_program(st, stfp, stfp->input_to_slot);
    }
 
-   if (stgp && !stgp->state.shader.tokens) {
-      GLuint inAttr, numIn = 0;
+   /* See if we've got a translated geometry program whose outputs match
+    * the fragment  program's inputs.
+    * XXX This could be a hash lookup, using InputsRead as the key.
+    */
+   if (stgp) {
+      for (xgp = stfp->geometry_programs; xgp; xgp = xgp->next) {
+         if (xgp->master == stgp && xgp->frag_inputs == fragInputsRead)
+            break;
+      }
+      /* No?  Allocate translated gp object now */
+      if (!xgp) {
+         xgp = ST_CALLOC_STRUCT(translated_geometry_program);
+         xgp->frag_inputs = fragInputsRead;
+         xgp->master = stgp;
+
+         xgp->next = stfp->geometry_programs;
+         stfp->geometry_programs = xgp;
+      }
 
-      for (inAttr = 0; inAttr < GEOM_ATTRIB_MAX; inAttr++) {
-         if (geomInputsRead & (1 << inAttr)) {
-            stgp->input_to_slot[inAttr] = numIn;
-            numIn++;
+      if (!stgp->state.shader.tokens) {
+         GLuint inAttr, numIn = 0;
+
+         for (inAttr = 0; inAttr < GEOM_ATTRIB_MAX; inAttr++) {
+            if (geomInputsRead & (1 << inAttr)) {
+               stgp->input_to_slot[inAttr] = numIn;
+               numIn++;
+            }
+            else {
+               stgp->input_to_slot[inAttr] = UNUSED;
+            }
          }
-         else {
-            stgp->input_to_slot[inAttr] = UNUSED;
+
+         stgp->num_input_slots = numIn;
+         assert(stgp->Base.Base.NumInstructions > 1);
+
+         if (xgp->serialNo != stgp->serialNo) {
+            GLuint outAttr;
+            const GLbitfield outputsWritten = stgp->Base.Base.OutputsWritten;
+            GLuint numGpOuts = 0;
+            GLboolean emitPntSize = GL_FALSE, emitBFC0 = GL_FALSE, emitBFC1 = 
GL_FALSE;
+            GLbitfield usedGenerics = 0x0;
+            GLbitfield usedOutputSlots = 0x0;
+
+            /* Compute mapping of geometry program outputs to slots, which 
depends
+             * on the fragment program's input->slot mapping.
+             */
+            for (outAttr = 0; outAttr < GEOM_RESULT_MAX; outAttr++) {
+               /* set defaults: */
+               xgp->output_to_slot[outAttr] = UNUSED;
+               xgp->output_to_semantic_name[outAttr] = TGSI_SEMANTIC_COUNT;
+               xgp->output_to_semantic_index[outAttr] = 99;
+
+               if (outAttr == GEOM_RESULT_POS) {
+                  /* always put xformed position into slot zero */
+                  GLuint slot = 0;
+                  xgp->output_to_slot[GEOM_RESULT_POS] = slot;
+                  xgp->output_to_semantic_name[outAttr] = 
TGSI_SEMANTIC_POSITION;
+                  xgp->output_to_semantic_index[outAttr] = 0;
+                  numGpOuts++;
+                  usedOutputSlots |= (1 << slot);
+               }
+               else if (outputsWritten & (1 << outAttr)) {
+                  /* see if the frag prog wants this geom output */
+                  GLint fpInAttrib = gp_out_to_fp_in(outAttr);
+                  if (fpInAttrib >= 0) {
+                     GLuint fpInSlot = stfp->input_to_slot[fpInAttrib];
+                     if (fpInSlot != ~0) {
+                        /* match this gp output to the fp input */
+                        GLuint gpOutSlot = stfp->input_map[fpInSlot];
+                        xgp->output_to_slot[outAttr] = gpOutSlot;
+                        xgp->output_to_semantic_name[outAttr] = 
stfp->input_semantic_name[fpInSlot];
+                        xgp->output_to_semantic_index[outAttr] = 
stfp->input_semantic_index[fpInSlot];
+                        numGpOuts++;
+                        usedOutputSlots |= (1 << gpOutSlot);
+                     }
+                     else {
+#if 0 /*debug*/
+                        printf("GP output %d not used by FP\n", outAttr);
+#endif
+                     }
+                  }
+                  else if (outAttr == GEOM_RESULT_PSIZ)
+                     emitPntSize = GL_TRUE;
+                  else if (outAttr == GEOM_RESULT_SCOL0)
+                     emitBFC0 = GL_TRUE;
+                  else if (outAttr == GEOM_RESULT_SCOL1)
+                     emitBFC1 = GL_TRUE;
+               }
+#if 0 /*debug*/
+               printf("assign gp output_to_slot[%d] = %d\n", outAttr,
+                      xgp->output_to_slot[outAttr]);
+#endif
+            }
+
+            /* must do these last */
+            if (emitPntSize) {
+               GLuint slot = numGpOuts++;
+               xgp->output_to_slot[GEOM_RESULT_PSIZ] = slot;
+               xgp->output_to_semantic_name[GEOM_RESULT_PSIZ] = 
TGSI_SEMANTIC_PSIZE;
+               xgp->output_to_semantic_index[GEOM_RESULT_PSIZ] = 0;
+               usedOutputSlots |= (1 << slot);
+            }
+            if (emitBFC0) {
+               GLuint slot = numGpOuts++;
+               xgp->output_to_slot[GEOM_RESULT_SCOL0] = slot;
+               xgp->output_to_semantic_name[GEOM_RESULT_SCOL0] = 
TGSI_SEMANTIC_COLOR;
+               xgp->output_to_semantic_index[GEOM_RESULT_SCOL0] = 0;
+               usedOutputSlots |= (1 << slot);
+            }
+            if (emitBFC1) {
+               GLuint slot = numGpOuts++;
+               xgp->output_to_slot[GEOM_RESULT_SCOL1] = slot;
+               xgp->output_to_semantic_name[GEOM_RESULT_SCOL1] = 
TGSI_SEMANTIC_COLOR;
+               xgp->output_to_semantic_index[GEOM_RESULT_SCOL1] = 1;
+               usedOutputSlots |= (1 << slot);
+            }
+
+            /* build usedGenerics mask */
+            usedGenerics = 0x0;
+            for (outAttr = 0; outAttr < GEOM_RESULT_MAX; outAttr++) {
+               if (xgp->output_to_semantic_name[outAttr] == 
TGSI_SEMANTIC_GENERIC) {
+                  usedGenerics |= (1 << 
xgp->output_to_semantic_index[outAttr]);
+               }
+            }
+
+            /* For each vertex geometry output that doesn't match up to a 
fragment
+             * program input, map the geometry program output to a free slot 
and
+             * free generic attribute.
+             */
+            for (outAttr = 0; outAttr < GEOM_RESULT_MAX; outAttr++) {
+               if (outputsWritten & (1 << outAttr)) {
+                  if (xgp->output_to_slot[outAttr] == UNUSED) {
+                     GLint freeGeneric = _mesa_ffs(~usedGenerics) - 1;
+                     GLint freeSlot = _mesa_ffs(~usedOutputSlots) - 1;
+                     usedGenerics |= (1 << freeGeneric);
+                     usedOutputSlots |= (1 << freeSlot);
+                     xgp->output_to_slot[outAttr] = freeSlot;
+                     xgp->output_to_semantic_name[outAttr] = 
TGSI_SEMANTIC_GENERIC;
+                     xgp->output_to_semantic_index[outAttr] = freeGeneric;
+                  }
+               }
+
+#if 0 /*debug*/
+               printf("gp output_to_slot[%d] = %d\n", outAttr,
+                      xgp->output_to_slot[outAttr]);
+#endif
+            }
          }
-      }
 
-      stgp->num_input_slots = numIn;
+         st_translate_geometry_program(st, stgp, stgp->input_to_slot,
+                                       xgp->output_to_slot,
+                                       xgp->output_to_semantic_name,
+                                       xgp->output_to_semantic_index);
 
-      assert(stgp->Base.Base.NumInstructions > 1);
+         xgp->gp = stgp;
 
-      st_translate_geometry_program(st, stgp, stgp->input_to_slot);
+         /* translated GP is up to date now */
+         xgp->serialNo = stgp->serialNo;
+      }
    }
-
    /* See if we've got a translated vertex program whose outputs match
-    * the fragment program's inputs.
+    * the fragment or geometry program's inputs.
     * XXX This could be a hash lookup, using InputsRead as the key.
     */
-   for (xvp = stfp->vertex_programs; xvp; xvp = xvp->next) {
-      if (xvp->master == stvp && xvp->frag_inputs == fragInputsRead) {
+#define LP_FUNC(FP, GP) ((stgp)?GP:FP)
+#define LP(X) ((stgp)?stgp->X:stfp->X)
+#define LP_SET(X, Y) do { if (stgp) stgp->X = Y; else stfp->X = Y; } while(0)
+
+   for (xvp = LP(vertex_programs); xvp; xvp = xvp->next) {
+      if (xvp->master == stvp && xvp->linked_inputs == linkedInputs)
          break;
-      }
    }
 
    /* No?  Allocate translated vp object now */
    if (!xvp) {
       xvp = ST_CALLOC_STRUCT(translated_vertex_program);
-      xvp->frag_inputs = fragInputsRead;
+      xvp->linked_inputs = linkedInputs;
       xvp->master = stvp;
 
-      xvp->next = stfp->vertex_programs;
-      stfp->vertex_programs = xvp;
+      xvp->next = LP(vertex_programs);
+      LP_SET(vertex_programs, xvp);
    }
 
    /* See if we need to translate vertex program to TGSI form */
@@ -226,21 +462,21 @@ find_translated_vp(struct st_context *st,
          }
          else if (outputsWritten & (1 << outAttr)) {
             /* see if the frag prog wants this vert output */
-            GLint fpInAttrib = vp_out_to_fp_in(outAttr);
-            if (fpInAttrib >= 0) {
-               GLuint fpInSlot = stfp->input_to_slot[fpInAttrib];
-               if (fpInSlot != ~0) {
-                  /* match this vp output to the fp input */
-                  GLuint vpOutSlot = stfp->input_map[fpInSlot];
+            GLint lpInAttrib = LP_FUNC(vp_out_to_fp_in(outAttr), 
vp_out_to_gp_in(outAttr));
+            if (lpInAttrib >= 0) {
+               GLuint lpInSlot = LP(input_to_slot[lpInAttrib]);
+               if (lpInSlot != ~0) {
+                  /* match this vp output to the lp input */
+                  GLuint vpOutSlot = LP(input_map[lpInSlot]);
                   xvp->output_to_slot[outAttr] = vpOutSlot;
-                  xvp->output_to_semantic_name[outAttr] = 
stfp->input_semantic_name[fpInSlot];
-                  xvp->output_to_semantic_index[outAttr] = 
stfp->input_semantic_index[fpInSlot];
+                  xvp->output_to_semantic_name[outAttr] = 
LP(input_semantic_name[lpInSlot]);
+                  xvp->output_to_semantic_index[outAttr] = 
LP(input_semantic_index[lpInSlot]);
                   numVpOuts++;
                   usedOutputSlots |= (1 << vpOutSlot);
                }
                else {
 #if 0 /*debug*/
-                  printf("VP output %d not used by FP\n", outAttr);
+                  printf("VP output %d not used by LP\n", outAttr);
 #endif
                }
             }
diff --git a/src/mesa/state_tracker/st_program.c 
b/src/mesa/state_tracker/st_program.c
index 5b646ba..f93a832 100644
--- a/src/mesa/state_tracker/st_program.c
+++ b/src/mesa/state_tracker/st_program.c
@@ -581,15 +581,16 @@ st_translate_fragment_program(struct st_context *st,
 void
 st_translate_geometry_program(struct st_context *st,
                               struct st_geometry_program *stgp,
-                              const GLuint inputMapping[])
+                              const GLuint inputMapping[],
+                              const GLuint outputMapping[],
+                              const ubyte *outputSemanticName,
+                              const ubyte *outputSemanticIndex)
 {
    struct pipe_context *pipe = st->pipe;
    struct tgsi_token *tokens;
-   GLuint *outputMapping;
    GLuint defaultInputMapping[GEOM_ATTRIB_MAX];
    GLuint defaultOutputMapping[GEOM_RESULT_MAX];
    struct pipe_geometry_shader_state gs;
-   GLuint interpMode[16];  /* XXX size? */
    GLuint attr;
    const GLbitfield inputsRead = stgp->Base.Base.InputsRead;
    GLuint vslot = 0;
@@ -631,60 +632,69 @@ st_translate_geometry_program(struct st_context *st,
       if (inputsRead & (1 << attr)) {
          const GLuint slot = gs_num_inputs;
 
-         defaultInputMapping[attr] = slot;
+         gs_num_inputs++;
 
-         stgp->input_map[slot] = vslot++;
+         defaultInputMapping[attr] = slot;
 
-         gs_num_inputs++;
+         stgp->input_map[slot] = vslot;
+         stgp->input_to_index[attr] = vslot;
+         stgp->index_to_input[vslot] = attr;
+         ++vslot;
 
          switch (attr) {
          case GEOM_ATTRIB_VERTICES:
             stgp->input_semantic_name[slot] = TGSI_SEMANTIC_VERTICES;
             stgp->input_semantic_index[slot] = 0;
-            interpMode[slot] = TGSI_INTERPOLATE_CONSTANT;
             break;
          case GEOM_ATTRIB_PRIMITIVE_ID:
             stgp->input_semantic_name[slot] = TGSI_SEMANTIC_PRIMID;
             stgp->input_semantic_index[slot] = 0;
-            interpMode[slot] = TGSI_INTERPOLATE_CONSTANT;
             break;
          case GEOM_ATTRIB_POSITION:
             stgp->input_semantic_name[slot] = TGSI_SEMANTIC_POSITION;
             stgp->input_semantic_index[slot] = 0;
-            interpMode[slot] = TGSI_INTERPOLATE_LINEAR;
             break;
          case GEOM_ATTRIB_COLOR0:
             stgp->input_semantic_name[slot] = TGSI_SEMANTIC_COLOR;
             stgp->input_semantic_index[slot] = 0;
-            interpMode[slot] = TGSI_INTERPOLATE_LINEAR;
             break;
          case GEOM_ATTRIB_COLOR1:
             stgp->input_semantic_name[slot] = TGSI_SEMANTIC_COLOR;
             stgp->input_semantic_index[slot] = 1;
-            interpMode[slot] = TGSI_INTERPOLATE_LINEAR;
             break;
          case GEOM_ATTRIB_FOG_FRAG_COORD:
             stgp->input_semantic_name[slot] = TGSI_SEMANTIC_FOG;
             stgp->input_semantic_index[slot] = 0;
-            interpMode[slot] = TGSI_INTERPOLATE_PERSPECTIVE;
             break;
          case GEOM_ATTRIB_TEX_COORD:
             stgp->input_semantic_name[slot] = TGSI_SEMANTIC_GENERIC;
             stgp->input_semantic_index[slot] = num_generic++;
-            interpMode[slot] = TGSI_INTERPOLATE_PERSPECTIVE;
             break;
          case GEOM_ATTRIB_VAR0:
             /* fall-through */
          default:
             stgp->input_semantic_name[slot] = TGSI_SEMANTIC_GENERIC;
             stgp->input_semantic_index[slot] = num_generic++;
-            interpMode[slot] = TGSI_INTERPOLATE_PERSPECTIVE;
          }
 
          input_flags[slot] = stgp->Base.Base.InputFlags[attr];
       }
    }
 
+#if 1
+   if (outputMapping && outputSemanticName) {
+      printf("GEOM_RESULT  written  out_slot  semantic_name  
semantic_index\n");
+      for (attr = 0; attr < GEOM_RESULT_MAX; attr++) {
+         printf("    %-2d          %c       %3d          %2d              
%2d\n",
+                attr,
+                ((stgp->Base.Base.OutputsWritten & (1 << attr)) ? 'Y' : ' '),
+                outputMapping[attr],
+                outputSemanticName[attr],
+                outputSemanticIndex[attr]);
+      }
+   }
+#endif
+
    /* initialize output semantics to defaults */
    for (i = 0; i < PIPE_MAX_SHADER_OUTPUTS; i++) {
       gs_output_semantic_name[i] = TGSI_SEMANTIC_GENERIC;
@@ -706,10 +716,15 @@ st_translate_geometry_program(struct st_context *st,
           * Use the generic semantic indexes from there, instead of
           * guessing below.
           */
-
-         slot = gs_num_outputs;
-         gs_num_outputs++;
-         defaultOutputMapping[attr] = slot;
+         if (outputMapping) {
+            slot = outputMapping[attr];
+            assert(slot != ~0);
+         }
+         else {
+            slot = gs_num_outputs;
+            gs_num_outputs++;
+            defaultOutputMapping[attr] = slot;
+         }
 
          switch (attr) {
          case GEOM_RESULT_POS:
@@ -753,18 +768,59 @@ st_translate_geometry_program(struct st_context *st,
          case GEOM_RESULT_VAR0:
             /* fall-through */
          default:
-            /* use default semantic info */
-            gs_output_semantic_name[slot] = TGSI_SEMANTIC_GENERIC;
-            gs_output_semantic_index[slot] = num_generic++;
+            assert(slot < Elements(gs_output_semantic_name));
+            if (outputSemanticName) {
+               /* use provided semantic into */
+               assert(outputSemanticName[attr] != TGSI_SEMANTIC_COUNT);
+               gs_output_semantic_name[slot] = outputSemanticName[attr];
+               gs_output_semantic_index[slot] = outputSemanticIndex[attr];
+            }
+            else {
+               /* use default semantic info */
+               gs_output_semantic_name[slot] = TGSI_SEMANTIC_GENERIC;
+               gs_output_semantic_index[slot] = num_generic++;
+            }
          }
 
+         assert(slot < Elements(output_flags));
          output_flags[slot] = stgp->Base.Base.OutputFlags[attr];
       }
    }
 
    assert(gs_output_semantic_name[0] == TGSI_SEMANTIC_POSITION);
 
-   outputMapping = defaultOutputMapping;
+   if (outputMapping) {
+      /* find max output slot referenced to compute gs_num_outputs */
+      GLuint maxSlot = 0;
+      for (attr = 0; attr < GEOM_RESULT_MAX; attr++) {
+         if (outputMapping[attr] != ~0 && outputMapping[attr] > maxSlot)
+            maxSlot = outputMapping[attr];
+      }
+      gs_num_outputs = maxSlot + 1;
+   }
+   else {
+      outputMapping = defaultOutputMapping;
+   }
+
+#if 1 /* debug */
+   {
+      GLuint i;
+      printf("outputMapping? %d\n", outputMapping ? 1 : 0);
+      if (outputMapping) {
+         printf("attr -> slot\n");
+         for (i = 0; i < 16;  i++) {
+            printf(" %2d       %3d\n", i, outputMapping[i]);
+         }
+      }
+      printf("slot    sem_name  sem_index\n");
+      for (i = 0; i < gs_num_outputs; i++) {
+         printf(" %2d         %d         %d\n",
+                i,
+                gs_output_semantic_name[i],
+                gs_output_semantic_index[i]);
+      }
+   }
+#endif
 
    /* free old shader state, if any */
    if (stgp->state.shader.tokens) {
diff --git a/src/mesa/state_tracker/st_program.h 
b/src/mesa/state_tracker/st_program.h
index 2f986ea..595733d 100644
--- a/src/mesa/state_tracker/st_program.h
+++ b/src/mesa/state_tracker/st_program.h
@@ -42,6 +42,7 @@
 struct cso_fragment_shader;
 struct cso_vertex_shader;
 struct translated_vertex_program;
+struct translated_geometry_program;
 
 
 /**
@@ -55,7 +56,7 @@ struct st_fragment_program
    GLuint input_to_slot[FRAG_ATTRIB_MAX];  /**< Maps FRAG_ATTRIB_x to slot */
    GLuint num_input_slots;
 
-   /** map FP input back to VP output */
+   /** map FP input back to VP/GP output */
    GLuint input_map[PIPE_MAX_SHADER_INPUTS];
 
    ubyte input_semantic_name[PIPE_MAX_SHADER_INPUTS];
@@ -70,6 +71,7 @@ struct st_fragment_program
     * outputs match this fragment program's inputs.
     */
    struct translated_vertex_program *vertex_programs;
+   struct translated_geometry_program *geometry_programs;
 
    /** Program prefixed with glBitmap prologue */
    struct st_fragment_program *bitmap_program;
@@ -110,9 +112,12 @@ struct st_geometry_program
    struct gl_geometry_program Base;  /**< The Mesa geometry program */
    GLuint serialNo;
 
-   /** maps a Mesa VERT_ATTRIB_x to a packed TGSI input index */
+   /** map GP input back to VP output */
+   GLuint input_map[PIPE_MAX_SHADER_INPUTS];
+
+   /** maps a Mesa GEOM_ATTRIB_x to a packed TGSI input index */
    GLuint input_to_index[GEOM_ATTRIB_MAX];
-   /** maps a TGSI input index back to a Mesa VERT_ATTRIB_x */
+   /** maps a TGSI input index back to a Mesa GEOM_ATTRIB_x */
    GLuint index_to_input[PIPE_MAX_SHADER_INPUTS];
 
    GLuint num_inputs;
@@ -120,12 +125,10 @@ struct st_geometry_program
    GLuint input_to_slot[GEOM_ATTRIB_MAX];  /**< Maps GEOM_ATTRIB_x to slot */
    GLuint num_input_slots;
 
-   /** map FP input back to VP output */
-   GLuint input_map[PIPE_MAX_SHADER_INPUTS];
-
    ubyte input_semantic_name[PIPE_MAX_SHADER_INPUTS];
    ubyte input_semantic_index[PIPE_MAX_SHADER_INPUTS];
 
+   struct translated_vertex_program *vertex_programs;
 
    struct pipe_geometry_shader_state state;
    void *driver_shader;
@@ -192,10 +195,14 @@ st_translate_fragment_program(struct st_context *st,
                               struct st_fragment_program *fp,
                               const GLuint inputMapping[]);
 
+
 extern void
 st_translate_geometry_program(struct st_context *st,
-                              struct st_geometry_program *fp,
-                              const GLuint inputMapping[]);
+                              struct st_geometry_program *stgp,
+                              const GLuint inputMapping[],
+                              const GLuint outputMapping[],
+                              const ubyte *outputSemanticName,
+                              const ubyte *outputSemanticIndex);
 
 extern void
 st_translate_vertex_program(struct st_context *st,

_______________________________________________
mesa-commit mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/mesa-commit

Reply via email to