llvmpipe: make some small steps to flush texture cache less frequently
No performance gain yet, but the code is a bit cleaner.
This commit is contained in:
parent
3121484a8b
commit
0f55a95b2f
|
@ -149,7 +149,8 @@ struct llvmpipe_context {
|
||||||
|
|
||||||
struct llvmpipe_tile_cache *cbuf_cache[PIPE_MAX_COLOR_BUFS];
|
struct llvmpipe_tile_cache *cbuf_cache[PIPE_MAX_COLOR_BUFS];
|
||||||
struct llvmpipe_tile_cache *zsbuf_cache;
|
struct llvmpipe_tile_cache *zsbuf_cache;
|
||||||
|
|
||||||
|
unsigned tex_timestamp;
|
||||||
struct llvmpipe_tile_cache *tex_cache[PIPE_MAX_SAMPLERS];
|
struct llvmpipe_tile_cache *tex_cache[PIPE_MAX_SAMPLERS];
|
||||||
|
|
||||||
unsigned use_sse : 1;
|
unsigned use_sse : 1;
|
||||||
|
|
|
@ -32,6 +32,7 @@
|
||||||
#include "draw/draw_vertex.h"
|
#include "draw/draw_vertex.h"
|
||||||
#include "draw/draw_private.h"
|
#include "draw/draw_private.h"
|
||||||
#include "lp_context.h"
|
#include "lp_context.h"
|
||||||
|
#include "lp_screen.h"
|
||||||
#include "lp_state.h"
|
#include "lp_state.h"
|
||||||
|
|
||||||
|
|
||||||
|
@ -200,6 +201,10 @@ update_tgsi_samplers( struct llvmpipe_context *llvmpipe )
|
||||||
llvmpipe->tgsi.frag_samplers[i].sampler = llvmpipe->sampler[i];
|
llvmpipe->tgsi.frag_samplers[i].sampler = llvmpipe->sampler[i];
|
||||||
llvmpipe->tgsi.frag_samplers[i].texture = llvmpipe->texture[i];
|
llvmpipe->tgsi.frag_samplers[i].texture = llvmpipe->texture[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < PIPE_MAX_SAMPLERS; i++) {
|
||||||
|
lp_tile_cache_validate_texture( llvmpipe->tex_cache[i] );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Hopefully this will remain quite simple, otherwise need to pull in
|
/* Hopefully this will remain quite simple, otherwise need to pull in
|
||||||
|
@ -207,6 +212,15 @@ update_tgsi_samplers( struct llvmpipe_context *llvmpipe )
|
||||||
*/
|
*/
|
||||||
void llvmpipe_update_derived( struct llvmpipe_context *llvmpipe )
|
void llvmpipe_update_derived( struct llvmpipe_context *llvmpipe )
|
||||||
{
|
{
|
||||||
|
struct llvmpipe_screen *lp_screen = llvmpipe_screen(llvmpipe->pipe.screen);
|
||||||
|
|
||||||
|
/* Check for updated textures.
|
||||||
|
*/
|
||||||
|
if (llvmpipe->tex_timestamp != lp_screen->timestamp) {
|
||||||
|
llvmpipe->tex_timestamp = lp_screen->timestamp;
|
||||||
|
llvmpipe->dirty |= LP_NEW_TEXTURE;
|
||||||
|
}
|
||||||
|
|
||||||
if (llvmpipe->dirty & (LP_NEW_SAMPLER |
|
if (llvmpipe->dirty & (LP_NEW_SAMPLER |
|
||||||
LP_NEW_TEXTURE))
|
LP_NEW_TEXTURE))
|
||||||
update_tgsi_samplers( llvmpipe );
|
update_tgsi_samplers( llvmpipe );
|
||||||
|
|
|
@ -227,7 +227,8 @@ llvmpipe_get_tex_surface(struct pipe_screen *screen,
|
||||||
if (ps->usage & (PIPE_BUFFER_USAGE_CPU_WRITE |
|
if (ps->usage & (PIPE_BUFFER_USAGE_CPU_WRITE |
|
||||||
PIPE_BUFFER_USAGE_GPU_WRITE)) {
|
PIPE_BUFFER_USAGE_GPU_WRITE)) {
|
||||||
/* Mark the surface as dirty. The tile cache will look for this. */
|
/* Mark the surface as dirty. The tile cache will look for this. */
|
||||||
lpt->modified = TRUE;
|
lpt->timestamp++;
|
||||||
|
llvmpipe_screen(screen)->timestamp++;
|
||||||
}
|
}
|
||||||
|
|
||||||
ps->face = face;
|
ps->face = face;
|
||||||
|
|
|
@ -48,7 +48,7 @@ struct llvmpipe_texture
|
||||||
*/
|
*/
|
||||||
struct pipe_buffer *buffer;
|
struct pipe_buffer *buffer;
|
||||||
|
|
||||||
boolean modified;
|
unsigned timestamp;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct llvmpipe_transfer
|
struct llvmpipe_transfer
|
||||||
|
|
|
@ -54,7 +54,10 @@ struct llvmpipe_tile_cache
|
||||||
struct pipe_surface *surface; /**< the surface we're caching */
|
struct pipe_surface *surface; /**< the surface we're caching */
|
||||||
struct pipe_transfer *transfer;
|
struct pipe_transfer *transfer;
|
||||||
void *transfer_map;
|
void *transfer_map;
|
||||||
|
|
||||||
struct pipe_texture *texture; /**< if caching a texture */
|
struct pipe_texture *texture; /**< if caching a texture */
|
||||||
|
unsigned timestamp;
|
||||||
|
|
||||||
struct llvmpipe_cached_tile entries[NUM_ENTRIES];
|
struct llvmpipe_cached_tile entries[NUM_ENTRIES];
|
||||||
uint clear_flags[(MAX_WIDTH / TILE_SIZE) * (MAX_HEIGHT / TILE_SIZE) / 32];
|
uint clear_flags[(MAX_WIDTH / TILE_SIZE) * (MAX_HEIGHT / TILE_SIZE) / 32];
|
||||||
float clear_color[4]; /**< for color bufs */
|
float clear_color[4]; /**< for color bufs */
|
||||||
|
@ -231,6 +234,23 @@ lp_tile_cache_unmap_transfers(struct llvmpipe_tile_cache *tc)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
lp_tile_cache_validate_texture(struct llvmpipe_tile_cache *tc)
|
||||||
|
{
|
||||||
|
if (tc->texture) {
|
||||||
|
struct llvmpipe_texture *lpt = llvmpipe_texture(tc->texture);
|
||||||
|
if (lpt->timestamp != tc->timestamp) {
|
||||||
|
/* texture was modified, invalidate all cached tiles */
|
||||||
|
uint i;
|
||||||
|
_debug_printf("INV %d %d\n", tc->timestamp, lpt->timestamp);
|
||||||
|
for (i = 0; i < NUM_ENTRIES; i++) {
|
||||||
|
tc->entries[i].x = -3;
|
||||||
|
}
|
||||||
|
|
||||||
|
tc->timestamp = lpt->timestamp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Specify the texture to cache.
|
* Specify the texture to cache.
|
||||||
|
@ -243,27 +263,29 @@ lp_tile_cache_set_texture(struct llvmpipe_tile_cache *tc,
|
||||||
|
|
||||||
assert(!tc->transfer);
|
assert(!tc->transfer);
|
||||||
|
|
||||||
pipe_texture_reference(&tc->texture, texture);
|
if (tc->texture != texture) {
|
||||||
|
pipe_texture_reference(&tc->texture, texture);
|
||||||
|
|
||||||
if (tc->tex_trans) {
|
if (tc->tex_trans) {
|
||||||
struct pipe_screen *screen = tc->tex_trans->texture->screen;
|
struct pipe_screen *screen = tc->tex_trans->texture->screen;
|
||||||
|
|
||||||
|
if (tc->tex_trans_map) {
|
||||||
|
screen->transfer_unmap(screen, tc->tex_trans);
|
||||||
|
tc->tex_trans_map = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
if (tc->tex_trans_map) {
|
screen->tex_transfer_destroy(tc->tex_trans);
|
||||||
screen->transfer_unmap(screen, tc->tex_trans);
|
tc->tex_trans = NULL;
|
||||||
tc->tex_trans_map = NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
screen->tex_transfer_destroy(tc->tex_trans);
|
/* mark as entries as invalid/empty */
|
||||||
tc->tex_trans = NULL;
|
/* XXX we should try to avoid this when the teximage hasn't changed */
|
||||||
}
|
for (i = 0; i < NUM_ENTRIES; i++) {
|
||||||
|
tc->entries[i].x = -1;
|
||||||
|
}
|
||||||
|
|
||||||
/* mark as entries as invalid/empty */
|
tc->tex_face = -1; /* any invalid value here */
|
||||||
/* XXX we should try to avoid this when the teximage hasn't changed */
|
|
||||||
for (i = 0; i < NUM_ENTRIES; i++) {
|
|
||||||
tc->entries[i].x = -1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
tc->tex_face = -1; /* any invalid value here */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -443,7 +465,7 @@ lp_get_cached_tile(struct llvmpipe_tile_cache *tc, int x, int y)
|
||||||
if (tile_x != tile->x ||
|
if (tile_x != tile->x ||
|
||||||
tile_y != tile->y) {
|
tile_y != tile->y) {
|
||||||
|
|
||||||
if (tile->x != -1) {
|
if (tile->x >= 0) {
|
||||||
/* put dirty tile back in framebuffer */
|
/* put dirty tile back in framebuffer */
|
||||||
if (tc->depth_stencil) {
|
if (tc->depth_stencil) {
|
||||||
pipe_put_tile_raw(pt,
|
pipe_put_tile_raw(pt,
|
||||||
|
@ -522,30 +544,24 @@ lp_get_cached_tile_tex(struct llvmpipe_tile_cache *tc,
|
||||||
face, level);
|
face, level);
|
||||||
struct llvmpipe_cached_tile *tile = tc->entries + pos;
|
struct llvmpipe_cached_tile *tile = tc->entries + pos;
|
||||||
|
|
||||||
if (tc->texture) {
|
|
||||||
struct llvmpipe_texture *lpt = llvmpipe_texture(tc->texture);
|
|
||||||
if (lpt->modified) {
|
|
||||||
/* texture was modified, invalidate all cached tiles */
|
|
||||||
uint p;
|
|
||||||
for (p = 0; p < NUM_ENTRIES; p++) {
|
|
||||||
tile = tc->entries + p;
|
|
||||||
tile->x = -1;
|
|
||||||
}
|
|
||||||
lpt->modified = FALSE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (tile_x != tile->x ||
|
if (tile_x != tile->x ||
|
||||||
tile_y != tile->y ||
|
tile_y != tile->y ||
|
||||||
z != tile->z ||
|
z != tile->z ||
|
||||||
face != tile->face ||
|
face != tile->face ||
|
||||||
level != tile->level) {
|
level != tile->level) {
|
||||||
/* cache miss */
|
|
||||||
|
|
||||||
|
/* cache miss. Most misses are because we've invaldiated the
|
||||||
|
* texture cache previously -- most commonly on binding a new
|
||||||
|
* texture. Currently we effectively flush the cache on texture
|
||||||
|
* bind.
|
||||||
|
*/
|
||||||
#if 0
|
#if 0
|
||||||
printf("miss at %u x=%d y=%d z=%d face=%d level=%d\n", pos,
|
_debug_printf("miss at %u: x=%d y=%d z=%d face=%d level=%d\n"
|
||||||
x/TILE_SIZE, y/TILE_SIZE, z, face, level);
|
" tile %u: x=%d y=%d z=%d face=%d level=%d\n",
|
||||||
|
pos, x/TILE_SIZE, y/TILE_SIZE, z, face, level,
|
||||||
|
pos, tile->x, tile->y, tile->z, tile->face, tile->level);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* check if we need to get a new transfer */
|
/* check if we need to get a new transfer */
|
||||||
if (!tc->tex_trans ||
|
if (!tc->tex_trans ||
|
||||||
tc->tex_face != face ||
|
tc->tex_face != face ||
|
||||||
|
|
|
@ -83,6 +83,9 @@ extern void
|
||||||
lp_tile_cache_set_texture(struct llvmpipe_tile_cache *tc,
|
lp_tile_cache_set_texture(struct llvmpipe_tile_cache *tc,
|
||||||
struct pipe_texture *texture);
|
struct pipe_texture *texture);
|
||||||
|
|
||||||
|
void
|
||||||
|
lp_tile_cache_validate_texture(struct llvmpipe_tile_cache *tc);
|
||||||
|
|
||||||
extern void
|
extern void
|
||||||
lp_flush_tile_cache(struct llvmpipe_tile_cache *tc);
|
lp_flush_tile_cache(struct llvmpipe_tile_cache *tc);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue