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);
-}
/**
ct->base.width0,
ct->base.height0,
16,
- &ct->stride[0] );
+ &ct->dt_stride );
return ct->dt != NULL;
}
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;
}
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);
}
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.
}
}
- 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
screen->transfer_map = cell_transfer_map;
screen->transfer_unmap = cell_transfer_unmap;
+
+ screen->flush_frontbuffer = cell_flush_frontbuffer;
}
* usage.
*/
struct sw_displaytarget *dt;
+ unsigned dt_stride;
/**
* Malloc'ed data for regular textures, or a mapping to dt above.
-/**
- * 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);
- }
- }
-}