Пример #1
0
/**
 * Return string name for given program/register file.
 */
const char *
_mesa_register_file_name(gl_register_file f)
{
    switch (f) {
    case PROGRAM_TEMPORARY:
        return "TEMP";
    case PROGRAM_STATE_VAR:
        return "STATE";
    case PROGRAM_INPUT:
        return "INPUT";
    case PROGRAM_OUTPUT:
        return "OUTPUT";
    case PROGRAM_CONSTANT:
        return "CONST";
    case PROGRAM_UNIFORM:
        return "UNIFORM";
    case PROGRAM_ADDRESS:
        return "ADDR";
    case PROGRAM_SAMPLER:
        return "SAMPLER";
    case PROGRAM_SYSTEM_VALUE:
        return "SYSVAL";
    case PROGRAM_UNDEFINED:
        return "UNDEFINED";
    default:
    {
        static char s[20];
        _mesa_snprintf(s, sizeof(s), "FILE%u", f);
        return s;
    }
    }
}
Пример #2
0
static void
compute_version_es2(struct gl_context *ctx)
{
   static const int max = 100;

   /* OpenGL ES 2.0 is derived from OpenGL 2.0 */
   const GLboolean ver_2_0 = (ctx->Extensions.ARB_texture_cube_map &&
                              ctx->Extensions.EXT_blend_color &&
                              ctx->Extensions.EXT_blend_func_separate &&
                              ctx->Extensions.EXT_blend_minmax &&
                              ctx->Extensions.ARB_shader_objects &&
                              ctx->Extensions.ARB_vertex_shader &&
                              ctx->Extensions.ARB_fragment_shader &&
                              ctx->Extensions.ARB_texture_non_power_of_two &&
                              ctx->Extensions.EXT_blend_equation_separate);
   if (ver_2_0) {
      ctx->VersionMajor = 2;
      ctx->VersionMinor = 0;
   } else {
      _mesa_problem(ctx, "Incomplete OpenGL ES 2.0 support.");
   }

   ctx->VersionString = (char *) malloc(max);
   if (ctx->VersionString) {
      _mesa_snprintf(ctx->VersionString, max,
		     "OpenGL ES 2.0 Mesa " MESA_VERSION_STRING
#ifdef MESA_GIT_SHA1
		     " (" MESA_GIT_SHA1 ")"
#endif
		     );
   }
}
Пример #3
0
/**
 * Append the shader's uniform info/values to the shader log file.
 * The log file will typically have been created by the
 * _mesa_write_shader_to_file function.
 */
void
_mesa_append_uniforms_to_file(const struct gl_shader *shader)
{
    const struct gl_program *const prog = shader->Program;
    const char *type;
    char filename[100];
    FILE *f;

    if (shader->Stage == MESA_SHADER_FRAGMENT)
        type = "frag";
    else
        type = "vert";

    _mesa_snprintf(filename, sizeof(filename), "shader_%u.%s", shader->Name, type);
    f = fopen(filename, "a"); /* append */
    if (!f) {
        fprintf(stderr, "Unable to open %s for appending\n", filename);
        return;
    }

    fprintf(f, "/* First-draw parameters / constants */\n");
    fprintf(f, "/*\n");
    _mesa_fprint_parameter_list(f, prog->Parameters);
    fprintf(f, "*/\n");

    fclose(f);
}
Пример #4
0
static void
compute_version_es1(struct gl_context *ctx)
{
   static const int max = 100;

   /* OpenGL ES 1.0 is derived from OpenGL 1.3 */
   const GLboolean ver_1_0 = (ctx->Extensions.ARB_texture_env_combine &&
                              ctx->Extensions.ARB_texture_env_dot3);
   /* OpenGL ES 1.1 is derived from OpenGL 1.5 */
   const GLboolean ver_1_1 = (ver_1_0 &&
                              ctx->Extensions.EXT_point_parameters);

   if (ver_1_1) {
      ctx->VersionMajor = 1;
      ctx->VersionMinor = 1;
   } else if (ver_1_0) {
      ctx->VersionMajor = 1;
      ctx->VersionMinor = 0;
   } else {
      _mesa_problem(ctx, "Incomplete OpenGL ES 1.0 support.");
   }

   ctx->VersionString = (char *) malloc(max);
   if (ctx->VersionString) {
      _mesa_snprintf(ctx->VersionString, max,
		     "OpenGL ES-CM 1.%d Mesa " MESA_VERSION_STRING
#ifdef MESA_GIT_SHA1
		     " (" MESA_GIT_SHA1 ")"
#endif
		     ,
		     ctx->VersionMinor);
   }
}
Пример #5
0
/**
 * Write shader and associated info to a file.
 */
void
_mesa_write_shader_to_file(const struct gl_shader *shader)
{
    const char *type = "????";
    char filename[100];
    FILE *f;

    switch (shader->Stage) {
    case MESA_SHADER_FRAGMENT:
        type = "frag";
        break;
    case MESA_SHADER_TESS_CTRL:
        type = "tesc";
        break;
    case MESA_SHADER_TESS_EVAL:
        type = "tese";
        break;
    case MESA_SHADER_VERTEX:
        type = "vert";
        break;
    case MESA_SHADER_GEOMETRY:
        type = "geom";
        break;
    case MESA_SHADER_COMPUTE:
        type = "comp";
        break;
    }

    _mesa_snprintf(filename, sizeof(filename), "shader_%u.%s", shader->Name, type);
    f = fopen(filename, "w");
    if (!f) {
        fprintf(stderr, "Unable to open %s for writing\n", filename);
        return;
    }

    fprintf(f, "/* Shader %u source, checksum %u */\n", shader->Name, shader->SourceChecksum);
    fputs(shader->Source, f);
    fprintf(f, "\n");

    fprintf(f, "/* Compile status: %s */\n",
            shader->CompileStatus ? "ok" : "fail");
    fprintf(f, "/* Log Info: */\n");
    if (shader->InfoLog) {
        fputs(shader->InfoLog, f);
    }
    if (shader->CompileStatus && shader->Program) {
        fprintf(f, "/* GPU code */\n");
        fprintf(f, "/*\n");
        _mesa_fprint_program_opt(f, shader->Program, PROG_PRINT_DEBUG, GL_TRUE);
        fprintf(f, "*/\n");
        fprintf(f, "/* Parameters / constants */\n");
        fprintf(f, "/*\n");
        _mesa_fprint_parameter_list(f, shader->Program->Parameters);
        fprintf(f, "*/\n");
    }

    fclose(f);
}
Пример #6
0
/**
 * Return string name for given program opcode.
 */
const char *
_mesa_opcode_string(gl_inst_opcode opcode)
{
   if (opcode < MAX_OPCODE)
      return InstInfo[opcode].Name;
   else {
      static char s[20];
      _mesa_snprintf(s, sizeof(s), "OP%u", opcode);
      return s;
   }
}
Пример #7
0
static GLvoid
grammar_error_to_log (slang_info_log *log)
{
   char buf[1024];
   GLint pos;

   grammar_get_last_error ((byte *) (buf), sizeof (buf), &pos);
   if (buf[0] == 0) {
      _mesa_snprintf(buf, sizeof(buf), "Preprocessor error");
   }
   slang_info_log_error (log, buf);
}
Пример #8
0
static void
output_if_debug(const char *prefixString, const char *outputString,
                GLboolean newline)
{
   static int debug = -1;

   /* Init the local 'debug' var once.
    * Note: the _mesa_init_debug() function should have been called
    * by now so MESA_DEBUG_FLAGS will be initialized.
    */
   if (debug == -1) {
      /* If MESA_LOG_FILE env var is set, log Mesa errors, warnings,
       * etc to the named file.  Otherwise, output to stderr.
       */
      const char *logFile = getenv("MESA_LOG_FILE");
      if (logFile)
         LogFile = fopen(logFile, "w");
      if (!LogFile)
         LogFile = stderr;
#ifdef DEBUG
      /* in debug builds, print messages unless MESA_DEBUG="silent" */
      if (MESA_DEBUG_FLAGS & DEBUG_SILENT)
         debug = 0;
      else
         debug = 1;
#else
      /* in release builds, be silent unless MESA_DEBUG is set */
      debug = getenv("MESA_DEBUG") != NULL;
#endif
   }

   /* Now only print the string if we're required to do so. */
   if (debug) {
      if (prefixString)
         fprintf(LogFile, "%s: %s", prefixString, outputString);
      else
         fprintf(LogFile, "%s", outputString);
      if (newline)
         fprintf(LogFile, "\n");
      fflush(LogFile);

#if defined(_WIN32)
      /* stderr from windows applications without console is not usually 
       * visible, so communicate with the debugger instead */ 
      {
         char buf[4096];
         _mesa_snprintf(buf, sizeof(buf), "%s: %s%s", prefixString, outputString, newline ? "\n" : "");
         OutputDebugStringA(buf);
      }
#endif
   }
}
Пример #9
0
/**
 * When a new type of error is recorded, print a message describing
 * previous errors which were accumulated.
 */
static void
flush_delayed_errors( struct gl_context *ctx )
{
   char s[MAX_DEBUG_MESSAGE_LENGTH];

   if (ctx->ErrorDebugCount) {
      _mesa_snprintf(s, MAX_DEBUG_MESSAGE_LENGTH, "%d similar %s errors", 
                     ctx->ErrorDebugCount,
                     _mesa_enum_to_string(ctx->ErrorValue));

      output_if_debug("Mesa", s, GL_TRUE);

      ctx->ErrorDebugCount = 0;
   }
}
Пример #10
0
extern "C" bool
_mesa_sampler_uniforms_are_valid(const struct gl_shader_program *shProg,
				 char *errMsg, size_t errMsgLength)
{
   /* Shader does not have samplers. */
   if (shProg->NumUniformStorage == 0)
      return true;

   if (!shProg->SamplersValidated) {
      _mesa_snprintf(errMsg, errMsgLength,
                     "active samplers with a different type "
                     "refer to the same texture image unit");
      return false;
   }
   return true;
}
Пример #11
0
/**
 * Builds the MESA version string.
 */
static GLboolean
create_version_string(struct gl_context *ctx, const char *prefix)
{
   static const int max = 100;

   ctx->VersionString = malloc(max);
   if (ctx->VersionString) {
      _mesa_snprintf(ctx->VersionString, max,
		     "%s%u.%u Mesa " MESA_VERSION_STRING
#ifdef MESA_GIT_SHA1
		     " (" MESA_GIT_SHA1 ")"
#endif
		     ,
		     prefix,
		     ctx->Version / 10, ctx->Version % 10);
   }
}
Пример #12
0
/**
 * Write shader and associated info to a file.
 */
void
_mesa_write_shader_to_file(const struct gl_shader *shader)
{
   const char *type;
   char filename[100];
   FILE *f;

   if (shader->Type == GL_FRAGMENT_SHADER)
      type = "frag";
   else if (shader->Type == GL_VERTEX_SHADER)
      type = "vert";
   else
      type = "geom";

   _mesa_snprintf(filename, sizeof(filename), "shader_%u.%s", shader->Name, type);
   f = fopen(filename, "w");
   if (!f) {
      fprintf(stderr, "Unable to open %s for writing\n", filename);
      return;
   }

   fprintf(f, "/* Shader %u source, checksum %u */\n", shader->Name, shader->SourceChecksum);
   fputs(shader->Source, f);
   fprintf(f, "\n");

   fprintf(f, "/* Compile status: %s */\n",
           shader->CompileStatus ? "ok" : "fail");
   fprintf(f, "/* Log Info: */\n");
   if (shader->InfoLog) {
      fputs(shader->InfoLog, f);
   }
   if (shader->CompileStatus && shader->Program) {
      fprintf(f, "/* GPU code */\n");
      fprintf(f, "/*\n");
      _mesa_fprint_program_opt(f, shader->Program, PROG_PRINT_DEBUG, GL_TRUE);
      fprintf(f, "*/\n");
      fprintf(f, "/* Parameters / constants */\n");
      fprintf(f, "/*\n");
      _mesa_fprint_parameter_list(f, shader->Program->Parameters);
      fprintf(f, "*/\n");
   }

   fclose(f);
}
Пример #13
0
/**
 * Builds the MESA version string.
 */
static void
create_version_string(struct gl_context *ctx, const char *prefix)
{
   static const int max = 100;

   ctx->VersionString = malloc(max);
   if (ctx->VersionString) {
      _mesa_snprintf(ctx->VersionString, max,
		     "%s%u.%u%s Mesa " MESA_VERSION_STRING
#ifdef MESA_GIT_SHA1
		     " (" MESA_GIT_SHA1 ")"
#endif
		     ,
		     prefix,
		     ctx->Version / 10, ctx->Version % 10,
		     (ctx->API == API_OPENGL_CORE) ? " (Core Profile)" : ""
		     );
   }
}
Пример #14
0
extern "C" bool
_mesa_sampler_uniforms_are_valid(const struct gl_shader_program *shProg,
				 char *errMsg, size_t errMsgLength)
{
   const glsl_type *unit_types[MAX_COMBINED_TEXTURE_IMAGE_UNITS];

   memset(unit_types, 0, sizeof(unit_types));

   for (unsigned i = 0; i < shProg->NumUserUniformStorage; i++) {
      const struct gl_uniform_storage *const storage =
	 &shProg->UniformStorage[i];
      const glsl_type *const t = (storage->type->is_array())
	 ? storage->type->fields.array : storage->type;

      if (!t->is_sampler())
	 continue;

      const unsigned count = MAX2(1, storage->type->array_size());
      for (unsigned j = 0; j < count; j++) {
	 const unsigned unit = storage->storage[j].i;

	 /* The types of the samplers associated with a particular texture
	  * unit must be an exact match.  Page 74 (page 89 of the PDF) of the
	  * OpenGL 3.3 core spec says:
	  *
	  *     "It is not allowed to have variables of different sampler
	  *     types pointing to the same texture image unit within a program
	  *     object."
	  */
	 if (unit_types[unit] == NULL) {
	    unit_types[unit] = t;
	 } else if (unit_types[unit] != t) {
	    _mesa_snprintf(errMsg, errMsgLength,
			   "Texture unit %d is accessed both as %s and %s",
			   unit, unit_types[unit]->name, t->name);
	    return false;
	 }
      }
   }

   return true;
}
Пример #15
0
/**
 * Return string name for given program/register file.
 */
static const char *
file_string(gl_register_file f, gl_prog_print_mode mode)
{
   switch (f) {
   case PROGRAM_TEMPORARY:
      return "TEMP";
   case PROGRAM_LOCAL_PARAM:
      return "LOCAL";
   case PROGRAM_ENV_PARAM:
      return "ENV";
   case PROGRAM_STATE_VAR:
      return "STATE";
   case PROGRAM_INPUT:
      return "INPUT";
   case PROGRAM_OUTPUT:
      return "OUTPUT";
   case PROGRAM_NAMED_PARAM:
      return "NAMED";
   case PROGRAM_CONSTANT:
      return "CONST";
   case PROGRAM_UNIFORM:
      return "UNIFORM";
   case PROGRAM_VARYING:
      return "VARYING";
   case PROGRAM_WRITE_ONLY:
      return "WRITE_ONLY";
   case PROGRAM_ADDRESS:
      return "ADDR";
   case PROGRAM_SAMPLER:
      return "SAMPLER";
   case PROGRAM_UNDEFINED:
      return "UNDEFINED";
   default:
      {
         static char s[20];
         _mesa_snprintf(s, sizeof(s), "FILE%u", f);
         return s;
      }
   }
}
Пример #16
0
/**
 * Record an OpenGL state error.  These usually occur when the user
 * passes invalid parameters to a GL function.
 *
 * If debugging is enabled (either at compile-time via the DEBUG macro, or
 * run-time via the MESA_DEBUG environment variable), report the error with
 * _mesa_debug().
 * 
 * \param ctx the GL context.
 * \param error the error value.
 * \param fmtString printf() style format string, followed by optional args
 */
void
_mesa_error( struct gl_context *ctx, GLenum error, const char *fmtString, ... )
{
   GLboolean do_output, do_log;
   /* Ideally this would be set up by the caller, so that we had proper IDs
    * per different message.
    */
   static GLuint error_msg_id = 0;

   _mesa_debug_get_id(&error_msg_id);

   do_output = should_output(ctx, error, fmtString);

   mtx_lock(&ctx->DebugMutex);
   if (ctx->Debug) {
      do_log = _mesa_debug_is_message_enabled(ctx->Debug,
                                              MESA_DEBUG_SOURCE_API,
                                              MESA_DEBUG_TYPE_ERROR,
                                              error_msg_id,
                                              MESA_DEBUG_SEVERITY_HIGH);
   }
   else {
      do_log = GL_FALSE;
   }
   mtx_unlock(&ctx->DebugMutex);

   if (do_output || do_log) {
      char s[MAX_DEBUG_MESSAGE_LENGTH], s2[MAX_DEBUG_MESSAGE_LENGTH];
      int len;
      va_list args;

      va_start(args, fmtString);
      len = _mesa_vsnprintf(s, MAX_DEBUG_MESSAGE_LENGTH, fmtString, args);
      va_end(args);

      if (len >= MAX_DEBUG_MESSAGE_LENGTH) {
         /* Too long error message. Whoever calls _mesa_error should use
          * shorter strings.
          */
         assert(0);
         return;
      }

      len = _mesa_snprintf(s2, MAX_DEBUG_MESSAGE_LENGTH, "%s in %s",
                           _mesa_enum_to_string(error), s);
      if (len >= MAX_DEBUG_MESSAGE_LENGTH) {
         /* Same as above. */
         assert(0);
         return;
      }

      /* Print the error to stderr if needed. */
      if (do_output) {
         output_if_debug("Mesa: User error", s2, GL_TRUE);
      }

      /* Log the error via ARB_debug_output if needed.*/
      if (do_log) {
         _mesa_log_msg(ctx, MESA_DEBUG_SOURCE_API, MESA_DEBUG_TYPE_ERROR,
                       error_msg_id, MESA_DEBUG_SEVERITY_HIGH, len, s2);
      }
   }

   /* Set the GL context error state for glGetError. */
   _mesa_record_error(ctx, error);
}
Пример #17
0
/**
 * Linking varying vars involves rearranging varying vars so that the
 * vertex program's output varyings matches the order of the fragment
 * program's input varyings.
 * We'll then rewrite instructions to replace PROGRAM_VARYING with either
 * PROGRAM_INPUT or PROGRAM_OUTPUT depending on whether it's a vertex or
 * fragment shader.
 * This is also where we set program Input/OutputFlags to indicate
 * which inputs are centroid-sampled, invariant, etc.
 */
static GLboolean
link_varying_vars(GLcontext *ctx,
                  struct gl_shader_program *shProg, struct gl_program *prog)
{
   GLuint *map, i, firstVarying, newFile;
   GLbitfield *inOutFlags;

   map = (GLuint *) malloc(prog->Varying->NumParameters * sizeof(GLuint));
   if (!map)
      return GL_FALSE;

   /* Varying variables are treated like other vertex program outputs
    * (and like other fragment program inputs).  The position of the
    * first varying differs for vertex/fragment programs...
    * Also, replace File=PROGRAM_VARYING with File=PROGRAM_INPUT/OUTPUT.
    */
   if (prog->Target == GL_VERTEX_PROGRAM_ARB) {
      firstVarying = VERT_RESULT_VAR0;
      newFile = PROGRAM_OUTPUT;
      inOutFlags = prog->OutputFlags;
   }
   else {
      assert(prog->Target == GL_FRAGMENT_PROGRAM_ARB);
      firstVarying = FRAG_ATTRIB_VAR0;
      newFile = PROGRAM_INPUT;
      inOutFlags = prog->InputFlags;
   }

   for (i = 0; i < prog->Varying->NumParameters; i++) {
      /* see if this varying is in the linked varying list */
      const struct gl_program_parameter *var = prog->Varying->Parameters + i;
      GLint j = _mesa_lookup_parameter_index(shProg->Varying, -1, var->Name);
      if (j >= 0) {
         /* varying is already in list, do some error checking */
         const struct gl_program_parameter *v =
            &shProg->Varying->Parameters[j];
         if (var->Size != v->Size) {
            link_error(shProg, "mismatched varying variable types");
            free(map);
            return GL_FALSE;
         }
         if (!bits_agree(var->Flags, v->Flags, PROG_PARAM_BIT_CENTROID)) {
            char msg[100];
            _mesa_snprintf(msg, sizeof(msg),
		     "centroid modifier mismatch for '%s'", var->Name);
            link_error(shProg, msg);
            free(map);
            return GL_FALSE;
         }
         if (!bits_agree(var->Flags, v->Flags, PROG_PARAM_BIT_INVARIANT)) {
            char msg[100];
            _mesa_snprintf(msg, sizeof(msg),
		     "invariant modifier mismatch for '%s'", var->Name);
            link_error(shProg, msg);
            free(map);
            return GL_FALSE;
         }
      }
      else {
         /* not already in linked list */
         j = _mesa_add_varying(shProg->Varying, var->Name, var->Size,
                               var->Flags);
      }

      if (shProg->Varying->NumParameters > ctx->Const.MaxVarying) {
         link_error(shProg, "Too many varying variables");
         free(map);
         return GL_FALSE;
      }

      /* Map varying[i] to varying[j].
       * Note: the loop here takes care of arrays or large (sz>4) vars.
       */
      {
         GLint sz = var->Size;
         while (sz > 0) {
            inOutFlags[firstVarying + j] = var->Flags;
            /*printf("Link varying from %d to %d\n", i, j);*/
            map[i++] = j++;
            sz -= 4;
         }
         i--; /* go back one */
      }
   }


   /* OK, now scan the program/shader instructions looking for varying vars,
    * replacing the old index with the new index.
    */
   for (i = 0; i < prog->NumInstructions; i++) {
      struct prog_instruction *inst = prog->Instructions + i;
      GLuint j;

      if (inst->DstReg.File == PROGRAM_VARYING) {
         inst->DstReg.File = newFile;
         inst->DstReg.Index = map[ inst->DstReg.Index ] + firstVarying;
      }

      for (j = 0; j < 3; j++) {
         if (inst->SrcReg[j].File == PROGRAM_VARYING) {
            inst->SrcReg[j].File = newFile;
            inst->SrcReg[j].Index = map[ inst->SrcReg[j].Index ] + firstVarying;
         }
      }
   }

   free(map);

   /* these will get recomputed before linking is completed */
   prog->InputsRead = 0x0;
   prog->OutputsWritten = 0x0;

   return GL_TRUE;
}
Пример #18
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);
}
Пример #19
0
/**
 * Examine enabled GL extensions to determine GL version.
 */
static void
compute_version(struct gl_context *ctx)
{
   GLuint major, minor;
   static const int max = 100;

   const GLboolean ver_1_3 = (ctx->Extensions.ARB_texture_border_clamp &&
                              ctx->Extensions.ARB_texture_cube_map &&
                              ctx->Extensions.ARB_texture_env_combine &&
                              ctx->Extensions.ARB_texture_env_dot3);
   const GLboolean ver_1_4 = (ver_1_3 &&
                              ctx->Extensions.ARB_depth_texture &&
                              ctx->Extensions.ARB_shadow &&
                              ctx->Extensions.ARB_texture_env_crossbar &&
                              ctx->Extensions.ARB_window_pos &&
                              ctx->Extensions.EXT_blend_color &&
                              ctx->Extensions.EXT_blend_func_separate &&
                              ctx->Extensions.EXT_blend_minmax &&
                              ctx->Extensions.EXT_fog_coord &&
                              ctx->Extensions.EXT_point_parameters &&
                              ctx->Extensions.EXT_secondary_color);
   const GLboolean ver_1_5 = (ver_1_4 &&
                              ctx->Extensions.ARB_occlusion_query &&
                              ctx->Extensions.EXT_shadow_funcs);
   const GLboolean ver_2_0 = (ver_1_5 &&
                              ctx->Extensions.ARB_point_sprite &&
                              ctx->Extensions.ARB_shader_objects &&
                              ctx->Extensions.ARB_vertex_shader &&
                              ctx->Extensions.ARB_fragment_shader &&
                              ctx->Extensions.ARB_texture_non_power_of_two &&
                              ctx->Extensions.EXT_blend_equation_separate &&

			      /* Technically, 2.0 requires the functionality
			       * of the EXT version.  Enable 2.0 if either
			       * extension is available, and assume that a
			       * driver that only exposes the ATI extension
			       * will fallback to software when necessary.
			       */
			      (ctx->Extensions.EXT_stencil_two_side
			       || ctx->Extensions.ATI_separate_stencil));
   const GLboolean ver_2_1 = (ver_2_0 &&
                              ctx->Const.GLSLVersion >= 120 &&
                              ctx->Extensions.EXT_pixel_buffer_object &&
                              ctx->Extensions.EXT_texture_sRGB);
   const GLboolean ver_3_0 = (ver_2_1 &&
                              ctx->Const.GLSLVersion >= 130 &&
                              ctx->Const.MaxSamples >= 4 &&
                              ctx->Extensions.ARB_color_buffer_float &&
                              ctx->Extensions.ARB_depth_buffer_float &&
                              ctx->Extensions.ARB_half_float_pixel &&
                              ctx->Extensions.ARB_half_float_vertex &&
                              ctx->Extensions.ARB_map_buffer_range &&
                              ctx->Extensions.ARB_shader_texture_lod &&
                              ctx->Extensions.ARB_texture_float &&
                              ctx->Extensions.ARB_texture_rg &&
                              ctx->Extensions.ARB_texture_compression_rgtc &&
                              ctx->Extensions.APPLE_vertex_array_object &&
                              ctx->Extensions.EXT_draw_buffers2 &&
                              ctx->Extensions.ARB_framebuffer_object &&
                              ctx->Extensions.EXT_framebuffer_sRGB &&
                              ctx->Extensions.EXT_packed_float &&
                              ctx->Extensions.EXT_texture_array &&
                              ctx->Extensions.EXT_texture_shared_exponent &&
                              ctx->Extensions.EXT_transform_feedback &&
                              ctx->Extensions.NV_conditional_render);
   const GLboolean ver_3_1 = (ver_3_0 &&
                              ctx->Const.GLSLVersion >= 140 &&
                              ctx->Extensions.ARB_copy_buffer &&
                              ctx->Extensions.ARB_draw_instanced &&
                              ctx->Extensions.ARB_texture_buffer_object &&
                              ctx->Extensions.ARB_uniform_buffer_object &&
                              ctx->Extensions.EXT_texture_snorm &&
                              ctx->Extensions.NV_primitive_restart &&
                              ctx->Extensions.NV_texture_rectangle &&
                              ctx->Const.MaxVertexTextureImageUnits >= 16);
   const GLboolean ver_3_2 = (ver_3_1 &&
                              ctx->Const.GLSLVersion >= 150 &&
                              ctx->Extensions.ARB_depth_clamp &&
                              ctx->Extensions.ARB_draw_elements_base_vertex &&
                              ctx->Extensions.ARB_fragment_coord_conventions &&
                              ctx->Extensions.ARB_geometry_shader4 &&
                              ctx->Extensions.EXT_provoking_vertex &&
                              ctx->Extensions.ARB_seamless_cube_map &&
                              ctx->Extensions.ARB_sync &&
                              ctx->Extensions.ARB_texture_multisample &&
                              ctx->Extensions.EXT_vertex_array_bgra);
   const GLboolean ver_3_3 = (ver_3_2 &&
                              ctx->Const.GLSLVersion >= 330 &&
                              ctx->Extensions.ARB_blend_func_extended &&
                              ctx->Extensions.ARB_explicit_attrib_location &&
                              ctx->Extensions.ARB_instanced_arrays &&
                              ctx->Extensions.ARB_occlusion_query2 &&
                              ctx->Extensions.ARB_sampler_objects &&
                              ctx->Extensions.ARB_shader_bit_encoding &&
                              ctx->Extensions.ARB_texture_rgb10_a2ui &&
                              ctx->Extensions.ARB_timer_query &&
                              ctx->Extensions.ARB_vertex_type_2_10_10_10_rev &&
                              ctx->Extensions.EXT_texture_swizzle);

   if (ver_3_3) {
      major = 3;
      minor = 3;
   }
   else if (ver_3_2) {
      major = 3;
      minor = 2;
   }
   else if (ver_3_1) {
      major = 3;
      minor = 1;
   }
   else if (ver_3_0) {
      major = 3;
      minor = 0;
   }
   else if (ver_2_1) {
      major = 2;
      minor = 1;
   }
   else if (ver_2_0) {
      major = 2;
      minor = 0;
   }
   else if (ver_1_5) {
      major = 1;
      minor = 5;
   }
   else if (ver_1_4) {
      major = 1;
      minor = 4;
   }
   else if (ver_1_3) {
      major = 1;
      minor = 3;
   }
   else {
      major = 1;
      minor = 2;
   }

   ctx->VersionMajor = major;
   ctx->VersionMinor = minor;

   override_version(ctx, &ctx->VersionMajor, &ctx->VersionMinor);

   ctx->VersionString = (char *) malloc(max);
   if (ctx->VersionString) {
      _mesa_snprintf(ctx->VersionString, max,
		     "%u.%u Mesa " MESA_VERSION_STRING
#ifdef MESA_GIT_SHA1
		     " (" MESA_GIT_SHA1 ")"
#endif
		     ,
		     ctx->VersionMajor, ctx->VersionMinor);
   }
}
Пример #20
0
void GLAPIENTRY
_mesa_ProgramStringARB(GLenum target, GLenum format, GLsizei len,
                       const GLvoid *string)
{
   struct gl_program *base;
   bool failed;
   GET_CURRENT_CONTEXT(ctx);

   FLUSH_VERTICES(ctx, _NEW_PROGRAM);

   if (!ctx->Extensions.ARB_vertex_program
       && !ctx->Extensions.ARB_fragment_program) {
      _mesa_error(ctx, GL_INVALID_OPERATION, "glProgramStringARB()");
      return;
   }

   if (format != GL_PROGRAM_FORMAT_ASCII_ARB) {
      _mesa_error(ctx, GL_INVALID_ENUM, "glProgramStringARB(format)");
      return;
   }

   if (target == GL_VERTEX_PROGRAM_ARB && ctx->Extensions.ARB_vertex_program) {
      struct gl_vertex_program *prog = ctx->VertexProgram.Current;
      _mesa_parse_arb_vertex_program(ctx, target, string, len, prog);

      base = & prog->Base;
   }
   else if (target == GL_FRAGMENT_PROGRAM_ARB
            && ctx->Extensions.ARB_fragment_program) {
      struct gl_fragment_program *prog = ctx->FragmentProgram.Current;
      _mesa_parse_arb_fragment_program(ctx, target, string, len, prog);

      base = & prog->Base;
   }
   else {
      _mesa_error(ctx, GL_INVALID_ENUM, "glProgramStringARB(target)");
      return;
   }

   failed = ctx->Program.ErrorPos != -1;

   if (!failed) {
      /* finally, give the program to the driver for translation/checking */
      if (!ctx->Driver.ProgramStringNotify(ctx, target, base)) {
         failed = true;
         _mesa_error(ctx, GL_INVALID_OPERATION,
                     "glProgramStringARB(rejected by driver");
      }
   }

   if (ctx->_Shader->Flags & GLSL_DUMP) {
      const char *shader_type =
         target == GL_FRAGMENT_PROGRAM_ARB ? "fragment" : "vertex";

      fprintf(stderr, "ARB_%s_program source for program %d:\n",
              shader_type, base->Id);
      fprintf(stderr, "%s\n", (const char *) string);

      if (failed) {
         fprintf(stderr, "ARB_%s_program %d failed to compile.\n",
                 shader_type, base->Id);
      } else {
         fprintf(stderr, "Mesa IR for ARB_%s_program %d:\n",
                 shader_type, base->Id);
         _mesa_print_program(base);
         fprintf(stderr, "\n");
      }
      fflush(stderr);
   }

   /* Capture vp-*.shader_test/fp-*.shader_test files. */
   const char *capture_path = _mesa_get_shader_capture_path();
   if (capture_path != NULL) {
      FILE *file;
      char filename[PATH_MAX];
      const char *shader_type =
         target == GL_FRAGMENT_PROGRAM_ARB ? "fragment" : "vertex";

      _mesa_snprintf(filename, sizeof(filename), "%s/%cp-%u.shader_test",
                     capture_path, shader_type[0], base->Id);
      file = fopen(filename, "w");
      if (file) {
         fprintf(file,
                 "[require]\nGL_ARB_%s_program\n\n[%s program]\n%s\n",
                 shader_type, shader_type, (const char *) string);
         fclose(file);
      } else {
         _mesa_warning(ctx, "Failed to open %s", filename);
      }
   }
}