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