• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 <stdio.h>
17 #include <stdlib.h>
18 
19 #if !defined(_WIN32)
20 #include <stdbool.h>
21 #endif
22 
23 #include <math.h>
24 #include <string.h>
25 
26 #if !defined (__APPLE__)
27 #include <CL/cl.h>
28 #endif
29 
30 #include "procs.h"
31 #include "gles/setup.h"
32 #include "harness/testHarness.h"
33 
34 #if !defined(_WIN32)
35 #include <unistd.h>
36 #endif
37 
38 static cl_context        sCurrentContext = NULL;
39 
40 
41 #define TEST_FN_REDIRECT( fn ) ADD_TEST( redirect_##fn )
42 #define TEST_FN_REDIRECTOR( fn ) \
43 int test_redirect_##fn(cl_device_id device, cl_context context, cl_command_queue queue, int numElements )    \
44 { \
45     int error; \
46     clCommandQueueWrapper realQueue = clCreateCommandQueue( sCurrentContext, device, 0, &error ); \
47     test_error( error, "Unable to create command queue" );    \
48     return test_##fn( device, sCurrentContext, realQueue, numElements ); \
49 }
50 
51 TEST_FN_REDIRECTOR( buffers )
52 TEST_FN_REDIRECTOR( buffers_getinfo )
53 TEST_FN_REDIRECTOR( images_read )
54 TEST_FN_REDIRECTOR( images_2D_getinfo )
55 TEST_FN_REDIRECTOR( images_read_cube )
56 TEST_FN_REDIRECTOR( images_cube_getinfo )
57 TEST_FN_REDIRECTOR( images_read_3D )
58 TEST_FN_REDIRECTOR( images_3D_getinfo )
59 TEST_FN_REDIRECTOR( images_write )
60 TEST_FN_REDIRECTOR( images_write_cube )
61 TEST_FN_REDIRECTOR( renderbuffer_read )
62 TEST_FN_REDIRECTOR( renderbuffer_write )
63 TEST_FN_REDIRECTOR( renderbuffer_getinfo )
64 
65 #ifdef GL_ES_VERSION_3_0
66 TEST_FN_REDIRECTOR(fence_sync)
67 #endif
68 
69 test_definition test_list[] = {
70     TEST_FN_REDIRECT( buffers ),
71     TEST_FN_REDIRECT( buffers_getinfo ),
72     TEST_FN_REDIRECT( images_read ),
73     TEST_FN_REDIRECT( images_2D_getinfo ),
74     TEST_FN_REDIRECT( images_read_cube ),
75     TEST_FN_REDIRECT( images_cube_getinfo ),
76     TEST_FN_REDIRECT( images_read_3D ),
77     TEST_FN_REDIRECT( images_3D_getinfo ),
78     TEST_FN_REDIRECT( images_write ),
79     TEST_FN_REDIRECT( images_write_cube ),
80     TEST_FN_REDIRECT( renderbuffer_read ),
81     TEST_FN_REDIRECT( renderbuffer_write ),
82     TEST_FN_REDIRECT( renderbuffer_getinfo )
83 };
84 
85 #ifdef GL_ES_VERSION_3_0
86 test_definition test_list32[] = {
87     TEST_FN_REDIRECT( fence_sync )
88 };
89 #endif
90 
91 const int test_num = ARRAY_SIZE( test_list );
92 
93 #ifdef GL_ES_VERSION_3_0
94 const int test_num32 = ARRAY_SIZE( test_list32 );
95 #endif
96 
97 
main(int argc,const char * argv[])98 int main(int argc, const char *argv[])
99 {
100   int error = 0;
101   cl_platform_id platform_id = NULL;
102   /* To keep it simple, use a static allocation of 32 argv pointers.
103      argc is not expected to go beyond 32 */
104   const char* argv_tmp[32] = {0};
105   int argc_tmp = 0;
106 
107     test_start();
108 
109   cl_device_type requestedDeviceType = CL_DEVICE_TYPE_DEFAULT;
110 
111     for(int z = 1; z < argc; ++z)
112     {//for
113     if(strcmp( argv[ z ], "-list" ) == 0 )
114     {
115         log_info( "Available 2.x tests:\n" );
116         for( int i = 0; i < test_num; i++ )
117             log_info( "\t%s\n", test_list[i].name );
118 
119 #ifdef GL_ES_VERSION_3_0
120         log_info( "Available 3.2 tests:\n" );
121         for( int i = 0; i < test_num32; i++ )
122             log_info( "\t%s\n", test_list32[i].name );
123 #endif
124 
125         log_info("Note: Any 3.2 test names must follow 2.1 test names on the "
126                  "command line.");
127         log_info("Use environment variables to specify desired device.");
128 
129         return 0;
130     }
131 
132     /* support requested device type */
133         if(!strcmp(argv[z], "CL_DEVICE_TYPE_GPU"))
134         {
135            printf("Requested device type is CL_DEVICE_TYPE_GPU\n");
136            requestedDeviceType = CL_DEVICE_TYPE_GPU;
137         }
138         else
139         if(!strcmp(argv[z], "CL_DEVICE_TYPE_CPU"))
140         {
141            printf("Requested device type is CL_DEVICE_TYPE_CPU\n");
142            log_info("Invalid CL device type. GL tests can only run on a GPU device.\n");
143            return 0;
144         }
145     }//for
146 
147   // Check to see if any 2.x or 3.2 test names were specified on the command line.
148   unsigned first_32_testname = 0;
149 
150 #ifdef GL_ES_VERSION_3_0
151   for (int j=1; (j<argc) && (!first_32_testname); ++j)
152     for (int i = 0; i < test_num32; ++i)
153       if (strcmp(test_list32[i].name, argv[j]) == 0 ) {
154         first_32_testname = j;
155         break;
156       }
157 #endif
158 
159   // Create the environment for the test.
160     GLEnvironment *glEnv = GLEnvironment::Instance();
161 
162   // Check if any devices of the requested type support CL/GL interop.
163   int supported = glEnv->SupportsCLGLInterop( requestedDeviceType );
164   if( supported == 0 ) {
165     log_info("Test not run because GL-CL interop is not supported for any devices of the requested type.\n");
166     error = 0;
167     goto cleanup;
168   } else if ( supported == -1 ) {
169     log_error("Failed to determine if CL-GL interop is supported.\n");
170     error = -1;
171     goto cleanup;
172   }
173 
174   // OpenGL tests for non-3.2 ////////////////////////////////////////////////////////
175   if ((argc == 1) || (first_32_testname != 1)) {
176 
177     // At least one device supports CL-GL interop, so init the test.
178     if( glEnv->Init( &argc, (char **)argv, CL_FALSE ) ) {
179       log_error("Failed to initialize the GL environment for this test.\n");
180       error = -1;
181       goto cleanup;
182     }
183 
184     // Create a context to use and then grab a device (or devices) from it
185     sCurrentContext = glEnv->CreateCLContext();
186     if( sCurrentContext == NULL )
187       {
188         log_error( "ERROR: Unable to obtain CL context from GL\n" );
189         error = -1;
190         goto cleanup;
191       }
192 
193     size_t numDevices = 0;
194     cl_device_id deviceIDs[ 16 ];
195 
196     error = clGetContextInfo( sCurrentContext, CL_CONTEXT_DEVICES, 0, NULL, &numDevices);
197     if( error != CL_SUCCESS )
198       {
199         print_error( error, "Unable to get device count from context" );
200         error = -1;
201         goto cleanup;
202       }
203     numDevices /= sizeof(cl_device_id);
204 
205     if (numDevices < 1) {
206       log_error("No devices found.\n");
207       error = -1;
208       goto cleanup;
209     }
210 
211     error = clGetContextInfo( sCurrentContext, CL_CONTEXT_DEVICES, sizeof( deviceIDs ), deviceIDs, NULL);
212     if( error != CL_SUCCESS ) {
213       print_error( error, "Unable to get device list from context" );
214       error = -1;
215       goto cleanup;
216     }
217 
218     // Execute tests.
219     int argc_ = (first_32_testname) ? first_32_testname : argc;
220 
221       for( size_t i = 0; i < numDevices; i++ ) {
222         log_info( "\nTesting OpenGL 2.x\n" );
223         if( printDeviceHeader( deviceIDs[ i ] ) != CL_SUCCESS ) {
224           error = -1;
225           goto cleanup;
226         }
227 
228         error = clGetDeviceInfo(deviceIDs[ i ],
229                                 CL_DEVICE_PLATFORM,
230                                 sizeof(platform_id),
231                                 &platform_id,
232                                 NULL);
233         if(error)
234         {
235           goto cleanup;
236         }
237 
238         error = init_clgl_ext(platform_id);
239         if (error < 0)
240         {
241           goto cleanup;
242         }
243 
244         /* parseAndCallCommandLineTests considers every command line argument
245            as a test name. This results in the test failing because of considering
246            args such as 'CL_DEVICE_TYPE_GPU' as test names unless
247            the actual test name happens to be the first argument.
248            Instead of changing the behaviour of parseAndCallCommandLineTests
249            modify the arguments passed to it so as to not affect other tests.
250         */
251     int w = 1;
252     argc_tmp= argc_;
253     for(int k = 1; k < argc; k++)
254     {
255         if( (strcmp(argv[k], "full") == 0) ||
256             (strcmp(argv[k], "CL_DEVICE_TYPE_CPU") == 0) ||
257             (strcmp(argv[k], "CL_DEVICE_TYPE_GPU") == 0))
258         {
259             argc_tmp--;
260             continue;
261         }
262         else
263         {
264             argv_tmp[w++] = argv[k];
265         }
266     }
267 
268         // Note: don't use the entire harness, because we have a different way of obtaining the device (via the context)
269         error = parseAndCallCommandLineTests( argc_tmp, argv_tmp, deviceIDs[i], test_num, test_list, true, 0, 1024 );
270         if( error != 0 )
271           break;
272     }
273 
274     // Clean-up.
275       // We move this to a common cleanup step to make sure that things will be released properly before the test exit
276       goto cleanup;
277       // clReleaseContext( sCurrentContext );
278       // delete glEnv;
279   }
280 
281   // OpenGL 3.2 tests. ////////////////////////////////////////////////////////
282   if ((argc==1) || first_32_testname) {
283 
284     // At least one device supports CL-GL interop, so init the test.
285     if( glEnv->Init( &argc, (char **)argv, CL_TRUE ) ) {
286       log_error("Failed to initialize the GL environment for this test.\n");
287       error = -1;
288       goto cleanup;
289     }
290 
291     // Create a context to use and then grab a device (or devices) from it
292     sCurrentContext = glEnv->CreateCLContext();
293     if( sCurrentContext == NULL ) {
294       log_error( "ERROR: Unable to obtain CL context from GL\n" );
295       error = -1;
296       goto cleanup;
297     }
298 
299     size_t numDevices = 0;
300     cl_device_id deviceIDs[ 16 ];
301 
302     error = clGetContextInfo( sCurrentContext, CL_CONTEXT_DEVICES, 0, NULL, &numDevices);
303     if( error != CL_SUCCESS ) {
304       print_error( error, "Unable to get device count from context" );
305       error = -1;
306       goto cleanup;
307     }
308     numDevices /= sizeof(cl_device_id);
309 
310     if (numDevices < 1) {
311       log_error("No devices found.\n");
312       error = -1;
313       goto cleanup;
314     }
315 
316     error = clGetContextInfo( sCurrentContext, CL_CONTEXT_DEVICES, sizeof( deviceIDs ), deviceIDs, NULL);
317     if( error != CL_SUCCESS ) {
318       print_error( error, "Unable to get device list from context" );
319       error = -1;
320       goto cleanup;
321     }
322 
323     int argc_ = (first_32_testname) ? 1 + (argc - first_32_testname) : argc;
324     const char** argv_ = (first_32_testname) ? &argv[first_32_testname-1] : argv;
325 
326     // Execute the tests.
327       for( size_t i = 0; i < numDevices; i++ ) {
328         log_info( "\nTesting OpenGL 3.2\n" );
329         if( printDeviceHeader( deviceIDs[ i ] ) != CL_SUCCESS ) {
330           error = -1;
331           goto cleanup;
332         }
333 #ifndef GLES3
334         log_info("Cannot test OpenGL 3.2! This test was built for OpenGL ES 2.0\n");
335         error = -1;
336         goto cleanup;
337 #else
338         // Note: don't use the entire harness, because we have a different way of obtaining the device (via the context)
339         error = parseAndCallCommandLineTests( argc_, argv_, deviceIDs[ i ], test_num32, test_list32, true, 0, 1024 );
340         if( error != 0 )
341           break;
342 #endif
343     }
344 
345     // Converge on a common cleanup to make sure that things will be released properly before the test exit
346     goto cleanup;
347   }
348 
349 
350 // cleanup CL/GL/EGL environment properly when the test exit.
351 // This change does not affect any functionality of the test
352 
353 // Intentional falling through
354 cleanup:
355 
356     // Always make sure that OpenCL context is released properly when the test exit
357     if(sCurrentContext)
358     {
359         clReleaseContext( sCurrentContext );
360         sCurrentContext = NULL;
361     }
362 
363     // Cleanup EGL
364     glEnv->terminate_egl_display();
365 
366     delete glEnv;
367 
368     return error;
369 }
370