Home | History | Annotate | Download | only in drm
      1 
      2 #include "i915_drm_winsys.h"
      3 #include "util/u_memory.h"
      4 #include "util/u_atomic.h"
      5 #include "util/u_inlines.h"
      6 
      7 /**
      8  * Because gem does not have fence's we have to create our own fences.
      9  *
     10  * They work by keeping the batchbuffer around and checking if that has
     11  * been idled. If bo is NULL fence has expired.
     12  */
     13 struct i915_drm_fence
     14 {
     15    struct pipe_reference reference;
     16    drm_intel_bo *bo;
     17 };
     18 
     19 
     20 struct pipe_fence_handle *
     21 i915_drm_fence_create(drm_intel_bo *bo)
     22 {
     23    struct i915_drm_fence *fence = CALLOC_STRUCT(i915_drm_fence);
     24 
     25    pipe_reference_init(&fence->reference, 1);
     26    /* bo is null if fence already expired */
     27    if (bo) {
     28       drm_intel_bo_reference(bo);
     29       fence->bo = bo;
     30    }
     31 
     32    return (struct pipe_fence_handle *)fence;
     33 }
     34 
     35 static void
     36 i915_drm_fence_reference(struct i915_winsys *iws,
     37                           struct pipe_fence_handle **ptr,
     38                           struct pipe_fence_handle *fence)
     39 {
     40    struct i915_drm_fence *old = (struct i915_drm_fence *)*ptr;
     41    struct i915_drm_fence *f = (struct i915_drm_fence *)fence;
     42 
     43    if (pipe_reference(&((struct i915_drm_fence *)(*ptr))->reference, &f->reference)) {
     44       if (old->bo)
     45          drm_intel_bo_unreference(old->bo);
     46       FREE(old);
     47    }
     48    *ptr = fence;
     49 }
     50 
     51 static int
     52 i915_drm_fence_signalled(struct i915_winsys *iws,
     53                           struct pipe_fence_handle *fence)
     54 {
     55    struct i915_drm_fence *f = (struct i915_drm_fence *)fence;
     56 
     57    /* fence already expired */
     58    if (!f->bo)
     59 	   return 1;
     60 
     61    return !drm_intel_bo_busy(f->bo);
     62 }
     63 
     64 static int
     65 i915_drm_fence_finish(struct i915_winsys *iws,
     66                        struct pipe_fence_handle *fence)
     67 {
     68    struct i915_drm_fence *f = (struct i915_drm_fence *)fence;
     69 
     70    /* fence already expired */
     71    if (!f->bo)
     72       return 0;
     73 
     74    drm_intel_bo_wait_rendering(f->bo);
     75    drm_intel_bo_unreference(f->bo);
     76    f->bo = NULL;
     77 
     78    return 0;
     79 }
     80 
     81 void
     82 i915_drm_winsys_init_fence_functions(struct i915_drm_winsys *idws)
     83 {
     84    idws->base.fence_reference = i915_drm_fence_reference;
     85    idws->base.fence_signalled = i915_drm_fence_signalled;
     86    idws->base.fence_finish = i915_drm_fence_finish;
     87 }
     88