diff options
Diffstat (limited to 'src/gallium/winsys/xlib/xm_winsys.c')
-rw-r--r-- | src/gallium/winsys/xlib/xm_winsys.c | 61 |
1 files changed, 51 insertions, 10 deletions
diff --git a/src/gallium/winsys/xlib/xm_winsys.c b/src/gallium/winsys/xlib/xm_winsys.c index 68ead7f528e..c4a30d37023 100644 --- a/src/gallium/winsys/xlib/xm_winsys.c +++ b/src/gallium/winsys/xlib/xm_winsys.c @@ -276,6 +276,39 @@ xm_buffer_destroy(struct pipe_winsys *pws, /** + * 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(uint *tile) +{ + uint tile2[TILE_SIZE * TILE_SIZE]; + 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); + tile2[y * TILE_SIZE + (x + 0)] = tile[k]; + tile2[y * TILE_SIZE + (x + 1)] = tile[k+1]; + tile2[(y + 1) * TILE_SIZE + (x + 0)] = tile[k+2]; + tile2[(y + 1) * TILE_SIZE + (x + 1)] = tile[k+3]; + } + } + memcpy(tile, tile2, sizeof(tile2)); +} + + + +/** * Display a surface that's in a tiled configuration. That is, all the * pixels for a TILE_SIZExTILE_SIZE block are contiguous in memory. */ @@ -287,16 +320,16 @@ xmesa_display_surface_tiled(XMesaBuffer b, const struct pipe_surface *surf) const uint tilesPerRow = (surf->width + TILE_SIZE - 1) / TILE_SIZE; uint x, y; - /* check that the XImage has been previously initialized */ - assert(ximage->format); - assert(ximage->bitmap_unit); - if (XSHM_ENABLED(xm_buf) && (xm_buf->tempImage == NULL)) { alloc_shm_ximage(xm_buf, b, TILE_SIZE, TILE_SIZE); } ximage = (XSHM_ENABLED(xm_buf)) ? xm_buf->tempImage : b->tempImage; + /* check that the XImage has been previously initialized */ + assert(ximage->format); + assert(ximage->bitmap_unit); + if (!XSHM_ENABLED(xm_buf)) { /* update XImage's fields */ ximage->width = TILE_SIZE; @@ -306,24 +339,32 @@ xmesa_display_surface_tiled(XMesaBuffer b, const struct pipe_surface *surf) for (y = 0; y < surf->height; y += TILE_SIZE) { for (x = 0; x < surf->width; x += TILE_SIZE) { - int dx = x; - int dy = y; 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 *= 4 * TILE_SIZE * TILE_SIZE; ximage->data = (char *) xm_buf->data + offset; + twiddle_tile((uint *) ximage->data); + if (XSHM_ENABLED(xm_buf)) { #if defined(USE_XSHM) && !defined(XFree86Server) XShmPutImage(b->xm_visual->display, b->drawable, b->gc, - ximage, 0, 0, x, y, TILE_SIZE, TILE_SIZE, False); + ximage, 0, 0, x, y, w, h, False); #endif - } else { + } + else { XPutImage(b->xm_visual->display, b->drawable, b->gc, - ximage, 0, 0, dx, dy, TILE_SIZE, TILE_SIZE); + ximage, 0, 0, x, y, w, h); } } } @@ -543,7 +584,7 @@ xm_surface_release(struct pipe_winsys *winsys, struct pipe_surface **s) surf->refcount--; if (surf->refcount == 0) { if (surf->buffer) - pipe_buffer_reference(winsys, &surf->buffer, NULL); + winsys_buffer_reference(winsys, &surf->buffer, NULL); free(surf); } *s = NULL; |