Exemple #1
0
static void emit_fb_write( struct brw_wm_compile *c )
{
   struct brw_fp_src payload_r0_depth = src_reg(BRW_FILE_PAYLOAD, PAYLOAD_DEPTH);
   struct brw_fp_src outdepth = find_output_by_semantic(c, TGSI_SEMANTIC_POSITION, 0);
   GLuint i;


   outdepth = src_scalar(outdepth, Z);

   for (i = 0 ; i < c->key.nr_cbufs; i++) {
      struct brw_fp_src outcolor;
      
      outcolor = find_output_by_semantic(c, TGSI_SEMANTIC_COLOR, i);

      /* Use emit_tex_op so that we can specify the inst->target
       * field, which is abused to contain the FB write target and the
       * EOT marker
       */
      emit_tex_op(c, WM_FB_WRITE,
		  dst_undef(),
		  (i == c->key.nr_cbufs - 1), /* EOT */
		  i,
                  0,            /* no sampler */
		  outcolor,
		  payload_r0_depth,
		  outdepth);
   }
}
Exemple #2
0
static void emit_render_target_writes( struct brw_wm_compile *c )
{
   struct prog_src_register payload_r0_depth = src_reg(PROGRAM_PAYLOAD, PAYLOAD_DEPTH);
   struct prog_src_register outdepth = src_reg(PROGRAM_OUTPUT, FRAG_RESULT_DEPTH);
   struct prog_src_register outcolor;
   GLuint i;

   struct prog_instruction *inst, *last_inst;

   /* The inst->Aux field is used for FB write target and the EOT marker */

   if (c->key.nr_color_regions > 1) {
      for (i = 0 ; i < c->key.nr_color_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, outcolor, payload_r0_depth, outdepth);
         inst->Aux = INST_AUX_TARGET(i);
         if (c->fp_fragcolor_emitted) {
            outcolor = src_reg(PROGRAM_OUTPUT, FRAG_RESULT_COLOR);
            last_inst = inst = emit_op(c, WM_FB_WRITE, dst_mask(dst_undef(), 0),
                                       0, outcolor, payload_r0_depth, outdepth);
            inst->Aux = INST_AUX_TARGET(i);
         }
      }
      last_inst->Aux |= INST_AUX_EOT;
   }
   else {
      /* if gl_FragData[0] is written, use it, else use gl_FragColor */
      if (c->fp->program.Base.OutputsWritten & BITFIELD64_BIT(FRAG_RESULT_DATA0))
         outcolor = src_reg(PROGRAM_OUTPUT, FRAG_RESULT_DATA0);
      else 
         outcolor = src_reg(PROGRAM_OUTPUT, FRAG_RESULT_COLOR);

      inst = emit_op(c, WM_FB_WRITE, dst_mask(dst_undef(),0),
                     0, outcolor, payload_r0_depth, outdepth);
      inst->Aux = INST_AUX_EOT | INST_AUX_TARGET(0);
   }
}
Exemple #3
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);

   emit_op(c,
	   WM_FB_WRITE,
	   dst_mask(dst_undef(),0),
	   0, 0, 0,
	   outcolor,
	   payload_r0_depth,
	   outdepth);
}
Exemple #4
0
/**
 * Some TEX instructions require extra code, cube map coordinate
 * normalization, or coordinate scaling for RECT textures, etc.
 * This function emits those extra instructions and the TEX
 * instruction itself.
 */
static void precalc_tex( struct brw_wm_compile *c,
			 struct brw_fp_dst dst,
			 unsigned target,
			 unsigned unit,
			 struct brw_fp_src src0,
			 struct brw_fp_src sampler )
{
   struct brw_fp_src coord;
   struct brw_fp_dst tmp = dst_undef();

   assert(unit < BRW_MAX_TEX_UNIT);

   /* Cubemap: find longest component of coord vector and normalize
    * it.
    */
   if (target == TGSI_TEXTURE_CUBE) {
      struct brw_fp_src tmpsrc;

      tmp = get_temp(c);
      tmpsrc = src_reg_from_dst(tmp);

      /* tmp = abs(src0) */
      emit_op1(c, 
	       TGSI_OPCODE_MOV,
	       tmp,
	       src_abs(src0));

      /* tmp.X = MAX(tmp.X, tmp.Y) */
      emit_op2(c, TGSI_OPCODE_MAX,
	       dst_mask(tmp, BRW_WRITEMASK_X),
	       src_scalar(tmpsrc, X),
	       src_scalar(tmpsrc, Y));

      /* tmp.X = MAX(tmp.X, tmp.Z) */
      emit_op2(c, TGSI_OPCODE_MAX,
	       dst_mask(tmp, BRW_WRITEMASK_X),
	       tmpsrc,
	       src_scalar(tmpsrc, Z));

      /* tmp.X = 1 / tmp.X */
      emit_op1(c, TGSI_OPCODE_RCP,
	      dst_mask(tmp, BRW_WRITEMASK_X),
	      tmpsrc);

      /* tmp = src0 * tmp.xxxx */
      emit_op2(c, TGSI_OPCODE_MUL,
	       tmp,
	       src0,
	       src_scalar(tmpsrc, X));

      coord = tmpsrc;
   }
   else if (target == TGSI_TEXTURE_RECT ||
	    target == TGSI_TEXTURE_SHADOWRECT) {
      /* XXX: need a mechanism for internally generated constants.
       */
      coord = src0;
   }
   else {
      coord = src0;
   }

   /* 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)) {
      /* convert ycbcr to RGBA */
      GLboolean  swap_uv = c->key.yuvtex_swap_mask & (1<<unit);
      struct brw_fp_dst tmp = get_temp(c);
      struct brw_fp_src tmpsrc = src_reg_from_dst(tmp);
      struct brw_fp_src C0 = src_imm4f( c,  -.5, -.0625, -.5, 1.164 );
      struct brw_fp_src C1 = src_imm4f( c, 1.596, -0.813, 2.018, -.391 );
     
      /* tmp     = TEX ...
       */
      emit_tex_op(c, 
                  TGSI_OPCODE_TEX,
                  dst_saturate(tmp, dst.saturate),
                  unit,
                  target,
                  sampler.index,
                  coord,
                  src_undef(),
                  src_undef());

      /* tmp.xyz =  ADD TMP, C0
       */
      emit_op2(c, TGSI_OPCODE_ADD,
	       dst_mask(tmp, BRW_WRITEMASK_XYZ),
	       tmpsrc,
	       C0);

      /* YUV.y   = MUL YUV.y, C0.w
       */
      emit_op2(c, TGSI_OPCODE_MUL,
	       dst_mask(tmp, BRW_WRITEMASK_Y),
	       tmpsrc,
	       src_scalar(C0, W));

      /* 
       * if (UV swaped)
       *     RGB.xyz = MAD YUV.zzx, C1, YUV.y
       * else
       *     RGB.xyz = MAD YUV.xxz, C1, YUV.y
       */

      emit_op3(c, TGSI_OPCODE_MAD,
	       dst_mask(dst, BRW_WRITEMASK_XYZ),
	       ( swap_uv ? 
		 src_swizzle(tmpsrc, Z,Z,X,X) : 
		 src_swizzle(tmpsrc, X,X,Z,Z)),
	       C1,
	       src_scalar(tmpsrc, Y));

      /*  RGB.y   = MAD YUV.z, C1.w, RGB.y
       */
      emit_op3(c,
	       TGSI_OPCODE_MAD,
	       dst_mask(dst, BRW_WRITEMASK_Y),
	       src_scalar(tmpsrc, Z),
	       src_scalar(C1, W),
	       src_scalar(src_reg_from_dst(dst), Y));

      release_temp(c, tmp);
   }
   else {
      /* ordinary RGBA tex instruction */
      emit_tex_op(c, 
                  TGSI_OPCODE_TEX,
                  dst,
                  unit,
                  target,
                  sampler.index,
                  coord,
                  src_undef(),
                  src_undef());
   }

   /* XXX: add GL_EXT_texture_swizzle support to gallium -- by
    * generating shader variants in mesa state tracker.
    */

   /* Release this temp if we ended up allocating it:
    */
   if (!dst_is_undef(tmp))
      release_temp(c, tmp);
}
Exemple #5
0
static void emit_insn( struct brw_wm_compile *c,
		       const struct tgsi_full_instruction *inst )
{
   unsigned opcode = inst->Instruction.Opcode;
   struct brw_fp_dst dst;
   struct brw_fp_src src[3];
   int i;

   dst = translate_dst( c, &inst->Dst[0],
			inst->Instruction.Saturate );

   for (i = 0; i < inst->Instruction.NumSrcRegs; i++)
      src[i] = translate_src( c, &inst->Src[i] );
   
   switch (opcode) {
   case TGSI_OPCODE_ABS:
      emit_op1(c, TGSI_OPCODE_MOV,
	       dst, 
	       src_abs(src[0]));
      break;

   case TGSI_OPCODE_SUB: 
      emit_op2(c, TGSI_OPCODE_ADD,
	       dst,
	       src[0],
	       src_negate(src[1]));
      break;

   case TGSI_OPCODE_SCS: 
      emit_op1(c, TGSI_OPCODE_SCS,
	       dst_mask(dst, BRW_WRITEMASK_XY),
	       src[0]);
      break;
	 
   case TGSI_OPCODE_DST:
      precalc_dst(c, dst, src[0], src[1]);
      break;

   case TGSI_OPCODE_LIT:
      precalc_lit(c, dst, src[0]);
      break;

   case TGSI_OPCODE_TEX:
      precalc_tex(c, dst,
		  inst->Texture.Texture,
		  src[1].index,	/* use sampler unit for tex idx */
		  src[0],       /* coord */
                  src[1]);      /* sampler */
      break;

   case TGSI_OPCODE_TXP:
      precalc_txp(c, dst,
		  inst->Texture.Texture,
		  src[1].index,	/* use sampler unit for tex idx */
		  src[0],       /* coord */
                  src[1]);      /* sampler */
      break;

   case TGSI_OPCODE_TXB:
      /* XXX: TXB not done
       */
      precalc_tex(c, dst,
		  inst->Texture.Texture,
		  src[1].index,	/* use sampler unit for tex idx*/
		  src[0],
                  src[1]);
      break;

   case TGSI_OPCODE_XPD: 
      emit_op2(c, TGSI_OPCODE_XPD,
	       dst_mask(dst, BRW_WRITEMASK_XYZ),
	       src[0], 
	       src[1]);
      break;

   case TGSI_OPCODE_KIL: 
      emit_op1(c, TGSI_OPCODE_KIL,
	       dst_mask(dst_undef(), 0),
	       src[0]);
      break;

   case TGSI_OPCODE_END:
      emit_fb_write(c);
      break;
   default:
      if (!c->key.has_flow_control &&
	  brw_wm_is_scalar_result(opcode))
	 emit_scalar_insn(c, opcode, dst, src[0], src[1], src[2]);
      else
	 emit_op3(c, opcode, dst, src[0], src[1], src[2]);
      break;
   }
}