José Fonseca | d614ced | 2009-10-08 12:51:46 +0100 | [diff] [blame] | 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 | |
Brian Paul | ab94381 | 2009-12-16 16:02:59 -0700 | [diff] [blame] | 28 | #include <limits.h> |
José Fonseca | d614ced | 2009-10-08 12:51:46 +0100 | [diff] [blame] | 29 | #include "util/u_memory.h" |
Brian Paul | aab1cec | 2009-12-07 18:01:12 -0700 | [diff] [blame] | 30 | #include "util/u_math.h" |
José Fonseca | 7f457ac | 2009-12-08 08:02:49 +0000 | [diff] [blame] | 31 | #include "util/u_cpu_detect.h" |
Brian Paul | 156eabb | 2009-12-11 11:46:23 -0700 | [diff] [blame] | 32 | #include "util/u_surface.h" |
José Fonseca | d614ced | 2009-10-08 12:51:46 +0100 | [diff] [blame] | 33 | |
Keith Whitwell | 663750d | 2009-12-13 18:17:25 +0000 | [diff] [blame] | 34 | #include "lp_scene_queue.h" |
Brian Paul | a08d630 | 2009-12-04 14:11:25 -0700 | [diff] [blame] | 35 | #include "lp_debug.h" |
Brian Paul | 4b70af9 | 2009-12-11 17:57:45 -0700 | [diff] [blame] | 36 | #include "lp_fence.h" |
José Fonseca | d614ced | 2009-10-08 12:51:46 +0100 | [diff] [blame] | 37 | #include "lp_rast.h" |
José Fonseca | 9215841 | 2009-10-08 17:26:13 +0100 | [diff] [blame] | 38 | #include "lp_rast_priv.h" |
| 39 | #include "lp_tile_soa.h" |
Zack Rusin | c61bf36 | 2010-02-08 18:05:22 -0500 | [diff] [blame^] | 40 | #include "gallivm/lp_bld_debug.h" |
Keith Whitwell | 663750d | 2009-12-13 18:17:25 +0000 | [diff] [blame] | 41 | #include "lp_scene.h" |
José Fonseca | d614ced | 2009-10-08 12:51:46 +0100 | [diff] [blame] | 42 | |
Keith Whitwell | 89498d0 | 2009-10-07 22:36:43 +0100 | [diff] [blame] | 43 | |
Brian Paul | 7505510 | 2009-11-30 14:02:01 -0700 | [diff] [blame] | 44 | /** |
| 45 | * Begin the rasterization phase. |
| 46 | * Map the framebuffer surfaces. Initialize the 'rast' state. |
| 47 | */ |
Brian Paul | 01b1900 | 2009-12-04 15:31:09 -0700 | [diff] [blame] | 48 | static boolean |
| 49 | lp_rast_begin( struct lp_rasterizer *rast, |
Brian Paul | 156eabb | 2009-12-11 11:46:23 -0700 | [diff] [blame] | 50 | const struct pipe_framebuffer_state *fb, |
| 51 | boolean write_color, |
| 52 | boolean write_zstencil ) |
Keith Whitwell | 84ab7dc | 2009-10-09 10:24:19 +0100 | [diff] [blame] | 53 | { |
Keith Whitwell | e0e2008 | 2009-10-09 14:29:25 +0100 | [diff] [blame] | 54 | struct pipe_screen *screen = rast->screen; |
Brian Paul | 156eabb | 2009-12-11 11:46:23 -0700 | [diff] [blame] | 55 | struct pipe_surface *cbuf, *zsbuf; |
Keith Whitwell | c1a0441 | 2010-01-10 17:22:09 +0000 | [diff] [blame] | 56 | int i; |
Keith Whitwell | e0e2008 | 2009-10-09 14:29:25 +0100 | [diff] [blame] | 57 | |
Brian Paul | 156eabb | 2009-12-11 11:46:23 -0700 | [diff] [blame] | 58 | LP_DBG(DEBUG_RAST, "%s\n", __FUNCTION__); |
Keith Whitwell | 4e1334c | 2009-10-09 14:02:39 +0100 | [diff] [blame] | 59 | |
Brian Paul | 156eabb | 2009-12-11 11:46:23 -0700 | [diff] [blame] | 60 | util_copy_framebuffer_state(&rast->state.fb, fb); |
Keith Whitwell | e0e2008 | 2009-10-09 14:29:25 +0100 | [diff] [blame] | 61 | |
Keith Whitwell | e0e2008 | 2009-10-09 14:29:25 +0100 | [diff] [blame] | 62 | rast->state.write_zstencil = write_zstencil; |
| 63 | rast->state.write_color = write_color; |
| 64 | |
Brian Paul | 156eabb | 2009-12-11 11:46:23 -0700 | [diff] [blame] | 65 | rast->check_for_clipped_tiles = (fb->width % TILE_SIZE != 0 || |
| 66 | fb->height % TILE_SIZE != 0); |
Keith Whitwell | e0e2008 | 2009-10-09 14:29:25 +0100 | [diff] [blame] | 67 | |
Keith Whitwell | c1a0441 | 2010-01-10 17:22:09 +0000 | [diff] [blame] | 68 | |
| 69 | for (i = 0; i < rast->state.fb.nr_cbufs; i++) { |
| 70 | cbuf = rast->state.fb.cbufs[i]; |
| 71 | if (cbuf) { |
| 72 | rast->cbuf_transfer[i] = screen->get_tex_transfer(rast->screen, |
| 73 | cbuf->texture, |
| 74 | cbuf->face, |
| 75 | cbuf->level, |
| 76 | cbuf->zslice, |
| 77 | PIPE_TRANSFER_READ_WRITE, |
| 78 | 0, 0, |
| 79 | cbuf->width, |
| 80 | cbuf->height); |
| 81 | if (!rast->cbuf_transfer[i]) |
| 82 | goto fail; |
Keith Whitwell | e0e2008 | 2009-10-09 14:29:25 +0100 | [diff] [blame] | 83 | |
Keith Whitwell | c1a0441 | 2010-01-10 17:22:09 +0000 | [diff] [blame] | 84 | rast->cbuf_map[i] = screen->transfer_map(rast->screen, |
| 85 | rast->cbuf_transfer[i]); |
| 86 | if (!rast->cbuf_map[i]) |
| 87 | goto fail; |
| 88 | } |
Keith Whitwell | e0e2008 | 2009-10-09 14:29:25 +0100 | [diff] [blame] | 89 | } |
| 90 | |
Brian Paul | 156eabb | 2009-12-11 11:46:23 -0700 | [diff] [blame] | 91 | zsbuf = rast->state.fb.zsbuf; |
Brian Paul | 51663f0 | 2009-12-03 11:41:45 -0700 | [diff] [blame] | 92 | if (zsbuf) { |
| 93 | rast->zsbuf_transfer = screen->get_tex_transfer(rast->screen, |
Brian Paul | 156eabb | 2009-12-11 11:46:23 -0700 | [diff] [blame] | 94 | zsbuf->texture, |
| 95 | zsbuf->face, |
| 96 | zsbuf->level, |
| 97 | zsbuf->zslice, |
| 98 | PIPE_TRANSFER_READ_WRITE, |
| 99 | 0, 0, |
Keith Whitwell | c1a0441 | 2010-01-10 17:22:09 +0000 | [diff] [blame] | 100 | zsbuf->width, |
| 101 | zsbuf->height); |
Brian Paul | 51663f0 | 2009-12-03 11:41:45 -0700 | [diff] [blame] | 102 | if (!rast->zsbuf_transfer) |
Keith Whitwell | c1a0441 | 2010-01-10 17:22:09 +0000 | [diff] [blame] | 103 | goto fail; |
Brian Paul | 51663f0 | 2009-12-03 11:41:45 -0700 | [diff] [blame] | 104 | |
| 105 | rast->zsbuf_map = screen->transfer_map(rast->screen, |
| 106 | rast->zsbuf_transfer); |
| 107 | if (!rast->zsbuf_map) |
Keith Whitwell | c1a0441 | 2010-01-10 17:22:09 +0000 | [diff] [blame] | 108 | goto fail; |
Brian Paul | 51663f0 | 2009-12-03 11:41:45 -0700 | [diff] [blame] | 109 | } |
| 110 | |
Keith Whitwell | e0e2008 | 2009-10-09 14:29:25 +0100 | [diff] [blame] | 111 | return TRUE; |
Keith Whitwell | c1a0441 | 2010-01-10 17:22:09 +0000 | [diff] [blame] | 112 | |
| 113 | fail: |
| 114 | /* Unmap and release transfers? |
| 115 | */ |
| 116 | return FALSE; |
Keith Whitwell | 84ab7dc | 2009-10-09 10:24:19 +0100 | [diff] [blame] | 117 | } |
| 118 | |
Keith Whitwell | e0e2008 | 2009-10-09 14:29:25 +0100 | [diff] [blame] | 119 | |
Brian Paul | 7505510 | 2009-11-30 14:02:01 -0700 | [diff] [blame] | 120 | /** |
| 121 | * Finish the rasterization phase. |
| 122 | * Unmap framebuffer surfaces. |
| 123 | */ |
Brian Paul | 01b1900 | 2009-12-04 15:31:09 -0700 | [diff] [blame] | 124 | static void |
| 125 | lp_rast_end( struct lp_rasterizer *rast ) |
Keith Whitwell | 89498d0 | 2009-10-07 22:36:43 +0100 | [diff] [blame] | 126 | { |
Keith Whitwell | e0e2008 | 2009-10-09 14:29:25 +0100 | [diff] [blame] | 127 | struct pipe_screen *screen = rast->screen; |
Keith Whitwell | c1a0441 | 2010-01-10 17:22:09 +0000 | [diff] [blame] | 128 | unsigned i; |
Keith Whitwell | 4e1334c | 2009-10-09 14:02:39 +0100 | [diff] [blame] | 129 | |
Keith Whitwell | c1a0441 | 2010-01-10 17:22:09 +0000 | [diff] [blame] | 130 | for (i = 0; i < rast->state.fb.nr_cbufs; i++) { |
| 131 | if (rast->cbuf_map[i]) |
| 132 | screen->transfer_unmap(screen, rast->cbuf_transfer[i]); |
| 133 | |
| 134 | if (rast->cbuf_transfer[i]) |
| 135 | screen->tex_transfer_destroy(rast->cbuf_transfer[i]); |
| 136 | |
| 137 | rast->cbuf_transfer[i] = NULL; |
| 138 | rast->cbuf_map[i] = NULL; |
| 139 | } |
Keith Whitwell | e0e2008 | 2009-10-09 14:29:25 +0100 | [diff] [blame] | 140 | |
| 141 | if (rast->zsbuf_map) |
| 142 | screen->transfer_unmap(screen, rast->zsbuf_transfer); |
| 143 | |
Keith Whitwell | e0e2008 | 2009-10-09 14:29:25 +0100 | [diff] [blame] | 144 | if (rast->zsbuf_transfer) |
Brian Paul | 51663f0 | 2009-12-03 11:41:45 -0700 | [diff] [blame] | 145 | screen->tex_transfer_destroy(rast->zsbuf_transfer); |
Keith Whitwell | e0e2008 | 2009-10-09 14:29:25 +0100 | [diff] [blame] | 146 | |
Keith Whitwell | e0e2008 | 2009-10-09 14:29:25 +0100 | [diff] [blame] | 147 | rast->zsbuf_transfer = NULL; |
Keith Whitwell | e0e2008 | 2009-10-09 14:29:25 +0100 | [diff] [blame] | 148 | rast->zsbuf_map = NULL; |
Keith Whitwell | 0718c77 | 2009-10-08 19:58:28 +0100 | [diff] [blame] | 149 | } |
| 150 | |
Keith Whitwell | 4e1334c | 2009-10-09 14:02:39 +0100 | [diff] [blame] | 151 | |
Brian Paul | 7505510 | 2009-11-30 14:02:01 -0700 | [diff] [blame] | 152 | /** |
| 153 | * Begining rasterization of a tile. |
| 154 | * \param x window X position of the tile, in pixels |
| 155 | * \param y window Y position of the tile, in pixels |
Keith Whitwell | 89498d0 | 2009-10-07 22:36:43 +0100 | [diff] [blame] | 156 | */ |
Brian Paul | b533b56 | 2009-12-04 14:47:40 -0700 | [diff] [blame] | 157 | static void |
| 158 | lp_rast_start_tile( struct lp_rasterizer *rast, |
Brian Paul | 3a06c11 | 2009-12-07 17:02:17 -0700 | [diff] [blame] | 159 | unsigned thread_index, |
Brian Paul | b533b56 | 2009-12-04 14:47:40 -0700 | [diff] [blame] | 160 | unsigned x, unsigned y ) |
Keith Whitwell | 89498d0 | 2009-10-07 22:36:43 +0100 | [diff] [blame] | 161 | { |
Brian Paul | a08d630 | 2009-12-04 14:11:25 -0700 | [diff] [blame] | 162 | LP_DBG(DEBUG_RAST, "%s %d,%d\n", __FUNCTION__, x, y); |
Keith Whitwell | 4e1334c | 2009-10-09 14:02:39 +0100 | [diff] [blame] | 163 | |
Brian Paul | 3a06c11 | 2009-12-07 17:02:17 -0700 | [diff] [blame] | 164 | rast->tasks[thread_index].x = x; |
| 165 | rast->tasks[thread_index].y = y; |
Keith Whitwell | 89498d0 | 2009-10-07 22:36:43 +0100 | [diff] [blame] | 166 | } |
| 167 | |
Brian Paul | 7505510 | 2009-11-30 14:02:01 -0700 | [diff] [blame] | 168 | |
| 169 | /** |
| 170 | * Clear the rasterizer's current color tile. |
Brian Paul | ffd0759 | 2009-12-03 14:57:44 -0700 | [diff] [blame] | 171 | * This is a bin command called during bin processing. |
Brian Paul | 7505510 | 2009-11-30 14:02:01 -0700 | [diff] [blame] | 172 | */ |
Keith Whitwell | d0c918b | 2009-10-08 17:20:40 +0100 | [diff] [blame] | 173 | void lp_rast_clear_color( struct lp_rasterizer *rast, |
Brian Paul | 3a06c11 | 2009-12-07 17:02:17 -0700 | [diff] [blame] | 174 | unsigned thread_index, |
Keith Whitwell | 4cdd10c | 2009-10-09 11:29:01 +0100 | [diff] [blame] | 175 | const union lp_rast_cmd_arg arg ) |
Keith Whitwell | 89498d0 | 2009-10-07 22:36:43 +0100 | [diff] [blame] | 176 | { |
Keith Whitwell | 4cdd10c | 2009-10-09 11:29:01 +0100 | [diff] [blame] | 177 | const uint8_t *clear_color = arg.clear_color; |
Keith Whitwell | c1a0441 | 2010-01-10 17:22:09 +0000 | [diff] [blame] | 178 | uint8_t **color_tile = rast->tasks[thread_index].tile.color; |
| 179 | unsigned i; |
| 180 | |
Brian Paul | a08d630 | 2009-12-04 14:11:25 -0700 | [diff] [blame] | 181 | LP_DBG(DEBUG_RAST, "%s 0x%x,0x%x,0x%x,0x%x\n", __FUNCTION__, |
Keith Whitwell | 295aea0 | 2009-10-09 14:07:25 +0100 | [diff] [blame] | 182 | clear_color[0], |
| 183 | clear_color[1], |
| 184 | clear_color[2], |
| 185 | clear_color[3]); |
Keith Whitwell | 4e1334c | 2009-10-09 14:02:39 +0100 | [diff] [blame] | 186 | |
José Fonseca | 37b86aa | 2009-10-08 17:59:44 +0100 | [diff] [blame] | 187 | if (clear_color[0] == clear_color[1] && |
| 188 | clear_color[1] == clear_color[2] && |
| 189 | clear_color[2] == clear_color[3]) { |
Brian Paul | f94a991 | 2010-01-13 18:54:48 -0700 | [diff] [blame] | 190 | /* clear to grayscale value {x, x, x, x} */ |
Keith Whitwell | c1a0441 | 2010-01-10 17:22:09 +0000 | [diff] [blame] | 191 | for (i = 0; i < rast->state.fb.nr_cbufs; i++) { |
| 192 | memset(color_tile[i], clear_color[0], TILE_SIZE * TILE_SIZE * 4); |
| 193 | } |
José Fonseca | 37b86aa | 2009-10-08 17:59:44 +0100 | [diff] [blame] | 194 | } |
| 195 | else { |
Brian Paul | f94a991 | 2010-01-13 18:54:48 -0700 | [diff] [blame] | 196 | /* Non-gray color. |
| 197 | * Note: if the swizzled tile layout changes (see TILE_PIXEL) this code |
| 198 | * will need to change. It'll be pretty obvious when clearing no longer |
| 199 | * works. |
| 200 | */ |
| 201 | const unsigned chunk = TILE_SIZE / 4; |
| 202 | for (i = 0; i < rast->state.fb.nr_cbufs; i++) { |
| 203 | uint8_t *c = color_tile[i]; |
| 204 | unsigned j; |
| 205 | for (j = 0; j < 4 * TILE_SIZE; j++) { |
| 206 | memset(c, clear_color[0], chunk); |
| 207 | c += chunk; |
| 208 | memset(c, clear_color[1], chunk); |
| 209 | c += chunk; |
| 210 | memset(c, clear_color[2], chunk); |
| 211 | c += chunk; |
| 212 | memset(c, clear_color[3], chunk); |
| 213 | c += chunk; |
| 214 | } |
| 215 | assert(c - color_tile[i] == TILE_SIZE * TILE_SIZE * 4); |
| 216 | } |
José Fonseca | 37b86aa | 2009-10-08 17:59:44 +0100 | [diff] [blame] | 217 | } |
Keith Whitwell | 89498d0 | 2009-10-07 22:36:43 +0100 | [diff] [blame] | 218 | } |
| 219 | |
Brian Paul | 7505510 | 2009-11-30 14:02:01 -0700 | [diff] [blame] | 220 | |
| 221 | /** |
| 222 | * Clear the rasterizer's current z/stencil tile. |
Brian Paul | ffd0759 | 2009-12-03 14:57:44 -0700 | [diff] [blame] | 223 | * This is a bin command called during bin processing. |
Brian Paul | 7505510 | 2009-11-30 14:02:01 -0700 | [diff] [blame] | 224 | */ |
Keith Whitwell | d0c918b | 2009-10-08 17:20:40 +0100 | [diff] [blame] | 225 | void lp_rast_clear_zstencil( struct lp_rasterizer *rast, |
Brian Paul | 3a06c11 | 2009-12-07 17:02:17 -0700 | [diff] [blame] | 226 | unsigned thread_index, |
Keith Whitwell | 4cdd10c | 2009-10-09 11:29:01 +0100 | [diff] [blame] | 227 | const union lp_rast_cmd_arg arg) |
Keith Whitwell | 89498d0 | 2009-10-07 22:36:43 +0100 | [diff] [blame] | 228 | { |
Brian Paul | 2ba1c81 | 2010-01-13 18:58:38 -0700 | [diff] [blame] | 229 | unsigned i; |
Brian Paul | 3a06c11 | 2009-12-07 17:02:17 -0700 | [diff] [blame] | 230 | uint32_t *depth_tile = rast->tasks[thread_index].tile.depth; |
Keith Whitwell | 89498d0 | 2009-10-07 22:36:43 +0100 | [diff] [blame] | 231 | |
Brian Paul | a08d630 | 2009-12-04 14:11:25 -0700 | [diff] [blame] | 232 | LP_DBG(DEBUG_RAST, "%s 0x%x\n", __FUNCTION__, arg.clear_zstencil); |
Keith Whitwell | 4e1334c | 2009-10-09 14:02:39 +0100 | [diff] [blame] | 233 | |
Brian Paul | 2ba1c81 | 2010-01-13 18:58:38 -0700 | [diff] [blame] | 234 | for (i = 0; i < TILE_SIZE * TILE_SIZE; i++) |
| 235 | depth_tile[i] = arg.clear_zstencil; |
Keith Whitwell | 89498d0 | 2009-10-07 22:36:43 +0100 | [diff] [blame] | 236 | } |
| 237 | |
Keith Whitwell | 89498d0 | 2009-10-07 22:36:43 +0100 | [diff] [blame] | 238 | |
Brian Paul | ffd0759 | 2009-12-03 14:57:44 -0700 | [diff] [blame] | 239 | /** |
| 240 | * Load tile color from the framebuffer surface. |
| 241 | * This is a bin command called during bin processing. |
| 242 | */ |
Keith Whitwell | d0c918b | 2009-10-08 17:20:40 +0100 | [diff] [blame] | 243 | void lp_rast_load_color( struct lp_rasterizer *rast, |
Brian Paul | 3a06c11 | 2009-12-07 17:02:17 -0700 | [diff] [blame] | 244 | unsigned thread_index, |
Keith Whitwell | 4cdd10c | 2009-10-09 11:29:01 +0100 | [diff] [blame] | 245 | const union lp_rast_cmd_arg arg) |
Keith Whitwell | 89498d0 | 2009-10-07 22:36:43 +0100 | [diff] [blame] | 246 | { |
Brian Paul | 92dc0f9 | 2009-12-11 15:00:28 -0700 | [diff] [blame] | 247 | struct lp_rasterizer_task *task = &rast->tasks[thread_index]; |
| 248 | const unsigned x = task->x; |
| 249 | const unsigned y = task->y; |
Keith Whitwell | c1a0441 | 2010-01-10 17:22:09 +0000 | [diff] [blame] | 250 | unsigned i; |
Keith Whitwell | 4e1334c | 2009-10-09 14:02:39 +0100 | [diff] [blame] | 251 | |
Brian Paul | 92dc0f9 | 2009-12-11 15:00:28 -0700 | [diff] [blame] | 252 | LP_DBG(DEBUG_RAST, "%s at %u, %u\n", __FUNCTION__, x, y); |
| 253 | |
Keith Whitwell | c1a0441 | 2010-01-10 17:22:09 +0000 | [diff] [blame] | 254 | for (i = 0; i < rast->state.fb.nr_cbufs; i++) { |
| 255 | struct pipe_transfer *transfer = rast->cbuf_transfer[i]; |
| 256 | int w = TILE_SIZE; |
| 257 | int h = TILE_SIZE; |
Brian Paul | 92dc0f9 | 2009-12-11 15:00:28 -0700 | [diff] [blame] | 258 | |
Keith Whitwell | c1a0441 | 2010-01-10 17:22:09 +0000 | [diff] [blame] | 259 | if (x >= transfer->width) |
| 260 | continue; |
Brian Paul | 92dc0f9 | 2009-12-11 15:00:28 -0700 | [diff] [blame] | 261 | |
Keith Whitwell | c1a0441 | 2010-01-10 17:22:09 +0000 | [diff] [blame] | 262 | if (y >= transfer->height) |
| 263 | continue; |
Keith Whitwell | c1a0441 | 2010-01-10 17:22:09 +0000 | [diff] [blame] | 264 | |
| 265 | assert(w >= 0); |
| 266 | assert(h >= 0); |
| 267 | assert(w <= TILE_SIZE); |
| 268 | assert(h <= TILE_SIZE); |
| 269 | |
| 270 | lp_tile_read_4ub(transfer->texture->format, |
Brian Paul | ec459f2 | 2010-01-19 16:58:25 -0700 | [diff] [blame] | 271 | task->tile.color[i], |
Keith Whitwell | c1a0441 | 2010-01-10 17:22:09 +0000 | [diff] [blame] | 272 | rast->cbuf_map[i], |
| 273 | transfer->stride, |
| 274 | x, y, |
| 275 | w, h); |
| 276 | } |
Keith Whitwell | 89498d0 | 2009-10-07 22:36:43 +0100 | [diff] [blame] | 277 | } |
| 278 | |
Brian Paul | ffd0759 | 2009-12-03 14:57:44 -0700 | [diff] [blame] | 279 | |
Keith Whitwell | 95ee14f | 2010-01-13 16:52:17 +0000 | [diff] [blame] | 280 | static void |
| 281 | lp_tile_read_z32(uint32_t *tile, |
| 282 | const uint8_t *map, |
| 283 | unsigned map_stride, |
| 284 | unsigned x0, unsigned y0, unsigned w, unsigned h) |
| 285 | { |
| 286 | unsigned x, y; |
| 287 | const uint8_t *map_row = map + y0*map_stride; |
| 288 | for (y = 0; y < h; ++y) { |
| 289 | const uint32_t *map_pixel = (uint32_t *)(map_row + x0*4); |
| 290 | for (x = 0; x < w; ++x) { |
| 291 | *tile++ = *map_pixel++; |
| 292 | } |
| 293 | map_row += map_stride; |
| 294 | } |
| 295 | } |
| 296 | |
Brian Paul | ffd0759 | 2009-12-03 14:57:44 -0700 | [diff] [blame] | 297 | /** |
| 298 | * Load tile z/stencil from the framebuffer surface. |
| 299 | * This is a bin command called during bin processing. |
| 300 | */ |
Keith Whitwell | d0c918b | 2009-10-08 17:20:40 +0100 | [diff] [blame] | 301 | void lp_rast_load_zstencil( struct lp_rasterizer *rast, |
Brian Paul | 3a06c11 | 2009-12-07 17:02:17 -0700 | [diff] [blame] | 302 | unsigned thread_index, |
Keith Whitwell | 4cdd10c | 2009-10-09 11:29:01 +0100 | [diff] [blame] | 303 | const union lp_rast_cmd_arg arg ) |
Keith Whitwell | 89498d0 | 2009-10-07 22:36:43 +0100 | [diff] [blame] | 304 | { |
Brian Paul | ec459f2 | 2010-01-19 16:58:25 -0700 | [diff] [blame] | 305 | struct lp_rasterizer_task *task = &rast->tasks[thread_index]; |
| 306 | const unsigned x = task->x; |
| 307 | const unsigned y = task->y; |
Keith Whitwell | 95ee14f | 2010-01-13 16:52:17 +0000 | [diff] [blame] | 308 | unsigned w = TILE_SIZE; |
| 309 | unsigned h = TILE_SIZE; |
Keith Whitwell | 4e1334c | 2009-10-09 14:02:39 +0100 | [diff] [blame] | 310 | |
Keith Whitwell | 95ee14f | 2010-01-13 16:52:17 +0000 | [diff] [blame] | 311 | if (x + w > rast->state.fb.width) |
| 312 | w -= x + w - rast->state.fb.width; |
| 313 | |
| 314 | if (y + h > rast->state.fb.height) |
| 315 | h -= y + h - rast->state.fb.height; |
| 316 | |
| 317 | LP_DBG(DEBUG_RAST, "%s %d,%d %dx%d\n", __FUNCTION__, x, y, w, h); |
| 318 | |
| 319 | assert(rast->zsbuf_transfer->texture->format == PIPE_FORMAT_Z32_UNORM); |
Brian Paul | ec459f2 | 2010-01-19 16:58:25 -0700 | [diff] [blame] | 320 | lp_tile_read_z32(task->tile.depth, |
Keith Whitwell | 95ee14f | 2010-01-13 16:52:17 +0000 | [diff] [blame] | 321 | rast->zsbuf_map, |
| 322 | rast->zsbuf_transfer->stride, |
| 323 | x, y, w, h); |
Keith Whitwell | 89498d0 | 2009-10-07 22:36:43 +0100 | [diff] [blame] | 324 | } |
| 325 | |
Brian Paul | ffd0759 | 2009-12-03 14:57:44 -0700 | [diff] [blame] | 326 | |
| 327 | void lp_rast_set_state( struct lp_rasterizer *rast, |
Brian Paul | 3a06c11 | 2009-12-07 17:02:17 -0700 | [diff] [blame] | 328 | unsigned thread_index, |
Brian Paul | ffd0759 | 2009-12-03 14:57:44 -0700 | [diff] [blame] | 329 | const union lp_rast_cmd_arg arg ) |
| 330 | { |
Brian Paul | e2f4634 | 2009-12-03 16:05:12 -0700 | [diff] [blame] | 331 | const struct lp_rast_state *state = arg.set_state; |
| 332 | |
Brian Paul | a08d630 | 2009-12-04 14:11:25 -0700 | [diff] [blame] | 333 | LP_DBG(DEBUG_RAST, "%s %p\n", __FUNCTION__, (void *) state); |
Brian Paul | ffd0759 | 2009-12-03 14:57:44 -0700 | [diff] [blame] | 334 | |
Brian Paul | b1659b9 | 2009-12-04 11:50:40 -0700 | [diff] [blame] | 335 | /* just set the current state pointer for this rasterizer */ |
Brian Paul | 3a06c11 | 2009-12-07 17:02:17 -0700 | [diff] [blame] | 336 | rast->tasks[thread_index].current_state = state; |
Brian Paul | ffd0759 | 2009-12-03 14:57:44 -0700 | [diff] [blame] | 337 | } |
| 338 | |
| 339 | |
| 340 | |
Brian Paul | ffd0759 | 2009-12-03 14:57:44 -0700 | [diff] [blame] | 341 | /** |
| 342 | * Run the shader on all blocks in a tile. This is used when a tile is |
| 343 | * completely contained inside a triangle. |
| 344 | * This is a bin command called during bin processing. |
| 345 | */ |
Keith Whitwell | 89498d0 | 2009-10-07 22:36:43 +0100 | [diff] [blame] | 346 | void lp_rast_shade_tile( struct lp_rasterizer *rast, |
Brian Paul | 3a06c11 | 2009-12-07 17:02:17 -0700 | [diff] [blame] | 347 | unsigned thread_index, |
Keith Whitwell | 4cdd10c | 2009-10-09 11:29:01 +0100 | [diff] [blame] | 348 | const union lp_rast_cmd_arg arg ) |
Keith Whitwell | 89498d0 | 2009-10-07 22:36:43 +0100 | [diff] [blame] | 349 | { |
Brian Paul | ec459f2 | 2010-01-19 16:58:25 -0700 | [diff] [blame] | 350 | struct lp_rasterizer_task *task = &rast->tasks[thread_index]; |
| 351 | const struct lp_rast_state *state = task->current_state; |
| 352 | struct lp_rast_tile *tile = &task->tile; |
Keith Whitwell | 4cdd10c | 2009-10-09 11:29:01 +0100 | [diff] [blame] | 353 | const struct lp_rast_shader_inputs *inputs = arg.shade_tile; |
Brian Paul | ec459f2 | 2010-01-19 16:58:25 -0700 | [diff] [blame] | 354 | const unsigned tile_x = task->x; |
| 355 | const unsigned tile_y = task->y; |
José Fonseca | 86dba3e | 2009-10-08 19:16:47 +0100 | [diff] [blame] | 356 | unsigned x, y; |
Keith Whitwell | 89498d0 | 2009-10-07 22:36:43 +0100 | [diff] [blame] | 357 | |
Brian Paul | a08d630 | 2009-12-04 14:11:25 -0700 | [diff] [blame] | 358 | LP_DBG(DEBUG_RAST, "%s\n", __FUNCTION__); |
Keith Whitwell | 4e1334c | 2009-10-09 14:02:39 +0100 | [diff] [blame] | 359 | |
Brian Paul | 2797f2b | 2010-01-15 11:21:16 -0700 | [diff] [blame] | 360 | /* render the whole 64x64 tile in 4x4 chunks */ |
| 361 | for (y = 0; y < TILE_SIZE; y += 4){ |
| 362 | for (x = 0; x < TILE_SIZE; x += 4) { |
| 363 | uint8_t *color[PIPE_MAX_COLOR_BUFS]; |
| 364 | uint32_t *depth; |
| 365 | unsigned block_offset, i; |
| 366 | |
| 367 | /* offset of the 16x16 pixel block within the tile */ |
| 368 | block_offset = ((y / 4) * (16 * 16) + (x / 4) * 16); |
| 369 | |
| 370 | /* color buffer */ |
| 371 | for (i = 0; i < rast->state.fb.nr_cbufs; i++) |
| 372 | color[i] = tile->color[i] + 4 * block_offset; |
| 373 | |
| 374 | /* depth buffer */ |
| 375 | depth = tile->depth + block_offset; |
| 376 | |
| 377 | /* run shader */ |
| 378 | state->jit_function[0]( &state->jit_context, |
| 379 | tile_x + x, tile_y + y, |
| 380 | inputs->a0, |
| 381 | inputs->dadx, |
| 382 | inputs->dady, |
| 383 | color, |
| 384 | depth, |
| 385 | INT_MIN, INT_MIN, INT_MIN, |
| 386 | NULL, NULL, NULL ); |
| 387 | } |
| 388 | } |
Keith Whitwell | 89498d0 | 2009-10-07 22:36:43 +0100 | [diff] [blame] | 389 | } |
| 390 | |
José Fonseca | a6676d8 | 2009-10-08 12:44:30 +0100 | [diff] [blame] | 391 | |
Brian Paul | 866e685 | 2009-12-02 15:13:45 -0700 | [diff] [blame] | 392 | /** |
| 393 | * Compute shading for a 4x4 block of pixels. |
Brian Paul | ffd0759 | 2009-12-03 14:57:44 -0700 | [diff] [blame] | 394 | * This is a bin command called during bin processing. |
Brian Paul | 866e685 | 2009-12-02 15:13:45 -0700 | [diff] [blame] | 395 | */ |
José Fonseca | ab76b2a | 2009-10-08 19:03:14 +0100 | [diff] [blame] | 396 | void lp_rast_shade_quads( struct lp_rasterizer *rast, |
Brian Paul | 3a06c11 | 2009-12-07 17:02:17 -0700 | [diff] [blame] | 397 | unsigned thread_index, |
José Fonseca | ab76b2a | 2009-10-08 19:03:14 +0100 | [diff] [blame] | 398 | const struct lp_rast_shader_inputs *inputs, |
| 399 | unsigned x, unsigned y, |
Brian Paul | ab94381 | 2009-12-16 16:02:59 -0700 | [diff] [blame] | 400 | int32_t c1, int32_t c2, int32_t c3) |
José Fonseca | a6676d8 | 2009-10-08 12:44:30 +0100 | [diff] [blame] | 401 | { |
Brian Paul | ec459f2 | 2010-01-19 16:58:25 -0700 | [diff] [blame] | 402 | struct lp_rasterizer_task *task = &rast->tasks[thread_index]; |
| 403 | const struct lp_rast_state *state = task->current_state; |
| 404 | struct lp_rast_tile *tile = &task->tile; |
Keith Whitwell | c1a0441 | 2010-01-10 17:22:09 +0000 | [diff] [blame] | 405 | uint8_t *color[PIPE_MAX_COLOR_BUFS]; |
José Fonseca | 86dba3e | 2009-10-08 19:16:47 +0100 | [diff] [blame] | 406 | void *depth; |
Keith Whitwell | c1a0441 | 2010-01-10 17:22:09 +0000 | [diff] [blame] | 407 | unsigned i; |
Keith Whitwell | 7b116e1 | 2009-10-20 03:17:17 +0100 | [diff] [blame] | 408 | unsigned ix, iy; |
Brian Paul | 866e685 | 2009-12-02 15:13:45 -0700 | [diff] [blame] | 409 | int block_offset; |
José Fonseca | a6676d8 | 2009-10-08 12:44:30 +0100 | [diff] [blame] | 410 | |
Brian Paul | ab94381 | 2009-12-16 16:02:59 -0700 | [diff] [blame] | 411 | #ifdef DEBUG |
Brian Paul | b1659b9 | 2009-12-04 11:50:40 -0700 | [diff] [blame] | 412 | assert(state); |
| 413 | |
José Fonseca | a6676d8 | 2009-10-08 12:44:30 +0100 | [diff] [blame] | 414 | /* Sanity checks */ |
José Fonseca | a6676d8 | 2009-10-08 12:44:30 +0100 | [diff] [blame] | 415 | assert(x % TILE_VECTOR_WIDTH == 0); |
| 416 | assert(y % TILE_VECTOR_HEIGHT == 0); |
José Fonseca | a6676d8 | 2009-10-08 12:44:30 +0100 | [diff] [blame] | 417 | |
Brian Paul | cdbcd96 | 2009-12-15 15:39:48 -0700 | [diff] [blame] | 418 | assert((x % 4) == 0); |
| 419 | assert((y % 4) == 0); |
Brian Paul | ab94381 | 2009-12-16 16:02:59 -0700 | [diff] [blame] | 420 | #endif |
Brian Paul | 866e685 | 2009-12-02 15:13:45 -0700 | [diff] [blame] | 421 | |
José Fonseca | 61f3eeb | 2009-10-09 19:16:36 +0100 | [diff] [blame] | 422 | ix = x % TILE_SIZE; |
| 423 | iy = y % TILE_SIZE; |
| 424 | |
Brian Paul | 866e685 | 2009-12-02 15:13:45 -0700 | [diff] [blame] | 425 | /* offset of the 16x16 pixel block within the tile */ |
Brian Paul | 2797f2b | 2010-01-15 11:21:16 -0700 | [diff] [blame] | 426 | block_offset = ((iy / 4) * (16 * 16) + (ix / 4) * 16); |
Brian Paul | 866e685 | 2009-12-02 15:13:45 -0700 | [diff] [blame] | 427 | |
José Fonseca | a6676d8 | 2009-10-08 12:44:30 +0100 | [diff] [blame] | 428 | /* color buffer */ |
Keith Whitwell | c1a0441 | 2010-01-10 17:22:09 +0000 | [diff] [blame] | 429 | for (i = 0; i < rast->state.fb.nr_cbufs; i++) |
| 430 | color[i] = tile->color[i] + 4 * block_offset; |
José Fonseca | a6676d8 | 2009-10-08 12:44:30 +0100 | [diff] [blame] | 431 | |
| 432 | /* depth buffer */ |
Brian Paul | 866e685 | 2009-12-02 15:13:45 -0700 | [diff] [blame] | 433 | depth = tile->depth + block_offset; |
José Fonseca | a6676d8 | 2009-10-08 12:44:30 +0100 | [diff] [blame] | 434 | |
Keith Whitwell | c1a0441 | 2010-01-10 17:22:09 +0000 | [diff] [blame] | 435 | |
| 436 | |
Brian Paul | ab94381 | 2009-12-16 16:02:59 -0700 | [diff] [blame] | 437 | #ifdef DEBUG |
Keith Whitwell | c1a0441 | 2010-01-10 17:22:09 +0000 | [diff] [blame] | 438 | assert(lp_check_alignment(tile->depth, 16)); |
| 439 | assert(lp_check_alignment(tile->color[0], 16)); |
José Fonseca | 8599969 | 2009-10-09 15:52:18 +0100 | [diff] [blame] | 440 | assert(lp_check_alignment(state->jit_context.blend_color, 16)); |
José Fonseca | a6676d8 | 2009-10-08 12:44:30 +0100 | [diff] [blame] | 441 | |
Brian Paul | ab94381 | 2009-12-16 16:02:59 -0700 | [diff] [blame] | 442 | assert(lp_check_alignment(inputs->step[0], 16)); |
| 443 | assert(lp_check_alignment(inputs->step[1], 16)); |
| 444 | assert(lp_check_alignment(inputs->step[2], 16)); |
| 445 | #endif |
| 446 | |
José Fonseca | a6676d8 | 2009-10-08 12:44:30 +0100 | [diff] [blame] | 447 | /* run shader */ |
Brian Paul | 2797f2b | 2010-01-15 11:21:16 -0700 | [diff] [blame] | 448 | state->jit_function[1]( &state->jit_context, |
José Fonseca | 61f3eeb | 2009-10-09 19:16:36 +0100 | [diff] [blame] | 449 | x, y, |
José Fonseca | 8599969 | 2009-10-09 15:52:18 +0100 | [diff] [blame] | 450 | inputs->a0, |
| 451 | inputs->dadx, |
| 452 | inputs->dady, |
José Fonseca | 8599969 | 2009-10-09 15:52:18 +0100 | [diff] [blame] | 453 | color, |
Brian Paul | ab94381 | 2009-12-16 16:02:59 -0700 | [diff] [blame] | 454 | depth, |
| 455 | c1, c2, c3, |
Keith Whitwell | c1a0441 | 2010-01-10 17:22:09 +0000 | [diff] [blame] | 456 | inputs->step[0], inputs->step[1], inputs->step[2]); |
José Fonseca | a6676d8 | 2009-10-08 12:44:30 +0100 | [diff] [blame] | 457 | } |
| 458 | |
| 459 | |
Brian Paul | 62623c4 | 2010-01-18 13:10:10 -0700 | [diff] [blame] | 460 | /** |
| 461 | * Set top row and left column of the tile's pixels to white. For debugging. |
| 462 | */ |
| 463 | static void |
| 464 | outline_tile(uint8_t *tile) |
| 465 | { |
| 466 | const uint8_t val = 0xff; |
| 467 | unsigned i; |
| 468 | |
| 469 | for (i = 0; i < TILE_SIZE; i++) { |
| 470 | TILE_PIXEL(tile, i, 0, 0) = val; |
| 471 | TILE_PIXEL(tile, i, 0, 1) = val; |
| 472 | TILE_PIXEL(tile, i, 0, 2) = val; |
| 473 | TILE_PIXEL(tile, i, 0, 3) = val; |
| 474 | |
| 475 | TILE_PIXEL(tile, 0, i, 0) = val; |
| 476 | TILE_PIXEL(tile, 0, i, 1) = val; |
| 477 | TILE_PIXEL(tile, 0, i, 2) = val; |
| 478 | TILE_PIXEL(tile, 0, i, 3) = val; |
| 479 | } |
| 480 | } |
Brian Paul | 62623c4 | 2010-01-18 13:10:10 -0700 | [diff] [blame] | 481 | |
| 482 | |
Brian Paul | 62623c4 | 2010-01-18 13:10:10 -0700 | [diff] [blame] | 483 | /** |
| 484 | * Draw grid of gray lines at 16-pixel intervals across the tile to |
| 485 | * show the sub-tile boundaries. For debugging. |
| 486 | */ |
| 487 | static void |
| 488 | outline_subtiles(uint8_t *tile) |
| 489 | { |
| 490 | const uint8_t val = 0x80; |
| 491 | const unsigned step = 16; |
| 492 | unsigned i, j; |
| 493 | |
Brian Paul | 0fccfc9 | 2010-01-19 09:30:44 -0700 | [diff] [blame] | 494 | for (i = 0; i < TILE_SIZE; i += step) { |
Brian Paul | 62623c4 | 2010-01-18 13:10:10 -0700 | [diff] [blame] | 495 | for (j = 0; j < TILE_SIZE; j++) { |
| 496 | TILE_PIXEL(tile, i, j, 0) = val; |
| 497 | TILE_PIXEL(tile, i, j, 1) = val; |
| 498 | TILE_PIXEL(tile, i, j, 2) = val; |
| 499 | TILE_PIXEL(tile, i, j, 3) = val; |
| 500 | |
| 501 | TILE_PIXEL(tile, j, i, 0) = val; |
| 502 | TILE_PIXEL(tile, j, i, 1) = val; |
| 503 | TILE_PIXEL(tile, j, i, 2) = val; |
| 504 | TILE_PIXEL(tile, j, i, 3) = val; |
| 505 | } |
| 506 | } |
| 507 | |
| 508 | outline_tile(tile); |
| 509 | } |
Brian Paul | 62623c4 | 2010-01-18 13:10:10 -0700 | [diff] [blame] | 510 | |
José Fonseca | 37b86aa | 2009-10-08 17:59:44 +0100 | [diff] [blame] | 511 | |
| 512 | |
Brian Paul | 7505510 | 2009-11-30 14:02:01 -0700 | [diff] [blame] | 513 | /** |
| 514 | * Write the rasterizer's color tile to the framebuffer. |
| 515 | */ |
Brian Paul | 3a06c11 | 2009-12-07 17:02:17 -0700 | [diff] [blame] | 516 | static void lp_rast_store_color( struct lp_rasterizer *rast, |
| 517 | unsigned thread_index) |
Keith Whitwell | 89498d0 | 2009-10-07 22:36:43 +0100 | [diff] [blame] | 518 | { |
Brian Paul | ec459f2 | 2010-01-19 16:58:25 -0700 | [diff] [blame] | 519 | struct lp_rasterizer_task *task = &rast->tasks[thread_index]; |
| 520 | const unsigned x = task->x; |
| 521 | const unsigned y = task->y; |
Keith Whitwell | c1a0441 | 2010-01-10 17:22:09 +0000 | [diff] [blame] | 522 | unsigned i; |
José Fonseca | 37b86aa | 2009-10-08 17:59:44 +0100 | [diff] [blame] | 523 | |
Keith Whitwell | c1a0441 | 2010-01-10 17:22:09 +0000 | [diff] [blame] | 524 | for (i = 0; i < rast->state.fb.nr_cbufs; i++) { |
| 525 | struct pipe_transfer *transfer = rast->cbuf_transfer[i]; |
| 526 | int w = TILE_SIZE; |
| 527 | int h = TILE_SIZE; |
Keith Whitwell | 05131f7 | 2009-10-09 16:19:00 +0100 | [diff] [blame] | 528 | |
Keith Whitwell | c1a0441 | 2010-01-10 17:22:09 +0000 | [diff] [blame] | 529 | if (x >= transfer->width) |
| 530 | continue; |
Brian Paul | 73e13c3 | 2009-12-07 18:18:37 -0700 | [diff] [blame] | 531 | |
Keith Whitwell | c1a0441 | 2010-01-10 17:22:09 +0000 | [diff] [blame] | 532 | if (y >= transfer->height) |
| 533 | continue; |
Keith Whitwell | 05131f7 | 2009-10-09 16:19:00 +0100 | [diff] [blame] | 534 | |
Keith Whitwell | c1a0441 | 2010-01-10 17:22:09 +0000 | [diff] [blame] | 535 | LP_DBG(DEBUG_RAST, "%s [%u] %d,%d %dx%d\n", __FUNCTION__, |
| 536 | thread_index, x, y, w, h); |
| 537 | |
Brian Paul | 62623c4 | 2010-01-18 13:10:10 -0700 | [diff] [blame] | 538 | if (LP_DEBUG & DEBUG_SHOW_SUBTILES) |
Brian Paul | ec459f2 | 2010-01-19 16:58:25 -0700 | [diff] [blame] | 539 | outline_subtiles(task->tile.color[i]); |
Brian Paul | 62623c4 | 2010-01-18 13:10:10 -0700 | [diff] [blame] | 540 | else if (LP_DEBUG & DEBUG_SHOW_TILES) |
Brian Paul | ec459f2 | 2010-01-19 16:58:25 -0700 | [diff] [blame] | 541 | outline_tile(task->tile.color[i]); |
Brian Paul | 62623c4 | 2010-01-18 13:10:10 -0700 | [diff] [blame] | 542 | |
Keith Whitwell | c1a0441 | 2010-01-10 17:22:09 +0000 | [diff] [blame] | 543 | lp_tile_write_4ub(transfer->texture->format, |
Brian Paul | ec459f2 | 2010-01-19 16:58:25 -0700 | [diff] [blame] | 544 | task->tile.color[i], |
Keith Whitwell | c1a0441 | 2010-01-10 17:22:09 +0000 | [diff] [blame] | 545 | rast->cbuf_map[i], |
| 546 | transfer->stride, |
| 547 | x, y, |
| 548 | w, h); |
| 549 | } |
Keith Whitwell | 89498d0 | 2009-10-07 22:36:43 +0100 | [diff] [blame] | 550 | } |
| 551 | |
José Fonseca | 4751004 | 2009-10-09 10:37:24 +0100 | [diff] [blame] | 552 | |
Brian Paul | 51663f0 | 2009-12-03 11:41:45 -0700 | [diff] [blame] | 553 | static void |
| 554 | lp_tile_write_z32(const uint32_t *src, uint8_t *dst, unsigned dst_stride, |
| 555 | unsigned x0, unsigned y0, unsigned w, unsigned h) |
| 556 | { |
| 557 | unsigned x, y; |
| 558 | uint8_t *dst_row = dst + y0*dst_stride; |
| 559 | for (y = 0; y < h; ++y) { |
| 560 | uint32_t *dst_pixel = (uint32_t *)(dst_row + x0*4); |
| 561 | for (x = 0; x < w; ++x) { |
| 562 | *dst_pixel++ = *src++; |
| 563 | } |
| 564 | dst_row += dst_stride; |
| 565 | } |
| 566 | } |
| 567 | |
Brian Paul | 7505510 | 2009-11-30 14:02:01 -0700 | [diff] [blame] | 568 | /** |
| 569 | * Write the rasterizer's z/stencil tile to the framebuffer. |
| 570 | */ |
Brian Paul | 3a06c11 | 2009-12-07 17:02:17 -0700 | [diff] [blame] | 571 | static void lp_rast_store_zstencil( struct lp_rasterizer *rast, |
| 572 | unsigned thread_index ) |
José Fonseca | 4751004 | 2009-10-09 10:37:24 +0100 | [diff] [blame] | 573 | { |
Brian Paul | ec459f2 | 2010-01-19 16:58:25 -0700 | [diff] [blame] | 574 | struct lp_rasterizer_task *task = &rast->tasks[thread_index]; |
| 575 | const unsigned x = task->x; |
| 576 | const unsigned y = task->y; |
Brian Paul | 51663f0 | 2009-12-03 11:41:45 -0700 | [diff] [blame] | 577 | unsigned w = TILE_SIZE; |
| 578 | unsigned h = TILE_SIZE; |
Keith Whitwell | 4e1334c | 2009-10-09 14:02:39 +0100 | [diff] [blame] | 579 | |
Brian Paul | 156eabb | 2009-12-11 11:46:23 -0700 | [diff] [blame] | 580 | if (x + w > rast->state.fb.width) |
| 581 | w -= x + w - rast->state.fb.width; |
Brian Paul | 51663f0 | 2009-12-03 11:41:45 -0700 | [diff] [blame] | 582 | |
Brian Paul | 156eabb | 2009-12-11 11:46:23 -0700 | [diff] [blame] | 583 | if (y + h > rast->state.fb.height) |
| 584 | h -= y + h - rast->state.fb.height; |
Brian Paul | 51663f0 | 2009-12-03 11:41:45 -0700 | [diff] [blame] | 585 | |
Brian Paul | a08d630 | 2009-12-04 14:11:25 -0700 | [diff] [blame] | 586 | LP_DBG(DEBUG_RAST, "%s %d,%d %dx%d\n", __FUNCTION__, x, y, w, h); |
Brian Paul | 51663f0 | 2009-12-03 11:41:45 -0700 | [diff] [blame] | 587 | |
José Fonseca | 080c40a | 2010-01-08 15:42:57 +0000 | [diff] [blame] | 588 | assert(rast->zsbuf_transfer->texture->format == PIPE_FORMAT_Z32_UNORM); |
Brian Paul | ec459f2 | 2010-01-19 16:58:25 -0700 | [diff] [blame] | 589 | lp_tile_write_z32(task->tile.depth, |
Brian Paul | 51663f0 | 2009-12-03 11:41:45 -0700 | [diff] [blame] | 590 | rast->zsbuf_map, |
| 591 | rast->zsbuf_transfer->stride, |
| 592 | x, y, w, h); |
José Fonseca | 4751004 | 2009-10-09 10:37:24 +0100 | [diff] [blame] | 593 | } |
| 594 | |
| 595 | |
Brian Paul | 7505510 | 2009-11-30 14:02:01 -0700 | [diff] [blame] | 596 | /** |
| 597 | * Write the rasterizer's tiles to the framebuffer. |
| 598 | */ |
Brian Paul | b533b56 | 2009-12-04 14:47:40 -0700 | [diff] [blame] | 599 | static void |
Brian Paul | 3a06c11 | 2009-12-07 17:02:17 -0700 | [diff] [blame] | 600 | lp_rast_end_tile( struct lp_rasterizer *rast, |
| 601 | unsigned thread_index ) |
José Fonseca | 4751004 | 2009-10-09 10:37:24 +0100 | [diff] [blame] | 602 | { |
Brian Paul | a08d630 | 2009-12-04 14:11:25 -0700 | [diff] [blame] | 603 | LP_DBG(DEBUG_RAST, "%s\n", __FUNCTION__); |
Keith Whitwell | 4e1334c | 2009-10-09 14:02:39 +0100 | [diff] [blame] | 604 | |
José Fonseca | 4751004 | 2009-10-09 10:37:24 +0100 | [diff] [blame] | 605 | if (rast->state.write_color) |
Brian Paul | 3a06c11 | 2009-12-07 17:02:17 -0700 | [diff] [blame] | 606 | lp_rast_store_color(rast, thread_index); |
José Fonseca | 4751004 | 2009-10-09 10:37:24 +0100 | [diff] [blame] | 607 | |
| 608 | if (rast->state.write_zstencil) |
Brian Paul | 3a06c11 | 2009-12-07 17:02:17 -0700 | [diff] [blame] | 609 | lp_rast_store_zstencil(rast, thread_index); |
José Fonseca | 4751004 | 2009-10-09 10:37:24 +0100 | [diff] [blame] | 610 | } |
| 611 | |
| 612 | |
Brian Paul | b533b56 | 2009-12-04 14:47:40 -0700 | [diff] [blame] | 613 | /** |
Brian Paul | 4b70af9 | 2009-12-11 17:57:45 -0700 | [diff] [blame] | 614 | * Signal on a fence. This is called during bin execution/rasterization. |
| 615 | * Called per thread. |
| 616 | */ |
| 617 | void lp_rast_fence( struct lp_rasterizer *rast, |
| 618 | unsigned thread_index, |
| 619 | const union lp_rast_cmd_arg arg ) |
| 620 | { |
| 621 | struct lp_fence *fence = arg.fence; |
| 622 | |
| 623 | pipe_mutex_lock( fence->mutex ); |
| 624 | |
| 625 | fence->count++; |
| 626 | assert(fence->count <= fence->rank); |
| 627 | |
| 628 | LP_DBG(DEBUG_RAST, "%s count=%u rank=%u\n", __FUNCTION__, |
| 629 | fence->count, fence->rank); |
| 630 | |
| 631 | pipe_condvar_signal( fence->signalled ); |
| 632 | |
| 633 | pipe_mutex_unlock( fence->mutex ); |
| 634 | } |
| 635 | |
| 636 | |
| 637 | /** |
Keith Whitwell | 663750d | 2009-12-13 18:17:25 +0000 | [diff] [blame] | 638 | * When all the threads are done rasterizing a scene, one thread will |
| 639 | * call this function to reset the scene and put it onto the empty queue. |
Brian Paul | 2bce5c1 | 2009-12-11 14:52:42 -0700 | [diff] [blame] | 640 | */ |
| 641 | static void |
Keith Whitwell | 663750d | 2009-12-13 18:17:25 +0000 | [diff] [blame] | 642 | release_scene( struct lp_rasterizer *rast, |
| 643 | struct lp_scene *scene ) |
Brian Paul | 2bce5c1 | 2009-12-11 14:52:42 -0700 | [diff] [blame] | 644 | { |
Keith Whitwell | 663750d | 2009-12-13 18:17:25 +0000 | [diff] [blame] | 645 | util_unreference_framebuffer_state( &scene->fb ); |
Brian Paul | 2bce5c1 | 2009-12-11 14:52:42 -0700 | [diff] [blame] | 646 | |
Keith Whitwell | 663750d | 2009-12-13 18:17:25 +0000 | [diff] [blame] | 647 | lp_scene_reset( scene ); |
| 648 | lp_scene_enqueue( rast->empty_scenes, scene ); |
| 649 | rast->curr_scene = NULL; |
Brian Paul | 2bce5c1 | 2009-12-11 14:52:42 -0700 | [diff] [blame] | 650 | } |
| 651 | |
| 652 | |
| 653 | /** |
Brian Paul | b533b56 | 2009-12-04 14:47:40 -0700 | [diff] [blame] | 654 | * Rasterize commands for a single bin. |
Brian Paul | 01b1900 | 2009-12-04 15:31:09 -0700 | [diff] [blame] | 655 | * \param x, y position of the bin's tile in the framebuffer |
Brian Paul | b533b56 | 2009-12-04 14:47:40 -0700 | [diff] [blame] | 656 | * Must be called between lp_rast_begin() and lp_rast_end(). |
Brian Paul | 9509f73 | 2009-12-10 14:56:30 -0700 | [diff] [blame] | 657 | * Called per thread. |
Brian Paul | b533b56 | 2009-12-04 14:47:40 -0700 | [diff] [blame] | 658 | */ |
Brian Paul | 01b1900 | 2009-12-04 15:31:09 -0700 | [diff] [blame] | 659 | static void |
| 660 | rasterize_bin( struct lp_rasterizer *rast, |
Brian Paul | 3a06c11 | 2009-12-07 17:02:17 -0700 | [diff] [blame] | 661 | unsigned thread_index, |
Brian Paul | 01b1900 | 2009-12-04 15:31:09 -0700 | [diff] [blame] | 662 | const struct cmd_bin *bin, |
| 663 | int x, int y) |
Brian Paul | b533b56 | 2009-12-04 14:47:40 -0700 | [diff] [blame] | 664 | { |
| 665 | const struct cmd_block_list *commands = &bin->commands; |
| 666 | struct cmd_block *block; |
| 667 | unsigned k; |
| 668 | |
Brian Paul | 3a06c11 | 2009-12-07 17:02:17 -0700 | [diff] [blame] | 669 | lp_rast_start_tile( rast, thread_index, x, y ); |
Brian Paul | b533b56 | 2009-12-04 14:47:40 -0700 | [diff] [blame] | 670 | |
| 671 | /* simply execute each of the commands in the block list */ |
| 672 | for (block = commands->head; block; block = block->next) { |
| 673 | for (k = 0; k < block->count; k++) { |
Brian Paul | aab1cec | 2009-12-07 18:01:12 -0700 | [diff] [blame] | 674 | block->cmd[k]( rast, thread_index, block->arg[k] ); |
Brian Paul | b533b56 | 2009-12-04 14:47:40 -0700 | [diff] [blame] | 675 | } |
| 676 | } |
| 677 | |
Brian Paul | 3a06c11 | 2009-12-07 17:02:17 -0700 | [diff] [blame] | 678 | lp_rast_end_tile( rast, thread_index ); |
Brian Paul | b533b56 | 2009-12-04 14:47:40 -0700 | [diff] [blame] | 679 | } |
| 680 | |
Keith Whitwell | 4231006 | 2010-01-13 20:14:04 +0000 | [diff] [blame] | 681 | |
| 682 | #define RAST(x) { lp_rast_##x, #x } |
| 683 | |
| 684 | static struct { |
| 685 | lp_rast_cmd cmd; |
| 686 | const char *name; |
| 687 | } cmd_names[] = |
| 688 | { |
| 689 | RAST(load_color), |
| 690 | RAST(load_zstencil), |
| 691 | RAST(clear_color), |
| 692 | RAST(clear_zstencil), |
| 693 | RAST(triangle), |
| 694 | RAST(shade_tile), |
| 695 | RAST(set_state), |
| 696 | RAST(fence), |
| 697 | }; |
| 698 | |
| 699 | static void |
| 700 | debug_bin( const struct cmd_bin *bin ) |
| 701 | { |
| 702 | const struct cmd_block *head = bin->commands.head; |
| 703 | int i, j; |
| 704 | |
| 705 | for (i = 0; i < head->count; i++) { |
| 706 | debug_printf("%d: ", i); |
| 707 | for (j = 0; j < Elements(cmd_names); j++) { |
| 708 | if (head->cmd[i] == cmd_names[j].cmd) { |
| 709 | debug_printf("%s\n", cmd_names[j].name); |
| 710 | break; |
| 711 | } |
| 712 | } |
| 713 | if (j == Elements(cmd_names)) |
| 714 | debug_printf("...other\n"); |
| 715 | } |
| 716 | |
| 717 | } |
| 718 | |
Keith Whitwell | db83ad4 | 2010-01-13 16:29:39 +0000 | [diff] [blame] | 719 | /* An empty bin is one that just loads the contents of the tile and |
| 720 | * stores them again unchanged. This typically happens when bins have |
| 721 | * been flushed for some reason in the middle of a frame, or when |
| 722 | * incremental updates are being made to a render target. |
| 723 | * |
| 724 | * Try to avoid doing pointless work in this case. |
| 725 | */ |
Keith Whitwell | da45f49 | 2010-01-13 14:41:02 +0000 | [diff] [blame] | 726 | static boolean |
Keith Whitwell | db83ad4 | 2010-01-13 16:29:39 +0000 | [diff] [blame] | 727 | is_empty_bin( const struct cmd_bin *bin ) |
Keith Whitwell | da45f49 | 2010-01-13 14:41:02 +0000 | [diff] [blame] | 728 | { |
| 729 | const struct cmd_block *head = bin->commands.head; |
| 730 | int i; |
Keith Whitwell | 4231006 | 2010-01-13 20:14:04 +0000 | [diff] [blame] | 731 | |
| 732 | if (0) |
| 733 | debug_bin(bin); |
| 734 | |
Keith Whitwell | db83ad4 | 2010-01-13 16:29:39 +0000 | [diff] [blame] | 735 | /* We emit at most two load-tile commands at the start of the first |
Keith Whitwell | 4231006 | 2010-01-13 20:14:04 +0000 | [diff] [blame] | 736 | * command block. In addition we seem to emit a couple of |
| 737 | * set-state commands even in empty bins. |
| 738 | * |
| 739 | * As a heuristic, if a bin has more than 4 commands, consider it |
| 740 | * non-empty. |
Keith Whitwell | db83ad4 | 2010-01-13 16:29:39 +0000 | [diff] [blame] | 741 | */ |
Keith Whitwell | da45f49 | 2010-01-13 14:41:02 +0000 | [diff] [blame] | 742 | if (head->next != NULL || |
Keith Whitwell | 4231006 | 2010-01-13 20:14:04 +0000 | [diff] [blame] | 743 | head->count > 4) { |
Keith Whitwell | da45f49 | 2010-01-13 14:41:02 +0000 | [diff] [blame] | 744 | return FALSE; |
Keith Whitwell | 4231006 | 2010-01-13 20:14:04 +0000 | [diff] [blame] | 745 | } |
Keith Whitwell | da45f49 | 2010-01-13 14:41:02 +0000 | [diff] [blame] | 746 | |
| 747 | for (i = 0; i < head->count; i++) |
| 748 | if (head->cmd[i] != lp_rast_load_color && |
Keith Whitwell | 4231006 | 2010-01-13 20:14:04 +0000 | [diff] [blame] | 749 | head->cmd[i] != lp_rast_load_zstencil && |
| 750 | head->cmd[i] != lp_rast_set_state) { |
Keith Whitwell | da45f49 | 2010-01-13 14:41:02 +0000 | [diff] [blame] | 751 | return FALSE; |
Keith Whitwell | 4231006 | 2010-01-13 20:14:04 +0000 | [diff] [blame] | 752 | } |
Keith Whitwell | da45f49 | 2010-01-13 14:41:02 +0000 | [diff] [blame] | 753 | |
| 754 | return TRUE; |
| 755 | } |
| 756 | |
| 757 | |
Brian Paul | b533b56 | 2009-12-04 14:47:40 -0700 | [diff] [blame] | 758 | |
Brian Paul | 01b1900 | 2009-12-04 15:31:09 -0700 | [diff] [blame] | 759 | /** |
Keith Whitwell | 663750d | 2009-12-13 18:17:25 +0000 | [diff] [blame] | 760 | * Rasterize/execute all bins within a scene. |
Brian Paul | 9509f73 | 2009-12-10 14:56:30 -0700 | [diff] [blame] | 761 | * Called per thread. |
Brian Paul | 01b1900 | 2009-12-04 15:31:09 -0700 | [diff] [blame] | 762 | */ |
Brian Paul | aab1cec | 2009-12-07 18:01:12 -0700 | [diff] [blame] | 763 | static void |
Keith Whitwell | 663750d | 2009-12-13 18:17:25 +0000 | [diff] [blame] | 764 | rasterize_scene( struct lp_rasterizer *rast, |
Brian Paul | aab1cec | 2009-12-07 18:01:12 -0700 | [diff] [blame] | 765 | unsigned thread_index, |
Keith Whitwell | 663750d | 2009-12-13 18:17:25 +0000 | [diff] [blame] | 766 | struct lp_scene *scene, |
Brian Paul | aab1cec | 2009-12-07 18:01:12 -0700 | [diff] [blame] | 767 | bool write_depth ) |
| 768 | { |
Keith Whitwell | 663750d | 2009-12-13 18:17:25 +0000 | [diff] [blame] | 769 | /* loop over scene bins, rasterize each */ |
Brian Paul | aab1cec | 2009-12-07 18:01:12 -0700 | [diff] [blame] | 770 | #if 0 |
| 771 | { |
| 772 | unsigned i, j; |
Keith Whitwell | 663750d | 2009-12-13 18:17:25 +0000 | [diff] [blame] | 773 | for (i = 0; i < scene->tiles_x; i++) { |
| 774 | for (j = 0; j < scene->tiles_y; j++) { |
| 775 | struct cmd_bin *bin = lp_get_bin(scene, i, j); |
Brian Paul | aab1cec | 2009-12-07 18:01:12 -0700 | [diff] [blame] | 776 | rasterize_bin( rast, thread_index, |
| 777 | bin, i * TILE_SIZE, j * TILE_SIZE ); |
| 778 | } |
| 779 | } |
| 780 | } |
| 781 | #else |
| 782 | { |
| 783 | struct cmd_bin *bin; |
| 784 | int x, y; |
| 785 | |
Keith Whitwell | 663750d | 2009-12-13 18:17:25 +0000 | [diff] [blame] | 786 | assert(scene); |
| 787 | while ((bin = lp_scene_bin_iter_next(scene, &x, &y))) { |
Keith Whitwell | db83ad4 | 2010-01-13 16:29:39 +0000 | [diff] [blame] | 788 | if (!is_empty_bin( bin )) |
Keith Whitwell | da45f49 | 2010-01-13 14:41:02 +0000 | [diff] [blame] | 789 | rasterize_bin( rast, thread_index, bin, x * TILE_SIZE, y * TILE_SIZE); |
Brian Paul | aab1cec | 2009-12-07 18:01:12 -0700 | [diff] [blame] | 790 | } |
| 791 | } |
| 792 | #endif |
| 793 | } |
| 794 | |
| 795 | |
| 796 | /** |
Brian Paul | 4e67f10 | 2009-12-11 11:16:48 -0700 | [diff] [blame] | 797 | * Called by setup module when it has something for us to render. |
Brian Paul | aab1cec | 2009-12-07 18:01:12 -0700 | [diff] [blame] | 798 | */ |
Brian Paul | 01b1900 | 2009-12-04 15:31:09 -0700 | [diff] [blame] | 799 | void |
Keith Whitwell | 663750d | 2009-12-13 18:17:25 +0000 | [diff] [blame] | 800 | lp_rasterize_scene( struct lp_rasterizer *rast, |
| 801 | struct lp_scene *scene, |
Brian Paul | 01b1900 | 2009-12-04 15:31:09 -0700 | [diff] [blame] | 802 | const struct pipe_framebuffer_state *fb, |
| 803 | bool write_depth ) |
| 804 | { |
Brian Paul | 96689d4 | 2009-12-09 16:32:32 -0700 | [diff] [blame] | 805 | boolean debug = false; |
| 806 | |
Brian Paul | 01b1900 | 2009-12-04 15:31:09 -0700 | [diff] [blame] | 807 | LP_DBG(DEBUG_SETUP, "%s\n", __FUNCTION__); |
| 808 | |
Brian Paul | 96689d4 | 2009-12-09 16:32:32 -0700 | [diff] [blame] | 809 | if (debug) { |
| 810 | unsigned x, y; |
José Fonseca | a1af8ee | 2010-02-05 13:48:35 +0000 | [diff] [blame] | 811 | debug_printf("rasterize scene:\n"); |
| 812 | debug_printf(" data size: %u\n", lp_scene_data_size(scene)); |
Keith Whitwell | 663750d | 2009-12-13 18:17:25 +0000 | [diff] [blame] | 813 | for (y = 0; y < scene->tiles_y; y++) { |
| 814 | for (x = 0; x < scene->tiles_x; x++) { |
José Fonseca | a1af8ee | 2010-02-05 13:48:35 +0000 | [diff] [blame] | 815 | debug_printf(" bin %u, %u size: %u\n", x, y, |
| 816 | lp_scene_bin_size(scene, x, y)); |
Brian Paul | 96689d4 | 2009-12-09 16:32:32 -0700 | [diff] [blame] | 817 | } |
| 818 | } |
| 819 | } |
| 820 | |
Brian Paul | 2bce5c1 | 2009-12-11 14:52:42 -0700 | [diff] [blame] | 821 | /* save framebuffer state in the bin */ |
Keith Whitwell | 663750d | 2009-12-13 18:17:25 +0000 | [diff] [blame] | 822 | util_copy_framebuffer_state(&scene->fb, fb); |
| 823 | scene->write_depth = write_depth; |
Brian Paul | aab1cec | 2009-12-07 18:01:12 -0700 | [diff] [blame] | 824 | |
| 825 | if (rast->num_threads == 0) { |
| 826 | /* no threading */ |
Brian Paul | 2bce5c1 | 2009-12-11 14:52:42 -0700 | [diff] [blame] | 827 | |
| 828 | lp_rast_begin( rast, fb, |
Keith Whitwell | c1a0441 | 2010-01-10 17:22:09 +0000 | [diff] [blame] | 829 | fb->nr_cbufs != 0, /* always write color if cbufs present */ |
Brian Paul | 2bce5c1 | 2009-12-11 14:52:42 -0700 | [diff] [blame] | 830 | fb->zsbuf != NULL && write_depth ); |
| 831 | |
Keith Whitwell | 663750d | 2009-12-13 18:17:25 +0000 | [diff] [blame] | 832 | lp_scene_bin_iter_begin( scene ); |
| 833 | rasterize_scene( rast, 0, scene, write_depth ); |
Brian Paul | 3bee8c2 | 2009-12-09 16:02:30 -0700 | [diff] [blame] | 834 | |
Keith Whitwell | 663750d | 2009-12-13 18:17:25 +0000 | [diff] [blame] | 835 | release_scene( rast, scene ); |
Brian Paul | 2bce5c1 | 2009-12-11 14:52:42 -0700 | [diff] [blame] | 836 | |
| 837 | lp_rast_end( rast ); |
Brian Paul | 01b1900 | 2009-12-04 15:31:09 -0700 | [diff] [blame] | 838 | } |
Brian Paul | aab1cec | 2009-12-07 18:01:12 -0700 | [diff] [blame] | 839 | else { |
| 840 | /* threaded rendering! */ |
| 841 | unsigned i; |
| 842 | |
Keith Whitwell | 663750d | 2009-12-13 18:17:25 +0000 | [diff] [blame] | 843 | lp_scene_enqueue( rast->full_scenes, scene ); |
Brian Paul | 9509f73 | 2009-12-10 14:56:30 -0700 | [diff] [blame] | 844 | |
Brian Paul | aab1cec | 2009-12-07 18:01:12 -0700 | [diff] [blame] | 845 | /* signal the threads that there's work to do */ |
| 846 | for (i = 0; i < rast->num_threads; i++) { |
| 847 | pipe_semaphore_signal(&rast->tasks[i].work_ready); |
| 848 | } |
| 849 | |
| 850 | /* wait for work to complete */ |
| 851 | for (i = 0; i < rast->num_threads; i++) { |
| 852 | pipe_semaphore_wait(&rast->tasks[i].work_done); |
Brian Paul | cdaea04 | 2009-12-07 15:31:50 -0700 | [diff] [blame] | 853 | } |
| 854 | } |
Brian Paul | 01b1900 | 2009-12-04 15:31:09 -0700 | [diff] [blame] | 855 | |
Brian Paul | 01b1900 | 2009-12-04 15:31:09 -0700 | [diff] [blame] | 856 | LP_DBG(DEBUG_SETUP, "%s done \n", __FUNCTION__); |
| 857 | } |
| 858 | |
| 859 | |
Brian Paul | aab1cec | 2009-12-07 18:01:12 -0700 | [diff] [blame] | 860 | /** |
| 861 | * This is the thread's main entrypoint. |
| 862 | * It's a simple loop: |
| 863 | * 1. wait for work |
| 864 | * 2. do work |
| 865 | * 3. signal that we're done |
| 866 | */ |
José Fonseca | a1af8ee | 2010-02-05 13:48:35 +0000 | [diff] [blame] | 867 | static PIPE_THREAD_ROUTINE( thread_func, init_data ) |
Brian Paul | aab1cec | 2009-12-07 18:01:12 -0700 | [diff] [blame] | 868 | { |
| 869 | struct lp_rasterizer_task *task = (struct lp_rasterizer_task *) init_data; |
| 870 | struct lp_rasterizer *rast = task->rast; |
Brian Paul | 9509f73 | 2009-12-10 14:56:30 -0700 | [diff] [blame] | 871 | boolean debug = false; |
Brian Paul | aab1cec | 2009-12-07 18:01:12 -0700 | [diff] [blame] | 872 | |
| 873 | while (1) { |
| 874 | /* wait for work */ |
| 875 | if (debug) |
| 876 | debug_printf("thread %d waiting for work\n", task->thread_index); |
| 877 | pipe_semaphore_wait(&task->work_ready); |
| 878 | |
Brian Paul | 2bce5c1 | 2009-12-11 14:52:42 -0700 | [diff] [blame] | 879 | if (task->thread_index == 0) { |
| 880 | /* thread[0]: |
Keith Whitwell | 663750d | 2009-12-13 18:17:25 +0000 | [diff] [blame] | 881 | * - get next scene to rasterize |
Brian Paul | 2bce5c1 | 2009-12-11 14:52:42 -0700 | [diff] [blame] | 882 | * - map the framebuffer surfaces |
| 883 | */ |
| 884 | const struct pipe_framebuffer_state *fb; |
| 885 | boolean write_depth; |
| 886 | |
Keith Whitwell | 591401f | 2010-01-16 21:12:10 +0000 | [diff] [blame] | 887 | rast->curr_scene = lp_scene_dequeue( rast->full_scenes, TRUE ); |
Brian Paul | 2bce5c1 | 2009-12-11 14:52:42 -0700 | [diff] [blame] | 888 | |
Keith Whitwell | 663750d | 2009-12-13 18:17:25 +0000 | [diff] [blame] | 889 | lp_scene_bin_iter_begin( rast->curr_scene ); |
Brian Paul | 2bce5c1 | 2009-12-11 14:52:42 -0700 | [diff] [blame] | 890 | |
Keith Whitwell | 663750d | 2009-12-13 18:17:25 +0000 | [diff] [blame] | 891 | fb = &rast->curr_scene->fb; |
| 892 | write_depth = rast->curr_scene->write_depth; |
Brian Paul | 2bce5c1 | 2009-12-11 14:52:42 -0700 | [diff] [blame] | 893 | |
| 894 | lp_rast_begin( rast, fb, |
Keith Whitwell | c1a0441 | 2010-01-10 17:22:09 +0000 | [diff] [blame] | 895 | fb->nr_cbufs != 0, |
Brian Paul | 2bce5c1 | 2009-12-11 14:52:42 -0700 | [diff] [blame] | 896 | fb->zsbuf != NULL && write_depth ); |
| 897 | } |
| 898 | |
| 899 | /* Wait for all threads to get here so that threads[1+] don't |
Keith Whitwell | 663750d | 2009-12-13 18:17:25 +0000 | [diff] [blame] | 900 | * get a null rast->curr_scene pointer. |
Brian Paul | 2bce5c1 | 2009-12-11 14:52:42 -0700 | [diff] [blame] | 901 | */ |
| 902 | pipe_barrier_wait( &rast->barrier ); |
Brian Paul | 9509f73 | 2009-12-10 14:56:30 -0700 | [diff] [blame] | 903 | |
Brian Paul | aab1cec | 2009-12-07 18:01:12 -0700 | [diff] [blame] | 904 | /* do work */ |
| 905 | if (debug) |
| 906 | debug_printf("thread %d doing work\n", task->thread_index); |
Keith Whitwell | 663750d | 2009-12-13 18:17:25 +0000 | [diff] [blame] | 907 | rasterize_scene(rast, |
| 908 | task->thread_index, |
| 909 | rast->curr_scene, |
| 910 | rast->curr_scene->write_depth); |
Brian Paul | 9509f73 | 2009-12-10 14:56:30 -0700 | [diff] [blame] | 911 | |
Keith Whitwell | 663750d | 2009-12-13 18:17:25 +0000 | [diff] [blame] | 912 | /* wait for all threads to finish with this scene */ |
Brian Paul | 2bce5c1 | 2009-12-11 14:52:42 -0700 | [diff] [blame] | 913 | pipe_barrier_wait( &rast->barrier ); |
| 914 | |
| 915 | if (task->thread_index == 0) { |
| 916 | /* thread[0]: |
Keith Whitwell | 663750d | 2009-12-13 18:17:25 +0000 | [diff] [blame] | 917 | * - release the scene object |
Brian Paul | 2bce5c1 | 2009-12-11 14:52:42 -0700 | [diff] [blame] | 918 | * - unmap the framebuffer surfaces |
| 919 | */ |
Keith Whitwell | 663750d | 2009-12-13 18:17:25 +0000 | [diff] [blame] | 920 | release_scene( rast, rast->curr_scene ); |
Brian Paul | 2bce5c1 | 2009-12-11 14:52:42 -0700 | [diff] [blame] | 921 | lp_rast_end( rast ); |
| 922 | } |
Brian Paul | aab1cec | 2009-12-07 18:01:12 -0700 | [diff] [blame] | 923 | |
| 924 | /* signal done with work */ |
| 925 | if (debug) |
| 926 | debug_printf("thread %d done working\n", task->thread_index); |
| 927 | pipe_semaphore_signal(&task->work_done); |
| 928 | } |
| 929 | |
| 930 | return NULL; |
| 931 | } |
| 932 | |
| 933 | |
| 934 | /** |
| 935 | * Initialize semaphores and spawn the threads. |
| 936 | */ |
| 937 | static void |
| 938 | create_rast_threads(struct lp_rasterizer *rast) |
| 939 | { |
| 940 | unsigned i; |
| 941 | |
José Fonseca | ad60552 | 2010-02-05 13:56:01 +0000 | [diff] [blame] | 942 | #ifdef PIPE_OS_WINDOWS |
| 943 | /* Multithreading not supported on windows until conditions and barriers are |
| 944 | * properly implemented. */ |
| 945 | rast->num_threads = 0; |
| 946 | #else |
José Fonseca | 7f457ac | 2009-12-08 08:02:49 +0000 | [diff] [blame] | 947 | rast->num_threads = util_cpu_caps.nr_cpus; |
| 948 | rast->num_threads = debug_get_num_option("LP_NUM_THREADS", rast->num_threads); |
Brian Paul | aab1cec | 2009-12-07 18:01:12 -0700 | [diff] [blame] | 949 | rast->num_threads = MIN2(rast->num_threads, MAX_THREADS); |
José Fonseca | ad60552 | 2010-02-05 13:56:01 +0000 | [diff] [blame] | 950 | #endif |
Brian Paul | aab1cec | 2009-12-07 18:01:12 -0700 | [diff] [blame] | 951 | |
| 952 | /* NOTE: if num_threads is zero, we won't use any threads */ |
| 953 | for (i = 0; i < rast->num_threads; i++) { |
| 954 | pipe_semaphore_init(&rast->tasks[i].work_ready, 0); |
| 955 | pipe_semaphore_init(&rast->tasks[i].work_done, 0); |
| 956 | rast->threads[i] = pipe_thread_create(thread_func, |
| 957 | (void *) &rast->tasks[i]); |
| 958 | } |
| 959 | } |
| 960 | |
| 961 | |
| 962 | |
Brian Paul | d7dbc66 | 2009-12-09 14:53:33 -0700 | [diff] [blame] | 963 | /** |
| 964 | * Create new lp_rasterizer. |
Keith Whitwell | 663750d | 2009-12-13 18:17:25 +0000 | [diff] [blame] | 965 | * \param empty the queue to put empty scenes on after we've finished |
Brian Paul | d7dbc66 | 2009-12-09 14:53:33 -0700 | [diff] [blame] | 966 | * processing them. |
| 967 | */ |
| 968 | struct lp_rasterizer * |
Keith Whitwell | 663750d | 2009-12-13 18:17:25 +0000 | [diff] [blame] | 969 | lp_rast_create( struct pipe_screen *screen, struct lp_scene_queue *empty ) |
Brian Paul | aab1cec | 2009-12-07 18:01:12 -0700 | [diff] [blame] | 970 | { |
| 971 | struct lp_rasterizer *rast; |
Keith Whitwell | c1a0441 | 2010-01-10 17:22:09 +0000 | [diff] [blame] | 972 | unsigned i, cbuf; |
Brian Paul | aab1cec | 2009-12-07 18:01:12 -0700 | [diff] [blame] | 973 | |
| 974 | rast = CALLOC_STRUCT(lp_rasterizer); |
| 975 | if(!rast) |
| 976 | return NULL; |
| 977 | |
| 978 | rast->screen = screen; |
| 979 | |
Keith Whitwell | 663750d | 2009-12-13 18:17:25 +0000 | [diff] [blame] | 980 | rast->empty_scenes = empty; |
| 981 | rast->full_scenes = lp_scene_queue_create(); |
Brian Paul | d7dbc66 | 2009-12-09 14:53:33 -0700 | [diff] [blame] | 982 | |
Brian Paul | aab1cec | 2009-12-07 18:01:12 -0700 | [diff] [blame] | 983 | for (i = 0; i < Elements(rast->tasks); i++) { |
Brian Paul | ec459f2 | 2010-01-19 16:58:25 -0700 | [diff] [blame] | 984 | struct lp_rasterizer_task *task = &rast->tasks[i]; |
Keith Whitwell | c1a0441 | 2010-01-10 17:22:09 +0000 | [diff] [blame] | 985 | |
Brian Paul | ec459f2 | 2010-01-19 16:58:25 -0700 | [diff] [blame] | 986 | for (cbuf = 0; cbuf < PIPE_MAX_COLOR_BUFS; cbuf++ ) |
| 987 | task->tile.color[cbuf] = align_malloc(TILE_SIZE * TILE_SIZE * 4, 16); |
| 988 | |
| 989 | task->tile.depth = align_malloc(TILE_SIZE * TILE_SIZE * 4, 16); |
| 990 | task->rast = rast; |
| 991 | task->thread_index = i; |
Brian Paul | aab1cec | 2009-12-07 18:01:12 -0700 | [diff] [blame] | 992 | } |
| 993 | |
| 994 | create_rast_threads(rast); |
| 995 | |
Brian Paul | 2bce5c1 | 2009-12-11 14:52:42 -0700 | [diff] [blame] | 996 | /* for synchronizing rasterization threads */ |
| 997 | pipe_barrier_init( &rast->barrier, rast->num_threads ); |
| 998 | |
Brian Paul | aab1cec | 2009-12-07 18:01:12 -0700 | [diff] [blame] | 999 | return rast; |
| 1000 | } |
| 1001 | |
Brian Paul | b533b56 | 2009-12-04 14:47:40 -0700 | [diff] [blame] | 1002 | |
Keith Whitwell | 89498d0 | 2009-10-07 22:36:43 +0100 | [diff] [blame] | 1003 | /* Shutdown: |
| 1004 | */ |
| 1005 | void lp_rast_destroy( struct lp_rasterizer *rast ) |
| 1006 | { |
Keith Whitwell | c1a0441 | 2010-01-10 17:22:09 +0000 | [diff] [blame] | 1007 | unsigned i, cbuf; |
Brian Paul | 3a06c11 | 2009-12-07 17:02:17 -0700 | [diff] [blame] | 1008 | |
Brian Paul | 156eabb | 2009-12-11 11:46:23 -0700 | [diff] [blame] | 1009 | util_unreference_framebuffer_state(&rast->state.fb); |
Brian Paul | 3a06c11 | 2009-12-07 17:02:17 -0700 | [diff] [blame] | 1010 | |
| 1011 | for (i = 0; i < Elements(rast->tasks); i++) { |
| 1012 | align_free(rast->tasks[i].tile.depth); |
Keith Whitwell | c1a0441 | 2010-01-10 17:22:09 +0000 | [diff] [blame] | 1013 | for (cbuf = 0; cbuf < PIPE_MAX_COLOR_BUFS; cbuf++ ) |
| 1014 | align_free(rast->tasks[i].tile.color[cbuf]); |
Brian Paul | 3a06c11 | 2009-12-07 17:02:17 -0700 | [diff] [blame] | 1015 | } |
| 1016 | |
Brian Paul | 2bce5c1 | 2009-12-11 14:52:42 -0700 | [diff] [blame] | 1017 | /* for synchronizing rasterization threads */ |
| 1018 | pipe_barrier_destroy( &rast->barrier ); |
| 1019 | |
Keith Whitwell | 89498d0 | 2009-10-07 22:36:43 +0100 | [diff] [blame] | 1020 | FREE(rast); |
| 1021 | } |
| 1022 | |
Brian Paul | 9323740 | 2009-12-11 17:45:52 -0700 | [diff] [blame] | 1023 | |
| 1024 | /** Return number of rasterization threads */ |
| 1025 | unsigned |
| 1026 | lp_rast_get_num_threads( struct lp_rasterizer *rast ) |
| 1027 | { |
| 1028 | return rast->num_threads; |
| 1029 | } |