xref: /aosp_15_r20/external/OpenCL-CTS/test_conformance/gles/main.cpp (revision 6467f958c7de8070b317fc65bcb0f6472e388d82)
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     test_harness_config config{};
270     config.forceNoContextCreation = true;
271     config.numElementsToUse = 1024;
272     config.queueProps = 0;
273     error = parseAndCallCommandLineTests(argc_tmp, argv_tmp, deviceIDs[i],
274                                          test_num, test_list, config);
275     if (error != 0) break;
276     }
277 
278     // Clean-up.
279       // We move this to a common cleanup step to make sure that things will be released properly before the test exit
280       goto cleanup;
281       // clReleaseContext( sCurrentContext );
282       // delete glEnv;
283   }
284 
285   // OpenGL 3.2 tests. ////////////////////////////////////////////////////////
286   if ((argc==1) || first_32_testname) {
287 
288     // At least one device supports CL-GL interop, so init the test.
289     if( glEnv->Init( &argc, (char **)argv, CL_TRUE ) ) {
290       log_error("Failed to initialize the GL environment for this test.\n");
291       error = -1;
292       goto cleanup;
293     }
294 
295     // Create a context to use and then grab a device (or devices) from it
296     sCurrentContext = glEnv->CreateCLContext();
297     if( sCurrentContext == NULL ) {
298       log_error( "ERROR: Unable to obtain CL context from GL\n" );
299       error = -1;
300       goto cleanup;
301     }
302 
303     size_t numDevices = 0;
304     cl_device_id deviceIDs[ 16 ];
305 
306     error = clGetContextInfo( sCurrentContext, CL_CONTEXT_DEVICES, 0, NULL, &numDevices);
307     if( error != CL_SUCCESS ) {
308       print_error( error, "Unable to get device count from context" );
309       error = -1;
310       goto cleanup;
311     }
312     numDevices /= sizeof(cl_device_id);
313 
314     if (numDevices < 1) {
315       log_error("No devices found.\n");
316       error = -1;
317       goto cleanup;
318     }
319 
320     error = clGetContextInfo( sCurrentContext, CL_CONTEXT_DEVICES, sizeof( deviceIDs ), deviceIDs, NULL);
321     if( error != CL_SUCCESS ) {
322       print_error( error, "Unable to get device list from context" );
323       error = -1;
324       goto cleanup;
325     }
326 
327 #ifdef GLES3
328     int argc_ = (first_32_testname) ? 1 + (argc - first_32_testname) : argc;
329     const char** argv_ = (first_32_testname) ? &argv[first_32_testname-1] : argv;
330 #endif
331 
332     // Execute the tests.
333       for( size_t i = 0; i < numDevices; i++ ) {
334         log_info( "\nTesting OpenGL 3.2\n" );
335         if( printDeviceHeader( deviceIDs[ i ] ) != CL_SUCCESS ) {
336           error = -1;
337           goto cleanup;
338         }
339 #ifndef GLES3
340         log_info("Cannot test OpenGL 3.2! This test was built for OpenGL ES 2.0\n");
341         error = -1;
342         goto cleanup;
343 #else
344         // Note: don't use the entire harness, because we have a different way of obtaining the device (via the context)
345         test_harness_config config{};
346         config.forceNoContextCreation = true;
347         config.numElementsToUse = 1024;
348         config.queueProps = 0;
349         error = parseAndCallCommandLineTests(argc_, argv_, deviceIDs[i],
350                                              test_num32, test_list32, config);
351         if( error != 0 )
352           break;
353 #endif
354     }
355 
356     // Converge on a common cleanup to make sure that things will be released properly before the test exit
357     goto cleanup;
358   }
359 
360 
361 // cleanup CL/GL/EGL environment properly when the test exit.
362 // This change does not affect any functionality of the test
363 
364 // Intentional falling through
365 cleanup:
366 
367     // Always make sure that OpenCL context is released properly when the test exit
368     if(sCurrentContext)
369     {
370         clReleaseContext( sCurrentContext );
371         sCurrentContext = NULL;
372     }
373 
374     // Cleanup EGL
375     glEnv->terminate_egl_display();
376 
377     delete glEnv;
378 
379     return error;
380 }
381