summaryrefslogtreecommitdiff
path: root/src/gallium/drivers/llvmpipe
diff options
context:
space:
mode:
authorBrian Paul <brianp@vmware.com>2009-12-04 11:50:40 -0700
committerBrian Paul <brianp@vmware.com>2009-12-04 11:50:43 -0700
commitb1659b9213f3eeee440590dfe379f0d193948307 (patch)
tree7aa9c3419c3debad517a3d9b33ff21989f9396b2 /src/gallium/drivers/llvmpipe
parent9dca0100489c7a7c02af77da42a39dbe1560d7e2 (diff)
llvmpipe: bin state-change commands
Previously, each triangle had a pointer to the state to use for shading. Now we insert state-change commands into the bins. When we execute one of those commands we just update a 'current state' pointer and use that pointer when calling the jit shader. When inserting state-change commands into a bin we check if the previous command was also a state-change command and simply replace it. This avoids accumulating useless/redundant state-change commands.
Diffstat (limited to 'src/gallium/drivers/llvmpipe')
-rw-r--r--src/gallium/drivers/llvmpipe/lp_rast.c9
-rw-r--r--src/gallium/drivers/llvmpipe/lp_rast.h15
-rw-r--r--src/gallium/drivers/llvmpipe/lp_rast_priv.h2
-rw-r--r--src/gallium/drivers/llvmpipe/lp_setup.c113
-rw-r--r--src/gallium/drivers/llvmpipe/lp_setup_context.h7
-rw-r--r--src/gallium/drivers/llvmpipe/lp_setup_tri.c2
6 files changed, 101 insertions, 47 deletions
diff --git a/src/gallium/drivers/llvmpipe/lp_rast.c b/src/gallium/drivers/llvmpipe/lp_rast.c
index d5fe6e9369..8f37a28e87 100644
--- a/src/gallium/drivers/llvmpipe/lp_rast.c
+++ b/src/gallium/drivers/llvmpipe/lp_rast.c
@@ -237,9 +237,10 @@ void lp_rast_set_state( struct lp_rasterizer *rast,
{
const struct lp_rast_state *state = arg.set_state;
- RAST_DEBUG("%s\n", __FUNCTION__);
+ RAST_DEBUG("%s %p\n", __FUNCTION__, (void *) state);
- /* XXX to do */
+ /* just set the current state pointer for this rasterizer */
+ rast->current_state = state;
}
@@ -279,7 +280,7 @@ void lp_rast_shade_quads( struct lp_rasterizer *rast,
unsigned mask)
{
#if 1
- const struct lp_rast_state *state = inputs->state;
+ const struct lp_rast_state *state = rast->current_state;
struct lp_rast_tile *tile = &rast->tile;
void *color;
void *depth;
@@ -287,6 +288,8 @@ void lp_rast_shade_quads( struct lp_rasterizer *rast,
unsigned ix, iy;
int block_offset;
+ assert(state);
+
/* Sanity checks */
assert(x % TILE_VECTOR_WIDTH == 0);
assert(y % TILE_VECTOR_HEIGHT == 0);
diff --git a/src/gallium/drivers/llvmpipe/lp_rast.h b/src/gallium/drivers/llvmpipe/lp_rast.h
index 435993d44d..e9a1fa49ad 100644
--- a/src/gallium/drivers/llvmpipe/lp_rast.h
+++ b/src/gallium/drivers/llvmpipe/lp_rast.h
@@ -55,18 +55,13 @@ struct lp_rast_state {
};
-/* Coefficients necessary to run the shader at a given location:
+
+/**
+ * Coefficients necessary to run the shader at a given location.
+ * First coefficient is position.
+ * These pointers point into the bin data buffer.
*/
struct lp_rast_shader_inputs {
-
- /* Current rasterizer state:
- */
- const struct lp_rast_state *state;
-
- /* Attribute interpolation:
- * First coefficient is position.
- * These pointers point into the bin data buffer.
- */
float (*a0)[4];
float (*dadx)[4];
float (*dady)[4];
diff --git a/src/gallium/drivers/llvmpipe/lp_rast_priv.h b/src/gallium/drivers/llvmpipe/lp_rast_priv.h
index 4c0dfe2282..98111edff7 100644
--- a/src/gallium/drivers/llvmpipe/lp_rast_priv.h
+++ b/src/gallium/drivers/llvmpipe/lp_rast_priv.h
@@ -86,6 +86,8 @@ struct lp_rasterizer
unsigned y;
unsigned mask;
} blocks[256];
+
+ const struct lp_rast_state *current_state;
};
diff --git a/src/gallium/drivers/llvmpipe/lp_setup.c b/src/gallium/drivers/llvmpipe/lp_setup.c
index fc7f4f6778..11a9fd2637 100644
--- a/src/gallium/drivers/llvmpipe/lp_setup.c
+++ b/src/gallium/drivers/llvmpipe/lp_setup.c
@@ -155,6 +155,34 @@ static void reset_context( struct setup_context *setup )
}
+/**
+ * Return last command in the bin
+ */
+static lp_rast_cmd
+lp_get_last_command( const struct cmd_bin *bin )
+{
+ const struct cmd_block *tail = bin->commands.tail;
+ const unsigned i = tail->count;
+ if (i > 0)
+ return tail->cmd[i - 1];
+ else
+ return NULL;
+}
+
+
+/**
+ * Replace the arg of the last command in the bin.
+ */
+static void
+lp_replace_last_command_arg( struct cmd_bin *bin,
+ const union lp_rast_cmd_arg arg )
+{
+ struct cmd_block *tail = bin->commands.tail;
+ const unsigned i = tail->count;
+ assert(i > 0);
+ tail->arg[i - 1] = arg;
+}
+
/* Add a command to all active bins.
@@ -170,6 +198,32 @@ static void bin_everywhere( struct setup_context *setup,
}
+/**
+ * Put a state-change command into all bins.
+ * If we find that the last command in a bin was also a state-change
+ * command, we can simply replace that one with the new one.
+ */
+static void
+bin_state_command( struct setup_context *setup,
+ lp_rast_cmd cmd,
+ const union lp_rast_cmd_arg arg )
+{
+ unsigned i, j;
+ for (i = 0; i < setup->tiles_x; i++) {
+ for (j = 0; j < setup->tiles_y; j++) {
+ struct cmd_bin *bin = &setup->tile[i][j];
+ lp_rast_cmd last_cmd = lp_get_last_command(bin);
+ if (last_cmd == cmd) {
+ lp_replace_last_command_arg(bin, arg);
+ }
+ else {
+ bin_command( bin, cmd, arg );
+ }
+ }
+ }
+}
+
+
/** Rasterize commands for a single bin */
static void
rasterize_bin( struct lp_rasterizer *rast,
@@ -234,31 +288,6 @@ begin_binning( struct setup_context *setup )
{
SETUP_DEBUG("%s\n", __FUNCTION__);
- if (!setup->fb.cbuf && !setup->fb.zsbuf) {
- setup->fb.width = 0;
- setup->fb.height = 0;
- }
- else if (!setup->fb.zsbuf) {
- setup->fb.width = setup->fb.cbuf->width;
- setup->fb.height = setup->fb.cbuf->height;
- }
- else if (!setup->fb.cbuf) {
- setup->fb.width = setup->fb.zsbuf->width;
- setup->fb.height = setup->fb.zsbuf->height;
- }
- else {
- /* XXX: not sure what we're really supposed to do for
- * mis-matched color & depth buffer sizes.
- */
- setup->fb.width = MIN2(setup->fb.cbuf->width,
- setup->fb.zsbuf->width);
- setup->fb.height = MIN2(setup->fb.cbuf->height,
- setup->fb.zsbuf->height);
- }
-
- setup->tiles_x = align(setup->fb.width, TILE_SIZE) / TILE_SIZE;
- setup->tiles_y = align(setup->fb.height, TILE_SIZE) / TILE_SIZE;
-
if (setup->fb.cbuf) {
if (setup->clear.flags & PIPE_CLEAR_COLOR)
bin_everywhere( setup,
@@ -352,8 +381,34 @@ lp_setup_bind_framebuffer( struct setup_context *setup,
pipe_surface_reference( &setup->fb.cbuf, color );
pipe_surface_reference( &setup->fb.zsbuf, zstencil );
+
+ if (!setup->fb.cbuf && !setup->fb.zsbuf) {
+ setup->fb.width = 0;
+ setup->fb.height = 0;
+ }
+ else if (!setup->fb.zsbuf) {
+ setup->fb.width = setup->fb.cbuf->width;
+ setup->fb.height = setup->fb.cbuf->height;
+ }
+ else if (!setup->fb.cbuf) {
+ setup->fb.width = setup->fb.zsbuf->width;
+ setup->fb.height = setup->fb.zsbuf->height;
+ }
+ else {
+ /* XXX: not sure what we're really supposed to do for
+ * mis-matched color & depth buffer sizes.
+ */
+ setup->fb.width = MIN2(setup->fb.cbuf->width,
+ setup->fb.zsbuf->width);
+ setup->fb.height = MIN2(setup->fb.cbuf->height,
+ setup->fb.zsbuf->height);
+ }
+
+ setup->tiles_x = align(setup->fb.width, TILE_SIZE) / TILE_SIZE;
+ setup->tiles_y = align(setup->fb.height, TILE_SIZE) / TILE_SIZE;
}
+
void
lp_setup_clear( struct setup_context *setup,
const float *color,
@@ -608,12 +663,10 @@ lp_setup_update_shader_state( struct setup_context *setup )
sizeof setup->fs.current);
setup->fs.stored = stored;
-#if 0
/* put the state-set command into all bins */
- bin_everywhere( setup,
- lp_rast_set_state,
- *setup->fs.stored );
-#endif
+ bin_state_command( setup,
+ lp_rast_set_state,
+ lp_rast_arg_state(setup->fs.stored) );
}
}
}
diff --git a/src/gallium/drivers/llvmpipe/lp_setup_context.h b/src/gallium/drivers/llvmpipe/lp_setup_context.h
index 1715048f76..7c7c34f3f7 100644
--- a/src/gallium/drivers/llvmpipe/lp_setup_context.h
+++ b/src/gallium/drivers/llvmpipe/lp_setup_context.h
@@ -76,10 +76,14 @@ struct cmd_block_list {
*/
struct cmd_bin {
struct cmd_block_list commands;
- struct lp_rast_state *curr_state;
};
+/**
+ * This stores bulk data which is shared by all bins.
+ * Examples include triangle data and state data. The commands in
+ * the per-tile bins will point to chunks of data in this structure.
+ */
struct data_block_list {
struct data_block *head;
struct data_block *tail;
@@ -241,5 +245,4 @@ static INLINE void bin_command( struct cmd_bin *bin,
}
-
#endif
diff --git a/src/gallium/drivers/llvmpipe/lp_setup_tri.c b/src/gallium/drivers/llvmpipe/lp_setup_tri.c
index 74ed0a9e8f..48733a599b 100644
--- a/src/gallium/drivers/llvmpipe/lp_setup_tri.c
+++ b/src/gallium/drivers/llvmpipe/lp_setup_tri.c
@@ -295,8 +295,6 @@ do_triangle_ccw(struct setup_context *setup,
return;
}
- tri->inputs.state = setup->fs.stored;
-
/*
*/
tri->oneoverarea = ((float)FIXED_ONE) / (float)area;