svga: only destroy render target view from a context that created it
authorCharmaine Lee <charmainel@vmware.com>
Thu, 3 Nov 2016 17:35:55 +0000 (10:35 -0700)
committerBrian Paul <brianp@vmware.com>
Fri, 7 Apr 2017 19:46:43 +0000 (13:46 -0600)
A texture can be destroyed from a different context from which it is
created, but destroying the render target view from a different context
will cause svga device errors. Similar to shader resource view,
this patch skips destroying render target view or depth stencil view
from a non-parent context.

Fixes driver errors running NobelClinician Viewer application.

Tested with NobelClinician Viewer, MTT piglit, glretrace.

Reviewed-by: Brian Paul <brianp@vmware.com>
src/gallium/drivers/svga/svga_surface.c

index cf00527..ef566c4 100644 (file)
@@ -534,20 +534,31 @@ svga_surface_destroy(struct pipe_context *pipe,
    if (s->view_id != SVGA3D_INVALID_ID) {
       unsigned try;
 
-      assert(svga_have_vgpu10(svga));
-      for (try = 0; try < 2; try++) {
-         if (util_format_is_depth_or_stencil(s->base.format)) {
-            ret = SVGA3D_vgpu10_DestroyDepthStencilView(svga->swc, s->view_id);
-         }
-         else {
-            ret = SVGA3D_vgpu10_DestroyRenderTargetView(svga->swc, s->view_id);
+      /* The SVGA3D device will generate a device error if the
+       * render target view or depth stencil view is destroyed from
+       * a context other than the one it was created with.
+       * Similar to shader resource view, in this case, we will skip
+       * the destroy for now.
+       */
+      if (surf->context != pipe) {
+         _debug_printf("context mismatch in %s\n", __func__);
+      }
+      else {
+         assert(svga_have_vgpu10(svga));
+         for (try = 0; try < 2; try++) {
+            if (util_format_is_depth_or_stencil(s->base.format)) {
+               ret = SVGA3D_vgpu10_DestroyDepthStencilView(svga->swc, s->view_id);
+            }
+            else {
+               ret = SVGA3D_vgpu10_DestroyRenderTargetView(svga->swc, s->view_id);
+            }
+            if (ret == PIPE_OK)
+               break;
+            svga_context_flush(svga, NULL);
          }
-         if (ret == PIPE_OK)
-            break;
-         svga_context_flush(svga, NULL);
+         assert(ret == PIPE_OK);
+         util_bitmask_clear(svga->surface_view_id_bm, s->view_id);
       }
-      assert(ret == PIPE_OK);
-      util_bitmask_clear(svga->surface_view_id_bm, s->view_id);
    }
 
    pipe_resource_reference(&surf->texture, NULL);