xref: /aosp_15_r20/external/OpenCL-CTS/test_common/gl/setup_win32.cpp (revision 6467f958c7de8070b317fc65bcb0f6472e388d82)
1*6467f958SSadaf Ebrahimi //
2*6467f958SSadaf Ebrahimi // Copyright (c) 2017 The Khronos Group Inc.
3*6467f958SSadaf Ebrahimi //
4*6467f958SSadaf Ebrahimi // Licensed under the Apache License, Version 2.0 (the "License");
5*6467f958SSadaf Ebrahimi // you may not use this file except in compliance with the License.
6*6467f958SSadaf Ebrahimi // You may obtain a copy of the License at
7*6467f958SSadaf Ebrahimi //
8*6467f958SSadaf Ebrahimi //    http://www.apache.org/licenses/LICENSE-2.0
9*6467f958SSadaf Ebrahimi //
10*6467f958SSadaf Ebrahimi // Unless required by applicable law or agreed to in writing, software
11*6467f958SSadaf Ebrahimi // distributed under the License is distributed on an "AS IS" BASIS,
12*6467f958SSadaf Ebrahimi // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*6467f958SSadaf Ebrahimi // See the License for the specific language governing permissions and
14*6467f958SSadaf Ebrahimi // limitations under the License.
15*6467f958SSadaf Ebrahimi //
16*6467f958SSadaf Ebrahimi 
17*6467f958SSadaf Ebrahimi #include "setup.h"
18*6467f958SSadaf Ebrahimi #include "testBase.h"
19*6467f958SSadaf Ebrahimi #include "harness/errorHelpers.h"
20*6467f958SSadaf Ebrahimi 
21*6467f958SSadaf Ebrahimi #include <CL/cl_ext.h>
22*6467f958SSadaf Ebrahimi 
23*6467f958SSadaf Ebrahimi typedef CL_API_ENTRY cl_int (CL_API_CALL *clGetGLContextInfoKHR_fn)(
24*6467f958SSadaf Ebrahimi     const cl_context_properties *properties,
25*6467f958SSadaf Ebrahimi     cl_gl_context_info param_name,
26*6467f958SSadaf Ebrahimi     size_t param_value_size,
27*6467f958SSadaf Ebrahimi     void *param_value,
28*6467f958SSadaf Ebrahimi     size_t *param_value_size_ret);
29*6467f958SSadaf Ebrahimi 
30*6467f958SSadaf Ebrahimi // Rename references to this dynamically linked function to avoid
31*6467f958SSadaf Ebrahimi // collision with static link version
32*6467f958SSadaf Ebrahimi #define clGetGLContextInfoKHR clGetGLContextInfoKHR_proc
33*6467f958SSadaf Ebrahimi static clGetGLContextInfoKHR_fn clGetGLContextInfoKHR;
34*6467f958SSadaf Ebrahimi 
35*6467f958SSadaf Ebrahimi #define MAX_DEVICES 32
36*6467f958SSadaf Ebrahimi 
37*6467f958SSadaf Ebrahimi class WGLEnvironment : public GLEnvironment
38*6467f958SSadaf Ebrahimi {
39*6467f958SSadaf Ebrahimi private:
40*6467f958SSadaf Ebrahimi     cl_device_id m_devices[MAX_DEVICES];
41*6467f958SSadaf Ebrahimi     int m_device_count;
42*6467f958SSadaf Ebrahimi     cl_platform_id m_platform;
43*6467f958SSadaf Ebrahimi     bool m_is_glut_init;
44*6467f958SSadaf Ebrahimi 
45*6467f958SSadaf Ebrahimi public:
WGLEnvironment()46*6467f958SSadaf Ebrahimi     WGLEnvironment()
47*6467f958SSadaf Ebrahimi     {
48*6467f958SSadaf Ebrahimi         m_device_count = 0;
49*6467f958SSadaf Ebrahimi         m_platform = 0;
50*6467f958SSadaf Ebrahimi         m_is_glut_init = false;
51*6467f958SSadaf Ebrahimi     }
Init(int * argc,char ** argv,int use_opengl_32)52*6467f958SSadaf Ebrahimi     virtual int Init( int *argc, char **argv, int use_opengl_32 )
53*6467f958SSadaf Ebrahimi     {
54*6467f958SSadaf Ebrahimi         if (!m_is_glut_init)
55*6467f958SSadaf Ebrahimi         {
56*6467f958SSadaf Ebrahimi             // Create a GLUT window to render into
57*6467f958SSadaf Ebrahimi             glutInit( argc, argv );
58*6467f958SSadaf Ebrahimi             glutInitWindowSize( 512, 512 );
59*6467f958SSadaf Ebrahimi             glutInitDisplayMode( GLUT_RGB | GLUT_DOUBLE );
60*6467f958SSadaf Ebrahimi             glutCreateWindow( "OpenCL <-> OpenGL Test" );
61*6467f958SSadaf Ebrahimi             glewInit();
62*6467f958SSadaf Ebrahimi             m_is_glut_init = true;
63*6467f958SSadaf Ebrahimi         }
64*6467f958SSadaf Ebrahimi         return 0;
65*6467f958SSadaf Ebrahimi     }
66*6467f958SSadaf Ebrahimi 
CreateCLContext(void)67*6467f958SSadaf Ebrahimi     virtual cl_context CreateCLContext( void )
68*6467f958SSadaf Ebrahimi     {
69*6467f958SSadaf Ebrahimi         HGLRC hGLRC = wglGetCurrentContext();
70*6467f958SSadaf Ebrahimi         HDC hDC = wglGetCurrentDC();
71*6467f958SSadaf Ebrahimi         cl_context_properties properties[] = {
72*6467f958SSadaf Ebrahimi             CL_CONTEXT_PLATFORM, (cl_context_properties) m_platform,
73*6467f958SSadaf Ebrahimi             CL_GL_CONTEXT_KHR,   (cl_context_properties) hGLRC,
74*6467f958SSadaf Ebrahimi             CL_WGL_HDC_KHR,      (cl_context_properties) hDC,
75*6467f958SSadaf Ebrahimi             0
76*6467f958SSadaf Ebrahimi         };
77*6467f958SSadaf Ebrahimi         cl_device_id devices[MAX_DEVICES];
78*6467f958SSadaf Ebrahimi         size_t dev_size;
79*6467f958SSadaf Ebrahimi         cl_int status;
80*6467f958SSadaf Ebrahimi 
81*6467f958SSadaf Ebrahimi         if (!hGLRC || !hDC) {
82*6467f958SSadaf Ebrahimi             print_error(CL_INVALID_CONTEXT, "No GL context bound");
83*6467f958SSadaf Ebrahimi             return 0;
84*6467f958SSadaf Ebrahimi         }
85*6467f958SSadaf Ebrahimi 
86*6467f958SSadaf Ebrahimi         if (!clGetGLContextInfoKHR) {
87*6467f958SSadaf Ebrahimi             // As OpenCL for the platforms.  Warn if more than one platform found,
88*6467f958SSadaf Ebrahimi             // since this might not be the platform we want.  By default, we simply
89*6467f958SSadaf Ebrahimi             // use the first returned platform.
90*6467f958SSadaf Ebrahimi 
91*6467f958SSadaf Ebrahimi             cl_uint nplatforms;
92*6467f958SSadaf Ebrahimi             cl_platform_id platform;
93*6467f958SSadaf Ebrahimi             clGetPlatformIDs(0, NULL, &nplatforms);
94*6467f958SSadaf Ebrahimi             clGetPlatformIDs(1, &platform, NULL);
95*6467f958SSadaf Ebrahimi 
96*6467f958SSadaf Ebrahimi             if (nplatforms > 1) {
97*6467f958SSadaf Ebrahimi                 log_info("clGetPlatformIDs returned multiple values.  This is not "
98*6467f958SSadaf Ebrahimi                     "an error, but might result in obtaining incorrect function "
99*6467f958SSadaf Ebrahimi                     "pointers if you do not want the first returned platform.\n");
100*6467f958SSadaf Ebrahimi 
101*6467f958SSadaf Ebrahimi                 // Show them the platform name, in case it is a problem.
102*6467f958SSadaf Ebrahimi 
103*6467f958SSadaf Ebrahimi                 size_t size;
104*6467f958SSadaf Ebrahimi                 char *name;
105*6467f958SSadaf Ebrahimi 
106*6467f958SSadaf Ebrahimi                 clGetPlatformInfo(platform, CL_PLATFORM_NAME, 0, NULL, &size);
107*6467f958SSadaf Ebrahimi                 name = (char*)malloc(size);
108*6467f958SSadaf Ebrahimi                 clGetPlatformInfo(platform, CL_PLATFORM_NAME, size, name, NULL);
109*6467f958SSadaf Ebrahimi 
110*6467f958SSadaf Ebrahimi                 log_info("Using platform with name: %s \n", name);
111*6467f958SSadaf Ebrahimi                 free(name);
112*6467f958SSadaf Ebrahimi             }
113*6467f958SSadaf Ebrahimi 
114*6467f958SSadaf Ebrahimi             clGetGLContextInfoKHR = (clGetGLContextInfoKHR_fn) clGetExtensionFunctionAddressForPlatform(platform, "clGetGLContextInfoKHR");
115*6467f958SSadaf Ebrahimi             if (!clGetGLContextInfoKHR) {
116*6467f958SSadaf Ebrahimi                 print_error(CL_INVALID_PLATFORM, "Failed to query proc address for clGetGLContextInfoKHR");
117*6467f958SSadaf Ebrahimi             }
118*6467f958SSadaf Ebrahimi         }
119*6467f958SSadaf Ebrahimi 
120*6467f958SSadaf Ebrahimi         status = clGetGLContextInfoKHR(properties,
121*6467f958SSadaf Ebrahimi                                        CL_DEVICES_FOR_GL_CONTEXT_KHR,
122*6467f958SSadaf Ebrahimi                                        sizeof(devices),
123*6467f958SSadaf Ebrahimi                                        devices,
124*6467f958SSadaf Ebrahimi                                        &dev_size);
125*6467f958SSadaf Ebrahimi         if (status != CL_SUCCESS) {
126*6467f958SSadaf Ebrahimi             print_error(status, "clGetGLContextInfoKHR failed");
127*6467f958SSadaf Ebrahimi             return 0;
128*6467f958SSadaf Ebrahimi         }
129*6467f958SSadaf Ebrahimi         dev_size /= sizeof(cl_device_id);
130*6467f958SSadaf Ebrahimi         log_info("GL context supports %d compute devices\n", dev_size);
131*6467f958SSadaf Ebrahimi 
132*6467f958SSadaf Ebrahimi         status = clGetGLContextInfoKHR(properties,
133*6467f958SSadaf Ebrahimi                                        CL_CURRENT_DEVICE_FOR_GL_CONTEXT_KHR,
134*6467f958SSadaf Ebrahimi                                        sizeof(devices),
135*6467f958SSadaf Ebrahimi                                        devices,
136*6467f958SSadaf Ebrahimi                                        &dev_size);
137*6467f958SSadaf Ebrahimi         if (status != CL_SUCCESS) {
138*6467f958SSadaf Ebrahimi             print_error(status, "clGetGLContextInfoKHR failed");
139*6467f958SSadaf Ebrahimi             return 0;
140*6467f958SSadaf Ebrahimi         }
141*6467f958SSadaf Ebrahimi 
142*6467f958SSadaf Ebrahimi         cl_device_id ctxDevice = m_devices[0];
143*6467f958SSadaf Ebrahimi         if (dev_size > 0) {
144*6467f958SSadaf Ebrahimi             log_info("GL context current device: 0x%x\n", devices[0]);
145*6467f958SSadaf Ebrahimi             for (int i = 0; i < m_device_count; i++) {
146*6467f958SSadaf Ebrahimi                 if (m_devices[i] == devices[0]) {
147*6467f958SSadaf Ebrahimi                     ctxDevice = devices[0];
148*6467f958SSadaf Ebrahimi                     break;
149*6467f958SSadaf Ebrahimi                 }
150*6467f958SSadaf Ebrahimi             }
151*6467f958SSadaf Ebrahimi         } else {
152*6467f958SSadaf Ebrahimi             log_info("GL context current device is not a CL device, using device %d.\n", ctxDevice);
153*6467f958SSadaf Ebrahimi         }
154*6467f958SSadaf Ebrahimi 
155*6467f958SSadaf Ebrahimi         return clCreateContext(properties, 1, &ctxDevice, NULL, NULL, &status);
156*6467f958SSadaf Ebrahimi     }
157*6467f958SSadaf Ebrahimi 
SupportsCLGLInterop(cl_device_type device_type)158*6467f958SSadaf Ebrahimi     virtual int SupportsCLGLInterop( cl_device_type device_type )
159*6467f958SSadaf Ebrahimi     {
160*6467f958SSadaf Ebrahimi         cl_device_id devices[MAX_DEVICES];
161*6467f958SSadaf Ebrahimi         cl_uint num_of_devices;
162*6467f958SSadaf Ebrahimi         int error;
163*6467f958SSadaf Ebrahimi         error = clGetPlatformIDs(1, &m_platform, NULL);
164*6467f958SSadaf Ebrahimi         if (error) {
165*6467f958SSadaf Ebrahimi             print_error(error, "clGetPlatformIDs failed");
166*6467f958SSadaf Ebrahimi             return -1;
167*6467f958SSadaf Ebrahimi         }
168*6467f958SSadaf Ebrahimi         error = clGetDeviceIDs(m_platform, device_type, MAX_DEVICES, devices, &num_of_devices);
169*6467f958SSadaf Ebrahimi         if (error) {
170*6467f958SSadaf Ebrahimi             print_error(error, "clGetDeviceIDs failed");
171*6467f958SSadaf Ebrahimi             return -1;
172*6467f958SSadaf Ebrahimi         }
173*6467f958SSadaf Ebrahimi 
174*6467f958SSadaf Ebrahimi         // Check all devices, search for one that supports cl_khr_gl_sharing
175*6467f958SSadaf Ebrahimi         for (int i=0; i<(int)num_of_devices; i++) {
176*6467f958SSadaf Ebrahimi             if (!is_extension_available(devices[i], "cl_khr_gl_sharing")) {
177*6467f958SSadaf Ebrahimi                 log_info("Device %d of %d does not support required extension cl_khr_gl_sharing.\n", i+1, num_of_devices);
178*6467f958SSadaf Ebrahimi             } else {
179*6467f958SSadaf Ebrahimi                 log_info("Device %d of %d supports required extension cl_khr_gl_sharing.\n", i+1, num_of_devices);
180*6467f958SSadaf Ebrahimi                 m_devices[m_device_count++] = devices[i];
181*6467f958SSadaf Ebrahimi             }
182*6467f958SSadaf Ebrahimi         }
183*6467f958SSadaf Ebrahimi         return m_device_count > 0;
184*6467f958SSadaf Ebrahimi     }
185*6467f958SSadaf Ebrahimi 
~WGLEnvironment()186*6467f958SSadaf Ebrahimi     virtual ~WGLEnvironment()
187*6467f958SSadaf Ebrahimi     {
188*6467f958SSadaf Ebrahimi     }
189*6467f958SSadaf Ebrahimi };
190*6467f958SSadaf Ebrahimi 
Instance(void)191*6467f958SSadaf Ebrahimi GLEnvironment * GLEnvironment::Instance( void )
192*6467f958SSadaf Ebrahimi {
193*6467f958SSadaf Ebrahimi     static WGLEnvironment * env = NULL;
194*6467f958SSadaf Ebrahimi     if( env == NULL )
195*6467f958SSadaf Ebrahimi         env = new WGLEnvironment();
196*6467f958SSadaf Ebrahimi     return env;
197*6467f958SSadaf Ebrahimi }
198