<commit_before>/*------------------------------------------------------------------------
 * 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.getPhysicalDeviceFeatures(physicalDevice, &deviceFeatures2.features);

		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<commit_msg>device_fault tests should use getPhysicalDeviceFeatures2<commit_after>/*------------------------------------------------------------------------
 * 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
{'fraction_non_alphanumeric': 0.10791957324579401, 'fraction_numerical': 0.006729585556011489, 'mean_word_length': 3.0191292875989446, 'pattern_counts': {'":': 0, '<': 23, '<?xml version=': 0, '>': 23, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5530510', 'n_tokens_mistral': 4714, 'n_tokens_neox': 3681, 'n_words': 853}