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