summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/gallium/drivers/svga/svga_resource_texture.c7
-rw-r--r--src/gallium/drivers/svga/svga_resource_texture.h10
-rw-r--r--src/gallium/drivers/svga/svga_sampler_view.c2
-rw-r--r--src/gallium/drivers/svga/svga_surface.c47
-rw-r--r--src/gallium/drivers/svga/svga_surface.h1
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 */