st/dri: Remove useless flush front.
authorStéphane Marchesin <marcheu@chromium.org>
Wed, 18 Jan 2012 21:03:56 +0000 (13:03 -0800)
committerStéphane Marchesin <marcheu@chromium.org>
Wed, 18 Jan 2012 21:22:27 +0000 (13:22 -0800)
In the following scenario:
- CreateContext C1
- MakeCurrent C1
- DestroyContext C1 (does not actually destroy the first context, postponed
 until the next MakeCurrent)
 - CreateContext C2
 - MakeCurrent C2
MakeCurrent will call flush on a half destroyed context, leading to crashes.
Since the other paths (destroy and makecurrent) already flush the context,
there is no need to flush here, so we remove this useless flush front call.

This fixes GPU crashes with Chrome and gallium drivers.

src/gallium/state_trackers/dri/common/dri_context.c

index b47d8d92c7e55aa4bbe30d69d52d294db34c7939..52c8f4a254b7aec9fe9412a1df39e9ee3ece8119 100644 (file)
@@ -166,7 +166,7 @@ dri_destroy_context(__DRIcontext * cPriv)
    FREE(ctx->optionCache.values);
 
    /* No particular reason to wait for command completion before
-    * destroying a context, but it is probably worthwhile flushing it
+    * destroying a context, but we flush the context here
     * to avoid having to add code elsewhere to cope with flushing a
     * partially destroyed context.
     */
@@ -188,7 +188,11 @@ dri_unbind_context(__DRIcontext * cPriv)
 
    if (--ctx->bind_count == 0) {
       if (ctx->st == ctx->stapi->get_current(ctx->stapi)) {
-         ctx->st->flush(ctx->st, ST_FLUSH_FRONT, NULL);
+         /* For conformance, unbind is supposed to flush the context.
+          * However, if we do it here we might end up flushing a partially
+          * destroyed context. Instead, we flush in dri_make_current and
+          * in dri_destroy_context which should cover all the cases.
+          */
          stapi->make_current(stapi, NULL, NULL, NULL);
       }
    }
@@ -207,6 +211,7 @@ dri_make_current(__DRIcontext * cPriv,
    struct dri_drawable *read = dri_drawable(driReadPriv);
    struct st_context_iface *old_st = ctx->stapi->get_current(ctx->stapi);
 
+   /* Flush the old context here so we don't have to flush on unbind() */
    if (old_st && old_st != ctx->st)
       old_st->flush(old_st, ST_FLUSH_FRONT, NULL);