diff options
authorCharmaine Lee <>2017-04-19 18:34:36 -0700
committerAndres Gomez <>2017-06-28 20:15:04 +0300
commitc56792f758755cdc4dd18b04aa79c2a7cc73de78 (patch)
parentbf425b48eabb67dc98daa78d4d4640bd6d07d810 (diff)
svga: use the winsys interface to invalidate surface
Instead of directly sending the InvalidateGBSurface command, this patch uses the invalidate_surface interface. Fixes Linux VM piglit failures including ext_texture_array-gen-mipmap, fbo-generatemipmap-array S3TC_DXT1 Reviewed-by: Brian Paul <> (cherry picked from commit 019d5d534682145a3d5921b061ea46f8c872d6a0) Squashed with commit: svga: fix pre-mature flushing of the command buffer When surface_invalidate is called to invalidate a newly created surface in svga_validate_surface_view(), it is possible that the command buffer is already full, and in this case, currently, the associated wddm winsys function will flush the command buffer and resend the invalidate surface command. However, this can pre-maturely flush the command buffer if there is still pending image updates to be patched. To fix the problem, this patch will add a return status to the surface_invalidate interface and if it returns FALSE, the caller will call svga_context_flush() to do the proper context flush. Note, we don't call svga_context_flush() if surface_invalidate() fails when flushing the screen surface cache though, because it is already in the process of context flush, all the image updates are already patched, calling svga_context_flush() can trigger a deadlock. So in this case, we call the winsys context flush interface directly to flush the command buffer. Fixes driver errors and graphics corruption running Tropics. VMware bug 1891975. Also tested with MTT glretrace, piglit and various OpenGL apps such as Heaven, CinebenchR15, NobelClinicianViewer, Lightsmark, GoogleEarth. cc: Reviewed-by: Brian Paul <> (cherry picked from commit 3fbdab8778d3b55ed6053a3781e92aeff85ca174)
5 files changed, 23 insertions, 8 deletions
diff --git a/src/gallium/drivers/svga/svga_screen_cache.c b/src/gallium/drivers/svga/svga_screen_cache.c
index 82d2ebce976..d0255fa5e43 100644
--- a/src/gallium/drivers/svga/svga_screen_cache.c
+++ b/src/gallium/drivers/svga/svga_screen_cache.c
@@ -362,7 +362,21 @@ svga_screen_cache_flush(struct svga_screen *svgascreen,
/* It is now safe to invalidate the surface content.
* It will be done using the current context.
- svga->swc->surface_invalidate(svga->swc, entry->handle);
+ if (svga->swc->surface_invalidate(svga->swc, entry->handle) != PIPE_OK) {
+ enum pipe_error ret;
+ /* Even though surface invalidation here is done after the command
+ * buffer is flushed, it is still possible that it will
+ * fail because there might be just enough of this command that is
+ * filling up the command buffer, so in this case we will call
+ * the winsys flush directly to flush the buffer.
+ * Note, we don't want to call svga_context_flush() here because
+ * this function itself is called inside svga_context_flush().
+ */
+ svga->swc->flush(svga->swc, NULL);
+ ret = svga->swc->surface_invalidate(svga->swc, entry->handle);
+ assert(ret == PIPE_OK);
+ }
/* add the entry to the invalidated list */
LIST_ADD(&entry->head, &cache->invalidated);
diff --git a/src/gallium/drivers/svga/svga_surface.c b/src/gallium/drivers/svga/svga_surface.c
index bbd31c63c8c..331a4cd2aa7 100644
--- a/src/gallium/drivers/svga/svga_surface.c
+++ b/src/gallium/drivers/svga/svga_surface.c
@@ -502,10 +502,10 @@ svga_validate_surface_view(struct svga_context *svga, struct svga_surface *s)
* 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;
+ if (svga->swc->surface_invalidate(svga->swc, stex->handle) != PIPE_OK) {
+ svga_context_flush(svga, NULL);
+ ret = svga->swc->surface_invalidate(svga->swc, stex->handle);
+ assert(ret == PIPE_OK);
stex->validated = TRUE;
diff --git a/src/gallium/drivers/svga/svga_winsys.h b/src/gallium/drivers/svga/svga_winsys.h
index 3bb23ce1438..77f9c1442f0 100644
--- a/src/gallium/drivers/svga/svga_winsys.h
+++ b/src/gallium/drivers/svga/svga_winsys.h
@@ -394,7 +394,7 @@ struct svga_winsys_context
* Invalidate the content of this surface
- void
+ enum pipe_error
(*surface_invalidate)(struct svga_winsys_context *swc,
struct svga_winsys_surface *surface);
diff --git a/src/gallium/winsys/svga/drm/vmw_surface.c b/src/gallium/winsys/svga/drm/vmw_surface.c
index 80cc0914cc0..04aa932784b 100644
--- a/src/gallium/winsys/svga/drm/vmw_surface.c
+++ b/src/gallium/winsys/svga/drm/vmw_surface.c
@@ -176,7 +176,7 @@ vmw_svga_winsys_surface_unmap(struct svga_winsys_context *swc,
+enum pipe_error
vmw_svga_winsys_surface_invalidate(struct svga_winsys_context *swc,
struct svga_winsys_surface *surf)
@@ -186,6 +186,7 @@ vmw_svga_winsys_surface_invalidate(struct svga_winsys_context *swc,
* when guest-backed surface is enabled, that implies DMA is always enabled;
* hence, surface invalidation is not needed.
+ return PIPE_OK;
diff --git a/src/gallium/winsys/svga/drm/vmw_surface.h b/src/gallium/winsys/svga/drm/vmw_surface.h
index d6f2381220a..0fdc8de1d56 100644
--- a/src/gallium/winsys/svga/drm/vmw_surface.h
+++ b/src/gallium/winsys/svga/drm/vmw_surface.h
@@ -94,7 +94,7 @@ void
vmw_svga_winsys_surface_unmap(struct svga_winsys_context *swc,
struct svga_winsys_surface *srf,
boolean *rebind);
+enum pipe_error
vmw_svga_winsys_surface_invalidate(struct svga_winsys_context *swc,
struct svga_winsys_surface *srf);