/** * Set top row and left column of the tile's pixels to white. For debugging. */ static void outline_tile(uint8_t *tile) { const uint8_t val = 0xff; unsigned i; for (i = 0; i < TILE_SIZE; i++) { TILE_PIXEL(tile, i, 0, 0) = val; TILE_PIXEL(tile, i, 0, 1) = val; TILE_PIXEL(tile, i, 0, 2) = val; TILE_PIXEL(tile, i, 0, 3) = val; TILE_PIXEL(tile, 0, i, 0) = val; TILE_PIXEL(tile, 0, i, 1) = val; TILE_PIXEL(tile, 0, i, 2) = val; TILE_PIXEL(tile, 0, i, 3) = val; } }
/** * Set a tile to a solid color. */ static void clear_tile(struct llvmpipe_cached_tile *tile, uint8_t clear_color[4]) { if (clear_color[0] == clear_color[1] && clear_color[1] == clear_color[2] && clear_color[2] == clear_color[3]) { memset(tile->color, clear_color[0], TILE_SIZE * TILE_SIZE * 4); } else { uint x, y, chan; for (y = 0; y < TILE_SIZE; y++) for (x = 0; x < TILE_SIZE; x++) for (chan = 0; chan < 4; ++chan) TILE_PIXEL(tile->color, x, y, chan) = clear_color[chan]; } }
/** * Draw grid of gray lines at 16-pixel intervals across the tile to * show the sub-tile boundaries. For debugging. */ static void outline_subtiles(uint8_t *tile) { const uint8_t val = 0x80; const unsigned step = 16; unsigned i, j; for (i = 0; i < TILE_SIZE; i += step) { for (j = 0; j < TILE_SIZE; j++) { TILE_PIXEL(tile, i, j, 0) = val; TILE_PIXEL(tile, i, j, 1) = val; TILE_PIXEL(tile, i, j, 2) = val; TILE_PIXEL(tile, i, j, 3) = val; TILE_PIXEL(tile, j, i, 0) = val; TILE_PIXEL(tile, j, i, 1) = val; TILE_PIXEL(tile, j, i, 2) = val; TILE_PIXEL(tile, j, i, 3) = val; } } outline_tile(tile); }
/** * Execute fragment shader for the four fragments in the quad. */ ALIGN_STACK static void shade_quads(struct llvmpipe_context *llvmpipe, struct quad_header *quads[], unsigned nr) { struct lp_fragment_shader *fs = llvmpipe->fs; struct quad_header *quad = quads[0]; const unsigned x = quad->input.x0; const unsigned y = quad->input.y0; uint8_t *tile; uint8_t *color; void *depth; uint32_t ALIGN16_ATTRIB mask[4][NUM_CHANNELS]; unsigned chan_index; unsigned q; assert(fs->current); if(!fs->current) return; /* Sanity checks */ assert(nr * QUAD_SIZE == TILE_VECTOR_HEIGHT * TILE_VECTOR_WIDTH); assert(x % TILE_VECTOR_WIDTH == 0); assert(y % TILE_VECTOR_HEIGHT == 0); for (q = 0; q < nr; ++q) { assert(quads[q]->input.x0 == x + q*2); assert(quads[q]->input.y0 == y); } /* mask */ for (q = 0; q < 4; ++q) for (chan_index = 0; chan_index < NUM_CHANNELS; ++chan_index) mask[q][chan_index] = quads[q]->inout.mask & (1 << chan_index) ? ~0 : 0; /* color buffer */ if(llvmpipe->framebuffer.nr_cbufs >= 1 && llvmpipe->framebuffer.cbufs[0]) { tile = lp_get_cached_tile(llvmpipe->cbuf_cache[0], x, y); color = &TILE_PIXEL(tile, x & (TILE_SIZE-1), y & (TILE_SIZE-1), 0); } else color = NULL; /* depth buffer */ if(llvmpipe->zsbuf_map) { assert((x % 2) == 0); assert((y % 2) == 0); depth = llvmpipe->zsbuf_map + y*llvmpipe->zsbuf_transfer->stride + 2*x*llvmpipe->zsbuf_transfer->block.size; } else depth = NULL; /* XXX: This will most likely fail on 32bit x86 without -mstackrealign */ assert(lp_check_alignment(mask, 16)); assert(lp_check_alignment(depth, 16)); assert(lp_check_alignment(color, 16)); assert(lp_check_alignment(llvmpipe->jit_context.blend_color, 16)); /* run shader */ fs->current->jit_function( &llvmpipe->jit_context, x, y, quad->coef->a0, quad->coef->dadx, quad->coef->dady, &mask[0][0], color, depth); }