Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mesa
Path: blob/21.2-virgl/src/gallium/drivers/llvmpipe/lp_fence.c
4570 views
1
/**************************************************************************
2
*
3
* Copyright 2009 VMware, Inc.
4
* All Rights Reserved.
5
*
6
* Permission is hereby granted, free of charge, to any person obtaining a
7
* copy of this software and associated documentation files (the
8
* "Software"), to deal in the Software without restriction, including
9
* without limitation the rights to use, copy, modify, merge, publish,
10
* distribute, sub license, and/or sell copies of the Software, and to
11
* permit persons to whom the Software is furnished to do so, subject to
12
* the following conditions:
13
*
14
* The above copyright notice and this permission notice (including the
15
* next paragraph) shall be included in all copies or substantial portions
16
* of the Software.
17
*
18
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
21
* IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
22
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25
*
26
**************************************************************************/
27
28
29
#include "pipe/p_screen.h"
30
#include "util/u_memory.h"
31
#include "lp_debug.h"
32
#include "lp_fence.h"
33
34
35
/**
36
* Create a new fence object.
37
*
38
* The rank will be the number of bins in the scene. Whenever a rendering
39
* thread hits a fence command, it'll increment the fence counter. When
40
* the counter == the rank, the fence is finished.
41
*
42
* \param rank the expected finished value of the fence counter.
43
*/
44
struct lp_fence *
45
lp_fence_create(unsigned rank)
46
{
47
static int fence_id;
48
struct lp_fence *fence = CALLOC_STRUCT(lp_fence);
49
50
if (!fence)
51
return NULL;
52
53
pipe_reference_init(&fence->reference, 1);
54
55
(void) mtx_init(&fence->mutex, mtx_plain);
56
cnd_init(&fence->signalled);
57
58
fence->id = fence_id++;
59
fence->rank = rank;
60
61
if (LP_DEBUG & DEBUG_FENCE)
62
debug_printf("%s %d\n", __FUNCTION__, fence->id);
63
64
return fence;
65
}
66
67
68
/** Destroy a fence. Called when refcount hits zero. */
69
void
70
lp_fence_destroy(struct lp_fence *fence)
71
{
72
if (LP_DEBUG & DEBUG_FENCE)
73
debug_printf("%s %d\n", __FUNCTION__, fence->id);
74
75
mtx_destroy(&fence->mutex);
76
cnd_destroy(&fence->signalled);
77
FREE(fence);
78
}
79
80
81
/**
82
* Called by the rendering threads to increment the fence counter.
83
* When the counter == the rank, the fence is finished.
84
*/
85
void
86
lp_fence_signal(struct lp_fence *fence)
87
{
88
if (LP_DEBUG & DEBUG_FENCE)
89
debug_printf("%s %d\n", __FUNCTION__, fence->id);
90
91
mtx_lock(&fence->mutex);
92
93
fence->count++;
94
assert(fence->count <= fence->rank);
95
96
if (LP_DEBUG & DEBUG_FENCE)
97
debug_printf("%s count=%u rank=%u\n", __FUNCTION__,
98
fence->count, fence->rank);
99
100
/* Wakeup all threads waiting on the mutex:
101
*/
102
cnd_broadcast(&fence->signalled);
103
104
mtx_unlock(&fence->mutex);
105
}
106
107
boolean
108
lp_fence_signalled(struct lp_fence *f)
109
{
110
return f->count == f->rank;
111
}
112
113
void
114
lp_fence_wait(struct lp_fence *f)
115
{
116
if (LP_DEBUG & DEBUG_FENCE)
117
debug_printf("%s %d\n", __FUNCTION__, f->id);
118
119
mtx_lock(&f->mutex);
120
assert(f->issued);
121
while (f->count < f->rank) {
122
cnd_wait(&f->signalled, &f->mutex);
123
}
124
mtx_unlock(&f->mutex);
125
}
126
127
128
boolean
129
lp_fence_timedwait(struct lp_fence *f, uint64_t timeout)
130
{
131
struct timespec ts;
132
int ret;
133
134
timespec_get(&ts, TIME_UTC);
135
136
ts.tv_nsec += timeout % 1000000000L;
137
ts.tv_sec += timeout / 1000000000L;
138
if (ts.tv_nsec >= 1000000000L) {
139
ts.tv_sec++;
140
ts.tv_nsec -= 1000000000L;
141
}
142
143
if (LP_DEBUG & DEBUG_FENCE)
144
debug_printf("%s %d\n", __FUNCTION__, f->id);
145
146
mtx_lock(&f->mutex);
147
assert(f->issued);
148
while (f->count < f->rank) {
149
ret = cnd_timedwait(&f->signalled, &f->mutex, &ts);
150
if (ret != thrd_success)
151
break;
152
}
153
const boolean result = (f->count >= f->rank);
154
mtx_unlock(&f->mutex);
155
return result;
156
}
157
158