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 "harness/compat.h"
17
18 #include <stdio.h>
19 #include <string.h>
20
21 #if !defined(__APPLE__)
22 #include <CL/cl.h>
23 #endif
24
25 #include "procs.h"
26 #include "gl/setup.h"
27 #include "harness/testHarness.h"
28 #include "harness/parseParameters.h"
29
30 #if !defined(_WIN32)
31 #include <unistd.h>
32 #endif
33
34 static cl_context sCurrentContext = NULL;
35
36
37 #define TEST_FN_REDIRECT(fn) ADD_TEST(redirect_##fn)
38 #define TEST_FN_REDIRECTOR(fn) \
39 int test_redirect_##fn(cl_device_id device, cl_context context, \
40 cl_command_queue queue, int numElements) \
41 { \
42 int error; \
43 clCommandQueueWrapper realQueue = clCreateCommandQueueWithProperties( \
44 sCurrentContext, device, 0, &error); \
45 test_error(error, "Unable to create command queue"); \
46 return test_##fn(device, sCurrentContext, realQueue, numElements); \
47 }
48
49 // buffers:
50 TEST_FN_REDIRECTOR(buffers)
51 TEST_FN_REDIRECTOR(buffers_getinfo)
52
53 // 1D images:
54 TEST_FN_REDIRECTOR(images_read_1D)
55 TEST_FN_REDIRECTOR(images_write_1D)
56 TEST_FN_REDIRECTOR(images_1D_getinfo)
57
58 // 1D image arrays:
59 TEST_FN_REDIRECTOR(images_read_1Darray)
60 TEST_FN_REDIRECTOR(images_write_1Darray)
61 TEST_FN_REDIRECTOR(images_1Darray_getinfo)
62
63 // 2D images:
64 TEST_FN_REDIRECTOR(images_read_2D)
65 TEST_FN_REDIRECTOR(images_read_cube)
66 TEST_FN_REDIRECTOR(images_write)
67 TEST_FN_REDIRECTOR(images_write_cube)
68 TEST_FN_REDIRECTOR(images_2D_getinfo)
69 TEST_FN_REDIRECTOR(images_cube_getinfo)
70
71 // 2D image arrays:
72 TEST_FN_REDIRECTOR(images_read_2Darray)
73 TEST_FN_REDIRECTOR(images_write_2Darray)
74 TEST_FN_REDIRECTOR(images_2Darray_getinfo)
75
76 // 3D images:
77 TEST_FN_REDIRECTOR(images_read_3D)
78 TEST_FN_REDIRECTOR(images_write_3D)
79 TEST_FN_REDIRECTOR(images_3D_getinfo)
80
81 #ifdef GL_VERSION_3_2
82
83 TEST_FN_REDIRECTOR(images_read_texturebuffer)
84 TEST_FN_REDIRECTOR(images_write_texturebuffer)
85 TEST_FN_REDIRECTOR(images_texturebuffer_getinfo)
86
87 // depth textures
88 TEST_FN_REDIRECTOR(images_read_2D_depth)
89 TEST_FN_REDIRECTOR(images_write_2D_depth)
90 TEST_FN_REDIRECTOR(images_read_2Darray_depth)
91 TEST_FN_REDIRECTOR(images_write_2Darray_depth)
92
93 TEST_FN_REDIRECTOR(images_read_2D_multisample)
94 TEST_FN_REDIRECTOR(images_read_2Darray_multisample)
95 TEST_FN_REDIRECTOR(image_methods_depth)
96 TEST_FN_REDIRECTOR(image_methods_multisample)
97 #endif
98
99 // Renderbuffer-backed images:
100 TEST_FN_REDIRECTOR(renderbuffer_read)
101 TEST_FN_REDIRECTOR(renderbuffer_write)
102 TEST_FN_REDIRECTOR(renderbuffer_getinfo)
103
104 TEST_FN_REDIRECTOR(fence_sync)
105
106 test_definition test_list[] = { TEST_FN_REDIRECT(buffers),
107 TEST_FN_REDIRECT(buffers_getinfo),
108
109 TEST_FN_REDIRECT(images_read_1D),
110 TEST_FN_REDIRECT(images_write_1D),
111 TEST_FN_REDIRECT(images_1D_getinfo),
112
113 TEST_FN_REDIRECT(images_read_1Darray),
114 TEST_FN_REDIRECT(images_write_1Darray),
115 TEST_FN_REDIRECT(images_1Darray_getinfo),
116
117 TEST_FN_REDIRECT(images_read_2D),
118 TEST_FN_REDIRECT(images_write),
119 TEST_FN_REDIRECT(images_2D_getinfo),
120
121 TEST_FN_REDIRECT(images_read_cube),
122 TEST_FN_REDIRECT(images_write_cube),
123 TEST_FN_REDIRECT(images_cube_getinfo),
124
125 TEST_FN_REDIRECT(images_read_2Darray),
126 TEST_FN_REDIRECT(images_write_2Darray),
127 TEST_FN_REDIRECT(images_2Darray_getinfo),
128
129 TEST_FN_REDIRECT(images_read_3D),
130 TEST_FN_REDIRECT(images_write_3D),
131 TEST_FN_REDIRECT(images_3D_getinfo),
132
133 TEST_FN_REDIRECT(renderbuffer_read),
134 TEST_FN_REDIRECT(renderbuffer_write),
135 TEST_FN_REDIRECT(renderbuffer_getinfo) };
136
137 test_definition test_list32[] = {
138 TEST_FN_REDIRECT(images_read_texturebuffer),
139 TEST_FN_REDIRECT(images_write_texturebuffer),
140 TEST_FN_REDIRECT(images_texturebuffer_getinfo),
141
142 TEST_FN_REDIRECT(fence_sync),
143 TEST_FN_REDIRECT(images_read_2D_depth),
144 TEST_FN_REDIRECT(images_write_2D_depth),
145 TEST_FN_REDIRECT(images_read_2Darray_depth),
146 TEST_FN_REDIRECT(images_write_2Darray_depth),
147 TEST_FN_REDIRECT(images_read_2D_multisample),
148 TEST_FN_REDIRECT(images_read_2Darray_multisample),
149 TEST_FN_REDIRECT(image_methods_depth),
150 TEST_FN_REDIRECT(image_methods_multisample)
151 };
152
153 const int test_num = ARRAY_SIZE(test_list);
154 const int test_num32 = ARRAY_SIZE(test_list32);
155
main(int argc,const char * argv[])156 int main(int argc, const char *argv[])
157 {
158 gTestRounding = true;
159 int error = 0;
160 int numErrors = 0;
161
162 test_start();
163 argc = parseCustomParam(argc, argv);
164 if (argc == -1)
165 {
166 return -1;
167 }
168
169 cl_device_type requestedDeviceType = CL_DEVICE_TYPE_DEFAULT;
170
171 /* Do we have a CPU/GPU specification? */
172 if (argc > 1)
173 {
174 if (strcmp(argv[argc - 1], "gpu") == 0
175 || strcmp(argv[argc - 1], "CL_DEVICE_TYPE_GPU") == 0)
176 {
177 requestedDeviceType = CL_DEVICE_TYPE_GPU;
178 argc--;
179 }
180 else if (strcmp(argv[argc - 1], "cpu") == 0
181 || strcmp(argv[argc - 1], "CL_DEVICE_TYPE_CPU") == 0)
182 {
183 requestedDeviceType = CL_DEVICE_TYPE_CPU;
184 argc--;
185 }
186 else if (strcmp(argv[argc - 1], "accelerator") == 0
187 || strcmp(argv[argc - 1], "CL_DEVICE_TYPE_ACCELERATOR") == 0)
188 {
189 requestedDeviceType = CL_DEVICE_TYPE_ACCELERATOR;
190 argc--;
191 }
192 else if (strcmp(argv[argc - 1], "CL_DEVICE_TYPE_DEFAULT") == 0)
193 {
194 requestedDeviceType = CL_DEVICE_TYPE_DEFAULT;
195 argc--;
196 }
197 }
198
199 if (argc > 1 && strcmp(argv[1], "-list") == 0)
200 {
201 log_info("Available 2.x tests:\n");
202 for (int i = 0; i < test_num; i++)
203 log_info("\t%s\n", test_list[i].name);
204
205 log_info("Available 3.2 tests:\n");
206 for (int i = 0; i < test_num32; i++)
207 log_info("\t%s\n", test_list32[i].name);
208
209 log_info("Note: Any 3.2 test names must follow 2.1 test names on the "
210 "command line.\n");
211 log_info("Use environment variables to specify desired device.\n");
212
213 return 0;
214 }
215
216 // Check to see if any 2.x or 3.2 test names were specified on the command
217 // line.
218 unsigned first_32_testname = 0;
219
220 for (int j = 1; (j < argc) && (!first_32_testname); ++j)
221 for (int i = 0; i < test_num32; ++i)
222 if (strcmp(test_list32[i].name, argv[j]) == 0)
223 {
224 first_32_testname = j;
225 break;
226 }
227
228 // Create the environment for the test.
229 GLEnvironment *glEnv = GLEnvironment::Instance();
230
231 // Check if any devices of the requested type support CL/GL interop.
232 int supported = glEnv->SupportsCLGLInterop(requestedDeviceType);
233 if (supported == 0)
234 {
235 log_info("Test not run because GL-CL interop is not supported for any "
236 "devices of the requested type.\n");
237 return 0;
238 }
239 else if (supported == -1)
240 {
241 log_error("Unable to setup the test or failed to determine if CL-GL "
242 "interop is supported.\n");
243 return -1;
244 }
245
246 // Initialize function pointers.
247 error = init_clgl_ext();
248 if (error < 0)
249 {
250 return error;
251 }
252
253 // OpenGL tests for non-3.2
254 // ////////////////////////////////////////////////////////
255 if ((argc == 1) || (first_32_testname != 1))
256 {
257
258 // At least one device supports CL-GL interop, so init the test.
259 if (glEnv->Init(&argc, (char **)argv, CL_FALSE))
260 {
261 log_error(
262 "Failed to initialize the GL environment for this test.\n");
263 return -1;
264 }
265
266 // Create a context to use and then grab a device (or devices) from it
267 sCurrentContext = glEnv->CreateCLContext();
268 if (sCurrentContext == NULL)
269 {
270 log_error("ERROR: Unable to obtain CL context from GL\n");
271 return -1;
272 }
273
274 size_t numDevices = 0;
275 cl_device_id *deviceIDs;
276
277 error = clGetContextInfo(sCurrentContext, CL_CONTEXT_DEVICES, 0, NULL,
278 &numDevices);
279 if (error != CL_SUCCESS)
280 {
281 print_error(error, "Unable to get device count from context");
282 return -1;
283 }
284 deviceIDs = (cl_device_id *)malloc(numDevices);
285 if (deviceIDs == NULL)
286 {
287 print_error(error, "malloc failed");
288 return -1;
289 }
290 error = clGetContextInfo(sCurrentContext, CL_CONTEXT_DEVICES,
291 numDevices, deviceIDs, NULL);
292 if (error != CL_SUCCESS)
293 {
294 print_error(error, "Unable to get device list from context");
295 return -1;
296 }
297
298 numDevices /= sizeof(cl_device_id);
299
300 if (numDevices < 1)
301 {
302 log_error("No devices found.\n");
303 return -1;
304 }
305
306 // Execute tests.
307 int argc_ = (first_32_testname) ? first_32_testname : argc;
308
309 for (size_t i = 0; i < numDevices; i++)
310 {
311 log_info("\nTesting OpenGL 2.x\n");
312 if (printDeviceHeader(deviceIDs[i]) != CL_SUCCESS)
313 {
314 return -1;
315 }
316
317 // Note: don't use the entire harness, because we have a different
318 // way of obtaining the device (via the context)
319 test_harness_config config{};
320 config.forceNoContextCreation = true;
321 config.numElementsToUse = 1024;
322 config.queueProps = 0;
323 error = parseAndCallCommandLineTests(argc_, argv, deviceIDs[i],
324 test_num, test_list, config);
325 if (error != 0) break;
326 }
327
328 numErrors += error;
329
330 // Clean-up.
331 free(deviceIDs);
332 clReleaseContext(sCurrentContext);
333 // delete glEnv;
334 }
335
336 // OpenGL 3.2 tests.
337 // ////////////////////////////////////////////////////////
338 if ((argc == 1) || first_32_testname)
339 {
340
341 // At least one device supports CL-GL interop, so init the test.
342 if (glEnv->Init(&argc, (char **)argv, CL_TRUE))
343 {
344 log_error(
345 "Failed to initialize the GL environment for this test.\n");
346 return -1;
347 }
348
349 // Create a context to use and then grab a device (or devices) from it
350 sCurrentContext = glEnv->CreateCLContext();
351 if (sCurrentContext == NULL)
352 {
353 log_error("ERROR: Unable to obtain CL context from GL\n");
354 return -1;
355 }
356
357 size_t numDevices = 0;
358 cl_device_id *deviceIDs;
359
360 error = clGetContextInfo(sCurrentContext, CL_CONTEXT_DEVICES, 0, NULL,
361 &numDevices);
362 if (error != CL_SUCCESS)
363 {
364 print_error(error, "Unable to get device count from context");
365 return -1;
366 }
367 deviceIDs = (cl_device_id *)malloc(numDevices);
368 if (deviceIDs == NULL)
369 {
370 print_error(error, "malloc failed");
371 return -1;
372 }
373 error = clGetContextInfo(sCurrentContext, CL_CONTEXT_DEVICES,
374 numDevices, deviceIDs, NULL);
375 if (error != CL_SUCCESS)
376 {
377 print_error(error, "Unable to get device list from context");
378 return -1;
379 }
380
381 numDevices /= sizeof(cl_device_id);
382
383 if (numDevices < 1)
384 {
385 log_error("No devices found.\n");
386 return -1;
387 }
388
389 int argc_ = (first_32_testname) ? 1 + (argc - first_32_testname) : argc;
390 const char **argv_ =
391 (first_32_testname) ? &argv[first_32_testname - 1] : argv;
392
393 // Execute the tests.
394 for (size_t i = 0; i < numDevices; i++)
395 {
396 log_info("\nTesting OpenGL 3.2\n");
397 if (printDeviceHeader(deviceIDs[i]) != CL_SUCCESS)
398 {
399 return -1;
400 }
401
402 // Note: don't use the entire harness, because we have a different
403 // way of obtaining the device (via the context)
404 test_harness_config config{};
405 config.forceNoContextCreation = true;
406 config.numElementsToUse = 1024;
407 config.queueProps = 0;
408 error = parseAndCallCommandLineTests(
409 argc_, argv_, deviceIDs[i], test_num32, test_list32, config);
410 if (error != 0) break;
411 }
412
413 numErrors += error;
414
415 // Clean-up.
416 free(deviceIDs);
417 clReleaseContext(sCurrentContext);
418 delete glEnv;
419 }
420
421 // All done.
422 return numErrors;
423 }
424