summaryrefslogtreecommitdiff
path: root/src/mesa/program
diff options
context:
space:
mode:
authorZack Rusin <zackr@vmware.com>2010-06-28 17:31:21 -0400
committerZack Rusin <zackr@vmware.com>2010-06-28 22:53:21 -0400
commitda7bd6a90e1fee5c16327338fd251c0f6be34e36 (patch)
tree5f7e3d8f6d30799033afd78beec3e643ef4c7d6c /src/mesa/program
parent0b50fcbd556ead8d35c2b543f13de433996a5822 (diff)
mesa: initial support for ARB_geometry_shader4
laying down the foundation for everything and implementing most of the stuff. linking, gl_VerticesIn and multidimensional inputs are left.
Diffstat (limited to 'src/mesa/program')
-rw-r--r--src/mesa/program/prog_instruction.c2
-rw-r--r--src/mesa/program/prog_instruction.h2
-rw-r--r--src/mesa/program/prog_print.c12
-rw-r--r--src/mesa/program/prog_uniform.h1
-rw-r--r--src/mesa/program/program.c54
-rw-r--r--src/mesa/program/program.h20
6 files changed, 88 insertions, 3 deletions
diff --git a/src/mesa/program/prog_instruction.c b/src/mesa/program/prog_instruction.c
index 81099cb99c..5d6cb476c1 100644
--- a/src/mesa/program/prog_instruction.c
+++ b/src/mesa/program/prog_instruction.c
@@ -177,7 +177,9 @@ static const struct instruction_info InstInfo[MAX_OPCODE] = {
{ OPCODE_DPH, "DPH", 2, 1 },
{ OPCODE_DST, "DST", 2, 1 },
{ OPCODE_ELSE, "ELSE", 0, 0 },
+ { OPCODE_EMIT_VERTEX, "EMIT_VERTEX", 0, 0 },
{ OPCODE_END, "END", 0, 0 },
+ { OPCODE_END_PRIMITIVE, "END_PRIMITIVE", 0, 0 },
{ OPCODE_ENDIF, "ENDIF", 0, 0 },
{ OPCODE_ENDLOOP,"ENDLOOP", 0, 0 },
{ OPCODE_ENDSUB, "ENDSUB", 0, 0 },
diff --git a/src/mesa/program/prog_instruction.h b/src/mesa/program/prog_instruction.h
index 28c797a4ba..5cdc321a31 100644
--- a/src/mesa/program/prog_instruction.h
+++ b/src/mesa/program/prog_instruction.h
@@ -170,7 +170,9 @@ typedef enum prog_opcode {
OPCODE_DPH, /* X X 1.1 */
OPCODE_DST, /* X X X X */
OPCODE_ELSE, /* X */
+ OPCODE_EMIT_VERTEX, /* X */
OPCODE_END, /* X X X X opt */
+ OPCODE_END_PRIMITIVE,/* X */
OPCODE_ENDIF, /* opt */
OPCODE_ENDLOOP, /* opt */
OPCODE_ENDSUB, /* opt */
diff --git a/src/mesa/program/prog_print.c b/src/mesa/program/prog_print.c
index 05aae83f0c..00810bd10b 100644
--- a/src/mesa/program/prog_print.c
+++ b/src/mesa/program/prog_print.c
@@ -773,6 +773,12 @@ _mesa_fprint_instruction_opt(FILE *f,
fprintf(f, "# %s\n", inst->Comment);
}
break;
+ case OPCODE_EMIT_VERTEX:
+ fprintf(f, "EMIT_VERTEX\n");
+ break;
+ case OPCODE_END_PRIMITIVE:
+ fprintf(f, "END_PRIMITIVE\n");
+ break;
/* XXX may need other special-case instructions */
default:
if (inst->Opcode < MAX_OPCODE) {
@@ -842,6 +848,8 @@ _mesa_fprint_program_opt(FILE *f,
else
fprintf(f, "# Fragment Program/Shader %u\n", prog->Id);
break;
+ case MESA_GEOMETRY_PROGRAM:
+ fprintf(f, "# Geometry Shader\n");
}
for (i = 0; i < prog->NumInstructions; i++) {
@@ -996,8 +1004,10 @@ _mesa_write_shader_to_file(const struct gl_shader *shader)
if (shader->Type == GL_FRAGMENT_SHADER)
type = "frag";
- else
+ else if (shader->Type == GL_VERTEX_SHADER)
type = "vert";
+ else
+ type = "geom";
_mesa_snprintf(filename, sizeof(filename), "shader_%u.%s", shader->Name, type);
f = fopen(filename, "w");
diff --git a/src/mesa/program/prog_uniform.h b/src/mesa/program/prog_uniform.h
index 22a2bfd970..a671d30bfe 100644
--- a/src/mesa/program/prog_uniform.h
+++ b/src/mesa/program/prog_uniform.h
@@ -50,6 +50,7 @@ struct gl_uniform
const char *Name; /**< Null-terminated string */
GLint VertPos;
GLint FragPos;
+ GLint GeomPos;
GLboolean Initialized; /**< For debug. Has this uniform been set? */
#if 0
GLenum DataType; /**< GL_FLOAT, GL_FLOAT_VEC2, etc */
diff --git a/src/mesa/program/program.c b/src/mesa/program/program.c
index a6ada8a048..cf46095ce8 100644
--- a/src/mesa/program/program.c
+++ b/src/mesa/program/program.c
@@ -98,6 +98,13 @@ _mesa_init_program(GLcontext *ctx)
ctx->FragmentProgram.Cache = _mesa_new_program_cache();
#endif
+#if FEATURE_ARB_geometry_shader4
+ ctx->GeometryProgram.Enabled = GL_FALSE;
+ /* right now by default we don't have a geometry program */
+ _mesa_reference_geomprog(ctx, &ctx->GeometryProgram.Current,
+ NULL);
+ ctx->GeometryProgram.Cache = _mesa_new_program_cache();
+#endif
/* XXX probably move this stuff */
#if FEATURE_ATI_fragment_shader
@@ -123,6 +130,10 @@ _mesa_free_program_data(GLcontext *ctx)
_mesa_reference_fragprog(ctx, &ctx->FragmentProgram.Current, NULL);
_mesa_delete_program_cache(ctx, ctx->FragmentProgram.Cache);
#endif
+#if FEATURE_ARB_geometry_shader4
+ _mesa_reference_geomprog(ctx, &ctx->GeometryProgram.Current, NULL);
+ _mesa_delete_program_cache(ctx, ctx->GeometryProgram.Cache);
+#endif
/* XXX probably move this stuff */
#if FEATURE_ATI_fragment_shader
if (ctx->ATIFragmentShader.Current) {
@@ -158,6 +169,12 @@ _mesa_update_default_objects_program(GLcontext *ctx)
assert(ctx->FragmentProgram.Current);
#endif
+#if FEATURE_ARB_geometry_shader4
+ _mesa_reference_geomprog(ctx, &ctx->GeometryProgram.Current,
+ (struct gl_geometry_program *)
+ ctx->Shared->DefaultGeometryProgram);
+#endif
+
/* XXX probably move this stuff */
#if FEATURE_ATI_fragment_shader
if (ctx->ATIFragmentShader.Current) {
@@ -286,6 +303,20 @@ _mesa_init_vertex_program( GLcontext *ctx, struct gl_vertex_program *prog,
/**
+ * Initialize a new geometry program object.
+ */
+struct gl_program *
+_mesa_init_geometry_program( GLcontext *ctx, struct gl_geometry_program *prog,
+ GLenum target, GLuint id)
+{
+ if (prog)
+ return _mesa_init_program_struct( ctx, &prog->Base, target, id );
+ else
+ return NULL;
+}
+
+
+/**
* Allocate and initialize a new fragment/vertex program object but
* don't put it into the program hash table. Called via
* ctx->Driver.NewProgram. May be overridden (ie. replaced) by a
@@ -313,6 +344,11 @@ _mesa_new_program(GLcontext *ctx, GLenum target, GLuint id)
CALLOC_STRUCT(gl_fragment_program),
target, id );
break;
+ case MESA_GEOMETRY_PROGRAM:
+ prog = _mesa_init_geometry_program(ctx,
+ CALLOC_STRUCT(gl_geometry_program),
+ target, id);
+ break;
default:
_mesa_problem(ctx, "bad target in _mesa_new_program");
prog = NULL;
@@ -387,6 +423,8 @@ _mesa_reference_program(GLcontext *ctx,
else if ((*ptr)->Target == GL_FRAGMENT_PROGRAM_ARB)
ASSERT(prog->Target == GL_FRAGMENT_PROGRAM_ARB ||
prog->Target == GL_FRAGMENT_PROGRAM_NV);
+ else if ((*ptr)->Target == MESA_GEOMETRY_PROGRAM)
+ ASSERT(prog->Target == MESA_GEOMETRY_PROGRAM);
}
if (*ptr == prog) {
return; /* no change */
@@ -398,7 +436,8 @@ _mesa_reference_program(GLcontext *ctx,
#if 0
printf("Program %p ID=%u Target=%s Refcount-- to %d\n",
*ptr, (*ptr)->Id,
- ((*ptr)->Target == GL_VERTEX_PROGRAM_ARB ? "VP" : "FP"),
+ ((*ptr)->Target == GL_VERTEX_PROGRAM_ARB ? "VP" :
+ ((*ptr)->Target == MESA_GEOMETRY_PROGRAM ? "GP" : "FP")),
(*ptr)->RefCount - 1);
#endif
ASSERT((*ptr)->RefCount > 0);
@@ -422,7 +461,8 @@ _mesa_reference_program(GLcontext *ctx,
#if 0
printf("Program %p ID=%u Target=%s Refcount++ to %d\n",
prog, prog->Id,
- (prog->Target == GL_VERTEX_PROGRAM_ARB ? "VP" : "FP"),
+ (prog->Target == GL_VERTEX_PROGRAM_ARB ? "VP" :
+ (prog->Target == MESA_GEOMETRY_PROGRAM ? "GP" : "FP")),
prog->RefCount);
#endif
/*_glthread_UNLOCK_MUTEX(prog->Mutex);*/
@@ -510,6 +550,16 @@ _mesa_clone_program(GLcontext *ctx, const struct gl_program *prog)
fpc->PixelCenterInteger = fp->PixelCenterInteger;
}
break;
+ case MESA_GEOMETRY_PROGRAM:
+ {
+ const struct gl_geometry_program *gp
+ = (const struct gl_geometry_program *) prog;
+ struct gl_geometry_program *gpc = (struct gl_geometry_program *) clone;
+ gpc->VerticesOut = gp->VerticesOut;
+ gpc->InputType = gp->InputType;
+ gpc->OutputType = gp->OutputType;
+ }
+ break;
default:
_mesa_problem(NULL, "Unexpected target in _mesa_clone_program");
}
diff --git a/src/mesa/program/program.h b/src/mesa/program/program.h
index af9f4170d1..286573de1f 100644
--- a/src/mesa/program/program.h
+++ b/src/mesa/program/program.h
@@ -74,6 +74,11 @@ _mesa_init_fragment_program(GLcontext *ctx,
GLenum target, GLuint id);
extern struct gl_program *
+_mesa_init_geometry_program(GLcontext *ctx,
+ struct gl_geometry_program *prog,
+ GLenum target, GLuint id);
+
+extern struct gl_program *
_mesa_new_program(GLcontext *ctx, GLenum target, GLuint id);
extern void
@@ -105,6 +110,15 @@ _mesa_reference_fragprog(GLcontext *ctx,
(struct gl_program *) prog);
}
+static INLINE void
+_mesa_reference_geomprog(GLcontext *ctx,
+ struct gl_geometry_program **ptr,
+ struct gl_geometry_program *prog)
+{
+ _mesa_reference_program(ctx, (struct gl_program **) ptr,
+ (struct gl_program *) prog);
+}
+
extern struct gl_program *
_mesa_clone_program(GLcontext *ctx, const struct gl_program *prog);
@@ -115,6 +129,12 @@ _mesa_clone_vertex_program(GLcontext *ctx,
return (struct gl_vertex_program *) _mesa_clone_program(ctx, &prog->Base);
}
+static INLINE struct gl_geometry_program *
+_mesa_clone_geometry_program(GLcontext *ctx,
+ const struct gl_geometry_program *prog)
+{
+ return (struct gl_geometry_program *) _mesa_clone_program(ctx, &prog->Base);
+}
static INLINE struct gl_fragment_program *
_mesa_clone_fragment_program(GLcontext *ctx,