Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mesa
Path: blob/21.2-virgl/src/gallium/targets/libgl-gdi/libgl_gdi.c
4565 views
1
/**************************************************************************
2
*
3
* Copyright 2009-2010 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 SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
17
* THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
18
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
19
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
20
* USE OR OTHER DEALINGS IN THE SOFTWARE.
21
*
22
* The above copyright notice and this permission notice (including the
23
* next paragraph) shall be included in all copies or substantial portions
24
* of the Software.
25
*
26
*
27
**************************************************************************/
28
29
/**
30
* @file
31
* Softpipe/LLVMpipe support.
32
*
33
* @author Jose Fonseca <[email protected]>
34
*/
35
36
37
#include <windows.h>
38
39
#include "util/u_debug.h"
40
#include "util/debug.h"
41
#include "stw_winsys.h"
42
#include "stw_device.h"
43
#include "gdi/gdi_sw_winsys.h"
44
#include "pipe/p_screen.h"
45
#include "pipe/p_context.h"
46
47
#ifdef GALLIUM_SOFTPIPE
48
#include "softpipe/sp_texture.h"
49
#include "softpipe/sp_screen.h"
50
#include "softpipe/sp_public.h"
51
#endif
52
53
#ifdef GALLIUM_LLVMPIPE
54
#include "llvmpipe/lp_texture.h"
55
#include "llvmpipe/lp_screen.h"
56
#include "llvmpipe/lp_public.h"
57
#endif
58
59
#ifdef GALLIUM_SWR
60
#include "swr/swr_public.h"
61
#endif
62
#ifdef GALLIUM_D3D12
63
#include "d3d12/wgl/d3d12_wgl_public.h"
64
#endif
65
66
#ifdef GALLIUM_ZINK
67
#include "zink/zink_public.h"
68
#endif
69
70
#ifdef GALLIUM_LLVMPIPE
71
static boolean use_llvmpipe = FALSE;
72
#endif
73
#ifdef GALLIUM_SWR
74
static boolean use_swr = FALSE;
75
#endif
76
#ifdef GALLIUM_D3D12
77
static boolean use_d3d12 = FALSE;
78
#endif
79
#ifdef GALLIUM_ZINK
80
static boolean use_zink = FALSE;
81
#endif
82
83
static struct pipe_screen *
84
gdi_screen_create_by_name(HDC hDC, const char* driver, struct sw_winsys *winsys)
85
{
86
struct pipe_screen* screen = NULL;
87
88
#ifdef GALLIUM_LLVMPIPE
89
if (strcmp(driver, "llvmpipe") == 0) {
90
screen = llvmpipe_create_screen(winsys);
91
if (screen)
92
use_llvmpipe = TRUE;
93
}
94
#endif
95
#ifdef GALLIUM_SWR
96
if (strcmp(driver, "swr") == 0) {
97
screen = swr_create_screen(winsys);
98
if (screen)
99
use_swr = TRUE;
100
}
101
#endif
102
#ifdef GALLIUM_D3D12
103
if (strcmp(driver, "d3d12") == 0) {
104
screen = d3d12_wgl_create_screen(winsys, hDC);
105
if (screen)
106
use_d3d12 = TRUE;
107
}
108
#endif
109
#ifdef GALLIUM_ZINK
110
if (strcmp(driver, "zink") == 0) {
111
screen = zink_create_screen(winsys);
112
if (screen)
113
use_zink = TRUE;
114
}
115
#endif
116
#ifdef GALLIUM_SOFTPIPE
117
if (strcmp(driver, "softpipe") == 0) {
118
screen = softpipe_create_screen(winsys);
119
}
120
#endif
121
122
return screen;
123
}
124
125
static struct pipe_screen *
126
gdi_screen_create(HDC hDC)
127
{
128
struct sw_winsys *winsys;
129
UNUSED bool sw_only = env_var_as_boolean("LIBGL_ALWAYS_SOFTWARE", false);
130
131
winsys = gdi_create_sw_winsys();
132
if (!winsys)
133
return NULL;
134
135
const char *const drivers[] = {
136
debug_get_option("GALLIUM_DRIVER", ""),
137
#ifdef GALLIUM_D3D12
138
sw_only ? "" : "d3d12",
139
#endif
140
#if defined(GALLIUM_LLVMPIPE)
141
"llvmpipe",
142
#endif
143
#if GALLIUM_SWR
144
"swr",
145
#endif
146
#if defined(GALLIUM_SOFTPIPE)
147
"softpipe",
148
#endif
149
};
150
151
/* If the default driver screen creation fails, fall back to the next option in the
152
* sorted list. Don't do this if GALLIUM_DRIVER is specified.
153
*/
154
for (unsigned i = 0; i < ARRAY_SIZE(drivers); ++i) {
155
struct pipe_screen* screen = gdi_screen_create_by_name(hDC, drivers[i], winsys);
156
if (screen)
157
return screen;
158
if (i == 0 && drivers[i][0] != '\0')
159
break;
160
}
161
162
winsys->destroy(winsys);
163
return NULL;
164
}
165
166
167
static void
168
gdi_present(struct pipe_screen *screen,
169
struct pipe_context *ctx,
170
struct pipe_resource *res,
171
HDC hDC)
172
{
173
/* This will fail if any interposing layer (trace, debug, etc) has
174
* been introduced between the gallium frontends and the pipe driver.
175
*
176
* Ideally this would get replaced with a call to
177
* pipe_screen::flush_frontbuffer().
178
*
179
* Failing that, it may be necessary for intervening layers to wrap
180
* other structs such as this stw_winsys as well...
181
*/
182
183
struct sw_winsys *winsys = NULL;
184
struct sw_displaytarget *dt = NULL;
185
186
#ifdef GALLIUM_LLVMPIPE
187
if (use_llvmpipe) {
188
winsys = llvmpipe_screen(screen)->winsys;
189
dt = llvmpipe_resource(res)->dt;
190
gdi_sw_display(winsys, dt, hDC);
191
return;
192
}
193
#endif
194
195
#ifdef GALLIUM_SWR
196
if (use_swr) {
197
swr_gdi_swap(screen, ctx, res, hDC);
198
return;
199
}
200
#endif
201
202
#ifdef GALLIUM_D3D12
203
if (use_d3d12) {
204
d3d12_wgl_present(screen, ctx, res, hDC);
205
return;
206
}
207
#endif
208
209
#ifdef GALLIUM_ZINK
210
if (use_zink) {
211
screen->flush_frontbuffer(screen, ctx, res, 0, 0, hDC, NULL);
212
return;
213
}
214
#endif
215
216
#ifdef GALLIUM_SOFTPIPE
217
winsys = softpipe_screen(screen)->winsys,
218
dt = softpipe_resource(res)->dt,
219
gdi_sw_display(winsys, dt, hDC);
220
#endif
221
}
222
223
224
#if WINVER >= 0xA00
225
static boolean
226
gdi_get_adapter_luid(struct pipe_screen* screen,
227
HDC hDC,
228
LUID* adapter_luid)
229
{
230
if (!stw_dev || !stw_dev->callbacks.pfnGetAdapterLuid)
231
return false;
232
233
stw_dev->callbacks.pfnGetAdapterLuid(hDC, adapter_luid);
234
return true;
235
}
236
#endif
237
238
239
static unsigned
240
gdi_get_pfd_flags(struct pipe_screen *screen)
241
{
242
#ifdef GALLIUM_D3D12
243
if (use_d3d12)
244
return d3d12_wgl_get_pfd_flags(screen);
245
#endif
246
return stw_pfd_gdi_support;
247
}
248
249
250
static struct stw_winsys_framebuffer *
251
gdi_create_framebuffer(struct pipe_screen *screen,
252
HDC hDC,
253
int iPixelFormat)
254
{
255
#ifdef GALLIUM_D3D12
256
if (use_d3d12)
257
return d3d12_wgl_create_framebuffer(screen, hDC, iPixelFormat);
258
#endif
259
return NULL;
260
}
261
262
263
static const struct stw_winsys stw_winsys = {
264
&gdi_screen_create,
265
&gdi_present,
266
#if WINVER >= 0xA00
267
&gdi_get_adapter_luid,
268
#else
269
NULL, /* get_adapter_luid */
270
#endif
271
NULL, /* shared_surface_open */
272
NULL, /* shared_surface_close */
273
NULL, /* compose */
274
&gdi_get_pfd_flags,
275
&gdi_create_framebuffer,
276
};
277
278
279
EXTERN_C BOOL WINAPI
280
DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved);
281
282
283
BOOL WINAPI
284
DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
285
{
286
switch (fdwReason) {
287
case DLL_PROCESS_ATTACH:
288
stw_init(&stw_winsys);
289
stw_init_thread();
290
break;
291
292
case DLL_THREAD_ATTACH:
293
stw_init_thread();
294
break;
295
296
case DLL_THREAD_DETACH:
297
stw_cleanup_thread();
298
break;
299
300
case DLL_PROCESS_DETACH:
301
if (lpvReserved == NULL) {
302
// We're being unloaded from the process.
303
stw_cleanup_thread();
304
stw_cleanup();
305
} else {
306
// Process itself is terminating, and all threads and modules are
307
// being detached.
308
//
309
// The order threads (including llvmpipe rasterizer threads) are
310
// destroyed can not be relied up, so it's not safe to cleanup.
311
//
312
// However global destructors (e.g., LLVM's) will still be called, and
313
// if Microsoft OPENGL32.DLL's DllMain is called after us, it will
314
// still try to invoke DrvDeleteContext to destroys all outstanding,
315
// so set stw_dev to NULL to return immediately if that happens.
316
stw_dev = NULL;
317
}
318
break;
319
}
320
return TRUE;
321
}
322
323