示例#1
0
/*
 * Called whenever we find an error during parsing.
 */
static void
record_error(struct parse_state *parseState, const char *msg, int lineNo)
{
#ifdef DEBUG
   GLint line, column;
   const GLubyte *lineStr;
   lineStr = _mesa_find_line_column(parseState->start,
                                    parseState->pos, &line, &column);
   _mesa_debug(parseState->ctx,
               "nvfragparse.c(%d): line %d, column %d:%s (%s)\n",
               lineNo, line, column, (char *) lineStr, msg);
   _mesa_free((void *) lineStr);
#else
   (void) lineNo;
#endif

   /* Check that no error was already recorded.  Only record the first one. */
   if (parseState->ctx->Program.ErrorString[0] == 0) {
      _mesa_set_program_error(parseState->ctx,
                              parseState->pos - parseState->start,
                              msg);
   }
}
示例#2
0
/**
 * Parse/compile the 'str' returning the compiled 'program'.
 * ctx->Program.ErrorPos will be -1 if successful.  Otherwise, ErrorPos
 * indicates the position of the error in 'str'.
 */
void
_mesa_parse_nv_vertex_program(GLcontext *ctx, GLenum dstTarget,
                              const GLubyte *str, GLsizei len,
                              struct vertex_program *program)
{
   struct parse_state parseState;
   struct vp_instruction instBuffer[MAX_NV_VERTEX_PROGRAM_INSTRUCTIONS];
   struct vp_instruction *newInst;
   GLenum target;
   GLubyte *programString;

   /* Make a null-terminated copy of the program string */
   programString = (GLubyte *) MALLOC(len + 1);
   if (!programString) {
      _mesa_error(ctx, GL_OUT_OF_MEMORY, "glLoadProgramNV");
      return;
   }
   MEMCPY(programString, str, len);
   programString[len] = 0;

   /* Get ready to parse */
   parseState.ctx = ctx;
   parseState.start = programString;
   parseState.isPositionInvariant = GL_FALSE;
   parseState.isVersion1_1 = GL_FALSE;
   parseState.numInst = 0;
   parseState.inputsRead = 0;
   parseState.outputsWritten = 0;
   parseState.anyProgRegsWritten = GL_FALSE;

   /* Reset error state */
   _mesa_set_program_error(ctx, -1, NULL);

   /* check the program header */
   if (_mesa_strncmp((const char *) programString, "!!VP1.0", 7) == 0) {
      target = GL_VERTEX_PROGRAM_NV;
      parseState.pos = programString + 7;
      parseState.isStateProgram = GL_FALSE;
   }
   else if (_mesa_strncmp((const char *) programString, "!!VP1.1", 7) == 0) {
      target = GL_VERTEX_PROGRAM_NV;
      parseState.pos = programString + 7;
      parseState.isStateProgram = GL_FALSE;
      parseState.isVersion1_1 = GL_TRUE;
   }
   else if (_mesa_strncmp((const char *) programString, "!!VSP1.0", 8) == 0) {
      target = GL_VERTEX_STATE_PROGRAM_NV;
      parseState.pos = programString + 8;
      parseState.isStateProgram = GL_TRUE;
   }
   else {
      /* invalid header */
      ctx->Program.ErrorPos = 0;
      _mesa_error(ctx, GL_INVALID_OPERATION, "glLoadProgramNV(bad header)");
      return;
   }

   /* make sure target and header match */
   if (target != dstTarget) {
      _mesa_error(ctx, GL_INVALID_OPERATION,
                  "glLoadProgramNV(target mismatch)");
      return;
   }


   if (Parse_Program(&parseState, instBuffer)) {
      /* successful parse! */

      if (parseState.isStateProgram) {
         if (!parseState.anyProgRegsWritten) {
            _mesa_error(ctx, GL_INVALID_OPERATION,
                        "glLoadProgramNV(c[#] not written)");
            return;
         }
      }
      else {
         if (!parseState.isPositionInvariant &&
             !(parseState.outputsWritten & 1)) {
            /* bit 1 = HPOS register */
            _mesa_error(ctx, GL_INVALID_OPERATION,
                        "glLoadProgramNV(HPOS not written)");
            return;
         }
      }

      /* copy the compiled instructions */
      assert(parseState.numInst <= MAX_NV_VERTEX_PROGRAM_INSTRUCTIONS);
      newInst = (struct vp_instruction *)
         MALLOC(parseState.numInst * sizeof(struct vp_instruction));
      if (!newInst) {
         _mesa_error(ctx, GL_OUT_OF_MEMORY, "glLoadProgramNV");
         FREE(programString);
         return;  /* out of memory */
      }
      MEMCPY(newInst, instBuffer,
             parseState.numInst * sizeof(struct vp_instruction));

      /* install the program */
      program->Base.Target = target;
      if (program->Base.String) {
         FREE(program->Base.String);
      }
      program->Base.String = programString;
      program->Base.Format = GL_PROGRAM_FORMAT_ASCII_ARB;
      if (program->Instructions) {
         FREE(program->Instructions);
      }
      program->Instructions = newInst;
      program->InputsRead = parseState.inputsRead;
      program->OutputsWritten = parseState.outputsWritten;
      program->IsPositionInvariant = parseState.isPositionInvariant;
      program->IsNVProgram = GL_TRUE;

#ifdef DEBUG_foo
      _mesa_printf("--- glLoadProgramNV result ---\n");
      _mesa_print_nv_vertex_program(program);
      _mesa_printf("------------------------------\n");
#endif
   }
   else {
      /* Error! */
      _mesa_error(ctx, GL_INVALID_OPERATION, "glLoadProgramNV");
      /* NOTE: _mesa_set_program_error would have been called already */
      /* GL_NV_vertex_program isn't supposed to set the error string
       * so we reset it here.
       */
      _mesa_set_program_error(ctx, ctx->Program.ErrorPos, NULL);
   }
}
示例#3
0
/**
 * Parse/compile the 'str' returning the compiled 'program'.
 * ctx->Program.ErrorPos will be -1 if successful.  Otherwise, ErrorPos
 * indicates the position of the error in 'str'.
 */
void
_mesa_parse_nv_fragment_program(struct gl_context *ctx, GLenum dstTarget,
                                const GLubyte *str, GLsizei len,
                                struct gl_fragment_program *program)
{
   struct parse_state parseState;
   struct prog_instruction instBuffer[MAX_NV_FRAGMENT_PROGRAM_INSTRUCTIONS];
   struct prog_instruction *newInst;
   GLenum target;
   GLubyte *programString;

   /* Make a null-terminated copy of the program string */
   programString = (GLubyte *) MALLOC(len + 1);
   if (!programString) {
      _mesa_error(ctx, GL_OUT_OF_MEMORY, "glLoadProgramNV");
      return;
   }
   memcpy(programString, str, len);
   programString[len] = 0;

   /* Get ready to parse */
   memset(&parseState, 0, sizeof(struct parse_state));
   parseState.ctx = ctx;
   parseState.start = programString;
   parseState.program = program;
   parseState.numInst = 0;
   parseState.curLine = programString;
   parseState.parameters = _mesa_new_parameter_list();

   /* Reset error state */
   _mesa_set_program_error(ctx, -1, NULL);

   /* check the program header */
   if (strncmp((const char *) programString, "!!FP1.0", 7) == 0) {
      target = GL_FRAGMENT_PROGRAM_NV;
      parseState.pos = programString + 7;
   }
   else if (strncmp((const char *) programString, "!!FCP1.0", 8) == 0) {
      /* fragment / register combiner program - not supported */
      _mesa_set_program_error(ctx, 0, "Invalid fragment program header");
      _mesa_error(ctx, GL_INVALID_OPERATION, "glLoadProgramNV(bad header)");
      return;
   }
   else {
      /* invalid header */
      _mesa_set_program_error(ctx, 0, "Invalid fragment program header");
      _mesa_error(ctx, GL_INVALID_OPERATION, "glLoadProgramNV(bad header)");
      return;
   }

   /* make sure target and header match */
   if (target != dstTarget) {
      _mesa_error(ctx, GL_INVALID_OPERATION,
                  "glLoadProgramNV(target mismatch 0x%x != 0x%x)",
                  target, dstTarget);
      return;
   }

   if (Parse_InstructionSequence(&parseState, instBuffer)) {
      GLuint u;
      /* successful parse! */

      if (parseState.outputsWritten == 0) {
         /* must write at least one output! */
         _mesa_error(ctx, GL_INVALID_OPERATION,
                     "Invalid fragment program - no outputs written.");
         return;
      }

      /* copy the compiled instructions */
      assert(parseState.numInst <= MAX_NV_FRAGMENT_PROGRAM_INSTRUCTIONS);
      newInst = _mesa_alloc_instructions(parseState.numInst);
      if (!newInst) {
         _mesa_error(ctx, GL_OUT_OF_MEMORY, "glLoadProgramNV");
         return;  /* out of memory */
      }
      _mesa_copy_instructions(newInst, instBuffer, parseState.numInst);

      /* install the program */
      program->Base.Target = target;
      if (program->Base.String) {
         FREE(program->Base.String);
      }
      program->Base.String = programString;
      program->Base.Format = GL_PROGRAM_FORMAT_ASCII_ARB;
      if (program->Base.Instructions) {
         free(program->Base.Instructions);
      }
      program->Base.Instructions = newInst;
      program->Base.NumInstructions = parseState.numInst;
      program->Base.InputsRead = parseState.inputsRead;
      program->Base.OutputsWritten = parseState.outputsWritten;
      for (u = 0; u < ctx->Const.MaxTextureImageUnits; u++)
         program->Base.TexturesUsed[u] = parseState.texturesUsed[u];

      /* save program parameters */
      program->Base.Parameters = parseState.parameters;

      /* allocate registers for declared program parameters */
#if 00
      _mesa_assign_program_registers(&(program->SymbolTable));
#endif

#ifdef DEBUG_foo
      printf("--- glLoadProgramNV(%d) result ---\n", program->Base.Id);
      _mesa_fprint_program_opt(stdout, &program->Base, PROG_PRINT_NV, 0);
      printf("----------------------------------\n");
#endif
   }
   else {
      /* Error! */
      _mesa_error(ctx, GL_INVALID_OPERATION, "glLoadProgramNV");
      /* NOTE: _mesa_set_program_error would have been called already */
   }
}