From 76a4fd098f44ae4f226d4747b9fdaf9db5d40270 Mon Sep 17 00:00:00 2001 From: Brian Date: Tue, 23 Oct 2007 18:49:19 -0600 Subject: [PATCH] a bit more work for optimizing clears in tile cache (not enabled yet) --- src/mesa/drivers/x11/xm_surface.c | 14 ++++ src/mesa/pipe/softpipe/sp_clear.c | 18 ++++- src/mesa/pipe/softpipe/sp_tile_cache.c | 104 +++++++++++++++++++------ src/mesa/pipe/softpipe/sp_tile_cache.h | 7 +- 4 files changed, 115 insertions(+), 28 deletions(-) diff --git a/src/mesa/drivers/x11/xm_surface.c b/src/mesa/drivers/x11/xm_surface.c index b2ef70ea90d..f83c7917c4d 100644 --- a/src/mesa/drivers/x11/xm_surface.c +++ b/src/mesa/drivers/x11/xm_surface.c @@ -46,6 +46,7 @@ #include "pipe/p_defines.h" #include "pipe/softpipe/sp_context.h" #include "pipe/softpipe/sp_clear.h" +#include "pipe/softpipe/sp_tile_cache.h" #include "state_tracker/st_context.h" @@ -219,6 +220,19 @@ xmesa_clear(struct pipe_context *pipe, struct pipe_surface *ps, GLuint value) */ pipe->flush(pipe, 0); + { + struct softpipe_context *sp = softpipe_context(pipe); + struct softpipe_surface *sps = softpipe_surface(ps); + if (sps == sp_tile_cache_get_surface(sp->cbuf_cache[0])) { + float clear[4]; + clear[0] = 0.2; /* XXX hack */ + clear[1] = 0.2; + clear[2] = 0.2; + clear[3] = 0.2; + sp_tile_cache_clear(sp->cbuf_cache[0], clear); + } + } + if (xrb && xrb->ximage) { /* clearing back color buffer */ GET_CURRENT_CONTEXT(ctx); diff --git a/src/mesa/pipe/softpipe/sp_clear.c b/src/mesa/pipe/softpipe/sp_clear.c index 96bca4b171b..08b87417aa4 100644 --- a/src/mesa/pipe/softpipe/sp_clear.c +++ b/src/mesa/pipe/softpipe/sp_clear.c @@ -47,7 +47,7 @@ softpipe_clear(struct pipe_context *pipe, struct pipe_surface *ps, unsigned clearValue) { struct softpipe_context *softpipe = softpipe_context(pipe); - /*struct softpipe_surface *sps = softpipe_surface(ps);*/ + struct softpipe_surface *sps = softpipe_surface(ps); unsigned x, y, w, h; softpipe_update_derived(softpipe); /* not needed?? */ @@ -66,9 +66,23 @@ softpipe_clear(struct pipe_context *pipe, struct pipe_surface *ps, assert(w <= ps->region->pitch); assert(h <= ps->region->height); - /* XXX skip this fill if we're using tile cache */ + if (sps == sp_tile_cache_get_surface(softpipe->zbuf_cache)) { + float clear[4]; + clear[0] = 1.0; /* XXX hack */ + sp_tile_cache_clear(softpipe->zbuf_cache, clear); + } + else if (sps == sp_tile_cache_get_surface(softpipe->cbuf_cache[0])) { + float clear[4]; + clear[0] = 0.2; /* XXX hack */ + clear[1] = 0.2; /* XXX hack */ + clear[2] = 0.2; /* XXX hack */ + clear[3] = 0.2; /* XXX hack */ + sp_tile_cache_clear(softpipe->cbuf_cache[0], clear); + } + pipe->region_fill(pipe, ps->region, 0, x, y, w, h, clearValue); + #if 0 sp_clear_tile_cache(sps, clearValue); #endif diff --git a/src/mesa/pipe/softpipe/sp_tile_cache.c b/src/mesa/pipe/softpipe/sp_tile_cache.c index 1e287c91a41..129785d26da 100644 --- a/src/mesa/pipe/softpipe/sp_tile_cache.c +++ b/src/mesa/pipe/softpipe/sp_tile_cache.c @@ -37,6 +37,7 @@ #include "sp_surface.h" #include "sp_tile_cache.h" +#define CLEAR_OPTIMIZATION 0 #define NUM_ENTRIES 20 @@ -52,6 +53,7 @@ struct softpipe_tile_cache struct pipe_mipmap_tree *texture; /**< if caching a texture */ struct softpipe_cached_tile entries[NUM_ENTRIES]; uint clear_flags[(MAX_WIDTH / TILE_SIZE) * (MAX_HEIGHT / TILE_SIZE) / 32]; + float clear_value[4]; }; @@ -73,6 +75,7 @@ is_clear_flag_set(const uint *bitvec, int x, int y) x /= TILE_SIZE; y /= TILE_SIZE; pos = y * (MAX_WIDTH / TILE_SIZE) + x; + assert(pos / 32 < (MAX_WIDTH / TILE_SIZE) * (MAX_HEIGHT / TILE_SIZE) / 32); bit = bitvec[pos / 32] & (1 << (pos & 31)); return bit; } @@ -85,6 +88,7 @@ clear_clear_flag(uint *bitvec, int x, int y) x /= TILE_SIZE; y /= TILE_SIZE; pos = y * (MAX_WIDTH / TILE_SIZE) + x; + assert(pos / 32 < (MAX_WIDTH / TILE_SIZE) * (MAX_HEIGHT / TILE_SIZE) / 32); bitvec[pos / 32] &= ~(1 << (pos & 31)); } @@ -125,6 +129,13 @@ sp_tile_cache_set_surface(struct softpipe_tile_cache *tc, } +struct softpipe_surface * +sp_tile_cache_get_surface(struct softpipe_tile_cache *tc) +{ + return tc->surface; +} + + void sp_tile_cache_set_texture(struct softpipe_tile_cache *tc, struct pipe_mipmap_tree *texture) @@ -174,6 +185,7 @@ sp_flush_tile_cache(struct softpipe_tile_cache *tc) inuse++; } } + /* printf("flushed tiles in use: %d\n", inuse); */ @@ -198,17 +210,9 @@ sp_get_cached_tile(struct softpipe_tile_cache *tc, int x, int y) const int pos = CACHE_POS(x, y); struct softpipe_cached_tile *tile = tc->entries + pos; - /* - printf("output %d, %d at pos %d\n", x, y, pos); - */ - if (tile_x != tile->x || tile_y != tile->y) { - /* - printf("new tile at %d, %d, pos %d\n", tile_x, tile_y, pos); - */ - if (tile->x != -1) { /* put dirty tile back in framebuffer */ if (is_depth_stencil) { @@ -223,23 +227,63 @@ sp_get_cached_tile(struct softpipe_tile_cache *tc, int x, int y) } } - if (0/*is_clear_flag_set(tc->clear_flags, x, y)*/) { + if (is_clear_flag_set(tc->clear_flags, x, y)) { /* don't get tile from framebuffer, just clear it */ -#if 0 - printf("clear tile\n"); uint i, j; - for (i = 0; i < TILE_SIZE; i++) { - for (j = 0; j < TILE_SIZE; j++) { - tile->data.color[i][j][0] = 0.5; - tile->data.color[i][j][1] = 0.5; - tile->data.color[i][j][2] = 0.5; - tile->data.color[i][j][3] = 0.5; + /* XXX these loops could be optimized */ + switch (ps->format) { + case PIPE_FORMAT_U_Z16: + { + ushort clear_val = (ushort) (tc->clear_value[0] * 0xffff); + for (i = 0; i < TILE_SIZE; i++) { + for (j = 0; j < TILE_SIZE; j++) { + tile->data.depth16[i][j] = clear_val; + } + } + } + break; + case PIPE_FORMAT_U_Z32: + { + uint clear_val = (uint) (tc->clear_value[0] * 0xffffffff); + for (i = 0; i < TILE_SIZE; i++) { + for (j = 0; j < TILE_SIZE; j++) { + tile->data.depth32[i][j] = clear_val; + } + } + } + break; + case PIPE_FORMAT_S8_Z24: + { + uint clear_val = (uint) (tc->clear_value[0] * 0xffffff); + clear_val |= ((uint) tc->clear_value[1]) << 24; + for (i = 0; i < TILE_SIZE; i++) { + for (j = 0; j < TILE_SIZE; j++) { + tile->data.depth32[i][j] = clear_val; + } + } + } + break; + case PIPE_FORMAT_U_S8: + { + ubyte clear_val = (uint) tc->clear_value[0]; + for (i = 0; i < TILE_SIZE; i++) { + for (j = 0; j < TILE_SIZE; j++) { + tile->data.stencil8[i][j] = clear_val; + } + } + } + break; + default: + /* color */ + for (i = 0; i < TILE_SIZE; i++) { + for (j = 0; j < TILE_SIZE; j++) { + tile->data.color[i][j][0] = tc->clear_value[0]; + tile->data.color[i][j][1] = tc->clear_value[1]; + tile->data.color[i][j][2] = tc->clear_value[2]; + tile->data.color[i][j][3] = tc->clear_value[3]; + } } } -#else - (void) is_clear_flag_set; -#endif - memset(tile->data.color, 0, sizeof(tile->data.color)); clear_clear_flag(tc->clear_flags, x, y); } else { @@ -322,10 +366,22 @@ sp_get_cached_tile_tex(struct pipe_context *pipe, } - +/** + * When a whole surface is being cleared to a value we can avoid + * fetching tiles above. + * Save the color and set a 'clearflag' for each tile of the screen. + */ void -sp_clear_tile_cache(struct softpipe_tile_cache *tc, unsigned clearval) +sp_tile_cache_clear(struct softpipe_tile_cache *tc, const float value[4]) { - (void) clearval; /* XXX use this */ + tc->clear_value[0] = value[0]; + tc->clear_value[1] = value[1]; + tc->clear_value[2] = value[2]; + tc->clear_value[3] = value[3]; + +#if CLEAR_OPTIMIZATION memset(tc->clear_flags, 255, sizeof(tc->clear_flags)); +#else + memset(tc->clear_flags, 0, sizeof(tc->clear_flags)); +#endif } diff --git a/src/mesa/pipe/softpipe/sp_tile_cache.h b/src/mesa/pipe/softpipe/sp_tile_cache.h index a1cc387a12d..15245a2efba 100644 --- a/src/mesa/pipe/softpipe/sp_tile_cache.h +++ b/src/mesa/pipe/softpipe/sp_tile_cache.h @@ -29,7 +29,7 @@ #define SP_TILE_CACHE_H -#include "p_compiler.h" +#include "pipe/p_compiler.h" struct softpipe_context; @@ -66,6 +66,9 @@ extern void sp_tile_cache_set_surface(struct softpipe_tile_cache *tc, struct softpipe_surface *sps); +extern struct softpipe_surface * +sp_tile_cache_get_surface(struct softpipe_tile_cache *tc); + extern void sp_tile_cache_set_texture(struct softpipe_tile_cache *tc, struct pipe_mipmap_tree *texture); @@ -74,7 +77,7 @@ extern void sp_flush_tile_cache(struct softpipe_tile_cache *tc); extern void -sp_clear_tile_cache(struct softpipe_tile_cache *tc, unsigned clearval); +sp_tile_cache_clear(struct softpipe_tile_cache *tc, const float value[4]); extern struct softpipe_cached_tile * sp_get_cached_tile(struct softpipe_tile_cache *tc, int x, int y); -- 2.30.2