From 65233674d3598fee90d762b0c2826752f2619f05 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Tue, 9 Mar 2010 14:03:41 +0000 Subject: 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. --- src/gallium/drivers/cell/ppu/cell_screen.c | 16 ------ src/gallium/drivers/cell/ppu/cell_texture.c | 89 ++++++++++++++++++----------- src/gallium/drivers/cell/ppu/cell_texture.h | 1 + 3 files changed, 58 insertions(+), 48 deletions(-) (limited to 'src/gallium/drivers') diff --git a/src/gallium/drivers/cell/ppu/cell_screen.c b/src/gallium/drivers/cell/ppu/cell_screen.c index 36479e8e0c..00035be53a 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 f3fc080aa3..002dd3a9b5 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 55b983218f..b89db1a5a8 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. -- cgit v1.2.3