• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #include "../common.h"
18 
19 extern cl_filter_mode gFilterModeToUse;
20 extern cl_addressing_mode gAddressModeToUse;
21 extern int gNormalizedModeToUse;
22 extern int gTypesToTest;
23 extern int gtestTypesToRun;
24 
25 extern int test_read_image_set_1D(cl_device_id device, cl_context context,
26                                   cl_command_queue queue,
27                                   const cl_image_format *format,
28                                   image_sampler_data *imageSampler,
29                                   bool floatCoords, ExplicitType outputType);
30 extern int test_read_image_set_2D(cl_device_id device, cl_context context,
31                                   cl_command_queue queue,
32                                   const cl_image_format *format,
33                                   image_sampler_data *imageSampler,
34                                   bool floatCoords, ExplicitType outputType);
35 extern int test_read_image_set_3D(cl_device_id device, cl_context context,
36                                   cl_command_queue queue,
37                                   const cl_image_format *format,
38                                   image_sampler_data *imageSampler,
39                                   bool floatCoords, ExplicitType outputType);
40 extern int test_read_image_set_1D_array(cl_device_id device, cl_context context,
41                                         cl_command_queue queue,
42                                         const cl_image_format *format,
43                                         image_sampler_data *imageSampler,
44                                         bool floatCoords,
45                                         ExplicitType outputType);
46 extern int test_read_image_set_2D_array(cl_device_id device, cl_context context,
47                                         cl_command_queue queue,
48                                         const cl_image_format *format,
49                                         image_sampler_data *imageSampler,
50                                         bool floatCoords,
51                                         ExplicitType outputType);
52 
test_read_image_type(cl_device_id device,cl_context context,cl_command_queue queue,const cl_image_format * format,bool floatCoords,image_sampler_data * imageSampler,ExplicitType outputType,cl_mem_object_type imageType)53 int test_read_image_type(cl_device_id device, cl_context context,
54                          cl_command_queue queue, const cl_image_format *format,
55                          bool floatCoords, image_sampler_data *imageSampler,
56                          ExplicitType outputType, cl_mem_object_type imageType)
57 {
58     int ret = 0;
59     cl_addressing_mode *addressModes = NULL;
60 
61     // The sampler-less read image functions behave exactly as the corresponding
62     // read image functions described in section 6.13.14.2 that take integer
63     // coordinates and a sampler with filter mode set to CLK_FILTER_NEAREST,
64     // normalized coordinates set to CLK_NORMALIZED_COORDS_FALSE and addressing
65     // mode to CLK_ADDRESS_NONE
66     cl_addressing_mode addressModes_rw[] = { CL_ADDRESS_NONE,
67                                              (cl_addressing_mode)-1 };
68     cl_addressing_mode addressModes_ro[] = {
69         /* CL_ADDRESS_CLAMP_NONE,*/ CL_ADDRESS_CLAMP_TO_EDGE, CL_ADDRESS_CLAMP,
70         CL_ADDRESS_REPEAT, CL_ADDRESS_MIRRORED_REPEAT, (cl_addressing_mode)-1
71     };
72 
73     if (gtestTypesToRun & kReadWriteTests)
74     {
75         addressModes = addressModes_rw;
76     }
77     else
78     {
79         addressModes = addressModes_ro;
80     }
81 
82 #if defined(__APPLE__)
83     // According to the OpenCL specification, we do not guarantee the precision
84     // of operations for linear filtering on the GPU.  We do not test linear
85     // filtering for the CL_RGB CL_UNORM_INT_101010 image format; however, we
86     // test it internally for a set of other image formats.
87     if ((gDeviceType & CL_DEVICE_TYPE_GPU)
88         && (imageSampler->filter_mode == CL_FILTER_LINEAR)
89         && (format->image_channel_order == CL_RGB)
90         && (format->image_channel_data_type == CL_UNORM_INT_101010))
91     {
92         log_info("--- Skipping CL_RGB CL_UNORM_INT_101010 format with "
93                  "CL_FILTER_LINEAR on GPU.\n");
94         return 0;
95     }
96 #endif
97 
98     for (int adMode = 0; addressModes[adMode] != (cl_addressing_mode)-1;
99          adMode++)
100     {
101         imageSampler->addressing_mode = addressModes[adMode];
102 
103         if ((addressModes[adMode] == CL_ADDRESS_REPEAT
104              || addressModes[adMode] == CL_ADDRESS_MIRRORED_REPEAT)
105             && !(imageSampler->normalized_coords))
106             continue; // Repeat doesn't make sense for non-normalized coords
107 
108         // Use this run if we were told to only run a certain filter mode
109         if (gAddressModeToUse != (cl_addressing_mode)-1
110             && imageSampler->addressing_mode != gAddressModeToUse)
111             continue;
112 
113         /*
114          Remove redundant check to see if workaround still necessary
115          // Check added in because this case was leaking through causing a crash
116          on CPU if( ! imageSampler->normalized_coords &&
117          imageSampler->addressing_mode == CL_ADDRESS_REPEAT ) continue; //repeat
118          mode requires normalized coordinates
119          */
120         print_read_header(format, imageSampler, false);
121 
122         gTestCount++;
123 
124         int retCode = 0;
125         switch (imageType)
126         {
127             case CL_MEM_OBJECT_IMAGE1D:
128                 retCode = test_read_image_set_1D(device, context, queue, format,
129                                                  imageSampler, floatCoords,
130                                                  outputType);
131                 break;
132             case CL_MEM_OBJECT_IMAGE1D_ARRAY:
133                 retCode = test_read_image_set_1D_array(device, context, queue,
134                                                        format, imageSampler,
135                                                        floatCoords, outputType);
136                 break;
137             case CL_MEM_OBJECT_IMAGE2D:
138                 retCode = test_read_image_set_2D(device, context, queue, format,
139                                                  imageSampler, floatCoords,
140                                                  outputType);
141                 break;
142             case CL_MEM_OBJECT_IMAGE2D_ARRAY:
143                 retCode = test_read_image_set_2D_array(device, context, queue,
144                                                        format, imageSampler,
145                                                        floatCoords, outputType);
146                 break;
147             case CL_MEM_OBJECT_IMAGE3D:
148                 retCode = test_read_image_set_3D(device, context, queue, format,
149                                                  imageSampler, floatCoords,
150                                                  outputType);
151                 break;
152         }
153         if (retCode != 0)
154         {
155             gFailCount++;
156             log_error("FAILED: ");
157             print_read_header(format, imageSampler, true);
158             log_info("\n");
159         }
160         ret |= retCode;
161     }
162 
163     return ret;
164 }
165 
test_read_image_formats(cl_device_id device,cl_context context,cl_command_queue queue,const std::vector<cl_image_format> & formatList,const std::vector<bool> & filterFlags,image_sampler_data * imageSampler,ExplicitType outputType,cl_mem_object_type imageType)166 int test_read_image_formats(cl_device_id device, cl_context context,
167                             cl_command_queue queue,
168                             const std::vector<cl_image_format> &formatList,
169                             const std::vector<bool> &filterFlags,
170                             image_sampler_data *imageSampler,
171                             ExplicitType outputType,
172                             cl_mem_object_type imageType)
173 {
174     int ret = 0;
175     bool flipFlop[2] = { false, true };
176     int normalizedIdx, floatCoordIdx;
177 
178 
179     // Use this run if we were told to only run a certain filter mode
180     if (gFilterModeToUse != (cl_filter_mode)-1
181         && imageSampler->filter_mode != gFilterModeToUse)
182         return 0;
183 
184     // Test normalized/non-normalized
185     for (normalizedIdx = 0; normalizedIdx < 2; normalizedIdx++)
186     {
187         imageSampler->normalized_coords = flipFlop[normalizedIdx];
188         if (gNormalizedModeToUse != 7
189             && gNormalizedModeToUse != (int)imageSampler->normalized_coords)
190             continue;
191 
192         for (floatCoordIdx = 0; floatCoordIdx < 2; floatCoordIdx++)
193         {
194             // Checks added in because this case was leaking through causing a
195             // crash on CPU
196             if (!flipFlop[floatCoordIdx])
197                 if (imageSampler->filter_mode != CL_FILTER_NEAREST
198                     || // integer coords can only be used with nearest
199                     flipFlop[normalizedIdx]) // Normalized integer coords makes
200                                              // no sense (they'd all be zero)
201                     continue;
202 
203             if (flipFlop[floatCoordIdx] && (gtestTypesToRun & kReadWriteTests))
204                 // sampler-less read in read_write tests run only integer coord
205                 continue;
206 
207 
208             log_info("read_image (%s coords, %s results) "
209                      "*****************************\n",
210                      flipFlop[floatCoordIdx] ? (imageSampler->normalized_coords
211                                                     ? "normalized float"
212                                                     : "unnormalized float")
213                                              : "integer",
214                      get_explicit_type_name(outputType));
215 
216             for (unsigned int i = 0; i < formatList.size(); i++)
217             {
218                 if (filterFlags[i]) continue;
219 
220                 const cl_image_format &imageFormat = formatList[i];
221 
222                 ret |=
223                     test_read_image_type(device, context, queue, &imageFormat,
224                                          flipFlop[floatCoordIdx], imageSampler,
225                                          outputType, imageType);
226             }
227         }
228     }
229     return ret;
230 }
231 
232 
test_image_set(cl_device_id device,cl_context context,cl_command_queue queue,test_format_set_fn formatTestFn,cl_mem_object_type imageType)233 int test_image_set(cl_device_id device, cl_context context,
234                    cl_command_queue queue, test_format_set_fn formatTestFn,
235                    cl_mem_object_type imageType)
236 {
237     int ret = 0;
238     static int printedFormatList = -1;
239 
240 
241     if ((imageType == CL_MEM_OBJECT_IMAGE3D)
242         && (formatTestFn == test_write_image_formats))
243     {
244         if (0 == is_extension_available(device, "cl_khr_3d_image_writes"))
245         {
246             log_info("-----------------------------------------------------\n");
247             log_info(
248                 "This device does not support "
249                 "cl_khr_3d_image_writes.\nSkipping 3d image write test. \n");
250             log_info(
251                 "-----------------------------------------------------\n\n");
252             return 0;
253         }
254     }
255 
256     if (gTestMipmaps)
257     {
258         if (0 == is_extension_available(device, "cl_khr_mipmap_image"))
259         {
260             log_info("-----------------------------------------------------\n");
261             log_info("This device does not support "
262                      "cl_khr_mipmap_image.\nSkipping mipmapped image test. \n");
263             log_info(
264                 "-----------------------------------------------------\n\n");
265             return 0;
266         }
267         if ((0 == is_extension_available(device, "cl_khr_mipmap_image_writes"))
268             && (formatTestFn == test_write_image_formats))
269         {
270             log_info("-----------------------------------------------------\n");
271             log_info("This device does not support "
272                      "cl_khr_mipmap_image_writes.\nSkipping mipmapped image "
273                      "write test. \n");
274             log_info(
275                 "-----------------------------------------------------\n\n");
276             return 0;
277         }
278     }
279 
280     int version_check = (get_device_cl_version(device) < Version(1, 2));
281     if (version_check != 0)
282     {
283         switch (imageType)
284         {
285             case CL_MEM_OBJECT_IMAGE1D:
286                 test_missing_feature(version_check, "image_1D");
287             case CL_MEM_OBJECT_IMAGE1D_ARRAY:
288                 test_missing_feature(version_check, "image_1D_array");
289             case CL_MEM_OBJECT_IMAGE2D_ARRAY:
290                 test_missing_feature(version_check, "image_2D_array");
291         }
292     }
293 
294     // This flag is only for querying the list of supported formats
295     // The flag for creating image will be set explicitly in test functions
296     cl_mem_flags flags;
297     const char *flagNames;
298     if (formatTestFn == test_read_image_formats)
299     {
300         if (gtestTypesToRun & kReadTests)
301         {
302             flags = CL_MEM_READ_ONLY;
303             flagNames = "read";
304         }
305         else
306         {
307             flags = CL_MEM_KERNEL_READ_AND_WRITE;
308             flagNames = "read_write";
309         }
310     }
311     else
312     {
313         if (gtestTypesToRun & kWriteTests)
314         {
315             flags = CL_MEM_WRITE_ONLY;
316             flagNames = "write";
317         }
318         else
319         {
320             flags = CL_MEM_KERNEL_READ_AND_WRITE;
321             flagNames = "read_write";
322         }
323     }
324 
325     // Grab the list of supported image formats for integer reads
326     std::vector<cl_image_format> formatList;
327     if (get_format_list(context, imageType, formatList, flags)) return -1;
328 
329     // First time through, we'll go ahead and print the formats supported,
330     // regardless of type
331     int test = imageType
332         | (formatTestFn == test_read_image_formats ? (1 << 16) : (1 << 17));
333     if (printedFormatList != test)
334     {
335         log_info("---- Supported %s %s formats for this device ---- \n",
336                  convert_image_type_to_string(imageType), flagNames);
337         for (unsigned int f = 0; f < formatList.size(); f++)
338         {
339             if (IsChannelOrderSupported(formatList[f].image_channel_order)
340                 && IsChannelTypeSupported(
341                     formatList[f].image_channel_data_type))
342                 log_info(
343                     "  %-7s %-24s %d\n",
344                     GetChannelOrderName(formatList[f].image_channel_order),
345                     GetChannelTypeName(formatList[f].image_channel_data_type),
346                     (int)get_format_channel_count(&formatList[f]));
347         }
348         log_info("------------------------------------------- \n");
349         printedFormatList = test;
350     }
351 
352     image_sampler_data imageSampler;
353 
354     for (auto test : imageTestTypes)
355     {
356         if (gTypesToTest & test.type)
357         {
358             std::vector<bool> filterFlags(formatList.size(), false);
359             if (filter_formats(formatList, filterFlags, test.channelTypes,
360                                gTestMipmaps)
361                 == 0)
362             {
363                 log_info("No formats supported for %s type\n", test.name);
364             }
365             else
366             {
367                 imageSampler.filter_mode = CL_FILTER_NEAREST;
368                 ret += formatTestFn(device, context, queue, formatList,
369                                     filterFlags, &imageSampler,
370                                     test.explicitType, imageType);
371 
372                 // Linear filtering is only supported with floats
373                 if (test.type == kTestFloat)
374                 {
375                     imageSampler.filter_mode = CL_FILTER_LINEAR;
376                     ret += formatTestFn(device, context, queue, formatList,
377                                         filterFlags, &imageSampler,
378                                         test.explicitType, imageType);
379                 }
380             }
381         }
382     }
383     return ret;
384 }
385