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 */
13struct i915_drm_fence
14{
15   struct pipe_reference reference;
16   drm_intel_bo *bo;
17};
18
19
20struct pipe_fence_handle *
21i915_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
35static void
36i915_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
51static int
52i915_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
64static int
65i915_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
81void
82i915_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