blob: 7855e03bed1c807716179a38cdfe9e46cbac0f56 [file] [log] [blame]
José Fonsecad614ced2009-10-08 12:51:46 +01001/**************************************************************************
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 Paulab943812009-12-16 16:02:59 -070028#include <limits.h>
José Fonsecad614ced2009-10-08 12:51:46 +010029#include "util/u_memory.h"
Brian Paulaab1cec2009-12-07 18:01:12 -070030#include "util/u_math.h"
José Fonseca7f457ac2009-12-08 08:02:49 +000031#include "util/u_cpu_detect.h"
Brian Paul156eabb2009-12-11 11:46:23 -070032#include "util/u_surface.h"
José Fonsecad614ced2009-10-08 12:51:46 +010033
Keith Whitwell663750d2009-12-13 18:17:25 +000034#include "lp_scene_queue.h"
Brian Paula08d6302009-12-04 14:11:25 -070035#include "lp_debug.h"
Brian Paul4b70af92009-12-11 17:57:45 -070036#include "lp_fence.h"
José Fonsecad614ced2009-10-08 12:51:46 +010037#include "lp_rast.h"
José Fonseca92158412009-10-08 17:26:13 +010038#include "lp_rast_priv.h"
39#include "lp_tile_soa.h"
Zack Rusinc61bf362010-02-08 18:05:22 -050040#include "gallivm/lp_bld_debug.h"
Keith Whitwell663750d2009-12-13 18:17:25 +000041#include "lp_scene.h"
José Fonsecad614ced2009-10-08 12:51:46 +010042
Keith Whitwell89498d02009-10-07 22:36:43 +010043
Brian Paul75055102009-11-30 14:02:01 -070044/**
45 * Begin the rasterization phase.
46 * Map the framebuffer surfaces. Initialize the 'rast' state.
47 */
Brian Paul01b19002009-12-04 15:31:09 -070048static boolean
49lp_rast_begin( struct lp_rasterizer *rast,
Brian Paul156eabb2009-12-11 11:46:23 -070050 const struct pipe_framebuffer_state *fb,
51 boolean write_color,
52 boolean write_zstencil )
Keith Whitwell84ab7dc2009-10-09 10:24:19 +010053{
Keith Whitwelle0e20082009-10-09 14:29:25 +010054 struct pipe_screen *screen = rast->screen;
Brian Paul156eabb2009-12-11 11:46:23 -070055 struct pipe_surface *cbuf, *zsbuf;
Keith Whitwellc1a04412010-01-10 17:22:09 +000056 int i;
Keith Whitwelle0e20082009-10-09 14:29:25 +010057
Brian Paul156eabb2009-12-11 11:46:23 -070058 LP_DBG(DEBUG_RAST, "%s\n", __FUNCTION__);
Keith Whitwell4e1334c2009-10-09 14:02:39 +010059
Brian Paul156eabb2009-12-11 11:46:23 -070060 util_copy_framebuffer_state(&rast->state.fb, fb);
Keith Whitwelle0e20082009-10-09 14:29:25 +010061
Keith Whitwelle0e20082009-10-09 14:29:25 +010062 rast->state.write_zstencil = write_zstencil;
63 rast->state.write_color = write_color;
64
Brian Paul156eabb2009-12-11 11:46:23 -070065 rast->check_for_clipped_tiles = (fb->width % TILE_SIZE != 0 ||
66 fb->height % TILE_SIZE != 0);
Keith Whitwelle0e20082009-10-09 14:29:25 +010067
Keith Whitwellc1a04412010-01-10 17:22:09 +000068
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 Whitwelle0e20082009-10-09 14:29:25 +010083
Keith Whitwellc1a04412010-01-10 17:22:09 +000084 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 Whitwelle0e20082009-10-09 14:29:25 +010089 }
90
Brian Paul156eabb2009-12-11 11:46:23 -070091 zsbuf = rast->state.fb.zsbuf;
Brian Paul51663f02009-12-03 11:41:45 -070092 if (zsbuf) {
93 rast->zsbuf_transfer = screen->get_tex_transfer(rast->screen,
Brian Paul156eabb2009-12-11 11:46:23 -070094 zsbuf->texture,
95 zsbuf->face,
96 zsbuf->level,
97 zsbuf->zslice,
98 PIPE_TRANSFER_READ_WRITE,
99 0, 0,
Keith Whitwellc1a04412010-01-10 17:22:09 +0000100 zsbuf->width,
101 zsbuf->height);
Brian Paul51663f02009-12-03 11:41:45 -0700102 if (!rast->zsbuf_transfer)
Keith Whitwellc1a04412010-01-10 17:22:09 +0000103 goto fail;
Brian Paul51663f02009-12-03 11:41:45 -0700104
105 rast->zsbuf_map = screen->transfer_map(rast->screen,
106 rast->zsbuf_transfer);
107 if (!rast->zsbuf_map)
Keith Whitwellc1a04412010-01-10 17:22:09 +0000108 goto fail;
Brian Paul51663f02009-12-03 11:41:45 -0700109 }
110
Keith Whitwelle0e20082009-10-09 14:29:25 +0100111 return TRUE;
Keith Whitwellc1a04412010-01-10 17:22:09 +0000112
113fail:
114 /* Unmap and release transfers?
115 */
116 return FALSE;
Keith Whitwell84ab7dc2009-10-09 10:24:19 +0100117}
118
Keith Whitwelle0e20082009-10-09 14:29:25 +0100119
Brian Paul75055102009-11-30 14:02:01 -0700120/**
121 * Finish the rasterization phase.
122 * Unmap framebuffer surfaces.
123 */
Brian Paul01b19002009-12-04 15:31:09 -0700124static void
125lp_rast_end( struct lp_rasterizer *rast )
Keith Whitwell89498d02009-10-07 22:36:43 +0100126{
Keith Whitwelle0e20082009-10-09 14:29:25 +0100127 struct pipe_screen *screen = rast->screen;
Keith Whitwellc1a04412010-01-10 17:22:09 +0000128 unsigned i;
Keith Whitwell4e1334c2009-10-09 14:02:39 +0100129
Keith Whitwellc1a04412010-01-10 17:22:09 +0000130 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 Whitwelle0e20082009-10-09 14:29:25 +0100140
141 if (rast->zsbuf_map)
142 screen->transfer_unmap(screen, rast->zsbuf_transfer);
143
Keith Whitwelle0e20082009-10-09 14:29:25 +0100144 if (rast->zsbuf_transfer)
Brian Paul51663f02009-12-03 11:41:45 -0700145 screen->tex_transfer_destroy(rast->zsbuf_transfer);
Keith Whitwelle0e20082009-10-09 14:29:25 +0100146
Keith Whitwelle0e20082009-10-09 14:29:25 +0100147 rast->zsbuf_transfer = NULL;
Keith Whitwelle0e20082009-10-09 14:29:25 +0100148 rast->zsbuf_map = NULL;
Keith Whitwell0718c772009-10-08 19:58:28 +0100149}
150
Keith Whitwell4e1334c2009-10-09 14:02:39 +0100151
Brian Paul75055102009-11-30 14:02:01 -0700152/**
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 Whitwell89498d02009-10-07 22:36:43 +0100156 */
Brian Paulb533b562009-12-04 14:47:40 -0700157static void
158lp_rast_start_tile( struct lp_rasterizer *rast,
Brian Paul3a06c112009-12-07 17:02:17 -0700159 unsigned thread_index,
Brian Paulb533b562009-12-04 14:47:40 -0700160 unsigned x, unsigned y )
Keith Whitwell89498d02009-10-07 22:36:43 +0100161{
Brian Paula08d6302009-12-04 14:11:25 -0700162 LP_DBG(DEBUG_RAST, "%s %d,%d\n", __FUNCTION__, x, y);
Keith Whitwell4e1334c2009-10-09 14:02:39 +0100163
Brian Paul3a06c112009-12-07 17:02:17 -0700164 rast->tasks[thread_index].x = x;
165 rast->tasks[thread_index].y = y;
Keith Whitwell89498d02009-10-07 22:36:43 +0100166}
167
Brian Paul75055102009-11-30 14:02:01 -0700168
169/**
170 * Clear the rasterizer's current color tile.
Brian Paulffd07592009-12-03 14:57:44 -0700171 * This is a bin command called during bin processing.
Brian Paul75055102009-11-30 14:02:01 -0700172 */
Keith Whitwelld0c918b2009-10-08 17:20:40 +0100173void lp_rast_clear_color( struct lp_rasterizer *rast,
Brian Paul3a06c112009-12-07 17:02:17 -0700174 unsigned thread_index,
Keith Whitwell4cdd10c2009-10-09 11:29:01 +0100175 const union lp_rast_cmd_arg arg )
Keith Whitwell89498d02009-10-07 22:36:43 +0100176{
Keith Whitwell4cdd10c2009-10-09 11:29:01 +0100177 const uint8_t *clear_color = arg.clear_color;
Keith Whitwellc1a04412010-01-10 17:22:09 +0000178 uint8_t **color_tile = rast->tasks[thread_index].tile.color;
179 unsigned i;
180
Brian Paula08d6302009-12-04 14:11:25 -0700181 LP_DBG(DEBUG_RAST, "%s 0x%x,0x%x,0x%x,0x%x\n", __FUNCTION__,
Keith Whitwell295aea02009-10-09 14:07:25 +0100182 clear_color[0],
183 clear_color[1],
184 clear_color[2],
185 clear_color[3]);
Keith Whitwell4e1334c2009-10-09 14:02:39 +0100186
José Fonseca37b86aa2009-10-08 17:59:44 +0100187 if (clear_color[0] == clear_color[1] &&
188 clear_color[1] == clear_color[2] &&
189 clear_color[2] == clear_color[3]) {
Brian Paulf94a9912010-01-13 18:54:48 -0700190 /* clear to grayscale value {x, x, x, x} */
Keith Whitwellc1a04412010-01-10 17:22:09 +0000191 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é Fonseca37b86aa2009-10-08 17:59:44 +0100194 }
195 else {
Brian Paulf94a9912010-01-13 18:54:48 -0700196 /* 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é Fonseca37b86aa2009-10-08 17:59:44 +0100217 }
Keith Whitwell89498d02009-10-07 22:36:43 +0100218}
219
Brian Paul75055102009-11-30 14:02:01 -0700220
221/**
222 * Clear the rasterizer's current z/stencil tile.
Brian Paulffd07592009-12-03 14:57:44 -0700223 * This is a bin command called during bin processing.
Brian Paul75055102009-11-30 14:02:01 -0700224 */
Keith Whitwelld0c918b2009-10-08 17:20:40 +0100225void lp_rast_clear_zstencil( struct lp_rasterizer *rast,
Brian Paul3a06c112009-12-07 17:02:17 -0700226 unsigned thread_index,
Keith Whitwell4cdd10c2009-10-09 11:29:01 +0100227 const union lp_rast_cmd_arg arg)
Keith Whitwell89498d02009-10-07 22:36:43 +0100228{
Brian Paul2ba1c812010-01-13 18:58:38 -0700229 unsigned i;
Brian Paul3a06c112009-12-07 17:02:17 -0700230 uint32_t *depth_tile = rast->tasks[thread_index].tile.depth;
Keith Whitwell89498d02009-10-07 22:36:43 +0100231
Brian Paula08d6302009-12-04 14:11:25 -0700232 LP_DBG(DEBUG_RAST, "%s 0x%x\n", __FUNCTION__, arg.clear_zstencil);
Keith Whitwell4e1334c2009-10-09 14:02:39 +0100233
Brian Paul2ba1c812010-01-13 18:58:38 -0700234 for (i = 0; i < TILE_SIZE * TILE_SIZE; i++)
235 depth_tile[i] = arg.clear_zstencil;
Keith Whitwell89498d02009-10-07 22:36:43 +0100236}
237
Keith Whitwell89498d02009-10-07 22:36:43 +0100238
Brian Paulffd07592009-12-03 14:57:44 -0700239/**
240 * Load tile color from the framebuffer surface.
241 * This is a bin command called during bin processing.
242 */
Keith Whitwelld0c918b2009-10-08 17:20:40 +0100243void lp_rast_load_color( struct lp_rasterizer *rast,
Brian Paul3a06c112009-12-07 17:02:17 -0700244 unsigned thread_index,
Keith Whitwell4cdd10c2009-10-09 11:29:01 +0100245 const union lp_rast_cmd_arg arg)
Keith Whitwell89498d02009-10-07 22:36:43 +0100246{
Brian Paul92dc0f92009-12-11 15:00:28 -0700247 struct lp_rasterizer_task *task = &rast->tasks[thread_index];
248 const unsigned x = task->x;
249 const unsigned y = task->y;
Keith Whitwellc1a04412010-01-10 17:22:09 +0000250 unsigned i;
Keith Whitwell4e1334c2009-10-09 14:02:39 +0100251
Brian Paul92dc0f92009-12-11 15:00:28 -0700252 LP_DBG(DEBUG_RAST, "%s at %u, %u\n", __FUNCTION__, x, y);
253
Keith Whitwellc1a04412010-01-10 17:22:09 +0000254 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 Paul92dc0f92009-12-11 15:00:28 -0700258
Keith Whitwellc1a04412010-01-10 17:22:09 +0000259 if (x >= transfer->width)
260 continue;
Brian Paul92dc0f92009-12-11 15:00:28 -0700261
Keith Whitwellc1a04412010-01-10 17:22:09 +0000262 if (y >= transfer->height)
263 continue;
Keith Whitwellc1a04412010-01-10 17:22:09 +0000264
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 Paulec459f22010-01-19 16:58:25 -0700271 task->tile.color[i],
Keith Whitwellc1a04412010-01-10 17:22:09 +0000272 rast->cbuf_map[i],
273 transfer->stride,
274 x, y,
275 w, h);
276 }
Keith Whitwell89498d02009-10-07 22:36:43 +0100277}
278
Brian Paulffd07592009-12-03 14:57:44 -0700279
Keith Whitwell95ee14f2010-01-13 16:52:17 +0000280static void
281lp_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 Paulffd07592009-12-03 14:57:44 -0700297/**
298 * Load tile z/stencil from the framebuffer surface.
299 * This is a bin command called during bin processing.
300 */
Keith Whitwelld0c918b2009-10-08 17:20:40 +0100301void lp_rast_load_zstencil( struct lp_rasterizer *rast,
Brian Paul3a06c112009-12-07 17:02:17 -0700302 unsigned thread_index,
Keith Whitwell4cdd10c2009-10-09 11:29:01 +0100303 const union lp_rast_cmd_arg arg )
Keith Whitwell89498d02009-10-07 22:36:43 +0100304{
Brian Paulec459f22010-01-19 16:58:25 -0700305 struct lp_rasterizer_task *task = &rast->tasks[thread_index];
306 const unsigned x = task->x;
307 const unsigned y = task->y;
Keith Whitwell95ee14f2010-01-13 16:52:17 +0000308 unsigned w = TILE_SIZE;
309 unsigned h = TILE_SIZE;
Keith Whitwell4e1334c2009-10-09 14:02:39 +0100310
Keith Whitwell95ee14f2010-01-13 16:52:17 +0000311 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 Paulec459f22010-01-19 16:58:25 -0700320 lp_tile_read_z32(task->tile.depth,
Keith Whitwell95ee14f2010-01-13 16:52:17 +0000321 rast->zsbuf_map,
322 rast->zsbuf_transfer->stride,
323 x, y, w, h);
Keith Whitwell89498d02009-10-07 22:36:43 +0100324}
325
Brian Paulffd07592009-12-03 14:57:44 -0700326
327void lp_rast_set_state( struct lp_rasterizer *rast,
Brian Paul3a06c112009-12-07 17:02:17 -0700328 unsigned thread_index,
Brian Paulffd07592009-12-03 14:57:44 -0700329 const union lp_rast_cmd_arg arg )
330{
Brian Paule2f46342009-12-03 16:05:12 -0700331 const struct lp_rast_state *state = arg.set_state;
332
Brian Paula08d6302009-12-04 14:11:25 -0700333 LP_DBG(DEBUG_RAST, "%s %p\n", __FUNCTION__, (void *) state);
Brian Paulffd07592009-12-03 14:57:44 -0700334
Brian Paulb1659b92009-12-04 11:50:40 -0700335 /* just set the current state pointer for this rasterizer */
Brian Paul3a06c112009-12-07 17:02:17 -0700336 rast->tasks[thread_index].current_state = state;
Brian Paulffd07592009-12-03 14:57:44 -0700337}
338
339
340
Brian Paulffd07592009-12-03 14:57:44 -0700341/**
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 Whitwell89498d02009-10-07 22:36:43 +0100346void lp_rast_shade_tile( struct lp_rasterizer *rast,
Brian Paul3a06c112009-12-07 17:02:17 -0700347 unsigned thread_index,
Keith Whitwell4cdd10c2009-10-09 11:29:01 +0100348 const union lp_rast_cmd_arg arg )
Keith Whitwell89498d02009-10-07 22:36:43 +0100349{
Brian Paulec459f22010-01-19 16:58:25 -0700350 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 Whitwell4cdd10c2009-10-09 11:29:01 +0100353 const struct lp_rast_shader_inputs *inputs = arg.shade_tile;
Brian Paulec459f22010-01-19 16:58:25 -0700354 const unsigned tile_x = task->x;
355 const unsigned tile_y = task->y;
José Fonseca86dba3e2009-10-08 19:16:47 +0100356 unsigned x, y;
Keith Whitwell89498d02009-10-07 22:36:43 +0100357
Brian Paula08d6302009-12-04 14:11:25 -0700358 LP_DBG(DEBUG_RAST, "%s\n", __FUNCTION__);
Keith Whitwell4e1334c2009-10-09 14:02:39 +0100359
Brian Paul2797f2b2010-01-15 11:21:16 -0700360 /* 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 Whitwell89498d02009-10-07 22:36:43 +0100389}
390
José Fonsecaa6676d82009-10-08 12:44:30 +0100391
Brian Paul866e6852009-12-02 15:13:45 -0700392/**
393 * Compute shading for a 4x4 block of pixels.
Brian Paulffd07592009-12-03 14:57:44 -0700394 * This is a bin command called during bin processing.
Brian Paul866e6852009-12-02 15:13:45 -0700395 */
José Fonsecaab76b2a2009-10-08 19:03:14 +0100396void lp_rast_shade_quads( struct lp_rasterizer *rast,
Brian Paul3a06c112009-12-07 17:02:17 -0700397 unsigned thread_index,
José Fonsecaab76b2a2009-10-08 19:03:14 +0100398 const struct lp_rast_shader_inputs *inputs,
399 unsigned x, unsigned y,
Brian Paulab943812009-12-16 16:02:59 -0700400 int32_t c1, int32_t c2, int32_t c3)
José Fonsecaa6676d82009-10-08 12:44:30 +0100401{
Brian Paulec459f22010-01-19 16:58:25 -0700402 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 Whitwellc1a04412010-01-10 17:22:09 +0000405 uint8_t *color[PIPE_MAX_COLOR_BUFS];
José Fonseca86dba3e2009-10-08 19:16:47 +0100406 void *depth;
Keith Whitwellc1a04412010-01-10 17:22:09 +0000407 unsigned i;
Keith Whitwell7b116e12009-10-20 03:17:17 +0100408 unsigned ix, iy;
Brian Paul866e6852009-12-02 15:13:45 -0700409 int block_offset;
José Fonsecaa6676d82009-10-08 12:44:30 +0100410
Brian Paulab943812009-12-16 16:02:59 -0700411#ifdef DEBUG
Brian Paulb1659b92009-12-04 11:50:40 -0700412 assert(state);
413
José Fonsecaa6676d82009-10-08 12:44:30 +0100414 /* Sanity checks */
José Fonsecaa6676d82009-10-08 12:44:30 +0100415 assert(x % TILE_VECTOR_WIDTH == 0);
416 assert(y % TILE_VECTOR_HEIGHT == 0);
José Fonsecaa6676d82009-10-08 12:44:30 +0100417
Brian Paulcdbcd962009-12-15 15:39:48 -0700418 assert((x % 4) == 0);
419 assert((y % 4) == 0);
Brian Paulab943812009-12-16 16:02:59 -0700420#endif
Brian Paul866e6852009-12-02 15:13:45 -0700421
José Fonseca61f3eeb2009-10-09 19:16:36 +0100422 ix = x % TILE_SIZE;
423 iy = y % TILE_SIZE;
424
Brian Paul866e6852009-12-02 15:13:45 -0700425 /* offset of the 16x16 pixel block within the tile */
Brian Paul2797f2b2010-01-15 11:21:16 -0700426 block_offset = ((iy / 4) * (16 * 16) + (ix / 4) * 16);
Brian Paul866e6852009-12-02 15:13:45 -0700427
José Fonsecaa6676d82009-10-08 12:44:30 +0100428 /* color buffer */
Keith Whitwellc1a04412010-01-10 17:22:09 +0000429 for (i = 0; i < rast->state.fb.nr_cbufs; i++)
430 color[i] = tile->color[i] + 4 * block_offset;
José Fonsecaa6676d82009-10-08 12:44:30 +0100431
432 /* depth buffer */
Brian Paul866e6852009-12-02 15:13:45 -0700433 depth = tile->depth + block_offset;
José Fonsecaa6676d82009-10-08 12:44:30 +0100434
Keith Whitwellc1a04412010-01-10 17:22:09 +0000435
436
Brian Paulab943812009-12-16 16:02:59 -0700437#ifdef DEBUG
Keith Whitwellc1a04412010-01-10 17:22:09 +0000438 assert(lp_check_alignment(tile->depth, 16));
439 assert(lp_check_alignment(tile->color[0], 16));
José Fonseca85999692009-10-09 15:52:18 +0100440 assert(lp_check_alignment(state->jit_context.blend_color, 16));
José Fonsecaa6676d82009-10-08 12:44:30 +0100441
Brian Paulab943812009-12-16 16:02:59 -0700442 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é Fonsecaa6676d82009-10-08 12:44:30 +0100447 /* run shader */
Brian Paul2797f2b2010-01-15 11:21:16 -0700448 state->jit_function[1]( &state->jit_context,
José Fonseca61f3eeb2009-10-09 19:16:36 +0100449 x, y,
José Fonseca85999692009-10-09 15:52:18 +0100450 inputs->a0,
451 inputs->dadx,
452 inputs->dady,
José Fonseca85999692009-10-09 15:52:18 +0100453 color,
Brian Paulab943812009-12-16 16:02:59 -0700454 depth,
455 c1, c2, c3,
Keith Whitwellc1a04412010-01-10 17:22:09 +0000456 inputs->step[0], inputs->step[1], inputs->step[2]);
José Fonsecaa6676d82009-10-08 12:44:30 +0100457}
458
459
Brian Paul62623c42010-01-18 13:10:10 -0700460/**
461 * Set top row and left column of the tile's pixels to white. For debugging.
462 */
463static void
464outline_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 Paul62623c42010-01-18 13:10:10 -0700481
482
Brian Paul62623c42010-01-18 13:10:10 -0700483/**
484 * Draw grid of gray lines at 16-pixel intervals across the tile to
485 * show the sub-tile boundaries. For debugging.
486 */
487static void
488outline_subtiles(uint8_t *tile)
489{
490 const uint8_t val = 0x80;
491 const unsigned step = 16;
492 unsigned i, j;
493
Brian Paul0fccfc92010-01-19 09:30:44 -0700494 for (i = 0; i < TILE_SIZE; i += step) {
Brian Paul62623c42010-01-18 13:10:10 -0700495 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 Paul62623c42010-01-18 13:10:10 -0700510
José Fonseca37b86aa2009-10-08 17:59:44 +0100511
512
Brian Paul75055102009-11-30 14:02:01 -0700513/**
514 * Write the rasterizer's color tile to the framebuffer.
515 */
Brian Paul3a06c112009-12-07 17:02:17 -0700516static void lp_rast_store_color( struct lp_rasterizer *rast,
517 unsigned thread_index)
Keith Whitwell89498d02009-10-07 22:36:43 +0100518{
Brian Paulec459f22010-01-19 16:58:25 -0700519 struct lp_rasterizer_task *task = &rast->tasks[thread_index];
520 const unsigned x = task->x;
521 const unsigned y = task->y;
Keith Whitwellc1a04412010-01-10 17:22:09 +0000522 unsigned i;
José Fonseca37b86aa2009-10-08 17:59:44 +0100523
Keith Whitwellc1a04412010-01-10 17:22:09 +0000524 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 Whitwell05131f72009-10-09 16:19:00 +0100528
Keith Whitwellc1a04412010-01-10 17:22:09 +0000529 if (x >= transfer->width)
530 continue;
Brian Paul73e13c32009-12-07 18:18:37 -0700531
Keith Whitwellc1a04412010-01-10 17:22:09 +0000532 if (y >= transfer->height)
533 continue;
Keith Whitwell05131f72009-10-09 16:19:00 +0100534
Keith Whitwellc1a04412010-01-10 17:22:09 +0000535 LP_DBG(DEBUG_RAST, "%s [%u] %d,%d %dx%d\n", __FUNCTION__,
536 thread_index, x, y, w, h);
537
Brian Paul62623c42010-01-18 13:10:10 -0700538 if (LP_DEBUG & DEBUG_SHOW_SUBTILES)
Brian Paulec459f22010-01-19 16:58:25 -0700539 outline_subtiles(task->tile.color[i]);
Brian Paul62623c42010-01-18 13:10:10 -0700540 else if (LP_DEBUG & DEBUG_SHOW_TILES)
Brian Paulec459f22010-01-19 16:58:25 -0700541 outline_tile(task->tile.color[i]);
Brian Paul62623c42010-01-18 13:10:10 -0700542
Keith Whitwellc1a04412010-01-10 17:22:09 +0000543 lp_tile_write_4ub(transfer->texture->format,
Brian Paulec459f22010-01-19 16:58:25 -0700544 task->tile.color[i],
Keith Whitwellc1a04412010-01-10 17:22:09 +0000545 rast->cbuf_map[i],
546 transfer->stride,
547 x, y,
548 w, h);
549 }
Keith Whitwell89498d02009-10-07 22:36:43 +0100550}
551
José Fonseca47510042009-10-09 10:37:24 +0100552
Brian Paul51663f02009-12-03 11:41:45 -0700553static void
554lp_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 Paul75055102009-11-30 14:02:01 -0700568/**
569 * Write the rasterizer's z/stencil tile to the framebuffer.
570 */
Brian Paul3a06c112009-12-07 17:02:17 -0700571static void lp_rast_store_zstencil( struct lp_rasterizer *rast,
572 unsigned thread_index )
José Fonseca47510042009-10-09 10:37:24 +0100573{
Brian Paulec459f22010-01-19 16:58:25 -0700574 struct lp_rasterizer_task *task = &rast->tasks[thread_index];
575 const unsigned x = task->x;
576 const unsigned y = task->y;
Brian Paul51663f02009-12-03 11:41:45 -0700577 unsigned w = TILE_SIZE;
578 unsigned h = TILE_SIZE;
Keith Whitwell4e1334c2009-10-09 14:02:39 +0100579
Brian Paul156eabb2009-12-11 11:46:23 -0700580 if (x + w > rast->state.fb.width)
581 w -= x + w - rast->state.fb.width;
Brian Paul51663f02009-12-03 11:41:45 -0700582
Brian Paul156eabb2009-12-11 11:46:23 -0700583 if (y + h > rast->state.fb.height)
584 h -= y + h - rast->state.fb.height;
Brian Paul51663f02009-12-03 11:41:45 -0700585
Brian Paula08d6302009-12-04 14:11:25 -0700586 LP_DBG(DEBUG_RAST, "%s %d,%d %dx%d\n", __FUNCTION__, x, y, w, h);
Brian Paul51663f02009-12-03 11:41:45 -0700587
José Fonseca080c40a2010-01-08 15:42:57 +0000588 assert(rast->zsbuf_transfer->texture->format == PIPE_FORMAT_Z32_UNORM);
Brian Paulec459f22010-01-19 16:58:25 -0700589 lp_tile_write_z32(task->tile.depth,
Brian Paul51663f02009-12-03 11:41:45 -0700590 rast->zsbuf_map,
591 rast->zsbuf_transfer->stride,
592 x, y, w, h);
José Fonseca47510042009-10-09 10:37:24 +0100593}
594
595
Brian Paul75055102009-11-30 14:02:01 -0700596/**
597 * Write the rasterizer's tiles to the framebuffer.
598 */
Brian Paulb533b562009-12-04 14:47:40 -0700599static void
Brian Paul3a06c112009-12-07 17:02:17 -0700600lp_rast_end_tile( struct lp_rasterizer *rast,
601 unsigned thread_index )
José Fonseca47510042009-10-09 10:37:24 +0100602{
Brian Paula08d6302009-12-04 14:11:25 -0700603 LP_DBG(DEBUG_RAST, "%s\n", __FUNCTION__);
Keith Whitwell4e1334c2009-10-09 14:02:39 +0100604
José Fonseca47510042009-10-09 10:37:24 +0100605 if (rast->state.write_color)
Brian Paul3a06c112009-12-07 17:02:17 -0700606 lp_rast_store_color(rast, thread_index);
José Fonseca47510042009-10-09 10:37:24 +0100607
608 if (rast->state.write_zstencil)
Brian Paul3a06c112009-12-07 17:02:17 -0700609 lp_rast_store_zstencil(rast, thread_index);
José Fonseca47510042009-10-09 10:37:24 +0100610}
611
612
Brian Paulb533b562009-12-04 14:47:40 -0700613/**
Brian Paul4b70af92009-12-11 17:57:45 -0700614 * Signal on a fence. This is called during bin execution/rasterization.
615 * Called per thread.
616 */
617void 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 Whitwell663750d2009-12-13 18:17:25 +0000638 * 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 Paul2bce5c12009-12-11 14:52:42 -0700640 */
641static void
Keith Whitwell663750d2009-12-13 18:17:25 +0000642release_scene( struct lp_rasterizer *rast,
643 struct lp_scene *scene )
Brian Paul2bce5c12009-12-11 14:52:42 -0700644{
Keith Whitwell663750d2009-12-13 18:17:25 +0000645 util_unreference_framebuffer_state( &scene->fb );
Brian Paul2bce5c12009-12-11 14:52:42 -0700646
Keith Whitwell663750d2009-12-13 18:17:25 +0000647 lp_scene_reset( scene );
648 lp_scene_enqueue( rast->empty_scenes, scene );
649 rast->curr_scene = NULL;
Brian Paul2bce5c12009-12-11 14:52:42 -0700650}
651
652
653/**
Brian Paulb533b562009-12-04 14:47:40 -0700654 * Rasterize commands for a single bin.
Brian Paul01b19002009-12-04 15:31:09 -0700655 * \param x, y position of the bin's tile in the framebuffer
Brian Paulb533b562009-12-04 14:47:40 -0700656 * Must be called between lp_rast_begin() and lp_rast_end().
Brian Paul9509f732009-12-10 14:56:30 -0700657 * Called per thread.
Brian Paulb533b562009-12-04 14:47:40 -0700658 */
Brian Paul01b19002009-12-04 15:31:09 -0700659static void
660rasterize_bin( struct lp_rasterizer *rast,
Brian Paul3a06c112009-12-07 17:02:17 -0700661 unsigned thread_index,
Brian Paul01b19002009-12-04 15:31:09 -0700662 const struct cmd_bin *bin,
663 int x, int y)
Brian Paulb533b562009-12-04 14:47:40 -0700664{
665 const struct cmd_block_list *commands = &bin->commands;
666 struct cmd_block *block;
667 unsigned k;
668
Brian Paul3a06c112009-12-07 17:02:17 -0700669 lp_rast_start_tile( rast, thread_index, x, y );
Brian Paulb533b562009-12-04 14:47:40 -0700670
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 Paulaab1cec2009-12-07 18:01:12 -0700674 block->cmd[k]( rast, thread_index, block->arg[k] );
Brian Paulb533b562009-12-04 14:47:40 -0700675 }
676 }
677
Brian Paul3a06c112009-12-07 17:02:17 -0700678 lp_rast_end_tile( rast, thread_index );
Brian Paulb533b562009-12-04 14:47:40 -0700679}
680
Keith Whitwell42310062010-01-13 20:14:04 +0000681
682#define RAST(x) { lp_rast_##x, #x }
683
684static 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
699static void
700debug_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 Whitwelldb83ad42010-01-13 16:29:39 +0000719/* 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 Whitwellda45f492010-01-13 14:41:02 +0000726static boolean
Keith Whitwelldb83ad42010-01-13 16:29:39 +0000727is_empty_bin( const struct cmd_bin *bin )
Keith Whitwellda45f492010-01-13 14:41:02 +0000728{
729 const struct cmd_block *head = bin->commands.head;
730 int i;
Keith Whitwell42310062010-01-13 20:14:04 +0000731
732 if (0)
733 debug_bin(bin);
734
Keith Whitwelldb83ad42010-01-13 16:29:39 +0000735 /* We emit at most two load-tile commands at the start of the first
Keith Whitwell42310062010-01-13 20:14:04 +0000736 * 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 Whitwelldb83ad42010-01-13 16:29:39 +0000741 */
Keith Whitwellda45f492010-01-13 14:41:02 +0000742 if (head->next != NULL ||
Keith Whitwell42310062010-01-13 20:14:04 +0000743 head->count > 4) {
Keith Whitwellda45f492010-01-13 14:41:02 +0000744 return FALSE;
Keith Whitwell42310062010-01-13 20:14:04 +0000745 }
Keith Whitwellda45f492010-01-13 14:41:02 +0000746
747 for (i = 0; i < head->count; i++)
748 if (head->cmd[i] != lp_rast_load_color &&
Keith Whitwell42310062010-01-13 20:14:04 +0000749 head->cmd[i] != lp_rast_load_zstencil &&
750 head->cmd[i] != lp_rast_set_state) {
Keith Whitwellda45f492010-01-13 14:41:02 +0000751 return FALSE;
Keith Whitwell42310062010-01-13 20:14:04 +0000752 }
Keith Whitwellda45f492010-01-13 14:41:02 +0000753
754 return TRUE;
755}
756
757
Brian Paulb533b562009-12-04 14:47:40 -0700758
Brian Paul01b19002009-12-04 15:31:09 -0700759/**
Keith Whitwell663750d2009-12-13 18:17:25 +0000760 * Rasterize/execute all bins within a scene.
Brian Paul9509f732009-12-10 14:56:30 -0700761 * Called per thread.
Brian Paul01b19002009-12-04 15:31:09 -0700762 */
Brian Paulaab1cec2009-12-07 18:01:12 -0700763static void
Keith Whitwell663750d2009-12-13 18:17:25 +0000764rasterize_scene( struct lp_rasterizer *rast,
Brian Paulaab1cec2009-12-07 18:01:12 -0700765 unsigned thread_index,
Keith Whitwell663750d2009-12-13 18:17:25 +0000766 struct lp_scene *scene,
Brian Paulaab1cec2009-12-07 18:01:12 -0700767 bool write_depth )
768{
Keith Whitwell663750d2009-12-13 18:17:25 +0000769 /* loop over scene bins, rasterize each */
Brian Paulaab1cec2009-12-07 18:01:12 -0700770#if 0
771 {
772 unsigned i, j;
Keith Whitwell663750d2009-12-13 18:17:25 +0000773 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 Paulaab1cec2009-12-07 18:01:12 -0700776 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 Whitwell663750d2009-12-13 18:17:25 +0000786 assert(scene);
787 while ((bin = lp_scene_bin_iter_next(scene, &x, &y))) {
Keith Whitwelldb83ad42010-01-13 16:29:39 +0000788 if (!is_empty_bin( bin ))
Keith Whitwellda45f492010-01-13 14:41:02 +0000789 rasterize_bin( rast, thread_index, bin, x * TILE_SIZE, y * TILE_SIZE);
Brian Paulaab1cec2009-12-07 18:01:12 -0700790 }
791 }
792#endif
793}
794
795
796/**
Brian Paul4e67f102009-12-11 11:16:48 -0700797 * Called by setup module when it has something for us to render.
Brian Paulaab1cec2009-12-07 18:01:12 -0700798 */
Brian Paul01b19002009-12-04 15:31:09 -0700799void
Keith Whitwell663750d2009-12-13 18:17:25 +0000800lp_rasterize_scene( struct lp_rasterizer *rast,
801 struct lp_scene *scene,
Brian Paul01b19002009-12-04 15:31:09 -0700802 const struct pipe_framebuffer_state *fb,
803 bool write_depth )
804{
Brian Paul96689d42009-12-09 16:32:32 -0700805 boolean debug = false;
806
Brian Paul01b19002009-12-04 15:31:09 -0700807 LP_DBG(DEBUG_SETUP, "%s\n", __FUNCTION__);
808
Brian Paul96689d42009-12-09 16:32:32 -0700809 if (debug) {
810 unsigned x, y;
José Fonsecaa1af8ee2010-02-05 13:48:35 +0000811 debug_printf("rasterize scene:\n");
812 debug_printf(" data size: %u\n", lp_scene_data_size(scene));
Keith Whitwell663750d2009-12-13 18:17:25 +0000813 for (y = 0; y < scene->tiles_y; y++) {
814 for (x = 0; x < scene->tiles_x; x++) {
José Fonsecaa1af8ee2010-02-05 13:48:35 +0000815 debug_printf(" bin %u, %u size: %u\n", x, y,
816 lp_scene_bin_size(scene, x, y));
Brian Paul96689d42009-12-09 16:32:32 -0700817 }
818 }
819 }
820
Brian Paul2bce5c12009-12-11 14:52:42 -0700821 /* save framebuffer state in the bin */
Keith Whitwell663750d2009-12-13 18:17:25 +0000822 util_copy_framebuffer_state(&scene->fb, fb);
823 scene->write_depth = write_depth;
Brian Paulaab1cec2009-12-07 18:01:12 -0700824
825 if (rast->num_threads == 0) {
826 /* no threading */
Brian Paul2bce5c12009-12-11 14:52:42 -0700827
828 lp_rast_begin( rast, fb,
Keith Whitwellc1a04412010-01-10 17:22:09 +0000829 fb->nr_cbufs != 0, /* always write color if cbufs present */
Brian Paul2bce5c12009-12-11 14:52:42 -0700830 fb->zsbuf != NULL && write_depth );
831
Keith Whitwell663750d2009-12-13 18:17:25 +0000832 lp_scene_bin_iter_begin( scene );
833 rasterize_scene( rast, 0, scene, write_depth );
Brian Paul3bee8c22009-12-09 16:02:30 -0700834
Keith Whitwell663750d2009-12-13 18:17:25 +0000835 release_scene( rast, scene );
Brian Paul2bce5c12009-12-11 14:52:42 -0700836
837 lp_rast_end( rast );
Brian Paul01b19002009-12-04 15:31:09 -0700838 }
Brian Paulaab1cec2009-12-07 18:01:12 -0700839 else {
840 /* threaded rendering! */
841 unsigned i;
842
Keith Whitwell663750d2009-12-13 18:17:25 +0000843 lp_scene_enqueue( rast->full_scenes, scene );
Brian Paul9509f732009-12-10 14:56:30 -0700844
Brian Paulaab1cec2009-12-07 18:01:12 -0700845 /* 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 Paulcdaea042009-12-07 15:31:50 -0700853 }
854 }
Brian Paul01b19002009-12-04 15:31:09 -0700855
Brian Paul01b19002009-12-04 15:31:09 -0700856 LP_DBG(DEBUG_SETUP, "%s done \n", __FUNCTION__);
857}
858
859
Brian Paulaab1cec2009-12-07 18:01:12 -0700860/**
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é Fonsecaa1af8ee2010-02-05 13:48:35 +0000867static PIPE_THREAD_ROUTINE( thread_func, init_data )
Brian Paulaab1cec2009-12-07 18:01:12 -0700868{
869 struct lp_rasterizer_task *task = (struct lp_rasterizer_task *) init_data;
870 struct lp_rasterizer *rast = task->rast;
Brian Paul9509f732009-12-10 14:56:30 -0700871 boolean debug = false;
Brian Paulaab1cec2009-12-07 18:01:12 -0700872
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 Paul2bce5c12009-12-11 14:52:42 -0700879 if (task->thread_index == 0) {
880 /* thread[0]:
Keith Whitwell663750d2009-12-13 18:17:25 +0000881 * - get next scene to rasterize
Brian Paul2bce5c12009-12-11 14:52:42 -0700882 * - map the framebuffer surfaces
883 */
884 const struct pipe_framebuffer_state *fb;
885 boolean write_depth;
886
Keith Whitwell591401f2010-01-16 21:12:10 +0000887 rast->curr_scene = lp_scene_dequeue( rast->full_scenes, TRUE );
Brian Paul2bce5c12009-12-11 14:52:42 -0700888
Keith Whitwell663750d2009-12-13 18:17:25 +0000889 lp_scene_bin_iter_begin( rast->curr_scene );
Brian Paul2bce5c12009-12-11 14:52:42 -0700890
Keith Whitwell663750d2009-12-13 18:17:25 +0000891 fb = &rast->curr_scene->fb;
892 write_depth = rast->curr_scene->write_depth;
Brian Paul2bce5c12009-12-11 14:52:42 -0700893
894 lp_rast_begin( rast, fb,
Keith Whitwellc1a04412010-01-10 17:22:09 +0000895 fb->nr_cbufs != 0,
Brian Paul2bce5c12009-12-11 14:52:42 -0700896 fb->zsbuf != NULL && write_depth );
897 }
898
899 /* Wait for all threads to get here so that threads[1+] don't
Keith Whitwell663750d2009-12-13 18:17:25 +0000900 * get a null rast->curr_scene pointer.
Brian Paul2bce5c12009-12-11 14:52:42 -0700901 */
902 pipe_barrier_wait( &rast->barrier );
Brian Paul9509f732009-12-10 14:56:30 -0700903
Brian Paulaab1cec2009-12-07 18:01:12 -0700904 /* do work */
905 if (debug)
906 debug_printf("thread %d doing work\n", task->thread_index);
Keith Whitwell663750d2009-12-13 18:17:25 +0000907 rasterize_scene(rast,
908 task->thread_index,
909 rast->curr_scene,
910 rast->curr_scene->write_depth);
Brian Paul9509f732009-12-10 14:56:30 -0700911
Keith Whitwell663750d2009-12-13 18:17:25 +0000912 /* wait for all threads to finish with this scene */
Brian Paul2bce5c12009-12-11 14:52:42 -0700913 pipe_barrier_wait( &rast->barrier );
914
915 if (task->thread_index == 0) {
916 /* thread[0]:
Keith Whitwell663750d2009-12-13 18:17:25 +0000917 * - release the scene object
Brian Paul2bce5c12009-12-11 14:52:42 -0700918 * - unmap the framebuffer surfaces
919 */
Keith Whitwell663750d2009-12-13 18:17:25 +0000920 release_scene( rast, rast->curr_scene );
Brian Paul2bce5c12009-12-11 14:52:42 -0700921 lp_rast_end( rast );
922 }
Brian Paulaab1cec2009-12-07 18:01:12 -0700923
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 */
937static void
938create_rast_threads(struct lp_rasterizer *rast)
939{
940 unsigned i;
941
José Fonsecaad605522010-02-05 13:56:01 +0000942#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é Fonseca7f457ac2009-12-08 08:02:49 +0000947 rast->num_threads = util_cpu_caps.nr_cpus;
948 rast->num_threads = debug_get_num_option("LP_NUM_THREADS", rast->num_threads);
Brian Paulaab1cec2009-12-07 18:01:12 -0700949 rast->num_threads = MIN2(rast->num_threads, MAX_THREADS);
José Fonsecaad605522010-02-05 13:56:01 +0000950#endif
Brian Paulaab1cec2009-12-07 18:01:12 -0700951
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 Pauld7dbc662009-12-09 14:53:33 -0700963/**
964 * Create new lp_rasterizer.
Keith Whitwell663750d2009-12-13 18:17:25 +0000965 * \param empty the queue to put empty scenes on after we've finished
Brian Pauld7dbc662009-12-09 14:53:33 -0700966 * processing them.
967 */
968struct lp_rasterizer *
Keith Whitwell663750d2009-12-13 18:17:25 +0000969lp_rast_create( struct pipe_screen *screen, struct lp_scene_queue *empty )
Brian Paulaab1cec2009-12-07 18:01:12 -0700970{
971 struct lp_rasterizer *rast;
Keith Whitwellc1a04412010-01-10 17:22:09 +0000972 unsigned i, cbuf;
Brian Paulaab1cec2009-12-07 18:01:12 -0700973
974 rast = CALLOC_STRUCT(lp_rasterizer);
975 if(!rast)
976 return NULL;
977
978 rast->screen = screen;
979
Keith Whitwell663750d2009-12-13 18:17:25 +0000980 rast->empty_scenes = empty;
981 rast->full_scenes = lp_scene_queue_create();
Brian Pauld7dbc662009-12-09 14:53:33 -0700982
Brian Paulaab1cec2009-12-07 18:01:12 -0700983 for (i = 0; i < Elements(rast->tasks); i++) {
Brian Paulec459f22010-01-19 16:58:25 -0700984 struct lp_rasterizer_task *task = &rast->tasks[i];
Keith Whitwellc1a04412010-01-10 17:22:09 +0000985
Brian Paulec459f22010-01-19 16:58:25 -0700986 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 Paulaab1cec2009-12-07 18:01:12 -0700992 }
993
994 create_rast_threads(rast);
995
Brian Paul2bce5c12009-12-11 14:52:42 -0700996 /* for synchronizing rasterization threads */
997 pipe_barrier_init( &rast->barrier, rast->num_threads );
998
Brian Paulaab1cec2009-12-07 18:01:12 -0700999 return rast;
1000}
1001
Brian Paulb533b562009-12-04 14:47:40 -07001002
Keith Whitwell89498d02009-10-07 22:36:43 +01001003/* Shutdown:
1004 */
1005void lp_rast_destroy( struct lp_rasterizer *rast )
1006{
Keith Whitwellc1a04412010-01-10 17:22:09 +00001007 unsigned i, cbuf;
Brian Paul3a06c112009-12-07 17:02:17 -07001008
Brian Paul156eabb2009-12-11 11:46:23 -07001009 util_unreference_framebuffer_state(&rast->state.fb);
Brian Paul3a06c112009-12-07 17:02:17 -07001010
1011 for (i = 0; i < Elements(rast->tasks); i++) {
1012 align_free(rast->tasks[i].tile.depth);
Keith Whitwellc1a04412010-01-10 17:22:09 +00001013 for (cbuf = 0; cbuf < PIPE_MAX_COLOR_BUFS; cbuf++ )
1014 align_free(rast->tasks[i].tile.color[cbuf]);
Brian Paul3a06c112009-12-07 17:02:17 -07001015 }
1016
Brian Paul2bce5c12009-12-11 14:52:42 -07001017 /* for synchronizing rasterization threads */
1018 pipe_barrier_destroy( &rast->barrier );
1019
Keith Whitwell89498d02009-10-07 22:36:43 +01001020 FREE(rast);
1021}
1022
Brian Paul93237402009-12-11 17:45:52 -07001023
1024/** Return number of rasterization threads */
1025unsigned
1026lp_rast_get_num_threads( struct lp_rasterizer *rast )
1027{
1028 return rast->num_threads;
1029}