Mesa (lp-surface-tiling): llvmpipe: checkpoint WIP: directly render to tiled texture buffers
Brian Paul
brianp at kemper.freedesktop.org
Fri Mar 19 16:06:08 PDT 2010
Module: Mesa
Branch: lp-surface-tiling
Commit: 3a2f08b6a550c69ef5e874f482be30252cbf8bfa
URL: http://cgit.freedesktop.org/mesa/mesa/commit/?id=3a2f08b6a550c69ef5e874f482be30252cbf8bfa
Author: Brian Paul <brianp at vmware.com>
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.
More information about the mesa-commit
mailing list