Module: Mesa Branch: lp-surface-tiling Commit: 3a2f08b6a550c69ef5e874f482be30252cbf8bfa URL: http://cgit.freedesktop.org/mesa/mesa/commit/?id=3a2f08b6a550c69ef5e874f482be30252cbf8bfa
Author: Brian Paul <[email protected]> Date: Fri Mar 19 17:03:14 2010 -0600 llvmpipe: checkpoint WIP: directly render to tiled texture buffers We're now directly writing colors into the tiled texture image buffers. This is a checkpoint commit with lots of dead code and temporary hacks. Everything will get cleaned up eventually. --- src/gallium/drivers/llvmpipe/lp_rast.c | 59 +++++++++++++++------- src/gallium/drivers/llvmpipe/lp_rast_priv.h | 72 ++++++++++++++++---------- src/gallium/drivers/llvmpipe/lp_texture.c | 61 ++++++++++++++++++++-- src/gallium/drivers/llvmpipe/lp_texture.h | 1 + 4 files changed, 141 insertions(+), 52 deletions(-) diff --git a/src/gallium/drivers/llvmpipe/lp_rast.c b/src/gallium/drivers/llvmpipe/lp_rast.c index 3a51800..967afac 100644 --- a/src/gallium/drivers/llvmpipe/lp_rast.c +++ b/src/gallium/drivers/llvmpipe/lp_rast.c @@ -65,9 +65,9 @@ lp_rast_begin( struct lp_rasterizer *rast, struct pipe_surface *cbuf = scene->fb.cbufs[i]; rast->cbuf[i].map = scene->cbuf_map[i]; rast->cbuf[i].format = cbuf->texture->format; - rast->cbuf[i].width = cbuf->width; - rast->cbuf[i].height = cbuf->height; - rast->cbuf[i].stride = llvmpipe_texture_stride(cbuf->texture, cbuf->level); + rast->cbuf[i].tiles_per_row = align(cbuf->width, TILE_SIZE) / TILE_SIZE; + rast->cbuf[i].blocksize = + util_format_get_blocksize(cbuf->texture->format); } if (write_zstencil) { @@ -124,7 +124,7 @@ lp_rast_clear_color(struct lp_rasterizer_task *task, { struct lp_rasterizer *rast = task->rast; const uint8_t *clear_color = arg.clear_color; - uint8_t **color_tile = task->tile.color; + unsigned i; LP_DBG(DEBUG_RAST, "%s 0x%x,0x%x,0x%x,0x%x\n", __FUNCTION__, @@ -138,7 +138,8 @@ lp_rast_clear_color(struct lp_rasterizer_task *task, clear_color[2] == clear_color[3]) { /* clear to grayscale value {x, x, x, x} */ for (i = 0; i < rast->state.nr_cbufs; i++) { - memset(color_tile[i], clear_color[0], TILE_SIZE * TILE_SIZE * 4); + void *ptr = lp_rast_color_pointer(rast, i, task->x, task->y); + memset(ptr, clear_color[0], TILE_SIZE * TILE_SIZE * 4); } } else { @@ -149,7 +150,7 @@ lp_rast_clear_color(struct lp_rasterizer_task *task, */ const unsigned chunk = TILE_SIZE / 4; for (i = 0; i < rast->state.nr_cbufs; i++) { - uint8_t *c = color_tile[i]; + uint8_t *c = lp_rast_color_pointer(rast, i, task->x, task->y); unsigned j; for (j = 0; j < 4 * TILE_SIZE; j++) { memset(c, clear_color[0], chunk); @@ -161,7 +162,6 @@ lp_rast_clear_color(struct lp_rasterizer_task *task, memset(c, clear_color[3], chunk); c += chunk; } - assert(c - color_tile[i] == TILE_SIZE * TILE_SIZE * 4); } } @@ -240,6 +240,7 @@ void lp_rast_load_color(struct lp_rasterizer_task *task, const union lp_rast_cmd_arg arg) { +#if 00 struct lp_rasterizer *rast = task->rast; const unsigned x = task->x, y = task->y; unsigned i; @@ -250,15 +251,18 @@ lp_rast_load_color(struct lp_rasterizer_task *task, if (x >= rast->cbuf[i].width || y >= rast->cbuf[i].height) continue; +#if 00 lp_tile_read_4ub(rast->cbuf[i].format, task->tile.color[i], rast->cbuf[i].map, rast->cbuf[i].stride, x, y, TILE_SIZE, TILE_SIZE); +#endif LP_COUNT(nr_color_tile_load); } +#endif } @@ -287,7 +291,6 @@ lp_rast_shade_tile(struct lp_rasterizer_task *task, { struct lp_rasterizer *rast = task->rast; const struct lp_rast_state *state = task->current_state; - struct lp_rast_tile *tile = &task->tile; const struct lp_rast_shader_inputs *inputs = arg.shade_tile; const unsigned tile_x = task->x, tile_y = task->y; unsigned x, y; @@ -306,12 +309,12 @@ lp_rast_shade_tile(struct lp_rasterizer_task *task, /* color buffer */ for (i = 0; i < rast->state.nr_cbufs; i++) - color[i] = tile->color[i] + 4 * block_offset; + color[i] = lp_rast_color_pointer(rast, i, tile_x + x, tile_y + y); /* depth buffer */ depth = lp_rast_depth_pointer(rast, tile_x + x, tile_y + y); - /* run shader */ + /* run shader on 4x4 block */ state->jit_function[RAST_WHOLE]( &state->jit_context, tile_x + x, tile_y + y, inputs->facing, @@ -330,6 +333,8 @@ lp_rast_shade_tile(struct lp_rasterizer_task *task, /** * Compute shading for a 4x4 block of pixels. * This is a bin command called during bin processing. + * \param x X position of quad in window coords + * \param y Y position of quad in window coords */ void lp_rast_shade_quads( struct lp_rasterizer_task *task, const struct lp_rast_shader_inputs *inputs, @@ -338,7 +343,6 @@ void lp_rast_shade_quads( struct lp_rasterizer_task *task, { const struct lp_rast_state *state = task->current_state; struct lp_rasterizer *rast = task->rast; - struct lp_rast_tile *tile = &task->tile; uint8_t *color[PIPE_MAX_COLOR_BUFS]; void *depth; unsigned i; @@ -361,21 +365,22 @@ void lp_rast_shade_quads( struct lp_rasterizer_task *task, block_offset = ((iy / 4) * (16 * 16) + (ix / 4) * 16); /* color buffer */ - for (i = 0; i < rast->state.nr_cbufs; i++) - color[i] = tile->color[i] + 4 * block_offset; + for (i = 0; i < rast->state.nr_cbufs; i++) { + color[i] = lp_rast_color_pointer(rast, i, x, y); + assert(lp_check_alignment(color[i], 16)); + } /* depth buffer */ depth = lp_rast_depth_pointer(rast, x, y); - assert(lp_check_alignment(tile->color[0], 16)); assert(lp_check_alignment(state->jit_context.blend_color, 16)); assert(lp_check_alignment(inputs->step[0], 16)); assert(lp_check_alignment(inputs->step[1], 16)); assert(lp_check_alignment(inputs->step[2], 16)); - /* run shader */ + /* run shader on 4x4 block */ state->jit_function[RAST_EDGE_TEST]( &state->jit_context, x, y, inputs->facing, @@ -451,9 +456,10 @@ static void lp_rast_store_color(struct lp_rasterizer_task *task) { struct lp_rasterizer *rast = task->rast; - const unsigned x = task->x, y = task->y; unsigned i; +#if 00 + const unsigned x = task->x, y = task->y; for (i = 0; i < rast->state.nr_cbufs; i++) { if (x >= rast->cbuf[i].width) continue; @@ -469,15 +475,28 @@ lp_rast_store_color(struct lp_rasterizer_task *task) else if (LP_DEBUG & DEBUG_SHOW_TILES) outline_tile(task->tile.color[i]); +#if 00 lp_tile_write_4ub(rast->cbuf[i].format, task->tile.color[i], rast->cbuf[i].map, rast->cbuf[i].stride, x, y, TILE_SIZE, TILE_SIZE); +#endif LP_COUNT(nr_color_tile_store); } + +#else + for (i = 0; i < rast->state.nr_cbufs; i++) { + uint8_t *color = lp_rast_color_pointer(rast, i, task->x, task->y); + + if (LP_DEBUG & DEBUG_SHOW_SUBTILES) + outline_subtiles(color); + else if (LP_DEBUG & DEBUG_SHOW_TILES) + outline_tile(color); + } +#endif } @@ -805,7 +824,7 @@ struct lp_rasterizer * lp_rast_create( void ) { struct lp_rasterizer *rast; - unsigned i, cbuf; + unsigned i; rast = CALLOC_STRUCT(lp_rasterizer); if(!rast) @@ -816,8 +835,10 @@ lp_rast_create( void ) for (i = 0; i < Elements(rast->tasks); i++) { struct lp_rasterizer_task *task = &rast->tasks[i]; +#if 0 for (cbuf = 0; cbuf < PIPE_MAX_COLOR_BUFS; cbuf++ ) task->tile.color[cbuf] = align_malloc(TILE_SIZE * TILE_SIZE * 4, 16); +#endif task->rast = rast; task->thread_index = i; @@ -836,12 +857,14 @@ lp_rast_create( void ) */ void lp_rast_destroy( struct lp_rasterizer *rast ) { - unsigned i, cbuf; + unsigned i; +#if 0 for (i = 0; i < Elements(rast->tasks); i++) { for (cbuf = 0; cbuf < PIPE_MAX_COLOR_BUFS; cbuf++ ) align_free(rast->tasks[i].tile.color[cbuf]); } +#endif /* Set exit_flag and signal each thread's work_ready semaphore. * Each thread will be woken up, notice that the exit_flag is set and diff --git a/src/gallium/drivers/llvmpipe/lp_rast_priv.h b/src/gallium/drivers/llvmpipe/lp_rast_priv.h index 6ee9bca..8833cf7 100644 --- a/src/gallium/drivers/llvmpipe/lp_rast_priv.h +++ b/src/gallium/drivers/llvmpipe/lp_rast_priv.h @@ -42,22 +42,10 @@ struct lp_rasterizer; /** - * A tile's color and depth memory. - * We can choose whatever layout for the internal tile storage we prefer. - */ -struct lp_rast_tile -{ - uint8_t *color[PIPE_MAX_COLOR_BUFS]; -}; - - -/** * Per-thread rasterization state */ struct lp_rasterizer_task { - struct lp_rast_tile tile; /** Tile color/z/stencil memory */ - unsigned x, y; /**< Pos of this tile in framebuffer, in pixels */ const struct lp_rast_state *current_state; @@ -86,9 +74,8 @@ struct lp_rasterizer */ struct { void *map; - unsigned stride; - unsigned width; - unsigned height; + unsigned tiles_per_row; + unsigned blocksize; enum pipe_format format; } cbuf[PIPE_MAX_COLOR_BUFS]; @@ -164,6 +151,36 @@ lp_rast_depth_pointer( struct lp_rasterizer *rast, } +static INLINE void * +lp_rast_color_pointer( struct lp_rasterizer *rast, + unsigned buf, unsigned x, unsigned y ) +{ + unsigned tx, ty, tile_offset; + unsigned px, py, pixel_offset; + void * color; + + assert((x % TILE_VECTOR_WIDTH) == 0); + assert((y % TILE_VECTOR_HEIGHT) == 0); + + if (!rast->cbuf[buf].map) + return NULL; + + tx = x / TILE_SIZE; + ty = y / TILE_SIZE; + tile_offset = ty * rast->cbuf[buf].tiles_per_row + tx; + tile_offset *= TILE_SIZE * TILE_SIZE * 4; + + px = x % TILE_SIZE; + py = y % TILE_SIZE; + pixel_offset = tile_pixel_offset(px, py, 0); + + color = (ubyte *) rast->cbuf[buf].map + tile_offset + pixel_offset; + + assert(lp_check_alignment(color, 16)); + return color; +} + + /** * Shade all pixels in a 4x4 block. The fragment code omits the @@ -177,7 +194,6 @@ lp_rast_shade_quads_all( struct lp_rasterizer_task *task, { struct lp_rasterizer *rast = task->rast; const struct lp_rast_state *state = task->current_state; - struct lp_rast_tile *tile = &task->tile; const unsigned ix = x % TILE_SIZE, iy = y % TILE_SIZE; uint8_t *color[PIPE_MAX_COLOR_BUFS]; void *depth; @@ -188,21 +204,21 @@ lp_rast_shade_quads_all( struct lp_rasterizer_task *task, /* color buffer */ for (i = 0; i < rast->state.nr_cbufs; i++) - color[i] = tile->color[i] + 4 * block_offset; + color[i] = lp_rast_color_pointer(rast, i, x, y); depth = lp_rast_depth_pointer(rast, x, y); - /* run shader */ - state->jit_function[0]( &state->jit_context, - x, y, - inputs->facing, - inputs->a0, - inputs->dadx, - inputs->dady, - color, - depth, - INT_MIN, INT_MIN, INT_MIN, - NULL, NULL, NULL ); + /* run shader on 4x4 block */ + state->jit_function[RAST_WHOLE]( &state->jit_context, + x, y, + inputs->facing, + inputs->a0, + inputs->dadx, + inputs->dady, + color, + depth, + INT_MIN, INT_MIN, INT_MIN, + NULL, NULL, NULL ); } diff --git a/src/gallium/drivers/llvmpipe/lp_texture.c b/src/gallium/drivers/llvmpipe/lp_texture.c index 4d5cc70..f36c49d 100644 --- a/src/gallium/drivers/llvmpipe/lp_texture.c +++ b/src/gallium/drivers/llvmpipe/lp_texture.c @@ -43,7 +43,7 @@ #include "lp_context.h" #include "lp_flush.h" #include "lp_screen.h" -#include "lp_swizzle.h" +#include "lp_tile_image.h" #include "lp_texture.h" #include "lp_tile_size.h" @@ -175,6 +175,19 @@ llvmpipe_texture_destroy(struct pipe_texture *pt) } +static unsigned +tiled_stride(unsigned width, unsigned height) +{ + /* size in tiles */ + unsigned wt = (width + TILE_SIZE - 1) / TILE_SIZE; + /*unsigned ht = (height + TILE_SIZE - 1) / TILE_SIZE;*/ + + unsigned tiled_stride = wt * TILE_SIZE * TILE_SIZE * 4; + + return tiled_stride; +} + + /** * Map a texture for read/write (rendering). Without any synchronization. */ @@ -203,6 +216,23 @@ llvmpipe_texture_map(struct pipe_texture *texture, /* FIXME: keep map count? */ map = winsys->displaytarget_map(winsys, lpt->dt, usage); + + /* convert from linear to tiled layout? */ + if (1111) + { + void *tiled = llvmpipe_get_tiled_texture_image(lpt, 0, 0, + LP_TEXTURE_READ_WRITE); + lp_linear_to_tiled(map, tiled, + lpt->base.width0, lpt->base.height0, + lpt->base.format, + lpt->stride[0], + tiled_stride(lpt->base.width0, lpt->base.height0)); + + lpt->dt_map = map; + + map = tiled; + } + } else { /* regular texture */ @@ -227,7 +257,10 @@ llvmpipe_texture_map(struct pipe_texture *texture, offset = 0; } - map = llvmpipe_get_linear_texture_image(lpt, face, level, usage); + if (layout == LP_TEXTURE_LINEAR) + map = llvmpipe_get_linear_texture_image(lpt, face, level, usage); + else + map = llvmpipe_get_tiled_texture_image(lpt, face, level, usage); map += offset; } @@ -255,6 +288,18 @@ llvmpipe_texture_unmap(struct pipe_texture *texture, assert(level == 0); assert(zslice == 0); + /* convert from tiled to linear layout */ + if (1111) + { + void *tiled = llvmpipe_get_tiled_texture_image(lpt, 0, 0, + LP_TEXTURE_READ); + lp_tiled_to_linear(tiled, lpt->dt_map, + lpt->base.width0, lpt->base.height0, + lpt->base.format, + tiled_stride(lpt->base.width0, lpt->base.height0), + lpt->stride[0]); + } + winsys->displaytarget_unmap(winsys, lpt->dt); } } @@ -524,11 +569,15 @@ get_texture_image_data(struct llvmpipe_texture *lpt, const unsigned height = u_minify(lpt->base.height0, level); if (getting_linear) - lp_tiled_to_linear(width, height, lpt->base.format, - lpt->stride[level], other_data, target_data); + lp_tiled_to_linear(other_data, target_data, + width, height, lpt->base.format, + tiled_stride(width, height), + lpt->stride[level]); else - lp_linear_to_tiled(width, height, lpt->base.format, - lpt->stride[level], other_data, target_data); + lp_linear_to_tiled(other_data, target_data, + width, height, lpt->base.format, + lpt->stride[level], + tiled_stride(width, height)); /* target image is now equal to the other image */ target_img->timestamp = other_img->timestamp; diff --git a/src/gallium/drivers/llvmpipe/lp_texture.h b/src/gallium/drivers/llvmpipe/lp_texture.h index 07c5284..bb1a8fd 100644 --- a/src/gallium/drivers/llvmpipe/lp_texture.h +++ b/src/gallium/drivers/llvmpipe/lp_texture.h @@ -86,6 +86,7 @@ struct llvmpipe_texture * usage. */ struct sw_displaytarget *dt; + void *dt_map; /** * Malloc'ed data for regular textures, or a mapping to dt above. _______________________________________________ mesa-commit mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/mesa-commit
