예제 #1
0
파일: shaderapi.c 프로젝트: UIKit0/mesa
/**
 * Use the named shader program for subsequent glUniform calls
 */
void
_mesa_active_program(struct gl_context *ctx, struct gl_shader_program *shProg,
		     const char *caller)
{
   if ((shProg != NULL) && !shProg->LinkStatus) {
      _mesa_error(ctx, GL_INVALID_OPERATION,
		  "%s(program %u not linked)", caller, shProg->Name);
      return;
   }

   if (ctx->Shader.ActiveProgram != shProg) {
      _mesa_reference_shader_program(ctx, &ctx->Shader.ActiveProgram, shProg);
   }
}
예제 #2
0
void
brw_meta_fast_clear_free(struct brw_context *brw)
{
   struct brw_fast_clear_state *clear = brw->fast_clear_state;
   GET_CURRENT_CONTEXT(old_context);

   if (clear == NULL)
      return;

   _mesa_make_current(&brw->ctx, NULL, NULL);

   _mesa_DeleteVertexArrays(1, &clear->vao);
   _mesa_reference_buffer_object(&brw->ctx, &clear->buf_obj, NULL);
   _mesa_reference_shader_program(&brw->ctx, &clear->shader_prog, NULL);
   free(clear);

   if (old_context)
      _mesa_make_current(old_context, old_context->WinSysDrawBuffer, old_context->WinSysReadBuffer);
   else
      _mesa_make_current(NULL, NULL, NULL);
}
예제 #3
0
파일: shaderapi.c 프로젝트: UIKit0/mesa
/**
 * Named w/ "2" to indicate OpenGL 2.x vs GL_ARB_fragment_programs's
 * DeleteProgramARB.
 */
static void
delete_shader_program(struct gl_context *ctx, GLuint name)
{
   /*
    * NOTE: deleting shaders/programs works a bit differently than
    * texture objects (and buffer objects, etc).  Shader/program
    * handles/IDs exist in the hash table until the object is really
    * deleted (refcount==0).  With texture objects, the handle/ID is
    * removed from the hash table in glDeleteTextures() while the tex
    * object itself might linger until its refcount goes to zero.
    */
   struct gl_shader_program *shProg;

   shProg = _mesa_lookup_shader_program_err(ctx, name, "glDeleteProgram");
   if (!shProg)
      return;

   if (!shProg->DeletePending) {
      shProg->DeletePending = GL_TRUE;

      /* effectively, decr shProg's refcount */
      _mesa_reference_shader_program(ctx, &shProg, NULL);
   }
}
/**
 * Update the ctx->Vertex/Geometry/FragmentProgram._Current pointers to point
 * to the current/active programs.  Then call ctx->Driver.BindProgram() to
 * tell the driver which programs to use.
 *
 * Programs may come from 3 sources: GLSL shaders, ARB/NV_vertex/fragment
 * programs or programs derived from fixed-function state.
 *
 * This function needs to be called after texture state validation in case
 * we're generating a fragment program from fixed-function texture state.
 *
 * \return bitfield which will indicate _NEW_PROGRAM state if a new vertex
 * or fragment program is being used.
 */
static GLbitfield
update_program(struct gl_context *ctx)
{
   const struct gl_shader_program *vsProg = ctx->Shader.CurrentVertexProgram;
   const struct gl_shader_program *gsProg = ctx->Shader.CurrentGeometryProgram;
   struct gl_shader_program *fsProg = ctx->Shader.CurrentFragmentProgram;
   const struct gl_vertex_program *prevVP = ctx->VertexProgram._Current;
   const struct gl_fragment_program *prevFP = ctx->FragmentProgram._Current;
   const struct gl_geometry_program *prevGP = ctx->GeometryProgram._Current;
   GLbitfield new_state = 0x0;

   /*
    * Set the ctx->VertexProgram._Current and ctx->FragmentProgram._Current
    * pointers to the programs that should be used for rendering.  If either
    * is NULL, use fixed-function code paths.
    *
    * These programs may come from several sources.  The priority is as
    * follows:
    *   1. OpenGL 2.0/ARB vertex/fragment shaders
    *   2. ARB/NV vertex/fragment programs
    *   3. Programs derived from fixed-function state.
    *
    * Note: it's possible for a vertex shader to get used with a fragment
    * program (and vice versa) here, but in practice that shouldn't ever
    * come up, or matter.
    */

   if (fsProg && fsProg->LinkStatus
       && fsProg->_LinkedShaders[MESA_SHADER_FRAGMENT]) {
      /* Use GLSL fragment shader */
      _mesa_reference_shader_program(ctx,
				     &ctx->Shader._CurrentFragmentProgram,
				     fsProg);
      _mesa_reference_fragprog(ctx, &ctx->FragmentProgram._Current,
                               gl_fragment_program(fsProg->_LinkedShaders[MESA_SHADER_FRAGMENT]->Program));
      _mesa_reference_fragprog(ctx, &ctx->FragmentProgram._TexEnvProgram,
			       NULL);
   }
   else if (ctx->FragmentProgram._Enabled) {
      /* Use user-defined fragment program */
      _mesa_reference_shader_program(ctx,
				     &ctx->Shader._CurrentFragmentProgram,
				     NULL);
      _mesa_reference_fragprog(ctx, &ctx->FragmentProgram._Current,
                               ctx->FragmentProgram.Current);
      _mesa_reference_fragprog(ctx, &ctx->FragmentProgram._TexEnvProgram,
			       NULL);
   }
   else if (ctx->FragmentProgram._MaintainTexEnvProgram) {
      /* Use fragment program generated from fixed-function state */
      struct gl_shader_program *f = _mesa_get_fixed_func_fragment_program(ctx);

      _mesa_reference_shader_program(ctx,
				     &ctx->Shader._CurrentFragmentProgram,
				     f);
      _mesa_reference_fragprog(ctx, &ctx->FragmentProgram._Current,
			       gl_fragment_program(f->_LinkedShaders[MESA_SHADER_FRAGMENT]->Program));
      _mesa_reference_fragprog(ctx, &ctx->FragmentProgram._TexEnvProgram,
			       gl_fragment_program(f->_LinkedShaders[MESA_SHADER_FRAGMENT]->Program));
   }
   else {
      /* No fragment program */
      _mesa_reference_fragprog(ctx, &ctx->FragmentProgram._Current, NULL);
      _mesa_reference_fragprog(ctx, &ctx->FragmentProgram._TexEnvProgram,
			       NULL);
   }

   if (gsProg && gsProg->LinkStatus
       && gsProg->_LinkedShaders[MESA_SHADER_GEOMETRY]) {
      /* Use GLSL geometry shader */
      _mesa_reference_geomprog(ctx, &ctx->GeometryProgram._Current,
			       gl_geometry_program(gsProg->_LinkedShaders[MESA_SHADER_GEOMETRY]->Program));
   } else {
      /* No geometry program */
      _mesa_reference_geomprog(ctx, &ctx->GeometryProgram._Current, NULL);
   }

   /* Examine vertex program after fragment program as
    * _mesa_get_fixed_func_vertex_program() needs to know active
    * fragprog inputs.
    */
   if (vsProg && vsProg->LinkStatus
       && vsProg->_LinkedShaders[MESA_SHADER_VERTEX]) {
      /* Use GLSL vertex shader */
      _mesa_reference_vertprog(ctx, &ctx->VertexProgram._Current,
			       gl_vertex_program(vsProg->_LinkedShaders[MESA_SHADER_VERTEX]->Program));
   }
   else if (ctx->VertexProgram._Enabled) {
      /* Use user-defined vertex program */
      _mesa_reference_vertprog(ctx, &ctx->VertexProgram._Current,
                               ctx->VertexProgram.Current);
   }
   else if (ctx->VertexProgram._MaintainTnlProgram) {
      /* Use vertex program generated from fixed-function state */
      _mesa_reference_vertprog(ctx, &ctx->VertexProgram._Current,
                               _mesa_get_fixed_func_vertex_program(ctx));
      _mesa_reference_vertprog(ctx, &ctx->VertexProgram._TnlProgram,
                               ctx->VertexProgram._Current);
   }
   else {
      /* no vertex program */
      _mesa_reference_vertprog(ctx, &ctx->VertexProgram._Current, NULL);
   }

   /* Let the driver know what's happening:
    */
   if (ctx->FragmentProgram._Current != prevFP) {
      new_state |= _NEW_PROGRAM;
      if (ctx->Driver.BindProgram) {
         ctx->Driver.BindProgram(ctx, GL_FRAGMENT_PROGRAM_ARB,
                          (struct gl_program *) ctx->FragmentProgram._Current);
      }
   }

   if (ctx->GeometryProgram._Current != prevGP) {
      new_state |= _NEW_PROGRAM;
      if (ctx->Driver.BindProgram) {
         ctx->Driver.BindProgram(ctx, MESA_GEOMETRY_PROGRAM,
                            (struct gl_program *) ctx->GeometryProgram._Current);
      }
   }

   if (ctx->VertexProgram._Current != prevVP) {
      new_state |= _NEW_PROGRAM;
      if (ctx->Driver.BindProgram) {
         ctx->Driver.BindProgram(ctx, GL_VERTEX_PROGRAM_ARB,
                            (struct gl_program *) ctx->VertexProgram._Current);
      }
   }

   return new_state;
}
예제 #5
0
파일: shaderapi.c 프로젝트: UIKit0/mesa
static bool
use_shader_program(struct gl_context *ctx, GLenum type,
		   struct gl_shader_program *shProg)
{
   struct gl_shader_program **target;

   switch (type) {
#if FEATURE_ARB_vertex_shader
   case GL_VERTEX_SHADER:
      target = &ctx->Shader.CurrentVertexProgram;
      if ((shProg == NULL)
	  || (shProg->_LinkedShaders[MESA_SHADER_VERTEX] == NULL)) {
	 shProg = NULL;
      }
      break;
#endif
#if FEATURE_ARB_geometry_shader4
   case GL_GEOMETRY_SHADER_ARB:
      target = &ctx->Shader.CurrentGeometryProgram;
      if ((shProg == NULL)
	  || (shProg->_LinkedShaders[MESA_SHADER_GEOMETRY] == NULL)) {
	 shProg = NULL;
      }
      break;
#endif
#if FEATURE_ARB_fragment_shader
   case GL_FRAGMENT_SHADER:
      target = &ctx->Shader.CurrentFragmentProgram;
      if ((shProg == NULL)
	  || (shProg->_LinkedShaders[MESA_SHADER_FRAGMENT] == NULL)) {
	 shProg = NULL;
      }
      break;
#endif
   default:
      return false;
   }

   if (*target != shProg) {
      FLUSH_VERTICES(ctx, _NEW_PROGRAM | _NEW_PROGRAM_CONSTANTS);

      /* If the shader is also bound as the current rendering shader, unbind
       * it from that binding point as well.  This ensures that the correct
       * semantics of glDeleteProgram are maintained.
       */
      switch (type) {
#if FEATURE_ARB_vertex_shader
      case GL_VERTEX_SHADER:
	 /* Empty for now. */
	 break;
#endif
#if FEATURE_ARB_geometry_shader4
      case GL_GEOMETRY_SHADER_ARB:
	 /* Empty for now. */
	 break;
#endif
#if FEATURE_ARB_fragment_shader
      case GL_FRAGMENT_SHADER:
	 if (*target == ctx->Shader._CurrentFragmentProgram) {
	    _mesa_reference_shader_program(ctx,
					   &ctx->Shader._CurrentFragmentProgram,
					   NULL);
	 }
	 break;
#endif
      }

      _mesa_reference_shader_program(ctx, target, shProg);
      return true;
   }

   return false;
}
예제 #6
0
파일: shader_api.c 프로젝트: Starlink/mesa
/**
 * Free the per-context shader-related state.
 */
void
_mesa_free_shader_state(GLcontext *ctx)
{
   _mesa_reference_shader_program(ctx, &ctx->Shader.CurrentProgram, NULL);
}