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