xref: /aosp_15_r20/external/OpenCL-CTS/test_conformance/basic/test_readimage.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 #include "harness/imageHelpers.h"
18 
19 #include <stdio.h>
20 #include <stdlib.h>
21 #include <string.h>
22 #include <sys/types.h>
23 #include <sys/stat.h>
24 
25 #include <algorithm>
26 #include <string>
27 #include <vector>
28 
29 #include "procs.h"
30 
31 #define TEST_IMAGE_WIDTH_2D (512)
32 #define TEST_IMAGE_HEIGHT_2D (512)
33 
34 #define TEST_IMAGE_WIDTH_3D (64)
35 #define TEST_IMAGE_HEIGHT_3D (64)
36 #define TEST_IMAGE_DEPTH_3D (64)
37 
38 #define TEST_IMAGE_WIDTH(TYPE)                                                 \
39     ((CL_MEM_OBJECT_IMAGE2D == TYPE) ? TEST_IMAGE_WIDTH_2D                     \
40                                      : TEST_IMAGE_WIDTH_3D)
41 #define TEST_IMAGE_HEIGHT(TYPE)                                                \
42     ((CL_MEM_OBJECT_IMAGE2D == TYPE) ? TEST_IMAGE_HEIGHT_2D                    \
43                                      : TEST_IMAGE_HEIGHT_3D)
44 #define TEST_IMAGE_DEPTH(TYPE)                                                 \
45     ((CL_MEM_OBJECT_IMAGE2D == TYPE) ? 1 : TEST_IMAGE_DEPTH_3D)
46 
47 namespace {
48 const char *kernel_source_2d = R"(
49 __kernel void test_CL_BGRACL_UNORM_INT8(read_only image2d_t srcimg, __global uchar4 *dst, sampler_t sampler)
50 {
51     int    tid_x = get_global_id(0);
52     int    tid_y = get_global_id(1);
53     int    indx = tid_y * get_image_width(srcimg) + tid_x;
54     float4 color;
55 
56     color = read_imagef(srcimg, sampler, (int2)(tid_x, tid_y)) * 255.0f;
57     dst[indx] = convert_uchar4_rte(color.zyxw);
58 }
59 
60 __kernel void test_CL_RGBACL_UNORM_INT8(read_only image2d_t srcimg, __global uchar4 *dst, sampler_t sampler)
61 {
62     int    tid_x = get_global_id(0);
63     int    tid_y = get_global_id(1);
64     int    indx = tid_y * get_image_width(srcimg) + tid_x;
65     float4 color;
66 
67     color = read_imagef(srcimg, sampler, (int2)(tid_x, tid_y)) * 255.0f;
68     dst[indx] = convert_uchar4_rte(color);
69 }
70 
71 __kernel void test_CL_RGBACL_UNORM_INT16(read_only image2d_t srcimg, __global ushort4 *dst, sampler_t smp)
72 {
73     int    tid_x = get_global_id(0);
74     int    tid_y = get_global_id(1);
75     int    indx = tid_y * get_image_width(srcimg) + tid_x;
76     float4 color;
77 
78     color = read_imagef(srcimg, smp, (int2)(tid_x, tid_y));
79     ushort4 dst_write;
80     dst_write.x = convert_ushort_rte(color.x * 65535.0f);
81     dst_write.y = convert_ushort_rte(color.y * 65535.0f);
82     dst_write.z = convert_ushort_rte(color.z * 65535.0f);
83     dst_write.w = convert_ushort_rte(color.w * 65535.0f);
84     dst[indx] = dst_write;
85 }
86 
87 __kernel void test_CL_RGBACL_FLOAT(read_only image2d_t srcimg, __global float4 *dst, sampler_t smp)
88 {
89     int    tid_x = get_global_id(0);
90     int    tid_y = get_global_id(1);
91     int    indx = tid_y * get_image_width(srcimg) + tid_x;
92     float4 color;
93 
94     color = read_imagef(srcimg, smp, (int2)(tid_x, tid_y));
95 
96     dst[indx].x = color.x;
97     dst[indx].y = color.y;
98     dst[indx].z = color.z;
99     dst[indx].w = color.w;
100 
101 }
102 )";
103 
104 static const char *kernel_source_3d = R"(
105 __kernel void test_CL_BGRACL_UNORM_INT8(read_only image3d_t srcimg, __global uchar4 *dst, sampler_t sampler)
106 {
107     int    tid_x = get_global_id(0);
108     int    tid_y = get_global_id(1);
109     int    tid_z = get_global_id(2);
110     int    indx = (tid_z * get_image_height(srcimg) + tid_y) * get_image_width(srcimg) + tid_x;
111     float4 color;
112 
113     color = read_imagef(srcimg, sampler, (int4)(tid_x, tid_y, tid_z, 0))* 255.0f;
114     dst[indx].x = color.z;
115     dst[indx].y = color.y;
116     dst[indx].z = color.x;
117     dst[indx].w = color.w;
118 
119 }
120 
121 __kernel void test_CL_RGBACL_UNORM_INT8(read_only image3d_t srcimg, __global uchar4 *dst, sampler_t sampler)
122 {
123     int    tid_x = get_global_id(0);
124     int    tid_y = get_global_id(1);
125     int    tid_z = get_global_id(2);
126     int    indx = (tid_z * get_image_height(srcimg) + tid_y) * get_image_width(srcimg) + tid_x;
127     float4 color;
128 
129     color = read_imagef(srcimg, sampler, (int4)(tid_x, tid_y, tid_z, 0))* 255.0f;
130 
131     dst[indx].x = color.x;
132     dst[indx].y = color.y;
133     dst[indx].z = color.z;
134     dst[indx].w = color.w;
135 
136 }
137 
138 __kernel void test_CL_RGBACL_UNORM_INT16(read_only image3d_t srcimg, __global ushort4 *dst, sampler_t sampler)
139 {
140     int    tid_x = get_global_id(0);
141     int    tid_y = get_global_id(1);
142     int    tid_z = get_global_id(2);
143     int    indx = (tid_z * get_image_height(srcimg) + tid_y) * get_image_width(srcimg) + tid_x;
144     float4 color;
145 
146     color = read_imagef(srcimg, sampler, (int4)(tid_x, tid_y, tid_z, 0));
147     ushort4 dst_write;
148     dst_write.x = convert_ushort_rte(color.x * 65535.0f);
149     dst_write.y = convert_ushort_rte(color.y * 65535.0f);
150     dst_write.z = convert_ushort_rte(color.z * 65535.0f);
151     dst_write.w = convert_ushort_rte(color.w * 65535.0f);
152     dst[indx] = dst_write;
153 
154 }
155 
156 __kernel void test_CL_RGBACL_FLOAT(read_only image3d_t srcimg, __global float *dst, sampler_t sampler)
157 {
158     int    tid_x = get_global_id(0);
159     int    tid_y = get_global_id(1);
160     int    tid_z = get_global_id(2);
161     int    indx = (tid_z * get_image_height(srcimg) + tid_y) * get_image_width(srcimg) + tid_x;
162     float4 color;
163 
164     color = read_imagef(srcimg, sampler, (int4)(tid_x, tid_y, tid_z, 0));
165     indx *= 4;
166     dst[indx+0] = color.x;
167     dst[indx+1] = color.y;
168     dst[indx+2] = color.z;
169     dst[indx+3] = color.w;
170 
171 }
172 )";
173 
generate_random_inputs(std::vector<T> & v)174 template <typename T> void generate_random_inputs(std::vector<T> &v)
175 {
176     RandomSeed seed(gRandomSeed);
177 
178     auto random_generator = [&seed]() {
179         return static_cast<T>(genrand_int32(seed));
180     };
181 
182     std::generate(v.begin(), v.end(), random_generator);
183 }
184 
generate_random_inputs(std::vector<float> & v)185 template <> void generate_random_inputs<float>(std::vector<float> &v)
186 {
187     RandomSeed seed(gRandomSeed);
188 
189     auto random_generator = [&seed]() {
190         return get_random_float(-0x40000000, 0x40000000, seed);
191     };
192 
193     std::generate(v.begin(), v.end(), random_generator);
194 }
195 
create_image_xd(cl_context context,cl_mem_flags flags,cl_mem_object_type type,const cl_image_format * fmt,size_t x,size_t y,size_t z,cl_int * err)196 cl_mem create_image_xd(cl_context context, cl_mem_flags flags,
197                        cl_mem_object_type type, const cl_image_format *fmt,
198                        size_t x, size_t y, size_t z, cl_int *err)
199 {
200 
201     return (CL_MEM_OBJECT_IMAGE2D == type)
202         ? create_image_2d(context, flags, fmt, x, y, 0, nullptr, err)
203         : create_image_3d(context, flags, fmt, x, y, z, 0, 0, nullptr, err);
204 }
205 
206 template <cl_mem_object_type IMG_TYPE, typename T>
test_readimage(cl_device_id device,cl_context context,cl_command_queue queue,const cl_image_format * img_format)207 int test_readimage(cl_device_id device, cl_context context,
208                    cl_command_queue queue, const cl_image_format *img_format)
209 {
210     clMemWrapper streams[2];
211     clProgramWrapper program;
212     clKernelWrapper kernel;
213     clSamplerWrapper sampler;
214 
215     std::string kernel_name("test_");
216 
217     size_t img_width = TEST_IMAGE_WIDTH(IMG_TYPE);
218     size_t img_height = TEST_IMAGE_HEIGHT(IMG_TYPE);
219     size_t img_depth = TEST_IMAGE_DEPTH(IMG_TYPE);
220 
221     int err;
222 
223     const size_t origin[3] = { 0, 0, 0 };
224     const size_t region[3] = { img_width, img_height, img_depth };
225 
226     const size_t num_elements = img_width * img_height * img_depth * 4;
227     const size_t length = num_elements * sizeof(T);
228 
229     PASSIVE_REQUIRE_IMAGE_SUPPORT(device)
230 
231     std::vector<T> input(num_elements);
232     std::vector<T> output(num_elements);
233 
234     generate_random_inputs(input);
235 
236     streams[0] =
237         create_image_xd(context, CL_MEM_READ_ONLY, IMG_TYPE, img_format,
238                         img_width, img_height, img_depth, &err);
239     test_error(err, "create_image failed.");
240 
241     streams[1] = clCreateBuffer(context, CL_MEM_READ_WRITE, length, NULL, &err);
242     test_error(err, "clCreateBuffer failed.");
243 
244     sampler = clCreateSampler(context, CL_FALSE, CL_ADDRESS_CLAMP_TO_EDGE,
245                               CL_FILTER_NEAREST, &err);
246     test_error(err, "clCreateSampler failed");
247 
248     err = clEnqueueWriteImage(queue, streams[0], CL_TRUE, origin, region, 0, 0,
249                               input.data(), 0, NULL, NULL);
250     test_error(err, "clEnqueueWriteImage failed.");
251 
252     kernel_name += GetChannelOrderName(img_format->image_channel_order);
253     kernel_name += GetChannelTypeName(img_format->image_channel_data_type);
254 
255     const char **kernel_source = (CL_MEM_OBJECT_IMAGE2D == IMG_TYPE)
256         ? &kernel_source_2d
257         : &kernel_source_3d;
258 
259     err = create_single_kernel_helper(context, &program, &kernel, 1,
260                                       kernel_source, kernel_name.c_str());
261     test_error(err, "create_single_kernel_helper failed.");
262 
263     err = clSetKernelArg(kernel, 0, sizeof(streams[0]), &streams[0]);
264     err |= clSetKernelArg(kernel, 1, sizeof(streams[1]), &streams[1]);
265     err |= clSetKernelArg(kernel, 2, sizeof(sampler), &sampler);
266     test_error(err, "clSetKernelArgs failed\n");
267 
268     err = clEnqueueNDRangeKernel(queue, kernel, 3, NULL, region, NULL, 0, NULL,
269                                  NULL);
270     test_error(err, "clEnqueueNDRangeKernel failed\n");
271 
272     err = clEnqueueReadBuffer(queue, streams[1], CL_TRUE, 0, length,
273                               output.data(), 0, NULL, NULL);
274     test_error(err, "clEnqueueReadBuffer failed\n");
275 
276     if (0 != memcmp(input.data(), output.data(), length))
277     {
278         log_error("READ_IMAGE_%s_%s test failed\n",
279                   GetChannelOrderName(img_format->image_channel_order),
280                   GetChannelTypeName(img_format->image_channel_data_type));
281         err = -1;
282     }
283     else
284     {
285         log_info("READ_IMAGE_%s_%s test passed\n",
286                  GetChannelOrderName(img_format->image_channel_order),
287                  GetChannelTypeName(img_format->image_channel_data_type));
288     }
289 
290     return err;
291 }
292 
check_format(cl_device_id device,cl_context context,cl_mem_object_type image_type,const cl_image_format img_format)293 bool check_format(cl_device_id device, cl_context context,
294                   cl_mem_object_type image_type,
295                   const cl_image_format img_format)
296 {
297     return is_image_format_required(img_format, CL_MEM_READ_ONLY, image_type,
298                                     device)
299         || is_image_format_supported(context, CL_MEM_READ_ONLY, image_type,
300                                      &img_format);
301 }
302 
303 }
test_readimage(cl_device_id device,cl_context context,cl_command_queue queue,int num_elements)304 int test_readimage(cl_device_id device, cl_context context,
305                    cl_command_queue queue, int num_elements)
306 {
307     const cl_image_format format[] = { { CL_RGBA, CL_UNORM_INT8 },
308                                        { CL_BGRA, CL_UNORM_INT8 } };
309 
310     int err = test_readimage<CL_MEM_OBJECT_IMAGE2D, cl_uchar>(
311         device, context, queue, &format[0]);
312 
313     if (check_format(device, context, CL_MEM_OBJECT_IMAGE2D, format[1]))
314     {
315         err |= test_readimage<CL_MEM_OBJECT_IMAGE2D, cl_uchar>(
316             device, context, queue, &format[1]);
317     }
318 
319     return err;
320 }
321 
test_readimage_int16(cl_device_id device,cl_context context,cl_command_queue queue,int num_elements)322 int test_readimage_int16(cl_device_id device, cl_context context,
323                          cl_command_queue queue, int num_elements)
324 {
325     const cl_image_format format = { CL_RGBA, CL_UNORM_INT16 };
326     return test_readimage<CL_MEM_OBJECT_IMAGE2D, cl_ushort>(device, context,
327                                                             queue, &format);
328 }
329 
test_readimage_fp32(cl_device_id device,cl_context context,cl_command_queue queue,int num_elements)330 int test_readimage_fp32(cl_device_id device, cl_context context,
331                         cl_command_queue queue, int num_elements)
332 {
333     const cl_image_format format = { CL_RGBA, CL_FLOAT };
334     return test_readimage<CL_MEM_OBJECT_IMAGE2D, cl_float>(device, context,
335                                                            queue, &format);
336 }
337 
test_readimage3d(cl_device_id device,cl_context context,cl_command_queue queue,int num_elements)338 int test_readimage3d(cl_device_id device, cl_context context,
339                      cl_command_queue queue, int num_elements)
340 {
341     const cl_image_format format[] = { { CL_RGBA, CL_UNORM_INT8 },
342                                        { CL_BGRA, CL_UNORM_INT8 } };
343 
344     PASSIVE_REQUIRE_3D_IMAGE_SUPPORT(device)
345 
346     int err = test_readimage<CL_MEM_OBJECT_IMAGE3D, cl_uchar>(
347         device, context, queue, &format[0]);
348 
349     if (check_format(device, context, CL_MEM_OBJECT_IMAGE3D, format[1]))
350     {
351         err |= test_readimage<CL_MEM_OBJECT_IMAGE3D, cl_uchar>(
352             device, context, queue, &format[1]);
353     }
354 
355     return err;
356 }
357 
test_readimage3d_int16(cl_device_id device,cl_context context,cl_command_queue queue,int num_elements)358 int test_readimage3d_int16(cl_device_id device, cl_context context,
359                            cl_command_queue queue, int num_elements)
360 {
361     const cl_image_format format = { CL_RGBA, CL_UNORM_INT16 };
362 
363     PASSIVE_REQUIRE_3D_IMAGE_SUPPORT(device)
364 
365     return test_readimage<CL_MEM_OBJECT_IMAGE3D, cl_ushort>(device, context,
366                                                             queue, &format);
367 }
test_readimage3d_fp32(cl_device_id device,cl_context context,cl_command_queue queue,int num_elements)368 int test_readimage3d_fp32(cl_device_id device, cl_context context,
369                           cl_command_queue queue, int num_elements)
370 {
371     const cl_image_format format = { CL_RGBA, CL_FLOAT };
372 
373     PASSIVE_REQUIRE_3D_IMAGE_SUPPORT(device)
374 
375     return test_readimage<CL_MEM_OBJECT_IMAGE3D, cl_float>(device, context,
376                                                            queue, &format);
377 }
378