1 /*-------------------------------------------------------------------------
2 * Vulkan Conformance Tests
3 * ------------------------
5 * Copyright (c) 2016 Google Inc.
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
11 * http://www.apache.org/licenses/LICENSE-2.0
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.
19 * \brief Vulkan external memory API tests
20 *//*--------------------------------------------------------------------*/
22 #include "vktApiExternalMemoryTests.hpp"
24 #include "vktTestCaseUtil.hpp"
25 #include "vkRefUtil.hpp"
26 #include "vkDeviceUtil.hpp"
27 #include "vkQueryUtil.hpp"
28 #include "vkPlatform.hpp"
29 #include "vkMemUtil.hpp"
30 #include "vkApiVersion.hpp"
32 #include "tcuTestLog.hpp"
34 #include "deUniquePtr.hpp"
35 #include "deStringUtil.hpp"
36 #include "deRandom.hpp"
40 #include "vktExternalMemoryUtil.hpp"
42 #if (DE_OS == DE_OS_ANDROID) || (DE_OS == DE_OS_UNIX)
46 # include <sys/types.h>
47 # include <sys/socket.h>
50 #if (DE_OS == DE_OS_WIN32)
51 # define WIN32_LEAN_AND_MEAN
57 using namespace vkt::ExternalMemoryUtil;
66 vk::VkMemoryDedicatedRequirements getMemoryDedicatedRequirements (const vk::DeviceInterface& vkd,
70 const vk::VkBufferMemoryRequirementsInfo2 requirementInfo =
72 vk::VK_STRUCTURE_TYPE_BUFFER_MEMORY_REQUIREMENTS_INFO_2,
76 vk::VkMemoryDedicatedRequirements dedicatedRequirements =
78 vk::VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS,
83 vk::VkMemoryRequirements2 requirements =
85 vk::VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2,
86 &dedicatedRequirements,
90 vkd.getBufferMemoryRequirements2(device, &requirementInfo, &requirements);
92 return dedicatedRequirements;
95 vk::VkMemoryDedicatedRequirements getMemoryDedicatedRequirements (const vk::DeviceInterface& vkd,
99 const vk::VkImageMemoryRequirementsInfo2 requirementInfo =
101 vk::VK_STRUCTURE_TYPE_IMAGE_MEMORY_REQUIREMENTS_INFO_2,
105 vk::VkMemoryDedicatedRequirements dedicatedRequirements =
107 vk::VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS,
112 vk::VkMemoryRequirements2 requirements =
114 vk::VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2,
115 &dedicatedRequirements,
119 vkd.getImageMemoryRequirements2(device, &requirementInfo, &requirements);
121 return dedicatedRequirements;
124 void writeHostMemory (const vk::DeviceInterface& vkd,
126 vk::VkDeviceMemory memory,
130 void* const ptr = vk::mapMemory(vkd, device, memory, 0, size, 0);
132 deMemcpy(ptr, data, size);
134 vkd.unmapMemory(device, memory);
137 void checkHostMemory (const vk::DeviceInterface& vkd,
139 vk::VkDeviceMemory memory,
143 void* const ptr = vk::mapMemory(vkd, device, memory, 0, size, 0);
145 if (deMemCmp(ptr, data, size) != 0)
146 TCU_FAIL("Memory contents don't match");
148 vkd.unmapMemory(device, memory);
151 std::vector<deUint8> genTestData (deUint32 seed, size_t size)
153 de::Random rng (seed);
154 std::vector<deUint8> data (size);
156 for (size_t ndx = 0; ndx < size; ndx++)
158 data[ndx] = rng.getUint8();
164 deUint32 chooseQueueFamilyIndex (const vk::InstanceInterface& vki,
165 vk::VkPhysicalDevice device,
166 vk::VkQueueFlags requireFlags)
168 const std::vector<vk::VkQueueFamilyProperties> properties (vk::getPhysicalDeviceQueueFamilyProperties(vki, device));
170 for (deUint32 queueFamilyIndex = 0; queueFamilyIndex < (deUint32)properties.size(); queueFamilyIndex++)
172 if ((properties[queueFamilyIndex].queueFlags & requireFlags) == requireFlags)
173 return queueFamilyIndex;
176 TCU_THROW(NotSupportedError, "Queue type not supported");
179 std::vector<std::string> getInstanceExtensions (const deUint32 instanceVersion,
180 const vk::VkExternalSemaphoreHandleTypeFlags externalSemaphoreTypes,
181 const vk::VkExternalMemoryHandleTypeFlags externalMemoryTypes,
182 const vk::VkExternalFenceHandleTypeFlags externalFenceTypes)
184 std::vector<std::string> instanceExtensions;
186 if (!vk::isCoreInstanceExtension(instanceVersion, "VK_KHR_get_physical_device_properties2"))
187 instanceExtensions.push_back("VK_KHR_get_physical_device_properties2");
189 if (externalSemaphoreTypes != 0)
190 if (!vk::isCoreInstanceExtension(instanceVersion, "VK_KHR_external_semaphore_capabilities"))
191 instanceExtensions.push_back("VK_KHR_external_semaphore_capabilities");
193 if (externalMemoryTypes != 0)
194 if (!vk::isCoreInstanceExtension(instanceVersion, "VK_KHR_external_memory_capabilities"))
195 instanceExtensions.push_back("VK_KHR_external_memory_capabilities");
197 if (externalFenceTypes != 0)
198 if (!vk::isCoreInstanceExtension(instanceVersion, "VK_KHR_external_fence_capabilities"))
199 instanceExtensions.push_back("VK_KHR_external_fence_capabilities");
201 return instanceExtensions;
204 vk::Move<vk::VkInstance> createInstance (const vk::PlatformInterface& vkp,
205 const vk::VkExternalSemaphoreHandleTypeFlags externalSemaphoreTypes,
206 const vk::VkExternalMemoryHandleTypeFlags externalMemoryTypes,
207 const vk::VkExternalFenceHandleTypeFlags externalFenceTypes)
211 deUint32 version = 0u;
212 vkp.enumerateInstanceVersion(&version);
213 return vk::createDefaultInstance(vkp, version, std::vector<std::string>(), getInstanceExtensions(version, externalSemaphoreTypes, externalMemoryTypes, externalFenceTypes));
215 catch (const vk::Error& error)
217 if (error.getError() == vk::VK_ERROR_EXTENSION_NOT_PRESENT)
218 TCU_THROW(NotSupportedError, "Required extensions not supported");
224 vk::Move<vk::VkDevice> createDevice (const deUint32 apiVersion,
225 const vk::InstanceInterface& vki,
226 vk::VkPhysicalDevice physicalDevice,
227 const vk::VkExternalSemaphoreHandleTypeFlags externalSemaphoreTypes,
228 const vk::VkExternalMemoryHandleTypeFlags externalMemoryTypes,
229 const vk::VkExternalFenceHandleTypeFlags externalFenceTypes,
230 deUint32 queueFamilyIndex,
231 bool useDedicatedAllocs = false)
233 std::vector<const char*> deviceExtensions;
235 if ((externalSemaphoreTypes
236 & (vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT
237 | vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT)) != 0)
239 deviceExtensions.push_back("VK_KHR_external_semaphore_fd");
242 if ((externalFenceTypes
243 & (vk::VK_EXTERNAL_FENCE_HANDLE_TYPE_SYNC_FD_BIT
244 | vk::VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_FD_BIT)) != 0)
246 deviceExtensions.push_back("VK_KHR_external_fence_fd");
249 if (useDedicatedAllocs)
251 if (!vk::isCoreDeviceExtension(apiVersion, "VK_KHR_dedicated_allocation"))
252 deviceExtensions.push_back("VK_KHR_dedicated_allocation");
253 if (!vk::isCoreDeviceExtension(apiVersion, "VK_KHR_get_memory_requirements2"))
254 deviceExtensions.push_back("VK_KHR_get_memory_requirements2");
257 if ((externalMemoryTypes
258 & vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT) != 0)
260 deviceExtensions.push_back("VK_KHR_external_memory_fd");
263 if ((externalSemaphoreTypes
264 & (vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_BIT
265 | vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT)) != 0)
267 deviceExtensions.push_back("VK_KHR_external_semaphore_win32");
270 if ((externalFenceTypes
271 & (vk::VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_WIN32_BIT
272 | vk::VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT)) != 0)
274 deviceExtensions.push_back("VK_KHR_external_fence_win32");
277 if ((externalMemoryTypes
278 & (vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT
279 | vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT
280 | vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D11_TEXTURE_BIT
281 | vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D11_TEXTURE_KMT_BIT
282 | vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D12_HEAP_BIT
283 | vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D12_RESOURCE_BIT)) != 0)
285 deviceExtensions.push_back("VK_KHR_external_memory_win32");
288 const float priority = 0.5f;
289 const vk::VkDeviceQueueCreateInfo queues[] =
292 vk::VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO,
301 const vk::VkDeviceCreateInfo deviceCreateInfo =
303 vk::VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,
307 DE_LENGTH_OF_ARRAY(queues),
313 (deUint32)deviceExtensions.size(),
314 deviceExtensions.empty() ? DE_NULL : &deviceExtensions[0],
320 return vk::createDevice(vki, physicalDevice, &deviceCreateInfo);
322 catch (const vk::Error& error)
324 if (error.getError() == vk::VK_ERROR_EXTENSION_NOT_PRESENT)
325 TCU_THROW(NotSupportedError, "Required extensions not supported");
331 vk::VkQueue getQueue (const vk::DeviceInterface& vkd,
333 deUint32 queueFamilyIndex)
337 vkd.getDeviceQueue(device, queueFamilyIndex, 0, &queue);
342 void checkSemaphoreSupport (const vk::InstanceInterface& vki,
343 vk::VkPhysicalDevice device,
344 vk::VkExternalSemaphoreHandleTypeFlagBits externalType)
346 const vk::VkPhysicalDeviceExternalSemaphoreInfo info =
348 vk::VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_SEMAPHORE_INFO,
352 vk::VkExternalSemaphoreProperties properties =
354 vk::VK_STRUCTURE_TYPE_EXTERNAL_SEMAPHORE_PROPERTIES,
361 vki.getPhysicalDeviceExternalSemaphoreProperties(device, &info, &properties);
363 if ((properties.externalSemaphoreFeatures & vk::VK_EXTERNAL_SEMAPHORE_FEATURE_EXPORTABLE_BIT) == 0)
364 TCU_THROW(NotSupportedError, "Semaphore doesn't support exporting in external type");
366 if ((properties.externalSemaphoreFeatures & vk::VK_EXTERNAL_SEMAPHORE_FEATURE_IMPORTABLE_BIT) == 0)
367 TCU_THROW(NotSupportedError, "Semaphore doesn't support importing in external type");
370 void checkFenceSupport (const vk::InstanceInterface& vki,
371 vk::VkPhysicalDevice device,
372 vk::VkExternalFenceHandleTypeFlagBits externalType)
374 const vk::VkPhysicalDeviceExternalFenceInfo info =
376 vk::VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_FENCE_INFO,
380 vk::VkExternalFenceProperties properties =
382 vk::VK_STRUCTURE_TYPE_EXTERNAL_FENCE_PROPERTIES,
389 vki.getPhysicalDeviceExternalFenceProperties(device, &info, &properties);
391 if ((properties.externalFenceFeatures & vk::VK_EXTERNAL_FENCE_FEATURE_EXPORTABLE_BIT) == 0)
392 TCU_THROW(NotSupportedError, "Fence doesn't support exporting in external type");
394 if ((properties.externalFenceFeatures & vk::VK_EXTERNAL_FENCE_FEATURE_IMPORTABLE_BIT) == 0)
395 TCU_THROW(NotSupportedError, "Fence doesn't support importing in external type");
398 void checkBufferSupport (const vk::InstanceInterface& vki,
399 vk::VkPhysicalDevice device,
400 vk::VkExternalMemoryHandleTypeFlagBits externalType,
401 vk::VkBufferViewCreateFlags createFlag,
402 vk::VkBufferUsageFlags usageFlag,
405 const vk::VkPhysicalDeviceExternalBufferInfo info =
407 vk::VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_BUFFER_INFO,
414 vk::VkExternalBufferProperties properties =
416 vk::VK_STRUCTURE_TYPE_EXTERNAL_BUFFER_PROPERTIES,
422 vki.getPhysicalDeviceExternalBufferProperties(device, &info, &properties);
424 if ((properties.externalMemoryProperties.externalMemoryFeatures & vk::VK_EXTERNAL_MEMORY_FEATURE_EXPORTABLE_BIT) == 0)
425 TCU_THROW(NotSupportedError, "External handle type doesn't support exporting buffer");
427 if ((properties.externalMemoryProperties.externalMemoryFeatures & vk::VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT) == 0)
428 TCU_THROW(NotSupportedError, "External handle type doesn't support importing buffer");
430 if (!dedicated && (properties.externalMemoryProperties.externalMemoryFeatures & vk::VK_EXTERNAL_MEMORY_FEATURE_DEDICATED_ONLY_BIT) != 0)
431 TCU_THROW(NotSupportedError, "External handle type requires dedicated allocation");
434 void checkImageSupport (const vk::InstanceInterface& vki,
435 vk::VkPhysicalDevice device,
436 vk::VkExternalMemoryHandleTypeFlagBits externalType,
437 vk::VkImageViewCreateFlags createFlag,
438 vk::VkImageUsageFlags usageFlag,
440 vk::VkImageTiling tiling,
443 const vk::VkPhysicalDeviceExternalImageFormatInfo externalInfo =
445 vk::VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_IMAGE_FORMAT_INFO,
449 const vk::VkPhysicalDeviceImageFormatInfo2 info =
451 vk::VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2,
455 vk::VK_IMAGE_TYPE_2D,
460 vk::VkExternalImageFormatProperties externalProperties =
462 vk::VK_STRUCTURE_TYPE_EXTERNAL_IMAGE_FORMAT_PROPERTIES,
466 vk::VkImageFormatProperties2 properties =
468 vk::VK_STRUCTURE_TYPE_IMAGE_FORMAT_PROPERTIES_2,
479 vki.getPhysicalDeviceImageFormatProperties2(device, &info, &properties);
481 if ((externalProperties.externalMemoryProperties.externalMemoryFeatures & vk::VK_EXTERNAL_MEMORY_FEATURE_EXPORTABLE_BIT) == 0)
482 TCU_THROW(NotSupportedError, "External handle type doesn't support exporting image");
484 if ((externalProperties.externalMemoryProperties.externalMemoryFeatures & vk::VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT) == 0)
485 TCU_THROW(NotSupportedError, "External handle type doesn't support importing image");
487 if (!dedicated && (externalProperties.externalMemoryProperties.externalMemoryFeatures & vk::VK_EXTERNAL_MEMORY_FEATURE_DEDICATED_ONLY_BIT) != 0)
488 TCU_THROW(NotSupportedError, "External handle type requires dedicated allocation");
491 void submitDummySignal (const vk::DeviceInterface& vkd,
493 vk::VkSemaphore semaphore)
495 const vk::VkSubmitInfo submit =
497 vk::VK_STRUCTURE_TYPE_SUBMIT_INFO,
511 VK_CHECK(vkd.queueSubmit(queue, 1, &submit, (vk::VkFence)0u));
514 void submitDummyWait (const vk::DeviceInterface& vkd,
516 vk::VkSemaphore semaphore)
518 const vk::VkPipelineStageFlags stage = vk::VK_PIPELINE_STAGE_ALL_COMMANDS_BIT;
519 const vk::VkSubmitInfo submit =
521 vk::VK_STRUCTURE_TYPE_SUBMIT_INFO,
535 VK_CHECK(vkd.queueSubmit(queue, 1, &submit, (vk::VkFence)0u));
538 void submitDummySignal (const vk::DeviceInterface& vkd,
542 const vk::VkSubmitInfo submit =
544 vk::VK_STRUCTURE_TYPE_SUBMIT_INFO,
558 VK_CHECK(vkd.queueSubmit(queue, 1, &submit, fence));
561 tcu::TestStatus testSemaphoreQueries (Context& context, vk::VkExternalSemaphoreHandleTypeFlagBits externalType)
563 const vk::PlatformInterface& vkp (context.getPlatformInterface());
564 const vk::Unique<vk::VkInstance> instance (createInstance(vkp, externalType, 0u, 0u));
565 const vk::InstanceDriver vki (vkp, *instance);
566 const vk::VkPhysicalDevice device (vk::chooseDevice(vki, *instance, context.getTestContext().getCommandLine()));
568 TestLog& log = context.getTestContext().getLog();
570 const vk::VkPhysicalDeviceExternalSemaphoreInfo info =
572 vk::VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_SEMAPHORE_INFO,
576 vk::VkExternalSemaphoreProperties properties =
578 vk::VK_STRUCTURE_TYPE_EXTERNAL_SEMAPHORE_PROPERTIES,
585 vki.getPhysicalDeviceExternalSemaphoreProperties(device, &info, &properties);
586 log << TestLog::Message << properties << TestLog::EndMessage;
588 TCU_CHECK(properties.pNext == DE_NULL);
589 TCU_CHECK(properties.sType == vk::VK_STRUCTURE_TYPE_EXTERNAL_SEMAPHORE_PROPERTIES);
591 return tcu::TestStatus::pass("Pass");
594 struct SemaphoreTestConfig
596 SemaphoreTestConfig (vk::VkExternalSemaphoreHandleTypeFlagBits externalType_,
597 Permanence permanence_)
598 : externalType (externalType_)
599 , permanence (permanence_)
603 vk::VkExternalSemaphoreHandleTypeFlagBits externalType;
604 Permanence permanence;
607 tcu::TestStatus testSemaphoreWin32Create (Context& context,
608 const SemaphoreTestConfig config)
610 #if (DE_OS == DE_OS_WIN32)
611 const Transference transference (getHandelTypeTransferences(config.externalType));
612 const vk::PlatformInterface& vkp (context.getPlatformInterface());
613 const vk::Unique<vk::VkInstance> instance (createInstance(vkp, config.externalType, 0u, 0u));
614 const vk::InstanceDriver vki (vkp, *instance);
615 const vk::VkPhysicalDevice physicalDevice (vk::chooseDevice(vki, *instance, context.getTestContext().getCommandLine()));
616 const deUint32 queueFamilyIndex (chooseQueueFamilyIndex(vki, physicalDevice, 0u));
618 checkSemaphoreSupport(vki, physicalDevice, config.externalType);
621 const vk::Unique<vk::VkDevice> device (createDevice(context.getUsedApiVersion(), vki, physicalDevice, config.externalType, 0u, 0u, queueFamilyIndex));
622 const vk::DeviceDriver vkd (vki, *device);
623 const vk::VkQueue queue (getQueue(vkd, *device, queueFamilyIndex));
624 const vk::VkExportSemaphoreWin32HandleInfoKHR win32ExportInfo =
626 vk::VK_STRUCTURE_TYPE_EXPORT_SEMAPHORE_WIN32_HANDLE_INFO_KHR,
629 (vk::pt::Win32SecurityAttributesPtr)DE_NULL,
630 DXGI_SHARED_RESOURCE_READ | DXGI_SHARED_RESOURCE_WRITE,
633 const vk::VkExportSemaphoreCreateInfo exportCreateInfo=
635 vk::VK_STRUCTURE_TYPE_EXPORT_SEMAPHORE_CREATE_INFO,
637 (vk::VkExternalMemoryHandleTypeFlags)config.externalType
639 const vk::VkSemaphoreCreateInfo createInfo =
641 vk::VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO,
645 const vk::Unique<vk::VkSemaphore> semaphore (vk::createSemaphore(vkd, *device, &createInfo));
647 if (transference == TRANSFERENCE_COPY)
648 submitDummySignal(vkd, queue, *semaphore);
650 NativeHandle handleA;
651 getSemaphoreNative(vkd, *device, *semaphore, config.externalType, handleA);
654 const vk::VkSemaphoreImportFlags flags = config.permanence == PERMANENCE_TEMPORARY ? vk::VK_SEMAPHORE_IMPORT_TEMPORARY_BIT : (vk::VkSemaphoreImportFlagBits)0u;
655 const vk::Unique<vk::VkSemaphore> semaphoreA (createAndImportSemaphore(vkd, *device, config.externalType, handleA, flags));
657 if (transference == TRANSFERENCE_COPY)
658 submitDummyWait(vkd, queue, *semaphoreA);
659 else if (transference == TRANSFERENCE_REFERENCE)
661 submitDummySignal(vkd, queue, *semaphore);
662 submitDummyWait(vkd, queue, *semaphoreA);
665 DE_FATAL("Unknown transference.");
667 VK_CHECK(vkd.queueWaitIdle(queue));
670 return tcu::TestStatus::pass("Pass");
675 TCU_THROW(NotSupportedError, "Platform doesn't support win32 handles");
679 tcu::TestStatus testSemaphoreImportTwice (Context& context,
680 const SemaphoreTestConfig config)
682 const Transference transference (getHandelTypeTransferences(config.externalType));
683 const vk::PlatformInterface& vkp (context.getPlatformInterface());
684 const vk::Unique<vk::VkInstance> instance (createInstance(vkp, config.externalType, 0u, 0u));
685 const vk::InstanceDriver vki (vkp, *instance);
686 const vk::VkPhysicalDevice physicalDevice (vk::chooseDevice(vki, *instance, context.getTestContext().getCommandLine()));
687 const deUint32 queueFamilyIndex (chooseQueueFamilyIndex(vki, physicalDevice, 0u));
689 checkSemaphoreSupport(vki, physicalDevice, config.externalType);
692 const vk::Unique<vk::VkDevice> device (createDevice(context.getUsedApiVersion(), vki, physicalDevice, config.externalType, 0u, 0u, queueFamilyIndex));
693 const vk::DeviceDriver vkd (vki, *device);
694 const vk::VkQueue queue (getQueue(vkd, *device, queueFamilyIndex));
695 const vk::Unique<vk::VkSemaphore> semaphore (createExportableSemaphore(vkd, *device, config.externalType));
697 if (transference == TRANSFERENCE_COPY)
698 submitDummySignal(vkd, queue, *semaphore);
700 NativeHandle handleA;
701 getSemaphoreNative(vkd, *device, *semaphore, config.externalType, handleA);
704 NativeHandle handleB (handleA);
705 const vk::VkSemaphoreImportFlags flags = config.permanence == PERMANENCE_TEMPORARY ? vk::VK_SEMAPHORE_IMPORT_TEMPORARY_BIT : (vk::VkSemaphoreImportFlagBits)0u;
706 const vk::Unique<vk::VkSemaphore> semaphoreA (createAndImportSemaphore(vkd, *device, config.externalType, handleA, flags));
707 const vk::Unique<vk::VkSemaphore> semaphoreB (createAndImportSemaphore(vkd, *device, config.externalType, handleB, flags));
709 if (transference == TRANSFERENCE_COPY)
710 submitDummyWait(vkd, queue, *semaphoreA);
711 else if (transference == TRANSFERENCE_REFERENCE)
713 submitDummySignal(vkd, queue, *semaphoreA);
714 submitDummyWait(vkd, queue, *semaphoreB);
717 DE_FATAL("Unknown transference.");
719 VK_CHECK(vkd.queueWaitIdle(queue));
722 return tcu::TestStatus::pass("Pass");
726 tcu::TestStatus testSemaphoreImportReimport (Context& context,
727 const SemaphoreTestConfig config)
729 const Transference transference (getHandelTypeTransferences(config.externalType));
730 const vk::PlatformInterface& vkp (context.getPlatformInterface());
731 const vk::Unique<vk::VkInstance> instance (createInstance(vkp, config.externalType, 0u, 0u));
732 const vk::InstanceDriver vki (vkp, *instance);
733 const vk::VkPhysicalDevice physicalDevice (vk::chooseDevice(vki, *instance, context.getTestContext().getCommandLine()));
734 const deUint32 queueFamilyIndex (chooseQueueFamilyIndex(vki, physicalDevice, 0u));
736 checkSemaphoreSupport(vki, physicalDevice, config.externalType);
739 const vk::Unique<vk::VkDevice> device (createDevice(context.getUsedApiVersion(), vki, physicalDevice, config.externalType, 0u, 0u, queueFamilyIndex));
740 const vk::DeviceDriver vkd (vki, *device);
741 const vk::VkQueue queue (getQueue(vkd, *device, queueFamilyIndex));
743 const vk::Unique<vk::VkSemaphore> semaphoreA (createExportableSemaphore(vkd, *device, config.externalType));
745 if (transference == TRANSFERENCE_COPY)
746 submitDummySignal(vkd, queue, *semaphoreA);
748 NativeHandle handleA;
749 getSemaphoreNative(vkd, *device, *semaphoreA, config.externalType, handleA);
751 NativeHandle handleB (handleA);
752 const vk::VkSemaphoreImportFlags flags = config.permanence == PERMANENCE_TEMPORARY ? vk::VK_SEMAPHORE_IMPORT_TEMPORARY_BIT : (vk::VkSemaphoreImportFlagBits)0u;
753 const vk::Unique<vk::VkSemaphore> semaphoreB (createAndImportSemaphore(vkd, *device, config.externalType, handleA, flags));
755 importSemaphore(vkd, *device, *semaphoreB, config.externalType, handleB, flags);
757 if (transference == TRANSFERENCE_COPY)
758 submitDummyWait(vkd, queue, *semaphoreB);
759 else if (transference == TRANSFERENCE_REFERENCE)
761 submitDummySignal(vkd, queue, *semaphoreA);
762 submitDummyWait(vkd, queue, *semaphoreB);
765 DE_FATAL("Unknown transference.");
767 VK_CHECK(vkd.queueWaitIdle(queue));
769 return tcu::TestStatus::pass("Pass");
773 tcu::TestStatus testSemaphoreSignalExportImportWait (Context& context,
774 const SemaphoreTestConfig config)
776 const vk::PlatformInterface& vkp (context.getPlatformInterface());
777 const vk::Unique<vk::VkInstance> instance (createInstance(vkp, config.externalType, 0u, 0u));
778 const vk::InstanceDriver vki (vkp, *instance);
779 const vk::VkPhysicalDevice physicalDevice (vk::chooseDevice(vki, *instance, context.getTestContext().getCommandLine()));
780 const deUint32 queueFamilyIndex (chooseQueueFamilyIndex(vki, physicalDevice, 0u));
782 checkSemaphoreSupport(vki, physicalDevice, config.externalType);
785 const vk::Unique<vk::VkDevice> device (createDevice(context.getUsedApiVersion(), vki, physicalDevice, config.externalType, 0u, 0u, queueFamilyIndex));
786 const vk::DeviceDriver vkd (vki, *device);
787 const vk::VkQueue queue (getQueue(vkd, *device, queueFamilyIndex));
788 const vk::Unique<vk::VkSemaphore> semaphoreA (createExportableSemaphore(vkd, *device, config.externalType));
790 submitDummySignal(vkd, queue, *semaphoreA);
795 getSemaphoreNative(vkd, *device, *semaphoreA, config.externalType, handle);
798 const vk::VkSemaphoreImportFlags flags = config.permanence == PERMANENCE_TEMPORARY ? vk::VK_SEMAPHORE_IMPORT_TEMPORARY_BIT : (vk::VkSemaphoreImportFlagBits)0u;
799 const vk::Unique<vk::VkSemaphore> semaphoreB (createAndImportSemaphore(vkd, *device, config.externalType, handle, flags));
800 submitDummyWait(vkd, queue, *semaphoreB);
802 VK_CHECK(vkd.queueWaitIdle(queue));
806 return tcu::TestStatus::pass("Pass");
810 tcu::TestStatus testSemaphoreExportSignalImportWait (Context& context,
811 const SemaphoreTestConfig config)
813 const vk::PlatformInterface& vkp (context.getPlatformInterface());
814 const vk::Unique<vk::VkInstance> instance (createInstance(vkp, config.externalType, 0u, 0u));
815 const vk::InstanceDriver vki (vkp, *instance);
816 const vk::VkPhysicalDevice physicalDevice (vk::chooseDevice(vki, *instance, context.getTestContext().getCommandLine()));
817 const deUint32 queueFamilyIndex (chooseQueueFamilyIndex(vki, physicalDevice, 0u));
818 const vk::VkSemaphoreImportFlags flags = config.permanence == PERMANENCE_TEMPORARY ? vk::VK_SEMAPHORE_IMPORT_TEMPORARY_BIT : (vk::VkSemaphoreImportFlagBits)0u;
820 DE_ASSERT(getHandelTypeTransferences(config.externalType) == TRANSFERENCE_REFERENCE);
821 checkSemaphoreSupport(vki, physicalDevice, config.externalType);
824 const vk::Unique<vk::VkDevice> device (createDevice(context.getUsedApiVersion(), vki, physicalDevice, config.externalType, 0u, 0u, queueFamilyIndex));
825 const vk::DeviceDriver vkd (vki, *device);
826 const vk::VkQueue queue (getQueue(vkd, *device, queueFamilyIndex));
828 const vk::Unique<vk::VkSemaphore> semaphoreA (createExportableSemaphore(vkd, *device, config.externalType));
831 getSemaphoreNative(vkd, *device, *semaphoreA, config.externalType, handle);
833 submitDummySignal(vkd, queue, *semaphoreA);
836 const vk::Unique<vk::VkSemaphore> semaphoreB (createAndImportSemaphore(vkd, *device, config.externalType, handle, flags));
838 submitDummyWait(vkd, queue, *semaphoreB);
839 VK_CHECK(vkd.queueWaitIdle(queue));
843 return tcu::TestStatus::pass("Pass");
847 tcu::TestStatus testSemaphoreExportImportSignalWait (Context& context,
848 const SemaphoreTestConfig config)
850 const vk::PlatformInterface& vkp (context.getPlatformInterface());
851 const vk::Unique<vk::VkInstance> instance (createInstance(vkp, config.externalType, 0u, 0u));
852 const vk::InstanceDriver vki (vkp, *instance);
853 const vk::VkPhysicalDevice physicalDevice (vk::chooseDevice(vki, *instance, context.getTestContext().getCommandLine()));
854 const deUint32 queueFamilyIndex (chooseQueueFamilyIndex(vki, physicalDevice, 0u));
856 DE_ASSERT(getHandelTypeTransferences(config.externalType) == TRANSFERENCE_REFERENCE);
857 checkSemaphoreSupport(vki, physicalDevice, config.externalType);
860 const vk::VkSemaphoreImportFlags flags = config.permanence == PERMANENCE_TEMPORARY ? vk::VK_SEMAPHORE_IMPORT_TEMPORARY_BIT : (vk::VkSemaphoreImportFlagBits)0u;
861 const vk::Unique<vk::VkDevice> device (createDevice(context.getUsedApiVersion(), vki, physicalDevice, config.externalType, 0u, 0u, queueFamilyIndex));
862 const vk::DeviceDriver vkd (vki, *device);
863 const vk::VkQueue queue (getQueue(vkd, *device, queueFamilyIndex));
865 const vk::Unique<vk::VkSemaphore> semaphoreA (createExportableSemaphore(vkd, *device, config.externalType));
868 getSemaphoreNative(vkd, *device, *semaphoreA, config.externalType, handle);
870 const vk::Unique<vk::VkSemaphore> semaphoreB (createAndImportSemaphore(vkd, *device, config.externalType, handle, flags));
872 submitDummySignal(vkd, queue, *semaphoreA);
873 submitDummyWait(vkd, queue, *semaphoreB);
875 VK_CHECK(vkd.queueWaitIdle(queue));
877 return tcu::TestStatus::pass("Pass");
881 tcu::TestStatus testSemaphoreSignalImport (Context& context,
882 const SemaphoreTestConfig config)
884 const Transference transference (getHandelTypeTransferences(config.externalType));
885 const vk::PlatformInterface& vkp (context.getPlatformInterface());
886 const vk::Unique<vk::VkInstance> instance (createInstance(vkp, config.externalType, 0u, 0u));
887 const vk::InstanceDriver vki (vkp, *instance);
888 const vk::VkPhysicalDevice physicalDevice (vk::chooseDevice(vki, *instance, context.getTestContext().getCommandLine()));
889 const deUint32 queueFamilyIndex (chooseQueueFamilyIndex(vki, physicalDevice, 0u));
891 checkSemaphoreSupport(vki, physicalDevice, config.externalType);
894 const vk::VkSemaphoreImportFlags flags = config.permanence == PERMANENCE_TEMPORARY ? vk::VK_SEMAPHORE_IMPORT_TEMPORARY_BIT : (vk::VkSemaphoreImportFlagBits)0u;
895 const vk::Unique<vk::VkDevice> device (createDevice(context.getUsedApiVersion(), vki, physicalDevice, config.externalType, 0u, 0u, queueFamilyIndex));
896 const vk::DeviceDriver vkd (vki, *device);
897 const vk::VkQueue queue (getQueue(vkd, *device, queueFamilyIndex));
899 const vk::Unique<vk::VkSemaphore> semaphoreA (createExportableSemaphore(vkd, *device, config.externalType));
900 const vk::Unique<vk::VkSemaphore> semaphoreB (createSemaphore(vkd, *device));
903 submitDummySignal(vkd, queue, *semaphoreB);
904 VK_CHECK(vkd.queueWaitIdle(queue));
906 if (transference == TRANSFERENCE_COPY)
907 submitDummySignal(vkd, queue, *semaphoreA);
909 getSemaphoreNative(vkd, *device, *semaphoreA, config.externalType, handle);
911 importSemaphore(vkd, *device, *semaphoreB, config.externalType, handle, flags);
913 if (transference == TRANSFERENCE_COPY)
914 submitDummyWait(vkd, queue, *semaphoreB);
915 else if (transference == TRANSFERENCE_REFERENCE)
917 submitDummySignal(vkd, queue, *semaphoreA);
918 submitDummyWait(vkd, queue, *semaphoreB);
921 DE_FATAL("Unknown transference.");
923 VK_CHECK(vkd.queueWaitIdle(queue));
925 return tcu::TestStatus::pass("Pass");
929 tcu::TestStatus testSemaphoreSignalWaitImport (Context& context,
930 const SemaphoreTestConfig config)
932 const Transference transference (getHandelTypeTransferences(config.externalType));
933 const vk::PlatformInterface& vkp (context.getPlatformInterface());
934 const vk::Unique<vk::VkInstance> instance (createInstance(vkp, config.externalType, 0u, 0u));
935 const vk::InstanceDriver vki (vkp, *instance);
936 const vk::VkPhysicalDevice physicalDevice (vk::chooseDevice(vki, *instance, context.getTestContext().getCommandLine()));
937 const deUint32 queueFamilyIndex (chooseQueueFamilyIndex(vki, physicalDevice, 0u));
939 checkSemaphoreSupport(vki, physicalDevice, config.externalType);
942 const vk::VkSemaphoreImportFlags flags = config.permanence == PERMANENCE_TEMPORARY ? vk::VK_SEMAPHORE_IMPORT_TEMPORARY_BIT : (vk::VkSemaphoreImportFlagBits)0u;
943 const vk::Unique<vk::VkDevice> device (createDevice(context.getUsedApiVersion(), vki, physicalDevice, config.externalType, 0u, 0u, queueFamilyIndex));
944 const vk::DeviceDriver vkd (vki, *device);
945 const vk::VkQueue queue (getQueue(vkd, *device, queueFamilyIndex));
947 const vk::Unique<vk::VkSemaphore> semaphoreA (createExportableSemaphore(vkd, *device, config.externalType));
948 const vk::Unique<vk::VkSemaphore> semaphoreB (createSemaphore(vkd, *device));
951 if (transference == TRANSFERENCE_COPY)
952 submitDummySignal(vkd, queue, *semaphoreA);
954 getSemaphoreNative(vkd, *device, *semaphoreA, config.externalType, handle);
956 submitDummySignal(vkd, queue, *semaphoreB);
957 submitDummyWait(vkd, queue, *semaphoreB);
959 VK_CHECK(vkd.queueWaitIdle(queue));
961 importSemaphore(vkd, *device, *semaphoreB, config.externalType, handle, flags);
963 if (transference == TRANSFERENCE_COPY)
964 submitDummyWait(vkd, queue, *semaphoreB);
965 else if (transference == TRANSFERENCE_REFERENCE)
967 submitDummySignal(vkd, queue, *semaphoreA);
968 submitDummyWait(vkd, queue, *semaphoreB);
971 DE_FATAL("Unknown transference.");
973 VK_CHECK(vkd.queueWaitIdle(queue));
975 return tcu::TestStatus::pass("Pass");
979 tcu::TestStatus testSemaphoreMultipleExports (Context& context,
980 const SemaphoreTestConfig config)
982 const size_t exportCount = 4 * 1024;
983 const Transference transference (getHandelTypeTransferences(config.externalType));
984 const vk::PlatformInterface& vkp (context.getPlatformInterface());
985 const vk::Unique<vk::VkInstance> instance (createInstance(vkp, config.externalType, 0u, 0u));
986 const vk::InstanceDriver vki (vkp, *instance);
987 const vk::VkPhysicalDevice physicalDevice (vk::chooseDevice(vki, *instance, context.getTestContext().getCommandLine()));
988 const deUint32 queueFamilyIndex (chooseQueueFamilyIndex(vki, physicalDevice, 0u));
990 checkSemaphoreSupport(vki, physicalDevice, config.externalType);
993 const vk::Unique<vk::VkDevice> device (createDevice(context.getUsedApiVersion(), vki, physicalDevice, config.externalType, 0u, 0u, queueFamilyIndex));
994 const vk::DeviceDriver vkd (vki, *device);
995 const vk::VkQueue queue (getQueue(vkd, *device, queueFamilyIndex));
996 const vk::Unique<vk::VkSemaphore> semaphore (createExportableSemaphore(vkd, *device, config.externalType));
998 for (size_t exportNdx = 0; exportNdx < exportCount; exportNdx++)
1000 NativeHandle handle;
1002 if (transference == TRANSFERENCE_COPY)
1003 submitDummySignal(vkd, queue, *semaphore);
1005 getSemaphoreNative(vkd, *device, *semaphore, config.externalType, handle);
1008 submitDummySignal(vkd, queue, *semaphore);
1009 submitDummyWait(vkd, queue, *semaphore);
1011 VK_CHECK(vkd.queueWaitIdle(queue));
1014 return tcu::TestStatus::pass("Pass");
1017 tcu::TestStatus testSemaphoreMultipleImports (Context& context,
1018 const SemaphoreTestConfig config)
1020 const size_t importCount = 4 * 1024;
1021 const Transference transference (getHandelTypeTransferences(config.externalType));
1022 const vk::PlatformInterface& vkp (context.getPlatformInterface());
1023 const vk::Unique<vk::VkInstance> instance (createInstance(vkp, config.externalType, 0u, 0u));
1024 const vk::InstanceDriver vki (vkp, *instance);
1025 const vk::VkPhysicalDevice physicalDevice (vk::chooseDevice(vki, *instance, context.getTestContext().getCommandLine()));
1026 const deUint32 queueFamilyIndex (chooseQueueFamilyIndex(vki, physicalDevice, 0u));
1028 checkSemaphoreSupport(vki, physicalDevice, config.externalType);
1031 const vk::VkSemaphoreImportFlags flags = config.permanence == PERMANENCE_TEMPORARY ? vk::VK_SEMAPHORE_IMPORT_TEMPORARY_BIT : (vk::VkSemaphoreImportFlagBits)0u;
1032 const vk::Unique<vk::VkDevice> device (createDevice(context.getUsedApiVersion(), vki, physicalDevice, config.externalType, 0u, 0u, queueFamilyIndex));
1033 const vk::DeviceDriver vkd (vki, *device);
1034 const vk::VkQueue queue (getQueue(vkd, *device, queueFamilyIndex));
1035 const vk::Unique<vk::VkSemaphore> semaphoreA (createExportableSemaphore(vkd, *device, config.externalType));
1036 NativeHandle handleA;
1038 if (transference == TRANSFERENCE_COPY)
1039 submitDummySignal(vkd, queue, *semaphoreA);
1041 getSemaphoreNative(vkd, *device, *semaphoreA, config.externalType, handleA);
1043 for (size_t importNdx = 0; importNdx < importCount; importNdx++)
1045 NativeHandle handleB (handleA);
1046 const vk::Unique<vk::VkSemaphore> semaphoreB (createAndImportSemaphore(vkd, *device, config.externalType, handleB, flags));
1049 if (transference == TRANSFERENCE_COPY)
1051 importSemaphore(vkd, *device, *semaphoreA, config.externalType, handleA, flags);
1052 submitDummyWait(vkd, queue, *semaphoreA);
1054 else if (transference == TRANSFERENCE_REFERENCE)
1056 submitDummySignal(vkd, queue, *semaphoreA);
1057 submitDummyWait(vkd, queue, *semaphoreA);
1060 DE_FATAL("Unknown transference.");
1062 VK_CHECK(vkd.queueWaitIdle(queue));
1065 return tcu::TestStatus::pass("Pass");
1068 tcu::TestStatus testSemaphoreTransference (Context& context,
1069 const SemaphoreTestConfig config)
1071 const Transference transference (getHandelTypeTransferences(config.externalType));
1072 const vk::PlatformInterface& vkp (context.getPlatformInterface());
1073 const vk::Unique<vk::VkInstance> instance (createInstance(vkp, config.externalType, 0u, 0u));
1074 const vk::InstanceDriver vki (vkp, *instance);
1075 const vk::VkPhysicalDevice physicalDevice (vk::chooseDevice(vki, *instance, context.getTestContext().getCommandLine()));
1076 const deUint32 queueFamilyIndex (chooseQueueFamilyIndex(vki, physicalDevice, 0u));
1078 checkSemaphoreSupport(vki, physicalDevice, config.externalType);
1081 const vk::VkSemaphoreImportFlags flags = config.permanence == PERMANENCE_TEMPORARY ? vk::VK_SEMAPHORE_IMPORT_TEMPORARY_BIT : (vk::VkSemaphoreImportFlagBits)0u;
1082 const vk::Unique<vk::VkDevice> device (createDevice(context.getUsedApiVersion(), vki, physicalDevice, config.externalType, 0u, 0u, queueFamilyIndex));
1083 const vk::DeviceDriver vkd (vki, *device);
1084 const vk::VkQueue queue (getQueue(vkd, *device, queueFamilyIndex));
1086 const vk::Unique<vk::VkSemaphore> semaphoreA (createExportableSemaphore(vkd, *device, config.externalType));
1087 NativeHandle handle;
1089 submitDummySignal(vkd, queue, *semaphoreA);
1091 getSemaphoreNative(vkd, *device, *semaphoreA, config.externalType, handle);
1094 const vk::Unique<vk::VkSemaphore> semaphoreB (createAndImportSemaphore(vkd, *device, config.externalType, handle, flags));
1096 if (config.permanence == PERMANENCE_PERMANENT)
1098 if (transference == TRANSFERENCE_COPY)
1100 submitDummySignal(vkd, queue, *semaphoreA);
1101 submitDummyWait(vkd, queue, *semaphoreB);
1102 VK_CHECK(vkd.queueWaitIdle(queue));
1104 submitDummySignal(vkd, queue, *semaphoreB);
1106 submitDummyWait(vkd, queue, *semaphoreA);
1107 submitDummyWait(vkd, queue, *semaphoreB);
1108 VK_CHECK(vkd.queueWaitIdle(queue));
1110 else if (transference== TRANSFERENCE_REFERENCE)
1112 submitDummyWait(vkd, queue, *semaphoreB);
1113 VK_CHECK(vkd.queueWaitIdle(queue));
1115 submitDummySignal(vkd, queue, *semaphoreA);
1116 submitDummyWait(vkd, queue, *semaphoreB);
1118 submitDummySignal(vkd, queue, *semaphoreB);
1119 submitDummyWait(vkd, queue, *semaphoreA);
1120 VK_CHECK(vkd.queueWaitIdle(queue));
1123 DE_FATAL("Unknown transference.");
1125 else if (config.permanence == PERMANENCE_TEMPORARY)
1127 if (transference == TRANSFERENCE_COPY)
1129 submitDummySignal(vkd, queue, *semaphoreA);
1130 submitDummyWait(vkd, queue, *semaphoreB);
1131 VK_CHECK(vkd.queueWaitIdle(queue));
1133 submitDummySignal(vkd, queue, *semaphoreB);
1135 submitDummyWait(vkd, queue, *semaphoreA);
1136 submitDummyWait(vkd, queue, *semaphoreB);
1137 VK_CHECK(vkd.queueWaitIdle(queue));
1139 else if (transference== TRANSFERENCE_REFERENCE)
1141 submitDummyWait(vkd, queue, *semaphoreB);
1142 VK_CHECK(vkd.queueWaitIdle(queue));
1144 submitDummySignal(vkd, queue, *semaphoreA);
1145 submitDummySignal(vkd, queue, *semaphoreB);
1147 submitDummyWait(vkd, queue, *semaphoreB);
1148 submitDummyWait(vkd, queue, *semaphoreA);
1149 VK_CHECK(vkd.queueWaitIdle(queue));
1152 DE_FATAL("Unknown transference.");
1155 DE_FATAL("Unknown permanence.");
1158 return tcu::TestStatus::pass("Pass");
1162 tcu::TestStatus testSemaphoreFdDup (Context& context,
1163 const SemaphoreTestConfig config)
1165 #if (DE_OS == DE_OS_ANDROID) || (DE_OS == DE_OS_UNIX)
1166 const Transference transference (getHandelTypeTransferences(config.externalType));
1167 const vk::PlatformInterface& vkp (context.getPlatformInterface());
1168 const vk::Unique<vk::VkInstance> instance (createInstance(vkp, config.externalType, 0u, 0u));
1169 const vk::InstanceDriver vki (vkp, *instance);
1170 const vk::VkPhysicalDevice physicalDevice (vk::chooseDevice(vki, *instance, context.getTestContext().getCommandLine()));
1171 const deUint32 queueFamilyIndex (chooseQueueFamilyIndex(vki, physicalDevice, 0u));
1173 checkSemaphoreSupport(vki, physicalDevice, config.externalType);
1176 const vk::VkSemaphoreImportFlags flags = config.permanence == PERMANENCE_TEMPORARY ? vk::VK_SEMAPHORE_IMPORT_TEMPORARY_BIT : (vk::VkSemaphoreImportFlagBits)0u;
1177 const vk::Unique<vk::VkDevice> device (createDevice(context.getUsedApiVersion(), vki, physicalDevice, config.externalType, 0u, 0u, queueFamilyIndex));
1178 const vk::DeviceDriver vkd (vki, *device);
1179 const vk::VkQueue queue (getQueue(vkd, *device, queueFamilyIndex));
1181 TestLog& log = context.getTestContext().getLog();
1182 const vk::Unique<vk::VkSemaphore> semaphoreA (createExportableSemaphore(vkd, *device, config.externalType));
1184 if (transference == TRANSFERENCE_COPY)
1185 submitDummySignal(vkd, queue, *semaphoreA);
1188 const NativeHandle fd (getSemaphoreFd(vkd, *device, *semaphoreA, config.externalType));
1189 NativeHandle newFd (dup(fd.getFd()));
1191 if (newFd.getFd() < 0)
1192 log << TestLog::Message << "dup() failed: '" << strerror(errno) << "'" << TestLog::EndMessage;
1194 TCU_CHECK_MSG(newFd.getFd() >= 0, "Failed to call dup() for semaphores fd");
1197 const vk::Unique<vk::VkSemaphore> semaphoreB (createAndImportSemaphore(vkd, *device, config.externalType, newFd, flags));
1199 if (transference == TRANSFERENCE_COPY)
1200 submitDummyWait(vkd, queue, *semaphoreB);
1201 else if (transference == TRANSFERENCE_REFERENCE)
1203 submitDummySignal(vkd, queue, *semaphoreA);
1204 submitDummyWait(vkd, queue, *semaphoreB);
1207 DE_FATAL("Unknown permanence.");
1211 VK_CHECK(vkd.queueWaitIdle(queue));
1213 return tcu::TestStatus::pass("Pass");
1218 TCU_THROW(NotSupportedError, "Platform doesn't support dup()");
1222 tcu::TestStatus testSemaphoreFdDup2 (Context& context,
1223 const SemaphoreTestConfig config)
1225 #if (DE_OS == DE_OS_ANDROID) || (DE_OS == DE_OS_UNIX)
1226 const Transference transference (getHandelTypeTransferences(config.externalType));
1227 const vk::PlatformInterface& vkp (context.getPlatformInterface());
1228 const vk::Unique<vk::VkInstance> instance (createInstance(vkp, config.externalType, 0u, 0u));
1229 const vk::InstanceDriver vki (vkp, *instance);
1230 const vk::VkPhysicalDevice physicalDevice (vk::chooseDevice(vki, *instance, context.getTestContext().getCommandLine()));
1231 const deUint32 queueFamilyIndex (chooseQueueFamilyIndex(vki, physicalDevice, 0u));
1233 checkSemaphoreSupport(vki, physicalDevice, config.externalType);
1236 const vk::VkSemaphoreImportFlags flags = config.permanence == PERMANENCE_TEMPORARY ? vk::VK_SEMAPHORE_IMPORT_TEMPORARY_BIT : (vk::VkSemaphoreImportFlagBits)0u;
1237 const vk::Unique<vk::VkDevice> device (createDevice(context.getUsedApiVersion(), vki, physicalDevice, config.externalType, 0u, 0u, queueFamilyIndex));
1238 const vk::DeviceDriver vkd (vki, *device);
1239 const vk::VkQueue queue (getQueue(vkd, *device, queueFamilyIndex));
1241 TestLog& log = context.getTestContext().getLog();
1242 const vk::Unique<vk::VkSemaphore> semaphoreA (createExportableSemaphore(vkd, *device, config.externalType));
1243 const vk::Unique<vk::VkSemaphore> semaphoreB (createExportableSemaphore(vkd, *device, config.externalType));
1245 if (transference == TRANSFERENCE_COPY)
1247 submitDummySignal(vkd, queue, *semaphoreA);
1248 submitDummySignal(vkd, queue, *semaphoreB);
1252 const NativeHandle fd (getSemaphoreFd(vkd, *device, *semaphoreA, config.externalType));
1253 NativeHandle secondFd (getSemaphoreFd(vkd, *device, *semaphoreB, config.externalType));
1254 int newFd (dup2(fd.getFd(), secondFd.getFd()));
1257 log << TestLog::Message << "dup2() failed: '" << strerror(errno) << "'" << TestLog::EndMessage;
1259 TCU_CHECK_MSG(newFd >= 0, "Failed to call dup2() for fences fd");
1262 const vk::Unique<vk::VkSemaphore> semaphoreC (createAndImportSemaphore(vkd, *device, config.externalType, secondFd, flags));
1264 if (transference == TRANSFERENCE_COPY)
1265 submitDummyWait(vkd, queue, *semaphoreC);
1266 else if (transference == TRANSFERENCE_REFERENCE)
1268 submitDummySignal(vkd, queue, *semaphoreA);
1269 submitDummyWait(vkd, queue, *semaphoreC);
1272 DE_FATAL("Unknown permanence.");
1276 VK_CHECK(vkd.queueWaitIdle(queue));
1278 return tcu::TestStatus::pass("Pass");
1283 TCU_THROW(NotSupportedError, "Platform doesn't support dup2()");
1287 tcu::TestStatus testSemaphoreFdDup3 (Context& context,
1288 const SemaphoreTestConfig config)
1290 #if (DE_OS == DE_OS_UNIX) && defined(_GNU_SOURCE)
1291 const Transference transference (getHandelTypeTransferences(config.externalType));
1292 const vk::PlatformInterface& vkp (context.getPlatformInterface());
1293 const vk::Unique<vk::VkInstance> instance (createInstance(vkp, config.externalType, 0u, 0u));
1294 const vk::InstanceDriver vki (vkp, *instance);
1295 const vk::VkPhysicalDevice physicalDevice (vk::chooseDevice(vki, *instance, context.getTestContext().getCommandLine()));
1296 const deUint32 queueFamilyIndex (chooseQueueFamilyIndex(vki, physicalDevice, 0u));
1298 checkSemaphoreSupport(vki, physicalDevice, config.externalType);
1301 const vk::Unique<vk::VkDevice> device (createDevice(context.getUsedApiVersion(), vki, physicalDevice, config.externalType, 0u, 0u, queueFamilyIndex));
1302 const vk::DeviceDriver vkd (vki, *device);
1303 const vk::VkQueue queue (getQueue(vkd, *device, queueFamilyIndex));
1305 TestLog& log = context.getTestContext().getLog();
1306 const vk::Unique<vk::VkSemaphore> semaphoreA (createExportableSemaphore(vkd, *device, config.externalType));
1307 const vk::Unique<vk::VkSemaphore> semaphoreB (createExportableSemaphore(vkd, *device, config.externalType));
1309 if (transference == TRANSFERENCE_COPY)
1311 submitDummySignal(vkd, queue, *semaphoreA);
1312 submitDummySignal(vkd, queue, *semaphoreB);
1316 const vk::VkSemaphoreImportFlags flags = config.permanence == PERMANENCE_TEMPORARY ? vk::VK_SEMAPHORE_IMPORT_TEMPORARY_BIT : (vk::VkSemaphoreImportFlagBits)0u;
1317 const NativeHandle fd (getSemaphoreFd(vkd, *device, *semaphoreA, config.externalType));
1318 NativeHandle secondFd (getSemaphoreFd(vkd, *device, *semaphoreB, config.externalType));
1319 const int newFd (dup3(fd.getFd(), secondFd.getFd(), 0));
1322 log << TestLog::Message << "dup3() failed: '" << strerror(errno) << "'" << TestLog::EndMessage;
1324 TCU_CHECK_MSG(newFd >= 0, "Failed to call dup3() for fences fd");
1327 const vk::Unique<vk::VkSemaphore> semaphoreC (createAndImportSemaphore(vkd, *device, config.externalType, secondFd, flags));
1329 if (transference == TRANSFERENCE_COPY)
1330 submitDummyWait(vkd, queue, *semaphoreC);
1331 else if (transference == TRANSFERENCE_REFERENCE)
1333 submitDummySignal(vkd, queue, *semaphoreA);
1334 submitDummyWait(vkd, queue, *semaphoreC);
1337 DE_FATAL("Unknown permanence.");
1341 VK_CHECK(vkd.queueWaitIdle(queue));
1343 return tcu::TestStatus::pass("Pass");
1348 TCU_THROW(NotSupportedError, "Platform doesn't support dup3()");
1352 tcu::TestStatus testSemaphoreFdSendOverSocket (Context& context,
1353 const SemaphoreTestConfig config)
1355 #if (DE_OS == DE_OS_ANDROID) || (DE_OS == DE_OS_UNIX)
1356 const Transference transference (getHandelTypeTransferences(config.externalType));
1357 const vk::PlatformInterface& vkp (context.getPlatformInterface());
1358 const vk::Unique<vk::VkInstance> instance (createInstance(vkp, config.externalType, 0u, 0u));
1359 const vk::InstanceDriver vki (vkp, *instance);
1360 const vk::VkPhysicalDevice physicalDevice (vk::chooseDevice(vki, *instance, context.getTestContext().getCommandLine()));
1361 const deUint32 queueFamilyIndex (chooseQueueFamilyIndex(vki, physicalDevice, 0u));
1363 checkSemaphoreSupport(vki, physicalDevice, config.externalType);
1366 const vk::Unique<vk::VkDevice> device (createDevice(context.getUsedApiVersion(), vki, physicalDevice, config.externalType, 0u, 0u, queueFamilyIndex));
1367 const vk::DeviceDriver vkd (vki, *device);
1368 const vk::VkQueue queue (getQueue(vkd, *device, queueFamilyIndex));
1370 TestLog& log = context.getTestContext().getLog();
1371 const vk::Unique<vk::VkSemaphore> semaphore (createExportableSemaphore(vkd, *device, config.externalType));
1373 if (transference == TRANSFERENCE_COPY)
1374 submitDummySignal(vkd, queue, *semaphore);
1376 const NativeHandle fd (getSemaphoreFd(vkd, *device, *semaphore, config.externalType));
1381 if (socketpair(AF_UNIX, SOCK_STREAM, 0, sv) != 0)
1383 log << TestLog::Message << "Failed to create socket pair: '" << strerror(errno) << "'" << TestLog::EndMessage;
1384 TCU_FAIL("Failed to create socket pair");
1388 const NativeHandle srcSocket (sv[0]);
1389 const NativeHandle dstSocket (sv[1]);
1390 std::string sendData ("deqp");
1394 const int fdRaw (fd.getFd());
1397 char buffer[CMSG_SPACE(sizeof(int))];
1398 iovec iov = { &sendData[0], sendData.length()};
1400 deMemset(&msg, 0, sizeof(msg));
1402 msg.msg_control = buffer;
1403 msg.msg_controllen = sizeof(buffer);
1407 cmsg = CMSG_FIRSTHDR(&msg);
1408 cmsg->cmsg_level = SOL_SOCKET;
1409 cmsg->cmsg_type = SCM_RIGHTS;
1410 cmsg->cmsg_len = CMSG_LEN(sizeof(int));
1412 deMemcpy(CMSG_DATA(cmsg), &fdRaw, sizeof(int));
1413 msg.msg_controllen = cmsg->cmsg_len;
1415 if (sendmsg(srcSocket.getFd(), &msg, 0) < 0)
1417 log << TestLog::Message << "Failed to send fd over socket: '" << strerror(errno) << "'" << TestLog::EndMessage;
1418 TCU_FAIL("Failed to send fd over socket");
1425 char buffer[CMSG_SPACE(sizeof(int))];
1426 std::string recvData (4, '\0');
1427 iovec iov = { &recvData[0], recvData.length() };
1429 deMemset(&msg, 0, sizeof(msg));
1431 msg.msg_control = buffer;
1432 msg.msg_controllen = sizeof(buffer);
1436 const ssize_t bytes = recvmsg(dstSocket.getFd(), &msg, 0);
1440 log << TestLog::Message << "Failed to recv fd over socket: '" << strerror(errno) << "'" << TestLog::EndMessage;
1441 TCU_FAIL("Failed to recv fd over socket");
1444 else if (bytes != (ssize_t)sendData.length())
1446 TCU_FAIL("recvmsg() returned unpexpected number of bytes");
1450 const vk::VkSemaphoreImportFlags flags = config.permanence == PERMANENCE_TEMPORARY ? vk::VK_SEMAPHORE_IMPORT_TEMPORARY_BIT : (vk::VkSemaphoreImportFlagBits)0u;
1451 const cmsghdr* const cmsg = CMSG_FIRSTHDR(&msg);
1453 deMemcpy(&newFd_, CMSG_DATA(cmsg), sizeof(int));
1454 NativeHandle newFd (newFd_);
1456 TCU_CHECK(cmsg->cmsg_level == SOL_SOCKET);
1457 TCU_CHECK(cmsg->cmsg_type == SCM_RIGHTS);
1458 TCU_CHECK(cmsg->cmsg_len == CMSG_LEN(sizeof(int)));
1459 TCU_CHECK(recvData == sendData);
1460 TCU_CHECK_MSG(newFd.getFd() >= 0, "Didn't receive valid fd from socket");
1463 const vk::Unique<vk::VkSemaphore> newSemaphore (createAndImportSemaphore(vkd, *device, config.externalType, newFd, flags));
1465 if (transference == TRANSFERENCE_COPY)
1466 submitDummyWait(vkd, queue, *newSemaphore);
1467 else if (transference == TRANSFERENCE_REFERENCE)
1469 submitDummySignal(vkd, queue, *newSemaphore);
1470 submitDummyWait(vkd, queue, *newSemaphore);
1473 DE_FATAL("Unknown permanence.");
1475 VK_CHECK(vkd.queueWaitIdle(queue));
1483 return tcu::TestStatus::pass("Pass");
1487 TCU_THROW(NotSupportedError, "Platform doesn't support sending file descriptors over socket");
1491 tcu::TestStatus testFenceQueries (Context& context, vk::VkExternalFenceHandleTypeFlagBits externalType)
1493 const vk::PlatformInterface& vkp (context.getPlatformInterface());
1494 const vk::Unique<vk::VkInstance> instance (createInstance(vkp, 0u, 0u, externalType));
1495 const vk::InstanceDriver vki (vkp, *instance);
1496 const vk::VkPhysicalDevice device (vk::chooseDevice(vki, *instance, context.getTestContext().getCommandLine()));
1498 TestLog& log = context.getTestContext().getLog();
1500 const vk::VkPhysicalDeviceExternalFenceInfo info =
1502 vk::VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_FENCE_INFO,
1506 vk::VkExternalFenceProperties properties =
1508 vk::VK_STRUCTURE_TYPE_EXTERNAL_FENCE_PROPERTIES,
1515 vki.getPhysicalDeviceExternalFenceProperties(device, &info, &properties);
1516 log << TestLog::Message << properties << TestLog::EndMessage;
1518 TCU_CHECK(properties.pNext == DE_NULL);
1519 TCU_CHECK(properties.sType == vk::VK_STRUCTURE_TYPE_EXTERNAL_FENCE_PROPERTIES);
1521 return tcu::TestStatus::pass("Pass");
1524 struct FenceTestConfig
1526 FenceTestConfig (vk::VkExternalFenceHandleTypeFlagBits externalType_,
1527 Permanence permanence_)
1528 : externalType (externalType_)
1529 , permanence (permanence_)
1533 vk::VkExternalFenceHandleTypeFlagBits externalType;
1534 Permanence permanence;
1538 tcu::TestStatus testFenceWin32Create (Context& context,
1539 const FenceTestConfig config)
1541 #if (DE_OS == DE_OS_WIN32)
1542 const Transference transference (getHandelTypeTransferences(config.externalType));
1543 const vk::PlatformInterface& vkp (context.getPlatformInterface());
1544 const vk::Unique<vk::VkInstance> instance (createInstance(vkp, 0u, 0u, config.externalType));
1545 const vk::InstanceDriver vki (vkp, *instance);
1546 const vk::VkPhysicalDevice physicalDevice (vk::chooseDevice(vki, *instance, context.getTestContext().getCommandLine()));
1547 const deUint32 queueFamilyIndex (chooseQueueFamilyIndex(vki, physicalDevice, 0u));
1549 checkFenceSupport(vki, physicalDevice, config.externalType);
1552 const vk::Unique<vk::VkDevice> device (createDevice(context.getUsedApiVersion(), vki, physicalDevice, 0u, 0u, config.externalType, queueFamilyIndex));
1553 const vk::DeviceDriver vkd (vki, *device);
1554 const vk::VkQueue queue (getQueue(vkd, *device, queueFamilyIndex));
1555 const vk::VkExportFenceWin32HandleInfoKHR win32ExportInfo =
1557 vk::VK_STRUCTURE_TYPE_EXPORT_FENCE_WIN32_HANDLE_INFO_KHR,
1560 (vk::pt::Win32SecurityAttributesPtr)DE_NULL,
1561 DXGI_SHARED_RESOURCE_READ | DXGI_SHARED_RESOURCE_WRITE,
1564 const vk::VkExportFenceCreateInfo exportCreateInfo=
1566 vk::VK_STRUCTURE_TYPE_EXPORT_FENCE_CREATE_INFO,
1568 (vk::VkExternalFenceHandleTypeFlags)config.externalType
1570 const vk::VkFenceCreateInfo createInfo =
1572 vk::VK_STRUCTURE_TYPE_FENCE_CREATE_INFO,
1576 const vk::Unique<vk::VkFence> fence (vk::createFence(vkd, *device, &createInfo));
1578 if (transference == TRANSFERENCE_COPY)
1579 submitDummySignal(vkd, queue, *fence);
1581 NativeHandle handleA;
1582 getFenceNative(vkd, *device, *fence, config.externalType, handleA);
1585 const vk::VkFenceImportFlags flags = config.permanence == PERMANENCE_TEMPORARY ? vk::VK_FENCE_IMPORT_TEMPORARY_BIT : (vk::VkFenceImportFlagBits)0u;
1586 const vk::Unique<vk::VkFence> fenceA (createAndImportFence(vkd, *device, config.externalType, handleA, flags));
1588 if (transference == TRANSFERENCE_COPY)
1589 VK_CHECK(vkd.waitForFences(*device, 1u, &*fenceA, VK_TRUE, ~0ull));
1590 else if (transference == TRANSFERENCE_REFERENCE)
1592 submitDummySignal(vkd, queue, *fence);
1593 VK_CHECK(vkd.waitForFences(*device, 1u, &*fenceA, VK_TRUE, ~0ull));
1596 DE_FATAL("Unknown transference.");
1598 VK_CHECK(vkd.queueWaitIdle(queue));
1601 return tcu::TestStatus::pass("Pass");
1606 TCU_THROW(NotSupportedError, "Platform doesn't support win32 handles");
1610 tcu::TestStatus testFenceImportTwice (Context& context,
1611 const FenceTestConfig config)
1613 const Transference transference (getHandelTypeTransferences(config.externalType));
1614 const vk::PlatformInterface& vkp (context.getPlatformInterface());
1615 const vk::Unique<vk::VkInstance> instance (createInstance(vkp, 0u, 0u, config.externalType));
1616 const vk::InstanceDriver vki (vkp, *instance);
1617 const vk::VkPhysicalDevice physicalDevice (vk::chooseDevice(vki, *instance, context.getTestContext().getCommandLine()));
1618 const deUint32 queueFamilyIndex (chooseQueueFamilyIndex(vki, physicalDevice, 0u));
1620 checkFenceSupport(vki, physicalDevice, config.externalType);
1623 const vk::Unique<vk::VkDevice> device (createDevice(context.getUsedApiVersion(), vki, physicalDevice, 0u, 0u, config.externalType, queueFamilyIndex));
1624 const vk::DeviceDriver vkd (vki, *device);
1625 const vk::VkQueue queue (getQueue(vkd, *device, queueFamilyIndex));
1626 const vk::Unique<vk::VkFence> fence (createExportableFence(vkd, *device, config.externalType));
1628 if (transference == TRANSFERENCE_COPY)
1629 submitDummySignal(vkd, queue, *fence);
1631 NativeHandle handleA;
1632 getFenceNative(vkd, *device, *fence, config.externalType, handleA);
1635 NativeHandle handleB (handleA);
1636 const vk::VkFenceImportFlags flags = config.permanence == PERMANENCE_TEMPORARY ? vk::VK_FENCE_IMPORT_TEMPORARY_BIT : (vk::VkFenceImportFlagBits)0u;
1637 const vk::Unique<vk::VkFence> fenceA (createAndImportFence(vkd, *device, config.externalType, handleA, flags));
1638 const vk::Unique<vk::VkFence> fenceB (createAndImportFence(vkd, *device, config.externalType, handleB, flags));
1640 if (transference == TRANSFERENCE_COPY)
1641 VK_CHECK(vkd.waitForFences(*device, 1u, &*fenceA, VK_TRUE, ~0ull));
1642 else if (transference == TRANSFERENCE_REFERENCE)
1644 submitDummySignal(vkd, queue, *fenceA);
1645 VK_CHECK(vkd.waitForFences(*device, 1u, &*fenceB, VK_TRUE, ~0ull));
1648 DE_FATAL("Unknown transference.");
1650 VK_CHECK(vkd.queueWaitIdle(queue));
1653 return tcu::TestStatus::pass("Pass");
1657 tcu::TestStatus testFenceImportReimport (Context& context,
1658 const FenceTestConfig config)
1660 const Transference transference (getHandelTypeTransferences(config.externalType));
1661 const vk::PlatformInterface& vkp (context.getPlatformInterface());
1662 const vk::Unique<vk::VkInstance> instance (createInstance(vkp, 0u, 0u, config.externalType));
1663 const vk::InstanceDriver vki (vkp, *instance);
1664 const vk::VkPhysicalDevice physicalDevice (vk::chooseDevice(vki, *instance, context.getTestContext().getCommandLine()));
1665 const deUint32 queueFamilyIndex (chooseQueueFamilyIndex(vki, physicalDevice, 0u));
1667 checkFenceSupport(vki, physicalDevice, config.externalType);
1670 const vk::Unique<vk::VkDevice> device (createDevice(context.getUsedApiVersion(), vki, physicalDevice, 0u, 0u, config.externalType, queueFamilyIndex));
1671 const vk::DeviceDriver vkd (vki, *device);
1672 const vk::VkQueue queue (getQueue(vkd, *device, queueFamilyIndex));
1674 const vk::Unique<vk::VkFence> fenceA (createExportableFence(vkd, *device, config.externalType));
1676 if (transference == TRANSFERENCE_COPY)
1677 submitDummySignal(vkd, queue, *fenceA);
1679 NativeHandle handleA;
1680 getFenceNative(vkd, *device, *fenceA, config.externalType, handleA);
1682 NativeHandle handleB (handleA);
1683 const vk::VkFenceImportFlags flags = config.permanence == PERMANENCE_TEMPORARY ? vk::VK_FENCE_IMPORT_TEMPORARY_BIT : (vk::VkFenceImportFlagBits)0u;
1684 const vk::Unique<vk::VkFence> fenceB (createAndImportFence(vkd, *device, config.externalType, handleA, flags));
1686 importFence(vkd, *device, *fenceB, config.externalType, handleB, flags);
1688 if (transference == TRANSFERENCE_COPY)
1689 VK_CHECK(vkd.waitForFences(*device, 1u, &*fenceB, VK_TRUE, ~0ull));
1690 else if (transference == TRANSFERENCE_REFERENCE)
1692 submitDummySignal(vkd, queue, *fenceA);
1693 VK_CHECK(vkd.waitForFences(*device, 1u, &*fenceB, VK_TRUE, ~0ull));
1696 DE_FATAL("Unknown transference.");
1698 VK_CHECK(vkd.queueWaitIdle(queue));
1700 return tcu::TestStatus::pass("Pass");
1704 tcu::TestStatus testFenceSignalExportImportWait (Context& context,
1705 const FenceTestConfig config)
1707 const vk::PlatformInterface& vkp (context.getPlatformInterface());
1708 const vk::Unique<vk::VkInstance> instance (createInstance(vkp, 0u, 0u, config.externalType));
1709 const vk::InstanceDriver vki (vkp, *instance);
1710 const vk::VkPhysicalDevice physicalDevice (vk::chooseDevice(vki, *instance, context.getTestContext().getCommandLine()));
1711 const deUint32 queueFamilyIndex (chooseQueueFamilyIndex(vki, physicalDevice, 0u));
1713 checkFenceSupport(vki, physicalDevice, config.externalType);
1716 const vk::Unique<vk::VkDevice> device (createDevice(context.getUsedApiVersion(), vki, physicalDevice, 0u, 0u, config.externalType, queueFamilyIndex));
1717 const vk::DeviceDriver vkd (vki, *device);
1718 const vk::VkQueue queue (getQueue(vkd, *device, queueFamilyIndex));
1719 const vk::Unique<vk::VkFence> fenceA (createExportableFence(vkd, *device, config.externalType));
1721 submitDummySignal(vkd, queue, *fenceA);
1724 NativeHandle handle;
1726 getFenceNative(vkd, *device, *fenceA, config.externalType, handle);
1729 const vk::VkFenceImportFlags flags = config.permanence == PERMANENCE_TEMPORARY ? vk::VK_FENCE_IMPORT_TEMPORARY_BIT : (vk::VkFenceImportFlagBits)0u;
1730 const vk::Unique<vk::VkFence> fenceB (createAndImportFence(vkd, *device, config.externalType, handle, flags));
1731 VK_CHECK(vkd.waitForFences(*device, 1u, &*fenceB, VK_TRUE, ~0ull));
1733 VK_CHECK(vkd.queueWaitIdle(queue));
1737 return tcu::TestStatus::pass("Pass");
1741 tcu::TestStatus testFenceExportSignalImportWait (Context& context,
1742 const FenceTestConfig config)
1744 const vk::PlatformInterface& vkp (context.getPlatformInterface());
1745 const vk::Unique<vk::VkInstance> instance (createInstance(vkp, 0u, 0u, config.externalType));
1746 const vk::InstanceDriver vki (vkp, *instance);
1747 const vk::VkPhysicalDevice physicalDevice (vk::chooseDevice(vki, *instance, context.getTestContext().getCommandLine()));
1748 const deUint32 queueFamilyIndex (chooseQueueFamilyIndex(vki, physicalDevice, 0u));
1749 const vk::VkFenceImportFlags flags = config.permanence == PERMANENCE_TEMPORARY ? vk::VK_FENCE_IMPORT_TEMPORARY_BIT : (vk::VkFenceImportFlagBits)0u;
1751 DE_ASSERT(getHandelTypeTransferences(config.externalType) == TRANSFERENCE_REFERENCE);
1752 checkFenceSupport(vki, physicalDevice, config.externalType);
1755 const vk::Unique<vk::VkDevice> device (createDevice(context.getUsedApiVersion(), vki, physicalDevice, 0u, 0u, config.externalType, queueFamilyIndex));
1756 const vk::DeviceDriver vkd (vki, *device);
1757 const vk::VkQueue queue (getQueue(vkd, *device, queueFamilyIndex));
1759 const vk::Unique<vk::VkFence> fenceA (createExportableFence(vkd, *device, config.externalType));
1760 NativeHandle handle;
1762 getFenceNative(vkd, *device, *fenceA, config.externalType, handle);
1764 submitDummySignal(vkd, queue, *fenceA);
1767 const vk::Unique<vk::VkFence> fenceB (createAndImportFence(vkd, *device, config.externalType, handle, flags));
1769 VK_CHECK(vkd.waitForFences(*device, 1u, &*fenceB, VK_TRUE, ~0ull));
1770 VK_CHECK(vkd.queueWaitIdle(queue));
1774 return tcu::TestStatus::pass("Pass");
1778 tcu::TestStatus testFenceExportImportSignalWait (Context& context,
1779 const FenceTestConfig config)
1781 const vk::PlatformInterface& vkp (context.getPlatformInterface());
1782 const vk::Unique<vk::VkInstance> instance (createInstance(vkp, 0u, 0u, config.externalType));
1783 const vk::InstanceDriver vki (vkp, *instance);
1784 const vk::VkPhysicalDevice physicalDevice (vk::chooseDevice(vki, *instance, context.getTestContext().getCommandLine()));
1785 const deUint32 queueFamilyIndex (chooseQueueFamilyIndex(vki, physicalDevice, 0u));
1787 DE_ASSERT(getHandelTypeTransferences(config.externalType) == TRANSFERENCE_REFERENCE);
1788 checkFenceSupport(vki, physicalDevice, config.externalType);
1791 const vk::VkFenceImportFlags flags = config.permanence == PERMANENCE_TEMPORARY ? vk::VK_FENCE_IMPORT_TEMPORARY_BIT : (vk::VkFenceImportFlagBits)0u;
1792 const vk::Unique<vk::VkDevice> device (createDevice(context.getUsedApiVersion(), vki, physicalDevice, 0u, 0u, config.externalType, queueFamilyIndex));
1793 const vk::DeviceDriver vkd (vki, *device);
1794 const vk::VkQueue queue (getQueue(vkd, *device, queueFamilyIndex));
1796 const vk::Unique<vk::VkFence> fenceA (createExportableFence(vkd, *device, config.externalType));
1797 NativeHandle handle;
1799 getFenceNative(vkd, *device, *fenceA, config.externalType, handle);
1801 const vk::Unique<vk::VkFence> fenceB (createAndImportFence(vkd, *device, config.externalType, handle, flags));
1803 submitDummySignal(vkd, queue, *fenceA);
1804 VK_CHECK(vkd.waitForFences(*device, 1u, &*fenceB, VK_TRUE, ~0ull));
1806 VK_CHECK(vkd.queueWaitIdle(queue));
1808 return tcu::TestStatus::pass("Pass");
1812 tcu::TestStatus testFenceSignalImport (Context& context,
1813 const FenceTestConfig config)
1815 const Transference transference (getHandelTypeTransferences(config.externalType));
1816 const vk::PlatformInterface& vkp (context.getPlatformInterface());
1817 const vk::Unique<vk::VkInstance> instance (createInstance(vkp, 0u, 0u, config.externalType));
1818 const vk::InstanceDriver vki (vkp, *instance);
1819 const vk::VkPhysicalDevice physicalDevice (vk::chooseDevice(vki, *instance, context.getTestContext().getCommandLine()));
1820 const deUint32 queueFamilyIndex (chooseQueueFamilyIndex(vki, physicalDevice, 0u));
1822 checkFenceSupport(vki, physicalDevice, config.externalType);
1825 const vk::VkFenceImportFlags flags = config.permanence == PERMANENCE_TEMPORARY ? vk::VK_FENCE_IMPORT_TEMPORARY_BIT : (vk::VkFenceImportFlagBits)0u;
1826 const vk::Unique<vk::VkDevice> device (createDevice(context.getUsedApiVersion(), vki, physicalDevice, 0u, 0u, config.externalType, queueFamilyIndex));
1827 const vk::DeviceDriver vkd (vki, *device);
1828 const vk::VkQueue queue (getQueue(vkd, *device, queueFamilyIndex));
1830 const vk::Unique<vk::VkFence> fenceA (createExportableFence(vkd, *device, config.externalType));
1831 const vk::Unique<vk::VkFence> fenceB (createFence(vkd, *device));
1832 NativeHandle handle;
1834 submitDummySignal(vkd, queue, *fenceB);
1835 VK_CHECK(vkd.queueWaitIdle(queue));
1837 if (transference == TRANSFERENCE_COPY)
1838 submitDummySignal(vkd, queue, *fenceA);
1840 getFenceNative(vkd, *device, *fenceA, config.externalType, handle);
1842 importFence(vkd, *device, *fenceB, config.externalType, handle, flags);
1844 if (transference == TRANSFERENCE_COPY)
1845 VK_CHECK(vkd.waitForFences(*device, 1u, &*fenceB, VK_TRUE, ~0ull));
1846 else if (transference == TRANSFERENCE_REFERENCE)
1848 submitDummySignal(vkd, queue, *fenceA);
1849 VK_CHECK(vkd.waitForFences(*device, 1u, &*fenceB, VK_TRUE, ~0ull));
1852 DE_FATAL("Unknown transference.");
1854 VK_CHECK(vkd.queueWaitIdle(queue));
1856 return tcu::TestStatus::pass("Pass");
1860 tcu::TestStatus testFenceReset (Context& context,
1861 const FenceTestConfig config)
1863 const Transference transference (getHandelTypeTransferences(config.externalType));
1864 const vk::PlatformInterface& vkp (context.getPlatformInterface());
1865 const vk::Unique<vk::VkInstance> instance (createInstance(vkp, 0u, 0u, config.externalType));
1866 const vk::InstanceDriver vki (vkp, *instance);
1867 const vk::VkPhysicalDevice physicalDevice (vk::chooseDevice(vki, *instance, context.getTestContext().getCommandLine()));
1868 const deUint32 queueFamilyIndex (chooseQueueFamilyIndex(vki, physicalDevice, 0u));
1870 checkFenceSupport(vki, physicalDevice, config.externalType);
1873 const vk::VkFenceImportFlags flags = config.permanence == PERMANENCE_TEMPORARY ? vk::VK_FENCE_IMPORT_TEMPORARY_BIT : (vk::VkFenceImportFlagBits)0u;
1874 const vk::Unique<vk::VkDevice> device (createDevice(context.getUsedApiVersion(), vki, physicalDevice, 0u, 0u, config.externalType, queueFamilyIndex));
1875 const vk::DeviceDriver vkd (vki, *device);
1876 const vk::VkQueue queue (getQueue(vkd, *device, queueFamilyIndex));
1878 const vk::Unique<vk::VkFence> fenceA (createExportableFence(vkd, *device, config.externalType));
1879 const vk::Unique<vk::VkFence> fenceB (createFence(vkd, *device));
1880 const vk::Unique<vk::VkFence> fenceC (createFence(vkd, *device));
1881 NativeHandle handle;
1883 submitDummySignal(vkd, queue, *fenceB);
1884 VK_CHECK(vkd.queueWaitIdle(queue));
1886 submitDummySignal(vkd, queue, *fenceA);
1888 getFenceNative(vkd, *device, *fenceA, config.externalType, handle);
1890 NativeHandle handleB (handle);
1891 importFence(vkd, *device, *fenceB, config.externalType, handleB, flags);
1893 importFence(vkd, *device, *fenceC, config.externalType, handle, flags);
1895 VK_CHECK(vkd.queueWaitIdle(queue));
1896 VK_CHECK(vkd.resetFences(*device, 1u, &*fenceB));
1898 if (config.permanence == PERMANENCE_TEMPORARY || transference == TRANSFERENCE_COPY)
1900 // vkResetFences() should restore fenceBs prior payload and reset that no affecting fenceCs payload
1901 // or fenceB should be separate copy of the payload and not affect fenceC
1902 VK_CHECK(vkd.waitForFences(*device, 1u, &*fenceC, VK_TRUE, ~0ull));
1904 // vkResetFences() should have restored fenceBs prior state and should be now reset
1905 // or fenceB should have it's separate payload
1906 submitDummySignal(vkd, queue, *fenceB);
1907 VK_CHECK(vkd.waitForFences(*device, 1u, &*fenceB, VK_TRUE, ~0ull));
1909 else if (config.permanence == PERMANENCE_PERMANENT)
1911 DE_ASSERT(transference == TRANSFERENCE_REFERENCE);
1913 // Reset fences should have reset all of the fences
1914 submitDummySignal(vkd, queue, *fenceC);
1916 VK_CHECK(vkd.waitForFences(*device, 1u, &*fenceA, VK_TRUE, ~0ull));
1917 VK_CHECK(vkd.waitForFences(*device, 1u, &*fenceB, VK_TRUE, ~0ull));
1918 VK_CHECK(vkd.waitForFences(*device, 1u, &*fenceC, VK_TRUE, ~0ull));
1921 DE_FATAL("Unknown permanence");
1923 VK_CHECK(vkd.queueWaitIdle(queue));
1925 return tcu::TestStatus::pass("Pass");
1929 tcu::TestStatus testFenceSignalWaitImport (Context& context,
1930 const FenceTestConfig config)
1932 const Transference transference (getHandelTypeTransferences(config.externalType));
1933 const vk::PlatformInterface& vkp (context.getPlatformInterface());
1934 const vk::Unique<vk::VkInstance> instance (createInstance(vkp, 0u, 0u, config.externalType));
1935 const vk::InstanceDriver vki (vkp, *instance);
1936 const vk::VkPhysicalDevice physicalDevice (vk::chooseDevice(vki, *instance, context.getTestContext().getCommandLine()));
1937 const deUint32 queueFamilyIndex (chooseQueueFamilyIndex(vki, physicalDevice, 0u));
1939 checkFenceSupport(vki, physicalDevice, config.externalType);
1942 const vk::VkFenceImportFlags flags = config.permanence == PERMANENCE_TEMPORARY ? vk::VK_FENCE_IMPORT_TEMPORARY_BIT : (vk::VkFenceImportFlagBits)0u;
1943 const vk::Unique<vk::VkDevice> device (createDevice(context.getUsedApiVersion(), vki, physicalDevice, 0u, 0u, config.externalType, queueFamilyIndex));
1944 const vk::DeviceDriver vkd (vki, *device);
1945 const vk::VkQueue queue (getQueue(vkd, *device, queueFamilyIndex));
1947 const vk::Unique<vk::VkFence> fenceA (createExportableFence(vkd, *device, config.externalType));
1948 const vk::Unique<vk::VkFence> fenceB (createFence(vkd, *device));
1949 NativeHandle handle;
1951 if (transference == TRANSFERENCE_COPY)
1952 submitDummySignal(vkd, queue, *fenceA);
1954 getFenceNative(vkd, *device, *fenceA, config.externalType, handle);
1956 submitDummySignal(vkd, queue, *fenceB);
1957 VK_CHECK(vkd.waitForFences(*device, 1u, &*fenceB, VK_TRUE, ~0ull));
1959 VK_CHECK(vkd.queueWaitIdle(queue));
1961 importFence(vkd, *device, *fenceB, config.externalType, handle, flags);
1963 if (transference == TRANSFERENCE_COPY)
1964 VK_CHECK(vkd.waitForFences(*device, 1u, &*fenceB, VK_TRUE, ~0ull));
1965 else if (transference == TRANSFERENCE_REFERENCE)
1967 submitDummySignal(vkd, queue, *fenceA);
1968 VK_CHECK(vkd.waitForFences(*device, 1u, &*fenceB, VK_TRUE, ~0ull));
1971 DE_FATAL("Unknown transference.");
1973 VK_CHECK(vkd.queueWaitIdle(queue));
1975 return tcu::TestStatus::pass("Pass");
1979 tcu::TestStatus testFenceMultipleExports (Context& context,
1980 const FenceTestConfig config)
1982 const size_t exportCount = 4 * 1024;
1983 const Transference transference (getHandelTypeTransferences(config.externalType));
1984 const vk::PlatformInterface& vkp (context.getPlatformInterface());
1985 const vk::Unique<vk::VkInstance> instance (createInstance(vkp, 0u, 0u, config.externalType));
1986 const vk::InstanceDriver vki (vkp, *instance);
1987 const vk::VkPhysicalDevice physicalDevice (vk::chooseDevice(vki, *instance, context.getTestContext().getCommandLine()));
1988 const deUint32 queueFamilyIndex (chooseQueueFamilyIndex(vki, physicalDevice, 0u));
1990 checkFenceSupport(vki, physicalDevice, config.externalType);
1993 const vk::Unique<vk::VkDevice> device (createDevice(context.getUsedApiVersion(), vki, physicalDevice, 0u, 0u, config.externalType, queueFamilyIndex));
1994 const vk::DeviceDriver vkd (vki, *device);
1995 const vk::VkQueue queue (getQueue(vkd, *device, queueFamilyIndex));
1996 const vk::Unique<vk::VkFence> fence (createExportableFence(vkd, *device, config.externalType));
1998 for (size_t exportNdx = 0; exportNdx < exportCount; exportNdx++)
2000 NativeHandle handle;
2002 if (transference == TRANSFERENCE_COPY)
2003 submitDummySignal(vkd, queue, *fence);
2005 getFenceNative(vkd, *device, *fence, config.externalType, handle);
2008 submitDummySignal(vkd, queue, *fence);
2009 VK_CHECK(vkd.waitForFences(*device, 1u, &*fence, VK_TRUE, ~0ull));
2011 VK_CHECK(vkd.queueWaitIdle(queue));
2014 return tcu::TestStatus::pass("Pass");
2017 tcu::TestStatus testFenceMultipleImports (Context& context,
2018 const FenceTestConfig config)
2020 const size_t importCount = 4 * 1024;
2021 const Transference transference (getHandelTypeTransferences(config.externalType));
2022 const vk::PlatformInterface& vkp (context.getPlatformInterface());
2023 const vk::Unique<vk::VkInstance> instance (createInstance(vkp, 0u, 0u, config.externalType));
2024 const vk::InstanceDriver vki (vkp, *instance);
2025 const vk::VkPhysicalDevice physicalDevice (vk::chooseDevice(vki, *instance, context.getTestContext().getCommandLine()));
2026 const deUint32 queueFamilyIndex (chooseQueueFamilyIndex(vki, physicalDevice, 0u));
2028 checkFenceSupport(vki, physicalDevice, config.externalType);
2031 const vk::VkFenceImportFlags flags = config.permanence == PERMANENCE_TEMPORARY ? vk::VK_FENCE_IMPORT_TEMPORARY_BIT : (vk::VkFenceImportFlagBits)0u;
2032 const vk::Unique<vk::VkDevice> device (createDevice(context.getUsedApiVersion(), vki, physicalDevice, 0u, 0u, config.externalType, queueFamilyIndex));
2033 const vk::DeviceDriver vkd (vki, *device);
2034 const vk::VkQueue queue (getQueue(vkd, *device, queueFamilyIndex));
2035 const vk::Unique<vk::VkFence> fenceA (createExportableFence(vkd, *device, config.externalType));
2036 NativeHandle handleA;
2038 if (transference == TRANSFERENCE_COPY)
2039 submitDummySignal(vkd, queue, *fenceA);
2041 getFenceNative(vkd, *device, *fenceA, config.externalType, handleA);
2043 for (size_t importNdx = 0; importNdx < importCount; importNdx++)
2045 NativeHandle handleB (handleA);
2046 const vk::Unique<vk::VkFence> fenceB (createAndImportFence(vkd, *device, config.externalType, handleB, flags));
2049 if (transference == TRANSFERENCE_COPY)
2051 importFence(vkd, *device, *fenceA, config.externalType, handleA, flags);
2052 VK_CHECK(vkd.waitForFences(*device, 1u, &*fenceA, VK_TRUE, ~0ull));
2054 else if (transference == TRANSFERENCE_REFERENCE)
2056 submitDummySignal(vkd, queue, *fenceA);
2057 VK_CHECK(vkd.waitForFences(*device, 1u, &*fenceA, VK_TRUE, ~0ull));
2060 DE_FATAL("Unknown transference.");
2062 VK_CHECK(vkd.queueWaitIdle(queue));
2065 return tcu::TestStatus::pass("Pass");
2068 tcu::TestStatus testFenceTransference (Context& context,
2069 const FenceTestConfig config)
2071 const Transference transference (getHandelTypeTransferences(config.externalType));
2072 const vk::PlatformInterface& vkp (context.getPlatformInterface());
2073 const vk::Unique<vk::VkInstance> instance (createInstance(vkp, 0u, 0u, config.externalType));
2074 const vk::InstanceDriver vki (vkp, *instance);
2075 const vk::VkPhysicalDevice physicalDevice (vk::chooseDevice(vki, *instance, context.getTestContext().getCommandLine()));
2076 const deUint32 queueFamilyIndex (chooseQueueFamilyIndex(vki, physicalDevice, 0u));
2078 checkFenceSupport(vki, physicalDevice, config.externalType);
2081 const vk::VkFenceImportFlags flags = config.permanence == PERMANENCE_TEMPORARY ? vk::VK_FENCE_IMPORT_TEMPORARY_BIT : (vk::VkFenceImportFlagBits)0u;
2082 const vk::Unique<vk::VkDevice> device (createDevice(context.getUsedApiVersion(), vki, physicalDevice, 0u, 0u, config.externalType, queueFamilyIndex));
2083 const vk::DeviceDriver vkd (vki, *device);
2084 const vk::VkQueue queue (getQueue(vkd, *device, queueFamilyIndex));
2086 const vk::Unique<vk::VkFence> fenceA (createExportableFence(vkd, *device, config.externalType));
2087 NativeHandle handle;
2089 submitDummySignal(vkd, queue, *fenceA);
2091 getFenceNative(vkd, *device, *fenceA, config.externalType, handle);
2094 const vk::Unique<vk::VkFence> fenceB (createAndImportFence(vkd, *device, config.externalType, handle, flags));
2096 if (config.permanence == PERMANENCE_PERMANENT)
2098 if (transference == TRANSFERENCE_COPY)
2100 submitDummySignal(vkd, queue, *fenceA);
2101 VK_CHECK(vkd.waitForFences(*device, 1u, &*fenceB, VK_TRUE, ~0ull));
2102 VK_CHECK(vkd.queueWaitIdle(queue));
2104 VK_CHECK(vkd.resetFences(*device, 1u, &*fenceB));
2105 submitDummySignal(vkd, queue, *fenceB);
2107 VK_CHECK(vkd.waitForFences(*device, 1u, &*fenceA, VK_TRUE, ~0ull));
2108 VK_CHECK(vkd.waitForFences(*device, 1u, &*fenceB, VK_TRUE, ~0ull));
2109 VK_CHECK(vkd.queueWaitIdle(queue));
2111 else if (transference== TRANSFERENCE_REFERENCE)
2113 VK_CHECK(vkd.waitForFences(*device, 1u, &*fenceB, VK_TRUE, ~0ull));
2114 VK_CHECK(vkd.queueWaitIdle(queue));
2116 VK_CHECK(vkd.resetFences(*device, 1u, &*fenceB));
2117 submitDummySignal(vkd, queue, *fenceA);
2118 VK_CHECK(vkd.waitForFences(*device, 1u, &*fenceB, VK_TRUE, ~0ull));
2120 VK_CHECK(vkd.resetFences(*device, 1u, &*fenceA));
2121 submitDummySignal(vkd, queue, *fenceB);
2122 VK_CHECK(vkd.waitForFences(*device, 1u, &*fenceA, VK_TRUE, ~0ull));
2123 VK_CHECK(vkd.queueWaitIdle(queue));
2126 DE_FATAL("Unknown transference.");
2128 else if (config.permanence == PERMANENCE_TEMPORARY)
2130 if (transference == TRANSFERENCE_COPY)
2132 submitDummySignal(vkd, queue, *fenceA);
2133 VK_CHECK(vkd.waitForFences(*device, 1u, &*fenceB, VK_TRUE, ~0ull));
2134 VK_CHECK(vkd.queueWaitIdle(queue));
2136 VK_CHECK(vkd.resetFences(*device, 1u, &*fenceB));
2137 submitDummySignal(vkd, queue, *fenceB);
2139 VK_CHECK(vkd.waitForFences(*device, 1u, &*fenceA, VK_TRUE, ~0ull));
2140 VK_CHECK(vkd.waitForFences(*device, 1u, &*fenceB, VK_TRUE, ~0ull));
2141 VK_CHECK(vkd.queueWaitIdle(queue));
2143 else if (transference == TRANSFERENCE_REFERENCE)
2145 VK_CHECK(vkd.waitForFences(*device, 1u, &*fenceB, VK_TRUE, ~0ull));
2146 VK_CHECK(vkd.queueWaitIdle(queue));
2148 VK_CHECK(vkd.resetFences(*device, 1u, &*fenceA));
2149 VK_CHECK(vkd.resetFences(*device, 1u, &*fenceB));
2150 submitDummySignal(vkd, queue, *fenceA);
2151 submitDummySignal(vkd, queue, *fenceB);
2153 VK_CHECK(vkd.waitForFences(*device, 1u, &*fenceB, VK_TRUE, ~0ull));
2154 VK_CHECK(vkd.waitForFences(*device, 1u, &*fenceA, VK_TRUE, ~0ull));
2155 VK_CHECK(vkd.queueWaitIdle(queue));
2158 DE_FATAL("Unknown transference.");
2161 DE_FATAL("Unknown permanence.");
2164 return tcu::TestStatus::pass("Pass");
2168 tcu::TestStatus testFenceFdDup (Context& context,
2169 const FenceTestConfig config)
2171 #if (DE_OS == DE_OS_ANDROID) || (DE_OS == DE_OS_UNIX)
2172 const Transference transference (getHandelTypeTransferences(config.externalType));
2173 const vk::PlatformInterface& vkp (context.getPlatformInterface());
2174 const vk::Unique<vk::VkInstance> instance (createInstance(vkp, 0u, 0u, config.externalType));
2175 const vk::InstanceDriver vki (vkp, *instance);
2176 const vk::VkPhysicalDevice physicalDevice (vk::chooseDevice(vki, *instance, context.getTestContext().getCommandLine()));
2177 const deUint32 queueFamilyIndex (chooseQueueFamilyIndex(vki, physicalDevice, 0u));
2179 checkFenceSupport(vki, physicalDevice, config.externalType);
2182 const vk::VkFenceImportFlags flags = config.permanence == PERMANENCE_TEMPORARY ? vk::VK_FENCE_IMPORT_TEMPORARY_BIT : (vk::VkFenceImportFlagBits)0u;
2183 const vk::Unique<vk::VkDevice> device (createDevice(context.getUsedApiVersion(), vki, physicalDevice, 0u, 0u, config.externalType, queueFamilyIndex));
2184 const vk::DeviceDriver vkd (vki, *device);
2185 const vk::VkQueue queue (getQueue(vkd, *device, queueFamilyIndex));
2187 TestLog& log = context.getTestContext().getLog();
2188 const vk::Unique<vk::VkFence> fenceA (createExportableFence(vkd, *device, config.externalType));
2190 if (transference == TRANSFERENCE_COPY)
2191 submitDummySignal(vkd, queue, *fenceA);
2194 const NativeHandle fd (getFenceFd(vkd, *device, *fenceA, config.externalType));
2195 NativeHandle newFd (dup(fd.getFd()));
2197 if (newFd.getFd() < 0)
2198 log << TestLog::Message << "dup() failed: '" << strerror(errno) << "'" << TestLog::EndMessage;
2200 TCU_CHECK_MSG(newFd.getFd() >= 0, "Failed to call dup() for fences fd");
2203 const vk::Unique<vk::VkFence> fenceB (createAndImportFence(vkd, *device, config.externalType, newFd, flags));
2205 if (transference == TRANSFERENCE_COPY)
2206 VK_CHECK(vkd.waitForFences(*device, 1u, &*fenceB, VK_TRUE, ~0ull));
2207 else if (transference == TRANSFERENCE_REFERENCE)
2209 submitDummySignal(vkd, queue, *fenceA);
2210 VK_CHECK(vkd.waitForFences(*device, 1u, &*fenceB, VK_TRUE, ~0ull));
2213 DE_FATAL("Unknown permanence.");
2217 VK_CHECK(vkd.queueWaitIdle(queue));
2219 return tcu::TestStatus::pass("Pass");
2224 TCU_THROW(NotSupportedError, "Platform doesn't support dup()");
2228 tcu::TestStatus testFenceFdDup2 (Context& context,
2229 const FenceTestConfig config)
2231 #if (DE_OS == DE_OS_ANDROID) || (DE_OS == DE_OS_UNIX)
2232 const Transference transference (getHandelTypeTransferences(config.externalType));
2233 const vk::PlatformInterface& vkp (context.getPlatformInterface());
2234 const vk::Unique<vk::VkInstance> instance (createInstance(vkp, 0u, 0u, config.externalType));
2235 const vk::InstanceDriver vki (vkp, *instance);
2236 const vk::VkPhysicalDevice physicalDevice (vk::chooseDevice(vki, *instance, context.getTestContext().getCommandLine()));
2237 const deUint32 queueFamilyIndex (chooseQueueFamilyIndex(vki, physicalDevice, 0u));
2239 checkFenceSupport(vki, physicalDevice, config.externalType);
2242 const vk::VkFenceImportFlags flags = config.permanence == PERMANENCE_TEMPORARY ? vk::VK_FENCE_IMPORT_TEMPORARY_BIT : (vk::VkFenceImportFlagBits)0u;
2243 const vk::Unique<vk::VkDevice> device (createDevice(context.getUsedApiVersion(), vki, physicalDevice, 0u, 0u, config.externalType, queueFamilyIndex));
2244 const vk::DeviceDriver vkd (vki, *device);
2245 const vk::VkQueue queue (getQueue(vkd, *device, queueFamilyIndex));
2247 TestLog& log = context.getTestContext().getLog();
2248 const vk::Unique<vk::VkFence> fenceA (createExportableFence(vkd, *device, config.externalType));
2249 const vk::Unique<vk::VkFence> fenceB (createExportableFence(vkd, *device, config.externalType));
2251 if (transference == TRANSFERENCE_COPY)
2253 submitDummySignal(vkd, queue, *fenceA);
2254 submitDummySignal(vkd, queue, *fenceB);
2258 const NativeHandle fd (getFenceFd(vkd, *device, *fenceA, config.externalType));
2259 NativeHandle secondFd (getFenceFd(vkd, *device, *fenceB, config.externalType));
2260 int newFd (dup2(fd.getFd(), secondFd.getFd()));
2263 log << TestLog::Message << "dup2() failed: '" << strerror(errno) << "'" << TestLog::EndMessage;
2265 TCU_CHECK_MSG(newFd >= 0, "Failed to call dup2() for fences fd");
2268 const vk::Unique<vk::VkFence> fenceC (createAndImportFence(vkd, *device, config.externalType, secondFd, flags));
2270 if (transference == TRANSFERENCE_COPY)
2271 VK_CHECK(vkd.waitForFences(*device, 1u, &*fenceC, VK_TRUE, ~0ull));
2272 else if (transference == TRANSFERENCE_REFERENCE)
2274 submitDummySignal(vkd, queue, *fenceA);
2275 VK_CHECK(vkd.waitForFences(*device, 1u, &*fenceC, VK_TRUE, ~0ull));
2278 DE_FATAL("Unknown permanence.");
2282 VK_CHECK(vkd.queueWaitIdle(queue));
2284 return tcu::TestStatus::pass("Pass");
2289 TCU_THROW(NotSupportedError, "Platform doesn't support dup2()");
2293 tcu::TestStatus testFenceFdDup3 (Context& context,
2294 const FenceTestConfig config)
2296 #if (DE_OS == DE_OS_UNIX) && defined(_GNU_SOURCE)
2297 const Transference transference (getHandelTypeTransferences(config.externalType));
2298 const vk::PlatformInterface& vkp (context.getPlatformInterface());
2299 const vk::Unique<vk::VkInstance> instance (createInstance(vkp, 0u, 0u, config.externalType));
2300 const vk::InstanceDriver vki (vkp, *instance);
2301 const vk::VkPhysicalDevice physicalDevice (vk::chooseDevice(vki, *instance, context.getTestContext().getCommandLine()));
2302 const deUint32 queueFamilyIndex (chooseQueueFamilyIndex(vki, physicalDevice, 0u));
2304 checkFenceSupport(vki, physicalDevice, config.externalType);
2307 const vk::Unique<vk::VkDevice> device (createDevice(context.getUsedApiVersion(), vki, physicalDevice, 0u, 0u, config.externalType, queueFamilyIndex));
2308 const vk::DeviceDriver vkd (vki, *device);
2309 const vk::VkQueue queue (getQueue(vkd, *device, queueFamilyIndex));
2311 TestLog& log = context.getTestContext().getLog();
2312 const vk::Unique<vk::VkFence> fenceA (createExportableFence(vkd, *device, config.externalType));
2313 const vk::Unique<vk::VkFence> fenceB (createExportableFence(vkd, *device, config.externalType));
2315 if (transference == TRANSFERENCE_COPY)
2317 submitDummySignal(vkd, queue, *fenceA);
2318 submitDummySignal(vkd, queue, *fenceB);
2322 const vk::VkFenceImportFlags flags = config.permanence == PERMANENCE_TEMPORARY ? vk::VK_FENCE_IMPORT_TEMPORARY_BIT : (vk::VkFenceImportFlagBits)0u;
2323 const NativeHandle fd (getFenceFd(vkd, *device, *fenceA, config.externalType));
2324 NativeHandle secondFd (getFenceFd(vkd, *device, *fenceB, config.externalType));
2325 const int newFd (dup3(fd.getFd(), secondFd.getFd(), 0));
2328 log << TestLog::Message << "dup3() failed: '" << strerror(errno) << "'" << TestLog::EndMessage;
2330 TCU_CHECK_MSG(newFd >= 0, "Failed to call dup3() for fences fd");
2333 const vk::Unique<vk::VkFence> fenceC (createAndImportFence(vkd, *device, config.externalType, secondFd, flags));
2335 if (transference == TRANSFERENCE_COPY)
2336 VK_CHECK(vkd.waitForFences(*device, 1u, &*fenceC, VK_TRUE, ~0ull));
2337 else if (transference == TRANSFERENCE_REFERENCE)
2339 submitDummySignal(vkd, queue, *fenceA);
2340 VK_CHECK(vkd.waitForFences(*device, 1u, &*fenceC, VK_TRUE, ~0ull));
2343 DE_FATAL("Unknown permanence.");
2347 VK_CHECK(vkd.queueWaitIdle(queue));
2349 return tcu::TestStatus::pass("Pass");
2354 TCU_THROW(NotSupportedError, "Platform doesn't support dup3()");
2358 tcu::TestStatus testFenceFdSendOverSocket (Context& context,
2359 const FenceTestConfig config)
2361 #if (DE_OS == DE_OS_ANDROID) || (DE_OS == DE_OS_UNIX)
2362 const Transference transference (getHandelTypeTransferences(config.externalType));
2363 const vk::PlatformInterface& vkp (context.getPlatformInterface());
2364 const vk::Unique<vk::VkInstance> instance (createInstance(vkp, 0u, 0u, config.externalType));
2365 const vk::InstanceDriver vki (vkp, *instance);
2366 const vk::VkPhysicalDevice physicalDevice (vk::chooseDevice(vki, *instance, context.getTestContext().getCommandLine()));
2367 const deUint32 queueFamilyIndex (chooseQueueFamilyIndex(vki, physicalDevice, 0u));
2369 checkFenceSupport(vki, physicalDevice, config.externalType);
2372 const vk::Unique<vk::VkDevice> device (createDevice(context.getUsedApiVersion(), vki, physicalDevice, 0u, 0u, config.externalType, queueFamilyIndex));
2373 const vk::DeviceDriver vkd (vki, *device);
2374 const vk::VkQueue queue (getQueue(vkd, *device, queueFamilyIndex));
2376 TestLog& log = context.getTestContext().getLog();
2377 const vk::Unique<vk::VkFence> fence (createExportableFence(vkd, *device, config.externalType));
2379 if (transference == TRANSFERENCE_COPY)
2380 submitDummySignal(vkd, queue, *fence);
2382 const NativeHandle fd (getFenceFd(vkd, *device, *fence, config.externalType));
2387 if (socketpair(AF_UNIX, SOCK_STREAM, 0, sv) != 0)
2389 log << TestLog::Message << "Failed to create socket pair: '" << strerror(errno) << "'" << TestLog::EndMessage;
2390 TCU_FAIL("Failed to create socket pair");
2394 const NativeHandle srcSocket (sv[0]);
2395 const NativeHandle dstSocket (sv[1]);
2396 std::string sendData ("deqp");
2400 const int fdRaw (fd.getFd());
2403 char buffer[CMSG_SPACE(sizeof(int))];
2404 iovec iov = { &sendData[0], sendData.length()};
2406 deMemset(&msg, 0, sizeof(msg));
2408 msg.msg_control = buffer;
2409 msg.msg_controllen = sizeof(buffer);
2413 cmsg = CMSG_FIRSTHDR(&msg);
2414 cmsg->cmsg_level = SOL_SOCKET;
2415 cmsg->cmsg_type = SCM_RIGHTS;
2416 cmsg->cmsg_len = CMSG_LEN(sizeof(int));
2418 deMemcpy(CMSG_DATA(cmsg), &fdRaw, sizeof(int));
2419 msg.msg_controllen = cmsg->cmsg_len;
2421 if (sendmsg(srcSocket.getFd(), &msg, 0) < 0)
2423 log << TestLog::Message << "Failed to send fd over socket: '" << strerror(errno) << "'" << TestLog::EndMessage;
2424 TCU_FAIL("Failed to send fd over socket");
2431 char buffer[CMSG_SPACE(sizeof(int))];
2432 std::string recvData (4, '\0');
2433 iovec iov = { &recvData[0], recvData.length() };
2435 deMemset(&msg, 0, sizeof(msg));
2437 msg.msg_control = buffer;
2438 msg.msg_controllen = sizeof(buffer);
2442 const ssize_t bytes = recvmsg(dstSocket.getFd(), &msg, 0);
2446 log << TestLog::Message << "Failed to recv fd over socket: '" << strerror(errno) << "'" << TestLog::EndMessage;
2447 TCU_FAIL("Failed to recv fd over socket");
2450 else if (bytes != (ssize_t)sendData.length())
2452 TCU_FAIL("recvmsg() returned unpexpected number of bytes");
2456 const vk::VkFenceImportFlags flags = config.permanence == PERMANENCE_TEMPORARY ? vk::VK_FENCE_IMPORT_TEMPORARY_BIT : (vk::VkFenceImportFlagBits)0u;
2457 const cmsghdr* const cmsg = CMSG_FIRSTHDR(&msg);
2459 deMemcpy(&newFd_, CMSG_DATA(cmsg), sizeof(int));
2460 NativeHandle newFd (newFd_);
2462 TCU_CHECK(cmsg->cmsg_level == SOL_SOCKET);
2463 TCU_CHECK(cmsg->cmsg_type == SCM_RIGHTS);
2464 TCU_CHECK(cmsg->cmsg_len == CMSG_LEN(sizeof(int)));
2465 TCU_CHECK(recvData == sendData);
2466 TCU_CHECK_MSG(newFd.getFd() >= 0, "Didn't receive valid fd from socket");
2469 const vk::Unique<vk::VkFence> newFence (createAndImportFence(vkd, *device, config.externalType, newFd, flags));
2471 if (transference == TRANSFERENCE_COPY)
2472 VK_CHECK(vkd.waitForFences(*device, 1u, &*newFence, VK_TRUE, ~0ull));
2473 else if (transference == TRANSFERENCE_REFERENCE)
2475 submitDummySignal(vkd, queue, *newFence);
2476 VK_CHECK(vkd.waitForFences(*device, 1u, &*newFence, VK_TRUE, ~0ull));
2479 DE_FATAL("Unknown permanence.");
2481 VK_CHECK(vkd.queueWaitIdle(queue));
2489 return tcu::TestStatus::pass("Pass");
2493 TCU_THROW(NotSupportedError, "Platform doesn't support sending file descriptors over socket");
2497 tcu::TestStatus testBufferQueries (Context& context, vk::VkExternalMemoryHandleTypeFlagBits externalType)
2499 const vk::VkBufferCreateFlags createFlags[] =
2502 vk::VK_BUFFER_CREATE_SPARSE_BINDING_BIT,
2503 vk::VK_BUFFER_CREATE_SPARSE_BINDING_BIT|vk::VK_BUFFER_CREATE_SPARSE_RESIDENCY_BIT,
2504 vk::VK_BUFFER_CREATE_SPARSE_BINDING_BIT|vk::VK_BUFFER_CREATE_SPARSE_ALIASED_BIT
2506 const vk::VkBufferUsageFlags usageFlags[] =
2508 vk::VK_BUFFER_USAGE_TRANSFER_SRC_BIT,
2509 vk::VK_BUFFER_USAGE_TRANSFER_DST_BIT,
2510 vk::VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT,
2511 vk::VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT,
2512 vk::VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT,
2513 vk::VK_BUFFER_USAGE_STORAGE_BUFFER_BIT,
2514 vk::VK_BUFFER_USAGE_INDEX_BUFFER_BIT,
2515 vk::VK_BUFFER_USAGE_VERTEX_BUFFER_BIT,
2516 vk::VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT
2518 const vk::PlatformInterface& vkp (context.getPlatformInterface());
2519 const vk::Unique<vk::VkInstance> instance (createInstance(vkp, 0u, externalType, 0u));
2520 const vk::InstanceDriver vki (vkp, *instance);
2521 const vk::VkPhysicalDevice physicalDevice (vk::chooseDevice(vki, *instance, context.getTestContext().getCommandLine()));
2522 const vk::VkPhysicalDeviceFeatures deviceFeatures (vk::getPhysicalDeviceFeatures(vki, physicalDevice));
2523 const deUint32 queueFamilyIndex (chooseQueueFamilyIndex(vki, physicalDevice, 0u));
2525 // VkDevice is only created if physical device claims to support any of these types.
2526 vk::Move<vk::VkDevice> device;
2527 de::MovePtr<vk::DeviceDriver> vkd;
2528 bool deviceHasDedicated = false;
2530 TestLog& log = context.getTestContext().getLog();
2532 for (size_t createFlagNdx = 0; createFlagNdx < DE_LENGTH_OF_ARRAY(createFlags); createFlagNdx++)
2533 for (size_t usageFlagNdx = 0; usageFlagNdx < DE_LENGTH_OF_ARRAY(usageFlags); usageFlagNdx++)
2535 const vk::VkBufferViewCreateFlags createFlag = createFlags[createFlagNdx];
2536 const vk::VkBufferUsageFlags usageFlag = usageFlags[usageFlagNdx];
2537 const vk::VkPhysicalDeviceExternalBufferInfo info =
2539 vk::VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_BUFFER_INFO,
2545 vk::VkExternalBufferProperties properties =
2547 vk::VK_STRUCTURE_TYPE_EXTERNAL_BUFFER_PROPERTIES,
2552 if (((createFlag & vk::VK_BUFFER_CREATE_SPARSE_BINDING_BIT) != 0) &&
2553 (deviceFeatures.sparseBinding == VK_FALSE))
2556 if (((createFlag & vk::VK_BUFFER_CREATE_SPARSE_ALIASED_BIT) != 0) &&
2557 (deviceFeatures.sparseResidencyAliased == VK_FALSE))
2560 if (((createFlag & vk::VK_BUFFER_CREATE_SPARSE_RESIDENCY_BIT) != 0) &&
2561 (deviceFeatures.sparseResidencyBuffer == VK_FALSE))
2564 vki.getPhysicalDeviceExternalBufferProperties(physicalDevice, &info, &properties);
2566 log << TestLog::Message << properties << TestLog::EndMessage;
2568 TCU_CHECK(properties.sType == vk::VK_STRUCTURE_TYPE_EXTERNAL_BUFFER_PROPERTIES);
2569 TCU_CHECK(properties.pNext == DE_NULL);
2570 // \todo [2017-06-06 pyry] Can we validate anything else? Compatible types?
2572 if ((properties.externalMemoryProperties.externalMemoryFeatures & (vk::VK_EXTERNAL_MEMORY_FEATURE_EXPORTABLE_BIT|vk::VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT)) != 0)
2574 const bool requiresDedicated = (properties.externalMemoryProperties.externalMemoryFeatures & vk::VK_EXTERNAL_MEMORY_FEATURE_DEDICATED_ONLY_BIT) != 0;
2576 if (!device || (requiresDedicated && !deviceHasDedicated))
2578 // \note We need to re-create with dedicated mem extensions if previous device instance didn't have them
2581 device = createDevice(context.getUsedApiVersion(), vki, physicalDevice, 0u, externalType, 0u, queueFamilyIndex, requiresDedicated);
2582 vkd = de::MovePtr<vk::DeviceDriver>(new vk::DeviceDriver(vki, *device));
2583 deviceHasDedicated = requiresDedicated;
2585 catch (const tcu::NotSupportedError& e)
2588 TCU_FAIL("Physical device claims to support handle type but required extensions are not supported");
2593 if ((properties.externalMemoryProperties.externalMemoryFeatures & vk::VK_EXTERNAL_MEMORY_FEATURE_EXPORTABLE_BIT) != 0)
2595 DE_ASSERT(!!device);
2598 if (deviceHasDedicated)
2600 const vk::Unique<vk::VkBuffer> buffer (createExternalBuffer(*vkd, *device, queueFamilyIndex, externalType, 1024u, createFlag, usageFlag));
2601 const vk::VkMemoryDedicatedRequirements reqs (getMemoryDedicatedRequirements(*vkd, *device, *buffer));
2602 const bool propertiesRequiresDedicated = (properties.externalMemoryProperties.externalMemoryFeatures & vk::VK_EXTERNAL_MEMORY_FEATURE_DEDICATED_ONLY_BIT) != 0;
2603 const bool objectRequiresDedicated = (reqs.requiresDedicatedAllocation != VK_FALSE);
2605 if (propertiesRequiresDedicated != objectRequiresDedicated)
2606 TCU_FAIL("vkGetPhysicalDeviceExternalBufferProperties and vkGetBufferMemoryRequirements2 report different dedicated requirements");
2610 // We can't query whether dedicated memory is required or not on per-object basis.
2611 // This check should be redundant as the code above tries to create device with
2612 // VK_KHR_dedicated_allocation & VK_KHR_get_memory_requirements2 if dedicated memory
2613 // is required. However, checking again doesn't hurt.
2614 TCU_CHECK((properties.externalMemoryProperties.externalMemoryFeatures & vk::VK_EXTERNAL_MEMORY_FEATURE_DEDICATED_ONLY_BIT) == 0);
2619 return tcu::TestStatus::pass("Pass");
2622 struct MemoryTestConfig
2624 MemoryTestConfig (vk::VkExternalMemoryHandleTypeFlagBits externalType_,
2627 : externalType (externalType_)
2628 , hostVisible (hostVisible_)
2629 , dedicated (dedicated_)
2633 vk::VkExternalMemoryHandleTypeFlagBits externalType;
2638 #if (DE_OS == DE_OS_WIN32)
2639 deUint32 chooseMemoryType (deUint32 bits)
2642 TCU_THROW(NotSupportedError, "No compatible memory type found");
2644 return deCtz32(bits);
2648 tcu::TestStatus testMemoryWin32Create (Context& context, MemoryTestConfig config)
2650 #if (DE_OS == DE_OS_WIN32)
2651 const vk::PlatformInterface& vkp (context.getPlatformInterface());
2652 const vk::Unique<vk::VkInstance> instance (createInstance(vkp, 0u, config.externalType, 0u));
2653 const vk::InstanceDriver vki (vkp, *instance);
2654 const vk::VkPhysicalDevice physicalDevice (vk::chooseDevice(vki, *instance, context.getTestContext().getCommandLine()));
2655 const deUint32 queueFamilyIndex (chooseQueueFamilyIndex(vki, physicalDevice, 0u));
2656 const vk::Unique<vk::VkDevice> device (createDevice(context.getUsedApiVersion(), vki, physicalDevice, 0u, config.externalType, 0u, queueFamilyIndex));
2657 const vk::DeviceDriver vkd (vki, *device);
2658 const vk::VkBufferUsageFlags usage = vk::VK_BUFFER_USAGE_TRANSFER_SRC_BIT|vk::VK_BUFFER_USAGE_TRANSFER_DST_BIT;
2659 const deUint32 seed = 1261033864u;
2660 const vk::VkDeviceSize bufferSize = 1024;
2661 const std::vector<deUint8> testData (genTestData(seed, (size_t)bufferSize));
2663 const vk::VkPhysicalDeviceMemoryProperties memoryProps = vk::getPhysicalDeviceMemoryProperties(context.getInstanceInterface(), context.getPhysicalDevice());
2664 const deUint32 compatibleMemTypes = vk::getCompatibleMemoryTypes(memoryProps, config.hostVisible ? vk::MemoryRequirement::HostVisible : vk::MemoryRequirement::Any);
2666 checkBufferSupport(vki, physicalDevice, config.externalType, 0u, usage, config.dedicated);
2668 // \note Buffer is only allocated to get memory requirements
2669 deUint32 exportedMemoryTypeIndex = ~0U;
2670 const vk::Unique<vk::VkBuffer> buffer (createExternalBuffer(vkd, *device, queueFamilyIndex, config.externalType, bufferSize, 0u, usage));
2671 const vk::VkMemoryRequirements requirements (getBufferMemoryRequirements(vkd, *device, *buffer));
2672 const vk::VkExportMemoryWin32HandleInfoKHR win32Info =
2674 vk::VK_STRUCTURE_TYPE_EXPORT_MEMORY_WIN32_HANDLE_INFO_KHR,
2677 (vk::pt::Win32SecurityAttributesPtr)DE_NULL,
2678 DXGI_SHARED_RESOURCE_READ | DXGI_SHARED_RESOURCE_WRITE,
2681 const vk::VkExportMemoryAllocateInfo exportInfo =
2683 vk::VK_STRUCTURE_TYPE_EXPORT_MEMORY_ALLOCATE_INFO,
2685 (vk::VkExternalMemoryHandleTypeFlags)config.externalType
2688 exportedMemoryTypeIndex = chooseMemoryType(requirements.memoryTypeBits & compatibleMemTypes);
2689 const vk::VkMemoryAllocateInfo info =
2691 vk::VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,
2694 exportedMemoryTypeIndex
2696 const vk::Unique<vk::VkDeviceMemory> memory (vk::allocateMemory(vkd, *device, &info));
2697 NativeHandle handleA;
2699 if (config.hostVisible)
2700 writeHostMemory(vkd, *device, *memory, testData.size(), &testData[0]);
2702 getMemoryNative(vkd, *device, *memory, config.externalType, handleA);
2705 const vk::Unique<vk::VkDeviceMemory> memoryA (importMemory(vkd, *device, requirements, config.externalType, exportedMemoryTypeIndex, handleA));
2707 if (config.hostVisible)
2709 const std::vector<deUint8> testDataA (genTestData(seed ^ 124798807u, (size_t)bufferSize));
2710 const std::vector<deUint8> testDataB (genTestData(seed ^ 970834278u, (size_t)bufferSize));
2712 checkHostMemory(vkd, *device, *memoryA, testData.size(), &testData[0]);
2713 checkHostMemory(vkd, *device, *memory, testData.size(), &testData[0]);
2715 writeHostMemory(vkd, *device, *memoryA, testDataA.size(), &testDataA[0]);
2716 writeHostMemory(vkd, *device, *memory, testDataA.size(), &testDataB[0]);
2718 checkHostMemory(vkd, *device, *memoryA, testData.size(), &testDataB[0]);
2719 checkHostMemory(vkd, *device, *memory, testData.size(), &testDataB[0]);
2723 return tcu::TestStatus::pass("Pass");
2727 TCU_THROW(NotSupportedError, "Platform doesn't support win32 handles");
2731 tcu::TestStatus testMemoryImportTwice (Context& context, MemoryTestConfig config)
2733 const vk::PlatformInterface& vkp (context.getPlatformInterface());
2734 const vk::Unique<vk::VkInstance> instance (createInstance(vkp, 0u, config.externalType, 0u));
2735 const vk::InstanceDriver vki (vkp, *instance);
2736 const vk::VkPhysicalDevice physicalDevice (vk::chooseDevice(vki, *instance, context.getTestContext().getCommandLine()));
2737 const deUint32 queueFamilyIndex (chooseQueueFamilyIndex(vki, physicalDevice, 0u));
2738 const vk::Unique<vk::VkDevice> device (createDevice(context.getUsedApiVersion(), vki, physicalDevice, 0u, config.externalType, 0u, queueFamilyIndex));
2739 const vk::DeviceDriver vkd (vki, *device);
2740 const vk::VkBufferUsageFlags usage = vk::VK_BUFFER_USAGE_TRANSFER_SRC_BIT|vk::VK_BUFFER_USAGE_TRANSFER_DST_BIT;
2741 const deUint32 seed = 1261033864u;
2742 const vk::VkDeviceSize bufferSize = 1024;
2743 const std::vector<deUint8> testData (genTestData(seed, (size_t)bufferSize));
2745 checkBufferSupport(vki, physicalDevice, config.externalType, 0u, usage, config.dedicated);
2747 deUint32 exportedMemoryTypeIndex = ~0U;
2748 // \note Buffer is only allocated to get memory requirements
2749 const vk::Unique<vk::VkBuffer> buffer (createExternalBuffer(vkd, *device, queueFamilyIndex, config.externalType, bufferSize, 0u, usage));
2750 const vk::VkMemoryRequirements requirements (getBufferMemoryRequirements(vkd, *device, *buffer));
2751 const vk::Unique<vk::VkDeviceMemory> memory (allocateExportableMemory(vki, physicalDevice, vkd, *device, requirements, config.externalType, config.hostVisible, config.dedicated ? *buffer : (vk::VkBuffer)0, exportedMemoryTypeIndex));
2752 NativeHandle handleA;
2754 if (config.hostVisible)
2755 writeHostMemory(vkd, *device, *memory, testData.size(), &testData[0]);
2757 getMemoryNative(vkd, *device, *memory, config.externalType, handleA);
2760 NativeHandle handleB (handleA);
2761 const vk::Unique<vk::VkDeviceMemory> memoryA (importMemory(vkd, *device, requirements, config.externalType, exportedMemoryTypeIndex, handleA));
2762 const vk::Unique<vk::VkDeviceMemory> memoryB (importMemory(vkd, *device, requirements, config.externalType, exportedMemoryTypeIndex, handleB));
2764 if (config.hostVisible)
2766 const std::vector<deUint8> testDataA (genTestData(seed ^ 124798807u, (size_t)bufferSize));
2767 const std::vector<deUint8> testDataB (genTestData(seed ^ 970834278u, (size_t)bufferSize));
2769 checkHostMemory(vkd, *device, *memoryA, testData.size(), &testData[0]);
2770 checkHostMemory(vkd, *device, *memoryB, testData.size(), &testData[0]);
2772 writeHostMemory(vkd, *device, *memoryA, testData.size(), &testDataA[0]);
2773 writeHostMemory(vkd, *device, *memoryB, testData.size(), &testDataB[0]);
2775 checkHostMemory(vkd, *device, *memoryA, testData.size(), &testDataB[0]);
2776 checkHostMemory(vkd, *device, *memory, testData.size(), &testDataB[0]);
2780 return tcu::TestStatus::pass("Pass");
2783 tcu::TestStatus testMemoryMultimpleImports (Context& context, MemoryTestConfig config)
2785 const size_t count = 4 * 1024;
2786 const vk::PlatformInterface& vkp (context.getPlatformInterface());
2787 const vk::Unique<vk::VkInstance> instance (createInstance(vkp, 0u, config.externalType, 0u));
2788 const vk::InstanceDriver vki (vkp, *instance);
2789 const vk::VkPhysicalDevice physicalDevice (vk::chooseDevice(vki, *instance, context.getTestContext().getCommandLine()));
2790 const deUint32 queueFamilyIndex (chooseQueueFamilyIndex(vki, physicalDevice, 0u));
2791 const vk::Unique<vk::VkDevice> device (createDevice(context.getUsedApiVersion(), vki, physicalDevice, 0u, config.externalType, 0u, queueFamilyIndex));
2792 const vk::DeviceDriver vkd (vki, *device);
2793 const vk::VkBufferUsageFlags usage = vk::VK_BUFFER_USAGE_TRANSFER_SRC_BIT|vk::VK_BUFFER_USAGE_TRANSFER_DST_BIT;
2794 const vk::VkDeviceSize bufferSize = 1024;
2796 checkBufferSupport(vki, physicalDevice, config.externalType, 0u, usage, config.dedicated);
2798 deUint32 exportedMemoryTypeIndex = ~0U;
2799 // \note Buffer is only allocated to get memory requirements
2800 const vk::Unique<vk::VkBuffer> buffer (createExternalBuffer(vkd, *device, queueFamilyIndex, config.externalType, bufferSize, 0u, usage));
2801 const vk::VkMemoryRequirements requirements (getBufferMemoryRequirements(vkd, *device, *buffer));
2802 const vk::Unique<vk::VkDeviceMemory> memory (allocateExportableMemory(vki, physicalDevice, vkd, *device, requirements, config.externalType, config.hostVisible, config.dedicated ? *buffer : (vk::VkBuffer)0, exportedMemoryTypeIndex));
2803 NativeHandle handleA;
2805 getMemoryNative(vkd, *device, *memory, config.externalType, handleA);
2807 for (size_t ndx = 0; ndx < count; ndx++)
2809 NativeHandle handleB (handleA);
2810 const vk::Unique<vk::VkDeviceMemory> memoryB (importMemory(vkd, *device, requirements, config.externalType, exportedMemoryTypeIndex, handleB));
2813 return tcu::TestStatus::pass("Pass");
2816 tcu::TestStatus testMemoryMultimpleExports (Context& context, MemoryTestConfig config)
2818 const size_t count = 4 * 1024;
2819 const vk::PlatformInterface& vkp (context.getPlatformInterface());
2820 const vk::Unique<vk::VkInstance> instance (createInstance(vkp, 0u, config.externalType, 0u));
2821 const vk::InstanceDriver vki (vkp, *instance);
2822 const vk::VkPhysicalDevice physicalDevice (vk::chooseDevice(vki, *instance, context.getTestContext().getCommandLine()));
2823 const deUint32 queueFamilyIndex (chooseQueueFamilyIndex(vki, physicalDevice, 0u));
2824 const vk::Unique<vk::VkDevice> device (createDevice(context.getUsedApiVersion(), vki, physicalDevice, 0u, config.externalType, 0u, queueFamilyIndex));
2825 const vk::DeviceDriver vkd (vki, *device);
2826 const vk::VkBufferUsageFlags usage = vk::VK_BUFFER_USAGE_TRANSFER_SRC_BIT|vk::VK_BUFFER_USAGE_TRANSFER_DST_BIT;
2827 const vk::VkDeviceSize bufferSize = 1024;
2829 checkBufferSupport(vki, physicalDevice, config.externalType, 0u, usage, config.dedicated);
2831 deUint32 exportedMemoryTypeIndex = ~0U;
2832 // \note Buffer is only allocated to get memory requirements
2833 const vk::Unique<vk::VkBuffer> buffer (createExternalBuffer(vkd, *device, queueFamilyIndex, config.externalType, bufferSize, 0u, usage));
2834 const vk::VkMemoryRequirements requirements (getBufferMemoryRequirements(vkd, *device, *buffer));
2835 const vk::Unique<vk::VkDeviceMemory> memory (allocateExportableMemory(vki, physicalDevice, vkd, *device, requirements, config.externalType, config.hostVisible, config.dedicated ? *buffer : (vk::VkBuffer)0, exportedMemoryTypeIndex));
2837 for (size_t ndx = 0; ndx < count; ndx++)
2839 NativeHandle handle;
2840 getMemoryNative(vkd, *device, *memory, config.externalType, handle);
2843 return tcu::TestStatus::pass("Pass");
2846 tcu::TestStatus testMemoryFdDup (Context& context, MemoryTestConfig config)
2848 #if (DE_OS == DE_OS_ANDROID) || (DE_OS == DE_OS_UNIX)
2849 const vk::PlatformInterface& vkp (context.getPlatformInterface());
2850 const vk::Unique<vk::VkInstance> instance (createInstance(vkp, 0u, config.externalType, 0u));
2851 const vk::InstanceDriver vki (vkp, *instance);
2852 const vk::VkPhysicalDevice physicalDevice (vk::chooseDevice(vki, *instance, context.getTestContext().getCommandLine()));
2853 const deUint32 queueFamilyIndex (chooseQueueFamilyIndex(vki, physicalDevice, 0u));
2856 const vk::Unique<vk::VkDevice> device (createDevice(context.getUsedApiVersion(), vki, physicalDevice, 0u, config.externalType, 0u, queueFamilyIndex));
2857 const vk::DeviceDriver vkd (vki, *device);
2859 TestLog& log = context.getTestContext().getLog();
2860 const vk::VkBufferUsageFlags usage = vk::VK_BUFFER_USAGE_TRANSFER_SRC_BIT|vk::VK_BUFFER_USAGE_TRANSFER_DST_BIT;
2861 const vk::VkDeviceSize bufferSize = 1024;
2862 const deUint32 seed = 851493858u;
2863 const std::vector<deUint8> testData (genTestData(seed, (size_t)bufferSize));
2865 checkBufferSupport(vki, physicalDevice, config.externalType, 0u, usage, config.dedicated);
2867 deUint32 exportedMemoryTypeIndex = ~0U;
2868 // \note Buffer is only allocated to get memory requirements
2869 const vk::Unique<vk::VkBuffer> buffer (createExternalBuffer(vkd, *device, queueFamilyIndex, config.externalType, bufferSize, 0u, usage));
2870 const vk::VkMemoryRequirements requirements (getBufferMemoryRequirements(vkd, *device, *buffer));
2871 const vk::Unique<vk::VkDeviceMemory> memory (allocateExportableMemory(vki, physicalDevice, vkd, *device, requirements, config.externalType, config.hostVisible, config.dedicated ? *buffer : (vk::VkBuffer)0, exportedMemoryTypeIndex));
2873 if (config.hostVisible)
2874 writeHostMemory(vkd, *device, *memory, testData.size(), &testData[0]);
2876 const NativeHandle fd (getMemoryFd(vkd, *device, *memory, config.externalType));
2877 NativeHandle newFd (dup(fd.getFd()));
2879 if (newFd.getFd() < 0)
2880 log << TestLog::Message << "dup() failed: '" << strerror(errno) << "'" << TestLog::EndMessage;
2882 TCU_CHECK_MSG(newFd.getFd() >= 0, "Failed to call dup() for memorys fd");
2885 const vk::Unique<vk::VkDeviceMemory> newMemory (importMemory(vkd, *device, requirements, config.externalType, exportedMemoryTypeIndex, newFd));
2887 if (config.hostVisible)
2889 const std::vector<deUint8> testDataA (genTestData(seed ^ 672929437u, (size_t)bufferSize));
2891 checkHostMemory(vkd, *device, *newMemory, testData.size(), &testData[0]);
2893 writeHostMemory(vkd, *device, *newMemory, testDataA.size(), &testDataA[0]);
2894 checkHostMemory(vkd, *device, *memory, testDataA.size(), &testDataA[0]);
2898 return tcu::TestStatus::pass("Pass");
2903 TCU_THROW(NotSupportedError, "Platform doesn't support dup()");
2907 tcu::TestStatus testMemoryFdDup2 (Context& context, MemoryTestConfig config)
2909 #if (DE_OS == DE_OS_ANDROID) || (DE_OS == DE_OS_UNIX)
2910 const vk::PlatformInterface& vkp (context.getPlatformInterface());
2911 const vk::Unique<vk::VkInstance> instance (createInstance(vkp, 0u, config.externalType, 0u));
2912 const vk::InstanceDriver vki (vkp, *instance);
2913 const vk::VkPhysicalDevice physicalDevice (vk::chooseDevice(vki, *instance, context.getTestContext().getCommandLine()));
2914 const deUint32 queueFamilyIndex (chooseQueueFamilyIndex(vki, physicalDevice, 0u));
2917 const vk::Unique<vk::VkDevice> device (createDevice(context.getUsedApiVersion(), vki, physicalDevice, 0u, config.externalType, 0u, queueFamilyIndex));
2918 const vk::DeviceDriver vkd (vki, *device);
2920 TestLog& log = context.getTestContext().getLog();
2921 const vk::VkBufferUsageFlags usage = vk::VK_BUFFER_USAGE_TRANSFER_SRC_BIT|vk::VK_BUFFER_USAGE_TRANSFER_DST_BIT;
2922 const vk::VkDeviceSize bufferSize = 1024;
2923 const deUint32 seed = 224466865u;
2924 const std::vector<deUint8> testData (genTestData(seed, (size_t)bufferSize));
2926 checkBufferSupport(vki, physicalDevice, config.externalType, 0u, usage, config.dedicated);
2928 deUint32 exportedMemoryTypeIndex = ~0U;
2929 // \note Buffer is only allocated to get memory requirements
2930 const vk::Unique<vk::VkBuffer> buffer (createExternalBuffer(vkd, *device, queueFamilyIndex, config.externalType, bufferSize, 0u, usage));
2931 const vk::VkMemoryRequirements requirements (getBufferMemoryRequirements(vkd, *device, *buffer));
2932 const vk::Unique<vk::VkDeviceMemory> memory (allocateExportableMemory(vki, physicalDevice, vkd, *device, requirements, config.externalType, config.hostVisible, config.dedicated ? *buffer : (vk::VkBuffer)0, exportedMemoryTypeIndex));
2934 if (config.hostVisible)
2935 writeHostMemory(vkd, *device, *memory, testData.size(), &testData[0]);
2937 const NativeHandle fd (getMemoryFd(vkd, *device, *memory, config.externalType));
2938 NativeHandle secondFd (getMemoryFd(vkd, *device, *memory, config.externalType));
2939 const int newFd (dup2(fd.getFd(), secondFd.getFd()));
2942 log << TestLog::Message << "dup2() failed: '" << strerror(errno) << "'" << TestLog::EndMessage;
2944 TCU_CHECK_MSG(newFd >= 0, "Failed to call dup2() for memorys fd");
2947 const vk::Unique<vk::VkDeviceMemory> newMemory (importMemory(vkd, *device, requirements, config.externalType, exportedMemoryTypeIndex, secondFd));
2949 if (config.hostVisible)
2951 const std::vector<deUint8> testDataA (genTestData(seed ^ 99012346u, (size_t)bufferSize));
2953 checkHostMemory(vkd, *device, *newMemory, testData.size(), &testData[0]);
2955 writeHostMemory(vkd, *device, *newMemory, testDataA.size(), &testDataA[0]);
2956 checkHostMemory(vkd, *device, *memory, testDataA.size(), &testDataA[0]);
2960 return tcu::TestStatus::pass("Pass");
2965 TCU_THROW(NotSupportedError, "Platform doesn't support dup()");
2969 tcu::TestStatus testMemoryFdDup3 (Context& context, MemoryTestConfig config)
2971 #if (DE_OS == DE_OS_UNIX) && defined(_GNU_SOURCE)
2972 const vk::PlatformInterface& vkp (context.getPlatformInterface());
2973 const vk::Unique<vk::VkInstance> instance (createInstance(vkp, 0u, config.externalType, 0u));
2974 const vk::InstanceDriver vki (vkp, *instance);
2975 const vk::VkPhysicalDevice physicalDevice (vk::chooseDevice(vki, *instance, context.getTestContext().getCommandLine()));
2976 const deUint32 queueFamilyIndex (chooseQueueFamilyIndex(vki, physicalDevice, 0u));
2979 const vk::Unique<vk::VkDevice> device (createDevice(context.getUsedApiVersion(), vki, physicalDevice, 0u, config.externalType, 0u, queueFamilyIndex));
2980 const vk::DeviceDriver vkd (vki, *device);
2982 TestLog& log = context.getTestContext().getLog();
2983 const vk::VkBufferUsageFlags usage = vk::VK_BUFFER_USAGE_TRANSFER_SRC_BIT|vk::VK_BUFFER_USAGE_TRANSFER_DST_BIT;
2984 const vk::VkDeviceSize bufferSize = 1024;
2985 const deUint32 seed = 2554088961u;
2986 const std::vector<deUint8> testData (genTestData(seed, (size_t)bufferSize));
2988 checkBufferSupport(vki, physicalDevice, config.externalType, 0u, usage, config.dedicated);
2990 deUint32 exportedMemoryTypeIndex = ~0U;
2991 // \note Buffer is only allocated to get memory requirements
2992 const vk::Unique<vk::VkBuffer> buffer (createExternalBuffer(vkd, *device, queueFamilyIndex, config.externalType, bufferSize, 0u, usage));
2993 const vk::VkMemoryRequirements requirements (getBufferMemoryRequirements(vkd, *device, *buffer));
2994 const vk::Unique<vk::VkDeviceMemory> memory (allocateExportableMemory(vki, physicalDevice, vkd, *device, requirements, config.externalType, config.hostVisible, config.dedicated ? *buffer : (vk::VkBuffer)0, exportedMemoryTypeIndex));
2996 if (config.hostVisible)
2997 writeHostMemory(vkd, *device, *memory, testData.size(), &testData[0]);
2999 const NativeHandle fd (getMemoryFd(vkd, *device, *memory, config.externalType));
3000 NativeHandle secondFd (getMemoryFd(vkd, *device, *memory, config.externalType));
3001 const int newFd (dup3(fd.getFd(), secondFd.getFd(), 0));
3004 log << TestLog::Message << "dup3() failed: '" << strerror(errno) << "'" << TestLog::EndMessage;
3006 TCU_CHECK_MSG(newFd >= 0, "Failed to call dup3() for memorys fd");
3009 const vk::Unique<vk::VkDeviceMemory> newMemory (importMemory(vkd, *device, requirements, config.externalType, exportedMemoryTypeIndex, secondFd));
3011 if (config.hostVisible)
3013 const std::vector<deUint8> testDataA (genTestData(seed ^ 4210342378u, (size_t)bufferSize));
3015 checkHostMemory(vkd, *device, *newMemory, testData.size(), &testData[0]);
3017 writeHostMemory(vkd, *device, *newMemory, testDataA.size(), &testDataA[0]);
3018 checkHostMemory(vkd, *device, *memory, testDataA.size(), &testDataA[0]);
3022 return tcu::TestStatus::pass("Pass");
3027 TCU_THROW(NotSupportedError, "Platform doesn't support dup()");
3031 tcu::TestStatus testMemoryFdSendOverSocket (Context& context, MemoryTestConfig config)
3033 #if (DE_OS == DE_OS_ANDROID) || (DE_OS == DE_OS_UNIX)
3034 const vk::PlatformInterface& vkp (context.getPlatformInterface());
3035 const vk::Unique<vk::VkInstance> instance (createInstance(vkp, 0u, config.externalType, 0u));
3036 const vk::InstanceDriver vki (vkp, *instance);
3037 const vk::VkPhysicalDevice physicalDevice (vk::chooseDevice(vki, *instance, context.getTestContext().getCommandLine()));
3038 const deUint32 queueFamilyIndex (chooseQueueFamilyIndex(vki, physicalDevice, 0u));
3041 const vk::Unique<vk::VkDevice> device (createDevice(context.getUsedApiVersion(), vki, physicalDevice, 0u, config.externalType, 0u, queueFamilyIndex));
3042 const vk::DeviceDriver vkd (vki, *device);
3044 TestLog& log = context.getTestContext().getLog();
3045 const vk::VkBufferUsageFlags usage = vk::VK_BUFFER_USAGE_TRANSFER_SRC_BIT|vk::VK_BUFFER_USAGE_TRANSFER_DST_BIT;
3046 const vk::VkDeviceSize bufferSize = 1024;
3047 const deUint32 seed = 3403586456u;
3048 const std::vector<deUint8> testData (genTestData(seed, (size_t)bufferSize));
3050 checkBufferSupport(vki, physicalDevice, config.externalType, 0u, usage, config.dedicated);
3052 deUint32 exportedMemoryTypeIndex = ~0U;
3053 // \note Buffer is only allocated to get memory requirements
3054 const vk::Unique<vk::VkBuffer> buffer (createExternalBuffer(vkd, *device, queueFamilyIndex, config.externalType, bufferSize, 0u, usage));
3055 const vk::VkMemoryRequirements requirements (getBufferMemoryRequirements(vkd, *device, *buffer));
3056 const vk::Unique<vk::VkDeviceMemory> memory (allocateExportableMemory(vki, physicalDevice, vkd, *device, requirements, config.externalType, config.hostVisible, config.dedicated ? *buffer : (vk::VkBuffer)0, exportedMemoryTypeIndex));
3058 if (config.hostVisible)
3059 writeHostMemory(vkd, *device, *memory, testData.size(), &testData[0]);
3061 const NativeHandle fd (getMemoryFd(vkd, *device, *memory, config.externalType));
3066 if (socketpair(AF_UNIX, SOCK_STREAM, 0, sv) != 0)
3068 log << TestLog::Message << "Failed to create socket pair: '" << strerror(errno) << "'" << TestLog::EndMessage;
3069 TCU_FAIL("Failed to create socket pair");
3073 const NativeHandle srcSocket (sv[0]);
3074 const NativeHandle dstSocket (sv[1]);
3075 std::string sendData ("deqp");
3079 const int fdRaw (fd.getFd());
3082 char tmpBuffer[CMSG_SPACE(sizeof(int))];
3083 iovec iov = { &sendData[0], sendData.length()};
3085 deMemset(&msg, 0, sizeof(msg));
3087 msg.msg_control = tmpBuffer;
3088 msg.msg_controllen = sizeof(tmpBuffer);
3092 cmsg = CMSG_FIRSTHDR(&msg);
3093 cmsg->cmsg_level = SOL_SOCKET;
3094 cmsg->cmsg_type = SCM_RIGHTS;
3095 cmsg->cmsg_len = CMSG_LEN(sizeof(int));
3097 deMemcpy(CMSG_DATA(cmsg), &fdRaw, sizeof(int));
3098 msg.msg_controllen = cmsg->cmsg_len;
3100 if (sendmsg(srcSocket.getFd(), &msg, 0) < 0)
3102 log << TestLog::Message << "Failed to send fd over socket: '" << strerror(errno) << "'" << TestLog::EndMessage;
3103 TCU_FAIL("Failed to send fd over socket");
3110 char tmpBuffer[CMSG_SPACE(sizeof(int))];
3111 std::string recvData (4, '\0');
3112 iovec iov = { &recvData[0], recvData.length() };
3114 deMemset(&msg, 0, sizeof(msg));
3116 msg.msg_control = tmpBuffer;
3117 msg.msg_controllen = sizeof(tmpBuffer);
3121 const ssize_t bytes = recvmsg(dstSocket.getFd(), &msg, 0);
3125 log << TestLog::Message << "Failed to recv fd over socket: '" << strerror(errno) << "'" << TestLog::EndMessage;
3126 TCU_FAIL("Failed to recv fd over socket");
3129 else if (bytes != (ssize_t)sendData.length())
3131 TCU_FAIL("recvmsg() returned unpexpected number of bytes");
3135 const cmsghdr* const cmsg = CMSG_FIRSTHDR(&msg);
3137 deMemcpy(&newFd_, CMSG_DATA(cmsg), sizeof(int));
3138 NativeHandle newFd (newFd_);
3140 TCU_CHECK(cmsg->cmsg_level == SOL_SOCKET);
3141 TCU_CHECK(cmsg->cmsg_type == SCM_RIGHTS);
3142 TCU_CHECK(cmsg->cmsg_len == CMSG_LEN(sizeof(int)));
3143 TCU_CHECK(recvData == sendData);
3144 TCU_CHECK_MSG(newFd.getFd() >= 0, "Didn't receive valid fd from socket");
3147 const vk::Unique<vk::VkDeviceMemory> newMemory (importMemory(vkd, *device, requirements, config.externalType, exportedMemoryTypeIndex, newFd));
3149 if (config.hostVisible)
3151 const std::vector<deUint8> testDataA (genTestData(seed ^ 23478978u, (size_t)bufferSize));
3153 checkHostMemory(vkd, *device, *newMemory, testData.size(), &testData[0]);
3155 writeHostMemory(vkd, *device, *newMemory, testDataA.size(), &testDataA[0]);
3156 checkHostMemory(vkd, *device, *memory, testDataA.size(), &testDataA[0]);
3165 return tcu::TestStatus::pass("Pass");
3169 TCU_THROW(NotSupportedError, "Platform doesn't support sending file descriptors over socket");
3173 struct BufferTestConfig
3175 BufferTestConfig (vk::VkExternalMemoryHandleTypeFlagBits externalType_,
3177 : externalType (externalType_)
3178 , dedicated (dedicated_)
3182 vk::VkExternalMemoryHandleTypeFlagBits externalType;
3186 tcu::TestStatus testBufferBindExportImportBind (Context& context,
3187 const BufferTestConfig config)
3189 const vk::PlatformInterface& vkp (context.getPlatformInterface());
3190 const vk::Unique<vk::VkInstance> instance (createInstance(vkp, 0u, config.externalType, 0u));
3191 const vk::InstanceDriver vki (vkp, *instance);
3192 const vk::VkPhysicalDevice physicalDevice (vk::chooseDevice(vki, *instance, context.getTestContext().getCommandLine()));
3193 const deUint32 queueFamilyIndex (chooseQueueFamilyIndex(vki, physicalDevice, 0u));
3194 const vk::Unique<vk::VkDevice> device (createDevice(context.getUsedApiVersion(), vki, physicalDevice, 0u, config.externalType, 0u, queueFamilyIndex, config.dedicated));
3195 const vk::DeviceDriver vkd (vki, *device);
3196 const vk::VkBufferUsageFlags usage = vk::VK_BUFFER_USAGE_TRANSFER_SRC_BIT|vk::VK_BUFFER_USAGE_TRANSFER_DST_BIT;
3197 const vk::VkDeviceSize bufferSize = 1024;
3199 checkBufferSupport(vki, physicalDevice, config.externalType, 0u, usage, config.dedicated);
3201 deUint32 exportedMemoryTypeIndex = ~0U;
3202 // \note Buffer is only allocated to get memory requirements
3203 const vk::Unique<vk::VkBuffer> bufferA (createExternalBuffer(vkd, *device, queueFamilyIndex, config.externalType, bufferSize, 0u, usage));
3204 const vk::VkMemoryRequirements requirements (getBufferMemoryRequirements(vkd, *device, *bufferA));
3205 const vk::Unique<vk::VkDeviceMemory> memoryA (allocateExportableMemory(vkd, *device, requirements, config.externalType, config.dedicated ? *bufferA : (vk::VkBuffer)0, exportedMemoryTypeIndex));
3206 NativeHandle handle;
3208 VK_CHECK(vkd.bindBufferMemory(*device, *bufferA, *memoryA, 0u));
3210 getMemoryNative(vkd, *device, *memoryA, config.externalType, handle);
3213 const vk::Unique<vk::VkDeviceMemory> memoryB (importMemory(vkd, *device, requirements, config.externalType, exportedMemoryTypeIndex, handle));
3214 const vk::Unique<vk::VkBuffer> bufferB (createExternalBuffer(vkd, *device, queueFamilyIndex, config.externalType, bufferSize, 0u, usage));
3216 VK_CHECK(vkd.bindBufferMemory(*device, *bufferB, *memoryB, 0u));
3219 return tcu::TestStatus::pass("Pass");
3222 tcu::TestStatus testBufferExportBindImportBind (Context& context,
3223 const BufferTestConfig config)
3225 const vk::PlatformInterface& vkp (context.getPlatformInterface());
3226 const vk::Unique<vk::VkInstance> instance (createInstance(vkp, 0u, config.externalType, 0u));
3227 const vk::InstanceDriver vki (vkp, *instance);
3228 const vk::VkPhysicalDevice physicalDevice (vk::chooseDevice(vki, *instance, context.getTestContext().getCommandLine()));
3229 const deUint32 queueFamilyIndex (chooseQueueFamilyIndex(vki, physicalDevice, 0u));
3230 const vk::Unique<vk::VkDevice> device (createDevice(context.getUsedApiVersion(), vki, physicalDevice, 0u, config.externalType, 0u, queueFamilyIndex, config.dedicated));
3231 const vk::DeviceDriver vkd (vki, *device);
3232 const vk::VkBufferUsageFlags usage = vk::VK_BUFFER_USAGE_TRANSFER_SRC_BIT|vk::VK_BUFFER_USAGE_TRANSFER_DST_BIT;
3233 const vk::VkDeviceSize bufferSize = 1024;
3235 checkBufferSupport(vki, physicalDevice, config.externalType, 0u, usage, config.dedicated);
3237 deUint32 exportedMemoryTypeIndex = ~0U;
3238 // \note Buffer is only allocated to get memory requirements
3239 const vk::Unique<vk::VkBuffer> bufferA (createExternalBuffer(vkd, *device, queueFamilyIndex, config.externalType, bufferSize, 0u, usage));
3240 const vk::VkMemoryRequirements requirements (getBufferMemoryRequirements(vkd, *device, *bufferA));
3241 const vk::Unique<vk::VkDeviceMemory> memoryA (allocateExportableMemory(vkd, *device, requirements, config.externalType, config.dedicated ? *bufferA : (vk::VkBuffer)0, exportedMemoryTypeIndex));
3242 NativeHandle handle;
3244 getMemoryNative(vkd, *device, *memoryA, config.externalType, handle);
3245 VK_CHECK(vkd.bindBufferMemory(*device, *bufferA, *memoryA, 0u));
3248 const vk::Unique<vk::VkDeviceMemory> memoryB (importMemory(vkd, *device, requirements, config.externalType, exportedMemoryTypeIndex, handle));
3249 const vk::Unique<vk::VkBuffer> bufferB (createExternalBuffer(vkd, *device, queueFamilyIndex, config.externalType, bufferSize, 0u, usage));
3251 VK_CHECK(vkd.bindBufferMemory(*device, *bufferB, *memoryB, 0u));
3254 return tcu::TestStatus::pass("Pass");
3257 tcu::TestStatus testBufferExportImportBindBind (Context& context,
3258 const BufferTestConfig config)
3260 const vk::PlatformInterface& vkp (context.getPlatformInterface());
3261 const vk::Unique<vk::VkInstance> instance (createInstance(vkp, 0u, config.externalType, 0u));
3262 const vk::InstanceDriver vki (vkp, *instance);
3263 const vk::VkPhysicalDevice physicalDevice (vk::chooseDevice(vki, *instance, context.getTestContext().getCommandLine()));
3264 const deUint32 queueFamilyIndex (chooseQueueFamilyIndex(vki, physicalDevice, 0u));
3265 const vk::Unique<vk::VkDevice> device (createDevice(context.getUsedApiVersion(), vki, physicalDevice, 0u, config.externalType, 0u, queueFamilyIndex, config.dedicated));
3266 const vk::DeviceDriver vkd (vki, *device);
3267 const vk::VkBufferUsageFlags usage = vk::VK_BUFFER_USAGE_TRANSFER_SRC_BIT|vk::VK_BUFFER_USAGE_TRANSFER_DST_BIT;
3268 const vk::VkDeviceSize bufferSize = 1024;
3270 checkBufferSupport(vki, physicalDevice, config.externalType, 0u, usage, config.dedicated);
3272 deUint32 exportedMemoryTypeIndex = ~0U;
3273 // \note Buffer is only allocated to get memory requirements
3274 const vk::Unique<vk::VkBuffer> bufferA (createExternalBuffer(vkd, *device, queueFamilyIndex, config.externalType, bufferSize, 0u, usage));
3275 const vk::VkMemoryRequirements requirements (getBufferMemoryRequirements(vkd, *device, *bufferA));
3276 const vk::Unique<vk::VkDeviceMemory> memoryA (allocateExportableMemory(vkd, *device, requirements, config.externalType, config.dedicated ? *bufferA : (vk::VkBuffer)0, exportedMemoryTypeIndex));
3277 NativeHandle handle;
3279 getMemoryNative(vkd, *device, *memoryA, config.externalType, handle);
3282 const vk::Unique<vk::VkDeviceMemory> memoryB (importMemory(vkd, *device, requirements, config.externalType, exportedMemoryTypeIndex, handle));
3283 const vk::Unique<vk::VkBuffer> bufferB (createExternalBuffer(vkd, *device, queueFamilyIndex, config.externalType, bufferSize, 0u, usage));
3285 VK_CHECK(vkd.bindBufferMemory(*device, *bufferA, *memoryA, 0u));
3286 VK_CHECK(vkd.bindBufferMemory(*device, *bufferB, *memoryB, 0u));
3289 return tcu::TestStatus::pass("Pass");
3292 tcu::TestStatus testImageQueries (Context& context, vk::VkExternalMemoryHandleTypeFlagBits externalType)
3294 const vk::VkImageCreateFlags createFlags[] =
3297 vk::VK_IMAGE_CREATE_SPARSE_BINDING_BIT,
3298 vk::VK_IMAGE_CREATE_SPARSE_BINDING_BIT|vk::VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT,
3299 vk::VK_IMAGE_CREATE_SPARSE_BINDING_BIT|vk::VK_IMAGE_CREATE_SPARSE_ALIASED_BIT,
3300 vk::VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT,
3301 vk::VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT,
3302 vk::VK_IMAGE_CREATE_2D_ARRAY_COMPATIBLE_BIT
3304 const vk::VkImageUsageFlags usageFlags[] =
3306 vk::VK_IMAGE_USAGE_TRANSFER_SRC_BIT,
3307 vk::VK_IMAGE_USAGE_TRANSFER_DST_BIT,
3308 vk::VK_IMAGE_USAGE_SAMPLED_BIT,
3309 vk::VK_IMAGE_USAGE_STORAGE_BIT,
3310 vk::VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT,
3311 vk::VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT,
3312 vk::VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT,
3313 vk::VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT
3315 const vk::PlatformInterface& vkp (context.getPlatformInterface());
3316 const vk::Unique<vk::VkInstance> instance (createInstance(vkp, 0u, externalType, 0u));
3317 const vk::InstanceDriver vki (vkp, *instance);
3318 const vk::VkPhysicalDevice physicalDevice (vk::chooseDevice(vki, *instance, context.getTestContext().getCommandLine()));
3319 const vk::VkPhysicalDeviceFeatures deviceFeatures (vk::getPhysicalDeviceFeatures(vki, physicalDevice));
3320 const deUint32 queueFamilyIndex (chooseQueueFamilyIndex(vki, physicalDevice, 0u));
3322 // VkDevice is only created if physical device claims to support any of these types.
3323 vk::Move<vk::VkDevice> device;
3324 de::MovePtr<vk::DeviceDriver> vkd;
3325 bool deviceHasDedicated = false;
3327 TestLog& log = context.getTestContext().getLog();
3329 for (size_t createFlagNdx = 0; createFlagNdx < DE_LENGTH_OF_ARRAY(createFlags); createFlagNdx++)
3330 for (size_t usageFlagNdx = 0; usageFlagNdx < DE_LENGTH_OF_ARRAY(usageFlags); usageFlagNdx++)
3332 const vk::VkImageViewCreateFlags createFlag = createFlags[createFlagNdx];
3333 const vk::VkImageUsageFlags usageFlag = usageFlags[usageFlagNdx];
3334 const vk::VkFormat format = vk::VK_FORMAT_R8G8B8A8_UNORM;
3335 const vk::VkImageType type = vk::VK_IMAGE_TYPE_2D;
3336 const vk::VkImageTiling tiling = vk::VK_IMAGE_TILING_OPTIMAL;
3337 const vk::VkPhysicalDeviceExternalImageFormatInfo externalInfo =
3339 vk::VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_IMAGE_FORMAT_INFO,
3343 const vk::VkPhysicalDeviceImageFormatInfo2 info =
3345 vk::VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2,
3354 vk::VkExternalImageFormatProperties externalProperties =
3356 vk::VK_STRUCTURE_TYPE_EXTERNAL_IMAGE_FORMAT_PROPERTIES,
3360 vk::VkImageFormatProperties2 properties =
3362 vk::VK_STRUCTURE_TYPE_IMAGE_FORMAT_PROPERTIES_2,
3363 &externalProperties,
3373 if (((createFlag & vk::VK_IMAGE_CREATE_SPARSE_BINDING_BIT) != 0) &&
3374 (deviceFeatures.sparseBinding == VK_FALSE))
3377 if (((createFlag & vk::VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT) != 0) &&
3378 (deviceFeatures.sparseResidencyImage2D == VK_FALSE))
3381 if (((createFlag & vk::VK_IMAGE_CREATE_SPARSE_ALIASED_BIT) != 0) &&
3382 (deviceFeatures.sparseResidencyAliased == VK_FALSE))
3385 vki.getPhysicalDeviceImageFormatProperties2(physicalDevice, &info, &properties);
3387 log << TestLog::Message << externalProperties << TestLog::EndMessage;
3388 TCU_CHECK(externalProperties.sType == vk::VK_STRUCTURE_TYPE_EXTERNAL_IMAGE_FORMAT_PROPERTIES);
3389 TCU_CHECK(externalProperties.pNext == DE_NULL);
3390 // \todo [2017-06-06 pyry] Can we validate anything else? Compatible types?
3392 if ((externalProperties.externalMemoryProperties.externalMemoryFeatures & (vk::VK_EXTERNAL_MEMORY_FEATURE_EXPORTABLE_BIT|vk::VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT)) != 0)
3394 const bool requiresDedicated = (externalProperties.externalMemoryProperties.externalMemoryFeatures & vk::VK_EXTERNAL_MEMORY_FEATURE_DEDICATED_ONLY_BIT) != 0;
3396 if (!device || (requiresDedicated && !deviceHasDedicated))
3398 // \note We need to re-create with dedicated mem extensions if previous device instance didn't have them
3401 device = createDevice(context.getUsedApiVersion(), vki, physicalDevice, 0u, externalType, 0u, queueFamilyIndex, requiresDedicated);
3402 vkd = de::MovePtr<vk::DeviceDriver>(new vk::DeviceDriver(vki, *device));
3403 deviceHasDedicated = requiresDedicated;
3405 catch (const tcu::NotSupportedError& e)
3408 TCU_FAIL("Physical device claims to support handle type but required extensions are not supported");
3413 if ((externalProperties.externalMemoryProperties.externalMemoryFeatures & vk::VK_EXTERNAL_MEMORY_FEATURE_EXPORTABLE_BIT) != 0)
3415 DE_ASSERT(!!device);
3418 if (deviceHasDedicated)
3420 const vk::Unique<vk::VkImage> image (createExternalImage(*vkd, *device, queueFamilyIndex, externalType, format, 16u, 16u, tiling, createFlag, usageFlag));
3421 const vk::VkMemoryDedicatedRequirements reqs (getMemoryDedicatedRequirements(*vkd, *device, *image));
3422 const bool propertiesRequiresDedicated = (externalProperties.externalMemoryProperties.externalMemoryFeatures & vk::VK_EXTERNAL_MEMORY_FEATURE_DEDICATED_ONLY_BIT) != 0;
3423 const bool objectRequiresDedicated = (reqs.requiresDedicatedAllocation != VK_FALSE);
3425 if (propertiesRequiresDedicated != objectRequiresDedicated)
3426 TCU_FAIL("vkGetPhysicalDeviceExternalBufferProperties and vkGetBufferMemoryRequirements2 report different dedicated requirements");
3430 // We can't query whether dedicated memory is required or not on per-object basis.
3431 // This check should be redundant as the code above tries to create device with
3432 // VK_KHR_dedicated_allocation & VK_KHR_get_memory_requirements2 if dedicated memory
3433 // is required. However, checking again doesn't hurt.
3434 TCU_CHECK((externalProperties.externalMemoryProperties.externalMemoryFeatures & vk::VK_EXTERNAL_MEMORY_FEATURE_DEDICATED_ONLY_BIT) == 0);
3439 return tcu::TestStatus::pass("Pass");
3442 struct ImageTestConfig
3444 ImageTestConfig (vk::VkExternalMemoryHandleTypeFlagBits externalType_,
3446 : externalType (externalType_)
3447 , dedicated (dedicated_)
3451 vk::VkExternalMemoryHandleTypeFlagBits externalType;
3455 tcu::TestStatus testImageBindExportImportBind (Context& context,
3456 const ImageTestConfig config)
3458 const vk::PlatformInterface& vkp (context.getPlatformInterface());
3459 const vk::Unique<vk::VkInstance> instance (createInstance(vkp, 0u, config.externalType, 0u));
3460 const vk::InstanceDriver vki (vkp, *instance);
3461 const vk::VkPhysicalDevice physicalDevice (vk::chooseDevice(vki, *instance, context.getTestContext().getCommandLine()));
3462 const deUint32 queueFamilyIndex (chooseQueueFamilyIndex(vki, physicalDevice, 0u));
3463 const vk::Unique<vk::VkDevice> device (createDevice(context.getUsedApiVersion(), vki, physicalDevice, 0u, config.externalType, 0u, queueFamilyIndex, config.dedicated));
3464 const vk::DeviceDriver vkd (vki, *device);
3465 const vk::VkImageUsageFlags usage = vk::VK_BUFFER_USAGE_TRANSFER_SRC_BIT|vk::VK_BUFFER_USAGE_TRANSFER_DST_BIT;
3466 const vk::VkFormat format = vk::VK_FORMAT_R8G8B8A8_UNORM;
3467 const deUint32 width = 64u;
3468 const deUint32 height = 64u;
3469 const vk::VkImageTiling tiling = vk::VK_IMAGE_TILING_OPTIMAL;
3471 checkImageSupport(vki, physicalDevice, config.externalType, 0u, usage, format, tiling, config.dedicated);
3473 deUint32 exportedMemoryTypeIndex = ~0U;
3474 const vk::Unique<vk::VkImage> imageA (createExternalImage(vkd, *device, queueFamilyIndex, config.externalType, format, width, height, tiling, 0u, usage));
3475 const vk::VkMemoryRequirements requirements (getImageMemoryRequirements(vkd, *device, *imageA));
3476 const vk::Unique<vk::VkDeviceMemory> memoryA (allocateExportableMemory(vkd, *device, requirements, config.externalType, config.dedicated ? *imageA : (vk::VkImage)0, exportedMemoryTypeIndex));
3477 NativeHandle handle;
3479 VK_CHECK(vkd.bindImageMemory(*device, *imageA, *memoryA, 0u));
3481 getMemoryNative(vkd, *device, *memoryA, config.externalType, handle);
3484 const vk::Unique<vk::VkImage> imageB (createExternalImage(vkd, *device, queueFamilyIndex, config.externalType, format, width, height, tiling, 0u, usage));
3485 const vk::Unique<vk::VkDeviceMemory> memoryB (config.dedicated
3486 ? importDedicatedMemory(vkd, *device, *imageB, requirements, config.externalType, exportedMemoryTypeIndex, handle)
3487 : importMemory(vkd, *device, requirements, config.externalType, exportedMemoryTypeIndex, handle));
3489 VK_CHECK(vkd.bindImageMemory(*device, *imageB, *memoryB, 0u));
3492 return tcu::TestStatus::pass("Pass");
3495 tcu::TestStatus testImageExportBindImportBind (Context& context,
3496 const ImageTestConfig config)
3498 const vk::PlatformInterface& vkp (context.getPlatformInterface());
3499 const vk::Unique<vk::VkInstance> instance (createInstance(vkp, 0u, config.externalType, 0u));
3500 const vk::InstanceDriver vki (vkp, *instance);
3501 const vk::VkPhysicalDevice physicalDevice (vk::chooseDevice(vki, *instance, context.getTestContext().getCommandLine()));
3502 const deUint32 queueFamilyIndex (chooseQueueFamilyIndex(vki, physicalDevice, 0u));
3503 const vk::Unique<vk::VkDevice> device (createDevice(context.getUsedApiVersion(), vki, physicalDevice, 0u, config.externalType, 0u, queueFamilyIndex, config.dedicated));
3504 const vk::DeviceDriver vkd (vki, *device);
3505 const vk::VkImageUsageFlags usage = vk::VK_BUFFER_USAGE_TRANSFER_SRC_BIT|vk::VK_BUFFER_USAGE_TRANSFER_DST_BIT;
3506 const vk::VkFormat format = vk::VK_FORMAT_R8G8B8A8_UNORM;
3507 const deUint32 width = 64u;
3508 const deUint32 height = 64u;
3509 const vk::VkImageTiling tiling = vk::VK_IMAGE_TILING_OPTIMAL;
3511 checkImageSupport(vki, physicalDevice, config.externalType, 0u, usage, format, tiling, config.dedicated);
3513 deUint32 exportedMemoryTypeIndex = ~0U;
3514 const vk::Unique<vk::VkImage> imageA (createExternalImage(vkd, *device, queueFamilyIndex, config.externalType, format, width, height, tiling, 0u, usage));
3515 const vk::VkMemoryRequirements requirements (getImageMemoryRequirements(vkd, *device, *imageA));
3516 const vk::Unique<vk::VkDeviceMemory> memoryA (allocateExportableMemory(vkd, *device, requirements, config.externalType, config.dedicated ? *imageA : (vk::VkImage)0, exportedMemoryTypeIndex));
3517 NativeHandle handle;
3519 getMemoryNative(vkd, *device, *memoryA, config.externalType, handle);
3520 VK_CHECK(vkd.bindImageMemory(*device, *imageA, *memoryA, 0u));
3523 const vk::Unique<vk::VkImage> imageB (createExternalImage(vkd, *device, queueFamilyIndex, config.externalType, format, width, height, tiling, 0u, usage));
3524 const vk::Unique<vk::VkDeviceMemory> memoryB (config.dedicated
3525 ? importDedicatedMemory(vkd, *device, *imageB, requirements, config.externalType, exportedMemoryTypeIndex, handle)
3526 : importMemory(vkd, *device, requirements, config.externalType, exportedMemoryTypeIndex, handle));
3528 VK_CHECK(vkd.bindImageMemory(*device, *imageB, *memoryB, 0u));
3531 return tcu::TestStatus::pass("Pass");
3534 tcu::TestStatus testImageExportImportBindBind (Context& context,
3535 const ImageTestConfig config)
3537 const vk::PlatformInterface& vkp (context.getPlatformInterface());
3538 const vk::Unique<vk::VkInstance> instance (createInstance(vkp, 0u, config.externalType, 0u));
3539 const vk::InstanceDriver vki (vkp, *instance);
3540 const vk::VkPhysicalDevice physicalDevice (vk::chooseDevice(vki, *instance, context.getTestContext().getCommandLine()));
3541 const deUint32 queueFamilyIndex (chooseQueueFamilyIndex(vki, physicalDevice, 0u));
3542 const vk::Unique<vk::VkDevice> device (createDevice(context.getUsedApiVersion(), vki, physicalDevice, 0u, config.externalType, 0u, queueFamilyIndex, config.dedicated));
3543 const vk::DeviceDriver vkd (vki, *device);
3544 const vk::VkImageUsageFlags usage = vk::VK_BUFFER_USAGE_TRANSFER_SRC_BIT|vk::VK_BUFFER_USAGE_TRANSFER_DST_BIT;
3545 const vk::VkFormat format = vk::VK_FORMAT_R8G8B8A8_UNORM;
3546 const deUint32 width = 64u;
3547 const deUint32 height = 64u;
3548 const vk::VkImageTiling tiling = vk::VK_IMAGE_TILING_OPTIMAL;
3550 checkImageSupport(vki, physicalDevice, config.externalType, 0u, usage, format, tiling, config.dedicated);
3552 deUint32 exportedMemoryTypeIndex = ~0U;
3553 // \note Image is only allocated to get memory requirements
3554 const vk::Unique<vk::VkImage> imageA (createExternalImage(vkd, *device, queueFamilyIndex, config.externalType, format, width, height, tiling, 0u, usage));
3555 const vk::VkMemoryRequirements requirements (getImageMemoryRequirements(vkd, *device, *imageA));
3556 const vk::Unique<vk::VkDeviceMemory> memoryA (allocateExportableMemory(vkd, *device, requirements, config.externalType, config.dedicated ? *imageA : (vk::VkImage)0, exportedMemoryTypeIndex));
3557 NativeHandle handle;
3559 getMemoryNative(vkd, *device, *memoryA, config.externalType, handle);
3562 const vk::Unique<vk::VkImage> imageB (createExternalImage(vkd, *device, queueFamilyIndex, config.externalType, format, width, height, tiling, 0u, usage));
3563 const vk::Unique<vk::VkDeviceMemory> memoryB (config.dedicated
3564 ? importDedicatedMemory(vkd, *device, *imageB, requirements, config.externalType, exportedMemoryTypeIndex, handle)
3565 : importMemory(vkd, *device, requirements, config.externalType, exportedMemoryTypeIndex, handle));
3567 VK_CHECK(vkd.bindImageMemory(*device, *imageA, *memoryA, 0u));
3568 VK_CHECK(vkd.bindImageMemory(*device, *imageB, *memoryB, 0u));
3571 return tcu::TestStatus::pass("Pass");
3573 de::MovePtr<tcu::TestCaseGroup> createFenceTests (tcu::TestContext& testCtx, vk::VkExternalFenceHandleTypeFlagBits externalType)
3577 const char* const name;
3578 const Permanence permanence;
3581 { "temporary", PERMANENCE_TEMPORARY },
3582 { "permanent", PERMANENCE_PERMANENT }
3585 de::MovePtr<tcu::TestCaseGroup> fenceGroup (new tcu::TestCaseGroup(testCtx, externalFenceTypeToName(externalType), externalFenceTypeToName(externalType)));
3587 addFunctionCase(fenceGroup.get(), "info", "Test external fence queries.", testFenceQueries, externalType);
3589 for (size_t permanenceNdx = 0; permanenceNdx < DE_LENGTH_OF_ARRAY(permanences); permanenceNdx++)
3591 const Permanence permanence (permanences[permanenceNdx].permanence);
3592 const char* const permanenceName (permanences[permanenceNdx].name);
3593 const FenceTestConfig config (externalType, permanence);
3595 if (!isSupportedPermanence(externalType, permanence))
3598 if (externalType == vk::VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_WIN32_BIT
3599 || externalType == vk::VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT)
3601 addFunctionCase(fenceGroup.get(), std::string("create_win32_") + permanenceName, "Test creating fence with win32 properties.", testFenceWin32Create, config);
3604 addFunctionCase(fenceGroup.get(), std::string("import_twice_") + permanenceName, "Test importing fence twice.", testFenceImportTwice, config);
3605 addFunctionCase(fenceGroup.get(), std::string("reimport_") + permanenceName, "Test importing again over previously imported fence.", testFenceImportReimport, config);
3606 addFunctionCase(fenceGroup.get(), std::string("import_multiple_times_") + permanenceName, "Test importing fence multiple times.", testFenceMultipleImports, config);
3607 addFunctionCase(fenceGroup.get(), std::string("signal_export_import_wait_") + permanenceName, "Test signaling, exporting, importing and waiting for the sempahore.", testFenceSignalExportImportWait, config);
3608 addFunctionCase(fenceGroup.get(), std::string("signal_import_") + permanenceName, "Test signaling and importing the fence.", testFenceSignalImport, config);
3609 addFunctionCase(fenceGroup.get(), std::string("reset_") + permanenceName, "Test resetting the fence.", testFenceReset, config);
3610 addFunctionCase(fenceGroup.get(), std::string("transference_") + permanenceName, "Test fences transference.", testFenceTransference, config);
3612 if (externalType == vk::VK_EXTERNAL_FENCE_HANDLE_TYPE_SYNC_FD_BIT
3613 || externalType == vk::VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_FD_BIT)
3615 // \note Not supported on WIN32 handles
3616 addFunctionCase(fenceGroup.get(), std::string("export_multiple_times_") + permanenceName, "Test exporting fence multiple times.", testFenceMultipleExports, config);
3618 addFunctionCase(fenceGroup.get(), std::string("dup_") + permanenceName, "Test calling dup() on exported fence.", testFenceFdDup, config);
3619 addFunctionCase(fenceGroup.get(), std::string("dup2_") + permanenceName, "Test calling dup2() on exported fence.", testFenceFdDup2, config);
3620 addFunctionCase(fenceGroup.get(), std::string("dup3_") + permanenceName, "Test calling dup3() on exported fence.", testFenceFdDup3, config);
3621 addFunctionCase(fenceGroup.get(), std::string("send_over_socket_") + permanenceName, "Test sending fence fd over socket.", testFenceFdSendOverSocket, config);
3624 if (getHandelTypeTransferences(externalType) == TRANSFERENCE_REFERENCE)
3626 addFunctionCase(fenceGroup.get(), std::string("signal_wait_import_") + permanenceName, "Test signaling and then waiting for the the sepmahore.", testFenceSignalWaitImport, config);
3627 addFunctionCase(fenceGroup.get(), std::string("export_signal_import_wait_") + permanenceName, "Test exporting, signaling, importing and waiting for the fence.", testFenceExportSignalImportWait, config);
3628 addFunctionCase(fenceGroup.get(), std::string("export_import_signal_wait_") + permanenceName, "Test exporting, importing, signaling and waiting for the fence.", testFenceExportImportSignalWait, config);
3635 de::MovePtr<tcu::TestCaseGroup> createFenceTests (tcu::TestContext& testCtx)
3637 de::MovePtr<tcu::TestCaseGroup> fenceGroup (new tcu::TestCaseGroup(testCtx, "fence", "Tests for external fences."));
3639 fenceGroup->addChild(createFenceTests(testCtx, vk::VK_EXTERNAL_FENCE_HANDLE_TYPE_SYNC_FD_BIT).release());
3640 fenceGroup->addChild(createFenceTests(testCtx, vk::VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_FD_BIT).release());
3641 fenceGroup->addChild(createFenceTests(testCtx, vk::VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_WIN32_BIT).release());
3642 fenceGroup->addChild(createFenceTests(testCtx, vk::VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT).release());
3647 de::MovePtr<tcu::TestCaseGroup> createSemaphoreTests (tcu::TestContext& testCtx, vk::VkExternalSemaphoreHandleTypeFlagBits externalType)
3651 const char* const name;
3652 const Permanence permanence;
3655 { "temporary", PERMANENCE_TEMPORARY },
3656 { "permanent", PERMANENCE_PERMANENT }
3659 de::MovePtr<tcu::TestCaseGroup> semaphoreGroup (new tcu::TestCaseGroup(testCtx, externalSemaphoreTypeToName(externalType), externalSemaphoreTypeToName(externalType)));
3661 addFunctionCase(semaphoreGroup.get(), "info", "Test external semaphore queries.", testSemaphoreQueries, externalType);
3663 for (size_t permanenceNdx = 0; permanenceNdx < DE_LENGTH_OF_ARRAY(permanences); permanenceNdx++)
3665 const Permanence permanence (permanences[permanenceNdx].permanence);
3666 const char* const permanenceName (permanences[permanenceNdx].name);
3667 const SemaphoreTestConfig config (externalType, permanence);
3669 if (!isSupportedPermanence(externalType, permanence))
3672 if (externalType == vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_BIT
3673 || externalType == vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT)
3675 addFunctionCase(semaphoreGroup.get(), std::string("create_win32_") + permanenceName, "Test creating semaphore with win32 properties.", testSemaphoreWin32Create, config);
3678 addFunctionCase(semaphoreGroup.get(), std::string("import_twice_") + permanenceName, "Test importing semaphore twice.", testSemaphoreImportTwice, config);
3679 addFunctionCase(semaphoreGroup.get(), std::string("reimport_") + permanenceName, "Test importing again over previously imported semaphore.", testSemaphoreImportReimport, config);
3680 addFunctionCase(semaphoreGroup.get(), std::string("import_multiple_times_") + permanenceName, "Test importing semaphore multiple times.", testSemaphoreMultipleImports, config);
3681 addFunctionCase(semaphoreGroup.get(), std::string("signal_export_import_wait_") + permanenceName, "Test signaling, exporting, importing and waiting for the sempahore.", testSemaphoreSignalExportImportWait, config);
3682 addFunctionCase(semaphoreGroup.get(), std::string("signal_import_") + permanenceName, "Test signaling and importing the semaphore.", testSemaphoreSignalImport, config);
3683 addFunctionCase(semaphoreGroup.get(), std::string("transference_") + permanenceName, "Test semaphores transference.", testSemaphoreTransference, config);
3685 if (externalType == vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT
3686 || externalType == vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT)
3688 // \note Not supported on WIN32 handles
3689 addFunctionCase(semaphoreGroup.get(), std::string("export_multiple_times_") + permanenceName, "Test exporting semaphore multiple times.", testSemaphoreMultipleExports, config);
3691 addFunctionCase(semaphoreGroup.get(), std::string("dup_") + permanenceName, "Test calling dup() on exported semaphore.", testSemaphoreFdDup, config);
3692 addFunctionCase(semaphoreGroup.get(), std::string("dup2_") + permanenceName, "Test calling dup2() on exported semaphore.", testSemaphoreFdDup2, config);
3693 addFunctionCase(semaphoreGroup.get(), std::string("dup3_") + permanenceName, "Test calling dup3() on exported semaphore.", testSemaphoreFdDup3, config);
3694 addFunctionCase(semaphoreGroup.get(), std::string("send_over_socket_") + permanenceName, "Test sending semaphore fd over socket.", testSemaphoreFdSendOverSocket, config);
3697 if (getHandelTypeTransferences(externalType) == TRANSFERENCE_REFERENCE)
3699 addFunctionCase(semaphoreGroup.get(), std::string("signal_wait_import_") + permanenceName, "Test signaling and then waiting for the the sepmahore.", testSemaphoreSignalWaitImport, config);
3700 addFunctionCase(semaphoreGroup.get(), std::string("export_signal_import_wait_") + permanenceName, "Test exporting, signaling, importing and waiting for the semaphore.", testSemaphoreExportSignalImportWait, config);
3701 addFunctionCase(semaphoreGroup.get(), std::string("export_import_signal_wait_") + permanenceName, "Test exporting, importing, signaling and waiting for the semaphore.", testSemaphoreExportImportSignalWait, config);
3705 return semaphoreGroup;
3708 de::MovePtr<tcu::TestCaseGroup> createSemaphoreTests (tcu::TestContext& testCtx)
3710 de::MovePtr<tcu::TestCaseGroup> semaphoreGroup (new tcu::TestCaseGroup(testCtx, "semaphore", "Tests for external semaphores."));
3712 semaphoreGroup->addChild(createSemaphoreTests(testCtx, vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT).release());
3713 semaphoreGroup->addChild(createSemaphoreTests(testCtx, vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT).release());
3714 semaphoreGroup->addChild(createSemaphoreTests(testCtx, vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_BIT).release());
3715 semaphoreGroup->addChild(createSemaphoreTests(testCtx, vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT).release());
3717 return semaphoreGroup;
3720 de::MovePtr<tcu::TestCaseGroup> createMemoryTests (tcu::TestContext& testCtx, vk::VkExternalMemoryHandleTypeFlagBits externalType)
3722 de::MovePtr<tcu::TestCaseGroup> group (new tcu::TestCaseGroup(testCtx, externalMemoryTypeToName(externalType), "Tests for external memory"));
3724 for (size_t dedicatedNdx = 0; dedicatedNdx < 2; dedicatedNdx++)
3726 const bool dedicated (dedicatedNdx == 1);
3727 de::MovePtr<tcu::TestCaseGroup> dedicatedGroup (new tcu::TestCaseGroup(testCtx, dedicated ? "dedicated" : "suballocated", ""));
3729 for (size_t hostVisibleNdx = 0; hostVisibleNdx < 2; hostVisibleNdx++)
3731 const bool hostVisible (hostVisibleNdx == 1);
3732 de::MovePtr<tcu::TestCaseGroup> hostVisibleGroup (new tcu::TestCaseGroup(testCtx, hostVisible ? "host_visible" : "device_only", ""));
3733 const MemoryTestConfig memoryConfig (externalType, hostVisible, dedicated);
3735 if (externalType == vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT
3736 || externalType == vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT)
3738 addFunctionCase(hostVisibleGroup.get(), "create_win32", "Test creating memory with win32 properties .", testMemoryWin32Create, memoryConfig);
3741 addFunctionCase(hostVisibleGroup.get(), "import_twice", "Test importing memory object twice.", testMemoryImportTwice, memoryConfig);
3742 addFunctionCase(hostVisibleGroup.get(), "import_multiple_times", "Test importing memory object multiple times.", testMemoryMultimpleImports, memoryConfig);
3744 if (externalType == vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT)
3746 addFunctionCase(hostVisibleGroup.get(), "dup", "Test calling dup() on exported memory.", testMemoryFdDup, memoryConfig);
3747 addFunctionCase(hostVisibleGroup.get(), "dup2", "Test calling dup2() on exported memory.", testMemoryFdDup2, memoryConfig);
3748 addFunctionCase(hostVisibleGroup.get(), "dup3", "Test calling dup3() on exported memory.", testMemoryFdDup3, memoryConfig);
3749 addFunctionCase(hostVisibleGroup.get(), "send_over_socket", "Test sending memory fd over socket.", testMemoryFdSendOverSocket, memoryConfig);
3750 // \note Not supported on WIN32 handles
3751 addFunctionCase(hostVisibleGroup.get(), "export_multiple_times", "Test exporting memory multiple times.", testMemoryMultimpleExports, memoryConfig);
3754 dedicatedGroup->addChild(hostVisibleGroup.release());
3758 de::MovePtr<tcu::TestCaseGroup> bufferGroup (new tcu::TestCaseGroup(testCtx, "buffer", ""));
3759 const BufferTestConfig bufferConfig (externalType, dedicated);
3761 addFunctionCase(bufferGroup.get(), "info", "External buffer memory info query.", testBufferQueries, externalType);
3762 addFunctionCase(bufferGroup.get(), "bind_export_import_bind", "Test binding, exporting, importing and binding buffer.", testBufferBindExportImportBind, bufferConfig);
3763 addFunctionCase(bufferGroup.get(), "export_bind_import_bind", "Test exporting, binding, importing and binding buffer.", testBufferExportBindImportBind, bufferConfig);
3764 addFunctionCase(bufferGroup.get(), "export_import_bind_bind", "Test exporting, importind and binding buffer.", testBufferExportImportBindBind, bufferConfig);
3766 dedicatedGroup->addChild(bufferGroup.release());
3770 de::MovePtr<tcu::TestCaseGroup> imageGroup (new tcu::TestCaseGroup(testCtx, "image", ""));
3771 const ImageTestConfig imageConfig (externalType, dedicated);
3773 addFunctionCase(imageGroup.get(), "info", "External image memory info query.", testImageQueries, externalType);
3774 addFunctionCase(imageGroup.get(), "bind_export_import_bind", "Test binding, exporting, importing and binding image.", testImageBindExportImportBind, imageConfig);
3775 addFunctionCase(imageGroup.get(), "export_bind_import_bind", "Test exporting, binding, importing and binding image.", testImageExportBindImportBind, imageConfig);
3776 addFunctionCase(imageGroup.get(), "export_import_bind_bind", "Test exporting, importind and binding image.", testImageExportImportBindBind, imageConfig);
3778 dedicatedGroup->addChild(imageGroup.release());
3781 group->addChild(dedicatedGroup.release());
3787 de::MovePtr<tcu::TestCaseGroup> createMemoryTests (tcu::TestContext& testCtx)
3789 de::MovePtr<tcu::TestCaseGroup> group (new tcu::TestCaseGroup(testCtx, "memory", "Tests for external memory"));
3791 group->addChild(createMemoryTests(testCtx, vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT).release());
3792 group->addChild(createMemoryTests(testCtx, vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT).release());
3793 group->addChild(createMemoryTests(testCtx, vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT).release());
3800 tcu::TestCaseGroup* createExternalMemoryTests (tcu::TestContext& testCtx)
3802 de::MovePtr<tcu::TestCaseGroup> group (new tcu::TestCaseGroup(testCtx, "external", "Tests for external Vulkan objects"));
3804 group->addChild(createSemaphoreTests(testCtx).release());
3805 group->addChild(createMemoryTests(testCtx).release());
3806 group->addChild(createFenceTests(testCtx).release());
3808 return group.release();