Exemple #1
0
/**
 * Do validation of the given shader program.
 * \param errMsg  returns error message if validation fails.
 * \return GL_TRUE if valid, GL_FALSE if invalid (and set errMsg)
 */
static GLboolean
validate_shader_program(const struct gl_shader_program *shProg,
                        char *errMsg)
{
   if (!shProg->LinkStatus) {
      return GL_FALSE;
   }

   /* From the GL spec, a program is invalid if any of these are true:

     any two active samplers in the current program object are of
     different types, but refer to the same texture image unit,

     any active sampler in the current program object refers to a texture
     image unit where fixed-function fragment processing accesses a
     texture target that does not match the sampler type, or 

     the sum of the number of active samplers in the program and the
     number of texture image units enabled for fixed-function fragment
     processing exceeds the combined limit on the total number of texture
     image units allowed.
   */


   /*
    * Check: any two active samplers in the current program object are of
    * different types, but refer to the same texture image unit,
    */
   if (!_mesa_sampler_uniforms_are_valid(shProg, errMsg, 100))
      return GL_FALSE;

   return GL_TRUE;
}
Exemple #2
0
/**
 * Prior to drawing anything with glBegin, glDrawArrays, etc. this function
 * is called to see if it's valid to render.  This involves checking that
 * the current shader is valid and the framebuffer is complete.
 * It also check the current pipeline object is valid if any.
 * If an error is detected it'll be recorded here.
 * \return GL_TRUE if OK to render, GL_FALSE if not
 */
GLboolean
_mesa_valid_to_render(struct gl_context *ctx, const char *where)
{
   /* This depends on having up to date derived state (shaders) */
   if (ctx->NewState)
      _mesa_update_state(ctx);

   if (ctx->API == API_OPENGL_COMPAT) {
      /* Any shader stages that are not supplied by the GLSL shader and have
       * assembly shaders enabled must now be validated.
       */
      if (!ctx->_Shader->CurrentProgram[MESA_SHADER_VERTEX]
          && ctx->VertexProgram.Enabled && !ctx->VertexProgram._Enabled) {
         _mesa_error(ctx, GL_INVALID_OPERATION,
                     "%s(vertex program not valid)", where);
         return GL_FALSE;
      }

      if (!ctx->_Shader->CurrentProgram[MESA_SHADER_FRAGMENT]) {
         if (ctx->FragmentProgram.Enabled && !ctx->FragmentProgram._Enabled) {
            _mesa_error(ctx, GL_INVALID_OPERATION,
                        "%s(fragment program not valid)", where);
            return GL_FALSE;
         }

         /* If drawing to integer-valued color buffers, there must be an
          * active fragment shader (GL_EXT_texture_integer).
          */
         if (ctx->DrawBuffer && ctx->DrawBuffer->_IntegerColor) {
            _mesa_error(ctx, GL_INVALID_OPERATION,
                        "%s(integer format but no fragment shader)", where);
            return GL_FALSE;
         }
      }
   }

   /* A pipeline object is bound */
   if (ctx->_Shader->Name && !ctx->_Shader->Validated) {
      if (!_mesa_validate_program_pipeline(ctx, ctx->_Shader)) {
         _mesa_error(ctx, GL_INVALID_OPERATION,
                     "glValidateProgramPipeline failed to validate the "
                     "pipeline");
         return GL_FALSE;
      }
   }

   /* If a program is active and SSO not in use, check if validation of
    * samplers succeeded for the active program. */
   if (ctx->_Shader->ActiveProgram && ctx->_Shader != ctx->Pipeline.Current) {
      char errMsg[100];
      if (!_mesa_sampler_uniforms_are_valid(ctx->_Shader->ActiveProgram,
                                            errMsg, 100)) {
         _mesa_error(ctx, GL_INVALID_OPERATION, "%s", errMsg);
         return GL_FALSE;
      }
   }

   if (ctx->DrawBuffer->_Status != GL_FRAMEBUFFER_COMPLETE_EXT) {
      _mesa_error(ctx, GL_INVALID_FRAMEBUFFER_OPERATION_EXT,
                  "%s(incomplete framebuffer)", where);
      return GL_FALSE;
   }

   if (!check_blend_func_error(ctx)) {
      return GL_FALSE;
   }

#ifdef DEBUG
   if (ctx->_Shader->Flags & GLSL_LOG) {
      struct gl_shader_program **shProg = ctx->_Shader->CurrentProgram;
      gl_shader_stage i;

      for (i = 0; i < MESA_SHADER_STAGES; i++) {
	 if (shProg[i] == NULL || shProg[i]->_Used
	     || shProg[i]->_LinkedShaders[i] == NULL)
	    continue;

	 /* This is the first time this shader is being used.
	  * Append shader's constants/uniforms to log file.
	  *
	  * Only log data for the program target that matches the shader
	  * target.  It's possible to have a program bound to the vertex
	  * shader target that also supplied a fragment shader.  If that
	  * program isn't also bound to the fragment shader target we don't
	  * want to log its fragment data.
	  */
	 _mesa_append_uniforms_to_file(shProg[i]->_LinkedShaders[i]);
      }

      for (i = 0; i < MESA_SHADER_STAGES; i++) {
	 if (shProg[i] != NULL)
	    shProg[i]->_Used = GL_TRUE;
      }
   }
#endif

   return GL_TRUE;
}