tu: Implement fallback linear staging blit for CopyImage
[mesa.git] / src / gallium / state_trackers / wgl / stw_context.c
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 #define WGL_WGLEXT_PROTOTYPES
31
32 #include <GL/gl.h>
33 #include <GL/wglext.h>
34
35 #include "pipe/p_compiler.h"
36 #include "pipe/p_context.h"
37 #include "pipe/p_state.h"
38 #include "util/u_memory.h"
39 #include "util/u_atomic.h"
40 #include "state_tracker/st_api.h"
41 #include "hud/hud_context.h"
42
43 #include "gldrv.h"
44 #include "stw_device.h"
45 #include "stw_winsys.h"
46 #include "stw_framebuffer.h"
47 #include "stw_pixelformat.h"
48 #include "stw_context.h"
49 #include "stw_tls.h"
50
51
52 struct stw_context *
53 stw_current_context(void)
54 {
55 struct st_context_iface *st;
56
57 st = (stw_dev) ? stw_dev->stapi->get_current(stw_dev->stapi) : NULL;
58
59 return (struct stw_context *) ((st) ? st->st_manager_private : NULL);
60 }
61
62
63 BOOL APIENTRY
64 DrvCopyContext(DHGLRC dhrcSource, DHGLRC dhrcDest, UINT fuMask)
65 {
66 struct stw_context *src;
67 struct stw_context *dst;
68 BOOL ret = FALSE;
69
70 if (!stw_dev)
71 return FALSE;
72
73 stw_lock_contexts(stw_dev);
74
75 src = stw_lookup_context_locked( dhrcSource );
76 dst = stw_lookup_context_locked( dhrcDest );
77
78 if (src && dst) {
79 /* FIXME */
80 assert(0);
81 (void) src;
82 (void) dst;
83 (void) fuMask;
84 }
85
86 stw_unlock_contexts(stw_dev);
87
88 return ret;
89 }
90
91
92 BOOL APIENTRY
93 DrvShareLists(DHGLRC dhglrc1, DHGLRC dhglrc2)
94 {
95 struct stw_context *ctx1;
96 struct stw_context *ctx2;
97 BOOL ret = FALSE;
98
99 if (!stw_dev)
100 return FALSE;
101
102 stw_lock_contexts(stw_dev);
103
104 ctx1 = stw_lookup_context_locked( dhglrc1 );
105 ctx2 = stw_lookup_context_locked( dhglrc2 );
106
107 if (ctx1 && ctx2 && ctx2->st->share) {
108 ret = ctx2->st->share(ctx2->st, ctx1->st);
109 ctx1->shared = TRUE;
110 ctx2->shared = TRUE;
111 }
112
113 stw_unlock_contexts(stw_dev);
114
115 return ret;
116 }
117
118
119 DHGLRC APIENTRY
120 DrvCreateContext(HDC hdc)
121 {
122 return DrvCreateLayerContext( hdc, 0 );
123 }
124
125
126 DHGLRC APIENTRY
127 DrvCreateLayerContext(HDC hdc, INT iLayerPlane)
128 {
129 return stw_create_context_attribs(hdc, iLayerPlane, 0, 1, 0, 0,
130 WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB,
131 0);
132 }
133
134
135 /**
136 * Return the stw pixel format that most closely matches the pixel format
137 * on HDC.
138 * Used to get a pixel format when SetPixelFormat() hasn't been called before.
139 */
140 static int
141 get_matching_pixel_format(HDC hdc)
142 {
143 int iPixelFormat = GetPixelFormat(hdc);
144 PIXELFORMATDESCRIPTOR pfd;
145
146 if (!iPixelFormat)
147 return 0;
148 if (!DescribePixelFormat(hdc, iPixelFormat, sizeof(pfd), &pfd))
149 return 0;
150 return stw_pixelformat_choose(hdc, &pfd);
151 }
152
153
154 /**
155 * Called via DrvCreateContext(), DrvCreateLayerContext() and
156 * wglCreateContextAttribsARB() to actually create a rendering context.
157 * \param handle the desired DHGLRC handle to use for the context, or zero
158 * if a new handle should be allocated.
159 * \return the handle for the new context or zero if there was a problem.
160 */
161 DHGLRC
162 stw_create_context_attribs(HDC hdc, INT iLayerPlane, DHGLRC hShareContext,
163 int majorVersion, int minorVersion,
164 int contextFlags, int profileMask,
165 DHGLRC handle)
166 {
167 int iPixelFormat;
168 struct stw_framebuffer *fb;
169 const struct stw_pixelformat_info *pfi;
170 struct st_context_attribs attribs;
171 struct stw_context *ctx = NULL;
172 struct stw_context *shareCtx = NULL;
173 enum st_context_error ctx_err = 0;
174
175 if (!stw_dev)
176 return 0;
177
178 if (iLayerPlane != 0)
179 return 0;
180
181 /*
182 * GDI only knows about displayable pixel formats, so determine the pixel
183 * format from the framebuffer.
184 *
185 * This also allows to use a OpenGL DLL / ICD without installing.
186 */
187 fb = stw_framebuffer_from_hdc( hdc );
188 if (fb) {
189 iPixelFormat = fb->iPixelFormat;
190 stw_framebuffer_unlock(fb);
191 } else {
192 /* Applications should call SetPixelFormat before creating a context,
193 * but not all do, and the opengl32 runtime seems to use a default
194 * pixel format in some cases, so use that.
195 */
196 iPixelFormat = get_matching_pixel_format(hdc);
197 if (!iPixelFormat)
198 return 0;
199 }
200
201 pfi = stw_pixelformat_get_info( iPixelFormat );
202
203 if (hShareContext != 0) {
204 stw_lock_contexts(stw_dev);
205 shareCtx = stw_lookup_context_locked( hShareContext );
206 shareCtx->shared = TRUE;
207 stw_unlock_contexts(stw_dev);
208 }
209
210 ctx = CALLOC_STRUCT( stw_context );
211 if (ctx == NULL)
212 goto no_ctx;
213
214 ctx->hDrawDC = hdc;
215 ctx->hReadDC = hdc;
216 ctx->iPixelFormat = iPixelFormat;
217 ctx->shared = shareCtx != NULL;
218
219 memset(&attribs, 0, sizeof(attribs));
220 attribs.visual = pfi->stvis;
221 attribs.major = majorVersion;
222 attribs.minor = minorVersion;
223 if (contextFlags & WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB)
224 attribs.flags |= ST_CONTEXT_FLAG_FORWARD_COMPATIBLE;
225 if (contextFlags & WGL_CONTEXT_DEBUG_BIT_ARB)
226 attribs.flags |= ST_CONTEXT_FLAG_DEBUG;
227
228 switch (profileMask) {
229 case WGL_CONTEXT_CORE_PROFILE_BIT_ARB:
230 /* There are no profiles before OpenGL 3.2. The
231 * WGL_ARB_create_context_profile spec says:
232 *
233 * "If the requested OpenGL version is less than 3.2,
234 * WGL_CONTEXT_PROFILE_MASK_ARB is ignored and the functionality
235 * of the context is determined solely by the requested version."
236 */
237 if (majorVersion > 3 || (majorVersion == 3 && minorVersion >= 2)) {
238 attribs.profile = ST_PROFILE_OPENGL_CORE;
239 break;
240 }
241 /* fall-through */
242 case WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB:
243 /*
244 * The spec also says:
245 *
246 * "If version 3.1 is requested, the context returned may implement
247 * any of the following versions:
248 *
249 * * Version 3.1. The GL_ARB_compatibility extension may or may not
250 * be implemented, as determined by the implementation.
251 * * The core profile of version 3.2 or greater."
252 *
253 * But Mesa doesn't support GL_ARB_compatibility, while most prevalent
254 * Windows OpenGL implementations do, and unfortunately many Windows
255 * applications don't check whether they receive or not a context with
256 * GL_ARB_compatibility, so returning a core profile here does more harm
257 * than good.
258 */
259 attribs.profile = ST_PROFILE_DEFAULT;
260 break;
261 case WGL_CONTEXT_ES_PROFILE_BIT_EXT:
262 if (majorVersion >= 2) {
263 attribs.profile = ST_PROFILE_OPENGL_ES2;
264 } else {
265 attribs.profile = ST_PROFILE_OPENGL_ES1;
266 }
267 break;
268 default:
269 assert(0);
270 goto no_st_ctx;
271 }
272
273 ctx->st = stw_dev->stapi->create_context(stw_dev->stapi,
274 stw_dev->smapi, &attribs, &ctx_err, shareCtx ? shareCtx->st : NULL);
275 if (ctx->st == NULL)
276 goto no_st_ctx;
277
278 ctx->st->st_manager_private = (void *) ctx;
279
280 if (ctx->st->cso_context) {
281 ctx->hud = hud_create(ctx->st->cso_context, NULL);
282 }
283
284 stw_lock_contexts(stw_dev);
285 if (handle) {
286 /* We're replacing the context data for this handle. See the
287 * wglCreateContextAttribsARB() function.
288 */
289 struct stw_context *old_ctx =
290 stw_lookup_context_locked((unsigned) handle);
291 if (old_ctx) {
292 /* free the old context data associated with this handle */
293 if (old_ctx->hud) {
294 hud_destroy(old_ctx->hud, NULL);
295 }
296 ctx->st->destroy(old_ctx->st);
297 FREE(old_ctx);
298 }
299
300 /* replace table entry */
301 handle_table_set(stw_dev->ctx_table, (unsigned) handle, ctx);
302 }
303 else {
304 /* create new table entry */
305 handle = (DHGLRC) handle_table_add(stw_dev->ctx_table, ctx);
306 }
307
308 ctx->dhglrc = handle;
309
310 stw_unlock_contexts(stw_dev);
311
312 if (!ctx->dhglrc)
313 goto no_hglrc;
314
315 return ctx->dhglrc;
316
317 no_hglrc:
318 if (ctx->hud) {
319 hud_destroy(ctx->hud, NULL);
320 }
321 ctx->st->destroy(ctx->st);
322 no_st_ctx:
323 FREE(ctx);
324 no_ctx:
325 return 0;
326 }
327
328
329 BOOL APIENTRY
330 DrvDeleteContext(DHGLRC dhglrc)
331 {
332 struct stw_context *ctx ;
333 BOOL ret = FALSE;
334
335 if (!stw_dev)
336 return FALSE;
337
338 stw_lock_contexts(stw_dev);
339 ctx = stw_lookup_context_locked(dhglrc);
340 handle_table_remove(stw_dev->ctx_table, dhglrc);
341 stw_unlock_contexts(stw_dev);
342
343 if (ctx) {
344 struct stw_context *curctx = stw_current_context();
345
346 /* Unbind current if deleting current context. */
347 if (curctx == ctx)
348 stw_dev->stapi->make_current(stw_dev->stapi, NULL, NULL, NULL);
349
350 if (ctx->hud) {
351 hud_destroy(ctx->hud, NULL);
352 }
353
354 ctx->st->destroy(ctx->st);
355 FREE(ctx);
356
357 ret = TRUE;
358 }
359
360 return ret;
361 }
362
363
364 BOOL APIENTRY
365 DrvReleaseContext(DHGLRC dhglrc)
366 {
367 struct stw_context *ctx;
368
369 if (!stw_dev)
370 return FALSE;
371
372 stw_lock_contexts(stw_dev);
373 ctx = stw_lookup_context_locked( dhglrc );
374 stw_unlock_contexts(stw_dev);
375
376 if (!ctx)
377 return FALSE;
378
379 /* The expectation is that ctx is the same context which is
380 * current for this thread. We should check that and return False
381 * if not the case.
382 */
383 if (ctx != stw_current_context())
384 return FALSE;
385
386 if (stw_make_current( NULL, NULL, 0 ) == FALSE)
387 return FALSE;
388
389 return TRUE;
390 }
391
392
393 DHGLRC
394 stw_get_current_context( void )
395 {
396 struct stw_context *ctx;
397
398 ctx = stw_current_context();
399 if (!ctx)
400 return 0;
401
402 return ctx->dhglrc;
403 }
404
405
406 HDC
407 stw_get_current_dc( void )
408 {
409 struct stw_context *ctx;
410
411 ctx = stw_current_context();
412 if (!ctx)
413 return NULL;
414
415 return ctx->hDrawDC;
416 }
417
418 HDC
419 stw_get_current_read_dc( void )
420 {
421 struct stw_context *ctx;
422
423 ctx = stw_current_context();
424 if (!ctx)
425 return NULL;
426
427 return ctx->hReadDC;
428 }
429
430 BOOL
431 stw_make_current(HDC hDrawDC, HDC hReadDC, DHGLRC dhglrc)
432 {
433 struct stw_context *old_ctx = NULL;
434 struct stw_context *ctx = NULL;
435 BOOL ret = FALSE;
436
437 if (!stw_dev)
438 return FALSE;
439
440 old_ctx = stw_current_context();
441 if (old_ctx != NULL) {
442 if (old_ctx->dhglrc == dhglrc) {
443 if (old_ctx->hDrawDC == hDrawDC && old_ctx->hReadDC == hReadDC) {
444 /* Return if already current. */
445 return TRUE;
446 }
447 } else {
448 if (old_ctx->shared) {
449 struct pipe_fence_handle *fence = NULL;
450 old_ctx->st->flush(old_ctx->st,
451 ST_FLUSH_FRONT | ST_FLUSH_WAIT, &fence,
452 NULL, NULL);
453 }
454 else {
455 old_ctx->st->flush(old_ctx->st, ST_FLUSH_FRONT, NULL, NULL, NULL);
456 }
457 }
458 }
459
460 if (dhglrc) {
461 struct stw_framebuffer *fb = NULL;
462 struct stw_framebuffer *fbRead = NULL;
463 stw_lock_contexts(stw_dev);
464 ctx = stw_lookup_context_locked( dhglrc );
465 stw_unlock_contexts(stw_dev);
466 if (!ctx) {
467 goto fail;
468 }
469
470 /* This call locks fb's mutex */
471 fb = stw_framebuffer_from_hdc( hDrawDC );
472 if (fb) {
473 stw_framebuffer_update(fb);
474 }
475 else {
476 /* Applications should call SetPixelFormat before creating a context,
477 * but not all do, and the opengl32 runtime seems to use a default
478 * pixel format in some cases, so we must create a framebuffer for
479 * those here.
480 */
481 int iPixelFormat = get_matching_pixel_format(hDrawDC);
482 if (iPixelFormat)
483 fb = stw_framebuffer_create( hDrawDC, iPixelFormat );
484 if (!fb)
485 goto fail;
486 }
487
488 if (fb->iPixelFormat != ctx->iPixelFormat) {
489 stw_framebuffer_unlock(fb);
490 SetLastError(ERROR_INVALID_PIXEL_FORMAT);
491 goto fail;
492 }
493
494 /* Bind the new framebuffer */
495 ctx->hDrawDC = hDrawDC;
496 ctx->hReadDC = hReadDC;
497
498 struct stw_framebuffer *old_fb = ctx->current_framebuffer;
499 if (old_fb != fb) {
500 stw_framebuffer_reference_locked(fb);
501 ctx->current_framebuffer = fb;
502 }
503 stw_framebuffer_unlock(fb);
504
505 if (hReadDC) {
506 if (hReadDC == hDrawDC) {
507 fbRead = fb;
508 }
509 else {
510 fbRead = stw_framebuffer_from_hdc( hReadDC );
511
512 if (fbRead) {
513 stw_framebuffer_update(fbRead);
514 }
515 else {
516 /* Applications should call SetPixelFormat before creating a
517 * context, but not all do, and the opengl32 runtime seems to
518 * use a default pixel format in some cases, so we must create
519 * a framebuffer for those here.
520 */
521 int iPixelFormat = GetPixelFormat(hReadDC);
522 if (iPixelFormat)
523 fbRead = stw_framebuffer_create( hReadDC, iPixelFormat );
524 if (!fbRead)
525 goto fail;
526 }
527
528 if (fbRead->iPixelFormat != ctx->iPixelFormat) {
529 stw_framebuffer_unlock(fbRead);
530 SetLastError(ERROR_INVALID_PIXEL_FORMAT);
531 goto fail;
532 }
533 stw_framebuffer_unlock(fbRead);
534 }
535 ret = stw_dev->stapi->make_current(stw_dev->stapi, ctx->st,
536 fb->stfb, fbRead->stfb);
537 }
538 else {
539 /* Note: when we call this function we will wind up in the
540 * stw_st_framebuffer_validate_locked() function which will incur
541 * a recursive fb->mutex lock.
542 */
543 ret = stw_dev->stapi->make_current(stw_dev->stapi, ctx->st,
544 fb->stfb, fb->stfb);
545 }
546
547 if (old_fb && old_fb != fb) {
548 stw_lock_framebuffers(stw_dev);
549 stw_framebuffer_lock(old_fb);
550 stw_framebuffer_release_locked(old_fb);
551 stw_unlock_framebuffers(stw_dev);
552 }
553
554 fail:
555 if (fb) {
556 /* fb must be unlocked at this point. */
557 assert(!stw_own_mutex(&fb->mutex));
558 }
559
560 /* On failure, make the thread's current rendering context not current
561 * before returning.
562 */
563 if (!ret) {
564 stw_make_current(NULL, NULL, 0);
565 }
566 } else {
567 ret = stw_dev->stapi->make_current(stw_dev->stapi, NULL, NULL, NULL);
568 }
569
570 /* Unreference the previous framebuffer if any. It must be done after
571 * make_current, as it can be referenced inside.
572 */
573 if (old_ctx && old_ctx != ctx) {
574 struct stw_framebuffer *old_fb = old_ctx->current_framebuffer;
575 if (old_fb) {
576 old_ctx->current_framebuffer = NULL;
577 stw_lock_framebuffers(stw_dev);
578 stw_framebuffer_lock(old_fb);
579 stw_framebuffer_release_locked(old_fb);
580 stw_unlock_framebuffers(stw_dev);
581 }
582 }
583
584 return ret;
585 }
586
587
588 /**
589 * Notify the current context that the framebuffer has become invalid.
590 */
591 void
592 stw_notify_current_locked( struct stw_framebuffer *fb )
593 {
594 p_atomic_inc(&fb->stfb->stamp);
595 }
596
597
598 /**
599 * Although WGL allows different dispatch entrypoints per context
600 */
601 static const GLCLTPROCTABLE cpt =
602 {
603 OPENGL_VERSION_110_ENTRIES,
604 {
605 &glNewList,
606 &glEndList,
607 &glCallList,
608 &glCallLists,
609 &glDeleteLists,
610 &glGenLists,
611 &glListBase,
612 &glBegin,
613 &glBitmap,
614 &glColor3b,
615 &glColor3bv,
616 &glColor3d,
617 &glColor3dv,
618 &glColor3f,
619 &glColor3fv,
620 &glColor3i,
621 &glColor3iv,
622 &glColor3s,
623 &glColor3sv,
624 &glColor3ub,
625 &glColor3ubv,
626 &glColor3ui,
627 &glColor3uiv,
628 &glColor3us,
629 &glColor3usv,
630 &glColor4b,
631 &glColor4bv,
632 &glColor4d,
633 &glColor4dv,
634 &glColor4f,
635 &glColor4fv,
636 &glColor4i,
637 &glColor4iv,
638 &glColor4s,
639 &glColor4sv,
640 &glColor4ub,
641 &glColor4ubv,
642 &glColor4ui,
643 &glColor4uiv,
644 &glColor4us,
645 &glColor4usv,
646 &glEdgeFlag,
647 &glEdgeFlagv,
648 &glEnd,
649 &glIndexd,
650 &glIndexdv,
651 &glIndexf,
652 &glIndexfv,
653 &glIndexi,
654 &glIndexiv,
655 &glIndexs,
656 &glIndexsv,
657 &glNormal3b,
658 &glNormal3bv,
659 &glNormal3d,
660 &glNormal3dv,
661 &glNormal3f,
662 &glNormal3fv,
663 &glNormal3i,
664 &glNormal3iv,
665 &glNormal3s,
666 &glNormal3sv,
667 &glRasterPos2d,
668 &glRasterPos2dv,
669 &glRasterPos2f,
670 &glRasterPos2fv,
671 &glRasterPos2i,
672 &glRasterPos2iv,
673 &glRasterPos2s,
674 &glRasterPos2sv,
675 &glRasterPos3d,
676 &glRasterPos3dv,
677 &glRasterPos3f,
678 &glRasterPos3fv,
679 &glRasterPos3i,
680 &glRasterPos3iv,
681 &glRasterPos3s,
682 &glRasterPos3sv,
683 &glRasterPos4d,
684 &glRasterPos4dv,
685 &glRasterPos4f,
686 &glRasterPos4fv,
687 &glRasterPos4i,
688 &glRasterPos4iv,
689 &glRasterPos4s,
690 &glRasterPos4sv,
691 &glRectd,
692 &glRectdv,
693 &glRectf,
694 &glRectfv,
695 &glRecti,
696 &glRectiv,
697 &glRects,
698 &glRectsv,
699 &glTexCoord1d,
700 &glTexCoord1dv,
701 &glTexCoord1f,
702 &glTexCoord1fv,
703 &glTexCoord1i,
704 &glTexCoord1iv,
705 &glTexCoord1s,
706 &glTexCoord1sv,
707 &glTexCoord2d,
708 &glTexCoord2dv,
709 &glTexCoord2f,
710 &glTexCoord2fv,
711 &glTexCoord2i,
712 &glTexCoord2iv,
713 &glTexCoord2s,
714 &glTexCoord2sv,
715 &glTexCoord3d,
716 &glTexCoord3dv,
717 &glTexCoord3f,
718 &glTexCoord3fv,
719 &glTexCoord3i,
720 &glTexCoord3iv,
721 &glTexCoord3s,
722 &glTexCoord3sv,
723 &glTexCoord4d,
724 &glTexCoord4dv,
725 &glTexCoord4f,
726 &glTexCoord4fv,
727 &glTexCoord4i,
728 &glTexCoord4iv,
729 &glTexCoord4s,
730 &glTexCoord4sv,
731 &glVertex2d,
732 &glVertex2dv,
733 &glVertex2f,
734 &glVertex2fv,
735 &glVertex2i,
736 &glVertex2iv,
737 &glVertex2s,
738 &glVertex2sv,
739 &glVertex3d,
740 &glVertex3dv,
741 &glVertex3f,
742 &glVertex3fv,
743 &glVertex3i,
744 &glVertex3iv,
745 &glVertex3s,
746 &glVertex3sv,
747 &glVertex4d,
748 &glVertex4dv,
749 &glVertex4f,
750 &glVertex4fv,
751 &glVertex4i,
752 &glVertex4iv,
753 &glVertex4s,
754 &glVertex4sv,
755 &glClipPlane,
756 &glColorMaterial,
757 &glCullFace,
758 &glFogf,
759 &glFogfv,
760 &glFogi,
761 &glFogiv,
762 &glFrontFace,
763 &glHint,
764 &glLightf,
765 &glLightfv,
766 &glLighti,
767 &glLightiv,
768 &glLightModelf,
769 &glLightModelfv,
770 &glLightModeli,
771 &glLightModeliv,
772 &glLineStipple,
773 &glLineWidth,
774 &glMaterialf,
775 &glMaterialfv,
776 &glMateriali,
777 &glMaterialiv,
778 &glPointSize,
779 &glPolygonMode,
780 &glPolygonStipple,
781 &glScissor,
782 &glShadeModel,
783 &glTexParameterf,
784 &glTexParameterfv,
785 &glTexParameteri,
786 &glTexParameteriv,
787 &glTexImage1D,
788 &glTexImage2D,
789 &glTexEnvf,
790 &glTexEnvfv,
791 &glTexEnvi,
792 &glTexEnviv,
793 &glTexGend,
794 &glTexGendv,
795 &glTexGenf,
796 &glTexGenfv,
797 &glTexGeni,
798 &glTexGeniv,
799 &glFeedbackBuffer,
800 &glSelectBuffer,
801 &glRenderMode,
802 &glInitNames,
803 &glLoadName,
804 &glPassThrough,
805 &glPopName,
806 &glPushName,
807 &glDrawBuffer,
808 &glClear,
809 &glClearAccum,
810 &glClearIndex,
811 &glClearColor,
812 &glClearStencil,
813 &glClearDepth,
814 &glStencilMask,
815 &glColorMask,
816 &glDepthMask,
817 &glIndexMask,
818 &glAccum,
819 &glDisable,
820 &glEnable,
821 &glFinish,
822 &glFlush,
823 &glPopAttrib,
824 &glPushAttrib,
825 &glMap1d,
826 &glMap1f,
827 &glMap2d,
828 &glMap2f,
829 &glMapGrid1d,
830 &glMapGrid1f,
831 &glMapGrid2d,
832 &glMapGrid2f,
833 &glEvalCoord1d,
834 &glEvalCoord1dv,
835 &glEvalCoord1f,
836 &glEvalCoord1fv,
837 &glEvalCoord2d,
838 &glEvalCoord2dv,
839 &glEvalCoord2f,
840 &glEvalCoord2fv,
841 &glEvalMesh1,
842 &glEvalPoint1,
843 &glEvalMesh2,
844 &glEvalPoint2,
845 &glAlphaFunc,
846 &glBlendFunc,
847 &glLogicOp,
848 &glStencilFunc,
849 &glStencilOp,
850 &glDepthFunc,
851 &glPixelZoom,
852 &glPixelTransferf,
853 &glPixelTransferi,
854 &glPixelStoref,
855 &glPixelStorei,
856 &glPixelMapfv,
857 &glPixelMapuiv,
858 &glPixelMapusv,
859 &glReadBuffer,
860 &glCopyPixels,
861 &glReadPixels,
862 &glDrawPixels,
863 &glGetBooleanv,
864 &glGetClipPlane,
865 &glGetDoublev,
866 &glGetError,
867 &glGetFloatv,
868 &glGetIntegerv,
869 &glGetLightfv,
870 &glGetLightiv,
871 &glGetMapdv,
872 &glGetMapfv,
873 &glGetMapiv,
874 &glGetMaterialfv,
875 &glGetMaterialiv,
876 &glGetPixelMapfv,
877 &glGetPixelMapuiv,
878 &glGetPixelMapusv,
879 &glGetPolygonStipple,
880 &glGetString,
881 &glGetTexEnvfv,
882 &glGetTexEnviv,
883 &glGetTexGendv,
884 &glGetTexGenfv,
885 &glGetTexGeniv,
886 &glGetTexImage,
887 &glGetTexParameterfv,
888 &glGetTexParameteriv,
889 &glGetTexLevelParameterfv,
890 &glGetTexLevelParameteriv,
891 &glIsEnabled,
892 &glIsList,
893 &glDepthRange,
894 &glFrustum,
895 &glLoadIdentity,
896 &glLoadMatrixf,
897 &glLoadMatrixd,
898 &glMatrixMode,
899 &glMultMatrixf,
900 &glMultMatrixd,
901 &glOrtho,
902 &glPopMatrix,
903 &glPushMatrix,
904 &glRotated,
905 &glRotatef,
906 &glScaled,
907 &glScalef,
908 &glTranslated,
909 &glTranslatef,
910 &glViewport,
911 &glArrayElement,
912 &glBindTexture,
913 &glColorPointer,
914 &glDisableClientState,
915 &glDrawArrays,
916 &glDrawElements,
917 &glEdgeFlagPointer,
918 &glEnableClientState,
919 &glIndexPointer,
920 &glIndexub,
921 &glIndexubv,
922 &glInterleavedArrays,
923 &glNormalPointer,
924 &glPolygonOffset,
925 &glTexCoordPointer,
926 &glVertexPointer,
927 &glAreTexturesResident,
928 &glCopyTexImage1D,
929 &glCopyTexImage2D,
930 &glCopyTexSubImage1D,
931 &glCopyTexSubImage2D,
932 &glDeleteTextures,
933 &glGenTextures,
934 &glGetPointerv,
935 &glIsTexture,
936 &glPrioritizeTextures,
937 &glTexSubImage1D,
938 &glTexSubImage2D,
939 &glPopClientAttrib,
940 &glPushClientAttrib
941 }
942 };
943
944
945 PGLCLTPROCTABLE APIENTRY
946 DrvSetContext(HDC hdc, DHGLRC dhglrc, PFN_SETPROCTABLE pfnSetProcTable)
947 {
948 PGLCLTPROCTABLE r = (PGLCLTPROCTABLE)&cpt;
949
950 if (!stw_make_current(hdc, hdc, dhglrc))
951 r = NULL;
952
953 return r;
954 }