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 "testBase.h"
17 
test_min_image_formats(cl_device_id device,cl_context context,cl_command_queue queue,int num_elements)18 int test_min_image_formats(cl_device_id device, cl_context context,
19                            cl_command_queue queue, int num_elements)
20 {
21     int missingFormats = 0;
22 
23     cl_int error = CL_SUCCESS;
24 
25     Version version = get_device_cl_version(device);
26 
27     cl_bool supports_images = CL_FALSE;
28     error = clGetDeviceInfo(device, CL_DEVICE_IMAGE_SUPPORT,
29                             sizeof(supports_images), &supports_images, NULL);
30     test_error(error, "clGetDeviceInfo for CL_DEVICE_IMAGE_SUPPORT failed");
31 
32     if (supports_images == CL_FALSE)
33     {
34         log_info("No image support on current device - skipped\n");
35         return TEST_SKIPPED_ITSELF;
36     }
37 
38     const cl_mem_object_type image_types[] = {
39         CL_MEM_OBJECT_IMAGE1D,       CL_MEM_OBJECT_IMAGE1D_BUFFER,
40         CL_MEM_OBJECT_IMAGE2D,       CL_MEM_OBJECT_IMAGE3D,
41         CL_MEM_OBJECT_IMAGE1D_ARRAY, CL_MEM_OBJECT_IMAGE2D_ARRAY,
42     };
43     const cl_mem_flags mem_flags[] = {
44         CL_MEM_READ_ONLY,
45         CL_MEM_WRITE_ONLY,
46         CL_MEM_KERNEL_READ_AND_WRITE,
47     };
48 
49     cl_bool supports_read_write_images = CL_FALSE;
50     if (version >= Version(3, 0))
51     {
52         cl_uint maxReadWriteImageArgs = 0;
53         error = clGetDeviceInfo(device, CL_DEVICE_MAX_READ_WRITE_IMAGE_ARGS,
54                                 sizeof(maxReadWriteImageArgs),
55                                 &maxReadWriteImageArgs, NULL);
56         test_error(error,
57                    "Unable to query "
58                    "CL_DEVICE_MAX_READ_WRITE_IMAGE_ARGS");
59 
60         // read-write images are supported if MAX_READ_WRITE_IMAGE_ARGS is
61         // nonzero
62         supports_read_write_images =
63             maxReadWriteImageArgs != 0 ? CL_TRUE : CL_FALSE;
64     }
65     else if (version >= Version(2, 0))
66     {
67         // read-write images are required for OpenCL 2.x
68         supports_read_write_images = CL_TRUE;
69     }
70 
71     int supports_3D_image_writes =
72         is_extension_available(device, "cl_khr_3d_image_writes");
73 
74     for (int t = 0; t < ARRAY_SIZE(image_types); t++)
75     {
76         const cl_mem_object_type type = image_types[t];
77         log_info("    testing %s...\n", convert_image_type_to_string(type));
78         for (int f = 0; f < ARRAY_SIZE(mem_flags); f++)
79         {
80             const cl_mem_flags flags = mem_flags[f];
81             const char* testTypeString = flags == CL_MEM_READ_ONLY
82                 ? "read-only"
83                 : flags == CL_MEM_WRITE_ONLY
84                     ? "write only"
85                     : flags == CL_MEM_KERNEL_READ_AND_WRITE ? "read and write"
86                                                             : "unknown???";
87 
88             if (flags == CL_MEM_KERNEL_READ_AND_WRITE
89                 && !supports_read_write_images)
90             {
91                 continue;
92             }
93 
94             if (type == CL_MEM_OBJECT_IMAGE3D && flags != CL_MEM_READ_ONLY
95                 && !supports_3D_image_writes)
96             {
97                 continue;
98             }
99 
100             cl_uint numImageFormats = 0;
101             error = clGetSupportedImageFormats(context, flags, type, 0, NULL,
102                                                &numImageFormats);
103             test_error(error, "Unable to query number of image formats");
104 
105             std::vector<cl_image_format> supportedFormats(numImageFormats);
106             if (numImageFormats != 0)
107             {
108                 error = clGetSupportedImageFormats(
109                     context, flags, type, supportedFormats.size(),
110                     supportedFormats.data(), NULL);
111                 test_error(error, "Unable to query image formats");
112             }
113 
114             std::vector<cl_image_format> requiredFormats;
115             build_required_image_formats(flags, type, device, requiredFormats);
116 
117             for (auto& format : requiredFormats)
118             {
119                 if (!find_format(supportedFormats.data(),
120                                  supportedFormats.size(), &format))
121                 {
122                     log_error(
123                         "Missing required %s format %s + %s.\n", testTypeString,
124                         GetChannelOrderName(format.image_channel_order),
125                         GetChannelTypeName(format.image_channel_data_type));
126                     ++missingFormats;
127                 }
128             }
129         }
130     }
131 
132     return missingFormats == 0 ? TEST_PASS : TEST_FAIL;
133 }
134