1 //
2 // Copyright (c) 2022 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
17 #include <vulkan_interop_common.hpp>
18 #include <opencl_vulkan_wrapper.hpp>
19 #include <vulkan_wrapper.hpp>
20 #if !defined(__APPLE__)
21 #include <CL/cl.h>
22 #include <CL/cl_ext.h>
23 #else
24 #include <OpenCL/cl.h>
25 #include <OpenCL/cl_ext.h>
26 #endif
27
28 #include <assert.h>
29 #include <vector>
30 #include <iostream>
31 #include <string.h>
32 #include "harness/testHarness.h"
33 #include "harness/typeWrappers.h"
34 #include "harness/deviceInfo.h"
35
test_consistency_external_buffer(cl_device_id deviceID,cl_context _context,cl_command_queue _queue,int num_elements)36 int test_consistency_external_buffer(cl_device_id deviceID, cl_context _context,
37 cl_command_queue _queue, int num_elements)
38 {
39 cl_int errNum;
40 VulkanDevice vkDevice;
41 // Context and command queue creation
42 cl_platform_id platform = NULL;
43 cl_context context = NULL;
44 cl_command_queue cmd_queue = NULL;
45
46 cl_context_properties contextProperties[] = { CL_CONTEXT_PLATFORM, 0, 0 };
47 errNum = clGetPlatformIDs(1, &platform, NULL);
48 test_error(errNum, "Failed to get platform Id");
49
50 contextProperties[1] = (cl_context_properties)platform;
51
52 context = clCreateContextFromType(contextProperties, CL_DEVICE_TYPE_GPU,
53 NULL, NULL, &errNum);
54 test_error(errNum, "Unable to create context with properties");
55
56 cmd_queue = clCreateCommandQueue(context, deviceID, 0, &errNum);
57 test_error(errNum, "Unable to create command queue");
58
59 uint32_t bufferSize = 32;
60 cl_device_id devList[] = { deviceID, NULL };
61
62 #ifdef _WIN32
63 if (!is_extension_available(devList[0], "cl_khr_external_memory_win32"))
64 {
65 throw std::runtime_error("Device does not support "
66 "cl_khr_external_memory_win32 extension \n");
67 }
68 #else
69 if (!is_extension_available(devList[0], "cl_khr_external_memory_opaque_fd"))
70 {
71 throw std::runtime_error(
72 "Device does not support "
73 "cl_khr_external_memory_opaque_fd extension \n");
74 }
75 #endif
76
77 VulkanExternalMemoryHandleType vkExternalMemoryHandleType =
78 getSupportedVulkanExternalMemoryHandleTypeList()[0];
79
80 VulkanBuffer vkDummyBuffer(vkDevice, 4 * 1024, vkExternalMemoryHandleType);
81 const VulkanMemoryTypeList& memoryTypeList =
82 vkDummyBuffer.getMemoryTypeList();
83
84 VulkanDeviceMemory* vkDeviceMem = new VulkanDeviceMemory(
85 vkDevice, bufferSize, memoryTypeList[0], vkExternalMemoryHandleType);
86 VulkanBufferList vkBufferList(1, vkDevice, bufferSize,
87 vkExternalMemoryHandleType);
88
89 vkDeviceMem->bindBuffer(vkBufferList[0], 0);
90
91 void* handle = NULL;
92 int fd;
93
94 std::vector<cl_mem_properties> extMemProperties{
95 (cl_mem_properties)CL_DEVICE_HANDLE_LIST_KHR,
96 (cl_mem_properties)devList[0],
97 (cl_mem_properties)CL_DEVICE_HANDLE_LIST_END_KHR,
98 };
99 cl_external_memory_handle_type_khr type;
100 switch (vkExternalMemoryHandleType)
101 {
102 #ifdef _WIN32
103 case VULKAN_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_NT:
104 handle = vkDeviceMem->getHandle(vkExternalMemoryHandleType);
105 type = CL_EXTERNAL_MEMORY_HANDLE_OPAQUE_WIN32_KHR;
106 errNum = check_external_memory_handle_type(devList[0], type);
107 extMemProperties.push_back((cl_mem_properties)type);
108 extMemProperties.push_back((cl_mem_properties)handle);
109 break;
110 case VULKAN_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_KMT:
111 handle = vkDeviceMem->getHandle(vkExternalMemoryHandleType);
112 type = CL_EXTERNAL_MEMORY_HANDLE_OPAQUE_WIN32_KMT_KHR;
113 errNum = check_external_memory_handle_type(devList[0], type);
114 extMemProperties.push_back((cl_mem_properties)type);
115 extMemProperties.push_back((cl_mem_properties)handle);
116 break;
117 #else
118 case VULKAN_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD:
119 fd = (int)vkDeviceMem->getHandle(vkExternalMemoryHandleType);
120 type = CL_EXTERNAL_MEMORY_HANDLE_OPAQUE_FD_KHR;
121 errNum = check_external_memory_handle_type(devList[0], type);
122 extMemProperties.push_back((cl_mem_properties)type);
123 extMemProperties.push_back((cl_mem_properties)fd);
124 break;
125 #endif
126 default:
127 errNum = TEST_FAIL;
128 log_error("Unsupported external memory handle type \n");
129 break;
130 }
131 if (errNum != CL_SUCCESS)
132 {
133 log_error("Checks failed for "
134 "CL_DEVICE_EXTERNAL_MEMORY_IMPORT_HANDLE_TYPES_KHR\n");
135 return TEST_FAIL;
136 }
137 extMemProperties.push_back(0);
138
139 clMemWrapper buffer;
140
141 // Passing NULL properties and a valid extMem_desc size
142 buffer = clCreateBufferWithProperties(context, NULL, 1, bufferSize, NULL,
143 &errNum);
144 test_error(errNum, "Unable to create buffer with NULL properties");
145
146 buffer.reset();
147
148 // Passing valid extMemProperties and buffersize
149 buffer = clCreateBufferWithProperties(context, extMemProperties.data(), 1,
150 bufferSize, NULL, &errNum);
151 test_error(errNum, "Unable to create buffer with Properties");
152
153 buffer.reset();
154
155 // Not passing external memory handle
156 std::vector<cl_mem_properties> extMemProperties2{
157 #ifdef _WIN32
158 (cl_mem_properties)type,
159 NULL, // Passing NULL handle
160 #else
161 (cl_mem_properties)type,
162 (cl_mem_properties)-64, // Passing random invalid fd
163 #endif
164 (cl_mem_properties)CL_DEVICE_HANDLE_LIST_KHR,
165 (cl_mem_properties)devList[0],
166 (cl_mem_properties)CL_DEVICE_HANDLE_LIST_END_KHR,
167 0
168 };
169 buffer = clCreateBufferWithProperties(context, extMemProperties2.data(), 1,
170 bufferSize, NULL, &errNum);
171 test_failure_error(errNum, CL_INVALID_VALUE,
172 "Should return CL_INVALID_VALUE ");
173
174 buffer.reset();
175
176 // Passing extMem_desc size = 0 but valid memProperties, CL_INVALID_SIZE
177 // should be returned.
178 buffer = clCreateBufferWithProperties(context, extMemProperties.data(), 1,
179 0, NULL, &errNum);
180 test_failure_error(errNum, CL_INVALID_BUFFER_SIZE,
181 "Should return CL_INVALID_BUFFER_SIZE");
182
183 return TEST_PASS;
184 }
185
test_consistency_external_image(cl_device_id deviceID,cl_context _context,cl_command_queue _queue,int num_elements)186 int test_consistency_external_image(cl_device_id deviceID, cl_context _context,
187 cl_command_queue _queue, int num_elements)
188 {
189 cl_int errNum;
190 VulkanDevice vkDevice;
191
192 // Context and command queue creation
193 cl_platform_id platform = NULL;
194 cl_context context = NULL;
195 cl_command_queue cmd_queue = NULL;
196
197 cl_context_properties contextProperties[] = { CL_CONTEXT_PLATFORM, 0, 0 };
198 errNum = clGetPlatformIDs(1, &platform, NULL);
199 test_error(errNum, "Failed to get platform id");
200
201 contextProperties[1] = (cl_context_properties)platform;
202
203 context = clCreateContextFromType(contextProperties, CL_DEVICE_TYPE_GPU,
204 NULL, NULL, &errNum);
205 test_error(errNum, "Unable to create context with properties");
206
207 cmd_queue = clCreateCommandQueue(context, deviceID, 0, &errNum);
208 test_error(errNum, "Unable to create command queue");
209
210 cl_device_id devList[] = { deviceID, NULL };
211
212 #ifdef _WIN32
213 if (!is_extension_available(devList[0], "cl_khr_external_memory_win32"))
214 {
215 throw std::runtime_error("Device does not support"
216 "cl_khr_external_memory_win32 extension \n");
217 }
218 #else
219 if (!is_extension_available(devList[0], "cl_khr_external_memory_opaque_fd"))
220 {
221 throw std::runtime_error(
222 "Device does not support cl_khr_external_memory_opaque_fd "
223 "extension \n");
224 }
225 #endif
226 uint32_t width = 256;
227 uint32_t height = 16;
228 cl_image_desc image_desc;
229 memset(&image_desc, 0x0, sizeof(cl_image_desc));
230 cl_image_format img_format = { 0 };
231
232 VulkanExternalMemoryHandleType vkExternalMemoryHandleType =
233 getSupportedVulkanExternalMemoryHandleTypeList()[0];
234 VulkanImage2D* vkImage2D =
235 new VulkanImage2D(vkDevice, VULKAN_FORMAT_R8G8B8A8_UNORM, width, height,
236 1, vkExternalMemoryHandleType);
237
238 const VulkanMemoryTypeList& memoryTypeList = vkImage2D->getMemoryTypeList();
239 uint64_t totalImageMemSize = vkImage2D->getSize();
240
241 log_info("Memory type index: %lu\n", (uint32_t)memoryTypeList[0]);
242 log_info("Memory type property: %d\n",
243 memoryTypeList[0].getMemoryTypeProperty());
244 log_info("Image size : %d\n", totalImageMemSize);
245
246 VulkanDeviceMemory* vkDeviceMem =
247 new VulkanDeviceMemory(vkDevice, totalImageMemSize, memoryTypeList[0],
248 vkExternalMemoryHandleType);
249 vkDeviceMem->bindImage(*vkImage2D, 0);
250
251 void* handle = NULL;
252 int fd;
253 std::vector<cl_mem_properties> extMemProperties{
254 (cl_mem_properties)CL_DEVICE_HANDLE_LIST_KHR,
255 (cl_mem_properties)devList[0],
256 (cl_mem_properties)CL_DEVICE_HANDLE_LIST_END_KHR,
257 };
258 switch (vkExternalMemoryHandleType)
259 {
260 #ifdef _WIN32
261 case VULKAN_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_NT:
262 handle = vkDeviceMem->getHandle(vkExternalMemoryHandleType);
263 errNum = check_external_memory_handle_type(
264 devList[0], CL_EXTERNAL_MEMORY_HANDLE_OPAQUE_WIN32_KHR);
265 extMemProperties.push_back(
266 (cl_mem_properties)CL_EXTERNAL_MEMORY_HANDLE_OPAQUE_WIN32_KHR);
267 extMemProperties.push_back((cl_mem_properties)handle);
268 break;
269 case VULKAN_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_KMT:
270 handle = vkDeviceMem->getHandle(vkExternalMemoryHandleType);
271 errNum = check_external_memory_handle_type(
272 devList[0], CL_EXTERNAL_MEMORY_HANDLE_OPAQUE_WIN32_KMT_KHR);
273 extMemProperties.push_back(
274 (cl_mem_properties)
275 CL_EXTERNAL_MEMORY_HANDLE_OPAQUE_WIN32_KMT_KHR);
276 extMemProperties.push_back((cl_mem_properties)handle);
277 break;
278 #else
279 case VULKAN_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD:
280 fd = (int)vkDeviceMem->getHandle(vkExternalMemoryHandleType);
281 errNum = check_external_memory_handle_type(
282 devList[0], CL_EXTERNAL_MEMORY_HANDLE_OPAQUE_FD_KHR);
283 extMemProperties.push_back(
284 (cl_mem_properties)CL_EXTERNAL_MEMORY_HANDLE_OPAQUE_FD_KHR);
285 extMemProperties.push_back((cl_mem_properties)fd);
286 break;
287 #endif
288 default:
289 errNum = TEST_FAIL;
290 log_error("Unsupported external memory handle type \n");
291 break;
292 }
293 if (errNum != CL_SUCCESS)
294 {
295 log_error("Checks failed for "
296 "CL_DEVICE_EXTERNAL_MEMORY_IMPORT_HANDLE_TYPES_KHR\n");
297 return TEST_FAIL;
298 }
299 extMemProperties.push_back(0);
300
301 const VkImageCreateInfo VulkanImageCreateInfo =
302 vkImage2D->getVkImageCreateInfo();
303
304 errNum = getCLImageInfoFromVkImageInfo(
305 &VulkanImageCreateInfo, totalImageMemSize, &img_format, &image_desc);
306 if (errNum != CL_SUCCESS)
307 {
308 log_error("getCLImageInfoFromVkImageInfo failed!!!");
309 return TEST_FAIL;
310 }
311
312 clMemWrapper image;
313
314 // Pass valid properties, image_desc and image_format
315 image = clCreateImageWithProperties(
316 context, extMemProperties.data(), CL_MEM_READ_WRITE, &img_format,
317 &image_desc, NULL /* host_ptr */, &errNum);
318 test_error(errNum, "Unable to create Image with Properties");
319 image.reset();
320
321 // Passing properties, image_desc and image_format all as NULL
322 image = clCreateImageWithProperties(context, NULL, CL_MEM_READ_WRITE, NULL,
323 NULL, NULL, &errNum);
324 test_failure_error(
325 errNum, CL_INVALID_IMAGE_DESCRIPTOR,
326 "Image creation must fail with CL_INVALID_IMAGE_DESCRIPTOR "
327 "when all are passed as NULL");
328
329 image.reset();
330
331 // Passing NULL properties and a valid image_format and image_desc
332 image =
333 clCreateImageWithProperties(context, NULL, CL_MEM_READ_WRITE,
334 &img_format, &image_desc, NULL, &errNum);
335 test_error(errNum,
336 "Unable to create image with NULL properties "
337 "with valid image format and image desc");
338
339 image.reset();
340
341 // Passing image_format as NULL
342 image = clCreateImageWithProperties(context, extMemProperties.data(),
343 CL_MEM_READ_WRITE, NULL, &image_desc,
344 NULL, &errNum);
345 test_failure_error(errNum, CL_INVALID_IMAGE_FORMAT_DESCRIPTOR,
346 "Image creation must fail with "
347 "CL_INVALID_IMAGE_FORMAT_DESCRIPTOR"
348 "when image desc passed as NULL");
349
350 image.reset();
351
352 // Passing image_desc as NULL
353 image = clCreateImageWithProperties(context, extMemProperties.data(),
354 CL_MEM_READ_WRITE, &img_format, NULL,
355 NULL, &errNum);
356 test_failure_error(errNum, CL_INVALID_IMAGE_DESCRIPTOR,
357 "Image creation must fail with "
358 "CL_INVALID_IMAGE_DESCRIPTOR "
359 "when image desc passed as NULL");
360 image.reset();
361
362 return TEST_PASS;
363 }
364
test_consistency_external_semaphore(cl_device_id deviceID,cl_context _context,cl_command_queue _queue,int num_elements)365 int test_consistency_external_semaphore(cl_device_id deviceID,
366 cl_context _context,
367 cl_command_queue _queue,
368 int num_elements)
369 {
370 cl_int errNum;
371 VulkanDevice vkDevice;
372 // Context and command queue creation
373 cl_platform_id platform = NULL;
374 cl_context context = NULL;
375 cl_command_queue cmd_queue = NULL;
376
377 errNum = clGetPlatformIDs(1, &platform, NULL);
378 test_error(errNum, "Failed to get platform Id");
379
380 cl_context_properties contextProperties[] = { CL_CONTEXT_PLATFORM, 0, 0 };
381
382 contextProperties[1] = (cl_context_properties)platform;
383
384 context = clCreateContextFromType(contextProperties, CL_DEVICE_TYPE_GPU,
385 NULL, NULL, &errNum);
386 test_error(errNum, "Unable to create context with properties");
387
388 cmd_queue = clCreateCommandQueue(context, deviceID, 0, &errNum);
389 test_error(errNum, "Unable to create command queue");
390
391 cl_device_id devList[] = { deviceID, NULL };
392
393 #ifdef _WIN32
394 if (!is_extension_available(devList[0], "cl_khr_external_semaphore_win32"))
395 {
396 throw std::runtime_error(
397 "Device does not support cl_khr_external_semaphore_win32 "
398 "extension \n");
399 }
400 #else
401 if (!is_extension_available(devList[0],
402 "cl_khr_external_semaphore_opaque_fd"))
403 {
404 throw std::runtime_error(
405 "Device does not support "
406 "cl_khr_external_semaphore_opaque_fd extension \n");
407 }
408 #endif
409 VulkanExternalSemaphoreHandleType vkExternalSemaphoreHandleType =
410 getSupportedVulkanExternalSemaphoreHandleTypeList()[0];
411 VulkanSemaphore vkVk2Clsemaphore(vkDevice, vkExternalSemaphoreHandleType);
412 VulkanSemaphore vkCl2Vksemaphore(vkDevice, vkExternalSemaphoreHandleType);
413 cl_semaphore_khr clCl2Vksemaphore;
414 cl_semaphore_khr clVk2Clsemaphore;
415
416 void* handle1 = NULL;
417 void* handle2 = NULL;
418 int fd1, fd2;
419 std::vector<cl_semaphore_properties_khr> sema_props1{
420 (cl_semaphore_properties_khr)CL_SEMAPHORE_TYPE_KHR,
421 (cl_semaphore_properties_khr)CL_SEMAPHORE_TYPE_BINARY_KHR,
422 };
423 std::vector<cl_semaphore_properties_khr> sema_props2{
424 (cl_semaphore_properties_khr)CL_SEMAPHORE_TYPE_KHR,
425 (cl_semaphore_properties_khr)CL_SEMAPHORE_TYPE_BINARY_KHR,
426 };
427 switch (vkExternalSemaphoreHandleType)
428 {
429 #ifdef _WIN32
430 case VULKAN_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_NT:
431 log_info(" Opaque NT handles are only supported on Windows\n");
432 handle1 = vkVk2Clsemaphore.getHandle(vkExternalSemaphoreHandleType);
433 handle2 = vkCl2Vksemaphore.getHandle(vkExternalSemaphoreHandleType);
434 errNum = check_external_semaphore_handle_type(
435 devList[0], CL_SEMAPHORE_HANDLE_OPAQUE_WIN32_KHR);
436 sema_props1.push_back((cl_semaphore_properties_khr)
437 CL_SEMAPHORE_HANDLE_OPAQUE_WIN32_KHR);
438 sema_props1.push_back((cl_semaphore_properties_khr)handle1);
439 sema_props2.push_back((cl_semaphore_properties_khr)
440 CL_SEMAPHORE_HANDLE_OPAQUE_WIN32_KHR);
441 sema_props2.push_back((cl_semaphore_properties_khr)handle2);
442 break;
443 case VULKAN_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_KMT:
444 log_info(" Opaque D3DKMT handles are only supported on Windows\n");
445 handle1 = vkVk2Clsemaphore.getHandle(vkExternalSemaphoreHandleType);
446 handle2 = vkCl2Vksemaphore.getHandle(vkExternalSemaphoreHandleType);
447 errNum = check_external_semaphore_handle_type(
448 devList[0], CL_SEMAPHORE_HANDLE_OPAQUE_WIN32_KMT_KHR);
449 sema_props1.push_back((cl_semaphore_properties_khr)
450 CL_SEMAPHORE_HANDLE_OPAQUE_WIN32_KMT_KHR);
451 sema_props1.push_back((cl_semaphore_properties_khr)handle1);
452 sema_props2.push_back((cl_semaphore_properties_khr)
453 CL_SEMAPHORE_HANDLE_OPAQUE_WIN32_KMT_KHR);
454 sema_props2.push_back((cl_semaphore_properties_khr)handle2);
455 break;
456 #else
457 case VULKAN_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD:
458 log_info(" Opaque file descriptors are not supported on Windows\n");
459 fd1 =
460 (int)vkVk2Clsemaphore.getHandle(vkExternalSemaphoreHandleType);
461 fd2 =
462 (int)vkCl2Vksemaphore.getHandle(vkExternalSemaphoreHandleType);
463 errNum = check_external_semaphore_handle_type(
464 devList[0], CL_SEMAPHORE_HANDLE_OPAQUE_FD_KHR);
465 sema_props1.push_back(
466 (cl_semaphore_properties_khr)CL_SEMAPHORE_HANDLE_OPAQUE_FD_KHR);
467 sema_props1.push_back((cl_semaphore_properties_khr)fd1);
468 sema_props2.push_back(
469 (cl_semaphore_properties_khr)CL_SEMAPHORE_HANDLE_OPAQUE_FD_KHR);
470 sema_props2.push_back((cl_semaphore_properties_khr)fd2);
471 break;
472 #endif
473 default: log_error("Unsupported external memory handle type\n"); break;
474 }
475 if (CL_SUCCESS != errNum)
476 {
477 throw std::runtime_error(
478 "Unsupported external sempahore handle type\n ");
479 }
480 sema_props1.push_back(
481 (cl_semaphore_properties_khr)CL_DEVICE_HANDLE_LIST_KHR);
482 sema_props1.push_back((cl_semaphore_properties_khr)devList[0]);
483 sema_props1.push_back(
484 (cl_semaphore_properties_khr)CL_DEVICE_HANDLE_LIST_END_KHR);
485 sema_props2.push_back(
486 (cl_semaphore_properties_khr)CL_DEVICE_HANDLE_LIST_KHR);
487 sema_props2.push_back((cl_semaphore_properties_khr)devList[0]);
488 sema_props2.push_back(
489 (cl_semaphore_properties_khr)CL_DEVICE_HANDLE_LIST_END_KHR);
490 sema_props1.push_back(0);
491 sema_props2.push_back(0);
492
493 // Pass NULL properties
494 cl_semaphore_khr cl_ext_semaphore =
495 clCreateSemaphoreWithPropertiesKHRptr(context, NULL, &errNum);
496 test_failure_error(errNum, CL_INVALID_VALUE,
497 "Semaphore creation must fail with CL_INVALID_VALUE "
498 " when properties are passed as NULL");
499
500
501 // Pass invalid semaphore object to wait
502 errNum =
503 clEnqueueWaitSemaphoresKHRptr(cmd_queue, 1, NULL, NULL, 0, NULL, NULL);
504 test_failure_error(errNum, CL_INVALID_VALUE,
505 "clEnqueueWaitSemaphoresKHR fails with CL_INVALID_VALUE "
506 "when invalid semaphore object is passed");
507
508
509 // Pass invalid semaphore object to signal
510 errNum = clEnqueueSignalSemaphoresKHRptr(cmd_queue, 1, NULL, NULL, 0, NULL,
511 NULL);
512 test_failure_error(
513 errNum, CL_INVALID_VALUE,
514 "clEnqueueSignalSemaphoresKHR fails with CL_INVALID_VALUE"
515 "when invalid semaphore object is passed");
516
517
518 // Create two semaphore objects
519 clVk2Clsemaphore = clCreateSemaphoreWithPropertiesKHRptr(
520 context, sema_props1.data(), &errNum);
521 test_error(errNum,
522 "Unable to create semaphore with valid semaphore properties");
523
524 clCl2Vksemaphore = clCreateSemaphoreWithPropertiesKHRptr(
525 context, sema_props2.data(), &errNum);
526 test_error(errNum,
527 "Unable to create semaphore with valid semaphore properties");
528
529
530 // Call Signal twice consecutively
531 errNum = clEnqueueSignalSemaphoresKHRptr(cmd_queue, 1, &clVk2Clsemaphore,
532 NULL, 0, NULL, NULL);
533 test_error(errNum, "clEnqueueSignalSemaphoresKHRptr failed");
534
535 errNum = clEnqueueSignalSemaphoresKHRptr(cmd_queue, 1, &clCl2Vksemaphore,
536 NULL, 0, NULL, NULL);
537 test_error(errNum,
538 "clEnqueueSignalSemaphoresKHRptr failed for two "
539 "consecutive wait events");
540
541
542 // Call Wait twice consecutively
543 errNum = clEnqueueWaitSemaphoresKHRptr(cmd_queue, 1, &clVk2Clsemaphore,
544 NULL, 0, NULL, NULL);
545 test_error(errNum, "clEnqueueWaitSemaphoresKHRptr failed");
546
547 errNum = clEnqueueWaitSemaphoresKHRptr(cmd_queue, 1, &clCl2Vksemaphore,
548 NULL, 0, NULL, NULL);
549 test_error(errNum,
550 "clEnqueueWaitSemaphoresKHRptr failed for two "
551 " consecutive wait events");
552
553
554 // Pass invalid object to release call
555 errNum = clReleaseSemaphoreKHRptr(NULL);
556 test_failure_error(errNum, CL_INVALID_VALUE,
557 "clReleaseSemaphoreKHRptr fails with "
558 "CL_INVALID_VALUE when NULL semaphore object is passed");
559
560 // Release both semaphore objects
561 errNum = clReleaseSemaphoreKHRptr(clVk2Clsemaphore);
562 test_error(errNum, "clReleaseSemaphoreKHRptr failed");
563
564 errNum = clReleaseSemaphoreKHRptr(clCl2Vksemaphore);
565 test_error(errNum, "clReleaseSemaphoreKHRptr failed");
566
567 return TEST_PASS;
568 }
569