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

📄 nvfragparse.c

📁 winNT技术操作系统,国外开放的原代码和LIUX一样
💻 C
📖 第 1 页 / 共 4 页
字号:
 */
static GLboolean
Parse_ScalarConstant(struct parse_state *parseState, GLfloat *number)
{
   char *end = NULL;

   *number = (GLfloat) _mesa_strtod((const char *) parseState->pos, &end);

   if (end && end > (char *) parseState->pos) {
      /* got a number */
      parseState->pos = (GLubyte *) end;
      number[1] = *number;
      number[2] = *number;
      number[3] = *number;
      return GL_TRUE;
   }
   else {
      /* should be an identifier */
      GLubyte ident[100];
      const GLfloat *constant;
      if (!Parse_Identifier(parseState, ident))
         RETURN_ERROR1("Expected an identifier");
      constant = _mesa_lookup_parameter_value(parseState->parameters,
                                              -1, (const char *) ident);
      /* XXX Check that it's a constant and not a parameter */
      if (!constant) {
         RETURN_ERROR1("Undefined symbol");
      }
      else {
         COPY_4V(number, constant);
         return GL_TRUE;
      }
   }
}



/**
 * Parse a vector constant, one of:
 *   { float }
 *   { float, float }
 *   { float, float, float }
 *   { float, float, float, float }
 */
static GLboolean
Parse_VectorConstant(struct parse_state *parseState, GLfloat *vec)
{
   /* "{" was already consumed */

   ASSIGN_4V(vec, 0.0, 0.0, 0.0, 1.0);

   if (!Parse_ScalarConstant(parseState, vec+0))  /* X */
      return GL_FALSE;

   if (Parse_String(parseState, "}")) {
      return GL_TRUE;
   }

   if (!Parse_String(parseState, ","))
      RETURN_ERROR1("Expected comma in vector constant");

   if (!Parse_ScalarConstant(parseState, vec+1))  /* Y */
      return GL_FALSE;

   if (Parse_String(parseState, "}")) {
      return GL_TRUE;
   }

   if (!Parse_String(parseState, ","))
      RETURN_ERROR1("Expected comma in vector constant");

   if (!Parse_ScalarConstant(parseState, vec+2))  /* Z */
      return GL_FALSE;

   if (Parse_String(parseState, "}")) {
      return GL_TRUE;
   }

   if (!Parse_String(parseState, ","))
      RETURN_ERROR1("Expected comma in vector constant");

   if (!Parse_ScalarConstant(parseState, vec+3))  /* W */
      return GL_FALSE;

   if (!Parse_String(parseState, "}"))
      RETURN_ERROR1("Expected closing brace in vector constant");

   return GL_TRUE;
}


/**
 * Parse <number>, <varname> or {a, b, c, d}.
 * Return number of values in the vector or scalar, or zero if parse error.
 */
static GLuint
Parse_VectorOrScalarConstant(struct parse_state *parseState, GLfloat *vec)
{
   if (Parse_String(parseState, "{")) {
      return Parse_VectorConstant(parseState, vec);
   }
   else {
      GLboolean b = Parse_ScalarConstant(parseState, vec);
      if (b) {
         vec[1] = vec[2] = vec[3] = vec[0];
      }
      return b;
   }
}


/**
 * Parse a texture image source:
 *    [TEX0 | TEX1 | .. | TEX15] , [1D | 2D | 3D | CUBE | RECT]
 */
static GLboolean
Parse_TextureImageId(struct parse_state *parseState,
                     GLubyte *texUnit, GLubyte *texTargetBit)
{
   GLubyte imageSrc[100];
   GLint unit;

   if (!Parse_Token(parseState, imageSrc))
      RETURN_ERROR;
   
   if (imageSrc[0] != 'T' ||
       imageSrc[1] != 'E' ||
       imageSrc[2] != 'X') {
      RETURN_ERROR1("Expected TEX# source");
   }
   unit = _mesa_atoi((const char *) imageSrc + 3);
   if ((unit < 0 || unit > MAX_TEXTURE_IMAGE_UNITS) ||
       (unit == 0 && (imageSrc[3] != '0' || imageSrc[4] != 0))) {
      RETURN_ERROR1("Invalied TEX# source index");
   }
   *texUnit = unit;

   if (!Parse_String(parseState, ","))
      RETURN_ERROR1("Expected ,");

   if (Parse_String(parseState, "1D")) {
      *texTargetBit = TEXTURE_1D_BIT;
   }
   else if (Parse_String(parseState, "2D")) {
      *texTargetBit = TEXTURE_2D_BIT;
   }
   else if (Parse_String(parseState, "3D")) {
      *texTargetBit = TEXTURE_3D_BIT;
   }
   else if (Parse_String(parseState, "CUBE")) {
      *texTargetBit = TEXTURE_CUBE_BIT;
   }
   else if (Parse_String(parseState, "RECT")) {
      *texTargetBit = TEXTURE_RECT_BIT;
   }
   else {
      RETURN_ERROR1("Invalid texture target token");
   }

   /* update record of referenced texture units */
   parseState->texturesUsed[*texUnit] |= *texTargetBit;
   if (_mesa_bitcount(parseState->texturesUsed[*texUnit]) > 1) {
      RETURN_ERROR1("Only one texture target can be used per texture unit.");
   }

   return GL_TRUE;
}


/**
 * Parse a scalar suffix like .x, .y, .z or .w or parse a swizzle suffix
 * like .wxyz, .xxyy, etc and return the swizzle indexes.
 */
static GLboolean
Parse_SwizzleSuffix(const GLubyte *token, GLuint swizzle[4])
{
   if (token[1] == 0) {
      /* single letter swizzle (scalar) */
      if (token[0] == 'x')
         ASSIGN_4V(swizzle, 0, 0, 0, 0);
      else if (token[0] == 'y')
         ASSIGN_4V(swizzle, 1, 1, 1, 1);
      else if (token[0] == 'z')
         ASSIGN_4V(swizzle, 2, 2, 2, 2);
      else if (token[0] == 'w')
         ASSIGN_4V(swizzle, 3, 3, 3, 3);
      else
         return GL_FALSE;
   }
   else {
      /* 4-component swizzle (vector) */
      GLint k;
      for (k = 0; token[k] && k < 4; k++) {
         if (token[k] == 'x')
            swizzle[k] = 0;
         else if (token[k] == 'y')
            swizzle[k] = 1;
         else if (token[k] == 'z')
            swizzle[k] = 2;
         else if (token[k] == 'w')
            swizzle[k] = 3;
         else
            return GL_FALSE;
      }
      if (k != 4)
         return GL_FALSE;
   }
   return GL_TRUE;
}


static GLboolean
Parse_CondCodeMask(struct parse_state *parseState,
                   struct fp_dst_register *dstReg)
{
   if (Parse_String(parseState, "EQ"))
      dstReg->CondMask = COND_EQ;
   else if (Parse_String(parseState, "GE"))
      dstReg->CondMask = COND_GE;
   else if (Parse_String(parseState, "GT"))
      dstReg->CondMask = COND_GT;
   else if (Parse_String(parseState, "LE"))
      dstReg->CondMask = COND_LE;
   else if (Parse_String(parseState, "LT"))
      dstReg->CondMask = COND_LT;
   else if (Parse_String(parseState, "NE"))
      dstReg->CondMask = COND_NE;
   else if (Parse_String(parseState, "TR"))
      dstReg->CondMask = COND_TR;
   else if (Parse_String(parseState, "FL"))
      dstReg->CondMask = COND_FL;
   else
      RETURN_ERROR1("Invalid condition code mask");

   /* look for optional .xyzw swizzle */
   if (Parse_String(parseState, ".")) {
      GLubyte token[100];
      GLuint swz[4];

      if (!Parse_Token(parseState, token))  /* get xyzw suffix */
         RETURN_ERROR;

      if (!Parse_SwizzleSuffix(token, swz))
         RETURN_ERROR1("Invalid swizzle suffix");

      dstReg->CondSwizzle = MAKE_SWIZZLE(swz);
   }

   return GL_TRUE;
}


/**
 * Parse a temporary register: Rnn or Hnn
 */
static GLboolean
Parse_TempReg(struct parse_state *parseState, GLint *tempRegNum)
{
   GLubyte token[100];

   /* Should be 'R##' or 'H##' */
   if (!Parse_Token(parseState, token))
      RETURN_ERROR;
   if (token[0] != 'R' && token[0] != 'H')
      RETURN_ERROR1("Expected R## or H##");

   if (IsDigit(token[1])) {
      GLint reg = _mesa_atoi((const char *) (token + 1));
      if (token[0] == 'H')
         reg += 32;
      if (reg >= MAX_NV_FRAGMENT_PROGRAM_TEMPS)
         RETURN_ERROR1("Invalid temporary register name");
      *tempRegNum = reg;
   }
   else {
      RETURN_ERROR1("Invalid temporary register name");
   }

   return GL_TRUE;
}


/**
 * Parse a write-only dummy register: RC or HC.
 */
static GLboolean
Parse_DummyReg(struct parse_state *parseState, GLint *regNum)
{
   if (Parse_String(parseState, "RC")) {
       *regNum = 0;
   }
   else if (Parse_String(parseState, "HC")) {
       *regNum = 1;
   }
   else {
      RETURN_ERROR1("Invalid write-only register name");
   }

   return GL_TRUE;
}


/**
 * Parse a program local parameter register "p[##]"
 */
static GLboolean
Parse_ProgramParamReg(struct parse_state *parseState, GLint *regNum)
{
   GLubyte token[100];

   if (!Parse_String(parseState, "p["))
      RETURN_ERROR1("Expected p[");

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

   if (IsDigit(token[0])) {
      /* a numbered program parameter register */
      GLint reg = _mesa_atoi((const char *) token);
      if (reg >= MAX_NV_FRAGMENT_PROGRAM_PARAMS)
         RETURN_ERROR1("Invalid constant program number");
      *regNum = reg;
   }
   else {
      RETURN_ERROR;
   }

   if (!Parse_String(parseState, "]"))
      RETURN_ERROR1("Expected ]");

   return GL_TRUE;
}


/**
 * Parse f[name]  - fragment input register
 */
static GLboolean
Parse_FragReg(struct parse_state *parseState, GLint *tempRegNum)
{
   GLubyte token[100];
   GLint j;

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

   /* get <name> and look for match */
   if (!Parse_Token(parseState, token)) {
      RETURN_ERROR;
   }
   for (j = 0; InputRegisters[j]; j++) {
      if (_mesa_strcmp((const char *) token, InputRegisters[j]) == 0) {
         *tempRegNum = j;
         parseState->inputsRead |= (1 << j);
         break;
      }
   }
   if (!InputRegisters[j]) {
      /* unknown input register label */
      RETURN_ERROR2("Invalid register name", token);
   }

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

   return GL_TRUE;
}


static GLboolean
Parse_OutputReg(struct parse_state *parseState, GLint *outputRegNum)
{
   GLubyte token[100];
   GLint j;

   /* Match "o[" */
   if (!Parse_String(parseState, "o["))
      RETURN_ERROR1("Expected o[");

   /* Get output reg name */
   if (!Parse_Token(parseState, token))
      RETURN_ERROR;

   /* try to match an output register name */
   for (j = 0; OutputRegisters[j]; j++) {
      if (_mesa_strcmp((const char *) token, OutputRegisters[j]) == 0) {
         static GLuint bothColors = (1 << FRAG_OUTPUT_COLR) | (1 << FRAG_OUTPUT_COLH);
         *outputRegNum = j;
         parseState->outputsWritten |= (1 << j);
         if ((parseState->outputsWritten & bothColors) == bothColors) {
            RETURN_ERROR1("Illegal to write to both o[COLR] and o[COLH]");
         }
         break;
      }
   }
   if (!OutputRegisters[j])
      RETURN_ERROR1("Invalid output register name");

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

   return GL_TRUE;
}


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

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

   if (_mesa_strcmp((const char *) token, "RC") == 0 ||
       _mesa_strcmp((const char *) token, "HC") == 0) {
      /* a write-only register */
      dstReg->File = PROGRAM_WRITE_ONLY;
      if (!Parse_DummyReg(parseState, &idx))
         RETURN_ERROR;
      dstReg->Index = idx;
   }
   else if (token[0] == 'R' || token[0] == 'H') {
      /* a temporary register */
      dstReg->File = PROGRAM_TEMPORARY;
      if (!Parse_TempReg(parseState, &idx))
         RETURN_ERROR;
      dstReg->Index = idx;
   }
   else if (token[0] == 'o') {
      /* an output register */
      dstReg->File = PROGRAM_OUTPUT;
      if (!Parse_OutputReg(parseState, &idx))
         RETURN_ERROR;
      dstReg->Index = idx;
   }
   else {
      RETURN_ERROR1("Invalid destination register name");
   }

   /* Parse optional write mask */
   if (Parse_String(parseState, ".")) {
      /* got a mask */
      GLint k = 0;

      if (!Parse_Token(parseState, token))  /* get xyzw writemask */
         RETURN_ERROR;

      dstReg->WriteMask = 0;

      if (token[k] == 'x') {
         dstReg->WriteMask |= WRITEMASK_X;

⌨️ 快捷键说明

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