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 "utils.h"
17
18 #include "harness/errorHelpers.h"
19 #include "harness/imageHelpers.h"
20 #include "harness/rounding_mode.h"
21
22 #include <math.h>
23
24 #include <CL/cl_half.h>
25
26 static RoundingMode gFloatToHalfRoundingMode = kDefaultRoundingMode;
27
28
CResult()29 CResult::CResult(): _result(TEST_PASS), _resultLast(TEST_NORESULT) {}
30
~CResult()31 CResult::~CResult() {}
32
ResultLast() const33 CResult::TTestResult CResult::ResultLast() const { return _resultLast; }
34
Result() const35 int CResult::Result() const
36 {
37 switch (_result)
38 {
39 case TEST_NORESULT:
40 case TEST_NOTSUPPORTED:
41 case TEST_PASS: return 0; break;
42 case TEST_FAIL: return 1; break;
43 case TEST_ERROR: return 2; break;
44 default: return -1; break;
45 }
46 }
47
ResultSub(TTestResult result)48 void CResult::ResultSub(TTestResult result)
49 {
50 _resultLast = result;
51 if (static_cast<int>(result) > static_cast<int>(_result)) _result = result;
52 }
53
FunctionContextCreateToString(TContextFuncType contextCreateFunction,std::string & contextFunction)54 void FunctionContextCreateToString(TContextFuncType contextCreateFunction,
55 std::string &contextFunction)
56 {
57 switch (contextCreateFunction)
58 {
59 case CONTEXT_CREATE_DEFAULT: contextFunction = "CreateContext"; break;
60 case CONTEXT_CREATE_FROM_TYPE:
61 contextFunction = "CreateContextFromType";
62 break;
63 default:
64 contextFunction = "Unknown";
65 log_error("FunctionContextCreateToString(): Unknown create "
66 "function enum!");
67 break;
68 }
69 }
70
AdapterToString(cl_dx9_media_adapter_type_khr adapterType,std::string & adapter)71 void AdapterToString(cl_dx9_media_adapter_type_khr adapterType,
72 std::string &adapter)
73 {
74 switch (adapterType)
75 {
76 case CL_ADAPTER_D3D9_KHR: adapter = "D3D9"; break;
77 case CL_ADAPTER_D3D9EX_KHR: adapter = "D3D9EX"; break;
78 case CL_ADAPTER_DXVA_KHR: adapter = "DXVA"; break;
79 default:
80 adapter = "Unknown";
81 log_error("AdapterToString(): Unknown adapter type!");
82 break;
83 }
84 }
85
86 cl_context_info
AdapterTypeToContextInfo(cl_dx9_media_adapter_type_khr adapterType)87 AdapterTypeToContextInfo(cl_dx9_media_adapter_type_khr adapterType)
88 {
89 switch (adapterType)
90 {
91 case CL_ADAPTER_D3D9_KHR: return CL_CONTEXT_ADAPTER_D3D9_KHR; break;
92 case CL_ADAPTER_D3D9EX_KHR: return CL_CONTEXT_ADAPTER_D3D9EX_KHR; break;
93 case CL_ADAPTER_DXVA_KHR: return CL_CONTEXT_ADAPTER_DXVA_KHR; break;
94 default:
95 log_error("AdapterTypeToContextInfo(): Unknown adapter type!");
96 return 0;
97 break;
98 }
99 }
100
YUVGenerateNV12(std::vector<cl_uchar> & yuv,unsigned int width,unsigned int height,cl_uchar valueMin,cl_uchar valueMax,double valueAdd)101 void YUVGenerateNV12(std::vector<cl_uchar> &yuv, unsigned int width,
102 unsigned int height, cl_uchar valueMin, cl_uchar valueMax,
103 double valueAdd)
104 {
105 yuv.clear();
106 yuv.resize(width * height * 3 / 2, 0);
107
108 double min = static_cast<double>(valueMin);
109 double max = static_cast<double>(valueMax);
110 double range = 255;
111 double add = static_cast<double>(valueAdd * range);
112 double stepX = (max - min) / static_cast<double>(width);
113 double stepY = (max - min) / static_cast<double>(height);
114
115 // generate Y plane
116 for (unsigned int i = 0; i < height; ++i)
117 {
118 unsigned int offset = i * width;
119 double valueYPlane0 = static_cast<double>(stepY * i);
120 for (unsigned int j = 0; j < width; ++j)
121 {
122 double valueXPlane0 = static_cast<double>(stepX * j);
123 yuv.at(offset + j) = static_cast<cl_uchar>(
124 min + valueXPlane0 / 2 + valueYPlane0 / 2 + add);
125 }
126 }
127
128 // generate UV planes
129 for (unsigned int i = 0; i < height / 2; ++i)
130 {
131 unsigned int offset = width * height + i * width;
132 double valueYPlane1 = static_cast<double>(stepY * i);
133 double valueYPlane2 = static_cast<double>(stepY * (height / 2 + i));
134 for (unsigned int j = 0; j < width / 2; ++j)
135 {
136 double valueXPlane1 = static_cast<double>(stepX * j);
137 double valueXPlane2 = static_cast<double>(stepX * (width / 2 + j));
138
139 yuv.at(offset + j * 2) = static_cast<cl_uchar>(
140 min + valueXPlane1 / 2 + valueYPlane1 / 2 + add);
141 yuv.at(offset + j * 2 + 1) = static_cast<cl_uchar>(
142 min + valueXPlane2 / 2 + valueYPlane2 / 2 + add);
143 }
144 }
145 }
146
YUVGenerateYV12(std::vector<cl_uchar> & yuv,unsigned int width,unsigned int height,cl_uchar valueMin,cl_uchar valueMax,double valueAdd)147 void YUVGenerateYV12(std::vector<cl_uchar> &yuv, unsigned int width,
148 unsigned int height, cl_uchar valueMin, cl_uchar valueMax,
149 double valueAdd /*= 0.0*/)
150 {
151 yuv.clear();
152 yuv.resize(width * height * 3 / 2, 0);
153
154 double min = static_cast<double>(valueMin);
155 double max = static_cast<double>(valueMax);
156 double range = 255;
157 double add = static_cast<double>(valueAdd * range);
158 double stepX = (max - min) / static_cast<double>(width);
159 double stepY = (max - min) / static_cast<double>(height);
160
161 unsigned offset = 0;
162
163 // generate Y plane
164 for (unsigned int i = 0; i < height; ++i)
165 {
166 unsigned int plane0Offset = offset + i * width;
167 double valueYPlane0 = static_cast<double>(stepY * i);
168 for (unsigned int j = 0; j < width; ++j)
169 {
170 double valueXPlane0 = static_cast<double>(stepX * j);
171 yuv.at(plane0Offset + j) = static_cast<cl_uchar>(
172 min + valueXPlane0 / 2 + valueYPlane0 / 2 + add);
173 }
174 }
175
176 // generate V plane
177 offset += width * height;
178 for (unsigned int i = 0; i < height / 2; ++i)
179 {
180 unsigned int plane1Offset = offset + i * width / 2;
181 double valueYPlane1 = static_cast<double>(stepY * i);
182 for (unsigned int j = 0; j < width / 2; ++j)
183 {
184 double valueXPlane1 = static_cast<double>(stepX * j);
185 yuv.at(plane1Offset + j) = static_cast<cl_uchar>(
186 min + valueXPlane1 / 2 + valueYPlane1 / 2 + add);
187 }
188 }
189
190 // generate U plane
191 offset += width * height / 4;
192 for (unsigned int i = 0; i < height / 2; ++i)
193 {
194 unsigned int plane2Offset = offset + i * width / 2;
195 double valueYPlane2 = static_cast<double>(stepY * (height / 2 + i));
196 for (unsigned int j = 0; j < width / 2; ++j)
197 {
198 double valueXPlane2 = static_cast<double>(stepX * j);
199 yuv.at(plane2Offset + j) = static_cast<cl_uchar>(
200 min + valueXPlane2 / 2 + valueYPlane2 / 2 + add);
201 }
202 }
203 }
204
205
YUVGenerate(TSurfaceFormat surfaceFormat,std::vector<cl_uchar> & yuv,unsigned int width,unsigned int height,cl_uchar valueMin,cl_uchar valueMax,double valueAdd)206 bool YUVGenerate(TSurfaceFormat surfaceFormat, std::vector<cl_uchar> &yuv,
207 unsigned int width, unsigned int height, cl_uchar valueMin,
208 cl_uchar valueMax, double valueAdd /*= 0.0*/)
209 {
210 switch (surfaceFormat)
211 {
212 case SURFACE_FORMAT_NV12:
213 YUVGenerateNV12(yuv, width, height, valueMin, valueMax, valueAdd);
214 break;
215 case SURFACE_FORMAT_YV12:
216 YUVGenerateYV12(yuv, width, height, valueMin, valueMax, valueAdd);
217 break;
218 default:
219 log_error("YUVGenerate(): Invalid surface type\n");
220 return false;
221 break;
222 }
223
224 return true;
225 }
226
YUVSurfaceSetNV12(std::auto_ptr<CSurfaceWrapper> & surface,const std::vector<cl_uchar> & yuv,unsigned int width,unsigned int height)227 bool YUVSurfaceSetNV12(std::auto_ptr<CSurfaceWrapper> &surface,
228 const std::vector<cl_uchar> &yuv, unsigned int width,
229 unsigned int height)
230 {
231 #if defined(_WIN32)
232 CD3D9SurfaceWrapper *d3dSurface =
233 static_cast<CD3D9SurfaceWrapper *>(surface.get());
234 D3DLOCKED_RECT rect;
235 if (FAILED((*d3dSurface)->LockRect(&rect, NULL, 0)))
236 {
237 log_error("YUVSurfaceSetNV12(): Surface lock failed\n");
238 return false;
239 }
240
241 size_t pitch = rect.Pitch / sizeof(cl_uchar);
242 size_t lineSize = width * sizeof(cl_uchar);
243 cl_uchar *ptr = static_cast<cl_uchar *>(rect.pBits);
244 for (size_t y = 0; y < height; ++y)
245 memcpy(ptr + y * pitch, &yuv.at(y * width), lineSize);
246
247 for (size_t y = 0; y < height / 2; ++y)
248 memcpy(ptr + height * pitch + y * pitch,
249 &yuv.at(width * height + y * width), lineSize);
250
251 (*d3dSurface)->UnlockRect();
252
253 return true;
254
255 #else
256 return false;
257 #endif
258 }
259
YUVSurfaceSetYV12(std::auto_ptr<CSurfaceWrapper> & surface,const std::vector<cl_uchar> & yuv,unsigned int width,unsigned int height)260 bool YUVSurfaceSetYV12(std::auto_ptr<CSurfaceWrapper> &surface,
261 const std::vector<cl_uchar> &yuv, unsigned int width,
262 unsigned int height)
263 {
264 #if defined(_WIN32)
265 CD3D9SurfaceWrapper *d3dSurface =
266 static_cast<CD3D9SurfaceWrapper *>(surface.get());
267 D3DLOCKED_RECT rect;
268 if (FAILED((*d3dSurface)->LockRect(&rect, NULL, 0)))
269 {
270 log_error("YUVSurfaceSetYV12(): Surface lock failed!\n");
271 return false;
272 }
273
274 size_t pitch = rect.Pitch / sizeof(cl_uchar);
275 size_t pitchHalf = pitch / 2;
276 size_t lineSize = width * sizeof(cl_uchar);
277 size_t lineHalfSize = lineSize / 2;
278 size_t surfaceOffset = 0;
279 size_t yuvOffset = 0;
280 cl_uchar *ptr = static_cast<cl_uchar *>(rect.pBits);
281
282 for (size_t y = 0; y < height; ++y)
283 memcpy(ptr + surfaceOffset + y * pitch, &yuv.at(yuvOffset + y * width),
284 lineSize);
285
286 surfaceOffset += height * pitch;
287 yuvOffset += width * height;
288 for (size_t y = 0; y < height / 2; ++y)
289 memcpy(ptr + surfaceOffset + y * pitchHalf,
290 &yuv.at(yuvOffset + y * lineHalfSize), lineHalfSize);
291
292 surfaceOffset += pitchHalf * height / 2;
293 yuvOffset += width * height / 4;
294 for (size_t y = 0; y < height / 2; ++y)
295 memcpy(ptr + surfaceOffset + y * pitchHalf,
296 &yuv.at(yuvOffset + y * lineHalfSize), lineHalfSize);
297
298 (*d3dSurface)->UnlockRect();
299
300 return true;
301
302 #else
303 return false;
304 #endif
305 }
306
YUVSurfaceSet(TSurfaceFormat surfaceFormat,std::auto_ptr<CSurfaceWrapper> & surface,const std::vector<cl_uchar> & yuv,unsigned int width,unsigned int height)307 bool YUVSurfaceSet(TSurfaceFormat surfaceFormat,
308 std::auto_ptr<CSurfaceWrapper> &surface,
309 const std::vector<cl_uchar> &yuv, unsigned int width,
310 unsigned int height)
311 {
312 switch (surfaceFormat)
313 {
314 case SURFACE_FORMAT_NV12:
315 if (!YUVSurfaceSetNV12(surface, yuv, width, height)) return false;
316 break;
317 case SURFACE_FORMAT_YV12:
318 if (!YUVSurfaceSetYV12(surface, yuv, width, height)) return false;
319 break;
320 default:
321 log_error("YUVSurfaceSet(): Invalid surface type!\n");
322 return false;
323 break;
324 }
325
326 return true;
327 }
328
YUVSurfaceGetNV12(std::auto_ptr<CSurfaceWrapper> & surface,std::vector<cl_uchar> & yuv,unsigned int width,unsigned int height)329 bool YUVSurfaceGetNV12(std::auto_ptr<CSurfaceWrapper> &surface,
330 std::vector<cl_uchar> &yuv, unsigned int width,
331 unsigned int height)
332 {
333 #if defined(_WIN32)
334 CD3D9SurfaceWrapper *d3dSurface =
335 static_cast<CD3D9SurfaceWrapper *>(surface.get());
336 D3DLOCKED_RECT rect;
337 if (FAILED((*d3dSurface)->LockRect(&rect, NULL, 0)))
338 {
339 log_error("YUVSurfaceGetNV12(): Surface lock failed!\n");
340 return false;
341 }
342
343 size_t pitch = rect.Pitch / sizeof(cl_uchar);
344 size_t lineSize = width * sizeof(cl_uchar);
345 cl_uchar *ptr = static_cast<cl_uchar *>(rect.pBits);
346 size_t yuvOffset = 0;
347 size_t surfaceOffset = 0;
348 for (size_t y = 0; y < height; ++y)
349 memcpy(&yuv.at(yuvOffset + y * width), ptr + y * pitch, lineSize);
350
351 yuvOffset += width * height;
352 surfaceOffset += pitch * height;
353 for (size_t y = 0; y < height / 2; ++y)
354 memcpy(&yuv.at(yuvOffset + y * width), ptr + surfaceOffset + y * pitch,
355 lineSize);
356
357 (*d3dSurface)->UnlockRect();
358
359 return true;
360
361 #else
362 return false;
363 #endif
364 }
365
YUVSurfaceGetYV12(std::auto_ptr<CSurfaceWrapper> & surface,std::vector<cl_uchar> & yuv,unsigned int width,unsigned int height)366 bool YUVSurfaceGetYV12(std::auto_ptr<CSurfaceWrapper> &surface,
367 std::vector<cl_uchar> &yuv, unsigned int width,
368 unsigned int height)
369 {
370 #if defined(_WIN32)
371 CD3D9SurfaceWrapper *d3dSurface =
372 static_cast<CD3D9SurfaceWrapper *>(surface.get());
373 D3DLOCKED_RECT rect;
374 if (FAILED((*d3dSurface)->LockRect(&rect, NULL, 0)))
375 {
376 log_error("YUVSurfaceGetYV12(): Surface lock failed!\n");
377 return false;
378 }
379
380 size_t pitch = rect.Pitch / sizeof(cl_uchar);
381 size_t pitchHalf = pitch / 2;
382 size_t lineSize = width * sizeof(cl_uchar);
383 size_t lineHalfSize = lineSize / 2;
384 size_t surfaceOffset = 0;
385 size_t yuvOffset = 0;
386 cl_uchar *ptr = static_cast<cl_uchar *>(rect.pBits);
387
388 for (size_t y = 0; y < height; ++y)
389 memcpy(&yuv.at(yuvOffset + y * width), ptr + surfaceOffset + y * pitch,
390 lineSize);
391
392 surfaceOffset += pitch * height;
393 yuvOffset += width * height;
394 for (size_t y = 0; y < height / 2; ++y)
395 memcpy(&yuv.at(yuvOffset + y * lineHalfSize),
396 ptr + surfaceOffset + y * pitchHalf, lineHalfSize);
397
398 surfaceOffset += pitchHalf * height / 2;
399 yuvOffset += width * height / 4;
400 for (size_t y = 0; y < height / 2; ++y)
401 memcpy(&yuv.at(yuvOffset + y * lineHalfSize),
402 ptr + surfaceOffset + y * pitchHalf, lineHalfSize);
403
404 (*d3dSurface)->UnlockRect();
405
406 return true;
407
408 #else
409 return false;
410 #endif
411 }
412
YUVSurfaceGet(TSurfaceFormat surfaceFormat,std::auto_ptr<CSurfaceWrapper> & surface,std::vector<cl_uchar> & yuv,unsigned int width,unsigned int height)413 bool YUVSurfaceGet(TSurfaceFormat surfaceFormat,
414 std::auto_ptr<CSurfaceWrapper> &surface,
415 std::vector<cl_uchar> &yuv, unsigned int width,
416 unsigned int height)
417 {
418 switch (surfaceFormat)
419 {
420 case SURFACE_FORMAT_NV12:
421 if (!YUVSurfaceGetNV12(surface, yuv, width, height)) return false;
422 break;
423 case SURFACE_FORMAT_YV12:
424 if (!YUVSurfaceGetYV12(surface, yuv, width, height)) return false;
425 break;
426 default:
427 log_error("YUVSurfaceGet(): Invalid surface type!\n");
428 return false;
429 break;
430 }
431
432 return true;
433 }
434
YUVCompareNV12(const std::vector<cl_uchar> & yuvTest,const std::vector<cl_uchar> & yuvRef,unsigned int width,unsigned int height)435 bool YUVCompareNV12(const std::vector<cl_uchar> &yuvTest,
436 const std::vector<cl_uchar> &yuvRef, unsigned int width,
437 unsigned int height)
438 {
439 // plane 0 verification
440 size_t offset = 0;
441 for (size_t y = 0; y < height; ++y)
442 {
443 size_t plane0Offset = offset + width * y;
444 for (size_t x = 0; x < width; ++x)
445 {
446 if (yuvTest[plane0Offset + x] != yuvRef[plane0Offset + x])
447 {
448 log_error("Plane 0 (Y) is different than expected, reference "
449 "value: %i, test value: %i, x: %i, y: %i\n",
450 yuvRef[plane0Offset + x], yuvTest[plane0Offset + x],
451 x, y);
452 return false;
453 }
454 }
455 }
456
457 // plane 1 and 2 verification
458 offset += width * height;
459 for (size_t y = 0; y < height / 2; ++y)
460 {
461 size_t plane12Offset = offset + width * y;
462 for (size_t x = 0; x < width / 2; ++x)
463 {
464 if (yuvTest.at(plane12Offset + 2 * x)
465 != yuvRef.at(plane12Offset + 2 * x))
466 {
467 log_error("Plane 1 (U) is different than expected, reference "
468 "value: %i, test value: %i, x: %i, y: %i\n",
469 yuvRef[plane12Offset + 2 * x],
470 yuvTest[plane12Offset + 2 * x], x, y);
471 return false;
472 }
473
474 if (yuvTest.at(plane12Offset + 2 * x + 1)
475 != yuvRef.at(plane12Offset + 2 * x + 1))
476 {
477 log_error("Plane 2 (V) is different than expected, reference "
478 "value: %i, test value: %i, x: %i, y: %i\n",
479 yuvRef[plane12Offset + 2 * x + 1],
480 yuvTest[plane12Offset + 2 * x + 1], x, y);
481 return false;
482 }
483 }
484 }
485
486 return true;
487 }
488
YUVCompareYV12(const std::vector<cl_uchar> & yuvTest,const std::vector<cl_uchar> & yuvRef,unsigned int width,unsigned int height)489 bool YUVCompareYV12(const std::vector<cl_uchar> &yuvTest,
490 const std::vector<cl_uchar> &yuvRef, unsigned int width,
491 unsigned int height)
492 {
493 // plane 0 verification
494 size_t offset = 0;
495 for (size_t y = 0; y < height; ++y)
496 {
497 size_t plane0Offset = width * y;
498 for (size_t x = 0; x < width; ++x)
499 {
500 if (yuvTest.at(plane0Offset + x) != yuvRef.at(plane0Offset + x))
501 {
502 log_error("Plane 0 (Y) is different than expected, reference "
503 "value: %i, test value: %i, x: %i, y: %i\n",
504 yuvRef[plane0Offset + x], yuvTest[plane0Offset + x],
505 x, y);
506 return false;
507 }
508 }
509 }
510
511 // plane 1 verification
512 offset += width * height;
513 for (size_t y = 0; y < height / 2; ++y)
514 {
515 size_t plane1Offset = offset + width * y / 2;
516 for (size_t x = 0; x < width / 2; ++x)
517 {
518 if (yuvTest.at(plane1Offset + x) != yuvRef.at(plane1Offset + x))
519 {
520 log_error("Plane 1 (V) is different than expected, reference "
521 "value: %i, test value: %i, x: %i, y: %i\n",
522 yuvRef[plane1Offset + x], yuvTest[plane1Offset + x],
523 x, y);
524 return false;
525 }
526 }
527 }
528
529 // plane 2 verification
530 offset += width * height / 4;
531 for (size_t y = 0; y < height / 2; ++y)
532 {
533 size_t plane2Offset = offset + width * y / 2;
534 for (size_t x = 0; x < width / 2; ++x)
535 {
536 if (yuvTest.at(plane2Offset + x) != yuvRef.at(plane2Offset + x))
537 {
538 log_error("Plane 2 (U) is different than expected, reference "
539 "value: %i, test value: %i, x: %i, y: %i\n",
540 yuvRef[plane2Offset + x], yuvTest[plane2Offset + x],
541 x, y);
542 return false;
543 }
544 }
545 }
546
547 return true;
548 }
549
YUVCompare(TSurfaceFormat surfaceFormat,const std::vector<cl_uchar> & yuvTest,const std::vector<cl_uchar> & yuvRef,unsigned int width,unsigned int height)550 bool YUVCompare(TSurfaceFormat surfaceFormat,
551 const std::vector<cl_uchar> &yuvTest,
552 const std::vector<cl_uchar> &yuvRef, unsigned int width,
553 unsigned int height)
554 {
555 switch (surfaceFormat)
556 {
557 case SURFACE_FORMAT_NV12:
558 if (!YUVCompareNV12(yuvTest, yuvRef, width, height))
559 {
560 log_error("OCL object is different than expected!\n");
561 return false;
562 }
563 break;
564 case SURFACE_FORMAT_YV12:
565 if (!YUVCompareYV12(yuvTest, yuvRef, width, height))
566 {
567 log_error("OCL object is different than expected!\n");
568 return false;
569 }
570 break;
571 default:
572 log_error("YUVCompare(): Invalid surface type!\n");
573 return false;
574 break;
575 }
576
577 return true;
578 }
579
DataGenerate(TSurfaceFormat surfaceFormat,cl_channel_type type,std::vector<float> & data,unsigned int width,unsigned int height,unsigned int channelNum,float cmin,float cmax,float add)580 void DataGenerate(TSurfaceFormat surfaceFormat, cl_channel_type type,
581 std::vector<float> &data, unsigned int width,
582 unsigned int height, unsigned int channelNum,
583 float cmin /*= 0.0f*/, float cmax /*= 1.0f*/,
584 float add /*= 0.0f*/)
585 {
586 data.clear();
587 data.reserve(width * height * channelNum);
588
589 double valueMin = static_cast<double>(cmin);
590 double valueMax = static_cast<double>(cmax);
591 double stepX = (valueMax - valueMin) / static_cast<double>(width);
592 double stepY = (valueMax - valueMin) / static_cast<double>(height);
593 double valueAdd = static_cast<double>(add);
594 for (unsigned int i = 0; i < height; ++i)
595 {
596 double valueY = static_cast<double>(stepY * i);
597 for (unsigned int j = 0; j < width; ++j)
598 {
599 double valueX = static_cast<double>(stepX * j);
600 switch (channelNum)
601 {
602 case 1:
603 data.push_back(static_cast<float>(valueMin + valueX / 2
604 + valueY / 2 + valueAdd));
605 break;
606 case 2:
607 data.push_back(
608 static_cast<float>(valueMin + valueX + valueAdd));
609 data.push_back(
610 static_cast<float>(valueMin + valueY + valueAdd));
611 break;
612 case 4:
613 data.push_back(
614 static_cast<float>(valueMin + valueX + valueAdd));
615 data.push_back(
616 static_cast<float>(valueMin + valueY + valueAdd));
617 data.push_back(
618 static_cast<float>(valueMin + valueX / 2 + valueAdd));
619 data.push_back(
620 static_cast<float>(valueMin + valueY / 2 + valueAdd));
621 break;
622 default:
623 log_error("DataGenerate(): invalid channel number!");
624 return;
625 break;
626 }
627 }
628 }
629 }
630
DataGenerate(TSurfaceFormat surfaceFormat,cl_channel_type type,std::vector<cl_half> & data,unsigned int width,unsigned int height,unsigned int channelNum,float cmin,float cmax,float add)631 void DataGenerate(TSurfaceFormat surfaceFormat, cl_channel_type type,
632 std::vector<cl_half> &data, unsigned int width,
633 unsigned int height, unsigned int channelNum,
634 float cmin /*= 0.0f*/, float cmax /*= 1.0f*/,
635 float add /*= 0.0f*/)
636 {
637 data.clear();
638 data.reserve(width * height * channelNum);
639
640 double valueMin = static_cast<double>(cmin);
641 double valueMax = static_cast<double>(cmax);
642 double stepX = (valueMax - valueMin) / static_cast<double>(width);
643 double stepY = (valueMax - valueMin) / static_cast<double>(height);
644
645 switch (type)
646 {
647 case CL_HALF_FLOAT: {
648 double valueAdd = static_cast<double>(add);
649
650 for (unsigned int i = 0; i < height; ++i)
651 {
652 double valueY = static_cast<double>(stepY * i);
653 for (unsigned int j = 0; j < width; ++j)
654 {
655 double valueX = static_cast<double>(stepX * j);
656 switch (channelNum)
657 {
658 case 1:
659 data.push_back(convert_float_to_half(
660 static_cast<float>(valueMin + valueX / 2
661 + valueY / 2 + valueAdd)));
662 break;
663 case 2:
664 data.push_back(
665 convert_float_to_half(static_cast<float>(
666 valueMin + valueX + valueAdd)));
667 data.push_back(
668 convert_float_to_half(static_cast<float>(
669 valueMin + valueY + valueAdd)));
670 break;
671 case 4:
672 data.push_back(
673 convert_float_to_half(static_cast<float>(
674 valueMin + valueX + valueAdd)));
675 data.push_back(
676 convert_float_to_half(static_cast<float>(
677 valueMin + valueY + valueAdd)));
678 data.push_back(
679 convert_float_to_half(static_cast<float>(
680 valueMin + valueX / 2 + valueAdd)));
681 data.push_back(
682 convert_float_to_half(static_cast<float>(
683 valueMin + valueY / 2 + valueAdd)));
684 break;
685 default:
686 log_error(
687 "DataGenerate(): invalid channel number!");
688 return;
689 break;
690 }
691 }
692 }
693 break;
694 }
695 case CL_UNORM_INT16: {
696 double range = 65535;
697 double valueAdd = static_cast<double>(add * range);
698
699 for (unsigned int i = 0; i < height; ++i)
700 {
701 double valueY = static_cast<double>(stepY * i * range);
702 for (unsigned int j = 0; j < width; ++j)
703 {
704 double valueX = static_cast<double>(stepX * j * range);
705 switch (channelNum)
706 {
707 case 1:
708 data.push_back(static_cast<cl_ushort>(
709 valueMin + valueX / 2 + valueY / 2 + valueAdd));
710 break;
711 case 2:
712 data.push_back(static_cast<cl_ushort>(
713 valueMin + valueX + valueAdd));
714 data.push_back(static_cast<cl_ushort>(
715 valueMin + valueY + valueAdd));
716 break;
717 case 4:
718 data.push_back(static_cast<cl_ushort>(
719 valueMin + valueX + valueAdd));
720 data.push_back(static_cast<cl_ushort>(
721 valueMin + valueY + valueAdd));
722 data.push_back(static_cast<cl_ushort>(
723 valueMin + valueX / 2 + valueAdd));
724 data.push_back(static_cast<cl_ushort>(
725 valueMin + valueY / 2 + valueAdd));
726 break;
727 default:
728 log_error(
729 "DataGenerate(): invalid channel number!");
730 return;
731 break;
732 }
733 }
734 }
735 }
736 break;
737 default:
738 log_error("DataGenerate(): unknown data type!");
739 return;
740 break;
741 }
742 }
743
DataGenerate(TSurfaceFormat surfaceFormat,cl_channel_type type,std::vector<cl_uchar> & data,unsigned int width,unsigned int height,unsigned int channelNum,float cmin,float cmax,float add)744 void DataGenerate(TSurfaceFormat surfaceFormat, cl_channel_type type,
745 std::vector<cl_uchar> &data, unsigned int width,
746 unsigned int height, unsigned int channelNum,
747 float cmin /*= 0.0f*/, float cmax /*= 1.0f*/,
748 float add /*= 0.0f*/)
749 {
750 data.clear();
751 data.reserve(width * height * channelNum);
752
753 double valueMin = static_cast<double>(cmin);
754 double valueMax = static_cast<double>(cmax);
755 double stepX = (valueMax - valueMin) / static_cast<double>(width);
756 double stepY = (valueMax - valueMin) / static_cast<double>(height);
757
758 double range = 255;
759 double valueAdd = static_cast<double>(add * range);
760
761 for (unsigned int i = 0; i < height; ++i)
762 {
763 double valueY = static_cast<double>(stepY * i * range);
764 for (unsigned int j = 0; j < width; ++j)
765 {
766 double valueX = static_cast<double>(stepX * j * range);
767 switch (channelNum)
768 {
769 case 1:
770 data.push_back(static_cast<cl_uchar>(
771 valueMin + valueX / 2 + valueY / 2 + valueAdd));
772 break;
773 case 2:
774 data.push_back(
775 static_cast<cl_uchar>(valueMin + valueX + valueAdd));
776 data.push_back(
777 static_cast<cl_uchar>(valueMin + valueY + valueAdd));
778 break;
779 case 4:
780 data.push_back(
781 static_cast<cl_uchar>(valueMin + valueX + valueAdd));
782 data.push_back(
783 static_cast<cl_uchar>(valueMin + valueY + valueAdd));
784 data.push_back(static_cast<cl_uchar>(valueMin + valueX / 2
785 + valueAdd));
786 if (surfaceFormat == SURFACE_FORMAT_X8R8G8B8)
787 data.push_back(static_cast<cl_uchar>(0xff));
788 else
789 data.push_back(static_cast<cl_uchar>(
790 valueMin + valueY / 2 + valueAdd));
791 break;
792 default:
793 log_error("DataGenerate(): invalid channel number!");
794 return;
795 break;
796 }
797 }
798 }
799 }
800
DataCompare(TSurfaceFormat surfaceFormat,cl_channel_type type,const std::vector<float> & dataTest,const std::vector<float> & dataExp,unsigned int width,unsigned int height,unsigned int channelNum)801 bool DataCompare(TSurfaceFormat surfaceFormat, cl_channel_type type,
802 const std::vector<float> &dataTest,
803 const std::vector<float> &dataExp, unsigned int width,
804 unsigned int height, unsigned int channelNum)
805 {
806 float epsilon = 0.000001f;
807 for (unsigned int i = 0; i < height; ++i)
808 {
809 unsigned int offset = i * width * channelNum;
810 for (unsigned int j = 0; j < width; ++j)
811 {
812 for (unsigned planeIdx = 0; planeIdx < channelNum; ++planeIdx)
813 {
814 if (abs(dataTest.at(offset + j * channelNum + planeIdx)
815 - dataExp.at(offset + j * channelNum + planeIdx))
816 > epsilon)
817 {
818 log_error(
819 "Tested image is different than reference (x,y,plane) "
820 "= (%i,%i,%i), test value = %f, expected value = %f\n",
821 j, i, planeIdx,
822 dataTest[offset + j * channelNum + planeIdx],
823 dataExp[offset + j * channelNum + planeIdx]);
824 return false;
825 }
826 }
827 }
828 }
829
830 return true;
831 }
832
DataCompare(TSurfaceFormat surfaceFormat,cl_channel_type type,const std::vector<cl_half> & dataTest,const std::vector<cl_half> & dataExp,unsigned int width,unsigned int height,unsigned int channelNum)833 bool DataCompare(TSurfaceFormat surfaceFormat, cl_channel_type type,
834 const std::vector<cl_half> &dataTest,
835 const std::vector<cl_half> &dataExp, unsigned int width,
836 unsigned int height, unsigned int channelNum)
837 {
838 switch (type)
839 {
840 case CL_HALF_FLOAT: {
841 float epsilon = 0.001f;
842 for (unsigned int i = 0; i < height; ++i)
843 {
844 unsigned int offset = i * width * channelNum;
845 for (unsigned int j = 0; j < width; ++j)
846 {
847 for (unsigned planeIdx = 0; planeIdx < channelNum;
848 ++planeIdx)
849 {
850 float test = cl_half_to_float(
851 dataTest.at(offset + j * channelNum + planeIdx));
852 float ref = cl_half_to_float(
853 dataExp.at(offset + j * channelNum + planeIdx));
854 if (abs(test - ref) > epsilon)
855 {
856 log_error("Tested image is different than "
857 "reference (x,y,plane) = "
858 "(%i,%i,%i), test value = %f, expected "
859 "value = %f\n",
860 j, i, planeIdx, test, ref);
861 return false;
862 }
863 }
864 }
865 }
866 }
867 break;
868 case CL_UNORM_INT16: {
869 cl_ushort epsilon = 1;
870 for (unsigned int i = 0; i < height; ++i)
871 {
872 unsigned int offset = i * width * channelNum;
873 for (unsigned int j = 0; j < width; ++j)
874 {
875 for (unsigned planeIdx = 0; planeIdx < channelNum;
876 ++planeIdx)
877 {
878 cl_ushort test =
879 dataTest.at(offset + j * channelNum + planeIdx);
880 cl_ushort ref =
881 dataExp.at(offset + j * channelNum + planeIdx);
882 if (abs(test - ref) > epsilon)
883 {
884 log_error("Tested image is different than "
885 "reference (x,y,plane) = (%i,%i,%i), "
886 "test value = %i, expected value = %i\n",
887 j, i, planeIdx, test, ref);
888 return false;
889 }
890 }
891 }
892 }
893 }
894 break;
895 default:
896 log_error("DataCompare(): Invalid data format!");
897 return false;
898 break;
899 }
900
901 return true;
902 }
903
DataCompare(TSurfaceFormat surfaceFormat,cl_channel_type type,const std::vector<cl_uchar> & dataTest,const std::vector<cl_uchar> & dataExp,unsigned int width,unsigned int height,unsigned int planeNum)904 bool DataCompare(TSurfaceFormat surfaceFormat, cl_channel_type type,
905 const std::vector<cl_uchar> &dataTest,
906 const std::vector<cl_uchar> &dataExp, unsigned int width,
907 unsigned int height, unsigned int planeNum)
908 {
909 for (unsigned int i = 0; i < height; ++i)
910 {
911 unsigned int offset = i * width * planeNum;
912 for (unsigned int j = 0; j < width; ++j)
913 {
914 for (unsigned planeIdx = 0; planeIdx < planeNum; ++planeIdx)
915 {
916 if (surfaceFormat == SURFACE_FORMAT_X8R8G8B8 && planeIdx == 3)
917 continue;
918
919 cl_uchar test = dataTest.at(offset + j * planeNum + planeIdx);
920 cl_uchar ref = dataExp.at(offset + j * planeNum + planeIdx);
921 if (test != ref)
922 {
923 log_error(
924 "Tested image is different than reference (x,y,plane) "
925 "= (%i,%i,%i), test value = %i, expected value = %i\n",
926 j, i, planeIdx, test, ref);
927 return false;
928 }
929 }
930 }
931 }
932
933 return true;
934 }
935
GetImageInfo(cl_mem object,cl_image_format formatExp,size_t elementSizeExp,size_t rowPitchExp,size_t slicePitchExp,size_t widthExp,size_t heightExp,size_t depthExp,unsigned int planeExp)936 bool GetImageInfo(cl_mem object, cl_image_format formatExp,
937 size_t elementSizeExp, size_t rowPitchExp,
938 size_t slicePitchExp, size_t widthExp, size_t heightExp,
939 size_t depthExp, unsigned int planeExp)
940 {
941 bool result = true;
942
943 cl_image_format format;
944 if (clGetImageInfo(object, CL_IMAGE_FORMAT, sizeof(cl_image_format),
945 &format, 0)
946 != CL_SUCCESS)
947 {
948 log_error("clGetImageInfo(CL_IMAGE_FORMAT) failed\n");
949 result = false;
950 }
951
952 if (formatExp.image_channel_order != format.image_channel_order
953 || formatExp.image_channel_data_type != format.image_channel_data_type)
954 {
955 log_error("Value of CL_IMAGE_FORMAT is different than expected\n");
956 result = false;
957 }
958
959 size_t elementSize = 0;
960 if (clGetImageInfo(object, CL_IMAGE_ELEMENT_SIZE, sizeof(size_t),
961 &elementSize, 0)
962 != CL_SUCCESS)
963 {
964 log_error("clGetImageInfo(CL_IMAGE_ELEMENT_SIZE) failed\n");
965 result = false;
966 }
967
968 if (elementSizeExp != elementSize)
969 {
970 log_error("Value of CL_IMAGE_ELEMENT_SIZE is different than expected "
971 "(size: %i, exp size: %i)\n",
972 elementSize, elementSizeExp);
973 result = false;
974 }
975
976 size_t rowPitch = 0;
977 if (clGetImageInfo(object, CL_IMAGE_ROW_PITCH, sizeof(size_t), &rowPitch, 0)
978 != CL_SUCCESS)
979 {
980 log_error("clGetImageInfo(CL_IMAGE_ROW_PITCH) failed\n");
981 result = false;
982 }
983
984 if ((rowPitchExp == 0 && rowPitchExp != rowPitch)
985 || (rowPitchExp > 0 && rowPitchExp > rowPitch))
986 {
987 log_error("Value of CL_IMAGE_ROW_PITCH is different than expected "
988 "(size: %i, exp size: %i)\n",
989 rowPitch, rowPitchExp);
990 result = false;
991 }
992
993 size_t slicePitch = 0;
994 if (clGetImageInfo(object, CL_IMAGE_SLICE_PITCH, sizeof(size_t),
995 &slicePitch, 0)
996 != CL_SUCCESS)
997 {
998 log_error("clGetImageInfo(CL_IMAGE_SLICE_PITCH) failed\n");
999 result = false;
1000 }
1001
1002 if ((slicePitchExp == 0 && slicePitchExp != slicePitch)
1003 || (slicePitchExp > 0 && slicePitchExp > slicePitch))
1004 {
1005 log_error("Value of CL_IMAGE_SLICE_PITCH is different than expected "
1006 "(size: %i, exp size: %i)\n",
1007 slicePitch, slicePitchExp);
1008 result = false;
1009 }
1010
1011 size_t width = 0;
1012 if (clGetImageInfo(object, CL_IMAGE_WIDTH, sizeof(size_t), &width, 0)
1013 != CL_SUCCESS)
1014 {
1015 log_error("clGetImageInfo(CL_IMAGE_WIDTH) failed\n");
1016 result = false;
1017 }
1018
1019 if (widthExp != width)
1020 {
1021 log_error("Value of CL_IMAGE_WIDTH is different than expected (size: "
1022 "%i, exp size: %i)\n",
1023 width, widthExp);
1024 result = false;
1025 }
1026
1027 size_t height = 0;
1028 if (clGetImageInfo(object, CL_IMAGE_HEIGHT, sizeof(size_t), &height, 0)
1029 != CL_SUCCESS)
1030 {
1031 log_error("clGetImageInfo(CL_IMAGE_HEIGHT) failed\n");
1032 result = false;
1033 }
1034
1035 if (heightExp != height)
1036 {
1037 log_error("Value of CL_IMAGE_HEIGHT is different than expected (size: "
1038 "%i, exp size: %i)\n",
1039 height, heightExp);
1040 result = false;
1041 }
1042
1043 size_t depth = 0;
1044 if (clGetImageInfo(object, CL_IMAGE_DEPTH, sizeof(size_t), &depth, 0)
1045 != CL_SUCCESS)
1046 {
1047 log_error("clGetImageInfo(CL_IMAGE_DEPTH) failed\n");
1048 result = false;
1049 }
1050
1051 if (depthExp != depth)
1052 {
1053 log_error("Value of CL_IMAGE_DEPTH is different than expected (size: "
1054 "%i, exp size: %i)\n",
1055 depth, depthExp);
1056 result = false;
1057 }
1058
1059 unsigned int plane = 99;
1060 size_t paramSize = 0;
1061 if (clGetImageInfo(object, CL_IMAGE_DX9_MEDIA_PLANE_KHR,
1062 sizeof(unsigned int), &plane, ¶mSize)
1063 != CL_SUCCESS)
1064 {
1065 log_error("clGetImageInfo(CL_IMAGE_MEDIA_SURFACE_PLANE_KHR) failed\n");
1066 result = false;
1067 }
1068
1069 if (planeExp != plane)
1070 {
1071 log_error("Value of CL_IMAGE_MEDIA_SURFACE_PLANE_KHR is different than "
1072 "expected (plane: %i, exp plane: %i)\n",
1073 plane, planeExp);
1074 result = false;
1075 }
1076
1077 return result;
1078 }
1079
GetMemObjInfo(cl_mem object,cl_dx9_media_adapter_type_khr adapterType,std::auto_ptr<CSurfaceWrapper> & surface,void * shareHandleExp)1080 bool GetMemObjInfo(cl_mem object, cl_dx9_media_adapter_type_khr adapterType,
1081 std::auto_ptr<CSurfaceWrapper> &surface,
1082 void *shareHandleExp)
1083 {
1084 bool result = true;
1085 switch (adapterType)
1086 {
1087 case CL_ADAPTER_D3D9_KHR:
1088 case CL_ADAPTER_D3D9EX_KHR:
1089 case CL_ADAPTER_DXVA_KHR: {
1090 #if defined(_WIN32)
1091 cl_dx9_surface_info_khr surfaceInfo;
1092 #else
1093 void *surfaceInfo = 0;
1094 return false;
1095 #endif
1096 size_t paramSize = 0;
1097 if (clGetMemObjectInfo(object, CL_MEM_DX9_MEDIA_SURFACE_INFO_KHR,
1098 sizeof(surfaceInfo), &surfaceInfo,
1099 ¶mSize)
1100 != CL_SUCCESS)
1101 {
1102 log_error("clGetImageInfo(CL_MEM_DX9_MEDIA_SURFACE_INFO_KHR) "
1103 "failed\n");
1104 result = false;
1105 }
1106
1107 #if defined(_WIN32)
1108 CD3D9SurfaceWrapper *d3d9Surface =
1109 static_cast<CD3D9SurfaceWrapper *>(surface.get());
1110 if (*d3d9Surface != surfaceInfo.resource)
1111 {
1112 log_error(
1113 "Invalid resource for CL_MEM_DX9_MEDIA_SURFACE_INFO_KHR\n");
1114 result = false;
1115 }
1116
1117 if (shareHandleExp != surfaceInfo.shared_handle)
1118 {
1119 log_error("Invalid shared handle for "
1120 "CL_MEM_DX9_MEDIA_SURFACE_INFO_KHR\n");
1121 result = false;
1122 }
1123 #else
1124 return false;
1125 #endif
1126
1127 if (paramSize != sizeof(surfaceInfo))
1128 {
1129 log_error("Invalid CL_MEM_DX9_MEDIA_SURFACE_INFO_KHR parameter "
1130 "size: %i, expected: %i\n",
1131 paramSize, sizeof(surfaceInfo));
1132 result = false;
1133 }
1134
1135 paramSize = 0;
1136 cl_dx9_media_adapter_type_khr mediaAdapterType;
1137 if (clGetMemObjectInfo(object, CL_MEM_DX9_MEDIA_ADAPTER_TYPE_KHR,
1138 sizeof(mediaAdapterType), &mediaAdapterType,
1139 ¶mSize)
1140 != CL_SUCCESS)
1141 {
1142 log_error("clGetImageInfo(CL_MEM_DX9_MEDIA_ADAPTER_TYPE_KHR) "
1143 "failed\n");
1144 result = false;
1145 }
1146
1147 if (adapterType != mediaAdapterType)
1148 {
1149 log_error("Invalid media adapter type for "
1150 "CL_MEM_DX9_MEDIA_ADAPTER_TYPE_KHR\n");
1151 result = false;
1152 }
1153
1154 if (paramSize != sizeof(mediaAdapterType))
1155 {
1156 log_error("Invalid CL_MEM_DX9_MEDIA_ADAPTER_TYPE_KHR parameter "
1157 "size: %i, expected: %i\n",
1158 paramSize, sizeof(mediaAdapterType));
1159 result = false;
1160 }
1161 }
1162 break;
1163 default:
1164 log_error("GetMemObjInfo(): Unknown adapter type!\n");
1165 return false;
1166 break;
1167 }
1168
1169 return result;
1170 }
1171
ImageInfoVerify(cl_dx9_media_adapter_type_khr adapterType,const std::vector<cl_mem> & memObjList,unsigned int width,unsigned int height,std::auto_ptr<CSurfaceWrapper> & surface,void * sharedHandle)1172 bool ImageInfoVerify(cl_dx9_media_adapter_type_khr adapterType,
1173 const std::vector<cl_mem> &memObjList, unsigned int width,
1174 unsigned int height,
1175 std::auto_ptr<CSurfaceWrapper> &surface,
1176 void *sharedHandle)
1177 {
1178 if (memObjList.size() != 2 && memObjList.size() != 3)
1179 {
1180 log_error("ImageInfoVerify(): Invalid object list parameter\n");
1181 return false;
1182 }
1183
1184 cl_image_format formatPlane;
1185 formatPlane.image_channel_data_type = CL_UNORM_INT8;
1186 formatPlane.image_channel_order = CL_R;
1187
1188 // plane 0 verification
1189 if (!GetImageInfo(memObjList[0], formatPlane, sizeof(cl_uchar),
1190 width * sizeof(cl_uchar), 0, width, height, 0, 0))
1191 {
1192 log_error("clGetImageInfo failed\n");
1193 return false;
1194 }
1195
1196 switch (memObjList.size())
1197 {
1198 case 2: {
1199 formatPlane.image_channel_data_type = CL_UNORM_INT8;
1200 formatPlane.image_channel_order = CL_RG;
1201 if (!GetImageInfo(memObjList[1], formatPlane, sizeof(cl_uchar) * 2,
1202 width * sizeof(cl_uchar), 0, width / 2,
1203 height / 2, 0, 1))
1204 {
1205 log_error("clGetImageInfo failed\n");
1206 return false;
1207 }
1208 }
1209 break;
1210 case 3: {
1211 if (!GetImageInfo(memObjList[1], formatPlane, sizeof(cl_uchar),
1212 width * sizeof(cl_uchar) / 2, 0, width / 2,
1213 height / 2, 0, 1))
1214 {
1215 log_error("clGetImageInfo failed\n");
1216 return false;
1217 }
1218
1219 if (!GetImageInfo(memObjList[2], formatPlane, sizeof(cl_uchar),
1220 width * sizeof(cl_uchar) / 2, 0, width / 2,
1221 height / 2, 0, 2))
1222 {
1223 log_error("clGetImageInfo failed\n");
1224 return false;
1225 }
1226 }
1227 break;
1228 default:
1229 log_error("ImageInfoVerify(): Invalid object list parameter\n");
1230 return false;
1231 break;
1232 }
1233
1234 for (size_t i = 0; i < memObjList.size(); ++i)
1235 {
1236 if (!GetMemObjInfo(memObjList[i], adapterType, surface, sharedHandle))
1237 {
1238 log_error("clGetMemObjInfo(%i) failed\n", i);
1239 return false;
1240 }
1241 }
1242
1243 return true;
1244 }
1245
ImageFormatCheck(cl_context context,cl_mem_object_type imageType,const cl_image_format imageFormatCheck)1246 bool ImageFormatCheck(cl_context context, cl_mem_object_type imageType,
1247 const cl_image_format imageFormatCheck)
1248 {
1249 cl_uint imageFormatsNum = 0;
1250 cl_int error = clGetSupportedImageFormats(
1251 context, CL_MEM_READ_WRITE, imageType, 0, 0, &imageFormatsNum);
1252 if (error != CL_SUCCESS)
1253 {
1254 log_error("clGetSupportedImageFormats failed\n");
1255 return false;
1256 }
1257
1258 if (imageFormatsNum < 1)
1259 {
1260 log_error("Invalid image format number returned by "
1261 "clGetSupportedImageFormats\n");
1262 return false;
1263 }
1264
1265 std::vector<cl_image_format> imageFormats(imageFormatsNum);
1266 error = clGetSupportedImageFormats(context, CL_MEM_READ_WRITE, imageType,
1267 imageFormatsNum, &imageFormats[0], 0);
1268 if (error != CL_SUCCESS)
1269 {
1270 log_error("clGetSupportedImageFormats failed\n");
1271 return false;
1272 }
1273
1274 for (cl_uint i = 0; i < imageFormatsNum; ++i)
1275 {
1276 if (imageFormats[i].image_channel_data_type
1277 == imageFormatCheck.image_channel_data_type
1278 && imageFormats[i].image_channel_order
1279 == imageFormatCheck.image_channel_order)
1280 {
1281 return true;
1282 }
1283 }
1284
1285 return false;
1286 }
1287
ChannelNum(TSurfaceFormat surfaceFormat)1288 unsigned int ChannelNum(TSurfaceFormat surfaceFormat)
1289 {
1290 switch (surfaceFormat)
1291 {
1292 case SURFACE_FORMAT_R32F:
1293 case SURFACE_FORMAT_R16F:
1294 case SURFACE_FORMAT_L16:
1295 case SURFACE_FORMAT_A8:
1296 case SURFACE_FORMAT_L8: return 1; break;
1297 case SURFACE_FORMAT_G32R32F:
1298 case SURFACE_FORMAT_G16R16F:
1299 case SURFACE_FORMAT_G16R16:
1300 case SURFACE_FORMAT_A8L8: return 2; break;
1301 case SURFACE_FORMAT_NV12:
1302 case SURFACE_FORMAT_YV12: return 3; break;
1303 case SURFACE_FORMAT_A32B32G32R32F:
1304 case SURFACE_FORMAT_A16B16G16R16F:
1305 case SURFACE_FORMAT_A16B16G16R16:
1306 case SURFACE_FORMAT_A8B8G8R8:
1307 case SURFACE_FORMAT_X8B8G8R8:
1308 case SURFACE_FORMAT_A8R8G8B8:
1309 case SURFACE_FORMAT_X8R8G8B8: return 4; break;
1310 default:
1311 log_error("ChannelNum(): unknown surface format!\n");
1312 return 0;
1313 break;
1314 }
1315 }
1316
PlanesNum(TSurfaceFormat surfaceFormat)1317 unsigned int PlanesNum(TSurfaceFormat surfaceFormat)
1318 {
1319 switch (surfaceFormat)
1320 {
1321 case SURFACE_FORMAT_R32F:
1322 case SURFACE_FORMAT_R16F:
1323 case SURFACE_FORMAT_L16:
1324 case SURFACE_FORMAT_A8:
1325 case SURFACE_FORMAT_L8:
1326 case SURFACE_FORMAT_G32R32F:
1327 case SURFACE_FORMAT_G16R16F:
1328 case SURFACE_FORMAT_G16R16:
1329 case SURFACE_FORMAT_A8L8:
1330 case SURFACE_FORMAT_A32B32G32R32F:
1331 case SURFACE_FORMAT_A16B16G16R16F:
1332 case SURFACE_FORMAT_A16B16G16R16:
1333 case SURFACE_FORMAT_A8B8G8R8:
1334 case SURFACE_FORMAT_X8B8G8R8:
1335 case SURFACE_FORMAT_A8R8G8B8:
1336 case SURFACE_FORMAT_X8R8G8B8: return 1; break;
1337 case SURFACE_FORMAT_NV12: return 2; break;
1338 case SURFACE_FORMAT_YV12: return 3; break;
1339 default:
1340 log_error("PlanesNum(): unknown surface format!\n");
1341 return 0;
1342 break;
1343 }
1344 }
1345
1346 #if defined(_WIN32)
SurfaceFormatToD3D(TSurfaceFormat surfaceFormat)1347 D3DFORMAT SurfaceFormatToD3D(TSurfaceFormat surfaceFormat)
1348 {
1349 switch (surfaceFormat)
1350 {
1351 case SURFACE_FORMAT_R32F: return D3DFMT_R32F; break;
1352 case SURFACE_FORMAT_R16F: return D3DFMT_R16F; break;
1353 case SURFACE_FORMAT_L16: return D3DFMT_L16; break;
1354 case SURFACE_FORMAT_A8: return D3DFMT_A8; break;
1355 case SURFACE_FORMAT_L8: return D3DFMT_L8; break;
1356 case SURFACE_FORMAT_G32R32F: return D3DFMT_G32R32F; break;
1357 case SURFACE_FORMAT_G16R16F: return D3DFMT_G16R16F; break;
1358 case SURFACE_FORMAT_G16R16: return D3DFMT_G16R16; break;
1359 case SURFACE_FORMAT_A8L8: return D3DFMT_A8L8; break;
1360 case SURFACE_FORMAT_A32B32G32R32F: return D3DFMT_A32B32G32R32F; break;
1361 case SURFACE_FORMAT_A16B16G16R16F: return D3DFMT_A16B16G16R16F; break;
1362 case SURFACE_FORMAT_A16B16G16R16: return D3DFMT_A16B16G16R16; break;
1363 case SURFACE_FORMAT_A8B8G8R8: return D3DFMT_A8B8G8R8; break;
1364 case SURFACE_FORMAT_X8B8G8R8: return D3DFMT_X8B8G8R8; break;
1365 case SURFACE_FORMAT_A8R8G8B8: return D3DFMT_A8R8G8B8; break;
1366 case SURFACE_FORMAT_X8R8G8B8: return D3DFMT_X8R8G8B8; break;
1367 case SURFACE_FORMAT_NV12:
1368 return static_cast<D3DFORMAT>(MAKEFOURCC('N', 'V', '1', '2'));
1369 break;
1370 case SURFACE_FORMAT_YV12:
1371 return static_cast<D3DFORMAT>(MAKEFOURCC('Y', 'V', '1', '2'));
1372 break;
1373 default:
1374 log_error("SurfaceFormatToD3D(): unknown surface format!\n");
1375 return D3DFMT_R32F;
1376 break;
1377 }
1378 }
1379 #endif
1380
DeviceCreate(cl_dx9_media_adapter_type_khr adapterType,std::auto_ptr<CDeviceWrapper> & device)1381 bool DeviceCreate(cl_dx9_media_adapter_type_khr adapterType,
1382 std::auto_ptr<CDeviceWrapper> &device)
1383 {
1384 switch (adapterType)
1385 {
1386 #if defined(_WIN32)
1387 case CL_ADAPTER_D3D9_KHR:
1388 device = std::auto_ptr<CDeviceWrapper>(new CD3D9Wrapper());
1389 break;
1390 case CL_ADAPTER_D3D9EX_KHR:
1391 device = std::auto_ptr<CDeviceWrapper>(new CD3D9ExWrapper());
1392 break;
1393 case CL_ADAPTER_DXVA_KHR:
1394 device = std::auto_ptr<CDeviceWrapper>(new CDXVAWrapper());
1395 break;
1396 #endif
1397 default:
1398 log_error("DeviceCreate(): Unknown adapter type!\n");
1399 return false;
1400 break;
1401 }
1402
1403 return device->Status();
1404 }
1405
SurfaceFormatCheck(cl_dx9_media_adapter_type_khr adapterType,const CDeviceWrapper & device,TSurfaceFormat surfaceFormat)1406 bool SurfaceFormatCheck(cl_dx9_media_adapter_type_khr adapterType,
1407 const CDeviceWrapper &device,
1408 TSurfaceFormat surfaceFormat)
1409 {
1410 switch (adapterType)
1411 {
1412 #if defined(_WIN32)
1413 case CL_ADAPTER_D3D9_KHR:
1414 case CL_ADAPTER_D3D9EX_KHR:
1415 case CL_ADAPTER_DXVA_KHR: {
1416 D3DFORMAT d3dFormat = SurfaceFormatToD3D(surfaceFormat);
1417 LPDIRECT3D9 d3d9 = static_cast<LPDIRECT3D9>(device.D3D());
1418 D3DDISPLAYMODE d3ddm;
1419 d3d9->GetAdapterDisplayMode(device.AdapterIdx(), &d3ddm);
1420
1421 if (FAILED(d3d9->CheckDeviceFormat(D3DADAPTER_DEFAULT,
1422 D3DDEVTYPE_HAL, d3ddm.Format, 0,
1423 D3DRTYPE_SURFACE, d3dFormat)))
1424 return false;
1425 }
1426 break;
1427 #endif
1428 default:
1429 log_error("SurfaceFormatCheck(): Unknown adapter type!\n");
1430 return false;
1431 break;
1432 }
1433
1434 return true;
1435 }
1436
SurfaceFormatToOCL(TSurfaceFormat surfaceFormat,cl_image_format & format)1437 bool SurfaceFormatToOCL(TSurfaceFormat surfaceFormat, cl_image_format &format)
1438 {
1439 switch (surfaceFormat)
1440 {
1441 case SURFACE_FORMAT_R32F:
1442 format.image_channel_order = CL_R;
1443 format.image_channel_data_type = CL_FLOAT;
1444 break;
1445 case SURFACE_FORMAT_R16F:
1446 format.image_channel_order = CL_R;
1447 format.image_channel_data_type = CL_HALF_FLOAT;
1448 break;
1449 case SURFACE_FORMAT_L16:
1450 format.image_channel_order = CL_R;
1451 format.image_channel_data_type = CL_UNORM_INT16;
1452 break;
1453 case SURFACE_FORMAT_A8:
1454 format.image_channel_order = CL_A;
1455 format.image_channel_data_type = CL_UNORM_INT8;
1456 break;
1457 case SURFACE_FORMAT_L8:
1458 format.image_channel_order = CL_R;
1459 format.image_channel_data_type = CL_UNORM_INT8;
1460 break;
1461 case SURFACE_FORMAT_G32R32F:
1462 format.image_channel_order = CL_RG;
1463 format.image_channel_data_type = CL_FLOAT;
1464 break;
1465 case SURFACE_FORMAT_G16R16F:
1466 format.image_channel_order = CL_RG;
1467 format.image_channel_data_type = CL_HALF_FLOAT;
1468 break;
1469 case SURFACE_FORMAT_G16R16:
1470 format.image_channel_order = CL_RG;
1471 format.image_channel_data_type = CL_UNORM_INT16;
1472 break;
1473 case SURFACE_FORMAT_A8L8:
1474 format.image_channel_order = CL_RG;
1475 format.image_channel_data_type = CL_UNORM_INT8;
1476 break;
1477 case SURFACE_FORMAT_A32B32G32R32F:
1478 format.image_channel_order = CL_RGBA;
1479 format.image_channel_data_type = CL_FLOAT;
1480 break;
1481 case SURFACE_FORMAT_A16B16G16R16F:
1482 format.image_channel_order = CL_RGBA;
1483 format.image_channel_data_type = CL_HALF_FLOAT;
1484 break;
1485 case SURFACE_FORMAT_A16B16G16R16:
1486 format.image_channel_order = CL_RGBA;
1487 format.image_channel_data_type = CL_UNORM_INT16;
1488 break;
1489 case SURFACE_FORMAT_A8B8G8R8:
1490 format.image_channel_order = CL_RGBA;
1491 format.image_channel_data_type = CL_UNORM_INT8;
1492 break;
1493 case SURFACE_FORMAT_X8B8G8R8:
1494 format.image_channel_order = CL_RGBA;
1495 format.image_channel_data_type = CL_UNORM_INT8;
1496 break;
1497 case SURFACE_FORMAT_A8R8G8B8:
1498 format.image_channel_order = CL_BGRA;
1499 format.image_channel_data_type = CL_UNORM_INT8;
1500 break;
1501 case SURFACE_FORMAT_X8R8G8B8:
1502 format.image_channel_order = CL_BGRA;
1503 format.image_channel_data_type = CL_UNORM_INT8;
1504 break;
1505 case SURFACE_FORMAT_NV12:
1506 format.image_channel_order = CL_R;
1507 format.image_channel_data_type = CL_UNORM_INT8;
1508 break;
1509 case SURFACE_FORMAT_YV12:
1510 format.image_channel_order = CL_R;
1511 format.image_channel_data_type = CL_UNORM_INT8;
1512 break;
1513 default:
1514 log_error("SurfaceFormatToOCL(): Unknown surface format!\n");
1515 return false;
1516 break;
1517 }
1518
1519 return true;
1520 }
1521
SurfaceFormatToString(TSurfaceFormat surfaceFormat,std::string & str)1522 void SurfaceFormatToString(TSurfaceFormat surfaceFormat, std::string &str)
1523 {
1524 switch (surfaceFormat)
1525 {
1526 case SURFACE_FORMAT_R32F: str = "R32F"; break;
1527 case SURFACE_FORMAT_R16F: str = "R16F"; break;
1528 case SURFACE_FORMAT_L16: str = "L16"; break;
1529 case SURFACE_FORMAT_A8: str = "A8"; break;
1530 case SURFACE_FORMAT_L8: str = "L8"; break;
1531 case SURFACE_FORMAT_G32R32F: str = "G32R32F"; break;
1532 case SURFACE_FORMAT_G16R16F: str = "G16R16F"; break;
1533 case SURFACE_FORMAT_G16R16: str = "G16R16"; break;
1534 case SURFACE_FORMAT_A8L8: str = "A8L8"; break;
1535 case SURFACE_FORMAT_A32B32G32R32F: str = "A32B32G32R32F"; break;
1536 case SURFACE_FORMAT_A16B16G16R16F: str = "A16B16G16R16F"; break;
1537 case SURFACE_FORMAT_A16B16G16R16: str = "A16B16G16R16"; break;
1538 case SURFACE_FORMAT_A8B8G8R8: str = "A8B8G8R8"; break;
1539 case SURFACE_FORMAT_X8B8G8R8: str = "X8B8G8R8"; break;
1540 case SURFACE_FORMAT_A8R8G8B8: str = "A8R8G8B8"; break;
1541 case SURFACE_FORMAT_X8R8G8B8: str = "X8R8G8B8"; break;
1542 case SURFACE_FORMAT_NV12: str = "NV12"; break;
1543 case SURFACE_FORMAT_YV12: str = "YV12"; break;
1544 default:
1545 log_error("SurfaceFormatToString(): unknown surface format!\n");
1546 str = "unknown";
1547 break;
1548 }
1549 }
1550
MediaSurfaceCreate(cl_dx9_media_adapter_type_khr adapterType,unsigned int width,unsigned int height,TSurfaceFormat surfaceFormat,CDeviceWrapper & device,std::auto_ptr<CSurfaceWrapper> & surface,bool sharedHandle,void ** objectSharedHandle)1551 bool MediaSurfaceCreate(cl_dx9_media_adapter_type_khr adapterType,
1552 unsigned int width, unsigned int height,
1553 TSurfaceFormat surfaceFormat, CDeviceWrapper &device,
1554 std::auto_ptr<CSurfaceWrapper> &surface,
1555 bool sharedHandle, void **objectSharedHandle)
1556 {
1557 switch (adapterType)
1558 {
1559 #if defined(_WIN32)
1560 case CL_ADAPTER_D3D9_KHR: {
1561 surface =
1562 std::auto_ptr<CD3D9SurfaceWrapper>(new CD3D9SurfaceWrapper);
1563 CD3D9SurfaceWrapper *d3dSurface =
1564 static_cast<CD3D9SurfaceWrapper *>(surface.get());
1565 HRESULT hr = 0;
1566 D3DFORMAT d3dFormat = SurfaceFormatToD3D(surfaceFormat);
1567 LPDIRECT3DDEVICE9 d3d9Device = (LPDIRECT3DDEVICE9)device.Device();
1568 hr = d3d9Device->CreateOffscreenPlainSurface(
1569 width, height, d3dFormat, D3DPOOL_DEFAULT, &(*d3dSurface),
1570 sharedHandle ? objectSharedHandle : 0);
1571
1572 if (FAILED(hr))
1573 {
1574 log_error("CreateOffscreenPlainSurface failed\n");
1575 return false;
1576 }
1577 }
1578 break;
1579 case CL_ADAPTER_D3D9EX_KHR: {
1580 surface =
1581 std::auto_ptr<CD3D9SurfaceWrapper>(new CD3D9SurfaceWrapper);
1582 CD3D9SurfaceWrapper *d3dSurface =
1583 static_cast<CD3D9SurfaceWrapper *>(surface.get());
1584 HRESULT hr = 0;
1585 D3DFORMAT d3dFormat = SurfaceFormatToD3D(surfaceFormat);
1586 LPDIRECT3DDEVICE9EX d3d9ExDevice =
1587 (LPDIRECT3DDEVICE9EX)device.Device();
1588 hr = d3d9ExDevice->CreateOffscreenPlainSurface(
1589 width, height, d3dFormat, D3DPOOL_DEFAULT, &(*d3dSurface),
1590 sharedHandle ? objectSharedHandle : 0);
1591
1592 if (FAILED(hr))
1593 {
1594 log_error("CreateOffscreenPlainSurface failed\n");
1595 return false;
1596 }
1597 }
1598 break;
1599 case CL_ADAPTER_DXVA_KHR: {
1600 surface =
1601 std::auto_ptr<CD3D9SurfaceWrapper>(new CD3D9SurfaceWrapper);
1602 CD3D9SurfaceWrapper *d3dSurface =
1603 static_cast<CD3D9SurfaceWrapper *>(surface.get());
1604 HRESULT hr = 0;
1605 D3DFORMAT d3dFormat = SurfaceFormatToD3D(surfaceFormat);
1606 IDXVAHD_Device *dxvaDevice = (IDXVAHD_Device *)device.Device();
1607 hr = dxvaDevice->CreateVideoSurface(
1608 width, height, d3dFormat, D3DPOOL_DEFAULT, 0,
1609 DXVAHD_SURFACE_TYPE_VIDEO_INPUT, 1, &(*d3dSurface),
1610 sharedHandle ? objectSharedHandle : 0);
1611
1612 if (FAILED(hr))
1613 {
1614 log_error("CreateVideoSurface failed\n");
1615 return false;
1616 }
1617 }
1618 break;
1619 #endif
1620 default:
1621 log_error("MediaSurfaceCreate(): Unknown adapter type!\n");
1622 return false;
1623 break;
1624 }
1625
1626 return true;
1627 }
1628
deviceExistForCLTest(cl_platform_id platform,cl_dx9_media_adapter_type_khr media_adapters_type,void * media_adapters,CResult & result,TSharedHandleType sharedHandle)1629 cl_int deviceExistForCLTest(
1630 cl_platform_id platform, cl_dx9_media_adapter_type_khr media_adapters_type,
1631 void *media_adapters, CResult &result,
1632 TSharedHandleType sharedHandle /*default SHARED_HANDLE_ENABLED*/
1633 )
1634 {
1635 cl_int _error;
1636 cl_uint devicesAllNum = 0;
1637 std::string sharedHandleStr =
1638 (sharedHandle == SHARED_HANDLE_ENABLED) ? "yes" : "no";
1639 std::string adapterStr;
1640 AdapterToString(media_adapters_type, adapterStr);
1641
1642 _error = clGetDeviceIDsFromDX9MediaAdapterKHR(
1643 platform, 1, &media_adapters_type, &media_adapters,
1644 CL_PREFERRED_DEVICES_FOR_DX9_MEDIA_ADAPTER_KHR, 0, 0, &devicesAllNum);
1645
1646 if (_error != CL_SUCCESS)
1647 {
1648 if (_error != CL_DEVICE_NOT_FOUND)
1649 {
1650 log_error("clGetDeviceIDsFromDX9MediaAdapterKHR failed: %s\n",
1651 IGetErrorString(_error));
1652 result.ResultSub(CResult::TEST_ERROR);
1653 }
1654 else
1655 {
1656 log_info("Skipping test case, device type is not supported by a "
1657 "device (adapter type: %s, shared handle: %s)\n",
1658 adapterStr.c_str(), sharedHandleStr.c_str());
1659 result.ResultSub(CResult::TEST_NOTSUPPORTED);
1660 }
1661 }
1662
1663 return _error;
1664 }
1665