/** * Convert a tiled image into a linear image. * \param src_stride source row stride in bytes (bytes per row of tiles) * \param dst_stride dest row stride in bytes */ void lp_tiled_to_linear(const uint8_t *src, uint8_t *dst, unsigned width, unsigned height, enum pipe_format format, unsigned src_stride, unsigned dst_stride) { const unsigned tiles_per_row = src_stride / BYTES_PER_TILE; unsigned i, j; for (j = 0; j < height; j += TILE_SIZE) { for (i = 0; i < width; i += TILE_SIZE) { unsigned tile_offset = ((j / TILE_SIZE) * tiles_per_row + i / TILE_SIZE); unsigned byte_offset = tile_offset * BYTES_PER_TILE; const uint8_t *src_tile = src + byte_offset; lp_tile_write_4ub(format, src_tile, dst, dst_stride, i, j, TILE_SIZE, TILE_SIZE); } } }
/** * Flush the tile cache: write all dirty tiles back to the transfer. * any tiles "flagged" as cleared will be "really" cleared. */ void lp_flush_tile_cache(struct llvmpipe_tile_cache *tc) { struct pipe_transfer *pt = tc->transfer; unsigned x, y; if(!pt) return; assert(tc->transfer_map); /* push the tile to all positions marked as clear */ for (y = 0; y < pt->height; y += TILE_SIZE) { for (x = 0; x < pt->width; x += TILE_SIZE) { struct llvmpipe_cached_tile *tile = &tc->entries[y/TILE_SIZE][x/TILE_SIZE]; if(tile->status != LP_TILE_STATUS_UNDEFINED) { unsigned w = TILE_SIZE; unsigned h = TILE_SIZE; if (!pipe_clip_tile(x, y, &w, &h, pt)) { switch(tile->status) { case LP_TILE_STATUS_CLEAR: /* Actually clear the tiles which were flagged as being in a * clear state. */ util_fill_rect(tc->transfer_map, &pt->block, pt->stride, x, y, w, h, tc->clear_val); break; case LP_TILE_STATUS_DEFINED: lp_tile_write_4ub(pt->format, tile->color, tc->transfer_map, pt->stride, x, y, w, h); break; default: assert(0); break; } } tile->status = LP_TILE_STATUS_UNDEFINED; } } } }