diff options
-rw-r--r-- | src/gallium/drivers/svga/svga_resource_texture.c | 7 | ||||
-rw-r--r-- | src/gallium/drivers/svga/svga_resource_texture.h | 10 | ||||
-rw-r--r-- | src/gallium/drivers/svga/svga_sampler_view.c | 2 | ||||
-rw-r--r-- | src/gallium/drivers/svga/svga_surface.c | 47 | ||||
-rw-r--r-- | src/gallium/drivers/svga/svga_surface.h | 1 |
5 files changed, 57 insertions, 10 deletions
diff --git a/src/gallium/drivers/svga/svga_resource_texture.c b/src/gallium/drivers/svga/svga_resource_texture.c index 20580e9dd92..1e2dfa82728 100644 --- a/src/gallium/drivers/svga/svga_resource_texture.c +++ b/src/gallium/drivers/svga/svga_resource_texture.c @@ -238,6 +238,10 @@ svga_texture_destroy(struct pipe_screen *screen, SVGA_DBG(DEBUG_DMA, "unref sid %p (texture)\n", tex->handle); svga_screen_surface_destroy(ss, &tex->key, &tex->handle); + /* Destroy the backed surface handle if exists */ + if (tex->backed_handle) + svga_screen_surface_destroy(ss, &tex->backed_key, &tex->backed_handle); + ss->hud.total_resource_bytes -= tex->size; FREE(tex->defined); @@ -1119,6 +1123,9 @@ svga_texture_create(struct pipe_screen *screen, tex->can_use_upload = svga_texture_transfer_map_can_upload(svgascreen, &tex->b.b); + /* Initialize the backing resource cache */ + tex->backed_handle = NULL; + svgascreen->hud.total_resource_bytes += tex->size; svgascreen->hud.num_resources++; diff --git a/src/gallium/drivers/svga/svga_resource_texture.h b/src/gallium/drivers/svga/svga_resource_texture.h index 9f7b0c6e659..4cb98970a5b 100644 --- a/src/gallium/drivers/svga/svga_resource_texture.h +++ b/src/gallium/drivers/svga/svga_resource_texture.h @@ -104,6 +104,16 @@ struct svga_texture * Set if the level is marked as dirty. */ ushort *dirty; + + /** + * A cached backing host side surface to be used if this texture is being + * used for rendering and sampling at the same time. + * Currently we only cache one handle. If needed, we can extend this to + * support multiple handles. + */ + struct svga_host_surface_cache_key backed_key; + struct svga_winsys_surface *backed_handle; + unsigned backed_age; }; diff --git a/src/gallium/drivers/svga/svga_sampler_view.c b/src/gallium/drivers/svga/svga_sampler_view.c index ee4ef3ca7b0..80a1b926a99 100644 --- a/src/gallium/drivers/svga/svga_sampler_view.c +++ b/src/gallium/drivers/svga/svga_sampler_view.c @@ -151,7 +151,7 @@ svga_get_tex_sampler_view(struct pipe_context *pipe, flags, format, min_lod, max_lod - min_lod + 1, - -1, 1, -1, + -1, 1, -1, FALSE, &sv->key); if (!sv->handle) { diff --git a/src/gallium/drivers/svga/svga_surface.c b/src/gallium/drivers/svga/svga_surface.c index cbeaa2390cd..795a7b8ffd6 100644 --- a/src/gallium/drivers/svga/svga_surface.c +++ b/src/gallium/drivers/svga/svga_surface.c @@ -158,11 +158,13 @@ svga_texture_view_surface(struct svga_context *svga, int layer_pick, unsigned num_layers, int zslice_pick, + boolean cacheable, struct svga_host_surface_cache_key *key) /* OUT */ { struct svga_screen *ss = svga_screen(svga->pipe.screen); struct svga_winsys_surface *handle; boolean validated; + boolean needCopyResource; SVGA_DBG(DEBUG_PERF, "svga: Create surface view: layer %d zslice %d mips %d..%d\n", @@ -198,9 +200,22 @@ svga_texture_view_surface(struct svga_context *svga, return NULL; } - SVGA_DBG(DEBUG_DMA, "surface_create for texture view\n"); - handle = svga_screen_surface_create(ss, bind_flags, PIPE_USAGE_DEFAULT, - &validated, key); + if (cacheable && tex->backed_handle && + memcmp(key, &tex->backed_key, sizeof *key) == 0) { + handle = tex->backed_handle; + needCopyResource = tex->backed_age < tex->age; + } else { + SVGA_DBG(DEBUG_DMA, "surface_create for texture view\n"); + handle = svga_screen_surface_create(ss, bind_flags, PIPE_USAGE_DEFAULT, + &validated, key); + needCopyResource = TRUE; + + if (cacheable && !tex->backed_handle) { + tex->backed_handle = handle; + memcpy(&tex->backed_key, key, sizeof *key); + } + } + if (!handle) { key->cachable = 0; return NULL; @@ -211,10 +226,13 @@ svga_texture_view_surface(struct svga_context *svga, if (layer_pick < 0) layer_pick = 0; - svga_texture_copy_handle_resource(svga, tex, handle, - key->numMipLevels, - key->numFaces * key->arraySize, - zslice_pick, start_mip, layer_pick); + if (needCopyResource) { + svga_texture_copy_handle_resource(svga, tex, handle, + key->numMipLevels, + key->numFaces * key->arraySize, + zslice_pick, start_mip, layer_pick); + tex->backed_age = tex->age; + } return handle; } @@ -328,7 +346,8 @@ svga_create_surface_view(struct pipe_context *pipe, s->handle = svga_texture_view_surface(svga, tex, bind, flags, tex->key.format, surf_tmpl->u.tex.level, 1, - layer, nlayers, zslice, &s->key); + layer, nlayers, zslice, + TRUE, &s->key); if (!s->handle) { FREE(s); goto done; @@ -585,7 +604,10 @@ svga_surface_destroy(struct pipe_context *pipe, s->backed = NULL; } - if (s->handle != t->handle) { + /* Destroy the surface handle if this is a backed handle and + * it is not being cached in the texture. + */ + if (s->handle != t->handle && s->handle != t->backed_handle) { SVGA_DBG(DEBUG_DMA, "unref sid %p (tex surface)\n", s->handle); svga_screen_surface_destroy(ss, &s->key, &s->handle); } @@ -750,6 +772,13 @@ svga_propagate_surface(struct svga_context *svga, struct pipe_surface *surf, /* Sync the surface view age with the texture age */ s->age = tex->age; + + /* If this backed surface is cached in the texture, + * update the backed age as well. + */ + if (tex->backed_handle == s->handle) { + tex->backed_age = tex->age; + } } SVGA_STATS_TIME_POP(ss->sws); diff --git a/src/gallium/drivers/svga/svga_surface.h b/src/gallium/drivers/svga/svga_surface.h index d1628d54525..8df1006d276 100644 --- a/src/gallium/drivers/svga/svga_surface.h +++ b/src/gallium/drivers/svga/svga_surface.h @@ -102,6 +102,7 @@ svga_texture_view_surface(struct svga_context *svga, int layer_pick, unsigned num_layers, int zslice_pick, + boolean cacheable, struct svga_host_surface_cache_key *key); /* OUT */ |