~mmach/netext73/mesa-haswell

« back to all changes in this revision

Viewing changes to src/gallium/frontends/wgl/stw_device.c

  • Committer: mmach
  • Date: 2022-09-22 19:56:13 UTC
  • Revision ID: netbit73@gmail.com-20220922195613-wtik9mmy20tmor0i
2022-09-22 21:17:09

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/**************************************************************************
2
 
 *
3
 
 * Copyright 2008 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
 
#include <windows.h>
29
 
 
30
 
#include "glapi/glapi.h"
31
 
#include "util/debug.h"
32
 
#include "util/u_debug.h"
33
 
#include "util/u_math.h"
34
 
#include "util/u_memory.h"
35
 
#include "util/u_driconf.h"
36
 
#include "util/driconf.h"
37
 
#include "pipe/p_screen.h"
38
 
 
39
 
#include "stw_device.h"
40
 
#include "stw_winsys.h"
41
 
#include "stw_pixelformat.h"
42
 
#include "gldrv.h"
43
 
#include "stw_tls.h"
44
 
#include "stw_framebuffer.h"
45
 
#include "stw_st.h"
46
 
 
47
 
 
48
 
struct stw_device *stw_dev = NULL;
49
 
 
50
 
static int
51
 
stw_get_param(struct st_manager *smapi,
52
 
              enum st_manager_param param)
53
 
{
54
 
   switch (param) {
55
 
   case ST_MANAGER_BROKEN_INVALIDATE:
56
 
      /*
57
 
       * Force framebuffer validation on glViewport.
58
 
       *
59
 
       * Certain applications, like Rhinoceros 4, uses glReadPixels
60
 
       * exclusively (never uses SwapBuffers), so framebuffers never get
61
 
       * resized unless we check on glViewport.
62
 
       */
63
 
      return 1;
64
 
   default:
65
 
      return 0;
66
 
   }
67
 
}
68
 
 
69
 
 
70
 
/** Get the refresh rate for the monitor, in Hz */
71
 
static int
72
 
get_refresh_rate(void)
73
 
{
74
 
   DEVMODE devModes;
75
 
 
76
 
   if (EnumDisplaySettings(NULL, ENUM_CURRENT_SETTINGS, &devModes)) {
77
 
      /* clamp the value, just in case we get garbage */
78
 
      return CLAMP(devModes.dmDisplayFrequency, 30, 120);
79
 
   }
80
 
   else {
81
 
      /* reasonable default */
82
 
      return 60;
83
 
   }
84
 
}
85
 
 
86
 
static bool
87
 
init_screen(const struct stw_winsys *stw_winsys, HDC hdc)
88
 
{
89
 
   struct pipe_screen *screen = stw_winsys->create_screen(hdc);
90
 
   if (!screen)
91
 
      return false;
92
 
 
93
 
   if (stw_winsys->get_adapter_luid)
94
 
      stw_winsys->get_adapter_luid(screen, hdc, &stw_dev->AdapterLuid);
95
 
 
96
 
   stw_dev->smapi->screen = screen;
97
 
   stw_dev->screen = screen;
98
 
   stw_dev->zink = !memcmp(screen->get_name(screen), "zink", 4);
99
 
 
100
 
   stw_dev->max_2d_length = screen->get_param(screen,
101
 
                                              PIPE_CAP_MAX_TEXTURE_2D_SIZE);
102
 
   return true;
103
 
}
104
 
 
105
 
static void
106
 
init_options()
107
 
{
108
 
   const driOptionDescription gallium_driconf[] = {
109
 
      #include "pipe-loader/driinfo_gallium.h"
110
 
   };
111
 
 
112
 
   const char *driver_name = stw_dev->stw_winsys->get_name ? stw_dev->stw_winsys->get_name() : NULL;
113
 
   driParseOptionInfo(&stw_dev->option_info, gallium_driconf, ARRAY_SIZE(gallium_driconf));
114
 
   driParseConfigFiles(&stw_dev->option_cache, &stw_dev->option_info, 0,
115
 
      driver_name ? driver_name : "", NULL, NULL, NULL, 0, NULL, 0);
116
 
   
117
 
   u_driconf_fill_st_options(&stw_dev->st_options, &stw_dev->option_cache);
118
 
}
119
 
 
120
 
boolean
121
 
stw_init(const struct stw_winsys *stw_winsys)
122
 
{
123
 
   static struct stw_device stw_dev_storage;
124
 
 
125
 
   if (env_var_as_boolean("WGL_DISABLE_ERROR_DIALOGS", false))
126
 
      debug_disable_win32_error_dialogs();
127
 
 
128
 
   assert(!stw_dev);
129
 
 
130
 
   stw_tls_init();
131
 
 
132
 
   stw_dev = &stw_dev_storage;
133
 
   memset(stw_dev, 0, sizeof(*stw_dev));
134
 
 
135
 
   stw_dev->stw_winsys = stw_winsys;
136
 
 
137
 
   stw_dev->stapi = stw_st_create_api();
138
 
   stw_dev->smapi = CALLOC_STRUCT(st_manager);
139
 
   if (!stw_dev->stapi || !stw_dev->smapi)
140
 
      goto error1;
141
 
 
142
 
   stw_dev->smapi->get_param = stw_get_param;
143
 
 
144
 
   InitializeCriticalSection(&stw_dev->screen_mutex);
145
 
   InitializeCriticalSection(&stw_dev->ctx_mutex);
146
 
   InitializeCriticalSection(&stw_dev->fb_mutex);
147
 
 
148
 
   stw_dev->ctx_table = handle_table_create();
149
 
   if (!stw_dev->ctx_table) {
150
 
      goto error1;
151
 
   }
152
 
 
153
 
   /* env var override for WGL_EXT_swap_control, useful for testing/debugging */
154
 
   const char *s = os_get_option("WGL_SWAP_INTERVAL");
155
 
   if (s) {
156
 
      stw_dev->swap_interval = atoi(s);
157
 
   }
158
 
   stw_dev->refresh_rate = get_refresh_rate();
159
 
 
160
 
   stw_dev->initialized = true;
161
 
 
162
 
   return TRUE;
163
 
 
164
 
error1:
165
 
   FREE(stw_dev->smapi);
166
 
   if (stw_dev->stapi)
167
 
      stw_dev->stapi->destroy(stw_dev->stapi);
168
 
 
169
 
   stw_dev = NULL;
170
 
   return FALSE;
171
 
}
172
 
 
173
 
boolean
174
 
stw_init_screen(HDC hdc)
175
 
{
176
 
   EnterCriticalSection(&stw_dev->screen_mutex);
177
 
 
178
 
   if (!stw_dev->screen_initialized) {
179
 
      stw_dev->screen_initialized = true;
180
 
      if (!init_screen(stw_dev->stw_winsys, hdc)) {
181
 
         LeaveCriticalSection(&stw_dev->screen_mutex);
182
 
         return false;
183
 
      }
184
 
      init_options();
185
 
      stw_pixelformat_init();
186
 
   }
187
 
 
188
 
   LeaveCriticalSection(&stw_dev->screen_mutex);
189
 
   return stw_dev->screen != NULL;
190
 
}
191
 
 
192
 
struct stw_device *
193
 
stw_get_device(void)
194
 
{
195
 
   return stw_dev;
196
 
}
197
 
 
198
 
boolean
199
 
stw_init_thread(void)
200
 
{
201
 
   return stw_tls_init_thread();
202
 
}
203
 
 
204
 
 
205
 
void
206
 
stw_cleanup_thread(void)
207
 
{
208
 
   stw_tls_cleanup_thread();
209
 
}
210
 
 
211
 
 
212
 
void
213
 
stw_cleanup(void)
214
 
{
215
 
   DHGLRC dhglrc;
216
 
 
217
 
   debug_printf("%s\n", __FUNCTION__);
218
 
 
219
 
   if (!stw_dev)
220
 
      return;
221
 
 
222
 
   /*
223
 
    * Abort cleanup if there are still active contexts. In some situations
224
 
    * this DLL may be unloaded before the DLL that is using GL contexts is.
225
 
    */
226
 
   stw_lock_contexts(stw_dev);
227
 
   dhglrc = handle_table_get_first_handle(stw_dev->ctx_table);
228
 
   stw_unlock_contexts(stw_dev);
229
 
   if (dhglrc) {
230
 
      debug_printf("%s: contexts still active -- cleanup aborted\n", __FUNCTION__);
231
 
      stw_dev = NULL;
232
 
      return;
233
 
   }
234
 
 
235
 
   free(stw_dev->st_options.force_gl_vendor);
236
 
   free(stw_dev->st_options.force_gl_renderer);
237
 
   free(stw_dev->st_options.mesa_extension_override);
238
 
   driDestroyOptionCache(&stw_dev->option_cache);
239
 
   driDestroyOptionInfo(&stw_dev->option_info);
240
 
 
241
 
   handle_table_destroy(stw_dev->ctx_table);
242
 
 
243
 
   stw_framebuffer_cleanup();
244
 
 
245
 
   DeleteCriticalSection(&stw_dev->fb_mutex);
246
 
   DeleteCriticalSection(&stw_dev->ctx_mutex);
247
 
   DeleteCriticalSection(&stw_dev->screen_mutex);
248
 
 
249
 
   if (stw_dev->smapi->destroy)
250
 
      stw_dev->smapi->destroy(stw_dev->smapi);
251
 
 
252
 
   FREE(stw_dev->smapi);
253
 
   stw_dev->stapi->destroy(stw_dev->stapi);
254
 
 
255
 
   stw_dev->screen->destroy(stw_dev->screen);
256
 
 
257
 
   /* glapi is statically linked: we can call the local destroy function. */
258
 
#ifdef _GLAPI_NO_EXPORTS
259
 
   _glapi_destroy_multithread();
260
 
#endif
261
 
 
262
 
   stw_tls_cleanup();
263
 
 
264
 
   util_dynarray_fini(&stw_dev->pixelformats);
265
 
 
266
 
   stw_dev = NULL;
267
 
}
268
 
 
269
 
 
270
 
void APIENTRY
271
 
DrvSetCallbackProcs(INT nProcs, PROC *pProcs)
272
 
{
273
 
   size_t size;
274
 
 
275
 
   if (stw_dev == NULL)
276
 
      return;
277
 
 
278
 
   size = MIN2(nProcs * sizeof *pProcs, sizeof stw_dev->callbacks);
279
 
   memcpy(&stw_dev->callbacks, pProcs, size);
280
 
 
281
 
   return;
282
 
}
283
 
 
284
 
 
285
 
BOOL APIENTRY
286
 
DrvValidateVersion(ULONG ulVersion)
287
 
{
288
 
   /* ulVersion is the version reported by the KMD:
289
 
    * - via D3DKMTQueryAdapterInfo(KMTQAITYPE_UMOPENGLINFO) on WDDM,
290
 
    * - or ExtEscape on XPDM and can be used to ensure the KMD and OpenGL ICD
291
 
    *   versions match.
292
 
    *
293
 
    * We should get the expected version number from the winsys, but for now
294
 
    * ignore it.
295
 
    */
296
 
   (void)ulVersion;
297
 
   return TRUE;
298
 
}