summaryrefslogtreecommitdiff
path: root/src/gallium/drivers/llvmpipe/lp_quad_fs.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/gallium/drivers/llvmpipe/lp_quad_fs.c')
-rw-r--r--src/gallium/drivers/llvmpipe/lp_quad_fs.c119
1 files changed, 113 insertions, 6 deletions
diff --git a/src/gallium/drivers/llvmpipe/lp_quad_fs.c b/src/gallium/drivers/llvmpipe/lp_quad_fs.c
index 1da50e493b..338a6be80c 100644
--- a/src/gallium/drivers/llvmpipe/lp_quad_fs.c
+++ b/src/gallium/drivers/llvmpipe/lp_quad_fs.c
@@ -1,8 +1,8 @@
/**************************************************************************
*
+ * Copyright 2008-2009 VMware, Inc.
* Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
* All Rights Reserved.
- * Copyright 2008 VMware, Inc. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the
@@ -65,6 +65,114 @@ quad_shade_stage(struct quad_stage *qs)
}
+static void
+shader_prepare( const struct lp_fragment_shader *shader,
+ struct tgsi_exec_machine *machine,
+ struct tgsi_sampler **samplers )
+{
+ /*
+ * Bind tokens/shader to the interpreter's machine state.
+ * Avoid redundant binding.
+ */
+ if (machine->Tokens != shader->base.tokens) {
+ tgsi_exec_machine_bind_shader( machine,
+ shader->base.tokens,
+ PIPE_MAX_SAMPLERS,
+ samplers );
+ }
+}
+
+
+
+static void
+setup_pos_vector(struct lp_fragment_shader *shader,
+ const struct tgsi_interp_coef *coef,
+ float x, float y)
+{
+ uint chan;
+
+ /* do X */
+ shader->pos[0].f[0] = x;
+ shader->pos[0].f[1] = x + 1;
+ shader->pos[0].f[2] = x;
+ shader->pos[0].f[3] = x + 1;
+
+ /* do Y */
+ shader->pos[1].f[0] = y;
+ shader->pos[1].f[1] = y;
+ shader->pos[1].f[2] = y + 1;
+ shader->pos[1].f[3] = y + 1;
+
+ /* do Z and W for all fragments in the quad */
+ for (chan = 2; chan < 4; chan++) {
+ const float dadx = coef->dadx[chan];
+ const float dady = coef->dady[chan];
+ const float a0 = coef->a0[chan] + dadx * x + dady * y;
+ shader->pos[chan].f[0] = a0;
+ shader->pos[chan].f[1] = a0 + dadx;
+ shader->pos[chan].f[2] = a0 + dady;
+ shader->pos[chan].f[3] = a0 + dadx + dady;
+ }
+}
+
+
+static void
+setup_coef_vector(struct lp_fragment_shader *shader,
+ const struct tgsi_interp_coef *coef)
+{
+ unsigned attrib, chan, i;
+
+ for (attrib = 0; attrib < PIPE_MAX_SHADER_INPUTS; ++attrib) {
+ for (chan = 0; chan < NUM_CHANNELS; ++chan) {
+ for( i = 0; i < QUAD_SIZE; ++i ) {
+ shader->a0[attrib][chan].f[i] = coef[attrib].a0[chan];
+ shader->dadx[attrib][chan].f[i] = coef[attrib].dadx[chan];
+ shader->dady[attrib][chan].f[i] = coef[attrib].dady[chan];
+ }
+ }
+ }
+}
+
+
+/* TODO: codegenerate the whole run function, skip this wrapper.
+ * TODO: break dependency on tgsi_exec_machine struct
+ * TODO: push Position calculation into the generated shader
+ * TODO: process >1 quad at a time
+ */
+static unsigned
+shader_run( struct lp_fragment_shader *shader,
+ struct tgsi_exec_machine *machine,
+ struct quad_header *quad )
+{
+ unsigned mask;
+
+ /* Compute X, Y, Z, W vals for this quad */
+ setup_pos_vector(shader,
+ quad->posCoef,
+ (float)quad->input.x0, (float)quad->input.y0);
+
+ setup_coef_vector(shader,
+ quad->coef);
+
+ /* init kill mask */
+ tgsi_set_kill_mask(machine, 0x0);
+ tgsi_set_exec_mask(machine, 1, 1, 1, 1);
+
+ memset(machine->Outputs, 0, sizeof machine->Outputs);
+
+ shader->jit_function( shader->pos,
+ shader->a0, shader->dadx, shader->dady,
+ machine->Consts,
+ machine->Outputs,
+ machine->Samplers);
+
+ /* FIXME */
+ mask = ~0;
+
+ return mask;
+}
+
+
/**
* Execute fragment shader for the four fragments in the quad.
*/
@@ -77,7 +185,7 @@ shade_quad(struct quad_stage *qs, struct quad_header *quad)
boolean z_written;
/* run shader */
- quad->inout.mask &= llvmpipe->fs->run( llvmpipe->fs, machine, quad );
+ quad->inout.mask &= shader_run( llvmpipe->fs, machine, quad );
if (quad->inout.mask == 0)
return FALSE;
@@ -177,10 +285,9 @@ shade_begin(struct quad_stage *qs)
struct quad_shade_stage *qss = quad_shade_stage(qs);
struct llvmpipe_context *llvmpipe = qs->llvmpipe;
- llvmpipe->fs->prepare( llvmpipe->fs,
- qss->machine,
- (struct tgsi_sampler **)
- llvmpipe->tgsi.frag_samplers_list );
+ shader_prepare( llvmpipe->fs,
+ qss->machine,
+ (struct tgsi_sampler **)llvmpipe->tgsi.frag_samplers_list );
qs->next->begin(qs->next);
}