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

📄 nvfragparse.c

📁 winNT技术操作系统,国外开放的原代码和LIUX一样
💻 C
📖 第 1 页 / 共 4 页
字号:
            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->TexSrcIdx = 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->TexSrcIdx = 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;
}



/**
 * 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(GLcontext *ctx, GLenum dstTarget,
                                const GLubyte *str, GLsizei len,
                                struct fragment_program *program)
{
   struct parse_state parseState;
   struct fp_instruction instBuffer[MAX_NV_FRAGMENT_PROGRAM_INSTRUCTIONS];
   struct fp_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 */
   _mesa_bzero(&parseState, 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 (_mesa_strncmp((const char *) programString, "!!FP1.0", 7) == 0) {
      target = GL_FRAGMENT_PROGRAM_NV;
      parseState.pos = programString + 7;
   }
   else if (_mesa_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 = (struct fp_instruction *)
         MALLOC(parseState.numInst * sizeof(struct fp_instruction));
      if (!newInst) {
         _mesa_error(ctx, GL_OUT_OF_MEMORY, "glLoadProgramNV");
         return;  /* out of memory */
      }
      MEMCPY(newInst, instBuffer,
             parseState.numInst * sizeof(struct fp_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;
      for (u = 0; u < ctx->Const.MaxTextureImageUnits; u++)
         program->TexturesUsed[u] = parseState.texturesUsed[u];

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

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

#ifdef DEBUG_foo
      _mesa_printf("--- glLoadProgramNV(%d) result ---\n", program->Base.Id);
      _mesa_print_nv_fragment_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 */
   }
}


static void
PrintSrcReg(const struct fragment_program *program,
            const struct fp_src_register *src)
{
   static const char comps[5] = "xyzw";

   if (src->NegateAbs) {
      _mesa_printf("-");
   }
   if (src->Abs) {
      _mesa_printf("|");
   }
   if (src->NegateBase) {
      _mesa_printf("-");
   }
   if (src->File == PROGRAM_NAMED_PARAM) {
      if (program->Parameters->Parameters[src->Index].Type == CONSTANT) {
         _mesa_printf("{%g, %g, %g, %g}",
                program->Parameters->ParameterValues[src->Index][0],
                program->Parameters->ParameterValues[src->Index][1],
                program->Parameters->ParameterValues[src->Index][2],
                program->Parameters->ParameterValues[src->Index][3]);
      }
      else {
         ASSERT(program->Parameters->Parameters[src->Index].Type
                == NAMED_PARAMETER);
         _mesa_printf("%s", program->Parameters->Parameters[src->Index].Name);
      }
   }
   else if (src->File == PROGRAM_OUTPUT) {
      _mesa_printf("o[%s]", OutputRegisters[src->Index]);
   }
   else if (src->File == PROGRAM_INPUT) {
      _mesa_printf("f[%s]", InputRegisters[src->Index]);
   }
   else if (src->File == PROGRAM_LOCAL_PARAM) {
      _mesa_printf("p[%d]", src->Index);
   }
   else if (src->File == PROGRAM_TEMPORARY) {
      if (src->Index >= 32)
         _mesa_printf("H%d", src->Index);
      else
         _mesa_printf("R%d", src->Index);
   }
   else if (src->File == PROGRAM_WRITE_ONLY) {
      _mesa_printf("%cC", "HR"[src->Index]);
   }
   else {
      _mesa_problem(NULL, "Invalid fragment register %d", src->Index);
      return;
   }
   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)]);
   }
   if (src->Abs) {
      _mesa_printf("|");
   }
}

static void
PrintTextureSrc(const struct fp_instruction *inst)
{
   _mesa_printf("TEX%d, ", inst->TexSrcUnit);
   switch (inst->TexSrcIdx) {
   case TEXTURE_1D_INDEX:
      _mesa_printf("1D");
      break;
   case TEXTURE_2D_INDEX:
      _mesa_printf("2D");
      break;
   case TEXTURE_3D_INDEX:
      _mesa_printf("3D");
      break;
   case TEXTURE_RECT_INDEX:
      _mesa_printf("RECT");
      break;
   case TEXTURE_CUBE_INDEX:
      _mesa_printf("CUBE");
      break;
   default:
      _mesa_problem(NULL, "Invalid textue target in PrintTextureSrc");
   }
}

static void
PrintCondCode(const struct fp_dst_register *dst)
{
   static const char *comps = "xyzw";
   static const char *ccString[] = {
      "??", "GT", "EQ", "LT", "UN", "GE", "LE", "NE", "TR", "FL", "??"
   };

   _mesa_printf("%s", ccString[dst->CondMask]);
   if (GET_SWZ(dst->CondSwizzle, 0) == GET_SWZ(dst->CondSwizzle, 1) &&
       GET_SWZ(dst->CondSwizzle, 0) == GET_SWZ(dst->CondSwizzle, 2) &&
       GET_SWZ(dst->CondSwizzle, 0) == GET_SWZ(dst->CondSwizzle, 3)) {
      _mesa_printf(".%c", comps[GET_SWZ(dst->CondSwizzle, 0)]);
   }
   else if (dst->CondSwizzle != SWIZZLE_NOOP) {
      _mesa_printf(".%c%c%c%c",
                   comps[GET_SWZ(dst->CondSwizzle, 0)],
                   comps[GET_SWZ(dst->CondSwizzle, 1)],
                   comps[GET_SWZ(dst->CondSwizzle, 2)],
                   comps[GET_SWZ(dst->CondSwizzle, 3)]);
   }
}


static void
PrintDstReg(const struct fp_dst_register *dst)
{
   if (dst->File == PROGRAM_OUTPUT) {
      _mesa_printf("o[%s]", OutputRegisters[dst->Index]);
   }
   else if (dst->File == PROGRAM_TEMPORARY) {
      if (dst->Index >= 32)
         _mesa_printf("H%d", dst->Index);
      else
         _mesa_printf("R%d", dst->Index);
   }
   else if (dst->File == PROGRAM_LOCAL_PARAM) {
      _mesa_printf("p[%d]", dst->Index);
   }
   else if (dst->File == PROGRAM_WRITE_ONLY) {
      _mesa_printf("%cC", "HR"[dst->Index]);
   }
   else {
      _mesa_printf("???");
   }

   if (dst->WriteMask != 0 && dst->WriteMask != 0xf) {
      _mesa_printf(".");
      if (dst->WriteMask & 0x1)
         _mesa_printf("x");
      if (dst->WriteMask & 0x2)
         _mesa_printf("y");
      if (dst->WriteMask & 0x4)
         _mesa_printf("z");
      if (dst->WriteMask & 0x8)
         _mesa_printf("w");
   }

   if (dst->CondMask != COND_TR ||
       dst->CondSwizzle != SWIZZLE_NOOP) {
      _mesa_printf(" (");
      PrintCondCode(dst);
      _mesa_printf(")");
   }
}


/**
 * Print (unparse) the given vertex program.  Just for debugging.
 */
void
_mesa_print_nv_fragment_program(const struct fragment_program *program)
{
   const struct fp_instruction *inst;

   for (inst = program->Instructions; inst->Opcode != FP_OPCODE_END; inst++) {
      int i;
      for (i = 0; Instructions[i].name; i++) {
         if (inst->Opcode == Instructions[i].opcode) {
            /* print instruction name */
            _mesa_printf("%s", Instructions[i].name);
            if (inst->Precision == FLOAT16)
               _mesa_printf("H");
            else if (inst->Precision == FIXED12)
               _mesa_printf("X");
            if (inst->UpdateCondRegister)
               _mesa_printf("C");
            if (inst->Saturate)
               _mesa_printf("_SAT");
            _mesa_printf(" ");

            if (Instructions[i].inputs == INPUT_CC) {
               PrintCondCode(&inst->DstReg);
            }
            else if (Instructions[i].outputs == OUTPUT_V ||
                     Instructions[i].outputs == OUTPUT_S) {
               /* print dest register */
               PrintDstReg(&inst->DstReg);
               _mesa_printf(", ");
            }

            /* print source register(s) */
            if (Instructions[i].inputs == INPUT_1V ||
                Instructions[i].inputs == INPUT_1S) {
               PrintSrcReg(program, &inst->SrcReg[0]);
            }
            else if (Instructions[i].inputs == INPUT_2V ||
                     Instructions[i].inputs == INPUT_2S) {
               PrintSrcReg(program, &inst->SrcReg[0]);
               _mesa_printf(", ");
               PrintSrcReg(program, &inst->SrcReg[1]);
            }
            else if (Instructions[i].inputs == INPUT_3V) {
               PrintSrcReg(program, &inst->SrcReg[0]);
               _mesa_printf(", ");
               PrintSrcReg(program, &inst->SrcReg[1]);
               _mesa_printf(", ");
               PrintSrcReg(program, &inst->SrcReg[2]);
            }
            else if (Instructions[i].inputs == INPUT_1V_T) {
               PrintSrcReg(program, &inst->SrcReg[0]);
               _mesa_printf(", ");
               PrintTextureSrc(inst);
            }
            else if (Instructions[i].inputs == INPUT_3V_T) {
               PrintSrcReg(program, &inst->SrcReg[0]);
               _mesa_printf(", ");
               PrintSrcReg(program, &inst->SrcReg[1]);
               _mesa_printf(", ");
               PrintSrcReg(program, &inst->SrcReg[2]);
               _mesa_printf(", ");
               PrintTextureSrc(inst);
            }
            _mesa_printf(";\n");
            break;
         }
      }
      if (!Instructions[i].name) {
         _mesa_printf("Invalid opcode %d\n", inst->Opcode);
      }
   }
   _mesa_printf("END\n");
}


const char *
_mesa_nv_fragment_input_register_name(GLuint i)
{
   ASSERT(i < MAX_NV_FRAGMENT_PROGRAM_INPUTS);
   return InputRegisters[i];
}


const char *
_mesa_nv_fragment_output_register_name(GLuint i)
{
   ASSERT(i < MAX_NV_FRAGMENT_PROGRAM_OUTPUTS);
   return OutputRegisters[i];
}

⌨️ 快捷键说明

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