/*------------------------------------------------------------------------
 * Vulkan Conformance Tests
 * ------------------------
 *
 * Copyright (c) 2017 The Khronos Group Inc.
 * Copyright (c) 2017 Samsung Electronics Co., Ltd.
 *
 * 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 Protected Memory Utility methods
 *//*--------------------------------------------------------------------*/

#include "vktProtectedMemUtils.hpp"
#include "vktCustomInstancesDevices.hpp"

#include "deString.h"
#include "deRandom.hpp"

#include "vkDeviceUtil.hpp"
#include "vkQueryUtil.hpp"
#include "vkTypeUtil.hpp"
#include "vkDebugReportUtil.hpp"
#include "vkApiVersion.hpp"
#include "vkObjUtil.hpp"

#include "vkPlatform.hpp"
#include "vktProtectedMemContext.hpp"
#include "vkWsiUtil.hpp"
#include "vkObjUtil.hpp"

namespace vkt
{

using namespace vk;

namespace ProtectedMem
{

typedef std::vector<vk::VkExtensionProperties> Extensions;

CustomInstance makeProtectedMemInstance (vkt::Context& context, const std::vector<std::string>& extraExtensions)
{
	const PlatformInterface&	vkp = context.getPlatformInterface();
	const Extensions			supportedExtensions(vk::enumerateInstanceExtensionProperties(vkp, DE_NULL));
	std::vector<std::string>	requiredExtensions = extraExtensions;

	deUint32 apiVersion = context.getUsedApiVersion();
	if (!isCoreInstanceExtension(apiVersion, "VK_KHR_get_physical_device_properties2"))
		requiredExtensions.push_back("VK_KHR_get_physical_device_properties2");

	// extract extension names
	std::vector<std::string> extensions;
	for (const auto& e : supportedExtensions)
		extensions.push_back(e.extensionName);

	for (const auto& extName : requiredExtensions)
	{
		if (!isInstanceExtensionSupported(apiVersion, extensions, extName))
			TCU_THROW(NotSupportedError, (extName + " is not supported").c_str());
	}

	return createCustomInstanceWithExtensions(context, requiredExtensions);
}

void checkProtectedQueueSupport (Context& context)
{
#ifdef NOT_PROTECTED
	return;
#endif

	const vk::InstanceInterface&				vkd				= context.getInstanceInterface();
	vk::VkPhysicalDevice						physDevice		= context.getPhysicalDevice();
	std::vector<vk::VkQueueFamilyProperties>	properties;
	deUint32									numFamilies		= 0;

	vkd.getPhysicalDeviceQueueFamilyProperties(physDevice, &numFamilies, DE_NULL);
	DE_ASSERT(numFamilies > 0);
	properties.resize(numFamilies);

	vkd.getPhysicalDeviceQueueFamilyProperties(physDevice, &numFamilies, properties.data());

	for (auto prop: properties)
		if (prop.queueFlags & vk::VK_QUEUE_PROTECTED_BIT)
			return;

	TCU_THROW(NotSupportedError, "No protected queue found.");
}

deUint32 chooseProtectedMemQueueFamilyIndex	(const vk::InstanceDriver&	vkd,
											 vk::VkPhysicalDevice		physicalDevice,
											 vk::VkSurfaceKHR			surface)
{
	std::vector<vk::VkQueueFamilyProperties>	properties;
	deUint32									numFamilies		= 0;

	vkd.getPhysicalDeviceQueueFamilyProperties(physicalDevice, &numFamilies, DE_NULL);
	DE_ASSERT(numFamilies > 0);
	properties.resize(numFamilies);

	vkd.getPhysicalDeviceQueueFamilyProperties(physicalDevice, &numFamilies, properties.data());

	// Get a universal protected queue family index
	vk::VkQueueFlags	requiredFlags = vk::VK_QUEUE_GRAPHICS_BIT
										| vk::VK_QUEUE_COMPUTE_BIT
#ifndef NOT_PROTECTED
										| vk::VK_QUEUE_PROTECTED_BIT
#endif
										;
	for (size_t idx = 0; idx < properties.size(); ++idx)
	{
		vk::VkQueueFlags	flags = properties[idx].queueFlags;

		if (surface != DE_NULL
			&& vk::wsi::getPhysicalDeviceSurfaceSupport(vkd, physicalDevice, (deUint32)idx, surface) == VK_FALSE)
			continue; // Skip the queue family index if it does not support the surface

		if ((flags & requiredFlags) == requiredFlags)
			return (deUint32)idx;
	}

	TCU_THROW(NotSupportedError, "No matching universal protected queue found");
}

vk::Move<vk::VkDevice> makeProtectedMemDevice	(const vk::PlatformInterface&		vkp,
												 vk::VkInstance						instance,
												 const vk::InstanceDriver&			vkd,
												 vk::VkPhysicalDevice				physicalDevice,
												 const deUint32						queueFamilyIndex,
												 const deUint32						apiVersion,
												 const std::vector<std::string>&	extraExtensions,
												 bool								validationEnabled)
{
	const Extensions					supportedExtensions	(vk::enumerateDeviceExtensionProperties(vkd, physicalDevice, DE_NULL));
	std::vector<std::string>			requiredExtensions;
	std::vector<std::string>			extensions			= extraExtensions;

	if (apiVersion < VK_API_VERSION_1_1)
		TCU_THROW(NotSupportedError, "Vulkan 1.1 is not supported");

	bool								useYCbCr			= de::contains(extensions.begin(), extensions.end(), std::string("VK_KHR_sampler_ycbcr_conversion"));

	// Check if the physical device supports the protected memory extension name
	for (deUint32 ndx = 0; ndx < extensions.size(); ++ndx)
	{
		bool notInCore = !isCoreDeviceExtension(apiVersion, extensions[ndx]);
		if (notInCore && !isExtensionSupported(supportedExtensions.begin(), supportedExtensions.end(), RequiredExtension(extensions[ndx])))
			TCU_THROW(NotSupportedError, (extensions[ndx] + " is not supported").c_str());

		if (notInCore)
			requiredExtensions.push_back(extensions[ndx]);
	}

	std::vector<const char*>			enabledExts			(requiredExtensions.size());
	for (size_t idx = 0; idx < requiredExtensions.size(); ++idx)
	{
		enabledExts[idx] = requiredExtensions[idx].c_str();
	}

	vk::VkPhysicalDeviceSamplerYcbcrConversionFeatures		ycbcrFeature	=
	{
		vk::VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLER_YCBCR_CONVERSION_FEATURES,
		DE_NULL,
		VK_FALSE
	};
	// Check if the protected memory can be enabled on the physical device.
	vk::VkPhysicalDeviceProtectedMemoryFeatures	protectedFeature =
	{
		vk::VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROTECTED_MEMORY_FEATURES,	// sType
		&ycbcrFeature,														// pNext
		VK_FALSE															// protectedMemory
	};
	vk::VkPhysicalDeviceFeatures					features;
	deMemset(&features, 0, sizeof(vk::VkPhysicalDeviceFeatures));

	vk::VkPhysicalDeviceFeatures2				featuresExt		=
	{
		vk::VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2,					// sType
		&protectedFeature,													// pNext
		features
	};

	vkd.getPhysicalDeviceFeatures2(physicalDevice, &featuresExt);

#ifndef NOT_PROTECTED
	if (protectedFeature.protectedMemory == VK_FALSE)
		TCU_THROW(NotSupportedError, "Protected Memory feature not supported by the device");
#endif

	if (useYCbCr && !ycbcrFeature.samplerYcbcrConversion)
		TCU_THROW(NotSupportedError, "VK_KHR_sampler_ycbcr_conversion is not supported");

	const float							queuePriorities[]	= { 1.0f };
	const vk::VkDeviceQueueCreateInfo	queueInfos[]		=
	{
		{
			vk::VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO,
			DE_NULL,
#ifndef NOT_PROTECTED
			(vk::VkDeviceQueueCreateFlags)vk::VK_DEVICE_QUEUE_CREATE_PROTECTED_BIT,
#else
			(vk::VkDeviceQueueCreateFlags)0u,
#endif
			queueFamilyIndex,
			DE_LENGTH_OF_ARRAY(queuePriorities),
			queuePriorities
		}
	};

	const vk::VkDeviceCreateInfo		deviceParams		=
	{
		vk::VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,						// sType
		&featuresExt,													// pNext
		(vk::VkDeviceCreateFlags)0,										// flags
		DE_LENGTH_OF_ARRAY(queueInfos),									// queueCreateInfosCount
		&queueInfos[0],													// pQueueCreateInfos
		0u,																// enabledLayerCount
		DE_NULL,														// pEnabledLayerNames
		(deUint32)requiredExtensions.size(),							// enabledExtensionCount
		requiredExtensions.empty() ? DE_NULL : &enabledExts[0],			// pEnabledExtensionNames
		DE_NULL															// pEnabledFeatures
	};

	return createCustomDevice(validationEnabled, vkp, instance, vkd, physicalDevice, &deviceParams, DE_NULL);
}

vk::VkQueue getProtectedQueue	(const vk::DeviceInterface&	vk,
								 vk::VkDevice				device,
								 const deUint32				queueFamilyIndex,
								 const deUint32				queueIdx)
{
	const vk::VkDeviceQueueInfo2	queueInfo	=
	{
		vk::VK_STRUCTURE_TYPE_DEVICE_QUEUE_INFO_2,		// sType
		DE_NULL,										// pNext
		vk::VK_DEVICE_QUEUE_CREATE_PROTECTED_BIT,		// flags
		queueFamilyIndex,								// queueFamilyIndex
		queueIdx,										// queueIndex
	};

	(void)queueInfo;
	vk::VkQueue						queue		=
#ifndef NOT_PROTECTED
													vk::getDeviceQueue2(vk, device, &queueInfo);
#else
													vk::getDeviceQueue(vk, device, queueFamilyIndex, 0);
#endif

	if (queue == DE_NULL)
		TCU_THROW(TestError, "Unable to get a protected queue");

	return queue;
}

de::MovePtr<vk::ImageWithMemory>	createImage2D		(ProtectedContext&		context,
														 ProtectionMode			protectionMode,
														 const deUint32			queueFamilyIdx,
														 deUint32				width,
														 deUint32				height,
														 vk::VkFormat			format,
														 vk::VkImageUsageFlags	usageFlags)
{
	const vk::DeviceInterface&	vk			= context.getDeviceInterface();
	const vk::VkDevice&			device		= context.getDevice();
	vk::Allocator&				allocator	= context.getDefaultAllocator();

#ifndef NOT_PROTECTED
	deUint32					flags		= (protectionMode == PROTECTION_ENABLED)
												? vk::VK_IMAGE_CREATE_PROTECTED_BIT
												: (vk::VkImageCreateFlagBits)0u;
#else
	DE_UNREF(protectionMode);
	deUint32					flags		= 0u;
#endif

	const vk::VkImageCreateInfo	params		=
	{
		vk::VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,		// VkStructureType			stype
		DE_NULL,										// const void*				pNext
		(vk::VkImageCreateFlags)flags,					// VkImageCreateFlags		flags
		vk::VK_IMAGE_TYPE_2D,							// VkImageType				imageType
		format,											// VkFormat					format
		{ width, height, 1 },							// VkExtent3D				extent
		1u,												// deUint32					mipLevels
		1u,												// deUint32					arrayLayers
		vk::VK_SAMPLE_COUNT_1_BIT,						// VkSampleCountFlagBits	samples
		vk::VK_IMAGE_TILING_OPTIMAL,					// VkImageTiling			tiling
		usageFlags,										// VkImageUsageFlags		usage
		vk::VK_SHARING_MODE_EXCLUSIVE,					// VkSharingMode			sharingMode
		1u,												// deUint32					queueFamilyIndexCount
		&queueFamilyIdx,								// const deUint32*			pQueueFamilyIndices
		vk::VK_IMAGE_LAYOUT_UNDEFINED,					// VkImageLayout			initialLayout
	};

#ifndef NOT_PROTECTED
	vk::MemoryRequirement		memReq		= (protectionMode == PROTECTION_ENABLED)
												? vk::MemoryRequirement::Protected
												: vk::MemoryRequirement::Any;
#else
	vk::MemoryRequirement		memReq		= vk::MemoryRequirement::Any;
#endif

	return de::MovePtr<vk::ImageWithMemory>(new vk::ImageWithMemory(vk, device, allocator, params, memReq));
}

de::MovePtr<vk::BufferWithMemory> makeBuffer (ProtectedContext&			context,
											  ProtectionMode			protectionMode,
											  const deUint32			queueFamilyIdx,
											  deUint32					size,
											  vk::VkBufferUsageFlags	usageFlags,
											  vk::MemoryRequirement		memReq)
{
	const vk::DeviceInterface&		vk			= context.getDeviceInterface();
	const vk::VkDevice&				device		= context.getDevice();
	vk::Allocator&					allocator	= context.getDefaultAllocator();

#ifndef NOT_PROTECTED
	deUint32						flags		= (protectionMode == PROTECTION_ENABLED)
													? vk::VK_BUFFER_CREATE_PROTECTED_BIT
													: (vk::VkBufferCreateFlagBits)0u;
	vk::MemoryRequirement			requirement	= memReq;
#else
	DE_UNREF(protectionMode);
	deUint32						flags		= 0u;
	vk::MemoryRequirement			requirement	= memReq & (
													vk::MemoryRequirement::HostVisible
													| vk::MemoryRequirement::Coherent
													| vk::MemoryRequirement::LazilyAllocated);
#endif

	const vk::VkBufferCreateInfo	params		=
	{
		vk::VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,	// sType
		DE_NULL,									// pNext
		(vk::VkBufferCreateFlags)flags,				// flags
		(vk::VkDeviceSize)size,						// size
		usageFlags,									// usage
		vk::VK_SHARING_MODE_EXCLUSIVE,				// sharingMode
		1u,											// queueFamilyCount
		&queueFamilyIdx,							// pQueueFamilyIndices
	};

	return de::MovePtr<vk::BufferWithMemory>(new vk::BufferWithMemory(vk, device, allocator, params, requirement));
}

vk::Move<vk::VkImageView> createImageView (ProtectedContext& context, vk::VkImage image, vk::VkFormat format)
{
	const vk::VkImageViewCreateInfo params =
	{
		vk::VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,		// sType
		DE_NULL,											// pNext
		0u,													// flags
		image,												// image
		vk::VK_IMAGE_VIEW_TYPE_2D,							// viewType
		format,												// format
		vk::makeComponentMappingRGBA(),						// components
		{ vk::VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u,1u },	// subresourceRange
	};

	return vk::createImageView(context.getDeviceInterface(), context.getDevice(), &params);
}

vk::Move<vk::VkRenderPass> createRenderPass (ProtectedContext& context, vk::VkFormat format)
{
	const vk::VkDevice					vkDevice				= context.getDevice();
	const vk::DeviceInterface&			vk						= context.getDeviceInterface();

	return vk::makeRenderPass(vk, vkDevice, format);
}

vk::Move<vk::VkFramebuffer> createFramebuffer (ProtectedContext& context, deUint32 width, deUint32 height,
												vk::VkRenderPass renderPass, vk::VkImageView colorImageView)
{
	const vk::VkDevice					vkDevice			= context.getDevice();
	const vk::DeviceInterface&			vk					= context.getDeviceInterface();

	const vk::VkFramebufferCreateInfo	framebufferParams	=
	{
		vk::VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,	// VkStructureType			sType;
		DE_NULL,										// const void*				pNext;
		0u,												// VkFramebufferCreateFlags	flags;
		renderPass,										// VkRenderPass				renderPass;
		1u,												// deUint32					attachmentCount;
		&colorImageView,								// const VkImageView*		pAttachments;
		width,											// deUint32					width;
		height,											// deUint32					height;
		1u												// deUint32					layers;
	};

	return vk::createFramebuffer(vk, vkDevice, &framebufferParams);
}


vk::Move<vk::VkPipelineLayout> createPipelineLayout (ProtectedContext& context, deUint32 layoutCount, vk::VkDescriptorSetLayout* setLayouts)
{
	const vk::VkPipelineLayoutCreateInfo	params	=
	{
		vk::VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,	// sType
		DE_NULL,											// pNext
		0u,													// flags
		layoutCount,										// setLayoutCount
		setLayouts,											// pSetLayouts
		0u,													// pushConstantRangeCount
		DE_NULL,											// pPushContantRanges
	};

	return vk::createPipelineLayout(context.getDeviceInterface(), context.getDevice(), &params);
}

void beginSecondaryCommandBuffer (const vk::DeviceInterface&				vk,
								  const vk::VkCommandBuffer					secondaryCmdBuffer,
								  const vk::VkCommandBufferInheritanceInfo	bufferInheritanceInfo)
{
	const vk::VkCommandBufferUsageFlags	flags		= bufferInheritanceInfo.renderPass != DE_NULL
													  ? (vk::VkCommandBufferUsageFlags)vk::VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT
													  : (vk::VkCommandBufferUsageFlags)0u;
	const vk::VkCommandBufferBeginInfo	beginInfo	=
	{
		vk::VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,			// sType
		DE_NULL,													// pNext
		flags,														// flags
		&bufferInheritanceInfo,										// pInheritanceInfo
	};
	VK_CHECK(vk.beginCommandBuffer(secondaryCmdBuffer, &beginInfo));
}

vk::VkResult queueSubmit (ProtectedContext&		context,
						  ProtectionMode		protectionMode,
						  vk::VkQueue			queue,
						  vk::VkCommandBuffer	cmdBuffer,
						  vk::VkFence			fence,
						  deUint64				timeout)
{
	const vk::DeviceInterface&			vk			= context.getDeviceInterface();
	const vk::VkDevice&					device		= context.getDevice();

	// Basic submit info
	vk::VkSubmitInfo					submitInfo	=
	{
		vk::VK_STRUCTURE_TYPE_SUBMIT_INFO,			// sType
		DE_NULL,									// pNext
		0u,											// waitSemaphoreCount
		DE_NULL,									// pWaitSempahores
		(const vk::VkPipelineStageFlags*)DE_NULL,	// stageFlags
		1u,											// commandBufferCount
		&cmdBuffer,									// pCommandBuffers
		0u,											// signalSemaphoreCount
		DE_NULL,									// pSignalSemaphores
	};

#ifndef NOT_PROTECTED
	// Protected extension submit info
	const vk::VkProtectedSubmitInfo		protectedInfo	=
	{
		vk::VK_STRUCTURE_TYPE_PROTECTED_SUBMIT_INFO,		// sType
		DE_NULL,											// pNext
		VK_TRUE,											// protectedSubmit
	};
	if (protectionMode == PROTECTION_ENABLED) {
		submitInfo.pNext = &protectedInfo;
	}
#else
	DE_UNREF(protectionMode);
#endif

	VK_CHECK(vk.queueSubmit(queue, 1u, &submitInfo, fence));
	return vk.waitForFences(device, 1u, &fence, DE_TRUE, timeout);
}

vk::Move<vk::VkPipeline> makeComputePipeline (const vk::DeviceInterface&		vk,
											  const vk::VkDevice				device,
											  const vk::VkPipelineLayout		pipelineLayout,
											  const vk::VkShaderModule			shaderModule,
											  const vk::VkSpecializationInfo*	specInfo)
{
	const vk::VkPipelineShaderStageCreateInfo shaderStageInfo =
	{
		vk::VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,	// VkStructureType					sType;
		DE_NULL,													// const void*						pNext;
		(vk::VkPipelineShaderStageCreateFlags)0,					// VkPipelineShaderStageCreateFlags	flags;
		vk::VK_SHADER_STAGE_COMPUTE_BIT,							// VkShaderStageFlagBits			stage;
		shaderModule,												// VkShaderModule					module;
		"main",														// const char*						pName;
		specInfo,													// const VkSpecializationInfo*		pSpecializationInfo;
	};
	const vk::VkComputePipelineCreateInfo pipelineInfo =
	{
		vk::VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO,	// VkStructureType					sType;
		DE_NULL,											// const void*						pNext;
		(vk::VkPipelineCreateFlags)0,						// VkPipelineCreateFlags			flags;
		shaderStageInfo,									// VkPipelineShaderStageCreateInfo	stage;
		pipelineLayout,										// VkPipelineLayout					layout;
		DE_NULL,											// VkPipeline						basePipelineHandle;
		0,													// deInt32							basePipelineIndex;
	};
	return vk::createComputePipeline(vk, device, DE_NULL , &pipelineInfo);
}

vk::Move<vk::VkSampler> makeSampler (const vk::DeviceInterface& vk, const vk::VkDevice& device)
{
	const vk::VkSamplerCreateInfo createInfo =
	{
		vk::VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO,
		DE_NULL,
		0u,

		vk::VK_FILTER_NEAREST,
		vk::VK_FILTER_NEAREST,

		vk::VK_SAMPLER_MIPMAP_MODE_LINEAR,
		vk::VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,
		vk::VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,
		vk::VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,
		0.0f,
		VK_FALSE,
		1.0f,
		VK_FALSE,
		vk::VK_COMPARE_OP_ALWAYS,
		0.0f,
		0.0f,
		vk::VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK,
		VK_FALSE
	};

	return vk::createSampler(vk, device, &createInfo);
}

vk::Move<vk::VkCommandPool> makeCommandPool (const vk::DeviceInterface&	vk,
											 const vk::VkDevice&		device,
											 ProtectionMode				protectionMode,
											 const deUint32				queueFamilyIdx)
{
	const deUint32	poolFlags	= vk::VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT
#ifndef NOT_PROTECTED
									| ((protectionMode == PROTECTION_ENABLED) ? vk::VK_COMMAND_POOL_CREATE_PROTECTED_BIT : 0x0)
#endif
									;
#ifdef NOT_PROTECTED
	DE_UNREF(protectionMode);
#endif

	return vk::createCommandPool(vk, device, poolFlags, queueFamilyIdx);
}

vk::Move<vk::VkPipeline> makeGraphicsPipeline (const vk::DeviceInterface&		vk,
											   const vk::VkDevice				device,
											   const vk::VkPipelineLayout		pipelineLayout,
											   const vk::VkRenderPass			renderPass,
											   const vk::VkShaderModule			vertexShaderModule,
											   const vk::VkShaderModule			fragmentShaderModule,
											   const VertexBindings&			vertexBindings,
											   const VertexAttribs&				vertexAttribs,
											   const tcu::UVec2&				renderSize,
											   const vk::VkPrimitiveTopology	topology)
{
	const std::vector<VkViewport>				viewports					(1, makeViewport(renderSize));
	const std::vector<VkRect2D>					scissors					(1, makeRect2D(renderSize));

	const VkPipelineVertexInputStateCreateInfo	vertexInputStateCreateInfo	=
	{
		VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,	// VkStructureType                             sType;
		DE_NULL,													// const void*                                 pNext;
		(VkPipelineVertexInputStateCreateFlags)0,					// VkPipelineVertexInputStateCreateFlags       flags;
		(deUint32)vertexBindings.size(),							// deUint32                                    vertexBindingDescriptionCount;
		vertexBindings.data(),										// const VkVertexInputBindingDescription*      pVertexBindingDescriptions;
		(deUint32)vertexAttribs.size(),								// deUint32                                    vertexAttributeDescriptionCount;
		vertexAttribs.data()										// const VkVertexInputAttributeDescription*    pVertexAttributeDescriptions;
	};

	return vk::makeGraphicsPipeline(vk,									// const DeviceInterface&                        vk
									device,								// const VkDevice                                device
									pipelineLayout,						// const VkPipelineLayout                        pipelineLayout
									vertexShaderModule,					// const VkShaderModule                          vertexShaderModule
									DE_NULL,							// const VkShaderModule                          tessellationControlModule
									DE_NULL,							// const VkShaderModule                          tessellationEvalModule
									DE_NULL,							// const VkShaderModule                          geometryShaderModule
									fragmentShaderModule,				// const VkShaderModule                          fragmentShaderModule
									renderPass,							// const VkRenderPass                            renderPass
									viewports,							// const std::vector<VkViewport>&                viewports
									scissors,							// const std::vector<VkRect2D>&                  scissors
									topology,							// const VkPrimitiveTopology                     topology
									0u,									// const deUint32                                subpass
									0u,									// const deUint32                                patchControlPoints
									&vertexInputStateCreateInfo);		// const VkPipelineVertexInputStateCreateInfo*   vertexInputStateCreateInfo
}

const char* getCmdBufferTypeStr (const CmdBufferType cmdBufferType)
{
	switch (cmdBufferType)
	{
		case CMD_BUFFER_PRIMARY:	return "primary";
		case CMD_BUFFER_SECONDARY:	return "secondary";

		default: DE_FATAL("Invalid command buffer type"); return "";
	}
}

void clearImage (ProtectedContext& ctx, vk::VkImage image)
{
	const vk::DeviceInterface&			vk					= ctx.getDeviceInterface();
	const vk::VkDevice					device				= ctx.getDevice();
	const vk::VkQueue					queue				= ctx.getQueue();
	const deUint32						queueFamilyIndex	= ctx.getQueueFamilyIndex();

	vk::Unique<vk::VkCommandPool>		cmdPool				(makeCommandPool(vk, device, PROTECTION_ENABLED, queueFamilyIndex));
	vk::Unique<vk::VkCommandBuffer>		cmdBuffer			(vk::allocateCommandBuffer(vk, device, *cmdPool, vk::VK_COMMAND_BUFFER_LEVEL_PRIMARY));

	const vk::VkClearColorValue			clearColor			= { { 0.0f, 0.0f, 0.0f, 0.0f } };

	const vk::VkImageSubresourceRange	subresourceRange	=
	{
		vk::VK_IMAGE_ASPECT_COLOR_BIT,	// VkImageAspectFlags	aspectMask
		0u,								// uint32_t				baseMipLevel
		1u,								// uint32_t				levelCount
		0u,								// uint32_t				baseArrayLayer
		1u,								// uint32_t				layerCount
	};

	const vk::VkImageMemoryBarrier		preImageBarrier		=
	{
		vk::VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,		// VkStructureType			sType;
		DE_NULL,										// const void*				pNext;
		0u,												// VkAccessFlags			srcAccessMask;
		vk::VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags			dstAccessMask;
		vk::VK_IMAGE_LAYOUT_UNDEFINED,					// VkImageLayout			oldLayout;
		vk::VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,		// VkImageLayout			newLayout;
		queueFamilyIndex,								// deUint32					srcQueueFamilyIndex;
		queueFamilyIndex,								// deUint32					dstQueueFamilyIndex;
		image,											// VkImage					image;
		subresourceRange								// VkImageSubresourceRange	subresourceRange;
	};

	const vk::VkImageMemoryBarrier		postImageBarrier	=
	{
		vk::VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,		// VkStructureType			sType;
		DE_NULL,										// const void*				pNext;
		vk::VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags			srcAccessMask;
		vk::VK_ACCESS_SHADER_WRITE_BIT,					// VkAccessFlags			dstAccessMask;
		vk::VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,		// VkImageLayout			oldLayout;
		vk::VK_IMAGE_LAYOUT_GENERAL,					// VkImageLayout			newLayout;
		queueFamilyIndex,								// deUint32					srcQueueFamilyIndex;
		queueFamilyIndex,								// deUint32					dstQueueFamilyIndex;
		image,											// VkImage					image;
		subresourceRange								// VkImageSubresourceRange	subresourceRange;
	};

	beginCommandBuffer(vk, *cmdBuffer);
	vk.cmdPipelineBarrier(*cmdBuffer,
						  vk::VK_PIPELINE_STAGE_HOST_BIT,
						  vk::VK_PIPELINE_STAGE_TRANSFER_BIT,
						  (vk::VkDependencyFlags)0,
						  0, (const vk::VkMemoryBarrier*)DE_NULL,
						  0, (const vk::VkBufferMemoryBarrier*)DE_NULL,
						  1, &preImageBarrier);
	vk.cmdClearColorImage(*cmdBuffer, image, vk::VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &clearColor, 1, &subresourceRange);
	vk.cmdPipelineBarrier(*cmdBuffer,
						  vk::VK_PIPELINE_STAGE_TRANSFER_BIT,
						  vk::VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT,
						  (vk::VkDependencyFlags)0,
						  0, (const vk::VkMemoryBarrier*)DE_NULL,
						  0, (const vk::VkBufferMemoryBarrier*)DE_NULL,
						  1, &postImageBarrier);
	endCommandBuffer(vk, *cmdBuffer);

	{
		const vk::Unique<vk::VkFence>	fence		(createFence(vk, device));
		VK_CHECK(queueSubmit(ctx, PROTECTION_ENABLED, queue, *cmdBuffer, *fence, ~0ull));
	}
}

void uploadImage (ProtectedContext& ctx, vk::VkImage image, const tcu::Texture2D& texture2D)
{
	const vk::DeviceInterface&			vk					= ctx.getDeviceInterface();
	const vk::VkDevice					device				= ctx.getDevice();
	const vk::VkQueue					queue				= ctx.getQueue();
	const deUint32						queueFamilyIndex	= ctx.getQueueFamilyIndex();

	vk::Unique<vk::VkCommandPool>		cmdPool				(makeCommandPool(vk, device, PROTECTION_DISABLED, queueFamilyIndex));
	vk::Unique<vk::VkCommandBuffer>		cmdBuffer			(vk::allocateCommandBuffer(vk, device, *cmdPool, vk::VK_COMMAND_BUFFER_LEVEL_PRIMARY));

	const deUint32						width				= (deUint32)texture2D.getWidth();
	const deUint32						height				= (deUint32)texture2D.getHeight();
	const deUint32						stagingBufferSize	= width * height * tcu::getPixelSize(texture2D.getFormat());

	de::UniquePtr<vk::BufferWithMemory>	stagingBuffer		(makeBuffer(ctx,
																		PROTECTION_DISABLED,
																		queueFamilyIndex,
																		stagingBufferSize,
																		vk::VK_BUFFER_USAGE_TRANSFER_SRC_BIT,
																		vk::MemoryRequirement::HostVisible));

	{
		const tcu::ConstPixelBufferAccess&	access		= texture2D.getLevel(0);
		const tcu::PixelBufferAccess		destAccess	(access.getFormat(), access.getSize(), stagingBuffer->getAllocation().getHostPtr());

		tcu::copy(destAccess, access);

		vk::flushMappedMemoryRange(vk, device, stagingBuffer->getAllocation().getMemory(), stagingBuffer->getAllocation().getOffset(), stagingBufferSize);
	}

	const vk::VkImageSubresourceRange	subresourceRange	=
	{
		vk::VK_IMAGE_ASPECT_COLOR_BIT,	// VkImageAspectFlags	aspectMask
		0u,								// uint32_t				baseMipLevel
		1u,								// uint32_t				levelCount
		0u,								// uint32_t				baseArrayLayer
		1u,								// uint32_t				layerCount
	};

	const vk::VkImageMemoryBarrier		preCopyBarrier		=
	{
		vk::VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,		// VkStructureType			sType;
		DE_NULL,										// const void*				pNext;
		0u,												// VkAccessFlags			srcAccessMask;
		vk::VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags			dstAccessMask;
		vk::VK_IMAGE_LAYOUT_UNDEFINED,					// VkImageLayout			oldLayout;
		vk::VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,		// VkImageLayout			newLayout;
		queueFamilyIndex,								// deUint32					srcQueueFamilyIndex;
		queueFamilyIndex,								// deUint32					dstQueueFamilyIndex;
		image,											// VkImage					image;
		subresourceRange								// VkImageSubresourceRange	subresourceRange;
	};

	const vk::VkImageMemoryBarrier		postCopyBarrier		=
	{
		vk::VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,		// VkStructureType			sType;
		DE_NULL,										// const void*				pNext;
		vk::VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags			srcAccessMask;
		vk::VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags			dstAccessMask;
		vk::VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,		// VkImageLayout			oldLayout;
		vk::VK_IMAGE_LAYOUT_GENERAL,					// VkImageLayout			newLayout;
		queueFamilyIndex,								// deUint32					srcQueueFamilyIndex;
		queueFamilyIndex,								// deUint32					dstQueueFamilyIndex;
		image,											// VkImage					image;
		subresourceRange								// VkImageSubresourceRange	subresourceRange;
	};

	const vk::VkImageSubresourceLayers	subresourceLayers	=
	{
		vk::VK_IMAGE_ASPECT_COLOR_BIT,	// VkImageAspectFlags	aspectMask;
		0u,								// deUint32				mipLevel;
		0u,								// deUint32				baseArrayLayer;
		1u								// deUint32				layerCount;
	};

	const vk::VkBufferImageCopy			copyRegion			=
	{
		0u,								// VkDeviceSize					bufferOffset;
		width,							// deUint32						bufferRowLength;
		height,							// deUint32						bufferImageHeight;
		subresourceLayers,				// VkImageSubresourceLayers		imageSubresource;
		{ 0u, 0u, 0u },					// VkOffset3D					imageOffset;
		{ width, height, 1u }			// VkExtent3D					imageExtent;
	};

	beginCommandBuffer(vk, *cmdBuffer);
	vk.cmdPipelineBarrier(*cmdBuffer,
						  (vk::VkPipelineStageFlags)vk::VK_PIPELINE_STAGE_HOST_BIT,
						  (vk::VkPipelineStageFlags)vk::VK_PIPELINE_STAGE_TRANSFER_BIT,
						  (vk::VkDependencyFlags)0u,
						  0u, (const vk::VkMemoryBarrier*)DE_NULL,
						  0u, (const vk::VkBufferMemoryBarrier*)DE_NULL,
						  1u, &preCopyBarrier);
	vk.cmdCopyBufferToImage(*cmdBuffer, **stagingBuffer, image, vk::VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1u, &copyRegion);
	vk.cmdPipelineBarrier(*cmdBuffer,
						  (vk::VkPipelineStageFlags)vk::VK_PIPELINE_STAGE_TRANSFER_BIT,
						  (vk::VkPipelineStageFlags)vk::VK_PIPELINE_STAGE_TRANSFER_BIT,
						  (vk::VkDependencyFlags)0u,
						  0u, (const vk::VkMemoryBarrier*)DE_NULL,
						  0u, (const vk::VkBufferMemoryBarrier*)DE_NULL,
						  1u, &postCopyBarrier);
	endCommandBuffer(vk, *cmdBuffer);

	{
		const vk::Unique<vk::VkFence>	fence		(createFence(vk, device));
		VK_CHECK(queueSubmit(ctx, PROTECTION_DISABLED, queue, *cmdBuffer, *fence, ~0ull));
	}
}

void copyToProtectedImage (ProtectedContext& ctx, vk::VkImage srcImage, vk::VkImage dstImage, vk::VkImageLayout dstImageLayout, deUint32 width, deUint32 height)
{
	const vk::DeviceInterface&			vk					= ctx.getDeviceInterface();
	const vk::VkDevice					device				= ctx.getDevice();
	const vk::VkQueue					queue				= ctx.getQueue();
	const deUint32						queueFamilyIndex	= ctx.getQueueFamilyIndex();

	vk::Unique<vk::VkCommandPool>		cmdPool				(makeCommandPool(vk, device, PROTECTION_ENABLED, queueFamilyIndex));
	vk::Unique<vk::VkCommandBuffer>		cmdBuffer			(vk::allocateCommandBuffer(vk, device, *cmdPool, vk::VK_COMMAND_BUFFER_LEVEL_PRIMARY));

	const vk::VkImageSubresourceRange	subresourceRange	=
	{
		vk::VK_IMAGE_ASPECT_COLOR_BIT,	// VkImageAspectFlags	aspectMask
		0u,								// uint32_t				baseMipLevel
		1u,								// uint32_t				levelCount
		0u,								// uint32_t				baseArrayLayer
		1u,								// uint32_t				layerCount
	};

	const vk::VkImageMemoryBarrier		preImageBarriers[]	=
	{
		// source image
		{
			vk::VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,		// VkStructureType			sType;
			DE_NULL,										// const void*				pNext;
			vk::VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags			srcAccessMask;
			vk::VK_ACCESS_TRANSFER_READ_BIT,				// VkAccessFlags			dstAccessMask;
			vk::VK_IMAGE_LAYOUT_GENERAL,					// VkImageLayout			oldLayout;
			vk::VK_IMAGE_LAYOUT_GENERAL,					// VkImageLayout			newLayout;
			queueFamilyIndex,								// deUint32					srcQueueFamilyIndex;
			queueFamilyIndex,								// deUint32					dstQueueFamilyIndex;
			srcImage,										// VkImage					image;
			subresourceRange								// VkImageSubresourceRange	subresourceRange;
		},
		// destination image
		{
			vk::VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,		// VkStructureType			sType;
			DE_NULL,										// const void*				pNext;
			0,												// VkAccessFlags			srcAccessMask;
			vk::VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags			dstAccessMask;
			vk::VK_IMAGE_LAYOUT_UNDEFINED,					// VkImageLayout			oldLayout;
			vk::VK_IMAGE_LAYOUT_GENERAL,					// VkImageLayout			newLayout;
			queueFamilyIndex,								// deUint32					srcQueueFamilyIndex;
			queueFamilyIndex,								// deUint32					dstQueueFamilyIndex;
			dstImage,										// VkImage					image;
			subresourceRange								// VkImageSubresourceRange	subresourceRange;
		}
	};

	const vk::VkImageMemoryBarrier		postImgBarrier		=
	{
		vk::VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,		// VkStructureType			sType;
		DE_NULL,										// const void*				pNext;
		vk::VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags			srcAccessMask;
		vk::VK_ACCESS_SHADER_READ_BIT,					// VkAccessFlags			dstAccessMask;
		vk::VK_IMAGE_LAYOUT_GENERAL,					// VkImageLayout			oldLayout;
		dstImageLayout,									// VkImageLayout			newLayout;
		queueFamilyIndex,								// deUint32					srcQueueFamilyIndex;
		queueFamilyIndex,								// deUint32					dstQueueFamilyIndex;
		dstImage,										// VkImage					image;
		subresourceRange								// VkImageSubresourceRange	subresourceRange;
	};

	const vk::VkImageSubresourceLayers	subresourceLayers	=
	{
		vk::VK_IMAGE_ASPECT_COLOR_BIT,	// VkImageAspectFlags	aspectMask;
		0u,								// deUint32				mipLevel;
		0u,								// deUint32				baseArrayLayer;
		1u								// deUint32				layerCount;
	};

	const vk::VkImageCopy				copyImageRegion		=
	{
		subresourceLayers,		// VkImageSubresourceCopy	srcSubresource;
		{ 0, 0, 0 },			// VkOffset3D				srcOffset;
		subresourceLayers,		// VkImageSubresourceCopy	destSubresource;
		{ 0, 0, 0 },			// VkOffset3D				destOffset;
		{ width, height, 1u },	// VkExtent3D				extent;
	};

	beginCommandBuffer(vk, *cmdBuffer);
	vk.cmdPipelineBarrier(*cmdBuffer,
						  vk::VK_PIPELINE_STAGE_TRANSFER_BIT,
						  vk::VK_PIPELINE_STAGE_TRANSFER_BIT,
						  (vk::VkDependencyFlags)0,
						  0, (const vk::VkMemoryBarrier*)DE_NULL,
						  0, (const vk::VkBufferMemoryBarrier*)DE_NULL,
						  DE_LENGTH_OF_ARRAY(preImageBarriers), preImageBarriers);
	vk.cmdCopyImage(*cmdBuffer, srcImage, vk::VK_IMAGE_LAYOUT_GENERAL, dstImage, vk::VK_IMAGE_LAYOUT_GENERAL, 1u, &copyImageRegion);
	vk.cmdPipelineBarrier(*cmdBuffer,
						  vk::VK_PIPELINE_STAGE_TRANSFER_BIT,
						  vk::VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT,
						  (vk::VkDependencyFlags)0,
						  0, (const vk::VkMemoryBarrier*)DE_NULL,
						  0, (const vk::VkBufferMemoryBarrier*)DE_NULL,
						  1, &postImgBarrier);
	endCommandBuffer(vk, *cmdBuffer);

	{
		const vk::Unique<vk::VkFence>	fence		(createFence(vk, device));
		VK_CHECK(queueSubmit(ctx, PROTECTION_ENABLED, queue, *cmdBuffer, *fence, ~0ull));
	}
}

void fillWithRandomColorTiles (const tcu::PixelBufferAccess& dst, const tcu::Vec4& minVal, const tcu::Vec4& maxVal, deUint32 seed)
{
	const int	numCols		= dst.getWidth()  >= 7 ? 7 : dst.getWidth();
	const int	numRows		= dst.getHeight() >= 5 ? 5 : dst.getHeight();
	de::Random	rnd			(seed);

	for (int slice = 0; slice < dst.getDepth(); slice++)
	for (int row = 0; row < numRows; row++)
	for (int col = 0; col < numCols; col++)
	{
		const int	yBegin	= (row + 0)*dst.getHeight() / numRows;
		const int	yEnd	= (row + 1)*dst.getHeight() / numRows;
		const int	xBegin	= (col + 0)*dst.getWidth() / numCols;
		const int	xEnd	= (col + 1)*dst.getWidth() / numCols;
		tcu::Vec4	color;
		for (int i = 0; i < 4; i++)
			color[i] = rnd.getFloat(minVal[i], maxVal[i]);
		tcu::clear(tcu::getSubregion(dst, xBegin, yBegin, slice, xEnd - xBegin, yEnd - yBegin, 1), color);
	}
}

} // ProtectedMem
} // vkt
