xref: /aosp_15_r20/external/OpenCL-CTS/test_conformance/gles/helpers.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 "testBase.h"
17 
18 #include "gl_headers.h"
19 
get_kernel_suffix(cl_image_format * format)20 const char *get_kernel_suffix( cl_image_format *format )
21 {
22     switch( format->image_channel_data_type )
23     {
24         case CL_UNORM_INT8:
25         case CL_UNORM_INT16:
26         case CL_SNORM_INT8:
27         case CL_SNORM_INT16:
28         case CL_FLOAT:
29             return "f";
30         case CL_HALF_FLOAT:
31             return "h";
32         case CL_SIGNED_INT8:
33         case CL_SIGNED_INT16:
34         case CL_SIGNED_INT32:
35             return "i";
36         case CL_UNSIGNED_INT8:
37         case CL_UNSIGNED_INT16:
38         case CL_UNSIGNED_INT32:
39             return "ui";
40         default:
41             return "";
42     }
43 }
44 
get_read_kernel_type(cl_image_format * format)45 ExplicitType get_read_kernel_type( cl_image_format *format )
46 {
47     switch( format->image_channel_data_type )
48     {
49         case CL_UNORM_INT8:
50         case CL_UNORM_INT16:
51         case CL_SNORM_INT8:
52         case CL_SNORM_INT16:
53         case CL_FLOAT:
54             return kFloat;
55         case CL_HALF_FLOAT:
56             return kHalf;
57         case CL_SIGNED_INT8:
58         case CL_SIGNED_INT16:
59         case CL_SIGNED_INT32:
60             return kInt;
61         case CL_UNSIGNED_INT8:
62         case CL_UNSIGNED_INT16:
63         case CL_UNSIGNED_INT32:
64             return kUInt;
65         default:
66             return kInt;
67     }
68 }
69 
get_write_kernel_type(cl_image_format * format)70 ExplicitType get_write_kernel_type( cl_image_format *format )
71 {
72     switch( format->image_channel_data_type )
73     {
74         case CL_UNORM_INT8:
75             return kFloat;
76         case CL_UNORM_INT16:
77             return kFloat;
78         case CL_SNORM_INT8:
79             return kFloat;
80         case CL_SNORM_INT16:
81             return kFloat;
82         case CL_HALF_FLOAT:
83             return kHalf;
84         case CL_FLOAT:
85             return kFloat;
86         case CL_SIGNED_INT8:
87             return kChar;
88         case CL_SIGNED_INT16:
89             return kShort;
90         case CL_SIGNED_INT32:
91             return kInt;
92         case CL_UNSIGNED_INT8:
93             return kUChar;
94         case CL_UNSIGNED_INT16:
95             return kUShort;
96         case CL_UNSIGNED_INT32:
97             return kUInt;
98         default:
99             return kInt;
100     }
101 }
102 
get_write_conversion(cl_image_format * format,ExplicitType type)103 const char* get_write_conversion( cl_image_format *format, ExplicitType type )
104 {
105     switch( format->image_channel_data_type )
106     {
107         case CL_UNORM_INT8:
108         case CL_UNORM_INT16:
109         case CL_SNORM_INT8:
110         case CL_SNORM_INT16:
111         case CL_FLOAT:
112             if(type != kFloat) return "convert_float4";
113             break;
114         case CL_HALF_FLOAT:
115             break;
116         case CL_SIGNED_INT8:
117         case CL_SIGNED_INT16:
118         case CL_SIGNED_INT32:
119             if(type != kInt) return "convert_int4";
120             break;
121         case CL_UNSIGNED_INT8:
122         case CL_UNSIGNED_INT16:
123         case CL_UNSIGNED_INT32:
124             if(type != kUInt) return "convert_uint4";
125             break;
126         default:
127             return "";
128     }
129     return "";
130 }
131 
132 // The only three input types to this function are kInt, kUInt and kFloat, due to the way we set up our tests
133 // The output types, though, are pretty much anything valid for GL to receive
134 
135 #define DOWNSCALE_INTEGER_CASE( enum, type, bitShift )    \
136     case enum:    \
137     {        \
138         cl_##type *dst = new cl_##type[ numPixels * 4 ]; \
139         for( size_t i = 0; i < numPixels * 4; i++ ) \
140             dst[ i ] = src[ i ];    \
141         return (char *)dst;        \
142     }
143 
144 #define UPSCALE_FLOAT_CASE( enum, type, typeMax )    \
145     case enum:    \
146     {        \
147         cl_##type *dst = new cl_##type[ numPixels * 4 ]; \
148         for( size_t i = 0; i < numPixels * 4; i++ ) \
149             dst[ i ] = (cl_##type)( src[ i ] * typeMax );    \
150         return (char *)dst;        \
151     }
152 
convert_to_expected(void * inputBuffer,size_t numPixels,ExplicitType inType,ExplicitType outType)153 char * convert_to_expected( void * inputBuffer, size_t numPixels, ExplicitType inType, ExplicitType outType )
154 {
155 #ifdef GLES_DEBUG
156     log_info( "- Converting from input type '%s' to output type '%s'\n",
157              get_explicit_type_name( inType ), get_explicit_type_name( outType ) );
158 #endif
159 
160     if( inType == outType )
161     {
162         char *outData = new char[ numPixels * 4 * get_explicit_type_size(outType) ] ; // sizeof( cl_int ) ];
163         memcpy( outData, inputBuffer, numPixels * 4 * get_explicit_type_size(inType)  );
164         return outData;
165     }
166     else if( inType == kChar )
167     {
168         cl_char *src = (cl_char *)inputBuffer;
169 
170         switch( outType )
171         {
172             case kInt:
173             {
174                 cl_int *outData = new cl_int[ numPixels * 4 ];
175                 for( size_t i = 0; i < numPixels * 4; i++ )
176                 {
177                     outData[ i ] = (cl_int)((src[ i ]));
178                 }
179                 return (char *)outData;
180             }
181             case kFloat:
182             {
183                 // If we're converting to float, then CL decided that we should be normalized
184                 cl_float *outData = new cl_float[ numPixels * 4 ];
185                 for( size_t i = 0; i < numPixels * 4; i++ )
186                 {
187                     outData[ i ] = (cl_float)src[ i ] / 127.0f;
188                 }
189                 return (char *)outData;
190             }
191             default:
192                 log_error( "ERROR: Unsupported conversion from %s to %s!\n", get_explicit_type_name( inType ), get_explicit_type_name( outType ) );
193                 return NULL;
194         }
195     }
196     else if( inType == kUChar )
197     {
198         cl_uchar *src = (cl_uchar *)inputBuffer;
199 
200         switch( outType )
201         {
202             case kUInt:
203             {
204                 cl_uint *outData = new cl_uint[ numPixels * 4 ];
205                 for( size_t i = 0; i < numPixels * 4; i++ )
206                 {
207                     outData[ i ] = (cl_uint)((src[ i ]));
208                 }
209                 return (char *)outData;
210             }
211             case kFloat:
212             {
213                 // If we're converting to float, then CL decided that we should be normalized
214                 cl_float *outData = new cl_float[ numPixels * 4 ];
215                 for( size_t i = 0; i < numPixels * 4; i++ )
216                 {
217                     outData[ i ] = (cl_float)(src[ i ]) / 256.0f;
218                 }
219                 return (char *)outData;
220             }
221             default:
222                 log_error( "ERROR: Unsupported conversion from %s to %s!\n", get_explicit_type_name( inType ), get_explicit_type_name( outType ) );
223                 return NULL;
224         }
225     }
226     else if( inType == kShort )
227     {
228         cl_short *src = (cl_short *)inputBuffer;
229 
230         switch( outType )
231         {
232             case kInt:
233             {
234                 cl_int *outData = new cl_int[ numPixels * 4 ];
235                 for( size_t i = 0; i < numPixels * 4; i++ )
236                 {
237                     outData[ i ] = (cl_int)((src[ i ]));
238                 }
239                 return (char *)outData;
240             }
241             case kFloat:
242             {
243                 // If we're converting to float, then CL decided that we should be normalized
244                 cl_float *outData = new cl_float[ numPixels * 4 ];
245                 for( size_t i = 0; i < numPixels * 4; i++ )
246                 {
247                     outData[ i ] = (cl_float)src[ i ] / 32768.0f;
248                 }
249                 return (char *)outData;
250             }
251             default:
252                 log_error( "ERROR: Unsupported conversion from %s to %s!\n", get_explicit_type_name( inType ), get_explicit_type_name( outType ) );
253                 return NULL;
254         }
255     }
256     else if( inType == kUShort )
257     {
258         cl_ushort *src = (cl_ushort *)inputBuffer;
259 
260         switch( outType )
261         {
262             case kUInt:
263             {
264                 cl_uint *outData = new cl_uint[ numPixels * 4 ];
265                 for( size_t i = 0; i < numPixels * 4; i++ )
266                 {
267                     outData[ i ] = (cl_uint)((src[ i ]));
268                 }
269                 return (char *)outData;
270             }
271             case kFloat:
272             {
273                 // If we're converting to float, then CL decided that we should be normalized
274                 cl_float *outData = new cl_float[ numPixels * 4 ];
275                 for( size_t i = 0; i < numPixels * 4; i++ )
276                 {
277                     outData[ i ] = (cl_float)(src[ i ]) / 65535.0f;
278                 }
279                 return (char *)outData;
280             }
281             default:
282                 log_error( "ERROR: Unsupported conversion from %s to %s!\n", get_explicit_type_name( inType ), get_explicit_type_name( outType ) );
283                 return NULL;
284         }
285     }
286     else if( inType == kInt )
287     {
288         cl_int *src = (cl_int *)inputBuffer;
289 
290         switch( outType )
291         {
292                 DOWNSCALE_INTEGER_CASE( kShort, short, 16 )
293                 DOWNSCALE_INTEGER_CASE( kChar, char, 24 )
294             case kFloat:
295             {
296                 // If we're converting to float, then CL decided that we should be normalized
297                 cl_float *outData = new cl_float[ numPixels * 4 ];
298                 for( size_t i = 0; i < numPixels * 4; i++ )
299                 {
300                     outData[ i ] = (cl_float)fmaxf( (float)src[ i ] / 2147483647.f, -1.f );
301                 }
302                 return (char *)outData;
303             }
304             default:
305                 log_error( "ERROR: Unsupported conversion from %s to %s!\n", get_explicit_type_name( inType ), get_explicit_type_name( outType ) );
306                 return NULL;
307         }
308     }
309     else if( inType == kUInt )
310     {
311         cl_uint *src = (cl_uint *)inputBuffer;
312 
313         switch( outType )
314         {
315                 DOWNSCALE_INTEGER_CASE( kUShort, ushort, 16 )
316                 DOWNSCALE_INTEGER_CASE( kUChar, uchar, 24 )
317             case kFloat:
318             {
319                 // If we're converting to float, then CL decided that we should be normalized
320                 cl_float *outData = new cl_float[ numPixels * 4 ];
321                 for( size_t i = 0; i < numPixels * 4; i++ )
322                 {
323                     outData[ i ] = (cl_float)src[ i ] / 4294967295.f;
324                 }
325                 return (char *)outData;
326             }
327             default:
328                 log_error( "ERROR: Unsupported conversion from %s to %s!\n", get_explicit_type_name( inType ), get_explicit_type_name( outType ) );
329                 return NULL;
330         }
331     }
332     else
333     {
334         cl_float *src = (cl_float *)inputBuffer;
335 
336         switch( outType )
337         {
338                 UPSCALE_FLOAT_CASE( kChar, char, 127.f )
339                 UPSCALE_FLOAT_CASE( kUChar, uchar, 255.f )
340                 UPSCALE_FLOAT_CASE( kShort, short, 32767.f )
341                 UPSCALE_FLOAT_CASE( kUShort, ushort, 65535.f )
342                 UPSCALE_FLOAT_CASE( kInt, int, 2147483647.f )
343                 UPSCALE_FLOAT_CASE( kUInt, uint, 4294967295.f )
344             default:
345                 log_error( "ERROR: Unsupported conversion from %s to %s!\n", get_explicit_type_name( inType ), get_explicit_type_name( outType ) );
346                 return NULL;
347         }
348     }
349 
350     return NULL;
351 }
352 
validate_integer_results(void * expectedResults,void * actualResults,size_t width,size_t height,size_t typeSize)353 int validate_integer_results( void *expectedResults, void *actualResults, size_t width, size_t height, size_t typeSize )
354 {
355     return validate_integer_results( expectedResults, actualResults, width, height, 0, typeSize );
356 }
357 
validate_integer_results(void * expectedResults,void * actualResults,size_t width,size_t height,size_t depth,size_t typeSize)358 int validate_integer_results( void *expectedResults, void *actualResults, size_t width, size_t height, size_t depth, size_t typeSize )
359 {
360     char *expected = (char *)expectedResults;
361     char *actual = (char *)actualResults;
362     for( size_t z = 0; z < ( ( depth == 0 ) ? 1 : depth ); z++ )
363     {
364         for( size_t y = 0; y < height; y++ )
365         {
366             for( size_t x = 0; x < width; x++ )
367             {
368                 if( memcmp( expected, actual, typeSize * 4 ) != 0 )
369                 {
370                     char scratch[ 1024 ];
371 
372                     if( depth == 0 )
373                         log_error( "ERROR: Data sample %d,%d did not validate!\n", (int)x, (int)y );
374                     else
375                         log_error( "ERROR: Data sample %d,%d,%d did not validate!\n", (int)x, (int)y, (int)z );
376                     log_error( "\tExpected: %s\n", GetDataVectorString( expected, typeSize, 4, scratch ) );
377                     log_error( "\t  Actual: %s\n", GetDataVectorString( actual, typeSize, 4, scratch ) );
378                     return -1;
379                 }
380                 expected += typeSize * 4;
381                 actual += typeSize * 4;
382             }
383         }
384     }
385 
386     return 0;
387 }
388 
validate_float_results(void * expectedResults,void * actualResults,size_t width,size_t height)389 int validate_float_results( void *expectedResults, void *actualResults, size_t width, size_t height )
390 {
391     return validate_float_results( expectedResults, actualResults, width, height, 0 );
392 }
393 
validate_float_results(void * expectedResults,void * actualResults,size_t width,size_t height,size_t depth)394 int validate_float_results( void *expectedResults, void *actualResults, size_t width, size_t height, size_t depth )
395 {
396     cl_float *expected = (cl_float *)expectedResults;
397     cl_float *actual = (cl_float *)actualResults;
398     for( size_t z = 0; z < ( ( depth == 0 ) ? 1 : depth ); z++ )
399     {
400         for( size_t y = 0; y < height; y++ )
401         {
402             for( size_t x = 0; x < width; x++ )
403             {
404                 float err = 0.f;
405                 for( size_t i = 0; i < 4; i++ )
406                 {
407                     float error = fabsf( expected[ i ] - actual[ i ] );
408                     if( error > err )
409                         err = error;
410                 }
411 
412                 if( err > 1.f / 127.f ) // Max expected range of error if we converted from an 8-bit integer to a normalized float
413                 {
414                     if( depth == 0 )
415                         log_error( "ERROR: Data sample %d,%d did not validate!\n", (int)x, (int)y );
416                     else
417                         log_error( "ERROR: Data sample %d,%d,%d did not validate!\n", (int)x, (int)y, (int)z );
418                     log_error( "\tExpected: %f %f %f %f\n", expected[ 0 ], expected[ 1 ], expected[ 2 ], expected[ 3 ] );
419                     log_error( "\t        : %a %a %a %a\n", expected[ 0 ], expected[ 1 ], expected[ 2 ], expected[ 3 ] );
420                     log_error( "\t  Actual: %f %f %f %f\n", actual[ 0 ], actual[ 1 ], actual[ 2 ], actual[ 3 ] );
421                     log_error( "\t        : %a %a %a %a\n", actual[ 0 ], actual[ 1 ], actual[ 2 ], actual[ 3 ] );
422                     return -1;
423                 }
424                 expected += 4;
425                 actual += 4;
426             }
427         }
428     }
429 
430     return 0;
431 }
432 
CheckGLObjectInfo(cl_mem mem,cl_gl_object_type expected_cl_gl_type,GLuint expected_gl_name,GLenum expected_cl_gl_texture_target,GLint expected_cl_gl_mipmap_level)433 int CheckGLObjectInfo(cl_mem mem, cl_gl_object_type expected_cl_gl_type, GLuint expected_gl_name,
434                   GLenum expected_cl_gl_texture_target, GLint expected_cl_gl_mipmap_level)
435 {
436   cl_gl_object_type object_type;
437   GLuint object_name;
438   GLenum texture_target;
439   GLint mipmap_level;
440     int error;
441 
442   error = (*clGetGLObjectInfo_ptr)(mem, &object_type, &object_name);
443   test_error( error, "clGetGLObjectInfo failed");
444   if (object_type != expected_cl_gl_type) {
445     log_error("clGetGLObjectInfo did not return expected object type: expected %d, got %d.\n", expected_cl_gl_type, object_type);
446     return -1;
447   }
448   if (object_name != expected_gl_name) {
449     log_error("clGetGLObjectInfo did not return expected object name: expected %d, got %d.\n", expected_gl_name, object_name);
450     return -1;
451   }
452 
453   if (object_type == CL_GL_OBJECT_TEXTURE2D || object_type == CL_GL_OBJECT_TEXTURE3D) {
454        error = (*clGetGLTextureInfo_ptr)(mem, CL_GL_TEXTURE_TARGET, sizeof(texture_target), &texture_target, NULL);
455     test_error( error, "clGetGLTextureInfo for CL_GL_TEXTURE_TARGET failed");
456 
457     if (texture_target != expected_cl_gl_texture_target) {
458       log_error("clGetGLTextureInfo did not return expected texture target: expected %d, got %d.\n", expected_cl_gl_texture_target, texture_target);
459       return -1;
460     }
461 
462        error = (*clGetGLTextureInfo_ptr)(mem, CL_GL_MIPMAP_LEVEL, sizeof(mipmap_level), &mipmap_level, NULL);
463     test_error( error, "clGetGLTextureInfo for CL_GL_MIPMAP_LEVEL failed");
464 
465     if (mipmap_level != expected_cl_gl_mipmap_level) {
466       log_error("clGetGLTextureInfo did not return expected mipmap level: expected %d, got %d.\n", expected_cl_gl_mipmap_level, mipmap_level);
467       return -1;
468     }
469   }
470   return 0;
471 }
472 
CheckGLIntegerExtensionSupport()473 bool CheckGLIntegerExtensionSupport()
474 {
475     // Get the OpenGL version and supported extensions
476     const GLubyte *glVersion = glGetString(GL_VERSION);
477     const GLubyte *glExtensionList = glGetString(GL_EXTENSIONS);
478 
479     // Check if the OpenGL vrsion is 3.0 or grater or GL_EXT_texture_integer is supported
480     return (((glVersion[0] - '0') >= 3) || (strstr((const char*)glExtensionList, "GL_EXT_texture_integer")));
481 }
482