Subversion Repositories Kolibri OS

Rev

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. #ifndef LP_RAST_PRIV_H
  29. #define LP_RAST_PRIV_H
  30.  
  31. #include "os/os_thread.h"
  32. #include "util/u_format.h"
  33. #include "gallivm/lp_bld_debug.h"
  34. #include "lp_memory.h"
  35. #include "lp_rast.h"
  36. #include "lp_scene.h"
  37. #include "lp_state.h"
  38. #include "lp_texture.h"
  39. #include "lp_limits.h"
  40.  
  41.  
  42. #define TILE_VECTOR_HEIGHT 4
  43. #define TILE_VECTOR_WIDTH 4
  44.  
  45. /* If we crash in a jitted function, we can examine jit_line and jit_state
  46.  * to get some info.  This is not thread-safe, however.
  47.  */
  48. #ifdef DEBUG
  49.  
  50. struct lp_rasterizer_task;
  51. extern int jit_line;
  52. extern const struct lp_rast_state *jit_state;
  53. extern const struct lp_rasterizer_task *jit_task;
  54.  
  55. #define BEGIN_JIT_CALL(state, task)                  \
  56.    do { \
  57.       jit_line = __LINE__; \
  58.       jit_state = state; \
  59.       jit_task = task; \
  60.    } while (0)
  61.  
  62. #define END_JIT_CALL() \
  63.    do { \
  64.       jit_line = 0; \
  65.       jit_state = NULL; \
  66.    } while (0)
  67.  
  68. #else
  69.  
  70. #define BEGIN_JIT_CALL(X, Y)
  71. #define END_JIT_CALL()
  72.  
  73. #endif
  74.  
  75.  
  76. struct lp_rasterizer;
  77. struct cmd_bin;
  78.  
  79. /**
  80.  * Per-thread rasterization state
  81.  */
  82. struct lp_rasterizer_task
  83. {
  84.    const struct cmd_bin *bin;
  85.    const struct lp_rast_state *state;
  86.  
  87.    struct lp_scene *scene;
  88.    unsigned x, y;          /**< Pos of this tile in framebuffer, in pixels */
  89.    unsigned width, height; /**< width, height of current tile, in pixels */
  90.  
  91.    uint8_t *color_tiles[PIPE_MAX_COLOR_BUFS];
  92.    uint8_t *depth_tile;
  93.  
  94.    /** "back" pointer */
  95.    struct lp_rasterizer *rast;
  96.  
  97.    /** "my" index */
  98.    unsigned thread_index;
  99.  
  100.    /** Non-interpolated passthru state and occlude counter for visible pixels */
  101.    struct lp_jit_thread_data thread_data;
  102.    uint64_t ps_invocations;
  103.    uint8_t ps_inv_multiplier;
  104.  
  105.    pipe_semaphore work_ready;
  106.    pipe_semaphore work_done;
  107. };
  108.  
  109.  
  110. /**
  111.  * This is the state required while rasterizing tiles.
  112.  * Note that this contains per-thread information too.
  113.  * The tile size is TILE_SIZE x TILE_SIZE pixels.
  114.  */
  115. struct lp_rasterizer
  116. {
  117.    boolean exit_flag;
  118.    boolean no_rast;  /**< For debugging/profiling */
  119.  
  120.    /** The incoming queue of scenes ready to rasterize */
  121.    struct lp_scene_queue *full_scenes;
  122.  
  123.    /** The scene currently being rasterized by the threads */
  124.    struct lp_scene *curr_scene;
  125.  
  126.    /** A task object for each rasterization thread */
  127.    struct lp_rasterizer_task tasks[LP_MAX_THREADS];
  128.  
  129.    unsigned num_threads;
  130.    pipe_thread threads[LP_MAX_THREADS];
  131.  
  132.    /** For synchronizing the rasterization threads */
  133.    pipe_barrier barrier;
  134. };
  135.  
  136.  
  137. void
  138. lp_rast_shade_quads_mask(struct lp_rasterizer_task *task,
  139.                          const struct lp_rast_shader_inputs *inputs,
  140.                          unsigned x, unsigned y,
  141.                          unsigned mask);
  142.  
  143.  
  144. /**
  145.  * Get the pointer to a 4x4 color block (within a 64x64 tile).
  146.  * \param x, y location of 4x4 block in window coords
  147.  */
  148. static INLINE uint8_t *
  149. lp_rast_get_color_block_pointer(struct lp_rasterizer_task *task,
  150.                                 unsigned buf, unsigned x, unsigned y,
  151.                                 unsigned layer)
  152. {
  153.    unsigned px, py, pixel_offset;
  154.    uint8_t *color;
  155.  
  156.    assert(x < task->scene->tiles_x * TILE_SIZE);
  157.    assert(y < task->scene->tiles_y * TILE_SIZE);
  158.    assert((x % TILE_VECTOR_WIDTH) == 0);
  159.    assert((y % TILE_VECTOR_HEIGHT) == 0);
  160.    assert(buf < task->scene->fb.nr_cbufs);
  161.  
  162.    assert(task->color_tiles[buf]);
  163.  
  164.    /*
  165.     * We don't actually benefit from having per tile cbuf/zsbuf pointers,
  166.     * it's just extra work - the mul/add would be exactly the same anyway.
  167.     * Fortunately the extra work (modulo) here is very cheap at least...
  168.     */
  169.    px = x % TILE_SIZE;
  170.    py = y % TILE_SIZE;
  171.  
  172.    pixel_offset = px * task->scene->cbufs[buf].format_bytes +
  173.                   py * task->scene->cbufs[buf].stride;
  174.    color = task->color_tiles[buf] + pixel_offset;
  175.  
  176.    if (layer) {
  177.       color += layer * task->scene->cbufs[buf].layer_stride;
  178.    }
  179.  
  180.    assert(lp_check_alignment(color, llvmpipe_get_format_alignment(task->scene->fb.cbufs[buf]->format)));
  181.    return color;
  182. }
  183.  
  184.  
  185. /**
  186.  * Get the pointer to a 4x4 depth block (within a 64x64 tile).
  187.  * \param x, y location of 4x4 block in window coords
  188.  */
  189. static INLINE uint8_t *
  190. lp_rast_get_depth_block_pointer(struct lp_rasterizer_task *task,
  191.                                 unsigned x, unsigned y, unsigned layer)
  192. {
  193.    unsigned px, py, pixel_offset;
  194.    uint8_t *depth;
  195.  
  196.    assert(x < task->scene->tiles_x * TILE_SIZE);
  197.    assert(y < task->scene->tiles_y * TILE_SIZE);
  198.    assert((x % TILE_VECTOR_WIDTH) == 0);
  199.    assert((y % TILE_VECTOR_HEIGHT) == 0);
  200.  
  201.    assert(task->depth_tile);
  202.  
  203.    px = x % TILE_SIZE;
  204.    py = y % TILE_SIZE;
  205.  
  206.    pixel_offset = px * task->scene->zsbuf.format_bytes +
  207.                   py * task->scene->zsbuf.stride;
  208.    depth = task->depth_tile + pixel_offset;
  209.  
  210.    if (layer) {
  211.       depth += layer * task->scene->zsbuf.layer_stride;
  212.    }
  213.  
  214.    assert(lp_check_alignment(depth, llvmpipe_get_format_alignment(task->scene->fb.zsbuf->format)));
  215.    return depth;
  216. }
  217.  
  218.  
  219.  
  220. /**
  221.  * Shade all pixels in a 4x4 block.  The fragment code omits the
  222.  * triangle in/out tests.
  223.  * \param x, y location of 4x4 block in window coords
  224.  */
  225. static INLINE void
  226. lp_rast_shade_quads_all( struct lp_rasterizer_task *task,
  227.                          const struct lp_rast_shader_inputs *inputs,
  228.                          unsigned x, unsigned y )
  229. {
  230.    const struct lp_scene *scene = task->scene;
  231.    const struct lp_rast_state *state = task->state;
  232.    struct lp_fragment_shader_variant *variant = state->variant;
  233.    uint8_t *color[PIPE_MAX_COLOR_BUFS];
  234.    unsigned stride[PIPE_MAX_COLOR_BUFS];
  235.    uint8_t *depth = NULL;
  236.    unsigned depth_stride = 0;
  237.    unsigned i;
  238.  
  239.    /* color buffer */
  240.    for (i = 0; i < scene->fb.nr_cbufs; i++) {
  241.       if (scene->fb.cbufs[i]) {
  242.          stride[i] = scene->cbufs[i].stride;
  243.          color[i] = lp_rast_get_color_block_pointer(task, i, x, y,
  244.                                                     inputs->layer);
  245.       }
  246.       else {
  247.          stride[i] = 0;
  248.          color[i] = NULL;
  249.       }
  250.    }
  251.  
  252.    if (scene->zsbuf.map) {
  253.       depth = lp_rast_get_depth_block_pointer(task, x, y, inputs->layer);
  254.       depth_stride = scene->zsbuf.stride;
  255.    }
  256.  
  257.    /*
  258.     * The rasterizer may produce fragments outside our
  259.     * allocated 4x4 blocks hence need to filter them out here.
  260.     */
  261.    if ((x % TILE_SIZE) < task->width && (y % TILE_SIZE) < task->height) {
  262.       /* not very accurate would need a popcount on the mask */
  263.       /* always count this not worth bothering? */
  264.       task->ps_invocations += 1 * variant->ps_inv_multiplier;
  265.  
  266.       /* Propagate non-interpolated raster state. */
  267.       task->thread_data.raster_state.viewport_index = inputs->viewport_index;
  268.  
  269.       /* run shader on 4x4 block */
  270.       BEGIN_JIT_CALL(state, task);
  271.       variant->jit_function[RAST_WHOLE]( &state->jit_context,
  272.                                          x, y,
  273.                                          inputs->frontfacing,
  274.                                          GET_A0(inputs),
  275.                                          GET_DADX(inputs),
  276.                                          GET_DADY(inputs),
  277.                                          color,
  278.                                          depth,
  279.                                          0xffff,
  280.                                          &task->thread_data,
  281.                                          stride,
  282.                                          depth_stride);
  283.       END_JIT_CALL();
  284.    }
  285. }
  286.  
  287. void lp_rast_triangle_1( struct lp_rasterizer_task *,
  288.                          const union lp_rast_cmd_arg );
  289. void lp_rast_triangle_2( struct lp_rasterizer_task *,
  290.                          const union lp_rast_cmd_arg );
  291. void lp_rast_triangle_3( struct lp_rasterizer_task *,
  292.                          const union lp_rast_cmd_arg );
  293. void lp_rast_triangle_4( struct lp_rasterizer_task *,
  294.                          const union lp_rast_cmd_arg );
  295. void lp_rast_triangle_5( struct lp_rasterizer_task *,
  296.                          const union lp_rast_cmd_arg );
  297. void lp_rast_triangle_6( struct lp_rasterizer_task *,
  298.                          const union lp_rast_cmd_arg );
  299. void lp_rast_triangle_7( struct lp_rasterizer_task *,
  300.                          const union lp_rast_cmd_arg );
  301. void lp_rast_triangle_8( struct lp_rasterizer_task *,
  302.                          const union lp_rast_cmd_arg );
  303.  
  304. void lp_rast_triangle_3_4(struct lp_rasterizer_task *,
  305.                           const union lp_rast_cmd_arg );
  306.  
  307. void lp_rast_triangle_3_16( struct lp_rasterizer_task *,
  308.                             const union lp_rast_cmd_arg );
  309.  
  310. void lp_rast_triangle_4_16( struct lp_rasterizer_task *,
  311.                             const union lp_rast_cmd_arg );
  312.  
  313.  
  314. void lp_rast_triangle_32_1( struct lp_rasterizer_task *,
  315.                          const union lp_rast_cmd_arg );
  316. void lp_rast_triangle_32_2( struct lp_rasterizer_task *,
  317.                          const union lp_rast_cmd_arg );
  318. void lp_rast_triangle_32_3( struct lp_rasterizer_task *,
  319.                          const union lp_rast_cmd_arg );
  320. void lp_rast_triangle_32_4( struct lp_rasterizer_task *,
  321.                          const union lp_rast_cmd_arg );
  322. void lp_rast_triangle_32_5( struct lp_rasterizer_task *,
  323.                          const union lp_rast_cmd_arg );
  324. void lp_rast_triangle_32_6( struct lp_rasterizer_task *,
  325.                          const union lp_rast_cmd_arg );
  326. void lp_rast_triangle_32_7( struct lp_rasterizer_task *,
  327.                          const union lp_rast_cmd_arg );
  328. void lp_rast_triangle_32_8( struct lp_rasterizer_task *,
  329.                          const union lp_rast_cmd_arg );
  330.  
  331. void lp_rast_triangle_32_3_4(struct lp_rasterizer_task *,
  332.                           const union lp_rast_cmd_arg );
  333.  
  334. void lp_rast_triangle_32_3_16( struct lp_rasterizer_task *,
  335.                             const union lp_rast_cmd_arg );
  336.  
  337. void lp_rast_triangle_32_4_16( struct lp_rasterizer_task *,
  338.                             const union lp_rast_cmd_arg );
  339.  
  340. void
  341. lp_rast_set_state(struct lp_rasterizer_task *task,
  342.                   const union lp_rast_cmd_arg arg);
  343.  
  344. void
  345. lp_debug_bin( const struct cmd_bin *bin, int x, int y );
  346.  
  347. #endif
  348.