xref: /aosp_15_r20/external/OpenCL-CTS/test_conformance/basic/test_imagereadwrite3d.cpp (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 #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