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

📄 programopt.c

📁 Mesa is an open-source implementation of the OpenGL specification - a system for rendering interacti
💻 C
📖 第 1 页 / 共 2 页
字号:
         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 + -