Home | History | Annotate | Download | only in llvmpipe
      1 /**************************************************************************
      2  *
      3  * Copyright 2009 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 #include <limits.h>
     29 #include "util/u_memory.h"
     30 #include "util/u_math.h"
     31 #include "util/u_rect.h"
     32 #include "util/u_surface.h"
     33 #include "util/u_pack_color.h"
     34 
     35 #include "lp_scene_queue.h"
     36 #include "lp_debug.h"
     37 #include "lp_fence.h"
     38 #include "lp_perf.h"
     39 #include "lp_query.h"
     40 #include "lp_rast.h"
     41 #include "lp_rast_priv.h"
     42 #include "lp_tile_soa.h"
     43 #include "gallivm/lp_bld_debug.h"
     44 #include "lp_scene.h"
     45 #include "lp_tex_sample.h"
     46 
     47 
     48 #ifdef DEBUG
     49 int jit_line = 0;
     50 const struct lp_rast_state *jit_state = NULL;
     51 const struct lp_rasterizer_task *jit_task = NULL;
     52 #endif
     53 
     54 
     55 /**
     56  * Begin rasterizing a scene.
     57  * Called once per scene by one thread.
     58  */
     59 static void
     60 lp_rast_begin( struct lp_rasterizer *rast,
     61                struct lp_scene *scene )
     62 {
     63 
     64    rast->curr_scene = scene;
     65 
     66    LP_DBG(DEBUG_RAST, "%s\n", __FUNCTION__);
     67 
     68    lp_scene_begin_rasterization( scene );
     69    lp_scene_bin_iter_begin( scene );
     70 }
     71 
     72 
     73 static void
     74 lp_rast_end( struct lp_rasterizer *rast )
     75 {
     76    lp_scene_end_rasterization( rast->curr_scene );
     77 
     78    rast->curr_scene = NULL;
     79 
     80 #ifdef DEBUG
     81    if (0)
     82       debug_printf("Post render scene: tile unswizzle: %u tile swizzle: %u\n",
     83                    lp_tile_unswizzle_count, lp_tile_swizzle_count);
     84 #endif
     85 }
     86 
     87 
     88 /**
     89  * Begining rasterization of a tile.
     90  * \param x  window X position of the tile, in pixels
     91  * \param y  window Y position of the tile, in pixels
     92  */
     93 static void
     94 lp_rast_tile_begin(struct lp_rasterizer_task *task,
     95                    const struct cmd_bin *bin)
     96 {
     97    const struct lp_scene *scene = task->scene;
     98    enum lp_texture_usage usage;
     99 
    100    LP_DBG(DEBUG_RAST, "%s %d,%d\n", __FUNCTION__, bin->x, bin->y);
    101 
    102    task->bin = bin;
    103    task->x = bin->x * TILE_SIZE;
    104    task->y = bin->y * TILE_SIZE;
    105 
    106    /* reset pointers to color tile(s) */
    107    memset(task->color_tiles, 0, sizeof(task->color_tiles));
    108 
    109    /* get pointer to depth/stencil tile */
    110    {
    111       struct pipe_surface *zsbuf = task->scene->fb.zsbuf;
    112       if (zsbuf) {
    113          struct llvmpipe_resource *lpt = llvmpipe_resource(zsbuf->texture);
    114 
    115          if (scene->has_depthstencil_clear)
    116             usage = LP_TEX_USAGE_WRITE_ALL;
    117          else
    118             usage = LP_TEX_USAGE_READ_WRITE;
    119 
    120          /* "prime" the tile: convert data from linear to tiled if necessary
    121           * and update the tile's layout info.
    122           */
    123          (void) llvmpipe_get_texture_tile(lpt,
    124                                           zsbuf->u.tex.first_layer,
    125                                           zsbuf->u.tex.level,
    126                                           usage,
    127                                           task->x,
    128                                           task->y);
    129          /* Get actual pointer to the tile data.  Note that depth/stencil
    130           * data is tiled differently than color data.
    131           */
    132          task->depth_tile = lp_rast_get_depth_block_pointer(task,
    133                                                             task->x,
    134                                                             task->y);
    135 
    136          assert(task->depth_tile);
    137       }
    138       else {
    139          task->depth_tile = NULL;
    140       }
    141    }
    142 }
    143 
    144 
    145 /**
    146  * Clear the rasterizer's current color tile.
    147  * This is a bin command called during bin processing.
    148  */
    149 static void
    150 lp_rast_clear_color(struct lp_rasterizer_task *task,
    151                     const union lp_rast_cmd_arg arg)
    152 {
    153    const struct lp_scene *scene = task->scene;
    154    const uint8_t *clear_color = arg.clear_color;
    155 
    156    unsigned i;
    157 
    158    LP_DBG(DEBUG_RAST, "%s 0x%x,0x%x,0x%x,0x%x\n", __FUNCTION__,
    159               clear_color[0],
    160               clear_color[1],
    161               clear_color[2],
    162               clear_color[3]);
    163 
    164    if (clear_color[0] == clear_color[1] &&
    165        clear_color[1] == clear_color[2] &&
    166        clear_color[2] == clear_color[3]) {
    167       /* clear to grayscale value {x, x, x, x} */
    168       for (i = 0; i < scene->fb.nr_cbufs; i++) {
    169          uint8_t *ptr =
    170             lp_rast_get_color_tile_pointer(task, i, LP_TEX_USAGE_WRITE_ALL);
    171 	 memset(ptr, clear_color[0], TILE_SIZE * TILE_SIZE * 4);
    172       }
    173    }
    174    else {
    175       /* Non-gray color.
    176        * Note: if the swizzled tile layout changes (see TILE_PIXEL) this code
    177        * will need to change.  It'll be pretty obvious when clearing no longer
    178        * works.
    179        */
    180       const unsigned chunk = TILE_SIZE / 4;
    181       for (i = 0; i < scene->fb.nr_cbufs; i++) {
    182          uint8_t *c =
    183             lp_rast_get_color_tile_pointer(task, i, LP_TEX_USAGE_WRITE_ALL);
    184          unsigned j;
    185 
    186          for (j = 0; j < 4 * TILE_SIZE; j++) {
    187             memset(c, clear_color[0], chunk);
    188             c += chunk;
    189             memset(c, clear_color[1], chunk);
    190             c += chunk;
    191             memset(c, clear_color[2], chunk);
    192             c += chunk;
    193             memset(c, clear_color[3], chunk);
    194             c += chunk;
    195          }
    196       }
    197    }
    198 
    199    LP_COUNT(nr_color_tile_clear);
    200 }
    201 
    202 
    203 
    204 
    205 
    206 
    207 /**
    208  * Clear the rasterizer's current z/stencil tile.
    209  * This is a bin command called during bin processing.
    210  */
    211 static void
    212 lp_rast_clear_zstencil(struct lp_rasterizer_task *task,
    213                        const union lp_rast_cmd_arg arg)
    214 {
    215    const struct lp_scene *scene = task->scene;
    216    uint32_t clear_value = arg.clear_zstencil.value;
    217    uint32_t clear_mask = arg.clear_zstencil.mask;
    218    const unsigned height = TILE_SIZE / TILE_VECTOR_HEIGHT;
    219    const unsigned width = TILE_SIZE * TILE_VECTOR_HEIGHT;
    220    const unsigned block_size = scene->zsbuf.blocksize;
    221    const unsigned dst_stride = scene->zsbuf.stride * TILE_VECTOR_HEIGHT;
    222    uint8_t *dst;
    223    unsigned i, j;
    224 
    225    LP_DBG(DEBUG_RAST, "%s: value=0x%08x, mask=0x%08x\n",
    226            __FUNCTION__, clear_value, clear_mask);
    227 
    228    /*
    229     * Clear the area of the swizzled depth/depth buffer matching this tile, in
    230     * stripes of TILE_VECTOR_HEIGHT x TILE_SIZE at a time.
    231     *
    232     * The swizzled depth format is such that the depths for
    233     * TILE_VECTOR_HEIGHT x TILE_VECTOR_WIDTH pixels have consecutive offsets.
    234     */
    235 
    236    dst = task->depth_tile;
    237 
    238    clear_value &= clear_mask;
    239 
    240    switch (block_size) {
    241    case 1:
    242       assert(clear_mask == 0xff);
    243       memset(dst, (uint8_t) clear_value, height * width);
    244       break;
    245    case 2:
    246       if (clear_mask == 0xffff) {
    247          for (i = 0; i < height; i++) {
    248             uint16_t *row = (uint16_t *)dst;
    249             for (j = 0; j < width; j++)
    250                *row++ = (uint16_t) clear_value;
    251             dst += dst_stride;
    252          }
    253       }
    254       else {
    255          for (i = 0; i < height; i++) {
    256             uint16_t *row = (uint16_t *)dst;
    257             for (j = 0; j < width; j++) {
    258                uint16_t tmp = ~clear_mask & *row;
    259                *row++ = clear_value | tmp;
    260             }
    261             dst += dst_stride;
    262          }
    263       }
    264       break;
    265    case 4:
    266       if (clear_mask == 0xffffffff) {
    267          for (i = 0; i < height; i++) {
    268             uint32_t *row = (uint32_t *)dst;
    269             for (j = 0; j < width; j++)
    270                *row++ = clear_value;
    271             dst += dst_stride;
    272          }
    273       }
    274       else {
    275          for (i = 0; i < height; i++) {
    276             uint32_t *row = (uint32_t *)dst;
    277             for (j = 0; j < width; j++) {
    278                uint32_t tmp = ~clear_mask & *row;
    279                *row++ = clear_value | tmp;
    280             }
    281             dst += dst_stride;
    282          }
    283       }
    284       break;
    285    default:
    286       assert(0);
    287       break;
    288    }
    289 }
    290 
    291 
    292 
    293 /**
    294  * Convert the color tile from tiled to linear layout.
    295  * This is generally only done when we're flushing the scene just prior to
    296  * SwapBuffers.  If we didn't do this here, we'd have to convert the entire
    297  * tiled color buffer to linear layout in the llvmpipe_texture_unmap()
    298  * function.  It's better to do it here to take advantage of
    299  * threading/parallelism.
    300  * This is a bin command which is stored in all bins.
    301  */
    302 static void
    303 lp_rast_store_linear_color( struct lp_rasterizer_task *task )
    304 {
    305    const struct lp_scene *scene = task->scene;
    306    unsigned buf;
    307 
    308    for (buf = 0; buf < scene->fb.nr_cbufs; buf++) {
    309       struct pipe_surface *cbuf = scene->fb.cbufs[buf];
    310       const unsigned layer = cbuf->u.tex.first_layer;
    311       const unsigned level = cbuf->u.tex.level;
    312       struct llvmpipe_resource *lpt = llvmpipe_resource(cbuf->texture);
    313 
    314       if (!task->color_tiles[buf])
    315          continue;
    316 
    317       llvmpipe_unswizzle_cbuf_tile(lpt,
    318                                    layer,
    319                                    level,
    320                                    task->x, task->y,
    321                                    task->color_tiles[buf]);
    322    }
    323 }
    324 
    325 
    326 
    327 /**
    328  * Run the shader on all blocks in a tile.  This is used when a tile is
    329  * completely contained inside a triangle.
    330  * This is a bin command called during bin processing.
    331  */
    332 static void
    333 lp_rast_shade_tile(struct lp_rasterizer_task *task,
    334                    const union lp_rast_cmd_arg arg)
    335 {
    336    const struct lp_scene *scene = task->scene;
    337    const struct lp_rast_shader_inputs *inputs = arg.shade_tile;
    338    const struct lp_rast_state *state;
    339    struct lp_fragment_shader_variant *variant;
    340    const unsigned tile_x = task->x, tile_y = task->y;
    341    unsigned x, y;
    342 
    343    if (inputs->disable) {
    344       /* This command was partially binned and has been disabled */
    345       return;
    346    }
    347 
    348    LP_DBG(DEBUG_RAST, "%s\n", __FUNCTION__);
    349 
    350    state = task->state;
    351    assert(state);
    352    if (!state) {
    353       return;
    354    }
    355    variant = state->variant;
    356 
    357    /* render the whole 64x64 tile in 4x4 chunks */
    358    for (y = 0; y < TILE_SIZE; y += 4){
    359       for (x = 0; x < TILE_SIZE; x += 4) {
    360          uint8_t *color[PIPE_MAX_COLOR_BUFS];
    361          uint32_t *depth;
    362          unsigned i;
    363 
    364          /* color buffer */
    365          for (i = 0; i < scene->fb.nr_cbufs; i++)
    366             color[i] = lp_rast_get_color_block_pointer(task, i,
    367                                                        tile_x + x, tile_y + y);
    368 
    369          /* depth buffer */
    370          depth = lp_rast_get_depth_block_pointer(task, tile_x + x, tile_y + y);
    371 
    372          /* run shader on 4x4 block */
    373          BEGIN_JIT_CALL(state, task);
    374          variant->jit_function[RAST_WHOLE]( &state->jit_context,
    375                                             tile_x + x, tile_y + y,
    376                                             inputs->frontfacing,
    377                                             GET_A0(inputs),
    378                                             GET_DADX(inputs),
    379                                             GET_DADY(inputs),
    380                                             color,
    381                                             depth,
    382                                             0xffff,
    383                                             &task->vis_counter);
    384          END_JIT_CALL();
    385       }
    386    }
    387 }
    388 
    389 
    390 /**
    391  * Run the shader on all blocks in a tile.  This is used when a tile is
    392  * completely contained inside a triangle, and the shader is opaque.
    393  * This is a bin command called during bin processing.
    394  */
    395 static void
    396 lp_rast_shade_tile_opaque(struct lp_rasterizer_task *task,
    397                           const union lp_rast_cmd_arg arg)
    398 {
    399    const struct lp_scene *scene = task->scene;
    400    unsigned i;
    401 
    402    LP_DBG(DEBUG_RAST, "%s\n", __FUNCTION__);
    403 
    404    assert(task->state);
    405    if (!task->state) {
    406       return;
    407    }
    408 
    409    /* this will prevent converting the layout from tiled to linear */
    410    for (i = 0; i < scene->fb.nr_cbufs; i++) {
    411       (void)lp_rast_get_color_tile_pointer(task, i, LP_TEX_USAGE_WRITE_ALL);
    412    }
    413 
    414    lp_rast_shade_tile(task, arg);
    415 }
    416 
    417 
    418 /**
    419  * Compute shading for a 4x4 block of pixels inside a triangle.
    420  * This is a bin command called during bin processing.
    421  * \param x  X position of quad in window coords
    422  * \param y  Y position of quad in window coords
    423  */
    424 void
    425 lp_rast_shade_quads_mask(struct lp_rasterizer_task *task,
    426                          const struct lp_rast_shader_inputs *inputs,
    427                          unsigned x, unsigned y,
    428                          unsigned mask)
    429 {
    430    const struct lp_rast_state *state = task->state;
    431    struct lp_fragment_shader_variant *variant = state->variant;
    432    const struct lp_scene *scene = task->scene;
    433    uint8_t *color[PIPE_MAX_COLOR_BUFS];
    434    void *depth;
    435    unsigned i;
    436 
    437    assert(state);
    438 
    439    /* Sanity checks */
    440    assert(x < scene->tiles_x * TILE_SIZE);
    441    assert(y < scene->tiles_y * TILE_SIZE);
    442    assert(x % TILE_VECTOR_WIDTH == 0);
    443    assert(y % TILE_VECTOR_HEIGHT == 0);
    444 
    445    assert((x % 4) == 0);
    446    assert((y % 4) == 0);
    447 
    448    /* color buffer */
    449    for (i = 0; i < scene->fb.nr_cbufs; i++) {
    450       color[i] = lp_rast_get_color_block_pointer(task, i, x, y);
    451       assert(lp_check_alignment(color[i], 16));
    452    }
    453 
    454    /* depth buffer */
    455    depth = lp_rast_get_depth_block_pointer(task, x, y);
    456 
    457 
    458    assert(lp_check_alignment(state->jit_context.blend_color, 16));
    459 
    460    /* run shader on 4x4 block */
    461    BEGIN_JIT_CALL(state, task);
    462    variant->jit_function[RAST_EDGE_TEST](&state->jit_context,
    463                                          x, y,
    464                                          inputs->frontfacing,
    465                                          GET_A0(inputs),
    466                                          GET_DADX(inputs),
    467                                          GET_DADY(inputs),
    468                                          color,
    469                                          depth,
    470                                          mask,
    471                                          &task->vis_counter);
    472    END_JIT_CALL();
    473 }
    474 
    475 
    476 
    477 /**
    478  * Begin a new occlusion query.
    479  * This is a bin command put in all bins.
    480  * Called per thread.
    481  */
    482 static void
    483 lp_rast_begin_query(struct lp_rasterizer_task *task,
    484                     const union lp_rast_cmd_arg arg)
    485 {
    486    struct llvmpipe_query *pq = arg.query_obj;
    487 
    488    assert(task->query == NULL);
    489    task->vis_counter = 0;
    490    task->query = pq;
    491 }
    492 
    493 
    494 /**
    495  * End the current occlusion query.
    496  * This is a bin command put in all bins.
    497  * Called per thread.
    498  */
    499 static void
    500 lp_rast_end_query(struct lp_rasterizer_task *task,
    501                   const union lp_rast_cmd_arg arg)
    502 {
    503    assert(task->query);
    504    if (task->query) {
    505       task->query->count[task->thread_index] += task->vis_counter;
    506       task->query = NULL;
    507    }
    508 }
    509 
    510 
    511 void
    512 lp_rast_set_state(struct lp_rasterizer_task *task,
    513                   const union lp_rast_cmd_arg arg)
    514 {
    515    task->state = arg.state;
    516 }
    517 
    518 
    519 
    520 /**
    521  * Set top row and left column of the tile's pixels to white.  For debugging.
    522  */
    523 static void
    524 outline_tile(uint8_t *tile)
    525 {
    526    const uint8_t val = 0xff;
    527    unsigned i;
    528 
    529    for (i = 0; i < TILE_SIZE; i++) {
    530       TILE_PIXEL(tile, i, 0, 0) = val;
    531       TILE_PIXEL(tile, i, 0, 1) = val;
    532       TILE_PIXEL(tile, i, 0, 2) = val;
    533       TILE_PIXEL(tile, i, 0, 3) = val;
    534 
    535       TILE_PIXEL(tile, 0, i, 0) = val;
    536       TILE_PIXEL(tile, 0, i, 1) = val;
    537       TILE_PIXEL(tile, 0, i, 2) = val;
    538       TILE_PIXEL(tile, 0, i, 3) = val;
    539    }
    540 }
    541 
    542 
    543 /**
    544  * Draw grid of gray lines at 16-pixel intervals across the tile to
    545  * show the sub-tile boundaries.  For debugging.
    546  */
    547 static void
    548 outline_subtiles(uint8_t *tile)
    549 {
    550    const uint8_t val = 0x80;
    551    const unsigned step = 16;
    552    unsigned i, j;
    553 
    554    for (i = 0; i < TILE_SIZE; i += step) {
    555       for (j = 0; j < TILE_SIZE; j++) {
    556          TILE_PIXEL(tile, i, j, 0) = val;
    557          TILE_PIXEL(tile, i, j, 1) = val;
    558          TILE_PIXEL(tile, i, j, 2) = val;
    559          TILE_PIXEL(tile, i, j, 3) = val;
    560 
    561          TILE_PIXEL(tile, j, i, 0) = val;
    562          TILE_PIXEL(tile, j, i, 1) = val;
    563          TILE_PIXEL(tile, j, i, 2) = val;
    564          TILE_PIXEL(tile, j, i, 3) = val;
    565       }
    566    }
    567 
    568    outline_tile(tile);
    569 }
    570 
    571 
    572 
    573 /**
    574  * Called when we're done writing to a color tile.
    575  */
    576 static void
    577 lp_rast_tile_end(struct lp_rasterizer_task *task)
    578 {
    579 #ifdef DEBUG
    580    if (LP_DEBUG & (DEBUG_SHOW_SUBTILES | DEBUG_SHOW_TILES)) {
    581       const struct lp_scene *scene = task->scene;
    582       unsigned buf;
    583 
    584       for (buf = 0; buf < scene->fb.nr_cbufs; buf++) {
    585          uint8_t *color = lp_rast_get_color_block_pointer(task, buf,
    586                                                           task->x, task->y);
    587 
    588          if (LP_DEBUG & DEBUG_SHOW_SUBTILES)
    589             outline_subtiles(color);
    590          else if (LP_DEBUG & DEBUG_SHOW_TILES)
    591             outline_tile(color);
    592       }
    593    }
    594 #else
    595    (void) outline_subtiles;
    596 #endif
    597 
    598    lp_rast_store_linear_color(task);
    599 
    600    if (task->query) {
    601       union lp_rast_cmd_arg dummy = {0};
    602       lp_rast_end_query(task, dummy);
    603    }
    604 
    605    /* debug */
    606    memset(task->color_tiles, 0, sizeof(task->color_tiles));
    607    task->depth_tile = NULL;
    608 
    609    task->bin = NULL;
    610 }
    611 
    612 static lp_rast_cmd_func dispatch[LP_RAST_OP_MAX] =
    613 {
    614    lp_rast_clear_color,
    615    lp_rast_clear_zstencil,
    616    lp_rast_triangle_1,
    617    lp_rast_triangle_2,
    618    lp_rast_triangle_3,
    619    lp_rast_triangle_4,
    620    lp_rast_triangle_5,
    621    lp_rast_triangle_6,
    622    lp_rast_triangle_7,
    623    lp_rast_triangle_8,
    624    lp_rast_triangle_3_4,
    625    lp_rast_triangle_3_16,
    626    lp_rast_triangle_4_16,
    627    lp_rast_shade_tile,
    628    lp_rast_shade_tile_opaque,
    629    lp_rast_begin_query,
    630    lp_rast_end_query,
    631    lp_rast_set_state,
    632 };
    633 
    634 
    635 static void
    636 do_rasterize_bin(struct lp_rasterizer_task *task,
    637                  const struct cmd_bin *bin)
    638 {
    639    const struct cmd_block *block;
    640    unsigned k;
    641 
    642    if (0)
    643       lp_debug_bin(bin);
    644 
    645    for (block = bin->head; block; block = block->next) {
    646       for (k = 0; k < block->count; k++) {
    647          dispatch[block->cmd[k]]( task, block->arg[k] );
    648       }
    649    }
    650 }
    651 
    652 
    653 
    654 /**
    655  * Rasterize commands for a single bin.
    656  * \param x, y  position of the bin's tile in the framebuffer
    657  * Must be called between lp_rast_begin() and lp_rast_end().
    658  * Called per thread.
    659  */
    660 static void
    661 rasterize_bin(struct lp_rasterizer_task *task,
    662               const struct cmd_bin *bin )
    663 {
    664    lp_rast_tile_begin( task, bin );
    665 
    666    do_rasterize_bin(task, bin);
    667 
    668    lp_rast_tile_end(task);
    669 
    670 
    671    /* Debug/Perf flags:
    672     */
    673    if (bin->head->count == 1) {
    674       if (bin->head->cmd[0] == LP_RAST_OP_SHADE_TILE_OPAQUE)
    675          LP_COUNT(nr_pure_shade_opaque_64);
    676       else if (bin->head->cmd[0] == LP_RAST_OP_SHADE_TILE)
    677          LP_COUNT(nr_pure_shade_64);
    678    }
    679 }
    680 
    681 
    682 /* An empty bin is one that just loads the contents of the tile and
    683  * stores them again unchanged.  This typically happens when bins have
    684  * been flushed for some reason in the middle of a frame, or when
    685  * incremental updates are being made to a render target.
    686  *
    687  * Try to avoid doing pointless work in this case.
    688  */
    689 static boolean
    690 is_empty_bin( const struct cmd_bin *bin )
    691 {
    692    return bin->head == NULL;
    693 }
    694 
    695 
    696 /**
    697  * Rasterize/execute all bins within a scene.
    698  * Called per thread.
    699  */
    700 static void
    701 rasterize_scene(struct lp_rasterizer_task *task,
    702                 struct lp_scene *scene)
    703 {
    704    task->scene = scene;
    705 
    706    if (!task->rast->no_rast) {
    707       /* loop over scene bins, rasterize each */
    708 #if 0
    709       {
    710          unsigned i, j;
    711          for (i = 0; i < scene->tiles_x; i++) {
    712             for (j = 0; j < scene->tiles_y; j++) {
    713                struct cmd_bin *bin = lp_scene_get_bin(scene, i, j);
    714                rasterize_bin(task, bin, i, j);
    715             }
    716          }
    717       }
    718 #else
    719       {
    720          struct cmd_bin *bin;
    721 
    722          assert(scene);
    723          while ((bin = lp_scene_bin_iter_next(scene))) {
    724             if (!is_empty_bin( bin ))
    725                rasterize_bin(task, bin);
    726          }
    727       }
    728 #endif
    729    }
    730 
    731 
    732    if (scene->fence) {
    733       lp_fence_signal(scene->fence);
    734    }
    735 
    736    task->scene = NULL;
    737 }
    738 
    739 
    740 /**
    741  * Called by setup module when it has something for us to render.
    742  */
    743 void
    744 lp_rast_queue_scene( struct lp_rasterizer *rast,
    745                      struct lp_scene *scene)
    746 {
    747    LP_DBG(DEBUG_SETUP, "%s\n", __FUNCTION__);
    748 
    749    if (rast->num_threads == 0) {
    750       /* no threading */
    751 
    752       lp_rast_begin( rast, scene );
    753 
    754       rasterize_scene( &rast->tasks[0], scene );
    755 
    756       lp_rast_end( rast );
    757 
    758       rast->curr_scene = NULL;
    759    }
    760    else {
    761       /* threaded rendering! */
    762       unsigned i;
    763 
    764       lp_scene_enqueue( rast->full_scenes, scene );
    765 
    766       /* signal the threads that there's work to do */
    767       for (i = 0; i < rast->num_threads; i++) {
    768          pipe_semaphore_signal(&rast->tasks[i].work_ready);
    769       }
    770    }
    771 
    772    LP_DBG(DEBUG_SETUP, "%s done \n", __FUNCTION__);
    773 }
    774 
    775 
    776 void
    777 lp_rast_finish( struct lp_rasterizer *rast )
    778 {
    779    if (rast->num_threads == 0) {
    780       /* nothing to do */
    781    }
    782    else {
    783       int i;
    784 
    785       /* wait for work to complete */
    786       for (i = 0; i < rast->num_threads; i++) {
    787          pipe_semaphore_wait(&rast->tasks[i].work_done);
    788       }
    789    }
    790 }
    791 
    792 
    793 /**
    794  * This is the thread's main entrypoint.
    795  * It's a simple loop:
    796  *   1. wait for work
    797  *   2. do work
    798  *   3. signal that we're done
    799  */
    800 static PIPE_THREAD_ROUTINE( thread_function, init_data )
    801 {
    802    struct lp_rasterizer_task *task = (struct lp_rasterizer_task *) init_data;
    803    struct lp_rasterizer *rast = task->rast;
    804    boolean debug = false;
    805 
    806    while (1) {
    807       /* wait for work */
    808       if (debug)
    809          debug_printf("thread %d waiting for work\n", task->thread_index);
    810       pipe_semaphore_wait(&task->work_ready);
    811 
    812       if (rast->exit_flag)
    813          break;
    814 
    815       if (task->thread_index == 0) {
    816          /* thread[0]:
    817           *  - get next scene to rasterize
    818           *  - map the framebuffer surfaces
    819           */
    820          lp_rast_begin( rast,
    821                         lp_scene_dequeue( rast->full_scenes, TRUE ) );
    822       }
    823 
    824       /* Wait for all threads to get here so that threads[1+] don't
    825        * get a null rast->curr_scene pointer.
    826        */
    827       pipe_barrier_wait( &rast->barrier );
    828 
    829       /* do work */
    830       if (debug)
    831          debug_printf("thread %d doing work\n", task->thread_index);
    832 
    833       rasterize_scene(task,
    834                       rast->curr_scene);
    835 
    836       /* wait for all threads to finish with this scene */
    837       pipe_barrier_wait( &rast->barrier );
    838 
    839       /* XXX: shouldn't be necessary:
    840        */
    841       if (task->thread_index == 0) {
    842          lp_rast_end( rast );
    843       }
    844 
    845       /* signal done with work */
    846       if (debug)
    847          debug_printf("thread %d done working\n", task->thread_index);
    848 
    849       pipe_semaphore_signal(&task->work_done);
    850    }
    851 
    852    return NULL;
    853 }
    854 
    855 
    856 /**
    857  * Initialize semaphores and spawn the threads.
    858  */
    859 static void
    860 create_rast_threads(struct lp_rasterizer *rast)
    861 {
    862    unsigned i;
    863 
    864    /* NOTE: if num_threads is zero, we won't use any threads */
    865    for (i = 0; i < rast->num_threads; i++) {
    866       pipe_semaphore_init(&rast->tasks[i].work_ready, 0);
    867       pipe_semaphore_init(&rast->tasks[i].work_done, 0);
    868       rast->threads[i] = pipe_thread_create(thread_function,
    869                                             (void *) &rast->tasks[i]);
    870    }
    871 }
    872 
    873 
    874 
    875 /**
    876  * Create new lp_rasterizer.  If num_threads is zero, don't create any
    877  * new threads, do rendering synchronously.
    878  * \param num_threads  number of rasterizer threads to create
    879  */
    880 struct lp_rasterizer *
    881 lp_rast_create( unsigned num_threads )
    882 {
    883    struct lp_rasterizer *rast;
    884    unsigned i;
    885 
    886    rast = CALLOC_STRUCT(lp_rasterizer);
    887    if (!rast) {
    888       goto no_rast;
    889    }
    890 
    891    rast->full_scenes = lp_scene_queue_create();
    892    if (!rast->full_scenes) {
    893       goto no_full_scenes;
    894    }
    895 
    896    for (i = 0; i < Elements(rast->tasks); i++) {
    897       struct lp_rasterizer_task *task = &rast->tasks[i];
    898       task->rast = rast;
    899       task->thread_index = i;
    900    }
    901 
    902    rast->num_threads = num_threads;
    903 
    904    rast->no_rast = debug_get_bool_option("LP_NO_RAST", FALSE);
    905 
    906    create_rast_threads(rast);
    907 
    908    /* for synchronizing rasterization threads */
    909    pipe_barrier_init( &rast->barrier, rast->num_threads );
    910 
    911    memset(lp_swizzled_cbuf, 0, sizeof lp_swizzled_cbuf);
    912 
    913    memset(lp_dummy_tile, 0, sizeof lp_dummy_tile);
    914 
    915    return rast;
    916 
    917 no_full_scenes:
    918    FREE(rast);
    919 no_rast:
    920    return NULL;
    921 }
    922 
    923 
    924 /* Shutdown:
    925  */
    926 void lp_rast_destroy( struct lp_rasterizer *rast )
    927 {
    928    unsigned i;
    929 
    930    /* Set exit_flag and signal each thread's work_ready semaphore.
    931     * Each thread will be woken up, notice that the exit_flag is set and
    932     * break out of its main loop.  The thread will then exit.
    933     */
    934    rast->exit_flag = TRUE;
    935    for (i = 0; i < rast->num_threads; i++) {
    936       pipe_semaphore_signal(&rast->tasks[i].work_ready);
    937    }
    938 
    939    /* Wait for threads to terminate before cleaning up per-thread data */
    940    for (i = 0; i < rast->num_threads; i++) {
    941       pipe_thread_wait(rast->threads[i]);
    942    }
    943 
    944    /* Clean up per-thread data */
    945    for (i = 0; i < rast->num_threads; i++) {
    946       pipe_semaphore_destroy(&rast->tasks[i].work_ready);
    947       pipe_semaphore_destroy(&rast->tasks[i].work_done);
    948    }
    949 
    950    /* for synchronizing rasterization threads */
    951    pipe_barrier_destroy( &rast->barrier );
    952 
    953    lp_scene_queue_destroy(rast->full_scenes);
    954 
    955    FREE(rast);
    956 }
    957 
    958 
    959 /** Return number of rasterization threads */
    960 unsigned
    961 lp_rast_get_num_threads( struct lp_rasterizer *rast )
    962 {
    963    return rast->num_threads;
    964 }
    965 
    966 
    967