-
-/**
- * Delete a program and remove it from the hash table, ignoring the
- * reference count.
- * \note Called from the GL API dispatcher.
- */
-void
-_mesa_delete_program(GLcontext *ctx, GLuint id)
-{
- struct program *prog = (struct program *)
- _mesa_HashLookup(ctx->Shared->Programs, id);
-
- 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);
- }
- }
- _mesa_HashRemove(ctx->Shared->Programs, id);
- _mesa_free(prog);
- }
-}
-
-
-/**
- * Bind a program (make it current)
- * \note Called from the GL API dispatcher.
- */
-void
-_mesa_BindProgramNV(GLenum target, GLuint id)
-{
- struct program *prog;
- GET_CURRENT_CONTEXT(ctx);
- ASSERT_OUTSIDE_BEGIN_END(ctx);
-
- if (target == GL_VERTEX_PROGRAM_NV) {
- if (ctx->VertexProgram.Current &&
- ctx->VertexProgram.Current->Base.Id == id)
- return;
- /* decrement refcount on previously bound vertex program */
- 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);
- }
- }
- else if (target == GL_FRAGMENT_PROGRAM_NV) {
- if (ctx->FragmentProgram.Current &&
- ctx->FragmentProgram.Current->Base.Id == id)
- return;
- /* decrement refcount on previously bound fragment program */
- 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);
- }
- }
- else {
- _mesa_error(ctx, GL_INVALID_ENUM, "glBindProgramNV");
- return;
- }
-
- /* NOTE: binding to a non-existant program is not an error.
- * That's supposed to be caught in glBegin.
- */
- if (id == 0) {
- /* OK, the null program object */
- prog = NULL;
- }
- 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)");
- return;
- }
- prog->Id = id;
- prog->Target = target;
- prog->Resident = GL_TRUE;
- prog->RefCount = 1;
- _mesa_HashInsert(ctx->Shared->Programs, id, prog);
- }
- }
-
- /* bind now */
- if (target == GL_VERTEX_PROGRAM_NV) {
- ctx->VertexProgram.Current = (struct vertex_program *) prog;
- }
- else if (target == GL_FRAGMENT_PROGRAM_NV) {
- ctx->FragmentProgram.Current = (struct fragment_program *) prog;
- }
-
- if (prog)
- prog->RefCount++;
-}
-
-
-/**
- * Delete a list of programs.
- * \note Not compiled into display lists.
- * \note Called from the GL API dispatcher.
- */
-void
-_mesa_DeleteProgramsNV(GLsizei n, const GLuint *ids)
-{
- GLint i;
- GET_CURRENT_CONTEXT(ctx);
- ASSERT_OUTSIDE_BEGIN_END(ctx);
-
- if (n < 0) {
- _mesa_error( ctx, GL_INVALID_VALUE, "glDeleteProgramsNV" );
- return;
- }
-
- for (i = 0; i < n; i++) {
- if (ids[i] != 0) {
- struct program *prog = (struct program *)
- _mesa_HashLookup(ctx->Shared->Programs, ids[i]);
- if (prog) {
- if (prog->Target == GL_VERTEX_PROGRAM_NV ||
- prog->Target == GL_VERTEX_STATE_PROGRAM_NV) {
- if (ctx->VertexProgram.Current &&
- ctx->VertexProgram.Current->Base.Id == ids[i]) {
- /* unbind this currently bound program */
- _mesa_BindProgramNV(prog->Target, 0);
- }
- }
- else if (prog->Target == GL_FRAGMENT_PROGRAM_NV) {
- if (ctx->FragmentProgram.Current &&
- ctx->FragmentProgram.Current->Base.Id == ids[i]) {
- /* unbind this currently bound program */
- _mesa_BindProgramNV(prog->Target, 0);
- }
- }
- else {
- _mesa_problem(ctx, "bad target in glDeleteProgramsNV");
- return;
- }
- prog->RefCount--;
- if (prog->RefCount <= 0) {
- _mesa_delete_program(ctx, ids[i]);
- }
- }
- }
- }
-}
-
-