xref: /aosp_15_r20/external/libepoxy/test/wgl_per_context_funcptrs.c (revision 706d0b42ae4182339789e08d473a0b312ecdc60f)
1*706d0b42SXin Li /*
2*706d0b42SXin Li  * Copyright © 2013 Intel Corporation
3*706d0b42SXin Li  *
4*706d0b42SXin Li  * Permission is hereby granted, free of charge, to any person obtaining a
5*706d0b42SXin Li  * copy of this software and associated documentation files (the "Software"),
6*706d0b42SXin Li  * to deal in the Software without restriction, including without limitation
7*706d0b42SXin Li  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8*706d0b42SXin Li  * and/or sell copies of the Software, and to permit persons to whom the
9*706d0b42SXin Li  * Software is furnished to do so, subject to the following conditions:
10*706d0b42SXin Li  *
11*706d0b42SXin Li  * The above copyright notice and this permission notice (including the next
12*706d0b42SXin Li  * paragraph) shall be included in all copies or substantial portions of the
13*706d0b42SXin Li  * Software.
14*706d0b42SXin Li  *
15*706d0b42SXin Li  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16*706d0b42SXin Li  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17*706d0b42SXin Li  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18*706d0b42SXin Li  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19*706d0b42SXin Li  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20*706d0b42SXin Li  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21*706d0b42SXin Li  * IN THE SOFTWARE.
22*706d0b42SXin Li  */
23*706d0b42SXin Li 
24*706d0b42SXin Li /**
25*706d0b42SXin Li  * @file wgl_per_context_funcptrs.c
26*706d0b42SXin Li  *
27*706d0b42SXin Li  * Tests that epoxy works correctly when wglGetProcAddress() returns
28*706d0b42SXin Li  * different function pointers for different contexts.
29*706d0b42SXin Li  *
30*706d0b42SXin Li  * wgl allows that to be the case when the device or pixel format are
31*706d0b42SXin Li  * different.  We don't know if the underlying implementation actually
32*706d0b42SXin Li  * *will* return different function pointers, so force the issue by
33*706d0b42SXin Li  * overriding wglGetProcAddress() to return our function pointers with
34*706d0b42SXin Li  * magic behavior.  This way we can test epoxy's implementation
35*706d0b42SXin Li  * regardless.
36*706d0b42SXin Li  */
37*706d0b42SXin Li 
38*706d0b42SXin Li #include <stdio.h>
39*706d0b42SXin Li #include <assert.h>
40*706d0b42SXin Li 
41*706d0b42SXin Li #include "wgl_common.h"
42*706d0b42SXin Li #include <epoxy/gl.h>
43*706d0b42SXin Li 
44*706d0b42SXin Li #define CREATESHADER_CTX1_VAL 1001
45*706d0b42SXin Li #define CREATESHADER_CTX2_VAL 1002
46*706d0b42SXin Li 
47*706d0b42SXin Li static HGLRC ctx1, ctx2, current_context;
48*706d0b42SXin Li static bool pass = true;
49*706d0b42SXin Li 
50*706d0b42SXin Li #define OVERRIDE_API(type) __declspec(dllexport) type __stdcall
51*706d0b42SXin Li 
52*706d0b42SXin Li OVERRIDE_API (GLuint) override_glCreateShader_ctx1(GLenum target);
53*706d0b42SXin Li OVERRIDE_API (GLuint) override_glCreateShader_ctx2(GLenum target);
54*706d0b42SXin Li OVERRIDE_API (PROC) override_wglGetProcAddress(LPCSTR name);
55*706d0b42SXin Li 
56*706d0b42SXin Li OVERRIDE_API (GLuint)
override_glCreateShader_ctx1(GLenum target)57*706d0b42SXin Li override_glCreateShader_ctx1(GLenum target)
58*706d0b42SXin Li {
59*706d0b42SXin Li     if (current_context != ctx1) {
60*706d0b42SXin Li         fputs("ctx1 called while other context current\n", stderr);
61*706d0b42SXin Li         pass = false;
62*706d0b42SXin Li     }
63*706d0b42SXin Li     return CREATESHADER_CTX1_VAL;
64*706d0b42SXin Li }
65*706d0b42SXin Li 
66*706d0b42SXin Li OVERRIDE_API (GLuint)
override_glCreateShader_ctx2(GLenum target)67*706d0b42SXin Li override_glCreateShader_ctx2(GLenum target)
68*706d0b42SXin Li {
69*706d0b42SXin Li     if (current_context != ctx2) {
70*706d0b42SXin Li         fputs("ctx2 called while other context current\n", stderr);
71*706d0b42SXin Li         pass = false;
72*706d0b42SXin Li     }
73*706d0b42SXin Li     return CREATESHADER_CTX2_VAL;
74*706d0b42SXin Li }
75*706d0b42SXin Li 
76*706d0b42SXin Li OVERRIDE_API (PROC)
override_wglGetProcAddress(LPCSTR name)77*706d0b42SXin Li override_wglGetProcAddress(LPCSTR name)
78*706d0b42SXin Li {
79*706d0b42SXin Li     assert(strcmp(name, "glCreateShader") == 0);
80*706d0b42SXin Li 
81*706d0b42SXin Li     if (current_context == ctx1) {
82*706d0b42SXin Li         return (PROC)override_glCreateShader_ctx1;
83*706d0b42SXin Li     } else {
84*706d0b42SXin Li         assert(current_context == ctx2);
85*706d0b42SXin Li         return (PROC)override_glCreateShader_ctx2;
86*706d0b42SXin Li     }
87*706d0b42SXin Li }
88*706d0b42SXin Li 
89*706d0b42SXin Li static void
test_createshader(HDC hdc,HGLRC ctx)90*706d0b42SXin Li test_createshader(HDC hdc, HGLRC ctx)
91*706d0b42SXin Li {
92*706d0b42SXin Li     GLuint shader, expected;
93*706d0b42SXin Li     int ctxnum;
94*706d0b42SXin Li 
95*706d0b42SXin Li     wglMakeCurrent(hdc, ctx);
96*706d0b42SXin Li     current_context = ctx;
97*706d0b42SXin Li 
98*706d0b42SXin Li     /* Install our GPA override so we can force per-context function
99*706d0b42SXin Li      * pointers.
100*706d0b42SXin Li      */
101*706d0b42SXin Li     wglGetProcAddress = override_wglGetProcAddress;
102*706d0b42SXin Li 
103*706d0b42SXin Li     if (ctx == ctx1) {
104*706d0b42SXin Li         expected = CREATESHADER_CTX1_VAL;
105*706d0b42SXin Li         ctxnum = 1;
106*706d0b42SXin Li     } else {
107*706d0b42SXin Li         assert(ctx == ctx2);
108*706d0b42SXin Li         expected = CREATESHADER_CTX2_VAL;
109*706d0b42SXin Li         ctxnum = 2;
110*706d0b42SXin Li     }
111*706d0b42SXin Li 
112*706d0b42SXin Li     shader = glCreateShader(GL_FRAGMENT_SHADER);
113*706d0b42SXin Li     printf("ctx%d: Returned %d\n", ctxnum, shader);
114*706d0b42SXin Li     if (shader != expected) {
115*706d0b42SXin Li         fprintf(stderr, "  expected %d\n", expected);
116*706d0b42SXin Li         pass = false;
117*706d0b42SXin Li     }
118*706d0b42SXin Li }
119*706d0b42SXin Li 
120*706d0b42SXin Li static int
test_function(HDC hdc)121*706d0b42SXin Li test_function(HDC hdc)
122*706d0b42SXin Li {
123*706d0b42SXin Li     ctx1 = wglCreateContext(hdc);
124*706d0b42SXin Li     ctx2 = wglCreateContext(hdc);
125*706d0b42SXin Li     if (!ctx1 || !ctx2) {
126*706d0b42SXin Li         fputs("Failed to create wgl contexts\n", stderr);
127*706d0b42SXin Li         return 1;
128*706d0b42SXin Li     }
129*706d0b42SXin Li 
130*706d0b42SXin Li     if (!wglMakeCurrent(hdc, ctx1)) {
131*706d0b42SXin Li         fputs("Failed to make context current\n", stderr);
132*706d0b42SXin Li         return 1;
133*706d0b42SXin Li     }
134*706d0b42SXin Li 
135*706d0b42SXin Li     if (epoxy_gl_version() < 20) {
136*706d0b42SXin Li         /* We could possibly do a 1.3 entrypoint or something instead. */
137*706d0b42SXin Li         fputs("Test relies on overriding a GL 2.0 entrypoint\n", stderr);
138*706d0b42SXin Li         return 77;
139*706d0b42SXin Li     }
140*706d0b42SXin Li 
141*706d0b42SXin Li     /* Force resolving epoxy_wglGetProcAddress. */
142*706d0b42SXin Li     wglGetProcAddress("glCreateShader");
143*706d0b42SXin Li 
144*706d0b42SXin Li     test_createshader(hdc, ctx1);
145*706d0b42SXin Li     test_createshader(hdc, ctx1);
146*706d0b42SXin Li     test_createshader(hdc, ctx2);
147*706d0b42SXin Li     test_createshader(hdc, ctx2);
148*706d0b42SXin Li     test_createshader(hdc, ctx1);
149*706d0b42SXin Li     test_createshader(hdc, ctx2);
150*706d0b42SXin Li 
151*706d0b42SXin Li     wglMakeCurrent(NULL, NULL);
152*706d0b42SXin Li     wglDeleteContext(ctx1);
153*706d0b42SXin Li     wglDeleteContext(ctx2);
154*706d0b42SXin Li 
155*706d0b42SXin Li     return !pass;
156*706d0b42SXin Li }
157*706d0b42SXin Li 
158*706d0b42SXin Li int
main(int argc,char ** argv)159*706d0b42SXin Li main(int argc, char **argv)
160*706d0b42SXin Li {
161*706d0b42SXin Li     make_window_and_test(test_function);
162*706d0b42SXin Li 
163*706d0b42SXin Li     /* UNREACHED */
164*706d0b42SXin Li     return 1;
165*706d0b42SXin Li }
166