summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorCharmaine Lee <[email protected]>2016-10-26 16:15:23 -0700
committerBrian Paul <[email protected]>2016-11-03 14:29:23 -0600
commit8a195e2fd59886b4f47c7761bda96478bb0f8f95 (patch)
tree0db28b278146bbd22e54f2ad45e9baa265e3bbda /src
parent06bba2452f00d6fa8a4b233567995af0480a3f4d (diff)
svga: invalidate new surface before it is bound to a render target view
Invalidate a "new" surface before it is bound to a render target view or depth stencil view in order to avoid the unnecessary host side copy of the surface data before it is rendered to. Note that, recycled surface is already invalidated before it is reused. Reviewed-by: Brian Paul <[email protected]>
Diffstat (limited to 'src')
-rw-r--r--src/gallium/drivers/svga/svga_resource_buffer_upload.c5
-rw-r--r--src/gallium/drivers/svga/svga_resource_texture.c3
-rw-r--r--src/gallium/drivers/svga/svga_resource_texture.h9
-rw-r--r--src/gallium/drivers/svga/svga_screen_cache.c5
-rw-r--r--src/gallium/drivers/svga/svga_screen_cache.h1
-rw-r--r--src/gallium/drivers/svga/svga_surface.c22
6 files changed, 42 insertions, 3 deletions
diff --git a/src/gallium/drivers/svga/svga_resource_buffer_upload.c b/src/gallium/drivers/svga/svga_resource_buffer_upload.c
index ac8cedfd3b7..b327a1679e4 100644
--- a/src/gallium/drivers/svga/svga_resource_buffer_upload.c
+++ b/src/gallium/drivers/svga/svga_resource_buffer_upload.c
@@ -146,6 +146,8 @@ svga_buffer_create_host_surface(struct svga_screen *ss,
assert(!sbuf->user);
if (!sbuf->handle) {
+ boolean validated;
+
sbuf->key.flags = 0;
sbuf->key.format = SVGA3D_BUFFER;
@@ -187,7 +189,8 @@ svga_buffer_create_host_surface(struct svga_screen *ss,
sbuf->b.b.width0);
sbuf->handle = svga_screen_surface_create(ss, sbuf->b.b.bind,
- sbuf->b.b.usage, &sbuf->key);
+ sbuf->b.b.usage,
+ &validated, &sbuf->key);
if (!sbuf->handle)
return PIPE_ERROR_OUT_OF_MEMORY;
diff --git a/src/gallium/drivers/svga/svga_resource_texture.c b/src/gallium/drivers/svga/svga_resource_texture.c
index 89909336e91..20580e9dd92 100644
--- a/src/gallium/drivers/svga/svga_resource_texture.c
+++ b/src/gallium/drivers/svga/svga_resource_texture.c
@@ -1102,7 +1102,8 @@ svga_texture_create(struct pipe_screen *screen,
SVGA_DBG(DEBUG_DMA, "surface_create for texture\n", tex->handle);
tex->handle = svga_screen_surface_create(svgascreen, bindings,
- tex->b.b.usage, &tex->key);
+ tex->b.b.usage,
+ &tex->validated, &tex->key);
if (!tex->handle) {
goto fail;
}
diff --git a/src/gallium/drivers/svga/svga_resource_texture.h b/src/gallium/drivers/svga/svga_resource_texture.h
index 6347ef6352f..9f7b0c6e659 100644
--- a/src/gallium/drivers/svga/svga_resource_texture.h
+++ b/src/gallium/drivers/svga/svga_resource_texture.h
@@ -78,6 +78,13 @@ struct svga_texture
struct svga_winsys_surface *handle;
/**
+ * Whether the host side surface is validated, either through the
+ * InvalidateGBSurface command or after the surface is updated
+ * or rendered to.
+ */
+ boolean validated;
+
+ /**
* Whether the host side surface is imported and not created by this
* driver.
*/
@@ -195,6 +202,7 @@ svga_define_texture_level(struct svga_texture *tex,
{
check_face_level(tex, face, level);
tex->defined[face] |= 1 << level;
+ tex->validated = TRUE;
}
@@ -213,6 +221,7 @@ svga_set_texture_rendered_to(struct svga_texture *tex,
{
check_face_level(tex, face, level);
tex->rendered_to[face] |= 1 << level;
+ tex->validated = TRUE;
}
diff --git a/src/gallium/drivers/svga/svga_screen_cache.c b/src/gallium/drivers/svga/svga_screen_cache.c
index 86a04136e64..76e34258f9c 100644
--- a/src/gallium/drivers/svga/svga_screen_cache.c
+++ b/src/gallium/drivers/svga/svga_screen_cache.c
@@ -433,10 +433,12 @@ svga_screen_cache_init(struct svga_screen *svgascreen)
* allocate a new surface.
* \param bind_flags bitmask of PIPE_BIND_x flags
* \param usage one of PIPE_USAGE_x values
+ * \param validated return True if the surface is a reused surface
*/
struct svga_winsys_surface *
svga_screen_surface_create(struct svga_screen *svgascreen,
unsigned bind_flags, enum pipe_resource_usage usage,
+ boolean *validated,
struct svga_host_surface_cache_key *key)
{
struct svga_winsys_screen *sws = svgascreen->sws;
@@ -510,6 +512,7 @@ svga_screen_surface_create(struct svga_screen *svgascreen,
key->numMipLevels,
key->numFaces,
key->arraySize);
+ *validated = TRUE;
}
}
@@ -536,6 +539,8 @@ svga_screen_surface_create(struct svga_screen *svgascreen,
key->size.width,
key->size.height,
key->size.depth);
+
+ *validated = FALSE;
}
return handle;
diff --git a/src/gallium/drivers/svga/svga_screen_cache.h b/src/gallium/drivers/svga/svga_screen_cache.h
index 9365f751f72..619603a8238 100644
--- a/src/gallium/drivers/svga/svga_screen_cache.h
+++ b/src/gallium/drivers/svga/svga_screen_cache.h
@@ -145,6 +145,7 @@ svga_screen_cache_init(struct svga_screen *svgascreen);
struct svga_winsys_surface *
svga_screen_surface_create(struct svga_screen *svgascreen,
unsigned bind_flags, enum pipe_resource_usage usage,
+ boolean *validated,
struct svga_host_surface_cache_key *key);
void
diff --git a/src/gallium/drivers/svga/svga_surface.c b/src/gallium/drivers/svga/svga_surface.c
index 2ffdce5e10c..cf0052727df 100644
--- a/src/gallium/drivers/svga/svga_surface.c
+++ b/src/gallium/drivers/svga/svga_surface.c
@@ -120,6 +120,7 @@ svga_texture_view_surface(struct svga_context *svga,
struct svga_winsys_surface *handle;
uint32_t i, j;
unsigned z_offset = 0;
+ boolean validated;
SVGA_DBG(DEBUG_PERF,
"svga: Create surface view: layer %d zslice %d mips %d..%d\n",
@@ -156,7 +157,8 @@ svga_texture_view_surface(struct svga_context *svga,
}
SVGA_DBG(DEBUG_DMA, "surface_create for texture view\n");
- handle = svga_screen_surface_create(ss, bind_flags, PIPE_USAGE_DEFAULT, key);
+ handle = svga_screen_surface_create(ss, bind_flags, PIPE_USAGE_DEFAULT,
+ &validated, key);
if (!handle) {
key->cachable = 0;
return NULL;
@@ -434,6 +436,23 @@ svga_validate_surface_view(struct svga_context *svga, struct svga_surface *s)
if (s && s->view_id == SVGA3D_INVALID_ID) {
SVGA3dResourceType resType;
SVGA3dRenderTargetViewDesc desc;
+ struct svga_texture *stex = svga_texture(s->base.texture);
+
+ if (stex->validated == FALSE) {
+ assert(stex->handle);
+
+ /* We are about to render into a surface that has not been validated.
+ * First invalidate the surface so that the device does not
+ * need to update the host-side copy with the invalid
+ * content when the associated mob is first bound to the surface.
+ */
+ ret = SVGA3D_InvalidateGBSurface(svga->swc, stex->handle);
+ if (ret != PIPE_OK) {
+ s = NULL;
+ goto done;
+ }
+ stex->validated = TRUE;
+ }
desc.tex.mipSlice = s->real_level;
desc.tex.firstArraySlice = s->real_layer + s->real_zslice;
@@ -481,6 +500,7 @@ svga_validate_surface_view(struct svga_context *svga, struct svga_surface *s)
}
}
+done:
SVGA_STATS_TIME_POP(svga_sws(svga));
return s ? &s->base : NULL;