summaryrefslogtreecommitdiff
path: root/src/gallium/drivers/llvmpipe/lp_setup_point.c
diff options
context:
space:
mode:
authorBrian Paul <brianp@vmware.com>2010-09-22 11:20:48 -0600
committerBrian Paul <brianp@vmware.com>2010-09-22 11:25:18 -0600
commit516ac2bd50ad1e71bd2a359d247532d9f18bcf99 (patch)
treef267f8969edd0bf08c72ed38965a0fe09f57e2f0 /src/gallium/drivers/llvmpipe/lp_setup_point.c
parentbd6b8107ad551d8c7439102b8e9027abf901b139 (diff)
llvmpipe: fix sprite texcoord setup for non-projective texturing
Normally the Mesa state tracker uses TXP instructions for texturing. But if a fragment shader uses texture2D() that's a TEX instruction. In that case we were incorrectly computing the texcoord coefficients in the point sprite setup code. Some new comments in the code explain things.
Diffstat (limited to 'src/gallium/drivers/llvmpipe/lp_setup_point.c')
-rw-r--r--src/gallium/drivers/llvmpipe/lp_setup_point.c85
1 files changed, 58 insertions, 27 deletions
diff --git a/src/gallium/drivers/llvmpipe/lp_setup_point.c b/src/gallium/drivers/llvmpipe/lp_setup_point.c
index 774a3c80da..2c354d1d0e 100644
--- a/src/gallium/drivers/llvmpipe/lp_setup_point.c
+++ b/src/gallium/drivers/llvmpipe/lp_setup_point.c
@@ -65,47 +65,77 @@ constant_coef(struct lp_setup_context *setup,
}
+/**
+ * Setup automatic texcoord coefficients (for sprite rendering).
+ * \param slot the vertex attribute slot to setup
+ * \param i the attribute channel in [0,3]
+ * \param sprite_coord_origin one of PIPE_SPRITE_COORD_x
+ * \param perspective_proj will the TEX instruction do a divide by Q?
+ */
static void
-perspective_coef(struct lp_setup_context *setup,
- struct lp_rast_triangle *point,
- const struct point_info *info,
- unsigned slot,
- unsigned vert_attr,
- unsigned i,
- unsigned sprite_coord_origin)
+texcoord_coef(struct lp_setup_context *setup,
+ struct lp_rast_triangle *point,
+ const struct point_info *info,
+ unsigned slot,
+ unsigned i,
+ unsigned sprite_coord_origin,
+ boolean perspective_proj)
{
+ assert(i < 4);
+
if (i == 0) {
float dadx = FIXED_ONE / (float)info->dx12;
float dady = 0.0f;
- point->inputs.dadx[slot][i] = dadx;
- point->inputs.dady[slot][i] = dady;
- point->inputs.a0[slot][i] = (0.5 -
- (dadx * ((float)info->v0[0][0] - setup->pixel_offset) +
- dady * ((float)info->v0[0][1] - setup->pixel_offset)));
+ float x0 = info->v0[0][0] - setup->pixel_offset;
+ float y0 = info->v0[0][1] - setup->pixel_offset;
+
+ point->inputs.dadx[slot][0] = dadx;
+ point->inputs.dady[slot][0] = dady;
+ point->inputs.a0[slot][0] = 0.5 - (dadx * x0 + dady * y0);
+
+ if (!perspective_proj) {
+ /* Divide coefficients by vertex.w here.
+ *
+ * It would be clearer to always multiply by w0 above and
+ * then divide it out for perspective projection here, but
+ * doing it this way involves less algebra.
+ */
+ float w0 = info->v0[0][3];
+ point->inputs.dadx[slot][0] *= w0;
+ point->inputs.dady[slot][0] *= w0;
+ point->inputs.a0[slot][0] *= w0;
+ }
}
else if (i == 1) {
float dadx = 0.0f;
float dady = FIXED_ONE / (float)info->dx12;
+ float x0 = info->v0[0][0] - setup->pixel_offset;
+ float y0 = info->v0[0][1] - setup->pixel_offset;
if (sprite_coord_origin == PIPE_SPRITE_COORD_LOWER_LEFT) {
dady = -dady;
}
- point->inputs.dadx[slot][i] = dadx;
- point->inputs.dady[slot][i] = dady;
- point->inputs.a0[slot][i] = (0.5 -
- (dadx * ((float)info->v0[0][0] - setup->pixel_offset) +
- dady * ((float)info->v0[0][1] - setup->pixel_offset)));
+ point->inputs.dadx[slot][1] = dadx;
+ point->inputs.dady[slot][1] = dady;
+ point->inputs.a0[slot][1] = 0.5 - (dadx * x0 + dady * y0);
+
+ if (!perspective_proj) {
+ float w0 = info->v0[0][3];
+ point->inputs.dadx[slot][1] *= w0;
+ point->inputs.dady[slot][1] *= w0;
+ point->inputs.a0[slot][1] *= w0;
+ }
}
else if (i == 2) {
- point->inputs.a0[slot][i] = 0.0f;
- point->inputs.dadx[slot][i] = 0.0f;
- point->inputs.dady[slot][i] = 0.0f;
+ point->inputs.a0[slot][2] = 0.0f;
+ point->inputs.dadx[slot][2] = 0.0f;
+ point->inputs.dady[slot][2] = 0.0f;
}
- else if (i == 3) {
- point->inputs.a0[slot][i] = 1.0f;
- point->inputs.dadx[slot][i] = 0.0f;
- point->inputs.dady[slot][i] = 0.0f;
+ else {
+ point->inputs.a0[slot][3] = 1.0f;
+ point->inputs.dadx[slot][3] = 0.0f;
+ point->inputs.dady[slot][3] = 0.0f;
}
}
@@ -184,7 +214,7 @@ setup_point_coefficients( struct lp_setup_context *setup,
case LP_INTERP_PERSPECTIVE:
/* check if the sprite coord flag is set for this attribute.
- * If so, set it up so it up so x any y vary from 0 to 1.
+ * If so, set it up so it up so x and y vary from 0 to 1.
*/
if (shader->info.input_semantic_name[slot] == TGSI_SEMANTIC_GENERIC) {
const int index = shader->info.input_semantic_index[slot];
@@ -195,8 +225,9 @@ setup_point_coefficients( struct lp_setup_context *setup,
(setup->sprite_coord_enable & (1 << index))) {
for (i = 0; i < NUM_CHANNELS; i++)
if (usage_mask & (1 << i))
- perspective_coef(setup, point, info, slot+1, vert_attr, i,
- setup->sprite_coord_origin);
+ texcoord_coef(setup, point, info, slot + 1, i,
+ setup->sprite_coord_origin,
+ (usage_mask & TGSI_WRITEMASK_W));
fragcoord_usage_mask |= TGSI_WRITEMASK_W;
break;
}