Example #1
0
void
_mesa_get_shaderiv(GLcontext *ctx, GLuint name, GLenum pname, GLint *params)
{
   struct gl_shader *shader = _mesa_lookup_shader(ctx, name);

   if (!shader) {
      _mesa_error(ctx, GL_INVALID_VALUE, "glGetShaderiv(shader)");
      return;
   }

   switch (pname) {
   case GL_SHADER_TYPE:
      *params = shader->Type;
      break;
   case GL_DELETE_STATUS:
      *params = shader->DeletePending;
      break;
   case GL_COMPILE_STATUS:
      *params = shader->CompileStatus;
      break;
   case GL_INFO_LOG_LENGTH:
      *params = shader->InfoLog ? strlen(shader->InfoLog) + 1 : 0;
      break;
   case GL_SHADER_SOURCE_LENGTH:
      *params = shader->Source ? strlen((char *) shader->Source) + 1 : 0;
      break;
   default:
      _mesa_error(ctx, GL_INVALID_ENUM, "glGetShaderiv(pname)");
      return;
   }
}
Example #2
0
static void
PrintShaderInstructions(GLuint shader, FILE *f)
{
   GET_CURRENT_CONTEXT(ctx);
   struct gl_shader *sh = _mesa_lookup_shader(ctx, shader);
   struct gl_program *prog = sh->Program;
   _mesa_fprint_program_opt(stdout, prog, Options.Mode, Options.LineNumbers);
   if (Options.Params)
      _mesa_print_program_parameters(ctx, prog);
}
Example #3
0
static void
get_shader_info_log(struct gl_context *ctx, GLuint shader, GLsizei bufSize,
                    GLsizei *length, GLchar *infoLog)
{
   struct gl_shader *sh = _mesa_lookup_shader(ctx, shader);
   if (!sh) {
      _mesa_error(ctx, GL_INVALID_VALUE, "glGetShaderInfoLog(shader)");
      return;
   }
   _mesa_copy_string(infoLog, bufSize, length, sh->InfoLog);
}
Example #4
0
/**
 * Called via ctx->Driver.CompileShader()
 */
void
_mesa_compile_shader(GLcontext *ctx, GLuint shaderObj)
{
   struct gl_shader *sh = _mesa_lookup_shader(ctx, shaderObj);

   if (!sh) {
      _mesa_error(ctx, GL_INVALID_VALUE, "glCompileShader(shaderObj)");
      return;
   }

   sh->CompileStatus = _slang_compile(ctx, sh);
}
Example #5
0
void
_mesa_delete_shader(GLcontext *ctx, GLuint shader)
{
   struct gl_shader *sh = _mesa_lookup_shader(ctx, shader);
   if (!sh) {
      return;
   }

   sh->DeletePending = GL_TRUE;

   /* effectively, decr sh's refcount */
   _mesa_reference_shader(ctx, &sh, NULL);
}
Example #6
0
/**
 * Called via ctx->Driver.GetShaderSource().
 */
void
_mesa_get_shader_source(GLcontext *ctx, GLuint shader, GLsizei maxLength,
                        GLsizei *length, GLchar *sourceOut)
{
   struct gl_shader *sh = _mesa_lookup_shader(ctx, shader);
   if (!sh) {
      GLenum err;
      if (_mesa_lookup_shader_program(ctx, shader))
         err = GL_INVALID_OPERATION;
      else
         err = GL_INVALID_VALUE;
      _mesa_error(ctx, err, "glGetShaderSource(shader)");
      return;
   }
   copy_string(sourceOut, maxLength, length, sh->Source);
}
Example #7
0
/**
 * For GL_EXT_separate_shader_objects
 */
GLuint GLAPIENTRY
_mesa_CreateShaderProgramEXT(GLenum type, const GLchar *string)
{
   GET_CURRENT_CONTEXT(ctx);
   const GLuint shader = create_shader(ctx, type);
   GLuint program = 0;

   if (shader) {
      shader_source(ctx, shader, _mesa_strdup(string));
      compile_shader(ctx, shader);

      program = create_shader_program(ctx);
      if (program) {
	 struct gl_shader_program *shProg;
	 struct gl_shader *sh;
	 GLint compiled = GL_FALSE;

	 shProg = _mesa_lookup_shader_program(ctx, program);
	 sh = _mesa_lookup_shader(ctx, shader);

	 get_shaderiv(ctx, shader, GL_COMPILE_STATUS, &compiled);
	 if (compiled) {
	    attach_shader(ctx, program, shader);
	    link_program(ctx, program);
	    detach_shader(ctx, program, shader);

#if 0
	    /* Possibly... */
	    if (active-user-defined-varyings-in-linked-program) {
	       append-error-to-info-log;
	       shProg->LinkStatus = GL_FALSE;
	    }
#endif
	 }

	 ralloc_strcat(&shProg->InfoLog, sh->InfoLog);
      }

      delete_shader(ctx, shader);
   }

   return program;
}
Example #8
0
/**
 * Called via ctx->Driver.ShaderSource()
 */
void
_mesa_shader_source(GLcontext *ctx, GLuint shader, const GLchar *source)
{
   struct gl_shader *sh = _mesa_lookup_shader(ctx, shader);
   if (!sh) {
      GLenum err;
      if (_mesa_lookup_shader_program(ctx, shader))
         err = GL_INVALID_OPERATION;
      else
         err = GL_INVALID_VALUE;
      _mesa_error(ctx, err, "glShaderSource(shaderObj)");
      return;
   }

   /* free old shader source string and install new one */
   if (sh->Source) {
      _mesa_free((void *) sh->Source);
   }
   sh->Source = source;
   sh->CompileStatus = GL_FALSE;
}
Example #9
0
/**
 * Called via ctx->Driver.AttachShader()
 */
void
_mesa_attach_shader(GLcontext *ctx, GLuint program, GLuint shader)
{
   struct gl_shader_program *shProg
      = _mesa_lookup_shader_program(ctx, program);
   struct gl_shader *sh = _mesa_lookup_shader(ctx, shader);
   GLuint n;
   GLuint i;

   if (!shProg || !sh) {
      _mesa_error(ctx, GL_INVALID_VALUE,
                  "glAttachShader(bad program or shader name)");
      return;
   }

   n = shProg->NumShaders;

   for (i = 0; i < n; i++) {
      if (shProg->Shaders[i] == sh) {
         /* already attached */
         return;
      }
   }

   /* grow list */
   shProg->Shaders = (struct gl_shader **)
      _mesa_realloc(shProg->Shaders,
                    n * sizeof(struct gl_shader *),
                    (n + 1) * sizeof(struct gl_shader *));
   if (!shProg->Shaders) {
      _mesa_error(ctx, GL_OUT_OF_MEMORY, "glAttachShader");
      return;
   }

   /* append */
   shProg->Shaders[n] = NULL; /* since realloc() didn't zero the new space */
   _mesa_reference_shader(ctx, &shProg->Shaders[n], sh);
   shProg->NumShaders++;
}
Example #10
0
static GLboolean
is_shader(struct gl_context *ctx, GLuint name)
{
   struct gl_shader *shader = _mesa_lookup_shader(ctx, name);
   return shader ? GL_TRUE : GL_FALSE;
}
Example #11
0
/**
 * Called via glShaderSource() and glShaderSourceARB() API functions.
 * Basically, concatenate the source code strings into one long string
 * and pass it to _mesa_shader_source().
 */
void GLAPIENTRY
_mesa_ShaderSourceARB(GLhandleARB shaderObj, GLsizei count,
                      const GLcharARB ** string, const GLint * length)
{
   GET_CURRENT_CONTEXT(ctx);
   GLint *offsets;
   GLsizei i, totalLength;
   GLcharARB *source;
   GLuint checksum;

   if (!shaderObj || string == NULL) {
      _mesa_error(ctx, GL_INVALID_VALUE, "glShaderSourceARB");
      return;
   }

   /*
    * This array holds offsets of where the appropriate string ends, thus the
    * last element will be set to the total length of the source code.
    */
   offsets = (GLint *) malloc(count * sizeof(GLint));
   if (offsets == NULL) {
      _mesa_error(ctx, GL_OUT_OF_MEMORY, "glShaderSourceARB");
      return;
   }

   for (i = 0; i < count; i++) {
      if (string[i] == NULL) {
         free((GLvoid *) offsets);
         _mesa_error(ctx, GL_INVALID_OPERATION,
                     "glShaderSourceARB(null string)");
         return;
      }
      if (length == NULL || length[i] < 0)
         offsets[i] = strlen(string[i]);
      else
         offsets[i] = length[i];
      /* accumulate string lengths */
      if (i > 0)
         offsets[i] += offsets[i - 1];
   }

   /* Total length of source string is sum off all strings plus two.
    * One extra byte for terminating zero, another extra byte to silence
    * valgrind warnings in the parser/grammer code.
    */
   totalLength = offsets[count - 1] + 2;
   source = (GLcharARB *) malloc(totalLength * sizeof(GLcharARB));
   if (source == NULL) {
      free((GLvoid *) offsets);
      _mesa_error(ctx, GL_OUT_OF_MEMORY, "glShaderSourceARB");
      return;
   }

   for (i = 0; i < count; i++) {
      GLint start = (i > 0) ? offsets[i - 1] : 0;
      memcpy(source + start, string[i],
             (offsets[i] - start) * sizeof(GLcharARB));
   }
   source[totalLength - 1] = '\0';
   source[totalLength - 2] = '\0';

   if (SHADER_SUBST) {
      /* Compute the shader's source code checksum then try to open a file
       * named newshader_<CHECKSUM>.  If it exists, use it in place of the
       * original shader source code.  For debugging.
       */
      char filename[100];
      GLcharARB *newSource;

      checksum = _mesa_str_checksum(source);

      _mesa_snprintf(filename, sizeof(filename), "newshader_%d", checksum);

      newSource = read_shader(filename);
      if (newSource) {
         fprintf(stderr, "Mesa: Replacing shader %u chksum=%d with %s\n",
                       shaderObj, checksum, filename);
         free(source);
         source = newSource;
      }
   }

   shader_source(ctx, shaderObj, source);

   if (SHADER_SUBST) {
      struct gl_shader *sh = _mesa_lookup_shader(ctx, shaderObj);
      if (sh)
         sh->SourceChecksum = checksum; /* save original checksum */
   }

   free(offsets);
}