11e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski/*------------------------------------------------------------------------
21e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski * Vulkan Conformance Tests
31e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski * ------------------------
41e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski *
51e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski * Copyright (c) 2016 The Khronos Group Inc.
61e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski * Copyright (c) 2014 The Android Open Source Project
71e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski *
81e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski * Licensed under the Apache License, Version 2.0 (the "License");
91e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski * you may not use this file except in compliance with the License.
101e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski * You may obtain a copy of the License at
111e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski *
121e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski *      http://www.apache.org/licenses/LICENSE-2.0
131e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski *
141e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski * Unless required by applicable law or agreed to in writing, software
151e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski * distributed under the License is distributed on an "AS IS" BASIS,
161e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
171e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski * See the License for the specific language governing permissions and
181e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski * limitations under the License.
191e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski *
201e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski *//*!
211e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski * \file
221e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski * \brief Scissor multi viewport tests
231e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski *//*--------------------------------------------------------------------*/
241e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski
251e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski#include "vktFragmentOperationsScissorMultiViewportTests.hpp"
261e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski#include "vktTestCaseUtil.hpp"
271e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski#include "vktFragmentOperationsMakeUtil.hpp"
281e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski
291e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski#include "vkDefs.hpp"
301e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski#include "vkRefUtil.hpp"
311e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski#include "vkTypeUtil.hpp"
321e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski#include "vkMemUtil.hpp"
331e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski#include "vkPrograms.hpp"
341e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski#include "vkImageUtil.hpp"
351e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski#include "vkQueryUtil.hpp"
361e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski
371e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski#include "tcuTestLog.hpp"
381e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski#include "tcuVector.hpp"
391e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski#include "tcuImageCompare.hpp"
401e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski#include "tcuTextureUtil.hpp"
411e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski
421e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski#include "deUniquePtr.hpp"
431e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski#include "deMath.h"
441e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski
451e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowskinamespace vkt
461e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski{
471e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowskinamespace FragmentOperations
481e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski{
491e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowskiusing namespace vk;
501e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowskiusing de::UniquePtr;
511e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowskiusing de::MovePtr;
521e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowskiusing tcu::Vec4;
531e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowskiusing tcu::Vec2;
541e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowskiusing tcu::IVec2;
551e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowskiusing tcu::IVec4;
561e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski
571e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowskinamespace
581e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski{
591e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski
601e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowskienum Constants
611e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski{
621e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski	MIN_MAX_VIEWPORTS = 16,		//!< Minimum number of viewports for an implementation supporting multiViewport.
631e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski};
641e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski
651e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowskitemplate<typename T>
661e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowskiinline VkDeviceSize sizeInBytes(const std::vector<T>& vec)
671e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski{
681e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski	return vec.size() * sizeof(vec[0]);
691e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski}
701e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski
71367618221ecadfacdef5aa50110347bcb8cddef8Maciej JesionowskiVkImageCreateInfo makeImageCreateInfo (const VkFormat format, const IVec2& size, VkImageUsageFlags usage)
721e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski{
731e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski	const VkImageCreateInfo imageParams =
741e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski	{
751e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski		VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,			// VkStructureType			sType;
761e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski		DE_NULL,										// const void*				pNext;
771e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski		(VkImageCreateFlags)0,							// VkImageCreateFlags		flags;
781e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski		VK_IMAGE_TYPE_2D,								// VkImageType				imageType;
791e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski		format,											// VkFormat					format;
801e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski		makeExtent3D(size.x(), size.y(), 1),			// VkExtent3D				extent;
811e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski		1u,												// deUint32					mipLevels;
821e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski		1u,												// deUint32					arrayLayers;
831e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski		VK_SAMPLE_COUNT_1_BIT,							// VkSampleCountFlagBits	samples;
841e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski		VK_IMAGE_TILING_OPTIMAL,						// VkImageTiling			tiling;
851e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski		usage,											// VkImageUsageFlags		usage;
861e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski		VK_SHARING_MODE_EXCLUSIVE,						// VkSharingMode			sharingMode;
871e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski		0u,												// deUint32					queueFamilyIndexCount;
881e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski		DE_NULL,										// const deUint32*			pQueueFamilyIndices;
891e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski		VK_IMAGE_LAYOUT_UNDEFINED,						// VkImageLayout			initialLayout;
901e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski	};
91367618221ecadfacdef5aa50110347bcb8cddef8Maciej Jesionowski	return imageParams;
921e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski}
931e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski
941e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski//! A single-attachment, single-subpass render pass.
951e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej JesionowskiMove<VkRenderPass> makeRenderPass (const DeviceInterface&	vk,
961e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski								   const VkDevice			device,
971e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski								   const VkFormat			colorFormat)
981e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski{
991e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski	const VkAttachmentDescription colorAttachmentDescription =
1001e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski	{
1011e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski		(VkAttachmentDescriptionFlags)0,					// VkAttachmentDescriptionFlags		flags;
1021e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski		colorFormat,										// VkFormat							format;
1031e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski		VK_SAMPLE_COUNT_1_BIT,								// VkSampleCountFlagBits			samples;
1041e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski		VK_ATTACHMENT_LOAD_OP_CLEAR,						// VkAttachmentLoadOp				loadOp;
1051e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski		VK_ATTACHMENT_STORE_OP_STORE,						// VkAttachmentStoreOp				storeOp;
1061e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski		VK_ATTACHMENT_LOAD_OP_DONT_CARE,					// VkAttachmentLoadOp				stencilLoadOp;
1071e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski		VK_ATTACHMENT_STORE_OP_DONT_CARE,					// VkAttachmentStoreOp				stencilStoreOp;
1081e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski		VK_IMAGE_LAYOUT_UNDEFINED,							// VkImageLayout					initialLayout;
1091e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski		VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,			// VkImageLayout					finalLayout;
1101e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski	};
1111e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski
1121e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski	const VkAttachmentReference colorAttachmentRef =
1131e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski	{
1141e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski		0u,													// deUint32			attachment;
1151e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski		VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL			// VkImageLayout	layout;
1161e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski	};
1171e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski
1181e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski	const VkSubpassDescription subpassDescription =
1191e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski	{
1201e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski		(VkSubpassDescriptionFlags)0,						// VkSubpassDescriptionFlags		flags;
1211e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski		VK_PIPELINE_BIND_POINT_GRAPHICS,					// VkPipelineBindPoint				pipelineBindPoint;
1221e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski		0u,													// deUint32							inputAttachmentCount;
1231e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski		DE_NULL,											// const VkAttachmentReference*		pInputAttachments;
1241e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski		1u,													// deUint32							colorAttachmentCount;
1251e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski		&colorAttachmentRef,								// const VkAttachmentReference*		pColorAttachments;
1261e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski		DE_NULL,											// const VkAttachmentReference*		pResolveAttachments;
1271e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski		DE_NULL,											// const VkAttachmentReference*		pDepthStencilAttachment;
1281e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski		0u,													// deUint32							preserveAttachmentCount;
1291e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski		DE_NULL												// const deUint32*					pPreserveAttachments;
1301e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski	};
1311e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski
1321e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski	const VkRenderPassCreateInfo renderPassInfo =
1331e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski	{
1341e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski		VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,			// VkStructureType					sType;
1351e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski		DE_NULL,											// const void*						pNext;
1361e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski		(VkRenderPassCreateFlags)0,							// VkRenderPassCreateFlags			flags;
1371e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski		1u,													// deUint32							attachmentCount;
1381e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski		&colorAttachmentDescription,						// const VkAttachmentDescription*	pAttachments;
1391e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski		1u,													// deUint32							subpassCount;
1401e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski		&subpassDescription,								// const VkSubpassDescription*		pSubpasses;
1411e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski		0u,													// deUint32							dependencyCount;
1421e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski		DE_NULL												// const VkSubpassDependency*		pDependencies;
1431e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski	};
1441e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski
1451e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski	return createRenderPass(vk, device, &renderPassInfo);
1461e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski}
1471e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski
1481e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej JesionowskiMove<VkPipeline> makeGraphicsPipeline (const DeviceInterface&		vk,
1491e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski									   const VkDevice				device,
1501e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski									   const VkPipelineLayout		pipelineLayout,
1511e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski									   const VkRenderPass			renderPass,
1521e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski									   const VkShaderModule			vertexModule,
1531e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski									   const VkShaderModule			geometryModule,
1541e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski									   const VkShaderModule			fragmentModule,
1551e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski									   const IVec2					renderSize,
1561e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski									   const int					numViewports,
1571e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski									   const std::vector<IVec4>		scissors)
1581e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski{
1591e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski	const VkVertexInputBindingDescription vertexInputBindingDescription =
1601e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski	{
1611e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski		0u,								// uint32_t				binding;
1621e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski		sizeof(Vec4),					// uint32_t				stride;
1631e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski		VK_VERTEX_INPUT_RATE_VERTEX,	// VkVertexInputRate	inputRate;
1641e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski	};
1651e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski
1661e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski	const VkVertexInputAttributeDescription vertexInputAttributeDescriptions[] =
1671e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski	{
1681e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski		{
1691e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski			0u,									// uint32_t			location;
1701e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski			0u,									// uint32_t			binding;
1711e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski			VK_FORMAT_R32G32B32A32_SFLOAT,		// VkFormat			format;
1721e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski			0u,									// uint32_t			offset;
1731e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski		},
1741e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski	};
1751e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski
1761e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski	const VkPipelineVertexInputStateCreateInfo vertexInputStateInfo =
1771e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski	{
1781e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski		VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,		// VkStructureType                             sType;
1791e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski		DE_NULL,														// const void*                                 pNext;
1801e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski		(VkPipelineVertexInputStateCreateFlags)0,						// VkPipelineVertexInputStateCreateFlags       flags;
1811e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski		1u,																// uint32_t                                    vertexBindingDescriptionCount;
1821e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski		&vertexInputBindingDescription,									// const VkVertexInputBindingDescription*      pVertexBindingDescriptions;
1831e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski		DE_LENGTH_OF_ARRAY(vertexInputAttributeDescriptions),			// uint32_t                                    vertexAttributeDescriptionCount;
1841e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski		vertexInputAttributeDescriptions,								// const VkVertexInputAttributeDescription*    pVertexAttributeDescriptions;
1851e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski	};
1861e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski
1871e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski	const VkPipelineInputAssemblyStateCreateInfo pipelineInputAssemblyStateInfo =
1881e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski	{
1891e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski		VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,	// VkStructureType                             sType;
1901e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski		DE_NULL,														// const void*                                 pNext;
1911e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski		(VkPipelineInputAssemblyStateCreateFlags)0,						// VkPipelineInputAssemblyStateCreateFlags     flags;
1921e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski		VK_PRIMITIVE_TOPOLOGY_POINT_LIST,								// VkPrimitiveTopology                         topology;
1931e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski		VK_FALSE,														// VkBool32                                    primitiveRestartEnable;
1941e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski	};
1951e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski
1961e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski	const VkViewport defaultViewport = makeViewport(
1971e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski		0.0f, 0.0f,
1981e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski		static_cast<float>(renderSize.x()), static_cast<float>(renderSize.y()),
1991e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski		0.0f, 1.0f);
2001e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski	const std::vector<VkViewport> viewports(numViewports, defaultViewport);
2011e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski
2021e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski	DE_ASSERT(numViewports == static_cast<int>(scissors.size()));
2031e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski
2041e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski	std::vector<VkRect2D> rectScissors;
2051e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski	rectScissors.reserve(numViewports);
2061e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski
2071e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski	for (std::vector<IVec4>::const_iterator it = scissors.begin(); it != scissors.end(); ++it)
2081e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski	{
2091e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski		const VkRect2D rect =
2101e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski		{
2111e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski			makeOffset2D(it->x(), it->y()),
2121e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski			makeExtent2D(static_cast<deUint32>(it->z()), static_cast<deUint32>(it->w())),
2131e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski		};
2141e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski		rectScissors.push_back(rect);
2151e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski	}
2161e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski
2171e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski	const VkPipelineViewportStateCreateInfo pipelineViewportStateInfo =
2181e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski	{
2191e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski		VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO,			// VkStructureType                             sType;
2201e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski		DE_NULL,														// const void*                                 pNext;
2211e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski		(VkPipelineViewportStateCreateFlags)0,							// VkPipelineViewportStateCreateFlags          flags;
2221e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski		static_cast<deUint32>(numViewports),							// uint32_t                                    viewportCount;
2231e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski		&viewports[0],													// const VkViewport*                           pViewports;
2241e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski		static_cast<deUint32>(numViewports),							// uint32_t                                    scissorCount;
2251e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski		&rectScissors[0],												// const VkRect2D*                             pScissors;
2261e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski	};
2271e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski
2281e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski	const VkPipelineRasterizationStateCreateInfo pipelineRasterizationStateInfo =
2291e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski	{
2301e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski		VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO,		// VkStructureType                          sType;
2311e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski		DE_NULL,														// const void*                              pNext;
2321e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski		(VkPipelineRasterizationStateCreateFlags)0,						// VkPipelineRasterizationStateCreateFlags  flags;
2331e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski		VK_FALSE,														// VkBool32                                 depthClampEnable;
2341e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski		VK_FALSE,														// VkBool32                                 rasterizerDiscardEnable;
2351e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski		VK_POLYGON_MODE_FILL,											// VkPolygonMode							polygonMode;
2361e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski		VK_CULL_MODE_NONE,												// VkCullModeFlags							cullMode;
2371e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski		VK_FRONT_FACE_COUNTER_CLOCKWISE,								// VkFrontFace								frontFace;
2381e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski		VK_FALSE,														// VkBool32									depthBiasEnable;
2391e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski		0.0f,															// float									depthBiasConstantFactor;
2401e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski		0.0f,															// float									depthBiasClamp;
2411e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski		0.0f,															// float									depthBiasSlopeFactor;
2421e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski		1.0f,															// float									lineWidth;
2431e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski	};
2441e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski
2451e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski	const VkPipelineMultisampleStateCreateInfo pipelineMultisampleStateInfo =
2461e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski	{
2471e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski		VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,		// VkStructureType							sType;
2481e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski		DE_NULL,														// const void*								pNext;
2491e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski		(VkPipelineMultisampleStateCreateFlags)0,						// VkPipelineMultisampleStateCreateFlags	flags;
2501e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski		VK_SAMPLE_COUNT_1_BIT,											// VkSampleCountFlagBits					rasterizationSamples;
2511e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski		VK_FALSE,														// VkBool32									sampleShadingEnable;
2521e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski		0.0f,															// float									minSampleShading;
2531e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski		DE_NULL,														// const VkSampleMask*						pSampleMask;
2541e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski		VK_FALSE,														// VkBool32									alphaToCoverageEnable;
2551e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski		VK_FALSE														// VkBool32									alphaToOneEnable;
2561e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski	};
2571e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski
2581e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski	const VkStencilOpState stencilOpState = makeStencilOpState(
2591e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski		VK_STENCIL_OP_KEEP,				// stencil fail
2601e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski		VK_STENCIL_OP_KEEP,				// depth & stencil pass
2611e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski		VK_STENCIL_OP_KEEP,				// depth only fail
2621e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski		VK_COMPARE_OP_ALWAYS,			// compare op
2631e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski		0u,								// compare mask
2641e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski		0u,								// write mask
2651e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski		0u);							// reference
2661e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski
2671e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski	VkPipelineDepthStencilStateCreateInfo pipelineDepthStencilStateInfo =
2681e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski	{
2691e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski		VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO,		// VkStructureType							sType;
2701e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski		DE_NULL,														// const void*								pNext;
2711e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski		(VkPipelineDepthStencilStateCreateFlags)0,						// VkPipelineDepthStencilStateCreateFlags	flags;
2721e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski		VK_FALSE,														// VkBool32									depthTestEnable;
2731e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski		VK_FALSE,														// VkBool32									depthWriteEnable;
2741e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski		VK_COMPARE_OP_LESS,												// VkCompareOp								depthCompareOp;
2751e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski		VK_FALSE,														// VkBool32									depthBoundsTestEnable;
2761e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski		VK_FALSE,														// VkBool32									stencilTestEnable;
2771e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski		stencilOpState,													// VkStencilOpState							front;
2781e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski		stencilOpState,													// VkStencilOpState							back;
2791e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski		0.0f,															// float									minDepthBounds;
2801e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski		1.0f,															// float									maxDepthBounds;
2811e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski	};
2821e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski
2831e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski	const VkColorComponentFlags					colorComponentsAll					= VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT;
2841e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski	const VkPipelineColorBlendAttachmentState	pipelineColorBlendAttachmentState	=
2851e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski	{
2861e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski		VK_FALSE,						// VkBool32					blendEnable;
2871e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski		VK_BLEND_FACTOR_ONE,			// VkBlendFactor			srcColorBlendFactor;
2881e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski		VK_BLEND_FACTOR_ZERO,			// VkBlendFactor			dstColorBlendFactor;
2891e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski		VK_BLEND_OP_ADD,				// VkBlendOp				colorBlendOp;
2901e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski		VK_BLEND_FACTOR_ONE,			// VkBlendFactor			srcAlphaBlendFactor;
2911e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski		VK_BLEND_FACTOR_ZERO,			// VkBlendFactor			dstAlphaBlendFactor;
2921e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski		VK_BLEND_OP_ADD,				// VkBlendOp				alphaBlendOp;
2931e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski		colorComponentsAll,				// VkColorComponentFlags	colorWriteMask;
2941e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski	};
2951e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski
2961e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski	const VkPipelineColorBlendStateCreateInfo pipelineColorBlendStateInfo =
2971e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski	{
2981e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski		VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,		// VkStructureType								sType;
2991e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski		DE_NULL,														// const void*									pNext;
3001e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski		(VkPipelineColorBlendStateCreateFlags)0,						// VkPipelineColorBlendStateCreateFlags			flags;
3011e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski		VK_FALSE,														// VkBool32										logicOpEnable;
3021e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski		VK_LOGIC_OP_COPY,												// VkLogicOp									logicOp;
3031e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski		1u,																// deUint32										attachmentCount;
3041e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski		&pipelineColorBlendAttachmentState,								// const VkPipelineColorBlendAttachmentState*	pAttachments;
3051e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski		{ 0.0f, 0.0f, 0.0f, 0.0f },										// float										blendConstants[4];
3061e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski	};
3071e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski
3081e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski	const VkPipelineShaderStageCreateInfo pShaderStages[] =
3091e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski	{
3101e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski		{
3111e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski			VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,		// VkStructureType						sType;
3121e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski			DE_NULL,													// const void*							pNext;
3131e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski			(VkPipelineShaderStageCreateFlags)0,						// VkPipelineShaderStageCreateFlags		flags;
3141e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski			VK_SHADER_STAGE_VERTEX_BIT,									// VkShaderStageFlagBits				stage;
3151e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski			vertexModule,												// VkShaderModule						module;
3161e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski			"main",														// const char*							pName;
3171e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski			DE_NULL,													// const VkSpecializationInfo*			pSpecializationInfo;
3181e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski		},
3191e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski		{
3201e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski			VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,		// VkStructureType						sType;
3211e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski			DE_NULL,													// const void*							pNext;
3221e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski			(VkPipelineShaderStageCreateFlags)0,						// VkPipelineShaderStageCreateFlags		flags;
3231e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski			VK_SHADER_STAGE_GEOMETRY_BIT,								// VkShaderStageFlagBits				stage;
3241e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski			geometryModule,												// VkShaderModule						module;
3251e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski			"main",														// const char*							pName;
3261e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski			DE_NULL,													// const VkSpecializationInfo*			pSpecializationInfo;
3271e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski		},
3281e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski		{
3291e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski			VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,		// VkStructureType						sType;
3301e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski			DE_NULL,													// const void*							pNext;
3311e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski			(VkPipelineShaderStageCreateFlags)0,						// VkPipelineShaderStageCreateFlags		flags;
3321e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski			VK_SHADER_STAGE_FRAGMENT_BIT,								// VkShaderStageFlagBits				stage;
3331e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski			fragmentModule,												// VkShaderModule						module;
3341e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski			"main",														// const char*							pName;
3351e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski			DE_NULL,													// const VkSpecializationInfo*			pSpecializationInfo;
3361e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski		},
3371e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski	};
3381e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski
3391e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski	const VkGraphicsPipelineCreateInfo graphicsPipelineInfo =
3401e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski	{
3411e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski		VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,	// VkStructureType									sType;
3421e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski		DE_NULL,											// const void*										pNext;
3431e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski		(VkPipelineCreateFlags)0,							// VkPipelineCreateFlags							flags;
3441e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski		DE_LENGTH_OF_ARRAY(pShaderStages),					// deUint32											stageCount;
3451e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski		pShaderStages,										// const VkPipelineShaderStageCreateInfo*			pStages;
3461e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski		&vertexInputStateInfo,								// const VkPipelineVertexInputStateCreateInfo*		pVertexInputState;
3471e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski		&pipelineInputAssemblyStateInfo,					// const VkPipelineInputAssemblyStateCreateInfo*	pInputAssemblyState;
3481e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski		DE_NULL,											// const VkPipelineTessellationStateCreateInfo*		pTessellationState;
3491e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski		&pipelineViewportStateInfo,							// const VkPipelineViewportStateCreateInfo*			pViewportState;
3501e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski		&pipelineRasterizationStateInfo,					// const VkPipelineRasterizationStateCreateInfo*	pRasterizationState;
3511e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski		&pipelineMultisampleStateInfo,						// const VkPipelineMultisampleStateCreateInfo*		pMultisampleState;
3521e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski		&pipelineDepthStencilStateInfo,						// const VkPipelineDepthStencilStateCreateInfo*		pDepthStencilState;
3531e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski		&pipelineColorBlendStateInfo,						// const VkPipelineColorBlendStateCreateInfo*		pColorBlendState;
3541e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski		DE_NULL,											// const VkPipelineDynamicStateCreateInfo*			pDynamicState;
3551e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski		pipelineLayout,										// VkPipelineLayout									layout;
3561e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski		renderPass,											// VkRenderPass										renderPass;
3571e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski		0u,													// deUint32											subpass;
3581e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski		DE_NULL,											// VkPipeline										basePipelineHandle;
3591e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski		0,													// deInt32											basePipelineIndex;
3601e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski	};
3611e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski
3621e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski	return createGraphicsPipeline(vk, device, DE_NULL, &graphicsPipelineInfo);
3631e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski}
3641e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski
3651e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowskivoid zeroBuffer (const DeviceInterface& vk, const VkDevice device, const Allocation& alloc, const VkDeviceSize size)
3661e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski{
3671e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski	deMemset(alloc.getHostPtr(), 0, static_cast<std::size_t>(size));
3681e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski	flushMappedMemoryRange(vk, device, alloc.getMemory(), alloc.getOffset(), size);
3691e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski}
3701e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski
3711e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowskivoid requireFeatureMultiViewport (const InstanceInterface& vki, const VkPhysicalDevice physDevice)
3721e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski{
3731e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski	const VkPhysicalDeviceFeatures	features	= getPhysicalDeviceFeatures(vki, physDevice);
3741e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski	const VkPhysicalDeviceLimits	limits		= getPhysicalDeviceProperties(vki, physDevice).limits;
3751e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski
376f349df7acdb7a6bcdf8df2a6b5d5e7e06292b277Maciej Jesionowski	if (!features.geometryShader)
377f349df7acdb7a6bcdf8df2a6b5d5e7e06292b277Maciej Jesionowski		TCU_THROW(NotSupportedError, "Required feature is not supported: geometryShader");
378f349df7acdb7a6bcdf8df2a6b5d5e7e06292b277Maciej Jesionowski
3791e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski	if (!features.multiViewport)
3801e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski		TCU_THROW(NotSupportedError, "Required feature is not supported: multiViewport");
3811e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski
3821e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski	if (limits.maxViewports < MIN_MAX_VIEWPORTS)
3831e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski		TCU_THROW(NotSupportedError, "Implementation doesn't support minimum required number of viewports");
3841e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski}
3851e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski
3861e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowskistd::vector<IVec4> generateScissors (const int numScissors, const IVec2& renderSize)
3871e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski{
3881e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski	// Scissor rects will be arranged in a grid-like fashion.
3891e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski
3901e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski	const int numCols		= deCeilFloatToInt32(deFloatSqrt(static_cast<float>(numScissors)));
3911e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski	const int numRows		= deCeilFloatToInt32(static_cast<float>(numScissors) / static_cast<float>(numCols));
3921e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski	const int rectWidth		= renderSize.x() / numCols;
3931e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski	const int rectHeight	= renderSize.y() / numRows;
3941e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski
3951e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski	std::vector<IVec4> scissors;
3961e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski	scissors.reserve(numScissors);
3971e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski
3981e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski	int x = 0;
3991e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski	int y = 0;
4001e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski
4011e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski	for (int scissorNdx = 0; scissorNdx < numScissors; ++scissorNdx)
4021e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski	{
4031e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski		const bool nextRow = (scissorNdx != 0) && (scissorNdx % numCols == 0);
4041e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski		if (nextRow)
4051e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski		{
4061e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski			x  = 0;
4071e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski			y += rectHeight;
4081e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski		}
4091e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski
4101e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski		scissors.push_back(IVec4(x, y, rectWidth, rectHeight));
4111e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski
4121e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski		x += rectWidth;
4131e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski	}
4141e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski
4151e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski	return scissors;
4161e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski}
4171e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski
4181e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowskistd::vector<Vec4> generateColors (const int numColors)
4191e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski{
4201e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski	const Vec4 colors[] =
4211e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski	{
4221e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski		Vec4(0.18f, 0.42f, 0.17f, 1.0f),
4231e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski		Vec4(0.29f, 0.62f, 0.28f, 1.0f),
4241e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski		Vec4(0.59f, 0.84f, 0.44f, 1.0f),
4251e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski		Vec4(0.96f, 0.95f, 0.72f, 1.0f),
4261e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski		Vec4(0.94f, 0.55f, 0.39f, 1.0f),
4271e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski		Vec4(0.82f, 0.19f, 0.12f, 1.0f),
4281e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski		Vec4(0.46f, 0.15f, 0.26f, 1.0f),
4291e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski		Vec4(0.24f, 0.14f, 0.24f, 1.0f),
4301e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski		Vec4(0.49f, 0.31f, 0.26f, 1.0f),
4311e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski		Vec4(0.78f, 0.52f, 0.33f, 1.0f),
4321e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski		Vec4(0.94f, 0.82f, 0.31f, 1.0f),
4331e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski		Vec4(0.98f, 0.65f, 0.30f, 1.0f),
4341e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski		Vec4(0.22f, 0.65f, 0.53f, 1.0f),
4351e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski		Vec4(0.67f, 0.81f, 0.91f, 1.0f),
4361e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski		Vec4(0.43f, 0.44f, 0.75f, 1.0f),
4371e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski		Vec4(0.26f, 0.24f, 0.48f, 1.0f),
4381e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski	};
4391e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski
4401e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski	DE_ASSERT(numColors <= DE_LENGTH_OF_ARRAY(colors));
4411e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski
4421e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski	return std::vector<Vec4>(colors, colors + numColors);
4431e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski}
4441e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski
4451e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski//! Renders a colorful grid of rectangles.
4461e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowskitcu::TextureLevel generateReferenceImage (const tcu::TextureFormat	format,
4471e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski										  const IVec2&				renderSize,
4481e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski										  const Vec4&				clearColor,
4491e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski										  const std::vector<IVec4>&	scissors,
4501e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski										  const std::vector<Vec4>&	scissorColors)
4511e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski{
4521e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski	DE_ASSERT(scissors.size() == scissorColors.size());
4531e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski
4541e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski	tcu::TextureLevel image(format, renderSize.x(), renderSize.y());
4551e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski	tcu::clear(image.getAccess(), clearColor);
4561e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski
4571e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski	for (std::size_t i = 0; i < scissors.size(); ++i)
4581e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski	{
4591e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski		tcu::clear(
4601e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski			tcu::getSubregion(image.getAccess(), scissors[i].x(), scissors[i].y(), scissors[i].z(), scissors[i].w()),
4611e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski			scissorColors[i]);
4621e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski	}
4631e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski
4641e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski	return image;
4651e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski}
4661e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski
4671e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowskivoid initPrograms (SourceCollections& programCollection, const int numViewports)
4681e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski{
4691e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski	DE_UNREF(numViewports);
4701e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski
4711e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski	// Vertex shader
4721e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski	{
4731e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski		std::ostringstream src;
4741e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski		src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
4751e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski			<< "\n"
4761e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski			<< "layout(location = 0) in  vec4 in_color;\n"
4771e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski			<< "layout(location = 0) out vec4 out_color;\n"
4781e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski			<< "\n"
4791e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski			<< "void main(void)\n"
4801e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski			<< "{\n"
4811e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski			<< "    out_color = in_color;\n"
4821e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski			<< "}\n";
4831e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski
4841e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski		programCollection.glslSources.add("vert") << glu::VertexSource(src.str());
4851e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski	}
4861e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski
4871e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski	// Geometry shader
4881e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski	{
4891e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski		// Each input point generates a fullscreen quad.
4901e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski
4911e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski		std::ostringstream src;
4921e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski		src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
4931e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski			<< "\n"
4941e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski			<< "layout(points) in;\n"
4951e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski			<< "layout(triangle_strip, max_vertices=4) out;\n"
4961e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski			<< "\n"
4971e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski			<< "out gl_PerVertex {\n"
4981e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski			<< "    vec4 gl_Position;\n"
4991e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski			<< "};\n"
5001e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski			<< "\n"
5011e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski			<< "layout(location = 0) in  vec4 in_color[];\n"
5021e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski			<< "layout(location = 0) out vec4 out_color;\n"
5031e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski			<< "\n"
5041e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski			<< "void main(void)\n"
5051e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski			<< "{\n"
5061e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski			<< "    gl_ViewportIndex = gl_PrimitiveIDIn;\n"
5071e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski			<< "    gl_Position      = vec4(-1.0, -1.0, 0.0, 1.0);\n"
5081e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski			<< "    out_color        = in_color[0];\n"
5091e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski			<< "    EmitVertex();"
5101e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski			<< "\n"
5111e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski			<< "    gl_ViewportIndex = gl_PrimitiveIDIn;\n"
5121e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski			<< "    gl_Position      = vec4(-1.0, 1.0, 0.0, 1.0);\n"
5131e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski			<< "    out_color        = in_color[0];\n"
5141e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski			<< "    EmitVertex();"
5151e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski			<< "\n"
5161e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski			<< "    gl_ViewportIndex = gl_PrimitiveIDIn;\n"
5171e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski			<< "    gl_Position      = vec4(1.0, -1.0, 0.0, 1.0);\n"
5181e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski			<< "    out_color        = in_color[0];\n"
5191e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski			<< "    EmitVertex();"
5201e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski			<< "\n"
5211e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski			<< "    gl_ViewportIndex = gl_PrimitiveIDIn;\n"
5221e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski			<< "    gl_Position      = vec4(1.0, 1.0, 0.0, 1.0);\n"
5231e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski			<< "    out_color        = in_color[0];\n"
5241e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski			<< "    EmitVertex();"
5251e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski			<< "}\n";
5261e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski
5271e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski		programCollection.glslSources.add("geom") << glu::GeometrySource(src.str());
5281e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski	}
5291e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski
5301e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski	// Fragment shader
5311e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski	{
5321e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski		std::ostringstream src;
5331e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski		src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
5341e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski			<< "\n"
5351e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski			<< "layout(location = 0) in  vec4 in_color;\n"
5361e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski			<< "layout(location = 0) out vec4 out_color;\n"
5371e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski			<< "\n"
5381e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski			<< "void main(void)\n"
5391e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski			<< "{\n"
5401e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski			<< "    out_color = in_color;\n"
5411e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski			<< "}\n";
5421e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski
5431e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski		programCollection.glslSources.add("frag") << glu::FragmentSource(src.str());
5441e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski	}
5451e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski}
5461e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski
5471e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowskiclass ScissorRenderer
5481e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski{
5491e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowskipublic:
5501e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski	ScissorRenderer (Context&					context,
5511e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski					 const IVec2&				renderSize,
5521e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski					 const int					numViewports,
5531e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski					 const std::vector<IVec4>&	scissors,
5541e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski					 const VkFormat				colorFormat,
5551e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski					 const Vec4&				clearColor,
5561e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski					 const std::vector<Vec4>&	vertices)
5571e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski		: m_renderSize				(renderSize)
5581e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski		, m_colorFormat				(colorFormat)
5591e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski		, m_colorSubresourceRange	(makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u))
5601e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski		, m_clearColor				(clearColor)
5611e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski		, m_numViewports			(numViewports)
5621e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski		, m_vertexBufferSize		(sizeInBytes(vertices))
5631e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski	{
5641e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski		const DeviceInterface&		vk					= context.getDeviceInterface();
5651e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski		const VkDevice				device				= context.getDevice();
5661e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski		const deUint32				queueFamilyIndex	= context.getUniversalQueueFamilyIndex();
5671e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski		Allocator&					allocator			= context.getDefaultAllocator();
5681e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski
569367618221ecadfacdef5aa50110347bcb8cddef8Maciej Jesionowski		m_colorImage		= makeImage				(vk, device, makeImageCreateInfo(m_colorFormat, m_renderSize, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT));
5701e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski		m_colorImageAlloc	= bindImage				(vk, device, allocator, *m_colorImage, MemoryRequirement::Any);
5711e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski		m_colorAttachment	= makeImageView			(vk, device, *m_colorImage, VK_IMAGE_VIEW_TYPE_2D, m_colorFormat, m_colorSubresourceRange);
5721e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski
573367618221ecadfacdef5aa50110347bcb8cddef8Maciej Jesionowski		m_vertexBuffer		= makeBuffer			(vk, device, makeBufferCreateInfo(m_vertexBufferSize, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT));
5741e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski		m_vertexBufferAlloc	= bindBuffer			(vk, device, allocator, *m_vertexBuffer, MemoryRequirement::HostVisible);
5751e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski
5761e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski		{
5771e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski			deMemcpy(m_vertexBufferAlloc->getHostPtr(), &vertices[0], static_cast<std::size_t>(m_vertexBufferSize));
5781e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski			flushMappedMemoryRange(vk, device, m_vertexBufferAlloc->getMemory(), m_vertexBufferAlloc->getOffset(), m_vertexBufferSize);
5791e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski		}
5801e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski
5811e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski		m_vertexModule		= createShaderModule	(vk, device, context.getBinaryCollection().get("vert"), 0u);
5821e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski		m_geometryModule	= createShaderModule	(vk, device, context.getBinaryCollection().get("geom"), 0u);
5831e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski		m_fragmentModule	= createShaderModule	(vk, device, context.getBinaryCollection().get("frag"), 0u);
5841e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski		m_renderPass		= makeRenderPass		(vk, device, m_colorFormat);
5851e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski		m_framebuffer		= makeFramebuffer		(vk, device, *m_renderPass, 1u, &m_colorAttachment.get(),
5861e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski													 static_cast<deUint32>(m_renderSize.x()),  static_cast<deUint32>(m_renderSize.y()));
5871e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski		m_pipelineLayout	= makePipelineLayout	(vk, device);
5881e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski		m_pipeline			= makeGraphicsPipeline	(vk, device, *m_pipelineLayout, *m_renderPass, *m_vertexModule, *m_geometryModule, *m_fragmentModule,
5891e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski													 m_renderSize, m_numViewports, scissors);
59055dd4426673bd260dde56addcfea802f21c31304Mika Isojärvi		m_cmdPool			= createCommandPool		(vk, device, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, queueFamilyIndex);
59155dd4426673bd260dde56addcfea802f21c31304Mika Isojärvi		m_cmdBuffer			= allocateCommandBuffer	(vk, device, *m_cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
5921e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski	}
5931e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski
5941e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski	void draw (Context& context, const VkBuffer colorBuffer) const
5951e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski	{
5961e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski		const DeviceInterface&		vk			= context.getDeviceInterface();
5971e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski		const VkDevice				device		= context.getDevice();
5981e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski		const VkQueue				queue		= context.getUniversalQueue();
5991e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski
6001e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski		beginCommandBuffer(vk, *m_cmdBuffer);
6011e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski
6021e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski		const VkClearValue			clearValue	= makeClearValueColor(m_clearColor);
6031e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski		const VkRect2D				renderArea	=
6041e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski		{
6051e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski			makeOffset2D(0, 0),
6061e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski			makeExtent2D(m_renderSize.x(), m_renderSize.y()),
6071e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski		};
6081e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski		const VkRenderPassBeginInfo renderPassBeginInfo =
6091e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski		{
6101e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski			VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,		// VkStructureType         sType;
6111e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski			DE_NULL,										// const void*             pNext;
6121e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski			*m_renderPass,									// VkRenderPass            renderPass;
6131e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski			*m_framebuffer,									// VkFramebuffer           framebuffer;
6141e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski			renderArea,										// VkRect2D                renderArea;
6151e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski			1u,												// uint32_t                clearValueCount;
6161e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski			&clearValue,									// const VkClearValue*     pClearValues;
6171e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski		};
6181e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski		vk.cmdBeginRenderPass(*m_cmdBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
6191e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski
6201e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski		vk.cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipeline);
6211e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski		{
6221e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski			const VkDeviceSize vertexBufferOffset = 0ull;
6231e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski			vk.cmdBindVertexBuffers(*m_cmdBuffer, 0u, 1u, &m_vertexBuffer.get(), &vertexBufferOffset);
6241e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski		}
6251e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski		vk.cmdDraw(*m_cmdBuffer, static_cast<deUint32>(m_numViewports), 1u, 0u, 0u);	// one vertex per viewport
6261e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski		vk.cmdEndRenderPass(*m_cmdBuffer);
6271e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski
6281e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski		// Prepare color image for copy
6291e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski		{
6301e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski			const VkImageMemoryBarrier barriers[] =
6311e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski			{
6321e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski				{
6331e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski					VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,						// VkStructureType			sType;
6341e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski					DE_NULL,													// const void*				pNext;
6351e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski					VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,						// VkAccessFlags			outputMask;
6361e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski					VK_ACCESS_TRANSFER_READ_BIT,								// VkAccessFlags			inputMask;
6371e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski					VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,					// VkImageLayout			oldLayout;
6381e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski					VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,						// VkImageLayout			newLayout;
6391e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski					VK_QUEUE_FAMILY_IGNORED,									// deUint32					srcQueueFamilyIndex;
6401e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski					VK_QUEUE_FAMILY_IGNORED,									// deUint32					destQueueFamilyIndex;
6411e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski					*m_colorImage,												// VkImage					image;
6421e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski					m_colorSubresourceRange,									// VkImageSubresourceRange	subresourceRange;
6431e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski				},
6441e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski			};
6451e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski
6461e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski			vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0u,
6471e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski				0u, DE_NULL, 0u, DE_NULL, DE_LENGTH_OF_ARRAY(barriers), barriers);
6481e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski		}
6491e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski		// Color image -> host buffer
6501e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski		{
6511e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski			const VkBufferImageCopy region =
6521e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski			{
6531e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski				0ull,																		// VkDeviceSize                bufferOffset;
6541e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski				0u,																			// uint32_t                    bufferRowLength;
6551e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski				0u,																			// uint32_t                    bufferImageHeight;
6561e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski				makeImageSubresourceLayers(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 0u, 1u),			// VkImageSubresourceLayers    imageSubresource;
6571e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski				makeOffset3D(0, 0, 0),														// VkOffset3D                  imageOffset;
6581e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski				makeExtent3D(m_renderSize.x(), m_renderSize.y(), 1u),						// VkExtent3D                  imageExtent;
6591e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski			};
6601e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski
6611e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski			vk.cmdCopyImageToBuffer(*m_cmdBuffer, *m_colorImage, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, colorBuffer, 1u, &region);
6621e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski		}
6631e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski		// Buffer write barrier
6641e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski		{
6651e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski			const VkBufferMemoryBarrier barriers[] =
6661e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski			{
6671e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski				{
6681e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski					VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,		// VkStructureType    sType;
6691e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski					DE_NULL,										// const void*        pNext;
6701e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski					VK_ACCESS_TRANSFER_WRITE_BIT,					// VkAccessFlags      srcAccessMask;
6711e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski					VK_ACCESS_HOST_READ_BIT,						// VkAccessFlags      dstAccessMask;
6721e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski					VK_QUEUE_FAMILY_IGNORED,						// uint32_t           srcQueueFamilyIndex;
6731e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski					VK_QUEUE_FAMILY_IGNORED,						// uint32_t           dstQueueFamilyIndex;
6741e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski					colorBuffer,									// VkBuffer           buffer;
6751e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski					0ull,											// VkDeviceSize       offset;
6761e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski					VK_WHOLE_SIZE,									// VkDeviceSize       size;
6771e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski				},
6781e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski			};
6791e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski
6801e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski			vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, 0u,
6811e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski				0u, DE_NULL, DE_LENGTH_OF_ARRAY(barriers), barriers, DE_NULL, 0u);
6821e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski		}
6831e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski
6841e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski		VK_CHECK(vk.endCommandBuffer(*m_cmdBuffer));
6851e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski		submitCommandsAndWait(vk, device, queue, *m_cmdBuffer);
6861e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski	}
6871e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski
6881e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowskiprivate:
6891e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski	const IVec2						m_renderSize;
6901e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski	const VkFormat					m_colorFormat;
6911e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski	const VkImageSubresourceRange	m_colorSubresourceRange;
6921e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski	const Vec4						m_clearColor;
6931e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski	const int						m_numViewports;
6941e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski	const VkDeviceSize				m_vertexBufferSize;
6951e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski
6961e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski	Move<VkImage>					m_colorImage;
6971e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski	MovePtr<Allocation>				m_colorImageAlloc;
6981e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski	Move<VkImageView>				m_colorAttachment;
6991e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski	Move<VkBuffer>					m_vertexBuffer;
7001e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski	MovePtr<Allocation>				m_vertexBufferAlloc;
7011e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski	Move<VkShaderModule>			m_vertexModule;
7021e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski	Move<VkShaderModule>			m_geometryModule;
7031e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski	Move<VkShaderModule>			m_fragmentModule;
7041e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski	Move<VkRenderPass>				m_renderPass;
7051e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski	Move<VkFramebuffer>				m_framebuffer;
7061e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski	Move<VkPipelineLayout>			m_pipelineLayout;
7071e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski	Move<VkPipeline>				m_pipeline;
7081e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski	Move<VkCommandPool>				m_cmdPool;
7091e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski	Move<VkCommandBuffer>			m_cmdBuffer;
7101e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski
7111e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski	// "deleted"
7121e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski						ScissorRenderer	(const ScissorRenderer&);
7131e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski	ScissorRenderer&	operator=		(const ScissorRenderer&);
7141e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski};
7151e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski
7161e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowskitcu::TestStatus test (Context& context, const int numViewports)
7171e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski{
7181e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski	requireFeatureMultiViewport(context.getInstanceInterface(), context.getPhysicalDevice());
7191e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski
7201e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski	const DeviceInterface&			vk					= context.getDeviceInterface();
7211e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski	const VkDevice					device				= context.getDevice();
7221e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski	Allocator&						allocator			= context.getDefaultAllocator();
7231e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski
7241e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski	const IVec2						renderSize			(128, 128);
7251e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski	const VkFormat					colorFormat			= VK_FORMAT_R8G8B8A8_UNORM;
7261e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski	const Vec4						clearColor			(0.5f, 0.5f, 0.5f, 1.0f);
7271e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski	const std::vector<Vec4>			vertexColors		= generateColors(numViewports);
7281e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski	const std::vector<IVec4>		scissors			= generateScissors(numViewports, renderSize);
7291e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski
7301e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski	const VkDeviceSize				colorBufferSize		= renderSize.x() * renderSize.y() * tcu::getPixelSize(mapVkFormat(colorFormat));
731367618221ecadfacdef5aa50110347bcb8cddef8Maciej Jesionowski	const Unique<VkBuffer>			colorBuffer			(makeBuffer(vk, device, makeBufferCreateInfo(colorBufferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT)));
7321e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski	const UniquePtr<Allocation>		colorBufferAlloc	(bindBuffer(vk, device, allocator, *colorBuffer, MemoryRequirement::HostVisible));
7331e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski
7341e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski	zeroBuffer(vk, device, *colorBufferAlloc, colorBufferSize);
7351e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski
7361e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski	{
7371e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski		context.getTestContext().getLog()
7381e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski			<< tcu::TestLog::Message << "Rendering a colorful grid of " << numViewports << " rectangle(s)." << tcu::TestLog::EndMessage
7391e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski			<< tcu::TestLog::Message << "Not covered area will be filled with a gray color." << tcu::TestLog::EndMessage;
7401e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski	}
7411e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski
7421e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski	// Draw
7431e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski	{
7441e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski		const ScissorRenderer renderer (context, renderSize, numViewports, scissors, colorFormat, clearColor, vertexColors);
7451e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski		renderer.draw(context, *colorBuffer);
7461e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski	}
7471e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski
7481e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski	// Log image
7491e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski	{
7501e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski		invalidateMappedMemoryRange(vk, device, colorBufferAlloc->getMemory(), 0ull, colorBufferSize);
7511e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski
7521e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski		const tcu::ConstPixelBufferAccess	resultImage		(mapVkFormat(colorFormat), renderSize.x(), renderSize.y(), 1u, colorBufferAlloc->getHostPtr());
7531e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski		const tcu::TextureLevel				referenceImage	= generateReferenceImage(mapVkFormat(colorFormat), renderSize, clearColor, scissors, vertexColors);
7541e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski
7551e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski		// Images should now match.
7561e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski		if (!tcu::floatThresholdCompare(context.getTestContext().getLog(), "color", "Image compare", referenceImage.getAccess(), resultImage, Vec4(0.02f), tcu::COMPARE_LOG_RESULT))
7571e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski			return tcu::TestStatus::fail("Rendered image is not correct");
7581e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski	}
7591e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski
7601e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski	return tcu::TestStatus::pass("OK");
7611e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski}
7621e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski
7631e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski} // anonymous
7641e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski
7651e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowskitcu::TestCaseGroup* createScissorMultiViewportTests	(tcu::TestContext& testCtx)
7661e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski{
7671e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski	MovePtr<tcu::TestCaseGroup> group (new tcu::TestCaseGroup(testCtx, "multi_viewport", ""));
7681e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski
7691e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski	for (int numViewports = 1; numViewports <= MIN_MAX_VIEWPORTS; ++numViewports)
7701e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski		addFunctionCaseWithPrograms(group.get(), "scissor_" + de::toString(numViewports), "", initPrograms, test, numViewports);
7711e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski
7721e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski	return group.release();
7731e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski}
7741e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski
7751e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski} // FragmentOperations
7761e18e8aea10cda4ca89348f7a9bba92efa58ce73Maciej Jesionowski} // vkt
777