1 //
2 // Copyright (c) 2017 The Khronos Group Inc.
3 //
4 // Licensed under the Apache License, Version 2.0 (the "License");
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
7 //
8 // http://www.apache.org/licenses/LICENSE-2.0
9 //
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
15 //
16 #include "setup.h"
17 #include "testBase.h"
18 #include "harness/errorHelpers.h"
19 #include <assert.h>
20
21 #include <CL/cl.h>
22 #include <CL/cl_ext.h>
23
24 #define EGLERR() \
25 assert(eglGetError() == EGL_SUCCESS); \
26
27 #define MAX_DEVICES 10
28
29 class EGLGLEnvironment : public GLEnvironment
30 {
31 private:
32 cl_platform_id _platform;
33 EGLDisplay _display;
34 EGLContext _context;
35 EGLSurface _surface;
36
37 public:
EGLGLEnvironment()38 EGLGLEnvironment()
39 :_platform(NULL)
40 ,_display(EGL_NO_DISPLAY)
41 ,_context(NULL)
42 ,_surface(EGL_NO_SURFACE)
43 {
44 }
45
Init(int * argc,char ** argv,int use_opengl_32)46 virtual int Init( int *argc, char **argv, int use_opengl_32 )
47 {
48 EGLint ConfigAttribs[] =
49 {
50 EGL_RED_SIZE, 8,
51 EGL_GREEN_SIZE, 8,
52 EGL_BLUE_SIZE, 8,
53 EGL_ALPHA_SIZE, 8,
54 EGL_DEPTH_SIZE, 16,
55 EGL_SURFACE_TYPE, EGL_PBUFFER_BIT,
56 // EGL_BIND_TO_TEXTURE_RGBA, EGL_TRUE,
57 EGL_NONE
58 };
59
60 static const EGLint ContextAttribs[] =
61 {
62 EGL_CONTEXT_CLIENT_VERSION, 2,
63 EGL_NONE
64 };
65
66 EGLint conf_list[] = {
67 EGL_WIDTH, 512,
68 EGL_HEIGHT, 512,
69 EGL_TEXTURE_FORMAT, EGL_TEXTURE_RGBA,
70 EGL_TEXTURE_TARGET, EGL_TEXTURE_2D,
71 EGL_NONE};
72
73 EGLint majorVersion;
74 EGLint minorVersion;
75 EGLConfig config;
76 EGLint numConfigs;
77
78 EGLERR();
79 _display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
80 EGLERR();
81
82 eglInitialize(_display, &majorVersion, &minorVersion);
83 EGLERR();
84
85 eglBindAPI(EGL_OPENGL_ES_API);
86 EGLERR();
87
88 eglChooseConfig(_display, ConfigAttribs, &config, 1, &numConfigs);
89 EGLERR();
90
91 _context = eglCreateContext(_display, config, NULL, ContextAttribs);
92 EGLERR();
93
94 _surface = eglCreatePbufferSurface(_display, config, conf_list);
95 EGLERR();
96
97 eglMakeCurrent(_display, _surface, _surface, _context);
98 EGLERR();
99
100 return 0;
101 }
102
CreateCLContext(void)103 virtual cl_context CreateCLContext( void )
104 {
105 cl_context_properties properties[] = {
106 CL_CONTEXT_PLATFORM, (cl_context_properties) _platform,
107 CL_GL_CONTEXT_KHR, (cl_context_properties) _context,
108 CL_EGL_DISPLAY_KHR, (cl_context_properties) _display,
109 0
110 };
111 cl_device_id devices[MAX_DEVICES];
112 size_t dev_size;
113 cl_int status;
114
115 clGetGLContextInfoKHR_fn GetGLContextInfo =
116 (clGetGLContextInfoKHR_fn)clGetExtensionFunctionAddressForPlatform(
117 _platform, "clGetGLContextInfoKHR");
118 if (GetGLContextInfo == NULL)
119 {
120 print_error(status, "clGetGLContextInfoKHR failed");
121 return NULL;
122 }
123
124 status = GetGLContextInfo(properties, CL_DEVICES_FOR_GL_CONTEXT_KHR,
125 sizeof(devices), devices, &dev_size);
126 if (status != CL_SUCCESS) {
127 print_error(status, "clGetGLContextInfoKHR failed");
128 return NULL;
129 }
130 dev_size /= sizeof(cl_device_id);
131 log_info("GL _context supports %d compute devices\n", dev_size);
132
133 status =
134 GetGLContextInfo(properties, CL_CURRENT_DEVICE_FOR_GL_CONTEXT_KHR,
135 sizeof(devices), devices, &dev_size);
136 if (status != CL_SUCCESS) {
137 print_error(status, "clGetGLContextInfoKHR failed");
138 return NULL;
139 }
140
141 if (!dev_size)
142 {
143 log_info("GL _context current device is not a CL device.\n");
144 return NULL;
145 }
146
147 return clCreateContext(properties, 1, &devices[0], NULL, NULL, &status);
148 }
149
SupportsCLGLInterop(cl_device_type device_type)150 virtual int SupportsCLGLInterop( cl_device_type device_type )
151 {
152 cl_device_id devices[MAX_DEVICES];
153 cl_uint num_of_devices;
154 int interop_devices = 0;
155 int error;
156
157 error = clGetPlatformIDs(1, &_platform, NULL);
158 if (error) {
159 print_error(error, "clGetPlatformIDs failed");
160 return -1;
161 }
162
163 error = clGetDeviceIDs(_platform, device_type, MAX_DEVICES, devices, &num_of_devices);
164 if (error) {
165 print_error(error, "clGetDeviceIDs failed");
166 return -1;
167 }
168
169 // Check all devices, search for one that supports cl_khr_gl_sharing
170 for (int i=0; i<(int)num_of_devices; i++) {
171 if (!is_extension_available(devices[i], "cl_khr_gl_sharing"))
172 {
173 log_info("Device %d of %d does not support required extension cl_khr_gl_sharing.\n", i+1, num_of_devices);
174 }
175 else
176 {
177 log_info("Device %d of %d supports required extension cl_khr_gl_sharing.\n", i+1, num_of_devices);
178 interop_devices++;
179 }
180 }
181 return interop_devices > 0;
182 }
183
184 // Change to cleanup egl environment properly when the test exit.
185 // This change does not affect any functionality of the test it self
terminate_egl_display()186 virtual void terminate_egl_display()
187 {
188 if(_display != EGL_NO_DISPLAY)
189 {
190 eglMakeCurrent(_display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
191 EGLERR();
192
193 eglDestroyContext(_display, _context);
194 EGLERR();
195 _context = EGL_NO_CONTEXT;
196
197 eglDestroySurface(_display, _surface);
198 EGLERR();
199 _surface = EGL_NO_SURFACE;
200
201 eglTerminate(_display);
202 EGLERR();
203 _display = EGL_NO_DISPLAY;
204 }
205 }
206
~EGLGLEnvironment()207 virtual ~EGLGLEnvironment()
208 {
209 }
210 };
211
Instance(void)212 GLEnvironment * GLEnvironment::Instance( void )
213 {
214 return new EGLGLEnvironment();
215 }
216