diff options
author | Carl Worth <cworth@cworth.org> | 2008-12-03 13:49:52 -0800 |
---|---|---|
committer | Zhenyu Wang <zhenyu.z.wang@intel.com> | 2008-12-11 09:45:50 +0800 |
commit | a13bb74af9d0dcfa5a6c9991711f46d258b962e1 (patch) | |
tree | 624509b8e9b6688e91b62762f499d65ed2b7125c /src | |
parent | 6ca0d7e6ff05bff2bb88bfae64c2d79ac115bd38 (diff) |
i965: Add batch_flush_notify hook to create new vertex-buffer bo
This avoids mapping a buffer object which is being referenced
by a batch that has already been flushed, (which is a terribly
expensive operation).
On my machine this brings the performance of x11perf -aa10text
from 85k back to 150k, (where it was before a recent kernel
upgrade). Also, before this patch, when I used my X server
actively performance would drop as low as 15k---hopefully that
bug is gone with this change.
(cherry picked from commit e8b95efbf5d9c3a5b75b2bb8b5b51844b5fcdfbc)
Diffstat (limited to 'src')
-rw-r--r-- | src/i830.h | 5 | ||||
-rw-r--r-- | src/i830_batchbuffer.c | 3 | ||||
-rw-r--r-- | src/i830_driver.c | 5 | ||||
-rw-r--r-- | src/i965_render.c | 25 |
4 files changed, 36 insertions, 2 deletions
@@ -538,6 +538,8 @@ typedef struct _I830Rec { #endif CloseScreenProcPtr CloseScreen; + void (*batch_flush_notify)(ScrnInfoPtr pScrn); + #ifdef I830_USE_EXA ExaDriverPtr EXADriverPtr; #endif @@ -944,6 +946,9 @@ Bool i965_prepare_composite(int op, PicturePtr pSrc, PicturePtr pMask, void i965_composite(PixmapPtr pDst, int srcX, int srcY, int maskX, int maskY, int dstX, int dstY, int w, int h); +void +i965_batch_flush_notify(ScrnInfoPtr pScrn); + Bool i830_get_transformed_coordinates(int x, int y, PictTransformPtr transform, float *x_out, float *y_out); diff --git a/src/i830_batchbuffer.c b/src/i830_batchbuffer.c index 9aa99ed9..13d939e6 100644 --- a/src/i830_batchbuffer.c +++ b/src/i830_batchbuffer.c @@ -201,4 +201,7 @@ intel_batch_flush(ScrnInfoPtr pScrn, Bool flushed) */ if (pI830->memory_manager != NULL) pI830->need_mi_flush = TRUE; + + if (pI830->batch_flush_notify) + pI830->batch_flush_notify (pScrn); } diff --git a/src/i830_driver.c b/src/i830_driver.c index 3327fbf2..4f87efb8 100644 --- a/src/i830_driver.c +++ b/src/i830_driver.c @@ -3364,6 +3364,11 @@ I830ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) } } + if (IS_I965G(pI830)) + pI830->batch_flush_notify = i965_batch_flush_notify; + else + pI830->batch_flush_notify = NULL; + miInitializeBackingStore(pScreen); xf86SetBackingStore(pScreen); xf86SetSilkenMouse(pScreen); diff --git a/src/i965_render.c b/src/i965_render.c index da6ded6e..a92c964a 100644 --- a/src/i965_render.c +++ b/src/i965_render.c @@ -1000,6 +1000,7 @@ _emit_batch_header_for_composite_internal (ScrnInfoPtr pScrn, Bool check_twice) render_state->vertex_buffer_bo = dri_bo_alloc (pI830->bufmgr, "vb", sizeof (gen4_vertex_buffer), 4096); + render_state->vb_offset = 0; } bo_table[0] = pI830->batch_bo; @@ -1480,15 +1481,22 @@ i965_composite(PixmapPtr pDst, int srcX, int srcY, int maskX, int maskY, } } + /* We're about to do a BEGIN_BATCH(12) for the vertex setup. And + * we first need to ensure that that's not going to cause a flush + * since we need to not flush between setting up our vertices in + * the VB and emitting them into the batch. */ + intel_batch_require_space(pScrn, pI830, 12 * 4); + /* If the vertex buffer is too full, then we flush and re-emit all * necessary state into the batch for the composite operation. */ if (render_state->vb_offset + VERTEX_FLOATS_PER_COMPOSITE > VERTEX_BUFFER_SIZE) { dri_bo_unreference (render_state->vertex_buffer_bo); render_state->vertex_buffer_bo = NULL; - render_state->vb_offset = 0; - _emit_batch_header_for_composite (pScrn); } + if (render_state->vertex_buffer_bo == NULL) + _emit_batch_header_for_composite (pScrn); + /* Map the vertex_buffer buffer object so we can write to it. */ dri_bo_map (render_state->vertex_buffer_bo, 1); vb = render_state->vertex_buffer_bo->virtual; @@ -1571,6 +1579,19 @@ i965_composite(PixmapPtr pDst, int srcX, int srcY, int maskX, int maskY, #endif } +void +i965_batch_flush_notify(ScrnInfoPtr pScrn) +{ + I830Ptr pI830 = I830PTR(pScrn); + struct gen4_render_state *render_state = pI830->gen4_render_state; + + /* Once a batch is emitted, we never want to map again any buffer + * object being referenced by that batch, (which would be very + * expensive). */ + dri_bo_unreference (render_state->vertex_buffer_bo); + render_state->vertex_buffer_bo = NULL; +} + /** * Called at EnterVT so we can set up our offsets into the state buffer. */ |