Home | History | Annotate | Download | only in llvmpipe
      1 /**************************************************************************
      2  *
      3  * Copyright 2006 VMware, Inc.
      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 VMWARE 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 <keithw (at) vmware.com>
     30   *   Michel Dnzer <daenzer (at) vmware.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/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_texture.h"
     50 #include "lp_setup.h"
     51 #include "lp_state.h"
     52 #include "lp_rast.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 /**
     64  * Conventional allocation path for non-display textures:
     65  * Compute strides and allocate data (unless asked not to).
     66  */
     67 static boolean
     68 llvmpipe_texture_layout(struct llvmpipe_screen *screen,
     69                         struct llvmpipe_resource *lpr,
     70                         boolean allocate)
     71 {
     72    struct pipe_resource *pt = &lpr->base;
     73    unsigned level;
     74    unsigned width = pt->width0;
     75    unsigned height = pt->height0;
     76    unsigned depth = pt->depth0;
     77    uint64_t total_size = 0;
     78    unsigned layers = pt->array_size;
     79    /* XXX:
     80     * This alignment here (same for displaytarget) was added for the purpose of
     81     * ARB_map_buffer_alignment. I am not convinced it's needed for non-buffer
     82     * resources. Otherwise we'd want the max of cacheline size and 16 (max size
     83     * of a block for all formats) though this should not be strictly necessary
     84     * neither. In any case it can only affect compressed or 1d textures.
     85     */
     86    unsigned mip_align = MAX2(64, util_cpu_caps.cacheline);
     87 
     88    assert(LP_MAX_TEXTURE_2D_LEVELS <= LP_MAX_TEXTURE_LEVELS);
     89    assert(LP_MAX_TEXTURE_3D_LEVELS <= LP_MAX_TEXTURE_LEVELS);
     90 
     91    for (level = 0; level <= pt->last_level; level++) {
     92       uint64_t mipsize;
     93       unsigned align_x, align_y, nblocksx, nblocksy, block_size, num_slices;
     94 
     95       /* Row stride and image stride */
     96 
     97       /* For non-compressed formats we need 4x4 pixel alignment
     98        * so we can read/write LP_RASTER_BLOCK_SIZE when rendering to them.
     99        * We also want cache line size in x direction,
    100        * otherwise same cache line could end up in multiple threads.
    101        * For explicit 1d resources however we reduce this to 4x1 and
    102        * handle specially in render output code (as we need to do special
    103        * handling there for buffers in any case).
    104        */
    105       if (util_format_is_compressed(pt->format))
    106          align_x = align_y = 1;
    107       else {
    108          align_x = LP_RASTER_BLOCK_SIZE;
    109          if (llvmpipe_resource_is_1d(&lpr->base))
    110             align_y = 1;
    111          else
    112             align_y = LP_RASTER_BLOCK_SIZE;
    113       }
    114 
    115       nblocksx = util_format_get_nblocksx(pt->format,
    116                                           align(width, align_x));
    117       nblocksy = util_format_get_nblocksy(pt->format,
    118                                           align(height, align_y));
    119       block_size = util_format_get_blocksize(pt->format);
    120 
    121       if (util_format_is_compressed(pt->format))
    122          lpr->row_stride[level] = nblocksx * block_size;
    123       else
    124          lpr->row_stride[level] = align(nblocksx * block_size, util_cpu_caps.cacheline);
    125 
    126       /* if row_stride * height > LP_MAX_TEXTURE_SIZE */
    127       if ((uint64_t)lpr->row_stride[level] * nblocksy > LP_MAX_TEXTURE_SIZE) {
    128          /* image too large */
    129          goto fail;
    130       }
    131 
    132       lpr->img_stride[level] = lpr->row_stride[level] * nblocksy;
    133 
    134       /* Number of 3D image slices, cube faces or texture array layers */
    135       if (lpr->base.target == PIPE_TEXTURE_CUBE) {
    136          assert(layers == 6);
    137       }
    138 
    139       if (lpr->base.target == PIPE_TEXTURE_3D)
    140          num_slices = depth;
    141       else if (lpr->base.target == PIPE_TEXTURE_1D_ARRAY ||
    142                lpr->base.target == PIPE_TEXTURE_2D_ARRAY ||
    143                lpr->base.target == PIPE_TEXTURE_CUBE ||
    144                lpr->base.target == PIPE_TEXTURE_CUBE_ARRAY)
    145          num_slices = layers;
    146       else
    147          num_slices = 1;
    148 
    149       /* if img_stride * num_slices_faces > LP_MAX_TEXTURE_SIZE */
    150       mipsize = (uint64_t)lpr->img_stride[level] * num_slices;
    151       if (mipsize > LP_MAX_TEXTURE_SIZE) {
    152          /* volume too large */
    153          goto fail;
    154       }
    155 
    156       lpr->mip_offsets[level] = total_size;
    157 
    158       total_size += align((unsigned)mipsize, mip_align);
    159       if (total_size > LP_MAX_TEXTURE_SIZE) {
    160          goto fail;
    161       }
    162 
    163       /* Compute size of next mipmap level */
    164       width = u_minify(width, 1);
    165       height = u_minify(height, 1);
    166       depth = u_minify(depth, 1);
    167    }
    168 
    169    if (allocate) {
    170       lpr->tex_data = align_malloc(total_size, mip_align);
    171       if (!lpr->tex_data) {
    172          return FALSE;
    173       }
    174       else {
    175          memset(lpr->tex_data, 0, total_size);
    176       }
    177    }
    178 
    179    return TRUE;
    180 
    181 fail:
    182    return FALSE;
    183 }
    184 
    185 
    186 /**
    187  * Check the size of the texture specified by 'res'.
    188  * \return TRUE if OK, FALSE if too large.
    189  */
    190 static boolean
    191 llvmpipe_can_create_resource(struct pipe_screen *screen,
    192                              const struct pipe_resource *res)
    193 {
    194    struct llvmpipe_resource lpr;
    195    memset(&lpr, 0, sizeof(lpr));
    196    lpr.base = *res;
    197    return llvmpipe_texture_layout(llvmpipe_screen(screen), &lpr, false);
    198 }
    199 
    200 
    201 static boolean
    202 llvmpipe_displaytarget_layout(struct llvmpipe_screen *screen,
    203                               struct llvmpipe_resource *lpr,
    204                               const void *map_front_private)
    205 {
    206    struct sw_winsys *winsys = screen->winsys;
    207 
    208    /* Round up the surface size to a multiple of the tile size to
    209     * avoid tile clipping.
    210     */
    211    const unsigned width = MAX2(1, align(lpr->base.width0, TILE_SIZE));
    212    const unsigned height = MAX2(1, align(lpr->base.height0, TILE_SIZE));
    213 
    214    lpr->dt = winsys->displaytarget_create(winsys,
    215                                           lpr->base.bind,
    216                                           lpr->base.format,
    217                                           width, height,
    218                                           64,
    219                                           map_front_private,
    220                                           &lpr->row_stride[0] );
    221 
    222    if (lpr->dt == NULL)
    223       return FALSE;
    224 
    225    if (!map_front_private) {
    226       void *map = winsys->displaytarget_map(winsys, lpr->dt,
    227                                             PIPE_TRANSFER_WRITE);
    228 
    229       if (map)
    230          memset(map, 0, height * lpr->row_stride[0]);
    231 
    232       winsys->displaytarget_unmap(winsys, lpr->dt);
    233    }
    234 
    235    return TRUE;
    236 }
    237 
    238 
    239 static struct pipe_resource *
    240 llvmpipe_resource_create_front(struct pipe_screen *_screen,
    241                                const struct pipe_resource *templat,
    242                                const void *map_front_private)
    243 {
    244    struct llvmpipe_screen *screen = llvmpipe_screen(_screen);
    245    struct llvmpipe_resource *lpr = CALLOC_STRUCT(llvmpipe_resource);
    246    if (!lpr)
    247       return NULL;
    248 
    249    lpr->base = *templat;
    250    pipe_reference_init(&lpr->base.reference, 1);
    251    lpr->base.screen = &screen->base;
    252 
    253    /* assert(lpr->base.bind); */
    254 
    255    if (llvmpipe_resource_is_texture(&lpr->base)) {
    256       if (lpr->base.bind & (PIPE_BIND_DISPLAY_TARGET |
    257                             PIPE_BIND_SCANOUT |
    258                             PIPE_BIND_SHARED)) {
    259          /* displayable surface */
    260          if (!llvmpipe_displaytarget_layout(screen, lpr, map_front_private))
    261             goto fail;
    262       }
    263       else {
    264          /* texture map */
    265          if (!llvmpipe_texture_layout(screen, lpr, true))
    266             goto fail;
    267       }
    268    }
    269    else {
    270       /* other data (vertex buffer, const buffer, etc) */
    271       const uint bytes = templat->width0;
    272       assert(util_format_get_blocksize(templat->format) == 1);
    273       assert(templat->height0 == 1);
    274       assert(templat->depth0 == 1);
    275       assert(templat->last_level == 0);
    276       /*
    277        * Reserve some extra storage since if we'd render to a buffer we
    278        * read/write always LP_RASTER_BLOCK_SIZE pixels, but the element
    279        * offset doesn't need to be aligned to LP_RASTER_BLOCK_SIZE.
    280        */
    281       lpr->data = align_malloc(bytes + (LP_RASTER_BLOCK_SIZE - 1) * 4 * sizeof(float), 64);
    282 
    283       /*
    284        * buffers don't really have stride but it's probably safer
    285        * (for code doing same calculations for buffers and textures)
    286        * to put something sane in there.
    287        */
    288       lpr->row_stride[0] = bytes;
    289       if (!lpr->data)
    290          goto fail;
    291       memset(lpr->data, 0, bytes);
    292    }
    293 
    294    lpr->id = id_counter++;
    295 
    296 #ifdef DEBUG
    297    insert_at_tail(&resource_list, lpr);
    298 #endif
    299 
    300    return &lpr->base;
    301 
    302  fail:
    303    FREE(lpr);
    304    return NULL;
    305 }
    306 static struct pipe_resource *
    307 llvmpipe_resource_create(struct pipe_screen *_screen,
    308                          const struct pipe_resource *templat)
    309 {
    310    return llvmpipe_resource_create_front(_screen, templat, NULL);
    311 }
    312 
    313 static void
    314 llvmpipe_resource_destroy(struct pipe_screen *pscreen,
    315                           struct pipe_resource *pt)
    316 {
    317    struct llvmpipe_screen *screen = llvmpipe_screen(pscreen);
    318    struct llvmpipe_resource *lpr = llvmpipe_resource(pt);
    319 
    320    if (lpr->dt) {
    321       /* display target */
    322       struct sw_winsys *winsys = screen->winsys;
    323       winsys->displaytarget_destroy(winsys, lpr->dt);
    324    }
    325    else if (llvmpipe_resource_is_texture(pt)) {
    326       /* free linear image data */
    327       if (lpr->tex_data) {
    328          align_free(lpr->tex_data);
    329          lpr->tex_data = NULL;
    330       }
    331    }
    332    else if (!lpr->userBuffer) {
    333       assert(lpr->data);
    334       align_free(lpr->data);
    335    }
    336 
    337 #ifdef DEBUG
    338    if (lpr->next)
    339       remove_from_list(lpr);
    340 #endif
    341 
    342    FREE(lpr);
    343 }
    344 
    345 
    346 /**
    347  * Map a resource for read/write.
    348  */
    349 void *
    350 llvmpipe_resource_map(struct pipe_resource *resource,
    351                       unsigned level,
    352                       unsigned layer,
    353                       enum lp_texture_usage tex_usage)
    354 {
    355    struct llvmpipe_resource *lpr = llvmpipe_resource(resource);
    356    uint8_t *map;
    357 
    358    assert(level < LP_MAX_TEXTURE_LEVELS);
    359    assert(layer < (u_minify(resource->depth0, level) + resource->array_size - 1));
    360 
    361    assert(tex_usage == LP_TEX_USAGE_READ ||
    362           tex_usage == LP_TEX_USAGE_READ_WRITE ||
    363           tex_usage == LP_TEX_USAGE_WRITE_ALL);
    364 
    365    if (lpr->dt) {
    366       /* display target */
    367       struct llvmpipe_screen *screen = llvmpipe_screen(resource->screen);
    368       struct sw_winsys *winsys = screen->winsys;
    369       unsigned dt_usage;
    370 
    371       if (tex_usage == LP_TEX_USAGE_READ) {
    372          dt_usage = PIPE_TRANSFER_READ;
    373       }
    374       else {
    375          dt_usage = PIPE_TRANSFER_READ_WRITE;
    376       }
    377 
    378       assert(level == 0);
    379       assert(layer == 0);
    380 
    381       /* FIXME: keep map count? */
    382       map = winsys->displaytarget_map(winsys, lpr->dt, dt_usage);
    383 
    384       /* install this linear image in texture data structure */
    385       lpr->tex_data = map;
    386 
    387       return map;
    388    }
    389    else if (llvmpipe_resource_is_texture(resource)) {
    390 
    391       map = llvmpipe_get_texture_image_address(lpr, layer, level);
    392       return map;
    393    }
    394    else {
    395       return lpr->data;
    396    }
    397 }
    398 
    399 
    400 /**
    401  * Unmap a resource.
    402  */
    403 void
    404 llvmpipe_resource_unmap(struct pipe_resource *resource,
    405                        unsigned level,
    406                        unsigned layer)
    407 {
    408    struct llvmpipe_resource *lpr = llvmpipe_resource(resource);
    409 
    410    if (lpr->dt) {
    411       /* display target */
    412       struct llvmpipe_screen *lp_screen = llvmpipe_screen(resource->screen);
    413       struct sw_winsys *winsys = lp_screen->winsys;
    414 
    415       assert(level == 0);
    416       assert(layer == 0);
    417 
    418       winsys->displaytarget_unmap(winsys, lpr->dt);
    419    }
    420 }
    421 
    422 
    423 void *
    424 llvmpipe_resource_data(struct pipe_resource *resource)
    425 {
    426    struct llvmpipe_resource *lpr = llvmpipe_resource(resource);
    427 
    428    assert(!llvmpipe_resource_is_texture(resource));
    429 
    430    return lpr->data;
    431 }
    432 
    433 
    434 static struct pipe_resource *
    435 llvmpipe_resource_from_handle(struct pipe_screen *screen,
    436                               const struct pipe_resource *template,
    437                               struct winsys_handle *whandle,
    438                               unsigned usage)
    439 {
    440    struct sw_winsys *winsys = llvmpipe_screen(screen)->winsys;
    441    struct llvmpipe_resource *lpr;
    442 
    443    /* XXX Seems like from_handled depth textures doesn't work that well */
    444 
    445    lpr = CALLOC_STRUCT(llvmpipe_resource);
    446    if (!lpr) {
    447       goto no_lpr;
    448    }
    449 
    450    lpr->base = *template;
    451    pipe_reference_init(&lpr->base.reference, 1);
    452    lpr->base.screen = screen;
    453 
    454    /*
    455     * Looks like unaligned displaytargets work just fine,
    456     * at least sampler/render ones.
    457     */
    458 #if 0
    459    assert(lpr->base.width0 == width);
    460    assert(lpr->base.height0 == height);
    461 #endif
    462 
    463    lpr->dt = winsys->displaytarget_from_handle(winsys,
    464                                                template,
    465                                                whandle,
    466                                                &lpr->row_stride[0]);
    467    if (!lpr->dt) {
    468       goto no_dt;
    469    }
    470 
    471    lpr->id = id_counter++;
    472 
    473 #ifdef DEBUG
    474    insert_at_tail(&resource_list, lpr);
    475 #endif
    476 
    477    return &lpr->base;
    478 
    479 no_dt:
    480    FREE(lpr);
    481 no_lpr:
    482    return NULL;
    483 }
    484 
    485 
    486 static boolean
    487 llvmpipe_resource_get_handle(struct pipe_screen *screen,
    488                              struct pipe_context *ctx,
    489                             struct pipe_resource *pt,
    490                             struct winsys_handle *whandle,
    491                              unsigned usage)
    492 {
    493    struct sw_winsys *winsys = llvmpipe_screen(screen)->winsys;
    494    struct llvmpipe_resource *lpr = llvmpipe_resource(pt);
    495 
    496    assert(lpr->dt);
    497    if (!lpr->dt)
    498       return FALSE;
    499 
    500    return winsys->displaytarget_get_handle(winsys, lpr->dt, whandle);
    501 }
    502 
    503 
    504 static void *
    505 llvmpipe_transfer_map( struct pipe_context *pipe,
    506                        struct pipe_resource *resource,
    507                        unsigned level,
    508                        unsigned usage,
    509                        const struct pipe_box *box,
    510                        struct pipe_transfer **transfer )
    511 {
    512    struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe);
    513    struct llvmpipe_screen *screen = llvmpipe_screen(pipe->screen);
    514    struct llvmpipe_resource *lpr = llvmpipe_resource(resource);
    515    struct llvmpipe_transfer *lpt;
    516    struct pipe_transfer *pt;
    517    ubyte *map;
    518    enum pipe_format format;
    519    enum lp_texture_usage tex_usage;
    520    const char *mode;
    521 
    522    assert(resource);
    523    assert(level <= resource->last_level);
    524 
    525    /*
    526     * Transfers, like other pipe operations, must happen in order, so flush the
    527     * context if necessary.
    528     */
    529    if (!(usage & PIPE_TRANSFER_UNSYNCHRONIZED)) {
    530       boolean read_only = !(usage & PIPE_TRANSFER_WRITE);
    531       boolean do_not_block = !!(usage & PIPE_TRANSFER_DONTBLOCK);
    532       if (!llvmpipe_flush_resource(pipe, resource,
    533                                    level,
    534                                    read_only,
    535                                    TRUE, /* cpu_access */
    536                                    do_not_block,
    537                                    __FUNCTION__)) {
    538          /*
    539           * It would have blocked, but state tracker requested no to.
    540           */
    541          assert(do_not_block);
    542          return NULL;
    543       }
    544    }
    545 
    546    /* Check if we're mapping a current constant buffer */
    547    if ((usage & PIPE_TRANSFER_WRITE) &&
    548        (resource->bind & PIPE_BIND_CONSTANT_BUFFER)) {
    549       unsigned i;
    550       for (i = 0; i < ARRAY_SIZE(llvmpipe->constants[PIPE_SHADER_FRAGMENT]); ++i) {
    551          if (resource == llvmpipe->constants[PIPE_SHADER_FRAGMENT][i].buffer) {
    552             /* constants may have changed */
    553             llvmpipe->dirty |= LP_NEW_FS_CONSTANTS;
    554             break;
    555          }
    556       }
    557    }
    558 
    559    lpt = CALLOC_STRUCT(llvmpipe_transfer);
    560    if (!lpt)
    561       return NULL;
    562    pt = &lpt->base;
    563    pipe_resource_reference(&pt->resource, resource);
    564    pt->box = *box;
    565    pt->level = level;
    566    pt->stride = lpr->row_stride[level];
    567    pt->layer_stride = lpr->img_stride[level];
    568    pt->usage = usage;
    569    *transfer = pt;
    570 
    571    assert(level < LP_MAX_TEXTURE_LEVELS);
    572 
    573    /*
    574    printf("tex_transfer_map(%d, %d  %d x %d of %d x %d,  usage %d )\n",
    575           transfer->x, transfer->y, transfer->width, transfer->height,
    576           transfer->texture->width0,
    577           transfer->texture->height0,
    578           transfer->usage);
    579    */
    580 
    581    if (usage == PIPE_TRANSFER_READ) {
    582       tex_usage = LP_TEX_USAGE_READ;
    583       mode = "read";
    584    }
    585    else {
    586       tex_usage = LP_TEX_USAGE_READ_WRITE;
    587       mode = "read/write";
    588    }
    589 
    590    if (0) {
    591       printf("transfer map tex %u  mode %s\n", lpr->id, mode);
    592    }
    593 
    594    format = lpr->base.format;
    595 
    596    map = llvmpipe_resource_map(resource,
    597                                level,
    598                                box->z,
    599                                tex_usage);
    600 
    601 
    602    /* May want to do different things here depending on read/write nature
    603     * of the map:
    604     */
    605    if (usage & PIPE_TRANSFER_WRITE) {
    606       /* Do something to notify sharing contexts of a texture change.
    607        */
    608       screen->timestamp++;
    609    }
    610 
    611    map +=
    612       box->y / util_format_get_blockheight(format) * pt->stride +
    613       box->x / util_format_get_blockwidth(format) * util_format_get_blocksize(format);
    614 
    615    return map;
    616 }
    617 
    618 
    619 static void
    620 llvmpipe_transfer_unmap(struct pipe_context *pipe,
    621                         struct pipe_transfer *transfer)
    622 {
    623    assert(transfer->resource);
    624 
    625    llvmpipe_resource_unmap(transfer->resource,
    626                            transfer->level,
    627                            transfer->box.z);
    628 
    629    /* Effectively do the texture_update work here - if texture images
    630     * needed post-processing to put them into hardware layout, this is
    631     * where it would happen.  For llvmpipe, nothing to do.
    632     */
    633    assert (transfer->resource);
    634    pipe_resource_reference(&transfer->resource, NULL);
    635    FREE(transfer);
    636 }
    637 
    638 unsigned int
    639 llvmpipe_is_resource_referenced( struct pipe_context *pipe,
    640                                  struct pipe_resource *presource,
    641                                  unsigned level)
    642 {
    643    struct llvmpipe_context *llvmpipe = llvmpipe_context( pipe );
    644    if (!(presource->bind & (PIPE_BIND_DEPTH_STENCIL |
    645                             PIPE_BIND_RENDER_TARGET |
    646                             PIPE_BIND_SAMPLER_VIEW)))
    647       return LP_UNREFERENCED;
    648 
    649    return lp_setup_is_resource_referenced(llvmpipe->setup, presource);
    650 }
    651 
    652 
    653 /**
    654  * Returns the largest possible alignment for a format in llvmpipe
    655  */
    656 unsigned
    657 llvmpipe_get_format_alignment( enum pipe_format format )
    658 {
    659    const struct util_format_description *desc = util_format_description(format);
    660    unsigned size = 0;
    661    unsigned bytes;
    662    unsigned i;
    663 
    664    for (i = 0; i < desc->nr_channels; ++i) {
    665       size += desc->channel[i].size;
    666    }
    667 
    668    bytes = size / 8;
    669 
    670    if (!util_is_power_of_two(bytes)) {
    671       bytes /= desc->nr_channels;
    672    }
    673 
    674    if (bytes % 2 || bytes < 1) {
    675       return 1;
    676    } else {
    677       return bytes;
    678    }
    679 }
    680 
    681 
    682 /**
    683  * Create buffer which wraps user-space data.
    684  * XXX unreachable.
    685  */
    686 struct pipe_resource *
    687 llvmpipe_user_buffer_create(struct pipe_screen *screen,
    688                             void *ptr,
    689                             unsigned bytes,
    690                             unsigned bind_flags)
    691 {
    692    struct llvmpipe_resource *buffer;
    693 
    694    buffer = CALLOC_STRUCT(llvmpipe_resource);
    695    if (!buffer)
    696       return NULL;
    697 
    698    pipe_reference_init(&buffer->base.reference, 1);
    699    buffer->base.screen = screen;
    700    buffer->base.format = PIPE_FORMAT_R8_UNORM; /* ?? */
    701    buffer->base.bind = bind_flags;
    702    buffer->base.usage = PIPE_USAGE_IMMUTABLE;
    703    buffer->base.flags = 0;
    704    buffer->base.width0 = bytes;
    705    buffer->base.height0 = 1;
    706    buffer->base.depth0 = 1;
    707    buffer->base.array_size = 1;
    708    buffer->userBuffer = TRUE;
    709    buffer->data = ptr;
    710 
    711    return &buffer->base;
    712 }
    713 
    714 
    715 /**
    716  * Compute size (in bytes) need to store a texture image / mipmap level,
    717  * for just one cube face, one array layer or one 3D texture slice
    718  */
    719 static unsigned
    720 tex_image_face_size(const struct llvmpipe_resource *lpr, unsigned level)
    721 {
    722    return lpr->img_stride[level];
    723 }
    724 
    725 
    726 /**
    727  * Return pointer to a 2D texture image/face/slice.
    728  * No tiled/linear conversion is done.
    729  */
    730 ubyte *
    731 llvmpipe_get_texture_image_address(struct llvmpipe_resource *lpr,
    732                                    unsigned face_slice, unsigned level)
    733 {
    734    unsigned offset;
    735 
    736    assert(llvmpipe_resource_is_texture(&lpr->base));
    737 
    738    offset = lpr->mip_offsets[level];
    739 
    740    if (face_slice > 0)
    741       offset += face_slice * tex_image_face_size(lpr, level);
    742 
    743    return (ubyte *) lpr->tex_data + offset;
    744 }
    745 
    746 
    747 /**
    748  * Return size of resource in bytes
    749  */
    750 unsigned
    751 llvmpipe_resource_size(const struct pipe_resource *resource)
    752 {
    753    const struct llvmpipe_resource *lpr = llvmpipe_resource_const(resource);
    754    unsigned size = 0;
    755 
    756    if (llvmpipe_resource_is_texture(resource)) {
    757       /* Note this will always return 0 for displaytarget resources */
    758       size = lpr->total_alloc_size;
    759    }
    760    else {
    761       size = resource->width0;
    762    }
    763    return size;
    764 }
    765 
    766 
    767 #ifdef DEBUG
    768 void
    769 llvmpipe_print_resources(void)
    770 {
    771    struct llvmpipe_resource *lpr;
    772    unsigned n = 0, total = 0;
    773 
    774    debug_printf("LLVMPIPE: current resources:\n");
    775    foreach(lpr, &resource_list) {
    776       unsigned size = llvmpipe_resource_size(&lpr->base);
    777       debug_printf("resource %u at %p, size %ux%ux%u: %u bytes, refcount %u\n",
    778                    lpr->id, (void *) lpr,
    779                    lpr->base.width0, lpr->base.height0, lpr->base.depth0,
    780                    size, lpr->base.reference.count);
    781       total += size;
    782       n++;
    783    }
    784    debug_printf("LLVMPIPE: total size of %u resources: %u\n", n, total);
    785 }
    786 #endif
    787 
    788 
    789 void
    790 llvmpipe_init_screen_resource_funcs(struct pipe_screen *screen)
    791 {
    792 #ifdef DEBUG
    793    /* init linked list for tracking resources */
    794    {
    795       static boolean first_call = TRUE;
    796       if (first_call) {
    797          memset(&resource_list, 0, sizeof(resource_list));
    798          make_empty_list(&resource_list);
    799          first_call = FALSE;
    800       }
    801    }
    802 #endif
    803 
    804    screen->resource_create = llvmpipe_resource_create;
    805 /*   screen->resource_create_front = llvmpipe_resource_create_front; */
    806    screen->resource_destroy = llvmpipe_resource_destroy;
    807    screen->resource_from_handle = llvmpipe_resource_from_handle;
    808    screen->resource_get_handle = llvmpipe_resource_get_handle;
    809    screen->can_create_resource = llvmpipe_can_create_resource;
    810 }
    811 
    812 
    813 void
    814 llvmpipe_init_context_resource_funcs(struct pipe_context *pipe)
    815 {
    816    pipe->transfer_map = llvmpipe_transfer_map;
    817    pipe->transfer_unmap = llvmpipe_transfer_unmap;
    818 
    819    pipe->transfer_flush_region = u_default_transfer_flush_region;
    820    pipe->buffer_subdata = u_default_buffer_subdata;
    821    pipe->texture_subdata = u_default_texture_subdata;
    822 }
    823