Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mesa
Path: blob/21.2-virgl/src/gallium/drivers/v3d/v3d_fence.c
4570 views
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 v3d_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
#include "util/os_time.h"
39
40
#include "v3d_context.h"
41
#include "v3d_bufmgr.h"
42
43
struct v3d_fence {
44
struct pipe_reference reference;
45
int fd;
46
};
47
48
static void
49
v3d_fence_reference(struct pipe_screen *pscreen,
50
struct pipe_fence_handle **pp,
51
struct pipe_fence_handle *pf)
52
{
53
struct v3d_fence **p = (struct v3d_fence **)pp;
54
struct v3d_fence *f = (struct v3d_fence *)pf;
55
struct v3d_fence *old = *p;
56
57
if (pipe_reference(&(*p)->reference, &f->reference)) {
58
close(old->fd);
59
free(old);
60
}
61
*p = f;
62
}
63
64
static bool
65
v3d_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 v3d_screen *screen = v3d_screen(pscreen);
71
struct v3d_fence *f = (struct v3d_fence *)pf;
72
int ret;
73
74
unsigned syncobj;
75
ret = drmSyncobjCreate(screen->fd, 0, &syncobj);
76
if (ret) {
77
fprintf(stderr, "Failed to create syncobj to wait on: %d\n",
78
ret);
79
return false;
80
}
81
82
ret = drmSyncobjImportSyncFile(screen->fd, syncobj, f->fd);
83
if (ret) {
84
fprintf(stderr, "Failed to import fence to syncobj: %d\n", ret);
85
return false;
86
}
87
88
uint64_t abs_timeout = os_time_get_absolute_timeout(timeout_ns);
89
if (abs_timeout == OS_TIMEOUT_INFINITE)
90
abs_timeout = INT64_MAX;
91
92
ret = drmSyncobjWait(screen->fd, &syncobj, 1, abs_timeout, 0, NULL);
93
94
drmSyncobjDestroy(screen->fd, syncobj);
95
96
return ret >= 0;
97
}
98
99
struct v3d_fence *
100
v3d_fence_create(struct v3d_context *v3d)
101
{
102
struct v3d_fence *f = calloc(1, sizeof(*f));
103
if (!f)
104
return NULL;
105
106
/* Snapshot the last V3D rendering's out fence. We'd rather have
107
* another syncobj instead of a sync file, but this is all we get.
108
* (HandleToFD/FDToHandle just gives you another syncobj ID for the
109
* same syncobj).
110
*/
111
drmSyncobjExportSyncFile(v3d->fd, v3d->out_sync, &f->fd);
112
if (f->fd == -1) {
113
fprintf(stderr, "export failed\n");
114
free(f);
115
return NULL;
116
}
117
118
pipe_reference_init(&f->reference, 1);
119
120
return f;
121
}
122
123
void
124
v3d_fence_init(struct v3d_screen *screen)
125
{
126
screen->base.fence_reference = v3d_fence_reference;
127
screen->base.fence_finish = v3d_fence_finish;
128
}
129
130