⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 nvvertparse.c

📁 Mesa is an open-source implementation of the OpenGL specification - a system for rendering interacti
💻 C
📖 第 1 页 / 共 3 页
字号:
   inst->Data = msg;   /* comma */   if (Parse_String(parseState, ",")) {      /* The second argument is a register name */      if (!Peek_Token(parseState, token))         RETURN_ERROR;      srcReg->RelAddr = GL_FALSE;      srcReg->NegateBase = NEGATE_NONE;      srcReg->Swizzle = SWIZZLE_NOOP;      /* Register can be R<n>, c[n], c[n +/- offset], a named vertex attrib,       * or an o[n] output register.       */      if (token[0] == 'R') {         srcReg->File = PROGRAM_TEMPORARY;         if (!Parse_TempReg(parseState, &idx))            RETURN_ERROR;	 srcReg->Index = idx;      }      else if (token[0] == 'c') {         srcReg->File = PROGRAM_ENV_PARAM;         if (!Parse_ParamReg(parseState, srcReg))            RETURN_ERROR;      }      else if (token[0] == 'v') {         srcReg->File = PROGRAM_INPUT;         if (!Parse_AttribReg(parseState, &idx))            RETURN_ERROR;	 srcReg->Index = idx;      }      else if (token[0] == 'o') {         srcReg->File = PROGRAM_OUTPUT;         if (!Parse_OutputReg(parseState, &idx))            RETURN_ERROR;	 srcReg->Index = idx;      }      else {         RETURN_ERROR2("Bad source register name", token);      }   }   else {      srcReg->File = 0;   }   /* semicolon */   if (!Parse_String(parseState, ";"))      RETURN_ERROR;   return GL_TRUE;}static GLbooleanParse_OptionSequence(struct parse_state *parseState,                     struct prog_instruction program[]){   (void) program;   while (1) {      if (!Parse_String(parseState, "OPTION"))         return GL_TRUE;  /* ok, not an OPTION statement */      if (Parse_String(parseState, "NV_position_invariant")) {         parseState->isPositionInvariant = GL_TRUE;      }      else {         RETURN_ERROR1("unexpected OPTION statement");      }      if (!Parse_String(parseState, ";"))         return GL_FALSE;   }}static GLbooleanParse_InstructionSequence(struct parse_state *parseState,                          struct prog_instruction program[]){   while (1) {      struct prog_instruction *inst = program + parseState->numInst;      /* Initialize the instruction */      _mesa_init_instructions(inst, 1);      if (Parse_String(parseState, "MOV")) {         if (!Parse_UnaryOpInstruction(parseState, inst, OPCODE_MOV))            RETURN_ERROR;      }      else if (Parse_String(parseState, "LIT")) {         if (!Parse_UnaryOpInstruction(parseState, inst, OPCODE_LIT))            RETURN_ERROR;      }      else if (Parse_String(parseState, "ABS")) {         if (!Parse_UnaryOpInstruction(parseState, inst, OPCODE_ABS))            RETURN_ERROR;      }      else if (Parse_String(parseState, "MUL")) {         if (!Parse_BiOpInstruction(parseState, inst, OPCODE_MUL))            RETURN_ERROR;      }      else if (Parse_String(parseState, "ADD")) {         if (!Parse_BiOpInstruction(parseState, inst, OPCODE_ADD))            RETURN_ERROR;      }      else if (Parse_String(parseState, "DP3")) {         if (!Parse_BiOpInstruction(parseState, inst, OPCODE_DP3))            RETURN_ERROR;      }      else if (Parse_String(parseState, "DP4")) {         if (!Parse_BiOpInstruction(parseState, inst, OPCODE_DP4))            RETURN_ERROR;      }      else if (Parse_String(parseState, "DST")) {         if (!Parse_BiOpInstruction(parseState, inst, OPCODE_DST))            RETURN_ERROR;      }      else if (Parse_String(parseState, "MIN")) {         if (!Parse_BiOpInstruction(parseState, inst, OPCODE_MIN))            RETURN_ERROR;      }      else if (Parse_String(parseState, "MAX")) {         if (!Parse_BiOpInstruction(parseState, inst, OPCODE_MAX))            RETURN_ERROR;      }      else if (Parse_String(parseState, "SLT")) {         if (!Parse_BiOpInstruction(parseState, inst, OPCODE_SLT))            RETURN_ERROR;      }      else if (Parse_String(parseState, "SGE")) {         if (!Parse_BiOpInstruction(parseState, inst, OPCODE_SGE))            RETURN_ERROR;      }      else if (Parse_String(parseState, "DPH")) {         if (!Parse_BiOpInstruction(parseState, inst, OPCODE_DPH))            RETURN_ERROR;      }      else if (Parse_String(parseState, "SUB")) {         if (!Parse_BiOpInstruction(parseState, inst, OPCODE_SUB))            RETURN_ERROR;      }      else if (Parse_String(parseState, "MAD")) {         if (!Parse_TriOpInstruction(parseState, inst, OPCODE_MAD))            RETURN_ERROR;      }      else if (Parse_String(parseState, "RCP")) {         if (!Parse_ScalarInstruction(parseState, inst, OPCODE_RCP))            RETURN_ERROR;      }      else if (Parse_String(parseState, "RSQ")) {         if (!Parse_ScalarInstruction(parseState, inst, OPCODE_RSQ))            RETURN_ERROR;      }      else if (Parse_String(parseState, "EXP")) {         if (!Parse_ScalarInstruction(parseState, inst, OPCODE_EXP))            RETURN_ERROR;      }      else if (Parse_String(parseState, "LOG")) {         if (!Parse_ScalarInstruction(parseState, inst, OPCODE_LOG))            RETURN_ERROR;      }      else if (Parse_String(parseState, "RCC")) {         if (!Parse_ScalarInstruction(parseState, inst, OPCODE_RCC))            RETURN_ERROR;      }      else if (Parse_String(parseState, "ARL")) {         if (!Parse_AddressInstruction(parseState, inst))            RETURN_ERROR;      }      else if (Parse_String(parseState, "PRINT")) {         if (!Parse_PrintInstruction(parseState, inst))            RETURN_ERROR;      }      else if (Parse_String(parseState, "END")) {         if (!Parse_EndInstruction(parseState, inst))            RETURN_ERROR;         else {            parseState->numInst++;            return GL_TRUE;  /* all done */         }      }      else {         /* bad instruction name */         RETURN_ERROR1("Unexpected token");      }      /* examine input/output registers */      if (inst->DstReg.File == PROGRAM_OUTPUT)         parseState->outputsWritten |= (1 << inst->DstReg.Index);      else if (inst->DstReg.File == PROGRAM_ENV_PARAM)         parseState->anyProgRegsWritten = GL_TRUE;      if (inst->SrcReg[0].File == PROGRAM_INPUT)         parseState->inputsRead |= (1 << inst->SrcReg[0].Index);      if (inst->SrcReg[1].File == PROGRAM_INPUT)         parseState->inputsRead |= (1 << inst->SrcReg[1].Index);      if (inst->SrcReg[2].File == PROGRAM_INPUT)         parseState->inputsRead |= (1 << inst->SrcReg[2].Index);      parseState->numInst++;      if (parseState->numInst >= MAX_NV_VERTEX_PROGRAM_INSTRUCTIONS)         RETURN_ERROR1("Program too long");   }   RETURN_ERROR;}static GLbooleanParse_Program(struct parse_state *parseState,              struct prog_instruction instBuffer[]){   if (parseState->isVersion1_1) {      if (!Parse_OptionSequence(parseState, instBuffer)) {         return GL_FALSE;      }   }   return Parse_InstructionSequence(parseState, instBuffer);}/** * 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 gl_vertex_program *program){   struct parse_state parseState;   struct prog_instruction instBuffer[MAX_NV_VERTEX_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 */   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 << VERT_RESULT_HPOS))) {            /* 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 = _mesa_alloc_instructions(parseState.numInst);      if (!newInst) {         _mesa_error(ctx, GL_OUT_OF_MEMORY, "glLoadProgramNV");         _mesa_free(programString);         return;  /* out of memory */      }      _mesa_copy_instructions(newInst, instBuffer, parseState.numInst);      /* install the program */      program->Base.Target = target;      if (program->Base.String) {         _mesa_free(program->Base.String);      }      program->Base.String = programString;      program->Base.Format = GL_PROGRAM_FORMAT_ASCII_ARB;      if (program->Base.Instructions) {         _mesa_free(program->Base.Instructions);      }      program->Base.Instructions = newInst;      program->Base.InputsRead = parseState.inputsRead;      if (parseState.isPositionInvariant)         program->Base.InputsRead |= VERT_BIT_POS;      program->Base.NumInstructions = parseState.numInst;      program->Base.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);   }}static voidPrintSrcReg(const struct prog_src_register *src){   static const char comps[5] = "xyzw";   if (src->NegateBase)      _mesa_printf("-");   if (src->RelAddr) {      if (src->Index > 0)         _mesa_printf("c[A0.x + %d]", src->Index);      else if (src->Index < 0)         _mesa_printf("c[A0.x - %d]", -src->Index);      else         _mesa_printf("c[A0.x]");   }   else if (src->File == PROGRAM_OUTPUT) {      _mesa_printf("o[%s]", OutputRegisters[src->Index]);   }   else if (src->File == PROGRAM_INPUT) {      _mesa_printf("v[%s]", InputRegisters[src->Index]);   }   else if (src->File == PROGRAM_ENV_PARAM) {      _mesa_printf("c[%d]", src->Index);   }   else {      ASSERT(src->File == PROGRAM_TEMPORARY);      _mesa_printf("R%d", src->Index);   }   if (GET_SWZ(src->Swizzle, 0) == GET_SWZ(src->Swizzle, 1) &&       GET_SWZ(src->Swizzle, 0) == GET_SWZ(src->Swizzle, 2) &&       GET_SWZ(src->Swizzle, 0) == GET_SWZ(src->Swizzle, 3)) {      _mesa_printf(".%c", comps[GET_SWZ(src->Swizzle, 0)]);   }   else if (src->Swizzle != SWIZZLE_NOOP) {      _mesa_printf(".%c%c%c%c",             comps[GET_SWZ(src->Swizzle, 0)],             comps[GET_SWZ(src->Swizzle, 1)],             comps[GET_SWZ(src->Swizzle, 2)],             comps[GET_SWZ(src->Swizzle, 3)]);   }}static voidPrintDstReg(const struct prog_dst_register *dst){   if (dst->File == PROGRAM_OUTPUT) {      _mesa_printf("o[%s]", OutputRegisters[dst->Index]);   }   else if (dst->File == PROGRAM_INPUT) {      _mesa_printf("v[%s]", InputRegisters[dst->Index]);   }   else if (dst->File == PROGRAM_ENV_PARAM) {      _mesa_printf("c[%d]", dst->Index);   }   else {      ASSERT(dst->File == PROGRAM_TEMPORARY);      _mesa_printf("R%d", dst->Index);   }   if (dst->WriteMask != 0 && dst->WriteMask != WRITEMASK_XYZW) {      _mesa_printf(".");      if (dst->WriteMask & WRITEMASK_X)         _mesa_printf("x");      if (dst->WriteMask & WRITEMASK_Y)         _mesa_printf("y");      if (dst->WriteMask & WRITEMASK_Z)         _mesa_printf("z");      if (dst->WriteMask & WRITEMASK_W)         _mesa_printf("w");   }}/** * Print a single NVIDIA vertex program instruction. */void_mesa_print_nv_vertex_instruction(const struct prog_instruction *inst){   GLuint i, n;   switch (inst->Opcode) {      case OPCODE_MOV:      case OPCODE_LIT:      case OPCODE_RCP:      case OPCODE_RSQ:      case OPCODE_EXP:      case OPCODE_LOG:      case OPCODE_RCC:      case OPCODE_ABS:      case OPCODE_MUL:      case OPCODE_ADD:      case OPCODE_DP3:      case OPCODE_DP4:      case OPCODE_DST:      case OPCODE_MIN:      case OPCODE_MAX:      case OPCODE_SLT:      case OPCODE_SGE:      case OPCODE_DPH:      case OPCODE_SUB:      case OPCODE_MAD:         _mesa_printf("%s ", _mesa_opcode_string(inst->Opcode));         PrintDstReg(&inst->DstReg);         _mesa_printf(", ");         n = _mesa_num_inst_src_regs(inst->Opcode);         for (i = 0; i < n; i++) {            PrintSrcReg(&inst->SrcReg[i]);            if (i + 1 < n)               _mesa_printf(", ");         }         _mesa_printf(";\n");         break;      case OPCODE_ARL:         _mesa_printf("ARL A0.x, ");         PrintSrcReg(&inst->SrcReg[0]);         _mesa_printf(";\n");         break;      case OPCODE_PRINT:         _mesa_printf("PRINT '%s'", inst->Data);         if (inst->SrcReg[0].File != PROGRAM_UNDEFINED) {            _mesa_printf(", ");            PrintSrcReg(&inst->SrcReg[0]);            _mesa_printf(";\n");         }         else {            _mesa_printf("\n");         }         break;      case OPCODE_END:         _mesa_printf("END\n");         break;      default:         _mesa_printf("BAD INSTRUCTION\n");   }}/** * Print (unparse) the given vertex program.  Just for debugging. */void_mesa_print_nv_vertex_program(const struct gl_vertex_program *program){   const struct prog_instruction *inst;   for (inst = program->Base.Instructions; ; inst++) {      _mesa_print_nv_vertex_instruction(inst);      if (inst->Opcode == OPCODE_END)         return;   }}const char *_mesa_nv_vertex_input_register_name(GLuint i){   ASSERT(i < MAX_NV_VERTEX_PROGRAM_INPUTS);   return InputRegisters[i];}const char *_mesa_nv_vertex_output_register_name(GLuint i){   ASSERT(i < MAX_NV_VERTEX_PROGRAM_OUTPUTS);   return OutputRegisters[i];}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -