This tells libdrm to not take fence registers into account. Instead it checks for fence register availability for the current batchbuffer in the various uxa_prepare_* hooks where it's known how many fences are needed _exactly_.
Signed-off-by: Daniel Vetter <[email protected]> --- src/i830.h | 13 ++++++- src/i830_batchbuffer.c | 2 + src/i830_driver.c | 32 ++++++++++++++++ src/i830_render.c | 12 +++--- src/i830_uxa.c | 95 +++++++++++++++++++++++++++++++++++++++++------- src/i915_render.c | 13 ++++--- 6 files changed, 139 insertions(+), 28 deletions(-) diff --git a/src/i830.h b/src/i830.h index 88949f6..fd9a798 100644 --- a/src/i830.h +++ b/src/i830.h @@ -71,11 +71,13 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "i915_drm.h" #include "uxa.h" +struct intel_pixmap; Bool i830_uxa_init(ScreenPtr pScreen); void i830_uxa_create_screen_resources(ScreenPtr pScreen); void i830_uxa_block_handler(ScreenPtr pScreen); -Bool i830_get_aperture_space(ScrnInfoPtr scrn, drm_intel_bo ** bo_table, - int num_bos); +Bool i830_get_aperture_space(ScrnInfoPtr scrn, + struct intel_pixmap ** pixmap_table, + int num_pixmaps); /* classic doubly-link circular list */ struct list { @@ -152,6 +154,7 @@ struct intel_pixmap { uint32_t batch_write_domain; uint32_t batch_read_domains; struct list flush, batch, in_flight; + unsigned int fence_allocated : 1; }; struct intel_pixmap *i830_get_pixmap_intel(PixmapPtr pixmap); @@ -262,6 +265,12 @@ typedef struct intel_screen_private { struct list flush_pixmaps; struct list in_flight; + /** Available fence registers */ + int available_fences; + int unfenced_relocs; + /** Fence registers used in current batchbuffer */ + int used_fences; + /* For Xvideo */ Bool use_drmmode_overlay; #ifdef INTEL_XVMC diff --git a/src/i830_batchbuffer.c b/src/i830_batchbuffer.c index 492472e..b41e567 100644 --- a/src/i830_batchbuffer.c +++ b/src/i830_batchbuffer.c @@ -176,8 +176,10 @@ void intel_batch_submit(ScrnInfoPtr scrn) batch); entry->batch_read_domains = entry->batch_write_domain = 0; + entry->fence_allocated = 0; list_del(&entry->batch); } + intel->used_fences = 0; /* Mark that we need to flush whatever potential rendering we've done in the * blockhandler. We could set this less often, but it's probably not worth diff --git a/src/i830_driver.c b/src/i830_driver.c index db8af06..b84c3a0 100644 --- a/src/i830_driver.c +++ b/src/i830_driver.c @@ -1051,6 +1051,38 @@ void i830_init_bufmgr(ScrnInfoPtr scrn) intel->bufmgr = drm_intel_bufmgr_gem_init(intel->drmSubFD, batch_size); drm_intel_bufmgr_gem_enable_reuse(intel->bufmgr); drm_intel_bufmgr_gem_enable_fenced_relocs(intel->bufmgr); + intel->unfenced_relocs = + drm_intel_bufmgr_gem_disable_fence_accounting(intel->bufmgr); + + if (!IS_I965G(intel)) { + drm_i915_getparam_t gp; + int ret; + + gp.param = I915_PARAM_NUM_FENCES_AVAIL; + gp.value = &intel->available_fences; + ret = ioctl(intel->drmSubFD, DRM_IOCTL_I915_GETPARAM, &gp); + if (ret) { + fprintf(stderr, "get fences failed: %d [%d]\n", ret, + errno); + fprintf(stderr, "param: %d, val: %d\n", gp.param, + *gp.value); + intel->available_fences = 0; + } else { + /* XXX The kernel reports the total number of fences, + * including any that may be pinned. + * + * libdrm subtracts to fences for maximal two scanout + * buffers. But we know that there's (currently) only + * at most one tiled scanout buffer, so subtract just + * one. */ + intel->available_fences -= 1; + if (intel->available_fences < 0) + intel->available_fences = 0; + } + } else + intel->available_fences = 0; + + intel->used_fences = 0; list_init(&intel->batch_pixmaps); list_init(&intel->flush_pixmaps); diff --git a/src/i830_render.c b/src/i830_render.c index 8e559c9..b415fe9 100644 --- a/src/i830_render.c +++ b/src/i830_render.c @@ -438,11 +438,10 @@ i830_prepare_composite(int op, PicturePtr source_picture, { ScrnInfoPtr scrn = xf86Screens[dest_picture->pDrawable->pScreen->myNum]; intel_screen_private *intel = intel_get_screen_private(scrn); - drm_intel_bo *bo_table[] = { - NULL, /* batch_bo */ - i830_get_pixmap_bo(source), - mask ? i830_get_pixmap_bo(mask) : NULL, - i830_get_pixmap_bo(dest), + struct intel_pixmap *pixmap_table[] = { + i830_get_pixmap_intel(source), + mask ? i830_get_pixmap_intel(mask) : NULL, + i830_get_pixmap_intel(dest), }; intel->render_source_picture = source_picture; @@ -464,7 +463,8 @@ i830_prepare_composite(int op, PicturePtr source_picture, if (!i830_get_dest_format(dest_picture, &intel->render_dest_format)) return FALSE; - if (!i830_get_aperture_space(scrn, bo_table, ARRAY_SIZE(bo_table))) + if (!i830_get_aperture_space(scrn, pixmap_table, + ARRAY_SIZE(pixmap_table))) return FALSE; if (mask) { diff --git a/src/i830_uxa.c b/src/i830_uxa.c index 984069e..8ed1198 100644 --- a/src/i830_uxa.c +++ b/src/i830_uxa.c @@ -80,11 +80,67 @@ const int I830PatternROP[16] = { static int uxa_pixmap_index; +static Bool +i830_get_fence_registers(ScrnInfoPtr scrn, + struct intel_pixmap ** pixmap_table, + int num_pixmaps) +{ + intel_screen_private *intel = intel_get_screen_private(scrn); + int i, retried = 0; + int reserved_fences; + + if (IS_I965G(intel)) + return TRUE; + +retry: + reserved_fences = 0; + for (i = 0; i < num_pixmaps; i++) { + if (pixmap_table[i]->tiling == I915_TILING_NONE) + continue; + + if (pixmap_table[i]->fence_allocated) + continue; + + pixmap_table[i]->fence_allocated = 1; + reserved_fences++; + } + + if (reserved_fences + intel->used_fences + <= intel->available_fences) { + intel->used_fences += reserved_fences; + return TRUE; + } + + if (retried) { + intel_debug_fallback(scrn, "Couldn't get fence " + "registers for BOs\n"); + return FALSE; + } + + intel_batch_submit(scrn); + for (i = 0; i < num_pixmaps; i++) + pixmap_table[i]->fence_allocated = 0; + retried = 1; + goto retry; +} + Bool -i830_get_aperture_space(ScrnInfoPtr scrn, drm_intel_bo ** bo_table, - int num_bos) +i830_get_aperture_space(ScrnInfoPtr scrn, + struct intel_pixmap ** pixmap_table, + int num_pixmaps) { intel_screen_private *intel = intel_get_screen_private(scrn); + drm_intel_bo *bo_table[num_pixmaps + 1]; + int i; + + bo_table[0] = NULL; /* for the batch bo */ + + for (i = 0; i < num_pixmaps; i++) { + if (pixmap_table[i]) + bo_table[i + 1] = pixmap_table[i]->bo; + else + bo_table[i + 1] = NULL; + } if (intel->batch_bo == NULL) { intel_debug_fallback(scrn, "VT inactive\n"); @@ -92,16 +148,21 @@ i830_get_aperture_space(ScrnInfoPtr scrn, drm_intel_bo ** bo_table, } bo_table[0] = intel->batch_bo; - if (drm_intel_bufmgr_check_aperture_space(bo_table, num_bos) != 0) { + if (drm_intel_bufmgr_check_aperture_space(bo_table, num_pixmaps) != 0) { intel_batch_submit(scrn); bo_table[0] = intel->batch_bo; - if (drm_intel_bufmgr_check_aperture_space(bo_table, num_bos) != - 0) { + if (drm_intel_bufmgr_check_aperture_space(bo_table, + num_pixmaps) != 0) { intel_debug_fallback(scrn, "Couldn't get aperture " "space for BOs\n"); return FALSE; } } + + if (!intel->unfenced_relocs) + return i830_get_fence_registers(scrn, pixmap_table, + num_pixmaps); + return TRUE; } @@ -203,9 +264,8 @@ i830_uxa_prepare_solid(PixmapPtr pixmap, int alu, Pixel planemask, Pixel fg) { ScrnInfoPtr scrn = xf86Screens[pixmap->drawable.pScreen->myNum]; intel_screen_private *intel = intel_get_screen_private(scrn); - drm_intel_bo *bo_table[] = { - NULL, /* batch_bo */ - i830_get_pixmap_bo(pixmap), + struct intel_pixmap *pixmap_table[] = { + i830_get_pixmap_intel(pixmap), }; if (IS_GEN6(intel)) { @@ -237,7 +297,12 @@ i830_uxa_prepare_solid(PixmapPtr pixmap, int alu, Pixel planemask, Pixel fg) return FALSE; } - if (!i830_get_aperture_space(scrn, bo_table, ARRAY_SIZE(bo_table))) + if (!i830_get_aperture_space(scrn, pixmap_table, + ARRAY_SIZE(pixmap_table))) + return FALSE; + + if (!i830_get_fence_registers(scrn, pixmap_table, + ARRAY_SIZE(pixmap_table))) return FALSE; intel->BR[13] = (I830PatternROP[alu] & 0xff) << 16; @@ -321,10 +386,9 @@ i830_uxa_prepare_copy(PixmapPtr source, PixmapPtr dest, int xdir, { ScrnInfoPtr scrn = xf86Screens[dest->drawable.pScreen->myNum]; intel_screen_private *intel = intel_get_screen_private(scrn); - drm_intel_bo *bo_table[] = { - NULL, /* batch_bo */ - i830_get_pixmap_bo(source), - i830_get_pixmap_bo(dest), + struct intel_pixmap *pixmap_table[] = { + i830_get_pixmap_intel(source), + i830_get_pixmap_intel(dest), }; if (IS_GEN6(intel)) { @@ -343,9 +407,12 @@ i830_uxa_prepare_copy(PixmapPtr source, PixmapPtr dest, int xdir, return FALSE; } - if (!i830_get_aperture_space(scrn, bo_table, ARRAY_SIZE(bo_table))) + if (!i830_get_aperture_space(scrn, pixmap_table, ARRAY_SIZE(pixmap_table))) return FALSE; + if (!i830_get_fence_registers(scrn, pixmap_table, + ARRAY_SIZE(pixmap_table))) + return FALSE; if (!intel_check_pitch_2d(source)) return FALSE; if (!intel_check_pitch_2d(dest)) diff --git a/src/i915_render.c b/src/i915_render.c index 98b5b88..cbc82f7 100644 --- a/src/i915_render.c +++ b/src/i915_render.c @@ -367,11 +367,10 @@ i915_prepare_composite(int op, PicturePtr source_picture, { ScrnInfoPtr scrn = xf86Screens[source_picture->pDrawable->pScreen->myNum]; intel_screen_private *intel = intel_get_screen_private(scrn); - drm_intel_bo *bo_table[] = { - NULL, /* batch_bo */ - i830_get_pixmap_bo(source), - mask ? i830_get_pixmap_bo(mask) : NULL, - i830_get_pixmap_bo(dest), + struct intel_pixmap *pixmap_table[] = { + i830_get_pixmap_intel(source), + mask ? i830_get_pixmap_intel(mask) : NULL, + i830_get_pixmap_intel(dest), }; int tex_unit = 0; @@ -424,8 +423,10 @@ i915_prepare_composite(int op, PicturePtr source_picture, &intel->i915_render_state.dst_format)) return FALSE; - if (!i830_get_aperture_space(scrn, bo_table, ARRAY_SIZE(bo_table))) + if (!i830_get_aperture_space(scrn, pixmap_table, + ARRAY_SIZE(pixmap_table))) return FALSE; + intel->dst_coord_adjust = 0; intel->src_coord_adjust = 0; intel->mask_coord_adjust = 0; -- 1.7.0.4 _______________________________________________ Intel-gfx mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/intel-gfx
