Example #1
0
/* Points setup - several simplifications as all attributes are
 * constant across the face of the point (point sprites excluded!)
 */
void brw_emit_point_setup(struct brw_sf_compile *c, bool allocate)
{
   struct brw_compile *p = &c->func;
   GLuint i;

   c->flag_value = 0xff;
   c->nr_verts = 1;

   if (allocate)
      alloc_regs(c);

   copy_z_inv_w(c);

   brw_MOV(p, c->m1Cx, brw_imm_ud(0)); /* zero - move out of loop */
   brw_MOV(p, c->m2Cy, brw_imm_ud(0)); /* zero - move out of loop */

   for (i = 0; i < c->nr_setup_regs; i++)
   {
      struct brw_reg a0 = offset(c->vert[0], i);
      GLushort pc, pc_persp, pc_linear;
      bool last = calculate_masks(c, i, &pc, &pc_persp, &pc_linear);

      if (pc_persp)
      {				
	 /* This seems odd as the values are all constant, but the
	  * fragment shader will be expecting it:
	  */
	 set_predicate_control_flag_value(p, c, pc_persp);
	 brw_MUL(p, a0, a0, c->inv_w[0]);
      }


      /* The delta values are always zero, just send the starting
       * coordinate.  Again, this is to fit in with the interpolation
       * code in the fragment shader.
       */
      {
	 set_predicate_control_flag_value(p, c, pc);

	 brw_MOV(p, c->m3C0, a0); /* constant value */

	 /* Copy m0..m3 to URB.
	  */
	 brw_urb_WRITE(p,
		       brw_null_reg(),
		       0,
		       brw_vec8_grf(0, 0),
                       last ? BRW_URB_WRITE_EOT_COMPLETE
                       : BRW_URB_WRITE_NO_FLAGS,
		       4, 	/* msg len */
		       0,	/* response len */
		       i*4,	/* urb destination offset */
		       BRW_URB_SWIZZLE_TRANSPOSE);
      }
   }

   brw_set_default_predicate_control(p, BRW_PREDICATE_NONE);
}
Example #2
0
void brw_clip_emit_vue(struct brw_clip_compile *c, 
		       struct brw_indirect vert,
		       GLboolean allocate,
		       GLboolean eot,
		       GLuint header)
{
   struct brw_compile *p = &c->func;
   GLuint start = c->last_mrf;

   brw_clip_ff_sync(c);

   assert(!(allocate && eot));
   
   /* Cycle through mrf regs - probably futile as we have to wait for
    * the allocation response anyway.  Also, the order this function
    * is invoked doesn't correspond to the order the instructions will
    * be executed, so it won't have any effect in many cases.
    */
#if 0
   if (start + c->nr_regs + 1 >= MAX_MRF)
      start = 0;

   c->last_mrf = start + c->nr_regs + 1;
#endif
	
   /* Copy the vertex from vertn into m1..mN+1:
    */
   brw_copy_from_indirect(p, brw_message_reg(start+1), vert, c->nr_regs);

   /* Overwrite PrimType and PrimStart in the message header, for
    * each vertex in turn:
    */
   brw_MOV(p, get_element_ud(c->reg.R0, 2), brw_imm_ud(header));


   /* Send each vertex as a seperate write to the urb.  This
    * is different to the concept in brw_sf_emit.c, where
    * subsequent writes are used to build up a single urb
    * entry.  Each of these writes instantiates a seperate
    * urb entry - (I think... what about 'allocate'?)
    */
   brw_urb_WRITE(p, 
		 allocate ? c->reg.R0 : retype(brw_null_reg(), BRW_REGISTER_TYPE_UD),
		 start,
		 c->reg.R0,
		 allocate,
		 1,		/* used */
		 c->nr_regs + 1, /* msg length */
		 allocate ? 1 : 0, /* response_length */ 
		 eot,		/* eot */
		 1,		/* writes_complete */
		 0,		/* urb offset */
		 BRW_URB_SWIZZLE_NONE);
}
Example #3
0
void
vec4_generator::generate_vs_urb_write(vec4_instruction *inst)
{
    brw_urb_WRITE(p,
                  brw_null_reg(), /* dest */
                  inst->base_mrf, /* starting mrf reg nr */
                  brw_vec8_grf(0, 0), /* src */
                  inst->urb_write_flags,
                  inst->mlen,
                  0,		/* response len */
                  inst->offset,	/* urb destination offset */
                  BRW_URB_SWIZZLE_INTERLEAVE);
}
Example #4
0
void
vec4_generator::generate_gs_thread_end(vec4_instruction *inst)
{
    struct brw_reg src = brw_message_reg(inst->base_mrf);
    brw_urb_WRITE(p,
                  brw_null_reg(), /* dest */
                  inst->base_mrf, /* starting mrf reg nr */
                  src,
                  BRW_URB_WRITE_EOT,
                  1,              /* message len */
                  0,              /* response len */
                  0,              /* urb destination offset */
                  BRW_URB_SWIZZLE_INTERLEAVE);
}
Example #5
0
void
vec4_generator::generate_gs_urb_write(vec4_instruction *inst)
{
    struct brw_reg src = brw_message_reg(inst->base_mrf);
    brw_urb_WRITE(p,
                  brw_null_reg(), /* dest */
                  inst->base_mrf, /* starting mrf reg nr */
                  src,
                  inst->urb_write_flags,
                  inst->mlen,
                  0,             /* response len */
                  inst->offset,  /* urb destination offset */
                  BRW_URB_SWIZZLE_INTERLEAVE);
}
Example #6
0
/**
 * Emit a vertex using the URB_WRITE message.  Use the contents of
 * c->reg.header for the message header, and the registers starting at \c vert
 * for the vertex data.
 *
 * If \c last is true, then this is the last vertex, so no further URB space
 * should be allocated, and this message should end the thread.
 *
 * If \c last is false, then a new URB entry will be allocated, and its handle
 * will be stored in DWORD 0 of c->reg.header for use in the next URB_WRITE
 * message.
 */
static void brw_ff_gs_emit_vue(struct brw_ff_gs_compile *c,
                               struct brw_reg vert,
                               bool last)
{
   struct brw_codegen *p = &c->func;
   int write_offset = 0;
   bool complete = false;

   do {
      /* We can't write more than 14 registers at a time to the URB */
      int write_len = MIN2(c->nr_regs - write_offset, 14);
      if (write_len == c->nr_regs - write_offset)
         complete = true;

      /* Copy the vertex from vertn into m1..mN+1:
       */
      brw_copy8(p, brw_message_reg(1), offset(vert, write_offset), write_len);

      /* Send the vertex data to the URB.  If this is the last write for this
       * vertex, then we mark it as complete, and either end the thread or
       * allocate another vertex URB entry (depending whether this is the last
       * vertex).
       */
      enum brw_urb_write_flags flags;
      if (!complete)
         flags = BRW_URB_WRITE_NO_FLAGS;
      else if (last)
         flags = BRW_URB_WRITE_EOT_COMPLETE;
      else
         flags = BRW_URB_WRITE_ALLOCATE_COMPLETE;
      brw_urb_WRITE(p,
                    (flags & BRW_URB_WRITE_ALLOCATE) ? c->reg.temp
                    : retype(brw_null_reg(), BRW_REGISTER_TYPE_UD),
                    0,
                    c->reg.header,
                    flags,
                    write_len + 1, /* msg length */
                    (flags & BRW_URB_WRITE_ALLOCATE) ? 1
                    : 0, /* response length */
                    write_offset,  /* urb offset */
                    BRW_URB_SWIZZLE_NONE);
      write_offset += write_len;
   } while (!complete);

   if (!last) {
      brw_MOV(p, get_element_ud(c->reg.header, 0),
              get_element_ud(c->reg.temp, 0));
   }
}
Example #7
0
static void brw_gs_emit_vue(struct brw_gs_compile *c, 
			    struct brw_reg vert,
			    GLboolean last,
			    GLuint header)
{
   struct brw_compile *p = &c->func;
   struct intel_context *intel = &c->func.brw->intel;
   GLboolean allocate = !last;
   struct brw_reg temp;

   if (intel->gen < 6)
       temp = c->reg.R0;
   else {
       temp = c->reg.temp;
       brw_MOV(p, retype(temp, BRW_REGISTER_TYPE_UD),
	       retype(c->reg.R0, BRW_REGISTER_TYPE_UD));
   }

   /* Overwrite PrimType and PrimStart in the message header, for
    * each vertex in turn:
    */
   brw_MOV(p, get_element_ud(temp, 2), brw_imm_ud(header));

   /* Copy the vertex from vertn into m1..mN+1:
    */
   brw_copy8(p, brw_message_reg(1), vert, c->nr_regs);

   /* Send each vertex as a seperate write to the urb.  This is
    * different to the concept in brw_sf_emit.c, where subsequent
    * writes are used to build up a single urb entry.  Each of these
    * writes instantiates a seperate urb entry, and a new one must be
    * allocated each time.
    */
   brw_urb_WRITE(p, 
		 allocate ? temp : retype(brw_null_reg(), BRW_REGISTER_TYPE_UD),
		 0,
		 temp,
		 allocate,
		 1,		/* used */
		 c->nr_regs + 1, /* msg length */
		 allocate ? 1 : 0, /* response length */
		 allocate ? 0 : 1, /* eot */
		 1,		/* writes_complete */
		 0,		/* urb offset */
		 BRW_URB_SWIZZLE_NONE);

   if (intel->gen >= 6 && allocate)
       brw_MOV(p, get_element_ud(c->reg.R0, 0), get_element_ud(temp, 0));
}
Example #8
0
void
vec4_generator::generate_urb_write(vec4_instruction *inst)
{
   brw_urb_WRITE(p,
		 brw_null_reg(), /* dest */
		 inst->base_mrf, /* starting mrf reg nr */
		 brw_vec8_grf(0, 0), /* src */
		 false,		/* allocate */
		 true,		/* used */
		 inst->mlen,
		 0,		/* response len */
		 inst->eot,	/* eot */
		 inst->eot,	/* writes complete */
		 inst->offset,	/* urb destination offset */
		 BRW_URB_SWIZZLE_INTERLEAVE);
}
Example #9
0
/**
 * De-allocate the URB entry that was previously allocated to this thread
 * (without writing any vertex data to it), and terminate the thread.  This is
 * used to implement RASTERIZER_DISCARD functionality.
 */
static void brw_gs_terminate(struct brw_gs_compile *c)
{
   struct brw_compile *p = &c->func;
   brw_urb_WRITE(p,
                 retype(brw_null_reg(), BRW_REGISTER_TYPE_UD), /* dest */
                 0, /* msg_reg_nr */
                 c->reg.header, /* src0 */
                 false, /* allocate */
                 false, /* used */
                 1, /* msg_length */
                 0, /* response_length */
                 true, /* eot */
                 true, /* writes_complete */
                 0, /* offset */
                 BRW_URB_SWIZZLE_NONE);
}
void brw_clip_kill_thread(struct brw_clip_compile *c)
{
   struct brw_codegen *p = &c->func;

   brw_clip_ff_sync(c);
   /* Send an empty message to kill the thread and release any
    * allocated urb entry:
    */
   brw_urb_WRITE(p,
		 retype(brw_null_reg(), BRW_REGISTER_TYPE_UD),
		 0,
		 c->reg.R0,
                 BRW_URB_WRITE_UNUSED | BRW_URB_WRITE_EOT_COMPLETE,
		 1, 		/* msg len */
		 0, 		/* response len */
		 0,
		 BRW_URB_SWIZZLE_NONE);
}
Example #11
0
void brw_clip_kill_thread(struct brw_clip_compile *c)
{
   struct brw_compile *p = &c->func;

   /* Send an empty message to kill the thread and release any
    * allocated urb entry:
    */
   brw_urb_WRITE(p, 
		 retype(brw_null_reg(), BRW_REGISTER_TYPE_UD),
		 0,
		 c->reg.R0,
		 0,		/* allocate */
		 0,		/* used */
		 1, 		/* msg len */
		 0, 		/* response len */
		 1, 		/* eot */
		 1,		/* writes complete */
		 0,
		 BRW_URB_SWIZZLE_NONE);
}
void brw_clip_emit_vue(struct brw_clip_compile *c,
		       struct brw_indirect vert,
                       enum brw_urb_write_flags flags,
		       GLuint header)
{
   struct brw_codegen *p = &c->func;
   bool allocate = flags & BRW_URB_WRITE_ALLOCATE;

   brw_clip_ff_sync(c);

   /* Any URB entry that is allocated must subsequently be used or discarded,
    * so it doesn't make sense to mark EOT and ALLOCATE at the same time.
    */
   assert(!(allocate && (flags & BRW_URB_WRITE_EOT)));

   /* Copy the vertex from vertn into m1..mN+1:
    */
   brw_copy_from_indirect(p, brw_message_reg(1), vert, c->nr_regs);

   /* Overwrite PrimType and PrimStart in the message header, for
    * each vertex in turn:
    */
   brw_MOV(p, get_element_ud(c->reg.R0, 2), brw_imm_ud(header));


   /* Send each vertex as a separate write to the urb.  This
    * is different to the concept in brw_sf_emit.c, where
    * subsequent writes are used to build up a single urb
    * entry.  Each of these writes instantiates a separate
    * urb entry - (I think... what about 'allocate'?)
    */
   brw_urb_WRITE(p,
		 allocate ? c->reg.R0 : retype(brw_null_reg(), BRW_REGISTER_TYPE_UD),
		 0,
		 c->reg.R0,
                 flags,
		 c->nr_regs + 1, /* msg length */
		 allocate ? 1 : 0, /* response_length */
		 0,		/* urb offset */
		 BRW_URB_SWIZZLE_NONE);
}
Example #13
0
void brw_clip_emit_vue(struct brw_clip_compile *c, 
		       struct brw_indirect vert,
		       bool allocate,
		       bool eot,
		       GLuint header)
{
   struct brw_compile *p = &c->func;

   brw_clip_ff_sync(c);

   assert(!(allocate && eot));

   /* Copy the vertex from vertn into m1..mN+1:
    */
   brw_copy_from_indirect(p, brw_message_reg(1), vert, c->nr_regs);

   /* Overwrite PrimType and PrimStart in the message header, for
    * each vertex in turn:
    */
   brw_MOV(p, get_element_ud(c->reg.R0, 2), brw_imm_ud(header));


   /* Send each vertex as a seperate write to the urb.  This
    * is different to the concept in brw_sf_emit.c, where
    * subsequent writes are used to build up a single urb
    * entry.  Each of these writes instantiates a seperate
    * urb entry - (I think... what about 'allocate'?)
    */
   brw_urb_WRITE(p, 
		 allocate ? c->reg.R0 : retype(brw_null_reg(), BRW_REGISTER_TYPE_UD),
		 0,
		 c->reg.R0,
		 allocate,
		 1,		/* used */
		 c->nr_regs + 1, /* msg length */
		 allocate ? 1 : 0, /* response_length */ 
		 eot,		/* eot */
		 1,		/* writes_complete */
		 0,		/* urb offset */
		 BRW_URB_SWIZZLE_NONE);
}
Example #14
0
/**
 * Emit a vertex using the URB_WRITE message.  Use the contents of
 * c->reg.header for the message header, and the registers starting at \c vert
 * for the vertex data.
 *
 * If \c last is true, then this is the last vertex, so no further URB space
 * should be allocated, and this message should end the thread.
 *
 * If \c last is false, then a new URB entry will be allocated, and its handle
 * will be stored in DWORD 0 of c->reg.header for use in the next URB_WRITE
 * message.
 */
static void brw_gs_emit_vue(struct brw_gs_compile *c, 
			    struct brw_reg vert,
			    bool last)
{
   struct brw_compile *p = &c->func;
   bool allocate = !last;

   /* Copy the vertex from vertn into m1..mN+1:
    */
   brw_copy8(p, brw_message_reg(1), vert, c->nr_regs);

   /* Send each vertex as a seperate write to the urb.  This is
    * different to the concept in brw_sf_emit.c, where subsequent
    * writes are used to build up a single urb entry.  Each of these
    * writes instantiates a seperate urb entry, and a new one must be
    * allocated each time.
    */
   brw_urb_WRITE(p, 
		 allocate ? c->reg.temp
                          : retype(brw_null_reg(), BRW_REGISTER_TYPE_UD),
		 0,
		 c->reg.header,
		 allocate,
		 1,		/* used */
		 c->nr_regs + 1, /* msg length */
		 allocate ? 1 : 0, /* response length */
		 allocate ? 0 : 1, /* eot */
		 1,		/* writes_complete */
		 0,		/* urb offset */
		 BRW_URB_SWIZZLE_NONE);

   if (allocate) {
      brw_MOV(p, get_element_ud(c->reg.header, 0),
              get_element_ud(c->reg.temp, 0));
   }
}
void brw_emit_point_sprite_setup( struct brw_sf_compile *c, GLboolean allocate)
{
   struct brw_compile *p = &c->func;
   GLuint i;

   c->nr_verts = 1;

   if (allocate)
      alloc_regs(c);

   copy_z_inv_w(c);
   for (i = 0; i < c->nr_setup_regs; i++)
   {
      struct brw_sf_point_tex *tex = &c->point_attrs[c->idx_to_attr[2*i]];
      struct brw_reg a0 = offset(c->vert[0], i);
      GLushort pc, pc_persp, pc_linear;
      GLboolean last = calculate_masks(c, i, &pc, &pc_persp, &pc_linear);
            
      if (pc_persp)
      {				
	  if (!tex->CoordReplace) {
	      brw_set_predicate_control_flag_value(p, pc_persp);
	      brw_MUL(p, a0, a0, c->inv_w[0]);
	  }
      }

      if (tex->CoordReplace) {
	  /* Caculate 1.0/PointWidth */
	  brw_math(&c->func,
		  c->tmp,
		  BRW_MATH_FUNCTION_INV,
		  BRW_MATH_SATURATE_NONE,
		  0,
		  c->dx0,
		  BRW_MATH_DATA_SCALAR,
		  BRW_MATH_PRECISION_FULL);

	  if (c->key.SpriteOrigin == GL_LOWER_LEFT) {
	   	brw_MUL(p, c->m1Cx, c->tmp, c->inv_w[0]);
		brw_MOV(p, vec1(suboffset(c->m1Cx, 1)), brw_imm_f(0.0));
	  	brw_MUL(p, c->m2Cy, c->tmp, negate(c->inv_w[0]));
		brw_MOV(p, vec1(suboffset(c->m2Cy, 0)), brw_imm_f(0.0));
	  } else {
	   	brw_MUL(p, c->m1Cx, c->tmp, c->inv_w[0]);
		brw_MOV(p, vec1(suboffset(c->m1Cx, 1)), brw_imm_f(0.0));
	  	brw_MUL(p, c->m2Cy, c->tmp, c->inv_w[0]);
		brw_MOV(p, vec1(suboffset(c->m2Cy, 0)), brw_imm_f(0.0));
	  }
      } else {
	  brw_MOV(p, c->m1Cx, brw_imm_ud(0));
	  brw_MOV(p, c->m2Cy, brw_imm_ud(0));
      }

      {
	 brw_set_predicate_control_flag_value(p, pc); 
	 if (tex->CoordReplace) {
	     if (c->key.SpriteOrigin == GL_LOWER_LEFT) {
		 brw_MUL(p, c->m3C0, c->inv_w[0], brw_imm_f(1.0));
		 brw_MOV(p, vec1(suboffset(c->m3C0, 0)), brw_imm_f(0.0));
	     }
	     else
		 brw_MOV(p, c->m3C0, brw_imm_f(0.0));
	 } else {
	 	brw_MOV(p, c->m3C0, a0); /* constant value */
	 }

	 /* Copy m0..m3 to URB. 
	  */
	 brw_urb_WRITE(p, 
		       brw_null_reg(),
		       0,
		       brw_vec8_grf(0, 0),
		       0, 	/* allocate */
		       1,	/* used */
		       4, 	/* msg len */
		       0,	/* response len */
		       last, 	/* eot */
		       last, 	/* writes complete */
		       i*4,	/* urb destination offset */
		       BRW_URB_SWIZZLE_TRANSPOSE);
      }
   }
}
Example #16
0
void brw_emit_point_sprite_setup(struct brw_sf_compile *c, bool allocate)
{
   struct brw_compile *p = &c->func;
   GLuint i;

   c->flag_value = 0xff;
   c->nr_verts = 1;

   if (allocate)
      alloc_regs(c);

   copy_z_inv_w(c);
   for (i = 0; i < c->nr_setup_regs; i++)
   {
      struct brw_reg a0 = offset(c->vert[0], i);
      GLushort pc, pc_persp, pc_linear, pc_coord_replace;
      bool last = calculate_masks(c, i, &pc, &pc_persp, &pc_linear);

      pc_coord_replace = calculate_point_sprite_mask(c, i);
      pc_persp &= ~pc_coord_replace;

      if (pc_persp) {
	 set_predicate_control_flag_value(p, c, pc_persp);
	 brw_MUL(p, a0, a0, c->inv_w[0]);
      }

      /* Point sprite coordinate replacement: A texcoord with this
       * enabled gets replaced with the value (x, y, 0, 1) where x and
       * y vary from 0 to 1 across the horizontal and vertical of the
       * point.
       */
      if (pc_coord_replace) {
	 set_predicate_control_flag_value(p, c, pc_coord_replace);
	 /* Caculate 1.0/PointWidth */
	 gen4_math(&c->func,
		   c->tmp,
		   BRW_MATH_FUNCTION_INV,
		   0,
		   c->dx0,
		   BRW_MATH_DATA_SCALAR,
		   BRW_MATH_PRECISION_FULL);

	 brw_set_default_access_mode(p, BRW_ALIGN_16);

	 /* dA/dx, dA/dy */
	 brw_MOV(p, c->m1Cx, brw_imm_f(0.0));
	 brw_MOV(p, c->m2Cy, brw_imm_f(0.0));
	 brw_MOV(p, brw_writemask(c->m1Cx, WRITEMASK_X), c->tmp);
	 if (c->key.sprite_origin_lower_left) {
	    brw_MOV(p, brw_writemask(c->m2Cy, WRITEMASK_Y), negate(c->tmp));
	 } else {
	    brw_MOV(p, brw_writemask(c->m2Cy, WRITEMASK_Y), c->tmp);
	 }

	 /* attribute constant offset */
	 brw_MOV(p, c->m3C0, brw_imm_f(0.0));
	 if (c->key.sprite_origin_lower_left) {
	    brw_MOV(p, brw_writemask(c->m3C0, WRITEMASK_YW), brw_imm_f(1.0));
	 } else {
	    brw_MOV(p, brw_writemask(c->m3C0, WRITEMASK_W), brw_imm_f(1.0));
	 }

	 brw_set_default_access_mode(p, BRW_ALIGN_1);
      }

      if (pc & ~pc_coord_replace) {
	 set_predicate_control_flag_value(p, c, pc & ~pc_coord_replace);
	 brw_MOV(p, c->m1Cx, brw_imm_ud(0));
	 brw_MOV(p, c->m2Cy, brw_imm_ud(0));
	 brw_MOV(p, c->m3C0, a0); /* constant value */
      }


      set_predicate_control_flag_value(p, c, pc);
      /* Copy m0..m3 to URB. */
      brw_urb_WRITE(p,
		    brw_null_reg(),
		    0,
		    brw_vec8_grf(0, 0),
                    last ? BRW_URB_WRITE_EOT_COMPLETE
                    : BRW_URB_WRITE_NO_FLAGS,
		    4, 	/* msg len */
		    0,	/* response len */
		    i*4,	/* urb destination offset */
		    BRW_URB_SWIZZLE_TRANSPOSE);
   }

   brw_set_default_predicate_control(p, BRW_PREDICATE_NONE);
}
Example #17
0
void brw_emit_line_setup(struct brw_sf_compile *c, bool allocate)
{
   struct brw_compile *p = &c->func;
   GLuint i;

   c->flag_value = 0xff;
   c->nr_verts = 2;

   if (allocate)
      alloc_regs(c);

   invert_det(c);
   copy_z_inv_w(c);

   if (c->has_flat_shading)
      do_flatshade_line(c);

   for (i = 0; i < c->nr_setup_regs; i++)
   {
      /* Pair of incoming attributes:
       */
      struct brw_reg a0 = offset(c->vert[0], i);
      struct brw_reg a1 = offset(c->vert[1], i);
      GLushort pc, pc_persp, pc_linear;
      bool last = calculate_masks(c, i, &pc, &pc_persp, &pc_linear);

      if (pc_persp)
      {
	 set_predicate_control_flag_value(p, c, pc_persp);
	 brw_MUL(p, a0, a0, c->inv_w[0]);
	 brw_MUL(p, a1, a1, c->inv_w[1]);
      }

      /* Calculate coefficients for position, color:
       */
      if (pc_linear) {
	 set_predicate_control_flag_value(p, c, pc_linear);

	 brw_ADD(p, c->a1_sub_a0, a1, negate(a0));

 	 brw_MUL(p, c->tmp, c->a1_sub_a0, c->dx0);
	 brw_MUL(p, c->m1Cx, c->tmp, c->inv_det);
		
	 brw_MUL(p, c->tmp, c->a1_sub_a0, c->dy0);
	 brw_MUL(p, c->m2Cy, c->tmp, c->inv_det);
      }

      {
	 set_predicate_control_flag_value(p, c, pc);

	 /* start point for interpolation
	  */
	 brw_MOV(p, c->m3C0, a0);

	 /* Copy m0..m3 to URB.
	  */
	 brw_urb_WRITE(p,
		       brw_null_reg(),
		       0,
		       brw_vec8_grf(0, 0),
                       last ? BRW_URB_WRITE_EOT_COMPLETE
                       : BRW_URB_WRITE_NO_FLAGS,
		       4, 	/* msg len */
		       0,	/* response len */
		       i*4,	/* urb destination offset */
		       BRW_URB_SWIZZLE_TRANSPOSE);
      }
   }

   brw_set_default_predicate_control(p, BRW_PREDICATE_NONE);
}
Example #18
0
void brw_emit_tri_setup(struct brw_sf_compile *c, bool allocate)
{
   struct brw_compile *p = &c->func;
   GLuint i;

   c->flag_value = 0xff;
   c->nr_verts = 3;

   if (allocate)
      alloc_regs(c);

   invert_det(c);
   copy_z_inv_w(c);

   if (c->key.do_twoside_color)
      do_twoside_color(c);

   if (c->has_flat_shading)
      do_flatshade_triangle(c);


   for (i = 0; i < c->nr_setup_regs; i++)
   {
      /* Pair of incoming attributes:
       */
      struct brw_reg a0 = offset(c->vert[0], i);
      struct brw_reg a1 = offset(c->vert[1], i);
      struct brw_reg a2 = offset(c->vert[2], i);
      GLushort pc, pc_persp, pc_linear;
      bool last = calculate_masks(c, i, &pc, &pc_persp, &pc_linear);

      if (pc_persp)
      {
	 set_predicate_control_flag_value(p, c, pc_persp);
	 brw_MUL(p, a0, a0, c->inv_w[0]);
	 brw_MUL(p, a1, a1, c->inv_w[1]);
	 brw_MUL(p, a2, a2, c->inv_w[2]);
      }


      /* Calculate coefficients for interpolated values:
       */
      if (pc_linear)
      {
	 set_predicate_control_flag_value(p, c, pc_linear);

	 brw_ADD(p, c->a1_sub_a0, a1, negate(a0));
	 brw_ADD(p, c->a2_sub_a0, a2, negate(a0));

	 /* calculate dA/dx
	  */
	 brw_MUL(p, brw_null_reg(), c->a1_sub_a0, c->dy2);
	 brw_MAC(p, c->tmp, c->a2_sub_a0, negate(c->dy0));
	 brw_MUL(p, c->m1Cx, c->tmp, c->inv_det);
		
	 /* calculate dA/dy
	  */
	 brw_MUL(p, brw_null_reg(), c->a2_sub_a0, c->dx0);
	 brw_MAC(p, c->tmp, c->a1_sub_a0, negate(c->dx2));
	 brw_MUL(p, c->m2Cy, c->tmp, c->inv_det);
      }

      {
	 set_predicate_control_flag_value(p, c, pc);
	 /* start point for interpolation
	  */
	 brw_MOV(p, c->m3C0, a0);

	 /* Copy m0..m3 to URB.  m0 is implicitly copied from r0 in
	  * the send instruction:
	  */	
	 brw_urb_WRITE(p,
		       brw_null_reg(),
		       0,
		       brw_vec8_grf(0, 0), /* r0, will be copied to m0 */
                       last ? BRW_URB_WRITE_EOT_COMPLETE
                       : BRW_URB_WRITE_NO_FLAGS,
		       4, 	/* msg len */
		       0,	/* response len */
		       i*4,	/* offset */
		       BRW_URB_SWIZZLE_TRANSPOSE); /* XXX: Swizzle control "SF to windower" */
      }
   }

   brw_set_default_predicate_control(p, BRW_PREDICATE_NONE);
}