xref: /aosp_15_r20/external/OpenCL-CTS/test_common/harness/imageHelpers.h (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 #ifndef _imageHelpers_h
17 #define _imageHelpers_h
18 
19 #include "compat.h"
20 
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <string.h>
24 #include <sys/types.h>
25 #include <sys/stat.h>
26 #include <vector>
27 
28 #if !defined(_WIN32)
29 #include <unistd.h>
30 #endif
31 
32 #include <time.h>
33 
34 #include "errorHelpers.h"
35 
36 #include "conversions.h"
37 #include "typeWrappers.h"
38 #include "kernelHelpers.h"
39 #include "errorHelpers.h"
40 #include "mt19937.h"
41 #include "rounding_mode.h"
42 #include "clImageHelper.h"
43 
44 #include <CL/cl_half.h>
45 
46 extern cl_device_type gDeviceType;
47 extern bool gTestRounding;
48 
49 // Number of iterations per image format to test if not testing max images,
50 // rounding, or small images
51 #define NUM_IMAGE_ITERATIONS 3
52 
53 
54 // Definition for our own sampler type, to mirror the cl_sampler internals
55 #define MAX_sRGB_TO_lRGB_CONVERSION_ERROR 0.5
56 #define MAX_lRGB_TO_sRGB_CONVERSION_ERROR 0.6
57 
58 // Definition for our own sampler type, to mirror the cl_sampler internals
59 typedef struct
60 {
61     cl_addressing_mode addressing_mode;
62     cl_filter_mode filter_mode;
63     bool normalized_coords;
64 } image_sampler_data;
65 
66 cl_int round_to_even(float v);
67 
68 #define NORMALIZE(v, max) (v < 0 ? 0 : (v > 1.f ? max : round_to_even(v * max)))
69 #define NORMALIZE_UNROUNDED(v, max) (v < 0 ? 0 : (v > 1.f ? max : v * max))
70 #define NORMALIZE_SIGNED(v, min, max)                                          \
71     (v < -1.0f ? min : (v > 1.f ? max : round_to_even(v * max)))
72 #define NORMALIZE_SIGNED_UNROUNDED(v, min, max)                                \
73     (v < -1.0f ? min : (v > 1.f ? max : v * max))
74 #define CONVERT_INT(v, min, max, max_val)                                      \
75     (v < min ? min : (v > max ? max_val : round_to_even(v)))
76 #define CONVERT_UINT(v, max, max_val)                                          \
77     (v < 0 ? 0 : (v > max ? max_val : round_to_even(v)))
78 
79 extern void print_read_header(const cl_image_format *format,
80                               image_sampler_data *sampler, bool err = false,
81                               int t = 0);
82 extern void print_write_header(const cl_image_format *format, bool err);
83 extern void print_header(const cl_image_format *format, bool err);
84 extern bool find_format(cl_image_format *formatList, unsigned int numFormats,
85                         cl_image_format *formatToFind);
86 extern bool is_image_format_required(cl_image_format format, cl_mem_flags flags,
87                                      cl_mem_object_type image_type,
88                                      cl_device_id device);
89 extern void
90 build_required_image_formats(cl_mem_flags flags, cl_mem_object_type image_type,
91                              cl_device_id device,
92                              std::vector<cl_image_format> &formatsToSupport);
93 
94 extern uint32_t get_format_type_size(const cl_image_format *format);
95 extern uint32_t get_channel_data_type_size(cl_channel_type channelType);
96 extern uint32_t get_format_channel_count(const cl_image_format *format);
97 extern uint32_t get_channel_order_channel_count(cl_channel_order order);
98 cl_channel_type get_channel_type_from_name(const char *name);
99 cl_channel_order get_channel_order_from_name(const char *name);
100 extern int is_format_signed(const cl_image_format *format);
101 extern uint32_t get_pixel_size(const cl_image_format *format);
102 
103 /* Helper to get any ol image format as long as it is 8-bits-per-channel */
104 extern int get_8_bit_image_format(cl_context context,
105                                   cl_mem_object_type objType,
106                                   cl_mem_flags flags, size_t channelCount,
107                                   cl_image_format *outFormat);
108 
109 /* Helper to get any ol image format as long as it is 32-bits-per-channel */
110 extern int get_32_bit_image_format(cl_context context,
111                                    cl_mem_object_type objType,
112                                    cl_mem_flags flags, size_t channelCount,
113                                    cl_image_format *outFormat);
114 
115 int random_in_range(int minV, int maxV, MTdata d);
116 int random_log_in_range(int minV, int maxV, MTdata d);
117 
118 typedef struct
119 {
120     size_t width;
121     size_t height;
122     size_t depth;
123     size_t rowPitch;
124     size_t slicePitch;
125     size_t arraySize;
126     const cl_image_format *format;
127     cl_mem buffer;
128     cl_mem_object_type type;
129     cl_uint num_mip_levels;
130 } image_descriptor;
131 
132 typedef struct
133 {
134     float p[4];
135 } FloatPixel;
136 
137 void print_first_pixel_difference_error(size_t where, const char *sourcePixel,
138                                         const char *destPixel,
139                                         image_descriptor *imageInfo, size_t y,
140                                         size_t thirdDim);
141 
142 size_t compare_scanlines(const image_descriptor *imageInfo, const char *aPtr,
143                          const char *bPtr);
144 
145 void get_max_sizes(size_t *numberOfSizes, const int maxNumberOfSizes,
146                    size_t sizes[][3], size_t maxWidth, size_t maxHeight,
147                    size_t maxDepth, size_t maxArraySize,
148                    const cl_ulong maxIndividualAllocSize,
149                    const cl_ulong maxTotalAllocSize,
150                    cl_mem_object_type image_type, const cl_image_format *format,
151                    int usingMaxPixelSize = 0);
152 extern size_t get_format_max_int(const cl_image_format *format);
153 
154 extern cl_ulong get_image_size(image_descriptor const *imageInfo);
155 extern cl_ulong get_image_size_mb(image_descriptor const *imageInfo);
156 
157 extern char *generate_random_image_data(image_descriptor *imageInfo,
158                                         BufferOwningPtr<char> &Owner, MTdata d);
159 
160 extern int debug_find_vector_in_image(void *imagePtr,
161                                       image_descriptor *imageInfo,
162                                       void *vectorToFind, size_t vectorSize,
163                                       int *outX, int *outY, int *outZ,
164                                       size_t lod = 0);
165 
166 extern int debug_find_pixel_in_image(void *imagePtr,
167                                      image_descriptor *imageInfo,
168                                      unsigned int *valuesToFind, int *outX,
169                                      int *outY, int *outZ, int lod = 0);
170 extern int debug_find_pixel_in_image(void *imagePtr,
171                                      image_descriptor *imageInfo,
172                                      int *valuesToFind, int *outX, int *outY,
173                                      int *outZ, int lod = 0);
174 extern int debug_find_pixel_in_image(void *imagePtr,
175                                      image_descriptor *imageInfo,
176                                      float *valuesToFind, int *outX, int *outY,
177                                      int *outZ, int lod = 0);
178 
179 extern void copy_image_data(image_descriptor *srcImageInfo,
180                             image_descriptor *dstImageInfo, void *imageValues,
181                             void *destImageValues, const size_t sourcePos[],
182                             const size_t destPos[], const size_t regionSize[]);
183 
184 int has_alpha(const cl_image_format *format);
185 
186 extern bool is_sRGBA_order(cl_channel_order image_channel_order);
187 
188 inline float calculate_array_index(float coord, float extent);
189 
190 cl_uint compute_max_mip_levels(size_t width, size_t height, size_t depth);
191 cl_ulong compute_mipmapped_image_size(image_descriptor imageInfo);
192 size_t compute_mip_level_offset(image_descriptor *imageInfo, size_t lod);
193 
194 template <class T>
read_image_pixel(void * imageData,image_descriptor * imageInfo,int x,int y,int z,T * outData,int lod)195 void read_image_pixel(void *imageData, image_descriptor *imageInfo, int x,
196                       int y, int z, T *outData, int lod)
197 {
198     size_t width_lod = imageInfo->width, height_lod = imageInfo->height,
199            depth_lod = imageInfo->depth,
200            slice_pitch_lod = 0 /*imageInfo->slicePitch*/,
201            row_pitch_lod = 0 /*imageInfo->rowPitch*/;
202     width_lod = (imageInfo->width >> lod) ? (imageInfo->width >> lod) : 1;
203 
204     if (imageInfo->type != CL_MEM_OBJECT_IMAGE1D_ARRAY
205         && imageInfo->type != CL_MEM_OBJECT_IMAGE1D)
206         height_lod =
207             (imageInfo->height >> lod) ? (imageInfo->height >> lod) : 1;
208 
209     if (imageInfo->type == CL_MEM_OBJECT_IMAGE3D)
210         depth_lod = (imageInfo->depth >> lod) ? (imageInfo->depth >> lod) : 1;
211     row_pitch_lod = (imageInfo->num_mip_levels > 0)
212         ? (width_lod * get_pixel_size(imageInfo->format))
213         : imageInfo->rowPitch;
214     slice_pitch_lod = (imageInfo->num_mip_levels > 0)
215         ? (row_pitch_lod * height_lod)
216         : imageInfo->slicePitch;
217 
218     // correct depth_lod and height_lod for array image types in order to avoid
219     // return
220     if (imageInfo->type == CL_MEM_OBJECT_IMAGE1D_ARRAY && height_lod == 1
221         && depth_lod == 1)
222     {
223         depth_lod = 0;
224         height_lod = 0;
225     }
226 
227     if (imageInfo->type == CL_MEM_OBJECT_IMAGE2D_ARRAY && depth_lod == 1)
228     {
229         depth_lod = 0;
230     }
231 
232     if (x < 0 || x >= (int)width_lod
233         || (height_lod != 0 && (y < 0 || y >= (int)height_lod))
234         || (depth_lod != 0 && (z < 0 || z >= (int)depth_lod))
235         || (imageInfo->arraySize != 0
236             && (z < 0 || z >= (int)imageInfo->arraySize)))
237     {
238         // Border color
239         if (imageInfo->format->image_channel_order == CL_DEPTH)
240         {
241             outData[0] = 1;
242         }
243         else
244         {
245             outData[0] = outData[1] = outData[2] = outData[3] = 0;
246             if (!has_alpha(imageInfo->format)) outData[3] = 1;
247         }
248         return;
249     }
250 
251     const cl_image_format *format = imageInfo->format;
252 
253     unsigned int i;
254     T tempData[4];
255 
256     // Advance to the right spot
257     char *ptr = (char *)imageData;
258     size_t pixelSize = get_pixel_size(format);
259 
260     ptr += z * slice_pitch_lod + y * row_pitch_lod + x * pixelSize;
261 
262     // OpenCL only supports reading floats from certain formats
263     switch (format->image_channel_data_type)
264     {
265         case CL_SNORM_INT8: {
266             cl_char *dPtr = (cl_char *)ptr;
267             for (i = 0; i < get_format_channel_count(format); i++)
268                 tempData[i] = (T)dPtr[i];
269             break;
270         }
271 
272         case CL_UNORM_INT8: {
273             cl_uchar *dPtr = (cl_uchar *)ptr;
274             for (i = 0; i < get_format_channel_count(format); i++)
275                 tempData[i] = (T)dPtr[i];
276             break;
277         }
278 
279         case CL_SIGNED_INT8: {
280             cl_char *dPtr = (cl_char *)ptr;
281             for (i = 0; i < get_format_channel_count(format); i++)
282                 tempData[i] = (T)dPtr[i];
283             break;
284         }
285 
286         case CL_UNSIGNED_INT8: {
287             cl_uchar *dPtr = (cl_uchar *)ptr;
288             for (i = 0; i < get_format_channel_count(format); i++)
289                 tempData[i] = (T)dPtr[i];
290             break;
291         }
292 
293         case CL_SNORM_INT16: {
294             cl_short *dPtr = (cl_short *)ptr;
295             for (i = 0; i < get_format_channel_count(format); i++)
296                 tempData[i] = (T)dPtr[i];
297             break;
298         }
299 
300         case CL_UNORM_INT16: {
301             cl_ushort *dPtr = (cl_ushort *)ptr;
302             for (i = 0; i < get_format_channel_count(format); i++)
303                 tempData[i] = (T)dPtr[i];
304             break;
305         }
306 
307         case CL_SIGNED_INT16: {
308             cl_short *dPtr = (cl_short *)ptr;
309             for (i = 0; i < get_format_channel_count(format); i++)
310                 tempData[i] = (T)dPtr[i];
311             break;
312         }
313 
314         case CL_UNSIGNED_INT16: {
315             cl_ushort *dPtr = (cl_ushort *)ptr;
316             for (i = 0; i < get_format_channel_count(format); i++)
317                 tempData[i] = (T)dPtr[i];
318             break;
319         }
320 
321         case CL_HALF_FLOAT: {
322             cl_half *dPtr = (cl_half *)ptr;
323             for (i = 0; i < get_format_channel_count(format); i++)
324                 tempData[i] = (T)cl_half_to_float(dPtr[i]);
325             break;
326         }
327 
328         case CL_SIGNED_INT32: {
329             cl_int *dPtr = (cl_int *)ptr;
330             for (i = 0; i < get_format_channel_count(format); i++)
331                 tempData[i] = (T)dPtr[i];
332             break;
333         }
334 
335         case CL_UNSIGNED_INT32: {
336             cl_uint *dPtr = (cl_uint *)ptr;
337             for (i = 0; i < get_format_channel_count(format); i++)
338                 tempData[i] = (T)dPtr[i];
339             break;
340         }
341 
342         case CL_UNORM_SHORT_565: {
343             cl_ushort *dPtr = (cl_ushort *)ptr;
344             tempData[0] = (T)(dPtr[0] >> 11);
345             tempData[1] = (T)((dPtr[0] >> 5) & 63);
346             tempData[2] = (T)(dPtr[0] & 31);
347             break;
348         }
349 
350 #ifdef OBSOLETE_FORMAT
351         case CL_UNORM_SHORT_565_REV: {
352             unsigned short *dPtr = (unsigned short *)ptr;
353             tempData[2] = (T)(dPtr[0] >> 11);
354             tempData[1] = (T)((dPtr[0] >> 5) & 63);
355             tempData[0] = (T)(dPtr[0] & 31);
356             break;
357         }
358 
359         case CL_UNORM_SHORT_555_REV: {
360             unsigned short *dPtr = (unsigned short *)ptr;
361             tempData[2] = (T)((dPtr[0] >> 10) & 31);
362             tempData[1] = (T)((dPtr[0] >> 5) & 31);
363             tempData[0] = (T)(dPtr[0] & 31);
364             break;
365         }
366 
367         case CL_UNORM_INT_8888: {
368             unsigned int *dPtr = (unsigned int *)ptr;
369             tempData[3] = (T)(dPtr[0] >> 24);
370             tempData[2] = (T)((dPtr[0] >> 16) & 0xff);
371             tempData[1] = (T)((dPtr[0] >> 8) & 0xff);
372             tempData[0] = (T)(dPtr[0] & 0xff);
373             break;
374         }
375         case CL_UNORM_INT_8888_REV: {
376             unsigned int *dPtr = (unsigned int *)ptr;
377             tempData[0] = (T)(dPtr[0] >> 24);
378             tempData[1] = (T)((dPtr[0] >> 16) & 0xff);
379             tempData[2] = (T)((dPtr[0] >> 8) & 0xff);
380             tempData[3] = (T)(dPtr[0] & 0xff);
381             break;
382         }
383 
384         case CL_UNORM_INT_101010_REV: {
385             unsigned int *dPtr = (unsigned int *)ptr;
386             tempData[2] = (T)((dPtr[0] >> 20) & 0x3ff);
387             tempData[1] = (T)((dPtr[0] >> 10) & 0x3ff);
388             tempData[0] = (T)(dPtr[0] & 0x3ff);
389             break;
390         }
391 #endif
392         case CL_UNORM_SHORT_555: {
393             cl_ushort *dPtr = (cl_ushort *)ptr;
394             tempData[0] = (T)((dPtr[0] >> 10) & 31);
395             tempData[1] = (T)((dPtr[0] >> 5) & 31);
396             tempData[2] = (T)(dPtr[0] & 31);
397             break;
398         }
399 
400         case CL_UNORM_INT_101010: {
401             cl_uint *dPtr = (cl_uint *)ptr;
402             tempData[0] = (T)((dPtr[0] >> 20) & 0x3ff);
403             tempData[1] = (T)((dPtr[0] >> 10) & 0x3ff);
404             tempData[2] = (T)(dPtr[0] & 0x3ff);
405             break;
406         }
407 
408         case CL_FLOAT: {
409             cl_float *dPtr = (cl_float *)ptr;
410             for (i = 0; i < get_format_channel_count(format); i++)
411                 tempData[i] = (T)dPtr[i];
412             break;
413         }
414 #ifdef CL_SFIXED14_APPLE
415         case CL_SFIXED14_APPLE: {
416             cl_float *dPtr = (cl_float *)ptr;
417             for (i = 0; i < get_format_channel_count(format); i++)
418                 tempData[i] = (T)dPtr[i] + 0x4000;
419             break;
420         }
421 #endif
422     }
423 
424 
425     outData[0] = outData[1] = outData[2] = 0;
426     outData[3] = 1;
427 
428     if (format->image_channel_order == CL_A)
429     {
430         outData[3] = tempData[0];
431     }
432     else if (format->image_channel_order == CL_R)
433     {
434         outData[0] = tempData[0];
435     }
436     else if (format->image_channel_order == CL_Rx)
437     {
438         outData[0] = tempData[0];
439     }
440     else if (format->image_channel_order == CL_RA)
441     {
442         outData[0] = tempData[0];
443         outData[3] = tempData[1];
444     }
445     else if (format->image_channel_order == CL_RG)
446     {
447         outData[0] = tempData[0];
448         outData[1] = tempData[1];
449     }
450     else if (format->image_channel_order == CL_RGx)
451     {
452         outData[0] = tempData[0];
453         outData[1] = tempData[1];
454     }
455     else if ((format->image_channel_order == CL_RGB)
456              || (format->image_channel_order == CL_sRGB))
457     {
458         outData[0] = tempData[0];
459         outData[1] = tempData[1];
460         outData[2] = tempData[2];
461     }
462     else if ((format->image_channel_order == CL_RGBx)
463              || (format->image_channel_order == CL_sRGBx))
464     {
465         outData[0] = tempData[0];
466         outData[1] = tempData[1];
467         outData[2] = tempData[2];
468         outData[3] = 0;
469     }
470     else if ((format->image_channel_order == CL_RGBA)
471              || (format->image_channel_order == CL_sRGBA))
472     {
473         outData[0] = tempData[0];
474         outData[1] = tempData[1];
475         outData[2] = tempData[2];
476         outData[3] = tempData[3];
477     }
478     else if (format->image_channel_order == CL_ARGB)
479     {
480         outData[0] = tempData[1];
481         outData[1] = tempData[2];
482         outData[2] = tempData[3];
483         outData[3] = tempData[0];
484     }
485     else if (format->image_channel_order == CL_ABGR)
486     {
487         outData[0] = tempData[3];
488         outData[1] = tempData[2];
489         outData[2] = tempData[1];
490         outData[3] = tempData[0];
491     }
492     else if ((format->image_channel_order == CL_BGRA)
493              || (format->image_channel_order == CL_sBGRA))
494     {
495         outData[0] = tempData[2];
496         outData[1] = tempData[1];
497         outData[2] = tempData[0];
498         outData[3] = tempData[3];
499     }
500     else if (format->image_channel_order == CL_INTENSITY)
501     {
502         outData[0] = tempData[0];
503         outData[1] = tempData[0];
504         outData[2] = tempData[0];
505         outData[3] = tempData[0];
506     }
507     else if (format->image_channel_order == CL_LUMINANCE)
508     {
509         outData[0] = tempData[0];
510         outData[1] = tempData[0];
511         outData[2] = tempData[0];
512     }
513     else if (format->image_channel_order == CL_DEPTH)
514     {
515         outData[0] = tempData[0];
516     }
517 #ifdef CL_1RGB_APPLE
518     else if (format->image_channel_order == CL_1RGB_APPLE)
519     {
520         outData[0] = tempData[1];
521         outData[1] = tempData[2];
522         outData[2] = tempData[3];
523         outData[3] = 0xff;
524     }
525 #endif
526 #ifdef CL_BGR1_APPLE
527     else if (format->image_channel_order == CL_BGR1_APPLE)
528     {
529         outData[0] = tempData[2];
530         outData[1] = tempData[1];
531         outData[2] = tempData[0];
532         outData[3] = 0xff;
533     }
534 #endif
535     else
536     {
537         log_error("Invalid format:");
538         print_header(format, true);
539     }
540 }
541 
542 template <class T>
read_image_pixel(void * imageData,image_descriptor * imageInfo,int x,int y,int z,T * outData)543 void read_image_pixel(void *imageData, image_descriptor *imageInfo, int x,
544                       int y, int z, T *outData)
545 {
546     read_image_pixel<T>(imageData, imageInfo, x, y, z, outData, 0);
547 }
548 
549 // Stupid template rules
550 bool get_integer_coords(float x, float y, float z, size_t width, size_t height,
551                         size_t depth, image_sampler_data *imageSampler,
552                         image_descriptor *imageInfo, int &outX, int &outY,
553                         int &outZ);
554 bool get_integer_coords_offset(float x, float y, float z, float xAddressOffset,
555                                float yAddressOffset, float zAddressOffset,
556                                size_t width, size_t height, size_t depth,
557                                image_sampler_data *imageSampler,
558                                image_descriptor *imageInfo, int &outX,
559                                int &outY, int &outZ);
560 
561 
562 template <class T>
sample_image_pixel_offset(void * imageData,image_descriptor * imageInfo,float x,float y,float z,float xAddressOffset,float yAddressOffset,float zAddressOffset,image_sampler_data * imageSampler,T * outData,int lod)563 void sample_image_pixel_offset(void *imageData, image_descriptor *imageInfo,
564                                float x, float y, float z, float xAddressOffset,
565                                float yAddressOffset, float zAddressOffset,
566                                image_sampler_data *imageSampler, T *outData,
567                                int lod)
568 {
569     int iX = 0, iY = 0, iZ = 0;
570 
571     float max_w = imageInfo->width;
572     float max_h;
573     float max_d;
574 
575     switch (imageInfo->type)
576     {
577         case CL_MEM_OBJECT_IMAGE1D_ARRAY:
578             max_h = imageInfo->arraySize;
579             max_d = 0;
580             break;
581         case CL_MEM_OBJECT_IMAGE2D_ARRAY:
582             max_h = imageInfo->height;
583             max_d = imageInfo->arraySize;
584             break;
585         default:
586             max_h = imageInfo->height;
587             max_d = imageInfo->depth;
588             break;
589     }
590 
591     if (/*gTestMipmaps*/ imageInfo->num_mip_levels > 1)
592     {
593         switch (imageInfo->type)
594         {
595             case CL_MEM_OBJECT_IMAGE3D:
596                 max_d = (float)((imageInfo->depth >> lod)
597                                     ? (imageInfo->depth >> lod)
598                                     : 1);
599             case CL_MEM_OBJECT_IMAGE2D:
600             case CL_MEM_OBJECT_IMAGE2D_ARRAY:
601                 max_h = (float)((imageInfo->height >> lod)
602                                     ? (imageInfo->height >> lod)
603                                     : 1);
604                 break;
605             default:;
606         }
607         max_w =
608             (float)((imageInfo->width >> lod) ? (imageInfo->width >> lod) : 1);
609     }
610     get_integer_coords_offset(x, y, z, xAddressOffset, yAddressOffset,
611                               zAddressOffset, max_w, max_h, max_d, imageSampler,
612                               imageInfo, iX, iY, iZ);
613 
614     read_image_pixel<T>(imageData, imageInfo, iX, iY, iZ, outData, lod);
615 }
616 
617 template <class T>
sample_image_pixel_offset(void * imageData,image_descriptor * imageInfo,float x,float y,float z,float xAddressOffset,float yAddressOffset,float zAddressOffset,image_sampler_data * imageSampler,T * outData)618 void sample_image_pixel_offset(void *imageData, image_descriptor *imageInfo,
619                                float x, float y, float z, float xAddressOffset,
620                                float yAddressOffset, float zAddressOffset,
621                                image_sampler_data *imageSampler, T *outData)
622 {
623     sample_image_pixel_offset<T>(imageData, imageInfo, x, y, z, xAddressOffset,
624                                  yAddressOffset, zAddressOffset, imageSampler,
625                                  outData, 0);
626 }
627 
628 template <class T>
sample_image_pixel(void * imageData,image_descriptor * imageInfo,float x,float y,float z,image_sampler_data * imageSampler,T * outData)629 void sample_image_pixel(void *imageData, image_descriptor *imageInfo, float x,
630                         float y, float z, image_sampler_data *imageSampler,
631                         T *outData)
632 {
633     return sample_image_pixel_offset<T>(imageData, imageInfo, x, y, z, 0.0f,
634                                         0.0f, 0.0f, imageSampler, outData);
635 }
636 
637 FloatPixel
638 sample_image_pixel_float(void *imageData, image_descriptor *imageInfo, float x,
639                          float y, float z, image_sampler_data *imageSampler,
640                          float *outData, int verbose, int *containsDenorms);
641 
642 FloatPixel sample_image_pixel_float(void *imageData,
643                                     image_descriptor *imageInfo, float x,
644                                     float y, float z,
645                                     image_sampler_data *imageSampler,
646                                     float *outData, int verbose,
647                                     int *containsDenorms, int lod);
648 
649 FloatPixel sample_image_pixel_float_offset(
650     void *imageData, image_descriptor *imageInfo, float x, float y, float z,
651     float xAddressOffset, float yAddressOffset, float zAddressOffset,
652     image_sampler_data *imageSampler, float *outData, int verbose,
653     int *containsDenorms);
654 FloatPixel sample_image_pixel_float_offset(
655     void *imageData, image_descriptor *imageInfo, float x, float y, float z,
656     float xAddressOffset, float yAddressOffset, float zAddressOffset,
657     image_sampler_data *imageSampler, float *outData, int verbose,
658     int *containsDenorms, int lod);
659 
660 
661 extern void pack_image_pixel(unsigned int *srcVector,
662                              const cl_image_format *imageFormat, void *outData);
663 extern void pack_image_pixel(int *srcVector, const cl_image_format *imageFormat,
664                              void *outData);
665 extern void pack_image_pixel(float *srcVector,
666                              const cl_image_format *imageFormat, void *outData);
667 extern void pack_image_pixel_error(const float *srcVector,
668                                    const cl_image_format *imageFormat,
669                                    const void *results, float *errors);
670 
671 extern char *create_random_image_data(ExplicitType dataType,
672                                       image_descriptor *imageInfo,
673                                       BufferOwningPtr<char> &P, MTdata d,
674                                       bool image2DFromBuffer = false);
675 
676 // deprecated
677 // extern bool clamp_image_coord( image_sampler_data *imageSampler, float value,
678 // size_t max, int &outValue );
679 
680 extern void get_sampler_kernel_code(image_sampler_data *imageSampler,
681                                     char *outLine);
682 extern float get_max_absolute_error(const cl_image_format *format,
683                                     image_sampler_data *sampler);
684 extern float get_max_relative_error(const cl_image_format *format,
685                                     image_sampler_data *sampler, int is3D,
686                                     int isLinearFilter);
687 
688 
689 #define errMax(_x, _y) ((_x) != (_x) ? (_x) : (_x) > (_y) ? (_x) : (_y))
690 
abs_diff_uint(cl_uint x,cl_uint y)691 static inline cl_uint abs_diff_uint(cl_uint x, cl_uint y)
692 {
693     return y > x ? y - x : x - y;
694 }
695 
abs_diff_int(cl_int x,cl_int y)696 static inline cl_uint abs_diff_int(cl_int x, cl_int y)
697 {
698     return (cl_uint)(y > x ? y - x : x - y);
699 }
700 
relative_error(float test,float expected)701 static inline cl_float relative_error(float test, float expected)
702 {
703     // 0-0/0 is 0 in this case, not NaN
704     if (test == 0.0f && expected == 0.0f) return 0.0f;
705 
706     return (test - expected) / expected;
707 }
708 
709 extern float random_float(float low, float high);
710 
711 class CoordWalker {
712 public:
713     CoordWalker(void *coords, bool useFloats, size_t vecSize);
714     ~CoordWalker();
715 
716     cl_float Get(size_t idx, size_t el);
717 
718 protected:
719     cl_float *mFloatCoords;
720     cl_int *mIntCoords;
721     size_t mVecSize;
722 };
723 
724 extern cl_half convert_float_to_half(float f);
725 extern int DetectFloatToHalfRoundingMode(
726     cl_command_queue); // Returns CL_SUCCESS on success
727 
728 // sign bit: don't care, exponent: maximum value, significand: non-zero
is_half_nan(cl_half half)729 static int inline is_half_nan(cl_half half) { return (half & 0x7fff) > 0x7c00; }
730 
731 // sign bit: don't care, exponent: zero, significand: non-zero
is_half_denorm(cl_half half)732 static int inline is_half_denorm(cl_half half) { return IsHalfSubnormal(half); }
733 
734 // sign bit: don't care, exponent: zero, significand: zero
is_half_zero(cl_half half)735 static int inline is_half_zero(cl_half half) { return (half & 0x7fff) == 0; }
736 
737 extern double sRGBmap(float fc);
738 
739 extern const char *convert_image_type_to_string(cl_mem_object_type imageType);
740 
741 
742 #endif // _imageHelpers_h
743