summaryrefslogtreecommitdiff
path: root/src/gallium/drivers/llvmpipe/lp_bld_interp.c
diff options
context:
space:
mode:
authorJosé Fonseca <jfonseca@vmware.com>2010-06-01 21:27:18 +0100
committerJosé Fonseca <jfonseca@vmware.com>2010-06-01 21:30:57 +0100
commit6ce68ad3ca242076bbb93fdd99bb448f87a31d15 (patch)
treec16f9df9eb36510f378feef5002c383bc17e9a55 /src/gallium/drivers/llvmpipe/lp_bld_interp.c
parentc7c64d97836c71eaf2ee3fc6d384877170b8c844 (diff)
llvmpipe: Use struct lp_shader_input in the interpolator.
Eliminates all this identical yet slightly different code to decide how shader inputs should be interpolated. As bonus, don't interpolate the position twice when it is listed in the TGSI shader inputs.
Diffstat (limited to 'src/gallium/drivers/llvmpipe/lp_bld_interp.c')
-rw-r--r--src/gallium/drivers/llvmpipe/lp_bld_interp.c165
1 files changed, 90 insertions, 75 deletions
diff --git a/src/gallium/drivers/llvmpipe/lp_bld_interp.c b/src/gallium/drivers/llvmpipe/lp_bld_interp.c
index 07c9e646630..d1f0185684d 100644
--- a/src/gallium/drivers/llvmpipe/lp_bld_interp.c
+++ b/src/gallium/drivers/llvmpipe/lp_bld_interp.c
@@ -105,15 +105,15 @@ coeffs_init(struct lp_build_interp_soa_context *bld,
for(chan = 0; chan < NUM_CHANNELS; ++chan) {
if(mask & (1 << chan)) {
LLVMValueRef index = LLVMConstInt(LLVMInt32Type(), attrib*NUM_CHANNELS + chan, 0);
- LLVMValueRef a0 = NULL;
- LLVMValueRef dadx = NULL;
- LLVMValueRef dady = NULL;
+ LLVMValueRef a0 = bld->base.undef;
+ LLVMValueRef dadx = bld->base.undef;
+ LLVMValueRef dady = bld->base.undef;
switch( interp ) {
- case TGSI_INTERPOLATE_PERSPECTIVE:
+ case LP_INTERP_PERSPECTIVE:
/* fall-through */
- case TGSI_INTERPOLATE_LINEAR:
+ case LP_INTERP_LINEAR:
dadx = LLVMBuildLoad(builder, LLVMBuildGEP(builder, dadx_ptr, &index, 1, ""), "");
dady = LLVMBuildLoad(builder, LLVMBuildGEP(builder, dady_ptr, &index, 1, ""), "");
dadx = lp_build_broadcast_scalar(&bld->base, dadx);
@@ -122,12 +122,17 @@ coeffs_init(struct lp_build_interp_soa_context *bld,
attrib_name(dady, attrib, chan, ".dady");
/* fall-through */
- case TGSI_INTERPOLATE_CONSTANT:
+ case LP_INTERP_CONSTANT:
+ case LP_INTERP_FACING:
a0 = LLVMBuildLoad(builder, LLVMBuildGEP(builder, a0_ptr, &index, 1, ""), "");
a0 = lp_build_broadcast_scalar(&bld->base, a0);
attrib_name(a0, attrib, chan, ".a0");
break;
+ case LP_INTERP_POSITION:
+ /* Nothing to do as the position coeffs are already setup in slot 0 */
+ break;
+
default:
assert(0);
break;
@@ -163,36 +168,44 @@ attribs_init(struct lp_build_interp_soa_context *bld)
const unsigned interp = bld->interp[attrib];
for(chan = 0; chan < NUM_CHANNELS; ++chan) {
if(mask & (1 << chan)) {
- LLVMValueRef a0 = bld->a0 [attrib][chan];
- LLVMValueRef dadx = bld->dadx[attrib][chan];
- LLVMValueRef dady = bld->dady[attrib][chan];
- LLVMValueRef res;
-
- res = a0;
-
- if (interp != TGSI_INTERPOLATE_CONSTANT) {
- /* res = res + x * dadx */
- res = lp_build_add(&bld->base, res, lp_build_mul(&bld->base, x, dadx));
- /* res = res + y * dady */
- res = lp_build_add(&bld->base, res, lp_build_mul(&bld->base, y, dady));
+ if (interp == LP_INTERP_POSITION) {
+ assert(attrib > 0);
+ bld->attribs[attrib][chan] = bld->attribs[0][chan];
}
+ else {
+ LLVMValueRef a0 = bld->a0 [attrib][chan];
+ LLVMValueRef dadx = bld->dadx[attrib][chan];
+ LLVMValueRef dady = bld->dady[attrib][chan];
+ LLVMValueRef res;
- /* Keep the value of the attribute before perspective divide
- * for faster updates.
- */
- bld->attribs_pre[attrib][chan] = res;
-
- if (interp == TGSI_INTERPOLATE_PERSPECTIVE) {
- LLVMValueRef w = bld->pos[3];
- assert(attrib != 0);
- if(!oow)
- oow = lp_build_rcp(&bld->base, w);
- res = lp_build_mul(&bld->base, res, oow);
- }
+ res = a0;
+
+ if (interp != LP_INTERP_CONSTANT &&
+ interp != LP_INTERP_FACING) {
+ /* res = res + x * dadx */
+ res = lp_build_add(&bld->base, res, lp_build_mul(&bld->base, x, dadx));
+ /* res = res + y * dady */
+ res = lp_build_add(&bld->base, res, lp_build_mul(&bld->base, y, dady));
+ }
- attrib_name(res, attrib, chan, "");
+ /* Keep the value of the attribute before perspective divide
+ * for faster updates.
+ */
+ bld->attribs_pre[attrib][chan] = res;
- bld->attribs[attrib][chan] = res;
+ if (interp == LP_INTERP_PERSPECTIVE) {
+ LLVMValueRef w = bld->pos[3];
+ assert(attrib != 0);
+ assert(bld->mask[0] & TGSI_WRITEMASK_W);
+ if(!oow)
+ oow = lp_build_rcp(&bld->base, w);
+ res = lp_build_mul(&bld->base, res, oow);
+ }
+
+ attrib_name(res, attrib, chan, "");
+
+ bld->attribs[attrib][chan] = res;
+ }
}
}
}
@@ -216,40 +229,48 @@ attribs_update(struct lp_build_interp_soa_context *bld, int quad_index)
const unsigned mask = bld->mask[attrib];
const unsigned interp = bld->interp[attrib];
- if (interp != TGSI_INTERPOLATE_CONSTANT) {
+ if (interp != LP_INTERP_CONSTANT &&
+ interp != LP_INTERP_FACING) {
for(chan = 0; chan < NUM_CHANNELS; ++chan) {
if(mask & (1 << chan)) {
- LLVMValueRef dadx = bld->dadx[attrib][chan];
- LLVMValueRef dady = bld->dady[attrib][chan];
- LLVMValueRef res;
-
- res = bld->attribs_pre[attrib][chan];
-
- if (quad_index == 1 || quad_index == 3) {
- /* top-right or bottom-right quad */
- /* build res = res + dadx + dadx */
- res = lp_build_add(&bld->base, res, dadx);
- res = lp_build_add(&bld->base, res, dadx);
+ if (interp == LP_INTERP_POSITION) {
+ assert(attrib > 0);
+ bld->attribs[attrib][chan] = bld->attribs[0][chan];
}
-
- if (quad_index == 2 || quad_index == 3) {
- /* bottom-left or bottom-right quad */
- /* build res = res + dady + dady */
- res = lp_build_add(&bld->base, res, dady);
- res = lp_build_add(&bld->base, res, dady);
+ else {
+ LLVMValueRef dadx = bld->dadx[attrib][chan];
+ LLVMValueRef dady = bld->dady[attrib][chan];
+ LLVMValueRef res;
+
+ res = bld->attribs_pre[attrib][chan];
+
+ if (quad_index == 1 || quad_index == 3) {
+ /* top-right or bottom-right quad */
+ /* build res = res + dadx + dadx */
+ res = lp_build_add(&bld->base, res, dadx);
+ res = lp_build_add(&bld->base, res, dadx);
+ }
+
+ if (quad_index == 2 || quad_index == 3) {
+ /* bottom-left or bottom-right quad */
+ /* build res = res + dady + dady */
+ res = lp_build_add(&bld->base, res, dady);
+ res = lp_build_add(&bld->base, res, dady);
+ }
+
+ if (interp == LP_INTERP_PERSPECTIVE) {
+ LLVMValueRef w = bld->pos[3];
+ assert(attrib != 0);
+ assert(bld->mask[0] & TGSI_WRITEMASK_W);
+ if(!oow)
+ oow = lp_build_rcp(&bld->base, w);
+ res = lp_build_mul(&bld->base, res, oow);
+ }
+
+ attrib_name(res, attrib, chan, "");
+
+ bld->attribs[attrib][chan] = res;
}
-
- if (interp == TGSI_INTERPOLATE_PERSPECTIVE) {
- LLVMValueRef w = bld->pos[3];
- assert(attrib != 0);
- if(!oow)
- oow = lp_build_rcp(&bld->base, w);
- res = lp_build_mul(&bld->base, res, oow);
- }
-
- attrib_name(res, attrib, chan, "");
-
- bld->attribs[attrib][chan] = res;
}
}
}
@@ -315,8 +336,8 @@ pos_update(struct lp_build_interp_soa_context *bld, int quad_index)
*/
void
lp_build_interp_soa_init(struct lp_build_interp_soa_context *bld,
- const struct tgsi_shader_info *info,
- boolean flatshade,
+ unsigned num_inputs,
+ const struct lp_shader_input *inputs,
LLVMBuilderRef builder,
struct lp_type type,
LLVMValueRef a0_ptr,
@@ -339,20 +360,14 @@ lp_build_interp_soa_init(struct lp_build_interp_soa_context *bld,
/* Position */
bld->num_attribs = 1;
bld->mask[0] = TGSI_WRITEMASK_ZW;
- bld->interp[0] = TGSI_INTERPOLATE_LINEAR;
+ bld->interp[0] = LP_INTERP_LINEAR;
/* Inputs */
- for (attrib = 0; attrib < info->num_inputs; ++attrib) {
- bld->mask[1 + attrib] = info->input_usage_mask[attrib];
-
- if (info->input_semantic_name[attrib] == TGSI_SEMANTIC_COLOR &&
- flatshade)
- bld->interp[1 + attrib] = TGSI_INTERPOLATE_CONSTANT;
- else
- bld->interp[1 + attrib] = info->input_interpolate[attrib];
-
+ for (attrib = 0; attrib < num_inputs; ++attrib) {
+ bld->mask[1 + attrib] = inputs[attrib].usage_mask;
+ bld->interp[1 + attrib] = inputs[attrib].interp;
}
- bld->num_attribs = 1 + info->num_inputs;
+ bld->num_attribs = 1 + num_inputs;
/* Ensure all masked out input channels have a valid value */
for (attrib = 0; attrib < bld->num_attribs; ++attrib) {