• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 *
i915_drm_fence_create(drm_intel_bo * bo)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
i915_drm_fence_reference(struct i915_winsys * iws,struct pipe_fence_handle ** ptr,struct pipe_fence_handle * fence)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
i915_drm_fence_signalled(struct i915_winsys * iws,struct pipe_fence_handle * fence)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
i915_drm_fence_finish(struct i915_winsys * iws,struct pipe_fence_handle * fence)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
i915_drm_winsys_init_fence_functions(struct i915_drm_winsys * idws)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