Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  1. /**************************************************************************
  2.  *
  3.  * Copyright 2007 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. /**
  29.  * Render target tile caching.
  30.  *
  31.  * Author:
  32.  *    Brian Paul
  33.  */
  34.  
  35. #include "util/u_inlines.h"
  36. #include "util/u_format.h"
  37. #include "util/u_memory.h"
  38. #include "util/u_tile.h"
  39. #include "sp_tile_cache.h"
  40.  
  41. static struct softpipe_cached_tile *
  42. sp_alloc_tile(struct softpipe_tile_cache *tc);
  43.  
  44.  
  45. /**
  46.  * Return the position in the cache for the tile that contains win pos (x,y).
  47.  * We currently use a direct mapped cache so this is like a hack key.
  48.  * At some point we should investige something more sophisticated, like
  49.  * a LRU replacement policy.
  50.  */
  51. #define CACHE_POS(x, y, l)                        \
  52.    (((x) + (y) * 5 + (l) * 10) % NUM_ENTRIES)
  53.  
  54.  
  55. static INLINE int addr_to_clear_pos(union tile_address addr)
  56. {
  57.    int pos;
  58.    pos = addr.bits.layer * (MAX_WIDTH / TILE_SIZE) * (MAX_HEIGHT / TILE_SIZE);
  59.    pos += addr.bits.y * (MAX_WIDTH / TILE_SIZE);
  60.    pos += addr.bits.x;
  61.    return pos;
  62. }
  63. /**
  64.  * Is the tile at (x,y) in cleared state?
  65.  */
  66. static INLINE uint
  67. is_clear_flag_set(const uint *bitvec, union tile_address addr, unsigned max)
  68. {
  69.    int pos, bit;
  70.    pos = addr_to_clear_pos(addr);
  71.    assert(pos / 32 < max);
  72.    bit = bitvec[pos / 32] & (1 << (pos & 31));
  73.    return bit;
  74. }
  75.    
  76.  
  77. /**
  78.  * Mark the tile at (x,y) as not cleared.
  79.  */
  80. static INLINE void
  81. clear_clear_flag(uint *bitvec, union tile_address addr, unsigned max)
  82. {
  83.    int pos;
  84.    pos = addr_to_clear_pos(addr);
  85.    assert(pos / 32 < max);
  86.    bitvec[pos / 32] &= ~(1 << (pos & 31));
  87. }
  88.    
  89.  
  90. struct softpipe_tile_cache *
  91. sp_create_tile_cache( struct pipe_context *pipe )
  92. {
  93.    struct softpipe_tile_cache *tc;
  94.    uint pos;
  95.    int maxLevels, maxTexSize;
  96.  
  97.    /* sanity checking: max sure MAX_WIDTH/HEIGHT >= largest texture image */
  98.    maxLevels = pipe->screen->get_param(pipe->screen, PIPE_CAP_MAX_TEXTURE_2D_LEVELS);
  99.    maxTexSize = 1 << (maxLevels - 1);
  100.    assert(MAX_WIDTH >= maxTexSize);
  101.  
  102.    assert(sizeof(union tile_address) == 4);
  103.  
  104.    assert((TILE_SIZE << TILE_ADDR_BITS) >= MAX_WIDTH);
  105.  
  106.    tc = CALLOC_STRUCT( softpipe_tile_cache );
  107.    if (tc) {
  108.       tc->pipe = pipe;
  109.       for (pos = 0; pos < Elements(tc->tile_addrs); pos++) {
  110.          tc->tile_addrs[pos].bits.invalid = 1;
  111.       }
  112.       tc->last_tile_addr.bits.invalid = 1;
  113.  
  114.       /* this allocation allows us to guarantee that allocation
  115.        * failures are never fatal later
  116.        */
  117.       tc->tile = MALLOC_STRUCT( softpipe_cached_tile );
  118.       if (!tc->tile)
  119.       {
  120.          FREE(tc);
  121.          return NULL;
  122.       }
  123.  
  124.       /* XXX this code prevents valgrind warnings about use of uninitialized
  125.        * memory in programs that don't clear the surface before rendering.
  126.        * However, it breaks clearing in other situations (such as in
  127.        * progs/tests/drawbuffers, see bug 24402).
  128.        */
  129. #if 0
  130.       /* set flags to indicate all the tiles are cleared */
  131.       memset(tc->clear_flags, 255, sizeof(tc->clear_flags));
  132. #endif
  133.    }
  134.    return tc;
  135. }
  136.  
  137.  
  138. void
  139. sp_destroy_tile_cache(struct softpipe_tile_cache *tc)
  140. {
  141.    if (tc) {
  142.       uint pos;
  143.  
  144.       for (pos = 0; pos < Elements(tc->entries); pos++) {
  145.          /*assert(tc->entries[pos].x < 0);*/
  146.          FREE( tc->entries[pos] );
  147.       }
  148.       FREE( tc->tile );
  149.  
  150.       if (tc->num_maps) {
  151.          int i;
  152.          for (i = 0; i < tc->num_maps; i++)
  153.             if (tc->transfer[i]) {
  154.                tc->pipe->transfer_unmap(tc->pipe, tc->transfer[i]);
  155.             }
  156.          FREE(tc->transfer);
  157.          FREE(tc->transfer_map);
  158.          FREE(tc->clear_flags);
  159.       }
  160.  
  161.       FREE( tc );
  162.    }
  163. }
  164.  
  165.  
  166. /**
  167.  * Specify the surface to cache.
  168.  */
  169. void
  170. sp_tile_cache_set_surface(struct softpipe_tile_cache *tc,
  171.                           struct pipe_surface *ps)
  172. {
  173.    struct pipe_context *pipe = tc->pipe;
  174.    int i;
  175.  
  176.    if (tc->num_maps) {
  177.       if (ps == tc->surface)
  178.          return;
  179.  
  180.       for (i = 0; i < tc->num_maps; i++) {
  181.          pipe->transfer_unmap(pipe, tc->transfer[i]);
  182.          tc->transfer[i] = NULL;
  183.          tc->transfer_map[i] = NULL;
  184.       }
  185.       FREE(tc->transfer);
  186.       FREE(tc->transfer_map);
  187.       tc->num_maps = 0;
  188.  
  189.       FREE(tc->clear_flags);
  190.       tc->clear_flags_size = 0;
  191.    }
  192.  
  193.    tc->surface = ps;
  194.  
  195.    if (ps) {
  196.       tc->num_maps = ps->u.tex.last_layer - ps->u.tex.first_layer + 1;
  197.       tc->transfer = CALLOC(tc->num_maps, sizeof(struct pipe_transfer *));
  198.       tc->transfer_map = CALLOC(tc->num_maps, sizeof(void *));
  199.  
  200.       tc->clear_flags_size = (MAX_WIDTH / TILE_SIZE) * (MAX_HEIGHT / TILE_SIZE) * tc->num_maps / 32 * sizeof(uint);
  201.       tc->clear_flags = CALLOC(1, tc->clear_flags_size);
  202.  
  203.       if (ps->texture->target != PIPE_BUFFER) {
  204.          for (i = 0; i < tc->num_maps; i++) {
  205.             tc->transfer_map[i] = pipe_transfer_map(pipe, ps->texture,
  206.                                                     ps->u.tex.level, ps->u.tex.first_layer + i,
  207.                                                     PIPE_TRANSFER_READ_WRITE |
  208.                                                     PIPE_TRANSFER_UNSYNCHRONIZED,
  209.                                                     0, 0, ps->width, ps->height,
  210.                                                     &tc->transfer[i]);
  211.          }
  212.       }
  213.       else {
  214.          /* can't render to buffers */
  215.          assert(0);
  216.       }
  217.  
  218.       tc->depth_stencil = util_format_is_depth_or_stencil(ps->format);
  219.    }
  220. }
  221.  
  222.  
  223. /**
  224.  * Return the transfer being cached.
  225.  */
  226. struct pipe_surface *
  227. sp_tile_cache_get_surface(struct softpipe_tile_cache *tc)
  228. {
  229.    return tc->surface;
  230. }
  231.  
  232.  
  233. /**
  234.  * Set pixels in a tile to the given clear color/value, float.
  235.  */
  236. static void
  237. clear_tile_rgba(struct softpipe_cached_tile *tile,
  238.                 enum pipe_format format,
  239.                 const union pipe_color_union *clear_value)
  240. {
  241.    if (clear_value->f[0] == 0.0 &&
  242.        clear_value->f[1] == 0.0 &&
  243.        clear_value->f[2] == 0.0 &&
  244.        clear_value->f[3] == 0.0) {
  245.       memset(tile->data.color, 0, sizeof(tile->data.color));
  246.    }
  247.    else {
  248.       uint i, j;
  249.  
  250.       if (util_format_is_pure_uint(format)) {
  251.          for (i = 0; i < TILE_SIZE; i++) {
  252.             for (j = 0; j < TILE_SIZE; j++) {
  253.                tile->data.colorui128[i][j][0] = clear_value->ui[0];
  254.                tile->data.colorui128[i][j][1] = clear_value->ui[1];
  255.                tile->data.colorui128[i][j][2] = clear_value->ui[2];
  256.                tile->data.colorui128[i][j][3] = clear_value->ui[3];
  257.             }
  258.          }
  259.       } else if (util_format_is_pure_sint(format)) {
  260.          for (i = 0; i < TILE_SIZE; i++) {
  261.             for (j = 0; j < TILE_SIZE; j++) {
  262.                tile->data.colori128[i][j][0] = clear_value->i[0];
  263.                tile->data.colori128[i][j][1] = clear_value->i[1];
  264.                tile->data.colori128[i][j][2] = clear_value->i[2];
  265.                tile->data.colori128[i][j][3] = clear_value->i[3];
  266.             }
  267.          }
  268.       } else {
  269.          for (i = 0; i < TILE_SIZE; i++) {
  270.             for (j = 0; j < TILE_SIZE; j++) {
  271.                tile->data.color[i][j][0] = clear_value->f[0];
  272.                tile->data.color[i][j][1] = clear_value->f[1];
  273.                tile->data.color[i][j][2] = clear_value->f[2];
  274.                tile->data.color[i][j][3] = clear_value->f[3];
  275.             }
  276.          }
  277.       }
  278.    }
  279. }
  280.  
  281.  
  282. /**
  283.  * Set a tile to a solid value/color.
  284.  */
  285. static void
  286. clear_tile(struct softpipe_cached_tile *tile,
  287.            enum pipe_format format,
  288.            uint64_t clear_value)
  289. {
  290.    uint i, j;
  291.  
  292.    switch (util_format_get_blocksize(format)) {
  293.    case 1:
  294.       memset(tile->data.any, (int) clear_value, TILE_SIZE * TILE_SIZE);
  295.       break;
  296.    case 2:
  297.       if (clear_value == 0) {
  298.          memset(tile->data.any, 0, 2 * TILE_SIZE * TILE_SIZE);
  299.       }
  300.       else {
  301.          for (i = 0; i < TILE_SIZE; i++) {
  302.             for (j = 0; j < TILE_SIZE; j++) {
  303.                tile->data.depth16[i][j] = (ushort) clear_value;
  304.             }
  305.          }
  306.       }
  307.       break;
  308.    case 4:
  309.       if (clear_value == 0) {
  310.          memset(tile->data.any, 0, 4 * TILE_SIZE * TILE_SIZE);
  311.       }
  312.       else {
  313.          for (i = 0; i < TILE_SIZE; i++) {
  314.             for (j = 0; j < TILE_SIZE; j++) {
  315.                tile->data.depth32[i][j] = (uint) clear_value;
  316.             }
  317.          }
  318.       }
  319.       break;
  320.    case 8:
  321.       if (clear_value == 0) {
  322.          memset(tile->data.any, 0, 8 * TILE_SIZE * TILE_SIZE);
  323.       }
  324.       else {
  325.          for (i = 0; i < TILE_SIZE; i++) {
  326.             for (j = 0; j < TILE_SIZE; j++) {
  327.                tile->data.depth64[i][j] = clear_value;
  328.             }
  329.          }
  330.       }
  331.       break;
  332.    default:
  333.       assert(0);
  334.    }
  335. }
  336.  
  337.  
  338. /**
  339.  * Actually clear the tiles which were flagged as being in a clear state.
  340.  */
  341. static void
  342. sp_tile_cache_flush_clear(struct softpipe_tile_cache *tc, int layer)
  343. {
  344.    struct pipe_transfer *pt = tc->transfer[layer];
  345.    const uint w = tc->transfer[layer]->box.width;
  346.    const uint h = tc->transfer[layer]->box.height;
  347.    uint x, y;
  348.    uint numCleared = 0;
  349.  
  350.    assert(pt->resource);
  351.  
  352.    /* clear the scratch tile to the clear value */
  353.    if (tc->depth_stencil) {
  354.       clear_tile(tc->tile, pt->resource->format, tc->clear_val);
  355.    } else {
  356.       clear_tile_rgba(tc->tile, pt->resource->format, &tc->clear_color);
  357.    }
  358.  
  359.    /* push the tile to all positions marked as clear */
  360.    for (y = 0; y < h; y += TILE_SIZE) {
  361.       for (x = 0; x < w; x += TILE_SIZE) {
  362.          union tile_address addr = tile_address(x, y, layer);
  363.  
  364.          if (is_clear_flag_set(tc->clear_flags, addr, tc->clear_flags_size)) {
  365.             /* write the scratch tile to the surface */
  366.             if (tc->depth_stencil) {
  367.                pipe_put_tile_raw(pt, tc->transfer_map[layer],
  368.                                  x, y, TILE_SIZE, TILE_SIZE,
  369.                                  tc->tile->data.any, 0/*STRIDE*/);
  370.             }
  371.             else {
  372.                if (util_format_is_pure_uint(tc->surface->format)) {
  373.                   pipe_put_tile_ui_format(pt, tc->transfer_map[layer],
  374.                                           x, y, TILE_SIZE, TILE_SIZE,
  375.                                           pt->resource->format,
  376.                                           (unsigned *) tc->tile->data.colorui128);
  377.                } else if (util_format_is_pure_sint(tc->surface->format)) {
  378.                   pipe_put_tile_i_format(pt, tc->transfer_map[layer],
  379.                                          x, y, TILE_SIZE, TILE_SIZE,
  380.                                          pt->resource->format,
  381.                                          (int *) tc->tile->data.colori128);
  382.                } else {
  383.                   pipe_put_tile_rgba(pt, tc->transfer_map[layer],
  384.                                      x, y, TILE_SIZE, TILE_SIZE,
  385.                                      (float *) tc->tile->data.color);
  386.                }
  387.             }
  388.             numCleared++;
  389.          }
  390.       }
  391.    }
  392.  
  393.  
  394. #if 0
  395.    debug_printf("num cleared: %u\n", numCleared);
  396. #endif
  397. }
  398.  
  399. static void
  400. sp_flush_tile(struct softpipe_tile_cache* tc, unsigned pos)
  401. {
  402.    int layer = tc->tile_addrs[pos].bits.layer;
  403.    if (!tc->tile_addrs[pos].bits.invalid) {
  404.       if (tc->depth_stencil) {
  405.          pipe_put_tile_raw(tc->transfer[layer], tc->transfer_map[layer],
  406.                            tc->tile_addrs[pos].bits.x * TILE_SIZE,
  407.                            tc->tile_addrs[pos].bits.y * TILE_SIZE,
  408.                            TILE_SIZE, TILE_SIZE,
  409.                            tc->entries[pos]->data.depth32, 0/*STRIDE*/);
  410.       }
  411.       else {
  412.          if (util_format_is_pure_uint(tc->surface->format)) {
  413.             pipe_put_tile_ui_format(tc->transfer[layer], tc->transfer_map[layer],
  414.                                     tc->tile_addrs[pos].bits.x * TILE_SIZE,
  415.                                     tc->tile_addrs[pos].bits.y * TILE_SIZE,
  416.                                     TILE_SIZE, TILE_SIZE,
  417.                                     tc->surface->format,
  418.                                     (unsigned *) tc->entries[pos]->data.colorui128);
  419.          } else if (util_format_is_pure_sint(tc->surface->format)) {
  420.             pipe_put_tile_i_format(tc->transfer[layer], tc->transfer_map[layer],
  421.                                    tc->tile_addrs[pos].bits.x * TILE_SIZE,
  422.                                    tc->tile_addrs[pos].bits.y * TILE_SIZE,
  423.                                    TILE_SIZE, TILE_SIZE,
  424.                                    tc->surface->format,
  425.                                    (int *) tc->entries[pos]->data.colori128);
  426.          } else {
  427.             pipe_put_tile_rgba_format(tc->transfer[layer], tc->transfer_map[layer],
  428.                                       tc->tile_addrs[pos].bits.x * TILE_SIZE,
  429.                                       tc->tile_addrs[pos].bits.y * TILE_SIZE,
  430.                                       TILE_SIZE, TILE_SIZE,
  431.                                       tc->surface->format,
  432.                                       (float *) tc->entries[pos]->data.color);
  433.          }
  434.       }
  435.       tc->tile_addrs[pos].bits.invalid = 1;  /* mark as empty */
  436.    }
  437. }
  438.  
  439. /**
  440.  * Flush the tile cache: write all dirty tiles back to the transfer.
  441.  * any tiles "flagged" as cleared will be "really" cleared.
  442.  */
  443. void
  444. sp_flush_tile_cache(struct softpipe_tile_cache *tc)
  445. {
  446.    int inuse = 0, pos;
  447.    int i;
  448.    if (tc->num_maps) {
  449.       /* caching a drawing transfer */
  450.       for (pos = 0; pos < Elements(tc->entries); pos++) {
  451.          struct softpipe_cached_tile *tile = tc->entries[pos];
  452.          if (!tile)
  453.          {
  454.             assert(tc->tile_addrs[pos].bits.invalid);
  455.             continue;
  456.          }
  457.          sp_flush_tile(tc, pos);
  458.          ++inuse;
  459.       }
  460.  
  461.       if (!tc->tile)
  462.          tc->tile = sp_alloc_tile(tc);
  463.  
  464.       for (i = 0; i < tc->num_maps; i++)
  465.          sp_tile_cache_flush_clear(tc, i);
  466.       /* reset all clear flags to zero */
  467.       memset(tc->clear_flags, 0, tc->clear_flags_size);
  468.  
  469.       tc->last_tile_addr.bits.invalid = 1;
  470.    }
  471.  
  472. #if 0
  473.    debug_printf("flushed tiles in use: %d\n", inuse);
  474. #endif
  475. }
  476.  
  477. static struct softpipe_cached_tile *
  478. sp_alloc_tile(struct softpipe_tile_cache *tc)
  479. {
  480.    struct softpipe_cached_tile * tile = MALLOC_STRUCT(softpipe_cached_tile);
  481.    if (!tile)
  482.    {
  483.       /* in this case, steal an existing tile */
  484.       if (!tc->tile)
  485.       {
  486.          unsigned pos;
  487.          for (pos = 0; pos < Elements(tc->entries); ++pos) {
  488.             if (!tc->entries[pos])
  489.                continue;
  490.  
  491.             sp_flush_tile(tc, pos);
  492.             tc->tile = tc->entries[pos];
  493.             tc->entries[pos] = NULL;
  494.             break;
  495.          }
  496.  
  497.          /* this should never happen */
  498.          if (!tc->tile)
  499.             abort();
  500.       }
  501.  
  502.       tile = tc->tile;
  503.       tc->tile = NULL;
  504.  
  505.       tc->last_tile_addr.bits.invalid = 1;
  506.    }
  507.    return tile;
  508. }
  509.  
  510. /**
  511.  * Get a tile from the cache.
  512.  * \param x, y  position of tile, in pixels
  513.  */
  514. struct softpipe_cached_tile *
  515. sp_find_cached_tile(struct softpipe_tile_cache *tc,
  516.                     union tile_address addr )
  517. {
  518.    struct pipe_transfer *pt;
  519.    /* cache pos/entry: */
  520.    const int pos = CACHE_POS(addr.bits.x,
  521.                              addr.bits.y, addr.bits.layer);
  522.    struct softpipe_cached_tile *tile = tc->entries[pos];
  523.    int layer;
  524.    if (!tile) {
  525.       tile = sp_alloc_tile(tc);
  526.       tc->entries[pos] = tile;
  527.    }
  528.  
  529.    if (addr.value != tc->tile_addrs[pos].value) {
  530.  
  531.       layer = tc->tile_addrs[pos].bits.layer;
  532.       if (tc->tile_addrs[pos].bits.invalid == 0) {
  533.          /* put dirty tile back in framebuffer */
  534.          if (tc->depth_stencil) {
  535.             pipe_put_tile_raw(tc->transfer[layer], tc->transfer_map[layer],
  536.                               tc->tile_addrs[pos].bits.x * TILE_SIZE,
  537.                               tc->tile_addrs[pos].bits.y * TILE_SIZE,
  538.                               TILE_SIZE, TILE_SIZE,
  539.                               tile->data.depth32, 0/*STRIDE*/);
  540.          }
  541.          else {
  542.             if (util_format_is_pure_uint(tc->surface->format)) {
  543.                pipe_put_tile_ui_format(tc->transfer[layer], tc->transfer_map[layer],
  544.                                       tc->tile_addrs[pos].bits.x * TILE_SIZE,
  545.                                       tc->tile_addrs[pos].bits.y * TILE_SIZE,
  546.                                       TILE_SIZE, TILE_SIZE,
  547.                                       tc->surface->format,
  548.                                       (unsigned *) tile->data.colorui128);
  549.             } else if (util_format_is_pure_sint(tc->surface->format)) {
  550.                pipe_put_tile_i_format(tc->transfer[layer], tc->transfer_map[layer],
  551.                                       tc->tile_addrs[pos].bits.x * TILE_SIZE,
  552.                                       tc->tile_addrs[pos].bits.y * TILE_SIZE,
  553.                                       TILE_SIZE, TILE_SIZE,
  554.                                       tc->surface->format,
  555.                                       (int *) tile->data.colori128);
  556.             } else {
  557.                pipe_put_tile_rgba_format(tc->transfer[layer], tc->transfer_map[layer],
  558.                                          tc->tile_addrs[pos].bits.x * TILE_SIZE,
  559.                                          tc->tile_addrs[pos].bits.y * TILE_SIZE,
  560.                                          TILE_SIZE, TILE_SIZE,
  561.                                          tc->surface->format,
  562.                                          (float *) tile->data.color);
  563.             }
  564.          }
  565.       }
  566.  
  567.       tc->tile_addrs[pos] = addr;
  568.  
  569.       layer = tc->tile_addrs[pos].bits.layer;
  570.       pt = tc->transfer[layer];
  571.       assert(pt->resource);
  572.  
  573.       if (is_clear_flag_set(tc->clear_flags, addr, tc->clear_flags_size)) {
  574.          /* don't get tile from framebuffer, just clear it */
  575.          if (tc->depth_stencil) {
  576.             clear_tile(tile, pt->resource->format, tc->clear_val);
  577.          }
  578.          else {
  579.             clear_tile_rgba(tile, pt->resource->format, &tc->clear_color);
  580.          }
  581.          clear_clear_flag(tc->clear_flags, addr, tc->clear_flags_size);
  582.       }
  583.       else {
  584.          /* get new tile data from transfer */
  585.          if (tc->depth_stencil) {
  586.             pipe_get_tile_raw(tc->transfer[layer], tc->transfer_map[layer],
  587.                               tc->tile_addrs[pos].bits.x * TILE_SIZE,
  588.                               tc->tile_addrs[pos].bits.y * TILE_SIZE,
  589.                               TILE_SIZE, TILE_SIZE,
  590.                               tile->data.depth32, 0/*STRIDE*/);
  591.          }
  592.          else {
  593.             if (util_format_is_pure_uint(tc->surface->format)) {
  594.                pipe_get_tile_ui_format(tc->transfer[layer], tc->transfer_map[layer],
  595.                                          tc->tile_addrs[pos].bits.x * TILE_SIZE,
  596.                                          tc->tile_addrs[pos].bits.y * TILE_SIZE,
  597.                                          TILE_SIZE, TILE_SIZE,
  598.                                          tc->surface->format,
  599.                                          (unsigned *) tile->data.colorui128);
  600.             } else if (util_format_is_pure_sint(tc->surface->format)) {
  601.                pipe_get_tile_i_format(tc->transfer[layer], tc->transfer_map[layer],
  602.                                          tc->tile_addrs[pos].bits.x * TILE_SIZE,
  603.                                          tc->tile_addrs[pos].bits.y * TILE_SIZE,
  604.                                          TILE_SIZE, TILE_SIZE,
  605.                                          tc->surface->format,
  606.                                          (int *) tile->data.colori128);
  607.             } else {
  608.                pipe_get_tile_rgba_format(tc->transfer[layer], tc->transfer_map[layer],
  609.                                          tc->tile_addrs[pos].bits.x * TILE_SIZE,
  610.                                          tc->tile_addrs[pos].bits.y * TILE_SIZE,
  611.                                          TILE_SIZE, TILE_SIZE,
  612.                                          tc->surface->format,
  613.                                          (float *) tile->data.color);
  614.             }
  615.          }
  616.       }
  617.    }
  618.  
  619.    tc->last_tile = tile;
  620.    tc->last_tile_addr = addr;
  621.    return tile;
  622. }
  623.  
  624.  
  625.  
  626.  
  627.  
  628. /**
  629.  * When a whole surface is being cleared to a value we can avoid
  630.  * fetching tiles above.
  631.  * Save the color and set a 'clearflag' for each tile of the screen.
  632.  */
  633. void
  634. sp_tile_cache_clear(struct softpipe_tile_cache *tc,
  635.                     const union pipe_color_union *color,
  636.                     uint64_t clearValue)
  637. {
  638.    uint pos;
  639.  
  640.    tc->clear_color = *color;
  641.  
  642.    tc->clear_val = clearValue;
  643.  
  644.    /* set flags to indicate all the tiles are cleared */
  645.    memset(tc->clear_flags, 255, tc->clear_flags_size);
  646.  
  647.    for (pos = 0; pos < Elements(tc->tile_addrs); pos++) {
  648.       tc->tile_addrs[pos].bits.invalid = 1;
  649.    }
  650.    tc->last_tile_addr.bits.invalid = 1;
  651. }
  652.