📄 nvfragparse.c
字号:
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;}/** * 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 gl_fragment_program *program){ struct parse_state parseState; struct prog_instruction instBuffer[MAX_NV_FRAGMENT_PROGRAM_INSTRUCTIONS]; struct prog_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 = _mesa_alloc_instructions(parseState.numInst); if (!newInst) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "glLoadProgramNV"); return; /* out of memory */ } _mesa_copy_instructions(newInst, instBuffer, parseState.numInst); /* 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->Base.Instructions) { _mesa_free(program->Base.Instructions); } program->Base.Instructions = newInst; program->Base.NumInstructions = parseState.numInst; program->Base.InputsRead = parseState.inputsRead; program->Base.OutputsWritten = parseState.outputsWritten; for (u = 0; u < ctx->Const.MaxTextureImageUnits; u++) program->Base.TexturesUsed[u] = parseState.texturesUsed[u]; /* save program parameters */ program->Base.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 voidPrintSrcReg(const struct gl_fragment_program *program, const struct prog_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->Base.Parameters->Parameters[src->Index].Type == PROGRAM_CONSTANT) { const GLfloat *v; v = program->Base.Parameters->ParameterValues[src->Index]; _mesa_printf("{%g, %g, %g, %g}", v[0], v[1], v[2], v[3]); } else { ASSERT(program->Base.Parameters->Parameters[src->Index].Type == PROGRAM_NAMED_PARAM); _mesa_printf("%s", program->Base.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 voidPrintTextureSrc(const struct prog_instruction *inst){ _mesa_printf("TEX%d, ", inst->TexSrcUnit); switch (inst->TexSrcTarget) { 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 voidPrintCondCode(const struct prog_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 voidPrintDstReg(const struct prog_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 != WRITEMASK_XYZW) { _mesa_printf("."); if (dst->WriteMask & WRITEMASK_X) _mesa_printf("x"); if (dst->WriteMask & WRITEMASK_Y) _mesa_printf("y"); if (dst->WriteMask & WRITEMASK_Z) _mesa_printf("z"); if (dst->WriteMask & WRITEMASK_W) _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 gl_fragment_program *program){ const struct prog_instruction *inst; for (inst = program->Base.Instructions; inst->Opcode != 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->CondUpdate) _mesa_printf("C"); if (inst->SaturateMode == SATURATE_ZERO_ONE) _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 + -