summaryrefslogtreecommitdiff
path: root/src/mesa/main/nvprogram.c
diff options
context:
space:
mode:
authorBrian Paul <brian.paul@tungstengraphics.com>2003-04-17 01:48:19 +0000
committerBrian Paul <brian.paul@tungstengraphics.com>2003-04-17 01:48:19 +0000
commit451f31093e950e2c76e8d7dee3cb097049a906b5 (patch)
tree84e85ea7c447acce7e3516c9d4d4dc9fadc8392d /src/mesa/main/nvprogram.c
parent2db8041ffed9db2e68c55f18eedeaa95c23ac761 (diff)
checkpoint: more infrastructure for GL_ARB_vertex/fragment_program.
Diffstat (limited to 'src/mesa/main/nvprogram.c')
-rw-r--r--src/mesa/main/nvprogram.c160
1 files changed, 93 insertions, 67 deletions
diff --git a/src/mesa/main/nvprogram.c b/src/mesa/main/nvprogram.c
index 9e1b2ed828..b91bf21e58 100644
--- a/src/mesa/main/nvprogram.c
+++ b/src/mesa/main/nvprogram.c
@@ -102,6 +102,45 @@ _mesa_find_line_column(const GLubyte *string, const GLubyte *pos,
+/**
+ * Allocate and initialize a new fragment/vertex program object
+ * \param ctx context
+ * \param id program id/number
+ * \param target program target/type
+ * \return pointer to new program object
+ */
+struct program *
+_mesa_alloc_program(GLcontext *ctx, GLenum target, GLuint id)
+{
+ struct program *prog;
+
+ if (target == GL_VERTEX_PROGRAM_NV
+ || target == GL_VERTEX_PROGRAM_ARB) {
+ struct vertex_program *vprog = CALLOC_STRUCT(vertex_program);
+ if (!vprog) {
+ return NULL;
+ }
+ prog = &(vprog->Base);
+ }
+ else if (target == GL_FRAGMENT_PROGRAM_NV
+ || target == GL_FRAGMENT_PROGRAM_ARB) {
+ struct fragment_program *fprog = CALLOC_STRUCT(fragment_program);
+ if (!fprog) {
+ return NULL;
+ }
+ prog = &(fprog->Base);
+ }
+ else {
+ _mesa_problem(ctx, "bad target in _mesa_alloc_program");
+ return NULL;
+ }
+ prog->Id = id;
+ prog->Target = target;
+ prog->Resident = GL_TRUE;
+ prog->RefCount = 1;
+ return prog;
+}
+
/**
* Delete a program and remove it from the hash table, ignoring the
@@ -109,35 +148,31 @@ _mesa_find_line_column(const GLubyte *string, const GLubyte *pos,
* \note Called from the GL API dispatcher.
*/
void
-_mesa_delete_program(GLcontext *ctx, GLuint id)
+_mesa_delete_program(GLcontext *ctx, struct program *prog)
{
- struct program *prog = (struct program *)
- _mesa_HashLookup(ctx->Shared->Programs, id);
+ ASSERT(prog);
- if (prog) {
- if (prog->String)
- _mesa_free(prog->String);
- if (prog->Target == GL_VERTEX_PROGRAM_NV ||
- prog->Target == GL_VERTEX_STATE_PROGRAM_NV) {
- struct vertex_program *vprog = (struct vertex_program *) prog;
- if (vprog->Instructions)
- _mesa_free(vprog->Instructions);
- }
- else if (prog->Target == GL_FRAGMENT_PROGRAM_NV) {
- struct fragment_program *fprog = (struct fragment_program *) prog;
- if (fprog->Instructions)
- _mesa_free(fprog->Instructions);
- if (fprog->Parameters) {
- GLuint i;
- for (i = 0; i < fprog->NumParameters; i++) {
- _mesa_free((void *) fprog->Parameters[i].Name);
- }
- _mesa_free(fprog->Parameters);
+ if (prog->String)
+ _mesa_free(prog->String);
+ if (prog->Target == GL_VERTEX_PROGRAM_NV ||
+ prog->Target == GL_VERTEX_STATE_PROGRAM_NV) {
+ struct vertex_program *vprog = (struct vertex_program *) prog;
+ if (vprog->Instructions)
+ _mesa_free(vprog->Instructions);
+ }
+ else if (prog->Target == GL_FRAGMENT_PROGRAM_NV) {
+ struct fragment_program *fprog = (struct fragment_program *) prog;
+ if (fprog->Instructions)
+ _mesa_free(fprog->Instructions);
+ if (fprog->Parameters) {
+ GLuint i;
+ for (i = 0; i < fprog->NumParameters; i++) {
+ _mesa_free((void *) fprog->Parameters[i].Name);
}
+ _mesa_free(fprog->Parameters);
}
- _mesa_HashRemove(ctx->Shared->Programs, id);
- _mesa_free(prog);
}
+ _mesa_free(prog);
}
@@ -152,7 +187,8 @@ _mesa_BindProgramNV(GLenum target, GLuint id)
GET_CURRENT_CONTEXT(ctx);
ASSERT_OUTSIDE_BEGIN_END(ctx);
- if (target == GL_VERTEX_PROGRAM_NV) {
+ if (target == GL_VERTEX_PROGRAM_NV
+ && ctx->Extensions.NV_vertex_program) {
if (ctx->VertexProgram.Current &&
ctx->VertexProgram.Current->Base.Id == id)
return;
@@ -160,11 +196,14 @@ _mesa_BindProgramNV(GLenum target, GLuint id)
if (ctx->VertexProgram.Current) {
ctx->VertexProgram.Current->Base.RefCount--;
/* and delete if refcount goes below one */
- if (ctx->VertexProgram.Current->Base.RefCount <= 0)
- _mesa_delete_program(ctx, ctx->VertexProgram.Current->Base.Id);
+ if (ctx->VertexProgram.Current->Base.RefCount <= 0) {
+ _mesa_delete_program(ctx, &(ctx->VertexProgram.Current->Base));
+ _mesa_HashRemove(ctx->Shared->Programs, id);
+ }
}
}
- else if (target == GL_FRAGMENT_PROGRAM_NV) {
+ else if (target == GL_FRAGMENT_PROGRAM_NV
+ && ctx->Extensions.NV_fragment_program) {
if (ctx->FragmentProgram.Current &&
ctx->FragmentProgram.Current->Base.Id == id)
return;
@@ -172,12 +211,14 @@ _mesa_BindProgramNV(GLenum target, GLuint id)
if (ctx->FragmentProgram.Current) {
ctx->FragmentProgram.Current->Base.RefCount--;
/* and delete if refcount goes below one */
- if (ctx->FragmentProgram.Current->Base.RefCount <= 0)
- _mesa_delete_program(ctx, ctx->FragmentProgram.Current->Base.Id);
+ if (ctx->FragmentProgram.Current->Base.RefCount <= 0) {
+ _mesa_delete_program(ctx, &(ctx->FragmentProgram.Current->Base));
+ _mesa_HashRemove(ctx->Shared->Programs, id);
+ }
}
}
else {
- _mesa_error(ctx, GL_INVALID_ENUM, "glBindProgramNV");
+ _mesa_error(ctx, GL_INVALID_ENUM, "glBindProgramNV(target)");
return;
}
@@ -190,27 +231,11 @@ _mesa_BindProgramNV(GLenum target, GLuint id)
}
else {
prog = (struct program *) _mesa_HashLookup(ctx->Shared->Programs, id);
-
if (!prog && id > 0){
/* allocate new program */
- if (target == GL_VERTEX_PROGRAM_NV) {
- struct vertex_program *vprog = CALLOC_STRUCT(vertex_program);
- if (!vprog) {
- _mesa_error(ctx, GL_OUT_OF_MEMORY, "glBindProgramNV");
- return;
- }
- prog = &(vprog->Base);
- }
- else if (target == GL_FRAGMENT_PROGRAM_NV) {
- struct fragment_program *fprog = CALLOC_STRUCT(fragment_program);
- if (!fprog) {
- _mesa_error(ctx, GL_OUT_OF_MEMORY, "glBindProgramNV");
- return;
- }
- prog = &(fprog->Base);
- }
- else {
- _mesa_error(ctx, GL_INVALID_ENUM, "glBindProgramNV(target)");
+ prog = _mesa_alloc_program(ctx, target, id);
+ if (!prog) {
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "glBindProgramNV");
return;
}
prog->Id = id;
@@ -277,7 +302,7 @@ _mesa_DeleteProgramsNV(GLsizei n, const GLuint *ids)
}
prog->RefCount--;
if (prog->RefCount <= 0) {
- _mesa_delete_program(ctx, ids[i]);
+ _mesa_delete_program(ctx, prog);
}
}
}
@@ -330,7 +355,7 @@ _mesa_GenProgramsNV(GLsizei n, GLuint *ids)
ASSERT_OUTSIDE_BEGIN_END(ctx);
if (n < 0) {
- _mesa_error(ctx, GL_INVALID_VALUE, "glGenProgramsNV");
+ _mesa_error(ctx, GL_INVALID_VALUE, "glGenPrograms");
return;
}
@@ -344,7 +369,7 @@ _mesa_GenProgramsNV(GLsizei n, GLuint *ids)
sizeof(struct fragment_program));
struct program *prog = (struct program *) _mesa_calloc(bytes);
if (!prog) {
- _mesa_error(ctx, GL_OUT_OF_MEMORY, "glGenProgramsNV");
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "glGenPrograms");
return;
}
prog->RefCount = 1;
@@ -595,7 +620,8 @@ _mesa_GetTrackMatrixivNV(GLenum target, GLuint address,
GET_CURRENT_CONTEXT(ctx);
ASSERT_OUTSIDE_BEGIN_END(ctx);
- if (target == GL_VERTEX_PROGRAM_NV) {
+ if (target == GL_VERTEX_PROGRAM_NV
+ && ctx->Extensions.NV_vertex_program) {
GLuint i;
if ((address & 0x3) || address >= MAX_NV_VERTEX_PROGRAM_PARAMS) {
@@ -769,7 +795,8 @@ _mesa_GetVertexAttribPointervNV(GLuint index, GLenum pname, GLvoid **pointer)
* \param id is the program identifier
* \return GL_TRUE if id is a program, else GL_FALSE.
*/
-GLboolean _mesa_IsProgramNV(GLuint id)
+GLboolean
+_mesa_IsProgramNV(GLuint id)
{
struct program *prog;
GET_CURRENT_CONTEXT(ctx);
@@ -787,7 +814,7 @@ GLboolean _mesa_IsProgramNV(GLuint id)
/**
- * Load a program.
+ * Load/parse/compile a program.
* \note Called from the GL API dispatcher.
*/
void
@@ -810,11 +837,9 @@ _mesa_LoadProgramNV(GLenum target, GLuint id, GLsizei len,
return;
}
- /* Reset error pos and string */
- _mesa_set_program_error(ctx, -1, NULL);
-
- if (target == GL_VERTEX_PROGRAM_NV ||
- target == GL_VERTEX_STATE_PROGRAM_NV) {
+ if ((target == GL_VERTEX_PROGRAM_NV ||
+ target == GL_VERTEX_STATE_PROGRAM_NV)
+ && ctx->Extensions.NV_vertex_program) {
struct vertex_program *vprog = (struct vertex_program *) prog;
if (!vprog) {
vprog = CALLOC_STRUCT(vertex_program);
@@ -828,7 +853,8 @@ _mesa_LoadProgramNV(GLenum target, GLuint id, GLsizei len,
}
_mesa_parse_nv_vertex_program(ctx, target, program, len, vprog);
}
- else if (target == GL_FRAGMENT_PROGRAM_NV) {
+ else if (target == GL_FRAGMENT_PROGRAM_NV
+ && ctx->Extensions.NV_fragment_program) {
struct fragment_program *fprog = (struct fragment_program *) prog;
if (!fprog) {
fprog = CALLOC_STRUCT(fragment_program);
@@ -843,7 +869,7 @@ _mesa_LoadProgramNV(GLenum target, GLuint id, GLsizei len,
_mesa_parse_nv_fragment_program(ctx, target, program, len, fprog);
}
else {
- _mesa_error(ctx, GL_INVALID_ENUM, "LoadProgramNV(target)");
+ _mesa_error(ctx, GL_INVALID_ENUM, "glLoadProgramNV(target)");
}
}
@@ -887,7 +913,7 @@ _mesa_ProgramParameter4fNV(GLenum target, GLuint index,
GET_CURRENT_CONTEXT(ctx);
ASSERT_OUTSIDE_BEGIN_END(ctx);
- if (target == GL_VERTEX_PROGRAM_NV) {
+ if (target == GL_VERTEX_PROGRAM_NV && ctx->Extensions.NV_vertex_program) {
if (index < MAX_NV_VERTEX_PROGRAM_PARAMS) {
index += VP_PROG_REG_START;
ASSIGN_4V(ctx->VertexProgram.Machine.Registers[index], x, y, z, w);
@@ -929,7 +955,7 @@ _mesa_ProgramParameters4dvNV(GLenum target, GLuint index,
GET_CURRENT_CONTEXT(ctx);
ASSERT_OUTSIDE_BEGIN_END(ctx);
- if (target == GL_VERTEX_PROGRAM_NV) {
+ if (target == GL_VERTEX_PROGRAM_NV && ctx->Extensions.NV_vertex_program) {
GLuint i;
if (index + num > MAX_NV_VERTEX_PROGRAM_PARAMS) {
_mesa_error(ctx, GL_INVALID_VALUE, "glProgramParameters4dvNV");
@@ -960,7 +986,7 @@ _mesa_ProgramParameters4fvNV(GLenum target, GLuint index,
GET_CURRENT_CONTEXT(ctx);
ASSERT_OUTSIDE_BEGIN_END(ctx);
- if (target == GL_VERTEX_PROGRAM_NV) {
+ if (target == GL_VERTEX_PROGRAM_NV && ctx->Extensions.NV_vertex_program) {
GLuint i;
if (index + num > MAX_NV_VERTEX_PROGRAM_PARAMS) {
_mesa_error(ctx, GL_INVALID_VALUE, "glProgramParameters4fvNV");
@@ -991,7 +1017,7 @@ _mesa_TrackMatrixNV(GLenum target, GLuint address,
GET_CURRENT_CONTEXT(ctx);
ASSERT_OUTSIDE_BEGIN_END(ctx);
- if (target == GL_VERTEX_PROGRAM_NV) {
+ if (target == GL_VERTEX_PROGRAM_NV && ctx->Extensions.NV_vertex_program) {
if (address & 0x3) {
/* addr must be multiple of four */
_mesa_error(ctx, GL_INVALID_VALUE, "glTrackMatrixNV(address)");