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