📄 nvfragparse.c
字号:
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 + -