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

Reply via email to