v3d: Rename the driver files from "vc5" to "v3d".
[mesa.git] / src / gallium / drivers / v3d / v3d_fence.c
1 /*
2 * Copyright © 2014 Broadcom
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
13 * Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21 * IN THE SOFTWARE.
22 */
23
24 /** @file vc5_fence.c
25 *
26 * Seqno-based fence management.
27 *
28 * We have two mechanisms for waiting in our kernel API: You can wait on a BO
29 * to have all rendering to from any process to be completed, or wait on a
30 * seqno for that particular seqno to be passed. The fence API we're
31 * implementing is based on waiting for all rendering in the context to have
32 * completed (with no reference to what other processes might be doing with
33 * the same BOs), so we can just use the seqno of the last rendering we'd
34 * fired off as our fence marker.
35 */
36
37 #include "util/u_inlines.h"
38
39 #include "v3d_context.h"
40 #include "v3d_bufmgr.h"
41
42 struct vc5_fence {
43 struct pipe_reference reference;
44 uint32_t sync;
45 };
46
47 static void
48 vc5_fence_reference(struct pipe_screen *pscreen,
49 struct pipe_fence_handle **pp,
50 struct pipe_fence_handle *pf)
51 {
52 struct vc5_screen *screen = vc5_screen(pscreen);
53 struct vc5_fence **p = (struct vc5_fence **)pp;
54 struct vc5_fence *f = (struct vc5_fence *)pf;
55 struct vc5_fence *old = *p;
56
57 if (pipe_reference(&(*p)->reference, &f->reference)) {
58 drmSyncobjDestroy(screen->fd, old->sync);
59 free(old);
60 }
61 *p = f;
62 }
63
64 static boolean
65 vc5_fence_finish(struct pipe_screen *pscreen,
66 struct pipe_context *ctx,
67 struct pipe_fence_handle *pf,
68 uint64_t timeout_ns)
69 {
70 struct vc5_screen *screen = vc5_screen(pscreen);
71 struct vc5_fence *f = (struct vc5_fence *)pf;
72
73 return drmSyncobjWait(screen->fd, &f->sync, 1, timeout_ns, 0, NULL);
74 }
75
76 struct vc5_fence *
77 vc5_fence_create(struct vc5_context *vc5)
78 {
79 struct vc5_fence *f = calloc(1, sizeof(*f));
80 if (!f)
81 return NULL;
82
83 uint32_t new_sync;
84 /* Make a new sync object for the context. */
85 int ret = drmSyncobjCreate(vc5->fd, DRM_SYNCOBJ_CREATE_SIGNALED,
86 &new_sync);
87 if (ret) {
88 free(f);
89 return NULL;
90 }
91
92 pipe_reference_init(&f->reference, 1);
93 f->sync = vc5->out_sync;
94 vc5->out_sync = new_sync;
95
96 return f;
97 }
98
99 void
100 vc5_fence_init(struct vc5_screen *screen)
101 {
102 screen->base.fence_reference = vc5_fence_reference;
103 screen->base.fence_finish = vc5_fence_finish;
104 }