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 
    307 
    308 static struct pipe_resource *
    309 llvmpipe_resource_create(struct pipe_screen *_screen,
    310                          const struct pipe_resource *templat)
    311 {
    312    return llvmpipe_resource_create_front(_screen, templat, NULL);
    313 }
    314 
    315 
    316 static void
    317 llvmpipe_resource_destroy(struct pipe_screen *pscreen,
    318                           struct pipe_resource *pt)
    319 {
    320    struct llvmpipe_screen *screen = llvmpipe_screen(pscreen);
    321    struct llvmpipe_resource *lpr = llvmpipe_resource(pt);
    322 
    323    if (lpr->dt) {
    324       /* display target */
    325       struct sw_winsys *winsys = screen->winsys;
    326       winsys->displaytarget_destroy(winsys, lpr->dt);
    327    }
    328    else if (llvmpipe_resource_is_texture(pt)) {
    329       /* free linear image data */
    330       if (lpr->tex_data) {
    331          align_free(lpr->tex_data);
    332          lpr->tex_data = NULL;
    333       }
    334    }
    335    else if (!lpr->userBuffer) {
    336       assert(lpr->data);
    337       align_free(lpr->data);
    338    }
    339 
    340 #ifdef DEBUG
    341    if (lpr->next)
    342       remove_from_list(lpr);
    343 #endif
    344 
    345    FREE(lpr);
    346 }
    347 
    348 
    349 /**
    350  * Map a resource for read/write.
    351  */
    352 void *
    353 llvmpipe_resource_map(struct pipe_resource *resource,
    354                       unsigned level,
    355                       unsigned layer,
    356                       enum lp_texture_usage tex_usage)
    357 {
    358    struct llvmpipe_resource *lpr = llvmpipe_resource(resource);
    359    uint8_t *map;
    360 
    361    assert(level < LP_MAX_TEXTURE_LEVELS);
    362    assert(layer < (u_minify(resource->depth0, level) + resource->array_size - 1));
    363 
    364    assert(tex_usage == LP_TEX_USAGE_READ ||
    365           tex_usage == LP_TEX_USAGE_READ_WRITE ||
    366           tex_usage == LP_TEX_USAGE_WRITE_ALL);
    367 
    368    if (lpr->dt) {
    369       /* display target */
    370       struct llvmpipe_screen *screen = llvmpipe_screen(resource->screen);
    371       struct sw_winsys *winsys = screen->winsys;
    372       unsigned dt_usage;
    373 
    374       if (tex_usage == LP_TEX_USAGE_READ) {
    375          dt_usage = PIPE_TRANSFER_READ;
    376       }
    377       else {
    378          dt_usage = PIPE_TRANSFER_READ_WRITE;
    379       }
    380 
    381       assert(level == 0);
    382       assert(layer == 0);
    383 
    384       /* FIXME: keep map count? */
    385       map = winsys->displaytarget_map(winsys, lpr->dt, dt_usage);
    386 
    387       /* install this linear image in texture data structure */
    388       lpr->tex_data = map;
    389 
    390       return map;
    391    }
    392    else if (llvmpipe_resource_is_texture(resource)) {
    393 
    394       map = llvmpipe_get_texture_image_address(lpr, layer, level);
    395       return map;
    396    }
    397    else {
    398       return lpr->data;
    399    }
    400 }
    401 
    402 
    403 /**
    404  * Unmap a resource.
    405  */
    406 void
    407 llvmpipe_resource_unmap(struct pipe_resource *resource,
    408                        unsigned level,
    409                        unsigned layer)
    410 {
    411    struct llvmpipe_resource *lpr = llvmpipe_resource(resource);
    412 
    413    if (lpr->dt) {
    414       /* display target */
    415       struct llvmpipe_screen *lp_screen = llvmpipe_screen(resource->screen);
    416       struct sw_winsys *winsys = lp_screen->winsys;
    417 
    418       assert(level == 0);
    419       assert(layer == 0);
    420 
    421       winsys->displaytarget_unmap(winsys, lpr->dt);
    422    }
    423 }
    424 
    425 
    426 void *
    427 llvmpipe_resource_data(struct pipe_resource *resource)
    428 {
    429    struct llvmpipe_resource *lpr = llvmpipe_resource(resource);
    430 
    431    assert(!llvmpipe_resource_is_texture(resource));
    432 
    433    return lpr->data;
    434 }
    435 
    436 
    437 static struct pipe_resource *
    438 llvmpipe_resource_from_handle(struct pipe_screen *screen,
    439                               const struct pipe_resource *template,
    440                               struct winsys_handle *whandle,
    441                               unsigned usage)
    442 {
    443    struct sw_winsys *winsys = llvmpipe_screen(screen)->winsys;
    444    struct llvmpipe_resource *lpr;
    445 
    446    /* XXX Seems like from_handled depth textures doesn't work that well */
    447 
    448    lpr = CALLOC_STRUCT(llvmpipe_resource);
    449    if (!lpr) {
    450       goto no_lpr;
    451    }
    452 
    453    lpr->base = *template;
    454    pipe_reference_init(&lpr->base.reference, 1);
    455    lpr->base.screen = screen;
    456 
    457    /*
    458     * Looks like unaligned displaytargets work just fine,
    459     * at least sampler/render ones.
    460     */
    461 #if 0
    462    assert(lpr->base.width0 == width);
    463    assert(lpr->base.height0 == height);
    464 #endif
    465 
    466    lpr->dt = winsys->displaytarget_from_handle(winsys,
    467                                                template,
    468                                                whandle,
    469                                                &lpr->row_stride[0]);
    470    if (!lpr->dt) {
    471       goto no_dt;
    472    }
    473 
    474    lpr->id = id_counter++;
    475 
    476 #ifdef DEBUG
    477    insert_at_tail(&resource_list, lpr);
    478 #endif
    479 
    480    return &lpr->base;
    481 
    482 no_dt:
    483    FREE(lpr);
    484 no_lpr:
    485    return NULL;
    486 }
    487 
    488 
    489 static boolean
    490 llvmpipe_resource_get_handle(struct pipe_screen *screen,
    491                              struct pipe_context *ctx,
    492                             struct pipe_resource *pt,
    493                             struct winsys_handle *whandle,
    494                              unsigned usage)
    495 {
    496    struct sw_winsys *winsys = llvmpipe_screen(screen)->winsys;
    497    struct llvmpipe_resource *lpr = llvmpipe_resource(pt);
    498 
    499    assert(lpr->dt);
    500    if (!lpr->dt)
    501       return FALSE;
    502 
    503    return winsys->displaytarget_get_handle(winsys, lpr->dt, whandle);
    504 }
    505 
    506 
    507 static void *
    508 llvmpipe_transfer_map( struct pipe_context *pipe,
    509                        struct pipe_resource *resource,
    510                        unsigned level,
    511                        unsigned usage,
    512                        const struct pipe_box *box,
    513                        struct pipe_transfer **transfer )
    514 {
    515    struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe);
    516    struct llvmpipe_screen *screen = llvmpipe_screen(pipe->screen);
    517    struct llvmpipe_resource *lpr = llvmpipe_resource(resource);
    518    struct llvmpipe_transfer *lpt;
    519    struct pipe_transfer *pt;
    520    ubyte *map;
    521    enum pipe_format format;
    522    enum lp_texture_usage tex_usage;
    523    const char *mode;
    524 
    525    assert(resource);
    526    assert(level <= resource->last_level);
    527 
    528    /*
    529     * Transfers, like other pipe operations, must happen in order, so flush the
    530     * context if necessary.
    531     */
    532    if (!(usage & PIPE_TRANSFER_UNSYNCHRONIZED)) {
    533       boolean read_only = !(usage & PIPE_TRANSFER_WRITE);
    534       boolean do_not_block = !!(usage & PIPE_TRANSFER_DONTBLOCK);
    535       if (!llvmpipe_flush_resource(pipe, resource,
    536                                    level,
    537                                    read_only,
    538                                    TRUE, /* cpu_access */
    539                                    do_not_block,
    540                                    __FUNCTION__)) {
    541          /*
    542           * It would have blocked, but state tracker requested no to.
    543           */
    544          assert(do_not_block);
    545          return NULL;
    546       }
    547    }
    548 
    549    /* Check if we're mapping a current constant buffer */
    550    if ((usage & PIPE_TRANSFER_WRITE) &&
    551        (resource->bind & PIPE_BIND_CONSTANT_BUFFER)) {
    552       unsigned i;
    553       for (i = 0; i < ARRAY_SIZE(llvmpipe->constants[PIPE_SHADER_FRAGMENT]); ++i) {
    554          if (resource == llvmpipe->constants[PIPE_SHADER_FRAGMENT][i].buffer) {
    555             /* constants may have changed */
    556             llvmpipe->dirty |= LP_NEW_FS_CONSTANTS;
    557             break;
    558          }
    559       }
    560    }
    561 
    562    lpt = CALLOC_STRUCT(llvmpipe_transfer);
    563    if (!lpt)
    564       return NULL;
    565    pt = &lpt->base;
    566    pipe_resource_reference(&pt->resource, resource);
    567    pt->box = *box;
    568    pt->level = level;
    569    pt->stride = lpr->row_stride[level];
    570    pt->layer_stride = lpr->img_stride[level];
    571    pt->usage = usage;
    572    *transfer = pt;
    573 
    574    assert(level < LP_MAX_TEXTURE_LEVELS);
    575 
    576    /*
    577    printf("tex_transfer_map(%d, %d  %d x %d of %d x %d,  usage %d )\n",
    578           transfer->x, transfer->y, transfer->width, transfer->height,
    579           transfer->texture->width0,
    580           transfer->texture->height0,
    581           transfer->usage);
    582    */
    583 
    584    if (usage == PIPE_TRANSFER_READ) {
    585       tex_usage = LP_TEX_USAGE_READ;
    586       mode = "read";
    587    }
    588    else {
    589       tex_usage = LP_TEX_USAGE_READ_WRITE;
    590       mode = "read/write";
    591    }
    592 
    593    if (0) {
    594       printf("transfer map tex %u  mode %s\n", lpr->id, mode);
    595    }
    596 
    597    format = lpr->base.format;
    598 
    599    map = llvmpipe_resource_map(resource,
    600                                level,
    601                                box->z,
    602                                tex_usage);
    603 
    604 
    605    /* May want to do different things here depending on read/write nature
    606     * of the map:
    607     */
    608    if (usage & PIPE_TRANSFER_WRITE) {
    609       /* Do something to notify sharing contexts of a texture change.
    610        */
    611       screen->timestamp++;
    612    }
    613 
    614    map +=
    615       box->y / util_format_get_blockheight(format) * pt->stride +
    616       box->x / util_format_get_blockwidth(format) * util_format_get_blocksize(format);
    617 
    618    return map;
    619 }
    620 
    621 
    622 static void
    623 llvmpipe_transfer_unmap(struct pipe_context *pipe,
    624                         struct pipe_transfer *transfer)
    625 {
    626    assert(transfer->resource);
    627 
    628    llvmpipe_resource_unmap(transfer->resource,
    629                            transfer->level,
    630                            transfer->box.z);
    631 
    632    /* Effectively do the texture_update work here - if texture images
    633     * needed post-processing to put them into hardware layout, this is
    634     * where it would happen.  For llvmpipe, nothing to do.
    635     */
    636    assert (transfer->resource);
    637    pipe_resource_reference(&transfer->resource, NULL);
    638    FREE(transfer);
    639 }
    640 
    641 unsigned int
    642 llvmpipe_is_resource_referenced( struct pipe_context *pipe,
    643                                  struct pipe_resource *presource,
    644                                  unsigned level)
    645 {
    646    struct llvmpipe_context *llvmpipe = llvmpipe_context( pipe );
    647    if (!(presource->bind & (PIPE_BIND_DEPTH_STENCIL |
    648                             PIPE_BIND_RENDER_TARGET |
    649                             PIPE_BIND_SAMPLER_VIEW)))
    650       return LP_UNREFERENCED;
    651 
    652    return lp_setup_is_resource_referenced(llvmpipe->setup, presource);
    653 }
    654 
    655 
    656 /**
    657  * Returns the largest possible alignment for a format in llvmpipe
    658  */
    659 unsigned
    660 llvmpipe_get_format_alignment( enum pipe_format format )
    661 {
    662    const struct util_format_description *desc = util_format_description(format);
    663    unsigned size = 0;
    664    unsigned bytes;
    665    unsigned i;
    666 
    667    for (i = 0; i < desc->nr_channels; ++i) {
    668       size += desc->channel[i].size;
    669    }
    670 
    671    bytes = size / 8;
    672 
    673    if (!util_is_power_of_two(bytes)) {
    674       bytes /= desc->nr_channels;
    675    }
    676 
    677    if (bytes % 2 || bytes < 1) {
    678       return 1;
    679    } else {
    680       return bytes;
    681    }
    682 }
    683 
    684 
    685 /**
    686  * Create buffer which wraps user-space data.
    687  * XXX unreachable.
    688  */
    689 struct pipe_resource *
    690 llvmpipe_user_buffer_create(struct pipe_screen *screen,
    691                             void *ptr,
    692                             unsigned bytes,
    693                             unsigned bind_flags)
    694 {
    695    struct llvmpipe_resource *buffer;
    696 
    697    buffer = CALLOC_STRUCT(llvmpipe_resource);
    698    if (!buffer)
    699       return NULL;
    700 
    701    pipe_reference_init(&buffer->base.reference, 1);
    702    buffer->base.screen = screen;
    703    buffer->base.format = PIPE_FORMAT_R8_UNORM; /* ?? */
    704    buffer->base.bind = bind_flags;
    705    buffer->base.usage = PIPE_USAGE_IMMUTABLE;
    706    buffer->base.flags = 0;
    707    buffer->base.width0 = bytes;
    708    buffer->base.height0 = 1;
    709    buffer->base.depth0 = 1;
    710    buffer->base.array_size = 1;
    711    buffer->userBuffer = TRUE;
    712    buffer->data = ptr;
    713 
    714    return &buffer->base;
    715 }
    716 
    717 
    718 /**
    719  * Compute size (in bytes) need to store a texture image / mipmap level,
    720  * for just one cube face, one array layer or one 3D texture slice
    721  */
    722 static unsigned
    723 tex_image_face_size(const struct llvmpipe_resource *lpr, unsigned level)
    724 {
    725    return lpr->img_stride[level];
    726 }
    727 
    728 
    729 /**
    730  * Return pointer to a 2D texture image/face/slice.
    731  * No tiled/linear conversion is done.
    732  */
    733 ubyte *
    734 llvmpipe_get_texture_image_address(struct llvmpipe_resource *lpr,
    735                                    unsigned face_slice, unsigned level)
    736 {
    737    unsigned offset;
    738 
    739    assert(llvmpipe_resource_is_texture(&lpr->base));
    740 
    741    offset = lpr->mip_offsets[level];
    742 
    743    if (face_slice > 0)
    744       offset += face_slice * tex_image_face_size(lpr, level);
    745 
    746    return (ubyte *) lpr->tex_data + offset;
    747 }
    748 
    749 
    750 /**
    751  * Return size of resource in bytes
    752  */
    753 unsigned
    754 llvmpipe_resource_size(const struct pipe_resource *resource)
    755 {
    756    const struct llvmpipe_resource *lpr = llvmpipe_resource_const(resource);
    757    unsigned size = 0;
    758 
    759    if (llvmpipe_resource_is_texture(resource)) {
    760       /* Note this will always return 0 for displaytarget resources */
    761       size = lpr->total_alloc_size;
    762    }
    763    else {
    764       size = resource->width0;
    765    }
    766    return size;
    767 }
    768 
    769 
    770 #ifdef DEBUG
    771 void
    772 llvmpipe_print_resources(void)
    773 {
    774    struct llvmpipe_resource *lpr;
    775    unsigned n = 0, total = 0;
    776 
    777    debug_printf("LLVMPIPE: current resources:\n");
    778    foreach(lpr, &resource_list) {
    779       unsigned size = llvmpipe_resource_size(&lpr->base);
    780       debug_printf("resource %u at %p, size %ux%ux%u: %u bytes, refcount %u\n",
    781                    lpr->id, (void *) lpr,
    782                    lpr->base.width0, lpr->base.height0, lpr->base.depth0,
    783                    size, lpr->base.reference.count);
    784       total += size;
    785       n++;
    786    }
    787    debug_printf("LLVMPIPE: total size of %u resources: %u\n", n, total);
    788 }
    789 #endif
    790 
    791 
    792 void
    793 llvmpipe_init_screen_resource_funcs(struct pipe_screen *screen)
    794 {
    795 #ifdef DEBUG
    796    /* init linked list for tracking resources */
    797    {
    798       static boolean first_call = TRUE;
    799       if (first_call) {
    800          memset(&resource_list, 0, sizeof(resource_list));
    801          make_empty_list(&resource_list);
    802          first_call = FALSE;
    803       }
    804    }
    805 #endif
    806 
    807    screen->resource_create = llvmpipe_resource_create;
    808 /*   screen->resource_create_front = llvmpipe_resource_create_front; */
    809    screen->resource_destroy = llvmpipe_resource_destroy;
    810    screen->resource_from_handle = llvmpipe_resource_from_handle;
    811    screen->resource_get_handle = llvmpipe_resource_get_handle;
    812    screen->can_create_resource = llvmpipe_can_create_resource;
    813 }
    814 
    815 
    816 void
    817 llvmpipe_init_context_resource_funcs(struct pipe_context *pipe)
    818 {
    819    pipe->transfer_map = llvmpipe_transfer_map;
    820    pipe->transfer_unmap = llvmpipe_transfer_unmap;
    821 
    822    pipe->transfer_flush_region = u_default_transfer_flush_region;
    823    pipe->buffer_subdata = u_default_buffer_subdata;
    824    pipe->texture_subdata = u_default_texture_subdata;
    825 }
    826