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