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