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. #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.    /* occlude counter for visible pixels */
  101.    struct lp_jit_thread_data thread_data;
  102.    uint64_t ps_invocations;
  103.  
  104.    pipe_semaphore work_ready;
  105.    pipe_semaphore work_done;
  106. };
  107.  
  108.  
  109. /**
  110.  * This is the state required while rasterizing tiles.
  111.  * Note that this contains per-thread information too.
  112.  * The tile size is TILE_SIZE x TILE_SIZE pixels.
  113.  */
  114. struct lp_rasterizer
  115. {
  116.    boolean exit_flag;
  117.    boolean no_rast;  /**< For debugging/profiling */
  118.  
  119.    /** The incoming queue of scenes ready to rasterize */
  120.    struct lp_scene_queue *full_scenes;
  121.  
  122.    /** The scene currently being rasterized by the threads */
  123.    struct lp_scene *curr_scene;
  124.  
  125.    /** A task object for each rasterization thread */
  126.    struct lp_rasterizer_task tasks[LP_MAX_THREADS];
  127.  
  128.    unsigned num_threads;
  129.    pipe_thread threads[LP_MAX_THREADS];
  130.  
  131.    /** For synchronizing the rasterization threads */
  132.    pipe_barrier barrier;
  133. };
  134.  
  135.  
  136. void
  137. lp_rast_shade_quads_mask(struct lp_rasterizer_task *task,
  138.                          const struct lp_rast_shader_inputs *inputs,
  139.                          unsigned x, unsigned y,
  140.                          unsigned mask);
  141.  
  142.  
  143.  
  144. /**
  145.  * Get pointer to the unswizzled color tile
  146.  */
  147. static INLINE uint8_t *
  148. lp_rast_get_unswizzled_color_tile_pointer(struct lp_rasterizer_task *task,
  149.                                           unsigned buf, enum lp_texture_usage usage)
  150. {
  151.    const struct lp_scene *scene = task->scene;
  152.    unsigned format_bytes;
  153.  
  154.    assert(task->x < scene->tiles_x * TILE_SIZE);
  155.    assert(task->y < scene->tiles_y * TILE_SIZE);
  156.    assert(task->x % TILE_SIZE == 0);
  157.    assert(task->y % TILE_SIZE == 0);
  158.    assert(buf < scene->fb.nr_cbufs);
  159.  
  160.    if (!task->color_tiles[buf]) {
  161.       struct pipe_surface *cbuf = scene->fb.cbufs[buf];
  162.       assert(cbuf);
  163.  
  164.       format_bytes = util_format_get_blocksize(cbuf->format);
  165.       task->color_tiles[buf] = scene->cbufs[buf].map + scene->cbufs[buf].stride * task->y + format_bytes * task->x;
  166.    }
  167.  
  168.    return task->color_tiles[buf];
  169. }
  170.  
  171.  
  172. /**
  173.  * Get pointer to the unswizzled depth tile
  174.  */
  175. static INLINE uint8_t *
  176. lp_rast_get_unswizzled_depth_tile_pointer(struct lp_rasterizer_task *task,
  177.                                           enum lp_texture_usage usage)
  178. {
  179.    const struct lp_scene *scene = task->scene;
  180.    unsigned format_bytes;
  181.  
  182.    assert(task->x < scene->tiles_x * TILE_SIZE);
  183.    assert(task->y < scene->tiles_y * TILE_SIZE);
  184.    assert(task->x % TILE_SIZE == 0);
  185.    assert(task->y % TILE_SIZE == 0);
  186.  
  187.    if (!task->depth_tile) {
  188.       struct pipe_surface *dbuf = scene->fb.zsbuf;
  189.       assert(dbuf);
  190.  
  191.       format_bytes = util_format_get_blocksize(dbuf->format);
  192.       task->depth_tile = scene->zsbuf.map + scene->zsbuf.stride * task->y + format_bytes * task->x;
  193.    }
  194.  
  195.    return task->depth_tile;
  196. }
  197.  
  198.  
  199. /**
  200.  * Get the pointer to an unswizzled 4x4 color block (within an unswizzled 64x64 tile).
  201.  * \param x, y location of 4x4 block in window coords
  202.  */
  203. static INLINE uint8_t *
  204. lp_rast_get_unswizzled_color_block_pointer(struct lp_rasterizer_task *task,
  205.                                            unsigned buf, unsigned x, unsigned y,
  206.                                            unsigned layer)
  207. {
  208.    unsigned px, py, pixel_offset, format_bytes;
  209.    uint8_t *color;
  210.  
  211.    assert(x < task->scene->tiles_x * TILE_SIZE);
  212.    assert(y < task->scene->tiles_y * TILE_SIZE);
  213.    assert((x % TILE_VECTOR_WIDTH) == 0);
  214.    assert((y % TILE_VECTOR_HEIGHT) == 0);
  215.    assert(buf < task->scene->fb.nr_cbufs);
  216.  
  217.    format_bytes = util_format_get_blocksize(task->scene->fb.cbufs[buf]->format);
  218.  
  219.    color = lp_rast_get_unswizzled_color_tile_pointer(task, buf, LP_TEX_USAGE_READ_WRITE);
  220.    assert(color);
  221.  
  222.    px = x % TILE_SIZE;
  223.    py = y % TILE_SIZE;
  224.    pixel_offset = px * format_bytes + py * task->scene->cbufs[buf].stride;
  225.  
  226.    color = color + pixel_offset;
  227.  
  228.    if (layer) {
  229.       color += layer * task->scene->cbufs[buf].layer_stride;
  230.    }
  231.  
  232.    assert(lp_check_alignment(color, llvmpipe_get_format_alignment(task->scene->fb.cbufs[buf]->format)));
  233.    return color;
  234. }
  235.  
  236.  
  237. /**
  238.  * Get the pointer to an unswizzled 4x4 depth block (within an unswizzled 64x64 tile).
  239.  * \param x, y location of 4x4 block in window coords
  240.  */
  241. static INLINE uint8_t *
  242. lp_rast_get_unswizzled_depth_block_pointer(struct lp_rasterizer_task *task,
  243.                                            unsigned x, unsigned y, unsigned layer)
  244. {
  245.    unsigned px, py, pixel_offset, format_bytes;
  246.    uint8_t *depth;
  247.  
  248.    assert(x < task->scene->tiles_x * TILE_SIZE);
  249.    assert(y < task->scene->tiles_y * TILE_SIZE);
  250.    assert((x % TILE_VECTOR_WIDTH) == 0);
  251.    assert((y % TILE_VECTOR_HEIGHT) == 0);
  252.  
  253.    format_bytes = util_format_get_blocksize(task->scene->fb.zsbuf->format);
  254.  
  255.    depth = lp_rast_get_unswizzled_depth_tile_pointer(task, LP_TEX_USAGE_READ_WRITE);
  256.    assert(depth);
  257.  
  258.    px = x % TILE_SIZE;
  259.    py = y % TILE_SIZE;
  260.    pixel_offset = px * format_bytes + py * task->scene->zsbuf.stride;
  261.  
  262.    depth = depth + pixel_offset;
  263.  
  264.    if (layer) {
  265.       depth += layer * task->scene->zsbuf.layer_stride;
  266.    }
  267.  
  268.    assert(lp_check_alignment(depth, llvmpipe_get_format_alignment(task->scene->fb.zsbuf->format)));
  269.    return depth;
  270. }
  271.  
  272.  
  273.  
  274. /**
  275.  * Shade all pixels in a 4x4 block.  The fragment code omits the
  276.  * triangle in/out tests.
  277.  * \param x, y location of 4x4 block in window coords
  278.  */
  279. static INLINE void
  280. lp_rast_shade_quads_all( struct lp_rasterizer_task *task,
  281.                          const struct lp_rast_shader_inputs *inputs,
  282.                          unsigned x, unsigned y )
  283. {
  284.    const struct lp_scene *scene = task->scene;
  285.    const struct lp_rast_state *state = task->state;
  286.    struct lp_fragment_shader_variant *variant = state->variant;
  287.    uint8_t *color[PIPE_MAX_COLOR_BUFS];
  288.    unsigned stride[PIPE_MAX_COLOR_BUFS];
  289.    uint8_t *depth = NULL;
  290.    unsigned depth_stride = 0;
  291.    unsigned i;
  292.  
  293.    /* color buffer */
  294.    for (i = 0; i < scene->fb.nr_cbufs; i++) {
  295.       stride[i] = scene->cbufs[i].stride;
  296.       color[i] = lp_rast_get_unswizzled_color_block_pointer(task, i, x, y, inputs->layer);
  297.    }
  298.  
  299.    if (scene->zsbuf.map) {
  300.       depth = lp_rast_get_unswizzled_depth_block_pointer(task, x, y, inputs->layer);
  301.       depth_stride = scene->zsbuf.stride;
  302.    }
  303.  
  304.    /*
  305.     * The rasterizer may produce fragments outside our
  306.     * allocated 4x4 blocks hence need to filter them out here.
  307.     */
  308.    if ((x % TILE_SIZE) < task->width && (y % TILE_SIZE) < task->height) {
  309.       /* not very accurate would need a popcount on the mask */
  310.       /* always count this not worth bothering? */
  311.       task->ps_invocations++;
  312.  
  313.       /* run shader on 4x4 block */
  314.       BEGIN_JIT_CALL(state, task);
  315.       variant->jit_function[RAST_WHOLE]( &state->jit_context,
  316.                                          x, y,
  317.                                          inputs->frontfacing,
  318.                                          GET_A0(inputs),
  319.                                          GET_DADX(inputs),
  320.                                          GET_DADY(inputs),
  321.                                          color,
  322.                                          depth,
  323.                                          0xffff,
  324.                                          &task->thread_data,
  325.                                          stride,
  326.                                          depth_stride);
  327.       END_JIT_CALL();
  328.    }
  329. }
  330.  
  331. void lp_rast_triangle_1( struct lp_rasterizer_task *,
  332.                          const union lp_rast_cmd_arg );
  333. void lp_rast_triangle_2( struct lp_rasterizer_task *,
  334.                          const union lp_rast_cmd_arg );
  335. void lp_rast_triangle_3( struct lp_rasterizer_task *,
  336.                          const union lp_rast_cmd_arg );
  337. void lp_rast_triangle_4( struct lp_rasterizer_task *,
  338.                          const union lp_rast_cmd_arg );
  339. void lp_rast_triangle_5( struct lp_rasterizer_task *,
  340.                          const union lp_rast_cmd_arg );
  341. void lp_rast_triangle_6( struct lp_rasterizer_task *,
  342.                          const union lp_rast_cmd_arg );
  343. void lp_rast_triangle_7( struct lp_rasterizer_task *,
  344.                          const union lp_rast_cmd_arg );
  345. void lp_rast_triangle_8( struct lp_rasterizer_task *,
  346.                          const union lp_rast_cmd_arg );
  347.  
  348. void lp_rast_triangle_3_4(struct lp_rasterizer_task *,
  349.                           const union lp_rast_cmd_arg );
  350.  
  351. void lp_rast_triangle_3_16( struct lp_rasterizer_task *,
  352.                             const union lp_rast_cmd_arg );
  353.  
  354. void lp_rast_triangle_4_16( struct lp_rasterizer_task *,
  355.                             const union lp_rast_cmd_arg );
  356.  
  357. void
  358. lp_rast_set_state(struct lp_rasterizer_task *task,
  359.                   const union lp_rast_cmd_arg arg);
  360.  
  361. void
  362. lp_debug_bin( const struct cmd_bin *bin, int x, int y );
  363.  
  364. #endif
  365.