1 /*-------------------------------------------------------------------------
2 * Vulkan Conformance Tests
3 * ------------------------
4 *
5 * Copyright (c) 2016 Google Inc.
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 *
19 * \brief Vulkan external memory utilities
20 *//*--------------------------------------------------------------------*/
21
22 #include "vktExternalMemoryUtil.hpp"
23
24 #include "vkQueryUtil.hpp"
25
26 #ifndef CTS_USES_VULKANSC
27
28 #if (DE_OS == DE_OS_ANDROID) || (DE_OS == DE_OS_UNIX) || (DE_OS == DE_OS_OSX)
29 # include <unistd.h>
30 # include <fcntl.h>
31 # include <errno.h>
32 # include <sys/types.h>
33 # include <sys/socket.h>
34 #endif
35
36 #if (DE_OS == DE_OS_WIN32)
37 # define WIN32_LEAN_AND_MEAN
38 # include <windows.h>
39 #endif
40
41 #if (DE_OS == DE_OS_ANDROID)
42 # include <sys/system_properties.h>
43 #endif
44
45 #if (DE_OS == DE_OS_ANDROID) && defined(__ANDROID_API_O__) && (DE_ANDROID_API >= __ANDROID_API_O__)
46 # include <android/hardware_buffer.h>
47 # include "deDynamicLibrary.hpp"
48 # define BUILT_WITH_ANDROID_HARDWARE_BUFFER 1
49 #endif
50
51
52 #if (DE_OS == DE_OS_FUCHSIA)
53 # include <zircon/syscalls.h>
54 # include <zircon/types.h>
55 #endif
56
57 namespace vkt
58 {
59 namespace ExternalMemoryUtil
60 {
61 namespace
62 {
63
64 } // anonymous
65
NativeHandle(void)66 NativeHandle::NativeHandle (void)
67 : m_fd (-1)
68 , m_zirconHandle (0)
69 , m_win32HandleType (WIN32HANDLETYPE_LAST)
70 , m_win32Handle (DE_NULL)
71 , m_androidHardwareBuffer (DE_NULL)
72 , m_hostPtr (DE_NULL)
73 {
74 }
75
NativeHandle(const NativeHandle & other)76 NativeHandle::NativeHandle (const NativeHandle& other)
77 : m_fd (-1)
78 , m_zirconHandle (0)
79 , m_win32HandleType (WIN32HANDLETYPE_LAST)
80 , m_win32Handle (DE_NULL)
81 , m_androidHardwareBuffer (DE_NULL)
82 , m_hostPtr (DE_NULL)
83 {
84 if (other.m_fd >= 0)
85 {
86 #if (DE_OS == DE_OS_ANDROID) || (DE_OS == DE_OS_UNIX) || (DE_OS == DE_OS_OSX)
87 DE_ASSERT(!other.m_win32Handle.internal);
88 DE_ASSERT(!other.m_androidHardwareBuffer.internal);
89 m_fd = dup(other.m_fd);
90 TCU_CHECK(m_fd >= 0);
91 #else
92 DE_FATAL("Platform doesn't support file descriptors");
93 #endif
94 }
95 else if (other.m_zirconHandle.internal)
96 {
97 #if (DE_OS == DE_OS_FUCHSIA)
98 DE_ASSERT(!other.m_win32Handle.internal);
99 zx_handle_duplicate(other.m_zirconHandle.internal, ZX_RIGHT_SAME_RIGHTS, &m_zirconHandle.internal);
100 #else
101 DE_FATAL("Platform doesn't support zircon handles");
102 #endif
103 }
104 else if (other.m_win32Handle.internal)
105 {
106 #if (DE_OS == DE_OS_WIN32)
107 m_win32HandleType = other.m_win32HandleType;
108
109 switch (other.m_win32HandleType)
110 {
111 case WIN32HANDLETYPE_NT:
112 {
113 DE_ASSERT(other.m_fd == -1);
114 DE_ASSERT(!other.m_androidHardwareBuffer.internal);
115
116 const HANDLE process = ::GetCurrentProcess();
117 ::DuplicateHandle(process, other.m_win32Handle.internal, process, &m_win32Handle.internal, 0, TRUE, DUPLICATE_SAME_ACCESS);
118
119 break;
120 }
121
122 case WIN32HANDLETYPE_KMT:
123 {
124 m_win32Handle = other.m_win32Handle;
125 break;
126 }
127
128 default:
129 DE_FATAL("Unknown win32 handle type");
130 }
131 #else
132 DE_FATAL("Platform doesn't support win32 handles");
133 #endif
134 }
135 else if (other.m_androidHardwareBuffer.internal)
136 {
137 DE_ASSERT(other.m_fd == -1);
138 DE_ASSERT(!other.m_win32Handle.internal);
139 m_androidHardwareBuffer = other.m_androidHardwareBuffer;
140
141 if (AndroidHardwareBufferExternalApi* ahbApi = AndroidHardwareBufferExternalApi::getInstance())
142 ahbApi->acquire(m_androidHardwareBuffer);
143 else
144 DE_FATAL("Platform doesn't support Android Hardware Buffer handles");
145 }
146 else
147 DE_FATAL("Native handle can't be duplicated");
148 }
149
NativeHandle(int fd)150 NativeHandle::NativeHandle (int fd)
151 : m_fd (fd)
152 , m_zirconHandle (0)
153 , m_win32HandleType (WIN32HANDLETYPE_LAST)
154 , m_win32Handle (DE_NULL)
155 , m_androidHardwareBuffer (DE_NULL)
156 , m_hostPtr (DE_NULL)
157 {
158 }
159
NativeHandle(Win32HandleType handleType,vk::pt::Win32Handle handle)160 NativeHandle::NativeHandle (Win32HandleType handleType, vk::pt::Win32Handle handle)
161 : m_fd (-1)
162 , m_zirconHandle (0)
163 , m_win32HandleType (handleType)
164 , m_win32Handle (handle)
165 , m_androidHardwareBuffer (DE_NULL)
166 , m_hostPtr (DE_NULL)
167 {
168 }
169
NativeHandle(vk::pt::AndroidHardwareBufferPtr buffer)170 NativeHandle::NativeHandle (vk::pt::AndroidHardwareBufferPtr buffer)
171 : m_fd (-1)
172 , m_zirconHandle (0)
173 , m_win32HandleType (WIN32HANDLETYPE_LAST)
174 , m_win32Handle (DE_NULL)
175 , m_androidHardwareBuffer (buffer)
176 , m_hostPtr (DE_NULL)
177 {
178 }
179
~NativeHandle(void)180 NativeHandle::~NativeHandle (void)
181 {
182 reset();
183 }
184
reset(void)185 void NativeHandle::reset (void)
186 {
187 if (m_fd >= 0)
188 {
189 #if (DE_OS == DE_OS_ANDROID) || (DE_OS == DE_OS_UNIX) || (DE_OS == DE_OS_OSX)
190 DE_ASSERT(!m_win32Handle.internal);
191 DE_ASSERT(!m_androidHardwareBuffer.internal);
192 ::close(m_fd);
193 #else
194 DE_FATAL("Platform doesn't support file descriptors");
195 #endif
196 }
197
198 if (m_zirconHandle.internal != 0)
199 {
200 #if (DE_OS == DE_OS_FUCHSIA)
201 zx_handle_close(m_zirconHandle.internal);
202 #else
203 DE_FATAL("Platform doesn't support fuchsia handles");
204 #endif
205 }
206
207
208 if (m_win32Handle.internal)
209 {
210 #if (DE_OS == DE_OS_WIN32)
211 switch (m_win32HandleType)
212 {
213 case WIN32HANDLETYPE_NT:
214 DE_ASSERT(m_fd == -1);
215 DE_ASSERT(!m_androidHardwareBuffer.internal);
216 ::CloseHandle((HANDLE)m_win32Handle.internal);
217 break;
218
219 case WIN32HANDLETYPE_KMT:
220 break;
221
222 default:
223 DE_FATAL("Unknown win32 handle type");
224 }
225 #else
226 DE_FATAL("Platform doesn't support win32 handles");
227 #endif
228 }
229 if (m_androidHardwareBuffer.internal)
230 {
231 DE_ASSERT(m_fd == -1);
232 DE_ASSERT(!m_win32Handle.internal);
233
234 if (AndroidHardwareBufferExternalApi* ahbApi = AndroidHardwareBufferExternalApi::getInstance())
235 ahbApi->release(m_androidHardwareBuffer);
236 else
237 DE_FATAL("Platform doesn't support Android Hardware Buffer handles");
238 }
239 m_fd = -1;
240 m_zirconHandle = vk::pt::zx_handle_t(0);
241 m_win32Handle = vk::pt::Win32Handle(DE_NULL);
242 m_win32HandleType = WIN32HANDLETYPE_LAST;
243 m_androidHardwareBuffer = vk::pt::AndroidHardwareBufferPtr(DE_NULL);
244 m_hostPtr = DE_NULL;
245 }
246
operator =(int fd)247 NativeHandle& NativeHandle::operator= (int fd)
248 {
249 reset();
250
251 m_fd = fd;
252
253 return *this;
254 }
255
operator =(vk::pt::AndroidHardwareBufferPtr buffer)256 NativeHandle& NativeHandle::operator= (vk::pt::AndroidHardwareBufferPtr buffer)
257 {
258 reset();
259
260 m_androidHardwareBuffer = buffer;
261
262 return *this;
263 }
264
setWin32Handle(Win32HandleType type,vk::pt::Win32Handle handle)265 void NativeHandle::setWin32Handle (Win32HandleType type, vk::pt::Win32Handle handle)
266 {
267 reset();
268
269 m_win32HandleType = type;
270 m_win32Handle = handle;
271 }
272
setZirconHandle(vk::pt::zx_handle_t zirconHandle)273 void NativeHandle::setZirconHandle (vk::pt::zx_handle_t zirconHandle)
274 {
275 reset();
276
277 m_zirconHandle = zirconHandle;
278 }
279
setHostPtr(void * hostPtr)280 void NativeHandle::setHostPtr(void* hostPtr)
281 {
282 reset();
283
284 m_hostPtr = hostPtr;
285 }
286
disown(void)287 void NativeHandle::disown (void)
288 {
289 m_fd = -1;
290 m_zirconHandle = vk::pt::zx_handle_t(0);
291 m_win32Handle = vk::pt::Win32Handle(DE_NULL);
292 m_androidHardwareBuffer = vk::pt::AndroidHardwareBufferPtr(DE_NULL);
293 m_hostPtr = DE_NULL;
294 }
295
getWin32Handle(void) const296 vk::pt::Win32Handle NativeHandle::getWin32Handle (void) const
297 {
298 DE_ASSERT(m_fd == -1);
299 DE_ASSERT(!m_androidHardwareBuffer.internal);
300 DE_ASSERT(m_hostPtr == DE_NULL);
301
302 return m_win32Handle;
303 }
304
getFd(void) const305 int NativeHandle::getFd (void) const
306 {
307 DE_ASSERT(!m_win32Handle.internal);
308 DE_ASSERT(!m_androidHardwareBuffer.internal);
309 DE_ASSERT(m_hostPtr == DE_NULL);
310 return m_fd;
311 }
312
getZirconHandle(void) const313 vk::pt::zx_handle_t NativeHandle::getZirconHandle (void) const
314 {
315 DE_ASSERT(!m_win32Handle.internal);
316 DE_ASSERT(!m_androidHardwareBuffer.internal);
317
318 return m_zirconHandle;
319 }
320
321
getAndroidHardwareBuffer(void) const322 vk::pt::AndroidHardwareBufferPtr NativeHandle::getAndroidHardwareBuffer (void) const
323 {
324 DE_ASSERT(m_fd == -1);
325 DE_ASSERT(!m_win32Handle.internal);
326 DE_ASSERT(m_hostPtr == DE_NULL);
327 return m_androidHardwareBuffer;
328 }
329
getHostPtr(void) const330 void* NativeHandle::getHostPtr(void) const
331 {
332 DE_ASSERT(m_fd == -1);
333 DE_ASSERT(!m_win32Handle.internal);
334 return m_hostPtr;
335 }
336
externalSemaphoreTypeToName(vk::VkExternalSemaphoreHandleTypeFlagBits type)337 const char* externalSemaphoreTypeToName (vk::VkExternalSemaphoreHandleTypeFlagBits type)
338 {
339 switch (type)
340 {
341 case vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT:
342 return "opaque_fd";
343
344 case vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_BIT:
345 return "opaque_win32";
346
347 case vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT:
348 return "opaque_win32_kmt";
349
350 case vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_D3D12_FENCE_BIT:
351 return "d3d12_fenc";
352
353 case vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT:
354 return "sync_fd";
355
356 case vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_ZIRCON_EVENT_BIT_FUCHSIA:
357 return "zircon_event";
358
359 default:
360 DE_FATAL("Unknown external semaphore type");
361 return DE_NULL;
362 }
363 }
364
externalFenceTypeToName(vk::VkExternalFenceHandleTypeFlagBits type)365 const char* externalFenceTypeToName (vk::VkExternalFenceHandleTypeFlagBits type)
366 {
367 switch (type)
368 {
369 case vk::VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_FD_BIT:
370 return "opaque_fd";
371
372 case vk::VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_WIN32_BIT:
373 return "opaque_win32";
374
375 case vk::VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT:
376 return "opaque_win32_kmt";
377
378 case vk::VK_EXTERNAL_FENCE_HANDLE_TYPE_SYNC_FD_BIT:
379 return "sync_fd";
380
381 default:
382 DE_FATAL("Unknown external fence type");
383 return DE_NULL;
384 }
385 }
386
externalMemoryTypeToName(vk::VkExternalMemoryHandleTypeFlagBits type)387 const char* externalMemoryTypeToName (vk::VkExternalMemoryHandleTypeFlagBits type)
388 {
389 switch (type)
390 {
391 case vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT:
392 return "opaque_fd";
393
394 case vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT:
395 return "opaque_win32";
396
397 case vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT:
398 return "opaque_win32_kmt";
399
400 case vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D11_TEXTURE_BIT:
401 return "d3d11_texture";
402
403 case vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D11_TEXTURE_KMT_BIT:
404 return "d3d11_texture_kmt";
405
406 case vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D12_HEAP_BIT:
407 return "d3d12_heap";
408
409 case vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D12_RESOURCE_BIT:
410 return "d3d12_resource";
411
412 case vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID:
413 return "android_hardware_buffer";
414
415 case vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT:
416 return "dma_buf";
417
418 case vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_ALLOCATION_BIT_EXT:
419 return "host_allocation";
420
421 case vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_ZIRCON_VMO_BIT_FUCHSIA:
422 return "zircon_vmo";
423
424
425 default:
426 DE_FATAL("Unknown external memory type");
427 return DE_NULL;
428 }
429 }
430
isSupportedPermanence(vk::VkExternalSemaphoreHandleTypeFlagBits type,Permanence permanence)431 bool isSupportedPermanence (vk::VkExternalSemaphoreHandleTypeFlagBits type,
432 Permanence permanence)
433 {
434 switch (type)
435 {
436 case vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_BIT:
437 case vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT:
438 return permanence == PERMANENCE_PERMANENT || permanence == PERMANENCE_TEMPORARY;
439
440 case vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT:
441 return permanence == PERMANENCE_PERMANENT || permanence == PERMANENCE_TEMPORARY;
442
443 case vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT:
444 return permanence == PERMANENCE_TEMPORARY;
445
446 case vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_ZIRCON_EVENT_BIT_FUCHSIA:
447 return permanence == PERMANENCE_PERMANENT || permanence == PERMANENCE_TEMPORARY;
448
449 default:
450 DE_FATAL("Unknown external semaphore type");
451 return false;
452 }
453 }
454
getHandelTypeTransferences(vk::VkExternalSemaphoreHandleTypeFlagBits type)455 Transference getHandelTypeTransferences (vk::VkExternalSemaphoreHandleTypeFlagBits type)
456 {
457 switch (type)
458 {
459 case vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_BIT:
460 case vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT:
461 return TRANSFERENCE_REFERENCE;
462
463 case vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT:
464 return TRANSFERENCE_REFERENCE;
465
466 case vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT:
467 return TRANSFERENCE_COPY;
468
469 case vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_ZIRCON_EVENT_BIT_FUCHSIA:
470 return TRANSFERENCE_REFERENCE;
471
472 default:
473 DE_FATAL("Unknown external semaphore type");
474 return TRANSFERENCE_REFERENCE;
475 }
476 }
477
isSupportedPermanence(vk::VkExternalFenceHandleTypeFlagBits type,Permanence permanence)478 bool isSupportedPermanence (vk::VkExternalFenceHandleTypeFlagBits type,
479 Permanence permanence)
480 {
481 switch (type)
482 {
483 case vk::VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_WIN32_BIT:
484 case vk::VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT:
485 return permanence == PERMANENCE_PERMANENT || permanence == PERMANENCE_TEMPORARY;
486
487 case vk::VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_FD_BIT:
488 return permanence == PERMANENCE_PERMANENT || permanence == PERMANENCE_TEMPORARY;
489
490 case vk::VK_EXTERNAL_FENCE_HANDLE_TYPE_SYNC_FD_BIT:
491 return permanence == PERMANENCE_TEMPORARY;
492
493 default:
494 DE_FATAL("Unknown external fence type");
495 return false;
496 }
497 }
498
getHandelTypeTransferences(vk::VkExternalFenceHandleTypeFlagBits type)499 Transference getHandelTypeTransferences (vk::VkExternalFenceHandleTypeFlagBits type)
500 {
501 switch (type)
502 {
503 case vk::VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_WIN32_BIT:
504 case vk::VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT:
505 return TRANSFERENCE_REFERENCE;
506
507 case vk::VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_FD_BIT:
508 return TRANSFERENCE_REFERENCE;
509
510 case vk::VK_EXTERNAL_FENCE_HANDLE_TYPE_SYNC_FD_BIT:
511 return TRANSFERENCE_COPY;
512
513 default:
514 DE_FATAL("Unknown external fence type");
515 return TRANSFERENCE_REFERENCE;
516 }
517 }
518
getMemoryFd(const vk::DeviceInterface & vkd,vk::VkDevice device,vk::VkDeviceMemory memory,vk::VkExternalMemoryHandleTypeFlagBits externalType)519 int getMemoryFd (const vk::DeviceInterface& vkd,
520 vk::VkDevice device,
521 vk::VkDeviceMemory memory,
522 vk::VkExternalMemoryHandleTypeFlagBits externalType)
523 {
524 const vk::VkMemoryGetFdInfoKHR info =
525 {
526 vk::VK_STRUCTURE_TYPE_MEMORY_GET_FD_INFO_KHR,
527 DE_NULL,
528
529 memory,
530 externalType
531 };
532 int fd = -1;
533
534 VK_CHECK(vkd.getMemoryFdKHR(device, &info, &fd));
535 TCU_CHECK(fd >= 0);
536
537 return fd;
538 }
539
getMemoryNative(const vk::DeviceInterface & vkd,vk::VkDevice device,vk::VkDeviceMemory memory,vk::VkExternalMemoryHandleTypeFlagBits externalType,NativeHandle & nativeHandle)540 void getMemoryNative (const vk::DeviceInterface& vkd,
541 vk::VkDevice device,
542 vk::VkDeviceMemory memory,
543 vk::VkExternalMemoryHandleTypeFlagBits externalType,
544 NativeHandle& nativeHandle)
545 {
546 if (externalType == vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT
547 || externalType == vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT)
548 {
549 const vk::VkMemoryGetFdInfoKHR info =
550 {
551 vk::VK_STRUCTURE_TYPE_MEMORY_GET_FD_INFO_KHR,
552 DE_NULL,
553
554 memory,
555 externalType
556 };
557 int fd = -1;
558
559 VK_CHECK(vkd.getMemoryFdKHR(device, &info, &fd));
560 TCU_CHECK(fd >= 0);
561 nativeHandle = fd;
562 }
563 else if (externalType == vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_ZIRCON_VMO_BIT_FUCHSIA)
564 {
565 const vk::VkMemoryGetZirconHandleInfoFUCHSIA info =
566 {
567 vk::VK_STRUCTURE_TYPE_MEMORY_GET_ZIRCON_HANDLE_INFO_FUCHSIA,
568 DE_NULL,
569
570 memory,
571 externalType
572 };
573 vk::pt::zx_handle_t handle(0);
574
575 VK_CHECK(vkd.getMemoryZirconHandleFUCHSIA(device, &info, &handle));
576 nativeHandle.setZirconHandle(handle);
577 }
578 else if (externalType == vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT
579 || externalType == vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT)
580 {
581 const vk::VkMemoryGetWin32HandleInfoKHR info =
582 {
583 vk::VK_STRUCTURE_TYPE_MEMORY_GET_WIN32_HANDLE_INFO_KHR,
584 DE_NULL,
585
586 memory,
587 externalType
588 };
589 vk::pt::Win32Handle handle (DE_NULL);
590
591 VK_CHECK(vkd.getMemoryWin32HandleKHR(device, &info, &handle));
592
593 switch (externalType)
594 {
595 case vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT:
596 nativeHandle.setWin32Handle(NativeHandle::WIN32HANDLETYPE_NT, handle);
597 break;
598
599 case vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT:
600 nativeHandle.setWin32Handle(NativeHandle::WIN32HANDLETYPE_KMT, handle);
601 break;
602
603 default:
604 DE_FATAL("Unknown external memory handle type");
605 }
606 }
607 else if (externalType == vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID)
608 {
609 if (!AndroidHardwareBufferExternalApi::getInstance())
610 {
611 TCU_THROW(NotSupportedError, "Platform doesn't support Android Hardware Buffer handles");
612 }
613 const vk::VkMemoryGetAndroidHardwareBufferInfoANDROID info =
614 {
615 vk::VK_STRUCTURE_TYPE_MEMORY_GET_ANDROID_HARDWARE_BUFFER_INFO_ANDROID,
616 DE_NULL,
617
618 memory,
619 };
620 vk::pt::AndroidHardwareBufferPtr ahb (DE_NULL);
621
622 VK_CHECK(vkd.getMemoryAndroidHardwareBufferANDROID(device, &info, &ahb));
623 TCU_CHECK(ahb.internal);
624 nativeHandle = ahb;
625 }
626 else
627 DE_FATAL("Unknown external memory handle type");
628 }
629
createExportableFence(const vk::DeviceInterface & vkd,vk::VkDevice device,vk::VkExternalFenceHandleTypeFlagBits externalType)630 vk::Move<vk::VkFence> createExportableFence (const vk::DeviceInterface& vkd,
631 vk::VkDevice device,
632 vk::VkExternalFenceHandleTypeFlagBits externalType)
633 {
634 const vk::VkExportFenceCreateInfo exportCreateInfo =
635 {
636 vk::VK_STRUCTURE_TYPE_EXPORT_FENCE_CREATE_INFO,
637 DE_NULL,
638 (vk::VkExternalFenceHandleTypeFlags)externalType
639 };
640 const vk::VkFenceCreateInfo createInfo =
641 {
642 vk::VK_STRUCTURE_TYPE_FENCE_CREATE_INFO,
643 &exportCreateInfo,
644 0u
645 };
646
647 return vk::createFence(vkd, device, &createInfo);
648 }
649
getFenceFd(const vk::DeviceInterface & vkd,vk::VkDevice device,vk::VkFence fence,vk::VkExternalFenceHandleTypeFlagBits externalType)650 int getFenceFd (const vk::DeviceInterface& vkd,
651 vk::VkDevice device,
652 vk::VkFence fence,
653 vk::VkExternalFenceHandleTypeFlagBits externalType)
654 {
655 const vk::VkFenceGetFdInfoKHR info =
656 {
657 vk::VK_STRUCTURE_TYPE_FENCE_GET_FD_INFO_KHR,
658 DE_NULL,
659
660 fence,
661 externalType
662 };
663 int fd = -1;
664
665 VK_CHECK(vkd.getFenceFdKHR(device, &info, &fd));
666 TCU_CHECK(fd >= 0);
667
668 return fd;
669 }
670
getFenceNative(const vk::DeviceInterface & vkd,vk::VkDevice device,vk::VkFence fence,vk::VkExternalFenceHandleTypeFlagBits externalType,NativeHandle & nativeHandle,bool expectFenceUnsignaled)671 void getFenceNative (const vk::DeviceInterface& vkd,
672 vk::VkDevice device,
673 vk::VkFence fence,
674 vk::VkExternalFenceHandleTypeFlagBits externalType,
675 NativeHandle& nativeHandle,
676 bool expectFenceUnsignaled)
677 {
678 if (externalType == vk::VK_EXTERNAL_FENCE_HANDLE_TYPE_SYNC_FD_BIT
679 || externalType == vk::VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_FD_BIT)
680 {
681 const vk::VkFenceGetFdInfoKHR info =
682 {
683 vk::VK_STRUCTURE_TYPE_FENCE_GET_FD_INFO_KHR,
684 DE_NULL,
685
686 fence,
687 externalType
688 };
689 int fd = -1;
690
691 VK_CHECK(vkd.getFenceFdKHR(device, &info, &fd));
692
693 if (externalType == vk::VK_EXTERNAL_FENCE_HANDLE_TYPE_SYNC_FD_BIT)
694 {
695 TCU_CHECK(!expectFenceUnsignaled || (fd >= 0) || (fd == -1));
696 }
697 else
698 {
699 TCU_CHECK(fd >= 0);
700 }
701
702 nativeHandle = fd;
703 }
704 else if (externalType == vk::VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_WIN32_BIT
705 || externalType == vk::VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT)
706 {
707 const vk::VkFenceGetWin32HandleInfoKHR info =
708 {
709 vk::VK_STRUCTURE_TYPE_FENCE_GET_WIN32_HANDLE_INFO_KHR,
710 DE_NULL,
711
712 fence,
713 externalType
714 };
715 vk::pt::Win32Handle handle (DE_NULL);
716
717 VK_CHECK(vkd.getFenceWin32HandleKHR(device, &info, &handle));
718
719 switch (externalType)
720 {
721 case vk::VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_WIN32_BIT:
722 nativeHandle.setWin32Handle(NativeHandle::WIN32HANDLETYPE_NT, handle);
723 break;
724
725 case vk::VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT:
726 nativeHandle.setWin32Handle(NativeHandle::WIN32HANDLETYPE_KMT, handle);
727 break;
728
729 default:
730 DE_FATAL("Unknow external memory handle type");
731 }
732 }
733 else
734 DE_FATAL("Unknow external fence handle type");
735 }
736
importFence(const vk::DeviceInterface & vkd,const vk::VkDevice device,const vk::VkFence fence,vk::VkExternalFenceHandleTypeFlagBits externalType,NativeHandle & handle,vk::VkFenceImportFlags flags)737 void importFence (const vk::DeviceInterface& vkd,
738 const vk::VkDevice device,
739 const vk::VkFence fence,
740 vk::VkExternalFenceHandleTypeFlagBits externalType,
741 NativeHandle& handle,
742 vk::VkFenceImportFlags flags)
743 {
744 if (externalType == vk::VK_EXTERNAL_FENCE_HANDLE_TYPE_SYNC_FD_BIT
745 || externalType == vk::VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_FD_BIT)
746 {
747 const vk::VkImportFenceFdInfoKHR importInfo =
748 {
749 vk::VK_STRUCTURE_TYPE_IMPORT_FENCE_FD_INFO_KHR,
750 DE_NULL,
751 fence,
752 flags,
753 externalType,
754 handle.getFd()
755 };
756
757 VK_CHECK(vkd.importFenceFdKHR(device, &importInfo));
758 handle.disown();
759 }
760 else if (externalType == vk::VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_WIN32_BIT
761 || externalType == vk::VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT)
762 {
763 const vk::VkImportFenceWin32HandleInfoKHR importInfo =
764 {
765 vk::VK_STRUCTURE_TYPE_IMPORT_FENCE_WIN32_HANDLE_INFO_KHR,
766 DE_NULL,
767 fence,
768 flags,
769 externalType,
770 handle.getWin32Handle(),
771 (vk::pt::Win32LPCWSTR)DE_NULL
772 };
773
774 VK_CHECK(vkd.importFenceWin32HandleKHR(device, &importInfo));
775 // \note Importing a fence payload from Windows handles does not transfer ownership of the handle to the Vulkan implementation,
776 // so we do not disown the handle until after all use has complete.
777 }
778 else
779 DE_FATAL("Unknown fence external handle type");
780 }
781
createAndImportFence(const vk::DeviceInterface & vkd,const vk::VkDevice device,vk::VkExternalFenceHandleTypeFlagBits externalType,NativeHandle & handle,vk::VkFenceImportFlags flags)782 vk::Move<vk::VkFence> createAndImportFence (const vk::DeviceInterface& vkd,
783 const vk::VkDevice device,
784 vk::VkExternalFenceHandleTypeFlagBits externalType,
785 NativeHandle& handle,
786 vk::VkFenceImportFlags flags)
787 {
788 vk::Move<vk::VkFence> fence (createFence(vkd, device));
789
790 importFence(vkd, device, *fence, externalType, handle, flags);
791
792 return fence;
793 }
794
createExportableSemaphore(const vk::DeviceInterface & vkd,vk::VkDevice device,vk::VkExternalSemaphoreHandleTypeFlagBits externalType)795 vk::Move<vk::VkSemaphore> createExportableSemaphore (const vk::DeviceInterface& vkd,
796 vk::VkDevice device,
797 vk::VkExternalSemaphoreHandleTypeFlagBits externalType)
798 {
799 const vk::VkExportSemaphoreCreateInfo exportCreateInfo =
800 {
801 vk::VK_STRUCTURE_TYPE_EXPORT_SEMAPHORE_CREATE_INFO,
802 DE_NULL,
803 (vk::VkExternalSemaphoreHandleTypeFlags)externalType
804 };
805 const vk::VkSemaphoreCreateInfo createInfo =
806 {
807 vk::VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO,
808 &exportCreateInfo,
809 0u
810 };
811
812 return vk::createSemaphore(vkd, device, &createInfo);
813 }
814
createExportableSemaphoreType(const vk::DeviceInterface & vkd,vk::VkDevice device,vk::VkSemaphoreType semaphoreType,vk::VkExternalSemaphoreHandleTypeFlagBits externalType)815 vk::Move<vk::VkSemaphore> createExportableSemaphoreType (const vk::DeviceInterface& vkd,
816 vk::VkDevice device,
817 vk::VkSemaphoreType semaphoreType,
818 vk::VkExternalSemaphoreHandleTypeFlagBits externalType)
819 {
820 const vk::VkSemaphoreTypeCreateInfo semaphoreTypeCreateInfo =
821 {
822 vk::VK_STRUCTURE_TYPE_SEMAPHORE_TYPE_CREATE_INFO,
823 DE_NULL,
824 semaphoreType,
825 0,
826 };
827 const vk::VkExportSemaphoreCreateInfo exportCreateInfo =
828 {
829 vk::VK_STRUCTURE_TYPE_EXPORT_SEMAPHORE_CREATE_INFO,
830 &semaphoreTypeCreateInfo,
831 (vk::VkExternalSemaphoreHandleTypeFlags)externalType
832 };
833 const vk::VkSemaphoreCreateInfo createInfo =
834 {
835 vk::VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO,
836 &exportCreateInfo,
837 0u
838 };
839
840 return vk::createSemaphore(vkd, device, &createInfo);
841 }
842
getSemaphoreFd(const vk::DeviceInterface & vkd,vk::VkDevice device,vk::VkSemaphore semaphore,vk::VkExternalSemaphoreHandleTypeFlagBits externalType)843 int getSemaphoreFd (const vk::DeviceInterface& vkd,
844 vk::VkDevice device,
845 vk::VkSemaphore semaphore,
846 vk::VkExternalSemaphoreHandleTypeFlagBits externalType)
847 {
848 const vk::VkSemaphoreGetFdInfoKHR info =
849 {
850 vk::VK_STRUCTURE_TYPE_SEMAPHORE_GET_FD_INFO_KHR,
851 DE_NULL,
852
853 semaphore,
854 externalType
855 };
856 int fd = -1;
857
858 VK_CHECK(vkd.getSemaphoreFdKHR(device, &info, &fd));
859 TCU_CHECK(fd >= 0);
860
861 return fd;
862 }
863
getSemaphoreNative(const vk::DeviceInterface & vkd,vk::VkDevice device,vk::VkSemaphore semaphore,vk::VkExternalSemaphoreHandleTypeFlagBits externalType,NativeHandle & nativeHandle)864 void getSemaphoreNative (const vk::DeviceInterface& vkd,
865 vk::VkDevice device,
866 vk::VkSemaphore semaphore,
867 vk::VkExternalSemaphoreHandleTypeFlagBits externalType,
868 NativeHandle& nativeHandle)
869 {
870 if (externalType == vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT
871 || externalType == vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT)
872 {
873 const vk::VkSemaphoreGetFdInfoKHR info =
874 {
875 vk::VK_STRUCTURE_TYPE_SEMAPHORE_GET_FD_INFO_KHR,
876 DE_NULL,
877
878 semaphore,
879 externalType
880 };
881 int fd = -1;
882
883 VK_CHECK(vkd.getSemaphoreFdKHR(device, &info, &fd));
884
885 if (externalType == vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT)
886 TCU_CHECK(fd >= -1);
887 else
888 TCU_CHECK(fd >= 0);
889
890 nativeHandle = fd;
891 }
892 else if (externalType == vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_ZIRCON_EVENT_BIT_FUCHSIA)
893 {
894 const vk::VkSemaphoreGetZirconHandleInfoFUCHSIA info =
895 {
896 vk::VK_STRUCTURE_TYPE_SEMAPHORE_GET_ZIRCON_HANDLE_INFO_FUCHSIA,
897 DE_NULL,
898
899 semaphore,
900 externalType
901 };
902 vk::pt::zx_handle_t zirconHandle(0);
903
904 VK_CHECK(vkd.getSemaphoreZirconHandleFUCHSIA(device, &info, &zirconHandle));
905 nativeHandle.setZirconHandle(zirconHandle);
906 }
907 else if (externalType == vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_BIT
908 || externalType == vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT)
909 {
910 const vk::VkSemaphoreGetWin32HandleInfoKHR info =
911 {
912 vk::VK_STRUCTURE_TYPE_SEMAPHORE_GET_WIN32_HANDLE_INFO_KHR,
913 DE_NULL,
914
915 semaphore,
916 externalType
917 };
918 vk::pt::Win32Handle handle (DE_NULL);
919
920 VK_CHECK(vkd.getSemaphoreWin32HandleKHR(device, &info, &handle));
921
922 switch (externalType)
923 {
924 case vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_BIT:
925 nativeHandle.setWin32Handle(NativeHandle::WIN32HANDLETYPE_NT, handle);
926 break;
927
928 case vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT:
929 nativeHandle.setWin32Handle(NativeHandle::WIN32HANDLETYPE_KMT, handle);
930 break;
931
932 default:
933 DE_FATAL("Unknow external memory handle type");
934 }
935 }
936 else
937 DE_FATAL("Unknow external semaphore handle type");
938 }
939
importSemaphore(const vk::DeviceInterface & vkd,const vk::VkDevice device,const vk::VkSemaphore semaphore,vk::VkExternalSemaphoreHandleTypeFlagBits externalType,NativeHandle & handle,vk::VkSemaphoreImportFlags flags)940 void importSemaphore (const vk::DeviceInterface& vkd,
941 const vk::VkDevice device,
942 const vk::VkSemaphore semaphore,
943 vk::VkExternalSemaphoreHandleTypeFlagBits externalType,
944 NativeHandle& handle,
945 vk::VkSemaphoreImportFlags flags)
946 {
947 if (externalType == vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT
948 || externalType == vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT)
949 {
950 const vk::VkImportSemaphoreFdInfoKHR importInfo =
951 {
952 vk::VK_STRUCTURE_TYPE_IMPORT_SEMAPHORE_FD_INFO_KHR,
953 DE_NULL,
954 semaphore,
955 flags,
956 externalType,
957 handle.getFd()
958 };
959
960 VK_CHECK(vkd.importSemaphoreFdKHR(device, &importInfo));
961 handle.disown();
962 }
963 else if (externalType == vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_ZIRCON_EVENT_BIT_FUCHSIA)
964 {
965 const vk::VkImportSemaphoreZirconHandleInfoFUCHSIA importInfo =
966 {
967 vk::VK_STRUCTURE_TYPE_IMPORT_SEMAPHORE_ZIRCON_HANDLE_INFO_FUCHSIA,
968 DE_NULL,
969 semaphore,
970 flags,
971 externalType,
972 handle.getZirconHandle()
973 };
974
975 VK_CHECK(vkd.importSemaphoreZirconHandleFUCHSIA(device, &importInfo));
976 handle.disown();
977 }
978 else if (externalType == vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_BIT
979 || externalType == vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT)
980 {
981 const vk::VkImportSemaphoreWin32HandleInfoKHR importInfo =
982 {
983 vk::VK_STRUCTURE_TYPE_IMPORT_SEMAPHORE_WIN32_HANDLE_INFO_KHR,
984 DE_NULL,
985 semaphore,
986 flags,
987 externalType,
988 handle.getWin32Handle(),
989 (vk::pt::Win32LPCWSTR)DE_NULL
990 };
991
992 VK_CHECK(vkd.importSemaphoreWin32HandleKHR(device, &importInfo));
993 // \note Importing a semaphore payload from Windows handles does not transfer ownership of the handle to the Vulkan implementation,
994 // so we do not disown the handle until after all use has complete.
995 }
996 else
997 DE_FATAL("Unknown semaphore external handle type");
998 }
999
createAndImportSemaphore(const vk::DeviceInterface & vkd,const vk::VkDevice device,vk::VkExternalSemaphoreHandleTypeFlagBits externalType,NativeHandle & handle,vk::VkSemaphoreImportFlags flags)1000 vk::Move<vk::VkSemaphore> createAndImportSemaphore (const vk::DeviceInterface& vkd,
1001 const vk::VkDevice device,
1002 vk::VkExternalSemaphoreHandleTypeFlagBits externalType,
1003 NativeHandle& handle,
1004 vk::VkSemaphoreImportFlags flags)
1005 {
1006 vk::Move<vk::VkSemaphore> semaphore (createSemaphore(vkd, device));
1007
1008 importSemaphore(vkd, device, *semaphore, externalType, handle, flags);
1009
1010 return semaphore;
1011 }
1012
chooseMemoryType(deUint32 bits)1013 deUint32 chooseMemoryType(deUint32 bits)
1014 {
1015 if (bits == 0)
1016 return 0;
1017
1018 for (deUint32 memoryTypeIndex = 0; (1u << memoryTypeIndex) <= bits; memoryTypeIndex++)
1019 {
1020 if ((bits & (1u << memoryTypeIndex)) != 0)
1021 return memoryTypeIndex;
1022 }
1023
1024 DE_FATAL("No supported memory types");
1025 return -1;
1026 }
1027
chooseHostVisibleMemoryType(deUint32 bits,const vk::VkPhysicalDeviceMemoryProperties properties)1028 deUint32 chooseHostVisibleMemoryType (deUint32 bits, const vk::VkPhysicalDeviceMemoryProperties properties)
1029 {
1030 DE_ASSERT(bits != 0);
1031
1032 for (deUint32 memoryTypeIndex = 0; (1u << memoryTypeIndex) <= bits; memoryTypeIndex++)
1033 {
1034 if (((bits & (1u << memoryTypeIndex)) != 0) &&
1035 ((properties.memoryTypes[memoryTypeIndex].propertyFlags & vk::VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) != 0))
1036 return memoryTypeIndex;
1037 }
1038
1039 TCU_THROW(NotSupportedError, "No supported memory type found");
1040 return -1;
1041 }
1042
getImageMemoryRequirements(const vk::DeviceInterface & vkd,vk::VkDevice device,vk::VkImage image,vk::VkExternalMemoryHandleTypeFlagBits externalType)1043 vk::VkMemoryRequirements getImageMemoryRequirements (const vk::DeviceInterface& vkd,
1044 vk::VkDevice device,
1045 vk::VkImage image,
1046 vk::VkExternalMemoryHandleTypeFlagBits externalType)
1047 {
1048 if (externalType == vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID)
1049 {
1050 return { 0u, 0u, 0u };
1051 }
1052 else
1053 {
1054 return vk::getImageMemoryRequirements(vkd, device, image);
1055 }
1056 }
1057
allocateExportableMemory(const vk::DeviceInterface & vkd,vk::VkDevice device,vk::VkDeviceSize allocationSize,deUint32 memoryTypeIndex,vk::VkExternalMemoryHandleTypeFlagBits externalType,vk::VkBuffer buffer)1058 vk::Move<vk::VkDeviceMemory> allocateExportableMemory (const vk::DeviceInterface& vkd,
1059 vk::VkDevice device,
1060 vk::VkDeviceSize allocationSize,
1061 deUint32 memoryTypeIndex,
1062 vk::VkExternalMemoryHandleTypeFlagBits externalType,
1063 vk::VkBuffer buffer)
1064 {
1065 const vk::VkMemoryDedicatedAllocateInfo dedicatedInfo =
1066 {
1067 vk::VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO,
1068 DE_NULL,
1069
1070 (vk::VkImage)0,
1071 buffer
1072 };
1073 const vk::VkExportMemoryAllocateInfo exportInfo =
1074 {
1075 vk::VK_STRUCTURE_TYPE_EXPORT_MEMORY_ALLOCATE_INFO,
1076 !!buffer ? &dedicatedInfo : DE_NULL,
1077 (vk::VkExternalMemoryHandleTypeFlags)externalType
1078 };
1079 const vk::VkMemoryAllocateInfo info =
1080 {
1081 vk::VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,
1082 &exportInfo,
1083 allocationSize,
1084 memoryTypeIndex
1085 };
1086 return vk::allocateMemory(vkd, device, &info);
1087 }
1088
allocateExportableMemory(const vk::DeviceInterface & vkd,vk::VkDevice device,vk::VkDeviceSize allocationSize,deUint32 memoryTypeIndex,vk::VkExternalMemoryHandleTypeFlagBits externalType,vk::VkImage image)1089 vk::Move<vk::VkDeviceMemory> allocateExportableMemory (const vk::DeviceInterface& vkd,
1090 vk::VkDevice device,
1091 vk::VkDeviceSize allocationSize,
1092 deUint32 memoryTypeIndex,
1093 vk::VkExternalMemoryHandleTypeFlagBits externalType,
1094 vk::VkImage image)
1095 {
1096 const vk::VkMemoryDedicatedAllocateInfo dedicatedInfo =
1097 {
1098 vk::VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO,
1099 DE_NULL,
1100
1101 image,
1102 (vk::VkBuffer)0
1103 };
1104 const vk::VkExportMemoryAllocateInfo exportInfo =
1105 {
1106 vk::VK_STRUCTURE_TYPE_EXPORT_MEMORY_ALLOCATE_INFO,
1107 !!image ? &dedicatedInfo : DE_NULL,
1108 (vk::VkExternalMemoryHandleTypeFlags)externalType
1109 };
1110 const vk::VkMemoryAllocateInfo info =
1111 {
1112 vk::VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,
1113 &exportInfo,
1114 allocationSize,
1115 memoryTypeIndex
1116 };
1117 return vk::allocateMemory(vkd, device, &info);
1118 }
1119
importMemory(const vk::DeviceInterface & vkd,vk::VkDevice device,vk::VkBuffer buffer,vk::VkImage image,const vk::VkMemoryRequirements & requirements,vk::VkExternalMemoryHandleTypeFlagBits externalType,deUint32 memoryTypeIndex,NativeHandle & handle)1120 static vk::Move<vk::VkDeviceMemory> importMemory (const vk::DeviceInterface& vkd,
1121 vk::VkDevice device,
1122 vk::VkBuffer buffer,
1123 vk::VkImage image,
1124 const vk::VkMemoryRequirements& requirements,
1125 vk::VkExternalMemoryHandleTypeFlagBits externalType,
1126 deUint32 memoryTypeIndex,
1127 NativeHandle& handle)
1128 {
1129 const bool isDedicated = !!buffer || !!image;
1130
1131 DE_ASSERT(!buffer || !image);
1132
1133 if (externalType == vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT
1134 || externalType == vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT)
1135 {
1136 const vk::VkImportMemoryFdInfoKHR importInfo =
1137 {
1138 vk::VK_STRUCTURE_TYPE_IMPORT_MEMORY_FD_INFO_KHR,
1139 DE_NULL,
1140 externalType,
1141 handle.getFd()
1142 };
1143 const vk::VkMemoryDedicatedAllocateInfo dedicatedInfo =
1144 {
1145 vk::VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO,
1146 &importInfo,
1147 image,
1148 buffer,
1149 };
1150 const vk::VkMemoryAllocateInfo info =
1151 {
1152 vk::VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,
1153 (isDedicated ? (const void*)&dedicatedInfo : (const void*)&importInfo),
1154 requirements.size,
1155 (memoryTypeIndex == ~0U) ? chooseMemoryType(requirements.memoryTypeBits) : memoryTypeIndex
1156 };
1157 vk::Move<vk::VkDeviceMemory> memory (vk::allocateMemory(vkd, device, &info));
1158
1159 handle.disown();
1160
1161 return memory;
1162 }
1163 else if (externalType == vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_ZIRCON_VMO_BIT_FUCHSIA)
1164 {
1165 const vk::VkImportMemoryZirconHandleInfoFUCHSIA importInfo =
1166 {
1167 vk::VK_STRUCTURE_TYPE_IMPORT_MEMORY_ZIRCON_HANDLE_INFO_FUCHSIA,
1168 DE_NULL,
1169 externalType,
1170 handle.getZirconHandle()
1171 };
1172 const vk::VkMemoryDedicatedAllocateInfo dedicatedInfo =
1173 {
1174 vk::VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO,
1175 &importInfo,
1176 image,
1177 buffer,
1178 };
1179 const vk::VkMemoryAllocateInfo info =
1180 {
1181 vk::VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,
1182 (isDedicated ? (const void*)&dedicatedInfo : (const void*)&importInfo),
1183 requirements.size,
1184 (memoryTypeIndex == ~0U) ? chooseMemoryType(requirements.memoryTypeBits) : memoryTypeIndex
1185 };
1186 vk::Move<vk::VkDeviceMemory> memory (vk::allocateMemory(vkd, device, &info));
1187
1188 handle.disown();
1189
1190 return memory;
1191 }
1192 else if (externalType == vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT
1193 || externalType == vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT)
1194 {
1195 const vk::VkImportMemoryWin32HandleInfoKHR importInfo =
1196 {
1197 vk::VK_STRUCTURE_TYPE_IMPORT_MEMORY_WIN32_HANDLE_INFO_KHR,
1198 DE_NULL,
1199 externalType,
1200 handle.getWin32Handle(),
1201 (vk::pt::Win32LPCWSTR)DE_NULL
1202 };
1203 const vk::VkMemoryDedicatedAllocateInfo dedicatedInfo =
1204 {
1205 vk::VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO,
1206 &importInfo,
1207 image,
1208 buffer,
1209 };
1210 const vk::VkMemoryAllocateInfo info =
1211 {
1212 vk::VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,
1213 (isDedicated ? (const void*)&dedicatedInfo : (const void*)&importInfo),
1214 requirements.size,
1215 (memoryTypeIndex == ~0U) ? chooseMemoryType(requirements.memoryTypeBits) : memoryTypeIndex
1216 };
1217 vk::Move<vk::VkDeviceMemory> memory (vk::allocateMemory(vkd, device, &info));
1218
1219 // The handle's owned reference must also be released. Do not discard the handle below.
1220 if (externalType != vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT)
1221 handle.disown();
1222
1223 return memory;
1224 }
1225 else if (externalType == vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID)
1226 {
1227 AndroidHardwareBufferExternalApi* ahbApi = AndroidHardwareBufferExternalApi::getInstance();
1228 if (!ahbApi)
1229 {
1230 TCU_THROW(NotSupportedError, "Platform doesn't support Android Hardware Buffer handles");
1231 }
1232
1233 deUint32 ahbFormat = 0;
1234 ahbApi->describe(handle.getAndroidHardwareBuffer(), DE_NULL, DE_NULL, DE_NULL, &ahbFormat, DE_NULL, DE_NULL);
1235 DE_ASSERT(ahbApi->ahbFormatIsBlob(ahbFormat) || image != 0);
1236
1237 vk::VkAndroidHardwareBufferPropertiesANDROID ahbProperties =
1238 {
1239 vk::VK_STRUCTURE_TYPE_ANDROID_HARDWARE_BUFFER_PROPERTIES_ANDROID,
1240 DE_NULL,
1241 0u,
1242 0u
1243 };
1244
1245 VK_CHECK(vkd.getAndroidHardwareBufferPropertiesANDROID(device, handle.getAndroidHardwareBuffer(), &ahbProperties));
1246
1247 vk::VkImportAndroidHardwareBufferInfoANDROID importInfo =
1248 {
1249 vk::VK_STRUCTURE_TYPE_IMPORT_ANDROID_HARDWARE_BUFFER_INFO_ANDROID,
1250 DE_NULL,
1251 handle.getAndroidHardwareBuffer()
1252 };
1253 const vk::VkMemoryDedicatedAllocateInfo dedicatedInfo =
1254 {
1255 vk::VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO_KHR,
1256 &importInfo,
1257 image,
1258 buffer,
1259 };
1260 const vk::VkMemoryAllocateInfo info =
1261 {
1262 vk::VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,
1263 (isDedicated ? (const void*)&dedicatedInfo : (const void*)&importInfo),
1264 ahbProperties.allocationSize,
1265 (memoryTypeIndex == ~0U) ? chooseMemoryType(ahbProperties.memoryTypeBits) : memoryTypeIndex
1266 };
1267 vk::Move<vk::VkDeviceMemory> memory (vk::allocateMemory(vkd, device, &info));
1268
1269 return memory;
1270 }
1271 else if (externalType == vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_ALLOCATION_BIT_EXT)
1272 {
1273 DE_ASSERT(memoryTypeIndex != ~0U);
1274
1275 const vk::VkImportMemoryHostPointerInfoEXT importInfo =
1276 {
1277 vk::VK_STRUCTURE_TYPE_IMPORT_MEMORY_HOST_POINTER_INFO_EXT,
1278 DE_NULL,
1279 externalType,
1280 handle.getHostPtr()
1281 };
1282 const vk::VkMemoryDedicatedAllocateInfo dedicatedInfo =
1283 {
1284 vk::VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO,
1285 &importInfo,
1286 image,
1287 buffer,
1288 };
1289 const vk::VkMemoryAllocateInfo info =
1290 {
1291 vk::VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,
1292 (isDedicated ? (const void*)&dedicatedInfo : (const void*)&importInfo),
1293 requirements.size,
1294 memoryTypeIndex
1295 };
1296 vk::Move<vk::VkDeviceMemory> memory (vk::allocateMemory(vkd, device, &info));
1297
1298 return memory;
1299 }
1300 else
1301 {
1302 DE_FATAL("Unknown external memory type");
1303 return vk::Move<vk::VkDeviceMemory>();
1304 }
1305 }
1306
importMemory(const vk::DeviceInterface & vkd,vk::VkDevice device,const vk::VkMemoryRequirements & requirements,vk::VkExternalMemoryHandleTypeFlagBits externalType,deUint32 memoryTypeIndex,NativeHandle & handle)1307 vk::Move<vk::VkDeviceMemory> importMemory (const vk::DeviceInterface& vkd,
1308 vk::VkDevice device,
1309 const vk::VkMemoryRequirements& requirements,
1310 vk::VkExternalMemoryHandleTypeFlagBits externalType,
1311 deUint32 memoryTypeIndex,
1312 NativeHandle& handle)
1313 {
1314 return importMemory(vkd, device, (vk::VkBuffer)0, (vk::VkImage)0, requirements, externalType, memoryTypeIndex, handle);
1315 }
1316
importDedicatedMemory(const vk::DeviceInterface & vkd,vk::VkDevice device,vk::VkBuffer buffer,const vk::VkMemoryRequirements & requirements,vk::VkExternalMemoryHandleTypeFlagBits externalType,deUint32 memoryTypeIndex,NativeHandle & handle)1317 vk::Move<vk::VkDeviceMemory> importDedicatedMemory (const vk::DeviceInterface& vkd,
1318 vk::VkDevice device,
1319 vk::VkBuffer buffer,
1320 const vk::VkMemoryRequirements& requirements,
1321 vk::VkExternalMemoryHandleTypeFlagBits externalType,
1322 deUint32 memoryTypeIndex,
1323 NativeHandle& handle)
1324 {
1325 return importMemory(vkd, device, buffer, (vk::VkImage)0, requirements, externalType, memoryTypeIndex, handle);
1326 }
1327
importDedicatedMemory(const vk::DeviceInterface & vkd,vk::VkDevice device,vk::VkImage image,const vk::VkMemoryRequirements & requirements,vk::VkExternalMemoryHandleTypeFlagBits externalType,deUint32 memoryTypeIndex,NativeHandle & handle)1328 vk::Move<vk::VkDeviceMemory> importDedicatedMemory (const vk::DeviceInterface& vkd,
1329 vk::VkDevice device,
1330 vk::VkImage image,
1331 const vk::VkMemoryRequirements& requirements,
1332 vk::VkExternalMemoryHandleTypeFlagBits externalType,
1333 deUint32 memoryTypeIndex,
1334 NativeHandle& handle)
1335 {
1336 return importMemory(vkd, device, (vk::VkBuffer)0, image, requirements, externalType, memoryTypeIndex, handle);
1337 }
1338
createExternalBuffer(const vk::DeviceInterface & vkd,vk::VkDevice device,deUint32 queueFamilyIndex,vk::VkExternalMemoryHandleTypeFlagBits externalType,vk::VkDeviceSize size,vk::VkBufferCreateFlags createFlags,vk::VkBufferUsageFlags usageFlags)1339 vk::Move<vk::VkBuffer> createExternalBuffer (const vk::DeviceInterface& vkd,
1340 vk::VkDevice device,
1341 deUint32 queueFamilyIndex,
1342 vk::VkExternalMemoryHandleTypeFlagBits externalType,
1343 vk::VkDeviceSize size,
1344 vk::VkBufferCreateFlags createFlags,
1345 vk::VkBufferUsageFlags usageFlags)
1346 {
1347 const vk::VkExternalMemoryBufferCreateInfo externalCreateInfo =
1348 {
1349 vk::VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_BUFFER_CREATE_INFO,
1350 DE_NULL,
1351 (vk::VkExternalMemoryHandleTypeFlags)externalType
1352 };
1353 const vk::VkBufferCreateInfo createInfo =
1354 {
1355 vk::VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
1356 &externalCreateInfo,
1357 createFlags,
1358 size,
1359 usageFlags,
1360 vk::VK_SHARING_MODE_EXCLUSIVE,
1361 1u,
1362 &queueFamilyIndex
1363 };
1364
1365 return vk::createBuffer(vkd, device, &createInfo);
1366 }
1367
createExternalImage(const vk::DeviceInterface & vkd,vk::VkDevice device,deUint32 queueFamilyIndex,vk::VkExternalMemoryHandleTypeFlagBits externalType,vk::VkFormat format,deUint32 width,deUint32 height,vk::VkImageTiling tiling,vk::VkImageCreateFlags createFlags,vk::VkImageUsageFlags usageFlags,deUint32 mipLevels,deUint32 arrayLayers)1368 vk::Move<vk::VkImage> createExternalImage (const vk::DeviceInterface& vkd,
1369 vk::VkDevice device,
1370 deUint32 queueFamilyIndex,
1371 vk::VkExternalMemoryHandleTypeFlagBits externalType,
1372 vk::VkFormat format,
1373 deUint32 width,
1374 deUint32 height,
1375 vk::VkImageTiling tiling,
1376 vk::VkImageCreateFlags createFlags,
1377 vk::VkImageUsageFlags usageFlags,
1378 deUint32 mipLevels,
1379 deUint32 arrayLayers)
1380 {
1381 if (createFlags & vk::VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT && arrayLayers < 6u)
1382 arrayLayers = 6u;
1383
1384 const vk::VkExternalMemoryImageCreateInfo externalCreateInfo =
1385 {
1386 vk::VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO,
1387 DE_NULL,
1388 (vk::VkExternalMemoryHandleTypeFlags)externalType
1389 };
1390 const vk::VkImageCreateInfo createInfo =
1391 {
1392 vk::VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
1393 &externalCreateInfo,
1394 createFlags,
1395 vk::VK_IMAGE_TYPE_2D,
1396 format,
1397 { width, height, 1u, },
1398 mipLevels,
1399 arrayLayers,
1400 vk::VK_SAMPLE_COUNT_1_BIT,
1401 tiling,
1402 usageFlags,
1403 vk::VK_SHARING_MODE_EXCLUSIVE,
1404 1,
1405 &queueFamilyIndex,
1406 vk::VK_IMAGE_LAYOUT_UNDEFINED
1407 };
1408
1409 return vk::createImage(vkd, device, &createInfo);
1410 }
1411
1412 #if (DE_OS == DE_OS_ANDROID)
1413 # if defined(__ANDROID_API_P__) && (DE_ANDROID_API >= __ANDROID_API_P__)
1414 # define BUILT_WITH_ANDROID_P_HARDWARE_BUFFER 1
1415 # endif
1416
androidGetSdkVersion()1417 static deInt32 androidGetSdkVersion()
1418 {
1419 static deInt32 sdkVersion = -1;
1420 if (sdkVersion < 0)
1421 {
1422 char value[128] = {0};
1423 __system_property_get("ro.build.version.sdk", value);
1424 sdkVersion = static_cast<deInt32>(strtol(value, DE_NULL, 10));
1425 printf("SDK Version is %d\n", sdkVersion);
1426 }
1427 return sdkVersion;
1428 }
1429
checkAnbApiBuild()1430 static deInt32 checkAnbApiBuild()
1431 {
1432 deInt32 sdkVersion = androidGetSdkVersion();
1433 #if !defined(BUILT_WITH_ANDROID_HARDWARE_BUFFER)
1434 // When testing AHB on Android-O and newer the CTS must be compiled against API26 or newer.
1435 DE_TEST_ASSERT(!(sdkVersion >= 26)); /* __ANDROID_API_O__ */
1436 #endif // !defined(BUILT_WITH_ANDROID_HARDWARE_BUFFER)
1437 #if !defined(BUILT_WITH_ANDROID_P_HARDWARE_BUFFER)
1438 // When testing AHB on Android-P and newer the CTS must be compiled against API28 or newer.
1439 DE_TEST_ASSERT(!(sdkVersion >= 28)); /*__ANDROID_API_P__ */
1440 #endif // !defined(BUILT_WITH_ANDROID_P_HARDWARE_BUFFER)
1441 return sdkVersion;
1442 }
1443
supportsAhb()1444 bool AndroidHardwareBufferExternalApi::supportsAhb()
1445 {
1446 return (checkAnbApiBuild() >= __ANDROID_API_O__);
1447 }
1448
supportsCubeMap()1449 bool AndroidHardwareBufferExternalApi::supportsCubeMap()
1450 {
1451 return (checkAnbApiBuild() >= 28);
1452 }
1453
AndroidHardwareBufferExternalApi()1454 AndroidHardwareBufferExternalApi::AndroidHardwareBufferExternalApi()
1455 {
1456 deInt32 sdkVersion = checkAnbApiBuild();
1457 if(sdkVersion >= __ANDROID_API_O__)
1458 {
1459 #if defined(BUILT_WITH_ANDROID_HARDWARE_BUFFER)
1460 if (!loadAhbDynamicApis(sdkVersion))
1461 {
1462 // Couldn't load Android AHB system APIs.
1463 DE_TEST_ASSERT(false);
1464 }
1465 #else
1466 // Invalid Android AHB APIs configuration. Please check the instructions on how to build NDK for Android.
1467 DE_TEST_ASSERT(false);
1468 #endif // defined(BUILT_WITH_ANDROID_HARDWARE_BUFFER)
1469 }
1470 }
1471
~AndroidHardwareBufferExternalApi()1472 AndroidHardwareBufferExternalApi::~AndroidHardwareBufferExternalApi()
1473 {
1474 }
1475
1476 #if defined(BUILT_WITH_ANDROID_HARDWARE_BUFFER)
1477 typedef int (*pfn_system_property_get)(const char *, char *);
1478 typedef int (*pfnAHardwareBuffer_allocate)(const AHardwareBuffer_Desc* desc, AHardwareBuffer** outBuffer);
1479 typedef void (*pfnAHardwareBuffer_describe)(const AHardwareBuffer* buffer, AHardwareBuffer_Desc* outDesc);
1480 typedef void (*pfnAHardwareBuffer_acquire)(AHardwareBuffer* buffer);
1481 typedef void (*pfnAHardwareBuffer_release)(AHardwareBuffer* buffer);
1482
1483 struct AhbFunctions
1484 {
1485 pfnAHardwareBuffer_allocate allocate;
1486 pfnAHardwareBuffer_describe describe;
1487 pfnAHardwareBuffer_acquire acquire;
1488 pfnAHardwareBuffer_release release;
1489 };
1490
1491 static AhbFunctions ahbFunctions;
1492
ahbFunctionsLoaded(AhbFunctions * pAhbFunctions)1493 static bool ahbFunctionsLoaded(AhbFunctions* pAhbFunctions)
1494 {
1495 static bool ahbApiLoaded = false;
1496 if (ahbApiLoaded ||
1497 ((pAhbFunctions->allocate != DE_NULL) &&
1498 (pAhbFunctions->describe != DE_NULL) &&
1499 (pAhbFunctions->acquire != DE_NULL) &&
1500 (pAhbFunctions->release != DE_NULL)))
1501 {
1502 ahbApiLoaded = true;
1503 return true;
1504 }
1505 return false;
1506 }
1507
loadAhbDynamicApis(deInt32 sdkVersion)1508 bool AndroidHardwareBufferExternalApi::loadAhbDynamicApis(deInt32 sdkVersion)
1509 {
1510 if(sdkVersion >= __ANDROID_API_O__)
1511 {
1512 if (!ahbFunctionsLoaded(&ahbFunctions))
1513 {
1514 static de::DynamicLibrary libnativewindow("libnativewindow.so");
1515 ahbFunctions.allocate = reinterpret_cast<pfnAHardwareBuffer_allocate>(libnativewindow.getFunction("AHardwareBuffer_allocate"));
1516 ahbFunctions.describe = reinterpret_cast<pfnAHardwareBuffer_describe>(libnativewindow.getFunction("AHardwareBuffer_describe"));
1517 ahbFunctions.acquire = reinterpret_cast<pfnAHardwareBuffer_acquire>(libnativewindow.getFunction("AHardwareBuffer_acquire"));
1518 ahbFunctions.release = reinterpret_cast<pfnAHardwareBuffer_release>(libnativewindow.getFunction("AHardwareBuffer_release"));
1519
1520 return ahbFunctionsLoaded(&ahbFunctions);
1521
1522 }
1523 else
1524 {
1525 return true;
1526 }
1527 }
1528
1529 return false;
1530 }
1531
1532 class AndroidHardwareBufferExternalApi26 : public AndroidHardwareBufferExternalApi
1533 {
1534 public:
1535
1536 virtual vk::pt::AndroidHardwareBufferPtr allocate(deUint32 width, deUint32 height, deUint32 layers, deUint32 format, deUint64 usage);
1537 virtual void acquire(vk::pt::AndroidHardwareBufferPtr buffer);
1538 virtual void release(vk::pt::AndroidHardwareBufferPtr buffer);
1539 virtual void describe(const vk::pt::AndroidHardwareBufferPtr buffer,
1540 deUint32* width,
1541 deUint32* height,
1542 deUint32* layers,
1543 deUint32* format,
1544 deUint64* usage,
1545 deUint32* stride);
1546 virtual deUint64 vkUsageToAhbUsage(vk::VkImageUsageFlagBits vkFlag);
1547 virtual deUint64 vkCreateToAhbUsage(vk::VkImageCreateFlagBits vkFlag);
1548 virtual deUint32 vkFormatToAhbFormat(vk::VkFormat vkFormat);
1549 virtual deUint64 mustSupportAhbUsageFlags();
ahbFormatIsBlob(deUint32 ahbFormat)1550 virtual bool ahbFormatIsBlob(deUint32 ahbFormat) { return (ahbFormat == AHARDWAREBUFFER_FORMAT_BLOB); };
1551
AndroidHardwareBufferExternalApi26()1552 AndroidHardwareBufferExternalApi26() : AndroidHardwareBufferExternalApi() {};
~AndroidHardwareBufferExternalApi26()1553 virtual ~AndroidHardwareBufferExternalApi26() {};
1554
1555 private:
1556 // Stop the compiler generating methods of copy the object
1557 AndroidHardwareBufferExternalApi26(AndroidHardwareBufferExternalApi26 const& copy); // Not Implemented
1558 AndroidHardwareBufferExternalApi26& operator=(AndroidHardwareBufferExternalApi26 const& copy); // Not Implemented
1559 };
1560
allocate(deUint32 width,deUint32 height,deUint32 layers,deUint32 format,deUint64 usage)1561 vk::pt::AndroidHardwareBufferPtr AndroidHardwareBufferExternalApi26::allocate( deUint32 width,
1562 deUint32 height,
1563 deUint32 layers,
1564 deUint32 format,
1565 deUint64 usage)
1566 {
1567 AHardwareBuffer_Desc hbufferdesc = {
1568 width,
1569 height,
1570 layers, // number of images
1571 format,
1572 usage,
1573 0u, // Stride in pixels, ignored for AHardwareBuffer_allocate()
1574 0u, // Initialize to zero, reserved for future use
1575 0u // Initialize to zero, reserved for future use
1576 };
1577
1578 AHardwareBuffer* hbuffer = DE_NULL;
1579 ahbFunctions.allocate(&hbufferdesc, &hbuffer);
1580
1581 return vk::pt::AndroidHardwareBufferPtr(hbuffer);
1582 }
1583
acquire(vk::pt::AndroidHardwareBufferPtr buffer)1584 void AndroidHardwareBufferExternalApi26::acquire(vk::pt::AndroidHardwareBufferPtr buffer)
1585 {
1586 ahbFunctions.acquire(static_cast<AHardwareBuffer*>(buffer.internal));
1587 }
1588
release(vk::pt::AndroidHardwareBufferPtr buffer)1589 void AndroidHardwareBufferExternalApi26::release(vk::pt::AndroidHardwareBufferPtr buffer)
1590 {
1591 ahbFunctions.release(static_cast<AHardwareBuffer*>(buffer.internal));
1592 }
1593
describe(const vk::pt::AndroidHardwareBufferPtr buffer,deUint32 * width,deUint32 * height,deUint32 * layers,deUint32 * format,deUint64 * usage,deUint32 * stride)1594 void AndroidHardwareBufferExternalApi26::describe( const vk::pt::AndroidHardwareBufferPtr buffer,
1595 deUint32* width,
1596 deUint32* height,
1597 deUint32* layers,
1598 deUint32* format,
1599 deUint64* usage,
1600 deUint32* stride)
1601 {
1602 AHardwareBuffer_Desc desc;
1603 ahbFunctions.describe(static_cast<const AHardwareBuffer*>(buffer.internal), &desc);
1604 if (width) *width = desc.width;
1605 if (height) *height = desc.height;
1606 if (layers) *layers = desc.layers;
1607 if (format) *format = desc.format;
1608 if (usage) *usage = desc.usage;
1609 if (stride) *stride = desc.stride;
1610 }
1611
vkUsageToAhbUsage(vk::VkImageUsageFlagBits vkFlags)1612 deUint64 AndroidHardwareBufferExternalApi26::vkUsageToAhbUsage(vk::VkImageUsageFlagBits vkFlags)
1613 {
1614 switch(vkFlags)
1615 {
1616 case vk::VK_IMAGE_USAGE_TRANSFER_SRC_BIT:
1617 case vk::VK_IMAGE_USAGE_TRANSFER_DST_BIT:
1618 // No AHB equivalent.
1619 return 0u;
1620 case vk::VK_IMAGE_USAGE_SAMPLED_BIT:
1621 return AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE;
1622 case vk::VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT:
1623 return AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE;
1624 case vk::VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT:
1625 case vk::VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT:
1626 // Alias of AHARDWAREBUFFER_USAGE_GPU_FRAMEBUFFER which is defined in later Android API versions.
1627 return AHARDWAREBUFFER_USAGE_GPU_COLOR_OUTPUT;
1628 default:
1629 return 0u;
1630 }
1631 }
1632
vkCreateToAhbUsage(vk::VkImageCreateFlagBits vkFlags)1633 deUint64 AndroidHardwareBufferExternalApi26::vkCreateToAhbUsage(vk::VkImageCreateFlagBits vkFlags)
1634 {
1635 switch(vkFlags)
1636 {
1637 case vk::VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT:
1638 case vk::VK_IMAGE_CREATE_EXTENDED_USAGE_BIT:
1639 // No AHB equivalent.
1640 return 0u;
1641 case vk::VK_IMAGE_CREATE_PROTECTED_BIT:
1642 return AHARDWAREBUFFER_USAGE_PROTECTED_CONTENT;
1643 default:
1644 return 0u;
1645 }
1646 }
1647
vkFormatToAhbFormat(vk::VkFormat vkFormat)1648 deUint32 AndroidHardwareBufferExternalApi26::vkFormatToAhbFormat(vk::VkFormat vkFormat)
1649 {
1650 switch(vkFormat)
1651 {
1652 case vk::VK_FORMAT_R8G8B8A8_UNORM:
1653 return AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM;
1654 case vk::VK_FORMAT_R8G8B8_UNORM:
1655 return AHARDWAREBUFFER_FORMAT_R8G8B8_UNORM;
1656 case vk::VK_FORMAT_R5G6B5_UNORM_PACK16:
1657 return AHARDWAREBUFFER_FORMAT_R5G6B5_UNORM;
1658 case vk::VK_FORMAT_R16G16B16A16_SFLOAT:
1659 return AHARDWAREBUFFER_FORMAT_R16G16B16A16_FLOAT;
1660 case vk::VK_FORMAT_A2B10G10R10_UNORM_PACK32:
1661 return AHARDWAREBUFFER_FORMAT_R10G10B10A2_UNORM;
1662 default:
1663 return 0u;
1664 }
1665 }
1666
mustSupportAhbUsageFlags()1667 deUint64 AndroidHardwareBufferExternalApi26::mustSupportAhbUsageFlags()
1668 {
1669 return (AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE | AHARDWAREBUFFER_USAGE_GPU_COLOR_OUTPUT);
1670 }
1671
1672 #if defined(BUILT_WITH_ANDROID_P_HARDWARE_BUFFER)
1673 class AndroidHardwareBufferExternalApi28 : public AndroidHardwareBufferExternalApi26
1674 {
1675 public:
1676
1677 virtual deUint64 vkCreateToAhbUsage(vk::VkImageCreateFlagBits vkFlag);
1678 virtual deUint32 vkFormatToAhbFormat(vk::VkFormat vkFormat);
1679 virtual deUint64 mustSupportAhbUsageFlags();
1680
AndroidHardwareBufferExternalApi28()1681 AndroidHardwareBufferExternalApi28() : AndroidHardwareBufferExternalApi26() {};
~AndroidHardwareBufferExternalApi28()1682 virtual ~AndroidHardwareBufferExternalApi28() {};
1683
1684 private:
1685 // Stop the compiler generating methods of copy the object
1686 AndroidHardwareBufferExternalApi28(AndroidHardwareBufferExternalApi28 const& copy); // Not Implemented
1687 AndroidHardwareBufferExternalApi28& operator=(AndroidHardwareBufferExternalApi28 const& copy); // Not Implemented
1688 };
1689
vkCreateToAhbUsage(vk::VkImageCreateFlagBits vkFlags)1690 deUint64 AndroidHardwareBufferExternalApi28::vkCreateToAhbUsage(vk::VkImageCreateFlagBits vkFlags)
1691 {
1692 switch(vkFlags)
1693 {
1694 case vk::VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT:
1695 return AHARDWAREBUFFER_USAGE_GPU_CUBE_MAP;
1696 default:
1697 return AndroidHardwareBufferExternalApi26::vkCreateToAhbUsage(vkFlags);
1698 }
1699 }
1700
vkFormatToAhbFormat(vk::VkFormat vkFormat)1701 deUint32 AndroidHardwareBufferExternalApi28::vkFormatToAhbFormat(vk::VkFormat vkFormat)
1702 {
1703 switch(vkFormat)
1704 {
1705 case vk::VK_FORMAT_D16_UNORM:
1706 return AHARDWAREBUFFER_FORMAT_D16_UNORM;
1707 case vk::VK_FORMAT_X8_D24_UNORM_PACK32:
1708 return AHARDWAREBUFFER_FORMAT_D24_UNORM;
1709 case vk::VK_FORMAT_D24_UNORM_S8_UINT:
1710 return AHARDWAREBUFFER_FORMAT_D24_UNORM_S8_UINT;
1711 case vk::VK_FORMAT_D32_SFLOAT:
1712 return AHARDWAREBUFFER_FORMAT_D32_FLOAT;
1713 case vk::VK_FORMAT_D32_SFLOAT_S8_UINT:
1714 return AHARDWAREBUFFER_FORMAT_D32_FLOAT_S8_UINT;
1715 case vk::VK_FORMAT_S8_UINT:
1716 return AHARDWAREBUFFER_FORMAT_S8_UINT;
1717 default:
1718 return AndroidHardwareBufferExternalApi26::vkFormatToAhbFormat(vkFormat);
1719 }
1720 }
1721
mustSupportAhbUsageFlags()1722 deUint64 AndroidHardwareBufferExternalApi28::mustSupportAhbUsageFlags()
1723 {
1724 return AndroidHardwareBufferExternalApi26::mustSupportAhbUsageFlags() | AHARDWAREBUFFER_USAGE_GPU_CUBE_MAP | AHARDWAREBUFFER_USAGE_GPU_MIPMAP_COMPLETE;
1725 }
1726
1727 #endif // defined(BUILT_WITH_ANDROID_P_HARDWARE_BUFFER)
1728
1729 #if defined(BUILT_WITH_ANDROID_T_HARDWARE_BUFFER)
1730 class AndroidHardwareBufferExternalApi33 : public AndroidHardwareBufferExternalApi28
1731 {
1732 public:
1733
1734 virtual deUint32 vkFormatToAhbFormat(vk::VkFormat vkFormat);
1735
AndroidHardwareBufferExternalApi33()1736 AndroidHardwareBufferExternalApi33() : AndroidHardwareBufferExternalApi28() {};
~AndroidHardwareBufferExternalApi33()1737 virtual ~AndroidHardwareBufferExternalApi33() {};
1738
1739 private:
1740 // Stop the compiler generating methods of copy the object
1741 AndroidHardwareBufferExternalApi33(AndroidHardwareBufferExternalApi33 const& copy); // Not Implemented
1742 AndroidHardwareBufferExternalApi33& operator=(AndroidHardwareBufferExternalApi33 const& copy); // Not Implemented
1743 };
1744
vkFormatToAhbFormat(vk::VkFormat vkFormat)1745 deUint32 AndroidHardwareBufferExternalApi33::vkFormatToAhbFormat(vk::VkFormat vkFormat)
1746 {
1747 switch(vkFormat)
1748 {
1749 case vk::VK_FORMAT_R8_UNORM:
1750 return AHARDWAREBUFFER_FORMAT_R8_UNORM;
1751 default:
1752 return AndroidHardwareBufferExternalApi28::vkFormatToAhbFormat(vkFormat);
1753 }
1754 }
1755
1756 #endif // defined(BUILT_WITH_ANDROID_T_HARDWARE_BUFFER)
1757 #endif // defined(BUILT_WITH_ANDROID_HARDWARE_BUFFER)
1758 #endif // (DE_OS == DE_OS_ANDROID)
1759
getInstance()1760 AndroidHardwareBufferExternalApi* AndroidHardwareBufferExternalApi::getInstance()
1761 {
1762 #if (DE_OS == DE_OS_ANDROID)
1763 deInt32 sdkVersion = checkAnbApiBuild();
1764 #if defined(BUILT_WITH_ANDROID_HARDWARE_BUFFER)
1765 # if defined(__ANDROID_API_P__) && (DE_ANDROID_API >= __ANDROID_API_P__)
1766 if (sdkVersion >= __ANDROID_API_P__ )
1767 {
1768 static AndroidHardwareBufferExternalApi28 api28Instance;
1769 return &api28Instance;
1770 }
1771 # endif
1772 # if defined(__ANDROID_API_O__) && (DE_ANDROID_API >= __ANDROID_API_O__)
1773 if (sdkVersion >= __ANDROID_API_O__ )
1774 {
1775 static AndroidHardwareBufferExternalApi26 api26Instance;
1776 return &api26Instance;
1777 }
1778 # endif
1779 #endif // defined(BUILT_WITH_ANDROID_HARDWARE_BUFFER)
1780 DE_UNREF(sdkVersion);
1781 #endif // DE_OS == DE_OS_ANDROID
1782 return DE_NULL;
1783 }
1784
getPhysicalDeviceExternalMemoryHostProperties(const vk::InstanceInterface & vki,vk::VkPhysicalDevice physicalDevice)1785 vk::VkPhysicalDeviceExternalMemoryHostPropertiesEXT getPhysicalDeviceExternalMemoryHostProperties(const vk::InstanceInterface& vki,
1786 vk::VkPhysicalDevice physicalDevice)
1787 {
1788 vk::VkPhysicalDeviceExternalMemoryHostPropertiesEXT externalProps =
1789 {
1790 vk::VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_MEMORY_HOST_PROPERTIES_EXT,
1791 DE_NULL,
1792 0u,
1793 };
1794
1795 vk::VkPhysicalDeviceProperties2 props2;
1796 deMemset(&props2, 0, sizeof(props2));
1797 props2.sType = vk::VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2;
1798 props2.pNext = &externalProps;
1799
1800 vki.getPhysicalDeviceProperties2(physicalDevice, &props2);
1801
1802 return externalProps;
1803 }
1804
1805 } // ExternalMemoryUtil
1806 } // vkt
1807
1808 #endif // CTS_USES_VULKANSC
1809