diff options
Diffstat (limited to 'src/gallium/drivers/llvmpipe/lp_texture.c')
-rw-r--r-- | src/gallium/drivers/llvmpipe/lp_texture.c | 176 |
1 files changed, 114 insertions, 62 deletions
diff --git a/src/gallium/drivers/llvmpipe/lp_texture.c b/src/gallium/drivers/llvmpipe/lp_texture.c index 5f75078109..779b486bfd 100644 --- a/src/gallium/drivers/llvmpipe/lp_texture.c +++ b/src/gallium/drivers/llvmpipe/lp_texture.c @@ -37,10 +37,12 @@ #include "util/u_format.h" #include "util/u_math.h" #include "util/u_memory.h" +#include "util/u_transfer.h" #include "lp_context.h" #include "lp_screen.h" #include "lp_texture.h" +#include "lp_setup.h" #include "lp_tile_size.h" #include "state_tracker/sw_winsys.h" @@ -50,10 +52,10 @@ * Simple, maximally packed layout. */ static boolean -llvmpipe_texture_layout(struct llvmpipe_screen *screen, - struct llvmpipe_texture *lpt) +llvmpipe_resource_layout(struct llvmpipe_screen *screen, + struct llvmpipe_resource *lpt) { - struct pipe_texture *pt = &lpt->base; + struct pipe_resource *pt = &lpt->base; unsigned level; unsigned width = pt->width0; unsigned height = pt->height0; @@ -91,7 +93,7 @@ llvmpipe_texture_layout(struct llvmpipe_screen *screen, static boolean llvmpipe_displaytarget_layout(struct llvmpipe_screen *screen, - struct llvmpipe_texture *lpt) + struct llvmpipe_resource *lpt) { struct sw_winsys *winsys = screen->winsys; @@ -111,12 +113,12 @@ llvmpipe_displaytarget_layout(struct llvmpipe_screen *screen, } -static struct pipe_texture * -llvmpipe_texture_create(struct pipe_screen *_screen, - const struct pipe_texture *templat) +static struct pipe_resource * +llvmpipe_resource_create(struct pipe_screen *_screen, + const struct pipe_resource *templat) { struct llvmpipe_screen *screen = llvmpipe_screen(_screen); - struct llvmpipe_texture *lpt = CALLOC_STRUCT(llvmpipe_texture); + struct llvmpipe_resource *lpt = CALLOC_STRUCT(llvmpipe_resource); if (!lpt) return NULL; @@ -131,7 +133,7 @@ llvmpipe_texture_create(struct pipe_screen *_screen, goto fail; } else { - if (!llvmpipe_texture_layout(screen, lpt)) + if (!llvmpipe_resource_layout(screen, lpt)) goto fail; } @@ -144,10 +146,11 @@ llvmpipe_texture_create(struct pipe_screen *_screen, static void -llvmpipe_texture_destroy(struct pipe_texture *pt) +llvmpipe_resource_destroy(struct pipe_screen *pscreen, + struct pipe_resource *pt) { - struct llvmpipe_screen *screen = llvmpipe_screen(pt->screen); - struct llvmpipe_texture *lpt = llvmpipe_texture(pt); + struct llvmpipe_screen *screen = llvmpipe_screen(pscreen); + struct llvmpipe_resource *lpt = llvmpipe_resource(pt); if (lpt->dt) { /* display target */ @@ -165,11 +168,11 @@ llvmpipe_texture_destroy(struct pipe_texture *pt) static struct pipe_surface * llvmpipe_get_tex_surface(struct pipe_screen *screen, - struct pipe_texture *pt, + struct pipe_resource *pt, unsigned face, unsigned level, unsigned zslice, unsigned usage) { - struct llvmpipe_texture *lpt = llvmpipe_texture(pt); + struct llvmpipe_resource *lpt = llvmpipe_resource(pt); struct pipe_surface *ps; assert(level <= pt->last_level); @@ -177,7 +180,7 @@ llvmpipe_get_tex_surface(struct pipe_screen *screen, ps = CALLOC_STRUCT(pipe_surface); if (ps) { pipe_reference_init(&ps->reference, 1); - pipe_texture_reference(&ps->texture, pt); + pipe_resource_reference(&ps->texture, pt); ps->format = pt->format; ps->width = u_minify(pt->width0, level); ps->height = u_minify(pt->height0, level); @@ -210,7 +213,7 @@ llvmpipe_get_tex_surface(struct pipe_screen *screen, /* XXX shouldn't that rather be tex_height = align(ps->height, 2); - to account for alignment done in llvmpipe_texture_layout ? + to account for alignment done in llvmpipe_resource_layout ? */ if (pt->target == PIPE_TEXTURE_CUBE) { unsigned tex_height = ps->height; @@ -237,55 +240,56 @@ llvmpipe_tex_surface_destroy(struct pipe_surface *surf) * where it would happen. For llvmpipe, nothing to do. */ assert(surf->texture); - pipe_texture_reference(&surf->texture, NULL); + pipe_resource_reference(&surf->texture, NULL); FREE(surf); } static struct pipe_transfer * llvmpipe_get_transfer(struct pipe_context *pipe, - struct pipe_texture *texture, - unsigned face, unsigned level, unsigned zslice, - enum pipe_transfer_usage usage, - unsigned x, unsigned y, unsigned w, unsigned h) + struct pipe_resource *resource, + struct pipe_subresource sr, + enum pipe_transfer_usage usage, + const struct pipe_box *box) { - struct llvmpipe_texture *lptex = llvmpipe_texture(texture); + struct llvmpipe_resource *lptex = llvmpipe_resource(resource); struct llvmpipe_transfer *lpt; - assert(texture); - assert(level <= texture->last_level); + assert(resource); + assert(sr.level <= resource->last_level); lpt = CALLOC_STRUCT(llvmpipe_transfer); if (lpt) { struct pipe_transfer *pt = &lpt->base; - pipe_texture_reference(&pt->texture, texture); - pt->x = x; - pt->y = y; - pt->width = align(w, TILE_SIZE); - pt->height = align(h, TILE_SIZE); - pt->stride = lptex->stride[level]; + pipe_resource_reference(&pt->resource, resource); + pt->box = *box; + pt->stride = lptex->stride[sr.level]; pt->usage = usage; - pt->face = face; - pt->level = level; - pt->zslice = zslice; - lpt->offset = lptex->level_offset[level]; + /* XXX: this is bogus - the caller should be doing this, not + * imposing it on all transfers. + */ + pt->box.width = align(pt->box.width, TILE_SIZE); + pt->box.height = align(pt->box.height, TILE_SIZE); + + pt->stride = lptex->stride[sr.level]; + lpt->offset = lptex->level_offset[sr.level]; /* XXX shouldn't that rather be - tex_height = align(u_minify(texture->height0, level), 2) - to account for alignment done in llvmpipe_texture_layout ? + tex_height = align(u_minify(resource->height0, level), 2) + to account for alignment done in llvmpipe_resource_layout ? */ - if (texture->target == PIPE_TEXTURE_CUBE) { - unsigned tex_height = u_minify(texture->height0, level); - lpt->offset += face * util_format_get_nblocksy(texture->format, tex_height) * pt->stride; + if (resource->target == PIPE_TEXTURE_CUBE) { + unsigned tex_height = u_minify(resource->height0, sr.level); + lpt->offset += sr.face * util_format_get_nblocksy(resource->format, tex_height) * pt->stride; } - else if (texture->target == PIPE_TEXTURE_3D) { - unsigned tex_height = u_minify(texture->height0, level); - lpt->offset += zslice * util_format_get_nblocksy(texture->format, tex_height) * pt->stride; + else if (resource->target == PIPE_TEXTURE_3D) { + unsigned tex_height = u_minify(resource->height0, sr.level); + lpt->offset += box->z * util_format_get_nblocksy(resource->format, tex_height) * pt->stride; } else { - assert(face == 0); - assert(zslice == 0); + assert(sr.face == 0); + assert(box->z == 0); } return pt; } @@ -301,8 +305,8 @@ llvmpipe_transfer_destroy(struct pipe_context *pipe, * needed post-processing to put them into hardware layout, this is * where it would happen. For llvmpipe, nothing to do. */ - assert (transfer->texture); - pipe_texture_reference(&transfer->texture, NULL); + assert (transfer->resource); + pipe_resource_reference(&transfer->resource, NULL); FREE(transfer); } @@ -313,11 +317,11 @@ llvmpipe_transfer_map( struct pipe_context *pipe, { struct llvmpipe_screen *screen = llvmpipe_screen(pipe->screen); ubyte *map, *xfer_map; - struct llvmpipe_texture *lpt; + struct llvmpipe_resource *lpt; enum pipe_format format; - assert(transfer->texture); - lpt = llvmpipe_texture(transfer->texture); + assert(transfer->resource); + lpt = llvmpipe_resource(transfer->resource); format = lpt->base.format; if (lpt->dt) { @@ -325,27 +329,27 @@ llvmpipe_transfer_map( struct pipe_context *pipe, struct sw_winsys *winsys = screen->winsys; map = winsys->displaytarget_map(winsys, lpt->dt, - pipe_transfer_buffer_flags(transfer)); + transfer->usage); if (map == NULL) return NULL; } else { - /* regular texture */ + /* regular resource */ map = lpt->data; } /* May want to different things here depending on read/write nature * of the map: */ - if (transfer->texture && (transfer->usage & PIPE_TRANSFER_WRITE)) { - /* Do something to notify sharing contexts of a texture change. + if (transfer->resource && (transfer->usage & PIPE_TRANSFER_WRITE)) { + /* Do something to notify sharing contexts of a resource change. */ screen->timestamp++; } xfer_map = map + llvmpipe_transfer(transfer)->offset + - transfer->y / util_format_get_blockheight(format) * transfer->stride + - transfer->x / util_format_get_blockwidth(format) * util_format_get_blocksize(format); + transfer->box.y / util_format_get_blockheight(format) * transfer->stride + + transfer->box.x / util_format_get_blockwidth(format) * util_format_get_blocksize(format); /*printf("map = %p xfer map = %p\n", map, xfer_map);*/ return xfer_map; } @@ -356,10 +360,10 @@ llvmpipe_transfer_unmap(struct pipe_context *pipe, struct pipe_transfer *transfer) { struct llvmpipe_screen *lp_screen = llvmpipe_screen(pipe->screen); - struct llvmpipe_texture *lpt; + struct llvmpipe_resource *lpt; - assert(transfer->texture); - lpt = llvmpipe_texture(transfer->texture); + assert(transfer->resource); + lpt = llvmpipe_resource(transfer->resource); if (lpt->dt) { /* display target */ @@ -368,12 +372,56 @@ llvmpipe_transfer_unmap(struct pipe_context *pipe, } } +static unsigned int +llvmpipe_is_resource_referenced( struct pipe_context *pipe, + struct pipe_resource *presource, + unsigned face, unsigned level) +{ + struct llvmpipe_context *llvmpipe = llvmpipe_context( pipe ); + + if (presource->target == PIPE_BUFFER) + return PIPE_UNREFERENCED; + + return lp_setup_is_resource_referenced(llvmpipe->setup, presource); +} + + + +/** + * Create buffer which wraps user-space data. + */ +static struct pipe_resource * +llvmpipe_user_buffer_create(struct pipe_screen *screen, + void *ptr, + unsigned bytes, + unsigned usage) +{ + struct llvmpipe_resource *buffer; + + buffer = CALLOC_STRUCT(llvmpipe_resource); + if(!buffer) + return NULL; + + pipe_reference_init(&buffer->base.reference, 1); + buffer->base.screen = screen; + buffer->base.format = PIPE_FORMAT_R8_UNORM; /* ?? */ + buffer->base.usage = PIPE_BUFFER_USAGE_CPU_READ | usage; + buffer->base.width0 = bytes; + buffer->base.height0 = 1; + buffer->base.depth0 = 1; + buffer->userBuffer = TRUE; + buffer->data = ptr; + + return &buffer->base; +} + void -llvmpipe_init_screen_texture_funcs(struct pipe_screen *screen) +llvmpipe_init_screen_resource_funcs(struct pipe_screen *screen) { - screen->texture_create = llvmpipe_texture_create; - screen->texture_destroy = llvmpipe_texture_destroy; + screen->resource_create = llvmpipe_resource_create; + screen->resource_destroy = llvmpipe_resource_destroy; + screen->user_buffer_create = llvmpipe_user_buffer_create; screen->get_tex_surface = llvmpipe_get_tex_surface; screen->tex_surface_destroy = llvmpipe_tex_surface_destroy; @@ -381,10 +429,14 @@ llvmpipe_init_screen_texture_funcs(struct pipe_screen *screen) void -llvmpipe_init_context_texture_funcs(struct pipe_context *pipe) +llvmpipe_init_context_resource_funcs(struct pipe_context *pipe) { pipe->get_transfer = llvmpipe_get_transfer; pipe->transfer_destroy = llvmpipe_transfer_destroy; pipe->transfer_map = llvmpipe_transfer_map; pipe->transfer_unmap = llvmpipe_transfer_unmap; + pipe->is_resource_referenced = llvmpipe_is_resource_referenced; + + pipe->transfer_flush_region = u_default_transfer_flush_region; + pipe->transfer_inline_write = u_default_transfer_inline_write; } |