From: Stéphane Marchesin Date: Fri, 8 Mar 2013 21:32:55 +0000 (-0800) Subject: i915g: Use PIPE_FLUSH_END_OF_FRAME to trigger throttling X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=1662178863d7b715530274148aa57e6494f935a8;p=mesa.git i915g: Use PIPE_FLUSH_END_OF_FRAME to trigger throttling This helps with jittering, instead of throttling at every command buffer we only throttle once a frame. --- diff --git a/src/gallium/drivers/i915/i915_batch.h b/src/gallium/drivers/i915/i915_batch.h index 0cb5801a14e..5f2b3242f53 100644 --- a/src/gallium/drivers/i915/i915_batch.h +++ b/src/gallium/drivers/i915/i915_batch.h @@ -47,12 +47,14 @@ #define OUT_RELOC_FENCED(buf, usage, offset) \ i915_winsys_batchbuffer_reloc(i915->batch, buf, usage, offset, true) -#define FLUSH_BATCH(fence) \ - i915_flush(i915, fence) +#define FLUSH_BATCH(fence, flags) \ + i915_flush(i915, fence, flags) /************************************************************************ * i915_flush.c */ -void i915_flush(struct i915_context *i915, struct pipe_fence_handle **fence); +extern void i915_flush(struct i915_context *i915, + struct pipe_fence_handle **fence, + enum pipe_flush_flags flags); #endif diff --git a/src/gallium/drivers/i915/i915_blit.c b/src/gallium/drivers/i915/i915_blit.c index baaed3767ff..ff81439d544 100644 --- a/src/gallium/drivers/i915/i915_blit.c +++ b/src/gallium/drivers/i915/i915_blit.c @@ -50,7 +50,7 @@ i915_fill_blit(struct i915_context *i915, __FUNCTION__, dst_buffer, dst_pitch, dst_offset, x, y, w, h); if(!i915_winsys_validate_buffers(i915->batch, &dst_buffer, 1)) { - FLUSH_BATCH(NULL); + FLUSH_BATCH(NULL, I915_FLUSH_ASYNC); assert(i915_winsys_validate_buffers(i915->batch, &dst_buffer, 1)); } @@ -72,7 +72,7 @@ i915_fill_blit(struct i915_context *i915, } if (!BEGIN_BATCH(6)) { - FLUSH_BATCH(NULL); + FLUSH_BATCH(NULL, I915_FLUSH_ASYNC); assert(BEGIN_BATCH(6)); } OUT_BATCH(CMD); @@ -111,7 +111,7 @@ i915_copy_blit(struct i915_context *i915, dst_buffer, dst_pitch, dst_offset, dst_x, dst_y, w, h); if(!i915_winsys_validate_buffers(i915->batch, buffers, 2)) { - FLUSH_BATCH(NULL); + FLUSH_BATCH(NULL, I915_FLUSH_ASYNC); assert(i915_winsys_validate_buffers(i915->batch, buffers, 2)); } @@ -144,7 +144,7 @@ i915_copy_blit(struct i915_context *i915, assert (dst_pitch > 0 && src_pitch > 0); if (!BEGIN_BATCH(8)) { - FLUSH_BATCH(NULL); + FLUSH_BATCH(NULL, I915_FLUSH_ASYNC); assert(BEGIN_BATCH(8)); } OUT_BATCH(CMD); diff --git a/src/gallium/drivers/i915/i915_clear.c b/src/gallium/drivers/i915/i915_clear.c index 30a39262ae0..af75b8526af 100644 --- a/src/gallium/drivers/i915/i915_clear.c +++ b/src/gallium/drivers/i915/i915_clear.c @@ -123,7 +123,7 @@ i915_clear_emit(struct pipe_context *pipe, unsigned buffers, i915_emit_hardware_state(i915); if (!BEGIN_BATCH(1 + 2*(7 + 7))) { - FLUSH_BATCH(NULL); + FLUSH_BATCH(NULL, I915_FLUSH_ASYNC); i915_emit_hardware_state(i915); i915->vbo_flushed = 1; @@ -174,7 +174,7 @@ i915_clear_emit(struct pipe_context *pipe, unsigned buffers, i915_emit_hardware_state(i915); if (!BEGIN_BATCH(1 + 7 + 7)) { - FLUSH_BATCH(NULL); + FLUSH_BATCH(NULL, I915_FLUSH_ASYNC); i915_emit_hardware_state(i915); i915->vbo_flushed = 1; @@ -206,7 +206,7 @@ i915_clear_emit(struct pipe_context *pipe, unsigned buffers, /* Flush after clear, its expected to be a costly operation. * This is not required, just a heuristic, but without the flush we'd need to * clobber the SCISSOR_ENABLE dynamic state. */ - FLUSH_BATCH(NULL); + FLUSH_BATCH(NULL, I915_FLUSH_ASYNC); i915->last_fired_vertices = i915->fired_vertices; i915->fired_vertices = 0; diff --git a/src/gallium/drivers/i915/i915_flush.c b/src/gallium/drivers/i915/i915_flush.c index d44b6f77c7f..3db6ca136a8 100644 --- a/src/gallium/drivers/i915/i915_flush.c +++ b/src/gallium/drivers/i915/i915_flush.c @@ -33,9 +33,9 @@ #include "pipe/p_defines.h" #include "draw/draw_context.h" #include "i915_context.h" -#include "i915_reg.h" #include "i915_batch.h" #include "i915_debug.h" +#include "i915_reg.h" static void i915_flush_pipe( struct pipe_context *pipe, @@ -43,6 +43,7 @@ static void i915_flush_pipe( struct pipe_context *pipe, enum pipe_flush_flags flags ) { struct i915_context *i915 = i915_context(pipe); + enum i915_winsys_flush_flags winsys_flags = I915_FLUSH_ASYNC; /* Only shortcut this if we have no fence, otherwise we must flush the * empty batchbuffer to get our fence back. @@ -51,9 +52,10 @@ static void i915_flush_pipe( struct pipe_context *pipe, return; } - /* If there are no flags, just flush pending commands to hardware: - */ - FLUSH_BATCH(fence); + if (flags == PIPE_FLUSH_END_OF_FRAME) + winsys_flags = I915_FLUSH_END_OF_FRAME; + + FLUSH_BATCH(fence, winsys_flags); I915_DBG(DBG_FLUSH, "%s: #####\n", __FUNCTION__); } @@ -67,11 +69,13 @@ void i915_init_flush_functions( struct i915_context *i915 ) * Here we handle all the notifications that needs to go out on a flush. * XXX might move above function to i915_pipe_flush.c and leave this here. */ -void i915_flush(struct i915_context *i915, struct pipe_fence_handle **fence) +void i915_flush(struct i915_context *i915, + struct pipe_fence_handle **fence, + enum pipe_flush_flags flags) { struct i915_winsys_batchbuffer *batch = i915->batch; - batch->iws->batchbuffer_flush(batch, fence); + batch->iws->batchbuffer_flush(batch, fence, flags); i915->vbo_flushed = 1; i915->hardware_dirty = ~0; i915->immediate_dirty = ~0; diff --git a/src/gallium/drivers/i915/i915_prim_emit.c b/src/gallium/drivers/i915/i915_prim_emit.c index 85656cd7846..4de5c9e898c 100644 --- a/src/gallium/drivers/i915/i915_prim_emit.c +++ b/src/gallium/drivers/i915/i915_prim_emit.c @@ -145,7 +145,7 @@ emit_prim( struct draw_stage *stage, assert(vertex_size >= 12); /* never smaller than 12 bytes */ if (!BEGIN_BATCH( 1 + nr * vertex_size / 4)) { - FLUSH_BATCH(NULL); + FLUSH_BATCH(NULL, I915_FLUSH_ASYNC); /* Make sure state is re-emitted after a flush: */ diff --git a/src/gallium/drivers/i915/i915_prim_vbuf.c b/src/gallium/drivers/i915/i915_prim_vbuf.c index f9b2ade3fa6..4e57eeadea7 100644 --- a/src/gallium/drivers/i915/i915_prim_vbuf.c +++ b/src/gallium/drivers/i915/i915_prim_vbuf.c @@ -466,7 +466,7 @@ draw_arrays_fallback(struct vbuf_render *render, i915_emit_hardware_state(i915); if (!BEGIN_BATCH(1 + (nr_indices + 1)/2)) { - FLUSH_BATCH(NULL); + FLUSH_BATCH(NULL, I915_FLUSH_ASYNC); /* Make sure state is re-emitted after a flush: */ @@ -514,7 +514,7 @@ i915_vbuf_render_draw_arrays(struct vbuf_render *render, i915_emit_hardware_state(i915); if (!BEGIN_BATCH(2)) { - FLUSH_BATCH(NULL); + FLUSH_BATCH(NULL, I915_FLUSH_ASYNC); /* Make sure state is re-emitted after a flush: */ @@ -634,7 +634,7 @@ i915_vbuf_render_draw_elements(struct vbuf_render *render, i915_emit_hardware_state(i915); if (!BEGIN_BATCH(1 + (nr_indices + 1)/2)) { - FLUSH_BATCH(NULL); + FLUSH_BATCH(NULL, I915_FLUSH_ASYNC); /* Make sure state is re-emitted after a flush: */ diff --git a/src/gallium/drivers/i915/i915_state_emit.c b/src/gallium/drivers/i915/i915_state_emit.c index 590a1baa420..554e967fcc0 100644 --- a/src/gallium/drivers/i915/i915_state_emit.c +++ b/src/gallium/drivers/i915/i915_state_emit.c @@ -494,12 +494,12 @@ i915_emit_hardware_state(struct i915_context *i915 ) i915_dump_hardware_dirty(i915, __FUNCTION__); if (!i915_validate_state(i915, &batch_space)) { - FLUSH_BATCH(NULL); + FLUSH_BATCH(NULL, I915_FLUSH_ASYNC); assert(i915_validate_state(i915, &batch_space)); } if(!BEGIN_BATCH(batch_space)) { - FLUSH_BATCH(NULL); + FLUSH_BATCH(NULL, I915_FLUSH_ASYNC); assert(i915_validate_state(i915, &batch_space)); assert(BEGIN_BATCH(batch_space)); } diff --git a/src/gallium/drivers/i915/i915_winsys.h b/src/gallium/drivers/i915/i915_winsys.h index 4c42c94fc00..8823c549a33 100644 --- a/src/gallium/drivers/i915/i915_winsys.h +++ b/src/gallium/drivers/i915/i915_winsys.h @@ -61,6 +61,12 @@ enum i915_winsys_buffer_tile I915_TILE_Y }; +enum i915_winsys_flush_flags +{ + I915_FLUSH_ASYNC = 0, + I915_FLUSH_END_OF_FRAME = 1 +}; + struct i915_winsys_batchbuffer { struct i915_winsys *iws; @@ -125,7 +131,8 @@ struct i915_winsys { * Flush a bufferbatch. */ void (*batchbuffer_flush)(struct i915_winsys_batchbuffer *batch, - struct pipe_fence_handle **fence); + struct pipe_fence_handle **fence, + enum i915_winsys_flush_flags flags); /** * Destroy a batchbuffer. diff --git a/src/gallium/winsys/i915/drm/i915_drm_batchbuffer.c b/src/gallium/winsys/i915/drm/i915_drm_batchbuffer.c index 03aa1b1537a..9fedb121565 100644 --- a/src/gallium/winsys/i915/drm/i915_drm_batchbuffer.c +++ b/src/gallium/winsys/i915/drm/i915_drm_batchbuffer.c @@ -151,7 +151,7 @@ i915_drm_batchbuffer_reloc(struct i915_winsys_batchbuffer *ibatch, return ret; } -static void +static void i915_drm_throttle(struct i915_drm_winsys *idws) { drmIoctl(idws->fd, DRM_IOCTL_I915_GEM_THROTTLE, NULL); @@ -159,7 +159,8 @@ i915_drm_throttle(struct i915_drm_winsys *idws) static void i915_drm_batchbuffer_flush(struct i915_winsys_batchbuffer *ibatch, - struct pipe_fence_handle **fence) + struct pipe_fence_handle **fence, + enum i915_winsys_flush_flags flags) { struct i915_drm_batchbuffer *batch = i915_drm_batchbuffer(ibatch); unsigned used; @@ -180,7 +181,8 @@ i915_drm_batchbuffer_flush(struct i915_winsys_batchbuffer *ibatch, if (ret == 0 && i915_drm_winsys(ibatch->iws)->send_cmd) ret = drm_intel_bo_exec(batch->bo, used, NULL, 0, 0); - i915_drm_throttle(i915_drm_winsys(ibatch->iws)); + if (flags & I915_FLUSH_END_OF_FRAME) + i915_drm_throttle(i915_drm_winsys(ibatch->iws)); if (ret != 0 || i915_drm_winsys(ibatch->iws)->dump_cmd) { i915_dump_batchbuffer(ibatch); diff --git a/src/gallium/winsys/i915/sw/i915_sw_batchbuffer.c b/src/gallium/winsys/i915/sw/i915_sw_batchbuffer.c index 3bf54011d9e..b52bbaa5077 100644 --- a/src/gallium/winsys/i915/sw/i915_sw_batchbuffer.c +++ b/src/gallium/winsys/i915/sw/i915_sw_batchbuffer.c @@ -100,7 +100,8 @@ i915_sw_batchbuffer_reloc(struct i915_winsys_batchbuffer *ibatch, static void i915_sw_batchbuffer_flush(struct i915_winsys_batchbuffer *ibatch, - struct pipe_fence_handle **fence) + struct pipe_fence_handle **fence, + enum i915_winsys_flush_flags flags) { struct i915_sw_batchbuffer *batch = i915_sw_batchbuffer(ibatch); unsigned used = 0;