Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mesa
Path: blob/21.2-virgl/src/gallium/drivers/swr/swr_fence.cpp
4570 views
1
/****************************************************************************
2
* Copyright (C) 2015 Intel Corporation. All Rights Reserved.
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
#include "pipe/p_screen.h"
25
#include "util/u_memory.h"
26
#include "util/os_time.h"
27
28
#include "swr_context.h"
29
#include "swr_screen.h"
30
#include "swr_fence.h"
31
32
#ifdef __APPLE__
33
#include <sched.h>
34
#endif
35
36
#if defined(PIPE_CC_MSVC) // portable thread yield
37
#define sched_yield SwitchToThread
38
#endif
39
40
/*
41
* Fence callback, called by back-end thread on completion of all rendering up
42
* to SwrSync call.
43
*/
44
static void
45
swr_fence_cb(uint64_t userData, uint64_t userData2, uint64_t userData3)
46
{
47
struct swr_fence *fence = (struct swr_fence *)userData;
48
49
/* Complete all work attached to the fence */
50
swr_fence_do_work(fence);
51
52
/* Correct value is in SwrSync data, and not the fence write field. */
53
/* Contexts may not finish in order, but fence value always increases */
54
if (fence->read < userData2)
55
fence->read = userData2;
56
}
57
58
/*
59
* Submit an existing fence.
60
*/
61
void
62
swr_fence_submit(struct swr_context *ctx, struct pipe_fence_handle *fh)
63
{
64
struct swr_fence *fence = swr_fence(fh);
65
66
fence->write++;
67
fence->pending = TRUE;
68
ctx->api.pfnSwrSync(ctx->swrContext, swr_fence_cb, (uint64_t)fence, fence->write, 0);
69
}
70
71
/*
72
* Create a new fence object.
73
*/
74
struct pipe_fence_handle *
75
swr_fence_create()
76
{
77
static int fence_id = 0;
78
struct swr_fence *fence = CALLOC_STRUCT(swr_fence);
79
if (!fence)
80
return NULL;
81
82
pipe_reference_init(&fence->reference, 1);
83
fence->id = fence_id++;
84
fence->work.tail = &fence->work.head;
85
86
return (struct pipe_fence_handle *)fence;
87
}
88
89
/** Destroy a fence. Called when refcount hits zero. */
90
static void
91
swr_fence_destroy(struct swr_fence *fence)
92
{
93
/* Complete any work left if fence was not submitted */
94
swr_fence_do_work(fence);
95
FREE(fence);
96
}
97
98
/**
99
* Set ptr = fence, with reference counting
100
*/
101
void
102
swr_fence_reference(struct pipe_screen *screen,
103
struct pipe_fence_handle **ptr,
104
struct pipe_fence_handle *f)
105
{
106
struct swr_fence *fence = swr_fence(f);
107
struct swr_fence *old;
108
109
if (likely(ptr)) {
110
old = swr_fence(*ptr);
111
*ptr = f;
112
} else {
113
old = NULL;
114
}
115
116
if (pipe_reference(&old->reference, &fence->reference)) {
117
swr_fence_finish(screen, NULL, (struct pipe_fence_handle *) old, 0);
118
swr_fence_destroy(old);
119
}
120
}
121
122
123
/*
124
* Wait for the fence to finish.
125
*/
126
bool
127
swr_fence_finish(struct pipe_screen *screen,
128
struct pipe_context *ctx,
129
struct pipe_fence_handle *fence_handle,
130
uint64_t timeout)
131
{
132
while (!swr_is_fence_done(fence_handle))
133
sched_yield();
134
135
swr_fence(fence_handle)->pending = FALSE;
136
137
return TRUE;
138
}
139
140
141
uint64_t
142
swr_get_timestamp(struct pipe_screen *screen)
143
{
144
return os_time_get_nano();
145
}
146
147
148
void
149
swr_fence_init(struct pipe_screen *p_screen)
150
{
151
p_screen->fence_reference = swr_fence_reference;
152
p_screen->fence_finish = swr_fence_finish;
153
p_screen->get_timestamp = swr_get_timestamp;
154
155
/* Create persistant StoreTiles "flush" fence, used to signal completion
156
* of flushing tile state back to resource texture, via StoreTiles. */
157
struct swr_screen *screen = swr_screen(p_screen);
158
screen->flush_fence = swr_fence_create();
159
}
160
161