svga: Condition preemptive flush on draw emission
authorSinclair Yeh <syeh@vmware.com>
Tue, 13 Oct 2015 19:58:26 +0000 (12:58 -0700)
committerBrian Paul <brianp@vmware.com>
Thu, 22 Oct 2015 23:19:20 +0000 (17:19 -0600)
On ultra high resolution modes, the preemptive flush flag can be
set midway through command submission, a condition that cannot be
recovered from a flush-retry, causing rendering artifacts.

This patch prevents a preemtive_flush until a draw has been
emitted.

Signed-off-by: Sinclair Yeh <syeh@vmware.com>
Reviewed-by: Thomas Hellstrom <thellstrom@vmware.com>
Reviewed-by: Charmaine Lee <charmainel@vmware.com>
Reviewed-by: Brian Paul <brianp@vmware.com>
src/gallium/drivers/svga/svga_cmd.c
src/gallium/drivers/svga/svga_cmd_vgpu10.c
src/gallium/drivers/svga/svga_winsys.h
src/gallium/winsys/svga/drm/vmw_context.c

index d3cf52f08e26c0250b0302843e8462b807383ea1..0e1e332d6cb47ce8b5c835acb129102edde30e72 100644 (file)
@@ -1016,6 +1016,8 @@ SVGA3D_BeginDrawPrimitives(struct svga_winsys_context *swc,
    *decls = declArray;
    *ranges = rangeArray;
 
+   swc->hints |= SVGA_HINT_FLAG_DRAW_EMITTED;
+
    return PIPE_OK;
 }
 
index 596ba953cd26ec3195660e3ca9bc027ab5052440..5c121089f918ecf6784372ea0c18a0b832045119 100644 (file)
@@ -535,6 +535,7 @@ SVGA3D_vgpu10_Draw(struct svga_winsys_context *swc,
 
    SVGA3D_COPY_BASIC_2(vertexCount, startVertexLocation);
 
+   swc->hints |= SVGA_HINT_FLAG_DRAW_EMITTED;
    swc->commit(swc);
    return PIPE_OK;
 }
@@ -550,6 +551,7 @@ SVGA3D_vgpu10_DrawIndexed(struct svga_winsys_context *swc,
    SVGA3D_COPY_BASIC_3(indexCount, startIndexLocation,
                        baseVertexLocation);
 
+   swc->hints |= SVGA_HINT_FLAG_DRAW_EMITTED;
    swc->commit(swc);
    return PIPE_OK;
 }
@@ -566,6 +568,7 @@ SVGA3D_vgpu10_DrawInstanced(struct svga_winsys_context *swc,
    SVGA3D_COPY_BASIC_4(vertexCountPerInstance, instanceCount,
                        startVertexLocation, startInstanceLocation);
 
+   swc->hints |= SVGA_HINT_FLAG_DRAW_EMITTED;
    swc->commit(swc);
    return PIPE_OK;
 }
@@ -584,6 +587,8 @@ SVGA3D_vgpu10_DrawIndexedInstanced(struct svga_winsys_context *swc,
                        startIndexLocation, baseVertexLocation,
                        startInstanceLocation);
 
+
+   swc->hints |= SVGA_HINT_FLAG_DRAW_EMITTED;
    swc->commit(swc);
    return PIPE_OK;
 }
@@ -593,6 +598,7 @@ SVGA3D_vgpu10_DrawAuto(struct svga_winsys_context *swc)
 {
    SVGA3D_CREATE_COMMAND(DrawAuto, DRAW_AUTO);
 
+   swc->hints |= SVGA_HINT_FLAG_DRAW_EMITTED;
    swc->commit(swc);
    return PIPE_OK;
 }
index c750603989f276c95da2e6238b622187da48e9a8..3129e46ed06aab6cefa8e71137052ee5992343d7 100644 (file)
@@ -85,6 +85,8 @@ struct winsys_handle;
 #define SVGA_QUERY_FLAG_SET        (1 << 0)
 #define SVGA_QUERY_FLAG_REF        (1 << 1)
 
+#define SVGA_HINT_FLAG_DRAW_EMITTED (1 << 0)
+
 /** Opaque surface handle */
 struct svga_winsys_surface;
 
@@ -212,6 +214,11 @@ struct svga_winsys_context
     */
    uint32 cid;
 
+   /**
+    * Flags to hint the current context state
+    */
+   uint32 hints;
+
    /**
     ** BEGIN new functions for guest-backed surfaces.
     **/
index 1675af4cbc83f172c09c921af673d0783bf7b1bd..4dc32366d61baee79533b820384e79414f573cc4 100644 (file)
@@ -251,6 +251,7 @@ vmw_swc_flush(struct svga_winsys_context *swc,
    vswc->must_flush = FALSE;
    debug_flush_flush(vswc->fctx);
 #endif
+   swc->hints &= ~SVGA_HINT_FLAG_DRAW_EMITTED;
    vswc->preemptive_flush = FALSE;
    vswc->seen_surfaces = 0;
    vswc->seen_regions = 0;
@@ -372,7 +373,8 @@ vmw_swc_region_relocation(struct svga_winsys_context *swc,
 
    if (vmw_swc_add_validate_buffer(vswc, reloc->buffer, flags)) {
       vswc->seen_regions += reloc->buffer->size;
-      if(vswc->seen_regions >= VMW_GMR_POOL_SIZE/5)
+      if ((swc->hints & SVGA_HINT_FLAG_DRAW_EMITTED) &&
+          vswc->seen_regions >= VMW_GMR_POOL_SIZE/5)
          vswc->preemptive_flush = TRUE;
    }
 
@@ -413,8 +415,10 @@ vmw_swc_mob_relocation(struct svga_winsys_context *swc,
 
    if (vmw_swc_add_validate_buffer(vswc, pb_buffer, flags)) {
       vswc->seen_mobs += pb_buffer->size;
-      /* divide by 5, tested for best performance */
-      if (vswc->seen_mobs >= vswc->vws->ioctl.max_mob_memory / VMW_MAX_MOB_MEM_FACTOR)
+
+      if ((swc->hints & SVGA_HINT_FLAG_DRAW_EMITTED) &&
+          vswc->seen_mobs >=
+            vswc->vws->ioctl.max_mob_memory / VMW_MAX_MOB_MEM_FACTOR)
          vswc->preemptive_flush = TRUE;
    }
 
@@ -475,8 +479,9 @@ vmw_swc_surface_only_relocation(struct svga_winsys_context *swc,
       ++vswc->surface.staged;
 
       vswc->seen_surfaces += vsurf->size;
-      /* divide by 5 not well tuned for performance */
-      if (vswc->seen_surfaces >= vswc->vws->ioctl.max_surface_memory / VMW_MAX_SURF_MEM_FACTOR)
+      if ((swc->hints & SVGA_HINT_FLAG_DRAW_EMITTED) &&
+          vswc->seen_surfaces >=
+            vswc->vws->ioctl.max_surface_memory / VMW_MAX_SURF_MEM_FACTOR)
          vswc->preemptive_flush = TRUE;
    }