summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorCharmaine Lee <[email protected]>2017-04-25 14:32:59 -0600
committerBrian Paul <[email protected]>2017-04-26 11:37:59 -0600
commit3626112214d25738411d8577f485fe51e9f8c96a (patch)
treee066033ceedfac4d76c4ab5196f12d0076f47e83
parent7f2f695d4d6447bdaf70acda3cdae8aa43b6df3a (diff)
svga: cache the backing surface handle in the texture object
CinebenchR15 not only binds the same texture for rendering and sampling, it actually changes the framebuffer buffer attachment very often, causing a lot of backed surface view to be created and a lot of surface copies to be done. This patch caches the backed surface handle in the texture resource and allows the backed surface view to reuse the backed surface handle. With this patch, the number of backed surface view reduces from 1312 to 3. Unfortunately, this does not eliminate all the surface copies. There are still surface copies involved when we switch from original to backed surface handle for rendering. Tested with CinebenchR15, NobelClinicianViewer, Turbine, Lightsmark2008, MTT glretrace, MTT piglit. Reviewed-by: Brian Paul <[email protected]>
-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 */