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"
31 #include "tcuTestLog.hpp"
33 #include "deUniquePtr.hpp"
34 #include "deStringUtil.hpp"
35 #include "deRandom.hpp"
39 #include "vktExternalMemoryUtil.hpp"
41 #if (DE_OS == DE_OS_ANDROID) || (DE_OS == DE_OS_UNIX)
45 # include <sys/types.h>
46 # include <sys/socket.h>
49 #if (DE_OS == DE_OS_WIN32)
50 # define WIN32_LEAN_AND_MEAN
56 using namespace vkt::ExternalMemoryUtil;
65 vk::VkMemoryDedicatedRequirementsKHR getMemoryDedicatedRequirements (const vk::DeviceInterface& vkd,
69 const vk::VkBufferMemoryRequirementsInfo2KHR requirementInfo =
71 vk::VK_STRUCTURE_TYPE_BUFFER_MEMORY_REQUIREMENTS_INFO_2_KHR,
75 vk::VkMemoryDedicatedRequirementsKHR dedicatedRequirements =
77 vk::VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS_KHR,
82 vk::VkMemoryRequirements2KHR requirements =
84 vk::VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2_KHR,
85 &dedicatedRequirements,
89 vkd.getBufferMemoryRequirements2KHR(device, &requirementInfo, &requirements);
91 return dedicatedRequirements;
94 vk::VkMemoryDedicatedRequirementsKHR getMemoryDedicatedRequirements (const vk::DeviceInterface& vkd,
98 const vk::VkImageMemoryRequirementsInfo2KHR requirementInfo =
100 vk::VK_STRUCTURE_TYPE_IMAGE_MEMORY_REQUIREMENTS_INFO_2_KHR,
104 vk::VkMemoryDedicatedRequirementsKHR dedicatedRequirements =
106 vk::VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS_KHR,
111 vk::VkMemoryRequirements2KHR requirements =
113 vk::VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2_KHR,
114 &dedicatedRequirements,
118 vkd.getImageMemoryRequirements2KHR(device, &requirementInfo, &requirements);
120 return dedicatedRequirements;
123 void writeHostMemory (const vk::DeviceInterface& vkd,
125 vk::VkDeviceMemory memory,
129 void* const ptr = vk::mapMemory(vkd, device, memory, 0, size, 0);
131 deMemcpy(ptr, data, size);
133 vkd.unmapMemory(device, memory);
136 void checkHostMemory (const vk::DeviceInterface& vkd,
138 vk::VkDeviceMemory memory,
142 void* const ptr = vk::mapMemory(vkd, device, memory, 0, size, 0);
144 if (deMemCmp(ptr, data, size) != 0)
145 TCU_FAIL("Memory contents don't match");
147 vkd.unmapMemory(device, memory);
150 std::vector<deUint8> genTestData (deUint32 seed, size_t size)
152 de::Random rng (seed);
153 std::vector<deUint8> data (size);
155 for (size_t ndx = 0; ndx < size; ndx++)
157 data[ndx] = rng.getUint8();
163 deUint32 chooseQueueFamilyIndex (const vk::InstanceInterface& vki,
164 vk::VkPhysicalDevice device,
165 vk::VkQueueFlags requireFlags)
167 const std::vector<vk::VkQueueFamilyProperties> properties (vk::getPhysicalDeviceQueueFamilyProperties(vki, device));
169 for (deUint32 queueFamilyIndex = 0; queueFamilyIndex < (deUint32)properties.size(); queueFamilyIndex++)
171 if ((properties[queueFamilyIndex].queueFlags & requireFlags) == requireFlags)
172 return queueFamilyIndex;
175 TCU_THROW(NotSupportedError, "Queue type not supported");
178 vk::Move<vk::VkInstance> createInstance (const vk::PlatformInterface& vkp,
179 const vk::VkExternalSemaphoreHandleTypeFlagsKHR externalSemaphoreTypes,
180 const vk::VkExternalMemoryHandleTypeFlagsKHR externalMemoryTypes,
181 const vk::VkExternalFenceHandleTypeFlagsKHR externalFenceTypes)
183 std::vector<std::string> instanceExtensions;
185 instanceExtensions.push_back("VK_KHR_get_physical_device_properties2");
187 if (externalSemaphoreTypes != 0)
188 instanceExtensions.push_back("VK_KHR_external_semaphore_capabilities");
190 if (externalMemoryTypes != 0)
191 instanceExtensions.push_back("VK_KHR_external_memory_capabilities");
193 if (externalFenceTypes != 0)
194 instanceExtensions.push_back("VK_KHR_external_fence_capabilities");
198 return vk::createDefaultInstance(vkp, std::vector<std::string>(), instanceExtensions);
200 catch (const vk::Error& error)
202 if (error.getError() == vk::VK_ERROR_EXTENSION_NOT_PRESENT)
203 TCU_THROW(NotSupportedError, "Required extensions not supported");
209 vk::Move<vk::VkDevice> createDevice (const vk::InstanceInterface& vki,
210 vk::VkPhysicalDevice physicalDevice,
211 const vk::VkExternalSemaphoreHandleTypeFlagsKHR externalSemaphoreTypes,
212 const vk::VkExternalMemoryHandleTypeFlagsKHR externalMemoryTypes,
213 const vk::VkExternalFenceHandleTypeFlagsKHR externalFenceTypes,
214 deUint32 queueFamilyIndex,
215 bool useDedicatedAllocs = false)
217 std::vector<const char*> deviceExtensions;
219 if ((externalSemaphoreTypes
220 & (vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT_KHR
221 | vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT_KHR)) != 0)
223 deviceExtensions.push_back("VK_KHR_external_semaphore_fd");
226 if ((externalFenceTypes
227 & (vk::VK_EXTERNAL_FENCE_HANDLE_TYPE_SYNC_FD_BIT_KHR
228 | vk::VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_FD_BIT_KHR)) != 0)
230 deviceExtensions.push_back("VK_KHR_external_fence_fd");
233 if (useDedicatedAllocs)
235 deviceExtensions.push_back("VK_KHR_dedicated_allocation");
236 deviceExtensions.push_back("VK_KHR_get_memory_requirements2");
239 if ((externalMemoryTypes
240 & vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT_KHR) != 0)
242 deviceExtensions.push_back("VK_KHR_external_memory_fd");
245 if ((externalSemaphoreTypes
246 & (vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_BIT_KHR
247 | vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT_KHR)) != 0)
249 deviceExtensions.push_back("VK_KHR_external_semaphore_win32");
252 if ((externalFenceTypes
253 & (vk::VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_WIN32_BIT_KHR
254 | vk::VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT_KHR)) != 0)
256 deviceExtensions.push_back("VK_KHR_external_fence_win32");
259 if ((externalMemoryTypes
260 & (vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT_KHR
261 | vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT_KHR
262 | vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D11_TEXTURE_BIT_KHR
263 | vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D11_TEXTURE_KMT_BIT_KHR
264 | vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D12_HEAP_BIT_KHR
265 | vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D12_RESOURCE_BIT_KHR)) != 0)
267 deviceExtensions.push_back("VK_KHR_external_memory_win32");
270 const float priority = 0.5f;
271 const vk::VkDeviceQueueCreateInfo queues[] =
274 vk::VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO,
283 const vk::VkDeviceCreateInfo deviceCreateInfo =
285 vk::VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,
289 DE_LENGTH_OF_ARRAY(queues),
295 (deUint32)deviceExtensions.size(),
296 deviceExtensions.empty() ? DE_NULL : &deviceExtensions[0],
302 return vk::createDevice(vki, physicalDevice, &deviceCreateInfo);
304 catch (const vk::Error& error)
306 if (error.getError() == vk::VK_ERROR_EXTENSION_NOT_PRESENT)
307 TCU_THROW(NotSupportedError, "Required extensions not supported");
313 vk::VkQueue getQueue (const vk::DeviceInterface& vkd,
315 deUint32 queueFamilyIndex)
319 vkd.getDeviceQueue(device, queueFamilyIndex, 0, &queue);
324 void checkSemaphoreSupport (const vk::InstanceInterface& vki,
325 vk::VkPhysicalDevice device,
326 vk::VkExternalSemaphoreHandleTypeFlagBitsKHR externalType)
328 const vk::VkPhysicalDeviceExternalSemaphoreInfoKHR info =
330 vk::VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_SEMAPHORE_INFO_KHR,
334 vk::VkExternalSemaphorePropertiesKHR properties =
336 vk::VK_STRUCTURE_TYPE_EXTERNAL_SEMAPHORE_PROPERTIES_KHR,
343 vki.getPhysicalDeviceExternalSemaphorePropertiesKHR(device, &info, &properties);
345 if ((properties.externalSemaphoreFeatures & vk::VK_EXTERNAL_SEMAPHORE_FEATURE_EXPORTABLE_BIT_KHR) == 0)
346 TCU_THROW(NotSupportedError, "Semaphore doesn't support exporting in external type");
348 if ((properties.externalSemaphoreFeatures & vk::VK_EXTERNAL_SEMAPHORE_FEATURE_IMPORTABLE_BIT_KHR) == 0)
349 TCU_THROW(NotSupportedError, "Semaphore doesn't support importing in external type");
352 void checkFenceSupport (const vk::InstanceInterface& vki,
353 vk::VkPhysicalDevice device,
354 vk::VkExternalFenceHandleTypeFlagBitsKHR externalType)
356 const vk::VkPhysicalDeviceExternalFenceInfoKHR info =
358 vk::VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_FENCE_INFO_KHR,
362 vk::VkExternalFencePropertiesKHR properties =
364 vk::VK_STRUCTURE_TYPE_EXTERNAL_FENCE_PROPERTIES_KHR,
371 vki.getPhysicalDeviceExternalFencePropertiesKHR(device, &info, &properties);
373 if ((properties.externalFenceFeatures & vk::VK_EXTERNAL_FENCE_FEATURE_EXPORTABLE_BIT_KHR) == 0)
374 TCU_THROW(NotSupportedError, "Fence doesn't support exporting in external type");
376 if ((properties.externalFenceFeatures & vk::VK_EXTERNAL_FENCE_FEATURE_IMPORTABLE_BIT_KHR) == 0)
377 TCU_THROW(NotSupportedError, "Fence doesn't support importing in external type");
380 void checkBufferSupport (const vk::InstanceInterface& vki,
381 vk::VkPhysicalDevice device,
382 vk::VkExternalMemoryHandleTypeFlagBitsKHR externalType,
383 vk::VkBufferViewCreateFlags createFlag,
384 vk::VkBufferUsageFlags usageFlag,
387 const vk::VkPhysicalDeviceExternalBufferInfoKHR info =
389 vk::VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_BUFFER_INFO_KHR,
396 vk::VkExternalBufferPropertiesKHR properties =
398 vk::VK_STRUCTURE_TYPE_EXTERNAL_BUFFER_PROPERTIES_KHR,
404 vki.getPhysicalDeviceExternalBufferPropertiesKHR(device, &info, &properties);
406 if ((properties.externalMemoryProperties.externalMemoryFeatures & vk::VK_EXTERNAL_MEMORY_FEATURE_EXPORTABLE_BIT_KHR) == 0)
407 TCU_THROW(NotSupportedError, "External handle type doesn't support exporting buffer");
409 if ((properties.externalMemoryProperties.externalMemoryFeatures & vk::VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT_KHR) == 0)
410 TCU_THROW(NotSupportedError, "External handle type doesn't support importing buffer");
412 if (!dedicated && (properties.externalMemoryProperties.externalMemoryFeatures & vk::VK_EXTERNAL_MEMORY_FEATURE_DEDICATED_ONLY_BIT_KHR) != 0)
413 TCU_THROW(NotSupportedError, "External handle type requires dedicated allocation");
416 void checkImageSupport (const vk::InstanceInterface& vki,
417 vk::VkPhysicalDevice device,
418 vk::VkExternalMemoryHandleTypeFlagBitsKHR externalType,
419 vk::VkImageViewCreateFlags createFlag,
420 vk::VkImageUsageFlags usageFlag,
422 vk::VkImageTiling tiling,
425 const vk::VkPhysicalDeviceExternalImageFormatInfoKHR externalInfo =
427 vk::VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_IMAGE_FORMAT_INFO_KHR,
431 const vk::VkPhysicalDeviceImageFormatInfo2KHR info =
433 vk::VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2_KHR,
437 vk::VK_IMAGE_TYPE_2D,
442 vk::VkExternalImageFormatPropertiesKHR externalProperties =
444 vk::VK_STRUCTURE_TYPE_EXTERNAL_IMAGE_FORMAT_PROPERTIES_KHR,
448 vk::VkImageFormatProperties2KHR properties =
450 vk::VK_STRUCTURE_TYPE_IMAGE_FORMAT_PROPERTIES_2_KHR,
461 vki.getPhysicalDeviceImageFormatProperties2KHR(device, &info, &properties);
463 if ((externalProperties.externalMemoryProperties.externalMemoryFeatures & vk::VK_EXTERNAL_MEMORY_FEATURE_EXPORTABLE_BIT_KHR) == 0)
464 TCU_THROW(NotSupportedError, "External handle type doesn't support exporting image");
466 if ((externalProperties.externalMemoryProperties.externalMemoryFeatures & vk::VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT_KHR) == 0)
467 TCU_THROW(NotSupportedError, "External handle type doesn't support importing image");
469 if (!dedicated && (externalProperties.externalMemoryProperties.externalMemoryFeatures & vk::VK_EXTERNAL_MEMORY_FEATURE_DEDICATED_ONLY_BIT_KHR) != 0)
470 TCU_THROW(NotSupportedError, "External handle type requires dedicated allocation");
473 void submitDummySignal (const vk::DeviceInterface& vkd,
475 vk::VkSemaphore semaphore)
477 const vk::VkSubmitInfo submit =
479 vk::VK_STRUCTURE_TYPE_SUBMIT_INFO,
493 VK_CHECK(vkd.queueSubmit(queue, 1, &submit, (vk::VkFence)0u));
496 void submitDummyWait (const vk::DeviceInterface& vkd,
498 vk::VkSemaphore semaphore)
500 const vk::VkPipelineStageFlags stage = vk::VK_PIPELINE_STAGE_ALL_COMMANDS_BIT;
501 const vk::VkSubmitInfo submit =
503 vk::VK_STRUCTURE_TYPE_SUBMIT_INFO,
517 VK_CHECK(vkd.queueSubmit(queue, 1, &submit, (vk::VkFence)0u));
520 void submitDummySignal (const vk::DeviceInterface& vkd,
524 const vk::VkSubmitInfo submit =
526 vk::VK_STRUCTURE_TYPE_SUBMIT_INFO,
540 VK_CHECK(vkd.queueSubmit(queue, 1, &submit, fence));
543 tcu::TestStatus testSemaphoreQueries (Context& context, vk::VkExternalSemaphoreHandleTypeFlagBitsKHR externalType)
545 const vk::PlatformInterface& vkp (context.getPlatformInterface());
546 const vk::Unique<vk::VkInstance> instance (createInstance(vkp, externalType, 0u, 0u));
547 const vk::InstanceDriver vki (vkp, *instance);
548 const vk::VkPhysicalDevice device (vk::chooseDevice(vki, *instance, context.getTestContext().getCommandLine()));
550 TestLog& log = context.getTestContext().getLog();
552 const vk::VkPhysicalDeviceExternalSemaphoreInfoKHR info =
554 vk::VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_SEMAPHORE_INFO_KHR,
558 vk::VkExternalSemaphorePropertiesKHR properties =
560 vk::VK_STRUCTURE_TYPE_EXTERNAL_SEMAPHORE_PROPERTIES_KHR,
567 vki.getPhysicalDeviceExternalSemaphorePropertiesKHR(device, &info, &properties);
568 log << TestLog::Message << properties << TestLog::EndMessage;
570 TCU_CHECK(properties.pNext == DE_NULL);
571 TCU_CHECK(properties.sType == vk::VK_STRUCTURE_TYPE_EXTERNAL_SEMAPHORE_PROPERTIES_KHR);
573 return tcu::TestStatus::pass("Pass");
576 struct SemaphoreTestConfig
578 SemaphoreTestConfig (vk::VkExternalSemaphoreHandleTypeFlagBitsKHR externalType_,
579 Permanence permanence_)
580 : externalType (externalType_)
581 , permanence (permanence_)
585 vk::VkExternalSemaphoreHandleTypeFlagBitsKHR externalType;
586 Permanence permanence;
589 tcu::TestStatus testSemaphoreWin32Create (Context& context,
590 const SemaphoreTestConfig config)
592 #if (DE_OS == DE_OS_WIN32)
593 const Transference transference (getHandelTypeTransferences(config.externalType));
594 const vk::PlatformInterface& vkp (context.getPlatformInterface());
595 const vk::Unique<vk::VkInstance> instance (createInstance(vkp, config.externalType, 0u, 0u));
596 const vk::InstanceDriver vki (vkp, *instance);
597 const vk::VkPhysicalDevice physicalDevice (vk::chooseDevice(vki, *instance, context.getTestContext().getCommandLine()));
598 const deUint32 queueFamilyIndex (chooseQueueFamilyIndex(vki, physicalDevice, 0u));
600 checkSemaphoreSupport(vki, physicalDevice, config.externalType);
603 const vk::Unique<vk::VkDevice> device (createDevice(vki, physicalDevice, config.externalType, 0u, 0u, queueFamilyIndex));
604 const vk::DeviceDriver vkd (vki, *device);
605 const vk::VkQueue queue (getQueue(vkd, *device, queueFamilyIndex));
606 const vk::VkExportSemaphoreWin32HandleInfoKHR win32ExportInfo =
608 vk::VK_STRUCTURE_TYPE_EXPORT_SEMAPHORE_WIN32_HANDLE_INFO_KHR,
611 (vk::pt::Win32SecurityAttributesPtr)DE_NULL,
612 DXGI_SHARED_RESOURCE_READ | DXGI_SHARED_RESOURCE_WRITE,
615 const vk::VkExportSemaphoreCreateInfoKHR exportCreateInfo=
617 vk::VK_STRUCTURE_TYPE_EXPORT_SEMAPHORE_CREATE_INFO_KHR,
619 (vk::VkExternalMemoryHandleTypeFlagsKHR)config.externalType
621 const vk::VkSemaphoreCreateInfo createInfo =
623 vk::VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO,
627 const vk::Unique<vk::VkSemaphore> semaphore (vk::createSemaphore(vkd, *device, &createInfo));
629 if (transference == TRANSFERENCE_COPY)
630 submitDummySignal(vkd, queue, *semaphore);
632 NativeHandle handleA;
633 getSemaphoreNative(vkd, *device, *semaphore, config.externalType, handleA);
636 const vk::VkSemaphoreImportFlagsKHR flags = config.permanence == PERMANENCE_TEMPORARY ? vk::VK_SEMAPHORE_IMPORT_TEMPORARY_BIT_KHR : (vk::VkSemaphoreImportFlagBitsKHR)0u;
637 const vk::Unique<vk::VkSemaphore> semaphoreA (createAndImportSemaphore(vkd, *device, config.externalType, handleA, flags));
639 if (transference == TRANSFERENCE_COPY)
640 submitDummyWait(vkd, queue, *semaphoreA);
641 else if (transference == TRANSFERENCE_REFERENCE)
643 submitDummySignal(vkd, queue, *semaphore);
644 submitDummyWait(vkd, queue, *semaphoreA);
647 DE_FATAL("Unknown transference.");
649 VK_CHECK(vkd.queueWaitIdle(queue));
652 return tcu::TestStatus::pass("Pass");
657 TCU_THROW(NotSupportedError, "Platform doesn't support win32 handles");
661 tcu::TestStatus testSemaphoreImportTwice (Context& context,
662 const SemaphoreTestConfig config)
664 const Transference transference (getHandelTypeTransferences(config.externalType));
665 const vk::PlatformInterface& vkp (context.getPlatformInterface());
666 const vk::Unique<vk::VkInstance> instance (createInstance(vkp, config.externalType, 0u, 0u));
667 const vk::InstanceDriver vki (vkp, *instance);
668 const vk::VkPhysicalDevice physicalDevice (vk::chooseDevice(vki, *instance, context.getTestContext().getCommandLine()));
669 const deUint32 queueFamilyIndex (chooseQueueFamilyIndex(vki, physicalDevice, 0u));
671 checkSemaphoreSupport(vki, physicalDevice, config.externalType);
674 const vk::Unique<vk::VkDevice> device (createDevice(vki, physicalDevice, config.externalType, 0u, 0u, queueFamilyIndex));
675 const vk::DeviceDriver vkd (vki, *device);
676 const vk::VkQueue queue (getQueue(vkd, *device, queueFamilyIndex));
677 const vk::Unique<vk::VkSemaphore> semaphore (createExportableSemaphore(vkd, *device, config.externalType));
679 if (transference == TRANSFERENCE_COPY)
680 submitDummySignal(vkd, queue, *semaphore);
682 NativeHandle handleA;
683 getSemaphoreNative(vkd, *device, *semaphore, config.externalType, handleA);
686 NativeHandle handleB (handleA);
687 const vk::VkSemaphoreImportFlagsKHR flags = config.permanence == PERMANENCE_TEMPORARY ? vk::VK_SEMAPHORE_IMPORT_TEMPORARY_BIT_KHR : (vk::VkSemaphoreImportFlagBitsKHR)0u;
688 const vk::Unique<vk::VkSemaphore> semaphoreA (createAndImportSemaphore(vkd, *device, config.externalType, handleA, flags));
689 const vk::Unique<vk::VkSemaphore> semaphoreB (createAndImportSemaphore(vkd, *device, config.externalType, handleB, flags));
691 if (transference == TRANSFERENCE_COPY)
692 submitDummyWait(vkd, queue, *semaphoreA);
693 else if (transference == TRANSFERENCE_REFERENCE)
695 submitDummySignal(vkd, queue, *semaphoreA);
696 submitDummyWait(vkd, queue, *semaphoreB);
699 DE_FATAL("Unknown transference.");
701 VK_CHECK(vkd.queueWaitIdle(queue));
704 return tcu::TestStatus::pass("Pass");
708 tcu::TestStatus testSemaphoreImportReimport (Context& context,
709 const SemaphoreTestConfig config)
711 const Transference transference (getHandelTypeTransferences(config.externalType));
712 const vk::PlatformInterface& vkp (context.getPlatformInterface());
713 const vk::Unique<vk::VkInstance> instance (createInstance(vkp, config.externalType, 0u, 0u));
714 const vk::InstanceDriver vki (vkp, *instance);
715 const vk::VkPhysicalDevice physicalDevice (vk::chooseDevice(vki, *instance, context.getTestContext().getCommandLine()));
716 const deUint32 queueFamilyIndex (chooseQueueFamilyIndex(vki, physicalDevice, 0u));
718 checkSemaphoreSupport(vki, physicalDevice, config.externalType);
721 const vk::Unique<vk::VkDevice> device (createDevice(vki, physicalDevice, config.externalType, 0u, 0u, queueFamilyIndex));
722 const vk::DeviceDriver vkd (vki, *device);
723 const vk::VkQueue queue (getQueue(vkd, *device, queueFamilyIndex));
725 const vk::Unique<vk::VkSemaphore> semaphoreA (createExportableSemaphore(vkd, *device, config.externalType));
727 if (transference == TRANSFERENCE_COPY)
728 submitDummySignal(vkd, queue, *semaphoreA);
730 NativeHandle handleA;
731 getSemaphoreNative(vkd, *device, *semaphoreA, config.externalType, handleA);
733 NativeHandle handleB (handleA);
734 const vk::VkSemaphoreImportFlagsKHR flags = config.permanence == PERMANENCE_TEMPORARY ? vk::VK_SEMAPHORE_IMPORT_TEMPORARY_BIT_KHR : (vk::VkSemaphoreImportFlagBitsKHR)0u;
735 const vk::Unique<vk::VkSemaphore> semaphoreB (createAndImportSemaphore(vkd, *device, config.externalType, handleA, flags));
737 importSemaphore(vkd, *device, *semaphoreB, config.externalType, handleB, flags);
739 if (transference == TRANSFERENCE_COPY)
740 submitDummyWait(vkd, queue, *semaphoreB);
741 else if (transference == TRANSFERENCE_REFERENCE)
743 submitDummySignal(vkd, queue, *semaphoreA);
744 submitDummyWait(vkd, queue, *semaphoreB);
747 DE_FATAL("Unknown transference.");
749 VK_CHECK(vkd.queueWaitIdle(queue));
751 return tcu::TestStatus::pass("Pass");
755 tcu::TestStatus testSemaphoreSignalExportImportWait (Context& context,
756 const SemaphoreTestConfig config)
758 const vk::PlatformInterface& vkp (context.getPlatformInterface());
759 const vk::Unique<vk::VkInstance> instance (createInstance(vkp, config.externalType, 0u, 0u));
760 const vk::InstanceDriver vki (vkp, *instance);
761 const vk::VkPhysicalDevice physicalDevice (vk::chooseDevice(vki, *instance, context.getTestContext().getCommandLine()));
762 const deUint32 queueFamilyIndex (chooseQueueFamilyIndex(vki, physicalDevice, 0u));
764 checkSemaphoreSupport(vki, physicalDevice, config.externalType);
767 const vk::Unique<vk::VkDevice> device (createDevice(vki, physicalDevice, config.externalType, 0u, 0u, queueFamilyIndex));
768 const vk::DeviceDriver vkd (vki, *device);
769 const vk::VkQueue queue (getQueue(vkd, *device, queueFamilyIndex));
770 const vk::Unique<vk::VkSemaphore> semaphoreA (createExportableSemaphore(vkd, *device, config.externalType));
772 submitDummySignal(vkd, queue, *semaphoreA);
777 getSemaphoreNative(vkd, *device, *semaphoreA, config.externalType, handle);
780 const vk::VkSemaphoreImportFlagsKHR flags = config.permanence == PERMANENCE_TEMPORARY ? vk::VK_SEMAPHORE_IMPORT_TEMPORARY_BIT_KHR : (vk::VkSemaphoreImportFlagBitsKHR)0u;
781 const vk::Unique<vk::VkSemaphore> semaphoreB (createAndImportSemaphore(vkd, *device, config.externalType, handle, flags));
782 submitDummyWait(vkd, queue, *semaphoreB);
784 VK_CHECK(vkd.queueWaitIdle(queue));
788 return tcu::TestStatus::pass("Pass");
792 tcu::TestStatus testSemaphoreExportSignalImportWait (Context& context,
793 const SemaphoreTestConfig config)
795 const vk::PlatformInterface& vkp (context.getPlatformInterface());
796 const vk::Unique<vk::VkInstance> instance (createInstance(vkp, config.externalType, 0u, 0u));
797 const vk::InstanceDriver vki (vkp, *instance);
798 const vk::VkPhysicalDevice physicalDevice (vk::chooseDevice(vki, *instance, context.getTestContext().getCommandLine()));
799 const deUint32 queueFamilyIndex (chooseQueueFamilyIndex(vki, physicalDevice, 0u));
800 const vk::VkSemaphoreImportFlagsKHR flags = config.permanence == PERMANENCE_TEMPORARY ? vk::VK_SEMAPHORE_IMPORT_TEMPORARY_BIT_KHR : (vk::VkSemaphoreImportFlagBitsKHR)0u;
802 DE_ASSERT(getHandelTypeTransferences(config.externalType) == TRANSFERENCE_REFERENCE);
803 checkSemaphoreSupport(vki, physicalDevice, config.externalType);
806 const vk::Unique<vk::VkDevice> device (createDevice(vki, physicalDevice, config.externalType, 0u, 0u, queueFamilyIndex));
807 const vk::DeviceDriver vkd (vki, *device);
808 const vk::VkQueue queue (getQueue(vkd, *device, queueFamilyIndex));
810 const vk::Unique<vk::VkSemaphore> semaphoreA (createExportableSemaphore(vkd, *device, config.externalType));
813 getSemaphoreNative(vkd, *device, *semaphoreA, config.externalType, handle);
815 submitDummySignal(vkd, queue, *semaphoreA);
818 const vk::Unique<vk::VkSemaphore> semaphoreB (createAndImportSemaphore(vkd, *device, config.externalType, handle, flags));
820 submitDummyWait(vkd, queue, *semaphoreB);
821 VK_CHECK(vkd.queueWaitIdle(queue));
825 return tcu::TestStatus::pass("Pass");
829 tcu::TestStatus testSemaphoreExportImportSignalWait (Context& context,
830 const SemaphoreTestConfig config)
832 const vk::PlatformInterface& vkp (context.getPlatformInterface());
833 const vk::Unique<vk::VkInstance> instance (createInstance(vkp, config.externalType, 0u, 0u));
834 const vk::InstanceDriver vki (vkp, *instance);
835 const vk::VkPhysicalDevice physicalDevice (vk::chooseDevice(vki, *instance, context.getTestContext().getCommandLine()));
836 const deUint32 queueFamilyIndex (chooseQueueFamilyIndex(vki, physicalDevice, 0u));
838 DE_ASSERT(getHandelTypeTransferences(config.externalType) == TRANSFERENCE_REFERENCE);
839 checkSemaphoreSupport(vki, physicalDevice, config.externalType);
842 const vk::VkSemaphoreImportFlagsKHR flags = config.permanence == PERMANENCE_TEMPORARY ? vk::VK_SEMAPHORE_IMPORT_TEMPORARY_BIT_KHR : (vk::VkSemaphoreImportFlagBitsKHR)0u;
843 const vk::Unique<vk::VkDevice> device (createDevice(vki, physicalDevice, config.externalType, 0u, 0u, queueFamilyIndex));
844 const vk::DeviceDriver vkd (vki, *device);
845 const vk::VkQueue queue (getQueue(vkd, *device, queueFamilyIndex));
847 const vk::Unique<vk::VkSemaphore> semaphoreA (createExportableSemaphore(vkd, *device, config.externalType));
850 getSemaphoreNative(vkd, *device, *semaphoreA, config.externalType, handle);
852 const vk::Unique<vk::VkSemaphore> semaphoreB (createAndImportSemaphore(vkd, *device, config.externalType, handle, flags));
854 submitDummySignal(vkd, queue, *semaphoreA);
855 submitDummyWait(vkd, queue, *semaphoreB);
857 VK_CHECK(vkd.queueWaitIdle(queue));
859 return tcu::TestStatus::pass("Pass");
863 tcu::TestStatus testSemaphoreSignalImport (Context& context,
864 const SemaphoreTestConfig config)
866 const Transference transference (getHandelTypeTransferences(config.externalType));
867 const vk::PlatformInterface& vkp (context.getPlatformInterface());
868 const vk::Unique<vk::VkInstance> instance (createInstance(vkp, config.externalType, 0u, 0u));
869 const vk::InstanceDriver vki (vkp, *instance);
870 const vk::VkPhysicalDevice physicalDevice (vk::chooseDevice(vki, *instance, context.getTestContext().getCommandLine()));
871 const deUint32 queueFamilyIndex (chooseQueueFamilyIndex(vki, physicalDevice, 0u));
873 checkSemaphoreSupport(vki, physicalDevice, config.externalType);
876 const vk::VkSemaphoreImportFlagsKHR flags = config.permanence == PERMANENCE_TEMPORARY ? vk::VK_SEMAPHORE_IMPORT_TEMPORARY_BIT_KHR : (vk::VkSemaphoreImportFlagBitsKHR)0u;
877 const vk::Unique<vk::VkDevice> device (createDevice(vki, physicalDevice, config.externalType, 0u, 0u, queueFamilyIndex));
878 const vk::DeviceDriver vkd (vki, *device);
879 const vk::VkQueue queue (getQueue(vkd, *device, queueFamilyIndex));
881 const vk::Unique<vk::VkSemaphore> semaphoreA (createExportableSemaphore(vkd, *device, config.externalType));
882 const vk::Unique<vk::VkSemaphore> semaphoreB (createSemaphore(vkd, *device));
885 submitDummySignal(vkd, queue, *semaphoreB);
886 VK_CHECK(vkd.queueWaitIdle(queue));
888 if (transference == TRANSFERENCE_COPY)
889 submitDummySignal(vkd, queue, *semaphoreA);
891 getSemaphoreNative(vkd, *device, *semaphoreA, config.externalType, handle);
893 importSemaphore(vkd, *device, *semaphoreB, config.externalType, handle, flags);
895 if (transference == TRANSFERENCE_COPY)
896 submitDummyWait(vkd, queue, *semaphoreB);
897 else if (transference == TRANSFERENCE_REFERENCE)
899 submitDummySignal(vkd, queue, *semaphoreA);
900 submitDummyWait(vkd, queue, *semaphoreB);
903 DE_FATAL("Unknown transference.");
905 VK_CHECK(vkd.queueWaitIdle(queue));
907 return tcu::TestStatus::pass("Pass");
911 tcu::TestStatus testSemaphoreSignalWaitImport (Context& context,
912 const SemaphoreTestConfig config)
914 const Transference transference (getHandelTypeTransferences(config.externalType));
915 const vk::PlatformInterface& vkp (context.getPlatformInterface());
916 const vk::Unique<vk::VkInstance> instance (createInstance(vkp, config.externalType, 0u, 0u));
917 const vk::InstanceDriver vki (vkp, *instance);
918 const vk::VkPhysicalDevice physicalDevice (vk::chooseDevice(vki, *instance, context.getTestContext().getCommandLine()));
919 const deUint32 queueFamilyIndex (chooseQueueFamilyIndex(vki, physicalDevice, 0u));
921 checkSemaphoreSupport(vki, physicalDevice, config.externalType);
924 const vk::VkSemaphoreImportFlagsKHR flags = config.permanence == PERMANENCE_TEMPORARY ? vk::VK_SEMAPHORE_IMPORT_TEMPORARY_BIT_KHR : (vk::VkSemaphoreImportFlagBitsKHR)0u;
925 const vk::Unique<vk::VkDevice> device (createDevice(vki, physicalDevice, config.externalType, 0u, 0u, queueFamilyIndex));
926 const vk::DeviceDriver vkd (vki, *device);
927 const vk::VkQueue queue (getQueue(vkd, *device, queueFamilyIndex));
929 const vk::Unique<vk::VkSemaphore> semaphoreA (createExportableSemaphore(vkd, *device, config.externalType));
930 const vk::Unique<vk::VkSemaphore> semaphoreB (createSemaphore(vkd, *device));
933 if (transference == TRANSFERENCE_COPY)
934 submitDummySignal(vkd, queue, *semaphoreA);
936 getSemaphoreNative(vkd, *device, *semaphoreA, config.externalType, handle);
938 submitDummySignal(vkd, queue, *semaphoreB);
939 submitDummyWait(vkd, queue, *semaphoreB);
941 VK_CHECK(vkd.queueWaitIdle(queue));
943 importSemaphore(vkd, *device, *semaphoreB, config.externalType, handle, flags);
945 if (transference == TRANSFERENCE_COPY)
946 submitDummyWait(vkd, queue, *semaphoreB);
947 else if (transference == TRANSFERENCE_REFERENCE)
949 submitDummySignal(vkd, queue, *semaphoreA);
950 submitDummyWait(vkd, queue, *semaphoreB);
953 DE_FATAL("Unknown transference.");
955 VK_CHECK(vkd.queueWaitIdle(queue));
957 return tcu::TestStatus::pass("Pass");
961 tcu::TestStatus testSemaphoreMultipleExports (Context& context,
962 const SemaphoreTestConfig config)
964 const size_t exportCount = 4 * 1024;
965 const Transference transference (getHandelTypeTransferences(config.externalType));
966 const vk::PlatformInterface& vkp (context.getPlatformInterface());
967 const vk::Unique<vk::VkInstance> instance (createInstance(vkp, config.externalType, 0u, 0u));
968 const vk::InstanceDriver vki (vkp, *instance);
969 const vk::VkPhysicalDevice physicalDevice (vk::chooseDevice(vki, *instance, context.getTestContext().getCommandLine()));
970 const deUint32 queueFamilyIndex (chooseQueueFamilyIndex(vki, physicalDevice, 0u));
972 checkSemaphoreSupport(vki, physicalDevice, config.externalType);
975 const vk::Unique<vk::VkDevice> device (createDevice(vki, physicalDevice, config.externalType, 0u, 0u, queueFamilyIndex));
976 const vk::DeviceDriver vkd (vki, *device);
977 const vk::VkQueue queue (getQueue(vkd, *device, queueFamilyIndex));
978 const vk::Unique<vk::VkSemaphore> semaphore (createExportableSemaphore(vkd, *device, config.externalType));
980 for (size_t exportNdx = 0; exportNdx < exportCount; exportNdx++)
984 if (transference == TRANSFERENCE_COPY)
985 submitDummySignal(vkd, queue, *semaphore);
987 getSemaphoreNative(vkd, *device, *semaphore, config.externalType, handle);
990 submitDummySignal(vkd, queue, *semaphore);
991 submitDummyWait(vkd, queue, *semaphore);
993 VK_CHECK(vkd.queueWaitIdle(queue));
996 return tcu::TestStatus::pass("Pass");
999 tcu::TestStatus testSemaphoreMultipleImports (Context& context,
1000 const SemaphoreTestConfig config)
1002 const size_t importCount = 4 * 1024;
1003 const Transference transference (getHandelTypeTransferences(config.externalType));
1004 const vk::PlatformInterface& vkp (context.getPlatformInterface());
1005 const vk::Unique<vk::VkInstance> instance (createInstance(vkp, config.externalType, 0u, 0u));
1006 const vk::InstanceDriver vki (vkp, *instance);
1007 const vk::VkPhysicalDevice physicalDevice (vk::chooseDevice(vki, *instance, context.getTestContext().getCommandLine()));
1008 const deUint32 queueFamilyIndex (chooseQueueFamilyIndex(vki, physicalDevice, 0u));
1010 checkSemaphoreSupport(vki, physicalDevice, config.externalType);
1013 const vk::VkSemaphoreImportFlagsKHR flags = config.permanence == PERMANENCE_TEMPORARY ? vk::VK_SEMAPHORE_IMPORT_TEMPORARY_BIT_KHR : (vk::VkSemaphoreImportFlagBitsKHR)0u;
1014 const vk::Unique<vk::VkDevice> device (createDevice(vki, physicalDevice, config.externalType, 0u, 0u, queueFamilyIndex));
1015 const vk::DeviceDriver vkd (vki, *device);
1016 const vk::VkQueue queue (getQueue(vkd, *device, queueFamilyIndex));
1017 const vk::Unique<vk::VkSemaphore> semaphoreA (createExportableSemaphore(vkd, *device, config.externalType));
1018 NativeHandle handleA;
1020 if (transference == TRANSFERENCE_COPY)
1021 submitDummySignal(vkd, queue, *semaphoreA);
1023 getSemaphoreNative(vkd, *device, *semaphoreA, config.externalType, handleA);
1025 for (size_t importNdx = 0; importNdx < importCount; importNdx++)
1027 NativeHandle handleB (handleA);
1028 const vk::Unique<vk::VkSemaphore> semaphoreB (createAndImportSemaphore(vkd, *device, config.externalType, handleB, flags));
1031 if (transference == TRANSFERENCE_COPY)
1033 importSemaphore(vkd, *device, *semaphoreA, config.externalType, handleA, flags);
1034 submitDummyWait(vkd, queue, *semaphoreA);
1036 else if (transference == TRANSFERENCE_REFERENCE)
1038 submitDummySignal(vkd, queue, *semaphoreA);
1039 submitDummyWait(vkd, queue, *semaphoreA);
1042 DE_FATAL("Unknown transference.");
1044 VK_CHECK(vkd.queueWaitIdle(queue));
1047 return tcu::TestStatus::pass("Pass");
1050 tcu::TestStatus testSemaphoreTransference (Context& context,
1051 const SemaphoreTestConfig config)
1053 const Transference transference (getHandelTypeTransferences(config.externalType));
1054 const vk::PlatformInterface& vkp (context.getPlatformInterface());
1055 const vk::Unique<vk::VkInstance> instance (createInstance(vkp, config.externalType, 0u, 0u));
1056 const vk::InstanceDriver vki (vkp, *instance);
1057 const vk::VkPhysicalDevice physicalDevice (vk::chooseDevice(vki, *instance, context.getTestContext().getCommandLine()));
1058 const deUint32 queueFamilyIndex (chooseQueueFamilyIndex(vki, physicalDevice, 0u));
1060 checkSemaphoreSupport(vki, physicalDevice, config.externalType);
1063 const vk::VkSemaphoreImportFlagsKHR flags = config.permanence == PERMANENCE_TEMPORARY ? vk::VK_SEMAPHORE_IMPORT_TEMPORARY_BIT_KHR : (vk::VkSemaphoreImportFlagBitsKHR)0u;
1064 const vk::Unique<vk::VkDevice> device (createDevice(vki, physicalDevice, config.externalType, 0u, 0u, queueFamilyIndex));
1065 const vk::DeviceDriver vkd (vki, *device);
1066 const vk::VkQueue queue (getQueue(vkd, *device, queueFamilyIndex));
1068 const vk::Unique<vk::VkSemaphore> semaphoreA (createExportableSemaphore(vkd, *device, config.externalType));
1069 NativeHandle handle;
1071 submitDummySignal(vkd, queue, *semaphoreA);
1073 getSemaphoreNative(vkd, *device, *semaphoreA, config.externalType, handle);
1076 const vk::Unique<vk::VkSemaphore> semaphoreB (createAndImportSemaphore(vkd, *device, config.externalType, handle, flags));
1078 if (config.permanence == PERMANENCE_PERMANENT)
1080 if (transference == TRANSFERENCE_COPY)
1082 submitDummySignal(vkd, queue, *semaphoreA);
1083 submitDummyWait(vkd, queue, *semaphoreB);
1084 VK_CHECK(vkd.queueWaitIdle(queue));
1086 submitDummySignal(vkd, queue, *semaphoreB);
1088 submitDummyWait(vkd, queue, *semaphoreA);
1089 submitDummyWait(vkd, queue, *semaphoreB);
1090 VK_CHECK(vkd.queueWaitIdle(queue));
1092 else if (transference== TRANSFERENCE_REFERENCE)
1094 submitDummyWait(vkd, queue, *semaphoreB);
1095 VK_CHECK(vkd.queueWaitIdle(queue));
1097 submitDummySignal(vkd, queue, *semaphoreA);
1098 submitDummyWait(vkd, queue, *semaphoreB);
1100 submitDummySignal(vkd, queue, *semaphoreB);
1101 submitDummyWait(vkd, queue, *semaphoreA);
1102 VK_CHECK(vkd.queueWaitIdle(queue));
1105 DE_FATAL("Unknown transference.");
1107 else if (config.permanence == PERMANENCE_TEMPORARY)
1109 if (transference == TRANSFERENCE_COPY)
1111 submitDummySignal(vkd, queue, *semaphoreA);
1112 submitDummyWait(vkd, queue, *semaphoreB);
1113 VK_CHECK(vkd.queueWaitIdle(queue));
1115 submitDummySignal(vkd, queue, *semaphoreB);
1117 submitDummyWait(vkd, queue, *semaphoreA);
1118 submitDummyWait(vkd, queue, *semaphoreB);
1119 VK_CHECK(vkd.queueWaitIdle(queue));
1121 else if (transference== TRANSFERENCE_REFERENCE)
1123 submitDummyWait(vkd, queue, *semaphoreB);
1124 VK_CHECK(vkd.queueWaitIdle(queue));
1126 submitDummySignal(vkd, queue, *semaphoreA);
1127 submitDummySignal(vkd, queue, *semaphoreB);
1129 submitDummyWait(vkd, queue, *semaphoreB);
1130 submitDummyWait(vkd, queue, *semaphoreA);
1131 VK_CHECK(vkd.queueWaitIdle(queue));
1134 DE_FATAL("Unknown transference.");
1137 DE_FATAL("Unknown permanence.");
1140 return tcu::TestStatus::pass("Pass");
1144 tcu::TestStatus testSemaphoreFdDup (Context& context,
1145 const SemaphoreTestConfig config)
1147 #if (DE_OS == DE_OS_ANDROID) || (DE_OS == DE_OS_UNIX)
1148 const Transference transference (getHandelTypeTransferences(config.externalType));
1149 const vk::PlatformInterface& vkp (context.getPlatformInterface());
1150 const vk::Unique<vk::VkInstance> instance (createInstance(vkp, config.externalType, 0u, 0u));
1151 const vk::InstanceDriver vki (vkp, *instance);
1152 const vk::VkPhysicalDevice physicalDevice (vk::chooseDevice(vki, *instance, context.getTestContext().getCommandLine()));
1153 const deUint32 queueFamilyIndex (chooseQueueFamilyIndex(vki, physicalDevice, 0u));
1155 checkSemaphoreSupport(vki, physicalDevice, config.externalType);
1158 const vk::VkSemaphoreImportFlagsKHR flags = config.permanence == PERMANENCE_TEMPORARY ? vk::VK_SEMAPHORE_IMPORT_TEMPORARY_BIT_KHR : (vk::VkSemaphoreImportFlagBitsKHR)0u;
1159 const vk::Unique<vk::VkDevice> device (createDevice(vki, physicalDevice, config.externalType, 0u, 0u, queueFamilyIndex));
1160 const vk::DeviceDriver vkd (vki, *device);
1161 const vk::VkQueue queue (getQueue(vkd, *device, queueFamilyIndex));
1163 TestLog& log = context.getTestContext().getLog();
1164 const vk::Unique<vk::VkSemaphore> semaphoreA (createExportableSemaphore(vkd, *device, config.externalType));
1166 if (transference == TRANSFERENCE_COPY)
1167 submitDummySignal(vkd, queue, *semaphoreA);
1170 const NativeHandle fd (getSemaphoreFd(vkd, *device, *semaphoreA, config.externalType));
1171 NativeHandle newFd (dup(fd.getFd()));
1173 if (newFd.getFd() < 0)
1174 log << TestLog::Message << "dup() failed: '" << strerror(errno) << "'" << TestLog::EndMessage;
1176 TCU_CHECK_MSG(newFd.getFd() >= 0, "Failed to call dup() for semaphores fd");
1179 const vk::Unique<vk::VkSemaphore> semaphoreB (createAndImportSemaphore(vkd, *device, config.externalType, newFd, flags));
1181 if (transference == TRANSFERENCE_COPY)
1182 submitDummyWait(vkd, queue, *semaphoreB);
1183 else if (transference == TRANSFERENCE_REFERENCE)
1185 submitDummySignal(vkd, queue, *semaphoreA);
1186 submitDummyWait(vkd, queue, *semaphoreB);
1189 DE_FATAL("Unknown permanence.");
1193 VK_CHECK(vkd.queueWaitIdle(queue));
1195 return tcu::TestStatus::pass("Pass");
1200 TCU_THROW(NotSupportedError, "Platform doesn't support dup()");
1204 tcu::TestStatus testSemaphoreFdDup2 (Context& context,
1205 const SemaphoreTestConfig config)
1207 #if (DE_OS == DE_OS_ANDROID) || (DE_OS == DE_OS_UNIX)
1208 const Transference transference (getHandelTypeTransferences(config.externalType));
1209 const vk::PlatformInterface& vkp (context.getPlatformInterface());
1210 const vk::Unique<vk::VkInstance> instance (createInstance(vkp, config.externalType, 0u, 0u));
1211 const vk::InstanceDriver vki (vkp, *instance);
1212 const vk::VkPhysicalDevice physicalDevice (vk::chooseDevice(vki, *instance, context.getTestContext().getCommandLine()));
1213 const deUint32 queueFamilyIndex (chooseQueueFamilyIndex(vki, physicalDevice, 0u));
1215 checkSemaphoreSupport(vki, physicalDevice, config.externalType);
1218 const vk::VkSemaphoreImportFlagsKHR flags = config.permanence == PERMANENCE_TEMPORARY ? vk::VK_SEMAPHORE_IMPORT_TEMPORARY_BIT_KHR : (vk::VkSemaphoreImportFlagBitsKHR)0u;
1219 const vk::Unique<vk::VkDevice> device (createDevice(vki, physicalDevice, config.externalType, 0u, 0u, queueFamilyIndex));
1220 const vk::DeviceDriver vkd (vki, *device);
1221 const vk::VkQueue queue (getQueue(vkd, *device, queueFamilyIndex));
1223 TestLog& log = context.getTestContext().getLog();
1224 const vk::Unique<vk::VkSemaphore> semaphoreA (createExportableSemaphore(vkd, *device, config.externalType));
1225 const vk::Unique<vk::VkSemaphore> semaphoreB (createExportableSemaphore(vkd, *device, config.externalType));
1227 if (transference == TRANSFERENCE_COPY)
1229 submitDummySignal(vkd, queue, *semaphoreA);
1230 submitDummySignal(vkd, queue, *semaphoreB);
1234 const NativeHandle fd (getSemaphoreFd(vkd, *device, *semaphoreA, config.externalType));
1235 NativeHandle secondFd (getSemaphoreFd(vkd, *device, *semaphoreB, config.externalType));
1236 int newFd (dup2(fd.getFd(), secondFd.getFd()));
1239 log << TestLog::Message << "dup2() failed: '" << strerror(errno) << "'" << TestLog::EndMessage;
1241 TCU_CHECK_MSG(newFd >= 0, "Failed to call dup2() for fences fd");
1244 const vk::Unique<vk::VkSemaphore> semaphoreC (createAndImportSemaphore(vkd, *device, config.externalType, secondFd, flags));
1246 if (transference == TRANSFERENCE_COPY)
1247 submitDummyWait(vkd, queue, *semaphoreC);
1248 else if (transference == TRANSFERENCE_REFERENCE)
1250 submitDummySignal(vkd, queue, *semaphoreA);
1251 submitDummyWait(vkd, queue, *semaphoreC);
1254 DE_FATAL("Unknown permanence.");
1258 VK_CHECK(vkd.queueWaitIdle(queue));
1260 return tcu::TestStatus::pass("Pass");
1265 TCU_THROW(NotSupportedError, "Platform doesn't support dup2()");
1269 tcu::TestStatus testSemaphoreFdDup3 (Context& context,
1270 const SemaphoreTestConfig config)
1272 #if (DE_OS == DE_OS_UNIX) && defined(_GNU_SOURCE)
1273 const Transference transference (getHandelTypeTransferences(config.externalType));
1274 const vk::PlatformInterface& vkp (context.getPlatformInterface());
1275 const vk::Unique<vk::VkInstance> instance (createInstance(vkp, config.externalType, 0u, 0u));
1276 const vk::InstanceDriver vki (vkp, *instance);
1277 const vk::VkPhysicalDevice physicalDevice (vk::chooseDevice(vki, *instance, context.getTestContext().getCommandLine()));
1278 const deUint32 queueFamilyIndex (chooseQueueFamilyIndex(vki, physicalDevice, 0u));
1280 checkSemaphoreSupport(vki, physicalDevice, config.externalType);
1283 const vk::Unique<vk::VkDevice> device (createDevice(vki, physicalDevice, config.externalType, 0u, 0u, queueFamilyIndex));
1284 const vk::DeviceDriver vkd (vki, *device);
1285 const vk::VkQueue queue (getQueue(vkd, *device, queueFamilyIndex));
1287 TestLog& log = context.getTestContext().getLog();
1288 const vk::Unique<vk::VkSemaphore> semaphoreA (createExportableSemaphore(vkd, *device, config.externalType));
1289 const vk::Unique<vk::VkSemaphore> semaphoreB (createExportableSemaphore(vkd, *device, config.externalType));
1291 if (transference == TRANSFERENCE_COPY)
1293 submitDummySignal(vkd, queue, *semaphoreA);
1294 submitDummySignal(vkd, queue, *semaphoreB);
1298 const vk::VkSemaphoreImportFlagsKHR flags = config.permanence == PERMANENCE_TEMPORARY ? vk::VK_SEMAPHORE_IMPORT_TEMPORARY_BIT_KHR : (vk::VkSemaphoreImportFlagBitsKHR)0u;
1299 const NativeHandle fd (getSemaphoreFd(vkd, *device, *semaphoreA, config.externalType));
1300 NativeHandle secondFd (getSemaphoreFd(vkd, *device, *semaphoreB, config.externalType));
1301 const int newFd (dup3(fd.getFd(), secondFd.getFd(), 0));
1304 log << TestLog::Message << "dup3() failed: '" << strerror(errno) << "'" << TestLog::EndMessage;
1306 TCU_CHECK_MSG(newFd >= 0, "Failed to call dup3() for fences fd");
1309 const vk::Unique<vk::VkSemaphore> semaphoreC (createAndImportSemaphore(vkd, *device, config.externalType, secondFd, flags));
1311 if (transference == TRANSFERENCE_COPY)
1312 submitDummyWait(vkd, queue, *semaphoreC);
1313 else if (transference == TRANSFERENCE_REFERENCE)
1315 submitDummySignal(vkd, queue, *semaphoreA);
1316 submitDummyWait(vkd, queue, *semaphoreC);
1319 DE_FATAL("Unknown permanence.");
1323 VK_CHECK(vkd.queueWaitIdle(queue));
1325 return tcu::TestStatus::pass("Pass");
1330 TCU_THROW(NotSupportedError, "Platform doesn't support dup3()");
1334 tcu::TestStatus testSemaphoreFdSendOverSocket (Context& context,
1335 const SemaphoreTestConfig config)
1337 #if (DE_OS == DE_OS_ANDROID) || (DE_OS == DE_OS_UNIX)
1338 const Transference transference (getHandelTypeTransferences(config.externalType));
1339 const vk::PlatformInterface& vkp (context.getPlatformInterface());
1340 const vk::Unique<vk::VkInstance> instance (createInstance(vkp, config.externalType, 0u, 0u));
1341 const vk::InstanceDriver vki (vkp, *instance);
1342 const vk::VkPhysicalDevice physicalDevice (vk::chooseDevice(vki, *instance, context.getTestContext().getCommandLine()));
1343 const deUint32 queueFamilyIndex (chooseQueueFamilyIndex(vki, physicalDevice, 0u));
1345 checkSemaphoreSupport(vki, physicalDevice, config.externalType);
1348 const vk::Unique<vk::VkDevice> device (createDevice(vki, physicalDevice, config.externalType, 0u, 0u, queueFamilyIndex));
1349 const vk::DeviceDriver vkd (vki, *device);
1350 const vk::VkQueue queue (getQueue(vkd, *device, queueFamilyIndex));
1352 TestLog& log = context.getTestContext().getLog();
1353 const vk::Unique<vk::VkSemaphore> semaphore (createExportableSemaphore(vkd, *device, config.externalType));
1355 if (transference == TRANSFERENCE_COPY)
1356 submitDummySignal(vkd, queue, *semaphore);
1358 const NativeHandle fd (getSemaphoreFd(vkd, *device, *semaphore, config.externalType));
1363 if (socketpair(AF_UNIX, SOCK_STREAM, 0, sv) != 0)
1365 log << TestLog::Message << "Failed to create socket pair: '" << strerror(errno) << "'" << TestLog::EndMessage;
1366 TCU_FAIL("Failed to create socket pair");
1370 const NativeHandle srcSocket (sv[0]);
1371 const NativeHandle dstSocket (sv[1]);
1372 std::string sendData ("deqp");
1376 const int fdRaw (fd.getFd());
1379 char buffer[CMSG_SPACE(sizeof(int))];
1380 iovec iov = { &sendData[0], sendData.length()};
1382 deMemset(&msg, 0, sizeof(msg));
1384 msg.msg_control = buffer;
1385 msg.msg_controllen = sizeof(buffer);
1389 cmsg = CMSG_FIRSTHDR(&msg);
1390 cmsg->cmsg_level = SOL_SOCKET;
1391 cmsg->cmsg_type = SCM_RIGHTS;
1392 cmsg->cmsg_len = CMSG_LEN(sizeof(int));
1394 deMemcpy(CMSG_DATA(cmsg), &fdRaw, sizeof(int));
1395 msg.msg_controllen = cmsg->cmsg_len;
1397 if (sendmsg(srcSocket.getFd(), &msg, 0) < 0)
1399 log << TestLog::Message << "Failed to send fd over socket: '" << strerror(errno) << "'" << TestLog::EndMessage;
1400 TCU_FAIL("Failed to send fd over socket");
1407 char buffer[CMSG_SPACE(sizeof(int))];
1408 std::string recvData (4, '\0');
1409 iovec iov = { &recvData[0], recvData.length() };
1411 deMemset(&msg, 0, sizeof(msg));
1413 msg.msg_control = buffer;
1414 msg.msg_controllen = sizeof(buffer);
1418 const ssize_t bytes = recvmsg(dstSocket.getFd(), &msg, 0);
1422 log << TestLog::Message << "Failed to recv fd over socket: '" << strerror(errno) << "'" << TestLog::EndMessage;
1423 TCU_FAIL("Failed to recv fd over socket");
1426 else if (bytes != (ssize_t)sendData.length())
1428 TCU_FAIL("recvmsg() returned unpexpected number of bytes");
1432 const vk::VkSemaphoreImportFlagsKHR flags = config.permanence == PERMANENCE_TEMPORARY ? vk::VK_SEMAPHORE_IMPORT_TEMPORARY_BIT_KHR : (vk::VkSemaphoreImportFlagBitsKHR)0u;
1433 const cmsghdr* const cmsg = CMSG_FIRSTHDR(&msg);
1435 deMemcpy(&newFd_, CMSG_DATA(cmsg), sizeof(int));
1436 NativeHandle newFd (newFd_);
1438 TCU_CHECK(cmsg->cmsg_level == SOL_SOCKET);
1439 TCU_CHECK(cmsg->cmsg_type == SCM_RIGHTS);
1440 TCU_CHECK(cmsg->cmsg_len == CMSG_LEN(sizeof(int)));
1441 TCU_CHECK(recvData == sendData);
1442 TCU_CHECK_MSG(newFd.getFd() >= 0, "Didn't receive valid fd from socket");
1445 const vk::Unique<vk::VkSemaphore> newSemaphore (createAndImportSemaphore(vkd, *device, config.externalType, newFd, flags));
1447 if (transference == TRANSFERENCE_COPY)
1448 submitDummyWait(vkd, queue, *newSemaphore);
1449 else if (transference == TRANSFERENCE_REFERENCE)
1451 submitDummySignal(vkd, queue, *newSemaphore);
1452 submitDummyWait(vkd, queue, *newSemaphore);
1455 DE_FATAL("Unknown permanence.");
1457 VK_CHECK(vkd.queueWaitIdle(queue));
1465 return tcu::TestStatus::pass("Pass");
1469 TCU_THROW(NotSupportedError, "Platform doesn't support sending file descriptors over socket");
1473 tcu::TestStatus testFenceQueries (Context& context, vk::VkExternalFenceHandleTypeFlagBitsKHR externalType)
1475 const vk::PlatformInterface& vkp (context.getPlatformInterface());
1476 const vk::Unique<vk::VkInstance> instance (createInstance(vkp, 0u, 0u, externalType));
1477 const vk::InstanceDriver vki (vkp, *instance);
1478 const vk::VkPhysicalDevice device (vk::chooseDevice(vki, *instance, context.getTestContext().getCommandLine()));
1480 TestLog& log = context.getTestContext().getLog();
1482 const vk::VkPhysicalDeviceExternalFenceInfoKHR info =
1484 vk::VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_FENCE_INFO_KHR,
1488 vk::VkExternalFencePropertiesKHR properties =
1490 vk::VK_STRUCTURE_TYPE_EXTERNAL_FENCE_PROPERTIES_KHR,
1497 vki.getPhysicalDeviceExternalFencePropertiesKHR(device, &info, &properties);
1498 log << TestLog::Message << properties << TestLog::EndMessage;
1500 TCU_CHECK(properties.pNext == DE_NULL);
1501 TCU_CHECK(properties.sType == vk::VK_STRUCTURE_TYPE_EXTERNAL_FENCE_PROPERTIES_KHR);
1503 return tcu::TestStatus::pass("Pass");
1506 struct FenceTestConfig
1508 FenceTestConfig (vk::VkExternalFenceHandleTypeFlagBitsKHR externalType_,
1509 Permanence permanence_)
1510 : externalType (externalType_)
1511 , permanence (permanence_)
1515 vk::VkExternalFenceHandleTypeFlagBitsKHR externalType;
1516 Permanence permanence;
1520 tcu::TestStatus testFenceWin32Create (Context& context,
1521 const FenceTestConfig config)
1523 #if (DE_OS == DE_OS_WIN32)
1524 const Transference transference (getHandelTypeTransferences(config.externalType));
1525 const vk::PlatformInterface& vkp (context.getPlatformInterface());
1526 const vk::Unique<vk::VkInstance> instance (createInstance(vkp, 0u, 0u, config.externalType));
1527 const vk::InstanceDriver vki (vkp, *instance);
1528 const vk::VkPhysicalDevice physicalDevice (vk::chooseDevice(vki, *instance, context.getTestContext().getCommandLine()));
1529 const deUint32 queueFamilyIndex (chooseQueueFamilyIndex(vki, physicalDevice, 0u));
1531 checkFenceSupport(vki, physicalDevice, config.externalType);
1534 const vk::Unique<vk::VkDevice> device (createDevice(vki, physicalDevice, 0u, 0u, config.externalType, queueFamilyIndex));
1535 const vk::DeviceDriver vkd (vki, *device);
1536 const vk::VkQueue queue (getQueue(vkd, *device, queueFamilyIndex));
1537 const vk::VkExportFenceWin32HandleInfoKHR win32ExportInfo =
1539 vk::VK_STRUCTURE_TYPE_EXPORT_FENCE_WIN32_HANDLE_INFO_KHR,
1542 (vk::pt::Win32SecurityAttributesPtr)DE_NULL,
1543 DXGI_SHARED_RESOURCE_READ | DXGI_SHARED_RESOURCE_WRITE,
1546 const vk::VkExportFenceCreateInfoKHR exportCreateInfo=
1548 vk::VK_STRUCTURE_TYPE_EXPORT_FENCE_CREATE_INFO_KHR,
1550 (vk::VkExternalFenceHandleTypeFlagsKHR)config.externalType
1552 const vk::VkFenceCreateInfo createInfo =
1554 vk::VK_STRUCTURE_TYPE_FENCE_CREATE_INFO,
1558 const vk::Unique<vk::VkFence> fence (vk::createFence(vkd, *device, &createInfo));
1560 if (transference == TRANSFERENCE_COPY)
1561 submitDummySignal(vkd, queue, *fence);
1563 NativeHandle handleA;
1564 getFenceNative(vkd, *device, *fence, config.externalType, handleA);
1567 const vk::VkFenceImportFlagsKHR flags = config.permanence == PERMANENCE_TEMPORARY ? vk::VK_FENCE_IMPORT_TEMPORARY_BIT_KHR : (vk::VkFenceImportFlagBitsKHR)0u;
1568 const vk::Unique<vk::VkFence> fenceA (createAndImportFence(vkd, *device, config.externalType, handleA, flags));
1570 if (transference == TRANSFERENCE_COPY)
1571 VK_CHECK(vkd.waitForFences(*device, 1u, &*fenceA, VK_TRUE, ~0ull));
1572 else if (transference == TRANSFERENCE_REFERENCE)
1574 submitDummySignal(vkd, queue, *fence);
1575 VK_CHECK(vkd.waitForFences(*device, 1u, &*fenceA, VK_TRUE, ~0ull));
1578 DE_FATAL("Unknown transference.");
1580 VK_CHECK(vkd.queueWaitIdle(queue));
1583 return tcu::TestStatus::pass("Pass");
1588 TCU_THROW(NotSupportedError, "Platform doesn't support win32 handles");
1592 tcu::TestStatus testFenceImportTwice (Context& context,
1593 const FenceTestConfig config)
1595 const Transference transference (getHandelTypeTransferences(config.externalType));
1596 const vk::PlatformInterface& vkp (context.getPlatformInterface());
1597 const vk::Unique<vk::VkInstance> instance (createInstance(vkp, 0u, 0u, config.externalType));
1598 const vk::InstanceDriver vki (vkp, *instance);
1599 const vk::VkPhysicalDevice physicalDevice (vk::chooseDevice(vki, *instance, context.getTestContext().getCommandLine()));
1600 const deUint32 queueFamilyIndex (chooseQueueFamilyIndex(vki, physicalDevice, 0u));
1602 checkFenceSupport(vki, physicalDevice, config.externalType);
1605 const vk::Unique<vk::VkDevice> device (createDevice(vki, physicalDevice, 0u, 0u, config.externalType, queueFamilyIndex));
1606 const vk::DeviceDriver vkd (vki, *device);
1607 const vk::VkQueue queue (getQueue(vkd, *device, queueFamilyIndex));
1608 const vk::Unique<vk::VkFence> fence (createExportableFence(vkd, *device, config.externalType));
1610 if (transference == TRANSFERENCE_COPY)
1611 submitDummySignal(vkd, queue, *fence);
1613 NativeHandle handleA;
1614 getFenceNative(vkd, *device, *fence, config.externalType, handleA);
1617 NativeHandle handleB (handleA);
1618 const vk::VkFenceImportFlagsKHR flags = config.permanence == PERMANENCE_TEMPORARY ? vk::VK_FENCE_IMPORT_TEMPORARY_BIT_KHR : (vk::VkFenceImportFlagBitsKHR)0u;
1619 const vk::Unique<vk::VkFence> fenceA (createAndImportFence(vkd, *device, config.externalType, handleA, flags));
1620 const vk::Unique<vk::VkFence> fenceB (createAndImportFence(vkd, *device, config.externalType, handleB, flags));
1622 if (transference == TRANSFERENCE_COPY)
1623 VK_CHECK(vkd.waitForFences(*device, 1u, &*fenceA, VK_TRUE, ~0ull));
1624 else if (transference == TRANSFERENCE_REFERENCE)
1626 submitDummySignal(vkd, queue, *fenceA);
1627 VK_CHECK(vkd.waitForFences(*device, 1u, &*fenceB, VK_TRUE, ~0ull));
1630 DE_FATAL("Unknown transference.");
1632 VK_CHECK(vkd.queueWaitIdle(queue));
1635 return tcu::TestStatus::pass("Pass");
1639 tcu::TestStatus testFenceImportReimport (Context& context,
1640 const FenceTestConfig config)
1642 const Transference transference (getHandelTypeTransferences(config.externalType));
1643 const vk::PlatformInterface& vkp (context.getPlatformInterface());
1644 const vk::Unique<vk::VkInstance> instance (createInstance(vkp, 0u, 0u, config.externalType));
1645 const vk::InstanceDriver vki (vkp, *instance);
1646 const vk::VkPhysicalDevice physicalDevice (vk::chooseDevice(vki, *instance, context.getTestContext().getCommandLine()));
1647 const deUint32 queueFamilyIndex (chooseQueueFamilyIndex(vki, physicalDevice, 0u));
1649 checkFenceSupport(vki, physicalDevice, config.externalType);
1652 const vk::Unique<vk::VkDevice> device (createDevice(vki, physicalDevice, 0u, 0u, config.externalType, queueFamilyIndex));
1653 const vk::DeviceDriver vkd (vki, *device);
1654 const vk::VkQueue queue (getQueue(vkd, *device, queueFamilyIndex));
1656 const vk::Unique<vk::VkFence> fenceA (createExportableFence(vkd, *device, config.externalType));
1658 if (transference == TRANSFERENCE_COPY)
1659 submitDummySignal(vkd, queue, *fenceA);
1661 NativeHandle handleA;
1662 getFenceNative(vkd, *device, *fenceA, config.externalType, handleA);
1664 NativeHandle handleB (handleA);
1665 const vk::VkFenceImportFlagsKHR flags = config.permanence == PERMANENCE_TEMPORARY ? vk::VK_FENCE_IMPORT_TEMPORARY_BIT_KHR : (vk::VkFenceImportFlagBitsKHR)0u;
1666 const vk::Unique<vk::VkFence> fenceB (createAndImportFence(vkd, *device, config.externalType, handleA, flags));
1668 importFence(vkd, *device, *fenceB, config.externalType, handleB, flags);
1670 if (transference == TRANSFERENCE_COPY)
1671 VK_CHECK(vkd.waitForFences(*device, 1u, &*fenceB, VK_TRUE, ~0ull));
1672 else if (transference == TRANSFERENCE_REFERENCE)
1674 submitDummySignal(vkd, queue, *fenceA);
1675 VK_CHECK(vkd.waitForFences(*device, 1u, &*fenceB, VK_TRUE, ~0ull));
1678 DE_FATAL("Unknown transference.");
1680 VK_CHECK(vkd.queueWaitIdle(queue));
1682 return tcu::TestStatus::pass("Pass");
1686 tcu::TestStatus testFenceSignalExportImportWait (Context& context,
1687 const FenceTestConfig config)
1689 const vk::PlatformInterface& vkp (context.getPlatformInterface());
1690 const vk::Unique<vk::VkInstance> instance (createInstance(vkp, 0u, 0u, config.externalType));
1691 const vk::InstanceDriver vki (vkp, *instance);
1692 const vk::VkPhysicalDevice physicalDevice (vk::chooseDevice(vki, *instance, context.getTestContext().getCommandLine()));
1693 const deUint32 queueFamilyIndex (chooseQueueFamilyIndex(vki, physicalDevice, 0u));
1695 checkFenceSupport(vki, physicalDevice, config.externalType);
1698 const vk::Unique<vk::VkDevice> device (createDevice(vki, physicalDevice, 0u, 0u, config.externalType, queueFamilyIndex));
1699 const vk::DeviceDriver vkd (vki, *device);
1700 const vk::VkQueue queue (getQueue(vkd, *device, queueFamilyIndex));
1701 const vk::Unique<vk::VkFence> fenceA (createExportableFence(vkd, *device, config.externalType));
1703 submitDummySignal(vkd, queue, *fenceA);
1706 NativeHandle handle;
1708 getFenceNative(vkd, *device, *fenceA, config.externalType, handle);
1711 const vk::VkFenceImportFlagsKHR flags = config.permanence == PERMANENCE_TEMPORARY ? vk::VK_FENCE_IMPORT_TEMPORARY_BIT_KHR : (vk::VkFenceImportFlagBitsKHR)0u;
1712 const vk::Unique<vk::VkFence> fenceB (createAndImportFence(vkd, *device, config.externalType, handle, flags));
1713 VK_CHECK(vkd.waitForFences(*device, 1u, &*fenceB, VK_TRUE, ~0ull));
1715 VK_CHECK(vkd.queueWaitIdle(queue));
1719 return tcu::TestStatus::pass("Pass");
1723 tcu::TestStatus testFenceExportSignalImportWait (Context& context,
1724 const FenceTestConfig config)
1726 const vk::PlatformInterface& vkp (context.getPlatformInterface());
1727 const vk::Unique<vk::VkInstance> instance (createInstance(vkp, 0u, 0u, config.externalType));
1728 const vk::InstanceDriver vki (vkp, *instance);
1729 const vk::VkPhysicalDevice physicalDevice (vk::chooseDevice(vki, *instance, context.getTestContext().getCommandLine()));
1730 const deUint32 queueFamilyIndex (chooseQueueFamilyIndex(vki, physicalDevice, 0u));
1731 const vk::VkFenceImportFlagsKHR flags = config.permanence == PERMANENCE_TEMPORARY ? vk::VK_FENCE_IMPORT_TEMPORARY_BIT_KHR : (vk::VkFenceImportFlagBitsKHR)0u;
1733 DE_ASSERT(getHandelTypeTransferences(config.externalType) == TRANSFERENCE_REFERENCE);
1734 checkFenceSupport(vki, physicalDevice, config.externalType);
1737 const vk::Unique<vk::VkDevice> device (createDevice(vki, physicalDevice, 0u, 0u, config.externalType, queueFamilyIndex));
1738 const vk::DeviceDriver vkd (vki, *device);
1739 const vk::VkQueue queue (getQueue(vkd, *device, queueFamilyIndex));
1741 const vk::Unique<vk::VkFence> fenceA (createExportableFence(vkd, *device, config.externalType));
1742 NativeHandle handle;
1744 getFenceNative(vkd, *device, *fenceA, config.externalType, handle);
1746 submitDummySignal(vkd, queue, *fenceA);
1749 const vk::Unique<vk::VkFence> fenceB (createAndImportFence(vkd, *device, config.externalType, handle, flags));
1751 VK_CHECK(vkd.waitForFences(*device, 1u, &*fenceB, VK_TRUE, ~0ull));
1752 VK_CHECK(vkd.queueWaitIdle(queue));
1756 return tcu::TestStatus::pass("Pass");
1760 tcu::TestStatus testFenceExportImportSignalWait (Context& context,
1761 const FenceTestConfig config)
1763 const vk::PlatformInterface& vkp (context.getPlatformInterface());
1764 const vk::Unique<vk::VkInstance> instance (createInstance(vkp, 0u, 0u, config.externalType));
1765 const vk::InstanceDriver vki (vkp, *instance);
1766 const vk::VkPhysicalDevice physicalDevice (vk::chooseDevice(vki, *instance, context.getTestContext().getCommandLine()));
1767 const deUint32 queueFamilyIndex (chooseQueueFamilyIndex(vki, physicalDevice, 0u));
1769 DE_ASSERT(getHandelTypeTransferences(config.externalType) == TRANSFERENCE_REFERENCE);
1770 checkFenceSupport(vki, physicalDevice, config.externalType);
1773 const vk::VkFenceImportFlagsKHR flags = config.permanence == PERMANENCE_TEMPORARY ? vk::VK_FENCE_IMPORT_TEMPORARY_BIT_KHR : (vk::VkFenceImportFlagBitsKHR)0u;
1774 const vk::Unique<vk::VkDevice> device (createDevice(vki, physicalDevice, 0u, 0u, config.externalType, queueFamilyIndex));
1775 const vk::DeviceDriver vkd (vki, *device);
1776 const vk::VkQueue queue (getQueue(vkd, *device, queueFamilyIndex));
1778 const vk::Unique<vk::VkFence> fenceA (createExportableFence(vkd, *device, config.externalType));
1779 NativeHandle handle;
1781 getFenceNative(vkd, *device, *fenceA, config.externalType, handle);
1783 const vk::Unique<vk::VkFence> fenceB (createAndImportFence(vkd, *device, config.externalType, handle, flags));
1785 submitDummySignal(vkd, queue, *fenceA);
1786 VK_CHECK(vkd.waitForFences(*device, 1u, &*fenceB, VK_TRUE, ~0ull));
1788 VK_CHECK(vkd.queueWaitIdle(queue));
1790 return tcu::TestStatus::pass("Pass");
1794 tcu::TestStatus testFenceSignalImport (Context& context,
1795 const FenceTestConfig config)
1797 const Transference transference (getHandelTypeTransferences(config.externalType));
1798 const vk::PlatformInterface& vkp (context.getPlatformInterface());
1799 const vk::Unique<vk::VkInstance> instance (createInstance(vkp, 0u, 0u, config.externalType));
1800 const vk::InstanceDriver vki (vkp, *instance);
1801 const vk::VkPhysicalDevice physicalDevice (vk::chooseDevice(vki, *instance, context.getTestContext().getCommandLine()));
1802 const deUint32 queueFamilyIndex (chooseQueueFamilyIndex(vki, physicalDevice, 0u));
1804 checkFenceSupport(vki, physicalDevice, config.externalType);
1807 const vk::VkFenceImportFlagsKHR flags = config.permanence == PERMANENCE_TEMPORARY ? vk::VK_FENCE_IMPORT_TEMPORARY_BIT_KHR : (vk::VkFenceImportFlagBitsKHR)0u;
1808 const vk::Unique<vk::VkDevice> device (createDevice(vki, physicalDevice, 0u, 0u, config.externalType, queueFamilyIndex));
1809 const vk::DeviceDriver vkd (vki, *device);
1810 const vk::VkQueue queue (getQueue(vkd, *device, queueFamilyIndex));
1812 const vk::Unique<vk::VkFence> fenceA (createExportableFence(vkd, *device, config.externalType));
1813 const vk::Unique<vk::VkFence> fenceB (createFence(vkd, *device));
1814 NativeHandle handle;
1816 submitDummySignal(vkd, queue, *fenceB);
1817 VK_CHECK(vkd.queueWaitIdle(queue));
1819 if (transference == TRANSFERENCE_COPY)
1820 submitDummySignal(vkd, queue, *fenceA);
1822 getFenceNative(vkd, *device, *fenceA, config.externalType, handle);
1824 importFence(vkd, *device, *fenceB, config.externalType, handle, flags);
1826 if (transference == TRANSFERENCE_COPY)
1827 VK_CHECK(vkd.waitForFences(*device, 1u, &*fenceB, VK_TRUE, ~0ull));
1828 else if (transference == TRANSFERENCE_REFERENCE)
1830 submitDummySignal(vkd, queue, *fenceA);
1831 VK_CHECK(vkd.waitForFences(*device, 1u, &*fenceB, VK_TRUE, ~0ull));
1834 DE_FATAL("Unknown transference.");
1836 VK_CHECK(vkd.queueWaitIdle(queue));
1838 return tcu::TestStatus::pass("Pass");
1842 tcu::TestStatus testFenceReset (Context& context,
1843 const FenceTestConfig config)
1845 const Transference transference (getHandelTypeTransferences(config.externalType));
1846 const vk::PlatformInterface& vkp (context.getPlatformInterface());
1847 const vk::Unique<vk::VkInstance> instance (createInstance(vkp, 0u, 0u, config.externalType));
1848 const vk::InstanceDriver vki (vkp, *instance);
1849 const vk::VkPhysicalDevice physicalDevice (vk::chooseDevice(vki, *instance, context.getTestContext().getCommandLine()));
1850 const deUint32 queueFamilyIndex (chooseQueueFamilyIndex(vki, physicalDevice, 0u));
1852 checkFenceSupport(vki, physicalDevice, config.externalType);
1855 const vk::VkFenceImportFlagsKHR flags = config.permanence == PERMANENCE_TEMPORARY ? vk::VK_FENCE_IMPORT_TEMPORARY_BIT_KHR : (vk::VkFenceImportFlagBitsKHR)0u;
1856 const vk::Unique<vk::VkDevice> device (createDevice(vki, physicalDevice, 0u, 0u, config.externalType, queueFamilyIndex));
1857 const vk::DeviceDriver vkd (vki, *device);
1858 const vk::VkQueue queue (getQueue(vkd, *device, queueFamilyIndex));
1860 const vk::Unique<vk::VkFence> fenceA (createExportableFence(vkd, *device, config.externalType));
1861 const vk::Unique<vk::VkFence> fenceB (createFence(vkd, *device));
1862 const vk::Unique<vk::VkFence> fenceC (createFence(vkd, *device));
1863 NativeHandle handle;
1865 submitDummySignal(vkd, queue, *fenceB);
1866 VK_CHECK(vkd.queueWaitIdle(queue));
1868 submitDummySignal(vkd, queue, *fenceA);
1870 getFenceNative(vkd, *device, *fenceA, config.externalType, handle);
1872 NativeHandle handleB (handle);
1873 importFence(vkd, *device, *fenceB, config.externalType, handleB, flags);
1875 importFence(vkd, *device, *fenceC, config.externalType, handle, flags);
1877 VK_CHECK(vkd.queueWaitIdle(queue));
1878 VK_CHECK(vkd.resetFences(*device, 1u, &*fenceB));
1880 if (config.permanence == PERMANENCE_TEMPORARY || transference == TRANSFERENCE_COPY)
1882 // vkResetFences() should restore fenceBs prior payload and reset that no affecting fenceCs payload
1883 // or fenceB should be separate copy of the payload and not affect fenceC
1884 VK_CHECK(vkd.waitForFences(*device, 1u, &*fenceC, VK_TRUE, ~0ull));
1886 // vkResetFences() should have restored fenceBs prior state and should be now reset
1887 // or fenceB should have it's separate payload
1888 submitDummySignal(vkd, queue, *fenceB);
1889 VK_CHECK(vkd.waitForFences(*device, 1u, &*fenceB, VK_TRUE, ~0ull));
1891 else if (config.permanence == PERMANENCE_PERMANENT)
1893 DE_ASSERT(transference == TRANSFERENCE_REFERENCE);
1895 // Reset fences should have reset all of the fences
1896 submitDummySignal(vkd, queue, *fenceC);
1898 VK_CHECK(vkd.waitForFences(*device, 1u, &*fenceA, VK_TRUE, ~0ull));
1899 VK_CHECK(vkd.waitForFences(*device, 1u, &*fenceB, VK_TRUE, ~0ull));
1900 VK_CHECK(vkd.waitForFences(*device, 1u, &*fenceC, VK_TRUE, ~0ull));
1903 DE_FATAL("Unknown permanence");
1905 VK_CHECK(vkd.queueWaitIdle(queue));
1907 return tcu::TestStatus::pass("Pass");
1911 tcu::TestStatus testFenceSignalWaitImport (Context& context,
1912 const FenceTestConfig config)
1914 const Transference transference (getHandelTypeTransferences(config.externalType));
1915 const vk::PlatformInterface& vkp (context.getPlatformInterface());
1916 const vk::Unique<vk::VkInstance> instance (createInstance(vkp, 0u, 0u, config.externalType));
1917 const vk::InstanceDriver vki (vkp, *instance);
1918 const vk::VkPhysicalDevice physicalDevice (vk::chooseDevice(vki, *instance, context.getTestContext().getCommandLine()));
1919 const deUint32 queueFamilyIndex (chooseQueueFamilyIndex(vki, physicalDevice, 0u));
1921 checkFenceSupport(vki, physicalDevice, config.externalType);
1924 const vk::VkFenceImportFlagsKHR flags = config.permanence == PERMANENCE_TEMPORARY ? vk::VK_FENCE_IMPORT_TEMPORARY_BIT_KHR : (vk::VkFenceImportFlagBitsKHR)0u;
1925 const vk::Unique<vk::VkDevice> device (createDevice(vki, physicalDevice, 0u, 0u, config.externalType, queueFamilyIndex));
1926 const vk::DeviceDriver vkd (vki, *device);
1927 const vk::VkQueue queue (getQueue(vkd, *device, queueFamilyIndex));
1929 const vk::Unique<vk::VkFence> fenceA (createExportableFence(vkd, *device, config.externalType));
1930 const vk::Unique<vk::VkFence> fenceB (createFence(vkd, *device));
1931 NativeHandle handle;
1933 if (transference == TRANSFERENCE_COPY)
1934 submitDummySignal(vkd, queue, *fenceA);
1936 getFenceNative(vkd, *device, *fenceA, config.externalType, handle);
1938 submitDummySignal(vkd, queue, *fenceB);
1939 VK_CHECK(vkd.waitForFences(*device, 1u, &*fenceB, VK_TRUE, ~0ull));
1941 VK_CHECK(vkd.queueWaitIdle(queue));
1943 importFence(vkd, *device, *fenceB, config.externalType, handle, flags);
1945 if (transference == TRANSFERENCE_COPY)
1946 VK_CHECK(vkd.waitForFences(*device, 1u, &*fenceB, VK_TRUE, ~0ull));
1947 else if (transference == TRANSFERENCE_REFERENCE)
1949 submitDummySignal(vkd, queue, *fenceA);
1950 VK_CHECK(vkd.waitForFences(*device, 1u, &*fenceB, VK_TRUE, ~0ull));
1953 DE_FATAL("Unknown transference.");
1955 VK_CHECK(vkd.queueWaitIdle(queue));
1957 return tcu::TestStatus::pass("Pass");
1961 tcu::TestStatus testFenceMultipleExports (Context& context,
1962 const FenceTestConfig config)
1964 const size_t exportCount = 4 * 1024;
1965 const Transference transference (getHandelTypeTransferences(config.externalType));
1966 const vk::PlatformInterface& vkp (context.getPlatformInterface());
1967 const vk::Unique<vk::VkInstance> instance (createInstance(vkp, 0u, 0u, config.externalType));
1968 const vk::InstanceDriver vki (vkp, *instance);
1969 const vk::VkPhysicalDevice physicalDevice (vk::chooseDevice(vki, *instance, context.getTestContext().getCommandLine()));
1970 const deUint32 queueFamilyIndex (chooseQueueFamilyIndex(vki, physicalDevice, 0u));
1972 checkFenceSupport(vki, physicalDevice, config.externalType);
1975 const vk::Unique<vk::VkDevice> device (createDevice(vki, physicalDevice, 0u, 0u, config.externalType, queueFamilyIndex));
1976 const vk::DeviceDriver vkd (vki, *device);
1977 const vk::VkQueue queue (getQueue(vkd, *device, queueFamilyIndex));
1978 const vk::Unique<vk::VkFence> fence (createExportableFence(vkd, *device, config.externalType));
1980 for (size_t exportNdx = 0; exportNdx < exportCount; exportNdx++)
1982 NativeHandle handle;
1984 if (transference == TRANSFERENCE_COPY)
1985 submitDummySignal(vkd, queue, *fence);
1987 getFenceNative(vkd, *device, *fence, config.externalType, handle);
1990 submitDummySignal(vkd, queue, *fence);
1991 VK_CHECK(vkd.waitForFences(*device, 1u, &*fence, VK_TRUE, ~0ull));
1993 VK_CHECK(vkd.queueWaitIdle(queue));
1996 return tcu::TestStatus::pass("Pass");
1999 tcu::TestStatus testFenceMultipleImports (Context& context,
2000 const FenceTestConfig config)
2002 const size_t importCount = 4 * 1024;
2003 const Transference transference (getHandelTypeTransferences(config.externalType));
2004 const vk::PlatformInterface& vkp (context.getPlatformInterface());
2005 const vk::Unique<vk::VkInstance> instance (createInstance(vkp, 0u, 0u, config.externalType));
2006 const vk::InstanceDriver vki (vkp, *instance);
2007 const vk::VkPhysicalDevice physicalDevice (vk::chooseDevice(vki, *instance, context.getTestContext().getCommandLine()));
2008 const deUint32 queueFamilyIndex (chooseQueueFamilyIndex(vki, physicalDevice, 0u));
2010 checkFenceSupport(vki, physicalDevice, config.externalType);
2013 const vk::VkFenceImportFlagsKHR flags = config.permanence == PERMANENCE_TEMPORARY ? vk::VK_FENCE_IMPORT_TEMPORARY_BIT_KHR : (vk::VkFenceImportFlagBitsKHR)0u;
2014 const vk::Unique<vk::VkDevice> device (createDevice(vki, physicalDevice, 0u, 0u, config.externalType, queueFamilyIndex));
2015 const vk::DeviceDriver vkd (vki, *device);
2016 const vk::VkQueue queue (getQueue(vkd, *device, queueFamilyIndex));
2017 const vk::Unique<vk::VkFence> fenceA (createExportableFence(vkd, *device, config.externalType));
2018 NativeHandle handleA;
2020 if (transference == TRANSFERENCE_COPY)
2021 submitDummySignal(vkd, queue, *fenceA);
2023 getFenceNative(vkd, *device, *fenceA, config.externalType, handleA);
2025 for (size_t importNdx = 0; importNdx < importCount; importNdx++)
2027 NativeHandle handleB (handleA);
2028 const vk::Unique<vk::VkFence> fenceB (createAndImportFence(vkd, *device, config.externalType, handleB, flags));
2031 if (transference == TRANSFERENCE_COPY)
2033 importFence(vkd, *device, *fenceA, config.externalType, handleA, flags);
2034 VK_CHECK(vkd.waitForFences(*device, 1u, &*fenceA, VK_TRUE, ~0ull));
2036 else if (transference == TRANSFERENCE_REFERENCE)
2038 submitDummySignal(vkd, queue, *fenceA);
2039 VK_CHECK(vkd.waitForFences(*device, 1u, &*fenceA, VK_TRUE, ~0ull));
2042 DE_FATAL("Unknown transference.");
2044 VK_CHECK(vkd.queueWaitIdle(queue));
2047 return tcu::TestStatus::pass("Pass");
2050 tcu::TestStatus testFenceTransference (Context& context,
2051 const FenceTestConfig config)
2053 const Transference transference (getHandelTypeTransferences(config.externalType));
2054 const vk::PlatformInterface& vkp (context.getPlatformInterface());
2055 const vk::Unique<vk::VkInstance> instance (createInstance(vkp, 0u, 0u, config.externalType));
2056 const vk::InstanceDriver vki (vkp, *instance);
2057 const vk::VkPhysicalDevice physicalDevice (vk::chooseDevice(vki, *instance, context.getTestContext().getCommandLine()));
2058 const deUint32 queueFamilyIndex (chooseQueueFamilyIndex(vki, physicalDevice, 0u));
2060 checkFenceSupport(vki, physicalDevice, config.externalType);
2063 const vk::VkFenceImportFlagsKHR flags = config.permanence == PERMANENCE_TEMPORARY ? vk::VK_FENCE_IMPORT_TEMPORARY_BIT_KHR : (vk::VkFenceImportFlagBitsKHR)0u;
2064 const vk::Unique<vk::VkDevice> device (createDevice(vki, physicalDevice, 0u, 0u, config.externalType, queueFamilyIndex));
2065 const vk::DeviceDriver vkd (vki, *device);
2066 const vk::VkQueue queue (getQueue(vkd, *device, queueFamilyIndex));
2068 const vk::Unique<vk::VkFence> fenceA (createExportableFence(vkd, *device, config.externalType));
2069 NativeHandle handle;
2071 submitDummySignal(vkd, queue, *fenceA);
2073 getFenceNative(vkd, *device, *fenceA, config.externalType, handle);
2076 const vk::Unique<vk::VkFence> fenceB (createAndImportFence(vkd, *device, config.externalType, handle, flags));
2078 if (config.permanence == PERMANENCE_PERMANENT)
2080 if (transference == TRANSFERENCE_COPY)
2082 submitDummySignal(vkd, queue, *fenceA);
2083 VK_CHECK(vkd.waitForFences(*device, 1u, &*fenceB, VK_TRUE, ~0ull));
2084 VK_CHECK(vkd.queueWaitIdle(queue));
2086 VK_CHECK(vkd.resetFences(*device, 1u, &*fenceB));
2087 submitDummySignal(vkd, queue, *fenceB);
2089 VK_CHECK(vkd.waitForFences(*device, 1u, &*fenceA, VK_TRUE, ~0ull));
2090 VK_CHECK(vkd.waitForFences(*device, 1u, &*fenceB, VK_TRUE, ~0ull));
2091 VK_CHECK(vkd.queueWaitIdle(queue));
2093 else if (transference== TRANSFERENCE_REFERENCE)
2095 VK_CHECK(vkd.waitForFences(*device, 1u, &*fenceB, VK_TRUE, ~0ull));
2096 VK_CHECK(vkd.queueWaitIdle(queue));
2098 VK_CHECK(vkd.resetFences(*device, 1u, &*fenceB));
2099 submitDummySignal(vkd, queue, *fenceA);
2100 VK_CHECK(vkd.waitForFences(*device, 1u, &*fenceB, VK_TRUE, ~0ull));
2102 VK_CHECK(vkd.resetFences(*device, 1u, &*fenceA));
2103 submitDummySignal(vkd, queue, *fenceB);
2104 VK_CHECK(vkd.waitForFences(*device, 1u, &*fenceA, VK_TRUE, ~0ull));
2105 VK_CHECK(vkd.queueWaitIdle(queue));
2108 DE_FATAL("Unknown transference.");
2110 else if (config.permanence == PERMANENCE_TEMPORARY)
2112 if (transference == TRANSFERENCE_COPY)
2114 submitDummySignal(vkd, queue, *fenceA);
2115 VK_CHECK(vkd.waitForFences(*device, 1u, &*fenceB, VK_TRUE, ~0ull));
2116 VK_CHECK(vkd.queueWaitIdle(queue));
2118 VK_CHECK(vkd.resetFences(*device, 1u, &*fenceB));
2119 submitDummySignal(vkd, queue, *fenceB);
2121 VK_CHECK(vkd.waitForFences(*device, 1u, &*fenceA, VK_TRUE, ~0ull));
2122 VK_CHECK(vkd.waitForFences(*device, 1u, &*fenceB, VK_TRUE, ~0ull));
2123 VK_CHECK(vkd.queueWaitIdle(queue));
2125 else if (transference == TRANSFERENCE_REFERENCE)
2127 VK_CHECK(vkd.waitForFences(*device, 1u, &*fenceB, VK_TRUE, ~0ull));
2128 VK_CHECK(vkd.queueWaitIdle(queue));
2130 VK_CHECK(vkd.resetFences(*device, 1u, &*fenceA));
2131 VK_CHECK(vkd.resetFences(*device, 1u, &*fenceB));
2132 submitDummySignal(vkd, queue, *fenceA);
2133 submitDummySignal(vkd, queue, *fenceB);
2135 VK_CHECK(vkd.waitForFences(*device, 1u, &*fenceB, VK_TRUE, ~0ull));
2136 VK_CHECK(vkd.waitForFences(*device, 1u, &*fenceA, VK_TRUE, ~0ull));
2137 VK_CHECK(vkd.queueWaitIdle(queue));
2140 DE_FATAL("Unknown transference.");
2143 DE_FATAL("Unknown permanence.");
2146 return tcu::TestStatus::pass("Pass");
2150 tcu::TestStatus testFenceFdDup (Context& context,
2151 const FenceTestConfig config)
2153 #if (DE_OS == DE_OS_ANDROID) || (DE_OS == DE_OS_UNIX)
2154 const Transference transference (getHandelTypeTransferences(config.externalType));
2155 const vk::PlatformInterface& vkp (context.getPlatformInterface());
2156 const vk::Unique<vk::VkInstance> instance (createInstance(vkp, 0u, 0u, config.externalType));
2157 const vk::InstanceDriver vki (vkp, *instance);
2158 const vk::VkPhysicalDevice physicalDevice (vk::chooseDevice(vki, *instance, context.getTestContext().getCommandLine()));
2159 const deUint32 queueFamilyIndex (chooseQueueFamilyIndex(vki, physicalDevice, 0u));
2161 checkFenceSupport(vki, physicalDevice, config.externalType);
2164 const vk::VkFenceImportFlagsKHR flags = config.permanence == PERMANENCE_TEMPORARY ? vk::VK_FENCE_IMPORT_TEMPORARY_BIT_KHR : (vk::VkFenceImportFlagBitsKHR)0u;
2165 const vk::Unique<vk::VkDevice> device (createDevice(vki, physicalDevice, 0u, 0u, config.externalType, queueFamilyIndex));
2166 const vk::DeviceDriver vkd (vki, *device);
2167 const vk::VkQueue queue (getQueue(vkd, *device, queueFamilyIndex));
2169 TestLog& log = context.getTestContext().getLog();
2170 const vk::Unique<vk::VkFence> fenceA (createExportableFence(vkd, *device, config.externalType));
2172 if (transference == TRANSFERENCE_COPY)
2173 submitDummySignal(vkd, queue, *fenceA);
2176 const NativeHandle fd (getFenceFd(vkd, *device, *fenceA, config.externalType));
2177 NativeHandle newFd (dup(fd.getFd()));
2179 if (newFd.getFd() < 0)
2180 log << TestLog::Message << "dup() failed: '" << strerror(errno) << "'" << TestLog::EndMessage;
2182 TCU_CHECK_MSG(newFd.getFd() >= 0, "Failed to call dup() for fences fd");
2185 const vk::Unique<vk::VkFence> fenceB (createAndImportFence(vkd, *device, config.externalType, newFd, flags));
2187 if (transference == TRANSFERENCE_COPY)
2188 VK_CHECK(vkd.waitForFences(*device, 1u, &*fenceB, VK_TRUE, ~0ull));
2189 else if (transference == TRANSFERENCE_REFERENCE)
2191 submitDummySignal(vkd, queue, *fenceA);
2192 VK_CHECK(vkd.waitForFences(*device, 1u, &*fenceB, VK_TRUE, ~0ull));
2195 DE_FATAL("Unknown permanence.");
2199 VK_CHECK(vkd.queueWaitIdle(queue));
2201 return tcu::TestStatus::pass("Pass");
2206 TCU_THROW(NotSupportedError, "Platform doesn't support dup()");
2210 tcu::TestStatus testFenceFdDup2 (Context& context,
2211 const FenceTestConfig config)
2213 #if (DE_OS == DE_OS_ANDROID) || (DE_OS == DE_OS_UNIX)
2214 const Transference transference (getHandelTypeTransferences(config.externalType));
2215 const vk::PlatformInterface& vkp (context.getPlatformInterface());
2216 const vk::Unique<vk::VkInstance> instance (createInstance(vkp, 0u, 0u, config.externalType));
2217 const vk::InstanceDriver vki (vkp, *instance);
2218 const vk::VkPhysicalDevice physicalDevice (vk::chooseDevice(vki, *instance, context.getTestContext().getCommandLine()));
2219 const deUint32 queueFamilyIndex (chooseQueueFamilyIndex(vki, physicalDevice, 0u));
2221 checkFenceSupport(vki, physicalDevice, config.externalType);
2224 const vk::VkFenceImportFlagsKHR flags = config.permanence == PERMANENCE_TEMPORARY ? vk::VK_FENCE_IMPORT_TEMPORARY_BIT_KHR : (vk::VkFenceImportFlagBitsKHR)0u;
2225 const vk::Unique<vk::VkDevice> device (createDevice(vki, physicalDevice, 0u, 0u, config.externalType, queueFamilyIndex));
2226 const vk::DeviceDriver vkd (vki, *device);
2227 const vk::VkQueue queue (getQueue(vkd, *device, queueFamilyIndex));
2229 TestLog& log = context.getTestContext().getLog();
2230 const vk::Unique<vk::VkFence> fenceA (createExportableFence(vkd, *device, config.externalType));
2231 const vk::Unique<vk::VkFence> fenceB (createExportableFence(vkd, *device, config.externalType));
2233 if (transference == TRANSFERENCE_COPY)
2235 submitDummySignal(vkd, queue, *fenceA);
2236 submitDummySignal(vkd, queue, *fenceB);
2240 const NativeHandle fd (getFenceFd(vkd, *device, *fenceA, config.externalType));
2241 NativeHandle secondFd (getFenceFd(vkd, *device, *fenceB, config.externalType));
2242 int newFd (dup2(fd.getFd(), secondFd.getFd()));
2245 log << TestLog::Message << "dup2() failed: '" << strerror(errno) << "'" << TestLog::EndMessage;
2247 TCU_CHECK_MSG(newFd >= 0, "Failed to call dup2() for fences fd");
2250 const vk::Unique<vk::VkFence> fenceC (createAndImportFence(vkd, *device, config.externalType, secondFd, flags));
2252 if (transference == TRANSFERENCE_COPY)
2253 VK_CHECK(vkd.waitForFences(*device, 1u, &*fenceC, VK_TRUE, ~0ull));
2254 else if (transference == TRANSFERENCE_REFERENCE)
2256 submitDummySignal(vkd, queue, *fenceA);
2257 VK_CHECK(vkd.waitForFences(*device, 1u, &*fenceC, VK_TRUE, ~0ull));
2260 DE_FATAL("Unknown permanence.");
2264 VK_CHECK(vkd.queueWaitIdle(queue));
2266 return tcu::TestStatus::pass("Pass");
2271 TCU_THROW(NotSupportedError, "Platform doesn't support dup2()");
2275 tcu::TestStatus testFenceFdDup3 (Context& context,
2276 const FenceTestConfig config)
2278 #if (DE_OS == DE_OS_UNIX) && defined(_GNU_SOURCE)
2279 const Transference transference (getHandelTypeTransferences(config.externalType));
2280 const vk::PlatformInterface& vkp (context.getPlatformInterface());
2281 const vk::Unique<vk::VkInstance> instance (createInstance(vkp, 0u, 0u, config.externalType));
2282 const vk::InstanceDriver vki (vkp, *instance);
2283 const vk::VkPhysicalDevice physicalDevice (vk::chooseDevice(vki, *instance, context.getTestContext().getCommandLine()));
2284 const deUint32 queueFamilyIndex (chooseQueueFamilyIndex(vki, physicalDevice, 0u));
2286 checkFenceSupport(vki, physicalDevice, config.externalType);
2289 const vk::Unique<vk::VkDevice> device (createDevice(vki, physicalDevice, 0u, 0u, config.externalType, queueFamilyIndex));
2290 const vk::DeviceDriver vkd (vki, *device);
2291 const vk::VkQueue queue (getQueue(vkd, *device, queueFamilyIndex));
2293 TestLog& log = context.getTestContext().getLog();
2294 const vk::Unique<vk::VkFence> fenceA (createExportableFence(vkd, *device, config.externalType));
2295 const vk::Unique<vk::VkFence> fenceB (createExportableFence(vkd, *device, config.externalType));
2297 if (transference == TRANSFERENCE_COPY)
2299 submitDummySignal(vkd, queue, *fenceA);
2300 submitDummySignal(vkd, queue, *fenceB);
2304 const vk::VkFenceImportFlagsKHR flags = config.permanence == PERMANENCE_TEMPORARY ? vk::VK_FENCE_IMPORT_TEMPORARY_BIT_KHR : (vk::VkFenceImportFlagBitsKHR)0u;
2305 const NativeHandle fd (getFenceFd(vkd, *device, *fenceA, config.externalType));
2306 NativeHandle secondFd (getFenceFd(vkd, *device, *fenceB, config.externalType));
2307 const int newFd (dup3(fd.getFd(), secondFd.getFd(), 0));
2310 log << TestLog::Message << "dup3() failed: '" << strerror(errno) << "'" << TestLog::EndMessage;
2312 TCU_CHECK_MSG(newFd >= 0, "Failed to call dup3() for fences fd");
2315 const vk::Unique<vk::VkFence> fenceC (createAndImportFence(vkd, *device, config.externalType, secondFd, flags));
2317 if (transference == TRANSFERENCE_COPY)
2318 VK_CHECK(vkd.waitForFences(*device, 1u, &*fenceC, VK_TRUE, ~0ull));
2319 else if (transference == TRANSFERENCE_REFERENCE)
2321 submitDummySignal(vkd, queue, *fenceA);
2322 VK_CHECK(vkd.waitForFences(*device, 1u, &*fenceC, VK_TRUE, ~0ull));
2325 DE_FATAL("Unknown permanence.");
2329 VK_CHECK(vkd.queueWaitIdle(queue));
2331 return tcu::TestStatus::pass("Pass");
2336 TCU_THROW(NotSupportedError, "Platform doesn't support dup3()");
2340 tcu::TestStatus testFenceFdSendOverSocket (Context& context,
2341 const FenceTestConfig config)
2343 #if (DE_OS == DE_OS_ANDROID) || (DE_OS == DE_OS_UNIX)
2344 const Transference transference (getHandelTypeTransferences(config.externalType));
2345 const vk::PlatformInterface& vkp (context.getPlatformInterface());
2346 const vk::Unique<vk::VkInstance> instance (createInstance(vkp, 0u, 0u, config.externalType));
2347 const vk::InstanceDriver vki (vkp, *instance);
2348 const vk::VkPhysicalDevice physicalDevice (vk::chooseDevice(vki, *instance, context.getTestContext().getCommandLine()));
2349 const deUint32 queueFamilyIndex (chooseQueueFamilyIndex(vki, physicalDevice, 0u));
2351 checkFenceSupport(vki, physicalDevice, config.externalType);
2354 const vk::Unique<vk::VkDevice> device (createDevice(vki, physicalDevice, 0u, 0u, config.externalType, queueFamilyIndex));
2355 const vk::DeviceDriver vkd (vki, *device);
2356 const vk::VkQueue queue (getQueue(vkd, *device, queueFamilyIndex));
2358 TestLog& log = context.getTestContext().getLog();
2359 const vk::Unique<vk::VkFence> fence (createExportableFence(vkd, *device, config.externalType));
2361 if (transference == TRANSFERENCE_COPY)
2362 submitDummySignal(vkd, queue, *fence);
2364 const NativeHandle fd (getFenceFd(vkd, *device, *fence, config.externalType));
2369 if (socketpair(AF_UNIX, SOCK_STREAM, 0, sv) != 0)
2371 log << TestLog::Message << "Failed to create socket pair: '" << strerror(errno) << "'" << TestLog::EndMessage;
2372 TCU_FAIL("Failed to create socket pair");
2376 const NativeHandle srcSocket (sv[0]);
2377 const NativeHandle dstSocket (sv[1]);
2378 std::string sendData ("deqp");
2382 const int fdRaw (fd.getFd());
2385 char buffer[CMSG_SPACE(sizeof(int))];
2386 iovec iov = { &sendData[0], sendData.length()};
2388 deMemset(&msg, 0, sizeof(msg));
2390 msg.msg_control = buffer;
2391 msg.msg_controllen = sizeof(buffer);
2395 cmsg = CMSG_FIRSTHDR(&msg);
2396 cmsg->cmsg_level = SOL_SOCKET;
2397 cmsg->cmsg_type = SCM_RIGHTS;
2398 cmsg->cmsg_len = CMSG_LEN(sizeof(int));
2400 deMemcpy(CMSG_DATA(cmsg), &fdRaw, sizeof(int));
2401 msg.msg_controllen = cmsg->cmsg_len;
2403 if (sendmsg(srcSocket.getFd(), &msg, 0) < 0)
2405 log << TestLog::Message << "Failed to send fd over socket: '" << strerror(errno) << "'" << TestLog::EndMessage;
2406 TCU_FAIL("Failed to send fd over socket");
2413 char buffer[CMSG_SPACE(sizeof(int))];
2414 std::string recvData (4, '\0');
2415 iovec iov = { &recvData[0], recvData.length() };
2417 deMemset(&msg, 0, sizeof(msg));
2419 msg.msg_control = buffer;
2420 msg.msg_controllen = sizeof(buffer);
2424 const ssize_t bytes = recvmsg(dstSocket.getFd(), &msg, 0);
2428 log << TestLog::Message << "Failed to recv fd over socket: '" << strerror(errno) << "'" << TestLog::EndMessage;
2429 TCU_FAIL("Failed to recv fd over socket");
2432 else if (bytes != (ssize_t)sendData.length())
2434 TCU_FAIL("recvmsg() returned unpexpected number of bytes");
2438 const vk::VkFenceImportFlagsKHR flags = config.permanence == PERMANENCE_TEMPORARY ? vk::VK_FENCE_IMPORT_TEMPORARY_BIT_KHR : (vk::VkFenceImportFlagBitsKHR)0u;
2439 const cmsghdr* const cmsg = CMSG_FIRSTHDR(&msg);
2441 deMemcpy(&newFd_, CMSG_DATA(cmsg), sizeof(int));
2442 NativeHandle newFd (newFd_);
2444 TCU_CHECK(cmsg->cmsg_level == SOL_SOCKET);
2445 TCU_CHECK(cmsg->cmsg_type == SCM_RIGHTS);
2446 TCU_CHECK(cmsg->cmsg_len == CMSG_LEN(sizeof(int)));
2447 TCU_CHECK(recvData == sendData);
2448 TCU_CHECK_MSG(newFd.getFd() >= 0, "Didn't receive valid fd from socket");
2451 const vk::Unique<vk::VkFence> newFence (createAndImportFence(vkd, *device, config.externalType, newFd, flags));
2453 if (transference == TRANSFERENCE_COPY)
2454 VK_CHECK(vkd.waitForFences(*device, 1u, &*newFence, VK_TRUE, ~0ull));
2455 else if (transference == TRANSFERENCE_REFERENCE)
2457 submitDummySignal(vkd, queue, *newFence);
2458 VK_CHECK(vkd.waitForFences(*device, 1u, &*newFence, VK_TRUE, ~0ull));
2461 DE_FATAL("Unknown permanence.");
2463 VK_CHECK(vkd.queueWaitIdle(queue));
2471 return tcu::TestStatus::pass("Pass");
2475 TCU_THROW(NotSupportedError, "Platform doesn't support sending file descriptors over socket");
2479 tcu::TestStatus testBufferQueries (Context& context, vk::VkExternalMemoryHandleTypeFlagBitsKHR externalType)
2481 const vk::VkBufferCreateFlags createFlags[] =
2484 vk::VK_BUFFER_CREATE_SPARSE_BINDING_BIT,
2485 vk::VK_BUFFER_CREATE_SPARSE_BINDING_BIT|vk::VK_BUFFER_CREATE_SPARSE_RESIDENCY_BIT,
2486 vk::VK_BUFFER_CREATE_SPARSE_BINDING_BIT|vk::VK_BUFFER_CREATE_SPARSE_ALIASED_BIT
2488 const vk::VkBufferUsageFlags usageFlags[] =
2490 vk::VK_BUFFER_USAGE_TRANSFER_SRC_BIT,
2491 vk::VK_BUFFER_USAGE_TRANSFER_DST_BIT,
2492 vk::VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT,
2493 vk::VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT,
2494 vk::VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT,
2495 vk::VK_BUFFER_USAGE_STORAGE_BUFFER_BIT,
2496 vk::VK_BUFFER_USAGE_INDEX_BUFFER_BIT,
2497 vk::VK_BUFFER_USAGE_VERTEX_BUFFER_BIT,
2498 vk::VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT
2500 const vk::PlatformInterface& vkp (context.getPlatformInterface());
2501 const vk::Unique<vk::VkInstance> instance (createInstance(vkp, 0u, externalType, 0u));
2502 const vk::InstanceDriver vki (vkp, *instance);
2503 const vk::VkPhysicalDevice physicalDevice (vk::chooseDevice(vki, *instance, context.getTestContext().getCommandLine()));
2504 const vk::VkPhysicalDeviceFeatures deviceFeatures (vk::getPhysicalDeviceFeatures(vki, physicalDevice));
2505 const deUint32 queueFamilyIndex (chooseQueueFamilyIndex(vki, physicalDevice, 0u));
2507 // VkDevice is only created if physical device claims to support any of these types.
2508 vk::Move<vk::VkDevice> device;
2509 de::MovePtr<vk::DeviceDriver> vkd;
2510 bool deviceHasDedicated = false;
2512 TestLog& log = context.getTestContext().getLog();
2514 for (size_t createFlagNdx = 0; createFlagNdx < DE_LENGTH_OF_ARRAY(createFlags); createFlagNdx++)
2515 for (size_t usageFlagNdx = 0; usageFlagNdx < DE_LENGTH_OF_ARRAY(usageFlags); usageFlagNdx++)
2517 const vk::VkBufferViewCreateFlags createFlag = createFlags[createFlagNdx];
2518 const vk::VkBufferUsageFlags usageFlag = usageFlags[usageFlagNdx];
2519 const vk::VkPhysicalDeviceExternalBufferInfoKHR info =
2521 vk::VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_BUFFER_INFO_KHR,
2527 vk::VkExternalBufferPropertiesKHR properties =
2529 vk::VK_STRUCTURE_TYPE_EXTERNAL_BUFFER_PROPERTIES_KHR,
2534 if (((createFlag & vk::VK_BUFFER_CREATE_SPARSE_BINDING_BIT) != 0) &&
2535 (deviceFeatures.sparseBinding == VK_FALSE))
2538 if (((createFlag & vk::VK_BUFFER_CREATE_SPARSE_ALIASED_BIT) != 0) &&
2539 (deviceFeatures.sparseResidencyAliased == VK_FALSE))
2542 if (((createFlag & vk::VK_BUFFER_CREATE_SPARSE_RESIDENCY_BIT) != 0) &&
2543 (deviceFeatures.sparseResidencyBuffer == VK_FALSE))
2546 vki.getPhysicalDeviceExternalBufferPropertiesKHR(physicalDevice, &info, &properties);
2548 log << TestLog::Message << properties << TestLog::EndMessage;
2550 TCU_CHECK(properties.sType == vk::VK_STRUCTURE_TYPE_EXTERNAL_BUFFER_PROPERTIES_KHR);
2551 TCU_CHECK(properties.pNext == DE_NULL);
2552 // \todo [2017-06-06 pyry] Can we validate anything else? Compatible types?
2554 if ((properties.externalMemoryProperties.externalMemoryFeatures & (vk::VK_EXTERNAL_MEMORY_FEATURE_EXPORTABLE_BIT_KHR|vk::VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT_KHR)) != 0)
2556 const bool requiresDedicated = (properties.externalMemoryProperties.externalMemoryFeatures & vk::VK_EXTERNAL_MEMORY_FEATURE_DEDICATED_ONLY_BIT_KHR) != 0;
2558 if (!device || (requiresDedicated && !deviceHasDedicated))
2560 // \note We need to re-create with dedicated mem extensions if previous device instance didn't have them
2563 device = createDevice(vki, physicalDevice, 0u, externalType, 0u, queueFamilyIndex, requiresDedicated);
2564 vkd = de::MovePtr<vk::DeviceDriver>(new vk::DeviceDriver(vki, *device));
2565 deviceHasDedicated = requiresDedicated;
2567 catch (const tcu::NotSupportedError& e)
2570 TCU_FAIL("Physical device claims to support handle type but required extensions are not supported");
2575 if ((properties.externalMemoryProperties.externalMemoryFeatures & vk::VK_EXTERNAL_MEMORY_FEATURE_EXPORTABLE_BIT_KHR) != 0)
2577 DE_ASSERT(!!device);
2580 if (deviceHasDedicated)
2582 const vk::Unique<vk::VkBuffer> buffer (createExternalBuffer(*vkd, *device, queueFamilyIndex, externalType, 1024u, createFlag, usageFlag));
2583 const vk::VkMemoryDedicatedRequirementsKHR reqs (getMemoryDedicatedRequirements(*vkd, *device, *buffer));
2584 const bool propertiesRequiresDedicated = (properties.externalMemoryProperties.externalMemoryFeatures & vk::VK_EXTERNAL_MEMORY_FEATURE_DEDICATED_ONLY_BIT_KHR) != 0;
2585 const bool objectRequiresDedicated = (reqs.requiresDedicatedAllocation != VK_FALSE);
2587 if (propertiesRequiresDedicated != objectRequiresDedicated)
2588 TCU_FAIL("vkGetPhysicalDeviceExternalBufferProperties and vkGetBufferMemoryRequirements2 report different dedicated requirements");
2592 // We can't query whether dedicated memory is required or not on per-object basis.
2593 // This check should be redundant as the code above tries to create device with
2594 // VK_KHR_dedicated_allocation & VK_KHR_get_memory_requirements2 if dedicated memory
2595 // is required. However, checking again doesn't hurt.
2596 TCU_CHECK((properties.externalMemoryProperties.externalMemoryFeatures & vk::VK_EXTERNAL_MEMORY_FEATURE_DEDICATED_ONLY_BIT_KHR) == 0);
2601 return tcu::TestStatus::pass("Pass");
2604 struct MemoryTestConfig
2606 MemoryTestConfig (vk::VkExternalMemoryHandleTypeFlagBitsKHR externalType_,
2609 : externalType (externalType_)
2610 , hostVisible (hostVisible_)
2611 , dedicated (dedicated_)
2615 vk::VkExternalMemoryHandleTypeFlagBitsKHR externalType;
2620 #if (DE_OS == DE_OS_WIN32)
2621 deUint32 chooseMemoryType (deUint32 bits)
2624 TCU_THROW(NotSupportedError, "No compatible memory type found");
2626 return deCtz32(bits);
2630 tcu::TestStatus testMemoryWin32Create (Context& context, MemoryTestConfig config)
2632 #if (DE_OS == DE_OS_WIN32)
2633 const vk::PlatformInterface& vkp (context.getPlatformInterface());
2634 const vk::Unique<vk::VkInstance> instance (createInstance(vkp, 0u, config.externalType, 0u));
2635 const vk::InstanceDriver vki (vkp, *instance);
2636 const vk::VkPhysicalDevice physicalDevice (vk::chooseDevice(vki, *instance, context.getTestContext().getCommandLine()));
2637 const deUint32 queueFamilyIndex (chooseQueueFamilyIndex(vki, physicalDevice, 0u));
2638 const vk::Unique<vk::VkDevice> device (createDevice(vki, physicalDevice, 0u, config.externalType, 0u, queueFamilyIndex));
2639 const vk::DeviceDriver vkd (vki, *device);
2640 const vk::VkBufferUsageFlags usage = vk::VK_BUFFER_USAGE_TRANSFER_SRC_BIT|vk::VK_BUFFER_USAGE_TRANSFER_DST_BIT;
2641 const deUint32 seed = 1261033864u;
2642 const vk::VkDeviceSize bufferSize = 1024;
2643 const std::vector<deUint8> testData (genTestData(seed, (size_t)bufferSize));
2645 const vk::VkPhysicalDeviceMemoryProperties memoryProps = vk::getPhysicalDeviceMemoryProperties(context.getInstanceInterface(), context.getPhysicalDevice());
2646 const deUint32 compatibleMemTypes = vk::getCompatibleMemoryTypes(memoryProps, config.hostVisible ? vk::MemoryRequirement::HostVisible : vk::MemoryRequirement::Any);
2648 checkBufferSupport(vki, physicalDevice, config.externalType, 0u, usage, config.dedicated);
2650 // \note Buffer is only allocated to get memory requirements
2651 const vk::Unique<vk::VkBuffer> buffer (createExternalBuffer(vkd, *device, queueFamilyIndex, config.externalType, bufferSize, 0u, usage));
2652 const vk::VkMemoryRequirements requirements (getBufferMemoryRequirements(vkd, *device, *buffer));
2653 const vk::VkExportMemoryWin32HandleInfoKHR win32Info =
2655 vk::VK_STRUCTURE_TYPE_EXPORT_MEMORY_WIN32_HANDLE_INFO_KHR,
2658 (vk::pt::Win32SecurityAttributesPtr)DE_NULL,
2659 DXGI_SHARED_RESOURCE_READ | DXGI_SHARED_RESOURCE_WRITE,
2662 const vk::VkExportMemoryAllocateInfoKHR exportInfo =
2664 vk::VK_STRUCTURE_TYPE_EXPORT_MEMORY_ALLOCATE_INFO_KHR,
2666 (vk::VkExternalMemoryHandleTypeFlagsKHR)config.externalType
2668 const vk::VkMemoryAllocateInfo info =
2670 vk::VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,
2673 chooseMemoryType(requirements.memoryTypeBits & compatibleMemTypes)
2675 const vk::Unique<vk::VkDeviceMemory> memory (vk::allocateMemory(vkd, *device, &info));
2676 NativeHandle handleA;
2678 if (config.hostVisible)
2679 writeHostMemory(vkd, *device, *memory, testData.size(), &testData[0]);
2681 getMemoryNative(vkd, *device, *memory, config.externalType, handleA);
2684 const vk::Unique<vk::VkDeviceMemory> memoryA (importMemory(vkd, *device, requirements, config.externalType, handleA));
2686 if (config.hostVisible)
2688 const std::vector<deUint8> testDataA (genTestData(seed ^ 124798807u, (size_t)bufferSize));
2689 const std::vector<deUint8> testDataB (genTestData(seed ^ 970834278u, (size_t)bufferSize));
2691 checkHostMemory(vkd, *device, *memoryA, testData.size(), &testData[0]);
2692 checkHostMemory(vkd, *device, *memory, testData.size(), &testData[0]);
2694 writeHostMemory(vkd, *device, *memoryA, testDataA.size(), &testDataA[0]);
2695 writeHostMemory(vkd, *device, *memory, testDataA.size(), &testDataB[0]);
2697 checkHostMemory(vkd, *device, *memoryA, testData.size(), &testDataB[0]);
2698 checkHostMemory(vkd, *device, *memory, testData.size(), &testDataB[0]);
2702 return tcu::TestStatus::pass("Pass");
2706 TCU_THROW(NotSupportedError, "Platform doesn't support win32 handles");
2710 tcu::TestStatus testMemoryImportTwice (Context& context, MemoryTestConfig config)
2712 const vk::PlatformInterface& vkp (context.getPlatformInterface());
2713 const vk::Unique<vk::VkInstance> instance (createInstance(vkp, 0u, config.externalType, 0u));
2714 const vk::InstanceDriver vki (vkp, *instance);
2715 const vk::VkPhysicalDevice physicalDevice (vk::chooseDevice(vki, *instance, context.getTestContext().getCommandLine()));
2716 const deUint32 queueFamilyIndex (chooseQueueFamilyIndex(vki, physicalDevice, 0u));
2717 const vk::Unique<vk::VkDevice> device (createDevice(vki, physicalDevice, 0u, config.externalType, 0u, queueFamilyIndex));
2718 const vk::DeviceDriver vkd (vki, *device);
2719 const vk::VkBufferUsageFlags usage = vk::VK_BUFFER_USAGE_TRANSFER_SRC_BIT|vk::VK_BUFFER_USAGE_TRANSFER_DST_BIT;
2720 const deUint32 seed = 1261033864u;
2721 const vk::VkDeviceSize bufferSize = 1024;
2722 const std::vector<deUint8> testData (genTestData(seed, (size_t)bufferSize));
2724 checkBufferSupport(vki, physicalDevice, config.externalType, 0u, usage, config.dedicated);
2726 // \note Buffer is only allocated to get memory requirements
2727 const vk::Unique<vk::VkBuffer> buffer (createExternalBuffer(vkd, *device, queueFamilyIndex, config.externalType, bufferSize, 0u, usage));
2728 const vk::VkMemoryRequirements requirements (getBufferMemoryRequirements(vkd, *device, *buffer));
2729 const vk::Unique<vk::VkDeviceMemory> memory (allocateExportableMemory(vki, physicalDevice, vkd, *device, requirements, config.externalType, config.hostVisible, config.dedicated ? *buffer : (vk::VkBuffer)0));
2730 NativeHandle handleA;
2732 if (config.hostVisible)
2733 writeHostMemory(vkd, *device, *memory, testData.size(), &testData[0]);
2735 getMemoryNative(vkd, *device, *memory, config.externalType, handleA);
2738 NativeHandle handleB (handleA);
2739 const vk::Unique<vk::VkDeviceMemory> memoryA (importMemory(vkd, *device, requirements, config.externalType, handleA));
2740 const vk::Unique<vk::VkDeviceMemory> memoryB (importMemory(vkd, *device, requirements, config.externalType, handleB));
2742 if (config.hostVisible)
2744 const std::vector<deUint8> testDataA (genTestData(seed ^ 124798807u, (size_t)bufferSize));
2745 const std::vector<deUint8> testDataB (genTestData(seed ^ 970834278u, (size_t)bufferSize));
2747 checkHostMemory(vkd, *device, *memoryA, testData.size(), &testData[0]);
2748 checkHostMemory(vkd, *device, *memoryB, testData.size(), &testData[0]);
2750 writeHostMemory(vkd, *device, *memoryA, testData.size(), &testDataA[0]);
2751 writeHostMemory(vkd, *device, *memoryB, testData.size(), &testDataB[0]);
2753 checkHostMemory(vkd, *device, *memoryA, testData.size(), &testDataB[0]);
2754 checkHostMemory(vkd, *device, *memory, testData.size(), &testDataB[0]);
2758 return tcu::TestStatus::pass("Pass");
2761 tcu::TestStatus testMemoryMultimpleImports (Context& context, MemoryTestConfig config)
2763 const size_t count = 4 * 1024;
2764 const vk::PlatformInterface& vkp (context.getPlatformInterface());
2765 const vk::Unique<vk::VkInstance> instance (createInstance(vkp, 0u, config.externalType, 0u));
2766 const vk::InstanceDriver vki (vkp, *instance);
2767 const vk::VkPhysicalDevice physicalDevice (vk::chooseDevice(vki, *instance, context.getTestContext().getCommandLine()));
2768 const deUint32 queueFamilyIndex (chooseQueueFamilyIndex(vki, physicalDevice, 0u));
2769 const vk::Unique<vk::VkDevice> device (createDevice(vki, physicalDevice, 0u, config.externalType, 0u, queueFamilyIndex));
2770 const vk::DeviceDriver vkd (vki, *device);
2771 const vk::VkBufferUsageFlags usage = vk::VK_BUFFER_USAGE_TRANSFER_SRC_BIT|vk::VK_BUFFER_USAGE_TRANSFER_DST_BIT;
2772 const vk::VkDeviceSize bufferSize = 1024;
2774 checkBufferSupport(vki, physicalDevice, config.externalType, 0u, usage, config.dedicated);
2776 // \note Buffer is only allocated to get memory requirements
2777 const vk::Unique<vk::VkBuffer> buffer (createExternalBuffer(vkd, *device, queueFamilyIndex, config.externalType, bufferSize, 0u, usage));
2778 const vk::VkMemoryRequirements requirements (getBufferMemoryRequirements(vkd, *device, *buffer));
2779 const vk::Unique<vk::VkDeviceMemory> memory (allocateExportableMemory(vki, physicalDevice, vkd, *device, requirements, config.externalType, config.hostVisible, config.dedicated ? *buffer : (vk::VkBuffer)0));
2780 NativeHandle handleA;
2782 getMemoryNative(vkd, *device, *memory, config.externalType, handleA);
2784 for (size_t ndx = 0; ndx < count; ndx++)
2786 NativeHandle handleB (handleA);
2787 const vk::Unique<vk::VkDeviceMemory> memoryB (importMemory(vkd, *device, requirements, config.externalType, handleB));
2790 return tcu::TestStatus::pass("Pass");
2793 tcu::TestStatus testMemoryMultimpleExports (Context& context, MemoryTestConfig config)
2795 const size_t count = 4 * 1024;
2796 const vk::PlatformInterface& vkp (context.getPlatformInterface());
2797 const vk::Unique<vk::VkInstance> instance (createInstance(vkp, 0u, config.externalType, 0u));
2798 const vk::InstanceDriver vki (vkp, *instance);
2799 const vk::VkPhysicalDevice physicalDevice (vk::chooseDevice(vki, *instance, context.getTestContext().getCommandLine()));
2800 const deUint32 queueFamilyIndex (chooseQueueFamilyIndex(vki, physicalDevice, 0u));
2801 const vk::Unique<vk::VkDevice> device (createDevice(vki, physicalDevice, 0u, config.externalType, 0u, queueFamilyIndex));
2802 const vk::DeviceDriver vkd (vki, *device);
2803 const vk::VkBufferUsageFlags usage = vk::VK_BUFFER_USAGE_TRANSFER_SRC_BIT|vk::VK_BUFFER_USAGE_TRANSFER_DST_BIT;
2804 const vk::VkDeviceSize bufferSize = 1024;
2806 checkBufferSupport(vki, physicalDevice, config.externalType, 0u, usage, config.dedicated);
2808 // \note Buffer is only allocated to get memory requirements
2809 const vk::Unique<vk::VkBuffer> buffer (createExternalBuffer(vkd, *device, queueFamilyIndex, config.externalType, bufferSize, 0u, usage));
2810 const vk::VkMemoryRequirements requirements (getBufferMemoryRequirements(vkd, *device, *buffer));
2811 const vk::Unique<vk::VkDeviceMemory> memory (allocateExportableMemory(vki, physicalDevice, vkd, *device, requirements, config.externalType, config.hostVisible, config.dedicated ? *buffer : (vk::VkBuffer)0));
2813 for (size_t ndx = 0; ndx < count; ndx++)
2815 NativeHandle handle;
2816 getMemoryNative(vkd, *device, *memory, config.externalType, handle);
2819 return tcu::TestStatus::pass("Pass");
2822 tcu::TestStatus testMemoryFdDup (Context& context, MemoryTestConfig config)
2824 #if (DE_OS == DE_OS_ANDROID) || (DE_OS == DE_OS_UNIX)
2825 const vk::PlatformInterface& vkp (context.getPlatformInterface());
2826 const vk::Unique<vk::VkInstance> instance (createInstance(vkp, 0u, config.externalType, 0u));
2827 const vk::InstanceDriver vki (vkp, *instance);
2828 const vk::VkPhysicalDevice physicalDevice (vk::chooseDevice(vki, *instance, context.getTestContext().getCommandLine()));
2829 const deUint32 queueFamilyIndex (chooseQueueFamilyIndex(vki, physicalDevice, 0u));
2832 const vk::Unique<vk::VkDevice> device (createDevice(vki, physicalDevice, 0u, config.externalType, 0u, queueFamilyIndex));
2833 const vk::DeviceDriver vkd (vki, *device);
2835 TestLog& log = context.getTestContext().getLog();
2836 const vk::VkBufferUsageFlags usage = vk::VK_BUFFER_USAGE_TRANSFER_SRC_BIT|vk::VK_BUFFER_USAGE_TRANSFER_DST_BIT;
2837 const vk::VkDeviceSize bufferSize = 1024;
2838 const deUint32 seed = 851493858u;
2839 const std::vector<deUint8> testData (genTestData(seed, (size_t)bufferSize));
2841 checkBufferSupport(vki, physicalDevice, config.externalType, 0u, usage, config.dedicated);
2843 // \note Buffer is only allocated to get memory requirements
2844 const vk::Unique<vk::VkBuffer> buffer (createExternalBuffer(vkd, *device, queueFamilyIndex, config.externalType, bufferSize, 0u, usage));
2845 const vk::VkMemoryRequirements requirements (getBufferMemoryRequirements(vkd, *device, *buffer));
2846 const vk::Unique<vk::VkDeviceMemory> memory (allocateExportableMemory(vki, physicalDevice, vkd, *device, requirements, config.externalType, config.hostVisible, config.dedicated ? *buffer : (vk::VkBuffer)0));
2848 if (config.hostVisible)
2849 writeHostMemory(vkd, *device, *memory, testData.size(), &testData[0]);
2851 const NativeHandle fd (getMemoryFd(vkd, *device, *memory, config.externalType));
2852 NativeHandle newFd (dup(fd.getFd()));
2854 if (newFd.getFd() < 0)
2855 log << TestLog::Message << "dup() failed: '" << strerror(errno) << "'" << TestLog::EndMessage;
2857 TCU_CHECK_MSG(newFd.getFd() >= 0, "Failed to call dup() for memorys fd");
2860 const vk::Unique<vk::VkDeviceMemory> newMemory (importMemory(vkd, *device, requirements, config.externalType, newFd));
2862 if (config.hostVisible)
2864 const std::vector<deUint8> testDataA (genTestData(seed ^ 672929437u, (size_t)bufferSize));
2866 checkHostMemory(vkd, *device, *newMemory, testData.size(), &testData[0]);
2868 writeHostMemory(vkd, *device, *newMemory, testDataA.size(), &testDataA[0]);
2869 checkHostMemory(vkd, *device, *memory, testDataA.size(), &testDataA[0]);
2873 return tcu::TestStatus::pass("Pass");
2878 TCU_THROW(NotSupportedError, "Platform doesn't support dup()");
2882 tcu::TestStatus testMemoryFdDup2 (Context& context, MemoryTestConfig config)
2884 #if (DE_OS == DE_OS_ANDROID) || (DE_OS == DE_OS_UNIX)
2885 const vk::PlatformInterface& vkp (context.getPlatformInterface());
2886 const vk::Unique<vk::VkInstance> instance (createInstance(vkp, 0u, config.externalType, 0u));
2887 const vk::InstanceDriver vki (vkp, *instance);
2888 const vk::VkPhysicalDevice physicalDevice (vk::chooseDevice(vki, *instance, context.getTestContext().getCommandLine()));
2889 const deUint32 queueFamilyIndex (chooseQueueFamilyIndex(vki, physicalDevice, 0u));
2892 const vk::Unique<vk::VkDevice> device (createDevice(vki, physicalDevice, 0u, config.externalType, 0u, queueFamilyIndex));
2893 const vk::DeviceDriver vkd (vki, *device);
2895 TestLog& log = context.getTestContext().getLog();
2896 const vk::VkBufferUsageFlags usage = vk::VK_BUFFER_USAGE_TRANSFER_SRC_BIT|vk::VK_BUFFER_USAGE_TRANSFER_DST_BIT;
2897 const vk::VkDeviceSize bufferSize = 1024;
2898 const deUint32 seed = 224466865u;
2899 const std::vector<deUint8> testData (genTestData(seed, (size_t)bufferSize));
2901 checkBufferSupport(vki, physicalDevice, config.externalType, 0u, usage, config.dedicated);
2903 // \note Buffer is only allocated to get memory requirements
2904 const vk::Unique<vk::VkBuffer> buffer (createExternalBuffer(vkd, *device, queueFamilyIndex, config.externalType, bufferSize, 0u, usage));
2905 const vk::VkMemoryRequirements requirements (getBufferMemoryRequirements(vkd, *device, *buffer));
2906 const vk::Unique<vk::VkDeviceMemory> memory (allocateExportableMemory(vki, physicalDevice, vkd, *device, requirements, config.externalType, config.hostVisible, config.dedicated ? *buffer : (vk::VkBuffer)0));
2908 if (config.hostVisible)
2909 writeHostMemory(vkd, *device, *memory, testData.size(), &testData[0]);
2911 const NativeHandle fd (getMemoryFd(vkd, *device, *memory, config.externalType));
2912 NativeHandle secondFd (getMemoryFd(vkd, *device, *memory, config.externalType));
2913 const int newFd (dup2(fd.getFd(), secondFd.getFd()));
2916 log << TestLog::Message << "dup2() failed: '" << strerror(errno) << "'" << TestLog::EndMessage;
2918 TCU_CHECK_MSG(newFd >= 0, "Failed to call dup2() for memorys fd");
2921 const vk::Unique<vk::VkDeviceMemory> newMemory (importMemory(vkd, *device, requirements, config.externalType, secondFd));
2923 if (config.hostVisible)
2925 const std::vector<deUint8> testDataA (genTestData(seed ^ 99012346u, (size_t)bufferSize));
2927 checkHostMemory(vkd, *device, *newMemory, testData.size(), &testData[0]);
2929 writeHostMemory(vkd, *device, *newMemory, testDataA.size(), &testDataA[0]);
2930 checkHostMemory(vkd, *device, *memory, testDataA.size(), &testDataA[0]);
2934 return tcu::TestStatus::pass("Pass");
2939 TCU_THROW(NotSupportedError, "Platform doesn't support dup()");
2943 tcu::TestStatus testMemoryFdDup3 (Context& context, MemoryTestConfig config)
2945 #if (DE_OS == DE_OS_UNIX) && defined(_GNU_SOURCE)
2946 const vk::PlatformInterface& vkp (context.getPlatformInterface());
2947 const vk::Unique<vk::VkInstance> instance (createInstance(vkp, 0u, config.externalType, 0u));
2948 const vk::InstanceDriver vki (vkp, *instance);
2949 const vk::VkPhysicalDevice physicalDevice (vk::chooseDevice(vki, *instance, context.getTestContext().getCommandLine()));
2950 const deUint32 queueFamilyIndex (chooseQueueFamilyIndex(vki, physicalDevice, 0u));
2953 const vk::Unique<vk::VkDevice> device (createDevice(vki, physicalDevice, 0u, config.externalType, 0u, queueFamilyIndex));
2954 const vk::DeviceDriver vkd (vki, *device);
2956 TestLog& log = context.getTestContext().getLog();
2957 const vk::VkBufferUsageFlags usage = vk::VK_BUFFER_USAGE_TRANSFER_SRC_BIT|vk::VK_BUFFER_USAGE_TRANSFER_DST_BIT;
2958 const vk::VkDeviceSize bufferSize = 1024;
2959 const deUint32 seed = 2554088961u;
2960 const std::vector<deUint8> testData (genTestData(seed, (size_t)bufferSize));
2962 checkBufferSupport(vki, physicalDevice, config.externalType, 0u, usage, config.dedicated);
2964 // \note Buffer is only allocated to get memory requirements
2965 const vk::Unique<vk::VkBuffer> buffer (createExternalBuffer(vkd, *device, queueFamilyIndex, config.externalType, bufferSize, 0u, usage));
2966 const vk::VkMemoryRequirements requirements (getBufferMemoryRequirements(vkd, *device, *buffer));
2967 const vk::Unique<vk::VkDeviceMemory> memory (allocateExportableMemory(vki, physicalDevice, vkd, *device, requirements, config.externalType, config.hostVisible, config.dedicated ? *buffer : (vk::VkBuffer)0));
2969 if (config.hostVisible)
2970 writeHostMemory(vkd, *device, *memory, testData.size(), &testData[0]);
2972 const NativeHandle fd (getMemoryFd(vkd, *device, *memory, config.externalType));
2973 NativeHandle secondFd (getMemoryFd(vkd, *device, *memory, config.externalType));
2974 const int newFd (dup3(fd.getFd(), secondFd.getFd(), 0));
2977 log << TestLog::Message << "dup3() failed: '" << strerror(errno) << "'" << TestLog::EndMessage;
2979 TCU_CHECK_MSG(newFd >= 0, "Failed to call dup3() for memorys fd");
2982 const vk::Unique<vk::VkDeviceMemory> newMemory (importMemory(vkd, *device, requirements, config.externalType, secondFd));
2984 if (config.hostVisible)
2986 const std::vector<deUint8> testDataA (genTestData(seed ^ 4210342378u, (size_t)bufferSize));
2988 checkHostMemory(vkd, *device, *newMemory, testData.size(), &testData[0]);
2990 writeHostMemory(vkd, *device, *newMemory, testDataA.size(), &testDataA[0]);
2991 checkHostMemory(vkd, *device, *memory, testDataA.size(), &testDataA[0]);
2995 return tcu::TestStatus::pass("Pass");
3000 TCU_THROW(NotSupportedError, "Platform doesn't support dup()");
3004 tcu::TestStatus testMemoryFdSendOverSocket (Context& context, MemoryTestConfig config)
3006 #if (DE_OS == DE_OS_ANDROID) || (DE_OS == DE_OS_UNIX)
3007 const vk::PlatformInterface& vkp (context.getPlatformInterface());
3008 const vk::Unique<vk::VkInstance> instance (createInstance(vkp, 0u, config.externalType, 0u));
3009 const vk::InstanceDriver vki (vkp, *instance);
3010 const vk::VkPhysicalDevice physicalDevice (vk::chooseDevice(vki, *instance, context.getTestContext().getCommandLine()));
3011 const deUint32 queueFamilyIndex (chooseQueueFamilyIndex(vki, physicalDevice, 0u));
3014 const vk::Unique<vk::VkDevice> device (createDevice(vki, physicalDevice, 0u, config.externalType, 0u, queueFamilyIndex));
3015 const vk::DeviceDriver vkd (vki, *device);
3017 TestLog& log = context.getTestContext().getLog();
3018 const vk::VkBufferUsageFlags usage = vk::VK_BUFFER_USAGE_TRANSFER_SRC_BIT|vk::VK_BUFFER_USAGE_TRANSFER_DST_BIT;
3019 const vk::VkDeviceSize bufferSize = 1024;
3020 const deUint32 seed = 3403586456u;
3021 const std::vector<deUint8> testData (genTestData(seed, (size_t)bufferSize));
3023 checkBufferSupport(vki, physicalDevice, config.externalType, 0u, usage, config.dedicated);
3025 // \note Buffer is only allocated to get memory requirements
3026 const vk::Unique<vk::VkBuffer> buffer (createExternalBuffer(vkd, *device, queueFamilyIndex, config.externalType, bufferSize, 0u, usage));
3027 const vk::VkMemoryRequirements requirements (getBufferMemoryRequirements(vkd, *device, *buffer));
3028 const vk::Unique<vk::VkDeviceMemory> memory (allocateExportableMemory(vki, physicalDevice, vkd, *device, requirements, config.externalType, config.hostVisible, config.dedicated ? *buffer : (vk::VkBuffer)0));
3030 if (config.hostVisible)
3031 writeHostMemory(vkd, *device, *memory, testData.size(), &testData[0]);
3033 const NativeHandle fd (getMemoryFd(vkd, *device, *memory, config.externalType));
3038 if (socketpair(AF_UNIX, SOCK_STREAM, 0, sv) != 0)
3040 log << TestLog::Message << "Failed to create socket pair: '" << strerror(errno) << "'" << TestLog::EndMessage;
3041 TCU_FAIL("Failed to create socket pair");
3045 const NativeHandle srcSocket (sv[0]);
3046 const NativeHandle dstSocket (sv[1]);
3047 std::string sendData ("deqp");
3051 const int fdRaw (fd.getFd());
3054 char tmpBuffer[CMSG_SPACE(sizeof(int))];
3055 iovec iov = { &sendData[0], sendData.length()};
3057 deMemset(&msg, 0, sizeof(msg));
3059 msg.msg_control = tmpBuffer;
3060 msg.msg_controllen = sizeof(tmpBuffer);
3064 cmsg = CMSG_FIRSTHDR(&msg);
3065 cmsg->cmsg_level = SOL_SOCKET;
3066 cmsg->cmsg_type = SCM_RIGHTS;
3067 cmsg->cmsg_len = CMSG_LEN(sizeof(int));
3069 deMemcpy(CMSG_DATA(cmsg), &fdRaw, sizeof(int));
3070 msg.msg_controllen = cmsg->cmsg_len;
3072 if (sendmsg(srcSocket.getFd(), &msg, 0) < 0)
3074 log << TestLog::Message << "Failed to send fd over socket: '" << strerror(errno) << "'" << TestLog::EndMessage;
3075 TCU_FAIL("Failed to send fd over socket");
3082 char tmpBuffer[CMSG_SPACE(sizeof(int))];
3083 std::string recvData (4, '\0');
3084 iovec iov = { &recvData[0], recvData.length() };
3086 deMemset(&msg, 0, sizeof(msg));
3088 msg.msg_control = tmpBuffer;
3089 msg.msg_controllen = sizeof(tmpBuffer);
3093 const ssize_t bytes = recvmsg(dstSocket.getFd(), &msg, 0);
3097 log << TestLog::Message << "Failed to recv fd over socket: '" << strerror(errno) << "'" << TestLog::EndMessage;
3098 TCU_FAIL("Failed to recv fd over socket");
3101 else if (bytes != (ssize_t)sendData.length())
3103 TCU_FAIL("recvmsg() returned unpexpected number of bytes");
3107 const cmsghdr* const cmsg = CMSG_FIRSTHDR(&msg);
3109 deMemcpy(&newFd_, CMSG_DATA(cmsg), sizeof(int));
3110 NativeHandle newFd (newFd_);
3112 TCU_CHECK(cmsg->cmsg_level == SOL_SOCKET);
3113 TCU_CHECK(cmsg->cmsg_type == SCM_RIGHTS);
3114 TCU_CHECK(cmsg->cmsg_len == CMSG_LEN(sizeof(int)));
3115 TCU_CHECK(recvData == sendData);
3116 TCU_CHECK_MSG(newFd.getFd() >= 0, "Didn't receive valid fd from socket");
3119 const vk::Unique<vk::VkDeviceMemory> newMemory (importMemory(vkd, *device, requirements, config.externalType, newFd));
3121 if (config.hostVisible)
3123 const std::vector<deUint8> testDataA (genTestData(seed ^ 23478978u, (size_t)bufferSize));
3125 checkHostMemory(vkd, *device, *newMemory, testData.size(), &testData[0]);
3127 writeHostMemory(vkd, *device, *newMemory, testDataA.size(), &testDataA[0]);
3128 checkHostMemory(vkd, *device, *memory, testDataA.size(), &testDataA[0]);
3137 return tcu::TestStatus::pass("Pass");
3141 TCU_THROW(NotSupportedError, "Platform doesn't support sending file descriptors over socket");
3145 struct BufferTestConfig
3147 BufferTestConfig (vk::VkExternalMemoryHandleTypeFlagBitsKHR externalType_,
3149 : externalType (externalType_)
3150 , dedicated (dedicated_)
3154 vk::VkExternalMemoryHandleTypeFlagBitsKHR externalType;
3158 tcu::TestStatus testBufferBindExportImportBind (Context& context,
3159 const BufferTestConfig config)
3161 const vk::PlatformInterface& vkp (context.getPlatformInterface());
3162 const vk::Unique<vk::VkInstance> instance (createInstance(vkp, 0u, config.externalType, 0u));
3163 const vk::InstanceDriver vki (vkp, *instance);
3164 const vk::VkPhysicalDevice physicalDevice (vk::chooseDevice(vki, *instance, context.getTestContext().getCommandLine()));
3165 const deUint32 queueFamilyIndex (chooseQueueFamilyIndex(vki, physicalDevice, 0u));
3166 const vk::Unique<vk::VkDevice> device (createDevice(vki, physicalDevice, 0u, config.externalType, 0u, queueFamilyIndex, config.dedicated));
3167 const vk::DeviceDriver vkd (vki, *device);
3168 const vk::VkBufferUsageFlags usage = vk::VK_BUFFER_USAGE_TRANSFER_SRC_BIT|vk::VK_BUFFER_USAGE_TRANSFER_DST_BIT;
3169 const vk::VkDeviceSize bufferSize = 1024;
3171 checkBufferSupport(vki, physicalDevice, config.externalType, 0u, usage, config.dedicated);
3173 // \note Buffer is only allocated to get memory requirements
3174 const vk::Unique<vk::VkBuffer> bufferA (createExternalBuffer(vkd, *device, queueFamilyIndex, config.externalType, bufferSize, 0u, usage));
3175 const vk::VkMemoryRequirements requirements (getBufferMemoryRequirements(vkd, *device, *bufferA));
3176 const vk::Unique<vk::VkDeviceMemory> memoryA (allocateExportableMemory(vkd, *device, requirements, config.externalType, config.dedicated ? *bufferA : (vk::VkBuffer)0));
3177 NativeHandle handle;
3179 VK_CHECK(vkd.bindBufferMemory(*device, *bufferA, *memoryA, 0u));
3181 getMemoryNative(vkd, *device, *memoryA, config.externalType, handle);
3184 const vk::Unique<vk::VkDeviceMemory> memoryB (importMemory(vkd, *device, requirements, config.externalType, handle));
3185 const vk::Unique<vk::VkBuffer> bufferB (createExternalBuffer(vkd, *device, queueFamilyIndex, config.externalType, bufferSize, 0u, usage));
3187 VK_CHECK(vkd.bindBufferMemory(*device, *bufferB, *memoryB, 0u));
3190 return tcu::TestStatus::pass("Pass");
3193 tcu::TestStatus testBufferExportBindImportBind (Context& context,
3194 const BufferTestConfig config)
3196 const vk::PlatformInterface& vkp (context.getPlatformInterface());
3197 const vk::Unique<vk::VkInstance> instance (createInstance(vkp, 0u, config.externalType, 0u));
3198 const vk::InstanceDriver vki (vkp, *instance);
3199 const vk::VkPhysicalDevice physicalDevice (vk::chooseDevice(vki, *instance, context.getTestContext().getCommandLine()));
3200 const deUint32 queueFamilyIndex (chooseQueueFamilyIndex(vki, physicalDevice, 0u));
3201 const vk::Unique<vk::VkDevice> device (createDevice(vki, physicalDevice, 0u, config.externalType, 0u, queueFamilyIndex, config.dedicated));
3202 const vk::DeviceDriver vkd (vki, *device);
3203 const vk::VkBufferUsageFlags usage = vk::VK_BUFFER_USAGE_TRANSFER_SRC_BIT|vk::VK_BUFFER_USAGE_TRANSFER_DST_BIT;
3204 const vk::VkDeviceSize bufferSize = 1024;
3206 checkBufferSupport(vki, physicalDevice, config.externalType, 0u, usage, config.dedicated);
3208 // \note Buffer is only allocated to get memory requirements
3209 const vk::Unique<vk::VkBuffer> bufferA (createExternalBuffer(vkd, *device, queueFamilyIndex, config.externalType, bufferSize, 0u, usage));
3210 const vk::VkMemoryRequirements requirements (getBufferMemoryRequirements(vkd, *device, *bufferA));
3211 const vk::Unique<vk::VkDeviceMemory> memoryA (allocateExportableMemory(vkd, *device, requirements, config.externalType, config.dedicated ? *bufferA : (vk::VkBuffer)0));
3212 NativeHandle handle;
3214 getMemoryNative(vkd, *device, *memoryA, config.externalType, handle);
3215 VK_CHECK(vkd.bindBufferMemory(*device, *bufferA, *memoryA, 0u));
3218 const vk::Unique<vk::VkDeviceMemory> memoryB (importMemory(vkd, *device, requirements, config.externalType, handle));
3219 const vk::Unique<vk::VkBuffer> bufferB (createExternalBuffer(vkd, *device, queueFamilyIndex, config.externalType, bufferSize, 0u, usage));
3221 VK_CHECK(vkd.bindBufferMemory(*device, *bufferB, *memoryB, 0u));
3224 return tcu::TestStatus::pass("Pass");
3227 tcu::TestStatus testBufferExportImportBindBind (Context& context,
3228 const BufferTestConfig config)
3230 const vk::PlatformInterface& vkp (context.getPlatformInterface());
3231 const vk::Unique<vk::VkInstance> instance (createInstance(vkp, 0u, config.externalType, 0u));
3232 const vk::InstanceDriver vki (vkp, *instance);
3233 const vk::VkPhysicalDevice physicalDevice (vk::chooseDevice(vki, *instance, context.getTestContext().getCommandLine()));
3234 const deUint32 queueFamilyIndex (chooseQueueFamilyIndex(vki, physicalDevice, 0u));
3235 const vk::Unique<vk::VkDevice> device (createDevice(vki, physicalDevice, 0u, config.externalType, 0u, queueFamilyIndex, config.dedicated));
3236 const vk::DeviceDriver vkd (vki, *device);
3237 const vk::VkBufferUsageFlags usage = vk::VK_BUFFER_USAGE_TRANSFER_SRC_BIT|vk::VK_BUFFER_USAGE_TRANSFER_DST_BIT;
3238 const vk::VkDeviceSize bufferSize = 1024;
3240 checkBufferSupport(vki, physicalDevice, config.externalType, 0u, usage, config.dedicated);
3242 // \note Buffer is only allocated to get memory requirements
3243 const vk::Unique<vk::VkBuffer> bufferA (createExternalBuffer(vkd, *device, queueFamilyIndex, config.externalType, bufferSize, 0u, usage));
3244 const vk::VkMemoryRequirements requirements (getBufferMemoryRequirements(vkd, *device, *bufferA));
3245 const vk::Unique<vk::VkDeviceMemory> memoryA (allocateExportableMemory(vkd, *device, requirements, config.externalType, config.dedicated ? *bufferA : (vk::VkBuffer)0));
3246 NativeHandle handle;
3248 getMemoryNative(vkd, *device, *memoryA, config.externalType, handle);
3251 const vk::Unique<vk::VkDeviceMemory> memoryB (importMemory(vkd, *device, requirements, config.externalType, handle));
3252 const vk::Unique<vk::VkBuffer> bufferB (createExternalBuffer(vkd, *device, queueFamilyIndex, config.externalType, bufferSize, 0u, usage));
3254 VK_CHECK(vkd.bindBufferMemory(*device, *bufferA, *memoryA, 0u));
3255 VK_CHECK(vkd.bindBufferMemory(*device, *bufferB, *memoryB, 0u));
3258 return tcu::TestStatus::pass("Pass");
3261 tcu::TestStatus testImageQueries (Context& context, vk::VkExternalMemoryHandleTypeFlagBitsKHR externalType)
3263 const vk::VkImageCreateFlags createFlags[] =
3266 vk::VK_IMAGE_CREATE_SPARSE_BINDING_BIT,
3267 vk::VK_IMAGE_CREATE_SPARSE_BINDING_BIT|vk::VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT,
3268 vk::VK_IMAGE_CREATE_SPARSE_BINDING_BIT|vk::VK_IMAGE_CREATE_SPARSE_ALIASED_BIT,
3269 vk::VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT,
3270 vk::VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT,
3271 vk::VK_IMAGE_CREATE_2D_ARRAY_COMPATIBLE_BIT_KHR
3273 const vk::VkImageUsageFlags usageFlags[] =
3275 vk::VK_IMAGE_USAGE_TRANSFER_SRC_BIT,
3276 vk::VK_IMAGE_USAGE_TRANSFER_DST_BIT,
3277 vk::VK_IMAGE_USAGE_SAMPLED_BIT,
3278 vk::VK_IMAGE_USAGE_STORAGE_BIT,
3279 vk::VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT,
3280 vk::VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT,
3281 vk::VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT,
3282 vk::VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT
3284 const vk::PlatformInterface& vkp (context.getPlatformInterface());
3285 const vk::Unique<vk::VkInstance> instance (createInstance(vkp, 0u, externalType, 0u));
3286 const vk::InstanceDriver vki (vkp, *instance);
3287 const vk::VkPhysicalDevice physicalDevice (vk::chooseDevice(vki, *instance, context.getTestContext().getCommandLine()));
3288 const vk::VkPhysicalDeviceFeatures deviceFeatures (vk::getPhysicalDeviceFeatures(vki, physicalDevice));
3289 const deUint32 queueFamilyIndex (chooseQueueFamilyIndex(vki, physicalDevice, 0u));
3291 // VkDevice is only created if physical device claims to support any of these types.
3292 vk::Move<vk::VkDevice> device;
3293 de::MovePtr<vk::DeviceDriver> vkd;
3294 bool deviceHasDedicated = false;
3296 TestLog& log = context.getTestContext().getLog();
3298 for (size_t createFlagNdx = 0; createFlagNdx < DE_LENGTH_OF_ARRAY(createFlags); createFlagNdx++)
3299 for (size_t usageFlagNdx = 0; usageFlagNdx < DE_LENGTH_OF_ARRAY(usageFlags); usageFlagNdx++)
3301 const vk::VkImageViewCreateFlags createFlag = createFlags[createFlagNdx];
3302 const vk::VkImageUsageFlags usageFlag = usageFlags[usageFlagNdx];
3303 const vk::VkFormat format = vk::VK_FORMAT_R8G8B8A8_UNORM;
3304 const vk::VkImageType type = vk::VK_IMAGE_TYPE_2D;
3305 const vk::VkImageTiling tiling = vk::VK_IMAGE_TILING_OPTIMAL;
3306 const vk::VkPhysicalDeviceExternalImageFormatInfoKHR externalInfo =
3308 vk::VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_IMAGE_FORMAT_INFO_KHR,
3312 const vk::VkPhysicalDeviceImageFormatInfo2KHR info =
3314 vk::VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2_KHR,
3323 vk::VkExternalImageFormatPropertiesKHR externalProperties =
3325 vk::VK_STRUCTURE_TYPE_EXTERNAL_IMAGE_FORMAT_PROPERTIES_KHR,
3329 vk::VkImageFormatProperties2KHR properties =
3331 vk::VK_STRUCTURE_TYPE_IMAGE_FORMAT_PROPERTIES_2_KHR,
3332 &externalProperties,
3342 if (((createFlag & vk::VK_IMAGE_CREATE_SPARSE_BINDING_BIT) != 0) &&
3343 (deviceFeatures.sparseBinding == VK_FALSE))
3346 if (((createFlag & vk::VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT) != 0) &&
3347 (deviceFeatures.sparseResidencyImage2D == VK_FALSE))
3350 if (((createFlag & vk::VK_IMAGE_CREATE_SPARSE_ALIASED_BIT) != 0) &&
3351 (deviceFeatures.sparseResidencyAliased == VK_FALSE))
3354 vki.getPhysicalDeviceImageFormatProperties2KHR(physicalDevice, &info, &properties);
3356 log << TestLog::Message << externalProperties << TestLog::EndMessage;
3357 TCU_CHECK(externalProperties.sType == vk::VK_STRUCTURE_TYPE_EXTERNAL_IMAGE_FORMAT_PROPERTIES_KHR);
3358 TCU_CHECK(externalProperties.pNext == DE_NULL);
3359 // \todo [2017-06-06 pyry] Can we validate anything else? Compatible types?
3361 if ((externalProperties.externalMemoryProperties.externalMemoryFeatures & (vk::VK_EXTERNAL_MEMORY_FEATURE_EXPORTABLE_BIT_KHR|vk::VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT_KHR)) != 0)
3363 const bool requiresDedicated = (externalProperties.externalMemoryProperties.externalMemoryFeatures & vk::VK_EXTERNAL_MEMORY_FEATURE_DEDICATED_ONLY_BIT_KHR) != 0;
3365 if (!device || (requiresDedicated && !deviceHasDedicated))
3367 // \note We need to re-create with dedicated mem extensions if previous device instance didn't have them
3370 device = createDevice(vki, physicalDevice, 0u, externalType, 0u, queueFamilyIndex, requiresDedicated);
3371 vkd = de::MovePtr<vk::DeviceDriver>(new vk::DeviceDriver(vki, *device));
3372 deviceHasDedicated = requiresDedicated;
3374 catch (const tcu::NotSupportedError& e)
3377 TCU_FAIL("Physical device claims to support handle type but required extensions are not supported");
3382 if ((externalProperties.externalMemoryProperties.externalMemoryFeatures & vk::VK_EXTERNAL_MEMORY_FEATURE_EXPORTABLE_BIT_KHR) != 0)
3384 DE_ASSERT(!!device);
3387 if (deviceHasDedicated)
3389 const vk::Unique<vk::VkImage> image (createExternalImage(*vkd, *device, queueFamilyIndex, externalType, format, 16u, 16u, tiling, createFlag, usageFlag));
3390 const vk::VkMemoryDedicatedRequirementsKHR reqs (getMemoryDedicatedRequirements(*vkd, *device, *image));
3391 const bool propertiesRequiresDedicated = (externalProperties.externalMemoryProperties.externalMemoryFeatures & vk::VK_EXTERNAL_MEMORY_FEATURE_DEDICATED_ONLY_BIT_KHR) != 0;
3392 const bool objectRequiresDedicated = (reqs.requiresDedicatedAllocation != VK_FALSE);
3394 if (propertiesRequiresDedicated != objectRequiresDedicated)
3395 TCU_FAIL("vkGetPhysicalDeviceExternalBufferProperties and vkGetBufferMemoryRequirements2 report different dedicated requirements");
3399 // We can't query whether dedicated memory is required or not on per-object basis.
3400 // This check should be redundant as the code above tries to create device with
3401 // VK_KHR_dedicated_allocation & VK_KHR_get_memory_requirements2 if dedicated memory
3402 // is required. However, checking again doesn't hurt.
3403 TCU_CHECK((externalProperties.externalMemoryProperties.externalMemoryFeatures & vk::VK_EXTERNAL_MEMORY_FEATURE_DEDICATED_ONLY_BIT_KHR) == 0);
3408 return tcu::TestStatus::pass("Pass");
3411 struct ImageTestConfig
3413 ImageTestConfig (vk::VkExternalMemoryHandleTypeFlagBitsKHR externalType_,
3415 : externalType (externalType_)
3416 , dedicated (dedicated_)
3420 vk::VkExternalMemoryHandleTypeFlagBitsKHR externalType;
3424 tcu::TestStatus testImageBindExportImportBind (Context& context,
3425 const ImageTestConfig config)
3427 const vk::PlatformInterface& vkp (context.getPlatformInterface());
3428 const vk::Unique<vk::VkInstance> instance (createInstance(vkp, 0u, config.externalType, 0u));
3429 const vk::InstanceDriver vki (vkp, *instance);
3430 const vk::VkPhysicalDevice physicalDevice (vk::chooseDevice(vki, *instance, context.getTestContext().getCommandLine()));
3431 const deUint32 queueFamilyIndex (chooseQueueFamilyIndex(vki, physicalDevice, 0u));
3432 const vk::Unique<vk::VkDevice> device (createDevice(vki, physicalDevice, 0u, config.externalType, 0u, queueFamilyIndex, config.dedicated));
3433 const vk::DeviceDriver vkd (vki, *device);
3434 const vk::VkImageUsageFlags usage = vk::VK_BUFFER_USAGE_TRANSFER_SRC_BIT|vk::VK_BUFFER_USAGE_TRANSFER_DST_BIT;
3435 const vk::VkFormat format = vk::VK_FORMAT_R8G8B8A8_UNORM;
3436 const deUint32 width = 64u;
3437 const deUint32 height = 64u;
3438 const vk::VkImageTiling tiling = vk::VK_IMAGE_TILING_OPTIMAL;
3440 checkImageSupport(vki, physicalDevice, config.externalType, 0u, usage, format, tiling, config.dedicated);
3442 const vk::Unique<vk::VkImage> imageA (createExternalImage(vkd, *device, queueFamilyIndex, config.externalType, format, width, height, tiling, 0u, usage));
3443 const vk::VkMemoryRequirements requirements (getImageMemoryRequirements(vkd, *device, *imageA));
3444 const vk::Unique<vk::VkDeviceMemory> memoryA (allocateExportableMemory(vkd, *device, requirements, config.externalType, config.dedicated ? *imageA : (vk::VkImage)0));
3445 NativeHandle handle;
3447 VK_CHECK(vkd.bindImageMemory(*device, *imageA, *memoryA, 0u));
3449 getMemoryNative(vkd, *device, *memoryA, config.externalType, handle);
3452 const vk::Unique<vk::VkDeviceMemory> memoryB (importMemory(vkd, *device, requirements, config.externalType, handle));
3453 const vk::Unique<vk::VkImage> imageB (createExternalImage(vkd, *device, queueFamilyIndex, config.externalType, format, width, height, tiling, 0u, usage));
3455 VK_CHECK(vkd.bindImageMemory(*device, *imageB, *memoryB, 0u));
3458 return tcu::TestStatus::pass("Pass");
3461 tcu::TestStatus testImageExportBindImportBind (Context& context,
3462 const ImageTestConfig config)
3464 const vk::PlatformInterface& vkp (context.getPlatformInterface());
3465 const vk::Unique<vk::VkInstance> instance (createInstance(vkp, 0u, config.externalType, 0u));
3466 const vk::InstanceDriver vki (vkp, *instance);
3467 const vk::VkPhysicalDevice physicalDevice (vk::chooseDevice(vki, *instance, context.getTestContext().getCommandLine()));
3468 const deUint32 queueFamilyIndex (chooseQueueFamilyIndex(vki, physicalDevice, 0u));
3469 const vk::Unique<vk::VkDevice> device (createDevice(vki, physicalDevice, 0u, config.externalType, 0u, queueFamilyIndex, config.dedicated));
3470 const vk::DeviceDriver vkd (vki, *device);
3471 const vk::VkImageUsageFlags usage = vk::VK_BUFFER_USAGE_TRANSFER_SRC_BIT|vk::VK_BUFFER_USAGE_TRANSFER_DST_BIT;
3472 const vk::VkFormat format = vk::VK_FORMAT_R8G8B8A8_UNORM;
3473 const deUint32 width = 64u;
3474 const deUint32 height = 64u;
3475 const vk::VkImageTiling tiling = vk::VK_IMAGE_TILING_OPTIMAL;
3477 checkImageSupport(vki, physicalDevice, config.externalType, 0u, usage, format, tiling, config.dedicated);
3479 const vk::Unique<vk::VkImage> imageA (createExternalImage(vkd, *device, queueFamilyIndex, config.externalType, format, width, height, tiling, 0u, usage));
3480 const vk::VkMemoryRequirements requirements (getImageMemoryRequirements(vkd, *device, *imageA));
3481 const vk::Unique<vk::VkDeviceMemory> memoryA (allocateExportableMemory(vkd, *device, requirements, config.externalType, config.dedicated ? *imageA : (vk::VkImage)0));
3482 NativeHandle handle;
3484 getMemoryNative(vkd, *device, *memoryA, config.externalType, handle);
3485 VK_CHECK(vkd.bindImageMemory(*device, *imageA, *memoryA, 0u));
3488 const vk::Unique<vk::VkDeviceMemory> memoryB (importMemory(vkd, *device, requirements, config.externalType, handle));
3489 const vk::Unique<vk::VkImage> imageB (createExternalImage(vkd, *device, queueFamilyIndex, config.externalType, format, width, height, tiling, 0u, usage));
3491 VK_CHECK(vkd.bindImageMemory(*device, *imageB, *memoryB, 0u));
3494 return tcu::TestStatus::pass("Pass");
3497 tcu::TestStatus testImageExportImportBindBind (Context& context,
3498 const ImageTestConfig config)
3500 const vk::PlatformInterface& vkp (context.getPlatformInterface());
3501 const vk::Unique<vk::VkInstance> instance (createInstance(vkp, 0u, config.externalType, 0u));
3502 const vk::InstanceDriver vki (vkp, *instance);
3503 const vk::VkPhysicalDevice physicalDevice (vk::chooseDevice(vki, *instance, context.getTestContext().getCommandLine()));
3504 const deUint32 queueFamilyIndex (chooseQueueFamilyIndex(vki, physicalDevice, 0u));
3505 const vk::Unique<vk::VkDevice> device (createDevice(vki, physicalDevice, 0u, config.externalType, 0u, queueFamilyIndex, config.dedicated));
3506 const vk::DeviceDriver vkd (vki, *device);
3507 const vk::VkImageUsageFlags usage = vk::VK_BUFFER_USAGE_TRANSFER_SRC_BIT|vk::VK_BUFFER_USAGE_TRANSFER_DST_BIT;
3508 const vk::VkFormat format = vk::VK_FORMAT_R8G8B8A8_UNORM;
3509 const deUint32 width = 64u;
3510 const deUint32 height = 64u;
3511 const vk::VkImageTiling tiling = vk::VK_IMAGE_TILING_OPTIMAL;
3513 checkImageSupport(vki, physicalDevice, config.externalType, 0u, usage, format, tiling, config.dedicated);
3515 // \note Image is only allocated to get memory requirements
3516 const vk::Unique<vk::VkImage> imageA (createExternalImage(vkd, *device, queueFamilyIndex, config.externalType, format, width, height, tiling, 0u, usage));
3517 const vk::VkMemoryRequirements requirements (getImageMemoryRequirements(vkd, *device, *imageA));
3518 const vk::Unique<vk::VkDeviceMemory> memoryA (allocateExportableMemory(vkd, *device, requirements, config.externalType, config.dedicated ? *imageA : (vk::VkImage)0));
3519 NativeHandle handle;
3521 getMemoryNative(vkd, *device, *memoryA, config.externalType, handle);
3524 const vk::Unique<vk::VkDeviceMemory> memoryB (importMemory(vkd, *device, requirements, config.externalType, handle));
3525 const vk::Unique<vk::VkImage> imageB (createExternalImage(vkd, *device, queueFamilyIndex, config.externalType, format, width, height, tiling, 0u, usage));
3527 VK_CHECK(vkd.bindImageMemory(*device, *imageA, *memoryA, 0u));
3528 VK_CHECK(vkd.bindImageMemory(*device, *imageB, *memoryB, 0u));
3531 return tcu::TestStatus::pass("Pass");
3533 de::MovePtr<tcu::TestCaseGroup> createFenceTests (tcu::TestContext& testCtx, vk::VkExternalFenceHandleTypeFlagBitsKHR externalType)
3537 const char* const name;
3538 const Permanence permanence;
3541 { "temporary", PERMANENCE_TEMPORARY },
3542 { "permanent", PERMANENCE_PERMANENT }
3545 de::MovePtr<tcu::TestCaseGroup> fenceGroup (new tcu::TestCaseGroup(testCtx, externalFenceTypeToName(externalType), externalFenceTypeToName(externalType)));
3547 addFunctionCase(fenceGroup.get(), "info", "Test external fence queries.", testFenceQueries, externalType);
3549 for (size_t permanenceNdx = 0; permanenceNdx < DE_LENGTH_OF_ARRAY(permanences); permanenceNdx++)
3551 const Permanence permanence (permanences[permanenceNdx].permanence);
3552 const char* const permanenceName (permanences[permanenceNdx].name);
3553 const FenceTestConfig config (externalType, permanence);
3555 if (!isSupportedPermanence(externalType, permanence))
3558 if (externalType == vk::VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_WIN32_BIT_KHR
3559 || externalType == vk::VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT_KHR)
3561 addFunctionCase(fenceGroup.get(), std::string("create_win32_") + permanenceName, "Test creating fence with win32 properties.", testFenceWin32Create, config);
3564 addFunctionCase(fenceGroup.get(), std::string("import_twice_") + permanenceName, "Test importing fence twice.", testFenceImportTwice, config);
3565 addFunctionCase(fenceGroup.get(), std::string("reimport_") + permanenceName, "Test importing again over previously imported fence.", testFenceImportReimport, config);
3566 addFunctionCase(fenceGroup.get(), std::string("import_multiple_times_") + permanenceName, "Test importing fence multiple times.", testFenceMultipleImports, config);
3567 addFunctionCase(fenceGroup.get(), std::string("signal_export_import_wait_") + permanenceName, "Test signaling, exporting, importing and waiting for the sempahore.", testFenceSignalExportImportWait, config);
3568 addFunctionCase(fenceGroup.get(), std::string("signal_import_") + permanenceName, "Test signaling and importing the fence.", testFenceSignalImport, config);
3569 addFunctionCase(fenceGroup.get(), std::string("reset_") + permanenceName, "Test resetting the fence.", testFenceReset, config);
3570 addFunctionCase(fenceGroup.get(), std::string("transference_") + permanenceName, "Test fences transference.", testFenceTransference, config);
3572 if (externalType == vk::VK_EXTERNAL_FENCE_HANDLE_TYPE_SYNC_FD_BIT_KHR
3573 || externalType == vk::VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_FD_BIT_KHR)
3575 // \note Not supported on WIN32 handles
3576 addFunctionCase(fenceGroup.get(), std::string("export_multiple_times_") + permanenceName, "Test exporting fence multiple times.", testFenceMultipleExports, config);
3578 addFunctionCase(fenceGroup.get(), std::string("dup_") + permanenceName, "Test calling dup() on exported fence.", testFenceFdDup, config);
3579 addFunctionCase(fenceGroup.get(), std::string("dup2_") + permanenceName, "Test calling dup2() on exported fence.", testFenceFdDup2, config);
3580 addFunctionCase(fenceGroup.get(), std::string("dup3_") + permanenceName, "Test calling dup3() on exported fence.", testFenceFdDup3, config);
3581 addFunctionCase(fenceGroup.get(), std::string("send_over_socket_") + permanenceName, "Test sending fence fd over socket.", testFenceFdSendOverSocket, config);
3584 if (getHandelTypeTransferences(externalType) == TRANSFERENCE_REFERENCE)
3586 addFunctionCase(fenceGroup.get(), std::string("signal_wait_import_") + permanenceName, "Test signaling and then waiting for the the sepmahore.", testFenceSignalWaitImport, config);
3587 addFunctionCase(fenceGroup.get(), std::string("export_signal_import_wait_") + permanenceName, "Test exporting, signaling, importing and waiting for the fence.", testFenceExportSignalImportWait, config);
3588 addFunctionCase(fenceGroup.get(), std::string("export_import_signal_wait_") + permanenceName, "Test exporting, importing, signaling and waiting for the fence.", testFenceExportImportSignalWait, config);
3595 de::MovePtr<tcu::TestCaseGroup> createFenceTests (tcu::TestContext& testCtx)
3597 de::MovePtr<tcu::TestCaseGroup> fenceGroup (new tcu::TestCaseGroup(testCtx, "fence", "Tests for external fences."));
3599 fenceGroup->addChild(createFenceTests(testCtx, vk::VK_EXTERNAL_FENCE_HANDLE_TYPE_SYNC_FD_BIT_KHR).release());
3600 fenceGroup->addChild(createFenceTests(testCtx, vk::VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_FD_BIT_KHR).release());
3601 fenceGroup->addChild(createFenceTests(testCtx, vk::VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_WIN32_BIT_KHR).release());
3602 fenceGroup->addChild(createFenceTests(testCtx, vk::VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT_KHR).release());
3607 de::MovePtr<tcu::TestCaseGroup> createSemaphoreTests (tcu::TestContext& testCtx, vk::VkExternalSemaphoreHandleTypeFlagBitsKHR externalType)
3611 const char* const name;
3612 const Permanence permanence;
3615 { "temporary", PERMANENCE_TEMPORARY },
3616 { "permanent", PERMANENCE_PERMANENT }
3619 de::MovePtr<tcu::TestCaseGroup> semaphoreGroup (new tcu::TestCaseGroup(testCtx, externalSemaphoreTypeToName(externalType), externalSemaphoreTypeToName(externalType)));
3621 addFunctionCase(semaphoreGroup.get(), "info", "Test external semaphore queries.", testSemaphoreQueries, externalType);
3623 for (size_t permanenceNdx = 0; permanenceNdx < DE_LENGTH_OF_ARRAY(permanences); permanenceNdx++)
3625 const Permanence permanence (permanences[permanenceNdx].permanence);
3626 const char* const permanenceName (permanences[permanenceNdx].name);
3627 const SemaphoreTestConfig config (externalType, permanence);
3629 if (!isSupportedPermanence(externalType, permanence))
3632 if (externalType == vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_BIT_KHR
3633 || externalType == vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT_KHR)
3635 addFunctionCase(semaphoreGroup.get(), std::string("create_win32_") + permanenceName, "Test creating semaphore with win32 properties.", testSemaphoreWin32Create, config);
3638 addFunctionCase(semaphoreGroup.get(), std::string("import_twice_") + permanenceName, "Test importing semaphore twice.", testSemaphoreImportTwice, config);
3639 addFunctionCase(semaphoreGroup.get(), std::string("reimport_") + permanenceName, "Test importing again over previously imported semaphore.", testSemaphoreImportReimport, config);
3640 addFunctionCase(semaphoreGroup.get(), std::string("import_multiple_times_") + permanenceName, "Test importing semaphore multiple times.", testSemaphoreMultipleImports, config);
3641 addFunctionCase(semaphoreGroup.get(), std::string("signal_export_import_wait_") + permanenceName, "Test signaling, exporting, importing and waiting for the sempahore.", testSemaphoreSignalExportImportWait, config);
3642 addFunctionCase(semaphoreGroup.get(), std::string("signal_import_") + permanenceName, "Test signaling and importing the semaphore.", testSemaphoreSignalImport, config);
3643 addFunctionCase(semaphoreGroup.get(), std::string("transference_") + permanenceName, "Test semaphores transference.", testSemaphoreTransference, config);
3645 if (externalType == vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT_KHR
3646 || externalType == vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT_KHR)
3648 // \note Not supported on WIN32 handles
3649 addFunctionCase(semaphoreGroup.get(), std::string("export_multiple_times_") + permanenceName, "Test exporting semaphore multiple times.", testSemaphoreMultipleExports, config);
3651 addFunctionCase(semaphoreGroup.get(), std::string("dup_") + permanenceName, "Test calling dup() on exported semaphore.", testSemaphoreFdDup, config);
3652 addFunctionCase(semaphoreGroup.get(), std::string("dup2_") + permanenceName, "Test calling dup2() on exported semaphore.", testSemaphoreFdDup2, config);
3653 addFunctionCase(semaphoreGroup.get(), std::string("dup3_") + permanenceName, "Test calling dup3() on exported semaphore.", testSemaphoreFdDup3, config);
3654 addFunctionCase(semaphoreGroup.get(), std::string("send_over_socket_") + permanenceName, "Test sending semaphore fd over socket.", testSemaphoreFdSendOverSocket, config);
3657 if (getHandelTypeTransferences(externalType) == TRANSFERENCE_REFERENCE)
3659 addFunctionCase(semaphoreGroup.get(), std::string("signal_wait_import_") + permanenceName, "Test signaling and then waiting for the the sepmahore.", testSemaphoreSignalWaitImport, config);
3660 addFunctionCase(semaphoreGroup.get(), std::string("export_signal_import_wait_") + permanenceName, "Test exporting, signaling, importing and waiting for the semaphore.", testSemaphoreExportSignalImportWait, config);
3661 addFunctionCase(semaphoreGroup.get(), std::string("export_import_signal_wait_") + permanenceName, "Test exporting, importing, signaling and waiting for the semaphore.", testSemaphoreExportImportSignalWait, config);
3665 return semaphoreGroup;
3668 de::MovePtr<tcu::TestCaseGroup> createSemaphoreTests (tcu::TestContext& testCtx)
3670 de::MovePtr<tcu::TestCaseGroup> semaphoreGroup (new tcu::TestCaseGroup(testCtx, "semaphore", "Tests for external semaphores."));
3672 semaphoreGroup->addChild(createSemaphoreTests(testCtx, vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT_KHR).release());
3673 semaphoreGroup->addChild(createSemaphoreTests(testCtx, vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT_KHR).release());
3674 semaphoreGroup->addChild(createSemaphoreTests(testCtx, vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_BIT_KHR).release());
3675 semaphoreGroup->addChild(createSemaphoreTests(testCtx, vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT_KHR).release());
3677 return semaphoreGroup;
3680 de::MovePtr<tcu::TestCaseGroup> createMemoryTests (tcu::TestContext& testCtx, vk::VkExternalMemoryHandleTypeFlagBitsKHR externalType)
3682 de::MovePtr<tcu::TestCaseGroup> group (new tcu::TestCaseGroup(testCtx, externalMemoryTypeToName(externalType), "Tests for external memory"));
3684 for (size_t dedicatedNdx = 0; dedicatedNdx < 2; dedicatedNdx++)
3686 const bool dedicated (dedicatedNdx == 1);
3687 de::MovePtr<tcu::TestCaseGroup> dedicatedGroup (new tcu::TestCaseGroup(testCtx, dedicated ? "dedicated" : "suballocated", ""));
3689 for (size_t hostVisibleNdx = 0; hostVisibleNdx < 2; hostVisibleNdx++)
3691 const bool hostVisible (hostVisibleNdx == 1);
3692 de::MovePtr<tcu::TestCaseGroup> hostVisibleGroup (new tcu::TestCaseGroup(testCtx, hostVisible ? "host_visible" : "device_only", ""));
3693 const MemoryTestConfig memoryConfig (externalType, hostVisible, dedicated);
3695 if (externalType == vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT_KHR
3696 || externalType == vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT_KHR)
3698 addFunctionCase(hostVisibleGroup.get(), "create_win32", "Test creating memory with win32 properties .", testMemoryWin32Create, memoryConfig);
3701 addFunctionCase(hostVisibleGroup.get(), "import_twice", "Test importing memory object twice.", testMemoryImportTwice, memoryConfig);
3702 addFunctionCase(hostVisibleGroup.get(), "import_multiple_times", "Test importing memory object multiple times.", testMemoryMultimpleImports, memoryConfig);
3704 if (externalType == vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT_KHR)
3706 addFunctionCase(hostVisibleGroup.get(), "dup", "Test calling dup() on exported memory.", testMemoryFdDup, memoryConfig);
3707 addFunctionCase(hostVisibleGroup.get(), "dup2", "Test calling dup2() on exported memory.", testMemoryFdDup2, memoryConfig);
3708 addFunctionCase(hostVisibleGroup.get(), "dup3", "Test calling dup3() on exported memory.", testMemoryFdDup3, memoryConfig);
3709 addFunctionCase(hostVisibleGroup.get(), "send_over_socket", "Test sending memory fd over socket.", testMemoryFdSendOverSocket, memoryConfig);
3710 // \note Not supported on WIN32 handles
3711 addFunctionCase(hostVisibleGroup.get(), "export_multiple_times", "Test exporting memory multiple times.", testMemoryMultimpleExports, memoryConfig);
3714 dedicatedGroup->addChild(hostVisibleGroup.release());
3718 de::MovePtr<tcu::TestCaseGroup> bufferGroup (new tcu::TestCaseGroup(testCtx, "buffer", ""));
3719 const BufferTestConfig bufferConfig (externalType, dedicated);
3721 addFunctionCase(bufferGroup.get(), "info", "External buffer memory info query.", testBufferQueries, externalType);
3722 addFunctionCase(bufferGroup.get(), "bind_export_import_bind", "Test binding, exporting, importing and binding buffer.", testBufferBindExportImportBind, bufferConfig);
3723 addFunctionCase(bufferGroup.get(), "export_bind_import_bind", "Test exporting, binding, importing and binding buffer.", testBufferExportBindImportBind, bufferConfig);
3724 addFunctionCase(bufferGroup.get(), "export_import_bind_bind", "Test exporting, importind and binding buffer.", testBufferExportImportBindBind, bufferConfig);
3726 dedicatedGroup->addChild(bufferGroup.release());
3730 de::MovePtr<tcu::TestCaseGroup> imageGroup (new tcu::TestCaseGroup(testCtx, "image", ""));
3731 const ImageTestConfig imageConfig (externalType, dedicated);
3733 addFunctionCase(imageGroup.get(), "info", "External image memory info query.", testImageQueries, externalType);
3734 addFunctionCase(imageGroup.get(), "bind_export_import_bind", "Test binding, exporting, importing and binding image.", testImageBindExportImportBind, imageConfig);
3735 addFunctionCase(imageGroup.get(), "export_bind_import_bind", "Test exporting, binding, importing and binding image.", testImageExportBindImportBind, imageConfig);
3736 addFunctionCase(imageGroup.get(), "export_import_bind_bind", "Test exporting, importind and binding image.", testImageExportImportBindBind, imageConfig);
3738 dedicatedGroup->addChild(imageGroup.release());
3741 group->addChild(dedicatedGroup.release());
3747 de::MovePtr<tcu::TestCaseGroup> createMemoryTests (tcu::TestContext& testCtx)
3749 de::MovePtr<tcu::TestCaseGroup> group (new tcu::TestCaseGroup(testCtx, "memory", "Tests for external memory"));
3751 group->addChild(createMemoryTests(testCtx, vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT_KHR).release());
3752 group->addChild(createMemoryTests(testCtx, vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT_KHR).release());
3753 group->addChild(createMemoryTests(testCtx, vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT_KHR).release());
3760 tcu::TestCaseGroup* createExternalMemoryTests (tcu::TestContext& testCtx)
3762 de::MovePtr<tcu::TestCaseGroup> group (new tcu::TestCaseGroup(testCtx, "external", "Tests for external Vulkan objects"));
3764 group->addChild(createSemaphoreTests(testCtx).release());
3765 group->addChild(createMemoryTests(testCtx).release());
3766 group->addChild(createFenceTests(testCtx).release());
3768 return group.release();