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 "harness/compat.h"
17
18 #include <stdio.h>
19 #include <stdlib.h>
20 #include <string.h>
21 #include <sys/types.h>
22 #include <sys/stat.h>
23
24
25 #include "procs.h"
26
27 static unsigned char *
generate_rgba8_image(int w,int h,int d,MTdata mtData)28 generate_rgba8_image(int w, int h, int d, MTdata mtData)
29 {
30 unsigned char *ptr = (unsigned char*)malloc(w * h * d *4);
31 int i;
32
33 for (i=0; i<w*h*d*4; i++)
34 ptr[i] = (unsigned char)genrand_int32(mtData);
35
36 return ptr;
37 }
38
39 static void
update_rgba8_image(unsigned char * p,int x,int y,int z,int w,int h,int d,int img_width,int img_height,int img_depth,MTdata mtData)40 update_rgba8_image(unsigned char *p, int x, int y, int z, int w, int h, int d, int img_width, int img_height, int img_depth, MTdata mtData)
41 {
42 int i, j, k, indx;
43 int img_slice = img_width * img_height;
44
45 for (k=z; k<z+d; k++)
46 for (j=y; j<y+h; j++)
47 {
48 indx = (k * img_slice + j * img_width + x) * 4;
49 for (i=x; i<x+w; i++,indx+=4)
50 {
51 p[indx+0] = (unsigned char)genrand_int32(mtData);
52 p[indx+1] = (unsigned char)genrand_int32(mtData);
53 p[indx+2] = (unsigned char)genrand_int32(mtData);
54 p[indx+3] = (unsigned char)genrand_int32(mtData);
55 }
56 }
57 }
58
59 static void
update_image_from_image(void * out,void * in,int x,int y,int z,int w,int h,int d,int img_width,int img_height,int img_depth,int elem_size)60 update_image_from_image(void *out, void *in, int x, int y, int z, int w, int h, int d, int img_width, int img_height, int img_depth, int elem_size)
61 {
62 int i, j, k, elem, out_indx, in_indx;
63 int img_slice = img_width * img_height;
64 in_indx = 0;
65
66 for (k=z; k<z+d; k++)
67 for (j=y; j<y+h; j++)
68 {
69 out_indx = (k * img_slice + j * img_width + x) * elem_size;
70 for (i=x; i<x+w; i++,out_indx+=elem_size)
71 {
72 for (elem=0; elem<elem_size; elem++)
73 {
74 ((char*)out)[out_indx + elem] = ((char*)in)[in_indx];
75 in_indx++;
76 }
77 }
78 }
79 }
80
81 static int
verify_rgba8_image(unsigned char * image,unsigned char * outptr,int w,int h,int d)82 verify_rgba8_image(unsigned char *image, unsigned char *outptr, int w, int h, int d)
83 {
84 int i;
85
86 for (i=0; i<w*h*d*4; i++)
87 {
88 if (outptr[i] != image[i])
89 {
90 log_error("i = %d. Expected (%d %d %d %d), got (%d %d %d %d)\n", i, image[i], image[i+1], image[i+2], image[i+3], outptr[i], outptr[i+1], outptr[i+2], outptr[i+3]);
91 return -1;
92 }
93 }
94
95 return 0;
96 }
97
98
99 static unsigned short *
generate_rgba16_image(int w,int h,int d,MTdata mtData)100 generate_rgba16_image(int w, int h, int d, MTdata mtData)
101 {
102 unsigned short *ptr = (unsigned short*)malloc(w * h * d * 4 * sizeof(unsigned short));
103 int i;
104
105 for (i=0; i<w*h*d*4; i++)
106 ptr[i] = (unsigned short)genrand_int32(mtData);
107
108 return ptr;
109 }
110
111 static void
update_rgba16_image(unsigned short * p,int x,int y,int z,int w,int h,int d,int img_width,int img_height,int img_depth,MTdata mtData)112 update_rgba16_image(unsigned short *p, int x, int y, int z, int w, int h, int d, int img_width, int img_height, int img_depth, MTdata mtData)
113 {
114 int i, j, k, indx;
115 int img_slice = img_width * img_height;
116
117 for (k=z; k<z+d; k++)
118 for (j=y; j<y+h; j++)
119 {
120 indx = (k * img_slice + j * img_width + x) * 4;
121 for (i=x; i<x+w; i++,indx+=4)
122 {
123 p[indx+0] = (unsigned short)genrand_int32(mtData);
124 p[indx+1] = (unsigned short)genrand_int32(mtData);
125 p[indx+2] = (unsigned short)genrand_int32(mtData);
126 p[indx+3] = (unsigned short)genrand_int32(mtData);
127 }
128 }
129 }
130
131 static int
verify_rgba16_image(unsigned short * image,unsigned short * outptr,int w,int h,int d)132 verify_rgba16_image(unsigned short *image, unsigned short *outptr, int w, int h, int d)
133 {
134 int i;
135
136 for (i=0; i<w*h*d*4; i++)
137 {
138 if (outptr[i] != image[i])
139 {
140 log_error("i = %d. Expected (%d %d %d %d), got (%d %d %d %d)\n", i, image[i], image[i+1], image[i+2], image[i+3], outptr[i], outptr[i+1], outptr[i+2], outptr[i+3]);
141 return -1;
142 }
143 }
144
145 return 0;
146 }
147
148
149 static float *
generate_rgbafp_image(int w,int h,int d,MTdata mtData)150 generate_rgbafp_image(int w, int h, int d, MTdata mtData)
151 {
152 float *ptr = (float*)malloc(w * h * d *4 * sizeof(float));
153 int i;
154
155 for (i=0; i<w*h*d*4; i++)
156 ptr[i] = get_random_float(-0x40000000, 0x40000000, mtData);
157
158 return ptr;
159 }
160
161 static void
update_rgbafp_image(float * p,int x,int y,int z,int w,int h,int d,int img_width,int img_height,int img_depth,MTdata mtData)162 update_rgbafp_image(float *p, int x, int y, int z, int w, int h, int d, int img_width, int img_height, int img_depth, MTdata mtData)
163 {
164 int i, j, k, indx;
165 int img_slice = img_width * img_height;
166
167 for (k=z; k<z+d; k++)
168 for (j=y; j<y+h; j++)
169 {
170 indx = (k * img_slice + j * img_width + x) * 4;
171 for (i=x; i<x+w; i++,indx+=4)
172 {
173 p[indx+0] = get_random_float(-0x40000000, 0x40000000, mtData);
174 p[indx+1] = get_random_float(-0x40000000, 0x40000000, mtData);
175 p[indx+2] = get_random_float(-0x40000000, 0x40000000, mtData);
176 p[indx+3] = get_random_float(-0x40000000, 0x40000000, mtData);
177 }
178 }
179 }
180
181 static int
verify_rgbafp_image(float * image,float * outptr,int w,int h,int d)182 verify_rgbafp_image(float *image, float *outptr, int w, int h, int d)
183 {
184 int i;
185
186 for (i=0; i<w*h*d*4; i++)
187 {
188 if (outptr[i] != image[i])
189 {
190 log_error("i = %d. Expected (%f %f %f %f), got (%f %f %f %f)\n", i, image[i], image[i+1], image[i+2], image[i+3], outptr[i], outptr[i+1], outptr[i+2], outptr[i+3]);
191 return -1;
192 }
193 }
194
195 return 0;
196 }
197
198
199 int
test_imagereadwrite3d(cl_device_id device,cl_context context,cl_command_queue queue,int num_elements)200 test_imagereadwrite3d(cl_device_id device, cl_context context, cl_command_queue queue, int num_elements)
201 {
202 cl_image_format img_format;
203 unsigned char *rgba8_inptr, *rgba8_outptr;
204 unsigned short *rgba16_inptr, *rgba16_outptr;
205 float *rgbafp_inptr, *rgbafp_outptr;
206 clMemWrapper streams[3];
207 int img_width = 64;
208 int img_height = 64;
209 int img_depth = 32;
210 int img_slice = img_width * img_height;
211 int num_tries = 30;
212 int i, j, err;
213 MTdata mtData;
214
215 PASSIVE_REQUIRE_3D_IMAGE_SUPPORT( device )
216
217 mtData = init_genrand( gRandomSeed );
218 rgba8_inptr = (unsigned char *)generate_rgba8_image(img_width, img_height, img_depth, mtData);
219 rgba16_inptr = (unsigned short *)generate_rgba16_image(img_width, img_height, img_depth, mtData);
220 rgbafp_inptr = (float *)generate_rgbafp_image(img_width, img_height, img_depth, mtData);
221
222 rgba8_outptr = (unsigned char*)malloc(sizeof(unsigned char) * 4 * img_width * img_height * img_depth);
223 rgba16_outptr = (unsigned short*)malloc(sizeof(unsigned short) * 4 * img_width * img_height * img_depth);
224 rgbafp_outptr = (float*)malloc(sizeof(float) * 4 * img_width * img_height * img_depth);
225
226 img_format.image_channel_order = CL_RGBA;
227 img_format.image_channel_data_type = CL_UNORM_INT8;
228 streams[0] = create_image_3d(context, CL_MEM_READ_ONLY, &img_format, img_width, img_height, img_depth, 0, 0, NULL, &err);
229 test_error(err, "create_image_3d failed");
230
231 img_format.image_channel_order = CL_RGBA;
232 img_format.image_channel_data_type = CL_UNORM_INT16;
233 streams[1] = create_image_3d(context, CL_MEM_READ_ONLY, &img_format, img_width, img_height, img_depth, 0, 0, NULL, &err);
234 test_error(err, "create_image_3d failed");
235
236 img_format.image_channel_order = CL_RGBA;
237 img_format.image_channel_data_type = CL_FLOAT;
238 streams[2] = create_image_3d(context, CL_MEM_READ_ONLY, &img_format, img_width, img_height, img_depth, 0, 0, NULL, &err);
239 test_error(err, "create_image_3d failed");
240
241 for (i=0; i<3; i++)
242 {
243 void *p;
244
245 if (i == 0)
246 p = (void *)rgba8_inptr;
247 else if (i == 1)
248 p = (void *)rgba16_inptr;
249 else
250 p = (void *)rgbafp_inptr;
251
252 size_t origin[3] = {0,0,0}, region[3] = {img_width, img_height, img_depth};
253 err = clEnqueueWriteImage(queue, streams[i], CL_TRUE,
254 origin, region, 0, 0,
255 p,
256 0, NULL, NULL);
257 test_error(err, "clEnqueueWriteImage failed");
258 }
259
260 for (i=0,j=0; i<num_tries*3; i++,j++)
261 {
262 int x = (int)get_random_float(0, (float)img_width - 1, mtData);
263 int y = (int)get_random_float(0, (float)img_height - 1, mtData);
264 int z = (int)get_random_float(0, (float)img_depth - 1, mtData);
265 int w = (int)get_random_float(1, (float)(img_width - x), mtData);
266 int h = (int)get_random_float(1, (float)(img_height - y), mtData);
267 int d = (int)get_random_float(1, (float)(img_depth - z), mtData);
268 size_t input_pitch, input_slice_pitch;
269 int set_input_pitch = (int)(genrand_int32(mtData) & 0x01);
270 int packed_update = (int)(genrand_int32(mtData) & 0x01);
271 void *p, *outp;
272 int elem_size;
273
274 if (j == 3)
275 j = 0;
276
277 // packed: the source image for the write is a whole image .
278 // unpacked: the source image for the write is a subset within a larger image
279 switch (j)
280 {
281 case 0:
282 elem_size = 4;
283 if(packed_update)
284 {
285 p = generate_rgba8_image(w, h, d, mtData);
286 update_image_from_image(rgba8_inptr, p, x, y, z, w, h, d, img_width, img_height, img_depth, elem_size);
287 }
288 else
289 {
290 update_rgba8_image(rgba8_inptr, x, y, z, w, h, d, img_width, img_height, img_depth, mtData);
291 p = (void *)(rgba8_inptr + ((z * img_slice + y * img_width + x) * 4));
292 }
293 outp = (void *)rgba8_outptr;
294 break;
295 case 1:
296 elem_size = 2*4;
297 if(packed_update)
298 {
299 p = generate_rgba16_image(w, h, d, mtData);
300 update_image_from_image(rgba16_inptr, p, x, y, z, w, h, d, img_width, img_height, img_depth, elem_size);
301 }
302 else
303 {
304 update_rgba16_image(rgba16_inptr, x, y, z, w, h, d, img_width, img_height, img_depth, mtData);
305 p = (void *)(rgba16_inptr + ((z * img_slice + y * img_width + x) * 4));
306 }
307 outp = (void *)rgba16_outptr;
308 break;
309 case 2:
310 elem_size = 4*4;
311 if(packed_update)
312 {
313 p = generate_rgbafp_image(w, h, d, mtData);
314 update_image_from_image(rgbafp_inptr, p, x, y, z, w, h, d, img_width, img_height, img_depth, elem_size);
315 }
316 else
317 {
318 update_rgbafp_image(rgbafp_inptr, x, y, z, w, h, d, img_width, img_height, img_depth, mtData);
319 p = (void *)(rgbafp_inptr + ((z * img_slice + y * img_width + x) * 4));
320 }
321 outp = (void *)rgbafp_outptr;
322 break;
323 }
324
325 const char* update_packed_pitch_name = "";
326 if(packed_update)
327 {
328 if(set_input_pitch)
329 {
330 // for packed updates the pitch does not need to be calculated here (but can be)
331 update_packed_pitch_name = "'packed with pitch'";
332 input_pitch = w*elem_size;
333 input_slice_pitch = w*h*elem_size;
334 }
335 else
336 {
337 // for packed updates the pitch does not need to be calculated here
338 update_packed_pitch_name = "'packed without pitch'";
339 input_pitch = 0;
340 input_slice_pitch = 0;
341 }
342 }
343 else
344 {
345 // for unpacked updates the pitch is required
346 update_packed_pitch_name = "'unpacked with pitch'";
347 input_pitch = img_width*elem_size;
348 input_slice_pitch = input_pitch*img_height;
349 }
350
351 size_t origin[3] = {x,y,z}, region[3] = {w, h, d};
352 err = clEnqueueWriteImage(queue, streams[j], CL_TRUE,
353 origin, region, input_pitch, input_slice_pitch,
354 p, 0, NULL, NULL);
355 test_error(err, "clEnqueueWriteImage failed");
356
357 if(packed_update)
358 {
359 free(p);
360 p = NULL;
361 }
362
363 memset(outp, 0x7, img_width*img_height*img_depth*elem_size);
364
365 origin[0]=0; origin[1]=0; origin[2]=0; region[0]=img_width; region[1]=img_height; region[2]=img_depth;
366 err = clEnqueueReadImage(queue, streams[j], CL_TRUE,
367 origin, region, 0, 0,
368 outp, 0, NULL, NULL);
369 test_error(err, "clEnqueueReadImage failed");
370
371 switch (j)
372 {
373 case 0:
374 err = verify_rgba8_image(rgba8_inptr, rgba8_outptr, img_width, img_height, img_depth);
375 if (err)
376 {
377 log_error("x=%d y=%d z=%d w=%d h=%d d=%d pitch=%d, slice_pitch=%d, try=%d\n", x, y, z, w, h, d, (int)input_pitch, (int)input_slice_pitch, (int)i);
378 log_error("IMAGE RGBA8 read, write %s test failed\n", update_packed_pitch_name);
379 }
380 break;
381 case 1:
382 err = verify_rgba16_image(rgba16_inptr, rgba16_outptr, img_width, img_height, img_depth);
383 if (err)
384 {
385 log_error("x=%d y=%d z=%d w=%d h=%d d=%d pitch=%d, slice_pitch=%d, try=%d\n", x, y, z, w, h, d, (int)input_pitch, (int)input_slice_pitch, (int)i);
386 log_error("IMAGE RGBA16 read, write %s test failed\n", update_packed_pitch_name);
387 }
388 break;
389 case 2:
390 err = verify_rgbafp_image(rgbafp_inptr, rgbafp_outptr, img_width, img_height, img_depth);
391 if (err)
392 {
393 log_error("x=%d y=%d z=%d w=%d h=%d d=%d pitch=%d, slice_pitch=%d, try=%d\n", x, y, z, w, h, d, (int)input_pitch, (int)input_slice_pitch, (int)i);
394 log_error("IMAGE RGBA FP read, write %s test failed\n", update_packed_pitch_name);
395 }
396 break;
397 }
398
399 if (err)
400 break;
401 }
402
403 free_mtdata(mtData);
404 free(rgba8_inptr);
405 free(rgba16_inptr);
406 free(rgbafp_inptr);
407 free(rgba8_outptr);
408 free(rgba16_outptr);
409 free(rgbafp_outptr);
410
411 if (!err)
412 log_info("IMAGE read, write test passed\n");
413
414 return err;
415 }
416
417
418
419