This helps with jittering, instead of throttling at every command buffer we only throttle once a frame.tags/mesa-9.2-rc1
@@ -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 |
@@ -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); |
@@ -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; |
@@ -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; |
@@ -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: | |||
*/ |
@@ -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: | |||
*/ |
@@ -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)); | |||
} |
@@ -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. |
@@ -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); |
@@ -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; |