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