llvmpipe: use bin iteration functions when rasterizing bins
[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 "util/u_memory.h"
29
30 #include "lp_debug.h"
31 #include "lp_state.h"
32 #include "lp_rast.h"
33 #include "lp_rast_priv.h"
34 #include "lp_tile_soa.h"
35 #include "lp_bld_debug.h"
36 #include "lp_bin.h"
37
38
39 struct lp_rasterizer *lp_rast_create( struct pipe_screen *screen )
40 {
41 struct lp_rasterizer *rast;
42
43 rast = CALLOC_STRUCT(lp_rasterizer);
44 if(!rast)
45 return NULL;
46
47 rast->screen = screen;
48 rast->tile.color = align_malloc( TILE_SIZE*TILE_SIZE*4, 16 );
49 rast->tile.depth = align_malloc( TILE_SIZE*TILE_SIZE*4, 16 );
50
51 return rast;
52 }
53
54
55 /**
56 * Begin the rasterization phase.
57 * Map the framebuffer surfaces. Initialize the 'rast' state.
58 */
59 static boolean
60 lp_rast_begin( struct lp_rasterizer *rast,
61 struct pipe_surface *cbuf,
62 struct pipe_surface *zsbuf,
63 boolean write_color,
64 boolean write_zstencil,
65 unsigned width,
66 unsigned height )
67 {
68 struct pipe_screen *screen = rast->screen;
69
70 LP_DBG(DEBUG_RAST, "%s %dx%d\n", __FUNCTION__, width, height);
71
72 pipe_surface_reference(&rast->state.cbuf, cbuf);
73 pipe_surface_reference(&rast->state.zsbuf, zsbuf);
74
75 rast->width = width;
76 rast->height = height;
77 rast->state.write_zstencil = write_zstencil;
78 rast->state.write_color = write_color;
79
80 rast->check_for_clipped_tiles = (width % TILE_SIZE != 0 ||
81 height % TILE_SIZE != 0);
82
83 if (cbuf) {
84 rast->cbuf_transfer = screen->get_tex_transfer(rast->screen,
85 cbuf->texture,
86 cbuf->face,
87 cbuf->level,
88 cbuf->zslice,
89 PIPE_TRANSFER_READ_WRITE,
90 0, 0, width, height);
91 if (!rast->cbuf_transfer)
92 return FALSE;
93
94 rast->cbuf_map = screen->transfer_map(rast->screen,
95 rast->cbuf_transfer);
96 if (!rast->cbuf_map)
97 return FALSE;
98 }
99
100 if (zsbuf) {
101 rast->zsbuf_transfer = screen->get_tex_transfer(rast->screen,
102 zsbuf->texture,
103 zsbuf->face,
104 zsbuf->level,
105 zsbuf->zslice,
106 PIPE_TRANSFER_READ_WRITE,
107 0, 0, width, height);
108 if (!rast->zsbuf_transfer)
109 return FALSE;
110
111 rast->zsbuf_map = screen->transfer_map(rast->screen,
112 rast->zsbuf_transfer);
113 if (!rast->zsbuf_map)
114 return FALSE;
115 }
116
117 return TRUE;
118 }
119
120
121 /**
122 * Finish the rasterization phase.
123 * Unmap framebuffer surfaces.
124 */
125 static void
126 lp_rast_end( struct lp_rasterizer *rast )
127 {
128 struct pipe_screen *screen = rast->screen;
129
130 if (rast->cbuf_map)
131 screen->transfer_unmap(screen, rast->cbuf_transfer);
132
133 if (rast->zsbuf_map)
134 screen->transfer_unmap(screen, rast->zsbuf_transfer);
135
136 if (rast->cbuf_transfer)
137 screen->tex_transfer_destroy(rast->cbuf_transfer);
138
139 if (rast->zsbuf_transfer)
140 screen->tex_transfer_destroy(rast->zsbuf_transfer);
141
142 rast->cbuf_transfer = NULL;
143 rast->zsbuf_transfer = NULL;
144 rast->cbuf_map = NULL;
145 rast->zsbuf_map = NULL;
146 }
147
148
149 /**
150 * Begining rasterization of a tile.
151 * \param x window X position of the tile, in pixels
152 * \param y window Y position of the tile, in pixels
153 */
154 static void
155 lp_rast_start_tile( struct lp_rasterizer *rast,
156 unsigned x, unsigned y )
157 {
158 LP_DBG(DEBUG_RAST, "%s %d,%d\n", __FUNCTION__, x, y);
159
160 rast->x = x;
161 rast->y = y;
162 }
163
164
165 /**
166 * Clear the rasterizer's current color tile.
167 * This is a bin command called during bin processing.
168 */
169 void lp_rast_clear_color( struct lp_rasterizer *rast,
170 const union lp_rast_cmd_arg arg )
171 {
172 const uint8_t *clear_color = arg.clear_color;
173
174 LP_DBG(DEBUG_RAST, "%s 0x%x,0x%x,0x%x,0x%x\n", __FUNCTION__,
175 clear_color[0],
176 clear_color[1],
177 clear_color[2],
178 clear_color[3]);
179
180 if (clear_color[0] == clear_color[1] &&
181 clear_color[1] == clear_color[2] &&
182 clear_color[2] == clear_color[3]) {
183 memset(rast->tile.color, clear_color[0], TILE_SIZE * TILE_SIZE * 4);
184 }
185 else {
186 unsigned x, y, chan;
187 for (y = 0; y < TILE_SIZE; y++)
188 for (x = 0; x < TILE_SIZE; x++)
189 for (chan = 0; chan < 4; ++chan)
190 TILE_PIXEL(rast->tile.color, x, y, chan) = clear_color[chan];
191 }
192 }
193
194
195 /**
196 * Clear the rasterizer's current z/stencil tile.
197 * This is a bin command called during bin processing.
198 */
199 void lp_rast_clear_zstencil( struct lp_rasterizer *rast,
200 const union lp_rast_cmd_arg arg)
201 {
202 unsigned i, j;
203
204 LP_DBG(DEBUG_RAST, "%s 0x%x\n", __FUNCTION__, arg.clear_zstencil);
205
206 for (i = 0; i < TILE_SIZE; i++)
207 for (j = 0; j < TILE_SIZE; j++)
208 rast->tile.depth[i*TILE_SIZE + j] = arg.clear_zstencil;
209 }
210
211
212 /**
213 * Load tile color from the framebuffer surface.
214 * This is a bin command called during bin processing.
215 */
216 void lp_rast_load_color( struct lp_rasterizer *rast,
217 const union lp_rast_cmd_arg arg)
218 {
219 LP_DBG(DEBUG_RAST, "%s\n", __FUNCTION__);
220
221 /* call u_tile func to load colors from surface */
222 }
223
224
225 /**
226 * Load tile z/stencil from the framebuffer surface.
227 * This is a bin command called during bin processing.
228 */
229 void lp_rast_load_zstencil( struct lp_rasterizer *rast,
230 const union lp_rast_cmd_arg arg )
231 {
232 LP_DBG(DEBUG_RAST, "%s\n", __FUNCTION__);
233
234 /* call u_tile func to load depth (and stencil?) from surface */
235 }
236
237
238 void lp_rast_set_state( struct lp_rasterizer *rast,
239 const union lp_rast_cmd_arg arg )
240 {
241 const struct lp_rast_state *state = arg.set_state;
242
243 LP_DBG(DEBUG_RAST, "%s %p\n", __FUNCTION__, (void *) state);
244
245 /* just set the current state pointer for this rasterizer */
246 rast->current_state = state;
247 }
248
249
250
251 /* Within a tile:
252 */
253
254 /**
255 * Run the shader on all blocks in a tile. This is used when a tile is
256 * completely contained inside a triangle.
257 * This is a bin command called during bin processing.
258 */
259 void lp_rast_shade_tile( struct lp_rasterizer *rast,
260 const union lp_rast_cmd_arg arg )
261 {
262 const struct lp_rast_shader_inputs *inputs = arg.shade_tile;
263 const unsigned mask = ~0;
264 unsigned x, y;
265
266 LP_DBG(DEBUG_RAST, "%s\n", __FUNCTION__);
267
268 /* Use the existing preference for 4x4 (four quads) shading:
269 */
270 for (y = 0; y < TILE_SIZE; y += 4)
271 for (x = 0; x < TILE_SIZE; x += 4)
272 lp_rast_shade_quads( rast, inputs, rast->x + x, rast->y + y, mask);
273 }
274
275
276 /**
277 * Compute shading for a 4x4 block of pixels.
278 * This is a bin command called during bin processing.
279 */
280 void lp_rast_shade_quads( struct lp_rasterizer *rast,
281 const struct lp_rast_shader_inputs *inputs,
282 unsigned x, unsigned y,
283 unsigned mask)
284 {
285 #if 1
286 const struct lp_rast_state *state = rast->current_state;
287 struct lp_rast_tile *tile = &rast->tile;
288 void *color;
289 void *depth;
290 uint32_t ALIGN16_ATTRIB masks[2][2][2][2];
291 unsigned ix, iy;
292 int block_offset;
293
294 assert(state);
295
296 /* Sanity checks */
297 assert(x % TILE_VECTOR_WIDTH == 0);
298 assert(y % TILE_VECTOR_HEIGHT == 0);
299
300 /* mask: the rasterizer wants to treat pixels in 4x4 blocks, but
301 * the pixel shader wants to swizzle them into 4 2x2 quads.
302 *
303 * Additionally, the pixel shader wants masks as full dword ~0,
304 * while the rasterizer wants to pack per-pixel bits tightly.
305 */
306 #if 0
307 unsigned qx, qy;
308 for (qy = 0; qy < 2; ++qy)
309 for (qx = 0; qx < 2; ++qx)
310 for (iy = 0; iy < 2; ++iy)
311 for (ix = 0; ix < 2; ++ix)
312 masks[qy][qx][iy][ix] = mask & (1 << (qy*8+iy*4+qx*2+ix)) ? ~0 : 0;
313 #else
314 masks[0][0][0][0] = mask & (1 << (0*8+0*4+0*2+0)) ? ~0 : 0;
315 masks[0][0][0][1] = mask & (1 << (0*8+0*4+0*2+1)) ? ~0 : 0;
316 masks[0][0][1][0] = mask & (1 << (0*8+1*4+0*2+0)) ? ~0 : 0;
317 masks[0][0][1][1] = mask & (1 << (0*8+1*4+0*2+1)) ? ~0 : 0;
318 masks[0][1][0][0] = mask & (1 << (0*8+0*4+1*2+0)) ? ~0 : 0;
319 masks[0][1][0][1] = mask & (1 << (0*8+0*4+1*2+1)) ? ~0 : 0;
320 masks[0][1][1][0] = mask & (1 << (0*8+1*4+1*2+0)) ? ~0 : 0;
321 masks[0][1][1][1] = mask & (1 << (0*8+1*4+1*2+1)) ? ~0 : 0;
322
323 masks[1][0][0][0] = mask & (1 << (1*8+0*4+0*2+0)) ? ~0 : 0;
324 masks[1][0][0][1] = mask & (1 << (1*8+0*4+0*2+1)) ? ~0 : 0;
325 masks[1][0][1][0] = mask & (1 << (1*8+1*4+0*2+0)) ? ~0 : 0;
326 masks[1][0][1][1] = mask & (1 << (1*8+1*4+0*2+1)) ? ~0 : 0;
327 masks[1][1][0][0] = mask & (1 << (1*8+0*4+1*2+0)) ? ~0 : 0;
328 masks[1][1][0][1] = mask & (1 << (1*8+0*4+1*2+1)) ? ~0 : 0;
329 masks[1][1][1][0] = mask & (1 << (1*8+1*4+1*2+0)) ? ~0 : 0;
330 masks[1][1][1][1] = mask & (1 << (1*8+1*4+1*2+1)) ? ~0 : 0;
331 #endif
332
333 assert((x % 2) == 0);
334 assert((y % 2) == 0);
335
336 ix = x % TILE_SIZE;
337 iy = y % TILE_SIZE;
338
339 /* offset of the 16x16 pixel block within the tile */
340 block_offset = ((iy/4)*(16*16) + (ix/4)*16);
341
342 /* color buffer */
343 color = tile->color + 4 * block_offset;
344
345 /* depth buffer */
346 depth = tile->depth + block_offset;
347
348 /* XXX: This will most likely fail on 32bit x86 without -mstackrealign */
349 assert(lp_check_alignment(masks, 16));
350
351 assert(lp_check_alignment(depth, 16));
352 assert(lp_check_alignment(color, 16));
353 assert(lp_check_alignment(state->jit_context.blend_color, 16));
354
355 /* run shader */
356 state->jit_function( &state->jit_context,
357 x, y,
358 inputs->a0,
359 inputs->dadx,
360 inputs->dady,
361 &masks[0][0][0][0],
362 color,
363 depth);
364 #else
365 struct lp_rast_tile *tile = &rast->tile;
366 unsigned chan_index;
367 unsigned q, ix, iy;
368
369 x %= TILE_SIZE;
370 y %= TILE_SIZE;
371
372 /* mask */
373 for (q = 0; q < 4; ++q)
374 for(iy = 0; iy < 2; ++iy)
375 for(ix = 0; ix < 2; ++ix)
376 if(masks[q] & (1 << (iy*2 + ix)))
377 for (chan_index = 0; chan_index < NUM_CHANNELS; ++chan_index)
378 TILE_PIXEL(tile->color, x + q*2 + ix, y + iy, chan_index) = 0xff;
379
380 #endif
381 }
382
383
384 /* End of tile:
385 */
386
387
388 /**
389 * Write the rasterizer's color tile to the framebuffer.
390 */
391 static void lp_rast_store_color( struct lp_rasterizer *rast )
392 {
393 const unsigned x = rast->x;
394 const unsigned y = rast->y;
395 unsigned w = TILE_SIZE;
396 unsigned h = TILE_SIZE;
397
398 if (x + w > rast->width)
399 w -= x + w - rast->width;
400
401 if (y + h > rast->height)
402 h -= y + h - rast->height;
403
404 LP_DBG(DEBUG_RAST, "%s %d,%d %dx%d\n", __FUNCTION__, x, y, w, h);
405
406 lp_tile_write_4ub(rast->cbuf_transfer->format,
407 rast->tile.color,
408 rast->cbuf_map,
409 rast->cbuf_transfer->stride,
410 x, y,
411 w, h);
412 }
413
414
415 static void
416 lp_tile_write_z32(const uint32_t *src, uint8_t *dst, unsigned dst_stride,
417 unsigned x0, unsigned y0, unsigned w, unsigned h)
418 {
419 unsigned x, y;
420 uint8_t *dst_row = dst + y0*dst_stride;
421 for (y = 0; y < h; ++y) {
422 uint32_t *dst_pixel = (uint32_t *)(dst_row + x0*4);
423 for (x = 0; x < w; ++x) {
424 *dst_pixel++ = *src++;
425 }
426 dst_row += dst_stride;
427 }
428 }
429
430 /**
431 * Write the rasterizer's z/stencil tile to the framebuffer.
432 */
433 static void lp_rast_store_zstencil( struct lp_rasterizer *rast )
434 {
435 const unsigned x = rast->x;
436 const unsigned y = rast->y;
437 unsigned w = TILE_SIZE;
438 unsigned h = TILE_SIZE;
439
440 if (x + w > rast->width)
441 w -= x + w - rast->width;
442
443 if (y + h > rast->height)
444 h -= y + h - rast->height;
445
446 LP_DBG(DEBUG_RAST, "%s %d,%d %dx%d\n", __FUNCTION__, x, y, w, h);
447
448 assert(rast->zsbuf_transfer->format == PIPE_FORMAT_Z32_UNORM);
449 lp_tile_write_z32(rast->tile.depth,
450 rast->zsbuf_map,
451 rast->zsbuf_transfer->stride,
452 x, y, w, h);
453 }
454
455
456 /**
457 * Write the rasterizer's tiles to the framebuffer.
458 */
459 static void
460 lp_rast_end_tile( struct lp_rasterizer *rast )
461 {
462 LP_DBG(DEBUG_RAST, "%s\n", __FUNCTION__);
463
464 if (rast->state.write_color)
465 lp_rast_store_color(rast);
466
467 if (rast->state.write_zstencil)
468 lp_rast_store_zstencil(rast);
469 }
470
471
472 /**
473 * Rasterize commands for a single bin.
474 * \param x, y position of the bin's tile in the framebuffer
475 * Must be called between lp_rast_begin() and lp_rast_end().
476 */
477 static void
478 rasterize_bin( struct lp_rasterizer *rast,
479 const struct cmd_bin *bin,
480 int x, int y)
481 {
482 const struct cmd_block_list *commands = &bin->commands;
483 struct cmd_block *block;
484 unsigned k;
485
486 lp_rast_start_tile( rast, x, y );
487
488 /* simply execute each of the commands in the block list */
489 for (block = commands->head; block; block = block->next) {
490 for (k = 0; k < block->count; k++) {
491 block->cmd[k]( rast, block->arg[k] );
492 }
493 }
494
495 lp_rast_end_tile( rast );
496 }
497
498
499 /**
500 * Rasterize/execute all bins.
501 */
502 void
503 lp_rasterize_bins( struct lp_rasterizer *rast,
504 struct lp_bins *bins,
505 const struct pipe_framebuffer_state *fb,
506 bool write_depth )
507 {
508 LP_DBG(DEBUG_SETUP, "%s\n", __FUNCTION__);
509
510 lp_rast_begin( rast,
511 fb->cbufs[0],
512 fb->zsbuf,
513 fb->cbufs[0] != NULL,
514 fb->zsbuf != NULL && write_depth,
515 fb->width,
516 fb->height );
517
518 /* loop over tile bins, rasterize each */
519 #if 0
520 {
521 unsigned i, j;
522 for (i = 0; i < bins->tiles_x; i++) {
523 for (j = 0; j < bins->tiles_y; j++) {
524 struct cmd_bin *bin = lp_get_bin(bins, i, j);
525 rasterize_bin( rast, bin, i * TILE_SIZE, j * TILE_SIZE );
526 }
527 }
528 }
529 #else
530 {
531 struct cmd_bin *bin;
532 int x, y;
533
534 lp_bin_iter_begin( bins );
535
536 while ((bin = lp_bin_iter_next(bins, &x, &y))) {
537 rasterize_bin( rast, bin, x * TILE_SIZE, y * TILE_SIZE);
538 }
539 }
540 #endif
541
542 lp_rast_end( rast );
543
544 LP_DBG(DEBUG_SETUP, "%s done \n", __FUNCTION__);
545 }
546
547
548
549 /* Shutdown:
550 */
551 void lp_rast_destroy( struct lp_rasterizer *rast )
552 {
553 pipe_surface_reference(&rast->state.cbuf, NULL);
554 pipe_surface_reference(&rast->state.zsbuf, NULL);
555 align_free(rast->tile.depth);
556 align_free(rast->tile.color);
557 FREE(rast);
558 }
559