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 
     29 /**
     30  * Binner data structures and bin-related functions.
     31  * Note: the "setup" code is concerned with building scenes while
     32  * The "rast" code is concerned with consuming/executing scenes.
     33  */
     34 
     35 #ifndef LP_SCENE_H
     36 #define LP_SCENE_H
     37 
     38 #include "os/os_thread.h"
     39 #include "lp_rast.h"
     40 #include "lp_debug.h"
     41 
     42 struct lp_scene_queue;
     43 struct lp_rast_state;
     44 
     45 /* We're limited to 2K by 2K for 32bit fixed point rasterization.
     46  * Will need a 64-bit version for larger framebuffers.
     47  */
     48 #define TILES_X (LP_MAX_WIDTH / TILE_SIZE)
     49 #define TILES_Y (LP_MAX_HEIGHT / TILE_SIZE)
     50 
     51 
     52 /* Commands per command block (ideally so sizeof(cmd_block) is a power of
     53  * two in size.)
     54  */
     55 #define CMD_BLOCK_MAX 29
     56 
     57 /* Bytes per data block.
     58  */
     59 #define DATA_BLOCK_SIZE (64 * 1024)
     60 
     61 /* Scene temporary storage is clamped to this size:
     62  */
     63 #define LP_SCENE_MAX_SIZE (9*1024*1024)
     64 
     65 /* The maximum amount of texture storage referenced by a scene is
     66  * clamped to this size:
     67  */
     68 #define LP_SCENE_MAX_RESOURCE_SIZE (64*1024*1024)
     69 
     70 
     71 /* switch to a non-pointer value for this:
     72  */
     73 typedef void (*lp_rast_cmd_func)( struct lp_rasterizer_task *,
     74                                   const union lp_rast_cmd_arg );
     75 
     76 
     77 struct cmd_block {
     78    uint8_t cmd[CMD_BLOCK_MAX];
     79    union lp_rast_cmd_arg arg[CMD_BLOCK_MAX];
     80    unsigned count;
     81    struct cmd_block *next;
     82 };
     83 
     84 
     85 struct data_block {
     86    ubyte data[DATA_BLOCK_SIZE];
     87    unsigned used;
     88    struct data_block *next;
     89 };
     90 
     91 
     92 
     93 /**
     94  * For each screen tile we have one of these bins.
     95  */
     96 struct cmd_bin {
     97    const struct lp_rast_state *last_state;       /* most recent state set in bin */
     98    struct cmd_block *head;
     99    struct cmd_block *tail;
    100 };
    101 
    102 
    103 /**
    104  * This stores bulk data which is used for all memory allocations
    105  * within a scene.
    106  *
    107  * Examples include triangle data and state data.  The commands in
    108  * the per-tile bins will point to chunks of data in this structure.
    109  *
    110  * Include the first block of data statically to ensure we can always
    111  * initiate a scene without relying on malloc succeeding.
    112  */
    113 struct data_block_list {
    114    struct data_block first;
    115    struct data_block *head;
    116 };
    117 
    118 struct resource_ref;
    119 
    120 /**
    121  * All bins and bin data are contained here.
    122  * Per-bin data goes into the 'tile' bins.
    123  * Shared data goes into the 'data' buffer.
    124  *
    125  * When there are multiple threads, will want to double-buffer between
    126  * scenes:
    127  */
    128 struct lp_scene {
    129    struct pipe_context *pipe;
    130    struct lp_fence *fence;
    131 
    132    /* The queries still active at end of scene */
    133    struct llvmpipe_query *active_queries[LP_MAX_ACTIVE_BINNED_QUERIES];
    134    unsigned num_active_queries;
    135    /* If queries were either active or there were begin/end query commands */
    136    boolean had_queries;
    137 
    138    /* Framebuffer mappings - valid only between begin_rasterization()
    139     * and end_rasterization().
    140     */
    141    struct {
    142       uint8_t *map;
    143       unsigned stride;
    144       unsigned layer_stride;
    145       unsigned format_bytes;
    146    } zsbuf, cbufs[PIPE_MAX_COLOR_BUFS];
    147 
    148    /* The amount of layers in the fb (minimum of all attachments) */
    149    unsigned fb_max_layer;
    150 
    151    /** the framebuffer to render the scene into */
    152    struct pipe_framebuffer_state fb;
    153 
    154    /** list of resources referenced by the scene commands */
    155    struct resource_ref *resources;
    156 
    157    /** Total memory used by the scene (in bytes).  This sums all the
    158     * data blocks and counts all bins, state, resource references and
    159     * other random allocations within the scene.
    160     */
    161    unsigned scene_size;
    162 
    163    /** Sum of sizes of all resources referenced by the scene.  Sums
    164     * all the textures read by the scene:
    165     */
    166    unsigned resource_reference_size;
    167 
    168    boolean alloc_failed;
    169    boolean discard;
    170    /**
    171     * Number of active tiles in each dimension.
    172     * This basically the framebuffer size divided by tile size
    173     */
    174    unsigned tiles_x, tiles_y;
    175 
    176    int curr_x, curr_y;  /**< for iterating over bins */
    177    pipe_mutex mutex;
    178 
    179    struct cmd_bin tile[TILES_X][TILES_Y];
    180    struct data_block_list data;
    181 };
    182 
    183 
    184 
    185 struct lp_scene *lp_scene_create(struct pipe_context *pipe);
    186 
    187 void lp_scene_destroy(struct lp_scene *scene);
    188 
    189 boolean lp_scene_is_empty(struct lp_scene *scene );
    190 boolean lp_scene_is_oom(struct lp_scene *scene );
    191 
    192 
    193 struct data_block *lp_scene_new_data_block( struct lp_scene *scene );
    194 
    195 struct cmd_block *lp_scene_new_cmd_block( struct lp_scene *scene,
    196                                           struct cmd_bin *bin );
    197 
    198 boolean lp_scene_add_resource_reference(struct lp_scene *scene,
    199                                         struct pipe_resource *resource,
    200                                         boolean initializing_scene);
    201 
    202 boolean lp_scene_is_resource_referenced(const struct lp_scene *scene,
    203                                         const struct pipe_resource *resource );
    204 
    205 
    206 /**
    207  * Allocate space for a command/data in the bin's data buffer.
    208  * Grow the block list if needed.
    209  */
    210 static inline void *
    211 lp_scene_alloc( struct lp_scene *scene, unsigned size)
    212 {
    213    struct data_block_list *list = &scene->data;
    214    struct data_block *block = list->head;
    215 
    216    assert(size <= DATA_BLOCK_SIZE);
    217    assert(block != NULL);
    218 
    219    if (LP_DEBUG & DEBUG_MEM)
    220       debug_printf("alloc %u block %u/%u tot %u/%u\n",
    221 		   size, block->used, DATA_BLOCK_SIZE,
    222 		   scene->scene_size, LP_SCENE_MAX_SIZE);
    223 
    224    if (block->used + size > DATA_BLOCK_SIZE) {
    225       block = lp_scene_new_data_block( scene );
    226       if (!block) {
    227          /* out of memory */
    228          return NULL;
    229       }
    230    }
    231 
    232    {
    233       ubyte *data = block->data + block->used;
    234       block->used += size;
    235       return data;
    236    }
    237 }
    238 
    239 
    240 /**
    241  * As above, but with specific alignment.
    242  */
    243 static inline void *
    244 lp_scene_alloc_aligned( struct lp_scene *scene, unsigned size,
    245 			unsigned alignment )
    246 {
    247    struct data_block_list *list = &scene->data;
    248    struct data_block *block = list->head;
    249 
    250    assert(block != NULL);
    251 
    252    if (LP_DEBUG & DEBUG_MEM)
    253       debug_printf("alloc %u block %u/%u tot %u/%u\n",
    254 		   size + alignment - 1,
    255 		   block->used, DATA_BLOCK_SIZE,
    256 		   scene->scene_size, LP_SCENE_MAX_SIZE);
    257 
    258    if (block->used + size + alignment - 1 > DATA_BLOCK_SIZE) {
    259       block = lp_scene_new_data_block( scene );
    260       if (!block)
    261          return NULL;
    262    }
    263 
    264    {
    265       ubyte *data = block->data + block->used;
    266       unsigned offset = (((uintptr_t)data + alignment - 1) & ~(alignment - 1)) - (uintptr_t)data;
    267       block->used += offset + size;
    268       return data + offset;
    269    }
    270 }
    271 
    272 
    273 /* Put back data if we decide not to use it, eg. culled triangles.
    274  */
    275 static inline void
    276 lp_scene_putback_data( struct lp_scene *scene, unsigned size)
    277 {
    278    struct data_block_list *list = &scene->data;
    279    assert(list->head && list->head->used >= size);
    280    list->head->used -= size;
    281 }
    282 
    283 
    284 /** Return pointer to a particular tile's bin. */
    285 static inline struct cmd_bin *
    286 lp_scene_get_bin(struct lp_scene *scene, unsigned x, unsigned y)
    287 {
    288    return &scene->tile[x][y];
    289 }
    290 
    291 
    292 /** Remove all commands from a bin */
    293 void
    294 lp_scene_bin_reset(struct lp_scene *scene, unsigned x, unsigned y);
    295 
    296 
    297 /* Add a command to bin[x][y].
    298  */
    299 static inline boolean
    300 lp_scene_bin_command( struct lp_scene *scene,
    301                       unsigned x, unsigned y,
    302                       unsigned cmd,
    303                       union lp_rast_cmd_arg arg )
    304 {
    305    struct cmd_bin *bin = lp_scene_get_bin(scene, x, y);
    306    struct cmd_block *tail = bin->tail;
    307 
    308    assert(x < scene->tiles_x);
    309    assert(y < scene->tiles_y);
    310    assert(cmd < LP_RAST_OP_MAX);
    311 
    312    if (tail == NULL || tail->count == CMD_BLOCK_MAX) {
    313       tail = lp_scene_new_cmd_block( scene, bin );
    314       if (!tail) {
    315          return FALSE;
    316       }
    317       assert(tail->count == 0);
    318    }
    319 
    320    {
    321       unsigned i = tail->count;
    322       tail->cmd[i] = cmd & LP_RAST_OP_MASK;
    323       tail->arg[i] = arg;
    324       tail->count++;
    325    }
    326 
    327    return TRUE;
    328 }
    329 
    330 
    331 static inline boolean
    332 lp_scene_bin_cmd_with_state( struct lp_scene *scene,
    333                              unsigned x, unsigned y,
    334                              const struct lp_rast_state *state,
    335                              unsigned cmd,
    336                              union lp_rast_cmd_arg arg )
    337 {
    338    struct cmd_bin *bin = lp_scene_get_bin(scene, x, y);
    339 
    340    if (state != bin->last_state) {
    341       bin->last_state = state;
    342       if (!lp_scene_bin_command(scene, x, y,
    343                                 LP_RAST_OP_SET_STATE,
    344                                 lp_rast_arg_state(state)))
    345          return FALSE;
    346    }
    347 
    348    if (!lp_scene_bin_command( scene, x, y, cmd, arg ))
    349       return FALSE;
    350 
    351    return TRUE;
    352 }
    353 
    354 
    355 /* Add a command to all active bins.
    356  */
    357 static inline boolean
    358 lp_scene_bin_everywhere( struct lp_scene *scene,
    359 			 unsigned cmd,
    360 			 const union lp_rast_cmd_arg arg )
    361 {
    362    unsigned i, j;
    363    for (i = 0; i < scene->tiles_x; i++) {
    364       for (j = 0; j < scene->tiles_y; j++) {
    365          if (!lp_scene_bin_command( scene, i, j, cmd, arg ))
    366             return FALSE;
    367       }
    368    }
    369 
    370    return TRUE;
    371 }
    372 
    373 
    374 static inline unsigned
    375 lp_scene_get_num_bins( const struct lp_scene *scene )
    376 {
    377    return scene->tiles_x * scene->tiles_y;
    378 }
    379 
    380 
    381 void
    382 lp_scene_bin_iter_begin( struct lp_scene *scene );
    383 
    384 struct cmd_bin *
    385 lp_scene_bin_iter_next( struct lp_scene *scene, int *x, int *y );
    386 
    387 
    388 
    389 /* Begin/end binning of a scene
    390  */
    391 void
    392 lp_scene_begin_binning( struct lp_scene *scene,
    393                         struct pipe_framebuffer_state *fb,
    394                         boolean discard );
    395 
    396 void
    397 lp_scene_end_binning( struct lp_scene *scene );
    398 
    399 
    400 /* Begin/end rasterization of a scene
    401  */
    402 void
    403 lp_scene_begin_rasterization(struct lp_scene *scene);
    404 
    405 void
    406 lp_scene_end_rasterization(struct lp_scene *scene );
    407 
    408 
    409 
    410 
    411 
    412 #endif /* LP_BIN_H */
    413