| |
| #include "i915_drm_winsys.h" |
| #include "util/u_memory.h" |
| #include "util/u_atomic.h" |
| #include "util/u_inlines.h" |
| |
| /** |
| * Because gem does not have fence's we have to create our own fences. |
| * |
| * They work by keeping the batchbuffer around and checking if that has |
| * been idled. If bo is NULL fence has expired. |
| */ |
| struct i915_drm_fence |
| { |
| struct pipe_reference reference; |
| drm_intel_bo *bo; |
| }; |
| |
| |
| struct pipe_fence_handle * |
| i915_drm_fence_create(drm_intel_bo *bo) |
| { |
| struct i915_drm_fence *fence = CALLOC_STRUCT(i915_drm_fence); |
| |
| pipe_reference_init(&fence->reference, 1); |
| /* bo is null if fence already expired */ |
| if (bo) { |
| drm_intel_bo_reference(bo); |
| fence->bo = bo; |
| } |
| |
| return (struct pipe_fence_handle *)fence; |
| } |
| |
| static void |
| i915_drm_fence_reference(struct i915_winsys *iws, |
| struct pipe_fence_handle **ptr, |
| struct pipe_fence_handle *fence) |
| { |
| struct i915_drm_fence *old = (struct i915_drm_fence *)*ptr; |
| struct i915_drm_fence *f = (struct i915_drm_fence *)fence; |
| |
| if (pipe_reference(&((struct i915_drm_fence *)(*ptr))->reference, &f->reference)) { |
| if (old->bo) |
| drm_intel_bo_unreference(old->bo); |
| FREE(old); |
| } |
| *ptr = fence; |
| } |
| |
| static int |
| i915_drm_fence_signalled(struct i915_winsys *iws, |
| struct pipe_fence_handle *fence) |
| { |
| struct i915_drm_fence *f = (struct i915_drm_fence *)fence; |
| |
| /* fence already expired */ |
| if (!f->bo) |
| return 1; |
| |
| return !drm_intel_bo_busy(f->bo); |
| } |
| |
| static int |
| i915_drm_fence_finish(struct i915_winsys *iws, |
| struct pipe_fence_handle *fence) |
| { |
| struct i915_drm_fence *f = (struct i915_drm_fence *)fence; |
| |
| /* fence already expired */ |
| if (!f->bo) |
| return 0; |
| |
| drm_intel_bo_wait_rendering(f->bo); |
| drm_intel_bo_unreference(f->bo); |
| f->bo = NULL; |
| |
| return 0; |
| } |
| |
| void |
| i915_drm_winsys_init_fence_functions(struct i915_drm_winsys *idws) |
| { |
| idws->base.fence_reference = i915_drm_fence_reference; |
| idws->base.fence_signalled = i915_drm_fence_signalled; |
| idws->base.fence_finish = i915_drm_fence_finish; |
| } |