Beispiel #1
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;
      const char *shader_type =
         target == GL_FRAGMENT_PROGRAM_ARB ? "fragment" : "vertex";
      char *filename =
         ralloc_asprintf(NULL, "%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);
      }
      ralloc_free(filename);
   }
}
Beispiel #2
0
/**
 * Load/parse/compile a program.
 * \note Called from the GL API dispatcher.
 */
void GLAPIENTRY
_mesa_LoadProgramNV(GLenum target, GLuint id, GLsizei len,
                    const GLubyte *program)
{
   struct gl_program *prog;
   GET_CURRENT_CONTEXT(ctx);
   ASSERT_OUTSIDE_BEGIN_END(ctx);

   if (!ctx->Extensions.NV_vertex_program
       && !ctx->Extensions.NV_fragment_program) {
      _mesa_error(ctx, GL_INVALID_OPERATION, "glLoadProgramNV()");
      return;
   }

   if (id == 0) {
      _mesa_error(ctx, GL_INVALID_VALUE, "glLoadProgramNV(id)");
      return;
   }

   if (len < 0) {
      _mesa_error(ctx, GL_INVALID_VALUE, "glLoadProgramNV(len)");
      return;
   }

   FLUSH_VERTICES(ctx, _NEW_PROGRAM);

   prog = _mesa_lookup_program(ctx, id);

   if (prog && prog->Target != 0 && prog->Target != target) {
      _mesa_error(ctx, GL_INVALID_OPERATION, "glLoadProgramNV(target)");
      return;
   }

   if ((target == GL_VERTEX_PROGRAM_NV ||
        target == GL_VERTEX_STATE_PROGRAM_NV)
       && ctx->Extensions.NV_vertex_program) {
      struct gl_vertex_program *vprog = (struct gl_vertex_program *) prog;
      if (!vprog || prog == &_mesa_DummyProgram) {
         vprog = (struct gl_vertex_program *)
            ctx->Driver.NewProgram(ctx, target, id);
         if (!vprog) {
            _mesa_error(ctx, GL_OUT_OF_MEMORY, "glLoadProgramNV");
            return;
         }
         _mesa_HashInsert(ctx->Shared->Programs, id, vprog);
      }

      if (ctx->Extensions.ARB_vertex_program
	  && (strncmp((char *) program, "!!ARB", 5) == 0)) {
	 _mesa_parse_arb_vertex_program(ctx, target, program, len, vprog);
      } else {
	 _mesa_parse_nv_vertex_program(ctx, target, program, len, vprog);
      }
   }
   else if (target == GL_FRAGMENT_PROGRAM_NV
            && ctx->Extensions.NV_fragment_program) {
      struct gl_fragment_program *fprog = (struct gl_fragment_program *) prog;
      if (!fprog || prog == &_mesa_DummyProgram) {
         fprog = (struct gl_fragment_program *)
            ctx->Driver.NewProgram(ctx, target, id);
         if (!fprog) {
            _mesa_error(ctx, GL_OUT_OF_MEMORY, "glLoadProgramNV");
            return;
         }
         _mesa_HashInsert(ctx->Shared->Programs, id, fprog);
      }
      _mesa_parse_nv_fragment_program(ctx, target, program, len, fprog);
   }
   else if (target == GL_FRAGMENT_PROGRAM_ARB
            && ctx->Extensions.ARB_fragment_program) {
      struct gl_fragment_program *fprog = (struct gl_fragment_program *) prog;
      if (!fprog || prog == &_mesa_DummyProgram) {
         fprog = (struct gl_fragment_program *)
            ctx->Driver.NewProgram(ctx, target, id);
         if (!fprog) {
            _mesa_error(ctx, GL_OUT_OF_MEMORY, "glLoadProgramNV");
            return;
         }
         _mesa_HashInsert(ctx->Shared->Programs, id, fprog);
      }
      _mesa_parse_arb_fragment_program(ctx, target, program, len, fprog);
   }
   else {
      _mesa_error(ctx, GL_INVALID_ENUM, "glLoadProgramNV(target)");
   }
}