Mesa (arb_geometry_shader4): gs: start implementing geometry shading

Zack Rusin zack at kemper.freedesktop.org
Sat Feb 14 04:19:04 UTC 2009


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

Author: Zack Rusin <zackr at vmware.com>
Date:   Fri Feb 13 23:12:36 2009 -0500

gs: start implementing geometry shading

---

 src/mesa/main/mtypes.h                 |  137 +++++++++++++++++++++++++++++++-
 src/mesa/shader/shader_api.c           |    4 +-
 src/mesa/shader/slang/slang_codegen.c  |   60 ++++++++++++--
 src/mesa/shader/slang/slang_compile.c  |   19 +++--
 src/mesa/shader/slang/slang_compile.h  |    4 +-
 src/mesa/shader/slang/slang_emit.c     |    8 +-
 src/mesa/state_tracker/st_cb_program.c |   29 +++++++-
 src/mesa/state_tracker/st_context.h    |    9 +-
 src/mesa/state_tracker/st_program.h    |   24 ++++++
 9 files changed, 268 insertions(+), 26 deletions(-)

diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h
index be982af..1057dd9 100644
--- a/src/mesa/main/mtypes.h
+++ b/src/mesa/main/mtypes.h
@@ -246,8 +246,110 @@ enum
 #define VERT_RESULT_MAX  (VERT_RESULT_VAR0 + MAX_VARYING)
 /*@}*/
 
+/*********************************************/
 
 /**
+ * Indexes for geometry program attributes.
+ */
+enum
+{
+   GEOM_ATTRIB_VERTICES = 0, /*gl_VerticesIn*/
+   GEOM_ATTRIB_COLOR0 = 1,
+   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_GENERIC0 = 16,
+   GEOM_ATTRIB_GENERIC1 = 17,
+   GEOM_ATTRIB_GENERIC2 = 18,
+   GEOM_ATTRIB_GENERIC3 = 19,
+   GEOM_ATTRIB_GENERIC4 = 20,
+   GEOM_ATTRIB_GENERIC5 = 21,
+   GEOM_ATTRIB_GENERIC6 = 22,
+   GEOM_ATTRIB_GENERIC7 = 23,
+   GEOM_ATTRIB_GENERIC8 = 24,
+   GEOM_ATTRIB_GENERIC9 = 25,
+   GEOM_ATTRIB_GENERIC10 = 26,
+   GEOM_ATTRIB_GENERIC11 = 27,
+   GEOM_ATTRIB_GENERIC12 = 28,
+   GEOM_ATTRIB_GENERIC13 = 29,
+   GEOM_ATTRIB_GENERIC14 = 30,
+   GEOM_ATTRIB_GENERIC15 = 31,
+   GEOM_ATTRIB_MAX = 32
+};
+
+/**
+ * Bitflags for geometry attributes.
+ * These are used in bitfields in many places.
+ */
+/*@{*/
+#define GEOM_BIT_VERTICES    (1 << GEOM_ATTRIB_VERTICES)
+#define GEOM_BIT_COLOR0      (1 << GEOM_ATTRIB_COLOR0)
+#define GEOM_BIT_COLOR1      (1 << GEOM_ATTRIB_COLOR1)
+#define GEOM_BIT_SCOLOR0     (1 << GEOM_ATTRIB_SECONDARY_COLOR0)
+#define GEOM_BIT_SCOLOR1     (1 << GEOM_ATTRIB_SECONDARY_COLOR1)
+#define GEOM_BIT_TEX_COORD   (1 << GEOM_ATTRIB_TEX_COORD)
+#define GEOM_BIT_FOG_COORD   (1 << GEOM_ATTRIB_FOG_FRAG_COORD)
+#define GEOM_BIT_POSITION    (1 << GEOM_ATTRIB_POSITION)
+#define GEOM_BIT_POINT_SIDE  (1 << GEOM_ATTRIB_POINT_SIZE)
+#define GEOM_BIT_CLIP_VERTEX (1 << GEOM_ATTRIB_CLIP_VERTEX)
+#define GEOM_BIT_PRIM_ID     (1 << GEOM_ATTRIB_PRIMITIVE_ID)
+#define GEOM_BIT_GENERIC0    (1 << GEOM_ATTRIB_GENERIC0)
+#define GEOM_BIT_GENERIC1    (1 << GEOM_ATTRIB_GENERIC1)
+#define GEOM_BIT_GENERIC2    (1 << GEOM_ATTRIB_GENERIC2)
+#define GEOM_BIT_GENERIC3    (1 << GEOM_ATTRIB_GENERIC3)
+#define GEOM_BIT_GENERIC4    (1 << GEOM_ATTRIB_GENERIC4)
+#define GEOM_BIT_GENERIC5    (1 << GEOM_ATTRIB_GENERIC5)
+#define GEOM_BIT_GENERIC6    (1 << GEOM_ATTRIB_GENERIC6)
+#define GEOM_BIT_GENERIC7    (1 << GEOM_ATTRIB_GENERIC7)
+#define GEOM_BIT_GENERIC8    (1 << GEOM_ATTRIB_GENERIC8)
+#define GEOM_BIT_GENERIC9    (1 << GEOM_ATTRIB_GENERIC9)
+#define GEOM_BIT_GENERIC10   (1 << GEOM_ATTRIB_GENERIC10)
+#define GEOM_BIT_GENERIC11   (1 << GEOM_ATTRIB_GENERIC11)
+#define GEOM_BIT_GENERIC12   (1 << GEOM_ATTRIB_GENERIC12)
+#define GEOM_BIT_GENERIC13   (1 << GEOM_ATTRIB_GENERIC13)
+#define GEOM_BIT_GENERIC14   (1 << GEOM_ATTRIB_GENERIC14)
+#define GEOM_BIT_GENERIC15   (1 << GEOM_ATTRIB_GENERIC15)
+
+#define GEOM_BIT_TEX(u)  (1 << (GEOM_ATTRIB_TEX0 + (u)))
+#define GEOM_BIT_GENERIC(g)  (1 << (GEOM_ATTRIB_GENERIC0 + (g)))
+/*@}*/
+
+
+/**
+ * Indexes for geometry program result attributes
+ */
+/*@{*/
+#define GEOM_RESULT_POS 0
+#define GEOM_RESULT_COL0 1
+#define GEOM_RESULT_COL1 2
+#define GEOM_RESULT_SCOL0 3
+#define GEOM_RESULT_SCOL1 4
+#define GEOM_RESULT_FOGC 5
+#define GEOM_RESULT_TEX0 6
+#define GEOM_RESULT_TEX1 7
+#define GEOM_RESULT_TEX2 8
+#define GEOM_RESULT_TEX3 9
+#define GEOM_RESULT_TEX4 10
+#define GEOM_RESULT_TEX5 11
+#define GEOM_RESULT_TEX6 12
+#define GEOM_RESULT_TEX7 13
+#define GEOM_RESULT_PSIZ 14
+#define GEOM_RESULT_CLPV 15
+#define GEOM_RESULT_PRID 16
+#define GEOM_RESULT_LAYR 17
+#define GEOM_RESULT_VAR0 18  /**< shader varying */
+#define GEOM_RESULT_MAX  (GEOM_RESULT_VAR0 + MAX_VARYING)
+/*@}*/
+
+/*********************************************/
+/**
  * Indexes for fragment program input attributes.
  */
 enum
@@ -1944,6 +2046,13 @@ struct gl_vertex_program
 };
 
 
+/** Geometry program object */
+struct gl_geometry_program
+{
+   struct gl_program Base;   /**< base class */
+};
+
+
 /** Fragment program object */
 struct gl_fragment_program
 {
@@ -2010,6 +2119,28 @@ struct gl_vertex_program_state
 
 
 /**
+ * Context state for geometry programs.
+ */
+struct gl_geometry_program_state
+{
+   GLboolean Enabled;               /**< GL_ARB_GEOMETRY_SHADER4 */
+   GLboolean _Enabled;              /**< Enabled and valid program? */
+   struct gl_geometry_program *Current;  /**< user-bound geometry program */
+
+   /** Currently enabled and valid program (including internal programs
+    * and compiled shader programs).
+    */
+   struct gl_geometry_program *_Current;
+
+   GLfloat Parameters[MAX_PROGRAM_ENV_PARAMS][4]; /**< Env params */
+
+   /** Cache of fixed-function programs */
+   struct gl_program_cache *Cache;
+};
+
+
+
+/**
  * Context state for fragment programs.
  */
 struct gl_fragment_program_state
@@ -2157,12 +2288,13 @@ struct gl_shader_program
    /* post-link info: */
    struct gl_vertex_program *VertexProgram;     /**< Linked vertex program */
    struct gl_fragment_program *FragmentProgram; /**< Linked fragment prog */
+   struct gl_geometry_program *GeometryProgram; /**< Linked geometry prog */
    struct gl_uniform_list *Uniforms;
    struct gl_program_parameter_list *Varying;
    GLboolean LinkStatus;   /**< GL_LINK_STATUS */
    GLboolean Validated;
    GLchar *InfoLog;
-};   
+};
 
 
 #define GLSL_DUMP      0x1  /**< Dump shaders to stdout */
@@ -2524,6 +2656,7 @@ struct gl_constants
    GLuint MaxViewportWidth, MaxViewportHeight;
    struct gl_program_constants VertexProgram;    /* GL_ARB_vertex_program */
    struct gl_program_constants FragmentProgram;  /* GL_ARB_fragment_program */
+   struct gl_program_constants GeometryProgram;  /* GL_ARB_geometry_shader4 */
    /* shared by vertex and fragment program: */
    GLuint MaxProgramMatrices;
    GLuint MaxProgramMatrixStackDepth;
@@ -2564,6 +2697,7 @@ struct gl_extensions
    GLboolean ARB_fragment_program_shadow;
    GLboolean ARB_fragment_shader;
    GLboolean ARB_framebuffer_object;
+   GLboolean ARB_geometry_shader4;
    GLboolean ARB_half_float_pixel;
    GLboolean ARB_imaging;
    GLboolean ARB_multisample;
@@ -3083,6 +3217,7 @@ struct __GLcontextRec
    struct gl_program_state Program;        /**< for vertex or fragment progs */
    struct gl_vertex_program_state VertexProgram;   /**< GL_ARB/NV_vertex_program */
    struct gl_fragment_program_state FragmentProgram;  /**< GL_ARB/NV_vertex_program */
+   struct gl_geometry_program_state GeometryProgram;  /**< GL_ARB_geometry_shader4 */
    struct gl_ati_fragment_shader_state ATIFragmentShader;  /**< GL_ATI_fragment_shader */
 
    struct gl_query_state Query;  /**< GL_ARB_occlusion_query */
diff --git a/src/mesa/shader/shader_api.c b/src/mesa/shader/shader_api.c
index 013e912..add955f 100644
--- a/src/mesa/shader/shader_api.c
+++ b/src/mesa/shader/shader_api.c
@@ -253,7 +253,8 @@ struct gl_shader *
 _mesa_new_shader(GLcontext *ctx, GLuint name, GLenum type)
 {
    struct gl_shader *shader;
-   assert(type == GL_FRAGMENT_SHADER || type == GL_VERTEX_SHADER);
+   assert(type == GL_FRAGMENT_SHADER || type == GL_VERTEX_SHADER ||
+          type == GL_GEOMETRY_SHADER_ARB);
    shader = CALLOC_STRUCT(gl_shader);
    if (shader) {
       shader->Type = type;
@@ -605,6 +606,7 @@ _mesa_create_shader(GLcontext *ctx, GLenum type)
    switch (type) {
    case GL_FRAGMENT_SHADER:
    case GL_VERTEX_SHADER:
+   case GL_GEOMETRY_SHADER_ARB:
       sh = _mesa_new_shader(ctx, name, type);
       break;
    default:
diff --git a/src/mesa/shader/slang/slang_codegen.c b/src/mesa/shader/slang/slang_codegen.c
index 11340d2..0fbe3be 100644
--- a/src/mesa/shader/slang/slang_codegen.c
+++ b/src/mesa/shader/slang/slang_codegen.c
@@ -398,6 +398,20 @@ _slang_input_index(const char *name, GLenum target, GLuint *swizzleOut)
       { "gl_MultiTexCoord7", VERT_ATTRIB_TEX7, SWIZZLE_NOOP },
       { NULL, 0, SWIZZLE_NOOP }
    };
+   static const struct input_info geoInputs[] = {
+      { "gl_VerticesIn", GEOM_ATTRIB_VERTICES, SWIZZLE_NOOP },
+      { "gl_FrontColorIn", GEOM_ATTRIB_COLOR0, SWIZZLE_NOOP },
+      { "gl_BackColorIn", GEOM_ATTRIB_COLOR1, SWIZZLE_NOOP },
+      { "gl_FrontSecondaryColorIn", GEOM_ATTRIB_SECONDARY_COLOR0, SWIZZLE_NOOP },
+      { "gl_BackSecondaryColorIn", GEOM_ATTRIB_SECONDARY_COLOR1, SWIZZLE_NOOP },
+      { "gl_TexCoordIn", GEOM_ATTRIB_TEX_COORD, SWIZZLE_NOOP },
+      { "gl_FogFragCoordIn", GEOM_ATTRIB_FOG_FRAG_COORD, SWIZZLE_NOOP },
+      { "gl_PositionIn", GEOM_ATTRIB_POSITION, SWIZZLE_NOOP },
+      { "gl_ClipVertexIn", GEOM_ATTRIB_CLIP_VERTEX, SWIZZLE_NOOP },
+      { "gl_PointSizeIn", GEOM_ATTRIB_POINT_SIZE, SWIZZLE_NOOP },
+      { "gl_PrimitiveIDIn", GEOM_ATTRIB_PRIMITIVE_ID, SWIZZLE_NOOP },
+      { NULL, 0, SWIZZLE_NOOP }
+   };
    static const struct input_info fragInputs[] = {
       { "gl_FragCoord", FRAG_ATTRIB_WPOS, SWIZZLE_NOOP },
       { "gl_Color", FRAG_ATTRIB_COL0, SWIZZLE_NOOP },
@@ -411,7 +425,8 @@ _slang_input_index(const char *name, GLenum target, GLuint *swizzleOut)
    };
    GLuint i;
    const struct input_info *inputs
-      = (target == GL_VERTEX_PROGRAM_ARB) ? vertInputs : fragInputs;
+      = (target == GL_VERTEX_PROGRAM_ARB) ? vertInputs :
+      ((target == GL_FRAGMENT_PROGRAM_ARB) ? fragInputs : geoInputs);
 
    ASSERT(MAX_TEXTURE_COORD_UNITS == 8); /* if this fails, fix vertInputs above */
 
@@ -449,6 +464,20 @@ _slang_output_index(const char *name, GLenum target)
       { "gl_PointSize", VERT_RESULT_PSIZ },
       { NULL, 0 }
    };
+   static const struct output_info geoOutputs[] = {
+      { "gl_Position", GEOM_RESULT_POS },
+      { "gl_FrontColor", GEOM_RESULT_COL0 },
+      { "gl_BackColor", GEOM_RESULT_COL1 },
+      { "gl_FrontSecondaryColor", GEOM_RESULT_SCOL0 },
+      { "gl_BackSecondaryColor", GEOM_RESULT_SCOL1 },
+      { "gl_TexCoord", GEOM_RESULT_TEX0 },
+      { "gl_FogFragCoord", GEOM_RESULT_FOGC },
+      { "gl_ClipVertex", GEOM_RESULT_CLPV },
+      { "gl_PointSize", GEOM_RESULT_PSIZ },
+      { "gl_PrimitiveID", GEOM_RESULT_PRID },
+      { "gl_Layer", GEOM_RESULT_LAYR },
+      { NULL, 0 }
+   };
    static const struct output_info fragOutputs[] = {
       { "gl_FragColor", FRAG_RESULT_COLR },
       { "gl_FragDepth", FRAG_RESULT_DEPR },
@@ -457,7 +486,8 @@ _slang_output_index(const char *name, GLenum target)
    };
    GLuint i;
    const struct output_info *outputs
-      = (target == GL_VERTEX_PROGRAM_ARB) ? vertOutputs : fragOutputs;
+      = (target == GL_VERTEX_PROGRAM_ARB) ? vertOutputs :
+      ((target == GL_FRAGMENT_PROGRAM_ARB) ? fragOutputs : geoOutputs);
 
    for (i = 0; outputs[i].Name; i++) {
       if (strcmp(outputs[i].Name, name) == 0) {
@@ -4274,7 +4304,7 @@ _slang_codegen_global_variable(slang_assemble_ctx *A, slang_variable *var,
    const char *varName = (char *) var->a_name;
    GLboolean success = GL_TRUE;
    slang_ir_storage *store = NULL;
-   int dbg = 0;
+   int dbg = 1;
    const GLenum datatype = _slang_gltype_from_specifier(&var->type.specifier);
    const GLint size = _slang_sizeof_type_specifier(&var->type.specifier);
    const GLint arrayLen = _slang_array_length(var);
@@ -4430,8 +4460,7 @@ _slang_codegen_global_variable(slang_assemble_ctx *A, slang_variable *var,
             assert(index < FRAG_ATTRIB_MAX);
             store = _slang_new_ir_storage_swz(PROGRAM_INPUT, index,
                                               size, swizzle);
-         }
-         else {
+         } else if (type == SLANG_UNIT_VERTEX_BUILTIN) {
             /* vertex program output */
             GLint index = _slang_output_index(varName, GL_VERTEX_PROGRAM_ARB);
             GLuint swizzle = _slang_var_swizzle(size, 0);
@@ -4440,6 +4469,15 @@ _slang_codegen_global_variable(slang_assemble_ctx *A, slang_variable *var,
             assert(type == SLANG_UNIT_VERTEX_BUILTIN);
             store = _slang_new_ir_storage_swz(PROGRAM_OUTPUT, index,
                                               size, swizzle);
+         } else {
+            /* geometry program output */
+            GLint index = _slang_output_index(varName, GL_GEOMETRY_SHADER_ARB);
+            GLuint swizzle = _slang_var_swizzle(size, 0);
+            assert(index >= 0);
+            assert(index < GEOM_RESULT_MAX);
+            assert(type == SLANG_UNIT_GEOMETRY_BUILTIN);
+            store = _slang_new_ir_storage_swz(PROGRAM_OUTPUT, index,
+                                              size, swizzle);
          }
          if (dbg) printf("V/F ");
       }
@@ -4484,12 +4522,16 @@ _slang_codegen_global_variable(slang_assemble_ctx *A, slang_variable *var,
       if (type == SLANG_UNIT_VERTEX_BUILTIN) {
          GLint index = _slang_output_index(varName, GL_VERTEX_PROGRAM_ARB);
          store = _slang_new_ir_storage(PROGRAM_OUTPUT, index, size);
-      }
-      else {
+      } else if (type == SLANG_UNIT_FRAGMENT_BUILTIN) {
          GLint index = _slang_output_index(varName, GL_FRAGMENT_PROGRAM_ARB);
          GLint specialSize = 4; /* treat all fragment outputs as float[4] */
          assert(type == SLANG_UNIT_FRAGMENT_BUILTIN);
          store = _slang_new_ir_storage(PROGRAM_OUTPUT, index, specialSize);
+      } else {
+         GLint index = _slang_output_index(varName, GL_GEOMETRY_SHADER_ARB);
+         GLint specialSize = 4; /* treat all fragment outputs as float[4] */
+         assert(type == SLANG_UNIT_GEOMETRY_BUILTIN);
+         store = _slang_new_ir_storage(PROGRAM_OUTPUT, index, specialSize);
       }
       if (dbg) printf("OUTPUT ");
    }
@@ -4538,7 +4580,7 @@ _slang_codegen_function(slang_assemble_ctx * A, slang_function * fun)
       /* we only really generate code for main, all other functions get
        * inlined or codegen'd upon an actual call.
        */
-#if 0
+#if 1
       /* do some basic error checking though */
       if (fun->header.type.specifier.type != SLANG_SPEC_VOID) {
          /* check that non-void functions actually return something */
@@ -4558,7 +4600,7 @@ _slang_codegen_function(slang_assemble_ctx * A, slang_function * fun)
       return GL_TRUE;  /* not an error */
    }
 
-#if 0
+#if 1
    printf("\n*********** codegen_function %s\n", (char *) fun->header.a_name);
    slang_print_function(fun, 1);
 #endif
diff --git a/src/mesa/shader/slang/slang_compile.c b/src/mesa/shader/slang/slang_compile.c
index cfed977..15c4b9b 100644
--- a/src/mesa/shader/slang/slang_compile.c
+++ b/src/mesa/shader/slang/slang_compile.c
@@ -2340,10 +2340,13 @@ parse_code_unit(slang_parse_ctx * C, slang_code_unit * unit,
        unit->type == SLANG_UNIT_FRAGMENT_SHADER) {
       maxRegs = ctx->Const.FragmentProgram.MaxTemps;
    }
-   else {
-      assert(unit->type == SLANG_UNIT_VERTEX_BUILTIN ||
-             unit->type == SLANG_UNIT_VERTEX_SHADER);
+   else if (unit->type == SLANG_UNIT_VERTEX_BUILTIN ||
+            unit->type == SLANG_UNIT_VERTEX_SHADER) {
       maxRegs = ctx->Const.VertexProgram.MaxTemps;
+   } else {
+      assert(unit->type == SLANG_UNIT_GEOMETRY_BUILTIN ||
+             unit->type == SLANG_UNIT_GEOMETRY_SHADER);
+      maxRegs = ctx->Const.GeometryProgram.MaxTemps;
    }
 
    /* setup output context */
@@ -2729,9 +2732,11 @@ _slang_compile(GLcontext *ctx, struct gl_shader *shader)
    if (shader->Type == GL_VERTEX_SHADER) {
       type = SLANG_UNIT_VERTEX_SHADER;
    }
-   else {
-      assert(shader->Type == GL_FRAGMENT_SHADER);
+   else if (shader->Type == GL_FRAGMENT_SHADER) {
       type = SLANG_UNIT_FRAGMENT_SHADER;
+   } else {
+      assert(shader->Type == GL_GEOMETRY_SHADER_ARB);
+      type = SLANG_UNIT_GEOMETRY_SHADER;
    }
 
    if (!shader->Source)
@@ -2745,8 +2750,10 @@ _slang_compile(GLcontext *ctx, struct gl_shader *shader)
       GLenum progTarget;
       if (shader->Type == GL_VERTEX_SHADER)
          progTarget = GL_VERTEX_PROGRAM_ARB;
-      else
+      else if (shader->Type == GL_FRAGMENT_SHADER)
          progTarget = GL_FRAGMENT_PROGRAM_ARB;
+      else
+         progTarget = GL_GEOMETRY_SHADER_ARB;
       shader->Program = ctx->Driver.NewProgram(ctx, progTarget, 1);
       shader->Program->Parameters = _mesa_new_parameter_list();
       shader->Program->Varying = _mesa_new_parameter_list();
diff --git a/src/mesa/shader/slang/slang_compile.h b/src/mesa/shader/slang/slang_compile.h
index 7fb549d..71fcaa3 100644
--- a/src/mesa/shader/slang/slang_compile.h
+++ b/src/mesa/shader/slang/slang_compile.h
@@ -48,8 +48,10 @@ typedef enum slang_unit_type_
 {
    SLANG_UNIT_FRAGMENT_SHADER,
    SLANG_UNIT_VERTEX_SHADER,
+   SLANG_UNIT_GEOMETRY_SHADER,
    SLANG_UNIT_FRAGMENT_BUILTIN,
-   SLANG_UNIT_VERTEX_BUILTIN
+   SLANG_UNIT_VERTEX_BUILTIN,
+   SLANG_UNIT_GEOMETRY_BUILTIN
 } slang_unit_type;
 
 
diff --git a/src/mesa/shader/slang/slang_emit.c b/src/mesa/shader/slang/slang_emit.c
index 2dd122c..18e5a3b 100644
--- a/src/mesa/shader/slang/slang_emit.c
+++ b/src/mesa/shader/slang/slang_emit.c
@@ -2417,15 +2417,17 @@ _slang_emit_code(slang_ir_node *n, slang_var_table *vt,
 
    if (!emitInfo.EmitCondCodes) {
       emitInfo.EmitHighLevelInstructions = GL_TRUE;
-   }      
+   }
 
    /* Check uniform/constant limits */
    if (prog->Target == GL_FRAGMENT_PROGRAM_ARB) {
       maxUniforms = ctx->Const.FragmentProgram.MaxUniformComponents / 4;
    }
-   else {
-      assert(prog->Target == GL_VERTEX_PROGRAM_ARB);
+   else if (prog->Target == GL_VERTEX_PROGRAM_ARB) {
       maxUniforms = ctx->Const.VertexProgram.MaxUniformComponents / 4;
+   } else {
+      assert(prog->Target == GL_GEOMETRY_SHADER_ARB);
+      maxUniforms = ctx->Const.GeometryProgram.MaxUniformComponents / 4;
    }
    if (prog->Parameters->NumParameters > maxUniforms) {
       slang_info_log_error(log, "Constant/uniform register limit exceeded");
diff --git a/src/mesa/state_tracker/st_cb_program.c b/src/mesa/state_tracker/st_cb_program.c
index 4398ab2..1c623eb 100644
--- a/src/mesa/state_tracker/st_cb_program.c
+++ b/src/mesa/state_tracker/st_cb_program.c
@@ -62,12 +62,15 @@ static void st_bind_program( GLcontext *ctx,
    struct st_context *st = st_context(ctx);
 
    switch (target) {
-   case GL_VERTEX_PROGRAM_ARB: 
+   case GL_VERTEX_PROGRAM_ARB:
       st->dirty.st |= ST_NEW_VERTEX_PROGRAM;
       break;
    case GL_FRAGMENT_PROGRAM_ARB:
       st->dirty.st |= ST_NEW_FRAGMENT_PROGRAM;
       break;
+   case GL_GEOMETRY_SHADER_ARB:
+      st->dirty.st |= ST_NEW_GEOMETRY_PROGRAM;
+      break;
    }
 }
 
@@ -83,6 +86,7 @@ static void st_use_program( GLcontext *ctx,
 
    st->dirty.st |= ST_NEW_FRAGMENT_PROGRAM;
    st->dirty.st |= ST_NEW_VERTEX_PROGRAM;
+   st->dirty.st |= ST_NEW_GEOMETRY_PROGRAM;
 
    _mesa_use_program(ctx, program);
 }
@@ -120,6 +124,14 @@ static struct gl_program *st_new_program( GLcontext *ctx,
 					  target, 
 					  id );
    }
+   case GL_GEOMETRY_SHADER_ARB: {
+      struct st_geometry_program *prog = CALLOC_STRUCT(st_geometry_program);
+
+      prog->serialNo = SerialNo++;
+
+      return _mesa_init_fragment_program(ctx, &prog->Base,
+                                         target, id);
+   }
 
    default:
       assert(0);
@@ -180,6 +192,21 @@ st_delete_program(GLcontext *ctx, struct gl_program *prog)
          st_free_translated_vertex_programs(st, stfp->vertex_programs);
       }
       break;
+   case GL_GEOMETRY_SHADER_ARB:
+      {
+         struct st_geometry_program *stgp = (struct st_geometry_program *) prog;
+
+         if (stgp->driver_shader) {
+            cso_delete_geometry_shader(st->cso_context, stgp->driver_shader);
+            stgp->driver_shader = NULL;
+         }
+
+         if (stgp->state.tokens) {
+            FREE((void *)stgp->state.tokens);
+            stgp->state.tokens = NULL;
+         }
+      }
+      break;
    default:
       assert(0); /* problem */
    }
diff --git a/src/mesa/state_tracker/st_context.h b/src/mesa/state_tracker/st_context.h
index 3547925..f184736 100644
--- a/src/mesa/state_tracker/st_context.h
+++ b/src/mesa/state_tracker/st_context.h
@@ -50,10 +50,11 @@ struct bitmap_cache;
 #define FRONT_STATUS_COPY_OF_BACK 2
 
 
-#define ST_NEW_MESA                    0x1 /* Mesa state has changed */
-#define ST_NEW_FRAGMENT_PROGRAM        0x2
-#define ST_NEW_VERTEX_PROGRAM          0x4
-#define ST_NEW_FRAMEBUFFER             0x8
+#define ST_NEW_MESA                    0x01 /* Mesa state has changed */
+#define ST_NEW_FRAGMENT_PROGRAM        0x02
+#define ST_NEW_VERTEX_PROGRAM          0x04
+#define ST_NEW_FRAMEBUFFER             0x08
+#define ST_NEW_GEOMETRY_PROGRAM        0x10
 
 
 struct st_state_flags {
diff --git a/src/mesa/state_tracker/st_program.h b/src/mesa/state_tracker/st_program.h
index e2e5edd..531c06d 100644
--- a/src/mesa/state_tracker/st_program.h
+++ b/src/mesa/state_tracker/st_program.h
@@ -102,6 +102,30 @@ struct st_vertex_program
 };
 
 
+/**
+ * Derived from Mesa gl_geometry_program:
+ */
+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 */
+   GLuint input_to_index[VERT_ATTRIB_MAX];
+   /** maps a TGSI input index back to a Mesa VERT_ATTRIB_x */
+   GLuint index_to_input[PIPE_MAX_SHADER_INPUTS];
+
+   GLuint num_inputs;
+
+   struct pipe_shader_state state;
+   void *driver_shader;
+
+   /*struct draw_geometry_shader *draw_shader;*/
+
+   GLuint param_state;
+};
+
+
 static INLINE struct st_fragment_program *
 st_fragment_program( struct gl_fragment_program *fp )
 {




More information about the mesa-commit mailing list