xref: /aosp_15_r20/external/OpenCL-CTS/test_conformance/extensions/cl_khr_dx9_media_sharing/utils.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 "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, &paramSize)
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                                    &paramSize)
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                                    &paramSize)
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