aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/gallium/drivers/softpipe/sp_context.h3
-rw-r--r--src/gallium/drivers/softpipe/sp_state_derived.c14
-rw-r--r--src/gallium/drivers/softpipe/sp_texture.c3
-rw-r--r--src/gallium/drivers/softpipe/sp_texture.h2
-rw-r--r--src/gallium/drivers/softpipe/sp_tile_cache.c80
-rw-r--r--src/gallium/drivers/softpipe/sp_tile_cache.h3
6 files changed, 70 insertions, 35 deletions
diff --git a/src/gallium/drivers/softpipe/sp_context.h b/src/gallium/drivers/softpipe/sp_context.h
index 7888c2f644b..f66f0b7849d 100644
--- a/src/gallium/drivers/softpipe/sp_context.h
+++ b/src/gallium/drivers/softpipe/sp_context.h
@@ -149,7 +149,8 @@ struct softpipe_context {
struct softpipe_tile_cache *cbuf_cache[PIPE_MAX_COLOR_BUFS];
struct softpipe_tile_cache *zsbuf_cache;
-
+
+ unsigned tex_timestamp;
struct softpipe_tile_cache *tex_cache[PIPE_MAX_SAMPLERS];
unsigned use_sse : 1;
diff --git a/src/gallium/drivers/softpipe/sp_state_derived.c b/src/gallium/drivers/softpipe/sp_state_derived.c
index 75be99768c9..629a1f8e293 100644
--- a/src/gallium/drivers/softpipe/sp_state_derived.c
+++ b/src/gallium/drivers/softpipe/sp_state_derived.c
@@ -32,6 +32,7 @@
#include "draw/draw_vertex.h"
#include "draw/draw_private.h"
#include "sp_context.h"
+#include "sp_screen.h"
#include "sp_state.h"
@@ -200,6 +201,10 @@ update_tgsi_samplers( struct softpipe_context *softpipe )
softpipe->tgsi.frag_samplers[i].sampler = softpipe->sampler[i];
softpipe->tgsi.frag_samplers[i].texture = softpipe->texture[i];
}
+
+ for (i = 0; i < PIPE_MAX_SAMPLERS; i++) {
+ sp_tile_cache_validate_texture( softpipe->tex_cache[i] );
+ }
}
/* Hopefully this will remain quite simple, otherwise need to pull in
@@ -207,6 +212,15 @@ update_tgsi_samplers( struct softpipe_context *softpipe )
*/
void softpipe_update_derived( struct softpipe_context *softpipe )
{
+ struct softpipe_screen *sp_screen = softpipe_screen(softpipe->pipe.screen);
+
+ /* Check for updated textures.
+ */
+ if (softpipe->tex_timestamp != sp_screen->timestamp) {
+ softpipe->tex_timestamp = sp_screen->timestamp;
+ softpipe->dirty |= SP_NEW_TEXTURE;
+ }
+
if (softpipe->dirty & (SP_NEW_SAMPLER |
SP_NEW_TEXTURE))
update_tgsi_samplers( softpipe );
diff --git a/src/gallium/drivers/softpipe/sp_texture.c b/src/gallium/drivers/softpipe/sp_texture.c
index 7a533dad9f0..0c84375bf10 100644
--- a/src/gallium/drivers/softpipe/sp_texture.c
+++ b/src/gallium/drivers/softpipe/sp_texture.c
@@ -227,7 +227,8 @@ softpipe_get_tex_surface(struct pipe_screen *screen,
if (ps->usage & (PIPE_BUFFER_USAGE_CPU_WRITE |
PIPE_BUFFER_USAGE_GPU_WRITE)) {
/* Mark the surface as dirty. The tile cache will look for this. */
- spt->modified = TRUE;
+ spt->timestamp++;
+ softpipe_screen(screen)->timestamp++;
}
ps->face = face;
diff --git a/src/gallium/drivers/softpipe/sp_texture.h b/src/gallium/drivers/softpipe/sp_texture.h
index 893aa7d11d8..42df722a2d1 100644
--- a/src/gallium/drivers/softpipe/sp_texture.h
+++ b/src/gallium/drivers/softpipe/sp_texture.h
@@ -48,7 +48,7 @@ struct softpipe_texture
*/
struct pipe_buffer *buffer;
- boolean modified;
+ unsigned timestamp;
};
struct softpipe_transfer
diff --git a/src/gallium/drivers/softpipe/sp_tile_cache.c b/src/gallium/drivers/softpipe/sp_tile_cache.c
index 306284808cd..79b1e036be8 100644
--- a/src/gallium/drivers/softpipe/sp_tile_cache.c
+++ b/src/gallium/drivers/softpipe/sp_tile_cache.c
@@ -54,7 +54,10 @@ struct softpipe_tile_cache
struct pipe_surface *surface; /**< the surface we're caching */
struct pipe_transfer *transfer;
void *transfer_map;
+
struct pipe_texture *texture; /**< if caching a texture */
+ unsigned timestamp;
+
struct softpipe_cached_tile entries[NUM_ENTRIES];
uint clear_flags[(MAX_WIDTH / TILE_SIZE) * (MAX_HEIGHT / TILE_SIZE) / 32];
float clear_color[4]; /**< for color bufs */
@@ -231,6 +234,23 @@ sp_tile_cache_unmap_transfers(struct softpipe_tile_cache *tc)
}
}
+void
+sp_tile_cache_validate_texture(struct softpipe_tile_cache *tc)
+{
+ if (tc->texture) {
+ struct softpipe_texture *spt = softpipe_texture(tc->texture);
+ if (spt->timestamp != tc->timestamp) {
+ /* texture was modified, invalidate all cached tiles */
+ uint i;
+ _debug_printf("INV %d %d\n", tc->timestamp, spt->timestamp);
+ for (i = 0; i < NUM_ENTRIES; i++) {
+ tc->entries[i].x = -3;
+ }
+
+ tc->timestamp = spt->timestamp;
+ }
+ }
+}
/**
* Specify the texture to cache.
@@ -243,27 +263,29 @@ sp_tile_cache_set_texture(struct softpipe_tile_cache *tc,
assert(!tc->transfer);
- pipe_texture_reference(&tc->texture, texture);
+ if (tc->texture != texture) {
+ pipe_texture_reference(&tc->texture, texture);
- if (tc->tex_trans) {
- struct pipe_screen *screen = tc->tex_trans->texture->screen;
+ if (tc->tex_trans) {
+ 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->transfer_unmap(screen, tc->tex_trans);
- tc->tex_trans_map = NULL;
+ screen->tex_transfer_destroy(tc->tex_trans);
+ tc->tex_trans = NULL;
}
- screen->tex_transfer_destroy(tc->tex_trans);
- tc->tex_trans = NULL;
- }
+ /* mark as entries as invalid/empty */
+ /* 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 */
- /* 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 */
}
-
- tc->tex_face = -1; /* any invalid value here */
}
@@ -443,7 +465,7 @@ sp_get_cached_tile(struct softpipe_tile_cache *tc, int x, int y)
if (tile_x != tile->x ||
tile_y != tile->y) {
- if (tile->x != -1) {
+ if (tile->x >= 0) {
/* put dirty tile back in framebuffer */
if (tc->depth_stencil) {
pipe_put_tile_raw(pt,
@@ -522,30 +544,24 @@ sp_get_cached_tile_tex(struct softpipe_tile_cache *tc,
face, level);
struct softpipe_cached_tile *tile = tc->entries + pos;
- if (tc->texture) {
- struct softpipe_texture *spt = softpipe_texture(tc->texture);
- if (spt->modified) {
- /* texture was modified, invalidate all cached tiles */
- uint p;
- for (p = 0; p < NUM_ENTRIES; p++) {
- tile = tc->entries + p;
- tile->x = -1;
- }
- spt->modified = FALSE;
- }
- }
-
if (tile_x != tile->x ||
tile_y != tile->y ||
z != tile->z ||
face != tile->face ||
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
- printf("miss at %u x=%d y=%d z=%d face=%d level=%d\n", pos,
- x/TILE_SIZE, y/TILE_SIZE, z, face, level);
+ _debug_printf("miss at %u: x=%d y=%d z=%d face=%d level=%d\n"
+ " 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
+
/* check if we need to get a new transfer */
if (!tc->tex_trans ||
tc->tex_face != face ||
diff --git a/src/gallium/drivers/softpipe/sp_tile_cache.h b/src/gallium/drivers/softpipe/sp_tile_cache.h
index 639cde67059..0d165b4ad74 100644
--- a/src/gallium/drivers/softpipe/sp_tile_cache.h
+++ b/src/gallium/drivers/softpipe/sp_tile_cache.h
@@ -83,6 +83,9 @@ extern void
sp_tile_cache_set_texture(struct softpipe_tile_cache *tc,
struct pipe_texture *texture);
+void
+sp_tile_cache_validate_texture(struct softpipe_tile_cache *tc);
+
extern void
sp_flush_tile_cache(struct softpipe_tile_cache *tc);