diff options
| author | Eric Anholt <eric@anholt.net> | 2010-03-08 12:12:31 -0800 | 
|---|---|---|
| committer | Eric Anholt <eric@anholt.net> | 2010-03-08 14:23:18 -0800 | 
| commit | bc632d04370566c1156cbd0345fe303834f0b910 (patch) | |
| tree | bd3d39bc412503773b627aae68c0e887371f81db | |
| parent | 1d84808dc045d7fcf2fade8d1504bc25e7c5041a (diff) | |
i965: Fix up the handling of point sprite coordinate replacement.
The code was walking over the regs of pairs of attributes and checking
whether the attribute with a given reg index had point sprite enabled.
So the point sprite setup code was rarely even getting executed.
Instead, we need to determine which channels of a reg need point
sprite coordinate replacement.  In addition, it was multiplying the
attribute by 1/w, when it's supposed to cover (0, 1) in each direction
regardless of w, and it wasn't filling in the Z and W components of
the texcoord as specified.
Fixes piglit point-sprite and the spriteblast demo.  Bug #24431, #22245.
| -rw-r--r-- | src/mesa/drivers/dri/i965/brw_sf.c | 21 | ||||
| -rw-r--r-- | src/mesa/drivers/dri/i965/brw_sf.h | 6 | ||||
| -rw-r--r-- | src/mesa/drivers/dri/i965/brw_sf_emit.c | 135 | 
3 files changed, 96 insertions, 66 deletions
| diff --git a/src/mesa/drivers/dri/i965/brw_sf.c b/src/mesa/drivers/dri/i965/brw_sf.c index 8e6839b812..57d1c29ade 100644 --- a/src/mesa/drivers/dri/i965/brw_sf.c +++ b/src/mesa/drivers/dri/i965/brw_sf.c @@ -46,7 +46,6 @@  static void compile_sf_prog( struct brw_context *brw,  			     struct brw_sf_prog_key *key )  { -   GLcontext *ctx = &brw->intel.ctx;     struct brw_sf_compile c;     const GLuint *program;     GLuint program_size; @@ -69,20 +68,14 @@ static void compile_sf_prog( struct brw_context *brw,     /* Construct map from attribute number to position in the vertex.      */ -   for (i = idx = 0; i < VERT_RESULT_MAX; i++)  +   for (i = idx = 0; i < VERT_RESULT_MAX; i++) {        if (c.key.attrs & BITFIELD64_BIT(i)) {  	 c.attr_to_idx[i] = idx;  	 c.idx_to_attr[idx] = i; -	 if (i >= VERT_RESULT_TEX0 && i <= VERT_RESULT_TEX7) { -            c.point_attrs[i].CoordReplace =  -               ctx->Point.CoordReplace[i - VERT_RESULT_TEX0]; -	 } -         else { -            c.point_attrs[i].CoordReplace = GL_FALSE; -         }  	 idx++;        } -    +   } +     /* Which primitive?  Or all three?       */     switch (key->primitive) { @@ -162,6 +155,14 @@ static void upload_sf_prog(struct brw_context *brw)     }     key.do_point_sprite = ctx->Point.PointSprite; +   if (key.do_point_sprite) { +      int i; + +      for (i = 0; i < 8; i++) { +	 if (ctx->Point.CoordReplace[i]) +	    key.point_sprite_coord_replace |= (1 << i); +      } +   }     key.sprite_origin_lower_left = (ctx->Point.SpriteOrigin == GL_LOWER_LEFT);     /* _NEW_LIGHT */     key.do_flat_shading = (ctx->Light.ShadeModel == GL_FLAT); diff --git a/src/mesa/drivers/dri/i965/brw_sf.h b/src/mesa/drivers/dri/i965/brw_sf.h index 0ba731fac9..a0680a56f2 100644 --- a/src/mesa/drivers/dri/i965/brw_sf.h +++ b/src/mesa/drivers/dri/i965/brw_sf.h @@ -46,6 +46,7 @@  struct brw_sf_prog_key {     GLbitfield64 attrs; +   uint8_t point_sprite_coord_replace;     GLuint primitive:2;     GLuint do_twoside_color:1;     GLuint do_flat_shading:1; @@ -56,10 +57,6 @@ struct brw_sf_prog_key {     GLuint pad:24;  }; -struct brw_sf_point_tex { -   GLboolean CoordReplace;	 -}; -  struct brw_sf_compile {     struct brw_compile func;     struct brw_sf_prog_key key; @@ -100,7 +97,6 @@ struct brw_sf_compile {     GLubyte attr_to_idx[VERT_RESULT_MAX];        GLubyte idx_to_attr[VERT_RESULT_MAX];    -   struct brw_sf_point_tex point_attrs[VERT_RESULT_MAX];  }; diff --git a/src/mesa/drivers/dri/i965/brw_sf_emit.c b/src/mesa/drivers/dri/i965/brw_sf_emit.c index bb08055e3b..56f7c986e7 100644 --- a/src/mesa/drivers/dri/i965/brw_sf_emit.c +++ b/src/mesa/drivers/dri/i965/brw_sf_emit.c @@ -354,6 +354,33 @@ static GLboolean calculate_masks( struct brw_sf_compile *c,     return is_last_attr;  } +/* Calculates the predicate control for which channels of a reg + * (containing 2 attrs) to do point sprite coordinate replacement on. + */ +static uint16_t +calculate_point_sprite_mask(struct brw_sf_compile *c, GLuint reg) +{ +   int attr1, attr2; +   uint16_t pc = 0; + +   attr1 = c->idx_to_attr[reg * 2]; +   if (attr1 >= VERT_RESULT_TEX0 && attr1 <= VERT_RESULT_TEX7) { +      if (c->key.point_sprite_coord_replace & (1 << (attr1 - VERT_RESULT_TEX0))) +	 pc |= 0x0f; +   } + +   if (reg * 2 + 1 < c->nr_setup_attrs) { +       attr2 = c->idx_to_attr[reg * 2 + 1]; +       if (attr2 >= VERT_RESULT_TEX0 && attr2 <= VERT_RESULT_TEX7) { +	  if (c->key.point_sprite_coord_replace & (1 << (attr2 - +							 VERT_RESULT_TEX0))) +	     pc |= 0xf0; +       } +   } + +   return pc; +} +  void brw_emit_tri_setup( struct brw_sf_compile *c, GLboolean allocate) @@ -529,22 +556,27 @@ void brw_emit_point_sprite_setup( struct brw_sf_compile *c, GLboolean allocate)     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; +      GLushort pc, pc_persp, pc_linear, pc_coord_replace;        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]); -	  } + +      pc_coord_replace = calculate_point_sprite_mask(c, i); +      pc_persp &= ~pc_coord_replace; + +      if (pc_persp) { +	 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, +      /* 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) { +	 brw_set_predicate_control_flag_value(p, pc_coord_replace); +	 /* Caculate 1.0/PointWidth */ +	 brw_math(&c->func,  		  c->tmp,  		  BRW_MATH_FUNCTION_INV,  		  BRW_MATH_SATURATE_NONE, @@ -553,50 +585,51 @@ void brw_emit_point_sprite_setup( struct brw_sf_compile *c, GLboolean allocate)  		  BRW_MATH_DATA_SCALAR,  		  BRW_MATH_PRECISION_FULL); -	  if (c->key.sprite_origin_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_access_mode(p, BRW_ALIGN_16); -      { -	 brw_set_predicate_control_flag_value(p, pc);  -	 if (tex->CoordReplace) { -	     if (c->key.sprite_origin_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)); +	 /* 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, c->m3C0, a0); /* constant value */ +	    brw_MOV(p, brw_writemask(c->m2Cy, WRITEMASK_Y), c->tmp);  	 } -	 /* 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); +	 /* 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_access_mode(p, BRW_ALIGN_1);        } + +      if (pc & ~pc_coord_replace) { +	 brw_set_predicate_control_flag_value(p, 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 */ +      } + + +      brw_set_predicate_control_flag_value(p, pc); +      /* 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);     }  } | 
