i915g: Use PIPE_FLUSH_END_OF_FRAME to trigger throttling
authorStéphane Marchesin <marcheu@chromium.org>
Fri, 8 Mar 2013 21:32:55 +0000 (13:32 -0800)
committerStéphane Marchesin <marcheu@chromium.org>
Sat, 9 Mar 2013 03:34:50 +0000 (19:34 -0800)
This helps with jittering, instead of throttling at every command
buffer we only throttle once a frame.

src/gallium/drivers/i915/i915_batch.h
src/gallium/drivers/i915/i915_blit.c
src/gallium/drivers/i915/i915_clear.c
src/gallium/drivers/i915/i915_flush.c
src/gallium/drivers/i915/i915_prim_emit.c
src/gallium/drivers/i915/i915_prim_vbuf.c
src/gallium/drivers/i915/i915_state_emit.c
src/gallium/drivers/i915/i915_winsys.h
src/gallium/winsys/i915/drm/i915_drm_batchbuffer.c
src/gallium/winsys/i915/sw/i915_sw_batchbuffer.c

index 0cb5801a14ec5c66e4568f23f9bab8952829cf03..5f2b3242f5305e284cca2a347b315739db94d5bf 100644 (file)
 #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
index baaed3767ff2e44dc9729705589177d1fcc677c3..ff81439d544b823cc877852fca243059b51e1bc6 100644 (file)
@@ -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);
index 30a39262ae078e09caae0d24f14ceba03d45857b..af75b8526af7d290a2e394803cb469cd1a788c8a 100644 (file)
@@ -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;
index d44b6f77c7f44d60ce39243148151867b5c09488..3db6ca136a80d0ef5515865a2694b659b0d0a2f9 100644 (file)
@@ -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;
index 85656cd784626ac0436ece27b20772c5bd03f038..4de5c9e898c49d30ecb4e41eaf3ed768c43e7d0a 100644 (file)
@@ -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: 
        */
index f9b2ade3fa6145fe11e4cf9b82ea1e229256ca35..4e57eeadea7324e846d6cb722442e1a274ba14ee 100644 (file)
@@ -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: 
        */
index 590a1baa42093213dd83cb2cd62918c5c4e04a72..554e967fcc0ced319f6e79b29155fc68c2791814 100644 (file)
@@ -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));
    }
index 4c42c94fc00b480806e97eddf99c98636d704ef3..8823c549a3312e0dfe7ce37a8040aa1379f40e8c 100644 (file)
@@ -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.
index 03aa1b1537a2d6ff3b9e9250244a380fae621504..9fedb121565b6e6b5d2bd0ab1df48509688f6c70 100644 (file)
@@ -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);
index 3bf54011d9eb5ede309ac39788ce083edfd07f30..b52bbaa5077e04349845ba8dfd396d9035aa8498 100644 (file)
@@ -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;