summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKeith Whitwell <[email protected]>2010-03-09 14:03:41 +0000
committerKeith Whitwell <[email protected]>2010-03-09 14:03:41 +0000
commit65233674d3598fee90d762b0c2826752f2619f05 (patch)
tree650d76d02c46df6ab011d6c384b6571f7a92db1a
parentfe94a363e53ac5e19a919ea6eef2e22b4da4fc6f (diff)
cell: untwiddle surface contents in flush_frontbuffer()
Don't make the shared software winsys rely on internal knowledge about the cell driver's texture twiddling. This is just a sketch and hasn't even been compile tested.
-rw-r--r--src/gallium/drivers/cell/ppu/cell_screen.c16
-rw-r--r--src/gallium/drivers/cell/ppu/cell_texture.c89
-rw-r--r--src/gallium/drivers/cell/ppu/cell_texture.h1
-rw-r--r--src/gallium/winsys/xlib/xlib_cell.c81
4 files changed, 58 insertions, 129 deletions
diff --git a/src/gallium/drivers/cell/ppu/cell_screen.c b/src/gallium/drivers/cell/ppu/cell_screen.c
index 36479e8e0c2..00035be53a1 100644
--- a/src/gallium/drivers/cell/ppu/cell_screen.c
+++ b/src/gallium/drivers/cell/ppu/cell_screen.c
@@ -164,22 +164,6 @@ cell_destroy_screen( struct pipe_screen *screen )
FREE(screen);
}
-/* This used to be overriden by the co-state tracker, but really needs
- * to be active with sw_winsys.
- */
-static void
-cell_flush_frontbuffer(struct pipe_screen *_screen,
- struct pipe_surface *surface,
- void *context_private)
-{
- struct cell_screen *screen = cell_screen(_screen);
- struct sw_winsys *winsys = screen->winsys;
- struct cell_texture *texture = cell_texture(surface->texture);
-
- assert(texture->dt);
- if (texture->dt)
- winsys->displaytarget_display(winsys, texture->dt, context_private);
-}
/**
diff --git a/src/gallium/drivers/cell/ppu/cell_texture.c b/src/gallium/drivers/cell/ppu/cell_texture.c
index f3fc080aa39..002dd3a9b55 100644
--- a/src/gallium/drivers/cell/ppu/cell_texture.c
+++ b/src/gallium/drivers/cell/ppu/cell_texture.c
@@ -108,7 +108,7 @@ cell_displaytarget_layout(struct pipe_screen *screen,
ct->base.width0,
ct->base.height0,
16,
- &ct->stride[0] );
+ &ct->dt_stride );
return ct->dt != NULL;
}
@@ -125,21 +125,29 @@ cell_texture_create(struct pipe_screen *screen,
pipe_reference_init(&ct->base.reference, 1);
ct->base.screen = screen;
+ /* Create both a displaytarget (linear) and regular texture
+ * (twiddled). Convert twiddled->linear at flush_frontbuffer time.
+ */
if (ct->base.tex_usage & (PIPE_TEXTURE_USAGE_DISPLAY_TARGET |
PIPE_TEXTURE_USAGE_SCANOUT |
PIPE_TEXTURE_USAGE_SHARED)) {
if (!cell_displaytarget_layout(screen, ct))
goto fail;
}
- else {
- if (!cell_texture_layout(screen, ct))
- goto fail;
- }
+
+ if (!cell_texture_layout(screen, ct))
+ goto fail;
return &ct->base;
fail:
+ if (ct->dt) {
+ struct sw_winsys winsys = cell_screen(screen)->winsys;
+ winsys->displaytarget_destroy(winsys, ct->dt);
+ }
+
FREE(ct);
+
return NULL;
}
@@ -151,20 +159,12 @@ cell_texture_destroy(struct pipe_texture *pt)
struct sw_winsys *winsys = screen->winsys;
struct cell_texture *ct = cell_texture(pt);
- if (ct->mapped) {
- if (ct->dt)
- winsys->displaytarget_unmap(winsys, ct->dt);
- ct->mapped = NULL;
- }
-
if (ct->dt) {
/* display target */
winsys->displaytarget_destroy(winsys, ct->dt);
}
- else {
- /* regular texture */
- align_free(ct->data);
- }
+
+ align_free(ct->data);
FREE(ct);
}
@@ -432,19 +432,9 @@ cell_transfer_map(struct pipe_screen *screen, struct pipe_transfer *transfer)
assert(transfer->texture);
if (ct->mapped == NULL) {
- if (ct->dt) {
- struct sw_winsys *winsys = cell_screen(screen)->winsys;
- ct->mapped = winsys->displaytarget_map(screen, ct->dt,
- pipe_transfer_buffer_flags(transfer));
- }
- else {
- ct->mapped = ct->data;
- }
+ ct->mapped = ct->data;
}
- if (ct->mapped == NULL)
- return NULL;
-
/*
* Create a buffer of ordinary memory for the linear texture.
* This is the memory that the user will read/write.
@@ -511,18 +501,51 @@ cell_transfer_unmap(struct pipe_screen *screen,
}
}
- if (ct->dt) {
- /* display target */
- struct sw_winsys *winsys = cell_screen(screen)->winsys;
- winsys->displaytarget_unmap(winsys, ct->dt);
- }
-
align_free(ctrans->map);
ctrans->map = NULL;
}
+/* This used to be overriden by the co-state tracker, but really needs
+ * to be active with sw_winsys.
+ *
+ * Contrasting with llvmpipe and softpipe, this is the only place
+ * where we use the ct->dt display target in any real sense.
+ *
+ * Basically just untwiddle our local data into the linear
+ * displaytarget.
+ */
+static void
+cell_flush_frontbuffer(struct pipe_screen *_screen,
+ struct pipe_surface *surface,
+ void *context_private)
+{
+ struct cell_screen *screen = cell_screen(_screen);
+ struct sw_winsys *winsys = screen->winsys;
+ struct cell_texture *ct = cell_texture(surface->texture);
+
+ if (!ct->dt)
+ return;
+
+ /* Need to untwiddle from our internal representation here:
+ */
+ {
+ unsigned *map = winsys->displaytarget_map(winsys, ct->dt);
+ unsigned *src = (unsigned *)(ct->data + ct->level_offset[surface->level]);
+
+ untwiddle_image_uint(surface->width,
+ surface->height,
+ TILE_SIZE,
+ map,
+ ct->dt_stride,
+ src);
+
+ winsys->displaytarget_unmap(winsys, c->dt);
+ }
+
+ winsys->displaytarget_display(winsys, ct->dt, context_private);
+}
void
@@ -539,4 +562,6 @@ cell_init_screen_texture_funcs(struct pipe_screen *screen)
screen->transfer_map = cell_transfer_map;
screen->transfer_unmap = cell_transfer_unmap;
+
+ screen->flush_frontbuffer = cell_flush_frontbuffer;
}
diff --git a/src/gallium/drivers/cell/ppu/cell_texture.h b/src/gallium/drivers/cell/ppu/cell_texture.h
index 55b983218f9..b89db1a5a8c 100644
--- a/src/gallium/drivers/cell/ppu/cell_texture.h
+++ b/src/gallium/drivers/cell/ppu/cell_texture.h
@@ -48,6 +48,7 @@ struct cell_texture
* usage.
*/
struct sw_displaytarget *dt;
+ unsigned dt_stride;
/**
* Malloc'ed data for regular textures, or a mapping to dt above.
diff --git a/src/gallium/winsys/xlib/xlib_cell.c b/src/gallium/winsys/xlib/xlib_cell.c
index ce4efe88510..2ad1aab4397 100644
--- a/src/gallium/winsys/xlib/xlib_cell.c
+++ b/src/gallium/winsys/xlib/xlib_cell.c
@@ -47,88 +47,7 @@
-/**
- * For Cell. Basically, rearrange the pixels/quads from this layout:
- * +--+--+--+--+
- * |p0|p1|p2|p3|....
- * +--+--+--+--+
- *
- * to this layout:
- * +--+--+
- * |p0|p1|....
- * +--+--+
- * |p2|p3|
- * +--+--+
- */
-static void
-twiddle_tile(const uint *tileIn, uint *tileOut)
-{
- int y, x;
-
- for (y = 0; y < TILE_SIZE; y+=2) {
- for (x = 0; x < TILE_SIZE; x+=2) {
- int k = 4 * (y/2 * TILE_SIZE/2 + x/2);
- tileOut[y * TILE_SIZE + (x + 0)] = tileIn[k];
- tileOut[y * TILE_SIZE + (x + 1)] = tileIn[k+1];
- tileOut[(y + 1) * TILE_SIZE + (x + 0)] = tileIn[k+2];
- tileOut[(y + 1) * TILE_SIZE + (x + 1)] = tileIn[k+3];
- }
- }
-}
-/**
- * Display a surface that's in a tiled configuration. That is, all the
- * pixels for a TILE_SIZExTILE_SIZE block are contiguous in memory.
- */
-static void
-xm_displaytarget_display(struct sw_winsys *ws,
- struct sw_displaytarget *dt,
- void *winsys_drawable)
-{
- struct xmesa_buffer *xm_buffer = (struct xm_drawable *)winsys_drawable;
- XImage *ximage;
- struct xm_buffer *xm_buf = xm_buffer(
- cell_texture(surf->texture)->buffer);
- const uint tilesPerRow = (surf->width + TILE_SIZE - 1) / TILE_SIZE;
- uint x, y;
-
- ximage = b->tempImage;
-
- /* check that the XImage has been previously initialized */
- assert(ximage->format);
- assert(ximage->bitmap_unit);
-
- /* update XImage's fields */
- ximage->width = TILE_SIZE;
- ximage->height = TILE_SIZE;
- ximage->bytes_per_line = TILE_SIZE * 4;
-
- for (y = 0; y < surf->height; y += TILE_SIZE) {
- for (x = 0; x < surf->width; x += TILE_SIZE) {
- uint tmpTile[TILE_SIZE * TILE_SIZE];
- int tx = x / TILE_SIZE;
- int ty = y / TILE_SIZE;
- int offset = ty * tilesPerRow + tx;
- int w = TILE_SIZE;
- int h = TILE_SIZE;
-
- if (y + h > surf->height)
- h = surf->height - y;
- if (x + w > surf->width)
- w = surf->width - x;
-
- /* offset in pixels */
- offset *= TILE_SIZE * TILE_SIZE;
-
- /* twiddle from ximage buffer to temp tile */
- twiddle_tile((uint *) xm_buf->data + offset, tmpTile);
- /* display temp tile data */
- ximage->data = (char *) tmpTile;
- XPutImage(b->xm_visual->display, b->drawable, b->gc,
- ximage, 0, 0, x, y, w, h);
- }
- }
-}