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

📄 nvvertparse.c

📁 winNT技术操作系统,国外开放的原代码和LIUX一样
💻 C
📖 第 1 页 / 共 3 页
字号:
   if (!Parse_Token(parseState, token))
      RETURN_ERROR;

   if (parseState->isPositionInvariant)
      start = 1; /* skip HPOS register name */
   else
      start = 0;

   /* try to match an output register name */
   for (j = start; OutputRegisters[j]; j++) {
      if (_mesa_strcmp((const char *) token, OutputRegisters[j]) == 0) {
         *outputRegNum = j;
         break;
      }
   }
   if (!OutputRegisters[j])
      RETURN_ERROR1("Unrecognized output register name");

   /* Match ']' */
   if (!Parse_String(parseState, "]"))
      RETURN_ERROR1("Expected ]");

   return GL_TRUE;
}


static GLboolean
Parse_MaskedDstReg(struct parse_state *parseState, struct vp_dst_register *dstReg)
{
   GLubyte token[100];
   GLint idx;

   /* Dst reg can be R<n> or o[n] */
   if (!Peek_Token(parseState, token))
      RETURN_ERROR;

   if (token[0] == 'R') {
      /* a temporary register */
      dstReg->File = PROGRAM_TEMPORARY;
      if (!Parse_TempReg(parseState, &idx))
         RETURN_ERROR;
      dstReg->Index = idx;
   }
   else if (!parseState->isStateProgram && token[0] == 'o') {
      /* an output register */
      dstReg->File = PROGRAM_OUTPUT;
      if (!Parse_OutputReg(parseState, &idx))
         RETURN_ERROR;
      dstReg->Index = idx;
   }
   else if (parseState->isStateProgram && token[0] == 'c' &&
            parseState->isStateProgram) {
      /* absolute program parameter register */
      /* Only valid for vertex state programs */
      dstReg->File = PROGRAM_ENV_PARAM;
      if (!Parse_AbsParamReg(parseState, &idx))
         RETURN_ERROR;
      dstReg->Index = idx;
   }
   else {
      RETURN_ERROR1("Bad destination register name");
   }

   /* Parse optional write mask */
   if (!Peek_Token(parseState, token))
      RETURN_ERROR;

   if (token[0] == '.') {
      /* got a mask */
      GLint k = 0;

      if (!Parse_String(parseState, "."))
         RETURN_ERROR;

      if (!Parse_Token(parseState, token))
         RETURN_ERROR;

      dstReg->WriteMask = 0;

      if (token[k] == 'x') {
         dstReg->WriteMask |= WRITEMASK_X;
         k++;
      }
      if (token[k] == 'y') {
         dstReg->WriteMask |= WRITEMASK_Y;
         k++;
      }
      if (token[k] == 'z') {
         dstReg->WriteMask |= WRITEMASK_Z;
         k++;
      }
      if (token[k] == 'w') {
         dstReg->WriteMask |= WRITEMASK_W;
         k++;
      }
      if (k == 0) {
         RETURN_ERROR1("Bad writemask character");
      }
      return GL_TRUE;
   }
   else {
      dstReg->WriteMask = WRITEMASK_XYZW;
      return GL_TRUE;
   }
}


static GLboolean
Parse_SwizzleSrcReg(struct parse_state *parseState, struct vp_src_register *srcReg)
{
   GLubyte token[100];
   GLint idx;

   srcReg->RelAddr = GL_FALSE;

   /* check for '-' */
   if (!Peek_Token(parseState, token))
      RETURN_ERROR;
   if (token[0] == '-') {
      (void) Parse_String(parseState, "-");
      srcReg->Negate = GL_TRUE;
      if (!Peek_Token(parseState, token))
         RETURN_ERROR;
   }
   else {
      srcReg->Negate = GL_FALSE;
   }

   /* Src reg can be R<n>, c[n], c[n +/- offset], or a named vertex attrib */
   if (token[0] == 'R') {
      srcReg->File = PROGRAM_TEMPORARY;
      if (!Parse_TempReg(parseState, &idx))
         RETURN_ERROR;
      srcReg->Index = idx;
   }
   else if (token[0] == 'c') {
      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 {
      RETURN_ERROR2("Bad source register name", token);
   }

   /* init swizzle fields */
   srcReg->Swizzle = SWIZZLE_NOOP;

   /* Look for optional swizzle suffix */
   if (!Peek_Token(parseState, token))
      RETURN_ERROR;
   if (token[0] == '.') {
      (void) Parse_String(parseState, ".");  /* consume . */

      if (!Parse_Token(parseState, token))
         RETURN_ERROR;

      if (token[1] == 0) {
         /* single letter swizzle */
         if (token[0] == 'x')
            srcReg->Swizzle = MAKE_SWIZZLE4(0, 0, 0, 0);
         else if (token[0] == 'y')
            srcReg->Swizzle = MAKE_SWIZZLE4(1, 1, 1, 1);
         else if (token[0] == 'z')
            srcReg->Swizzle = MAKE_SWIZZLE4(2, 2, 2, 2);
         else if (token[0] == 'w')
            srcReg->Swizzle = MAKE_SWIZZLE4(3, 3, 3, 3);
         else
            RETURN_ERROR1("Expected x, y, z, or w");
      }
      else {
         /* 2, 3 or 4-component swizzle */
         GLint k;
         for (k = 0; token[k] && k < 5; k++) {
            if (token[k] == 'x')
               srcReg->Swizzle |= 0 << (k*3);
            else if (token[k] == 'y')
               srcReg->Swizzle |= 1 << (k*3);
            else if (token[k] == 'z')
               srcReg->Swizzle |= 2 << (k*3);
            else if (token[k] == 'w')
               srcReg->Swizzle |= 3 << (k*3);
            else
               RETURN_ERROR;
         }
         if (k >= 5)
            RETURN_ERROR;
      }
   }

   return GL_TRUE;
}


static GLboolean
Parse_ScalarSrcReg(struct parse_state *parseState, struct vp_src_register *srcReg)
{
   GLubyte token[100];
   GLint idx;

   srcReg->RelAddr = GL_FALSE;

   /* check for '-' */
   if (!Peek_Token(parseState, token))
      RETURN_ERROR;
   if (token[0] == '-') {
      srcReg->Negate = GL_TRUE;
      (void) Parse_String(parseState, "-"); /* consume '-' */
      if (!Peek_Token(parseState, token))
         RETURN_ERROR;
   }
   else {
      srcReg->Negate = GL_FALSE;
   }

   /* Src reg can be R<n>, c[n], c[n +/- offset], or a named vertex attrib */
   if (token[0] == 'R') {
      srcReg->File = PROGRAM_TEMPORARY;
      if (!Parse_TempReg(parseState, &idx))
         RETURN_ERROR;
      srcReg->Index = idx;
   }
   else if (token[0] == 'c') {
      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 {
      RETURN_ERROR2("Bad source register name", token);
   }

   /* Look for .[xyzw] suffix */
   if (!Parse_String(parseState, "."))
      RETURN_ERROR;

   if (!Parse_Token(parseState, token))
      RETURN_ERROR;

   if (token[0] == 'x' && token[1] == 0) {
      srcReg->Swizzle = 0;
   }
   else if (token[0] == 'y' && token[1] == 0) {
      srcReg->Swizzle = 1;
   }
   else if (token[0] == 'z' && token[1] == 0) {
      srcReg->Swizzle = 2;
   }
   else if (token[0] == 'w' && token[1] == 0) {
      srcReg->Swizzle = 3;
   }
   else {
      RETURN_ERROR1("Bad scalar source suffix");
   }

   return GL_TRUE;
}


static GLint
Parse_UnaryOpInstruction(struct parse_state *parseState,
                         struct vp_instruction *inst, enum vp_opcode opcode)
{
   if (opcode == VP_OPCODE_ABS && !parseState->isVersion1_1)
      RETURN_ERROR1("ABS illegal for vertex program 1.0");

   inst->Opcode = opcode;
   inst->StringPos = parseState->curLine - parseState->start;

   /* dest reg */
   if (!Parse_MaskedDstReg(parseState, &inst->DstReg))
      RETURN_ERROR;

   /* comma */
   if (!Parse_String(parseState, ","))
      RETURN_ERROR;

   /* src arg */
   if (!Parse_SwizzleSrcReg(parseState, &inst->SrcReg[0]))
      RETURN_ERROR;

   /* semicolon */
   if (!Parse_String(parseState, ";"))
      RETURN_ERROR;

   return GL_TRUE;
}


static GLboolean
Parse_BiOpInstruction(struct parse_state *parseState,
                      struct vp_instruction *inst, enum vp_opcode opcode)
{
   if (opcode == VP_OPCODE_DPH && !parseState->isVersion1_1)
      RETURN_ERROR1("DPH illegal for vertex program 1.0");
   if (opcode == VP_OPCODE_SUB && !parseState->isVersion1_1)
      RETURN_ERROR1("SUB illegal for vertex program 1.0");

   inst->Opcode = opcode;
   inst->StringPos = parseState->curLine - parseState->start;

   /* dest reg */
   if (!Parse_MaskedDstReg(parseState, &inst->DstReg))
      RETURN_ERROR;

   /* comma */
   if (!Parse_String(parseState, ","))
      RETURN_ERROR;

   /* first src arg */
   if (!Parse_SwizzleSrcReg(parseState, &inst->SrcReg[0]))
      RETURN_ERROR;

   /* comma */
   if (!Parse_String(parseState, ","))
      RETURN_ERROR;

   /* second src arg */
   if (!Parse_SwizzleSrcReg(parseState, &inst->SrcReg[1]))
      RETURN_ERROR;

   /* semicolon */
   if (!Parse_String(parseState, ";"))
      RETURN_ERROR;

   /* make sure we don't reference more than one program parameter register */
   if (inst->SrcReg[0].File == PROGRAM_ENV_PARAM &&
       inst->SrcReg[1].File == PROGRAM_ENV_PARAM &&
       inst->SrcReg[0].Index != inst->SrcReg[1].Index)
      RETURN_ERROR1("Can't reference two program parameter registers");

   /* make sure we don't reference more than one vertex attribute register */
   if (inst->SrcReg[0].File == PROGRAM_INPUT &&
       inst->SrcReg[1].File == PROGRAM_INPUT &&
       inst->SrcReg[0].Index != inst->SrcReg[1].Index)
      RETURN_ERROR1("Can't reference two vertex attribute registers");

   return GL_TRUE;
}


static GLboolean
Parse_TriOpInstruction(struct parse_state *parseState,
                       struct vp_instruction *inst, enum vp_opcode opcode)
{
   inst->Opcode = opcode;
   inst->StringPos = parseState->curLine - parseState->start;

   /* dest reg */
   if (!Parse_MaskedDstReg(parseState, &inst->DstReg))
      RETURN_ERROR;

   /* comma */
   if (!Parse_String(parseState, ","))
      RETURN_ERROR;

   /* first src arg */
   if (!Parse_SwizzleSrcReg(parseState, &inst->SrcReg[0]))
      RETURN_ERROR;

   /* comma */
   if (!Parse_String(parseState, ","))
      RETURN_ERROR;

   /* second src arg */
   if (!Parse_SwizzleSrcReg(parseState, &inst->SrcReg[1]))
      RETURN_ERROR;

   /* comma */
   if (!Parse_String(parseState, ","))
      RETURN_ERROR;

   /* third src arg */
   if (!Parse_SwizzleSrcReg(parseState, &inst->SrcReg[2]))
      RETURN_ERROR;

   /* semicolon */
   if (!Parse_String(parseState, ";"))
      RETURN_ERROR;

   /* make sure we don't reference more than one program parameter register */
   if ((inst->SrcReg[0].File == PROGRAM_ENV_PARAM &&
        inst->SrcReg[1].File == PROGRAM_ENV_PARAM &&
        inst->SrcReg[0].Index != inst->SrcReg[1].Index) ||
       (inst->SrcReg[0].File == PROGRAM_ENV_PARAM &&
        inst->SrcReg[2].File == PROGRAM_ENV_PARAM &&
        inst->SrcReg[0].Index != inst->SrcReg[2].Index) ||
       (inst->SrcReg[1].File == PROGRAM_ENV_PARAM &&
        inst->SrcReg[2].File == PROGRAM_ENV_PARAM &&
        inst->SrcReg[1].Index != inst->SrcReg[2].Index))
      RETURN_ERROR1("Can only reference one program register");

   /* make sure we don't reference more than one vertex attribute register */
   if ((inst->SrcReg[0].File == PROGRAM_INPUT &&
        inst->SrcReg[1].File == PROGRAM_INPUT &&
        inst->SrcReg[0].Index != inst->SrcReg[1].Index) ||
       (inst->SrcReg[0].File == PROGRAM_INPUT &&
        inst->SrcReg[2].File == PROGRAM_INPUT &&
        inst->SrcReg[0].Index != inst->SrcReg[2].Index) ||
       (inst->SrcReg[1].File == PROGRAM_INPUT &&
        inst->SrcReg[2].File == PROGRAM_INPUT &&
        inst->SrcReg[1].Index != inst->SrcReg[2].Index))
      RETURN_ERROR1("Can only reference one input register");

   return GL_TRUE;
}


static GLboolean
Parse_ScalarInstruction(struct parse_state *parseState,
                        struct vp_instruction *inst, enum vp_opcode opcode)
{
   if (opcode == VP_OPCODE_RCC && !parseState->isVersion1_1)
      RETURN_ERROR1("RCC illegal for vertex program 1.0");

   inst->Opcode = opcode;
   inst->StringPos = parseState->curLine - parseState->start;

   /* dest reg */
   if (!Parse_MaskedDstReg(parseState, &inst->DstReg))
      RETURN_ERROR;

   /* comma */
   if (!Parse_String(parseState, ","))
      RETURN_ERROR;

   /* first src arg */
   if (!Parse_ScalarSrcReg(parseState, &inst->SrcReg[0]))
      RETURN_ERROR;

   /* semicolon */
   if (!Parse_String(parseState, ";"))
      RETURN_ERROR;

   return GL_TRUE;
}


static GLboolean
Parse_AddressInstruction(struct parse_state *parseState, struct vp_instruction *inst)
{
   inst->Opcode = VP_OPCODE_ARL;
   inst->StringPos = parseState->curLine - parseState->start;

   /* dest A0 reg */
   if (!Parse_AddrReg(parseState))
      RETURN_ERROR;

   /* comma */
   if (!Parse_String(parseState, ","))
      RETURN_ERROR;

   /* parse src reg */
   if (!Parse_ScalarSrcReg(parseState, &inst->SrcReg[0]))
      RETURN_ERROR;

   /* semicolon */
   if (!Parse_String(parseState, ";"))
      RETURN_ERROR;

   return GL_TRUE;
}


static GLboolean
Parse_EndInstruction(struct parse_state *parseState, struct vp_instruction *inst)
{
   GLubyte token[100];

   inst->Opcode = VP_OPCODE_END;
   inst->StringPos = parseState->curLine - parseState->start;

   /* this should fail! */
   if (Parse_Token(parseState, token))
      RETURN_ERROR2("Unexpected token after END:", token);
   else
      return GL_TRUE;
}


/**
 * The PRINT instruction is Mesa-specific and is meant as a debugging aid for
 * the vertex program developer.
 * The NV_vertex_program extension grammar is modified as follows:
 *
 *  <instruction>        ::= <ARL-instruction>
 *                         | ...
 *                         | <PRINT-instruction>
 *
 *  <PRINT-instruction>  ::= "PRINT" <string literal>
 *                         | "PRINT" <string literal> "," <srcReg>
 *                         | "PRINT" <string literal> "," <dstReg>
 */
static GLboolean
Parse_PrintInstruction(struct parse_state *parseState, struct vp_instruction *inst)
{
   const GLubyte *str;
   GLubyte *msg;
   GLuint len;
   GLubyte token[100];
   struct vp_src_register *srcReg = &inst->SrcReg[0];
   GLint idx;

   inst->Opcode = VP_OPCODE_PRINT;
   inst->StringPos = parseState->curLine - parseState->start;

   /* The first argument is a literal string 'just like this' */
   if (!Parse_String(parseState, "'"))
      RETURN_ERROR;

   str = parseState->pos;
   for (len = 0; str[len] != '\''; len++) /* find closing quote */
      ;
   parseState->pos += len + 1;
   msg = _mesa_malloc(len + 1);

   _mesa_memcpy(msg, str, len);
   msg[len] = 0;
   inst->Data = msg;

   /* comma */
   if (Parse_String(parseState, ",")) {

      /* The second argument is a register name */
      if (!Peek_Token(parseState, token))
         RETURN_ERROR;

⌨️ 快捷键说明

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