xref: /aosp_15_r20/external/OpenCL-CTS/test_conformance/gl/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 #if defined(__APPLE__)
18 #include <OpenGL/glu.h>
19 #else
20 #include <GL/glu.h>
21 #endif
22 
get_kernel_suffix(cl_image_format * format)23 const char *get_kernel_suffix(cl_image_format *format)
24 {
25     switch (format->image_channel_data_type)
26     {
27         case CL_UNORM_INT8:
28         case CL_UNORM_INT16:
29         case CL_UNORM_INT24:
30         case CL_SNORM_INT8:
31         case CL_SNORM_INT16:
32         case CL_HALF_FLOAT:
33         case CL_FLOAT:
34         case CL_UNORM_INT_101010: return "f";
35         case CL_SIGNED_INT8:
36         case CL_SIGNED_INT16:
37         case CL_SIGNED_INT32: return "i";
38         case CL_UNSIGNED_INT8:
39         case CL_UNSIGNED_INT16:
40         case CL_UNSIGNED_INT32: return "ui";
41         default:
42             log_error("Test error: unsupported kernel suffix for "
43                       "image_channel_data_type 0x%X\n",
44                       format->image_channel_data_type);
45             return "";
46     }
47 }
48 
get_read_kernel_type(cl_image_format * format)49 ExplicitType get_read_kernel_type(cl_image_format *format)
50 {
51     switch (format->image_channel_data_type)
52     {
53         case CL_UNORM_INT8:
54         case CL_UNORM_INT16:
55         case CL_UNORM_INT24:
56         case CL_SNORM_INT8:
57         case CL_SNORM_INT16:
58         case CL_HALF_FLOAT:
59         case CL_FLOAT:
60         case CL_UNORM_INT_101010:
61 #ifdef GL_VERSION_3_2
62         case CL_DEPTH:
63 #endif
64             return kFloat;
65         case CL_SIGNED_INT8:
66         case CL_SIGNED_INT16:
67         case CL_SIGNED_INT32: return kInt;
68         case CL_UNSIGNED_INT8:
69         case CL_UNSIGNED_INT16:
70         case CL_UNSIGNED_INT32: return kUInt;
71         default:
72             log_error("Test error: unsupported kernel suffix for "
73                       "image_channel_data_type 0x%X\n",
74                       format->image_channel_data_type);
75             return kNumExplicitTypes;
76     }
77 }
78 
get_write_kernel_type(cl_image_format * format)79 ExplicitType get_write_kernel_type(cl_image_format *format)
80 {
81     switch (format->image_channel_data_type)
82     {
83         case CL_UNORM_INT8: return kFloat;
84         case CL_UNORM_INT16: return kFloat;
85         case CL_UNORM_INT24: return kFloat;
86         case CL_SNORM_INT8: return kFloat;
87         case CL_SNORM_INT16: return kFloat;
88         case CL_HALF_FLOAT: return kHalf;
89         case CL_FLOAT: return kFloat;
90         case CL_SIGNED_INT8: return kChar;
91         case CL_SIGNED_INT16: return kShort;
92         case CL_SIGNED_INT32: return kInt;
93         case CL_UNSIGNED_INT8: return kUChar;
94         case CL_UNSIGNED_INT16: return kUShort;
95         case CL_UNSIGNED_INT32: return kUInt;
96         case CL_UNORM_INT_101010: return kFloat;
97 #ifdef GL_VERSION_3_2
98         case CL_DEPTH: return kFloat;
99 #endif
100         default: return kInt;
101     }
102 }
103 
get_write_conversion(cl_image_format * format,ExplicitType type)104 const char *get_write_conversion(cl_image_format *format, ExplicitType type)
105 {
106     switch (format->image_channel_data_type)
107     {
108         case CL_UNORM_INT8:
109         case CL_UNORM_INT16:
110         case CL_SNORM_INT8:
111         case CL_SNORM_INT16:
112         case CL_HALF_FLOAT:
113         case CL_FLOAT:
114         case CL_UNORM_INT_101010:
115         case CL_UNORM_INT24:
116             if (type != kFloat) return "convert_float4";
117             break;
118         case CL_SIGNED_INT8:
119         case CL_SIGNED_INT16:
120         case CL_SIGNED_INT32:
121             if (type != kInt) return "convert_int4";
122             break;
123         case CL_UNSIGNED_INT8:
124         case CL_UNSIGNED_INT16:
125         case CL_UNSIGNED_INT32:
126             if (type != kUInt) return "convert_uint4";
127             break;
128         default: return "";
129     }
130     return "";
131 }
132 
133 // The only three input types to this function are kInt, kUInt and kFloat, due
134 // to the way we set up our tests The output types, though, are pretty much
135 // anything valid for GL to receive
136 
137 #define DOWNSCALE_INTEGER_CASE(enum, type, bitShift)                           \
138     case enum: {                                                               \
139         cl_##type *dst = new cl_##type[numPixels * 4];                         \
140         for (size_t i = 0; i < numPixels * 4; i++) dst[i] = src[i];            \
141         return (char *)dst;                                                    \
142     }
143 
144 #define UPSCALE_FLOAT_CASE(enum, type, typeMax)                                \
145     case enum: {                                                               \
146         cl_##type *dst = new cl_##type[numPixels * 4];                         \
147         for (size_t i = 0; i < numPixels * 4; i++)                             \
148             dst[i] = (cl_##type)(src[i] * typeMax);                            \
149         return (char *)dst;                                                    \
150     }
151 
convert_to_expected(void * inputBuffer,size_t numPixels,ExplicitType inType,ExplicitType outType,size_t channelNum,GLenum glDataType)152 char *convert_to_expected(void *inputBuffer, size_t numPixels,
153                           ExplicitType inType, ExplicitType outType,
154                           size_t channelNum, GLenum glDataType)
155 {
156 #ifdef DEBUG
157     log_info("- Converting from input type '%s' to output type '%s'\n",
158              get_explicit_type_name(inType), get_explicit_type_name(outType));
159 #endif
160 
161     if (inType == outType)
162     {
163         char *outData =
164             new char[numPixels * channelNum
165                      * get_explicit_type_size(outType)]; // sizeof( cl_int ) ];
166         if (glDataType == GL_FLOAT_32_UNSIGNED_INT_24_8_REV)
167         {
168             for (size_t i = 0; i < numPixels; ++i)
169             {
170                 ((cl_float *)outData)[i] = ((cl_float *)inputBuffer)[2 * i];
171             }
172         }
173         else
174         {
175             memcpy(outData, inputBuffer,
176                    numPixels * channelNum * get_explicit_type_size(inType));
177         }
178         return outData;
179     }
180     else if (inType == kChar)
181     {
182         cl_char *src = (cl_char *)inputBuffer;
183 
184         switch (outType)
185         {
186             case kInt: {
187                 cl_int *outData = new cl_int[numPixels * channelNum];
188                 for (size_t i = 0; i < numPixels * channelNum; i++)
189                 {
190                     outData[i] = (cl_int)((src[i]));
191                 }
192                 return (char *)outData;
193             }
194             case kFloat: {
195                 // If we're converting to float, then CL decided that we should
196                 // be normalized
197                 cl_float *outData = new cl_float[numPixels * channelNum];
198                 for (size_t i = 0; i < numPixels * channelNum; i++)
199                 {
200                     outData[i] = (cl_float)src[i] / 127.0f;
201                 }
202                 return (char *)outData;
203             }
204             default:
205                 log_error("ERROR: Unsupported conversion from %s to %s!\n",
206                           get_explicit_type_name(inType),
207                           get_explicit_type_name(outType));
208                 return NULL;
209         }
210     }
211     else if (inType == kUChar)
212     {
213         cl_uchar *src = (cl_uchar *)inputBuffer;
214 
215         switch (outType)
216         {
217             case kUInt: {
218                 cl_uint *outData = new cl_uint[numPixels * channelNum];
219                 for (size_t i = 0; i < numPixels * channelNum; i++)
220                 {
221                     outData[i] = (cl_uint)((src[i]));
222                 }
223                 return (char *)outData;
224             }
225             case kFloat: {
226                 // If we're converting to float, then CL decided that we should
227                 // be normalized
228                 cl_float *outData = new cl_float[numPixels * channelNum];
229                 for (size_t i = 0; i < numPixels * channelNum; i++)
230                 {
231                     outData[i] = (cl_float)(src[i]) / 256.0f;
232                 }
233                 return (char *)outData;
234             }
235             default:
236                 log_error("ERROR: Unsupported conversion from %s to %s!\n",
237                           get_explicit_type_name(inType),
238                           get_explicit_type_name(outType));
239                 return NULL;
240         }
241     }
242     else if (inType == kShort)
243     {
244         cl_short *src = (cl_short *)inputBuffer;
245 
246         switch (outType)
247         {
248             case kInt: {
249                 cl_int *outData = new cl_int[numPixels * channelNum];
250                 for (size_t i = 0; i < numPixels * channelNum; i++)
251                 {
252                     outData[i] = (cl_int)((src[i]));
253                 }
254                 return (char *)outData;
255             }
256             case kFloat: {
257                 // If we're converting to float, then CL decided that we should
258                 // be normalized
259                 cl_float *outData = new cl_float[numPixels * channelNum];
260                 for (size_t i = 0; i < numPixels * channelNum; i++)
261                 {
262                     outData[i] = (cl_float)src[i] / 32768.0f;
263                 }
264                 return (char *)outData;
265             }
266             default:
267                 log_error("ERROR: Unsupported conversion from %s to %s!\n",
268                           get_explicit_type_name(inType),
269                           get_explicit_type_name(outType));
270                 return NULL;
271         }
272     }
273     else if (inType == kUShort)
274     {
275         cl_ushort *src = (cl_ushort *)inputBuffer;
276 
277         switch (outType)
278         {
279             case kUInt: {
280                 cl_uint *outData = new cl_uint[numPixels * channelNum];
281                 for (size_t i = 0; i < numPixels * channelNum; i++)
282                 {
283                     outData[i] = (cl_uint)((src[i]));
284                 }
285                 return (char *)outData;
286             }
287             case kFloat: {
288                 // If we're converting to float, then CL decided that we should
289                 // be normalized
290                 cl_float *outData = new cl_float[numPixels * channelNum];
291                 for (size_t i = 0; i < numPixels * channelNum; i++)
292                 {
293                     outData[i] = (cl_float)(src[i]) / 65535.0f;
294                 }
295                 return (char *)outData;
296             }
297             default:
298                 log_error("ERROR: Unsupported conversion from %s to %s!\n",
299                           get_explicit_type_name(inType),
300                           get_explicit_type_name(outType));
301                 return NULL;
302         }
303     }
304     else if (inType == kInt)
305     {
306         cl_int *src = (cl_int *)inputBuffer;
307 
308         switch (outType)
309         {
310             DOWNSCALE_INTEGER_CASE(kShort, short, 16)
311             DOWNSCALE_INTEGER_CASE(kChar, char, 24)
312             case kFloat: {
313                 // If we're converting to float, then CL decided that we should
314                 // be normalized
315                 cl_float *outData = new cl_float[numPixels * channelNum];
316                 for (size_t i = 0; i < numPixels * channelNum; i++)
317                 {
318                     outData[i] =
319                         (cl_float)fmaxf((float)src[i] / 2147483647.f, -1.f);
320                 }
321                 return (char *)outData;
322             }
323             default:
324                 log_error("ERROR: Unsupported conversion from %s to %s!\n",
325                           get_explicit_type_name(inType),
326                           get_explicit_type_name(outType));
327                 return NULL;
328         }
329     }
330     else if (inType == kUInt)
331     {
332         cl_uint *src = (cl_uint *)inputBuffer;
333 
334         switch (outType)
335         {
336             DOWNSCALE_INTEGER_CASE(kUShort, ushort, 16)
337             DOWNSCALE_INTEGER_CASE(kUChar, uchar, 24)
338             case kFloat: {
339                 // If we're converting to float, then CL decided that we should
340                 // be normalized
341                 cl_float *outData = new cl_float[numPixels * channelNum];
342                 const cl_float MaxValue = (glDataType == GL_UNSIGNED_INT_24_8)
343                     ? 16777215.f
344                     : 4294967295.f;
345                 const cl_uint ShiftBits =
346                     (glDataType == GL_UNSIGNED_INT_24_8) ? 8 : 0;
347                 for (size_t i = 0; i < numPixels * channelNum; i++)
348                 {
349                     outData[i] = (cl_float)(src[i] >> ShiftBits) / MaxValue;
350                 }
351                 return (char *)outData;
352             }
353             default:
354                 log_error("ERROR: Unsupported conversion from %s to %s!\n",
355                           get_explicit_type_name(inType),
356                           get_explicit_type_name(outType));
357                 return NULL;
358         }
359     }
360     else if (inType == kHalf)
361     {
362         cl_half *src = (cl_half *)inputBuffer;
363 
364         switch (outType)
365         {
366             case kFloat: {
367                 cl_float *outData = new cl_float[numPixels * channelNum];
368                 for (size_t i = 0; i < numPixels * channelNum; i++)
369                 {
370                     outData[i] = cl_half_to_float(src[i]);
371                 }
372                 return (char *)outData;
373             }
374             default:
375                 log_error("ERROR: Unsupported conversion from %s to %s!\n",
376                           get_explicit_type_name(inType),
377                           get_explicit_type_name(outType));
378                 return NULL;
379         }
380     }
381     else
382     {
383         cl_float *src = (cl_float *)inputBuffer;
384 
385         switch (outType)
386         {
387             UPSCALE_FLOAT_CASE(kChar, char, 127.f)
388             UPSCALE_FLOAT_CASE(kUChar, uchar, 255.f)
389             UPSCALE_FLOAT_CASE(kShort, short, 32767.f)
390             UPSCALE_FLOAT_CASE(kUShort, ushort, 65535.f)
391             UPSCALE_FLOAT_CASE(kInt, int, 2147483647.f)
392             UPSCALE_FLOAT_CASE(kUInt, uint, 4294967295.f)
393             default:
394                 log_error("ERROR: Unsupported conversion from %s to %s!\n",
395                           get_explicit_type_name(inType),
396                           get_explicit_type_name(outType));
397                 return NULL;
398         }
399     }
400 
401     return NULL;
402 }
403 
validate_integer_results(void * expectedResults,void * actualResults,size_t width,size_t height,size_t sampleNum,size_t typeSize)404 int validate_integer_results(void *expectedResults, void *actualResults,
405                              size_t width, size_t height, size_t sampleNum,
406                              size_t typeSize)
407 {
408     return validate_integer_results(expectedResults, actualResults, width,
409                                     height, sampleNum, 0, typeSize);
410 }
411 
validate_integer_results(void * expectedResults,void * actualResults,size_t width,size_t height,size_t depth,size_t sampleNum,size_t typeSize)412 int validate_integer_results(void *expectedResults, void *actualResults,
413                              size_t width, size_t height, size_t depth,
414                              size_t sampleNum, size_t typeSize)
415 {
416     char *expected = (char *)expectedResults;
417     char *actual = (char *)actualResults;
418     for (size_t s = 0; s < sampleNum; s++)
419     {
420         for (size_t z = 0; z < ((depth == 0) ? 1 : depth); z++)
421         {
422             for (size_t y = 0; y < height; y++)
423             {
424                 for (size_t x = 0; x < width; x++)
425                 {
426                     if (memcmp(expected, actual, typeSize * 4) != 0)
427                     {
428                         char scratch[1024];
429 
430                         if (depth == 0)
431                             log_error("ERROR: Data sample %d,%d,%d did not "
432                                       "validate!\n",
433                                       (int)x, (int)y, (int)s);
434                         else
435                             log_error("ERROR: Data sample %d,%d,%d,%d did not "
436                                       "validate!\n",
437                                       (int)x, (int)y, (int)z, (int)s);
438                         log_error("\tExpected: %s\n",
439                                   GetDataVectorString(expected, typeSize, 4,
440                                                       scratch));
441                         log_error(
442                             "\t  Actual: %s\n",
443                             GetDataVectorString(actual, typeSize, 4, scratch));
444                         return -1;
445                     }
446                     expected += typeSize * 4;
447                     actual += typeSize * 4;
448                 }
449             }
450         }
451     }
452 
453     return 0;
454 }
455 
validate_float_results(void * expectedResults,void * actualResults,size_t width,size_t height,size_t sampleNum,size_t channelNum)456 int validate_float_results(void *expectedResults, void *actualResults,
457                            size_t width, size_t height, size_t sampleNum,
458                            size_t channelNum)
459 {
460     return validate_float_results(expectedResults, actualResults, width, height,
461                                   sampleNum, 0, channelNum);
462 }
463 
validate_float_results(void * expectedResults,void * actualResults,size_t width,size_t height,size_t depth,size_t sampleNum,size_t channelNum)464 int validate_float_results(void *expectedResults, void *actualResults,
465                            size_t width, size_t height, size_t depth,
466                            size_t sampleNum, size_t channelNum)
467 {
468     cl_float *expected = (cl_float *)expectedResults;
469     cl_float *actual = (cl_float *)actualResults;
470     for (size_t s = 0; s < sampleNum; s++)
471     {
472         for (size_t z = 0; z < ((depth == 0) ? 1 : depth); z++)
473         {
474             for (size_t y = 0; y < height; y++)
475             {
476                 for (size_t x = 0; x < width; x++)
477                 {
478                     float err = 0.f;
479                     for (size_t i = 0; i < channelNum; i++)
480                     {
481                         float error = fabsf(expected[i] - actual[i]);
482                         if (error > err) err = error;
483                     }
484 
485                     if (err > 1.f / 127.f) // Max expected range of error if we
486                                            // converted from an 8-bit integer to
487                                            // a normalized float
488                     {
489                         if (depth == 0)
490                             log_error("ERROR: Data sample %d,%d,%d did not "
491                                       "validate!\n",
492                                       (int)x, (int)y, (int)s);
493                         else
494                             log_error("ERROR: Data sample %d,%d,%d,%d did not "
495                                       "validate!\n",
496                                       (int)x, (int)y, (int)z, (int)s);
497 
498                         if (channelNum == 4)
499                         {
500                             log_error("\tExpected: %f %f %f %f\n", expected[0],
501                                       expected[1], expected[2], expected[3]);
502                             log_error("\t        : %a %a %a %a\n", expected[0],
503                                       expected[1], expected[2], expected[3]);
504                             log_error("\t  Actual: %f %f %f %f\n", actual[0],
505                                       actual[1], actual[2], actual[3]);
506                             log_error("\t        : %a %a %a %a\n", actual[0],
507                                       actual[1], actual[2], actual[3]);
508                         }
509                         else if (channelNum == 1)
510                         {
511                             log_error("\tExpected: %f\n", expected[0]);
512                             log_error("\t        : %a\n", expected[0]);
513                             log_error("\t  Actual: %f\n", actual[0]);
514                             log_error("\t        : %a\n", actual[0]);
515                         }
516                         return -1;
517                     }
518                     expected += channelNum;
519                     actual += channelNum;
520                 }
521             }
522         }
523     }
524 
525     return 0;
526 }
527 
validate_float_results_rgb_101010(void * expectedResults,void * actualResults,size_t width,size_t height,size_t sampleNum)528 int validate_float_results_rgb_101010(void *expectedResults,
529                                       void *actualResults, size_t width,
530                                       size_t height, size_t sampleNum)
531 {
532     return validate_float_results_rgb_101010(expectedResults, actualResults,
533                                              width, height, sampleNum, 0);
534 }
535 
validate_float_results_rgb_101010(void * expectedResults,void * actualResults,size_t width,size_t height,size_t depth,size_t sampleNum)536 int validate_float_results_rgb_101010(void *expectedResults,
537                                       void *actualResults, size_t width,
538                                       size_t height, size_t depth,
539                                       size_t sampleNum)
540 {
541     cl_float *expected = (cl_float *)expectedResults;
542     cl_float *actual = (cl_float *)actualResults;
543     for (size_t s = 0; s < sampleNum; s++)
544     {
545         for (size_t z = 0; z < ((depth == 0) ? 1 : depth); z++)
546         {
547             for (size_t y = 0; y < height; y++)
548             {
549                 for (size_t x = 0; x < width; x++)
550                 {
551                     float err = 0.f;
552                     for (size_t i = 0; i < 3; i++) // skip the fourth channel
553                     {
554                         float error = fabsf(expected[i] - actual[i]);
555                         if (error > err) err = error;
556                     }
557 
558                     if (err > 1.f / 127.f) // Max expected range of error if we
559                                            // converted from an 8-bit integer to
560                                            // a normalized float
561                     {
562                         if (depth == 0)
563                             log_error("ERROR: Data sample %d,%d,%d did not "
564                                       "validate!\n",
565                                       (int)x, (int)y, (int)s);
566                         else
567                             log_error("ERROR: Data sample %d,%d,%d,%d did not "
568                                       "validate!\n",
569                                       (int)x, (int)y, (int)z, (int)s);
570                         log_error("\tExpected: %f %f %f\n", expected[0],
571                                   expected[1], expected[2]);
572                         log_error("\t        : %a %a %a\n", expected[0],
573                                   expected[1], expected[2]);
574                         log_error("\t  Actual: %f %f %f\n", actual[0],
575                                   actual[1], actual[2]);
576                         log_error("\t        : %a %a %a\n", actual[0],
577                                   actual[1], actual[2]);
578                         return -1;
579                     }
580                     expected += 4;
581                     actual += 4;
582                 }
583             }
584         }
585     }
586 
587     return 0;
588 }
589 
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)590 int CheckGLObjectInfo(cl_mem mem, cl_gl_object_type expected_cl_gl_type,
591                       GLuint expected_gl_name,
592                       GLenum expected_cl_gl_texture_target,
593                       GLint expected_cl_gl_mipmap_level)
594 {
595     cl_gl_object_type object_type;
596     GLuint object_name;
597     GLenum texture_target;
598     GLint mipmap_level;
599     int error;
600 
601     error = (*clGetGLObjectInfo_ptr)(mem, &object_type, &object_name);
602     test_error(error, "clGetGLObjectInfo failed");
603     if (object_type != expected_cl_gl_type)
604     {
605         log_error("clGetGLObjectInfo did not return expected object type: "
606                   "expected %d, got %d.\n",
607                   expected_cl_gl_type, object_type);
608         return -1;
609     }
610     if (object_name != expected_gl_name)
611     {
612         log_error("clGetGLObjectInfo did not return expected object name: "
613                   "expected %d, got %d.\n",
614                   expected_gl_name, object_name);
615         return -1;
616     }
617 
618     // If we're dealing with a buffer or render buffer, we are done.
619 
620     if (object_type == CL_GL_OBJECT_BUFFER
621         || object_type == CL_GL_OBJECT_RENDERBUFFER)
622     {
623         return 0;
624     }
625 
626     // Otherwise, it's a texture-based object and requires a bit more checking.
627 
628     error = (*clGetGLTextureInfo_ptr)(mem, CL_GL_TEXTURE_TARGET,
629                                       sizeof(texture_target), &texture_target,
630                                       NULL);
631     test_error(error, "clGetGLTextureInfo for CL_GL_TEXTURE_TARGET failed");
632 
633     if (texture_target != expected_cl_gl_texture_target)
634     {
635         log_error("clGetGLTextureInfo did not return expected texture target: "
636                   "expected %d, got %d.\n",
637                   expected_cl_gl_texture_target, texture_target);
638         return -1;
639     }
640 
641     error = (*clGetGLTextureInfo_ptr)(
642         mem, CL_GL_MIPMAP_LEVEL, sizeof(mipmap_level), &mipmap_level, NULL);
643     test_error(error, "clGetGLTextureInfo for CL_GL_MIPMAP_LEVEL failed");
644 
645     if (mipmap_level != expected_cl_gl_mipmap_level)
646     {
647         log_error("clGetGLTextureInfo did not return expected mipmap level: "
648                   "expected %d, got %d.\n",
649                   expected_cl_gl_mipmap_level, mipmap_level);
650         return -1;
651     }
652 
653     return 0;
654 }
655 
CheckGLIntegerExtensionSupport()656 bool CheckGLIntegerExtensionSupport()
657 {
658     // Get the OpenGL version and supported extensions
659     const GLubyte *glVersion = glGetString(GL_VERSION);
660     const GLubyte *glExtensionList = glGetString(GL_EXTENSIONS);
661 
662     // Check if the OpenGL vrsion is 3.0 or grater or GL_EXT_texture_integer is
663     // supported
664     return (
665         ((glVersion[0] - '0') >= 3)
666         || (strstr((const char *)glExtensionList, "GL_EXT_texture_integer")));
667 }
668 
is_rgb_101010_supported(cl_context context,GLenum gl_target)669 int is_rgb_101010_supported(cl_context context, GLenum gl_target)
670 {
671     cl_image_format formatList[128];
672     cl_uint formatCount = 0;
673     unsigned int i;
674     int error;
675 
676     cl_mem_object_type image_type;
677 
678     switch (get_base_gl_target(gl_target))
679     {
680         case GL_TEXTURE_1D: image_type = CL_MEM_OBJECT_IMAGE1D;
681         case GL_TEXTURE_BUFFER:
682             image_type = CL_MEM_OBJECT_IMAGE1D_BUFFER;
683             break;
684         case GL_TEXTURE_RECTANGLE_EXT:
685         case GL_TEXTURE_2D:
686         case GL_COLOR_ATTACHMENT0:
687         case GL_RENDERBUFFER:
688         case GL_TEXTURE_CUBE_MAP:
689         case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
690         case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
691         case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
692         case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
693         case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
694         case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
695             image_type = CL_MEM_OBJECT_IMAGE2D;
696             break;
697         case GL_TEXTURE_3D: image_type = CL_MEM_OBJECT_IMAGE3D;
698         case GL_TEXTURE_1D_ARRAY: image_type = CL_MEM_OBJECT_IMAGE1D_ARRAY;
699         case GL_TEXTURE_2D_ARRAY:
700             image_type = CL_MEM_OBJECT_IMAGE2D_ARRAY;
701             break;
702         default: image_type = CL_MEM_OBJECT_IMAGE2D;
703     }
704 
705     if ((error =
706              clGetSupportedImageFormats(context, CL_MEM_READ_WRITE, image_type,
707                                         128, formatList, &formatCount)))
708     {
709         return error;
710     }
711 
712     // Check if the RGB 101010 format is supported
713     for (i = 0; i < formatCount; i++)
714     {
715         if (formatList[i].image_channel_data_type == CL_UNORM_INT_101010)
716         {
717             return 1;
718         }
719     }
720 
721     return 0;
722 }
723