1 /*------------------------------------------------------------------------
2 * Vulkan Conformance Tests
3 * ------------------------
5 * Copyright (c) 2016 The Khronos Group 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.
21 * \brief Synchronization tests for resources shared between instances.
22 *//*--------------------------------------------------------------------*/
24 #include "vktSynchronizationCrossInstanceSharingTests.hpp"
26 #include "vkDeviceUtil.hpp"
27 #include "vkPlatform.hpp"
28 #include "vktTestCaseUtil.hpp"
30 #include "vktSynchronizationUtil.hpp"
31 #include "vktSynchronizationOperation.hpp"
32 #include "vktSynchronizationOperationTestData.hpp"
33 #include "vktSynchronizationOperationResources.hpp"
34 #include "vktExternalMemoryUtil.hpp"
36 #include "tcuResultCollector.hpp"
37 #include "tcuTestLog.hpp"
40 using namespace vkt::ExternalMemoryUtil;
44 namespace synchronization
51 TestConfig (const ResourceDescription& resource_,
52 OperationName writeOp_,
53 OperationName readOp_,
54 vk::VkExternalMemoryHandleTypeFlagBits memoryHandleType_,
55 vk::VkExternalSemaphoreHandleTypeFlagBits semaphoreHandleType_,
57 : resource (resource_)
60 , memoryHandleType (memoryHandleType_)
61 , semaphoreHandleType (semaphoreHandleType_)
62 , dedicated (dedicated_)
66 const ResourceDescription resource;
67 const OperationName writeOp;
68 const OperationName readOp;
69 const vk::VkExternalMemoryHandleTypeFlagBits memoryHandleType;
70 const vk::VkExternalSemaphoreHandleTypeFlagBits semaphoreHandleType;
74 // A helper class to test for extensions upfront and throw not supported to speed up test runtimes compared to failing only
75 // after creating unnecessary vkInstances. A common example of this is win32 platforms taking a long time to run _fd tests.
76 class NotSupportedChecker
79 NotSupportedChecker (const Context& context,
81 const OperationSupport& writeOp,
82 const OperationSupport& readOp)
85 // Check instance support
86 requireInstanceExtension("VK_KHR_get_physical_device_properties2");
88 requireInstanceExtension("VK_KHR_external_semaphore_capabilities");
89 requireInstanceExtension("VK_KHR_external_memory_capabilities");
91 // Check device support
93 requireDeviceExtension("VK_KHR_dedicated_allocation");
95 requireDeviceExtension("VK_KHR_external_semaphore");
96 requireDeviceExtension("VK_KHR_external_memory");
98 if (config.memoryHandleType == vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT_KHR
99 || config.semaphoreHandleType == vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT_KHR
100 || config.semaphoreHandleType == vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT_KHR)
102 requireDeviceExtension("VK_KHR_external_semaphore_fd");
103 requireDeviceExtension("VK_KHR_external_memory_fd");
106 if (config.memoryHandleType == vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT_KHR
107 || config.memoryHandleType == vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT_KHR
108 || config.semaphoreHandleType == vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_BIT_KHR
109 || config.semaphoreHandleType == vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT_KHR)
111 requireDeviceExtension("VK_KHR_external_semaphore_win32");
112 requireDeviceExtension("VK_KHR_external_memory_win32");
115 TestLog& log = context.getTestContext().getLog();
116 const vk::InstanceInterface& vki = context.getInstanceInterface();
117 const vk::VkPhysicalDevice physicalDevice = context.getPhysicalDevice();
119 // Check resource support
120 if (config.resource.type == RESOURCE_TYPE_IMAGE)
122 const vk::VkPhysicalDeviceExternalImageFormatInfo externalInfo =
124 vk::VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_IMAGE_FORMAT_INFO,
126 config.memoryHandleType
128 const vk::VkPhysicalDeviceImageFormatInfo2 imageFormatInfo =
130 vk::VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2,
132 config.resource.imageFormat,
133 config.resource.imageType,
134 vk::VK_IMAGE_TILING_OPTIMAL,
135 readOp.getResourceUsageFlags() | writeOp.getResourceUsageFlags(),
138 vk::VkExternalImageFormatProperties externalProperties =
140 vk::VK_STRUCTURE_TYPE_EXTERNAL_IMAGE_FORMAT_PROPERTIES,
144 vk::VkImageFormatProperties2 formatProperties =
146 vk::VK_STRUCTURE_TYPE_IMAGE_FORMAT_PROPERTIES_2,
158 const vk::VkResult res = vki.getPhysicalDeviceImageFormatProperties2(physicalDevice, &imageFormatInfo, &formatProperties);
160 if (res == vk::VK_ERROR_FORMAT_NOT_SUPPORTED)
161 TCU_THROW(NotSupportedError, "Image format not supported");
163 VK_CHECK(res); // Check other errors
166 log << TestLog::Message << "External image format properties: " << imageFormatInfo << "\n"<< externalProperties << TestLog::EndMessage;
168 if ((externalProperties.externalMemoryProperties.externalMemoryFeatures & vk::VK_EXTERNAL_MEMORY_FEATURE_EXPORTABLE_BIT_KHR) == 0)
169 TCU_THROW(NotSupportedError, "Exporting image resource not supported");
171 if ((externalProperties.externalMemoryProperties.externalMemoryFeatures & vk::VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT_KHR) == 0)
172 TCU_THROW(NotSupportedError, "Importing image resource not supported");
174 if (!config.dedicated && (externalProperties.externalMemoryProperties.externalMemoryFeatures & vk::VK_EXTERNAL_MEMORY_FEATURE_DEDICATED_ONLY_BIT_KHR) != 0)
176 TCU_THROW(NotSupportedError, "Handle requires dedicated allocation, but test uses suballocated memory");
181 const vk::VkPhysicalDeviceExternalBufferInfo info =
183 vk::VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_BUFFER_INFO,
187 readOp.getResourceUsageFlags() | writeOp.getResourceUsageFlags(),
188 config.memoryHandleType
190 vk::VkExternalBufferProperties properties =
192 vk::VK_STRUCTURE_TYPE_EXTERNAL_BUFFER_PROPERTIES,
196 vki.getPhysicalDeviceExternalBufferProperties(physicalDevice, &info, &properties);
198 log << TestLog::Message << "External buffer properties: " << info << "\n" << properties << TestLog::EndMessage;
200 if ((properties.externalMemoryProperties.externalMemoryFeatures & vk::VK_EXTERNAL_MEMORY_FEATURE_EXPORTABLE_BIT_KHR) == 0
201 || (properties.externalMemoryProperties.externalMemoryFeatures & vk::VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT_KHR) == 0)
202 TCU_THROW(NotSupportedError, "Exporting and importing memory type not supported");
204 if (!config.dedicated && (properties.externalMemoryProperties.externalMemoryFeatures & vk::VK_EXTERNAL_MEMORY_FEATURE_DEDICATED_ONLY_BIT_KHR) != 0)
206 TCU_THROW(NotSupportedError, "Handle requires dedicated allocation, but test uses suballocated memory");
210 // Check semaphore support
212 const vk::VkPhysicalDeviceExternalSemaphoreInfo info =
214 vk::VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_SEMAPHORE_INFO,
216 config.semaphoreHandleType
218 vk::VkExternalSemaphoreProperties properties;
220 vki.getPhysicalDeviceExternalSemaphoreProperties(physicalDevice, &info, &properties);
222 log << TestLog::Message << info << "\n" << properties << TestLog::EndMessage;
224 if ((properties.externalSemaphoreFeatures & vk::VK_EXTERNAL_SEMAPHORE_FEATURE_EXPORTABLE_BIT_KHR) == 0
225 || (properties.externalSemaphoreFeatures & vk::VK_EXTERNAL_SEMAPHORE_FEATURE_IMPORTABLE_BIT_KHR) == 0)
226 TCU_THROW(NotSupportedError, "Exporting and importing semaphore type not supported");
231 void requireDeviceExtension(const char* name) const
233 if (!de::contains(m_context.getDeviceExtensions().begin(), m_context.getDeviceExtensions().end(), name))
234 TCU_THROW(NotSupportedError, (std::string(name) + " is not supported").c_str());
237 void requireInstanceExtension(const char* name) const
239 if (!de::contains(m_context.getInstanceExtensions().begin(), m_context.getInstanceExtensions().end(), name))
240 TCU_THROW(NotSupportedError, (std::string(name) + " is not supported").c_str());
243 const Context& m_context;
246 bool checkQueueFlags (vk::VkQueueFlags availableFlags, const vk::VkQueueFlags neededFlags)
248 if ((availableFlags & (vk::VK_QUEUE_GRAPHICS_BIT | vk::VK_QUEUE_COMPUTE_BIT)) != 0)
249 availableFlags |= vk::VK_QUEUE_TRANSFER_BIT;
251 return (availableFlags & neededFlags) != 0;
254 class SimpleAllocation : public vk::Allocation
257 SimpleAllocation (const vk::DeviceInterface& vkd,
259 const vk::VkDeviceMemory memory);
260 ~SimpleAllocation (void);
263 const vk::DeviceInterface& m_vkd;
264 const vk::VkDevice m_device;
267 SimpleAllocation::SimpleAllocation (const vk::DeviceInterface& vkd,
269 const vk::VkDeviceMemory memory)
270 : Allocation (memory, 0, DE_NULL)
276 SimpleAllocation::~SimpleAllocation (void)
278 m_vkd.freeMemory(m_device, getMemory(), DE_NULL);
284 DeviceId (deUint32 vendorId,
285 deUint32 driverVersion,
286 const deUint8 driverUUID[VK_UUID_SIZE],
287 const deUint8 deviceUUID[VK_UUID_SIZE]);
289 bool operator== (const DeviceId& other) const;
290 bool operator|= (const DeviceId& other) const;
293 const deUint32 m_vendorId;
294 const deUint32 m_driverVersion;
295 deUint8 m_driverUUID[VK_UUID_SIZE];
296 deUint8 m_deviceUUID[VK_UUID_SIZE];
299 DeviceId::DeviceId (deUint32 vendorId,
300 deUint32 driverVersion,
301 const deUint8 driverUUID[VK_UUID_SIZE],
302 const deUint8 deviceUUID[VK_UUID_SIZE])
303 : m_vendorId (vendorId)
304 , m_driverVersion (driverVersion)
306 deMemcpy(m_driverUUID, driverUUID, sizeof(m_driverUUID));
307 deMemcpy(m_deviceUUID, deviceUUID, sizeof(m_deviceUUID));
310 bool DeviceId::operator== (const DeviceId& other) const
315 if (m_vendorId != other.m_vendorId)
318 if (m_driverVersion != other.m_driverVersion)
321 if (deMemCmp(m_driverUUID, other.m_driverUUID, sizeof(m_driverUUID)) != 0)
324 return deMemCmp(m_deviceUUID, other.m_deviceUUID, sizeof(m_deviceUUID)) == 0;
327 DeviceId getDeviceId (const vk::InstanceInterface& vki,
328 vk::VkPhysicalDevice physicalDevice)
330 vk::VkPhysicalDeviceIDProperties propertiesId;
331 vk::VkPhysicalDeviceProperties2 properties;
333 deMemset(&properties, 0, sizeof(properties));
334 deMemset(&propertiesId, 0, sizeof(propertiesId));
336 propertiesId.sType = vk::VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ID_PROPERTIES;
338 properties.sType = vk::VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2;
339 properties.pNext = &propertiesId;
341 vki.getPhysicalDeviceProperties2(physicalDevice, &properties);
343 return DeviceId(properties.properties.vendorID, properties.properties.driverVersion, propertiesId.driverUUID, propertiesId.deviceUUID);
346 vk::Move<vk::VkInstance> createInstance (const vk::PlatformInterface& vkp, deUint32 version)
350 std::vector<std::string> extensions;
351 if (!vk::isCoreInstanceExtension(version, "VK_KHR_get_physical_device_properties2"))
352 extensions.push_back("VK_KHR_get_physical_device_properties2");
353 if (!vk::isCoreInstanceExtension(version, "VK_KHR_external_semaphore_capabilities"))
354 extensions.push_back("VK_KHR_external_semaphore_capabilities");
355 if (!vk::isCoreInstanceExtension(version, "VK_KHR_external_memory_capabilities"))
356 extensions.push_back("VK_KHR_external_memory_capabilities");
358 return vk::createDefaultInstance(vkp, version, std::vector<std::string>(), extensions);
360 catch (const vk::Error& error)
362 if (error.getError() == vk::VK_ERROR_EXTENSION_NOT_PRESENT)
363 TCU_THROW(NotSupportedError, "Required external memory extensions not supported by the instance");
369 vk::VkPhysicalDevice getPhysicalDevice (const vk::InstanceInterface& vki,
370 vk::VkInstance instance,
371 const tcu::CommandLine& cmdLine)
373 return vk::chooseDevice(vki, instance, cmdLine);
376 vk::VkPhysicalDevice getPhysicalDevice (const vk::InstanceInterface& vki, vk::VkInstance instance, const DeviceId& deviceId)
378 const std::vector<vk::VkPhysicalDevice> devices (vk::enumeratePhysicalDevices(vki, instance));
380 for (size_t deviceNdx = 0; deviceNdx < devices.size(); deviceNdx++)
382 if (deviceId == getDeviceId(vki, devices[deviceNdx]))
383 return devices[deviceNdx];
386 TCU_FAIL("No matching device found");
388 return (vk::VkPhysicalDevice)0;
391 vk::Move<vk::VkDevice> createDevice (const deUint32 apiVersion,
392 const vk::InstanceInterface& vki,
393 vk::VkPhysicalDevice physicalDevice,
394 vk::VkExternalMemoryHandleTypeFlagBits memoryHandleType,
395 vk::VkExternalSemaphoreHandleTypeFlagBits semaphoreHandleType,
397 bool khrMemReqSupported)
399 const float priority = 0.0f;
400 const std::vector<vk::VkQueueFamilyProperties> queueFamilyProperties = vk::getPhysicalDeviceQueueFamilyProperties(vki, physicalDevice);
401 std::vector<deUint32> queueFamilyIndices (queueFamilyProperties.size(), 0xFFFFFFFFu);
402 std::vector<const char*> extensions;
405 if (!vk::isCoreDeviceExtension(apiVersion, "VK_KHR_dedicated_allocation"))
406 extensions.push_back("VK_KHR_dedicated_allocation");
408 if (khrMemReqSupported)
409 if (!vk::isCoreDeviceExtension(apiVersion, "VK_KHR_get_memory_requirements2"))
410 extensions.push_back("VK_KHR_get_memory_requirements2");
412 if (!vk::isCoreDeviceExtension(apiVersion, "VK_KHR_external_semaphore"))
413 extensions.push_back("VK_KHR_external_semaphore");
414 if (!vk::isCoreDeviceExtension(apiVersion, "VK_KHR_external_memory"))
415 extensions.push_back("VK_KHR_external_memory");
417 if (memoryHandleType == vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT
418 || semaphoreHandleType == vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT
419 || semaphoreHandleType == vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT)
421 extensions.push_back("VK_KHR_external_semaphore_fd");
422 extensions.push_back("VK_KHR_external_memory_fd");
425 if (memoryHandleType == vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT
426 || memoryHandleType == vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT
427 || semaphoreHandleType == vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_BIT
428 || semaphoreHandleType == vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT)
430 extensions.push_back("VK_KHR_external_semaphore_win32");
431 extensions.push_back("VK_KHR_external_memory_win32");
436 std::vector<vk::VkDeviceQueueCreateInfo> queues;
438 for (size_t ndx = 0; ndx < queueFamilyProperties.size(); ndx++)
440 const vk::VkDeviceQueueCreateInfo createInfo =
442 vk::VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO,
451 queues.push_back(createInfo);
454 const vk::VkDeviceCreateInfo createInfo =
456 vk::VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,
460 (deUint32)queues.size(),
466 (deUint32)extensions.size(),
467 extensions.empty() ? DE_NULL : &extensions[0],
471 return vk::createDevice(vki, physicalDevice, &createInfo);
473 catch (const vk::Error& error)
475 if (error.getError() == vk::VK_ERROR_EXTENSION_NOT_PRESENT)
476 TCU_THROW(NotSupportedError, "Required extensions not supported");
482 vk::VkQueue getQueue (const vk::DeviceInterface& vkd,
483 const vk::VkDevice device,
484 deUint32 familyIndex)
488 vkd.getDeviceQueue(device, familyIndex, 0u, &queue);
493 vk::Move<vk::VkCommandPool> createCommandPool (const vk::DeviceInterface& vkd,
495 deUint32 queueFamilyIndex)
497 const vk::VkCommandPoolCreateInfo createInfo =
499 vk::VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,
506 return vk::createCommandPool(vkd, device, &createInfo);
509 vk::Move<vk::VkCommandBuffer> createCommandBuffer (const vk::DeviceInterface& vkd,
511 vk::VkCommandPool commandPool)
513 const vk::VkCommandBufferLevel level = vk::VK_COMMAND_BUFFER_LEVEL_PRIMARY;
514 const vk::VkCommandBufferAllocateInfo allocateInfo =
516 vk::VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,
524 return vk::allocateCommandBuffer(vkd, device, &allocateInfo);
527 de::MovePtr<vk::Allocation> allocateAndBindMemory (const vk::DeviceInterface& vkd,
530 vk::VkExternalMemoryHandleTypeFlagBits externalType,
531 deUint32& exportedMemoryTypeIndex,
533 bool getMemReq2Supported)
535 vk::VkMemoryRequirements memoryRequirements = { 0u, 0u, 0u, };
537 if (getMemReq2Supported)
539 const vk::VkBufferMemoryRequirementsInfo2 requirementInfo =
541 vk::VK_STRUCTURE_TYPE_BUFFER_MEMORY_REQUIREMENTS_INFO_2,
545 vk::VkMemoryDedicatedRequirements dedicatedRequirements =
547 vk::VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS,
552 vk::VkMemoryRequirements2 requirements =
554 vk::VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2,
555 &dedicatedRequirements,
558 vkd.getBufferMemoryRequirements2(device, &requirementInfo, &requirements);
560 if (!dedicated && dedicatedRequirements.requiresDedicatedAllocation)
561 TCU_THROW(NotSupportedError, "Memory requires dedicated allocation");
563 memoryRequirements = requirements.memoryRequirements;
567 vkd.getBufferMemoryRequirements(device, buffer, &memoryRequirements);
571 vk::Move<vk::VkDeviceMemory> memory = allocateExportableMemory(vkd, device, memoryRequirements, externalType, dedicated ? buffer : (vk::VkBuffer)0, exportedMemoryTypeIndex);
572 VK_CHECK(vkd.bindBufferMemory(device, buffer, *memory, 0u));
574 return de::MovePtr<vk::Allocation>(new SimpleAllocation(vkd, device, memory.disown()));
577 de::MovePtr<vk::Allocation> allocateAndBindMemory (const vk::DeviceInterface& vkd,
580 vk::VkExternalMemoryHandleTypeFlagBits externalType,
581 deUint32& exportedMemoryTypeIndex,
583 bool getMemReq2Supported)
585 vk::VkMemoryRequirements memoryRequirements = { 0u, 0u, 0u, };
587 if (getMemReq2Supported)
589 const vk::VkImageMemoryRequirementsInfo2 requirementInfo =
591 vk::VK_STRUCTURE_TYPE_IMAGE_MEMORY_REQUIREMENTS_INFO_2,
595 vk::VkMemoryDedicatedRequirements dedicatedRequirements =
597 vk::VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS,
602 vk::VkMemoryRequirements2 requirements =
604 vk::VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2,
605 &dedicatedRequirements,
608 vkd.getImageMemoryRequirements2(device, &requirementInfo, &requirements);
610 if (!dedicated && dedicatedRequirements.requiresDedicatedAllocation)
611 TCU_THROW(NotSupportedError, "Memory requires dedicated allocation");
613 memoryRequirements = requirements.memoryRequirements;
617 vkd.getImageMemoryRequirements(device, image, &memoryRequirements);
620 vk::Move<vk::VkDeviceMemory> memory = allocateExportableMemory(vkd, device, memoryRequirements, externalType, dedicated ? image : (vk::VkImage)0, exportedMemoryTypeIndex);
621 VK_CHECK(vkd.bindImageMemory(device, image, *memory, 0u));
623 return de::MovePtr<vk::Allocation>(new SimpleAllocation(vkd, device, memory.disown()));
626 de::MovePtr<Resource> createResource (const vk::DeviceInterface& vkd,
628 const ResourceDescription& resourceDesc,
629 const std::vector<deUint32>& queueFamilyIndices,
630 const OperationSupport& readOp,
631 const OperationSupport& writeOp,
632 vk::VkExternalMemoryHandleTypeFlagBits externalType,
633 deUint32& exportedMemoryTypeIndex,
635 bool getMemReq2Supported)
637 if (resourceDesc.type == RESOURCE_TYPE_IMAGE)
639 const vk::VkExtent3D extent =
641 (deUint32)resourceDesc.size.x(),
642 de::max(1u, (deUint32)resourceDesc.size.y()),
643 de::max(1u, (deUint32)resourceDesc.size.z())
645 const vk::VkImageSubresourceRange subresourceRange =
647 resourceDesc.imageAspect,
653 const vk::VkImageSubresourceLayers subresourceLayers =
655 resourceDesc.imageAspect,
660 const vk::VkExternalMemoryImageCreateInfo externalInfo =
662 vk::VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO,
664 (vk::VkExternalMemoryHandleTypeFlags)externalType
666 const vk::VkImageCreateInfo createInfo =
668 vk::VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
672 resourceDesc.imageType,
673 resourceDesc.imageFormat,
677 vk::VK_SAMPLE_COUNT_1_BIT,
678 vk::VK_IMAGE_TILING_OPTIMAL,
679 readOp.getResourceUsageFlags() | writeOp.getResourceUsageFlags(),
680 vk::VK_SHARING_MODE_EXCLUSIVE,
682 (deUint32)queueFamilyIndices.size(),
683 &queueFamilyIndices[0],
684 vk::VK_IMAGE_LAYOUT_UNDEFINED
687 vk::Move<vk::VkImage> image = vk::createImage(vkd, device, &createInfo);
688 de::MovePtr<vk::Allocation> allocation = allocateAndBindMemory(vkd, device, *image, externalType, exportedMemoryTypeIndex, dedicated, getMemReq2Supported);
690 return de::MovePtr<Resource>(new Resource(image, allocation, extent, resourceDesc.imageType, resourceDesc.imageFormat, subresourceRange, subresourceLayers));
694 const vk::VkDeviceSize offset = 0u;
695 const vk::VkDeviceSize size = static_cast<vk::VkDeviceSize>(resourceDesc.size.x());
696 const vk::VkBufferUsageFlags usage = readOp.getResourceUsageFlags() | writeOp.getResourceUsageFlags();
697 const vk:: VkExternalMemoryBufferCreateInfo externalInfo =
699 vk::VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_BUFFER_CREATE_INFO,
701 (vk::VkExternalMemoryHandleTypeFlags)externalType
703 const vk::VkBufferCreateInfo createInfo =
705 vk::VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
711 vk::VK_SHARING_MODE_EXCLUSIVE,
712 (deUint32)queueFamilyIndices.size(),
713 &queueFamilyIndices[0]
715 vk::Move<vk::VkBuffer> buffer = vk::createBuffer(vkd, device, &createInfo);
716 de::MovePtr<vk::Allocation> allocation = allocateAndBindMemory(vkd, device, *buffer, externalType, exportedMemoryTypeIndex, dedicated, getMemReq2Supported);
718 return de::MovePtr<Resource>(new Resource(resourceDesc.type, buffer, allocation, offset, size));
722 de::MovePtr<vk::Allocation> importAndBindMemory (const vk::DeviceInterface& vkd,
725 NativeHandle& nativeHandle,
726 vk::VkExternalMemoryHandleTypeFlagBits externalType,
727 deUint32 exportedMemoryTypeIndex,
730 const vk::VkMemoryRequirements requirements = vk::getBufferMemoryRequirements(vkd, device, buffer);
731 vk::Move<vk::VkDeviceMemory> memory = dedicated
732 ? importDedicatedMemory(vkd, device, buffer, requirements, externalType, exportedMemoryTypeIndex, nativeHandle)
733 : importMemory(vkd, device, requirements, externalType, exportedMemoryTypeIndex, nativeHandle);
735 VK_CHECK(vkd.bindBufferMemory(device, buffer, *memory, 0u));
737 return de::MovePtr<vk::Allocation>(new SimpleAllocation(vkd, device, memory.disown()));
740 de::MovePtr<vk::Allocation> importAndBindMemory (const vk::DeviceInterface& vkd,
743 NativeHandle& nativeHandle,
744 vk::VkExternalMemoryHandleTypeFlagBits externalType,
745 deUint32 exportedMemoryTypeIndex,
748 const vk::VkMemoryRequirements requirements = vk::getImageMemoryRequirements(vkd, device, image);
749 vk::Move<vk::VkDeviceMemory> memory = dedicated
750 ? importDedicatedMemory(vkd, device, image, requirements, externalType, exportedMemoryTypeIndex, nativeHandle)
751 : importMemory(vkd, device, requirements, externalType, exportedMemoryTypeIndex, nativeHandle);
752 VK_CHECK(vkd.bindImageMemory(device, image, *memory, 0u));
754 return de::MovePtr<vk::Allocation>(new SimpleAllocation(vkd, device, memory.disown()));
757 de::MovePtr<Resource> importResource (const vk::DeviceInterface& vkd,
759 const ResourceDescription& resourceDesc,
760 const std::vector<deUint32>& queueFamilyIndices,
761 const OperationSupport& readOp,
762 const OperationSupport& writeOp,
763 NativeHandle& nativeHandle,
764 vk::VkExternalMemoryHandleTypeFlagBits externalType,
765 deUint32 exportedMemoryTypeIndex,
768 if (resourceDesc.type == RESOURCE_TYPE_IMAGE)
770 const vk::VkExtent3D extent =
772 (deUint32)resourceDesc.size.x(),
773 de::max(1u, (deUint32)resourceDesc.size.y()),
774 de::max(1u, (deUint32)resourceDesc.size.z())
776 const vk::VkImageSubresourceRange subresourceRange =
778 resourceDesc.imageAspect,
784 const vk::VkImageSubresourceLayers subresourceLayers =
786 resourceDesc.imageAspect,
791 const vk:: VkExternalMemoryImageCreateInfo externalInfo =
793 vk::VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO,
795 (vk::VkExternalMemoryHandleTypeFlags)externalType
797 const vk::VkImageCreateInfo createInfo =
799 vk::VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
803 resourceDesc.imageType,
804 resourceDesc.imageFormat,
808 vk::VK_SAMPLE_COUNT_1_BIT,
809 vk::VK_IMAGE_TILING_OPTIMAL,
810 readOp.getResourceUsageFlags() | writeOp.getResourceUsageFlags(),
811 vk::VK_SHARING_MODE_EXCLUSIVE,
813 (deUint32)queueFamilyIndices.size(),
814 &queueFamilyIndices[0],
815 vk::VK_IMAGE_LAYOUT_UNDEFINED
818 vk::Move<vk::VkImage> image = vk::createImage(vkd, device, &createInfo);
819 de::MovePtr<vk::Allocation> allocation = importAndBindMemory(vkd, device, *image, nativeHandle, externalType, exportedMemoryTypeIndex, dedicated);
821 return de::MovePtr<Resource>(new Resource(image, allocation, extent, resourceDesc.imageType, resourceDesc.imageFormat, subresourceRange, subresourceLayers));
825 const vk::VkDeviceSize offset = 0u;
826 const vk::VkDeviceSize size = static_cast<vk::VkDeviceSize>(resourceDesc.size.x());
827 const vk::VkBufferUsageFlags usage = readOp.getResourceUsageFlags() | writeOp.getResourceUsageFlags();
828 const vk:: VkExternalMemoryBufferCreateInfo externalInfo =
830 vk::VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_BUFFER_CREATE_INFO,
832 (vk::VkExternalMemoryHandleTypeFlags)externalType
834 const vk::VkBufferCreateInfo createInfo =
836 vk::VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
842 vk::VK_SHARING_MODE_EXCLUSIVE,
843 (deUint32)queueFamilyIndices.size(),
844 &queueFamilyIndices[0]
846 vk::Move<vk::VkBuffer> buffer = vk::createBuffer(vkd, device, &createInfo);
847 de::MovePtr<vk::Allocation> allocation = importAndBindMemory(vkd, device, *buffer, nativeHandle, externalType, exportedMemoryTypeIndex, dedicated);
849 return de::MovePtr<Resource>(new Resource(resourceDesc.type, buffer, allocation, offset, size));
853 void recordWriteBarrier (const vk::DeviceInterface& vkd,
854 vk::VkCommandBuffer commandBuffer,
855 const Resource& resource,
856 const SyncInfo& writeSync,
857 deUint32 writeQueueFamilyIndex,
858 const SyncInfo& readSync)
860 const vk::VkPipelineStageFlags srcStageMask = writeSync.stageMask;
861 const vk::VkAccessFlags srcAccessMask = writeSync.accessMask;
863 const vk::VkPipelineStageFlags dstStageMask = readSync.stageMask;
864 const vk::VkAccessFlags dstAccessMask = readSync.accessMask;
866 const vk::VkDependencyFlags dependencyFlags = 0;
868 if (resource.getType() == RESOURCE_TYPE_IMAGE)
870 const vk::VkImageMemoryBarrier barrier =
872 vk::VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
878 writeSync.imageLayout,
879 readSync.imageLayout,
881 writeQueueFamilyIndex,
882 VK_QUEUE_FAMILY_EXTERNAL,
884 resource.getImage().handle,
885 resource.getImage().subresourceRange
888 vkd.cmdPipelineBarrier(commandBuffer, srcStageMask, dstStageMask, dependencyFlags, 0u, (const vk::VkMemoryBarrier*)DE_NULL, 0u, (const vk::VkBufferMemoryBarrier*)DE_NULL, 1u, (const vk::VkImageMemoryBarrier*)&barrier);
892 const vk::VkBufferMemoryBarrier barrier =
894 vk::VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
900 writeQueueFamilyIndex,
901 VK_QUEUE_FAMILY_EXTERNAL,
903 resource.getBuffer().handle,
908 vkd.cmdPipelineBarrier(commandBuffer, srcStageMask, dstStageMask, dependencyFlags, 0u, (const vk::VkMemoryBarrier*)DE_NULL, 1u, (const vk::VkBufferMemoryBarrier*)&barrier, 0u, (const vk::VkImageMemoryBarrier*)DE_NULL);
912 void recordReadBarrier (const vk::DeviceInterface& vkd,
913 vk::VkCommandBuffer commandBuffer,
914 const Resource& resource,
915 const SyncInfo& writeSync,
916 const SyncInfo& readSync,
917 deUint32 readQueueFamilyIndex)
919 const vk::VkPipelineStageFlags srcStageMask = readSync.stageMask;
920 const vk::VkAccessFlags srcAccessMask = readSync.accessMask;
922 const vk::VkPipelineStageFlags dstStageMask = readSync.stageMask;
923 const vk::VkAccessFlags dstAccessMask = readSync.accessMask;
925 const vk::VkDependencyFlags dependencyFlags = 0;
927 if (resource.getType() == RESOURCE_TYPE_IMAGE)
929 const vk::VkImageMemoryBarrier barrier =
931 vk::VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
937 writeSync.imageLayout,
938 readSync.imageLayout,
940 VK_QUEUE_FAMILY_EXTERNAL,
941 readQueueFamilyIndex,
943 resource.getImage().handle,
944 resource.getImage().subresourceRange
947 vkd.cmdPipelineBarrier(commandBuffer, srcStageMask, dstStageMask, dependencyFlags, 0u, (const vk::VkMemoryBarrier*)DE_NULL, 0u, (const vk::VkBufferMemoryBarrier*)DE_NULL, 1u, (const vk::VkImageMemoryBarrier*)&barrier);
951 const vk::VkBufferMemoryBarrier barrier =
953 vk::VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
959 VK_QUEUE_FAMILY_EXTERNAL,
960 readQueueFamilyIndex,
962 resource.getBuffer().handle,
967 vkd.cmdPipelineBarrier(commandBuffer, srcStageMask, dstStageMask, dependencyFlags, 0u, (const vk::VkMemoryBarrier*)DE_NULL, 1u, (const vk::VkBufferMemoryBarrier*)&barrier, 0u, (const vk::VkImageMemoryBarrier*)DE_NULL);
971 std::vector<deUint32> getFamilyIndices (const std::vector<vk::VkQueueFamilyProperties>& properties)
973 std::vector<deUint32> indices (properties.size(), 0);
975 for (deUint32 ndx = 0; ndx < properties.size(); ndx++)
981 class SharingTestInstance : public TestInstance
984 SharingTestInstance (Context& context,
987 virtual tcu::TestStatus iterate (void);
990 const TestConfig m_config;
991 const de::UniquePtr<OperationSupport> m_supportWriteOp;
992 const de::UniquePtr<OperationSupport> m_supportReadOp;
993 const NotSupportedChecker m_notSupportedChecker; // Must declare before VkInstance to effectively reduce runtimes!
995 const vk::Unique<vk::VkInstance> m_instanceA;
997 const vk::InstanceDriver m_vkiA;
998 const vk::VkPhysicalDevice m_physicalDeviceA;
999 const std::vector<vk::VkQueueFamilyProperties> m_queueFamiliesA;
1000 const std::vector<deUint32> m_queueFamilyIndicesA;
1002 const bool m_getMemReq2Supported;
1004 const vk::Unique<vk::VkDevice> m_deviceA;
1005 const vk::DeviceDriver m_vkdA;
1007 const vk::Unique<vk::VkInstance> m_instanceB;
1008 const vk::InstanceDriver m_vkiB;
1009 const vk::VkPhysicalDevice m_physicalDeviceB;
1010 const std::vector<vk::VkQueueFamilyProperties> m_queueFamiliesB;
1011 const std::vector<deUint32> m_queueFamilyIndicesB;
1012 const vk::Unique<vk::VkDevice> m_deviceB;
1013 const vk::DeviceDriver m_vkdB;
1015 const vk::VkExternalSemaphoreHandleTypeFlagBits m_semaphoreHandleType;
1016 const vk::VkExternalMemoryHandleTypeFlagBits m_memoryHandleType;
1018 // \todo Should this be moved to the group same way as in the other tests?
1019 PipelineCacheData m_pipelineCacheData;
1020 tcu::ResultCollector m_resultCollector;
1025 SharingTestInstance::SharingTestInstance (Context& context,
1027 : TestInstance (context)
1029 , m_supportWriteOp (makeOperationSupport(config.writeOp, config.resource))
1030 , m_supportReadOp (makeOperationSupport(config.readOp, config.resource))
1031 , m_notSupportedChecker (context, m_config, *m_supportWriteOp, *m_supportReadOp)
1033 , m_instanceA (createInstance(context.getPlatformInterface(), context.getUsedApiVersion()))
1035 , m_vkiA (context.getPlatformInterface(), *m_instanceA) // \todo [2017-06-13 pyry] Provide correct extension list
1036 , m_physicalDeviceA (getPhysicalDevice(m_vkiA, *m_instanceA, context.getTestContext().getCommandLine()))
1037 , m_queueFamiliesA (vk::getPhysicalDeviceQueueFamilyProperties(m_vkiA, m_physicalDeviceA))
1038 , m_queueFamilyIndicesA (getFamilyIndices(m_queueFamiliesA))
1039 , m_getMemReq2Supported (vk::isDeviceExtensionSupported(context.getUsedApiVersion(), context.getDeviceExtensions(), "VK_KHR_get_memory_requirements2"))
1040 , m_deviceA (createDevice(context.getUsedApiVersion(), m_vkiA, m_physicalDeviceA, m_config.memoryHandleType, m_config.semaphoreHandleType, m_config.dedicated, m_getMemReq2Supported))
1041 , m_vkdA (m_vkiA, *m_deviceA)
1043 , m_instanceB (createInstance(context.getPlatformInterface(), context.getUsedApiVersion()))
1045 , m_vkiB (context.getPlatformInterface(), *m_instanceB) // \todo [2017-06-13 pyry] Provide correct extension list
1046 , m_physicalDeviceB (getPhysicalDevice(m_vkiB, *m_instanceB, getDeviceId(m_vkiA, m_physicalDeviceA)))
1047 , m_queueFamiliesB (vk::getPhysicalDeviceQueueFamilyProperties(m_vkiB, m_physicalDeviceB))
1048 , m_queueFamilyIndicesB (getFamilyIndices(m_queueFamiliesB))
1049 , m_deviceB (createDevice(context.getUsedApiVersion(), m_vkiB, m_physicalDeviceB, m_config.memoryHandleType, m_config.semaphoreHandleType, m_config.dedicated, m_getMemReq2Supported))
1050 , m_vkdB (m_vkiB, *m_deviceB)
1052 , m_semaphoreHandleType (m_config.semaphoreHandleType)
1053 , m_memoryHandleType (m_config.memoryHandleType)
1055 , m_resultCollector (context.getTestContext().getLog())
1061 tcu::TestStatus SharingTestInstance::iterate (void)
1063 TestLog& log (m_context.getTestContext().getLog());
1067 const deUint32 queueFamilyA = (deUint32)m_queueANdx;
1068 const deUint32 queueFamilyB = (deUint32)m_queueBNdx;
1070 const tcu::ScopedLogSection queuePairSection (log,
1071 "WriteQueue-" + de::toString(queueFamilyA) + "-ReadQueue-" + de::toString(queueFamilyB),
1072 "WriteQueue-" + de::toString(queueFamilyA) + "-ReadQueue-" + de::toString(queueFamilyB));
1074 const vk::Unique<vk::VkSemaphore> semaphoreA (createExportableSemaphore(m_vkdA, *m_deviceA, m_semaphoreHandleType));
1075 const vk::Unique<vk::VkSemaphore> semaphoreB (createSemaphore(m_vkdB, *m_deviceB));
1077 deUint32 exportedMemoryTypeIndex = ~0U;
1078 const de::UniquePtr<Resource> resourceA (createResource(m_vkdA, *m_deviceA, m_config.resource, m_queueFamilyIndicesA, *m_supportReadOp, *m_supportWriteOp, m_memoryHandleType, exportedMemoryTypeIndex, m_config.dedicated, m_getMemReq2Supported));
1080 NativeHandle nativeMemoryHandle;
1081 getMemoryNative(m_vkdA, *m_deviceA, resourceA->getMemory(), m_memoryHandleType, nativeMemoryHandle);
1083 const de::UniquePtr<Resource> resourceB (importResource(m_vkdB, *m_deviceB, m_config.resource, m_queueFamilyIndicesB, *m_supportReadOp, *m_supportWriteOp, nativeMemoryHandle, m_memoryHandleType, exportedMemoryTypeIndex, m_config.dedicated));
1086 const vk::VkQueue queueA (getQueue(m_vkdA, *m_deviceA, queueFamilyA));
1087 const vk::Unique<vk::VkCommandPool> commandPoolA (createCommandPool(m_vkdA, *m_deviceA, queueFamilyA));
1088 const vk::Unique<vk::VkCommandBuffer> commandBufferA (createCommandBuffer(m_vkdA, *m_deviceA, *commandPoolA));
1089 vk::SimpleAllocator allocatorA (m_vkdA, *m_deviceA, vk::getPhysicalDeviceMemoryProperties(m_vkiA, m_physicalDeviceA));
1090 const std::vector<std::string> deviceExtensionsA;
1091 OperationContext operationContextA (m_context.getUsedApiVersion(), m_vkiA, m_vkdA, m_physicalDeviceA, *m_deviceA, allocatorA, deviceExtensionsA, m_context.getBinaryCollection(), m_pipelineCacheData);
1093 if (!checkQueueFlags(m_queueFamiliesA[m_queueANdx].queueFlags , m_supportWriteOp->getQueueFlags(operationContextA)))
1094 TCU_THROW(NotSupportedError, "Operation not supported by the source queue");
1096 const vk::VkQueue queueB (getQueue(m_vkdB, *m_deviceB, queueFamilyB));
1097 const vk::Unique<vk::VkCommandPool> commandPoolB (createCommandPool(m_vkdB, *m_deviceB, queueFamilyB));
1098 const vk::Unique<vk::VkCommandBuffer> commandBufferB (createCommandBuffer(m_vkdB, *m_deviceB, *commandPoolB));
1099 vk::SimpleAllocator allocatorB (m_vkdB, *m_deviceB, vk::getPhysicalDeviceMemoryProperties(m_vkiB, m_physicalDeviceB));
1100 const std::vector<std::string> deviceExtensionsB;
1101 OperationContext operationContextB (m_context.getUsedApiVersion(), m_vkiB, m_vkdB, m_physicalDeviceB, *m_deviceB, allocatorB, deviceExtensionsB, m_context.getBinaryCollection(), m_pipelineCacheData);
1103 if (!checkQueueFlags(m_queueFamiliesB[m_queueBNdx].queueFlags , m_supportReadOp->getQueueFlags(operationContextB)))
1104 TCU_THROW(NotSupportedError, "Operation not supported by the destination queue");
1106 const de::UniquePtr<Operation> writeOp (m_supportWriteOp->build(operationContextA, *resourceA));
1107 const de::UniquePtr<Operation> readOp (m_supportReadOp->build(operationContextB, *resourceB));
1109 const SyncInfo writeSync = writeOp->getSyncInfo();
1110 const SyncInfo readSync = readOp->getSyncInfo();
1112 beginCommandBuffer(m_vkdA, *commandBufferA);
1113 writeOp->recordCommands(*commandBufferA);
1114 recordWriteBarrier(m_vkdA, *commandBufferA, *resourceA, writeSync, queueFamilyA, readSync);
1115 endCommandBuffer(m_vkdA, *commandBufferA);
1117 beginCommandBuffer(m_vkdB, *commandBufferB);
1118 recordReadBarrier(m_vkdB, *commandBufferB, *resourceB, writeSync, readSync, queueFamilyB);
1119 readOp->recordCommands(*commandBufferB);
1120 endCommandBuffer(m_vkdB, *commandBufferB);
1123 const vk::VkCommandBuffer commandBuffer = *commandBufferA;
1124 const vk::VkSemaphore semaphore = *semaphoreA;
1125 const vk::VkSubmitInfo submitInfo =
1127 vk::VK_STRUCTURE_TYPE_SUBMIT_INFO,
1140 VK_CHECK(m_vkdA.queueSubmit(queueA, 1u, &submitInfo, DE_NULL));
1143 NativeHandle nativeSemaphoreHandle;
1145 getSemaphoreNative(m_vkdA, *m_deviceA, *semaphoreA, m_semaphoreHandleType, nativeSemaphoreHandle);
1146 importSemaphore(m_vkdB, *m_deviceB, *semaphoreB, m_semaphoreHandleType, nativeSemaphoreHandle, 0u);
1150 const vk::VkCommandBuffer commandBuffer = *commandBufferB;
1151 const vk::VkSemaphore semaphore = *semaphoreB;
1152 const vk::VkPipelineStageFlags dstStage = readSync.stageMask;
1153 const vk::VkSubmitInfo submitInfo =
1155 vk::VK_STRUCTURE_TYPE_SUBMIT_INFO,
1168 VK_CHECK(m_vkdB.queueSubmit(queueB, 1u, &submitInfo, DE_NULL));
1171 VK_CHECK(m_vkdA.queueWaitIdle(queueA));
1172 VK_CHECK(m_vkdB.queueWaitIdle(queueB));
1175 const Data expected = writeOp->getData();
1176 const Data actual = readOp->getData();
1178 DE_ASSERT(expected.size == actual.size);
1180 if (0 != deMemCmp(expected.data, actual.data, expected.size))
1182 const size_t maxBytesLogged = 256;
1183 std::ostringstream expectedData;
1184 std::ostringstream actualData;
1187 // Find first byte difference
1188 for (; actual.data[byteNdx] == expected.data[byteNdx]; byteNdx++)
1193 log << TestLog::Message << "First different byte at offset: " << byteNdx << TestLog::EndMessage;
1195 // Log 8 previous bytes before the first incorrect byte
1198 expectedData << "... ";
1199 actualData << "... ";
1206 for (size_t i = 0; i < maxBytesLogged && byteNdx < expected.size; i++, byteNdx++)
1208 expectedData << (i > 0 ? ", " : "") << (deUint32)expected.data[byteNdx];
1209 actualData << (i > 0 ? ", " : "") << (deUint32)actual.data[byteNdx];
1212 if (expected.size > byteNdx)
1214 expectedData << "...";
1215 actualData << "...";
1218 log << TestLog::Message << "Expected data: (" << expectedData.str() << ")" << TestLog::EndMessage;
1219 log << TestLog::Message << "Actual data: (" << actualData.str() << ")" << TestLog::EndMessage;
1221 m_resultCollector.fail("Memory contents don't match");
1225 catch (const tcu::NotSupportedError& error)
1227 log << TestLog::Message << "Not supported: " << error.getMessage() << TestLog::EndMessage;
1229 catch (const tcu::TestError& error)
1231 m_resultCollector.fail(std::string("Exception: ") + error.getMessage());
1234 // Move to next queue
1238 if (m_queueBNdx >= m_queueFamiliesB.size())
1242 if (m_queueANdx >= m_queueFamiliesA.size())
1244 return tcu::TestStatus(m_resultCollector.getResult(), m_resultCollector.getMessage());
1250 return tcu::TestStatus::incomplete();
1254 return tcu::TestStatus::incomplete();
1260 void init (vk::SourceCollections& dst, TestConfig config) const
1262 const de::UniquePtr<OperationSupport> readOp (makeOperationSupport(config.readOp, config.resource));
1263 const de::UniquePtr<OperationSupport> writeOp (makeOperationSupport(config.writeOp, config.resource));
1265 readOp->initPrograms(dst);
1266 writeOp->initPrograms(dst);
1272 tcu::TestCaseGroup* createCrossInstanceSharingTest (tcu::TestContext& testCtx)
1276 vk::VkExternalMemoryHandleTypeFlagBits memoryType;
1277 vk::VkExternalSemaphoreHandleTypeFlagBits semaphoreType;
1278 const char* nameSuffix;
1282 vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT,
1283 vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT,
1287 vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT,
1288 vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT,
1292 vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT,
1293 vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT,
1297 vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT,
1298 vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_BIT,
1302 de::MovePtr<tcu::TestCaseGroup> group (new tcu::TestCaseGroup(testCtx, "cross_instance", ""));
1304 for (size_t dedicatedNdx = 0; dedicatedNdx < 2; dedicatedNdx++)
1306 const bool dedicated (dedicatedNdx == 1);
1307 de::MovePtr<tcu::TestCaseGroup> dedicatedGroup (new tcu::TestCaseGroup(testCtx, dedicated ? "dedicated" : "suballocated", ""));
1309 for (size_t writeOpNdx = 0; writeOpNdx < DE_LENGTH_OF_ARRAY(s_writeOps); ++writeOpNdx)
1310 for (size_t readOpNdx = 0; readOpNdx < DE_LENGTH_OF_ARRAY(s_readOps); ++readOpNdx)
1312 const OperationName writeOp = s_writeOps[writeOpNdx];
1313 const OperationName readOp = s_readOps[readOpNdx];
1314 const std::string opGroupName = getOperationName(writeOp) + "_" + getOperationName(readOp);
1317 de::MovePtr<tcu::TestCaseGroup> opGroup (new tcu::TestCaseGroup(testCtx, opGroupName.c_str(), ""));
1319 for (size_t resourceNdx = 0; resourceNdx < DE_LENGTH_OF_ARRAY(s_resources); ++resourceNdx)
1321 const ResourceDescription& resource = s_resources[resourceNdx];
1323 for (size_t caseNdx = 0; caseNdx < DE_LENGTH_OF_ARRAY(cases); caseNdx++)
1325 std::string name= getResourceName(resource) + cases[caseNdx].nameSuffix;
1327 if (isResourceSupported(writeOp, resource) && isResourceSupported(readOp, resource))
1329 const TestConfig config (resource, writeOp, readOp, cases[caseNdx].memoryType, cases[caseNdx].semaphoreType, dedicated);
1331 opGroup->addChild(new InstanceFactory1<SharingTestInstance, TestConfig, Progs>(testCtx, tcu::NODETYPE_SELF_VALIDATE, name, "", Progs(), config));
1338 dedicatedGroup->addChild(opGroup.release());
1341 group->addChild(dedicatedGroup.release());
1344 return group.release();
1347 } // synchronization