summaryrefslogtreecommitdiff
path: root/src/gallium/drivers/llvmpipe/lp_state_fs.c
diff options
context:
space:
mode:
authorJosé Fonseca <jfonseca@vmware.com>2009-08-23 12:28:34 +0100
committerJosé Fonseca <jfonseca@vmware.com>2009-08-29 09:21:41 +0100
commitf85c5f8621382ba1c8baa1582d87b46b388258d2 (patch)
tree16a9aa88a190d6780d9446ab8f4cb50cad4b4c83 /src/gallium/drivers/llvmpipe/lp_state_fs.c
parent03180dca7a3b5d57100158eb06d00419e55d9dc8 (diff)
llvmpipe: Factor out and optimize the input interpolation.
Special attention is given to the interpolation of side by side quads. Multiplications are made only for the first quad. Interpolation of inputs for posterior quads are done exclusively with additions, and perspective divide if necessary.
Diffstat (limited to 'src/gallium/drivers/llvmpipe/lp_state_fs.c')
-rw-r--r--src/gallium/drivers/llvmpipe/lp_state_fs.c100
1 files changed, 33 insertions, 67 deletions
diff --git a/src/gallium/drivers/llvmpipe/lp_state_fs.c b/src/gallium/drivers/llvmpipe/lp_state_fs.c
index e639f9c20f..361b30699c 100644
--- a/src/gallium/drivers/llvmpipe/lp_state_fs.c
+++ b/src/gallium/drivers/llvmpipe/lp_state_fs.c
@@ -69,9 +69,11 @@
#include "tgsi/tgsi_scan.h"
#include "tgsi/tgsi_parse.h"
#include "lp_bld_type.h"
+#include "lp_bld_const.h"
#include "lp_bld_conv.h"
#include "lp_bld_logic.h"
#include "lp_bld_depth.h"
+#include "lp_bld_interp.h"
#include "lp_bld_tgsi.h"
#include "lp_bld_alpha.h"
#include "lp_bld_blend.h"
@@ -88,22 +90,16 @@ static const unsigned char quad_offset_x[4] = {0, 1, 0, 1};
static const unsigned char quad_offset_y[4] = {0, 0, 1, 1};
-/**
- * Generate the position vectors.
- *
- * TODO: This should be called only once per fragment pipeline, for the first
- * quad, and the neighboring quad positions obtained by additions.
- *
- * Parameter x, y are the integer values with the quad upper left coordinates.
+/*
+ * Derive from the quad's upper left scalar coordinates the coordinates for
+ * all other quad pixels
*/
static void
-generate_pos(LLVMBuilderRef builder,
- LLVMValueRef x,
- LLVMValueRef y,
- LLVMValueRef a0_ptr,
- LLVMValueRef dadx_ptr,
- LLVMValueRef dady_ptr,
- LLVMValueRef *pos)
+generate_pos0(LLVMBuilderRef builder,
+ LLVMValueRef x,
+ LLVMValueRef y,
+ LLVMValueRef *x0,
+ LLVMValueRef *y0)
{
LLVMTypeRef int_elem_type = LLVMInt32Type();
LLVMTypeRef int_vec_type = LLVMVectorType(int_elem_type, QUAD_SIZE);
@@ -111,14 +107,8 @@ generate_pos(LLVMBuilderRef builder,
LLVMTypeRef vec_type = LLVMVectorType(elem_type, QUAD_SIZE);
LLVMValueRef x_offsets[QUAD_SIZE];
LLVMValueRef y_offsets[QUAD_SIZE];
- unsigned chan;
unsigned i;
- /*
- * Derive from the quad's upper left scalar coordinates the coordinates for
- * all other quad pixels
- */
-
x = lp_build_broadcast(builder, int_vec_type, x);
y = lp_build_broadcast(builder, int_vec_type, y);
@@ -130,33 +120,8 @@ generate_pos(LLVMBuilderRef builder,
x = LLVMBuildAdd(builder, x, LLVMConstVector(x_offsets, QUAD_SIZE), "");
y = LLVMBuildAdd(builder, y, LLVMConstVector(y_offsets, QUAD_SIZE), "");
- x = LLVMBuildSIToFP(builder, x, vec_type, "");
- y = LLVMBuildSIToFP(builder, y, vec_type, "");
-
- pos[0] = x;
- pos[1] = y;
-
- /*
- * Calculate z and w from the interpolation factors.
- */
-
- for(chan = 2; chan < NUM_CHANNELS; ++chan) {
- LLVMValueRef index = LLVMConstInt(LLVMInt32Type(), chan, 0);
- LLVMValueRef a0 = LLVMBuildLoad(builder, LLVMBuildGEP(builder, a0_ptr, &index, 1, ""), "");
- LLVMValueRef dadx = LLVMBuildLoad(builder, LLVMBuildGEP(builder, dadx_ptr, &index, 1, ""), "");
- LLVMValueRef dady = LLVMBuildLoad(builder, LLVMBuildGEP(builder, dady_ptr, &index, 1, ""), "");
- LLVMValueRef res;
- a0 = lp_build_broadcast(builder, vec_type, a0);
- dadx = lp_build_broadcast(builder, vec_type, dadx);
- dady = lp_build_broadcast(builder, vec_type, dady);
- res = a0;
- res = LLVMBuildAdd(builder, res, LLVMBuildMul(builder, dadx, x, ""), "");
- res = LLVMBuildAdd(builder, res, LLVMBuildMul(builder, dady, y, ""), "");
- pos[chan] = res;
- }
-
- for(chan = 0; chan < NUM_CHANNELS; ++chan)
- lp_build_name(pos[chan], "pos.%c", "xyzw"[chan]);
+ *x0 = LLVMBuildSIToFP(builder, x, vec_type, "");
+ *y0 = LLVMBuildSIToFP(builder, y, vec_type, "");
}
@@ -218,11 +183,7 @@ generate_fs(struct llvmpipe_context *lp,
union lp_type type,
LLVMValueRef context_ptr,
unsigned i,
- LLVMValueRef x,
- LLVMValueRef y,
- LLVMValueRef a0_ptr,
- LLVMValueRef dadx_ptr,
- LLVMValueRef dady_ptr,
+ const struct lp_build_interp_soa_context *interp,
LLVMValueRef *pmask,
LLVMValueRef *color,
LLVMValueRef depth_ptr)
@@ -233,8 +194,8 @@ generate_fs(struct llvmpipe_context *lp,
LLVMTypeRef int_vec_type;
LLVMValueRef consts_ptr;
LLVMValueRef samplers_ptr;
- LLVMValueRef pos[NUM_CHANNELS];
LLVMValueRef outputs[PIPE_MAX_SHADER_OUTPUTS][NUM_CHANNELS];
+ LLVMValueRef z = interp->pos[2];
struct lp_build_mask_context mask;
boolean early_depth_test;
unsigned attrib;
@@ -247,8 +208,6 @@ generate_fs(struct llvmpipe_context *lp,
consts_ptr = lp_jit_context_constants(builder, context_ptr);
samplers_ptr = lp_jit_context_samplers(builder, context_ptr);
- generate_pos(builder, x, y, a0_ptr, dadx_ptr, dady_ptr, pos);
-
lp_build_mask_begin(&mask, builder, type, *pmask);
early_depth_test =
@@ -260,14 +219,14 @@ generate_fs(struct llvmpipe_context *lp,
if(early_depth_test)
generate_depth(lp, builder, &key->depth,
- type, &mask,
- pos[2], depth_ptr);
+ type, &mask,
+ z, depth_ptr);
memset(outputs, 0, sizeof outputs);
lp_build_tgsi_soa(builder, tokens, type, &mask,
- pos, a0_ptr, dadx_ptr, dady_ptr,
- consts_ptr, outputs, samplers_ptr);
+ consts_ptr, interp->pos, interp->inputs,
+ outputs, samplers_ptr);
for (attrib = 0; attrib < shader->info.num_outputs; ++attrib) {
for(chan = 0; chan < NUM_CHANNELS; ++chan) {
@@ -300,7 +259,7 @@ generate_fs(struct llvmpipe_context *lp,
case TGSI_SEMANTIC_POSITION:
if(chan == 2)
- pos[2] = outputs[attrib][chan];
+ z = outputs[attrib][chan];
break;
}
}
@@ -309,8 +268,8 @@ generate_fs(struct llvmpipe_context *lp,
if(!early_depth_test)
generate_depth(lp, builder, &key->depth,
- type, &mask,
- pos[2], depth_ptr);
+ type, &mask,
+ z, depth_ptr);
lp_build_mask_end(&mask);
@@ -400,6 +359,9 @@ generate_fragment(struct llvmpipe_context *lp,
LLVMValueRef depth_ptr;
LLVMBasicBlockRef block;
LLVMBuilderRef builder;
+ LLVMValueRef x0;
+ LLVMValueRef y0;
+ struct lp_build_interp_soa_context interp;
LLVMValueRef fs_mask[LP_MAX_VECTOR_LENGTH];
LLVMValueRef fs_out_color[NUM_CHANNELS][LP_MAX_VECTOR_LENGTH];
LLVMValueRef blend_mask;
@@ -516,14 +478,19 @@ generate_fragment(struct llvmpipe_context *lp,
builder = LLVMCreateBuilder();
LLVMPositionBuilderAtEnd(builder, block);
+ generate_pos0(builder, x, y, &x0, &y0);
+
+ lp_build_interp_soa_init(&interp, shader->base.tokens, builder, fs_type,
+ a0_ptr, dadx_ptr, dady_ptr,
+ x0, y0, 2, 0);
+
for(i = 0; i < num_fs; ++i) {
LLVMValueRef index = LLVMConstInt(LLVMInt32Type(), i, 0);
LLVMValueRef out_color[NUM_CHANNELS];
- LLVMValueRef x_i;
LLVMValueRef depth_ptr_i;
- /* TODO: Reuse position interpolation */
- x_i = LLVMBuildAdd(builder, x, LLVMConstInt(LLVMInt32Type(), 2*i, 0), "");
+ if(i != 0)
+ lp_build_interp_soa_update(&interp);
fs_mask[i] = LLVMBuildLoad(builder, LLVMBuildGEP(builder, mask_ptr, &index, 1, ""), "");
depth_ptr_i = LLVMBuildGEP(builder, depth_ptr, &index, 1, "");
@@ -533,8 +500,7 @@ generate_fragment(struct llvmpipe_context *lp,
fs_type,
context_ptr,
i,
- x_i, y,
- a0_ptr, dadx_ptr, dady_ptr,
+ &interp,
&fs_mask[i],
out_color,
depth_ptr_i);