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