📄 programopt.c
字号:
inst->SrcReg[1].File = PROGRAM_TEMPORARY; inst->SrcReg[1].Index = fogFactorTemp; inst->SrcReg[1].Swizzle = SWIZZLE_XXXX; inst++; } /* EX2_SAT fogFactorTemp.x, -fogFactorTemp.x; */ inst->Opcode = OPCODE_EX2; inst->DstReg.File = PROGRAM_TEMPORARY; inst->DstReg.Index = fogFactorTemp; inst->DstReg.WriteMask = WRITEMASK_X; inst->SrcReg[0].File = PROGRAM_TEMPORARY; inst->SrcReg[0].Index = fogFactorTemp; inst->SrcReg[0].NegateBase = NEGATE_XYZW; inst->SrcReg[0].Swizzle = SWIZZLE_XXXX; inst->SaturateMode = SATURATE_ZERO_ONE; inst++; } /* LRP result.color.xyz, fogFactorTemp.xxxx, colorTemp, fogColorRef; */ inst->Opcode = OPCODE_LRP; inst->DstReg.File = PROGRAM_OUTPUT; inst->DstReg.Index = FRAG_RESULT_COLR; inst->DstReg.WriteMask = WRITEMASK_XYZ; inst->SrcReg[0].File = PROGRAM_TEMPORARY; inst->SrcReg[0].Index = fogFactorTemp; inst->SrcReg[0].Swizzle = SWIZZLE_XXXX; inst->SrcReg[1].File = PROGRAM_TEMPORARY; inst->SrcReg[1].Index = colorTemp; inst->SrcReg[1].Swizzle = SWIZZLE_NOOP; inst->SrcReg[2].File = PROGRAM_STATE_VAR; inst->SrcReg[2].Index = fogColorRef; inst->SrcReg[2].Swizzle = SWIZZLE_NOOP; inst++; /* MOV result.color.w, colorTemp.x; # copy alpha */ inst->Opcode = OPCODE_MOV; inst->DstReg.File = PROGRAM_OUTPUT; inst->DstReg.Index = FRAG_RESULT_COLR; inst->DstReg.WriteMask = WRITEMASK_W; inst->SrcReg[0].File = PROGRAM_TEMPORARY; inst->SrcReg[0].Index = colorTemp; inst->SrcReg[0].Swizzle = SWIZZLE_NOOP; inst++; /* END; */ inst->Opcode = OPCODE_END; inst++; /* free old instructions */ _mesa_free_instructions(fprog->Base.Instructions, origLen); /* install new instructions */ fprog->Base.Instructions = newInst; fprog->Base.NumInstructions = inst - newInst; fprog->Base.InputsRead |= FRAG_BIT_FOGC; /* XXX do this? fprog->FogOption = GL_NONE; */}static GLbooleanis_texture_instruction(const struct prog_instruction *inst){ switch (inst->Opcode) { case OPCODE_TEX: case OPCODE_TXB: case OPCODE_TXD: case OPCODE_TXL: case OPCODE_TXP: case OPCODE_TXP_NV: return GL_TRUE; default: return GL_FALSE; }} /** * Count the number of texure indirections in the given program. * The program's NumTexIndirections field will be updated. * See the GL_ARB_fragment_program spec (issue 24) for details. * XXX we count texture indirections in texenvprogram.c (maybe use this code * instead and elsewhere). */void_mesa_count_texture_indirections(struct gl_program *prog){ GLuint indirections = 1; GLbitfield tempsOutput = 0x0; GLbitfield aluTemps = 0x0; GLuint i; for (i = 0; i < prog->NumInstructions; i++) { const struct prog_instruction *inst = prog->Instructions + i; if (is_texture_instruction(inst)) { if (((inst->SrcReg[0].File == PROGRAM_TEMPORARY) && (tempsOutput & (1 << inst->SrcReg[0].Index))) || ((inst->Opcode != OPCODE_KIL) && (inst->DstReg.File == PROGRAM_TEMPORARY) && (aluTemps & (1 << inst->DstReg.Index)))) { indirections++; tempsOutput = 0x0; aluTemps = 0x0; } } else { GLuint j; for (j = 0; j < 3; j++) { if (inst->SrcReg[j].File == PROGRAM_TEMPORARY) aluTemps |= (1 << inst->SrcReg[j].Index); } if (inst->DstReg.File == PROGRAM_TEMPORARY) aluTemps |= (1 << inst->DstReg.Index); } if ((inst->Opcode != OPCODE_KIL) && (inst->DstReg.File == PROGRAM_TEMPORARY)) tempsOutput |= (1 << inst->DstReg.Index); } prog->NumTexIndirections = indirections;}/** * Count number of texture instructions in given program and update the * program's NumTexInstructions field. */void_mesa_count_texture_instructions(struct gl_program *prog){ GLuint i; prog->NumTexInstructions = 0; for (i = 0; i < prog->NumInstructions; i++) { prog->NumTexInstructions += is_texture_instruction(prog->Instructions + i); }}/** * Scan/rewrite program to remove reads of custom (output) registers. * The passed type has to be either PROGRAM_OUTPUT or PROGRAM_VARYING * (for vertex shaders). * In GLSL shaders, varying vars can be read and written. * On some hardware, trying to read an output register causes trouble. * So, rewrite the program to use a temporary register in this case. */void_mesa_remove_output_reads(struct gl_program *prog, enum register_file type){ GLuint i; GLint outputMap[VERT_RESULT_MAX]; GLuint numVaryingReads = 0; assert(type == PROGRAM_VARYING || type == PROGRAM_OUTPUT); assert(prog->Target == GL_VERTEX_PROGRAM_ARB || type != PROGRAM_VARYING); for (i = 0; i < VERT_RESULT_MAX; i++) outputMap[i] = -1; /* look for instructions which read from varying vars */ for (i = 0; i < prog->NumInstructions; i++) { struct prog_instruction *inst = prog->Instructions + i; const GLuint numSrc = _mesa_num_inst_src_regs(inst->Opcode); GLuint j; for (j = 0; j < numSrc; j++) { if (inst->SrcReg[j].File == type) { /* replace the read with a temp reg */ const GLuint var = inst->SrcReg[j].Index; if (outputMap[var] == -1) { numVaryingReads++; outputMap[var] = _mesa_find_free_register(prog, PROGRAM_TEMPORARY); } inst->SrcReg[j].File = PROGRAM_TEMPORARY; inst->SrcReg[j].Index = outputMap[var]; } } } if (numVaryingReads == 0) return; /* nothing to be done */ /* look for instructions which write to the varying vars identified above */ for (i = 0; i < prog->NumInstructions; i++) { struct prog_instruction *inst = prog->Instructions + i; const GLuint numSrc = _mesa_num_inst_src_regs(inst->Opcode); GLuint j; for (j = 0; j < numSrc; j++) { if (inst->DstReg.File == type && outputMap[inst->DstReg.Index] >= 0) { /* change inst to write to the temp reg, instead of the varying */ inst->DstReg.File = PROGRAM_TEMPORARY; inst->DstReg.Index = outputMap[inst->DstReg.Index]; } } } /* insert new instructions to copy the temp vars to the varying vars */ { struct prog_instruction *inst; GLint endPos, var; /* Look for END instruction and insert the new varying writes */ endPos = -1; for (i = 0; i < prog->NumInstructions; i++) { struct prog_instruction *inst = prog->Instructions + i; if (inst->Opcode == OPCODE_END) { endPos = i; _mesa_insert_instructions(prog, i, numVaryingReads); break; } } assert(endPos >= 0); /* insert new MOV instructions here */ inst = prog->Instructions + endPos; for (var = 0; var < VERT_RESULT_MAX; var++) { if (outputMap[var] >= 0) { /* MOV VAR[var], TEMP[tmp]; */ inst->Opcode = OPCODE_MOV; inst->DstReg.File = type; inst->DstReg.Index = var; inst->SrcReg[0].File = PROGRAM_TEMPORARY; inst->SrcReg[0].Index = outputMap[var]; inst++; } } }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -