• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //
2 // Copyright (c) 2017 The Khronos Group Inc.
3 //
4 // Licensed under the Apache License, Version 2.0 (the "License");
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
7 //
8 //    http://www.apache.org/licenses/LICENSE-2.0
9 //
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
15 //
16 #include "utils.h"
17 
memory_access(cl_device_id deviceID,cl_context context,cl_command_queue queue,int num_elements,unsigned int width,unsigned int height,cl_dx9_media_adapter_type_khr adapterType,TSurfaceFormat surfaceFormat,TSharedHandleType sharedHandle)18 int memory_access(cl_device_id deviceID, cl_context context,
19                   cl_command_queue queue, int num_elements, unsigned int width,
20                   unsigned int height,
21                   cl_dx9_media_adapter_type_khr adapterType,
22                   TSurfaceFormat surfaceFormat, TSharedHandleType sharedHandle)
23 {
24     CResult result;
25 
26     std::auto_ptr<CDeviceWrapper> deviceWrapper;
27     // creates device
28     if (!DeviceCreate(adapterType, deviceWrapper))
29     {
30         result.ResultSub(CResult::TEST_ERROR);
31         return result.Result();
32     }
33 
34     // generate input and expected data
35     size_t frameSize = width * height * 3 / 2;
36     std::vector<cl_uchar> bufferRef0(frameSize, 0);
37     std::vector<cl_uchar> bufferRef1(frameSize, 0);
38     std::vector<cl_uchar> bufferRef2(frameSize, 0);
39     if (!YUVGenerate(surfaceFormat, bufferRef0, width, height, 0, 90)
40         || !YUVGenerate(surfaceFormat, bufferRef1, width, height, 91, 180)
41         || !YUVGenerate(surfaceFormat, bufferRef2, width, height, 181, 255))
42     {
43         result.ResultSub(CResult::TEST_ERROR);
44         return result.Result();
45     }
46 
47     // iterates through all devices
48     while (deviceWrapper->AdapterNext())
49     {
50         cl_int error;
51         // check if the test can be run on the adapter
52         if (CL_SUCCESS
53             != (error = deviceExistForCLTest(gPlatformIDdetected, adapterType,
54                                              deviceWrapper->Device(), result,
55                                              sharedHandle)))
56         {
57             return result.Result();
58         }
59 
60         if (surfaceFormat != SURFACE_FORMAT_NV12
61             && !SurfaceFormatCheck(adapterType, *deviceWrapper, surfaceFormat))
62         {
63             std::string sharedHandleStr =
64                 (sharedHandle == SHARED_HANDLE_ENABLED) ? "yes" : "no";
65             std::string formatStr;
66             std::string adapterStr;
67             SurfaceFormatToString(surfaceFormat, formatStr);
68             AdapterToString(adapterType, adapterStr);
69             log_info(
70                 "Skipping test case, image format is not supported by a device "
71                 "(adapter type: %s, format: %s, shared handle: %s)\n",
72                 adapterStr.c_str(), formatStr.c_str(), sharedHandleStr.c_str());
73             return result.Result();
74         }
75 
76         void *objectSharedHandle = 0;
77         std::auto_ptr<CSurfaceWrapper> surface;
78 
79         // creates surface
80         if (!MediaSurfaceCreate(
81                 adapterType, width, height, surfaceFormat, *deviceWrapper,
82                 surface, (sharedHandle == SHARED_HANDLE_ENABLED) ? true : false,
83                 &objectSharedHandle))
84         {
85             log_error("Media surface creation failed for %i adapter\n",
86                       deviceWrapper->AdapterIdx());
87             result.ResultSub(CResult::TEST_ERROR);
88             return result.Result();
89         }
90 
91         if (!YUVSurfaceSet(surfaceFormat, surface, bufferRef0, width, height))
92         {
93             result.ResultSub(CResult::TEST_ERROR);
94             return result.Result();
95         }
96 
97         cl_context_properties contextProperties[] = {
98             CL_CONTEXT_PLATFORM,
99             (cl_context_properties)gPlatformIDdetected,
100             AdapterTypeToContextInfo(adapterType),
101             (cl_context_properties)deviceWrapper->Device(),
102             0,
103         };
104 
105         clContextWrapper ctx = clCreateContext(
106             &contextProperties[0], 1, &gDeviceIDdetected, NULL, NULL, &error);
107         if (error != CL_SUCCESS)
108         {
109             log_error("clCreateContext failed: %s\n", IGetErrorString(error));
110             result.ResultSub(CResult::TEST_FAIL);
111             return result.Result();
112         }
113 
114         clCommandQueueWrapper cmdQueue = clCreateCommandQueueWithProperties(
115             ctx, gDeviceIDdetected, 0, &error);
116         if (error != CL_SUCCESS)
117         {
118             log_error("Unable to create command queue: %s\n",
119                       IGetErrorString(error));
120             result.ResultSub(CResult::TEST_FAIL);
121             return result.Result();
122         }
123 
124         { // memory access write
125 #if defined(_WIN32)
126             cl_dx9_surface_info_khr surfaceInfo;
127             surfaceInfo.resource =
128                 *(static_cast<CD3D9SurfaceWrapper *>(surface.get()));
129             surfaceInfo.shared_handle = objectSharedHandle;
130 #else
131             void *surfaceInfo = 0;
132             return TEST_NOT_IMPLEMENTED;
133 #endif
134 
135             std::vector<cl_mem> memObjList;
136             unsigned int planesNum = PlanesNum(surfaceFormat);
137             std::vector<clMemWrapper> planesList(planesNum);
138             for (unsigned int planeIdx = 0; planeIdx < planesNum; ++planeIdx)
139             {
140                 planesList[planeIdx] = clCreateFromDX9MediaSurfaceKHR(
141                     ctx, CL_MEM_WRITE_ONLY, adapterType, &surfaceInfo, planeIdx,
142                     &error);
143                 if (error != CL_SUCCESS)
144                 {
145                     log_error("clCreateFromDX9MediaSurfaceKHR failed for "
146                               "WRITE_ONLY plane %i: %s\n",
147                               planeIdx, IGetErrorString(error));
148                     result.ResultSub(CResult::TEST_FAIL);
149                     return result.Result();
150                 }
151                 memObjList.push_back(planesList[planeIdx]);
152             }
153 
154             error = clEnqueueAcquireDX9MediaSurfacesKHR(
155                 cmdQueue, static_cast<cl_uint>(memObjList.size()),
156                 &memObjList[0], 0, 0, 0);
157             if (error != CL_SUCCESS)
158             {
159                 log_error("clEnqueueAcquireDX9MediaSurfacesKHR failed: %s\n",
160                           IGetErrorString(error));
161                 result.ResultSub(CResult::TEST_FAIL);
162                 return result.Result();
163             }
164 
165             size_t offset = 0;
166             size_t origin[3] = { 0, 0, 0 };
167             for (size_t i = 0; i < memObjList.size(); ++i)
168             {
169                 size_t planeWidth = (i == 0) ? width : width / 2;
170                 size_t planeHeight = (i == 0) ? height : height / 2;
171                 size_t regionPlane[3] = { planeWidth, planeHeight, 1 };
172 
173                 error = clEnqueueWriteImage(cmdQueue, memObjList[i], CL_TRUE,
174                                             origin, regionPlane, 0, 0,
175                                             &bufferRef1[offset], 0, 0, 0);
176                 if (error != CL_SUCCESS)
177                 {
178                     log_error("clEnqueueWriteImage failed: %s\n",
179                               IGetErrorString(error));
180                     result.ResultSub(CResult::TEST_FAIL);
181                 }
182 
183                 offset += planeWidth * planeHeight;
184             }
185 
186             error = clEnqueueReleaseDX9MediaSurfacesKHR(
187                 cmdQueue, static_cast<cl_uint>(memObjList.size()),
188                 &memObjList[0], 0, 0, 0);
189             if (error != CL_SUCCESS)
190             {
191                 log_error("clEnqueueReleaseDX9MediaSurfacesKHR failed: %s\n",
192                           IGetErrorString(error));
193                 result.ResultSub(CResult::TEST_FAIL);
194             }
195         }
196 
197         std::vector<cl_uchar> bufferOut0(frameSize, 0);
198         if (!YUVSurfaceGet(surfaceFormat, surface, bufferOut0, width, height))
199         {
200             result.ResultSub(CResult::TEST_FAIL);
201             return result.Result();
202         }
203 
204         if (!YUVCompare(surfaceFormat, bufferOut0, bufferRef1, width, height))
205         {
206             log_error("Media surface is different than expected\n");
207             result.ResultSub(CResult::TEST_FAIL);
208         }
209 
210         { // memory access read
211 #if defined(_WIN32)
212             cl_dx9_surface_info_khr surfaceInfo;
213             surfaceInfo.resource =
214                 *(static_cast<CD3D9SurfaceWrapper *>(surface.get()));
215             surfaceInfo.shared_handle = objectSharedHandle;
216 #else
217             void *surfaceInfo = 0;
218             return TEST_NOT_IMPLEMENTED;
219 #endif
220 
221             std::vector<cl_mem> memObjList;
222             unsigned int planesNum = PlanesNum(surfaceFormat);
223             std::vector<clMemWrapper> planesList(planesNum);
224             for (unsigned int planeIdx = 0; planeIdx < planesNum; ++planeIdx)
225             {
226                 planesList[planeIdx] = clCreateFromDX9MediaSurfaceKHR(
227                     ctx, CL_MEM_READ_ONLY, adapterType, &surfaceInfo, planeIdx,
228                     &error);
229                 if (error != CL_SUCCESS)
230                 {
231                     log_error("clCreateFromDX9MediaSurfaceKHR failed for "
232                               "READ_ONLY plane %i: %s\n",
233                               planeIdx, IGetErrorString(error));
234                     result.ResultSub(CResult::TEST_FAIL);
235                     return result.Result();
236                 }
237                 memObjList.push_back(planesList[planeIdx]);
238             }
239 
240             error = clEnqueueAcquireDX9MediaSurfacesKHR(
241                 cmdQueue, static_cast<cl_uint>(memObjList.size()),
242                 &memObjList[0], 0, 0, 0);
243             if (error != CL_SUCCESS)
244             {
245                 log_error("clEnqueueAcquireDX9MediaSurfacesKHR failed: %s\n",
246                           IGetErrorString(error));
247                 result.ResultSub(CResult::TEST_FAIL);
248                 return result.Result();
249             }
250 
251             std::vector<cl_uchar> out(frameSize, 0);
252             size_t offset = 0;
253             size_t origin[3] = { 0, 0, 0 };
254 
255             for (size_t i = 0; i < memObjList.size(); ++i)
256             {
257                 size_t planeWidth = (i == 0) ? width : width / 2;
258                 size_t planeHeight = (i == 0) ? height : height / 2;
259                 size_t regionPlane[3] = { planeWidth, planeHeight, 1 };
260 
261                 error = clEnqueueReadImage(cmdQueue, memObjList[i], CL_TRUE,
262                                            origin, regionPlane, 0, 0,
263                                            &out[offset], 0, 0, 0);
264                 if (error != CL_SUCCESS)
265                 {
266                     log_error("clEnqueueReadImage failed: %s\n",
267                               IGetErrorString(error));
268                     result.ResultSub(CResult::TEST_FAIL);
269                 }
270 
271                 offset += planeWidth * planeHeight;
272             }
273 
274             if (!YUVCompare(surfaceFormat, out, bufferRef1, width, height))
275             {
276                 log_error("OCL image (READ_ONLY) is different then expected\n");
277                 result.ResultSub(CResult::TEST_FAIL);
278             }
279 
280             error = clEnqueueReleaseDX9MediaSurfacesKHR(
281                 cmdQueue, static_cast<cl_uint>(memObjList.size()),
282                 &memObjList[0], 0, 0, 0);
283             if (error != CL_SUCCESS)
284             {
285                 log_error("clEnqueueReleaseDX9MediaSurfacesKHR failed: %s\n",
286                           IGetErrorString(error));
287                 result.ResultSub(CResult::TEST_FAIL);
288             }
289         }
290 
291         std::vector<cl_uchar> bufferOut1(frameSize, 0);
292         if (!YUVSurfaceGet(surfaceFormat, surface, bufferOut1, width, height))
293         {
294             result.ResultSub(CResult::TEST_FAIL);
295             return result.Result();
296         }
297 
298         if (!YUVCompare(surfaceFormat, bufferOut1, bufferRef1, width, height))
299         {
300             log_error("Media surface is different than expected\n");
301             result.ResultSub(CResult::TEST_FAIL);
302         }
303 
304         { // memory access read write
305 #if defined(_WIN32)
306             cl_dx9_surface_info_khr surfaceInfo;
307             surfaceInfo.resource =
308                 *(static_cast<CD3D9SurfaceWrapper *>(surface.get()));
309             surfaceInfo.shared_handle = objectSharedHandle;
310 #else
311             void *surfaceInfo = 0;
312             return TEST_NOT_IMPLEMENTED;
313 #endif
314 
315             std::vector<cl_mem> memObjList;
316             unsigned int planesNum = PlanesNum(surfaceFormat);
317             std::vector<clMemWrapper> planesList(planesNum);
318             for (unsigned int planeIdx = 0; planeIdx < planesNum; ++planeIdx)
319             {
320                 planesList[planeIdx] = clCreateFromDX9MediaSurfaceKHR(
321                     ctx, CL_MEM_READ_WRITE, adapterType, &surfaceInfo, planeIdx,
322                     &error);
323                 if (error != CL_SUCCESS)
324                 {
325                     log_error("clCreateFromDX9MediaSurfaceKHR failed for "
326                               "READ_WRITE plane %i: %s\n",
327                               planeIdx, IGetErrorString(error));
328                     result.ResultSub(CResult::TEST_FAIL);
329                     return result.Result();
330                 }
331                 memObjList.push_back(planesList[planeIdx]);
332             }
333 
334             error = clEnqueueAcquireDX9MediaSurfacesKHR(
335                 cmdQueue, static_cast<cl_uint>(memObjList.size()),
336                 &memObjList[0], 0, 0, 0);
337             if (error != CL_SUCCESS)
338             {
339                 log_error("clEnqueueAcquireDX9MediaSurfacesKHR failed: %s\n",
340                           IGetErrorString(error));
341                 result.ResultSub(CResult::TEST_FAIL);
342                 return result.Result();
343             }
344 
345             { // read
346                 std::vector<cl_uchar> out(frameSize, 0);
347                 size_t offset = 0;
348                 size_t origin[3] = { 0, 0, 0 };
349 
350                 for (size_t i = 0; i < memObjList.size(); ++i)
351                 {
352                     size_t planeWidth = (i == 0) ? width : width / 2;
353                     size_t planeHeight = (i == 0) ? height : height / 2;
354                     size_t regionPlane[3] = { planeWidth, planeHeight, 1 };
355 
356                     error = clEnqueueReadImage(cmdQueue, memObjList[i], CL_TRUE,
357                                                origin, regionPlane, 0, 0,
358                                                &out[offset], 0, 0, 0);
359                     if (error != CL_SUCCESS)
360                     {
361                         log_error("clEnqueueReadImage failed: %s\n",
362                                   IGetErrorString(error));
363                         result.ResultSub(CResult::TEST_FAIL);
364                     }
365 
366                     offset += planeWidth * planeHeight;
367                 }
368 
369                 if (!YUVCompare(surfaceFormat, out, bufferRef1, width, height))
370                 {
371                     log_error(
372                         "OCL image (READ_WRITE) is different then expected\n");
373                     result.ResultSub(CResult::TEST_FAIL);
374                 }
375             }
376 
377             { // write
378                 size_t offset = 0;
379                 size_t origin[3] = { 0, 0, 0 };
380                 for (size_t i = 0; i < memObjList.size(); ++i)
381                 {
382                     size_t planeWidth = (i == 0) ? width : width / 2;
383                     size_t planeHeight = (i == 0) ? height : height / 2;
384                     size_t regionPlane[3] = { planeWidth, planeHeight, 1 };
385 
386                     error = clEnqueueWriteImage(
387                         cmdQueue, memObjList[i], CL_TRUE, origin, regionPlane,
388                         0, 0, &bufferRef2[offset], 0, 0, 0);
389                     if (error != CL_SUCCESS)
390                     {
391                         log_error("clEnqueueWriteImage failed: %s\n",
392                                   IGetErrorString(error));
393                         result.ResultSub(CResult::TEST_FAIL);
394                     }
395 
396                     offset += planeWidth * planeHeight;
397                 }
398             }
399 
400             error = clEnqueueReleaseDX9MediaSurfacesKHR(
401                 cmdQueue, static_cast<cl_uint>(memObjList.size()),
402                 &memObjList[0], 0, 0, 0);
403             if (error != CL_SUCCESS)
404             {
405                 log_error("clEnqueueReleaseDX9MediaSurfacesKHR failed: %s\n",
406                           IGetErrorString(error));
407                 result.ResultSub(CResult::TEST_FAIL);
408             }
409         }
410 
411         std::vector<cl_uchar> bufferOut2(frameSize, 0);
412         if (!YUVSurfaceGet(surfaceFormat, surface, bufferOut2, width, height))
413         {
414             result.ResultSub(CResult::TEST_FAIL);
415             return result.Result();
416         }
417 
418         if (!YUVCompare(surfaceFormat, bufferOut2, bufferRef2, width, height))
419         {
420             log_error("Media surface is different than expected\n");
421             result.ResultSub(CResult::TEST_FAIL);
422         }
423     }
424 
425     if (deviceWrapper->Status() != DEVICE_PASS)
426     {
427         std::string adapterName;
428         AdapterToString(adapterType, adapterName);
429         if (deviceWrapper->Status() == DEVICE_FAIL)
430         {
431             log_error("%s init failed\n", adapterName.c_str());
432             result.ResultSub(CResult::TEST_FAIL);
433         }
434         else
435         {
436             log_error("%s init incomplete due to unsupported device\n",
437                       adapterName.c_str());
438             result.ResultSub(CResult::TEST_NOTSUPPORTED);
439         }
440     }
441 
442     return result.Result();
443 }
444 
test_memory_access(cl_device_id deviceID,cl_context context,cl_command_queue queue,int num_elements)445 int test_memory_access(cl_device_id deviceID, cl_context context,
446                        cl_command_queue queue, int num_elements)
447 {
448     CResult result;
449 
450 #if defined(_WIN32)
451     // D3D9
452     if (memory_access(deviceID, context, queue, num_elements, 256, 256,
453                       CL_ADAPTER_D3D9_KHR, SURFACE_FORMAT_NV12,
454                       SHARED_HANDLE_DISABLED)
455         != 0)
456     {
457         log_error("\nTest case (D3D9, NV12, no shared handle) failed\n\n");
458         result.ResultSub(CResult::TEST_FAIL);
459     }
460 
461     if (memory_access(deviceID, context, queue, num_elements, 512, 256,
462                       CL_ADAPTER_D3D9_KHR, SURFACE_FORMAT_YV12,
463                       SHARED_HANDLE_DISABLED)
464         != 0)
465     {
466         log_error("\nTest case (D3D9, YV12, no shared handle) failed\n\n");
467         result.ResultSub(CResult::TEST_FAIL);
468     }
469 
470     // D3D9EX
471     if (memory_access(deviceID, context, queue, num_elements, 256, 512,
472                       CL_ADAPTER_D3D9EX_KHR, SURFACE_FORMAT_NV12,
473                       SHARED_HANDLE_DISABLED)
474         != 0)
475     {
476         log_error("\nTest case (D3D9EX, NV12, no shared handle) failed\n\n");
477         result.ResultSub(CResult::TEST_FAIL);
478     }
479 
480     if (memory_access(deviceID, context, queue, num_elements, 512, 256,
481                       CL_ADAPTER_D3D9EX_KHR, SURFACE_FORMAT_NV12,
482                       SHARED_HANDLE_ENABLED)
483         != 0)
484     {
485         log_error("\nTest case (D3D9EX, NV12, shared handle) failed\n\n");
486         result.ResultSub(CResult::TEST_FAIL);
487     }
488 
489     if (memory_access(deviceID, context, queue, num_elements, 256, 256,
490                       CL_ADAPTER_D3D9EX_KHR, SURFACE_FORMAT_YV12,
491                       SHARED_HANDLE_DISABLED)
492         != 0)
493     {
494         log_error("\nTest case (D3D9EX, YV12, no shared handle) failed\n\n");
495         result.ResultSub(CResult::TEST_FAIL);
496     }
497 
498     if (memory_access(deviceID, context, queue, num_elements, 128, 128,
499                       CL_ADAPTER_D3D9EX_KHR, SURFACE_FORMAT_YV12,
500                       SHARED_HANDLE_ENABLED)
501         != 0)
502     {
503         log_error("\nTest case (D3D9EX, YV12, shared handle) failed\n\n");
504         result.ResultSub(CResult::TEST_FAIL);
505     }
506 
507     // DXVA
508     if (memory_access(deviceID, context, queue, num_elements, 128, 128,
509                       CL_ADAPTER_DXVA_KHR, SURFACE_FORMAT_NV12,
510                       SHARED_HANDLE_DISABLED)
511         != 0)
512     {
513         log_error("\nTest case (DXVA, NV12, no shared handle) failed\n\n");
514         result.ResultSub(CResult::TEST_FAIL);
515     }
516 
517     if (memory_access(deviceID, context, queue, num_elements, 64, 64,
518                       CL_ADAPTER_DXVA_KHR, SURFACE_FORMAT_NV12,
519                       SHARED_HANDLE_ENABLED)
520         != 0)
521     {
522         log_error("\nTest case (DXVA, NV12, shared handle) failed\n\n");
523         result.ResultSub(CResult::TEST_FAIL);
524     }
525 
526     if (memory_access(deviceID, context, queue, num_elements, 512, 512,
527                       CL_ADAPTER_DXVA_KHR, SURFACE_FORMAT_YV12,
528                       SHARED_HANDLE_DISABLED)
529         != 0)
530     {
531         log_error("\nTest case (DXVA, YV12, no shared handle) failed\n\n");
532         result.ResultSub(CResult::TEST_FAIL);
533     }
534 
535     if (memory_access(deviceID, context, queue, num_elements, 1024, 1024,
536                       CL_ADAPTER_DXVA_KHR, SURFACE_FORMAT_YV12,
537                       SHARED_HANDLE_ENABLED)
538         != 0)
539     {
540         log_error("\nTest case (DXVA, YV12, shared handle) failed\n\n");
541         result.ResultSub(CResult::TEST_FAIL);
542     }
543 
544 #else
545     return TEST_NOT_IMPLEMENTED;
546 #endif
547 
548     return result.Result();
549 }
550