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 
api_functions(cl_device_id deviceID,cl_context context,cl_command_queue queue,int num_elements,unsigned int iterationNum,unsigned int width,unsigned int height,cl_dx9_media_adapter_type_khr adapterType,TSurfaceFormat surfaceFormat,TSharedHandleType sharedHandle)18 int api_functions(cl_device_id deviceID, cl_context context,
19                   cl_command_queue queue, int num_elements,
20                   unsigned int iterationNum, unsigned int width,
21                   unsigned int height,
22                   cl_dx9_media_adapter_type_khr adapterType,
23                   TSurfaceFormat surfaceFormat, TSharedHandleType sharedHandle)
24 {
25     const unsigned int FRAME_NUM = 2;
26     const cl_uchar MAX_VALUE = 255 / 2;
27     CResult result;
28 
29     // create device
30     std::auto_ptr<CDeviceWrapper> deviceWrapper;
31     if (!DeviceCreate(adapterType, deviceWrapper))
32     {
33         result.ResultSub(CResult::TEST_ERROR);
34         return result.Result();
35     }
36 
37     // generate input and expected data
38     std::vector<std::vector<cl_uchar>> bufferRef1(FRAME_NUM);
39     std::vector<std::vector<cl_uchar>> bufferRef2(FRAME_NUM);
40     std::vector<std::vector<cl_uchar>> bufferRef3(FRAME_NUM);
41     size_t frameSize = width * height * 3 / 2;
42     cl_uchar step = MAX_VALUE / FRAME_NUM;
43     for (size_t i = 0; i < FRAME_NUM; ++i)
44     {
45         if (!YUVGenerate(surfaceFormat, bufferRef1[i], width, height,
46                          static_cast<cl_uchar>(step * i),
47                          static_cast<cl_uchar>(step * (i + 1)))
48             || !YUVGenerate(surfaceFormat, bufferRef2[i], width, height,
49                             static_cast<cl_uchar>(step * i),
50                             static_cast<cl_uchar>(step * (i + 1)), 0.2)
51             || !YUVGenerate(surfaceFormat, bufferRef3[i], width, height,
52                             static_cast<cl_uchar>(step * i),
53                             static_cast<cl_uchar>(step * (i + 1)), 0.4))
54         {
55             result.ResultSub(CResult::TEST_ERROR);
56             return result.Result();
57         }
58     }
59 
60     // iterates through all devices
61     while (deviceWrapper->AdapterNext())
62     {
63         cl_int error;
64         // check if the test can be run on the adapter
65         if (CL_SUCCESS
66             != (error = deviceExistForCLTest(gPlatformIDdetected, adapterType,
67                                              deviceWrapper->Device(), result,
68                                              sharedHandle)))
69         {
70             return result.Result();
71         }
72 
73         if (surfaceFormat != SURFACE_FORMAT_NV12
74             && !SurfaceFormatCheck(adapterType, *deviceWrapper, surfaceFormat))
75         {
76             std::string sharedHandleStr =
77                 (sharedHandle == SHARED_HANDLE_ENABLED) ? "yes" : "no";
78             std::string formatStr;
79             std::string adapterStr;
80             SurfaceFormatToString(surfaceFormat, formatStr);
81             AdapterToString(adapterType, adapterStr);
82             log_info(
83                 "Skipping test case, image format is not supported by a device "
84                 "(adapter type: %s, format: %s, shared handle: %s)\n",
85                 adapterStr.c_str(), formatStr.c_str(), sharedHandleStr.c_str());
86             return result.Result();
87         }
88 
89         void *objectSharedHandle = 0;
90         std::auto_ptr<CSurfaceWrapper> surface;
91 
92         // create surface
93         if (!MediaSurfaceCreate(
94                 adapterType, width, height, surfaceFormat, *deviceWrapper,
95                 surface, (sharedHandle == SHARED_HANDLE_ENABLED) ? true : false,
96                 &objectSharedHandle))
97         {
98             log_error("Media surface creation failed for %i adapter\n",
99                       deviceWrapper->AdapterIdx());
100             result.ResultSub(CResult::TEST_ERROR);
101             return result.Result();
102         }
103 
104         cl_context_properties contextProperties[] = {
105             CL_CONTEXT_PLATFORM,
106             (cl_context_properties)gPlatformIDdetected,
107             AdapterTypeToContextInfo(adapterType),
108             (cl_context_properties)deviceWrapper->Device(),
109             0,
110         };
111 
112         clContextWrapper ctx = clCreateContext(
113             &contextProperties[0], 1, &gDeviceIDdetected, NULL, NULL, &error);
114         if (error != CL_SUCCESS)
115         {
116             log_error("clCreateContext failed: %s\n", IGetErrorString(error));
117             result.ResultSub(CResult::TEST_FAIL);
118             return result.Result();
119         }
120 
121 #if defined(_WIN32)
122         cl_dx9_surface_info_khr surfaceInfo;
123         surfaceInfo.resource =
124             *(static_cast<CD3D9SurfaceWrapper *>(surface.get()));
125         surfaceInfo.shared_handle = objectSharedHandle;
126 #else
127         void *surfaceInfo = 0;
128         return TEST_NOT_IMPLEMENTED;
129 #endif
130 
131         std::vector<cl_mem> memObjList;
132         unsigned int planesNum = PlanesNum(surfaceFormat);
133         std::vector<clMemWrapper> planesList(planesNum);
134         for (unsigned int planeIdx = 0; planeIdx < planesNum; ++planeIdx)
135         {
136             planesList[planeIdx] = clCreateFromDX9MediaSurfaceKHR(
137                 ctx, CL_MEM_READ_WRITE, adapterType, &surfaceInfo, planeIdx,
138                 &error);
139             if (error != CL_SUCCESS)
140             {
141                 log_error(
142                     "clCreateFromDX9MediaSurfaceKHR failed for plane %i: %s\n",
143                     planeIdx, IGetErrorString(error));
144                 result.ResultSub(CResult::TEST_FAIL);
145                 return result.Result();
146             }
147             memObjList.push_back(planesList[planeIdx]);
148         }
149 
150         clCommandQueueWrapper cmdQueue = clCreateCommandQueueWithProperties(
151             ctx, gDeviceIDdetected, 0, &error);
152         if (error != CL_SUCCESS)
153         {
154             log_error("Unable to create command queue: %s\n",
155                       IGetErrorString(error));
156             result.ResultSub(CResult::TEST_FAIL);
157             return result.Result();
158         }
159 
160         if (!ImageInfoVerify(adapterType, memObjList, width, height, surface,
161                              objectSharedHandle))
162         {
163             log_error("Image info verification failed\n");
164             result.ResultSub(CResult::TEST_FAIL);
165         }
166 
167         for (size_t frameIdx = 0; frameIdx < iterationNum; ++frameIdx)
168         {
169             if (!YUVSurfaceSet(surfaceFormat, surface,
170                                bufferRef1[frameIdx % FRAME_NUM], width, height))
171             {
172                 result.ResultSub(CResult::TEST_ERROR);
173                 return result.Result();
174             }
175 
176             error = clEnqueueAcquireDX9MediaSurfacesKHR(
177                 cmdQueue, static_cast<cl_uint>(memObjList.size()),
178                 &memObjList[0], 0, NULL, NULL);
179             if (error != CL_SUCCESS)
180             {
181                 log_error("clEnqueueAcquireDX9MediaSurfacesKHR failed: %s\n",
182                           IGetErrorString(error));
183                 result.ResultSub(CResult::TEST_FAIL);
184                 return result.Result();
185             }
186 
187             { // read operation
188                 std::vector<cl_uchar> out(frameSize, 0);
189                 size_t offset = 0;
190                 size_t origin[3] = { 0, 0, 0 };
191 
192                 for (size_t i = 0; i < memObjList.size(); ++i)
193                 {
194                     size_t planeWidth = (i == 0) ? width : width / 2;
195                     size_t planeHeight = (i == 0) ? height : height / 2;
196                     size_t regionPlane[3] = { planeWidth, planeHeight, 1 };
197 
198                     error = clEnqueueReadImage(cmdQueue, memObjList[i], CL_TRUE,
199                                                origin, regionPlane, 0, 0,
200                                                &out[offset], 0, 0, 0);
201                     if (error != CL_SUCCESS)
202                     {
203                         log_error("clEnqueueReadImage failed: %s\n",
204                                   IGetErrorString(error));
205                         result.ResultSub(CResult::TEST_FAIL);
206                     }
207 
208                     offset += planeWidth * planeHeight;
209                 }
210 
211                 if (!YUVCompare(surfaceFormat, out,
212                                 bufferRef1[frameIdx % FRAME_NUM], width,
213                                 height))
214                 {
215                     log_error("Frame idx: %i, OCL image is different then "
216                               "shared OCL object: clEnqueueReadImage\n",
217                               frameIdx);
218                     result.ResultSub(CResult::TEST_FAIL);
219                 }
220             }
221 
222             { // write operation
223                 size_t offset = 0;
224                 size_t origin[3] = { 0, 0, 0 };
225                 for (size_t i = 0; i < memObjList.size(); ++i)
226                 {
227                     size_t planeWidth = (i == 0) ? width : width / 2;
228                     size_t planeHeight = (i == 0) ? height : height / 2;
229                     size_t regionPlane[3] = { planeWidth, planeHeight, 1 };
230 
231                     error = clEnqueueWriteImage(
232                         cmdQueue, memObjList[i], CL_TRUE, origin, regionPlane,
233                         0, 0, &bufferRef2[frameIdx % FRAME_NUM][offset], 0, 0,
234                         0);
235                     if (error != CL_SUCCESS)
236                     {
237                         log_error("clEnqueueWriteImage failed: %s\n",
238                                   IGetErrorString(error));
239                         result.ResultSub(CResult::TEST_FAIL);
240                     }
241 
242                     offset += planeWidth * planeHeight;
243                 }
244             }
245 
246             { // read operation
247                 std::vector<cl_uchar> out(frameSize, 0);
248                 size_t offset = 0;
249                 size_t origin[3] = { 0, 0, 0 };
250 
251                 for (size_t i = 0; i < memObjList.size(); ++i)
252                 {
253                     size_t planeWidth = (i == 0) ? width : width / 2;
254                     size_t planeHeight = (i == 0) ? height : height / 2;
255                     size_t regionPlane[3] = { planeWidth, planeHeight, 1 };
256 
257                     error = clEnqueueReadImage(cmdQueue, memObjList[i], CL_TRUE,
258                                                origin, regionPlane, 0, 0,
259                                                &out[offset], 0, 0, 0);
260                     if (error != CL_SUCCESS)
261                     {
262                         log_error("clEnqueueReadImage failed: %s\n",
263                                   IGetErrorString(error));
264                         result.ResultSub(CResult::TEST_FAIL);
265                     }
266 
267                     offset += planeWidth * planeHeight;
268                 }
269 
270                 if (!YUVCompare(surfaceFormat, out,
271                                 bufferRef2[frameIdx % FRAME_NUM], width,
272                                 height))
273                 {
274                     log_error("Frame idx: %i, Shared OCL image verification "
275                               "after clEnqueueWriteImage failed\n",
276                               frameIdx);
277                     result.ResultSub(CResult::TEST_FAIL);
278                 }
279             }
280 
281             { // copy operation (shared OCL to OCL)
282                 size_t offset = 0;
283                 size_t origin[3] = { 0, 0, 0 };
284                 std::vector<cl_uchar> out(frameSize, 0);
285                 for (size_t i = 0; i < memObjList.size(); ++i)
286                 {
287                     size_t planeWidth = (i == 0) ? width : width / 2;
288                     size_t planeHeight = (i == 0) ? height : height / 2;
289                     size_t regionPlane[3] = { planeWidth, planeHeight, 1 };
290 
291                     cl_image_format formatPlane;
292                     formatPlane.image_channel_data_type = CL_UNORM_INT8;
293                     formatPlane.image_channel_order =
294                         (surfaceFormat == SURFACE_FORMAT_NV12 && i > 0) ? CL_RG
295                                                                         : CL_R;
296 
297                     cl_image_desc imageDesc = { 0 };
298                     imageDesc.image_type = CL_MEM_OBJECT_IMAGE2D;
299                     imageDesc.image_width = planeWidth;
300                     imageDesc.image_height = planeHeight;
301 
302                     clMemWrapper planeOCL =
303                         clCreateImage(ctx, CL_MEM_READ_WRITE, &formatPlane,
304                                       &imageDesc, 0, &error);
305                     if (error != CL_SUCCESS)
306                     {
307                         log_error("clCreateImage failed: %s\n",
308                                   IGetErrorString(error));
309                         result.ResultSub(CResult::TEST_FAIL);
310                     }
311 
312                     error = clEnqueueCopyImage(cmdQueue, memObjList[i],
313                                                planeOCL, origin, origin,
314                                                regionPlane, 0, 0, 0);
315                     if (error != CL_SUCCESS)
316                     {
317                         log_error("clEnqueueCopyImage failed: %s\n",
318                                   IGetErrorString(error));
319                         result.ResultSub(CResult::TEST_FAIL);
320                     }
321 
322                     error = clEnqueueReadImage(cmdQueue, planeOCL, CL_TRUE,
323                                                origin, regionPlane, 0, 0,
324                                                &out[offset], 0, 0, 0);
325                     if (error != CL_SUCCESS)
326                     {
327                         log_error("clEnqueueReadImage failed: %s\n",
328                                   IGetErrorString(error));
329                         result.ResultSub(CResult::TEST_FAIL);
330                     }
331 
332                     offset += planeWidth * planeHeight;
333                 }
334 
335                 if (!YUVCompare(surfaceFormat, out,
336                                 bufferRef2[frameIdx % FRAME_NUM], width,
337                                 height))
338                 {
339                     log_error(
340                         "Frame idx: %i, OCL image verification after "
341                         "clEnqueueCopyImage (from shared OCL to OCL) failed\n",
342                         frameIdx);
343                     result.ResultSub(CResult::TEST_FAIL);
344                 }
345             }
346 
347             { // copy operation (OCL to shared OCL)
348                 size_t offset = 0;
349                 size_t origin[3] = { 0, 0, 0 };
350                 std::vector<cl_uchar> out(frameSize, 0);
351                 for (size_t i = 0; i < memObjList.size(); ++i)
352                 {
353                     size_t planeWidth = (i == 0) ? width : width / 2;
354                     size_t planeHeight = (i == 0) ? height : height / 2;
355                     size_t regionPlane[3] = { planeWidth, planeHeight, 1 };
356                     size_t pitchSize =
357                         ((surfaceFormat == SURFACE_FORMAT_NV12 && i > 0)
358                              ? width
359                              : planeWidth)
360                         * sizeof(cl_uchar);
361 
362                     cl_image_format formatPlane;
363                     formatPlane.image_channel_data_type = CL_UNORM_INT8;
364                     formatPlane.image_channel_order =
365                         (surfaceFormat == SURFACE_FORMAT_NV12 && i > 0) ? CL_RG
366                                                                         : CL_R;
367 
368                     cl_image_desc imageDesc = { 0 };
369                     imageDesc.image_type = CL_MEM_OBJECT_IMAGE2D;
370                     imageDesc.image_width = planeWidth;
371                     imageDesc.image_height = planeHeight;
372                     imageDesc.image_row_pitch = pitchSize;
373 
374                     clMemWrapper planeOCL = clCreateImage(
375                         ctx, CL_MEM_COPY_HOST_PTR, &formatPlane, &imageDesc,
376                         &bufferRef1[frameIdx % FRAME_NUM][offset], &error);
377                     if (error != CL_SUCCESS)
378                     {
379                         log_error("clCreateImage failed: %s\n",
380                                   IGetErrorString(error));
381                         result.ResultSub(CResult::TEST_FAIL);
382                     }
383 
384                     error = clEnqueueCopyImage(cmdQueue, planeOCL,
385                                                memObjList[i], origin, origin,
386                                                regionPlane, 0, 0, 0);
387                     if (error != CL_SUCCESS)
388                     {
389                         log_error("clEnqueueCopyImage failed: %s\n",
390                                   IGetErrorString(error));
391                         result.ResultSub(CResult::TEST_FAIL);
392                     }
393 
394                     error = clEnqueueReadImage(cmdQueue, memObjList[i], CL_TRUE,
395                                                origin, regionPlane, 0, 0,
396                                                &out[offset], 0, 0, 0);
397                     if (error != CL_SUCCESS)
398                     {
399                         log_error("clEnqueueReadImage failed: %s\n",
400                                   IGetErrorString(error));
401                         result.ResultSub(CResult::TEST_FAIL);
402                     }
403 
404                     offset += planeWidth * planeHeight;
405                 }
406 
407                 if (!YUVCompare(surfaceFormat, out,
408                                 bufferRef1[frameIdx % FRAME_NUM], width,
409                                 height))
410                 {
411                     log_error(
412                         "Frame idx: %i, OCL image verification after "
413                         "clEnqueueCopyImage (from OCL to shared OCL) failed\n",
414                         frameIdx);
415                     result.ResultSub(CResult::TEST_FAIL);
416                 }
417             }
418 
419             { // copy from image to buffer
420                 size_t offset = 0;
421                 size_t origin[3] = { 0, 0, 0 };
422                 size_t bufferSize = sizeof(cl_uchar) * frameSize;
423                 clMemWrapper buffer = clCreateBuffer(ctx, CL_MEM_READ_WRITE,
424                                                      bufferSize, NULL, &error);
425                 if (error != CL_SUCCESS)
426                 {
427                     log_error("clCreateBuffer failed: %s\n",
428                               IGetErrorString(error));
429                     result.ResultSub(CResult::TEST_FAIL);
430                 }
431 
432                 for (size_t i = 0; i < memObjList.size(); ++i)
433                 {
434                     size_t planeWidth = (i == 0) ? width : width / 2;
435                     size_t planeHeight = (i == 0) ? height : height / 2;
436                     size_t regionPlane[3] = { planeWidth, planeHeight, 1 };
437 
438                     error = clEnqueueCopyImageToBuffer(
439                         cmdQueue, memObjList[i], buffer, origin, regionPlane,
440                         offset, 0, 0, 0);
441                     if (error != CL_SUCCESS)
442                     {
443                         log_error("clEnqueueCopyImageToBuffer failed: %s\n",
444                                   IGetErrorString(error));
445                         result.ResultSub(CResult::TEST_FAIL);
446                     }
447 
448                     offset += planeWidth * planeHeight * sizeof(cl_uchar);
449                 }
450 
451                 std::vector<cl_uchar> out(frameSize, 0);
452                 error = clEnqueueReadBuffer(cmdQueue, buffer, CL_TRUE, 0,
453                                             bufferSize, &out[0], 0, NULL, NULL);
454                 if (error != CL_SUCCESS)
455                 {
456                     log_error("Unable to read buffer");
457                     result.ResultSub(CResult::TEST_FAIL);
458                 }
459 
460                 if (!YUVCompare(surfaceFormat, out,
461                                 bufferRef1[frameIdx % FRAME_NUM], width,
462                                 height))
463                 {
464                     log_error("Frame idx: %i, OCL buffer verification after "
465                               "clEnqueueCopyImageToBuffer (from shared OCL "
466                               "image to OCL buffer) failed\n",
467                               frameIdx);
468                     result.ResultSub(CResult::TEST_FAIL);
469                 }
470             }
471 
472             { // copy buffer to image
473                 size_t bufferSize = sizeof(cl_uchar) * frameSize;
474                 clMemWrapper buffer = clCreateBuffer(
475                     ctx, CL_MEM_COPY_HOST_PTR, bufferSize,
476                     &bufferRef2[frameIdx % FRAME_NUM][0], &error);
477                 if (error != CL_SUCCESS)
478                 {
479                     log_error("clCreateBuffer failed: %s\n",
480                               IGetErrorString(error));
481                     result.ResultSub(CResult::TEST_FAIL);
482                 }
483 
484                 size_t offset = 0;
485                 size_t origin[3] = { 0, 0, 0 };
486                 std::vector<cl_uchar> out(frameSize, 0);
487                 for (size_t i = 0; i < memObjList.size(); ++i)
488                 {
489                     size_t planeWidth = (i == 0) ? width : width / 2;
490                     size_t planeHeight = (i == 0) ? height : height / 2;
491                     size_t regionPlane[3] = { planeWidth, planeHeight, 1 };
492 
493                     error = clEnqueueCopyBufferToImage(
494                         cmdQueue, buffer, memObjList[i], offset, origin,
495                         regionPlane, 0, 0, 0);
496                     if (error != CL_SUCCESS)
497                     {
498                         log_error("clEnqueueCopyBufferToImage failed: %s\n",
499                                   IGetErrorString(error));
500                         result.ResultSub(CResult::TEST_FAIL);
501                     }
502 
503                     error = clEnqueueReadImage(cmdQueue, memObjList[i], CL_TRUE,
504                                                origin, regionPlane, 0, 0,
505                                                &out[offset], 0, 0, 0);
506                     if (error != CL_SUCCESS)
507                     {
508                         log_error("clEnqueueReadImage failed: %s\n",
509                                   IGetErrorString(error));
510                         result.ResultSub(CResult::TEST_FAIL);
511                     }
512 
513                     offset += planeWidth * planeHeight * sizeof(cl_uchar);
514                 }
515 
516                 if (!YUVCompare(surfaceFormat, out,
517                                 bufferRef2[frameIdx % FRAME_NUM], width,
518                                 height))
519                 {
520                     log_error("Frame idx: %i, OCL image verification after "
521                               "clEnqueueCopyBufferToImage (from OCL buffer to "
522                               "shared OCL image) failed\n",
523                               frameIdx);
524                     result.ResultSub(CResult::TEST_FAIL);
525                 }
526             }
527 
528             { // map operation to read
529                 size_t offset = 0;
530                 size_t origin[3] = { 0, 0, 0 };
531                 std::vector<cl_uchar> out(frameSize, 0);
532                 for (size_t i = 0; i < memObjList.size(); ++i)
533                 {
534                     size_t planeWidth = (i == 0) ? width : width / 2;
535                     size_t planeHeight = (i == 0) ? height : height / 2;
536                     size_t regionPlane[3] = { planeWidth, planeHeight, 1 };
537                     size_t pitchSize =
538                         ((surfaceFormat == SURFACE_FORMAT_NV12 && i > 0)
539                              ? width
540                              : planeWidth);
541 
542                     size_t rowPitch = 0;
543                     size_t slicePitch = 0;
544                     void *mapPtr = clEnqueueMapImage(
545                         cmdQueue, memObjList[i], CL_TRUE, CL_MAP_READ, origin,
546                         regionPlane, &rowPitch, &slicePitch, 0, 0, 0, &error);
547                     if (error != CL_SUCCESS)
548                     {
549                         log_error("clEnqueueMapImage failed: %s\n",
550                                   IGetErrorString(error));
551                         result.ResultSub(CResult::TEST_FAIL);
552                     }
553 
554                     for (size_t y = 0; y < planeHeight; ++y)
555                         memcpy(&out[offset + y * pitchSize],
556                                static_cast<cl_uchar *>(mapPtr)
557                                    + y * rowPitch / sizeof(cl_uchar),
558                                pitchSize * sizeof(cl_uchar));
559 
560                     error = clEnqueueUnmapMemObject(cmdQueue, memObjList[i],
561                                                     mapPtr, 0, 0, 0);
562                     if (error != CL_SUCCESS)
563                     {
564                         log_error("clEnqueueUnmapMemObject failed: %s\n",
565                                   IGetErrorString(error));
566                         result.ResultSub(CResult::TEST_FAIL);
567                     }
568 
569                     offset += pitchSize * planeHeight;
570                 }
571 
572                 if (!YUVCompare(surfaceFormat, out,
573                                 bufferRef2[frameIdx % FRAME_NUM], width,
574                                 height))
575                 {
576                     log_error("Frame idx: %i, Mapped shared OCL image is "
577                               "different then expected\n",
578                               frameIdx);
579                     result.ResultSub(CResult::TEST_FAIL);
580                 }
581             }
582 
583             { // map operation to write
584                 size_t offset = 0;
585                 size_t origin[3] = { 0, 0, 0 };
586                 for (size_t i = 0; i < memObjList.size(); ++i)
587                 {
588                     size_t planeWidth = (i == 0) ? width : width / 2;
589                     size_t planeHeight = (i == 0) ? height : height / 2;
590                     size_t regionPlane[3] = { planeWidth, planeHeight, 1 };
591                     size_t pitchSize =
592                         ((surfaceFormat == SURFACE_FORMAT_NV12 && i > 0)
593                              ? width
594                              : planeWidth);
595 
596                     size_t rowPitch = 0;
597                     size_t slicePitch = 0;
598                     void *mapPtr = clEnqueueMapImage(
599                         cmdQueue, memObjList[i], CL_TRUE, CL_MAP_WRITE, origin,
600                         regionPlane, &rowPitch, &slicePitch, 0, 0, 0, &error);
601                     if (error != CL_SUCCESS)
602                     {
603                         log_error("clEnqueueMapImage failed: %s\n",
604                                   IGetErrorString(error));
605                         result.ResultSub(CResult::TEST_FAIL);
606                     }
607 
608                     for (size_t y = 0; y < planeHeight; ++y)
609                         memcpy(static_cast<cl_uchar *>(mapPtr)
610                                    + y * rowPitch / sizeof(cl_uchar),
611                                &bufferRef3[frameIdx % FRAME_NUM]
612                                           [offset + y * pitchSize],
613                                pitchSize * sizeof(cl_uchar));
614 
615                     error = clEnqueueUnmapMemObject(cmdQueue, memObjList[i],
616                                                     mapPtr, 0, 0, 0);
617                     if (error != CL_SUCCESS)
618                     {
619                         log_error("clEnqueueUnmapMemObject failed: %s\n",
620                                   IGetErrorString(error));
621                         result.ResultSub(CResult::TEST_FAIL);
622                     }
623 
624                     offset += pitchSize * planeHeight;
625                 }
626             }
627 
628             error = clEnqueueReleaseDX9MediaSurfacesKHR(
629                 cmdQueue, static_cast<cl_uint>(memObjList.size()),
630                 &memObjList[0], 0, NULL, NULL);
631             if (error != CL_SUCCESS)
632             {
633                 log_error("clEnqueueReleaseDX9MediaSurfacesKHR failed: %s\n",
634                           IGetErrorString(error));
635                 result.ResultSub(CResult::TEST_FAIL);
636             }
637 
638             std::vector<cl_uchar> bufferOut(frameSize, 0);
639             if (!YUVSurfaceGet(surfaceFormat, surface, bufferOut, width,
640                                height))
641             {
642                 result.ResultSub(CResult::TEST_FAIL);
643                 return result.Result();
644             }
645 
646             if (!YUVCompare(surfaceFormat, bufferOut,
647                             bufferRef3[frameIdx % FRAME_NUM], width, height))
648             {
649                 log_error(
650                     "Frame idx: %i, media surface is different than expected\n",
651                     frameIdx);
652                 result.ResultSub(CResult::TEST_FAIL);
653             }
654         }
655     }
656 
657     if (deviceWrapper->Status() != DEVICE_PASS)
658     {
659         std::string adapterName;
660         AdapterToString(adapterType, adapterName);
661         if (deviceWrapper->Status() == DEVICE_FAIL)
662         {
663             log_error("%s init failed\n", adapterName.c_str());
664             result.ResultSub(CResult::TEST_FAIL);
665         }
666         else
667         {
668             log_error("%s init incomplete due to unsupported device\n",
669                       adapterName.c_str());
670             result.ResultSub(CResult::TEST_NOTSUPPORTED);
671         }
672     }
673 
674     return result.Result();
675 }
676 
test_api(cl_device_id deviceID,cl_context context,cl_command_queue queue,int num_elements)677 int test_api(cl_device_id deviceID, cl_context context, cl_command_queue queue,
678              int num_elements)
679 {
680     CResult result;
681 
682 #if defined(_WIN32)
683     // D3D9
684     if (api_functions(deviceID, context, queue, num_elements, 10, 256, 256,
685                       CL_ADAPTER_D3D9_KHR, SURFACE_FORMAT_NV12,
686                       SHARED_HANDLE_DISABLED)
687         != 0)
688     {
689         log_error("\nTest case (D3D9, NV12, no shared handle) failed\n\n");
690         result.ResultSub(CResult::TEST_FAIL);
691     }
692 
693     if (api_functions(deviceID, context, queue, num_elements, 3, 512, 256,
694                       CL_ADAPTER_D3D9_KHR, SURFACE_FORMAT_YV12,
695                       SHARED_HANDLE_DISABLED)
696         != 0)
697     {
698         log_error("\nTest case (D3D9, YV12, no shared handle) failed\n\n");
699         result.ResultSub(CResult::TEST_FAIL);
700     }
701 
702     // D3D9EX
703     if (api_functions(deviceID, context, queue, num_elements, 5, 256, 512,
704                       CL_ADAPTER_D3D9EX_KHR, SURFACE_FORMAT_NV12,
705                       SHARED_HANDLE_DISABLED)
706         != 0)
707     {
708         log_error("\nTest case (D3D9EX, NV12, no shared handle) failed\n\n");
709         result.ResultSub(CResult::TEST_FAIL);
710     }
711 
712     if (api_functions(deviceID, context, queue, num_elements, 7, 512, 256,
713                       CL_ADAPTER_D3D9EX_KHR, SURFACE_FORMAT_NV12,
714                       SHARED_HANDLE_ENABLED)
715         != 0)
716     {
717         log_error("\nTest case (D3D9EX, NV12, shared handle) failed\n\n");
718         result.ResultSub(CResult::TEST_FAIL);
719     }
720 
721     if (api_functions(deviceID, context, queue, num_elements, 10, 256, 256,
722                       CL_ADAPTER_D3D9EX_KHR, SURFACE_FORMAT_YV12,
723                       SHARED_HANDLE_DISABLED)
724         != 0)
725     {
726         log_error("\nTest case (D3D9EX, YV12, no shared handle) failed\n\n");
727         result.ResultSub(CResult::TEST_FAIL);
728     }
729 
730     if (api_functions(deviceID, context, queue, num_elements, 15, 128, 128,
731                       CL_ADAPTER_D3D9EX_KHR, SURFACE_FORMAT_YV12,
732                       SHARED_HANDLE_ENABLED)
733         != 0)
734     {
735         log_error("\nTest case (D3D9EX, YV12, shared handle) failed\n\n");
736         result.ResultSub(CResult::TEST_FAIL);
737     }
738 
739     // DXVA
740     if (api_functions(deviceID, context, queue, num_elements, 20, 128, 128,
741                       CL_ADAPTER_DXVA_KHR, SURFACE_FORMAT_NV12,
742                       SHARED_HANDLE_DISABLED)
743         != 0)
744     {
745         log_error("\nTest case (DXVA, NV12, no shared handle) failed\n\n");
746         result.ResultSub(CResult::TEST_FAIL);
747     }
748 
749     if (api_functions(deviceID, context, queue, num_elements, 40, 64, 64,
750                       CL_ADAPTER_DXVA_KHR, SURFACE_FORMAT_NV12,
751                       SHARED_HANDLE_ENABLED)
752         != 0)
753     {
754         log_error("\nTest case (DXVA, NV12, shared handle) failed\n\n");
755         result.ResultSub(CResult::TEST_FAIL);
756     }
757 
758     if (api_functions(deviceID, context, queue, num_elements, 5, 512, 512,
759                       CL_ADAPTER_DXVA_KHR, SURFACE_FORMAT_YV12,
760                       SHARED_HANDLE_DISABLED)
761         != 0)
762     {
763         log_error("\nTest case (DXVA, YV12, no shared handle) failed\n\n");
764         result.ResultSub(CResult::TEST_FAIL);
765     }
766 
767     if (api_functions(deviceID, context, queue, num_elements, 2, 1024, 1024,
768                       CL_ADAPTER_DXVA_KHR, SURFACE_FORMAT_YV12,
769                       SHARED_HANDLE_ENABLED)
770         != 0)
771     {
772         log_error("\nTest case (DXVA, YV12, shared handle) failed\n\n");
773         result.ResultSub(CResult::TEST_FAIL);
774     }
775 
776 #else
777     return TEST_NOT_IMPLEMENTED;
778 #endif
779 
780     return result.Result();
781 }
782