mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-06 13:48:06 +02:00
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.
This commit is contained in:
parent
fe94a363e5
commit
65233674d3
4 changed files with 58 additions and 129 deletions
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue