Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | RSS feed

  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 ot 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.    } zsbuf, cbufs[PIPE_MAX_COLOR_BUFS];
  146.  
  147.    /* OpenGL permits different amount of layers per rt, but rendering limited to minimum */
  148.    unsigned fb_max_layer;
  149.  
  150.    /** the framebuffer to render the scene into */
  151.    struct pipe_framebuffer_state fb;
  152.  
  153.    /** list of resources referenced by the scene commands */
  154.    struct resource_ref *resources;
  155.  
  156.    /** Total memory used by the scene (in bytes).  This sums all the
  157.     * data blocks and counts all bins, state, resource references and
  158.     * other random allocations within the scene.
  159.     */
  160.    unsigned scene_size;
  161.  
  162.    /** Sum of sizes of all resources referenced by the scene.  Sums
  163.     * all the textures read by the scene:
  164.     */
  165.    unsigned resource_reference_size;
  166.  
  167.    boolean alloc_failed;
  168.    boolean has_depthstencil_clear;
  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.