|
| 1 | +--- a/src/gallium/drivers/v3d/v3d_context.c |
| 2 | ++++ b/src/gallium/drivers/v3d/v3d_context.c |
| 3 | +@@ -379,6 +379,8 @@ |
| 4 | + |
| 5 | + v3d->fd = screen->fd; |
| 6 | + |
| 7 | ++ v3d->fence = NULL; |
| 8 | ++ |
| 9 | + slab_create_child(&v3d->transfer_pool, &screen->transfer_pool); |
| 10 | + |
| 11 | + v3d->uploader = u_upload_create_default(&v3d->base); |
| 12 | +--- a/src/gallium/drivers/v3d/v3d_context.h |
| 13 | ++++ b/src/gallium/drivers/v3d/v3d_context.h |
| 14 | +@@ -555,6 +555,9 @@ |
| 15 | + uint32_t prim_counts_offset; |
| 16 | + struct pipe_debug_callback debug; |
| 17 | + /** @} */ |
| 18 | ++ |
| 19 | ++ // Custom field to track fence destruction |
| 20 | ++ struct v3d_fence * fence; |
| 21 | + }; |
| 22 | + |
| 23 | + struct v3d_rasterizer_state { |
| 24 | +--- a/src/gallium/frontends/dri/dri_drawable.c |
| 25 | ++++ b/src/gallium/frontends/dri/dri_drawable.c |
| 26 | +@@ -523,14 +523,22 @@ |
| 27 | + struct pipe_screen *screen = drawable->screen->base.screen; |
| 28 | + struct pipe_fence_handle *new_fence = NULL; |
| 29 | + |
| 30 | ++ /* bool */ screen->fence_lock(); |
| 31 | ++ |
| 32 | + st->flush(st, flush_flags, &new_fence, args.ctx ? notify_before_flush_cb : NULL, &args); |
| 33 | ++ screen->fence_finish(screen, NULL, new_fence, PIPE_TIMEOUT_INFINITE); |
| 34 | ++ screen->fence_reference(screen, &new_fence, NULL); |
| 35 | ++ |
| 36 | ++ /* bool */ screen->fence_unlock(); |
| 37 | + |
| 38 | ++#ifdef _0 |
| 39 | + /* throttle on the previous fence */ |
| 40 | + if (drawable->throttle_fence) { |
| 41 | + screen->fence_finish(screen, NULL, drawable->throttle_fence, PIPE_TIMEOUT_INFINITE); |
| 42 | + screen->fence_reference(screen, &drawable->throttle_fence, NULL); |
| 43 | + } |
| 44 | + drawable->throttle_fence = new_fence; |
| 45 | ++#endif |
| 46 | + } |
| 47 | + else if (flags & (__DRI2_FLUSH_DRAWABLE | __DRI2_FLUSH_CONTEXT)) { |
| 48 | + st->flush(st, flush_flags, NULL, args.ctx ? notify_before_flush_cb : NULL, &args); |
| 49 | +--- a/src/gallium/include/pipe/p_screen.h |
| 50 | ++++ b/src/gallium/include/pipe/p_screen.h |
| 51 | +@@ -604,6 +604,10 @@ |
| 52 | + unsigned int (*get_dmabuf_modifier_planes)(struct pipe_screen *screen, |
| 53 | + uint64_t modifier, |
| 54 | + enum pipe_format format); |
| 55 | ++ |
| 56 | ++ // (Un)lock the flow create, finish, reference |
| 57 | ++ bool (* fence_lock) (void); |
| 58 | ++ bool (* fence_unlock) (void); |
| 59 | + }; |
| 60 | + |
| 61 | + |
| 62 | +--- a/src/mesa/state_tracker/st_cb_flush.c |
| 63 | ++++ b/src/mesa/state_tracker/st_cb_flush.c |
| 64 | +@@ -70,6 +70,9 @@ |
| 65 | + struct pipe_fence_handle *fence = NULL; |
| 66 | + |
| 67 | + st_flush_bitmap_cache(st); |
| 68 | ++ |
| 69 | ++ /* bool */ st->screen->fence_lock (); |
| 70 | ++ |
| 71 | + st_flush(st, &fence, PIPE_FLUSH_ASYNC | PIPE_FLUSH_HINT_FINISH); |
| 72 | + |
| 73 | + if (fence) { |
| 74 | +@@ -78,6 +81,8 @@ |
| 75 | + st->screen->fence_reference(st->screen, &fence, NULL); |
| 76 | + } |
| 77 | + |
| 78 | ++ /* bool */ st->screen->fence_unlock (); |
| 79 | ++ |
| 80 | + st_manager_flush_swapbuffers(); |
| 81 | + } |
| 82 | + |
| 83 | +--- a/src/gallium/drivers/v3d/v3d_fence.c |
| 84 | ++++ b/src/gallium/drivers/v3d/v3d_fence.c |
| 85 | +@@ -43,8 +43,12 @@ |
| 86 | + struct v3d_fence { |
| 87 | + struct pipe_reference reference; |
| 88 | + int fd; |
| 89 | ++ struct v3d_context * ctx; |
| 90 | + }; |
| 91 | + |
| 92 | ++static bool v3d_fence_lock (void); |
| 93 | ++static bool v3d_fence_unlock (void); |
| 94 | ++ |
| 95 | + static void |
| 96 | + v3d_fence_reference(struct pipe_screen *pscreen, |
| 97 | + struct pipe_fence_handle **pp, |
| 98 | +@@ -55,8 +59,19 @@ |
| 99 | + struct v3d_fence *old = *p; |
| 100 | + |
| 101 | + if (pipe_reference(&(*p)->reference, &f->reference)) { |
| 102 | +- close(old->fd); |
| 103 | ++ /* bool */ v3d_fence_lock (); |
| 104 | ++ |
| 105 | ++ assert (old->ctx != NULL); |
| 106 | ++ assert (old->ctx->fence->fd == old->fd || old->ctx->fence->fd == -1); |
| 107 | ++ |
| 108 | ++ old->ctx->fence = NULL; |
| 109 | ++ |
| 110 | ++ /* int */ close(old->fd); |
| 111 | + free(old); |
| 112 | ++ |
| 113 | ++ /* bool */ v3d_fence_unlock (); |
| 114 | ++ |
| 115 | ++ fprintf(stderr, "Sync file destructed\n"); |
| 116 | + } |
| 117 | + *p = f; |
| 118 | + } |
| 119 | +@@ -103,6 +118,19 @@ |
| 120 | + if (!f) |
| 121 | + return NULL; |
| 122 | + |
| 123 | ++ /* bool */ v3d_fence_lock (); |
| 124 | ++ |
| 125 | ++ if (v3d->fence != NULL) { |
| 126 | ++ fprintf(stderr, "Sync file iNOT properly destructed\n"); |
| 127 | ++ |
| 128 | ++ /* int */ close (v3d->fence->fd); |
| 129 | ++ free (v3d->fence); |
| 130 | ++ |
| 131 | ++ v3d->fence = NULL; |
| 132 | ++ } |
| 133 | ++ |
| 134 | ++ /* bool */ v3d_fence_unlock (); |
| 135 | ++ |
| 136 | + /* Snapshot the last V3D rendering's out fence. We'd rather have |
| 137 | + * another syncobj instead of a sync file, but this is all we get. |
| 138 | + * (HandleToFD/FDToHandle just gives you another syncobj ID for the |
| 139 | +@@ -115,14 +143,43 @@ |
| 140 | + return NULL; |
| 141 | + } |
| 142 | + |
| 143 | ++ // Update our custom fields in the v3d_context and v3d_fence |
| 144 | ++ |
| 145 | ++ /* bool */ v3d_fence_lock (); |
| 146 | ++ |
| 147 | ++ v3d->fence = f; |
| 148 | ++ |
| 149 | ++ f->ctx = v3d; |
| 150 | ++ |
| 151 | ++ /* bool */ v3d_fence_unlock (); |
| 152 | ++ |
| 153 | + pipe_reference_init(&f->reference, 1); |
| 154 | + |
| 155 | + return f; |
| 156 | + } |
| 157 | + |
| 158 | ++pthread_mutex_t mutex = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP; |
| 159 | ++ |
| 160 | ++/* static */ bool v3d_fence_lock (void) |
| 161 | ++{ |
| 162 | ++ bool ret = pthread_mutex_lock (& mutex) == 0; |
| 163 | ++ assert (ret != false); |
| 164 | ++ return ret; |
| 165 | ++} |
| 166 | ++ |
| 167 | ++/* static */ bool v3d_fence_unlock (void) |
| 168 | ++{ |
| 169 | ++ bool ret = pthread_mutex_unlock (& mutex) == 0; |
| 170 | ++ assert (ret != false); |
| 171 | ++ return ret; |
| 172 | ++} |
| 173 | ++ |
| 174 | + void |
| 175 | + v3d_fence_init(struct v3d_screen *screen) |
| 176 | + { |
| 177 | + screen->base.fence_reference = v3d_fence_reference; |
| 178 | + screen->base.fence_finish = v3d_fence_finish; |
| 179 | ++ |
| 180 | ++ screen->base.fence_lock = v3d_fence_lock; |
| 181 | ++ screen->base.fence_unlock = v3d_fence_unlock; |
| 182 | + } |
0 commit comments