Home | History | Annotate | Download | only in svga
      1 /**********************************************************
      2  * Copyright 2008-2009 VMware, Inc.  All rights reserved.
      3  *
      4  * Permission is hereby granted, free of charge, to any person
      5  * obtaining a copy of this software and associated documentation
      6  * files (the "Software"), to deal in the Software without
      7  * restriction, including without limitation the rights to use, copy,
      8  * modify, merge, publish, distribute, sublicense, and/or sell copies
      9  * of the Software, and to permit persons to whom the Software is
     10  * furnished to do so, subject to the following conditions:
     11  *
     12  * The above copyright notice and this permission notice shall be
     13  * included in all copies or substantial portions of the Software.
     14  *
     15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
     16  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
     17  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
     18  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
     19  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
     20  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
     21  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
     22  * SOFTWARE.
     23  *
     24  **********************************************************/
     25 
     26 #include "svga3d_reg.h"
     27 #include "svga3d_surfacedefs.h"
     28 
     29 #include "pipe/p_state.h"
     30 #include "pipe/p_defines.h"
     31 #include "os/os_thread.h"
     32 #include "util/u_format.h"
     33 #include "util/u_inlines.h"
     34 #include "util/u_math.h"
     35 #include "util/u_memory.h"
     36 #include "util/u_resource.h"
     37 #include "util/u_upload_mgr.h"
     38 
     39 #include "svga_cmd.h"
     40 #include "svga_format.h"
     41 #include "svga_screen.h"
     42 #include "svga_context.h"
     43 #include "svga_resource_texture.h"
     44 #include "svga_resource_buffer.h"
     45 #include "svga_sampler_view.h"
     46 #include "svga_winsys.h"
     47 #include "svga_debug.h"
     48 
     49 
     50 static void
     51 svga_transfer_dma_band(struct svga_context *svga,
     52                        struct svga_transfer *st,
     53                        SVGA3dTransferType transfer,
     54                        unsigned x, unsigned y, unsigned z,
     55                        unsigned w, unsigned h, unsigned d,
     56                        unsigned srcx, unsigned srcy, unsigned srcz,
     57                        SVGA3dSurfaceDMAFlags flags)
     58 {
     59    struct svga_texture *texture = svga_texture(st->base.resource);
     60    SVGA3dCopyBox box;
     61    enum pipe_error ret;
     62 
     63    assert(!st->use_direct_map);
     64 
     65    box.x = x;
     66    box.y = y;
     67    box.z = z;
     68    box.w = w;
     69    box.h = h;
     70    box.d = d;
     71    box.srcx = srcx;
     72    box.srcy = srcy;
     73    box.srcz = srcz;
     74 
     75    SVGA_DBG(DEBUG_DMA, "dma %s sid %p, face %u, (%u, %u, %u) - "
     76             "(%u, %u, %u), %ubpp\n",
     77             transfer == SVGA3D_WRITE_HOST_VRAM ? "to" : "from",
     78             texture->handle,
     79             st->slice,
     80             x,
     81             y,
     82             z,
     83             x + w,
     84             y + h,
     85             z + 1,
     86             util_format_get_blocksize(texture->b.b.format) * 8 /
     87             (util_format_get_blockwidth(texture->b.b.format)
     88              * util_format_get_blockheight(texture->b.b.format)));
     89 
     90    ret = SVGA3D_SurfaceDMA(svga->swc, st, transfer, &box, 1, flags);
     91    if (ret != PIPE_OK) {
     92       svga_context_flush(svga, NULL);
     93       ret = SVGA3D_SurfaceDMA(svga->swc, st, transfer, &box, 1, flags);
     94       assert(ret == PIPE_OK);
     95    }
     96 }
     97 
     98 
     99 static void
    100 svga_transfer_dma(struct svga_context *svga,
    101                   struct svga_transfer *st,
    102                   SVGA3dTransferType transfer,
    103                   SVGA3dSurfaceDMAFlags flags)
    104 {
    105    struct svga_texture *texture = svga_texture(st->base.resource);
    106    struct svga_screen *screen = svga_screen(texture->b.b.screen);
    107    struct svga_winsys_screen *sws = screen->sws;
    108    struct pipe_fence_handle *fence = NULL;
    109 
    110    assert(!st->use_direct_map);
    111 
    112    if (transfer == SVGA3D_READ_HOST_VRAM) {
    113       SVGA_DBG(DEBUG_PERF, "%s: readback transfer\n", __FUNCTION__);
    114    }
    115 
    116    /* Ensure any pending operations on host surfaces are queued on the command
    117     * buffer first.
    118     */
    119    svga_surfaces_flush( svga );
    120 
    121    if (!st->swbuf) {
    122       /* Do the DMA transfer in a single go */
    123       svga_transfer_dma_band(svga, st, transfer,
    124                              st->base.box.x, st->base.box.y, st->base.box.z,
    125                              st->base.box.width, st->base.box.height, st->base.box.depth,
    126                              0, 0, 0,
    127                              flags);
    128 
    129       if (transfer == SVGA3D_READ_HOST_VRAM) {
    130          svga_context_flush(svga, &fence);
    131          sws->fence_finish(sws, fence, 0);
    132          sws->fence_reference(sws, &fence, NULL);
    133       }
    134    }
    135    else {
    136       int y, h, srcy;
    137       unsigned blockheight =
    138          util_format_get_blockheight(st->base.resource->format);
    139 
    140       h = st->hw_nblocksy * blockheight;
    141       srcy = 0;
    142 
    143       for (y = 0; y < st->base.box.height; y += h) {
    144          unsigned offset, length;
    145          void *hw, *sw;
    146 
    147          if (y + h > st->base.box.height)
    148             h = st->base.box.height - y;
    149 
    150          /* Transfer band must be aligned to pixel block boundaries */
    151          assert(y % blockheight == 0);
    152          assert(h % blockheight == 0);
    153 
    154          offset = y * st->base.stride / blockheight;
    155          length = h * st->base.stride / blockheight;
    156 
    157          sw = (uint8_t *) st->swbuf + offset;
    158 
    159          if (transfer == SVGA3D_WRITE_HOST_VRAM) {
    160             unsigned usage = PIPE_TRANSFER_WRITE;
    161 
    162             /* Wait for the previous DMAs to complete */
    163             /* TODO: keep one DMA (at half the size) in the background */
    164             if (y) {
    165                svga_context_flush(svga, NULL);
    166                usage |= PIPE_TRANSFER_DISCARD_WHOLE_RESOURCE;
    167             }
    168 
    169             hw = sws->buffer_map(sws, st->hwbuf, usage);
    170             assert(hw);
    171             if (hw) {
    172                memcpy(hw, sw, length);
    173                sws->buffer_unmap(sws, st->hwbuf);
    174             }
    175          }
    176 
    177          svga_transfer_dma_band(svga, st, transfer,
    178                                 st->base.box.x, y, st->base.box.z,
    179                                 st->base.box.width, h, st->base.box.depth,
    180                                 0, srcy, 0, flags);
    181 
    182          /*
    183           * Prevent the texture contents to be discarded on the next band
    184           * upload.
    185           */
    186          flags.discard = FALSE;
    187 
    188          if (transfer == SVGA3D_READ_HOST_VRAM) {
    189             svga_context_flush(svga, &fence);
    190             sws->fence_finish(sws, fence, 0);
    191 
    192             hw = sws->buffer_map(sws, st->hwbuf, PIPE_TRANSFER_READ);
    193             assert(hw);
    194             if (hw) {
    195                memcpy(sw, hw, length);
    196                sws->buffer_unmap(sws, st->hwbuf);
    197             }
    198          }
    199       }
    200    }
    201 }
    202 
    203 
    204 
    205 static boolean
    206 svga_texture_get_handle(struct pipe_screen *screen,
    207                         struct pipe_resource *texture,
    208                         struct winsys_handle *whandle)
    209 {
    210    struct svga_winsys_screen *sws = svga_winsys_screen(texture->screen);
    211    unsigned stride;
    212 
    213    assert(svga_texture(texture)->key.cachable == 0);
    214    svga_texture(texture)->key.cachable = 0;
    215 
    216    stride = util_format_get_nblocksx(texture->format, texture->width0) *
    217             util_format_get_blocksize(texture->format);
    218 
    219    return sws->surface_get_handle(sws, svga_texture(texture)->handle,
    220                                   stride, whandle);
    221 }
    222 
    223 
    224 static void
    225 svga_texture_destroy(struct pipe_screen *screen,
    226 		     struct pipe_resource *pt)
    227 {
    228    struct svga_screen *ss = svga_screen(screen);
    229    struct svga_texture *tex = svga_texture(pt);
    230 
    231    ss->texture_timestamp++;
    232 
    233    svga_sampler_view_reference(&tex->cached_view, NULL);
    234 
    235    /*
    236      DBG("%s deleting %p\n", __FUNCTION__, (void *) tex);
    237    */
    238    SVGA_DBG(DEBUG_DMA, "unref sid %p (texture)\n", tex->handle);
    239    svga_screen_surface_destroy(ss, &tex->key, &tex->handle);
    240 
    241    ss->hud.total_resource_bytes -= tex->size;
    242 
    243    FREE(tex->defined);
    244    FREE(tex->rendered_to);
    245    FREE(tex->dirty);
    246    FREE(tex);
    247 
    248    assert(ss->hud.num_resources > 0);
    249    if (ss->hud.num_resources > 0)
    250       ss->hud.num_resources--;
    251 }
    252 
    253 
    254 /**
    255  * Determine if the resource was rendered to
    256  */
    257 static inline boolean
    258 was_tex_rendered_to(struct pipe_resource *resource,
    259                     const struct pipe_transfer *transfer)
    260 {
    261    unsigned face;
    262 
    263    if (resource->target == PIPE_TEXTURE_CUBE) {
    264       assert(transfer->box.depth == 1);
    265       face = transfer->box.z;
    266    }
    267    else {
    268       face = 0;
    269    }
    270 
    271    return svga_was_texture_rendered_to(svga_texture(resource),
    272                                        face, transfer->level);
    273 }
    274 
    275 
    276 /**
    277  * Determine if we need to read back a texture image before mapping it.
    278  */
    279 static inline boolean
    280 need_tex_readback(struct pipe_transfer *transfer)
    281 {
    282    if (transfer->usage & PIPE_TRANSFER_READ)
    283       return TRUE;
    284 
    285    if ((transfer->usage & PIPE_TRANSFER_WRITE) &&
    286        ((transfer->usage & PIPE_TRANSFER_DISCARD_WHOLE_RESOURCE) == 0)) {
    287       return was_tex_rendered_to(transfer->resource, transfer);
    288    }
    289 
    290    return FALSE;
    291 }
    292 
    293 
    294 static enum pipe_error
    295 readback_image_vgpu9(struct svga_context *svga,
    296                    struct svga_winsys_surface *surf,
    297                    unsigned slice,
    298                    unsigned level)
    299 {
    300    enum pipe_error ret;
    301 
    302    ret = SVGA3D_ReadbackGBImage(svga->swc, surf, slice, level);
    303    if (ret != PIPE_OK) {
    304       svga_context_flush(svga, NULL);
    305       ret = SVGA3D_ReadbackGBImage(svga->swc, surf, slice, level);
    306    }
    307    return ret;
    308 }
    309 
    310 
    311 static enum pipe_error
    312 readback_image_vgpu10(struct svga_context *svga,
    313                     struct svga_winsys_surface *surf,
    314                     unsigned slice,
    315                     unsigned level,
    316                     unsigned numMipLevels)
    317 {
    318    enum pipe_error ret;
    319    unsigned subResource;
    320 
    321    subResource = slice * numMipLevels + level;
    322    ret = SVGA3D_vgpu10_ReadbackSubResource(svga->swc, surf, subResource);
    323    if (ret != PIPE_OK) {
    324       svga_context_flush(svga, NULL);
    325       ret = SVGA3D_vgpu10_ReadbackSubResource(svga->swc, surf, subResource);
    326    }
    327    return ret;
    328 }
    329 
    330 
    331 /**
    332  * Use DMA for the transfer request
    333  */
    334 static void *
    335 svga_texture_transfer_map_dma(struct svga_context *svga,
    336                               struct svga_transfer *st)
    337 {
    338    struct svga_winsys_screen *sws = svga_screen(svga->pipe.screen)->sws;
    339    struct pipe_resource *texture = st->base.resource;
    340    unsigned nblocksx, nblocksy;
    341    unsigned d;
    342    unsigned usage = st->base.usage;
    343 
    344    /* we'll put the data into a tightly packed buffer */
    345    nblocksx = util_format_get_nblocksx(texture->format, st->base.box.width);
    346    nblocksy = util_format_get_nblocksy(texture->format, st->base.box.height);
    347    d = st->base.box.depth;
    348 
    349    st->base.stride = nblocksx*util_format_get_blocksize(texture->format);
    350    st->base.layer_stride = st->base.stride * nblocksy;
    351    st->hw_nblocksy = nblocksy;
    352 
    353    st->hwbuf = svga_winsys_buffer_create(svga, 1, 0,
    354                                          st->hw_nblocksy * st->base.stride * d);
    355 
    356    while (!st->hwbuf && (st->hw_nblocksy /= 2)) {
    357       st->hwbuf =
    358          svga_winsys_buffer_create(svga, 1, 0,
    359                                    st->hw_nblocksy * st->base.stride * d);
    360    }
    361 
    362    if (!st->hwbuf)
    363       return NULL;
    364 
    365    if (st->hw_nblocksy < nblocksy) {
    366       /* We couldn't allocate a hardware buffer big enough for the transfer,
    367        * so allocate regular malloc memory instead
    368        */
    369       if (0) {
    370          debug_printf("%s: failed to allocate %u KB of DMA, "
    371                       "splitting into %u x %u KB DMA transfers\n",
    372                       __FUNCTION__,
    373                       (nblocksy * st->base.stride + 1023) / 1024,
    374                       (nblocksy + st->hw_nblocksy - 1) / st->hw_nblocksy,
    375                       (st->hw_nblocksy * st->base.stride + 1023) / 1024);
    376       }
    377 
    378       st->swbuf = MALLOC(nblocksy * st->base.stride * d);
    379       if (!st->swbuf) {
    380          sws->buffer_destroy(sws, st->hwbuf);
    381          return NULL;
    382       }
    383    }
    384 
    385    if (usage & PIPE_TRANSFER_READ) {
    386       SVGA3dSurfaceDMAFlags flags;
    387       memset(&flags, 0, sizeof flags);
    388       svga_transfer_dma(svga, st, SVGA3D_READ_HOST_VRAM, flags);
    389    }
    390 
    391    if (st->swbuf) {
    392       return st->swbuf;
    393    }
    394    else {
    395       return sws->buffer_map(sws, st->hwbuf, usage);
    396    }
    397 }
    398 
    399 
    400 /**
    401  * Use direct map for the transfer request
    402  */
    403 static void *
    404 svga_texture_transfer_map_direct(struct svga_context *svga,
    405                                  struct svga_transfer *st)
    406 {
    407    struct svga_winsys_screen *sws = svga_screen(svga->pipe.screen)->sws;
    408    struct pipe_transfer *transfer = &st->base;
    409    struct pipe_resource *texture = transfer->resource;
    410    struct svga_texture *tex = svga_texture(texture);
    411    struct svga_winsys_surface *surf = tex->handle;
    412    unsigned level = st->base.level;
    413    unsigned w, h, nblocksx, nblocksy;
    414    unsigned usage = st->base.usage;
    415 
    416    if (need_tex_readback(transfer)) {
    417       enum pipe_error ret;
    418 
    419       svga_surfaces_flush(svga);
    420 
    421       if (svga_have_vgpu10(svga)) {
    422          ret = readback_image_vgpu10(svga, surf, st->slice, level,
    423                                      tex->b.b.last_level + 1);
    424       } else {
    425          ret = readback_image_vgpu9(svga, surf, st->slice, level);
    426       }
    427 
    428       svga->hud.num_readbacks++;
    429       SVGA_STATS_COUNT_INC(sws, SVGA_STATS_COUNT_TEXREADBACK);
    430 
    431       assert(ret == PIPE_OK);
    432       (void) ret;
    433 
    434       svga_context_flush(svga, NULL);
    435       /*
    436        * Note: if PIPE_TRANSFER_DISCARD_WHOLE_RESOURCE were specified
    437        * we could potentially clear the flag for all faces/layers/mips.
    438        */
    439       svga_clear_texture_rendered_to(tex, st->slice, level);
    440    }
    441    else {
    442       assert(usage & PIPE_TRANSFER_WRITE);
    443       if ((usage & PIPE_TRANSFER_UNSYNCHRONIZED) == 0) {
    444          if (svga_is_texture_dirty(tex, st->slice, level)) {
    445             /*
    446              * do a surface flush if the subresource has been modified
    447              * in this command buffer.
    448              */
    449             svga_surfaces_flush(svga);
    450             if (!sws->surface_is_flushed(sws, surf)) {
    451                svga->hud.surface_write_flushes++;
    452                SVGA_STATS_COUNT_INC(sws, SVGA_STATS_COUNT_SURFACEWRITEFLUSH);
    453                svga_context_flush(svga, NULL);
    454             }
    455          }
    456       }
    457    }
    458 
    459    /* we'll directly access the guest-backed surface */
    460    w = u_minify(texture->width0, level);
    461    h = u_minify(texture->height0, level);
    462    nblocksx = util_format_get_nblocksx(texture->format, w);
    463    nblocksy = util_format_get_nblocksy(texture->format, h);
    464    st->hw_nblocksy = nblocksy;
    465    st->base.stride = nblocksx*util_format_get_blocksize(texture->format);
    466    st->base.layer_stride = st->base.stride * nblocksy;
    467 
    468    /*
    469     * Begin mapping code
    470     */
    471    {
    472       SVGA3dSize baseLevelSize;
    473       uint8_t *map;
    474       boolean retry;
    475       unsigned offset, mip_width, mip_height;
    476 
    477       map = svga->swc->surface_map(svga->swc, surf, usage, &retry);
    478       if (map == NULL && retry) {
    479          /*
    480           * At this point, the svga_surfaces_flush() should already have
    481           * called in svga_texture_get_transfer().
    482           */
    483          svga->hud.surface_write_flushes++;
    484          svga_context_flush(svga, NULL);
    485          map = svga->swc->surface_map(svga->swc, surf, usage, &retry);
    486       }
    487 
    488       /*
    489        * Make sure we return NULL if the map fails
    490        */
    491       if (!map) {
    492          return NULL;
    493       }
    494 
    495       /**
    496        * Compute the offset to the specific texture slice in the buffer.
    497        */
    498       baseLevelSize.width = tex->b.b.width0;
    499       baseLevelSize.height = tex->b.b.height0;
    500       baseLevelSize.depth = tex->b.b.depth0;
    501 
    502       if ((tex->b.b.target == PIPE_TEXTURE_1D_ARRAY) ||
    503           (tex->b.b.target == PIPE_TEXTURE_2D_ARRAY)) {
    504          st->base.layer_stride =
    505             svga3dsurface_get_image_offset(tex->key.format, baseLevelSize,
    506                                            tex->b.b.last_level + 1, 1, 0);
    507       }
    508 
    509       offset = svga3dsurface_get_image_offset(tex->key.format, baseLevelSize,
    510                                               tex->b.b.last_level + 1, /* numMips */
    511                                               st->slice, level);
    512       if (level > 0) {
    513          assert(offset > 0);
    514       }
    515 
    516       mip_width = u_minify(tex->b.b.width0, level);
    517       mip_height = u_minify(tex->b.b.height0, level);
    518 
    519       offset += svga3dsurface_get_pixel_offset(tex->key.format,
    520                                                mip_width, mip_height,
    521                                                st->base.box.x,
    522                                                st->base.box.y,
    523                                                st->base.box.z);
    524       return (void *) (map + offset);
    525    }
    526 }
    527 
    528 
    529 /**
    530  * Request a transfer map to the texture resource
    531  */
    532 static void *
    533 svga_texture_transfer_map(struct pipe_context *pipe,
    534                           struct pipe_resource *texture,
    535                           unsigned level,
    536                           unsigned usage,
    537                           const struct pipe_box *box,
    538                           struct pipe_transfer **ptransfer)
    539 {
    540    struct svga_context *svga = svga_context(pipe);
    541    struct svga_winsys_screen *sws = svga_screen(pipe->screen)->sws;
    542    struct svga_texture *tex = svga_texture(texture);
    543    struct svga_transfer *st;
    544    struct svga_winsys_surface *surf = tex->handle;
    545    boolean use_direct_map = svga_have_gb_objects(svga) &&
    546                             !svga_have_gb_dma(svga);
    547    void *map = NULL;
    548    int64_t begin = svga_get_time(svga);
    549 
    550    SVGA_STATS_TIME_PUSH(sws, SVGA_STATS_TIME_TEXTRANSFERMAP);
    551 
    552    if (!surf)
    553       goto done;
    554 
    555    /* We can't map texture storage directly unless we have GB objects */
    556    if (usage & PIPE_TRANSFER_MAP_DIRECTLY) {
    557       if (svga_have_gb_objects(svga))
    558          use_direct_map = TRUE;
    559       else
    560          goto done;
    561    }
    562 
    563    st = CALLOC_STRUCT(svga_transfer);
    564    if (!st)
    565       goto done;
    566 
    567    st->base.level = level;
    568    st->base.usage = usage;
    569    st->base.box = *box;
    570 
    571    switch (tex->b.b.target) {
    572    case PIPE_TEXTURE_CUBE:
    573       st->slice = st->base.box.z;
    574       st->base.box.z = 0;   /* so we don't apply double offsets below */
    575       break;
    576    case PIPE_TEXTURE_2D_ARRAY:
    577    case PIPE_TEXTURE_1D_ARRAY:
    578       st->slice = st->base.box.z;
    579       st->base.box.z = 0;   /* so we don't apply double offsets below */
    580 
    581       /* Force direct map for transfering multiple slices */
    582       if (st->base.box.depth > 1)
    583          use_direct_map = svga_have_gb_objects(svga);
    584 
    585       break;
    586    default:
    587       st->slice = 0;
    588       break;
    589    }
    590 
    591    st->use_direct_map = use_direct_map;
    592    pipe_resource_reference(&st->base.resource, texture);
    593 
    594    /* If this is the first time mapping to the surface in this
    595     * command buffer, clear the dirty masks of this surface.
    596     */
    597    if (sws->surface_is_flushed(sws, surf)) {
    598       svga_clear_texture_dirty(tex);
    599    }
    600 
    601    if (!use_direct_map) {
    602       /* upload to the DMA buffer */
    603       map = svga_texture_transfer_map_dma(svga, st);
    604    }
    605    else {
    606       boolean can_use_upload = tex->can_use_upload &&
    607                                !(st->base.usage & PIPE_TRANSFER_READ);
    608       boolean was_rendered_to = was_tex_rendered_to(texture, &st->base);
    609 
    610       /* If the texture was already rendered to and upload buffer
    611        * is supported, then we will use upload buffer to
    612        * avoid the need to read back the texture content; otherwise,
    613        * we'll first try to map directly to the GB surface, if it is blocked,
    614        * then we'll try the upload buffer.
    615        */
    616       if (was_rendered_to && can_use_upload) {
    617          map = svga_texture_transfer_map_upload(svga, st);
    618       }
    619       else {
    620          unsigned orig_usage = st->base.usage;
    621 
    622          /* First try directly map to the GB surface */
    623          if (can_use_upload)
    624             st->base.usage |= PIPE_TRANSFER_DONTBLOCK;
    625          map = svga_texture_transfer_map_direct(svga, st);
    626          st->base.usage = orig_usage;
    627 
    628          if (!map && can_use_upload) {
    629             /* if direct map with DONTBLOCK fails, then try upload to the
    630              * texture upload buffer.
    631              */
    632             map = svga_texture_transfer_map_upload(svga, st);
    633          }
    634       }
    635 
    636       /* If upload fails, then try direct map again without forcing it
    637        * to DONTBLOCK.
    638        */
    639       if (!map) {
    640          map = svga_texture_transfer_map_direct(svga, st);
    641       }
    642    }
    643 
    644    if (!map) {
    645       FREE(st);
    646    }
    647    else {
    648       *ptransfer = &st->base;
    649       svga->hud.num_textures_mapped++;
    650       if (usage & PIPE_TRANSFER_WRITE) {
    651          /* record texture upload for HUD */
    652          svga->hud.num_bytes_uploaded +=
    653             st->base.layer_stride * st->base.box.depth;
    654 
    655          /* mark this texture level as dirty */
    656          svga_set_texture_dirty(tex, st->slice, level);
    657       }
    658    }
    659 
    660 done:
    661    svga->hud.map_buffer_time += (svga_get_time(svga) - begin);
    662    SVGA_STATS_TIME_POP(sws);
    663    (void) sws;
    664 
    665    return map;
    666 }
    667 
    668 /**
    669  * Unmap a GB texture surface.
    670  */
    671 static void
    672 svga_texture_surface_unmap(struct svga_context *svga,
    673                            struct pipe_transfer *transfer)
    674 {
    675    struct svga_winsys_surface *surf = svga_texture(transfer->resource)->handle;
    676    struct svga_winsys_context *swc = svga->swc;
    677    boolean rebind;
    678 
    679    assert(surf);
    680 
    681    swc->surface_unmap(swc, surf, &rebind);
    682    if (rebind) {
    683       enum pipe_error ret;
    684       ret = SVGA3D_BindGBSurface(swc, surf);
    685       if (ret != PIPE_OK) {
    686          /* flush and retry */
    687          svga_context_flush(svga, NULL);
    688          ret = SVGA3D_BindGBSurface(swc, surf);
    689          assert(ret == PIPE_OK);
    690       }
    691    }
    692 }
    693 
    694 
    695 static enum pipe_error
    696 update_image_vgpu9(struct svga_context *svga,
    697                    struct svga_winsys_surface *surf,
    698                    const SVGA3dBox *box,
    699                    unsigned slice,
    700                    unsigned level)
    701 {
    702    enum pipe_error ret;
    703 
    704    ret = SVGA3D_UpdateGBImage(svga->swc, surf, box, slice, level);
    705    if (ret != PIPE_OK) {
    706       svga_context_flush(svga, NULL);
    707       ret = SVGA3D_UpdateGBImage(svga->swc, surf, box, slice, level);
    708    }
    709    return ret;
    710 }
    711 
    712 
    713 static enum pipe_error
    714 update_image_vgpu10(struct svga_context *svga,
    715                     struct svga_winsys_surface *surf,
    716                     const SVGA3dBox *box,
    717                     unsigned slice,
    718                     unsigned level,
    719                     unsigned numMipLevels)
    720 {
    721    enum pipe_error ret;
    722    unsigned subResource;
    723 
    724    subResource = slice * numMipLevels + level;
    725    ret = SVGA3D_vgpu10_UpdateSubResource(svga->swc, surf, box, subResource);
    726    if (ret != PIPE_OK) {
    727       svga_context_flush(svga, NULL);
    728       ret = SVGA3D_vgpu10_UpdateSubResource(svga->swc, surf, box, subResource);
    729    }
    730    return ret;
    731 }
    732 
    733 
    734 /**
    735  * unmap DMA transfer request
    736  */
    737 static void
    738 svga_texture_transfer_unmap_dma(struct svga_context *svga,
    739 			        struct svga_transfer *st)
    740 {
    741    struct svga_winsys_screen *sws = svga_screen(svga->pipe.screen)->sws;
    742 
    743    if (st->hwbuf)
    744       sws->buffer_unmap(sws, st->hwbuf);
    745 
    746    if (st->base.usage & PIPE_TRANSFER_WRITE) {
    747       /* Use DMA to transfer texture data */
    748       SVGA3dSurfaceDMAFlags flags;
    749 
    750       memset(&flags, 0, sizeof flags);
    751       if (st->base.usage & PIPE_TRANSFER_DISCARD_WHOLE_RESOURCE) {
    752          flags.discard = TRUE;
    753       }
    754       if (st->base.usage & PIPE_TRANSFER_UNSYNCHRONIZED) {
    755          flags.unsynchronized = TRUE;
    756       }
    757 
    758       svga_transfer_dma(svga, st, SVGA3D_WRITE_HOST_VRAM, flags);
    759    }
    760 
    761    FREE(st->swbuf);
    762    sws->buffer_destroy(sws, st->hwbuf);
    763 }
    764 
    765 
    766 /**
    767  * unmap direct map transfer request
    768  */
    769 static void
    770 svga_texture_transfer_unmap_direct(struct svga_context *svga,
    771 			           struct svga_transfer *st)
    772 {
    773    struct pipe_transfer *transfer = &st->base;
    774    struct svga_texture *tex = svga_texture(transfer->resource);
    775 
    776    svga_texture_surface_unmap(svga, transfer);
    777 
    778    /* Now send an update command to update the content in the backend. */
    779    if (st->base.usage & PIPE_TRANSFER_WRITE) {
    780       struct svga_winsys_surface *surf = tex->handle;
    781       SVGA3dBox box;
    782       enum pipe_error ret;
    783       unsigned nlayers = 1;
    784 
    785       assert(svga_have_gb_objects(svga));
    786 
    787       /* update the effected region */
    788       box.x = transfer->box.x;
    789       box.y = transfer->box.y;
    790       box.w = transfer->box.width;
    791       box.h = transfer->box.height;
    792       box.d = transfer->box.depth;
    793 
    794       switch (tex->b.b.target) {
    795       case PIPE_TEXTURE_CUBE:
    796          box.z = 0;
    797          break;
    798       case PIPE_TEXTURE_2D_ARRAY:
    799          nlayers = box.d;
    800          box.z = 0;
    801          box.d = 1;
    802          break;
    803       case PIPE_TEXTURE_1D_ARRAY:
    804          nlayers = box.d;
    805          box.y = box.z = 0;
    806          box.d = 1;
    807          break;
    808       default:
    809          box.z = transfer->box.z;
    810          break;
    811       }
    812 
    813       if (0)
    814          debug_printf("%s %d, %d, %d  %d x %d x %d\n",
    815                       __FUNCTION__,
    816                       box.x, box.y, box.z,
    817                       box.w, box.h, box.d);
    818 
    819       if (svga_have_vgpu10(svga)) {
    820          unsigned i;
    821          for (i = 0; i < nlayers; i++) {
    822             ret = update_image_vgpu10(svga, surf, &box,
    823                                       st->slice + i, transfer->level,
    824                                       tex->b.b.last_level + 1);
    825             assert(ret == PIPE_OK);
    826          }
    827       } else {
    828          assert(nlayers == 1);
    829          ret = update_image_vgpu9(svga, surf, &box, st->slice, transfer->level);
    830          assert(ret == PIPE_OK);
    831       }
    832       (void) ret;
    833    }
    834 }
    835 
    836 static void
    837 svga_texture_transfer_unmap(struct pipe_context *pipe,
    838 			    struct pipe_transfer *transfer)
    839 {
    840    struct svga_context *svga = svga_context(pipe);
    841    struct svga_screen *ss = svga_screen(pipe->screen);
    842    struct svga_winsys_screen *sws = ss->sws;
    843    struct svga_transfer *st = svga_transfer(transfer);
    844    struct svga_texture *tex = svga_texture(transfer->resource);
    845 
    846    SVGA_STATS_TIME_PUSH(sws, SVGA_STATS_TIME_TEXTRANSFERUNMAP);
    847 
    848    if (!st->use_direct_map) {
    849       svga_texture_transfer_unmap_dma(svga, st);
    850    }
    851    else if (st->upload.buf) {
    852       svga_texture_transfer_unmap_upload(svga, st);
    853    }
    854    else {
    855       svga_texture_transfer_unmap_direct(svga, st);
    856    }
    857 
    858    if (st->base.usage & PIPE_TRANSFER_WRITE) {
    859       svga->hud.num_resource_updates++;
    860 
    861       /* Mark the texture level as dirty */
    862       ss->texture_timestamp++;
    863       svga_age_texture_view(tex, transfer->level);
    864       if (transfer->resource->target == PIPE_TEXTURE_CUBE)
    865          svga_define_texture_level(tex, st->slice, transfer->level);
    866       else
    867          svga_define_texture_level(tex, 0, transfer->level);
    868    }
    869 
    870    pipe_resource_reference(&st->base.resource, NULL);
    871    FREE(st);
    872    SVGA_STATS_TIME_POP(sws);
    873    (void) sws;
    874 }
    875 
    876 
    877 /**
    878  * Does format store depth values?
    879  */
    880 static inline boolean
    881 format_has_depth(enum pipe_format format)
    882 {
    883    const struct util_format_description *desc = util_format_description(format);
    884    return util_format_has_depth(desc);
    885 }
    886 
    887 
    888 struct u_resource_vtbl svga_texture_vtbl =
    889 {
    890    svga_texture_get_handle,	      /* get_handle */
    891    svga_texture_destroy,	      /* resource_destroy */
    892    svga_texture_transfer_map,	      /* transfer_map */
    893    u_default_transfer_flush_region,   /* transfer_flush_region */
    894    svga_texture_transfer_unmap,	      /* transfer_unmap */
    895 };
    896 
    897 
    898 struct pipe_resource *
    899 svga_texture_create(struct pipe_screen *screen,
    900                     const struct pipe_resource *template)
    901 {
    902    struct svga_screen *svgascreen = svga_screen(screen);
    903    struct svga_texture *tex;
    904    unsigned bindings = template->bind;
    905 
    906    SVGA_STATS_TIME_PUSH(svgascreen->sws,
    907                         SVGA_STATS_TIME_CREATETEXTURE);
    908 
    909    assert(template->last_level < SVGA_MAX_TEXTURE_LEVELS);
    910    if (template->last_level >= SVGA_MAX_TEXTURE_LEVELS) {
    911       goto fail_notex;
    912    }
    913 
    914    tex = CALLOC_STRUCT(svga_texture);
    915    if (!tex) {
    916       goto fail_notex;
    917    }
    918 
    919    tex->defined = CALLOC(template->depth0 * template->array_size,
    920                          sizeof(tex->defined[0]));
    921    if (!tex->defined) {
    922       FREE(tex);
    923       goto fail_notex;
    924    }
    925 
    926    tex->rendered_to = CALLOC(template->depth0 * template->array_size,
    927                              sizeof(tex->rendered_to[0]));
    928    if (!tex->rendered_to) {
    929       goto fail;
    930    }
    931 
    932    tex->dirty = CALLOC(template->depth0 * template->array_size,
    933                              sizeof(tex->dirty[0]));
    934    if (!tex->dirty) {
    935       goto fail;
    936    }
    937 
    938    tex->b.b = *template;
    939    tex->b.vtbl = &svga_texture_vtbl;
    940    pipe_reference_init(&tex->b.b.reference, 1);
    941    tex->b.b.screen = screen;
    942 
    943    tex->key.flags = 0;
    944    tex->key.size.width = template->width0;
    945    tex->key.size.height = template->height0;
    946    tex->key.size.depth = template->depth0;
    947    tex->key.arraySize = 1;
    948    tex->key.numFaces = 1;
    949 
    950    /* single sample texture can be treated as non-multisamples texture */
    951    tex->key.sampleCount = template->nr_samples > 1 ? template->nr_samples : 0;
    952 
    953    if (template->nr_samples > 1) {
    954       tex->key.flags |= SVGA3D_SURFACE_MASKABLE_ANTIALIAS;
    955    }
    956 
    957    if (svgascreen->sws->have_vgpu10) {
    958       switch (template->target) {
    959       case PIPE_TEXTURE_1D:
    960          tex->key.flags |= SVGA3D_SURFACE_1D;
    961          break;
    962       case PIPE_TEXTURE_1D_ARRAY:
    963          tex->key.flags |= SVGA3D_SURFACE_1D;
    964          /* fall-through */
    965       case PIPE_TEXTURE_2D_ARRAY:
    966          tex->key.flags |= SVGA3D_SURFACE_ARRAY;
    967          tex->key.arraySize = template->array_size;
    968          break;
    969       case PIPE_TEXTURE_3D:
    970          tex->key.flags |= SVGA3D_SURFACE_VOLUME;
    971          break;
    972       case PIPE_TEXTURE_CUBE:
    973          tex->key.flags |= (SVGA3D_SURFACE_CUBEMAP | SVGA3D_SURFACE_ARRAY);
    974          tex->key.numFaces = 6;
    975          break;
    976       default:
    977          break;
    978       }
    979    }
    980    else {
    981       switch (template->target) {
    982       case PIPE_TEXTURE_3D:
    983          tex->key.flags |= SVGA3D_SURFACE_VOLUME;
    984          break;
    985       case PIPE_TEXTURE_CUBE:
    986          tex->key.flags |= SVGA3D_SURFACE_CUBEMAP;
    987          tex->key.numFaces = 6;
    988          break;
    989       default:
    990          break;
    991       }
    992    }
    993 
    994    tex->key.cachable = 1;
    995 
    996    if ((bindings & (PIPE_BIND_RENDER_TARGET | PIPE_BIND_DEPTH_STENCIL)) &&
    997        !(bindings & PIPE_BIND_SAMPLER_VIEW)) {
    998       /* Also check if the format can be sampled from */
    999       if (screen->is_format_supported(screen, template->format,
   1000                                       template->target,
   1001                                       template->nr_samples,
   1002                                       PIPE_BIND_SAMPLER_VIEW)) {
   1003          bindings |= PIPE_BIND_SAMPLER_VIEW;
   1004       }
   1005    }
   1006 
   1007    if (bindings & PIPE_BIND_SAMPLER_VIEW) {
   1008       tex->key.flags |= SVGA3D_SURFACE_HINT_TEXTURE;
   1009       tex->key.flags |= SVGA3D_SURFACE_BIND_SHADER_RESOURCE;
   1010 
   1011       if (!(bindings & PIPE_BIND_RENDER_TARGET)) {
   1012          /* Also check if the format is color renderable */
   1013          if (screen->is_format_supported(screen, template->format,
   1014                                          template->target,
   1015                                          template->nr_samples,
   1016                                          PIPE_BIND_RENDER_TARGET)) {
   1017             bindings |= PIPE_BIND_RENDER_TARGET;
   1018          }
   1019       }
   1020 
   1021       if (!(bindings & PIPE_BIND_DEPTH_STENCIL)) {
   1022          /* Also check if the format is depth/stencil renderable */
   1023          if (screen->is_format_supported(screen, template->format,
   1024                                          template->target,
   1025                                          template->nr_samples,
   1026                                          PIPE_BIND_DEPTH_STENCIL)) {
   1027             bindings |= PIPE_BIND_DEPTH_STENCIL;
   1028          }
   1029       }
   1030    }
   1031 
   1032    if (bindings & PIPE_BIND_DISPLAY_TARGET) {
   1033       tex->key.cachable = 0;
   1034    }
   1035 
   1036    if (bindings & PIPE_BIND_SHARED) {
   1037       tex->key.cachable = 0;
   1038    }
   1039 
   1040    if (bindings & (PIPE_BIND_SCANOUT | PIPE_BIND_CURSOR)) {
   1041       tex->key.scanout = 1;
   1042       tex->key.cachable = 0;
   1043    }
   1044 
   1045    /*
   1046     * Note: Previously we never passed the
   1047     * SVGA3D_SURFACE_HINT_RENDERTARGET hint. Mesa cannot
   1048     * know beforehand whether a texture will be used as a rendertarget or not
   1049     * and it always requests PIPE_BIND_RENDER_TARGET, therefore
   1050     * passing the SVGA3D_SURFACE_HINT_RENDERTARGET here defeats its purpose.
   1051     *
   1052     * However, this was changed since other state trackers
   1053     * (XA for example) uses it accurately and certain device versions
   1054     * relies on it in certain situations to render correctly.
   1055     */
   1056    if ((bindings & PIPE_BIND_RENDER_TARGET) &&
   1057        !util_format_is_s3tc(template->format)) {
   1058       tex->key.flags |= SVGA3D_SURFACE_HINT_RENDERTARGET;
   1059       tex->key.flags |= SVGA3D_SURFACE_BIND_RENDER_TARGET;
   1060    }
   1061 
   1062    if (bindings & PIPE_BIND_DEPTH_STENCIL) {
   1063       tex->key.flags |= SVGA3D_SURFACE_HINT_DEPTHSTENCIL;
   1064       tex->key.flags |= SVGA3D_SURFACE_BIND_DEPTH_STENCIL;
   1065    }
   1066 
   1067    tex->key.numMipLevels = template->last_level + 1;
   1068 
   1069    tex->key.format = svga_translate_format(svgascreen, template->format,
   1070                                            bindings);
   1071    if (tex->key.format == SVGA3D_FORMAT_INVALID) {
   1072       goto fail;
   1073    }
   1074 
   1075    /* Use typeless formats for sRGB and depth resources.  Typeless
   1076     * formats can be reinterpreted as other formats.  For example,
   1077     * SVGA3D_R8G8B8A8_UNORM_TYPELESS can be interpreted as
   1078     * SVGA3D_R8G8B8A8_UNORM_SRGB or SVGA3D_R8G8B8A8_UNORM.
   1079     */
   1080    if (svgascreen->sws->have_vgpu10 &&
   1081        (util_format_is_srgb(template->format) ||
   1082         format_has_depth(template->format))) {
   1083       SVGA3dSurfaceFormat typeless = svga_typeless_format(tex->key.format);
   1084       if (0) {
   1085          debug_printf("Convert resource type %s -> %s (bind 0x%x)\n",
   1086                       svga_format_name(tex->key.format),
   1087                       svga_format_name(typeless),
   1088                       bindings);
   1089       }
   1090 
   1091       if (svga_format_is_uncompressed_snorm(tex->key.format)) {
   1092          /* We can't normally render to snorm surfaces, but once we
   1093           * substitute a typeless format, we can if the rendertarget view
   1094           * is unorm.  This can happen with GL_ARB_copy_image.
   1095           */
   1096          tex->key.flags |= SVGA3D_SURFACE_HINT_RENDERTARGET;
   1097          tex->key.flags |= SVGA3D_SURFACE_BIND_RENDER_TARGET;
   1098       }
   1099 
   1100       tex->key.format = typeless;
   1101    }
   1102 
   1103    SVGA_DBG(DEBUG_DMA, "surface_create for texture\n", tex->handle);
   1104    tex->handle = svga_screen_surface_create(svgascreen, bindings,
   1105                                             tex->b.b.usage,
   1106                                             &tex->validated, &tex->key);
   1107    if (!tex->handle) {
   1108       goto fail;
   1109    }
   1110 
   1111    SVGA_DBG(DEBUG_DMA, "  --> got sid %p (texture)\n", tex->handle);
   1112 
   1113    debug_reference(&tex->b.b.reference,
   1114                    (debug_reference_descriptor)debug_describe_resource, 0);
   1115 
   1116    tex->size = util_resource_size(template);
   1117 
   1118    /* Determine if texture upload buffer can be used to upload this texture */
   1119    tex->can_use_upload = svga_texture_transfer_map_can_upload(svgascreen,
   1120                                                               &tex->b.b);
   1121 
   1122    svgascreen->hud.total_resource_bytes += tex->size;
   1123    svgascreen->hud.num_resources++;
   1124 
   1125    SVGA_STATS_TIME_POP(svgascreen->sws);
   1126 
   1127    return &tex->b.b;
   1128 
   1129 fail:
   1130    if (tex->dirty)
   1131       FREE(tex->dirty);
   1132    if (tex->rendered_to)
   1133       FREE(tex->rendered_to);
   1134    if (tex->defined)
   1135       FREE(tex->defined);
   1136    FREE(tex);
   1137 fail_notex:
   1138    SVGA_STATS_TIME_POP(svgascreen->sws);
   1139    return NULL;
   1140 }
   1141 
   1142 
   1143 struct pipe_resource *
   1144 svga_texture_from_handle(struct pipe_screen *screen,
   1145 			 const struct pipe_resource *template,
   1146 			 struct winsys_handle *whandle)
   1147 {
   1148    struct svga_winsys_screen *sws = svga_winsys_screen(screen);
   1149    struct svga_screen *ss = svga_screen(screen);
   1150    struct svga_winsys_surface *srf;
   1151    struct svga_texture *tex;
   1152    enum SVGA3dSurfaceFormat format = 0;
   1153    assert(screen);
   1154 
   1155    /* Only supports one type */
   1156    if ((template->target != PIPE_TEXTURE_2D &&
   1157        template->target != PIPE_TEXTURE_RECT) ||
   1158        template->last_level != 0 ||
   1159        template->depth0 != 1) {
   1160       return NULL;
   1161    }
   1162 
   1163    srf = sws->surface_from_handle(sws, whandle, &format);
   1164 
   1165    if (!srf)
   1166       return NULL;
   1167 
   1168    if (svga_translate_format(svga_screen(screen), template->format,
   1169                              template->bind) != format) {
   1170       unsigned f1 = svga_translate_format(svga_screen(screen),
   1171                                           template->format, template->bind);
   1172       unsigned f2 = format;
   1173 
   1174       /* It's okay for XRGB and ARGB or depth with/out stencil to get mixed up.
   1175        */
   1176       if (f1 == SVGA3D_B8G8R8A8_UNORM)
   1177          f1 = SVGA3D_A8R8G8B8;
   1178       if (f1 == SVGA3D_B8G8R8X8_UNORM)
   1179          f1 = SVGA3D_X8R8G8B8;
   1180 
   1181       if ( !( (f1 == f2) ||
   1182               (f1 == SVGA3D_X8R8G8B8 && f2 == SVGA3D_A8R8G8B8) ||
   1183               (f1 == SVGA3D_X8R8G8B8 && f2 == SVGA3D_B8G8R8X8_UNORM) ||
   1184               (f1 == SVGA3D_A8R8G8B8 && f2 == SVGA3D_X8R8G8B8) ||
   1185               (f1 == SVGA3D_A8R8G8B8 && f2 == SVGA3D_B8G8R8A8_UNORM) ||
   1186               (f1 == SVGA3D_Z_D24X8 && f2 == SVGA3D_Z_D24S8) ||
   1187               (f1 == SVGA3D_Z_DF24 && f2 == SVGA3D_Z_D24S8_INT) ) ) {
   1188          debug_printf("%s wrong format %s != %s\n", __FUNCTION__,
   1189                       svga_format_name(f1), svga_format_name(f2));
   1190          return NULL;
   1191       }
   1192    }
   1193 
   1194    tex = CALLOC_STRUCT(svga_texture);
   1195    if (!tex)
   1196       return NULL;
   1197 
   1198    tex->defined = CALLOC(template->depth0 * template->array_size,
   1199                          sizeof(tex->defined[0]));
   1200    if (!tex->defined) {
   1201       FREE(tex);
   1202       return NULL;
   1203    }
   1204 
   1205    tex->b.b = *template;
   1206    tex->b.vtbl = &svga_texture_vtbl;
   1207    pipe_reference_init(&tex->b.b.reference, 1);
   1208    tex->b.b.screen = screen;
   1209 
   1210    SVGA_DBG(DEBUG_DMA, "wrap surface sid %p\n", srf);
   1211 
   1212    tex->key.cachable = 0;
   1213    tex->key.format = format;
   1214    tex->handle = srf;
   1215 
   1216    tex->rendered_to = CALLOC(1, sizeof(tex->rendered_to[0]));
   1217    if (!tex->rendered_to)
   1218       goto fail;
   1219 
   1220    tex->dirty = CALLOC(1, sizeof(tex->dirty[0]));
   1221    if (!tex->dirty)
   1222       goto fail;
   1223 
   1224    tex->imported = TRUE;
   1225 
   1226    ss->hud.num_resources++;
   1227 
   1228    return &tex->b.b;
   1229 
   1230 fail:
   1231    if (tex->defined)
   1232       FREE(tex->defined);
   1233    if (tex->rendered_to)
   1234       FREE(tex->rendered_to);
   1235    if (tex->dirty)
   1236       FREE(tex->dirty);
   1237    FREE(tex);
   1238    return NULL;
   1239 }
   1240 
   1241 boolean
   1242 svga_texture_generate_mipmap(struct pipe_context *pipe,
   1243                              struct pipe_resource *pt,
   1244                              enum pipe_format format,
   1245                              unsigned base_level,
   1246                              unsigned last_level,
   1247                              unsigned first_layer,
   1248                              unsigned last_layer)
   1249 {
   1250    struct pipe_sampler_view templ, *psv;
   1251    struct svga_pipe_sampler_view *sv;
   1252    struct svga_context *svga = svga_context(pipe);
   1253    struct svga_texture *tex = svga_texture(pt);
   1254    enum pipe_error ret;
   1255 
   1256    assert(svga_have_vgpu10(svga));
   1257 
   1258    /* Only support 2D texture for now */
   1259    if (pt->target != PIPE_TEXTURE_2D)
   1260       return FALSE;
   1261 
   1262    /* Fallback to the mipmap generation utility for those formats that
   1263     * do not support hw generate mipmap
   1264     */
   1265    if (!svga_format_support_gen_mips(format))
   1266       return FALSE;
   1267 
   1268    /* Make sure the texture surface was created with
   1269     * SVGA3D_SURFACE_BIND_RENDER_TARGET
   1270     */
   1271    if (!tex->handle || !(tex->key.flags & SVGA3D_SURFACE_BIND_RENDER_TARGET))
   1272       return FALSE;
   1273 
   1274    templ.format = format;
   1275    templ.u.tex.first_layer = first_layer;
   1276    templ.u.tex.last_layer = last_layer;
   1277    templ.u.tex.first_level = base_level;
   1278    templ.u.tex.last_level = last_level;
   1279 
   1280    psv = pipe->create_sampler_view(pipe, pt, &templ);
   1281    if (psv == NULL)
   1282       return FALSE;
   1283 
   1284    sv = svga_pipe_sampler_view(psv);
   1285    ret = svga_validate_pipe_sampler_view(svga, sv);
   1286    if (ret != PIPE_OK) {
   1287       svga_context_flush(svga, NULL);
   1288       ret = svga_validate_pipe_sampler_view(svga, sv);
   1289       assert(ret == PIPE_OK);
   1290    }
   1291 
   1292    ret = SVGA3D_vgpu10_GenMips(svga->swc, sv->id, tex->handle);
   1293    if (ret != PIPE_OK) {
   1294       svga_context_flush(svga, NULL);
   1295       ret = SVGA3D_vgpu10_GenMips(svga->swc, sv->id, tex->handle);
   1296    }
   1297    pipe_sampler_view_reference(&psv, NULL);
   1298 
   1299    svga->hud.num_generate_mipmap++;
   1300 
   1301    return TRUE;
   1302 }
   1303 
   1304 
   1305 /* texture upload buffer default size in bytes */
   1306 #define TEX_UPLOAD_DEFAULT_SIZE (1024 * 1024)
   1307 
   1308 /**
   1309  * Create a texture upload buffer
   1310  */
   1311 boolean
   1312 svga_texture_transfer_map_upload_create(struct svga_context *svga)
   1313 {
   1314    svga->tex_upload = u_upload_create(&svga->pipe, TEX_UPLOAD_DEFAULT_SIZE,
   1315                                       0, PIPE_USAGE_STAGING);
   1316    return svga->tex_upload != NULL;
   1317 }
   1318 
   1319 
   1320 /**
   1321  * Destroy the texture upload buffer
   1322  */
   1323 void
   1324 svga_texture_transfer_map_upload_destroy(struct svga_context *svga)
   1325 {
   1326    u_upload_destroy(svga->tex_upload);
   1327 }
   1328 
   1329 
   1330 /**
   1331  * Returns true if this transfer map request can use the upload buffer.
   1332  */
   1333 boolean
   1334 svga_texture_transfer_map_can_upload(const struct svga_screen *svgascreen,
   1335                                      const struct pipe_resource *texture)
   1336 {
   1337    if (svgascreen->sws->have_transfer_from_buffer_cmd == FALSE)
   1338       return FALSE;
   1339 
   1340    /* TransferFromBuffer command is not well supported with multi-samples surface */
   1341    if (texture->nr_samples > 1)
   1342       return FALSE;
   1343 
   1344    if (util_format_is_compressed(texture->format)) {
   1345       /* XXX Need to take a closer look to see why texture upload
   1346        * with 3D texture with compressed format fails
   1347        */
   1348       if (texture->target == PIPE_TEXTURE_3D)
   1349           return FALSE;
   1350    }
   1351    else if (texture->format == PIPE_FORMAT_R9G9B9E5_FLOAT) {
   1352       return FALSE;
   1353    }
   1354 
   1355    return TRUE;
   1356 }
   1357 
   1358 
   1359 /**
   1360  * Use upload buffer for the transfer map request.
   1361  */
   1362 void *
   1363 svga_texture_transfer_map_upload(struct svga_context *svga,
   1364                                  struct svga_transfer *st)
   1365 {
   1366    struct pipe_resource *texture = st->base.resource;
   1367    struct pipe_resource *tex_buffer = NULL;
   1368    void *tex_map;
   1369    unsigned nblocksx, nblocksy;
   1370    unsigned offset;
   1371    unsigned upload_size;
   1372 
   1373    assert(svga->tex_upload);
   1374 
   1375    st->upload.box.x = st->base.box.x;
   1376    st->upload.box.y = st->base.box.y;
   1377    st->upload.box.z = st->base.box.z;
   1378    st->upload.box.w = st->base.box.width;
   1379    st->upload.box.h = st->base.box.height;
   1380    st->upload.box.d = st->base.box.depth;
   1381    st->upload.nlayers = 1;
   1382 
   1383    switch (texture->target) {
   1384    case PIPE_TEXTURE_CUBE:
   1385       st->upload.box.z = 0;
   1386       break;
   1387    case PIPE_TEXTURE_2D_ARRAY:
   1388       st->upload.nlayers = st->base.box.depth;
   1389       st->upload.box.z = 0;
   1390       st->upload.box.d = 1;
   1391       break;
   1392    case PIPE_TEXTURE_1D_ARRAY:
   1393       st->upload.nlayers = st->base.box.depth;
   1394       st->upload.box.y = st->upload.box.z = 0;
   1395       st->upload.box.d = 1;
   1396       break;
   1397    default:
   1398       break;
   1399    }
   1400 
   1401    nblocksx = util_format_get_nblocksx(texture->format, st->base.box.width);
   1402    nblocksy = util_format_get_nblocksy(texture->format, st->base.box.height);
   1403 
   1404    st->base.stride = nblocksx * util_format_get_blocksize(texture->format);
   1405    st->base.layer_stride = st->base.stride * nblocksy;
   1406 
   1407    /* In order to use the TransferFromBuffer command to update the
   1408     * texture content from the buffer, the layer stride for a multi-layers
   1409     * surface needs to be in multiples of 16 bytes.
   1410     */
   1411    if (st->upload.nlayers > 1 && st->base.layer_stride & 15)
   1412       return NULL;
   1413 
   1414    upload_size = st->base.layer_stride * st->base.box.depth;
   1415    upload_size = align(upload_size, 16);
   1416 
   1417 #ifdef DEBUG
   1418    if (util_format_is_compressed(texture->format)) {
   1419       struct svga_texture *tex = svga_texture(texture);
   1420       unsigned blockw, blockh, bytesPerBlock;
   1421 
   1422       svga_format_size(tex->key.format, &blockw, &blockh, &bytesPerBlock);
   1423 
   1424       /* dest box must start on block boundary */
   1425       assert((st->base.box.x % blockw) == 0);
   1426       assert((st->base.box.y % blockh) == 0);
   1427    }
   1428 #endif
   1429 
   1430    /* If the upload size exceeds the default buffer size, the
   1431     * upload buffer manager code will try to allocate a new buffer
   1432     * with the new buffer size.
   1433     */
   1434    u_upload_alloc(svga->tex_upload, 0, upload_size, 16,
   1435                   &offset, &tex_buffer, &tex_map);
   1436 
   1437    if (!tex_map) {
   1438       return NULL;
   1439    }
   1440 
   1441    st->upload.buf = tex_buffer;
   1442    st->upload.map = tex_map;
   1443    st->upload.offset = offset;
   1444 
   1445    return tex_map;
   1446 }
   1447 
   1448 
   1449 /**
   1450  * Unmap upload map transfer request
   1451  */
   1452 void
   1453 svga_texture_transfer_unmap_upload(struct svga_context *svga,
   1454                                    struct svga_transfer *st)
   1455 {
   1456    struct svga_winsys_surface *srcsurf;
   1457    struct svga_winsys_surface *dstsurf;
   1458    struct pipe_resource *texture = st->base.resource;
   1459    struct svga_texture *tex = svga_texture(texture);
   1460    enum pipe_error ret;
   1461    unsigned subResource;
   1462    unsigned numMipLevels;
   1463    unsigned i, layer;
   1464    unsigned offset = st->upload.offset;
   1465 
   1466    assert(svga->tex_upload);
   1467    assert(st->upload.buf);
   1468 
   1469    /* unmap the texture upload buffer */
   1470    u_upload_unmap(svga->tex_upload);
   1471 
   1472    srcsurf = svga_buffer_handle(svga, st->upload.buf);
   1473    dstsurf = svga_texture(texture)->handle;
   1474    assert(dstsurf);
   1475 
   1476    numMipLevels = texture->last_level + 1;
   1477 
   1478    for (i = 0, layer = st->slice; i < st->upload.nlayers; i++, layer++) {
   1479       subResource = layer * numMipLevels + st->base.level;
   1480 
   1481       /* send a transferFromBuffer command to update the host texture surface */
   1482       assert((offset & 15) == 0);
   1483 
   1484       ret = SVGA3D_vgpu10_TransferFromBuffer(svga->swc, srcsurf,
   1485                                              offset,
   1486                                              st->base.stride,
   1487                                              st->base.layer_stride,
   1488                                              dstsurf, subResource,
   1489                                              &st->upload.box);
   1490       if (ret != PIPE_OK) {
   1491          svga_context_flush(svga, NULL);
   1492          ret = SVGA3D_vgpu10_TransferFromBuffer(svga->swc, srcsurf,
   1493                                                 offset,
   1494                                                 st->base.stride,
   1495                                                 st->base.layer_stride,
   1496                                                 dstsurf, subResource,
   1497                                                 &st->upload.box);
   1498          assert(ret == PIPE_OK);
   1499       }
   1500       offset += st->base.layer_stride;
   1501 
   1502       /* Set rendered-to flag */
   1503       svga_set_texture_rendered_to(tex, layer, st->base.level);
   1504    }
   1505 
   1506    pipe_resource_reference(&st->upload.buf, NULL);
   1507 }
   1508