Home | History | Annotate | Download | only in llvmpipe
      1 /**************************************************************************
      2  *
      3  * Copyright 2006 Tungsten Graphics, Inc., Cedar Park, Texas.
      4  * All Rights Reserved.
      5  *
      6  * Permission is hereby granted, free of charge, to any person obtaining a
      7  * copy of this software and associated documentation files (the
      8  * "Software"), to deal in the Software without restriction, including
      9  * without limitation the rights to use, copy, modify, merge, publish,
     10  * distribute, sub license, and/or sell copies of the Software, and to
     11  * permit persons to whom the Software is furnished to do so, subject to
     12  * the following conditions:
     13  *
     14  * The above copyright notice and this permission notice (including the
     15  * next paragraph) shall be included in all copies or substantial portions
     16  * of the Software.
     17  *
     18  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
     19  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
     20  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
     21  * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
     22  * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
     23  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
     24  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
     25  *
     26  **************************************************************************/
     27  /*
     28   * Authors:
     29   *   Keith Whitwell <keith (at) tungstengraphics.com>
     30   *   Michel Dnzer <michel (at) tungstengraphics.com>
     31   */
     32 
     33 #include <stdio.h>
     34 
     35 #include "pipe/p_context.h"
     36 #include "pipe/p_defines.h"
     37 
     38 #include "util/u_inlines.h"
     39 #include "util/u_cpu_detect.h"
     40 #include "util/u_format.h"
     41 #include "util/u_math.h"
     42 #include "util/u_memory.h"
     43 #include "util/u_simple_list.h"
     44 #include "util/u_transfer.h"
     45 
     46 #include "lp_context.h"
     47 #include "lp_flush.h"
     48 #include "lp_screen.h"
     49 #include "lp_tile_image.h"
     50 #include "lp_texture.h"
     51 #include "lp_setup.h"
     52 #include "lp_state.h"
     53 
     54 #include "state_tracker/sw_winsys.h"
     55 
     56 
     57 #ifdef DEBUG
     58 static struct llvmpipe_resource resource_list;
     59 #endif
     60 static unsigned id_counter = 0;
     61 
     62 
     63 static INLINE boolean
     64 resource_is_texture(const struct pipe_resource *resource)
     65 {
     66    switch (resource->target) {
     67    case PIPE_BUFFER:
     68       return FALSE;
     69    case PIPE_TEXTURE_1D:
     70    case PIPE_TEXTURE_2D:
     71    case PIPE_TEXTURE_RECT:
     72    case PIPE_TEXTURE_3D:
     73    case PIPE_TEXTURE_CUBE:
     74       return TRUE;
     75    default:
     76       assert(0);
     77       return FALSE;
     78    }
     79 }
     80 
     81 
     82 
     83 /**
     84  * Allocate storage for llvmpipe_texture::layout array.
     85  * The number of elements is width_in_tiles * height_in_tiles.
     86  */
     87 static enum lp_texture_layout *
     88 alloc_layout_array(unsigned num_slices, unsigned width, unsigned height)
     89 {
     90    const unsigned tx = align(width, TILE_SIZE) / TILE_SIZE;
     91    const unsigned ty = align(height, TILE_SIZE) / TILE_SIZE;
     92 
     93    assert(num_slices * tx * ty > 0);
     94    assert(LP_TEX_LAYOUT_NONE == 0); /* calloc'ing LP_TEX_LAYOUT_NONE here */
     95 
     96    return (enum lp_texture_layout *)
     97       CALLOC(num_slices * tx * ty, sizeof(enum lp_texture_layout));
     98 }
     99 
    100 
    101 
    102 /**
    103  * Conventional allocation path for non-display textures:
    104  * Just compute row strides here.  Storage is allocated on demand later.
    105  */
    106 static boolean
    107 llvmpipe_texture_layout(struct llvmpipe_screen *screen,
    108                         struct llvmpipe_resource *lpr)
    109 {
    110    struct pipe_resource *pt = &lpr->base;
    111    unsigned level;
    112    unsigned width = pt->width0;
    113    unsigned height = pt->height0;
    114    unsigned depth = pt->depth0;
    115    size_t total_size = 0;
    116 
    117    assert(LP_MAX_TEXTURE_2D_LEVELS <= LP_MAX_TEXTURE_LEVELS);
    118    assert(LP_MAX_TEXTURE_3D_LEVELS <= LP_MAX_TEXTURE_LEVELS);
    119 
    120    for (level = 0; level <= pt->last_level; level++) {
    121 
    122       /* Row stride and image stride (for linear layout) */
    123       {
    124          unsigned alignment, nblocksx, nblocksy, block_size;
    125 
    126          /* For non-compressed formats we need to align the texture size
    127           * to the tile size to facilitate render-to-texture.
    128           */
    129          if (util_format_is_compressed(pt->format))
    130             alignment = 1;
    131          else
    132             alignment = TILE_SIZE;
    133 
    134          nblocksx = util_format_get_nblocksx(pt->format,
    135                                              align(width, alignment));
    136          nblocksy = util_format_get_nblocksy(pt->format,
    137                                              align(height, alignment));
    138          block_size = util_format_get_blocksize(pt->format);
    139 
    140          lpr->row_stride[level] = align(nblocksx * block_size, 16);
    141 
    142          lpr->img_stride[level] = lpr->row_stride[level] * nblocksy;
    143       }
    144 
    145       /* Size of the image in tiles (for tiled layout) */
    146       {
    147          const unsigned width_t = align(width, TILE_SIZE) / TILE_SIZE;
    148          const unsigned height_t = align(height, TILE_SIZE) / TILE_SIZE;
    149          lpr->tiles_per_row[level] = width_t;
    150          lpr->tiles_per_image[level] = width_t * height_t;
    151       }
    152 
    153       /* Number of 3D image slices or cube faces */
    154       {
    155          unsigned num_slices;
    156 
    157          if (lpr->base.target == PIPE_TEXTURE_CUBE)
    158             num_slices = 6;
    159          else if (lpr->base.target == PIPE_TEXTURE_3D)
    160             num_slices = depth;
    161          else
    162             num_slices = 1;
    163 
    164          lpr->num_slices_faces[level] = num_slices;
    165 
    166          lpr->layout[level] = alloc_layout_array(num_slices, width, height);
    167          if (!lpr->layout[level]) {
    168             goto fail;
    169          }
    170       }
    171 
    172       total_size += lpr->num_slices_faces[level] * lpr->img_stride[level];
    173       if (total_size > LP_MAX_TEXTURE_SIZE) {
    174          goto fail;
    175       }
    176 
    177       /* Compute size of next mipmap level */
    178       width = u_minify(width, 1);
    179       height = u_minify(height, 1);
    180       depth = u_minify(depth, 1);
    181    }
    182 
    183    return TRUE;
    184 
    185 fail:
    186    for (level = 0; level <= pt->last_level; level++) {
    187       if (lpr->layout[level]) {
    188          FREE(lpr->layout[level]);
    189       }
    190    }
    191 
    192    return FALSE;
    193 }
    194 
    195 
    196 
    197 static boolean
    198 llvmpipe_displaytarget_layout(struct llvmpipe_screen *screen,
    199                               struct llvmpipe_resource *lpr)
    200 {
    201    struct sw_winsys *winsys = screen->winsys;
    202 
    203    /* Round up the surface size to a multiple of the tile size to
    204     * avoid tile clipping.
    205     */
    206    const unsigned width = align(lpr->base.width0, TILE_SIZE);
    207    const unsigned height = align(lpr->base.height0, TILE_SIZE);
    208    const unsigned width_t = width / TILE_SIZE;
    209    const unsigned height_t = height / TILE_SIZE;
    210 
    211    lpr->tiles_per_row[0] = width_t;
    212    lpr->tiles_per_image[0] = width_t * height_t;
    213    lpr->num_slices_faces[0] = 1;
    214    lpr->img_stride[0] = 0;
    215 
    216    lpr->layout[0] = alloc_layout_array(1, width, height);
    217    if (!lpr->layout[0]) {
    218       return FALSE;
    219    }
    220 
    221    lpr->dt = winsys->displaytarget_create(winsys,
    222                                           lpr->base.bind,
    223                                           lpr->base.format,
    224                                           width, height,
    225                                           16,
    226                                           &lpr->row_stride[0] );
    227 
    228    if (lpr->dt == NULL)
    229       return FALSE;
    230 
    231    {
    232       void *map = winsys->displaytarget_map(winsys, lpr->dt,
    233                                             PIPE_TRANSFER_WRITE);
    234 
    235       if (map)
    236          memset(map, 0, height * lpr->row_stride[0]);
    237 
    238       winsys->displaytarget_unmap(winsys, lpr->dt);
    239    }
    240 
    241    return TRUE;
    242 }
    243 
    244 
    245 static struct pipe_resource *
    246 llvmpipe_resource_create(struct pipe_screen *_screen,
    247                          const struct pipe_resource *templat)
    248 {
    249    struct llvmpipe_screen *screen = llvmpipe_screen(_screen);
    250    struct llvmpipe_resource *lpr = CALLOC_STRUCT(llvmpipe_resource);
    251    if (!lpr)
    252       return NULL;
    253 
    254    lpr->base = *templat;
    255    pipe_reference_init(&lpr->base.reference, 1);
    256    lpr->base.screen = &screen->base;
    257 
    258    /* assert(lpr->base.bind); */
    259 
    260    if (resource_is_texture(&lpr->base)) {
    261       if (lpr->base.bind & PIPE_BIND_DISPLAY_TARGET) {
    262          /* displayable surface */
    263          if (!llvmpipe_displaytarget_layout(screen, lpr))
    264             goto fail;
    265          assert(lpr->layout[0][0] == LP_TEX_LAYOUT_NONE);
    266       }
    267       else {
    268          /* texture map */
    269          if (!llvmpipe_texture_layout(screen, lpr))
    270             goto fail;
    271          assert(lpr->layout[0][0] == LP_TEX_LAYOUT_NONE);
    272       }
    273       assert(lpr->layout[0]);
    274    }
    275    else {
    276       /* other data (vertex buffer, const buffer, etc) */
    277       const enum pipe_format format = templat->format;
    278       const uint w = templat->width0 / util_format_get_blockheight(format);
    279       /* XXX buffers should only have one dimension, those values should be 1 */
    280       const uint h = templat->height0 / util_format_get_blockwidth(format);
    281       const uint d = templat->depth0;
    282       const uint bpp = util_format_get_blocksize(format);
    283       const uint bytes = w * h * d * bpp;
    284       lpr->data = align_malloc(bytes, 16);
    285       if (!lpr->data)
    286          goto fail;
    287       memset(lpr->data, 0, bytes);
    288    }
    289 
    290    lpr->id = id_counter++;
    291 
    292 #ifdef DEBUG
    293    insert_at_tail(&resource_list, lpr);
    294 #endif
    295 
    296    return &lpr->base;
    297 
    298  fail:
    299    FREE(lpr);
    300    return NULL;
    301 }
    302 
    303 
    304 static void
    305 llvmpipe_resource_destroy(struct pipe_screen *pscreen,
    306 			  struct pipe_resource *pt)
    307 {
    308    struct llvmpipe_screen *screen = llvmpipe_screen(pscreen);
    309    struct llvmpipe_resource *lpr = llvmpipe_resource(pt);
    310 
    311    if (lpr->dt) {
    312       /* display target */
    313       struct sw_winsys *winsys = screen->winsys;
    314       winsys->displaytarget_destroy(winsys, lpr->dt);
    315 
    316       if (lpr->tiled[0].data) {
    317          align_free(lpr->tiled[0].data);
    318          lpr->tiled[0].data = NULL;
    319       }
    320 
    321       FREE(lpr->layout[0]);
    322    }
    323    else if (resource_is_texture(pt)) {
    324       /* regular texture */
    325       uint level;
    326 
    327       /* free linear image data */
    328       for (level = 0; level < Elements(lpr->linear); level++) {
    329          if (lpr->linear[level].data) {
    330             align_free(lpr->linear[level].data);
    331             lpr->linear[level].data = NULL;
    332          }
    333       }
    334 
    335       /* free tiled image data */
    336       for (level = 0; level < Elements(lpr->tiled); level++) {
    337          if (lpr->tiled[level].data) {
    338             align_free(lpr->tiled[level].data);
    339             lpr->tiled[level].data = NULL;
    340          }
    341       }
    342 
    343       /* free layout flag arrays */
    344       for (level = 0; level < Elements(lpr->tiled); level++) {
    345          FREE(lpr->layout[level]);
    346          lpr->layout[level] = NULL;
    347       }
    348    }
    349    else if (!lpr->userBuffer) {
    350       assert(lpr->data);
    351       align_free(lpr->data);
    352    }
    353 
    354 #ifdef DEBUG
    355    if (lpr->next)
    356       remove_from_list(lpr);
    357 #endif
    358 
    359    FREE(lpr);
    360 }
    361 
    362 
    363 /**
    364  * Map a resource for read/write.
    365  */
    366 void *
    367 llvmpipe_resource_map(struct pipe_resource *resource,
    368                       unsigned level,
    369                       unsigned layer,
    370                       enum lp_texture_usage tex_usage,
    371                       enum lp_texture_layout layout)
    372 {
    373    struct llvmpipe_resource *lpr = llvmpipe_resource(resource);
    374    uint8_t *map;
    375 
    376    assert(level < LP_MAX_TEXTURE_LEVELS);
    377    assert(layer < (u_minify(resource->depth0, level) + resource->array_size - 1));
    378 
    379    assert(tex_usage == LP_TEX_USAGE_READ ||
    380           tex_usage == LP_TEX_USAGE_READ_WRITE ||
    381           tex_usage == LP_TEX_USAGE_WRITE_ALL);
    382 
    383    assert(layout == LP_TEX_LAYOUT_NONE ||
    384           layout == LP_TEX_LAYOUT_TILED ||
    385           layout == LP_TEX_LAYOUT_LINEAR);
    386 
    387    if (lpr->dt) {
    388       /* display target */
    389       struct llvmpipe_screen *screen = llvmpipe_screen(resource->screen);
    390       struct sw_winsys *winsys = screen->winsys;
    391       unsigned dt_usage;
    392       uint8_t *map2;
    393 
    394       if (tex_usage == LP_TEX_USAGE_READ) {
    395          dt_usage = PIPE_TRANSFER_READ;
    396       }
    397       else {
    398          dt_usage = PIPE_TRANSFER_READ_WRITE;
    399       }
    400 
    401       assert(level == 0);
    402       assert(layer == 0);
    403 
    404       /* FIXME: keep map count? */
    405       map = winsys->displaytarget_map(winsys, lpr->dt, dt_usage);
    406 
    407       /* install this linear image in texture data structure */
    408       lpr->linear[level].data = map;
    409 
    410       /* make sure tiled data gets converted to linear data */
    411       map2 = llvmpipe_get_texture_image(lpr, 0, 0, tex_usage, layout);
    412       if (layout == LP_TEX_LAYOUT_LINEAR)
    413          assert(map == map2);
    414 
    415       return map2;
    416    }
    417    else if (resource_is_texture(resource)) {
    418 
    419       map = llvmpipe_get_texture_image(lpr, layer, level,
    420                                        tex_usage, layout);
    421       return map;
    422    }
    423    else {
    424       return lpr->data;
    425    }
    426 }
    427 
    428 
    429 /**
    430  * Unmap a resource.
    431  */
    432 void
    433 llvmpipe_resource_unmap(struct pipe_resource *resource,
    434                        unsigned level,
    435                        unsigned layer)
    436 {
    437    struct llvmpipe_resource *lpr = llvmpipe_resource(resource);
    438 
    439    if (lpr->dt) {
    440       /* display target */
    441       struct llvmpipe_screen *lp_screen = llvmpipe_screen(resource->screen);
    442       struct sw_winsys *winsys = lp_screen->winsys;
    443 
    444       assert(level == 0);
    445       assert(layer == 0);
    446 
    447       /* make sure linear image is up to date */
    448       (void) llvmpipe_get_texture_image(lpr, layer, level,
    449                                         LP_TEX_USAGE_READ,
    450                                         LP_TEX_LAYOUT_LINEAR);
    451 
    452       winsys->displaytarget_unmap(winsys, lpr->dt);
    453    }
    454 }
    455 
    456 
    457 void *
    458 llvmpipe_resource_data(struct pipe_resource *resource)
    459 {
    460    struct llvmpipe_resource *lpr = llvmpipe_resource(resource);
    461 
    462    assert(!resource_is_texture(resource));
    463 
    464    return lpr->data;
    465 }
    466 
    467 
    468 static struct pipe_resource *
    469 llvmpipe_resource_from_handle(struct pipe_screen *screen,
    470 			      const struct pipe_resource *template,
    471 			      struct winsys_handle *whandle)
    472 {
    473    struct sw_winsys *winsys = llvmpipe_screen(screen)->winsys;
    474    struct llvmpipe_resource *lpr;
    475    unsigned width, height, width_t, height_t;
    476 
    477    /* XXX Seems like from_handled depth textures doesn't work that well */
    478 
    479    lpr = CALLOC_STRUCT(llvmpipe_resource);
    480    if (!lpr) {
    481       goto no_lpr;
    482    }
    483 
    484    lpr->base = *template;
    485    pipe_reference_init(&lpr->base.reference, 1);
    486    lpr->base.screen = screen;
    487 
    488    width = align(lpr->base.width0, TILE_SIZE);
    489    height = align(lpr->base.height0, TILE_SIZE);
    490    width_t = width / TILE_SIZE;
    491    height_t = height / TILE_SIZE;
    492 
    493    /*
    494     * Looks like unaligned displaytargets work just fine,
    495     * at least sampler/render ones.
    496     */
    497 #if 0
    498    assert(lpr->base.width0 == width);
    499    assert(lpr->base.height0 == height);
    500 #endif
    501 
    502    lpr->tiles_per_row[0] = width_t;
    503    lpr->tiles_per_image[0] = width_t * height_t;
    504    lpr->num_slices_faces[0] = 1;
    505    lpr->img_stride[0] = 0;
    506 
    507    lpr->dt = winsys->displaytarget_from_handle(winsys,
    508                                                template,
    509                                                whandle,
    510                                                &lpr->row_stride[0]);
    511    if (!lpr->dt) {
    512       goto no_dt;
    513    }
    514 
    515    lpr->layout[0] = alloc_layout_array(1, lpr->base.width0, lpr->base.height0);
    516    if (!lpr->layout[0]) {
    517       goto no_layout_0;
    518    }
    519 
    520    assert(lpr->layout[0][0] == LP_TEX_LAYOUT_NONE);
    521 
    522    lpr->id = id_counter++;
    523 
    524 #ifdef DEBUG
    525    insert_at_tail(&resource_list, lpr);
    526 #endif
    527 
    528    return &lpr->base;
    529 
    530 no_layout_0:
    531    winsys->displaytarget_destroy(winsys, lpr->dt);
    532 no_dt:
    533    FREE(lpr);
    534 no_lpr:
    535    return NULL;
    536 }
    537 
    538 
    539 static boolean
    540 llvmpipe_resource_get_handle(struct pipe_screen *screen,
    541                             struct pipe_resource *pt,
    542                             struct winsys_handle *whandle)
    543 {
    544    struct sw_winsys *winsys = llvmpipe_screen(screen)->winsys;
    545    struct llvmpipe_resource *lpr = llvmpipe_resource(pt);
    546 
    547    assert(lpr->dt);
    548    if (!lpr->dt)
    549       return FALSE;
    550 
    551    return winsys->displaytarget_get_handle(winsys, lpr->dt, whandle);
    552 }
    553 
    554 
    555 static struct pipe_surface *
    556 llvmpipe_create_surface(struct pipe_context *pipe,
    557                         struct pipe_resource *pt,
    558                         const struct pipe_surface *surf_tmpl)
    559 {
    560    struct pipe_surface *ps;
    561 
    562    assert(surf_tmpl->u.tex.level <= pt->last_level);
    563 
    564    ps = CALLOC_STRUCT(pipe_surface);
    565    if (ps) {
    566       pipe_reference_init(&ps->reference, 1);
    567       pipe_resource_reference(&ps->texture, pt);
    568       ps->context = pipe;
    569       ps->format = surf_tmpl->format;
    570       ps->width = u_minify(pt->width0, surf_tmpl->u.tex.level);
    571       ps->height = u_minify(pt->height0, surf_tmpl->u.tex.level);
    572       ps->usage = surf_tmpl->usage;
    573 
    574       ps->u.tex.level = surf_tmpl->u.tex.level;
    575       ps->u.tex.first_layer = surf_tmpl->u.tex.first_layer;
    576       ps->u.tex.last_layer = surf_tmpl->u.tex.last_layer;
    577    }
    578    return ps;
    579 }
    580 
    581 
    582 static void
    583 llvmpipe_surface_destroy(struct pipe_context *pipe,
    584                          struct pipe_surface *surf)
    585 {
    586    /* Effectively do the texture_update work here - if texture images
    587     * needed post-processing to put them into hardware layout, this is
    588     * where it would happen.  For llvmpipe, nothing to do.
    589     */
    590    assert(surf->texture);
    591    pipe_resource_reference(&surf->texture, NULL);
    592    FREE(surf);
    593 }
    594 
    595 
    596 static struct pipe_transfer *
    597 llvmpipe_get_transfer(struct pipe_context *pipe,
    598                       struct pipe_resource *resource,
    599                       unsigned level,
    600                       unsigned usage,
    601                       const struct pipe_box *box)
    602 {
    603    struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe);
    604    struct llvmpipe_resource *lprex = llvmpipe_resource(resource);
    605    struct llvmpipe_transfer *lpr;
    606 
    607    assert(resource);
    608    assert(level <= resource->last_level);
    609 
    610    /*
    611     * Transfers, like other pipe operations, must happen in order, so flush the
    612     * context if necessary.
    613     */
    614    if (!(usage & PIPE_TRANSFER_UNSYNCHRONIZED)) {
    615       boolean read_only = !(usage & PIPE_TRANSFER_WRITE);
    616       boolean do_not_block = !!(usage & PIPE_TRANSFER_DONTBLOCK);
    617       if (!llvmpipe_flush_resource(pipe, resource,
    618                                    level,
    619                                    box->depth > 1 ? -1 : box->z,
    620                                    read_only,
    621                                    TRUE, /* cpu_access */
    622                                    do_not_block,
    623                                    __FUNCTION__)) {
    624          /*
    625           * It would have blocked, but state tracker requested no to.
    626           */
    627          assert(do_not_block);
    628          return NULL;
    629       }
    630    }
    631 
    632    if (resource == llvmpipe->constants[PIPE_SHADER_FRAGMENT][0])
    633       llvmpipe->dirty |= LP_NEW_CONSTANTS;
    634 
    635    lpr = CALLOC_STRUCT(llvmpipe_transfer);
    636    if (lpr) {
    637       struct pipe_transfer *pt = &lpr->base;
    638       pipe_resource_reference(&pt->resource, resource);
    639       pt->box = *box;
    640       pt->level = level;
    641       pt->stride = lprex->row_stride[level];
    642       pt->layer_stride = lprex->img_stride[level];
    643       pt->usage = usage;
    644 
    645       return pt;
    646    }
    647    return NULL;
    648 }
    649 
    650 
    651 static void
    652 llvmpipe_transfer_destroy(struct pipe_context *pipe,
    653                               struct pipe_transfer *transfer)
    654 {
    655    /* Effectively do the texture_update work here - if texture images
    656     * needed post-processing to put them into hardware layout, this is
    657     * where it would happen.  For llvmpipe, nothing to do.
    658     */
    659    assert (transfer->resource);
    660    pipe_resource_reference(&transfer->resource, NULL);
    661    FREE(transfer);
    662 }
    663 
    664 
    665 static void *
    666 llvmpipe_transfer_map( struct pipe_context *pipe,
    667                        struct pipe_transfer *transfer )
    668 {
    669    struct llvmpipe_screen *screen = llvmpipe_screen(pipe->screen);
    670    ubyte *map;
    671    struct llvmpipe_resource *lpr;
    672    enum pipe_format format;
    673    enum lp_texture_usage tex_usage;
    674    const char *mode;
    675 
    676    assert(transfer->level < LP_MAX_TEXTURE_LEVELS);
    677 
    678    /*
    679    printf("tex_transfer_map(%d, %d  %d x %d of %d x %d,  usage %d )\n",
    680           transfer->x, transfer->y, transfer->width, transfer->height,
    681           transfer->texture->width0,
    682           transfer->texture->height0,
    683           transfer->usage);
    684    */
    685 
    686    if (transfer->usage == PIPE_TRANSFER_READ) {
    687       tex_usage = LP_TEX_USAGE_READ;
    688       mode = "read";
    689    }
    690    else {
    691       tex_usage = LP_TEX_USAGE_READ_WRITE;
    692       mode = "read/write";
    693    }
    694 
    695    if (0) {
    696       struct llvmpipe_resource *lpr = llvmpipe_resource(transfer->resource);
    697       printf("transfer map tex %u  mode %s\n", lpr->id, mode);
    698    }
    699 
    700 
    701    assert(transfer->resource);
    702    lpr = llvmpipe_resource(transfer->resource);
    703    format = lpr->base.format;
    704 
    705    map = llvmpipe_resource_map(transfer->resource,
    706                                transfer->level,
    707                                transfer->box.z,
    708                                tex_usage, LP_TEX_LAYOUT_LINEAR);
    709 
    710 
    711    /* May want to do different things here depending on read/write nature
    712     * of the map:
    713     */
    714    if (transfer->usage & PIPE_TRANSFER_WRITE) {
    715       /* Do something to notify sharing contexts of a texture change.
    716        */
    717       screen->timestamp++;
    718    }
    719 
    720    map +=
    721       transfer->box.y / util_format_get_blockheight(format) * transfer->stride +
    722       transfer->box.x / util_format_get_blockwidth(format) * util_format_get_blocksize(format);
    723 
    724    return map;
    725 }
    726 
    727 
    728 static void
    729 llvmpipe_transfer_unmap(struct pipe_context *pipe,
    730                         struct pipe_transfer *transfer)
    731 {
    732    assert(transfer->resource);
    733 
    734    llvmpipe_resource_unmap(transfer->resource,
    735                            transfer->level,
    736                            transfer->box.z);
    737 }
    738 
    739 unsigned int
    740 llvmpipe_is_resource_referenced( struct pipe_context *pipe,
    741                                  struct pipe_resource *presource,
    742                                  unsigned level, int layer)
    743 {
    744    struct llvmpipe_context *llvmpipe = llvmpipe_context( pipe );
    745 
    746    if (presource->target == PIPE_BUFFER)
    747       return LP_UNREFERENCED;
    748 
    749    return lp_setup_is_resource_referenced(llvmpipe->setup, presource);
    750 }
    751 
    752 
    753 
    754 /**
    755  * Create buffer which wraps user-space data.
    756  */
    757 struct pipe_resource *
    758 llvmpipe_user_buffer_create(struct pipe_screen *screen,
    759                             void *ptr,
    760                             unsigned bytes,
    761 			    unsigned bind_flags)
    762 {
    763    struct llvmpipe_resource *buffer;
    764 
    765    buffer = CALLOC_STRUCT(llvmpipe_resource);
    766    if(!buffer)
    767       return NULL;
    768 
    769    pipe_reference_init(&buffer->base.reference, 1);
    770    buffer->base.screen = screen;
    771    buffer->base.format = PIPE_FORMAT_R8_UNORM; /* ?? */
    772    buffer->base.bind = bind_flags;
    773    buffer->base.usage = PIPE_USAGE_IMMUTABLE;
    774    buffer->base.flags = 0;
    775    buffer->base.width0 = bytes;
    776    buffer->base.height0 = 1;
    777    buffer->base.depth0 = 1;
    778    buffer->base.array_size = 1;
    779    buffer->userBuffer = TRUE;
    780    buffer->data = ptr;
    781 
    782    return &buffer->base;
    783 }
    784 
    785 
    786 /**
    787  * Compute size (in bytes) need to store a texture image / mipmap level,
    788  * for just one cube face or one 3D texture slice
    789  */
    790 static unsigned
    791 tex_image_face_size(const struct llvmpipe_resource *lpr, unsigned level,
    792                     enum lp_texture_layout layout)
    793 {
    794    const unsigned width = u_minify(lpr->base.width0, level);
    795    const unsigned height = u_minify(lpr->base.height0, level);
    796 
    797    assert(layout == LP_TEX_LAYOUT_TILED ||
    798           layout == LP_TEX_LAYOUT_LINEAR);
    799 
    800    if (layout == LP_TEX_LAYOUT_TILED) {
    801       /* for tiled layout, force a 32bpp format */
    802       const enum pipe_format format = PIPE_FORMAT_B8G8R8A8_UNORM;
    803       const unsigned block_size = util_format_get_blocksize(format);
    804       const unsigned nblocksy =
    805          util_format_get_nblocksy(format, align(height, TILE_SIZE));
    806       const unsigned nblocksx =
    807          util_format_get_nblocksx(format, align(width, TILE_SIZE));
    808       const unsigned buffer_size = block_size * nblocksy * nblocksx;
    809       return buffer_size;
    810    }
    811    else {
    812       /* we already computed this */
    813       return lpr->img_stride[level];
    814    }
    815 }
    816 
    817 
    818 /**
    819  * Compute size (in bytes) need to store a texture image / mipmap level,
    820  * including all cube faces or 3D image slices
    821  */
    822 static unsigned
    823 tex_image_size(const struct llvmpipe_resource *lpr, unsigned level,
    824                enum lp_texture_layout layout)
    825 {
    826    const unsigned buf_size = tex_image_face_size(lpr, level, layout);
    827    return buf_size * lpr->num_slices_faces[level];
    828 }
    829 
    830 
    831 /**
    832  * This function encapsulates some complicated logic for determining
    833  * how to convert a tile of image data from linear layout to tiled
    834  * layout, or vice versa.
    835  * \param cur_layout  the current tile layout
    836  * \param target_layout  the desired tile layout
    837  * \param usage  how the tile will be accessed (R/W vs. read-only, etc)
    838  * \param new_layout_return  returns the new layout mode
    839  * \param convert_return  returns TRUE if image conversion is needed
    840  */
    841 static void
    842 layout_logic(enum lp_texture_layout cur_layout,
    843              enum lp_texture_layout target_layout,
    844              enum lp_texture_usage usage,
    845              enum lp_texture_layout *new_layout_return,
    846              boolean *convert)
    847 {
    848    enum lp_texture_layout other_layout, new_layout;
    849 
    850    *convert = FALSE;
    851 
    852    new_layout = 99; /* debug check */
    853 
    854    if (target_layout == LP_TEX_LAYOUT_LINEAR) {
    855       other_layout = LP_TEX_LAYOUT_TILED;
    856    }
    857    else {
    858       assert(target_layout == LP_TEX_LAYOUT_TILED);
    859       other_layout = LP_TEX_LAYOUT_LINEAR;
    860    }
    861 
    862    new_layout = target_layout;  /* may get changed below */
    863 
    864    if (cur_layout == LP_TEX_LAYOUT_BOTH) {
    865       if (usage == LP_TEX_USAGE_READ) {
    866          new_layout = LP_TEX_LAYOUT_BOTH;
    867       }
    868    }
    869    else if (cur_layout == other_layout) {
    870       if (usage != LP_TEX_USAGE_WRITE_ALL) {
    871          /* need to convert tiled data to linear or vice versa */
    872          *convert = TRUE;
    873 
    874          if (usage == LP_TEX_USAGE_READ)
    875             new_layout = LP_TEX_LAYOUT_BOTH;
    876       }
    877    }
    878    else {
    879       assert(cur_layout == LP_TEX_LAYOUT_NONE ||
    880              cur_layout == target_layout);
    881    }
    882 
    883    assert(new_layout == LP_TEX_LAYOUT_BOTH ||
    884           new_layout == target_layout);
    885 
    886    *new_layout_return = new_layout;
    887 }
    888 
    889 
    890 /**
    891  * Return pointer to a 2D texture image/face/slice.
    892  * No tiled/linear conversion is done.
    893  */
    894 ubyte *
    895 llvmpipe_get_texture_image_address(struct llvmpipe_resource *lpr,
    896                                    unsigned face_slice, unsigned level,
    897                                    enum lp_texture_layout layout)
    898 {
    899    struct llvmpipe_texture_image *img;
    900    unsigned offset;
    901 
    902    if (layout == LP_TEX_LAYOUT_LINEAR) {
    903       img = &lpr->linear[level];
    904    }
    905    else {
    906       assert (layout == LP_TEX_LAYOUT_TILED);
    907       img = &lpr->tiled[level];
    908    }
    909 
    910    if (face_slice > 0)
    911       offset = face_slice * tex_image_face_size(lpr, level, layout);
    912    else
    913       offset = 0;
    914 
    915    return (ubyte *) img->data + offset;
    916 }
    917 
    918 
    919 static INLINE enum lp_texture_layout
    920 llvmpipe_get_texture_tile_layout(const struct llvmpipe_resource *lpr,
    921                                  unsigned face_slice, unsigned level,
    922                                  unsigned x, unsigned y)
    923 {
    924    uint i;
    925    assert(resource_is_texture(&lpr->base));
    926    assert(x < lpr->tiles_per_row[level]);
    927    i = face_slice * lpr->tiles_per_image[level]
    928       + y * lpr->tiles_per_row[level] + x;
    929    return lpr->layout[level][i];
    930 }
    931 
    932 
    933 static INLINE void
    934 llvmpipe_set_texture_tile_layout(struct llvmpipe_resource *lpr,
    935                                  unsigned face_slice, unsigned level,
    936                                  unsigned x, unsigned y,
    937                                  enum lp_texture_layout layout)
    938 {
    939    uint i;
    940    assert(resource_is_texture(&lpr->base));
    941    assert(x < lpr->tiles_per_row[level]);
    942    i = face_slice * lpr->tiles_per_image[level]
    943       + y * lpr->tiles_per_row[level] + x;
    944    lpr->layout[level][i] = layout;
    945 }
    946 
    947 
    948 /**
    949  * Set the layout mode for all tiles in a particular image.
    950  */
    951 static INLINE void
    952 llvmpipe_set_texture_image_layout(struct llvmpipe_resource *lpr,
    953                                   unsigned face_slice, unsigned level,
    954                                   unsigned width_t, unsigned height_t,
    955                                   enum lp_texture_layout layout)
    956 {
    957    const unsigned start = face_slice * lpr->tiles_per_image[level];
    958    unsigned i;
    959 
    960    for (i = 0; i < width_t * height_t; i++) {
    961       lpr->layout[level][start + i] = layout;
    962    }
    963 }
    964 
    965 
    966 /**
    967  * Allocate storage for a linear or tile texture image (all cube
    968  * faces and all 3D slices.
    969  */
    970 static void
    971 alloc_image_data(struct llvmpipe_resource *lpr, unsigned level,
    972                  enum lp_texture_layout layout)
    973 {
    974    uint alignment = MAX2(16, util_cpu_caps.cacheline);
    975 
    976    if (lpr->dt)
    977       assert(level == 0);
    978 
    979    if (layout == LP_TEX_LAYOUT_TILED) {
    980       /* tiled data is stored in regular memory */
    981       uint buffer_size = tex_image_size(lpr, level, layout);
    982       lpr->tiled[level].data = align_malloc(buffer_size, alignment);
    983       if (lpr->tiled[level].data) {
    984          memset(lpr->tiled[level].data, 0, buffer_size);
    985       }
    986    }
    987    else {
    988       assert(layout == LP_TEX_LAYOUT_LINEAR);
    989       if (lpr->dt) {
    990          /* we get the linear memory from the winsys, and it has
    991           * already been zeroed
    992           */
    993          struct llvmpipe_screen *screen = llvmpipe_screen(lpr->base.screen);
    994          struct sw_winsys *winsys = screen->winsys;
    995 
    996          lpr->linear[0].data =
    997             winsys->displaytarget_map(winsys, lpr->dt,
    998                                       PIPE_TRANSFER_READ_WRITE);
    999       }
   1000       else {
   1001          /* not a display target - allocate regular memory */
   1002          uint buffer_size = tex_image_size(lpr, level, LP_TEX_LAYOUT_LINEAR);
   1003          lpr->linear[level].data = align_malloc(buffer_size, alignment);
   1004          if (lpr->linear[level].data) {
   1005             memset(lpr->linear[level].data, 0, buffer_size);
   1006          }
   1007       }
   1008    }
   1009 }
   1010 
   1011 
   1012 
   1013 /**
   1014  * Return pointer to texture image data (either linear or tiled layout)
   1015  * for a particular cube face or 3D texture slice.
   1016  *
   1017  * \param face_slice  the cube face or 3D slice of interest
   1018  * \param usage  one of LP_TEX_USAGE_READ/WRITE_ALL/READ_WRITE
   1019  * \param layout  either LP_TEX_LAYOUT_LINEAR or _TILED or _NONE
   1020  */
   1021 void *
   1022 llvmpipe_get_texture_image(struct llvmpipe_resource *lpr,
   1023                            unsigned face_slice, unsigned level,
   1024                            enum lp_texture_usage usage,
   1025                            enum lp_texture_layout layout)
   1026 {
   1027    /*
   1028     * 'target' refers to the image which we're retrieving (either in
   1029     * tiled or linear layout).
   1030     * 'other' refers to the same image but in the other layout. (it may
   1031     *  or may not exist.
   1032     */
   1033    struct llvmpipe_texture_image *target_img;
   1034    struct llvmpipe_texture_image *other_img;
   1035    void *target_data;
   1036    void *other_data;
   1037    const unsigned width = u_minify(lpr->base.width0, level);
   1038    const unsigned height = u_minify(lpr->base.height0, level);
   1039    const unsigned width_t = align(width, TILE_SIZE) / TILE_SIZE;
   1040    const unsigned height_t = align(height, TILE_SIZE) / TILE_SIZE;
   1041    enum lp_texture_layout other_layout;
   1042    boolean only_allocate;
   1043 
   1044    assert(layout == LP_TEX_LAYOUT_NONE ||
   1045           layout == LP_TEX_LAYOUT_TILED ||
   1046           layout == LP_TEX_LAYOUT_LINEAR);
   1047 
   1048    assert(usage == LP_TEX_USAGE_READ ||
   1049           usage == LP_TEX_USAGE_READ_WRITE ||
   1050           usage == LP_TEX_USAGE_WRITE_ALL);
   1051 
   1052    /* check for the special case of layout == LP_TEX_LAYOUT_NONE */
   1053    if (layout == LP_TEX_LAYOUT_NONE) {
   1054       only_allocate = TRUE;
   1055       layout = LP_TEX_LAYOUT_TILED;
   1056    }
   1057    else {
   1058       only_allocate = FALSE;
   1059    }
   1060 
   1061    if (lpr->dt) {
   1062       assert(lpr->linear[level].data);
   1063    }
   1064 
   1065    /* which is target?  which is other? */
   1066    if (layout == LP_TEX_LAYOUT_LINEAR) {
   1067       target_img = &lpr->linear[level];
   1068       other_img = &lpr->tiled[level];
   1069       other_layout = LP_TEX_LAYOUT_TILED;
   1070    }
   1071    else {
   1072       target_img = &lpr->tiled[level];
   1073       other_img = &lpr->linear[level];
   1074       other_layout = LP_TEX_LAYOUT_LINEAR;
   1075    }
   1076 
   1077    target_data = target_img->data;
   1078    other_data = other_img->data;
   1079 
   1080    if (!target_data) {
   1081       /* allocate memory for the target image now */
   1082       alloc_image_data(lpr, level, layout);
   1083       target_data = target_img->data;
   1084    }
   1085 
   1086    if (face_slice > 0) {
   1087       unsigned target_offset, other_offset;
   1088 
   1089       target_offset = face_slice * tex_image_face_size(lpr, level, layout);
   1090       other_offset = face_slice * tex_image_face_size(lpr, level, other_layout);
   1091       if (target_data) {
   1092          target_data = (uint8_t *) target_data + target_offset;
   1093       }
   1094       if (other_data) {
   1095          other_data = (uint8_t *) other_data + other_offset;
   1096       }
   1097    }
   1098 
   1099    if (only_allocate) {
   1100       /* Just allocating tiled memory.  Don't initialize it from the
   1101        * linear data if it exists.
   1102        */
   1103       return target_data;
   1104    }
   1105 
   1106    if (other_data) {
   1107       /* may need to convert other data to the requested layout */
   1108       enum lp_texture_layout new_layout;
   1109       unsigned x, y;
   1110 
   1111       /* loop over all image tiles, doing layout conversion where needed */
   1112       for (y = 0; y < height_t; y++) {
   1113          for (x = 0; x < width_t; x++) {
   1114             enum lp_texture_layout cur_layout =
   1115                llvmpipe_get_texture_tile_layout(lpr, face_slice, level, x, y);
   1116             boolean convert;
   1117 
   1118             layout_logic(cur_layout, layout, usage, &new_layout, &convert);
   1119 
   1120             if (convert && other_data && target_data) {
   1121                if (layout == LP_TEX_LAYOUT_TILED) {
   1122                   lp_linear_to_tiled(other_data, target_data,
   1123                                      x * TILE_SIZE, y * TILE_SIZE,
   1124                                      TILE_SIZE, TILE_SIZE,
   1125                                      lpr->base.format,
   1126                                      lpr->row_stride[level],
   1127                                      lpr->tiles_per_row[level]);
   1128                }
   1129                else {
   1130                   assert(layout == LP_TEX_LAYOUT_LINEAR);
   1131                   lp_tiled_to_linear(other_data, target_data,
   1132                                      x * TILE_SIZE, y * TILE_SIZE,
   1133                                      TILE_SIZE, TILE_SIZE,
   1134                                      lpr->base.format,
   1135                                      lpr->row_stride[level],
   1136                                      lpr->tiles_per_row[level]);
   1137                }
   1138             }
   1139 
   1140             if (new_layout != cur_layout)
   1141                llvmpipe_set_texture_tile_layout(lpr, face_slice, level, x, y,
   1142                                                 new_layout);
   1143          }
   1144       }
   1145    }
   1146    else {
   1147       /* no other data */
   1148       llvmpipe_set_texture_image_layout(lpr, face_slice, level,
   1149                                         width_t, height_t, layout);
   1150    }
   1151 
   1152    return target_data;
   1153 }
   1154 
   1155 
   1156 /**
   1157  * Return pointer to start of a texture image (1D, 2D, 3D, CUBE).
   1158  * All cube faces and 3D slices will be converted to the requested
   1159  * layout if needed.
   1160  * This is typically used when we're about to sample from a texture.
   1161  */
   1162 void *
   1163 llvmpipe_get_texture_image_all(struct llvmpipe_resource *lpr,
   1164                                unsigned level,
   1165                                enum lp_texture_usage usage,
   1166                                enum lp_texture_layout layout)
   1167 {
   1168    const int slices = lpr->num_slices_faces[level];
   1169    int slice;
   1170    void *map = NULL;
   1171 
   1172    assert(slices > 0);
   1173 
   1174    for (slice = slices - 1; slice >= 0; slice--) {
   1175       map = llvmpipe_get_texture_image(lpr, slice, level, usage, layout);
   1176    }
   1177 
   1178    return map;
   1179 }
   1180 
   1181 
   1182 /**
   1183  * Get pointer to a linear image (not the tile!) where the tile at (x,y)
   1184  * is known to be in linear layout.
   1185  * Conversion from tiled to linear will be done if necessary.
   1186  * \return pointer to start of image/face (not the tile)
   1187  */
   1188 ubyte *
   1189 llvmpipe_get_texture_tile_linear(struct llvmpipe_resource *lpr,
   1190                                  unsigned face_slice, unsigned level,
   1191                                  enum lp_texture_usage usage,
   1192                                  unsigned x, unsigned y)
   1193 {
   1194    struct llvmpipe_texture_image *linear_img = &lpr->linear[level];
   1195    enum lp_texture_layout cur_layout, new_layout;
   1196    const unsigned tx = x / TILE_SIZE, ty = y / TILE_SIZE;
   1197    boolean convert;
   1198    uint8_t *tiled_image, *linear_image;
   1199 
   1200    assert(resource_is_texture(&lpr->base));
   1201    assert(x % TILE_SIZE == 0);
   1202    assert(y % TILE_SIZE == 0);
   1203 
   1204    if (!linear_img->data) {
   1205       /* allocate memory for the linear image now */
   1206       alloc_image_data(lpr, level, LP_TEX_LAYOUT_LINEAR);
   1207    }
   1208 
   1209    /* compute address of the slice/face of the image that contains the tile */
   1210    tiled_image = llvmpipe_get_texture_image_address(lpr, face_slice, level,
   1211                                                     LP_TEX_LAYOUT_TILED);
   1212    linear_image = llvmpipe_get_texture_image_address(lpr, face_slice, level,
   1213                                                      LP_TEX_LAYOUT_LINEAR);
   1214 
   1215    /* get current tile layout and determine if data conversion is needed */
   1216    cur_layout = llvmpipe_get_texture_tile_layout(lpr, face_slice, level, tx, ty);
   1217 
   1218    layout_logic(cur_layout, LP_TEX_LAYOUT_LINEAR, usage,
   1219                 &new_layout, &convert);
   1220 
   1221    if (convert && tiled_image && linear_image) {
   1222       lp_tiled_to_linear(tiled_image, linear_image,
   1223                          x, y, TILE_SIZE, TILE_SIZE, lpr->base.format,
   1224                          lpr->row_stride[level],
   1225                          lpr->tiles_per_row[level]);
   1226    }
   1227 
   1228    if (new_layout != cur_layout)
   1229       llvmpipe_set_texture_tile_layout(lpr, face_slice, level, tx, ty, new_layout);
   1230 
   1231    return linear_image;
   1232 }
   1233 
   1234 
   1235 /**
   1236  * Get pointer to tiled data for rendering.
   1237  * \return pointer to the tiled data at the given tile position
   1238  */
   1239 ubyte *
   1240 llvmpipe_get_texture_tile(struct llvmpipe_resource *lpr,
   1241                           unsigned face_slice, unsigned level,
   1242                           enum lp_texture_usage usage,
   1243                           unsigned x, unsigned y)
   1244 {
   1245    struct llvmpipe_texture_image *tiled_img = &lpr->tiled[level];
   1246    enum lp_texture_layout cur_layout, new_layout;
   1247    const unsigned tx = x / TILE_SIZE, ty = y / TILE_SIZE;
   1248    boolean convert;
   1249    uint8_t *tiled_image, *linear_image;
   1250    unsigned tile_offset;
   1251 
   1252    assert(x % TILE_SIZE == 0);
   1253    assert(y % TILE_SIZE == 0);
   1254 
   1255    if (!tiled_img->data) {
   1256       /* allocate memory for the tiled image now */
   1257       alloc_image_data(lpr, level, LP_TEX_LAYOUT_TILED);
   1258    }
   1259 
   1260    /* compute address of the slice/face of the image that contains the tile */
   1261    tiled_image = llvmpipe_get_texture_image_address(lpr, face_slice, level,
   1262                                                     LP_TEX_LAYOUT_TILED);
   1263    linear_image = llvmpipe_get_texture_image_address(lpr, face_slice, level,
   1264                                                      LP_TEX_LAYOUT_LINEAR);
   1265 
   1266    /* get current tile layout and see if we need to convert the data */
   1267    cur_layout = llvmpipe_get_texture_tile_layout(lpr, face_slice, level, tx, ty);
   1268 
   1269    layout_logic(cur_layout, LP_TEX_LAYOUT_TILED, usage, &new_layout, &convert);
   1270    if (convert && linear_image && tiled_image) {
   1271       lp_linear_to_tiled(linear_image, tiled_image,
   1272                          x, y, TILE_SIZE, TILE_SIZE, lpr->base.format,
   1273                          lpr->row_stride[level],
   1274                          lpr->tiles_per_row[level]);
   1275    }
   1276 
   1277    if (!tiled_image)
   1278       return NULL;
   1279 
   1280    if (new_layout != cur_layout)
   1281       llvmpipe_set_texture_tile_layout(lpr, face_slice, level, tx, ty, new_layout);
   1282 
   1283    /* compute, return address of the 64x64 tile */
   1284    tile_offset = (ty * lpr->tiles_per_row[level] + tx)
   1285          * TILE_SIZE * TILE_SIZE * 4;
   1286 
   1287    return (ubyte *) tiled_image + tile_offset;
   1288 }
   1289 
   1290 
   1291 /**
   1292  * Get pointer to tiled data for rendering.
   1293  * \return pointer to the tiled data at the given tile position
   1294  */
   1295 void
   1296 llvmpipe_unswizzle_cbuf_tile(struct llvmpipe_resource *lpr,
   1297                              unsigned face_slice, unsigned level,
   1298                              unsigned x, unsigned y,
   1299                              uint8_t *tile)
   1300 {
   1301    struct llvmpipe_texture_image *linear_img = &lpr->linear[level];
   1302    const unsigned tx = x / TILE_SIZE, ty = y / TILE_SIZE;
   1303    uint8_t *linear_image;
   1304 
   1305    assert(x % TILE_SIZE == 0);
   1306    assert(y % TILE_SIZE == 0);
   1307 
   1308    if (!linear_img->data) {
   1309       /* allocate memory for the linear image now */
   1310       alloc_image_data(lpr, level, LP_TEX_LAYOUT_LINEAR);
   1311    }
   1312 
   1313    /* compute address of the slice/face of the image that contains the tile */
   1314    linear_image = llvmpipe_get_texture_image_address(lpr, face_slice, level,
   1315                                                      LP_TEX_LAYOUT_LINEAR);
   1316 
   1317    {
   1318       uint ii = x, jj = y;
   1319       uint tile_offset = jj / TILE_SIZE + ii / TILE_SIZE;
   1320       uint byte_offset = tile_offset * TILE_SIZE * TILE_SIZE * 4;
   1321 
   1322       /* Note that lp_tiled_to_linear expects the tile parameter to
   1323        * point at the first tile in a whole-image sized array.  In
   1324        * this code, we have only a single tile and have to do some
   1325        * pointer arithmetic to figure out where the "image" would have
   1326        * started.
   1327        */
   1328       lp_tiled_to_linear(tile - byte_offset, linear_image,
   1329                          x, y, TILE_SIZE, TILE_SIZE,
   1330                          lpr->base.format,
   1331                          lpr->row_stride[level],
   1332                          1);       /* tiles per row */
   1333    }
   1334 
   1335    llvmpipe_set_texture_tile_layout(lpr, face_slice, level, tx, ty,
   1336                                     LP_TEX_LAYOUT_LINEAR);
   1337 }
   1338 
   1339 
   1340 /**
   1341  * Get pointer to tiled data for rendering.
   1342  * \return pointer to the tiled data at the given tile position
   1343  */
   1344 void
   1345 llvmpipe_swizzle_cbuf_tile(struct llvmpipe_resource *lpr,
   1346                            unsigned face_slice, unsigned level,
   1347                            unsigned x, unsigned y,
   1348                            uint8_t *tile)
   1349 {
   1350    uint8_t *linear_image;
   1351 
   1352    assert(x % TILE_SIZE == 0);
   1353    assert(y % TILE_SIZE == 0);
   1354 
   1355    /* compute address of the slice/face of the image that contains the tile */
   1356    linear_image = llvmpipe_get_texture_image_address(lpr, face_slice, level,
   1357                                                      LP_TEX_LAYOUT_LINEAR);
   1358 
   1359    if (linear_image) {
   1360       uint ii = x, jj = y;
   1361       uint tile_offset = jj / TILE_SIZE + ii / TILE_SIZE;
   1362       uint byte_offset = tile_offset * TILE_SIZE * TILE_SIZE * 4;
   1363 
   1364       /* Note that lp_linear_to_tiled expects the tile parameter to
   1365        * point at the first tile in a whole-image sized array.  In
   1366        * this code, we have only a single tile and have to do some
   1367        * pointer arithmetic to figure out where the "image" would have
   1368        * started.
   1369        */
   1370       lp_linear_to_tiled(linear_image, tile - byte_offset,
   1371                          x, y, TILE_SIZE, TILE_SIZE,
   1372                          lpr->base.format,
   1373                          lpr->row_stride[level],
   1374                          1);       /* tiles per row */
   1375    }
   1376 }
   1377 
   1378 
   1379 /**
   1380  * Return size of resource in bytes
   1381  */
   1382 unsigned
   1383 llvmpipe_resource_size(const struct pipe_resource *resource)
   1384 {
   1385    const struct llvmpipe_resource *lpr = llvmpipe_resource_const(resource);
   1386    unsigned lvl, size = 0;
   1387 
   1388    for (lvl = 0; lvl <= lpr->base.last_level; lvl++) {
   1389       if (lpr->linear[lvl].data)
   1390          size += tex_image_size(lpr, lvl, LP_TEX_LAYOUT_LINEAR);
   1391 
   1392       if (lpr->tiled[lvl].data)
   1393          size += tex_image_size(lpr, lvl, LP_TEX_LAYOUT_TILED);
   1394    }
   1395 
   1396    return size;
   1397 }
   1398 
   1399 
   1400 #ifdef DEBUG
   1401 void
   1402 llvmpipe_print_resources(void)
   1403 {
   1404    struct llvmpipe_resource *lpr;
   1405    unsigned n = 0, total = 0;
   1406 
   1407    debug_printf("LLVMPIPE: current resources:\n");
   1408    foreach(lpr, &resource_list) {
   1409       unsigned size = llvmpipe_resource_size(&lpr->base);
   1410       debug_printf("resource %u at %p, size %ux%ux%u: %u bytes, refcount %u\n",
   1411                    lpr->id, (void *) lpr,
   1412                    lpr->base.width0, lpr->base.height0, lpr->base.depth0,
   1413                    size, lpr->base.reference.count);
   1414       total += size;
   1415       n++;
   1416    }
   1417    debug_printf("LLVMPIPE: total size of %u resources: %u\n", n, total);
   1418 }
   1419 #endif
   1420 
   1421 
   1422 void
   1423 llvmpipe_init_screen_resource_funcs(struct pipe_screen *screen)
   1424 {
   1425 #ifdef DEBUG
   1426    /* init linked list for tracking resources */
   1427    {
   1428       static boolean first_call = TRUE;
   1429       if (first_call) {
   1430          memset(&resource_list, 0, sizeof(resource_list));
   1431          make_empty_list(&resource_list);
   1432          first_call = FALSE;
   1433       }
   1434    }
   1435 #endif
   1436 
   1437    screen->resource_create = llvmpipe_resource_create;
   1438    screen->resource_destroy = llvmpipe_resource_destroy;
   1439    screen->resource_from_handle = llvmpipe_resource_from_handle;
   1440    screen->resource_get_handle = llvmpipe_resource_get_handle;
   1441 }
   1442 
   1443 
   1444 void
   1445 llvmpipe_init_context_resource_funcs(struct pipe_context *pipe)
   1446 {
   1447    pipe->get_transfer = llvmpipe_get_transfer;
   1448    pipe->transfer_destroy = llvmpipe_transfer_destroy;
   1449    pipe->transfer_map = llvmpipe_transfer_map;
   1450    pipe->transfer_unmap = llvmpipe_transfer_unmap;
   1451 
   1452    pipe->transfer_flush_region = u_default_transfer_flush_region;
   1453    pipe->transfer_inline_write = u_default_transfer_inline_write;
   1454 
   1455    pipe->create_surface = llvmpipe_create_surface;
   1456    pipe->surface_destroy = llvmpipe_surface_destroy;
   1457 }
   1458