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

📄 brw_wm_fp.c

📁 Mesa is an open-source implementation of the OpenGL specification - a system for rendering interacti
💻 C
📖 第 1 页 / 共 2 页
字号:
		    0, 0, 0,		    src_swizzle1(src0, SWIZZLE_ONE),		    src_undef(),		    src_undef());      /* Avoid letting the negation flag of src0 affect our 1 constant. */      swz->SrcReg[0].NegateBase = 0;   }   if (dst.WriteMask & WRITEMASK_YZ) {      emit_op(c,	      OPCODE_LIT,	      dst_mask(dst, WRITEMASK_YZ),	      inst->SaturateMode, 0, 0,	      src0,	      src_undef(),	      src_undef());   }}static void precalc_tex( struct brw_wm_compile *c,			 const struct prog_instruction *inst ){   struct prog_src_register coord;   struct prog_dst_register tmpcoord;   GLuint unit = c->fp->program.Base.SamplerUnits[inst->TexSrcUnit];   if (inst->TexSrcTarget == TEXTURE_CUBE_INDEX) {       struct prog_instruction *out;       struct prog_dst_register tmp0 = get_temp(c);       struct prog_src_register tmp0src = src_reg_from_dst(tmp0);       struct prog_dst_register tmp1 = get_temp(c);       struct prog_src_register tmp1src = src_reg_from_dst(tmp1);       struct prog_src_register src0 = inst->SrcReg[0];       tmpcoord = get_temp(c);       coord = src_reg_from_dst(tmpcoord);       out = emit_op(c, OPCODE_MOV,                     tmpcoord,                     0, 0, 0,                     src0,                     src_undef(),                     src_undef());       out->SrcReg[0].NegateBase = 0;       out->SrcReg[0].Abs = 1;       emit_op(c, OPCODE_MAX,               tmp0,               0, 0, 0,               src_swizzle1(coord, X),               src_swizzle1(coord, Y),               src_undef());       emit_op(c, OPCODE_MAX,               tmp1,               0, 0, 0,               tmp0src,               src_swizzle1(coord, Z),               src_undef());       emit_op(c, OPCODE_RCP,               tmp0,               0, 0, 0,               tmp1src,               src_undef(),               src_undef());       emit_op(c, OPCODE_MUL,               tmpcoord,               0, 0, 0,               src0,               tmp0src,               src_undef());       release_temp(c, tmp0);       release_temp(c, tmp1);   } else if (inst->TexSrcTarget == TEXTURE_RECT_INDEX) {      struct prog_src_register scale = 	 search_or_add_param5( c, 			       STATE_INTERNAL, 			       STATE_TEXRECT_SCALE,			       unit,			       0,0 );      tmpcoord = get_temp(c);      /* coord.xy   = MUL inst->SrcReg[0], { 1/width, 1/height }       */      emit_op(c,	      OPCODE_MUL,	      tmpcoord,	      0, 0, 0,	      inst->SrcReg[0],	      scale,	      src_undef());      coord = src_reg_from_dst(tmpcoord);   }   else {      coord = inst->SrcReg[0];   }   /* Need to emit YUV texture conversions by hand.  Probably need to    * do this here - the alternative is in brw_wm_emit.c, but the    * conversion requires allocating a temporary variable which we    * don't have the facility to do that late in the compilation.    */   if (!(c->key.yuvtex_mask & (1<<unit))) {      emit_op(c, 	      OPCODE_TEX,	      inst->DstReg,	      inst->SaturateMode,	      unit,	      inst->TexSrcTarget,	      coord,	      src_undef(),	      src_undef());   }   else {       GLboolean  swap_uv = c->key.yuvtex_swap_mask & (1<<unit);      /* 	 CONST C0 = { -.5, -.0625,  -.5, 1.164 }	 CONST C1 = { 1.596, -0.813, 2.018, -.391 }	 UYV     = TEX ...	 UYV.xyz = ADD UYV,     C0	 UYV.y   = MUL UYV.y,   C0.w 	 if (UV swaped)	    RGB.xyz = MAD UYV.zzx, C1,   UYV.y	 else	    RGB.xyz = MAD UYV.xxz, C1,   UYV.y 	 RGB.y   = MAD UYV.z,   C1.w, RGB.y      */      struct prog_dst_register dst = inst->DstReg;      struct prog_dst_register tmp = get_temp(c);      struct prog_src_register tmpsrc = src_reg_from_dst(tmp);      struct prog_src_register C0 = search_or_add_const4f( c,  -.5, -.0625, -.5, 1.164 );      struct prog_src_register C1 = search_or_add_const4f( c, 1.596, -0.813, 2.018, -.391 );           /* tmp     = TEX ...       */      emit_op(c, 	      OPCODE_TEX,	      tmp,	      inst->SaturateMode,	      unit,	      inst->TexSrcTarget,	      coord,	      src_undef(),	      src_undef());      /* tmp.xyz =  ADD TMP, C0       */      emit_op(c,	      OPCODE_ADD,	      dst_mask(tmp, WRITEMASK_XYZ),	      0, 0, 0,	      tmpsrc,	      C0,	      src_undef());      /* YUV.y   = MUL YUV.y, C0.w       */      emit_op(c,	      OPCODE_MUL,	      dst_mask(tmp, WRITEMASK_Y),	      0, 0, 0,	      tmpsrc,	      src_swizzle1(C0, W),	      src_undef());      /*        * if (UV swaped)       *     RGB.xyz = MAD YUV.zzx, C1, YUV.y       * else       *     RGB.xyz = MAD YUV.xxz, C1, YUV.y       */      emit_op(c,	      OPCODE_MAD,	      dst_mask(dst, WRITEMASK_XYZ),	      0, 0, 0,	      swap_uv?src_swizzle(tmpsrc, Z,Z,X,X):src_swizzle(tmpsrc, X,X,Z,Z),	      C1,	      src_swizzle1(tmpsrc, Y));      /*  RGB.y   = MAD YUV.z, C1.w, RGB.y       */      emit_op(c,	      OPCODE_MAD,	      dst_mask(dst, WRITEMASK_Y),	      0, 0, 0,	      src_swizzle1(tmpsrc, Z),	      src_swizzle1(C1, W),	      src_swizzle1(src_reg_from_dst(dst), Y));      release_temp(c, tmp);   }   if ((inst->TexSrcTarget == TEXTURE_RECT_INDEX) ||       (inst->TexSrcTarget == TEXTURE_CUBE_INDEX))      release_temp(c, tmpcoord);}static GLboolean projtex( struct brw_wm_compile *c,			  const struct prog_instruction *inst ){   struct prog_src_register src = inst->SrcReg[0];   /* Only try to detect the simplest cases.  Could detect (later)    * cases where we are trying to emit code like RCP {1.0}, MUL x,    * {1.0}, and so on.    *    * More complex cases than this typically only arise from    * user-provided fragment programs anyway:    */   if (inst->TexSrcTarget == TEXTURE_CUBE_INDEX)      return 0;  /* ut2004 gun rendering !?! */   else if (src.File == PROGRAM_INPUT && 	    GET_SWZ(src.Swizzle, W) == W &&           (c->key.projtex_mask & (1<<(src.Index + FRAG_ATTRIB_WPOS - FRAG_ATTRIB_TEX0))) == 0)      return 0;   else      return 1;}static void precalc_txp( struct brw_wm_compile *c,			       const struct prog_instruction *inst ){   struct prog_src_register src0 = inst->SrcReg[0];   if (projtex(c, inst)) {      struct prog_dst_register tmp = get_temp(c);      struct prog_instruction tmp_inst;      /* tmp0.w = RCP inst.arg[0][3]       */      emit_op(c,	      OPCODE_RCP,	      dst_mask(tmp, WRITEMASK_W),	      0, 0, 0,	      src_swizzle1(src0, GET_SWZ(src0.Swizzle, W)),	      src_undef(),	      src_undef());      /* tmp0.xyz =  MUL inst.arg[0], tmp0.wwww       */      emit_op(c,	      OPCODE_MUL,	      dst_mask(tmp, WRITEMASK_XYZ),	      0, 0, 0,	      src0,	      src_swizzle1(src_reg_from_dst(tmp), W),	      src_undef());      /* dst = precalc(TEX tmp0)       */      tmp_inst = *inst;      tmp_inst.SrcReg[0] = src_reg_from_dst(tmp);      precalc_tex(c, &tmp_inst);      release_temp(c, tmp);   }   else   {      /* dst = precalc(TEX src0)       */      precalc_tex(c, inst);   }}/*********************************************************************** * Add instructions to perform fog blending */static void fog_blend( struct brw_wm_compile *c,			     struct prog_src_register fog_factor ){   struct prog_dst_register outcolor = dst_reg(PROGRAM_OUTPUT, FRAG_RESULT_COLR);   struct prog_src_register fogcolor = search_or_add_param5( c, STATE_FOG_COLOR, 0,0,0,0 );   /* color.xyz = LRP fog_factor.xxxx, output_color, fog_color */      emit_op(c, 	   OPCODE_LRP,	   dst_mask(outcolor, WRITEMASK_XYZ),	   0, 0, 0,	   fog_factor,	   src_reg_from_dst(outcolor),	   fogcolor);}/* This one is simple - just take the interpolated fog coordinate and * use it as the fog blend factor. */static void fog_interpolated( struct brw_wm_compile *c ){   struct prog_src_register fogc = src_reg(PROGRAM_INPUT, FRAG_ATTRIB_FOGC);      if (!(c->fp_interp_emitted & (1<<FRAG_ATTRIB_FOGC)))       emit_interp(c, FRAG_ATTRIB_FOGC);   fog_blend( c, src_swizzle1(fogc, GET_SWZ(fogc.Swizzle,X)));}static void emit_fog( struct brw_wm_compile *c ) {   if (!c->fp->program.FogOption)      return;   if (1)       fog_interpolated( c );   else {      /* TODO: per-pixel fog */      assert(0);   }}static void emit_fb_write( struct brw_wm_compile *c ){   struct prog_src_register outcolor = src_reg(PROGRAM_OUTPUT, FRAG_RESULT_COLR);   struct prog_src_register payload_r0_depth = src_reg(PROGRAM_PAYLOAD, PAYLOAD_DEPTH);   struct prog_src_register outdepth = src_reg(PROGRAM_OUTPUT, FRAG_RESULT_DEPR);   GLuint i;   struct prog_instruction *inst, *last_inst;   struct brw_context *brw = c->func.brw;   /* inst->Sampler is not used by backend,       use it for fb write target and eot */   if (brw->state.nr_draw_regions > 1) {       for (i = 0 ; i < brw->state.nr_draw_regions; i++) {	   outcolor = src_reg(PROGRAM_OUTPUT, FRAG_RESULT_DATA0 + i);	   last_inst = inst = emit_op(c,		   WM_FB_WRITE, dst_mask(dst_undef(),0), 0, 0, 0,		   outcolor, payload_r0_depth, outdepth);	   inst->Sampler = (i<<1);	   if (c->fp_fragcolor_emitted) {	       outcolor = src_reg(PROGRAM_OUTPUT, FRAG_RESULT_COLR);	       last_inst = inst = emit_op(c, WM_FB_WRITE, dst_mask(dst_undef(),0),		       0, 0, 0, outcolor, payload_r0_depth, outdepth);	       inst->Sampler = (i<<1);	   }       }       last_inst->Sampler |= 1; //eot   }else {       inst = emit_op(c, WM_FB_WRITE, dst_mask(dst_undef(),0),	       0, 0, 0, outcolor, payload_r0_depth, outdepth);       inst->Sampler = 1|(0<<1);   }}/*********************************************************************** * Emit INTERP instructions ahead of first use of each attrib. */static void validate_src_regs( struct brw_wm_compile *c,			       const struct prog_instruction *inst ){   GLuint nr_args = brw_wm_nr_args( inst->Opcode );   GLuint i;   for (i = 0; i < nr_args; i++) {      if (inst->SrcReg[i].File == PROGRAM_INPUT) {	 GLuint idx = inst->SrcReg[i].Index;	 if (!(c->fp_interp_emitted & (1<<idx))) {	    emit_interp(c, idx);	 }      }   }}	 static void validate_dst_regs( struct brw_wm_compile *c,			       const struct prog_instruction *inst ){   if (inst->DstReg.File == PROGRAM_OUTPUT) {       GLuint idx = inst->DstReg.Index;       if (idx == FRAG_RESULT_COLR)	   c->fp_fragcolor_emitted = 1;   }}static void print_insns( const struct prog_instruction *insn,			 GLuint nr ){   GLuint i;   for (i = 0; i < nr; i++, insn++) {      _mesa_printf("%3d: ", i);      if (insn->Opcode < MAX_OPCODE)	 _mesa_print_instruction(insn);      else if (insn->Opcode < MAX_WM_OPCODE) {	 GLuint idx = insn->Opcode - MAX_OPCODE;	 _mesa_print_alu_instruction(insn,				     wm_opcode_strings[idx],				     3);      }      else 	 _mesa_printf("UNKNOWN\n");	      }}void brw_wm_pass_fp( struct brw_wm_compile *c ){   struct brw_fragment_program *fp = c->fp;   GLuint insn;   if (INTEL_DEBUG & DEBUG_WM) {      _mesa_printf("\n\n\npre-fp:\n");      _mesa_print_program(&fp->program.Base);       _mesa_printf("\n");   }   c->pixel_xy = src_undef();   c->delta_xy = src_undef();   c->pixel_w = src_undef();   c->nr_fp_insns = 0;   /* Emit preamble instructions:    */   for (insn = 0; insn < fp->program.Base.NumInstructions; insn++) {      const struct prog_instruction *inst = &fp->program.Base.Instructions[insn];      validate_src_regs(c, inst);      validate_dst_regs(c, inst);   }   for (insn = 0; insn < fp->program.Base.NumInstructions; insn++) {      const struct prog_instruction *inst = &fp->program.Base.Instructions[insn];      struct prog_instruction *out;      /* Check for INPUT values, emit INTERP instructions where       * necessary:       */      switch (inst->Opcode) {      case OPCODE_SWZ: 	 out = emit_insn(c, inst);	 out->Opcode = OPCODE_MOV;	 break;	       case OPCODE_ABS:	 out = emit_insn(c, inst);	 out->Opcode = OPCODE_MOV;	 out->SrcReg[0].NegateBase = 0;	 out->SrcReg[0].Abs = 1;	 break;      case OPCODE_SUB: 	 out = emit_insn(c, inst);	 out->Opcode = OPCODE_ADD;	 out->SrcReg[1].NegateBase ^= 0xf;	 break;      case OPCODE_SCS: 	 out = emit_insn(c, inst);	 /* This should probably be done in the parser. 	  */	 out->DstReg.WriteMask &= WRITEMASK_XY;	 break;	       case OPCODE_DST:	 precalc_dst(c, inst);	 break;      case OPCODE_LIT:	 precalc_lit(c, inst);	 break;      case OPCODE_TEX:	 precalc_tex(c, inst);	 break;      case OPCODE_TXP:	 precalc_txp(c, inst);	 break;      case OPCODE_TXB:	 out = emit_insn(c, inst);	 out->TexSrcUnit = fp->program.Base.SamplerUnits[inst->TexSrcUnit];	 break;      case OPCODE_XPD: 	 out = emit_insn(c, inst);	 /* This should probably be done in the parser. 	  */	 out->DstReg.WriteMask &= WRITEMASK_XYZ;	 break;      case OPCODE_KIL: 	 out = emit_insn(c, inst);	 /* This should probably be done in the parser. 	  */	 out->DstReg.WriteMask = 0;	 break;      case OPCODE_DDX:	 emit_ddx(c, inst);	 break;      case OPCODE_DDY:         emit_ddy(c, inst);	break;      case OPCODE_END:	 emit_fog(c);	 emit_fb_write(c);	 break;      case OPCODE_PRINT:	 break;	       default:	 emit_insn(c, inst);	 break;      }   }   if (INTEL_DEBUG & DEBUG_WM) {	   _mesa_printf("\n\n\npass_fp:\n");	   print_insns( c->prog_instructions, c->nr_fp_insns );	   _mesa_printf("\n");   }}

⌨️ 快捷键说明

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