From 231d53923918f4a885e74da0a063dcbf1a4353e3 Mon Sep 17 00:00:00 2001 From: Sinclair Yeh Date: Tue, 13 Oct 2015 12:58:26 -0700 Subject: [PATCH] svga: Condition preemptive flush on draw emission 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 Reviewed-by: Thomas Hellstrom Reviewed-by: Charmaine Lee Reviewed-by: Brian Paul --- src/gallium/drivers/svga/svga_cmd.c | 2 ++ src/gallium/drivers/svga/svga_cmd_vgpu10.c | 6 ++++++ src/gallium/drivers/svga/svga_winsys.h | 7 +++++++ src/gallium/winsys/svga/drm/vmw_context.c | 15 ++++++++++----- 4 files changed, 25 insertions(+), 5 deletions(-) diff --git a/src/gallium/drivers/svga/svga_cmd.c b/src/gallium/drivers/svga/svga_cmd.c index d3cf52f08e2..0e1e332d6cb 100644 --- a/src/gallium/drivers/svga/svga_cmd.c +++ b/src/gallium/drivers/svga/svga_cmd.c @@ -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; } diff --git a/src/gallium/drivers/svga/svga_cmd_vgpu10.c b/src/gallium/drivers/svga/svga_cmd_vgpu10.c index 596ba953cd2..5c121089f91 100644 --- a/src/gallium/drivers/svga/svga_cmd_vgpu10.c +++ b/src/gallium/drivers/svga/svga_cmd_vgpu10.c @@ -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; } diff --git a/src/gallium/drivers/svga/svga_winsys.h b/src/gallium/drivers/svga/svga_winsys.h index c750603989f..3129e46ed06 100644 --- a/src/gallium/drivers/svga/svga_winsys.h +++ b/src/gallium/drivers/svga/svga_winsys.h @@ -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. **/ diff --git a/src/gallium/winsys/svga/drm/vmw_context.c b/src/gallium/winsys/svga/drm/vmw_context.c index 1675af4cbc8..4dc32366d61 100644 --- a/src/gallium/winsys/svga/drm/vmw_context.c +++ b/src/gallium/winsys/svga/drm/vmw_context.c @@ -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; } -- 2.30.2