diff --git a/src/gallium/drivers/i915/i915_batchbuffer.h b/src/gallium/drivers/i915/i915_batchbuffer.h index 4bf2b703f0a..afffa04e500 100644 --- a/src/gallium/drivers/i915/i915_batchbuffer.h +++ b/src/gallium/drivers/i915/i915_batchbuffer.h @@ -101,4 +101,15 @@ i915_winsys_batchbuffer_reloc(struct i915_winsys_batchbuffer *batch, return batch->iws->batchbuffer_reloc(batch, buffer, usage, offset, fenced); } +static inline void +i915_winsys_batchbuffer_emit_start(struct i915_winsys_batchbuffer *batch) +{ + batch->iws->emit_start(batch); +} + +static inline void +i915_winsys_batchbuffer_emit_restart(struct i915_winsys_batchbuffer *batch) +{ + batch->iws->emit_restart(batch); +} #endif diff --git a/src/gallium/drivers/i915/i915_blit.c b/src/gallium/drivers/i915/i915_blit.c index 7c6fa201482..313c4620be9 100644 --- a/src/gallium/drivers/i915/i915_blit.c +++ b/src/gallium/drivers/i915/i915_blit.c @@ -37,15 +37,11 @@ i915_fill_blit(struct i915_context *i915, unsigned cpp, unsigned rgba_mask, unsigned color) { unsigned BR13, CMD; + bool flushed = false; I915_DBG(DBG_BLIT, "%s dst:buf(%p)/%d+%d %d,%d sz:%dx%d\n", __func__, dst_buffer, dst_pitch, dst_offset, x, y, w, h); - if (!i915_winsys_validate_buffers(i915->batch, &dst_buffer, 1)) { - FLUSH_BATCH(NULL, I915_FLUSH_ASYNC); - assert(i915_winsys_validate_buffers(i915->batch, &dst_buffer, 1)); - } - switch (cpp) { case 1: case 2: @@ -61,17 +57,25 @@ i915_fill_blit(struct i915_context *i915, unsigned cpp, unsigned rgba_mask, return; } - if (!BEGIN_BATCH(6)) { + i915_winsys_batchbuffer_emit_start(i915->batch); + while (true) { + if (!BEGIN_BATCH(6)) { + FLUSH_BATCH(NULL, I915_FLUSH_ASYNC); + assert(BEGIN_BATCH(6)); + } + OUT_BATCH(CMD); + OUT_BATCH(BR13); + OUT_BATCH((y << 16) | x); + OUT_BATCH(((y + h) << 16) | (x + w)); + OUT_RELOC_FENCED(dst_buffer, I915_USAGE_2D_TARGET, dst_offset); + OUT_BATCH(color); + if (flushed || i915_winsys_validate_buffers(i915->batch, &dst_buffer, 0)) + break; + i915_winsys_batchbuffer_emit_restart(i915->batch); FLUSH_BATCH(NULL, I915_FLUSH_ASYNC); - assert(BEGIN_BATCH(6)); + assert(i915_winsys_validate_buffers(i915->batch, &dst_buffer, 0)); + flushed = true; } - OUT_BATCH(CMD); - OUT_BATCH(BR13); - OUT_BATCH((y << 16) | x); - OUT_BATCH(((y + h) << 16) | (x + w)); - OUT_RELOC_FENCED(dst_buffer, I915_USAGE_2D_TARGET, dst_offset); - OUT_BATCH(color); - i915_set_flush_dirty(i915, I915_FLUSH_CACHE); } @@ -86,18 +90,13 @@ i915_copy_blit(struct i915_context *i915, unsigned cpp, unsigned CMD, BR13; int dst_y2 = dst_y + h; int dst_x2 = dst_x + w; - struct i915_winsys_buffer *buffers[2] = {src_buffer, dst_buffer}; + bool flushed = false; I915_DBG(DBG_BLIT, "%s src:buf(%p)/%d+%d %d,%d dst:buf(%p)/%d+%d %d,%d sz:%dx%d\n", __func__, src_buffer, src_pitch, src_offset, src_x, src_y, dst_buffer, dst_pitch, dst_offset, dst_x, dst_y, w, h); - if (!i915_winsys_validate_buffers(i915->batch, buffers, 2)) { - FLUSH_BATCH(NULL, I915_FLUSH_ASYNC); - assert(i915_winsys_validate_buffers(i915->batch, buffers, 2)); - } - switch (cpp) { case 1: case 2: @@ -123,19 +122,27 @@ i915_copy_blit(struct i915_context *i915, unsigned cpp, * need for either at this stage. */ assert(dst_pitch > 0 && src_pitch > 0); - - if (!BEGIN_BATCH(8)) { + + i915_winsys_batchbuffer_emit_start(i915->batch); + while (true) { + if (!BEGIN_BATCH(8)) { + FLUSH_BATCH(NULL, I915_FLUSH_ASYNC); + assert(BEGIN_BATCH(8)); + } + OUT_BATCH(CMD); + OUT_BATCH(BR13); + OUT_BATCH((dst_y << 16) | dst_x); + OUT_BATCH((dst_y2 << 16) | dst_x2); + OUT_RELOC_FENCED(dst_buffer, I915_USAGE_2D_TARGET, dst_offset); + OUT_BATCH((src_y << 16) | src_x); + OUT_BATCH(((int)src_pitch & 0xffff)); + OUT_RELOC_FENCED(src_buffer, I915_USAGE_2D_SOURCE, src_offset); + if (flushed || i915_winsys_validate_buffers(i915->batch, &dst_buffer, 0)) + break; + i915_winsys_batchbuffer_emit_restart(i915->batch); FLUSH_BATCH(NULL, I915_FLUSH_ASYNC); - assert(BEGIN_BATCH(8)); + assert(i915_winsys_validate_buffers(i915->batch, &dst_buffer, 0)); + flushed = true; } - OUT_BATCH(CMD); - OUT_BATCH(BR13); - OUT_BATCH((dst_y << 16) | dst_x); - OUT_BATCH((dst_y2 << 16) | dst_x2); - OUT_RELOC_FENCED(dst_buffer, I915_USAGE_2D_TARGET, dst_offset); - OUT_BATCH((src_y << 16) | src_x); - OUT_BATCH(((int)src_pitch & 0xffff)); - OUT_RELOC_FENCED(src_buffer, I915_USAGE_2D_SOURCE, src_offset); - i915_set_flush_dirty(i915, I915_FLUSH_CACHE); } diff --git a/src/gallium/drivers/i915/i915_winsys.h b/src/gallium/drivers/i915/i915_winsys.h index aaa0154b300..4c81d690506 100644 --- a/src/gallium/drivers/i915/i915_winsys.h +++ b/src/gallium/drivers/i915/i915_winsys.h @@ -74,6 +74,9 @@ struct i915_winsys_batchbuffer { size_t size; size_t relocs; + + uint8_t *ptr_start; + int reloc_count_start; /*@}*/ }; @@ -130,6 +133,16 @@ struct i915_winsys { * Destroy a batchbuffer. */ void (*batchbuffer_destroy)(struct i915_winsys_batchbuffer *batch); + + /** + * Store start values of emit + */ + void (*emit_start)(struct i915_winsys_batchbuffer *batch); + + /** + * Go back to start values + */ + void (*emit_restart)(struct i915_winsys_batchbuffer *batch); /*@}*/ /** diff --git a/src/gallium/winsys/i915/drm/i915_drm_batchbuffer.c b/src/gallium/winsys/i915/drm/i915_drm_batchbuffer.c index 2add5367c9f..7e87764cbe9 100644 --- a/src/gallium/winsys/i915/drm/i915_drm_batchbuffer.c +++ b/src/gallium/winsys/i915/drm/i915_drm_batchbuffer.c @@ -84,7 +84,7 @@ i915_drm_batchbuffer_validate_buffers(struct i915_winsys_batchbuffer *batch, for (i = 0; i < num_of_buffers; i++) bos[i+1] = intel_bo(buffer[i]); - ret = drm_intel_bufmgr_check_aperture_space(bos, num_of_buffers); + ret = drm_intel_bufmgr_check_aperture_space(bos, num_of_buffers + 1); if (ret != 0) return false; @@ -227,6 +227,22 @@ i915_drm_batchbuffer_destroy(struct i915_winsys_batchbuffer *ibatch) FREE(batch); } +static void +i915_drm_batchbuffer_emit_start(struct i915_winsys_batchbuffer *ibatch) +{ + struct i915_drm_batchbuffer *batch = i915_drm_batchbuffer(ibatch); + ibatch->ptr_start = ibatch->ptr; + ibatch->reloc_count_start = drm_intel_gem_bo_get_reloc_count(batch->bo); +} + +static void +i915_drm_batchbuffer_emit_restart(struct i915_winsys_batchbuffer *ibatch) +{ + struct i915_drm_batchbuffer *batch = i915_drm_batchbuffer(ibatch); + drm_intel_gem_bo_clear_relocs(batch->bo, ibatch->reloc_count_start); + ibatch->ptr = ibatch->ptr_start; +} + void i915_drm_winsys_init_batchbuffer_functions(struct i915_drm_winsys *idws) { idws->base.batchbuffer_create = i915_drm_batchbuffer_create; @@ -234,4 +250,6 @@ void i915_drm_winsys_init_batchbuffer_functions(struct i915_drm_winsys *idws) idws->base.batchbuffer_reloc = i915_drm_batchbuffer_reloc; idws->base.batchbuffer_flush = i915_drm_batchbuffer_flush; idws->base.batchbuffer_destroy = i915_drm_batchbuffer_destroy; + idws->base.emit_start = i915_drm_batchbuffer_emit_start; + idws->base.emit_restart = i915_drm_batchbuffer_emit_restart; }