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 <brianp@vmware.com>
SVGA_DBG(DEBUG_DMA, "unref sid %p (texture)\n", tex->handle);
svga_screen_surface_destroy(ss, &tex->key, &tex->handle);
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);
ss->hud.total_resource_bytes -= tex->size;
FREE(tex->defined);
tex->can_use_upload = svga_texture_transfer_map_can_upload(svgascreen,
&tex->b.b);
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++;
svgascreen->hud.total_resource_bytes += tex->size;
svgascreen->hud.num_resources++;
* Set if the level is marked as dirty.
*/
ushort *dirty;
* 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;
flags, format,
min_lod,
max_lod - min_lod + 1,
flags, format,
min_lod,
max_lod - min_lod + 1,
&sv->key);
if (!sv->handle) {
&sv->key);
if (!sv->handle) {
int layer_pick,
unsigned num_layers,
int zslice_pick,
int layer_pick,
unsigned num_layers,
int zslice_pick,
struct svga_host_surface_cache_key *key) /* OUT */
{
struct svga_screen *ss = svga_screen(svga->pipe.screen);
struct svga_winsys_surface *handle;
boolean validated;
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",
SVGA_DBG(DEBUG_PERF,
"svga: Create surface view: layer %d zslice %d mips %d..%d\n",
- 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;
if (!handle) {
key->cachable = 0;
return NULL;
if (layer_pick < 0)
layer_pick = 0;
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;
+ }
s->handle = svga_texture_view_surface(svga, tex, bind, flags,
tex->key.format,
surf_tmpl->u.tex.level, 1,
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;
if (!s->handle) {
FREE(s);
goto done;
- 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);
}
SVGA_DBG(DEBUG_DMA, "unref sid %p (tex surface)\n", s->handle);
svga_screen_surface_destroy(ss, &s->key, &s->handle);
}
/* Sync the surface view age with the texture age */
s->age = tex->age;
/* 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);
}
SVGA_STATS_TIME_POP(ss->sws);
int layer_pick,
unsigned num_layers,
int zslice_pick,
int layer_pick,
unsigned num_layers,
int zslice_pick,
struct svga_host_surface_cache_key *key); /* OUT */
struct svga_host_surface_cache_key *key); /* OUT */