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.
This commit is contained in:
parent
9dca010048
commit
b1659b9213
|
@ -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);
|
||||
|
|
|
@ -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];
|
||||
|
|
|
@ -86,6 +86,8 @@ struct lp_rasterizer
|
|||
unsigned y;
|
||||
unsigned mask;
|
||||
} blocks[256];
|
||||
|
||||
const struct lp_rast_state *current_state;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -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) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue