Exemplo n.º 1
0
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 GLint
Parse_UnaryOpInstruction(struct parse_state *parseState,
                         struct prog_instruction *inst,
                         enum prog_opcode opcode)
{
   if (opcode == 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 prog_instruction *inst,
                      enum prog_opcode opcode)
{
   if (opcode == OPCODE_DPH && !parseState->isVersion1_1)
      RETURN_ERROR1("DPH illegal for vertex program 1.0");
   if (opcode == 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;
}
Exemplo n.º 4
0
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;
}
Exemplo n.º 5
0
static GLboolean
Parse_InstructionSequence(struct parse_state *parseState,
                          struct prog_instruction program[])
{
   while (1) {
      struct prog_instruction *inst = program + parseState->numInst;
      struct instruction_pattern instMatch;
      GLubyte token[100];

      /* Initialize the instruction */
      _mesa_init_instructions(inst, 1);

      /* special instructions */
      if (Parse_String(parseState, "DEFINE")) {
         GLubyte id[100];
         GLfloat value[7];  /* yes, 7 to be safe */
         if (!Parse_Identifier(parseState, id))
            RETURN_ERROR;
         /* XXX make sure id is not a reserved identifer, like R9 */
         if (!Parse_String(parseState, "="))
            RETURN_ERROR1("Expected =");
         if (!Parse_VectorOrScalarConstant(parseState, value))
            RETURN_ERROR;
         if (!Parse_String(parseState, ";"))
            RETURN_ERROR1("Expected ;");
         if (_mesa_lookup_parameter_index(parseState->parameters,
                                          -1, (const char *) id) >= 0) {
            RETURN_ERROR2(id, "already defined");
         }
         _mesa_add_named_parameter(parseState->parameters,
                                   (const char *) id, value);
      }
      else if (Parse_String(parseState, "DECLARE")) {
         GLubyte id[100];
         GLfloat value[7] = {0, 0, 0, 0, 0, 0, 0};  /* yes, to be safe */
         if (!Parse_Identifier(parseState, id))
            RETURN_ERROR;
         /* XXX make sure id is not a reserved identifer, like R9 */
         if (Parse_String(parseState, "=")) {
            if (!Parse_VectorOrScalarConstant(parseState, value))
               RETURN_ERROR;
         }
         if (!Parse_String(parseState, ";"))
            RETURN_ERROR1("Expected ;");
         if (_mesa_lookup_parameter_index(parseState->parameters,
                                          -1, (const char *) id) >= 0) {
            RETURN_ERROR2(id, "already declared");
         }
         _mesa_add_named_parameter(parseState->parameters,
                                   (const char *) id, value);
      }
      else if (Parse_String(parseState, "END")) {
         inst->Opcode = OPCODE_END;
         parseState->numInst++;
         if (Parse_Token(parseState, token)) {
            RETURN_ERROR1("Code after END opcode.");
         }
         break;
      }
      else {
         /* general/arithmetic instruction */

         /* get token */
         if (!Parse_Token(parseState, token)) {
            RETURN_ERROR1("Missing END instruction.");
         }

         /* try to find matching instuction */
         instMatch = MatchInstruction(token);
         if (instMatch.opcode >= MAX_OPCODE) {
            /* bad instruction name */
            RETURN_ERROR2("Unexpected token: ", token);
         }

         inst->Opcode = instMatch.opcode;
         inst->Precision = instMatch.suffixes & (_R | _H | _X);
         inst->SaturateMode = (instMatch.suffixes & (_S))
            ? SATURATE_ZERO_ONE : SATURATE_OFF;
         inst->CondUpdate = (instMatch.suffixes & (_C)) ? GL_TRUE : GL_FALSE;

         /*
          * parse the input and output operands
          */
         if (instMatch.outputs == OUTPUT_S || instMatch.outputs == OUTPUT_V) {
            if (!Parse_MaskedDstReg(parseState, &inst->DstReg))
               RETURN_ERROR;
            if (!Parse_String(parseState, ","))
               RETURN_ERROR1("Expected ,");
         }
         else if (instMatch.outputs == OUTPUT_NONE) {
            if (instMatch.opcode == OPCODE_KIL_NV) {
               /* This is a little weird, the cond code info is in
                * the dest register.
                */
               if (!Parse_CondCodeMask(parseState, &inst->DstReg))
                  RETURN_ERROR;
            }
            else {
               ASSERT(instMatch.opcode == OPCODE_PRINT);
            }
         }

         if (instMatch.inputs == INPUT_1V) {
            if (!Parse_VectorSrc(parseState, &inst->SrcReg[0]))
               RETURN_ERROR;
         }
         else if (instMatch.inputs == INPUT_2V) {
            if (!Parse_VectorSrc(parseState, &inst->SrcReg[0]))
               RETURN_ERROR;
            if (!Parse_String(parseState, ","))
               RETURN_ERROR1("Expected ,");
            if (!Parse_VectorSrc(parseState, &inst->SrcReg[1]))
               RETURN_ERROR;
         }
         else if (instMatch.inputs == INPUT_3V) {
            if (!Parse_VectorSrc(parseState, &inst->SrcReg[0]))
               RETURN_ERROR;
            if (!Parse_String(parseState, ","))
               RETURN_ERROR1("Expected ,");
            if (!Parse_VectorSrc(parseState, &inst->SrcReg[1]))
               RETURN_ERROR;
            if (!Parse_String(parseState, ","))
               RETURN_ERROR1("Expected ,");
            if (!Parse_VectorSrc(parseState, &inst->SrcReg[2]))
               RETURN_ERROR;
         }
         else if (instMatch.inputs == INPUT_1S) {
            if (!Parse_ScalarSrcReg(parseState, &inst->SrcReg[0]))
               RETURN_ERROR;
         }
         else if (instMatch.inputs == INPUT_2S) {
            if (!Parse_ScalarSrcReg(parseState, &inst->SrcReg[0]))
               RETURN_ERROR;
            if (!Parse_String(parseState, ","))
               RETURN_ERROR1("Expected ,");
            if (!Parse_ScalarSrcReg(parseState, &inst->SrcReg[1]))
               RETURN_ERROR;
         }
         else if (instMatch.inputs == INPUT_CC) {
            /* XXX to-do */
         }
         else if (instMatch.inputs == INPUT_1V_T) {
	    GLubyte unit, idx;
            if (!Parse_VectorSrc(parseState, &inst->SrcReg[0]))
               RETURN_ERROR;
            if (!Parse_String(parseState, ","))
               RETURN_ERROR1("Expected ,");
            if (!Parse_TextureImageId(parseState, &unit, &idx))
               RETURN_ERROR;
	    inst->TexSrcUnit = unit;
	    inst->TexSrcTarget = idx;
         }
         else if (instMatch.inputs == INPUT_3V_T) {
	    GLubyte unit, idx;
            if (!Parse_VectorSrc(parseState, &inst->SrcReg[0]))
               RETURN_ERROR;
            if (!Parse_String(parseState, ","))
               RETURN_ERROR1("Expected ,");
            if (!Parse_VectorSrc(parseState, &inst->SrcReg[1]))
               RETURN_ERROR;
            if (!Parse_String(parseState, ","))
               RETURN_ERROR1("Expected ,");
            if (!Parse_VectorSrc(parseState, &inst->SrcReg[2]))
               RETURN_ERROR;
            if (!Parse_String(parseState, ","))
               RETURN_ERROR1("Expected ,");
            if (!Parse_TextureImageId(parseState, &unit, &idx))
               RETURN_ERROR;
	    inst->TexSrcUnit = unit;
	    inst->TexSrcTarget = idx;
         }
         else if (instMatch.inputs == INPUT_1V_S) {
            if (!Parse_PrintInstruction(parseState, inst))
               RETURN_ERROR;
         }

         /* end of statement semicolon */
         if (!Parse_String(parseState, ";"))
            RETURN_ERROR1("Expected ;");

         parseState->numInst++;

         if (parseState->numInst >= MAX_NV_FRAGMENT_PROGRAM_INSTRUCTIONS)
            RETURN_ERROR1("Program too long");
      }
   }
   return GL_TRUE;
}