/*-------------------------------------------------------------------------
 * Vulkan Conformance Tests
 * ------------------------
 *
 * Copyright (c) 2015 Google 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 Simple Smoke Tests
 *//*--------------------------------------------------------------------*/

#include "vktApiTests.hpp"

#include "vktTestCaseUtil.hpp"

#include "vkDefs.hpp"
#include "vkPlatform.hpp"
#include "vkStrUtil.hpp"
#include "vkRef.hpp"
#include "vkRefUtil.hpp"
#include "vkQueryUtil.hpp"
#include "vkMemUtil.hpp"
#include "vkDeviceUtil.hpp"
#include "vkPrograms.hpp"
#include "vkTypeUtil.hpp"
#include "vkImageUtil.hpp"
#include "vkCmdUtil.hpp"
#include "vkObjUtil.hpp"

#include "tcuTestLog.hpp"
#include "tcuFormatUtil.hpp"
#include "tcuTextureUtil.hpp"
#include "tcuImageCompare.hpp"

#include "rrRenderer.hpp"

#include "deUniquePtr.hpp"

namespace vkt
{
namespace api
{

namespace
{

using namespace vk;
using std::vector;
using tcu::TestLog;
using de::UniquePtr;

tcu::TestStatus createSamplerTest (Context& context)
{
	const VkDevice			vkDevice	= context.getDevice();
	const DeviceInterface&	vk			= context.getDeviceInterface();

	{
		const struct VkSamplerCreateInfo		samplerInfo	=
		{
			VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO,		// sType
			DE_NULL,									// pNext
			0u,											// flags
			VK_FILTER_NEAREST,							// magFilter
			VK_FILTER_NEAREST,							// minFilter
			VK_SAMPLER_MIPMAP_MODE_NEAREST,				// mipmapMode
			VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,		// addressModeU
			VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,		// addressModeV
			VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,		// addressModeW
			0.0f,										// mipLodBias
			VK_FALSE,									// anisotropyEnable
			1.0f,										// maxAnisotropy
			DE_FALSE,									// compareEnable
			VK_COMPARE_OP_ALWAYS,						// compareOp
			0.0f,										// minLod
			0.0f,										// maxLod
			VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK,	// borderColor
			VK_FALSE,									// unnormalizedCoords
		};

		Move<VkSampler>			tmpSampler	= createSampler(vk, vkDevice, &samplerInfo);
		Move<VkSampler>			tmp2Sampler;

		tmp2Sampler = tmpSampler;

		const Unique<VkSampler>	sampler		(tmp2Sampler);
	}

	return tcu::TestStatus::pass("Creating sampler succeeded");
}

void createShaderProgs (SourceCollections& dst)
{
	dst.glslSources.add("test") << glu::VertexSource(
		"#version 310 es\n"
		"layout(location = 0) in highp vec4 a_position;\n"
		"void main (void) { gl_Position = a_position; }\n");
}

tcu::TestStatus createShaderModuleTest (Context& context)
{
	const VkDevice					vkDevice	= context.getDevice();
	const DeviceInterface&			vk			= context.getDeviceInterface();
	const Unique<VkShaderModule>	shader		(createShaderModule(vk, vkDevice, context.getBinaryCollection().get("test"), 0));

	return tcu::TestStatus::pass("Creating shader module succeeded");
}

void createTriangleAsmProgs (SourceCollections& dst)
{
	dst.spirvAsmSources.add("vert") <<
		"		 OpCapability Shader\n"
		"%1 =	 OpExtInstImport \"GLSL.std.450\"\n"
		"		 OpMemoryModel Logical GLSL450\n"
		"		 OpEntryPoint Vertex %4 \"main\" %10 %12 %16 %17\n"
		"		 OpSource ESSL 300\n"
		"		 OpName %4 \"main\"\n"
		"		 OpName %10 \"gl_Position\"\n"
		"		 OpName %12 \"a_position\"\n"
		"		 OpName %16 \"gl_VertexIndex\"\n"
		"		 OpName %17 \"gl_InstanceIndex\"\n"
		"		 OpDecorate %10 BuiltIn Position\n"
		"		 OpDecorate %12 Location 0\n"
		"		 OpDecorate %16 BuiltIn VertexIndex\n"
		"		 OpDecorate %17 BuiltIn InstanceIndex\n"
		"%2 =	 OpTypeVoid\n"
		"%3 =	 OpTypeFunction %2\n"
		"%7 =	 OpTypeFloat 32\n"
		"%8 =	 OpTypeVector %7 4\n"
		"%9 =	 OpTypePointer Output %8\n"
		"%10 =	 OpVariable %9 Output\n"
		"%11 =	 OpTypePointer Input %8\n"
		"%12 =	 OpVariable %11 Input\n"
		"%14 =	 OpTypeInt 32 1\n"
		"%15 =	 OpTypePointer Input %14\n"
		"%16 =	 OpVariable %15 Input\n"
		"%17 =	 OpVariable %15 Input\n"
		"%4 =	 OpFunction %2 None %3\n"
		"%5 =	 OpLabel\n"
		"%13 =	 OpLoad %8 %12\n"
		"		 OpStore %10 %13\n"
		"		 OpBranch %6\n"
		"%6 =	 OpLabel\n"
		"		 OpReturn\n"
		"		 OpFunctionEnd\n";
	dst.spirvAsmSources.add("frag") <<
		"		OpCapability Shader\n"
		"%1 =	OpExtInstImport \"GLSL.std.450\"\n"
		"		OpMemoryModel Logical GLSL450\n"
		"		OpEntryPoint Fragment %4 \"main\" %10\n"
		"		OpExecutionMode %4 OriginUpperLeft\n"
		"		OpSource ESSL 300\n"
		"		OpName %4 \"main\"\n"
		"		OpName %10 \"o_color\"\n"
		"		OpDecorate %10 RelaxedPrecision\n"
		"		OpDecorate %10 Location 0\n"
		"%2 =	OpTypeVoid\n"
		"%3 =	OpTypeFunction %2\n"
		"%7 =	OpTypeFloat 32\n"
		"%8 =	OpTypeVector %7 4\n"
		"%9 =	OpTypePointer Output %8\n"
		"%10 =	OpVariable %9 Output\n"
		"%11 =	OpConstant %7 1065353216\n"
		"%12 =	OpConstant %7 0\n"
		"%13 =	OpConstantComposite %8 %11 %12 %11 %11\n"
		"%4 =	OpFunction %2 None %3\n"
		"%5 =	OpLabel\n"
		"		OpStore %10 %13\n"
		"		OpBranch %6\n"
		"%6 =	OpLabel\n"
		"		OpReturn\n"
		"		OpFunctionEnd\n";
}

void createTriangleProgs (SourceCollections& dst)
{
	dst.glslSources.add("vert") << glu::VertexSource(
		"#version 310 es\n"
		"layout(location = 0) in highp vec4 a_position;\n"
		"void main (void) { gl_Position = a_position; }\n");
	dst.glslSources.add("frag") << glu::FragmentSource(
		"#version 310 es\n"
		"layout(location = 0) out lowp vec4 o_color;\n"
		"void main (void) { o_color = vec4(1.0, 0.0, 1.0, 1.0); }\n");
}

void createProgsNoOpName (SourceCollections& dst)
{
	dst.spirvAsmSources.add("vert") <<
		"OpCapability Shader\n"
		"%1 = OpExtInstImport \"GLSL.std.450\"\n"
		"OpMemoryModel Logical GLSL450\n"
		"OpEntryPoint Vertex %4 \"main\" %20 %22 %26\n"
		"OpSource ESSL 310\n"
		"OpMemberDecorate %18 0 BuiltIn Position\n"
		"OpMemberDecorate %18 1 BuiltIn PointSize\n"
		"OpDecorate %18 Block\n"
		"OpDecorate %22 Location 0\n"
		"OpDecorate %26 Location 2\n"
		"%2 = OpTypeVoid\n"
		"%3 = OpTypeFunction %2\n"
		"%6 = OpTypeFloat 32\n"
		"%7 = OpTypeVector %6 4\n"
		"%8 = OpTypeStruct %7\n"
		"%9 = OpTypePointer Function %8\n"
		"%11 = OpTypeInt 32 1\n"
		"%12 = OpConstant %11 0\n"
		"%13 = OpConstant %6 1\n"
		"%14 = OpConstant %6 0\n"
		"%15 = OpConstantComposite %7 %13 %14 %13 %13\n"
		"%16 = OpTypePointer Function %7\n"
		"%18 = OpTypeStruct %7 %6\n"
		"%19 = OpTypePointer Output %18\n"
		"%20 = OpVariable %19 Output\n"
		"%21 = OpTypePointer Input %7\n"
		"%22 = OpVariable %21 Input\n"
		"%24 = OpTypePointer Output %7\n"
		"%26 = OpVariable %24 Output\n"
		"%4 = OpFunction %2 None %3\n"
		"%5 = OpLabel\n"
		"%10 = OpVariable %9 Function\n"
		"%17 = OpAccessChain %16 %10 %12\n"
		"OpStore %17 %15\n"
		"%23 = OpLoad %7 %22\n"
		"%25 = OpAccessChain %24 %20 %12\n"
		"OpStore %25 %23\n"
		"%27 = OpAccessChain %16 %10 %12\n"
		"%28 = OpLoad %7 %27\n"
		"OpStore %26 %28\n"
		"OpReturn\n"
		"OpFunctionEnd\n";
	dst.spirvAsmSources.add("frag") <<
		"OpCapability Shader\n"
		"%1 = OpExtInstImport \"GLSL.std.450\"\n"
		"OpMemoryModel Logical GLSL450\n"
		"OpEntryPoint Fragment %4 \"main\" %9 %11\n"
		"OpExecutionMode %4 OriginUpperLeft\n"
		"OpSource ESSL 310\n"
		"OpDecorate %9 RelaxedPrecision\n"
		"OpDecorate %9 Location 0\n"
		"OpDecorate %11 Location 2\n"
		"%2 = OpTypeVoid\n"
		"%3 = OpTypeFunction %2\n"
		"%6 = OpTypeFloat 32\n"
		"%7 = OpTypeVector %6 4\n"
		"%8 = OpTypePointer Output %7\n"
		"%9 = OpVariable %8 Output\n"
		"%10 = OpTypePointer Input %7\n"
		"%11 = OpVariable %10 Input\n"
		"%4 = OpFunction %2 None %3\n"
		"%5 = OpLabel\n"
		"%12 = OpLoad %7 %11\n"
		"OpStore %9 %12\n"
		"OpReturn\n"
		"OpFunctionEnd\n";
}

class RefVertexShader : public rr::VertexShader
{
public:
	RefVertexShader (void)
		: rr::VertexShader(1, 0)
	{
		m_inputs[0].type = rr::GENERICVECTYPE_FLOAT;
	}

	void shadeVertices (const rr::VertexAttrib* inputs, rr::VertexPacket* const* packets, const int numPackets) const
	{
		for (int packetNdx = 0; packetNdx < numPackets; ++packetNdx)
		{
			packets[packetNdx]->position = rr::readVertexAttribFloat(inputs[0],
																	 packets[packetNdx]->instanceNdx,
																	 packets[packetNdx]->vertexNdx);
		}
	}
};

class RefFragmentShader : public rr::FragmentShader
{
public:
	RefFragmentShader (void)
		: rr::FragmentShader(0, 1)
	{
		m_outputs[0].type = rr::GENERICVECTYPE_FLOAT;
	}

	void shadeFragments (rr::FragmentPacket*, const int numPackets, const rr::FragmentShadingContext& context) const
	{
		for (int packetNdx = 0; packetNdx < numPackets; ++packetNdx)
		{
			for (int fragNdx = 0; fragNdx < rr::NUM_FRAGMENTS_PER_PACKET; ++fragNdx)
			{
				rr::writeFragmentOutput(context, packetNdx, fragNdx, 0, tcu::Vec4(1.0f, 0.0f, 1.0f, 1.0f));
			}
		}
	}
};

void renderReferenceTriangle (const tcu::PixelBufferAccess& dst, const tcu::Vec4 (&vertices)[3], const int subpixelBits)
{
	const RefVertexShader					vertShader;
	const RefFragmentShader					fragShader;
	const rr::Program						program			(&vertShader, &fragShader);
	const rr::MultisamplePixelBufferAccess	colorBuffer		= rr::MultisamplePixelBufferAccess::fromSinglesampleAccess(dst);
	const rr::RenderTarget					renderTarget	(colorBuffer);
	const rr::RenderState					renderState		((rr::ViewportState(colorBuffer)), subpixelBits, rr::VIEWPORTORIENTATION_UPPER_LEFT);
	const rr::Renderer						renderer;
	const rr::VertexAttrib					vertexAttribs[]	=
	{
		rr::VertexAttrib(rr::VERTEXATTRIBTYPE_FLOAT, 4, sizeof(tcu::Vec4), 0, vertices[0].getPtr())
	};

	renderer.draw(rr::DrawCommand(renderState,
								  renderTarget,
								  program,
								  DE_LENGTH_OF_ARRAY(vertexAttribs),
								  &vertexAttribs[0],
								  rr::PrimitiveList(rr::PRIMITIVETYPE_TRIANGLES, DE_LENGTH_OF_ARRAY(vertices), 0)));
}

tcu::TestStatus renderTriangleTest (Context& context)
{
	const VkDevice							vkDevice				= context.getDevice();
	const DeviceInterface&					vk						= context.getDeviceInterface();
	const VkQueue							queue					= context.getUniversalQueue();
	const deUint32							queueFamilyIndex		= context.getUniversalQueueFamilyIndex();
	SimpleAllocator							memAlloc				(vk, vkDevice, getPhysicalDeviceMemoryProperties(context.getInstanceInterface(), context.getPhysicalDevice()));
	const tcu::IVec2						renderSize				(256, 256);
	const VkFormat							colorFormat				= VK_FORMAT_R8G8B8A8_UNORM;
	const tcu::Vec4							clearColor				(0.125f, 0.25f, 0.75f, 1.0f);

	const tcu::Vec4							vertices[]				=
	{
		tcu::Vec4(-0.5f, -0.5f, 0.0f, 1.0f),
		tcu::Vec4(+0.5f, -0.5f, 0.0f, 1.0f),
		tcu::Vec4( 0.0f, +0.5f, 0.0f, 1.0f)
	};

	const VkBufferCreateInfo				vertexBufferParams		=
	{
		VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,	// sType
		DE_NULL,								// pNext
		0u,										// flags
		(VkDeviceSize)sizeof(vertices),			// size
		VK_BUFFER_USAGE_VERTEX_BUFFER_BIT,		// usage
		VK_SHARING_MODE_EXCLUSIVE,				// sharingMode
		1u,										// queueFamilyIndexCount
		&queueFamilyIndex,						// pQueueFamilyIndices
	};
	const Unique<VkBuffer>					vertexBuffer			(createBuffer(vk, vkDevice, &vertexBufferParams));
	const UniquePtr<Allocation>				vertexBufferMemory		(memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *vertexBuffer), MemoryRequirement::HostVisible));

	VK_CHECK(vk.bindBufferMemory(vkDevice, *vertexBuffer, vertexBufferMemory->getMemory(), vertexBufferMemory->getOffset()));

	const VkDeviceSize						imageSizeBytes			= (VkDeviceSize)(sizeof(deUint32)*renderSize.x()*renderSize.y());
	const VkBufferCreateInfo				readImageBufferParams	=
	{
		VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,		// sType
		DE_NULL,									// pNext
		(VkBufferCreateFlags)0u,					// flags
		imageSizeBytes,								// size
		VK_BUFFER_USAGE_TRANSFER_DST_BIT,			// usage
		VK_SHARING_MODE_EXCLUSIVE,					// sharingMode
		1u,											// queueFamilyIndexCount
		&queueFamilyIndex,							// pQueueFamilyIndices
	};
	const Unique<VkBuffer>					readImageBuffer			(createBuffer(vk, vkDevice, &readImageBufferParams));
	const UniquePtr<Allocation>				readImageBufferMemory	(memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *readImageBuffer), MemoryRequirement::HostVisible));

	VK_CHECK(vk.bindBufferMemory(vkDevice, *readImageBuffer, readImageBufferMemory->getMemory(), readImageBufferMemory->getOffset()));

	const VkImageCreateInfo					imageParams				=
	{
		VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,									// sType
		DE_NULL,																// pNext
		0u,																		// flags
		VK_IMAGE_TYPE_2D,														// imageType
		VK_FORMAT_R8G8B8A8_UNORM,												// format
		{ (deUint32)renderSize.x(), (deUint32)renderSize.y(), 1 },				// extent
		1u,																		// mipLevels
		1u,																		// arraySize
		VK_SAMPLE_COUNT_1_BIT,													// samples
		VK_IMAGE_TILING_OPTIMAL,												// tiling
		VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT|VK_IMAGE_USAGE_TRANSFER_SRC_BIT,	// usage
		VK_SHARING_MODE_EXCLUSIVE,												// sharingMode
		1u,																		// queueFamilyIndexCount
		&queueFamilyIndex,														// pQueueFamilyIndices
		VK_IMAGE_LAYOUT_UNDEFINED,												// initialLayout
	};

	const Unique<VkImage>					image					(createImage(vk, vkDevice, &imageParams));
	const UniquePtr<Allocation>				imageMemory				(memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, *image), MemoryRequirement::Any));

	VK_CHECK(vk.bindImageMemory(vkDevice, *image, imageMemory->getMemory(), imageMemory->getOffset()));

	const Unique<VkRenderPass>				renderPass				(makeRenderPass(vk, vkDevice, VK_FORMAT_R8G8B8A8_UNORM));

	const VkImageViewCreateInfo				colorAttViewParams		=
	{
		VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,		// sType
		DE_NULL,										// pNext
		0u,												// flags
		*image,											// image
		VK_IMAGE_VIEW_TYPE_2D,							// viewType
		VK_FORMAT_R8G8B8A8_UNORM,						// format
		{
			VK_COMPONENT_SWIZZLE_R,
			VK_COMPONENT_SWIZZLE_G,
			VK_COMPONENT_SWIZZLE_B,
			VK_COMPONENT_SWIZZLE_A
		},												// components
		{
			VK_IMAGE_ASPECT_COLOR_BIT,						// aspectMask
			0u,												// baseMipLevel
			1u,												// levelCount
			0u,												// baseArrayLayer
			1u,												// layerCount
		},												// subresourceRange
	};
	const Unique<VkImageView>				colorAttView			(createImageView(vk, vkDevice, &colorAttViewParams));

	// Pipeline layout
	const VkPipelineLayoutCreateInfo		pipelineLayoutParams	=
	{
		VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,			// sType
		DE_NULL,												// pNext
		(vk::VkPipelineLayoutCreateFlags)0,
		0u,														// setLayoutCount
		DE_NULL,												// pSetLayouts
		0u,														// pushConstantRangeCount
		DE_NULL,												// pPushConstantRanges
	};
	const Unique<VkPipelineLayout>			pipelineLayout			(createPipelineLayout(vk, vkDevice, &pipelineLayoutParams));

	// Shaders
	const Unique<VkShaderModule>			vertShaderModule		(createShaderModule(vk, vkDevice, context.getBinaryCollection().get("vert"), 0));
	const Unique<VkShaderModule>			fragShaderModule		(createShaderModule(vk, vkDevice, context.getBinaryCollection().get("frag"), 0));

	// Pipeline
	const std::vector<VkViewport>			viewports				(1, makeViewport(renderSize));
	const std::vector<VkRect2D>				scissors				(1, makeRect2D(renderSize));

	const Unique<VkPipeline>				pipeline				(makeGraphicsPipeline(vk,					// const DeviceInterface&            vk
																						  vkDevice,				// const VkDevice                    device
																						  *pipelineLayout,		// const VkPipelineLayout            pipelineLayout
																						  *vertShaderModule,	// const VkShaderModule              vertexShaderModule
																						  DE_NULL,				// const VkShaderModule              tessellationControlModule
																						  DE_NULL,				// const VkShaderModule              tessellationEvalModule
																						  DE_NULL,				// const VkShaderModule              geometryShaderModule
																						  *fragShaderModule,	// const VkShaderModule              fragmentShaderModule
																						  *renderPass,			// const VkRenderPass                renderPass
																						  viewports,			// const std::vector<VkViewport>&    viewports
																						  scissors));			// const std::vector<VkRect2D>&      scissors

	// Framebuffer
	const VkFramebufferCreateInfo			framebufferParams		=
	{
		VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,				// sType
		DE_NULL,												// pNext
		0u,														// flags
		*renderPass,											// renderPass
		1u,														// attachmentCount
		&*colorAttView,											// pAttachments
		(deUint32)renderSize.x(),								// width
		(deUint32)renderSize.y(),								// height
		1u,														// layers
	};
	const Unique<VkFramebuffer>				framebuffer				(createFramebuffer(vk, vkDevice, &framebufferParams));

	const VkCommandPoolCreateInfo			cmdPoolParams			=
	{
		VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,					// sType
		DE_NULL,													// pNext
		VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT,			// flags
		queueFamilyIndex,											// queueFamilyIndex
	};
	const Unique<VkCommandPool>				cmdPool					(createCommandPool(vk, vkDevice, &cmdPoolParams));

	// Command buffer
	const VkCommandBufferAllocateInfo		cmdBufParams			=
	{
		VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,			// sType
		DE_NULL,												// pNext
		*cmdPool,												// pool
		VK_COMMAND_BUFFER_LEVEL_PRIMARY,						// level
		1u,														// bufferCount
	};
	const Unique<VkCommandBuffer>			cmdBuf					(allocateCommandBuffer(vk, vkDevice, &cmdBufParams));

	// Record commands
	beginCommandBuffer(vk, *cmdBuf);

	{
		const VkMemoryBarrier		vertFlushBarrier	=
		{
			VK_STRUCTURE_TYPE_MEMORY_BARRIER,			// sType
			DE_NULL,									// pNext
			VK_ACCESS_HOST_WRITE_BIT,					// srcAccessMask
			VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT,		// dstAccessMask
		};
		const VkImageMemoryBarrier	colorAttBarrier		=
		{
			VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,		// sType
			DE_NULL,									// pNext
			0u,											// srcAccessMask
			(VK_ACCESS_COLOR_ATTACHMENT_READ_BIT|
			 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT),		// dstAccessMask
			VK_IMAGE_LAYOUT_UNDEFINED,					// oldLayout
			VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,	// newLayout
			queueFamilyIndex,							// srcQueueFamilyIndex
			queueFamilyIndex,							// dstQueueFamilyIndex
			*image,										// image
			{
				VK_IMAGE_ASPECT_COLOR_BIT,					// aspectMask
				0u,											// baseMipLevel
				1u,											// levelCount
				0u,											// baseArrayLayer
				1u,											// layerCount
			}											// subresourceRange
		};
		vk.cmdPipelineBarrier(*cmdBuf, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, (VkDependencyFlags)0, 1, &vertFlushBarrier, 0, (const VkBufferMemoryBarrier*)DE_NULL, 1, &colorAttBarrier);
	}

	beginRenderPass(vk, *cmdBuf, *renderPass, *framebuffer, makeRect2D(0, 0, renderSize.x(), renderSize.y()), clearColor);

	vk.cmdBindPipeline(*cmdBuf, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipeline);
	{
		const VkDeviceSize bindingOffset = 0;
		vk.cmdBindVertexBuffers(*cmdBuf, 0u, 1u, &vertexBuffer.get(), &bindingOffset);
	}
	vk.cmdDraw(*cmdBuf, 3u, 1u, 0u, 0u);
	endRenderPass(vk, *cmdBuf);
	copyImageToBuffer(vk, *cmdBuf, *image, *readImageBuffer, renderSize);
	endCommandBuffer(vk, *cmdBuf);

	// Upload vertex data
	deMemcpy(vertexBufferMemory->getHostPtr(), &vertices[0], sizeof(vertices));
	flushAlloc(vk, vkDevice, *vertexBufferMemory);

	// Submit & wait for completion
	submitCommandsAndWait(vk, vkDevice, queue, cmdBuf.get());

	// Read results, render reference, compare
	{
		const tcu::TextureFormat			tcuFormat		= vk::mapVkFormat(colorFormat);
		const VkMappedMemoryRange			range			=
		{
			VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE,	// sType
			DE_NULL,								// pNext
			readImageBufferMemory->getMemory(),		// memory
			0,										// offset
			imageSizeBytes,							// size
		};
		const tcu::ConstPixelBufferAccess	resultAccess	(tcuFormat, renderSize.x(), renderSize.y(), 1, readImageBufferMemory->getHostPtr());

		VK_CHECK(vk.invalidateMappedMemoryRanges(vkDevice, 1u, &range));

		{
			tcu::TextureLevel	refImage		(tcuFormat, renderSize.x(), renderSize.y());
			const tcu::UVec4	threshold		(0u);
			const tcu::IVec3	posDeviation	(1,1,0);

			tcu::clear(refImage.getAccess(), clearColor);
			renderReferenceTriangle(refImage.getAccess(), vertices, context.getDeviceProperties().limits.subPixelPrecisionBits);

			if (tcu::intThresholdPositionDeviationCompare(context.getTestContext().getLog(),
														  "ComparisonResult",
														  "Image comparison result",
														  refImage.getAccess(),
														  resultAccess,
														  threshold,
														  posDeviation,
														  false,
														  tcu::COMPARE_LOG_RESULT))
				return tcu::TestStatus::pass("Rendering succeeded");
			else
				return tcu::TestStatus::fail("Image comparison failed");
		}
	}

	return tcu::TestStatus::pass("Rendering succeeded");
}

tcu::TestStatus renderTriangleUnusedResolveAttachmentTest (Context& context)
{
	const VkDevice							vkDevice				= context.getDevice();
	const DeviceInterface&					vk						= context.getDeviceInterface();
	const VkQueue							queue					= context.getUniversalQueue();
	const deUint32							queueFamilyIndex		= context.getUniversalQueueFamilyIndex();
	SimpleAllocator							memAlloc				(vk, vkDevice, getPhysicalDeviceMemoryProperties(context.getInstanceInterface(), context.getPhysicalDevice()));
	const tcu::IVec2						renderSize				(256, 256);
	const VkFormat							colorFormat				= VK_FORMAT_R8G8B8A8_UNORM;
	const tcu::Vec4							clearColor				(0.125f, 0.25f, 0.75f, 1.0f);

	const tcu::Vec4							vertices[]				=
	{
		tcu::Vec4(-0.5f, -0.5f, 0.0f, 1.0f),
		tcu::Vec4(+0.5f, -0.5f, 0.0f, 1.0f),
		tcu::Vec4( 0.0f, +0.5f, 0.0f, 1.0f)
	};

	const VkBufferCreateInfo				vertexBufferParams		=
	{
		VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,	// sType
		DE_NULL,								// pNext
		0u,										// flags
		(VkDeviceSize)sizeof(vertices),			// size
		VK_BUFFER_USAGE_VERTEX_BUFFER_BIT,		// usage
		VK_SHARING_MODE_EXCLUSIVE,				// sharingMode
		1u,										// queueFamilyIndexCount
		&queueFamilyIndex,						// pQueueFamilyIndices
	};
	const Unique<VkBuffer>					vertexBuffer			(createBuffer(vk, vkDevice, &vertexBufferParams));
	const UniquePtr<Allocation>				vertexBufferMemory		(memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *vertexBuffer), MemoryRequirement::HostVisible));

	VK_CHECK(vk.bindBufferMemory(vkDevice, *vertexBuffer, vertexBufferMemory->getMemory(), vertexBufferMemory->getOffset()));

	const VkDeviceSize						imageSizeBytes			= (VkDeviceSize)(sizeof(deUint32)*renderSize.x()*renderSize.y());
	const VkBufferCreateInfo				readImageBufferParams	=
	{
		VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,		// sType
		DE_NULL,									// pNext
		(VkBufferCreateFlags)0u,					// flags
		imageSizeBytes,								// size
		VK_BUFFER_USAGE_TRANSFER_DST_BIT,			// usage
		VK_SHARING_MODE_EXCLUSIVE,					// sharingMode
		1u,											// queueFamilyIndexCount
		&queueFamilyIndex,							// pQueueFamilyIndices
	};
	const Unique<VkBuffer>					readImageBuffer			(createBuffer(vk, vkDevice, &readImageBufferParams));
	const UniquePtr<Allocation>				readImageBufferMemory	(memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *readImageBuffer), MemoryRequirement::HostVisible));

	VK_CHECK(vk.bindBufferMemory(vkDevice, *readImageBuffer, readImageBufferMemory->getMemory(), readImageBufferMemory->getOffset()));

	const VkImageCreateInfo					imageParams				=
	{
		VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,									// sType
		DE_NULL,																// pNext
		0u,																		// flags
		VK_IMAGE_TYPE_2D,														// imageType
		VK_FORMAT_R8G8B8A8_UNORM,												// format
		{ (deUint32)renderSize.x(), (deUint32)renderSize.y(), 1 },				// extent
		1u,																		// mipLevels
		1u,																		// arraySize
		VK_SAMPLE_COUNT_1_BIT,													// samples
		VK_IMAGE_TILING_OPTIMAL,												// tiling
		VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT|VK_IMAGE_USAGE_TRANSFER_SRC_BIT,	// usage
		VK_SHARING_MODE_EXCLUSIVE,												// sharingMode
		1u,																		// queueFamilyIndexCount
		&queueFamilyIndex,														// pQueueFamilyIndices
		VK_IMAGE_LAYOUT_UNDEFINED,												// initialLayout
	};

	const Unique<VkImage>					image					(createImage(vk, vkDevice, &imageParams));
	const UniquePtr<Allocation>				imageMemory				(memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, *image), MemoryRequirement::Any));

	VK_CHECK(vk.bindImageMemory(vkDevice, *image, imageMemory->getMemory(), imageMemory->getOffset()));

	const VkAttachmentDescription			colorAttDesc			=
	{
		0u,												// flags
		VK_FORMAT_R8G8B8A8_UNORM,						// format
		VK_SAMPLE_COUNT_1_BIT,							// samples
		VK_ATTACHMENT_LOAD_OP_CLEAR,					// loadOp
		VK_ATTACHMENT_STORE_OP_STORE,					// storeOp
		VK_ATTACHMENT_LOAD_OP_DONT_CARE,				// stencilLoadOp
		VK_ATTACHMENT_STORE_OP_DONT_CARE,				// stencilStoreOp
		VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,		// initialLayout
		VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,		// finalLayout
	};
	const VkAttachmentReference				colorAttRef				=
	{
		0u,												// attachment
		VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,		// layout
	};
	const VkAttachmentReference				resolveAttRef			=
	{
		VK_ATTACHMENT_UNUSED,
		VK_IMAGE_LAYOUT_GENERAL
	};
	const VkSubpassDescription				subpassDesc				=
	{
		(VkSubpassDescriptionFlags)0u,					// flags
		VK_PIPELINE_BIND_POINT_GRAPHICS,				// pipelineBindPoint
		0u,												// inputAttachmentCount
		DE_NULL,										// pInputAttachments
		1u,												// colorAttachmentCount
		&colorAttRef,									// pColorAttachments
		&resolveAttRef,									// pResolveAttachments
		DE_NULL,										// depthStencilAttachment
		0u,												// preserveAttachmentCount
		DE_NULL,										// pPreserveAttachments
	};
	const VkRenderPassCreateInfo			renderPassParams		=
	{
		VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,		// sType
		DE_NULL,										// pNext
		0u,												// flags
		1u,												// attachmentCount
		&colorAttDesc,									// pAttachments
		1u,												// subpassCount
		&subpassDesc,									// pSubpasses
		0u,												// dependencyCount
		DE_NULL,										// pDependencies
	};
	const Unique<VkRenderPass>				renderPass				(createRenderPass(vk, vkDevice, &renderPassParams));

	const VkImageViewCreateInfo				colorAttViewParams		=
	{
		VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,		// sType
		DE_NULL,										// pNext
		0u,												// flags
		*image,											// image
		VK_IMAGE_VIEW_TYPE_2D,							// viewType
		VK_FORMAT_R8G8B8A8_UNORM,						// format
		{
			VK_COMPONENT_SWIZZLE_R,
			VK_COMPONENT_SWIZZLE_G,
			VK_COMPONENT_SWIZZLE_B,
			VK_COMPONENT_SWIZZLE_A
		},												// components
		{
			VK_IMAGE_ASPECT_COLOR_BIT,						// aspectMask
			0u,												// baseMipLevel
			1u,												// levelCount
			0u,												// baseArrayLayer
			1u,												// layerCount
		},												// subresourceRange
	};
	const Unique<VkImageView>				colorAttView			(createImageView(vk, vkDevice, &colorAttViewParams));

	// Pipeline layout
	const VkPipelineLayoutCreateInfo		pipelineLayoutParams	=
	{
		VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,			// sType
		DE_NULL,												// pNext
		(vk::VkPipelineLayoutCreateFlags)0,
		0u,														// setLayoutCount
		DE_NULL,												// pSetLayouts
		0u,														// pushConstantRangeCount
		DE_NULL,												// pPushConstantRanges
	};
	const Unique<VkPipelineLayout>			pipelineLayout			(createPipelineLayout(vk, vkDevice, &pipelineLayoutParams));

	// Shaders
	const Unique<VkShaderModule>			vertShaderModule		(createShaderModule(vk, vkDevice, context.getBinaryCollection().get("vert"), 0));
	const Unique<VkShaderModule>			fragShaderModule		(createShaderModule(vk, vkDevice, context.getBinaryCollection().get("frag"), 0));

	// Pipeline
	const std::vector<VkViewport>			viewports				(1, makeViewport(renderSize));
	const std::vector<VkRect2D>				scissors				(1, makeRect2D(renderSize));

	const Unique<VkPipeline>				pipeline				(makeGraphicsPipeline(vk,					// const DeviceInterface&            vk
																						  vkDevice,				// const VkDevice                    device
																						  *pipelineLayout,		// const VkPipelineLayout            pipelineLayout
																						  *vertShaderModule,	// const VkShaderModule              vertexShaderModule
																						  DE_NULL,				// const VkShaderModule              tessellationControlShaderModule
																						  DE_NULL,				// const VkShaderModule              tessellationEvalShaderModule
																						  DE_NULL,				// const VkShaderModule              geometryShaderModule
																						  *fragShaderModule,	// const VkShaderModule              fragmentShaderModule
																						  *renderPass,			// const VkRenderPass                renderPass
																						  viewports,			// const std::vector<VkViewport>&    viewports
																						  scissors));			// const std::vector<VkRect2D>&      scissors

	// Framebuffer
	const VkFramebufferCreateInfo			framebufferParams		=
	{
		VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,				// sType
		DE_NULL,												// pNext
		0u,														// flags
		*renderPass,											// renderPass
		1u,														// attachmentCount
		&*colorAttView,											// pAttachments
		(deUint32)renderSize.x(),								// width
		(deUint32)renderSize.y(),								// height
		1u,														// layers
	};
	const Unique<VkFramebuffer>				framebuffer				(createFramebuffer(vk, vkDevice, &framebufferParams));

	const VkCommandPoolCreateInfo			cmdPoolParams			=
	{
		VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,					// sType
		DE_NULL,													// pNext
		VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT,			// flags
		queueFamilyIndex,											// queueFamilyIndex
	};
	const Unique<VkCommandPool>				cmdPool					(createCommandPool(vk, vkDevice, &cmdPoolParams));

	// Command buffer
	const VkCommandBufferAllocateInfo		cmdBufParams			=
	{
		VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,			// sType
		DE_NULL,												// pNext
		*cmdPool,												// pool
		VK_COMMAND_BUFFER_LEVEL_PRIMARY,						// level
		1u,														// bufferCount
	};
	const Unique<VkCommandBuffer>			cmdBuf					(allocateCommandBuffer(vk, vkDevice, &cmdBufParams));

	// Record commands
	beginCommandBuffer(vk, *cmdBuf);

	{
		const VkMemoryBarrier		vertFlushBarrier	=
		{
			VK_STRUCTURE_TYPE_MEMORY_BARRIER,			// sType
			DE_NULL,									// pNext
			VK_ACCESS_HOST_WRITE_BIT,					// srcAccessMask
			VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT,		// dstAccessMask
		};
		const VkImageMemoryBarrier	colorAttBarrier		=
		{
			VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,		// sType
			DE_NULL,									// pNext
			0u,											// srcAccessMask
			(VK_ACCESS_COLOR_ATTACHMENT_READ_BIT|
			 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT),		// dstAccessMask
			VK_IMAGE_LAYOUT_UNDEFINED,					// oldLayout
			VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,	// newLayout
			queueFamilyIndex,							// srcQueueFamilyIndex
			queueFamilyIndex,							// dstQueueFamilyIndex
			*image,										// image
			{
				VK_IMAGE_ASPECT_COLOR_BIT,					// aspectMask
				0u,											// baseMipLevel
				1u,											// levelCount
				0u,											// baseArrayLayer
				1u,											// layerCount
			}											// subresourceRange
		};
		vk.cmdPipelineBarrier(*cmdBuf, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, (VkDependencyFlags)0, 1, &vertFlushBarrier, 0, (const VkBufferMemoryBarrier*)DE_NULL, 1, &colorAttBarrier);
	}

	beginRenderPass(vk, *cmdBuf, *renderPass, *framebuffer, makeRect2D(0, 0, renderSize.x(), renderSize.y()), clearColor);

	vk.cmdBindPipeline(*cmdBuf, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipeline);
	{
		const VkDeviceSize bindingOffset = 0;
		vk.cmdBindVertexBuffers(*cmdBuf, 0u, 1u, &vertexBuffer.get(), &bindingOffset);
	}
	vk.cmdDraw(*cmdBuf, 3u, 1u, 0u, 0u);
	endRenderPass(vk, *cmdBuf);
	copyImageToBuffer(vk, *cmdBuf, *image, *readImageBuffer, renderSize);
	endCommandBuffer(vk, *cmdBuf);

	// Upload vertex data
	deMemcpy(vertexBufferMemory->getHostPtr(), &vertices[0], sizeof(vertices));
	flushAlloc(vk, vkDevice, *vertexBufferMemory);

	// Submit & wait for completion
	submitCommandsAndWait(vk, vkDevice, queue, cmdBuf.get());

	// Read results, render reference, compare
	{
		const tcu::TextureFormat			tcuFormat		= vk::mapVkFormat(colorFormat);
		const VkMappedMemoryRange			range			=
		{
			VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE,	// sType
			DE_NULL,								// pNext
			readImageBufferMemory->getMemory(),		// memory
			0,										// offset
			imageSizeBytes,							// size
		};
		const tcu::ConstPixelBufferAccess	resultAccess	(tcuFormat, renderSize.x(), renderSize.y(), 1, readImageBufferMemory->getHostPtr());

		VK_CHECK(vk.invalidateMappedMemoryRanges(vkDevice, 1u, &range));

		{
			tcu::TextureLevel	refImage		(tcuFormat, renderSize.x(), renderSize.y());
			const tcu::UVec4	threshold		(0u);
			const tcu::IVec3	posDeviation	(1,1,0);

			tcu::clear(refImage.getAccess(), clearColor);
			renderReferenceTriangle(refImage.getAccess(), vertices, context.getDeviceProperties().limits.subPixelPrecisionBits);

			if (tcu::intThresholdPositionDeviationCompare(context.getTestContext().getLog(),
														  "ComparisonResult",
														  "Image comparison result",
														  refImage.getAccess(),
														  resultAccess,
														  threshold,
														  posDeviation,
														  false,
														  tcu::COMPARE_LOG_RESULT))
				return tcu::TestStatus::pass("Rendering succeeded");
			else
				return tcu::TestStatus::fail("Image comparison failed");
		}
	}

	return tcu::TestStatus::pass("Rendering succeeded");
}

} // anonymous

tcu::TestCaseGroup* createSmokeTests (tcu::TestContext& testCtx)
{
	de::MovePtr<tcu::TestCaseGroup>	smokeTests	(new tcu::TestCaseGroup(testCtx, "smoke", "Smoke Tests"));

	addFunctionCase				(smokeTests.get(), "create_sampler",			"",	createSamplerTest);
	addFunctionCaseWithPrograms	(smokeTests.get(), "create_shader",				"", createShaderProgs,		createShaderModuleTest);
	addFunctionCaseWithPrograms	(smokeTests.get(), "triangle",					"", createTriangleProgs,	renderTriangleTest);
	addFunctionCaseWithPrograms	(smokeTests.get(), "asm_triangle",				"", createTriangleAsmProgs,	renderTriangleTest);
	addFunctionCaseWithPrograms	(smokeTests.get(), "asm_triangle_no_opname",	"", createProgsNoOpName,	renderTriangleTest);
	addFunctionCaseWithPrograms	(smokeTests.get(), "unused_resolve_attachment",	"", createTriangleProgs,	renderTriangleUnusedResolveAttachmentTest);

	return smokeTests.release();
}

} // api
} // vkt
