/*-------------------------------------------------------------------------
* Vulkan CTS
* ----------
*
* Copyright (c) 2019 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.
*/

#include "deSTLUtil.hpp"
#include "deString.h"
#include "vkQueryUtil.hpp"
#include "vkDeviceFeatures.inl"
#include "vkDeviceFeatures.hpp"

namespace vk
{

DeviceFeatures::DeviceFeatures	(const InstanceInterface&			vki,
								 const deUint32						apiVersion,
								 const VkPhysicalDevice				physicalDevice,
								 const std::vector<std::string>&	instanceExtensions,
								 const std::vector<std::string>&	deviceExtensions)
{
	VkPhysicalDeviceRobustness2FeaturesEXT*			robustness2Features			= nullptr;
	VkPhysicalDeviceImageRobustnessFeaturesEXT*		imageRobustnessFeatures		= nullptr;
	VkPhysicalDeviceFragmentShadingRateFeaturesKHR*	fragmentShadingRateFeatures	= nullptr;
	VkPhysicalDeviceShadingRateImageFeaturesNV*		shadingRateImageFeatures	= nullptr;
	VkPhysicalDeviceFragmentDensityMapFeaturesEXT*	fragmentDensityMapFeatures	= nullptr;

	m_coreFeatures2		= initVulkanStructure();
	m_vulkan11Features	= initVulkanStructure();
	m_vulkan12Features	= initVulkanStructure();

	if (isInstanceExtensionSupported(apiVersion, instanceExtensions, "VK_KHR_get_physical_device_properties2"))
	{
		const std::vector<VkExtensionProperties>	deviceExtensionProperties	= enumerateDeviceExtensionProperties(vki, physicalDevice, DE_NULL);
		void**										nextPtr						= &m_coreFeatures2.pNext;
		std::vector<FeatureStructWrapperBase*>		featuresToFillFromBlob;
		bool										vk12Supported				= (apiVersion >= VK_MAKE_VERSION(1, 2, 0));

		// in vk12 we have blob structures combining features of couple previously
		// available feature structures, that now in vk12 must be removed from chain
		if (vk12Supported)
		{
			addToChainVulkanStructure(&nextPtr, m_vulkan11Features);
			addToChainVulkanStructure(&nextPtr, m_vulkan12Features);
		}

		// iterate over data for all feature that are defined in specification
		for (const auto& featureStructCreationData : featureStructCreationArray)
		{
			const char* featureName = featureStructCreationData.name;

			// check if this feature is available on current device
			if (de::contains(deviceExtensions.begin(), deviceExtensions.end(), featureName) &&
				verifyFeatureAddCriteria(featureStructCreationData, deviceExtensionProperties))
			{
				FeatureStructWrapperBase* p = (*featureStructCreationData.creatorFunction)();
				if (p == DE_NULL)
					continue;

				// if feature struct is part of VkPhysicalDeviceVulkan1{1,2}Features
				// we dont add it to the chain but store and fill later from blob data
				bool featureFilledFromBlob = false;
				if (vk12Supported)
					featureFilledFromBlob = isPartOfBlobFeatures(p->getFeatureDesc().sType);

				if (featureFilledFromBlob)
					featuresToFillFromBlob.push_back(p);
				else
				{
					VkStructureType	structType		= p->getFeatureDesc().sType;
					void*			rawStructPtr	= p->getFeatureTypeRaw();

					if (structType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ROBUSTNESS_2_FEATURES_EXT)
						robustness2Features = reinterpret_cast<VkPhysicalDeviceRobustness2FeaturesEXT*>(rawStructPtr);
					else if (structType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_ROBUSTNESS_FEATURES_EXT)
						imageRobustnessFeatures = reinterpret_cast<VkPhysicalDeviceImageRobustnessFeaturesEXT*>(rawStructPtr);
					else if (structType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_SHADING_RATE_FEATURES_KHR)
						fragmentShadingRateFeatures = reinterpret_cast<VkPhysicalDeviceFragmentShadingRateFeaturesKHR*>(rawStructPtr);
					else if (structType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADING_RATE_IMAGE_FEATURES_NV)
						shadingRateImageFeatures = reinterpret_cast<VkPhysicalDeviceShadingRateImageFeaturesNV*>(rawStructPtr);
					else if (structType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_DENSITY_MAP_FEATURES_EXT)
						fragmentDensityMapFeatures = reinterpret_cast<VkPhysicalDeviceFragmentDensityMapFeaturesEXT*>(rawStructPtr);

					// add to chain
					*nextPtr	= rawStructPtr;
					nextPtr		= p->getFeatureTypeNext();
				}
				m_features.push_back(p);
			}
		}

		vki.getPhysicalDeviceFeatures2(physicalDevice, &m_coreFeatures2);

		// fill data from VkPhysicalDeviceVulkan1{1,2}Features
		if (vk12Supported)
		{
			AllFeaturesBlobs allBlobs =
			{
				m_vulkan11Features,
				m_vulkan12Features,
				// add blobs from future vulkan versions here
			};

			for (auto feature : featuresToFillFromBlob)
				feature->initializeFeatureFromBlob(allBlobs);
		}
	}
	else
		m_coreFeatures2.features = getPhysicalDeviceFeatures(vki, physicalDevice);

	// Disable robustness by default, as it has an impact on performance on some HW.
	if (robustness2Features)
	{
		robustness2Features->robustBufferAccess2	= false;
		robustness2Features->robustImageAccess2		= false;
		robustness2Features->nullDescriptor			= false;
	}
	if (imageRobustnessFeatures)
	{
		imageRobustnessFeatures->robustImageAccess	= false;
	}
	m_coreFeatures2.features.robustBufferAccess = false;

	// Disable VK_EXT_fragment_density_map and VK_NV_shading_rate_image features
	// that must: not be enabled if KHR fragment shading rate features are enabled.
	if (fragmentShadingRateFeatures &&
		(fragmentShadingRateFeatures->pipelineFragmentShadingRate ||
			fragmentShadingRateFeatures->primitiveFragmentShadingRate ||
			fragmentShadingRateFeatures->attachmentFragmentShadingRate))
	{
		if (shadingRateImageFeatures)
			shadingRateImageFeatures->shadingRateImage = false;
		if (fragmentDensityMapFeatures)
			fragmentDensityMapFeatures->fragmentDensityMap = false;
	}
}

bool DeviceFeatures::verifyFeatureAddCriteria (const FeatureStructCreationData& item, const std::vector<VkExtensionProperties>& properties)
{
	if (deStringEqual(item.name, VK_KHR_VULKAN_MEMORY_MODEL_EXTENSION_NAME))
	{
		for (const auto& property : properties)
		{
			if (deStringEqual(property.extensionName, item.name))
				return (property.specVersion == item.specVersion);
		}
	}

	return true;
}

bool DeviceFeatures::contains (const std::string& feature, bool throwIfNotExists) const
{
	for (const auto f : m_features)
	{
		if (deStringEqual(f->getFeatureDesc().name, feature.c_str()))
			return true;
	}

	if (throwIfNotExists)
		TCU_THROW(NotSupportedError, "Feature " + feature + " is not supported");

	return false;
}

bool DeviceFeatures::isDeviceFeatureInitialized (VkStructureType sType) const
{
	for (const auto f : m_features)
	{
		if (f->getFeatureDesc().sType == sType)
			return true;
	}
	return false;
}

DeviceFeatures::~DeviceFeatures (void)
{
	for (auto p : m_features)
		delete p;

	m_features.clear();
}

} // vk

