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.
This commit is contained in:
parent
1d84808dc0
commit
bc632d0437
|
@ -46,7 +46,6 @@
|
||||||
static void compile_sf_prog( struct brw_context *brw,
|
static void compile_sf_prog( struct brw_context *brw,
|
||||||
struct brw_sf_prog_key *key )
|
struct brw_sf_prog_key *key )
|
||||||
{
|
{
|
||||||
GLcontext *ctx = &brw->intel.ctx;
|
|
||||||
struct brw_sf_compile c;
|
struct brw_sf_compile c;
|
||||||
const GLuint *program;
|
const GLuint *program;
|
||||||
GLuint program_size;
|
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.
|
/* 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)) {
|
if (c.key.attrs & BITFIELD64_BIT(i)) {
|
||||||
c.attr_to_idx[i] = idx;
|
c.attr_to_idx[i] = idx;
|
||||||
c.idx_to_attr[idx] = i;
|
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++;
|
idx++;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Which primitive? Or all three?
|
/* Which primitive? Or all three?
|
||||||
*/
|
*/
|
||||||
switch (key->primitive) {
|
switch (key->primitive) {
|
||||||
|
@ -162,6 +155,14 @@ static void upload_sf_prog(struct brw_context *brw)
|
||||||
}
|
}
|
||||||
|
|
||||||
key.do_point_sprite = ctx->Point.PointSprite;
|
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);
|
key.sprite_origin_lower_left = (ctx->Point.SpriteOrigin == GL_LOWER_LEFT);
|
||||||
/* _NEW_LIGHT */
|
/* _NEW_LIGHT */
|
||||||
key.do_flat_shading = (ctx->Light.ShadeModel == GL_FLAT);
|
key.do_flat_shading = (ctx->Light.ShadeModel == GL_FLAT);
|
||||||
|
|
|
@ -46,6 +46,7 @@
|
||||||
|
|
||||||
struct brw_sf_prog_key {
|
struct brw_sf_prog_key {
|
||||||
GLbitfield64 attrs;
|
GLbitfield64 attrs;
|
||||||
|
uint8_t point_sprite_coord_replace;
|
||||||
GLuint primitive:2;
|
GLuint primitive:2;
|
||||||
GLuint do_twoside_color:1;
|
GLuint do_twoside_color:1;
|
||||||
GLuint do_flat_shading:1;
|
GLuint do_flat_shading:1;
|
||||||
|
@ -56,10 +57,6 @@ struct brw_sf_prog_key {
|
||||||
GLuint pad:24;
|
GLuint pad:24;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct brw_sf_point_tex {
|
|
||||||
GLboolean CoordReplace;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct brw_sf_compile {
|
struct brw_sf_compile {
|
||||||
struct brw_compile func;
|
struct brw_compile func;
|
||||||
struct brw_sf_prog_key key;
|
struct brw_sf_prog_key key;
|
||||||
|
@ -100,7 +97,6 @@ struct brw_sf_compile {
|
||||||
|
|
||||||
GLubyte attr_to_idx[VERT_RESULT_MAX];
|
GLubyte attr_to_idx[VERT_RESULT_MAX];
|
||||||
GLubyte idx_to_attr[VERT_RESULT_MAX];
|
GLubyte idx_to_attr[VERT_RESULT_MAX];
|
||||||
struct brw_sf_point_tex point_attrs[VERT_RESULT_MAX];
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -354,6 +354,33 @@ static GLboolean calculate_masks( struct brw_sf_compile *c,
|
||||||
return is_last_attr;
|
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)
|
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);
|
copy_z_inv_w(c);
|
||||||
for (i = 0; i < c->nr_setup_regs; i++)
|
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);
|
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);
|
GLboolean last = calculate_masks(c, i, &pc, &pc_persp, &pc_linear);
|
||||||
|
|
||||||
if (pc_persp)
|
pc_coord_replace = calculate_point_sprite_mask(c, i);
|
||||||
{
|
pc_persp &= ~pc_coord_replace;
|
||||||
if (!tex->CoordReplace) {
|
|
||||||
brw_set_predicate_control_flag_value(p, pc_persp);
|
if (pc_persp) {
|
||||||
brw_MUL(p, a0, a0, c->inv_w[0]);
|
brw_set_predicate_control_flag_value(p, pc_persp);
|
||||||
}
|
brw_MUL(p, a0, a0, c->inv_w[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tex->CoordReplace) {
|
/* Point sprite coordinate replacement: A texcoord with this
|
||||||
/* Caculate 1.0/PointWidth */
|
* enabled gets replaced with the value (x, y, 0, 1) where x and
|
||||||
brw_math(&c->func,
|
* 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,
|
c->tmp,
|
||||||
BRW_MATH_FUNCTION_INV,
|
BRW_MATH_FUNCTION_INV,
|
||||||
BRW_MATH_SATURATE_NONE,
|
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_DATA_SCALAR,
|
||||||
BRW_MATH_PRECISION_FULL);
|
BRW_MATH_PRECISION_FULL);
|
||||||
|
|
||||||
if (c->key.sprite_origin_lower_left) {
|
brw_set_access_mode(p, BRW_ALIGN_16);
|
||||||
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));
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
/* dA/dx, dA/dy */
|
||||||
brw_set_predicate_control_flag_value(p, pc);
|
brw_MOV(p, c->m1Cx, brw_imm_f(0.0));
|
||||||
if (tex->CoordReplace) {
|
brw_MOV(p, c->m2Cy, brw_imm_f(0.0));
|
||||||
if (c->key.sprite_origin_lower_left) {
|
brw_MOV(p, brw_writemask(c->m1Cx, WRITEMASK_X), c->tmp);
|
||||||
brw_MUL(p, c->m3C0, c->inv_w[0], brw_imm_f(1.0));
|
if (c->key.sprite_origin_lower_left) {
|
||||||
brw_MOV(p, vec1(suboffset(c->m3C0, 0)), brw_imm_f(0.0));
|
brw_MOV(p, brw_writemask(c->m2Cy, WRITEMASK_Y), negate(c->tmp));
|
||||||
}
|
|
||||||
else
|
|
||||||
brw_MOV(p, c->m3C0, brw_imm_f(0.0));
|
|
||||||
} else {
|
} 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.
|
/* attribute constant offset */
|
||||||
*/
|
brw_MOV(p, c->m3C0, brw_imm_f(0.0));
|
||||||
brw_urb_WRITE(p,
|
if (c->key.sprite_origin_lower_left) {
|
||||||
brw_null_reg(),
|
brw_MOV(p, brw_writemask(c->m3C0, WRITEMASK_YW), brw_imm_f(1.0));
|
||||||
0,
|
} else {
|
||||||
brw_vec8_grf(0, 0),
|
brw_MOV(p, brw_writemask(c->m3C0, WRITEMASK_W), brw_imm_f(1.0));
|
||||||
0, /* allocate */
|
}
|
||||||
1, /* used */
|
|
||||||
4, /* msg len */
|
brw_set_access_mode(p, BRW_ALIGN_1);
|
||||||
0, /* response len */
|
|
||||||
last, /* eot */
|
|
||||||
last, /* writes complete */
|
|
||||||
i*4, /* urb destination offset */
|
|
||||||
BRW_URB_SWIZZLE_TRANSPOSE);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue