/** * Actually clear the tiles which were flagged as being in a clear state. */ static void sp_tile_cache_flush_clear(struct softpipe_tile_cache *tc) { struct pipe_transfer *pt = tc->transfer; const uint w = tc->transfer->box.width; const uint h = tc->transfer->box.height; uint x, y; uint numCleared = 0; assert(pt->resource); /* clear the scratch tile to the clear value */ if (tc->depth_stencil) { clear_tile(&tc->tile, pt->resource->format, tc->clear_val); } else { clear_tile_rgba(&tc->tile, pt->resource->format, tc->clear_color); } /* push the tile to all positions marked as clear */ for (y = 0; y < h; y += TILE_SIZE) { for (x = 0; x < w; x += TILE_SIZE) { union tile_address addr = tile_address(x, y); if (is_clear_flag_set(tc->clear_flags, addr)) { /* write the scratch tile to the surface */ if (tc->depth_stencil) { pipe_put_tile_raw(tc->pipe, pt, x, y, TILE_SIZE, TILE_SIZE, tc->tile.data.any, 0/*STRIDE*/); } else { pipe_put_tile_rgba(tc->pipe, pt, x, y, TILE_SIZE, TILE_SIZE, (float *) tc->tile.data.color); } numCleared++; } } } /* reset all clear flags to zero */ memset(tc->clear_flags, 0, sizeof(tc->clear_flags)); #if 0 debug_printf("num cleared: %u\n", numCleared); #endif }
/** * Get a tile from the cache. * \param x, y position of tile, in pixels */ void * lp_get_cached_tile(struct llvmpipe_tile_cache *tc, unsigned x, unsigned y ) { struct llvmpipe_cached_tile *tile = &tc->entries[y/TILE_SIZE][x/TILE_SIZE]; struct pipe_transfer *pt = tc->transfer; assert(tc->surface); assert(tc->transfer); switch(tile->status) { case LP_TILE_STATUS_CLEAR: /* don't get tile from framebuffer, just clear it */ clear_tile(tile, tc->clear_color); tile->status = LP_TILE_STATUS_DEFINED; break; case LP_TILE_STATUS_UNDEFINED: { unsigned w = TILE_SIZE; unsigned h = TILE_SIZE; x &= ~(TILE_SIZE - 1); y &= ~(TILE_SIZE - 1); if (!pipe_clip_tile(x, y, &w, &h, tc->transfer)) lp_tile_read_4ub(pt->format, tile->color, tc->transfer_map, tc->transfer->stride, x, y, w, h); tile->status = LP_TILE_STATUS_DEFINED; break; } case LP_TILE_STATUS_DEFINED: /* nothing to do */ break; } return tile->color; }
/** * Get a tile from the cache. * \param x, y position of tile, in pixels */ struct softpipe_cached_tile * sp_find_cached_tile(struct softpipe_tile_cache *tc, union tile_address addr ) { struct pipe_transfer *pt = tc->transfer; /* cache pos/entry: */ const int pos = CACHE_POS(addr.bits.x, addr.bits.y); struct softpipe_cached_tile *tile = tc->entries + pos; if (addr.value != tile->addr.value) { assert(pt->resource); if (tile->addr.bits.invalid == 0) { /* put dirty tile back in framebuffer */ if (tc->depth_stencil) { pipe_put_tile_raw(tc->pipe, pt, tile->addr.bits.x * TILE_SIZE, tile->addr.bits.y * TILE_SIZE, TILE_SIZE, TILE_SIZE, tile->data.depth32, 0/*STRIDE*/); } else { pipe_put_tile_rgba(tc->pipe, pt, tile->addr.bits.x * TILE_SIZE, tile->addr.bits.y * TILE_SIZE, TILE_SIZE, TILE_SIZE, (float *) tile->data.color); } } tile->addr = addr; if (is_clear_flag_set(tc->clear_flags, addr)) { /* don't get tile from framebuffer, just clear it */ if (tc->depth_stencil) { clear_tile(tile, pt->resource->format, tc->clear_val); } else { clear_tile_rgba(tile, pt->resource->format, tc->clear_color); } clear_clear_flag(tc->clear_flags, addr); } else { /* get new tile data from transfer */ if (tc->depth_stencil) { pipe_get_tile_raw(tc->pipe, pt, tile->addr.bits.x * TILE_SIZE, tile->addr.bits.y * TILE_SIZE, TILE_SIZE, TILE_SIZE, tile->data.depth32, 0/*STRIDE*/); } else { pipe_get_tile_rgba(tc->pipe, pt, tile->addr.bits.x * TILE_SIZE, tile->addr.bits.y * TILE_SIZE, TILE_SIZE, TILE_SIZE, (float *) tile->data.color); } } } tc->last_tile = tile; return tile; }
/** * Get a tile from the cache. * \param x, y position of tile, in pixels */ struct softpipe_cached_tile * sp_find_cached_tile(struct softpipe_tile_cache *tc, union tile_address addr ) { struct pipe_transfer *pt = tc->transfer; /* cache pos/entry: */ const int pos = CACHE_POS(addr.bits.x, addr.bits.y); struct softpipe_cached_tile *tile = tc->entries[pos]; if (!tile) { tile = sp_alloc_tile(tc); tc->entries[pos] = tile; } if (addr.value != tc->tile_addrs[pos].value) { assert(pt->resource); if (tc->tile_addrs[pos].bits.invalid == 0) { /* put dirty tile back in framebuffer */ if (tc->depth_stencil) { pipe_put_tile_raw(tc->pipe, pt, tc->tile_addrs[pos].bits.x * TILE_SIZE, tc->tile_addrs[pos].bits.y * TILE_SIZE, TILE_SIZE, TILE_SIZE, tile->data.depth32, 0/*STRIDE*/); } else { if (util_format_is_pure_uint(tc->surface->format)) { pipe_put_tile_ui_format(tc->pipe, pt, tc->tile_addrs[pos].bits.x * TILE_SIZE, tc->tile_addrs[pos].bits.y * TILE_SIZE, TILE_SIZE, TILE_SIZE, tc->surface->format, (unsigned *) tile->data.colorui128); } else if (util_format_is_pure_sint(tc->surface->format)) { pipe_put_tile_i_format(tc->pipe, pt, tc->tile_addrs[pos].bits.x * TILE_SIZE, tc->tile_addrs[pos].bits.y * TILE_SIZE, TILE_SIZE, TILE_SIZE, tc->surface->format, (int *) tile->data.colori128); } else { pipe_put_tile_rgba_format(tc->pipe, pt, tc->tile_addrs[pos].bits.x * TILE_SIZE, tc->tile_addrs[pos].bits.y * TILE_SIZE, TILE_SIZE, TILE_SIZE, tc->surface->format, (float *) tile->data.color); } } } tc->tile_addrs[pos] = addr; if (is_clear_flag_set(tc->clear_flags, addr)) { /* don't get tile from framebuffer, just clear it */ if (tc->depth_stencil) { clear_tile(tile, pt->resource->format, tc->clear_val); } else { clear_tile_rgba(tile, pt->resource->format, &tc->clear_color); } clear_clear_flag(tc->clear_flags, addr); } else { /* get new tile data from transfer */ if (tc->depth_stencil) { pipe_get_tile_raw(tc->pipe, pt, tc->tile_addrs[pos].bits.x * TILE_SIZE, tc->tile_addrs[pos].bits.y * TILE_SIZE, TILE_SIZE, TILE_SIZE, tile->data.depth32, 0/*STRIDE*/); } else { if (util_format_is_pure_uint(tc->surface->format)) { pipe_get_tile_ui_format(tc->pipe, pt, tc->tile_addrs[pos].bits.x * TILE_SIZE, tc->tile_addrs[pos].bits.y * TILE_SIZE, TILE_SIZE, TILE_SIZE, tc->surface->format, (unsigned *) tile->data.colorui128); } else if (util_format_is_pure_sint(tc->surface->format)) { pipe_get_tile_i_format(tc->pipe, pt, tc->tile_addrs[pos].bits.x * TILE_SIZE, tc->tile_addrs[pos].bits.y * TILE_SIZE, TILE_SIZE, TILE_SIZE, tc->surface->format, (int *) tile->data.colori128); } else { pipe_get_tile_rgba_format(tc->pipe, pt, tc->tile_addrs[pos].bits.x * TILE_SIZE, tc->tile_addrs[pos].bits.y * TILE_SIZE, TILE_SIZE, TILE_SIZE, tc->surface->format, (float *) tile->data.color); } } } } tc->last_tile = tile; tc->last_tile_addr = addr; return tile; }