Merge vk-gl-cts/main into vk-gl-cts/dev/VK_EXT_device_fault
authorMatthew Netsch <quic_mnetsch@quicinc.com>
Fri, 18 Nov 2022 17:29:12 +0000 (09:29 -0800)
committerMatthew Netsch <quic_mnetsch@quicinc.com>
Fri, 18 Nov 2022 17:29:12 +0000 (09:29 -0800)
Change-Id: I9aaf9f104f8edea608db8f888e59243e07604852

1  2 
AndroidGen.mk
external/vulkancts/modules/vulkan/postmortem/CMakeLists.txt
external/vulkancts/modules/vulkan/postmortem/vktPostmortemDeviceFaultTests.cpp

diff --cc AndroidGen.mk
Simple merge
index 4748202,0000000..481ca50
mode 100644,000000..100644
--- /dev/null
@@@ -1,492 -1,0 +1,490 @@@
-                       engineVersion                   = VK_MAKE_VERSION(3,4,5);
-                       apiVersion                              = VK_MAKE_API_VERSION(1,7,3,11);
 +/*------------------------------------------------------------------------
 + * Vulkan Conformance Tests
 + * ------------------------
 + *
 + * Copyright (c) 2021 The Khronos Group Inc.
 + *
 + * Licensed under the Apache License, Version 2.0 (the "License");
 + * you may not use this file except in compliance with the License.
 + * You may obtain a copy of the License at
 + *
 + *      http://www.apache.org/licenses/LICENSE-2.0
 + *
 + * Unless required by applicable law or agreed to in writing, software
 + * distributed under the License is distributed on an "AS IS" BASIS,
 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 + * See the License for the specific language governing permissions and
 + * limitations under the License.
 + *
 + *//*!
 + * \file
 + * \brief VK_EXT_device_fault extension tests.
 + *//*--------------------------------------------------------------------*/
 +
 +#include "vktPostmortemDeviceFaultTests.hpp"
 +#include "vktCustomInstancesDevices.hpp"
 +
 +#include "deStringUtil.hpp"
 +#include "vkDefs.hpp"
 +#include "vktTestCase.hpp"
 +#include "vktTestGroupUtil.hpp"
 +#include "tcuTestLog.hpp"
 +#include "tcuCommandLine.hpp"
 +
 +#include <functional>
 +#include <limits>
 +#include <sstream>
 +#include <utility>
 +#include <vector>
 +
 +#define ARRAY_LENGTH(a_) std::extent<decltype(a_)>::value
 +
 +#ifndef VK_EXT_DEVICE_FAULT_EXTENSION_NAME
 +      #define VK_EXT_DEVICE_FAULT_EXTENSION_NAME "VK_EXT_device_fault"
 +#else
 +      // This should never have happened
 +      // static_assert(false, "Trying to redefine VK_EXT_DEVICE_FAULT_EXTENSION_NAME");
 +#endif
 +
 +namespace vkt
 +{
 +namespace postmortem
 +{
 +namespace
 +{
 +using namespace vk;
 +using namespace tcu;
 +
 +enum class TestType
 +{
 +      Fake,
 +      Real,
 +      CustomDevice
 +};
 +
 +struct TestParams
 +{
 +      TestType        type;
 +};
 +
 +class DeviceFaultCase : public TestCase
 +{
 +public:
 +                                                      DeviceFaultCase         (TestContext&           testCtx,
 +                                                                                               const std::string&     name,
 +                                                                                               const TestParams&      params)
 +                                                              : TestCase      (testCtx, name, std::string())
 +                                                              , m_params      (params) {}
 +      virtual                                 ~DeviceFaultCase        () = default;
 +      virtual TestInstance*   createInstance          (Context&                       context) const override;
 +      virtual void                    checkSupport            (Context&                       context) const override;
 +private:
 +      const TestParams        m_params;
 +};
 +
 +class DeviceFaultInstance : public TestInstance
 +{
 +public:
 +                                                      DeviceFaultInstance     (Context& context, const TestParams& params)
 +                                                              : TestInstance                          (context)
 +                                                              , m_params                                      (params) {}
 +      virtual                                 ~DeviceFaultInstance() =  default;
 +
 +      virtual TestStatus              iterate                         (void) override;
 +      void                                    log                                     (const std::vector<VkDeviceFaultAddressInfoEXT>&        addressInfos,
 +                                                                                               const std::vector<VkDeviceFaultVendorInfoEXT>&         vendorInfos,
 +                                                                                               const std::vector<deUint8>&                                            vendorBinaryData) const;
 +private:
 +      const TestParams        m_params;
 +};
 +
 +class DeviceFaultCustomInstance : public TestInstance
 +{
 +public:
 +                                                      DeviceFaultCustomInstance       (Context& context)
 +                                                              : TestInstance                  (context) {}
 +      virtual                                 ~DeviceFaultCustomInstance      () =  default;
 +
 +      virtual TestStatus              iterate                                         (void) override;
 +};
 +
 +TestInstance* DeviceFaultCase::createInstance (Context& context) const
 +{
 +      TestInstance* instance = nullptr;
 +      if (m_params.type == TestType::CustomDevice)
 +              instance = new DeviceFaultCustomInstance(context);
 +      else instance = new DeviceFaultInstance(context, m_params);
 +      return instance;
 +}
 +
 +class CustomDevice
 +{
 +      Move<VkDevice>                          m_logicalDevice;
 +
 +public:
 +      CustomDevice (Context& context)
 +      {
 +              const bool                                                              useValidation           = context.getTestContext().getCommandLine().isValidationEnabled();
 +              const PlatformInterface&                                platformInterface       = context.getPlatformInterface();
 +              const VkInstance                                                instance                        = context.getInstance();
 +              const InstanceInterface&                                instanceInterface       = context.getInstanceInterface();
 +              const VkPhysicalDevice                                  physicalDevice          = context.getPhysicalDevice();
 +              const deUint32                                                  queueFamilyIndex        = context.getUniversalQueueFamilyIndex();
 +              const float                                                             queuePriority           = 1.0f;
 +
 +              const VkDeviceQueueCreateInfo                   queueCreateInfo
 +              {
 +                      VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO,                             // VkStructureType                                      sType;
 +                      nullptr,                                                                                                // const void*                                          pNext;
 +                      0,                                                                                                              // VkDeviceQueueCreateFlags                     flags;
 +                      queueFamilyIndex,                                                                               // uint32_t                                                     queueFamilyIndex;
 +                      1u,                                                                                                             // uint32_t                                                     queueCount;
 +                      &queuePriority                                                                                  // const float*                                         pQueuePriorities;
 +              };
 +
 +              VkPhysicalDeviceFaultFeaturesEXT                deviceFaultFeatures
 +              {
 +                      VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FAULT_FEATURES_EXT,   // VkStructureType                                      sType;
 +                      nullptr,                                                                                                // void*                                                        pNext;
 +                      VK_TRUE,                                                                                                // VkBool32                                                     deviceFault;
 +                      VK_TRUE                                                                                                 // VkBool32                                                     deviceFaultVendorBinary;
 +              };
 +
 +              VkPhysicalDeviceFeatures2                               deviceFeatures2
 +              {
 +                      VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2,                   // VkStructureType                                      sType;
 +                      &deviceFaultFeatures,                                                                   // void*                                                        pNext;
 +                      { /* zeroed automatically since c++11 */ }                              // VkPhysicalDeviceFeatures                     features;
 +              };
 +              instanceInterface.getPhysicalDeviceFeatures2(physicalDevice, &deviceFeatures2);
 +
 +              const VkDeviceCreateInfo                                deviceCreateInfo
 +              {
 +                      VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,                                   // VkStructureType                                      sType;
 +                      &deviceFeatures2,                                                                               // const void*                                          pNext;
 +                      0u,                                                                                                             // VkDeviceCreateFlags                          flags;
 +                      1,                                                                                                              // deUint32                                                     queueCreateInfoCount;
 +                      &queueCreateInfo,                                                                               // const VkDeviceQueueCreateInfo*       pQueueCreateInfos;
 +                      0u,                                                                                                             // deUint32                                                     enabledLayerCount;
 +                      nullptr,                                                                                                // const char* const*                           ppEnabledLayerNames;
 +                      0u,                                                                                                             // deUint32                                                     enabledExtensionCount;
 +                      nullptr,                                                                                                // const char* const*                           ppEnabledExtensionNames;
 +                      nullptr                                                                                                 // const VkPhysicalDeviceFeatures*      pEnabledFeatures;
 +              };
 +
 +              m_logicalDevice = createCustomDevice(useValidation, platformInterface, instance, instanceInterface, physicalDevice, &deviceCreateInfo);
 +      }
 +
 +      VkDevice        getDevice () const { return *m_logicalDevice;   }
 +};
 +
 +class FakeInstanceInterface : public InstanceDriver
 +{
 +      const InstanceInterface&        m_instanceInterface;
 +public:
 +
 +      FakeInstanceInterface (Context& ctx)
 +              : InstanceDriver                (ctx.getPlatformInterface(), ctx.getInstance())
 +              , m_instanceInterface   (ctx.getInstanceInterface()) {}
 +
 +      virtual void getPhysicalDeviceFeatures2 (VkPhysicalDevice physicalDevice, VkPhysicalDeviceFeatures2* pFeatures) const override
 +      {
 +              DE_ASSERT(pFeatures);
 +
 +              InstanceDriver::getPhysicalDeviceFeatures(physicalDevice, &pFeatures->features);
 +
 +              auto pBaseStructure = reinterpret_cast<VkBaseOutStructure*>(pFeatures)->pNext;
 +              while (pBaseStructure)
 +              {
 +                      if (pBaseStructure->sType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FAULT_FEATURES_EXT)
 +                      {
 +                              const VkPhysicalDeviceFaultFeaturesEXT deviceFaultFeatures
 +                              {
 +                                      VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FAULT_FEATURES_EXT,   // VkStructureType      sType;
 +                                      nullptr,                                                                                                // void*                        pNext;
 +                                      VK_TRUE,                                                                                                // VkBool32             deviceFault;
 +                                      VK_TRUE                                                                                                 // VkBool32             deviceFaultVendorBinary;
 +                              };
 +                              *(VkPhysicalDeviceFaultFeaturesEXT*)pBaseStructure = deviceFaultFeatures;
 +                              break;
 +                      }
 +                      pBaseStructure = pBaseStructure->pNext;
 +              }
 +      }
 +};
 +
 +class FakeDeviceInterface : public DeviceDriver
 +{
 +public:
 +      FakeDeviceInterface (Context& ctx)
 +              : DeviceDriver(ctx.getPlatformInterface(), ctx.getInstance(), ctx.getDevice()) {}
 +
 +      struct Header : VkDeviceFaultVendorBinaryHeaderVersionOneEXT
 +      {
 +              char applicationName[32];
 +              char engineName[32];
 +              Header() {
 +                      headerSize                              = sizeof(VkDeviceFaultVendorBinaryHeaderVersionOneEXT);
 +                      headerVersion                   = VK_DEVICE_FAULT_VENDOR_BINARY_HEADER_VERSION_ONE_EXT;
 +                      vendorID                                = 0x9876;
 +                      deviceID                                = 0x5432;
 +                      driverVersion                   = VK_MAKE_VERSION(3,4,5);
 +                      deMemcpy(pipelineCacheUUID, this, sizeof(pipelineCacheUUID));
 +                      applicationNameOffset   = deUint32(sizeof(VkDeviceFaultVendorBinaryHeaderVersionOneEXT));
 +                      applicationVersion              = VK_MAKE_API_VERSION(1,7,3,11);
 +                      engineNameOffset                = deUint32(applicationNameOffset + sizeof(applicationName));
 +
 +                      strcpy(applicationName, "application.exe");
 +                      strcpy(engineName, "driver.so.3.4.5");
 +              }
 +      };
 +
 +      virtual VkResult getDeviceFaultInfoEXT (VkDevice, VkDeviceFaultCountsEXT* pFaultCounts, VkDeviceFaultInfoEXT* pFaultInfo) const override
 +      {
 +              static std::vector<VkDeviceFaultAddressInfoEXT> addressInfos;
 +              static std::vector<VkDeviceFaultVendorInfoEXT>  vendorInfos;
 +              static VkDeviceFaultAddressTypeEXT                              addressTypes[]
 +              {
 +                      VK_DEVICE_FAULT_ADDRESS_TYPE_NONE_EXT,
 +                      VK_DEVICE_FAULT_ADDRESS_TYPE_READ_INVALID_EXT,
 +                      VK_DEVICE_FAULT_ADDRESS_TYPE_WRITE_INVALID_EXT,
 +                      VK_DEVICE_FAULT_ADDRESS_TYPE_EXECUTE_INVALID_EXT,
 +                      VK_DEVICE_FAULT_ADDRESS_TYPE_INSTRUCTION_POINTER_UNKNOWN_EXT,
 +                      VK_DEVICE_FAULT_ADDRESS_TYPE_INSTRUCTION_POINTER_INVALID_EXT,
 +                      VK_DEVICE_FAULT_ADDRESS_TYPE_INSTRUCTION_POINTER_FAULT_EXT,
 +              };
 +              static VkDeviceSize                                                             addressPrecisions[]
 +              {
 +                      2, 4, 8, 16
 +              };
 +              static deUint64                                                                 vendorFaultCodes[]
 +              {
 +                      0x11223344, 0x22334455, 0xAABBCCDD, 0xCCDDEEFF
 +              };
 +              static Header                                                                   vendorBinaryData;
 +
 +              if (DE_NULL == pFaultInfo)
 +              {
 +                      if (DE_NULL == pFaultCounts) return VK_ERROR_UNKNOWN;
 +
 +                      DE_ASSERT(pFaultCounts->sType == VK_STRUCTURE_TYPE_DEVICE_FAULT_COUNTS_EXT);
 +                      DE_ASSERT(pFaultCounts->pNext == nullptr);
 +
 +                      pFaultCounts->vendorBinarySize = sizeof(Header);
 +                      pFaultCounts->vendorInfoCount = 2;
 +                      pFaultCounts->addressInfoCount = 2;
 +              }
 +              else
 +              {
 +                      DE_ASSERT(pFaultCounts);
 +                      DE_ASSERT(pFaultCounts->sType == VK_STRUCTURE_TYPE_DEVICE_FAULT_COUNTS_EXT);
 +                      DE_ASSERT(pFaultCounts->pNext == nullptr);
 +                      DE_ASSERT(pFaultInfo->sType == VK_STRUCTURE_TYPE_DEVICE_FAULT_INFO_EXT);
 +                      DE_ASSERT(pFaultInfo->pNext == nullptr);
 +
 +                      if (pFaultCounts->addressInfoCount && pFaultInfo->pAddressInfos)
 +                      {
 +                              VkDeviceAddress deviceAddress = 1024;
 +                              addressInfos.resize(pFaultCounts->addressInfoCount);
 +                              for (deUint32 i = 0; i < pFaultCounts->addressInfoCount; ++i)
 +                              {
 +                                      VkDeviceFaultAddressInfoEXT& info = addressInfos[i];
 +                                      info.addressType                = addressTypes[ i % ARRAY_LENGTH(addressTypes) ];
 +                                      info.addressPrecision   = addressPrecisions[ i % ARRAY_LENGTH(addressPrecisions) ];
 +                                      info.reportedAddress    = deviceAddress;
 +                                      deviceAddress                   <<= 1;
 +
 +                                      pFaultInfo->pAddressInfos[i] = info;
 +                              }
 +                      }
 +
 +                      if (pFaultCounts->vendorInfoCount && pFaultInfo->pVendorInfos)
 +                      {
 +                              vendorInfos.resize(pFaultCounts->vendorInfoCount);
 +                              for (deUint32 i = 0; i < pFaultCounts->vendorInfoCount; ++i)
 +                              {
 +                                      VkDeviceFaultVendorInfoEXT& info = vendorInfos[i];
 +                                      info.vendorFaultCode = vendorFaultCodes[ i % ARRAY_LENGTH(vendorFaultCodes) ];
 +                                      info.vendorFaultData = (i + 1) % ARRAY_LENGTH(vendorFaultCodes);
 +                                      deMemset(info.description, 0, sizeof(info.description));
 +
 +                                      std::stringstream s;
 +                                      s << "VendorFaultDescription" << info.vendorFaultData;
 +                                      s.sync();
 +                                      const auto& str = s.str();
 +                                      deMemcpy(info.description, str.c_str(), str.length());
 +
 +                                      pFaultInfo->pVendorInfos[i] = info;
 +                              }
 +                      }
 +
 +                      if (pFaultCounts->vendorBinarySize && pFaultInfo->pVendorBinaryData)
 +                      {
 +                              DE_ASSERT(pFaultCounts->vendorBinarySize >= sizeof(VkDeviceFaultVendorBinaryHeaderVersionOneEXT));
 +                              deMemcpy(pFaultInfo->pVendorBinaryData, &vendorBinaryData,
 +                                               deMaxu32(sizeof(Header), deUint32(pFaultCounts->vendorBinarySize)));
 +                      }
 +              }
 +
 +              return VK_SUCCESS;
 +      }
 +};
 +
 +class FakeContext
 +{
 +      FakeDeviceInterface             m_deviceInterface;
 +      FakeInstanceInterface   m_instanceInterface;
 +public:
 +
 +      FakeContext (Context& ctx)
 +              : m_deviceInterface             (ctx)
 +              , m_instanceInterface   (ctx) {}
 +
 +      const DeviceInterface&          getDeviceInterface () const { return m_deviceInterface; }
 +      const InstanceInterface&        getInstanceInterface () const { return m_instanceInterface; }
 +};
 +
 +void DeviceFaultCase::checkSupport (Context& context) const
 +{
 +      FakeContext                                     fakeContext                     (context);
 +      VkPhysicalDevice                        physicalDevice          = context.getPhysicalDevice();
 +      const InstanceInterface&        instanceInterface       = (m_params.type == TestType::Real) ? context.getInstanceInterface() : fakeContext.getInstanceInterface();
 +
 +      context.requireInstanceFunctionality(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
 +
 +      if (m_params.type == TestType::Real)
 +      {
 +              context.requireDeviceFunctionality(VK_EXT_DEVICE_FAULT_EXTENSION_NAME);
 +      }
 +
 +      VkPhysicalDeviceFaultFeaturesEXT deviceFaultFeatures{};
 +      deviceFaultFeatures.sType       = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FAULT_FEATURES_EXT;
 +
 +      VkPhysicalDeviceFeatures2               deviceFeatures2{};
 +      deviceFeatures2.sType           = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2;
 +      deviceFeatures2.pNext           = &deviceFaultFeatures;
 +
 +      instanceInterface.getPhysicalDeviceFeatures2(physicalDevice, &deviceFeatures2);
 +
 +      if (VK_FALSE == deviceFaultFeatures.deviceFault)
 +              TCU_THROW(NotSupportedError, "VK_EXT_device_fault extension is not supported by device");
 +}
 +
 +TestStatus DeviceFaultCustomInstance::iterate (void)
 +{
 +      CustomDevice            customDevice    (m_context);
 +      const VkDevice          device                  = customDevice.getDevice();
 +      return (device != DE_NULL) ? TestStatus::pass("") : TestStatus::fail("");
 +}
 +
 +void DeviceFaultInstance::log (const std::vector<VkDeviceFaultAddressInfoEXT>&        addressInfos,
 +                                                         const std::vector<VkDeviceFaultVendorInfoEXT>&       vendorInfos,
 +                                                         const std::vector<deUint8>&                                          vendorBinaryData) const
 +{
 +      const char*     nl = "\n";
 +      deUint32        cnt = 0;
 +      TestLog&        log = m_context.getTestContext().getLog();
 +
 +      if (addressInfos.size())
 +      {
 +              log << TestLog::Section("addressInfos", "");
 +              auto msg = log << TestLog::Message;
 +              cnt = 0;
 +              for (const auto& addressInfo : addressInfos)
 +              {
 +                      if (cnt++) msg << nl;
 +                      msg << addressInfo;
 +              }
 +              msg << TestLog::EndMessage << TestLog::EndSection;
 +      }
 +
 +      if (vendorInfos.size())
 +      {
 +              log << TestLog::Section("vendorInfos", "");
 +              auto msg = log << TestLog::Message;
 +              cnt = 0;
 +              for (const auto& vendorInfo : vendorInfos)
 +              {
 +                      if (cnt++) msg << nl;
 +                      msg << vendorInfo;
 +              }
 +              msg << TestLog::EndMessage << TestLog::EndSection;
 +      }
 +
 +      if (vendorBinaryData.size())
 +      {
 +              DE_ASSERT(vendorBinaryData.size() >= sizeof(VkDeviceFaultVendorBinaryHeaderVersionOneEXT));
 +
 +              log << TestLog::Section("vendorBinaryData", "");
 +              auto msg = log << TestLog::Message;
 +              auto pHeader = reinterpret_cast<VkDeviceFaultVendorBinaryHeaderVersionOneEXT const*>(vendorBinaryData.data());
 +              msg << *pHeader;
 +              msg << TestLog::EndMessage << TestLog::EndSection;
 +      }
 +}
 +
 +TestStatus DeviceFaultInstance::iterate (void)
 +{
 +      FakeContext                                     fakeContext                     (m_context);
 +      const VkDevice                          device                          = m_context.getDevice();
 +      const VkPhysicalDevice          physicalDevice          = m_context.getPhysicalDevice();
 +      const DeviceInterface&          deviceInterface         = (m_params.type == TestType::Fake) ? fakeContext.getDeviceInterface() : m_context.getDeviceInterface();
 +      const InstanceInterface&        instanceInterface       = (m_params.type == TestType::Fake) ? fakeContext.getInstanceInterface() : m_context.getInstanceInterface();
 +
 +      VkDeviceFaultCountsEXT  fc{};
 +      fc.sType = VK_STRUCTURE_TYPE_DEVICE_FAULT_COUNTS_EXT;
 +      fc.pNext = nullptr;
 +      deviceInterface.getDeviceFaultInfoEXT(device, &fc, nullptr);
 +
 +      const deUint32 vendorBinarySize = std::min(deUint32(fc.vendorBinarySize), std::numeric_limits<deUint32>::max());
 +
 +      VkPhysicalDeviceFaultFeaturesEXT        deviceFaultFeatures{};
 +      deviceFaultFeatures.sType       = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FAULT_FEATURES_EXT;
 +
 +      VkPhysicalDeviceFeatures2                       deviceFeatures2{};
 +      deviceFeatures2.sType           = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2;
 +      deviceFeatures2.pNext           = &deviceFaultFeatures;
 +
 +      instanceInterface.getPhysicalDeviceFeatures2(physicalDevice, &deviceFeatures2);
 +
 +      fc.vendorBinarySize = deviceFaultFeatures.deviceFaultVendorBinary ? vendorBinarySize : 0;
 +
 +      std::vector<VkDeviceFaultAddressInfoEXT>        addressInfos    (fc.addressInfoCount);
 +      std::vector<VkDeviceFaultVendorInfoEXT>         vendorInfos             (fc.vendorInfoCount);
 +      std::vector<deUint8>                                            vendorBinaryData(vendorBinarySize);
 +
 +      VkDeviceFaultInfoEXT fi{};
 +      fi.sType                                = VK_STRUCTURE_TYPE_DEVICE_FAULT_INFO_EXT;
 +      fi.pNext                                = nullptr;
 +      fi.pAddressInfos                = addressInfos.data();
 +      fi.pVendorInfos                 = vendorInfos.data();
 +      fi.pVendorBinaryData    = deviceFaultFeatures.deviceFaultVendorBinary ? vendorBinaryData.data() : nullptr;
 +
 +      const VkResult result = deviceInterface.getDeviceFaultInfoEXT(device, &fc, &fi);
 +
 +      log(addressInfos, vendorInfos, vendorBinaryData);
 +
 +      return (result == VK_SUCCESS) ? TestStatus::pass("") : TestStatus::fail("");
 +}
 +
 +} // unnamed
 +
 +tcu::TestCaseGroup*   createDeviceFaultTests (tcu::TestContext& testCtx)
 +{
 +      TestParams p;
 +      struct {
 +              TestType        type;
 +              const char*     name;
 +      } const types[] = { { TestType::Real, "real" }, { TestType::Fake, "fake" }, { TestType::CustomDevice, "custom_device" } };
 +
 +      auto rootGroup = new TestCaseGroup(testCtx, "device_fault", "VK_EXT_device_fault extension tests.");
 +      for (const auto& type : types)
 +      {
 +              p.type = type.type;
 +              rootGroup->addChild(new DeviceFaultCase(testCtx, type.name, p));
 +      }
 +      return rootGroup;
 +}
 +
 +} // postmortem
 +} // vkt