Пример #1
0
/**
 * Binds the given program string to GL_FRAGMENT_PROGRAM_ARB, caching the
 * program object.
 */
void
meta_set_fragment_program(struct dri_metaops *meta,
			  struct gl_fragment_program **prog,
			  const char *prog_string)
{
   GLcontext *ctx = meta->ctx;
   assert(meta->saved_fp == NULL);

   _mesa_reference_fragprog(ctx, &meta->saved_fp,
			    ctx->FragmentProgram.Current);
   if (*prog == NULL) {
      GLuint prog_name;
      _mesa_GenPrograms(1, &prog_name);
      _mesa_BindProgram(GL_FRAGMENT_PROGRAM_ARB, prog_name);
      _mesa_ProgramStringARB(GL_FRAGMENT_PROGRAM_ARB,
			     GL_PROGRAM_FORMAT_ASCII_ARB,
			     strlen(prog_string), (const GLubyte *)prog_string);
      _mesa_reference_fragprog(ctx, prog, ctx->FragmentProgram.Current);
      /* Note that DeletePrograms unbinds the program on us */
      _mesa_DeletePrograms(1, &prog_name);
   }

   FLUSH_VERTICES(ctx, _NEW_PROGRAM);
   _mesa_reference_fragprog(ctx, &ctx->FragmentProgram.Current, *prog);
   ctx->Driver.BindProgram(ctx, GL_FRAGMENT_PROGRAM_ARB, &((*prog)->Base));

   meta->saved_fp_enable = ctx->FragmentProgram.Enabled;
   _mesa_Enable(GL_FRAGMENT_PROGRAM_ARB);
}
Пример #2
0
/**
 * Delete a list of programs.
 * \note Not compiled into display lists.
 * \note Called by both glDeleteProgramsNV and glDeleteProgramsARB.
 */
void GLAPIENTRY 
_mesa_DeletePrograms(GLsizei n, const GLuint *ids)
{
   GLint i;
   GET_CURRENT_CONTEXT(ctx);
   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(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_BindProgram(prog->Target, 0);
               }
            }
            else if (prog->Target == GL_FRAGMENT_PROGRAM_NV ||
                     prog->Target == GL_FRAGMENT_PROGRAM_ARB) {
               if (ctx->FragmentProgram.Current &&
                   ctx->FragmentProgram.Current->Base.Id == ids[i]) {
                  /* unbind this currently bound program */
                  _mesa_BindProgram(prog->Target, 0);
               }
            }
            else {
               _mesa_problem(ctx, "bad target in glDeleteProgramsNV");
               return;
            }
            prog->RefCount--;
            if (prog->RefCount <= 0) {
               _mesa_delete_program(ctx, prog);
            }
            /* always remove from hash table */
            _mesa_HashRemove(ctx->Shared->Programs, ids[i]);
         }
      }
   }
}
Пример #3
0
/**
 * Delete a list of programs.
 * \note Not compiled into display lists.
 * \note Called by both glDeleteProgramsNV and glDeleteProgramsARB.
 */
void GLAPIENTRY 
_mesa_DeletePrograms(GLsizei n, const GLuint *ids)
{
   GLint i;
   GET_CURRENT_CONTEXT(ctx);
   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);

   if (n < 0) {
      _mesa_error( ctx, GL_INVALID_VALUE, "glDeleteProgramsNV" );
      return;
   }

   for (i = 0; i < n; i++) {
      if (ids[i] != 0) {
         struct gl_program *prog = _mesa_lookup_program(ctx, ids[i]);
         if (prog == &_mesa_DummyProgram) {
            _mesa_HashRemove(ctx->Shared->Programs, ids[i]);
         }
         else if (prog) {
            /* Unbind program if necessary */
            if (prog->Target == GL_VERTEX_PROGRAM_ARB || /* == 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_BindProgram(prog->Target, 0);
               }
            }
            else if (prog->Target == GL_FRAGMENT_PROGRAM_NV ||
                     prog->Target == GL_FRAGMENT_PROGRAM_ARB) {
               if (ctx->FragmentProgram.Current &&
                   ctx->FragmentProgram.Current->Base.Id == ids[i]) {
                  /* unbind this currently bound program */
                  _mesa_BindProgram(prog->Target, 0);
               }
            }
            else {
               _mesa_problem(ctx, "bad target in glDeleteProgramsNV");
               return;
            }
            /* The ID is immediately available for re-use now */
            _mesa_HashRemove(ctx->Shared->Programs, ids[i]);
            _mesa_reference_program(ctx, &prog, NULL);
         }
      }
   }
}
Пример #4
0
/**
 * Set up a vertex program to pass through the position and first texcoord
 * for pixel path.
 */
void
meta_set_passthrough_vertex_program(struct dri_metaops *meta)
{
   GLcontext *ctx = meta->ctx;
   static const char *vp =
      "!!ARBvp1.0\n"
      "TEMP vertexClip;\n"
      "DP4 vertexClip.x, state.matrix.mvp.row[0], vertex.position;\n"
      "DP4 vertexClip.y, state.matrix.mvp.row[1], vertex.position;\n"
      "DP4 vertexClip.z, state.matrix.mvp.row[2], vertex.position;\n"
      "DP4 vertexClip.w, state.matrix.mvp.row[3], vertex.position;\n"
      "MOV result.position, vertexClip;\n"
      "MOV result.texcoord[0], vertex.texcoord[0];\n"
      "MOV result.color, vertex.color;\n"
      "END\n";

   assert(meta->saved_vp == NULL);

   _mesa_reference_vertprog(ctx, &meta->saved_vp,
			    ctx->VertexProgram.Current);
   if (meta->passthrough_vp == NULL) {
      GLuint prog_name;
      _mesa_GenPrograms(1, &prog_name);
      _mesa_BindProgram(GL_VERTEX_PROGRAM_ARB, prog_name);
      _mesa_ProgramStringARB(GL_VERTEX_PROGRAM_ARB,
			     GL_PROGRAM_FORMAT_ASCII_ARB,
			     strlen(vp), (const GLubyte *)vp);
      _mesa_reference_vertprog(ctx, &meta->passthrough_vp,
			       ctx->VertexProgram.Current);
      _mesa_DeletePrograms(1, &prog_name);
   }

   FLUSH_VERTICES(ctx, _NEW_PROGRAM);
   _mesa_reference_vertprog(ctx, &ctx->VertexProgram.Current,
			    meta->passthrough_vp);
   ctx->Driver.BindProgram(ctx, GL_VERTEX_PROGRAM_ARB,
			   &meta->passthrough_vp->Base);

   meta->saved_vp_enable = ctx->VertexProgram.Enabled;
   _mesa_Enable(GL_VERTEX_PROGRAM_ARB);
}