d8dc24e4519162115f37a782bc49cb56d0dd009d
[mesa.git] / src / gallium / drivers / llvmpipe / lp_rast.c
1 /**************************************************************************
2 *
3 * Copyright 2009 VMware, Inc.
4 * All Rights Reserved.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the
8 * "Software"), to deal in the Software without restriction, including
9 * without limitation the rights to use, copy, modify, merge, publish,
10 * distribute, sub license, and/or sell copies of the Software, and to
11 * permit persons to whom the Software is furnished to do so, subject to
12 * the following conditions:
13 *
14 * The above copyright notice and this permission notice (including the
15 * next paragraph) shall be included in all copies or substantial portions
16 * of the Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
21 * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
22 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25 *
26 **************************************************************************/
27
28 #include <limits.h>
29 #include "util/u_memory.h"
30 #include "util/u_math.h"
31 #include "util/u_rect.h"
32 #include "util/u_surface.h"
33
34 #include "lp_scene_queue.h"
35 #include "lp_debug.h"
36 #include "lp_fence.h"
37 #include "lp_perf.h"
38 #include "lp_query.h"
39 #include "lp_rast.h"
40 #include "lp_rast_priv.h"
41 #include "lp_tile_soa.h"
42 #include "gallivm/lp_bld_debug.h"
43 #include "lp_scene.h"
44
45
46 #ifdef DEBUG
47 int jit_line = 0;
48 const struct lp_rast_state *jit_state = NULL;
49 #endif
50
51
52 /**
53 * Begin rasterizing a scene.
54 * Called once per scene by one thread.
55 */
56 static void
57 lp_rast_begin( struct lp_rasterizer *rast,
58 struct lp_scene *scene )
59 {
60 const struct pipe_framebuffer_state *fb = &scene->fb;
61 int i;
62
63 rast->curr_scene = scene;
64
65 LP_DBG(DEBUG_RAST, "%s\n", __FUNCTION__);
66
67 rast->state.nr_cbufs = scene->fb.nr_cbufs;
68
69 for (i = 0; i < rast->state.nr_cbufs; i++) {
70 struct pipe_surface *cbuf = scene->fb.cbufs[i];
71 llvmpipe_resource_map(cbuf->texture,
72 cbuf->face,
73 cbuf->level,
74 cbuf->zslice,
75 LP_TEX_USAGE_READ_WRITE,
76 LP_TEX_LAYOUT_LINEAR);
77 }
78
79 if (fb->zsbuf) {
80 struct pipe_surface *zsbuf = scene->fb.zsbuf;
81 rast->zsbuf.stride = llvmpipe_resource_stride(zsbuf->texture, zsbuf->level);
82 rast->zsbuf.blocksize =
83 util_format_get_blocksize(zsbuf->texture->format);
84
85 rast->zsbuf.map = llvmpipe_resource_map(zsbuf->texture,
86 zsbuf->face,
87 zsbuf->level,
88 zsbuf->zslice,
89 LP_TEX_USAGE_READ_WRITE,
90 LP_TEX_LAYOUT_NONE);
91 }
92
93 lp_scene_bin_iter_begin( scene );
94 }
95
96
97 static void
98 lp_rast_end( struct lp_rasterizer *rast )
99 {
100 struct lp_scene *scene = rast->curr_scene;
101 unsigned i;
102
103 /* Unmap color buffers */
104 for (i = 0; i < rast->state.nr_cbufs; i++) {
105 struct pipe_surface *cbuf = scene->fb.cbufs[i];
106 llvmpipe_resource_unmap(cbuf->texture,
107 cbuf->face,
108 cbuf->level,
109 cbuf->zslice);
110 }
111
112 /* Unmap z/stencil buffer */
113 if (rast->zsbuf.map) {
114 struct pipe_surface *zsbuf = scene->fb.zsbuf;
115 llvmpipe_resource_unmap(zsbuf->texture,
116 zsbuf->face,
117 zsbuf->level,
118 zsbuf->zslice);
119 rast->zsbuf.map = NULL;
120 }
121
122 lp_scene_reset( rast->curr_scene );
123
124 rast->curr_scene = NULL;
125
126 #ifdef DEBUG
127 if (0)
128 debug_printf("Post render scene: tile unswizzle: %u tile swizzle: %u\n",
129 lp_tile_unswizzle_count, lp_tile_swizzle_count);
130 #endif
131 }
132
133
134 /**
135 * Begining rasterization of a tile.
136 * \param x window X position of the tile, in pixels
137 * \param y window Y position of the tile, in pixels
138 */
139 static void
140 lp_rast_tile_begin(struct lp_rasterizer_task *task,
141 unsigned x, unsigned y)
142 {
143 struct lp_rasterizer *rast = task->rast;
144 struct lp_scene *scene = rast->curr_scene;
145 enum lp_texture_usage usage;
146
147 LP_DBG(DEBUG_RAST, "%s %d,%d\n", __FUNCTION__, x, y);
148
149 assert(x % TILE_SIZE == 0);
150 assert(y % TILE_SIZE == 0);
151
152 task->x = x;
153 task->y = y;
154
155 /* reset pointers to color tile(s) */
156 memset(task->color_tiles, 0, sizeof(task->color_tiles));
157
158 /* get pointer to depth/stencil tile */
159 {
160 struct pipe_surface *zsbuf = rast->curr_scene->fb.zsbuf;
161 if (zsbuf) {
162 struct llvmpipe_resource *lpt = llvmpipe_resource(zsbuf->texture);
163
164 if (scene->has_depthstencil_clear)
165 usage = LP_TEX_USAGE_WRITE_ALL;
166 else
167 usage = LP_TEX_USAGE_READ_WRITE;
168
169 /* "prime" the tile: convert data from linear to tiled if necessary
170 * and update the tile's layout info.
171 */
172 (void) llvmpipe_get_texture_tile(lpt,
173 zsbuf->face + zsbuf->zslice,
174 zsbuf->level,
175 usage,
176 x, y);
177 /* Get actual pointer to the tile data. Note that depth/stencil
178 * data is tiled differently than color data.
179 */
180 task->depth_tile = lp_rast_get_depth_block_pointer(task, x, y);
181
182 assert(task->depth_tile);
183 }
184 else {
185 task->depth_tile = NULL;
186 }
187 }
188 }
189
190
191 /**
192 * Clear the rasterizer's current color tile.
193 * This is a bin command called during bin processing.
194 */
195 void
196 lp_rast_clear_color(struct lp_rasterizer_task *task,
197 const union lp_rast_cmd_arg arg)
198 {
199 struct lp_rasterizer *rast = task->rast;
200 const uint8_t *clear_color = arg.clear_color;
201
202 unsigned i;
203
204 LP_DBG(DEBUG_RAST, "%s 0x%x,0x%x,0x%x,0x%x\n", __FUNCTION__,
205 clear_color[0],
206 clear_color[1],
207 clear_color[2],
208 clear_color[3]);
209
210 if (clear_color[0] == clear_color[1] &&
211 clear_color[1] == clear_color[2] &&
212 clear_color[2] == clear_color[3]) {
213 /* clear to grayscale value {x, x, x, x} */
214 for (i = 0; i < rast->state.nr_cbufs; i++) {
215 uint8_t *ptr =
216 lp_rast_get_color_tile_pointer(task, i, LP_TEX_USAGE_WRITE_ALL);
217 memset(ptr, clear_color[0], TILE_SIZE * TILE_SIZE * 4);
218 }
219 }
220 else {
221 /* Non-gray color.
222 * Note: if the swizzled tile layout changes (see TILE_PIXEL) this code
223 * will need to change. It'll be pretty obvious when clearing no longer
224 * works.
225 */
226 const unsigned chunk = TILE_SIZE / 4;
227 for (i = 0; i < rast->state.nr_cbufs; i++) {
228 uint8_t *c =
229 lp_rast_get_color_tile_pointer(task, i, LP_TEX_USAGE_WRITE_ALL);
230 unsigned j;
231
232 for (j = 0; j < 4 * TILE_SIZE; j++) {
233 memset(c, clear_color[0], chunk);
234 c += chunk;
235 memset(c, clear_color[1], chunk);
236 c += chunk;
237 memset(c, clear_color[2], chunk);
238 c += chunk;
239 memset(c, clear_color[3], chunk);
240 c += chunk;
241 }
242 }
243 }
244
245 LP_COUNT(nr_color_tile_clear);
246 }
247
248
249 /**
250 * Clear the rasterizer's current z/stencil tile.
251 * This is a bin command called during bin processing.
252 */
253 void
254 lp_rast_clear_zstencil(struct lp_rasterizer_task *task,
255 const union lp_rast_cmd_arg arg)
256 {
257 struct lp_rasterizer *rast = task->rast;
258 unsigned clear_value = arg.clear_zstencil.value;
259 unsigned clear_mask = arg.clear_zstencil.mask;
260 const unsigned height = TILE_SIZE / TILE_VECTOR_HEIGHT;
261 const unsigned width = TILE_SIZE * TILE_VECTOR_HEIGHT;
262 const unsigned block_size = rast->zsbuf.blocksize;
263 const unsigned dst_stride = rast->zsbuf.stride * TILE_VECTOR_HEIGHT;
264 uint8_t *dst;
265 unsigned i, j;
266
267 LP_DBG(DEBUG_RAST, "%s 0x%x%x\n", __FUNCTION__, clear_value, clear_mask);
268
269 /*
270 * Clear the aera of the swizzled depth/depth buffer matching this tile, in
271 * stripes of TILE_VECTOR_HEIGHT x TILE_SIZE at a time.
272 *
273 * The swizzled depth format is such that the depths for
274 * TILE_VECTOR_HEIGHT x TILE_VECTOR_WIDTH pixels have consecutive offsets.
275 */
276
277 dst = task->depth_tile;
278
279 switch (block_size) {
280 case 1:
281 memset(dst, (uint8_t) clear_value, height * width);
282 break;
283 case 2:
284 for (i = 0; i < height; i++) {
285 uint16_t *row = (uint16_t *)dst;
286 for (j = 0; j < width; j++)
287 *row++ = (uint16_t) clear_value;
288 dst += dst_stride;
289 }
290 break;
291 case 4:
292 if (clear_mask == 0xffffffff) {
293 for (i = 0; i < height; i++) {
294 uint32_t *row = (uint32_t *)dst;
295 for (j = 0; j < width; j++)
296 *row++ = clear_value;
297 dst += dst_stride;
298 }
299 }
300 else {
301 for (i = 0; i < height; i++) {
302 uint32_t *row = (uint32_t *)dst;
303 for (j = 0; j < width; j++) {
304 uint32_t tmp = ~clear_mask & *row;
305 *row++ = (clear_value & clear_mask) | tmp;
306 }
307 dst += dst_stride;
308 }
309 }
310 break;
311 default:
312 assert(0);
313 break;
314 }
315 }
316
317
318
319
320 /**
321 * Convert the color tile from tiled to linear layout.
322 * This is generally only done when we're flushing the scene just prior to
323 * SwapBuffers. If we didn't do this here, we'd have to convert the entire
324 * tiled color buffer to linear layout in the llvmpipe_texture_unmap()
325 * function. It's better to do it here to take advantage of
326 * threading/parallelism.
327 * This is a bin command which is stored in all bins.
328 */
329 void
330 lp_rast_store_linear_color( struct lp_rasterizer_task *task,
331 const union lp_rast_cmd_arg arg)
332 {
333 struct lp_rasterizer *rast = task->rast;
334 struct lp_scene *scene = rast->curr_scene;
335 unsigned buf;
336
337 for (buf = 0; buf < rast->state.nr_cbufs; buf++) {
338 struct pipe_surface *cbuf = scene->fb.cbufs[buf];
339 const unsigned face_slice = cbuf->face + cbuf->zslice;
340 const unsigned level = cbuf->level;
341 struct llvmpipe_resource *lpt = llvmpipe_resource(cbuf->texture);
342
343 if (!task->color_tiles[buf])
344 continue;
345
346 llvmpipe_unswizzle_cbuf_tile(lpt,
347 face_slice,
348 level,
349 task->x, task->y,
350 task->color_tiles[buf]);
351 }
352 }
353
354
355
356 /**
357 * Run the shader on all blocks in a tile. This is used when a tile is
358 * completely contained inside a triangle.
359 * This is a bin command called during bin processing.
360 */
361 void
362 lp_rast_shade_tile(struct lp_rasterizer_task *task,
363 const union lp_rast_cmd_arg arg)
364 {
365 struct lp_rasterizer *rast = task->rast;
366 const struct lp_rast_shader_inputs *inputs = arg.shade_tile;
367 const struct lp_rast_state *state = inputs->state;
368 struct lp_fragment_shader_variant *variant = state->variant;
369 const unsigned tile_x = task->x, tile_y = task->y;
370 unsigned x, y;
371
372 LP_DBG(DEBUG_RAST, "%s\n", __FUNCTION__);
373
374 /* render the whole 64x64 tile in 4x4 chunks */
375 for (y = 0; y < TILE_SIZE; y += 4){
376 for (x = 0; x < TILE_SIZE; x += 4) {
377 uint8_t *color[PIPE_MAX_COLOR_BUFS];
378 uint32_t *depth;
379 unsigned i;
380
381 /* color buffer */
382 for (i = 0; i < rast->state.nr_cbufs; i++)
383 color[i] = lp_rast_get_color_block_pointer(task, i,
384 tile_x + x, tile_y + y);
385
386 /* depth buffer */
387 depth = lp_rast_get_depth_block_pointer(task, tile_x + x, tile_y + y);
388
389 /* run shader on 4x4 block */
390 BEGIN_JIT_CALL(state);
391 variant->jit_function[RAST_WHOLE]( &state->jit_context,
392 tile_x + x, tile_y + y,
393 inputs->facing,
394 inputs->a0,
395 inputs->dadx,
396 inputs->dady,
397 color,
398 depth,
399 0xffff,
400 &task->vis_counter);
401 END_JIT_CALL();
402 }
403 }
404 }
405
406
407 /**
408 * Run the shader on all blocks in a tile. This is used when a tile is
409 * completely contained inside a triangle, and the shader is opaque.
410 * This is a bin command called during bin processing.
411 */
412 void
413 lp_rast_shade_tile_opaque(struct lp_rasterizer_task *task,
414 const union lp_rast_cmd_arg arg)
415 {
416 struct lp_rasterizer *rast = task->rast;
417 unsigned i;
418
419 LP_DBG(DEBUG_RAST, "%s\n", __FUNCTION__);
420
421 /* this will prevent converting the layout from tiled to linear */
422 for (i = 0; i < rast->state.nr_cbufs; i++) {
423 (void)lp_rast_get_color_tile_pointer(task, i, LP_TEX_USAGE_WRITE_ALL);
424 }
425
426 lp_rast_shade_tile(task, arg);
427 }
428
429
430 /**
431 * Compute shading for a 4x4 block of pixels inside a triangle.
432 * This is a bin command called during bin processing.
433 * \param x X position of quad in window coords
434 * \param y Y position of quad in window coords
435 */
436 void
437 lp_rast_shade_quads_mask(struct lp_rasterizer_task *task,
438 const struct lp_rast_shader_inputs *inputs,
439 unsigned x, unsigned y,
440 unsigned mask)
441 {
442 const struct lp_rast_state *state = inputs->state;
443 struct lp_fragment_shader_variant *variant = state->variant;
444 struct lp_rasterizer *rast = task->rast;
445 uint8_t *color[PIPE_MAX_COLOR_BUFS];
446 void *depth;
447 unsigned i;
448
449 assert(state);
450
451 /* Sanity checks */
452 assert(x % TILE_VECTOR_WIDTH == 0);
453 assert(y % TILE_VECTOR_HEIGHT == 0);
454
455 assert((x % 4) == 0);
456 assert((y % 4) == 0);
457
458 /* color buffer */
459 for (i = 0; i < rast->state.nr_cbufs; i++) {
460 color[i] = lp_rast_get_color_block_pointer(task, i, x, y);
461 assert(lp_check_alignment(color[i], 16));
462 }
463
464 /* depth buffer */
465 depth = lp_rast_get_depth_block_pointer(task, x, y);
466
467
468 assert(lp_check_alignment(state->jit_context.blend_color, 16));
469
470 /* run shader on 4x4 block */
471 BEGIN_JIT_CALL(state);
472 variant->jit_function[RAST_EDGE_TEST](&state->jit_context,
473 x, y,
474 inputs->facing,
475 inputs->a0,
476 inputs->dadx,
477 inputs->dady,
478 color,
479 depth,
480 mask,
481 &task->vis_counter);
482 END_JIT_CALL();
483 }
484
485
486
487 /**
488 * Set top row and left column of the tile's pixels to white. For debugging.
489 */
490 static void
491 outline_tile(uint8_t *tile)
492 {
493 const uint8_t val = 0xff;
494 unsigned i;
495
496 for (i = 0; i < TILE_SIZE; i++) {
497 TILE_PIXEL(tile, i, 0, 0) = val;
498 TILE_PIXEL(tile, i, 0, 1) = val;
499 TILE_PIXEL(tile, i, 0, 2) = val;
500 TILE_PIXEL(tile, i, 0, 3) = val;
501
502 TILE_PIXEL(tile, 0, i, 0) = val;
503 TILE_PIXEL(tile, 0, i, 1) = val;
504 TILE_PIXEL(tile, 0, i, 2) = val;
505 TILE_PIXEL(tile, 0, i, 3) = val;
506 }
507 }
508
509
510 /**
511 * Draw grid of gray lines at 16-pixel intervals across the tile to
512 * show the sub-tile boundaries. For debugging.
513 */
514 static void
515 outline_subtiles(uint8_t *tile)
516 {
517 const uint8_t val = 0x80;
518 const unsigned step = 16;
519 unsigned i, j;
520
521 for (i = 0; i < TILE_SIZE; i += step) {
522 for (j = 0; j < TILE_SIZE; j++) {
523 TILE_PIXEL(tile, i, j, 0) = val;
524 TILE_PIXEL(tile, i, j, 1) = val;
525 TILE_PIXEL(tile, i, j, 2) = val;
526 TILE_PIXEL(tile, i, j, 3) = val;
527
528 TILE_PIXEL(tile, j, i, 0) = val;
529 TILE_PIXEL(tile, j, i, 1) = val;
530 TILE_PIXEL(tile, j, i, 2) = val;
531 TILE_PIXEL(tile, j, i, 3) = val;
532 }
533 }
534
535 outline_tile(tile);
536 }
537
538
539
540 /**
541 * Called when we're done writing to a color tile.
542 */
543 static void
544 lp_rast_tile_end(struct lp_rasterizer_task *task)
545 {
546 #ifdef DEBUG
547 if (LP_DEBUG & (DEBUG_SHOW_SUBTILES | DEBUG_SHOW_TILES)) {
548 struct lp_rasterizer *rast = task->rast;
549 unsigned buf;
550
551 for (buf = 0; buf < rast->state.nr_cbufs; buf++) {
552 uint8_t *color = lp_rast_get_color_block_pointer(task, buf,
553 task->x, task->y);
554
555 if (LP_DEBUG & DEBUG_SHOW_SUBTILES)
556 outline_subtiles(color);
557 else if (LP_DEBUG & DEBUG_SHOW_TILES)
558 outline_tile(color);
559 }
560 }
561 #else
562 (void) outline_subtiles;
563 #endif
564
565 {
566 union lp_rast_cmd_arg dummy = {0};
567 lp_rast_store_linear_color(task, dummy);
568 }
569
570 if (task->query) {
571 union lp_rast_cmd_arg dummy = {0};
572 lp_rast_end_query(task, dummy);
573 }
574
575 /* debug */
576 memset(task->color_tiles, 0, sizeof(task->color_tiles));
577 task->depth_tile = NULL;
578 }
579
580
581
582 /**
583 * Signal on a fence. This is called during bin execution/rasterization.
584 * Called per thread.
585 */
586 void
587 lp_rast_fence(struct lp_rasterizer_task *task,
588 const union lp_rast_cmd_arg arg)
589 {
590 struct lp_fence *fence = arg.fence;
591 lp_fence_signal(fence);
592 }
593
594
595 /**
596 * Begin a new occlusion query.
597 * This is a bin command put in all bins.
598 * Called per thread.
599 */
600 void
601 lp_rast_begin_query(struct lp_rasterizer_task *task,
602 const union lp_rast_cmd_arg arg)
603 {
604 struct llvmpipe_query *pq = arg.query_obj;
605
606 assert(task->query == NULL);
607 task->vis_counter = 0;
608 task->query = pq;
609 pq->count[task->thread_index] = 0;
610 }
611
612
613 /* Much like begin_query, but don't reset the counter to zero.
614 */
615 void
616 lp_rast_restart_query(struct lp_rasterizer_task *task,
617 const union lp_rast_cmd_arg arg)
618 {
619 struct llvmpipe_query *pq = arg.query_obj;
620
621 assert(task->query == NULL);
622 task->vis_counter = 0;
623 task->query = pq;
624 }
625
626
627 /**
628 * End the current occlusion query.
629 * This is a bin command put in all bins.
630 * Called per thread.
631 */
632 void
633 lp_rast_end_query(struct lp_rasterizer_task *task,
634 const union lp_rast_cmd_arg arg)
635 {
636 task->query->count[task->thread_index] += task->vis_counter;
637 task->query = NULL;
638 }
639
640
641
642 /**
643 * Rasterize commands for a single bin.
644 * \param x, y position of the bin's tile in the framebuffer
645 * Must be called between lp_rast_begin() and lp_rast_end().
646 * Called per thread.
647 */
648 static void
649 rasterize_bin(struct lp_rasterizer_task *task,
650 const struct cmd_bin *bin,
651 int x, int y)
652 {
653 const struct cmd_block_list *commands = &bin->commands;
654 struct cmd_block *block;
655 unsigned k;
656
657 lp_rast_tile_begin( task, x * TILE_SIZE, y * TILE_SIZE );
658
659 /* simply execute each of the commands in the block list */
660 for (block = commands->head; block; block = block->next) {
661 for (k = 0; k < block->count; k++) {
662 block->cmd[k]( task, block->arg[k] );
663 }
664 }
665
666 lp_rast_tile_end(task);
667
668 /* Free data for this bin.
669 */
670 lp_scene_bin_reset( task->rast->curr_scene, x, y);
671 }
672
673
674 #define RAST(x) { lp_rast_##x, #x }
675
676 static struct {
677 lp_rast_cmd cmd;
678 const char *name;
679 } cmd_names[] =
680 {
681 RAST(clear_color),
682 RAST(clear_zstencil),
683 RAST(triangle_1),
684 RAST(triangle_2),
685 RAST(triangle_3),
686 RAST(triangle_4),
687 RAST(triangle_5),
688 RAST(triangle_6),
689 RAST(triangle_7),
690 RAST(shade_tile),
691 RAST(shade_tile_opaque),
692 RAST(store_linear_color),
693 RAST(fence),
694 RAST(begin_query),
695 RAST(restart_query),
696 RAST(end_query),
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
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 */
726 static boolean
727 is_empty_bin( const struct cmd_bin *bin )
728 {
729 if (0) debug_bin(bin);
730 return bin->commands.head->count == 0;
731 }
732
733
734
735 /**
736 * Rasterize/execute all bins within a scene.
737 * Called per thread.
738 */
739 static void
740 rasterize_scene(struct lp_rasterizer_task *task,
741 struct lp_scene *scene)
742 {
743 /* loop over scene bins, rasterize each */
744 #if 0
745 {
746 unsigned i, j;
747 for (i = 0; i < scene->tiles_x; i++) {
748 for (j = 0; j < scene->tiles_y; j++) {
749 struct cmd_bin *bin = lp_scene_get_bin(scene, i, j);
750 rasterize_bin(task, bin, i, j);
751 }
752 }
753 }
754 #else
755 {
756 struct cmd_bin *bin;
757 int x, y;
758
759 assert(scene);
760 while ((bin = lp_scene_bin_iter_next(scene, &x, &y))) {
761 if (!is_empty_bin( bin ))
762 rasterize_bin(task, bin, x, y);
763 }
764 }
765 #endif
766
767 if (scene->fence) {
768 lp_rast_fence(task, lp_rast_arg_fence(scene->fence));
769 }
770 }
771
772
773 /**
774 * Called by setup module when it has something for us to render.
775 */
776 void
777 lp_rast_queue_scene( struct lp_rasterizer *rast,
778 struct lp_scene *scene)
779 {
780 LP_DBG(DEBUG_SETUP, "%s\n", __FUNCTION__);
781
782 if (rast->num_threads == 0) {
783 /* no threading */
784
785 lp_rast_begin( rast, scene );
786
787 rasterize_scene( &rast->tasks[0], scene );
788
789 lp_scene_reset( scene );
790
791 lp_rast_end( rast );
792
793 rast->curr_scene = NULL;
794 }
795 else {
796 /* threaded rendering! */
797 unsigned i;
798
799 lp_scene_enqueue( rast->full_scenes, scene );
800
801 /* signal the threads that there's work to do */
802 for (i = 0; i < rast->num_threads; i++) {
803 pipe_semaphore_signal(&rast->tasks[i].work_ready);
804 }
805 }
806
807 LP_DBG(DEBUG_SETUP, "%s done \n", __FUNCTION__);
808 }
809
810
811 void
812 lp_rast_finish( struct lp_rasterizer *rast )
813 {
814 if (rast->num_threads == 0) {
815 /* nothing to do */
816 }
817 else {
818 int i;
819
820 /* wait for work to complete */
821 for (i = 0; i < rast->num_threads; i++) {
822 pipe_semaphore_wait(&rast->tasks[i].work_done);
823 }
824 }
825 }
826
827
828 /**
829 * This is the thread's main entrypoint.
830 * It's a simple loop:
831 * 1. wait for work
832 * 2. do work
833 * 3. signal that we're done
834 */
835 static PIPE_THREAD_ROUTINE( thread_func, init_data )
836 {
837 struct lp_rasterizer_task *task = (struct lp_rasterizer_task *) init_data;
838 struct lp_rasterizer *rast = task->rast;
839 boolean debug = false;
840
841 while (1) {
842 /* wait for work */
843 if (debug)
844 debug_printf("thread %d waiting for work\n", task->thread_index);
845 pipe_semaphore_wait(&task->work_ready);
846
847 if (rast->exit_flag)
848 break;
849
850 if (task->thread_index == 0) {
851 /* thread[0]:
852 * - get next scene to rasterize
853 * - map the framebuffer surfaces
854 */
855 lp_rast_begin( rast,
856 lp_scene_dequeue( rast->full_scenes, TRUE ) );
857 }
858
859 /* Wait for all threads to get here so that threads[1+] don't
860 * get a null rast->curr_scene pointer.
861 */
862 pipe_barrier_wait( &rast->barrier );
863
864 /* do work */
865 if (debug)
866 debug_printf("thread %d doing work\n", task->thread_index);
867
868 rasterize_scene(task,
869 rast->curr_scene);
870
871 /* wait for all threads to finish with this scene */
872 pipe_barrier_wait( &rast->barrier );
873
874 /* XXX: shouldn't be necessary:
875 */
876 if (task->thread_index == 0) {
877 lp_rast_end( rast );
878 }
879
880 /* signal done with work */
881 if (debug)
882 debug_printf("thread %d done working\n", task->thread_index);
883
884 pipe_semaphore_signal(&task->work_done);
885 }
886
887 return NULL;
888 }
889
890
891 /**
892 * Initialize semaphores and spawn the threads.
893 */
894 static void
895 create_rast_threads(struct lp_rasterizer *rast)
896 {
897 unsigned i;
898
899 /* NOTE: if num_threads is zero, we won't use any threads */
900 for (i = 0; i < rast->num_threads; i++) {
901 pipe_semaphore_init(&rast->tasks[i].work_ready, 0);
902 pipe_semaphore_init(&rast->tasks[i].work_done, 0);
903 rast->threads[i] = pipe_thread_create(thread_func,
904 (void *) &rast->tasks[i]);
905 }
906 }
907
908
909
910 /**
911 * Create new lp_rasterizer. If num_threads is zero, don't create any
912 * new threads, do rendering synchronously.
913 * \param num_threads number of rasterizer threads to create
914 */
915 struct lp_rasterizer *
916 lp_rast_create( unsigned num_threads )
917 {
918 struct lp_rasterizer *rast;
919 unsigned i;
920
921 rast = CALLOC_STRUCT(lp_rasterizer);
922 if(!rast)
923 return NULL;
924
925 rast->full_scenes = lp_scene_queue_create();
926
927 for (i = 0; i < Elements(rast->tasks); i++) {
928 struct lp_rasterizer_task *task = &rast->tasks[i];
929 task->rast = rast;
930 task->thread_index = i;
931 }
932
933 rast->num_threads = num_threads;
934
935 create_rast_threads(rast);
936
937 /* for synchronizing rasterization threads */
938 pipe_barrier_init( &rast->barrier, rast->num_threads );
939
940 memset(lp_swizzled_cbuf, 0, sizeof lp_swizzled_cbuf);
941
942 memset(lp_dummy_tile, 0, sizeof lp_dummy_tile);
943
944 return rast;
945 }
946
947
948 /* Shutdown:
949 */
950 void lp_rast_destroy( struct lp_rasterizer *rast )
951 {
952 unsigned i;
953
954 /* Set exit_flag and signal each thread's work_ready semaphore.
955 * Each thread will be woken up, notice that the exit_flag is set and
956 * break out of its main loop. The thread will then exit.
957 */
958 rast->exit_flag = TRUE;
959 for (i = 0; i < rast->num_threads; i++) {
960 pipe_semaphore_signal(&rast->tasks[i].work_ready);
961 }
962
963 /* Wait for threads to terminate before cleaning up per-thread data */
964 for (i = 0; i < rast->num_threads; i++) {
965 pipe_thread_wait(rast->threads[i]);
966 }
967
968 /* Clean up per-thread data */
969 for (i = 0; i < rast->num_threads; i++) {
970 pipe_semaphore_destroy(&rast->tasks[i].work_ready);
971 pipe_semaphore_destroy(&rast->tasks[i].work_done);
972 }
973
974 /* for synchronizing rasterization threads */
975 pipe_barrier_destroy( &rast->barrier );
976
977 lp_scene_queue_destroy(rast->full_scenes);
978
979 FREE(rast);
980 }
981
982
983 /** Return number of rasterization threads */
984 unsigned
985 lp_rast_get_num_threads( struct lp_rasterizer *rast )
986 {
987 return rast->num_threads;
988 }
989
990