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