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