1abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski/*------------------------------------------------------------------------
2abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski * Vulkan Conformance Tests
3abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski * ------------------------
4abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski *
5abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski * Copyright (c) 2014 The Android Open Source Project
6abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski * Copyright (c) 2016 The Khronos Group Inc.
7abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski *
8abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski * Licensed under the Apache License, Version 2.0 (the "License");
9abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski * you may not use this file except in compliance with the License.
10abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski * You may obtain a copy of the License at
11abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski *
12abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski *      http://www.apache.org/licenses/LICENSE-2.0
13abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski *
14abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski * Unless required by applicable law or agreed to in writing, software
15abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski * distributed under the License is distributed on an "AS IS" BASIS,
16abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski * See the License for the specific language governing permissions and
18abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski * limitations under the License.
19abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski *
20abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski *//*!
21abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski * \file
22abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski * \brief Tessellation Utilities
23abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski *//*--------------------------------------------------------------------*/
24abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
25abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski#include "vktTessellationUtil.hpp"
26abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski#include "vkTypeUtil.hpp"
27abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski#include "deMath.h"
28abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
29abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowskinamespace vkt
30abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski{
31abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowskinamespace tessellation
32abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski{
33abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
34abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowskiusing namespace vk;
35abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
36abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej JesionowskiVkBufferCreateInfo makeBufferCreateInfo (const VkDeviceSize			bufferSize,
37abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski										 const VkBufferUsageFlags	usage)
38abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski{
39abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	const VkBufferCreateInfo bufferCreateInfo =
40abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	{
41abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,	// VkStructureType		sType;
42abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		DE_NULL,								// const void*			pNext;
43abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		(VkBufferCreateFlags)0,					// VkBufferCreateFlags	flags;
44abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		bufferSize,								// VkDeviceSize			size;
45abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		usage,									// VkBufferUsageFlags	usage;
46abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		VK_SHARING_MODE_EXCLUSIVE,				// VkSharingMode		sharingMode;
47abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		0u,										// deUint32				queueFamilyIndexCount;
48abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		DE_NULL,								// const deUint32*		pQueueFamilyIndices;
49abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	};
50abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	return bufferCreateInfo;
51abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski}
52abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
53abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej JesionowskiVkBufferMemoryBarrier makeBufferMemoryBarrier (const VkAccessFlags	srcAccessMask,
54abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski											   const VkAccessFlags	dstAccessMask,
55abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski											   const VkBuffer		buffer,
56abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski											   const VkDeviceSize	offset,
57abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski											   const VkDeviceSize	bufferSizeBytes)
58abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski{
59abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	const VkBufferMemoryBarrier barrier =
60abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	{
61abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,	// VkStructureType	sType;
62abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		DE_NULL,									// const void*		pNext;
63abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		srcAccessMask,								// VkAccessFlags	srcAccessMask;
64abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		dstAccessMask,								// VkAccessFlags	dstAccessMask;
65abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		VK_QUEUE_FAMILY_IGNORED,					// deUint32			srcQueueFamilyIndex;
66abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		VK_QUEUE_FAMILY_IGNORED,					// deUint32			destQueueFamilyIndex;
67abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		buffer,										// VkBuffer			buffer;
68abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		offset,										// VkDeviceSize		offset;
69abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		bufferSizeBytes,							// VkDeviceSize		size;
70abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	};
71abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	return barrier;
72abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski}
73abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
74abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej JesionowskiVkImageMemoryBarrier makeImageMemoryBarrier	(const VkAccessFlags			srcAccessMask,
75abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski											 const VkAccessFlags			dstAccessMask,
76abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski											 const VkImageLayout			oldLayout,
77abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski											 const VkImageLayout			newLayout,
78abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski											 const VkImage					image,
79abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski											 const VkImageSubresourceRange	subresourceRange)
80abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski{
81abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	const VkImageMemoryBarrier barrier =
82abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	{
83abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,			// VkStructureType			sType;
84abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		DE_NULL,										// const void*				pNext;
85abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		srcAccessMask,									// VkAccessFlags			outputMask;
86abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		dstAccessMask,									// VkAccessFlags			inputMask;
87abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		oldLayout,										// VkImageLayout			oldLayout;
88abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		newLayout,										// VkImageLayout			newLayout;
89abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		VK_QUEUE_FAMILY_IGNORED,						// deUint32					srcQueueFamilyIndex;
90abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		VK_QUEUE_FAMILY_IGNORED,						// deUint32					destQueueFamilyIndex;
91abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		image,											// VkImage					image;
92abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		subresourceRange,								// VkImageSubresourceRange	subresourceRange;
93abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	};
94abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	return barrier;
95abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski}
96abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
97abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej JesionowskiMove<VkCommandPool> makeCommandPool (const DeviceInterface& vk, const VkDevice device, const deUint32 queueFamilyIndex)
98abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski{
99abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	const VkCommandPoolCreateInfo info =
100abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	{
101abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,			// VkStructureType			sType;
102abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		DE_NULL,											// const void*				pNext;
103abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT,	// VkCommandPoolCreateFlags	flags;
104abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		queueFamilyIndex,									// deUint32					queueFamilyIndex;
105abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	};
106abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	return createCommandPool(vk, device, &info);
107abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski}
108abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
109abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej JesionowskiMove<VkCommandBuffer> makeCommandBuffer (const DeviceInterface& vk, const VkDevice device, const VkCommandPool commandPool)
110abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski{
111abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	const VkCommandBufferAllocateInfo info =
112abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	{
113abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,		// VkStructureType		sType;
114abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		DE_NULL,											// const void*			pNext;
115abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		commandPool,										// VkCommandPool		commandPool;
116abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		VK_COMMAND_BUFFER_LEVEL_PRIMARY,					// VkCommandBufferLevel	level;
117abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		1u,													// deUint32				commandBufferCount;
118abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	};
119abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	return allocateCommandBuffer(vk, device, &info);
120abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski}
121abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
122abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej JesionowskiMove<VkDescriptorSet> makeDescriptorSet (const DeviceInterface&			vk,
123abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski										 const VkDevice					device,
124abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski										 const VkDescriptorPool			descriptorPool,
125abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski										 const VkDescriptorSetLayout	setLayout)
126abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski{
127abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	const VkDescriptorSetAllocateInfo info =
128abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	{
129abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,		// VkStructureType				sType;
130abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		DE_NULL,											// const void*					pNext;
131abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		descriptorPool,										// VkDescriptorPool				descriptorPool;
132abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		1u,													// deUint32						descriptorSetCount;
133abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		&setLayout,											// const VkDescriptorSetLayout*	pSetLayouts;
134abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	};
135abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	return allocateDescriptorSet(vk, device, &info);
136abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski}
137abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
138abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej JesionowskiMove<VkPipelineLayout> makePipelineLayout (const DeviceInterface&		vk,
139abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski										   const VkDevice				device,
140abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski										   const VkDescriptorSetLayout	descriptorSetLayout)
141abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski{
142abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	const VkPipelineLayoutCreateInfo info =
143abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	{
144abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,		// VkStructureType				sType;
145abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		DE_NULL,											// const void*					pNext;
146abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		(VkPipelineLayoutCreateFlags)0,						// VkPipelineLayoutCreateFlags	flags;
147abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		1u,													// deUint32						setLayoutCount;
148abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		&descriptorSetLayout,								// const VkDescriptorSetLayout*	pSetLayouts;
149abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		0u,													// deUint32						pushConstantRangeCount;
150abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		DE_NULL,											// const VkPushConstantRange*	pPushConstantRanges;
151abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	};
152abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	return createPipelineLayout(vk, device, &info);
153abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski}
154abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
155abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej JesionowskiMove<VkPipelineLayout> makePipelineLayoutWithoutDescriptors (const DeviceInterface&		vk,
156abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski															 const VkDevice				device)
157abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski{
158abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	const VkPipelineLayoutCreateInfo info =
159abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	{
160abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,		// VkStructureType				sType;
161abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		DE_NULL,											// const void*					pNext;
162abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		(VkPipelineLayoutCreateFlags)0,						// VkPipelineLayoutCreateFlags	flags;
163abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		0u,													// deUint32						setLayoutCount;
164abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		DE_NULL,											// const VkDescriptorSetLayout*	pSetLayouts;
165abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		0u,													// deUint32						pushConstantRangeCount;
166abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		DE_NULL,											// const VkPushConstantRange*	pPushConstantRanges;
167abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	};
168abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	return createPipelineLayout(vk, device, &info);
169abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski}
170abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
171abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej JesionowskiMove<VkPipeline> makeComputePipeline (const DeviceInterface&		vk,
172abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski									  const VkDevice				device,
173abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski									  const VkPipelineLayout		pipelineLayout,
174abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski									  const VkShaderModule			shaderModule,
175abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski									  const VkSpecializationInfo*	specInfo)
176abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski{
177abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	const VkPipelineShaderStageCreateInfo shaderStageInfo =
178abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	{
179abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,	// VkStructureType					sType;
180abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		DE_NULL,												// const void*						pNext;
181abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		(VkPipelineShaderStageCreateFlags)0,					// VkPipelineShaderStageCreateFlags	flags;
182abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		VK_SHADER_STAGE_COMPUTE_BIT,							// VkShaderStageFlagBits			stage;
183abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		shaderModule,											// VkShaderModule					module;
184abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		"main",													// const char*						pName;
185abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		specInfo,												// const VkSpecializationInfo*		pSpecializationInfo;
186abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	};
187abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	const VkComputePipelineCreateInfo pipelineInfo =
188abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	{
189abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO,		// VkStructureType					sType;
190abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		DE_NULL,											// const void*						pNext;
191abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		(VkPipelineCreateFlags)0,							// VkPipelineCreateFlags			flags;
192abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		shaderStageInfo,									// VkPipelineShaderStageCreateInfo	stage;
193abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		pipelineLayout,										// VkPipelineLayout					layout;
194abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		DE_NULL,											// VkPipeline						basePipelineHandle;
195abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		0,													// deInt32							basePipelineIndex;
196abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	};
197abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	return createComputePipeline(vk, device, DE_NULL , &pipelineInfo);
198abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski}
199abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
200abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej JesionowskiVkImageCreateInfo makeImageCreateInfo (const tcu::IVec2& size, const VkFormat format, const VkImageUsageFlags usage, const deUint32 numArrayLayers)
201abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski{
202abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	const VkImageCreateInfo imageInfo =
203abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	{
204abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,		// VkStructureType          sType;
205abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		DE_NULL,									// const void*              pNext;
206abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		(VkImageCreateFlags)0,						// VkImageCreateFlags       flags;
207abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		VK_IMAGE_TYPE_2D,							// VkImageType              imageType;
208abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		format,										// VkFormat                 format;
209abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		makeExtent3D(size.x(), size.y(), 1),		// VkExtent3D               extent;
210abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		1u,											// uint32_t                 mipLevels;
211abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		numArrayLayers,								// uint32_t                 arrayLayers;
212abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		VK_SAMPLE_COUNT_1_BIT,						// VkSampleCountFlagBits    samples;
213abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		VK_IMAGE_TILING_OPTIMAL,					// VkImageTiling            tiling;
214abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		usage,										// VkImageUsageFlags        usage;
215abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		VK_SHARING_MODE_EXCLUSIVE,					// VkSharingMode            sharingMode;
216abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		0u,											// uint32_t                 queueFamilyIndexCount;
217abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		DE_NULL,									// const uint32_t*          pQueueFamilyIndices;
218abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		VK_IMAGE_LAYOUT_UNDEFINED,					// VkImageLayout            initialLayout;
219abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	};
220abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	return imageInfo;
221abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski}
222abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
223abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej JesionowskiMove<VkImageView> makeImageView (const DeviceInterface&			vk,
224abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski								 const VkDevice					vkDevice,
225abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski								 const VkImage					image,
226abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski								 const VkImageViewType			viewType,
227abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski								 const VkFormat					format,
228abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski								 const VkImageSubresourceRange	subresourceRange)
229abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski{
230abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	const VkImageViewCreateInfo imageViewParams =
231abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	{
232abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,		// VkStructureType			sType;
233abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		DE_NULL,										// const void*				pNext;
234abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		(VkImageViewCreateFlags)0,						// VkImageViewCreateFlags	flags;
235abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		image,											// VkImage					image;
236abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		viewType,										// VkImageViewType			viewType;
237abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		format,											// VkFormat					format;
238abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		makeComponentMappingRGBA(),						// VkComponentMapping		components;
239abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		subresourceRange,								// VkImageSubresourceRange	subresourceRange;
240abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	};
241abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	return createImageView(vk, vkDevice, &imageViewParams);
242abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski}
243abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
244abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej JesionowskiVkBufferImageCopy makeBufferImageCopy (const VkExtent3D					extent,
245abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski									   const VkImageSubresourceLayers	subresourceLayers)
246abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski{
247abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	const VkBufferImageCopy copyParams =
248abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	{
249abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		0ull,										//	VkDeviceSize				bufferOffset;
250abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		0u,											//	deUint32					bufferRowLength;
251abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		0u,											//	deUint32					bufferImageHeight;
252abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		subresourceLayers,							//	VkImageSubresourceLayers	imageSubresource;
253abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		makeOffset3D(0, 0, 0),						//	VkOffset3D					imageOffset;
254abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		extent,										//	VkExtent3D					imageExtent;
255abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	};
256abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	return copyParams;
257abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski}
258abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
259abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowskivoid beginCommandBuffer (const DeviceInterface& vk, const VkCommandBuffer commandBuffer)
260abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski{
261abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	const VkCommandBufferBeginInfo info =
262abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	{
263abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,	// VkStructureType                          sType;
264abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		DE_NULL,										// const void*                              pNext;
265abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT,	// VkCommandBufferUsageFlags                flags;
266abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		DE_NULL,										// const VkCommandBufferInheritanceInfo*    pInheritanceInfo;
267abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	};
268abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	VK_CHECK(vk.beginCommandBuffer(commandBuffer, &info));
269abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski}
270abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
271abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowskivoid endCommandBuffer (const DeviceInterface& vk, const VkCommandBuffer commandBuffer)
272abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski{
273abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	VK_CHECK(vk.endCommandBuffer(commandBuffer));
274abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski}
275abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
276abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowskivoid submitCommandsAndWait (const DeviceInterface&	vk,
277abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski							const VkDevice			device,
278abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski							const VkQueue			queue,
279abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski							const VkCommandBuffer	commandBuffer)
280abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski{
281abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	const VkFenceCreateInfo fenceInfo =
282abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	{
283abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		VK_STRUCTURE_TYPE_FENCE_CREATE_INFO,	// VkStructureType		sType;
284abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		DE_NULL,								// const void*			pNext;
285abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		(VkFenceCreateFlags)0,					// VkFenceCreateFlags	flags;
286abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	};
287abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	const Unique<VkFence> fence(createFence(vk, device, &fenceInfo));
288abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
289abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	const VkSubmitInfo submitInfo =
290abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	{
291abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		VK_STRUCTURE_TYPE_SUBMIT_INFO,		// VkStructureType                sType;
292abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		DE_NULL,							// const void*                    pNext;
293abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		0u,									// uint32_t                       waitSemaphoreCount;
294abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		DE_NULL,							// const VkSemaphore*             pWaitSemaphores;
295abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		DE_NULL,							// const VkPipelineStageFlags*    pWaitDstStageMask;
296abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		1u,									// uint32_t                       commandBufferCount;
297abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		&commandBuffer,						// const VkCommandBuffer*         pCommandBuffers;
298abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		0u,									// uint32_t                       signalSemaphoreCount;
299abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		DE_NULL,							// const VkSemaphore*             pSignalSemaphores;
300abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	};
301abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	VK_CHECK(vk.queueSubmit(queue, 1u, &submitInfo, *fence));
302abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	VK_CHECK(vk.waitForFences(device, 1u, &fence.get(), DE_TRUE, ~0ull));
303abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski}
304abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
305abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowskivoid beginRenderPass (const DeviceInterface&	vk,
306abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski					  const VkCommandBuffer		commandBuffer,
307abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski					  const VkRenderPass		renderPass,
308abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski					  const VkFramebuffer		framebuffer,
309abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski					  const VkRect2D&			renderArea,
310abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski					  const tcu::Vec4&			clearColor)
311abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski{
312abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	const VkClearValue clearValue = makeClearValueColor(clearColor);
313abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
314abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	const VkRenderPassBeginInfo renderPassBeginInfo = {
315abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,		// VkStructureType         sType;
316abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		DE_NULL,										// const void*             pNext;
317abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		renderPass,										// VkRenderPass            renderPass;
318abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		framebuffer,									// VkFramebuffer           framebuffer;
319abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		renderArea,										// VkRect2D                renderArea;
320abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		1u,												// uint32_t                clearValueCount;
321abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		&clearValue,									// const VkClearValue*     pClearValues;
322abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	};
323abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
324abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	vk.cmdBeginRenderPass(commandBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
325abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski}
326abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
327abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowskivoid beginRenderPassWithRasterizationDisabled (const DeviceInterface&	vk,
328abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski											   const VkCommandBuffer	commandBuffer,
329abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski											   const VkRenderPass		renderPass,
330abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski											   const VkFramebuffer		framebuffer)
331abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski{
332abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	const VkRect2D renderArea = {{ 0, 0 }, { 0, 0 }};
333abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
334abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	const VkRenderPassBeginInfo renderPassBeginInfo = {
335abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,		// VkStructureType         sType;
336abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		DE_NULL,										// const void*             pNext;
337abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		renderPass,										// VkRenderPass            renderPass;
338abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		framebuffer,									// VkFramebuffer           framebuffer;
339abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		renderArea,										// VkRect2D                renderArea;
340abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		0u,												// uint32_t                clearValueCount;
341abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		DE_NULL,										// const VkClearValue*     pClearValues;
342abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	};
343abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
344abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	vk.cmdBeginRenderPass(commandBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
345abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski}
346abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
347abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowskivoid endRenderPass (const DeviceInterface&	vk,
348abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski					const VkCommandBuffer	commandBuffer)
349abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski{
350abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	vk.cmdEndRenderPass(commandBuffer);
351abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski}
352abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
353abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej JesionowskiMove<VkRenderPass> makeRenderPass (const DeviceInterface&	vk,
354abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski								   const VkDevice			device,
355abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski								   const VkFormat			colorFormat)
356abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski{
357abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	const VkAttachmentDescription colorAttachmentDescription =
358abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	{
359abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		(VkAttachmentDescriptionFlags)0,					// VkAttachmentDescriptionFlags		flags;
360abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		colorFormat,										// VkFormat							format;
361abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		VK_SAMPLE_COUNT_1_BIT,								// VkSampleCountFlagBits			samples;
362abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		VK_ATTACHMENT_LOAD_OP_CLEAR,						// VkAttachmentLoadOp				loadOp;
363abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		VK_ATTACHMENT_STORE_OP_STORE,						// VkAttachmentStoreOp				storeOp;
364abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		VK_ATTACHMENT_LOAD_OP_DONT_CARE,					// VkAttachmentLoadOp				stencilLoadOp;
365abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		VK_ATTACHMENT_STORE_OP_DONT_CARE,					// VkAttachmentStoreOp				stencilStoreOp;
366abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,			// VkImageLayout					initialLayout;
367abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL			// VkImageLayout					finalLayout;
368abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	};
369abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
370abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	const VkAttachmentReference colorAttachmentReference =
371abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	{
372abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		0u,													// deUint32			attachment;
373abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL			// VkImageLayout	layout;
374abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	};
375abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
376abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	const VkAttachmentReference depthAttachmentReference =
377abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	{
378abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		VK_ATTACHMENT_UNUSED,								// deUint32			attachment;
379abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		VK_IMAGE_LAYOUT_UNDEFINED							// VkImageLayout	layout;
380abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	};
381abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
382abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	const VkSubpassDescription subpassDescription =
383abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	{
384abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		(VkSubpassDescriptionFlags)0,						// VkSubpassDescriptionFlags		flags;
385abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		VK_PIPELINE_BIND_POINT_GRAPHICS,					// VkPipelineBindPoint				pipelineBindPoint;
386abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		0u,													// deUint32							inputAttachmentCount;
387abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		DE_NULL,											// const VkAttachmentReference*		pInputAttachments;
388abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		1u,													// deUint32							colorAttachmentCount;
389abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		&colorAttachmentReference,							// const VkAttachmentReference*		pColorAttachments;
390abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		DE_NULL,											// const VkAttachmentReference*		pResolveAttachments;
391abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		&depthAttachmentReference,							// const VkAttachmentReference*		pDepthStencilAttachment;
392abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		0u,													// deUint32							preserveAttachmentCount;
393abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		DE_NULL												// const deUint32*					pPreserveAttachments;
394abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	};
395abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
396abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	const VkRenderPassCreateInfo renderPassInfo =
397abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	{
398abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,			// VkStructureType					sType;
399abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		DE_NULL,											// const void*						pNext;
400abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		(VkRenderPassCreateFlags)0,							// VkRenderPassCreateFlags			flags;
401abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		1u,													// deUint32							attachmentCount;
402abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		&colorAttachmentDescription,						// const VkAttachmentDescription*	pAttachments;
403abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		1u,													// deUint32							subpassCount;
404abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		&subpassDescription,								// const VkSubpassDescription*		pSubpasses;
405abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		0u,													// deUint32							dependencyCount;
406abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		DE_NULL												// const VkSubpassDependency*		pDependencies;
407abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	};
408abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
409abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	return createRenderPass(vk, device, &renderPassInfo);
410abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski}
411abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
412abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej JesionowskiMove<VkRenderPass> makeRenderPassWithoutAttachments (const DeviceInterface&	vk,
413abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski													 const VkDevice			device)
414abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski{
415abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	const VkAttachmentReference unusedAttachment =
416abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	{
417abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		VK_ATTACHMENT_UNUSED,								// deUint32			attachment;
418abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		VK_IMAGE_LAYOUT_UNDEFINED							// VkImageLayout	layout;
419abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	};
420abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
421abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	const VkSubpassDescription subpassDescription =
422abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	{
423abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		(VkSubpassDescriptionFlags)0,						// VkSubpassDescriptionFlags		flags;
424abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		VK_PIPELINE_BIND_POINT_GRAPHICS,					// VkPipelineBindPoint				pipelineBindPoint;
425abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		0u,													// deUint32							inputAttachmentCount;
426abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		DE_NULL,											// const VkAttachmentReference*		pInputAttachments;
427abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		0u,													// deUint32							colorAttachmentCount;
428abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		DE_NULL,											// const VkAttachmentReference*		pColorAttachments;
429abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		DE_NULL,											// const VkAttachmentReference*		pResolveAttachments;
430abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		&unusedAttachment,									// const VkAttachmentReference*		pDepthStencilAttachment;
431abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		0u,													// deUint32							preserveAttachmentCount;
432abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		DE_NULL												// const deUint32*					pPreserveAttachments;
433abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	};
434abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
435abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	const VkRenderPassCreateInfo renderPassInfo =
436abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	{
437abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,			// VkStructureType					sType;
438abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		DE_NULL,											// const void*						pNext;
439abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		(VkRenderPassCreateFlags)0,							// VkRenderPassCreateFlags			flags;
440abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		0u,													// deUint32							attachmentCount;
441abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		DE_NULL,											// const VkAttachmentDescription*	pAttachments;
442abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		1u,													// deUint32							subpassCount;
443abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		&subpassDescription,								// const VkSubpassDescription*		pSubpasses;
444abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		0u,													// deUint32							dependencyCount;
445abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		DE_NULL												// const VkSubpassDependency*		pDependencies;
446abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	};
447abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
448abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	return createRenderPass(vk, device, &renderPassInfo);
449abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski}
450abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
451abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej JesionowskiMove<VkFramebuffer> makeFramebuffer (const DeviceInterface&		vk,
452abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski									 const VkDevice				device,
453abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski									 const VkRenderPass			renderPass,
454abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski									 const VkImageView			colorAttachment,
455abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski									 const deUint32				width,
456abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski									 const deUint32				height,
457abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski									 const deUint32				layers)
458abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski{
459abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	const VkFramebufferCreateInfo framebufferInfo = {
460abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,		// VkStructureType                             sType;
461abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		DE_NULL,										// const void*                                 pNext;
462abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		(VkFramebufferCreateFlags)0,					// VkFramebufferCreateFlags                    flags;
463abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		renderPass,										// VkRenderPass                                renderPass;
464abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		1u,												// uint32_t                                    attachmentCount;
465abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		&colorAttachment,								// const VkImageView*                          pAttachments;
466abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		width,											// uint32_t                                    width;
467abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		height,											// uint32_t                                    height;
468abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		layers,											// uint32_t                                    layers;
469abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	};
470abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
471abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	return createFramebuffer(vk, device, &framebufferInfo);
472abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski}
473abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
474abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej JesionowskiMove<VkFramebuffer> makeFramebufferWithoutAttachments (const DeviceInterface&		vk,
475abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski													   const VkDevice				device,
476abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski													   const VkRenderPass			renderPass)
477abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski{
478abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	const VkFramebufferCreateInfo framebufferInfo = {
479abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,		// VkStructureType                             sType;
480abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		DE_NULL,										// const void*                                 pNext;
481abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		(VkFramebufferCreateFlags)0,					// VkFramebufferCreateFlags                    flags;
482abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		renderPass,										// VkRenderPass                                renderPass;
483abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		0u,												// uint32_t                                    attachmentCount;
484abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		DE_NULL,										// const VkImageView*                          pAttachments;
4858c6859a60e7648a2dbfa192908e41f464e11ccd7Alex Walters		1u,												// uint32_t                                    width;
4868c6859a60e7648a2dbfa192908e41f464e11ccd7Alex Walters		1u,												// uint32_t                                    height;
4878c6859a60e7648a2dbfa192908e41f464e11ccd7Alex Walters		1u,												// uint32_t                                    layers;
488abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	};
489abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
490abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	return createFramebuffer(vk, device, &framebufferInfo);
491abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski}
492abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
493abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej JesionowskiGraphicsPipelineBuilder& GraphicsPipelineBuilder::setShader (const DeviceInterface&			vk,
494abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski															 const VkDevice					device,
495abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski															 const VkShaderStageFlagBits	stage,
496abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski															 const ProgramBinary&			binary,
497abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski															 const VkSpecializationInfo*	specInfo)
498abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski{
499abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	VkShaderModule module;
500abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	switch (stage)
501abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	{
502abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		case (VK_SHADER_STAGE_VERTEX_BIT):
503abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			DE_ASSERT(m_vertexShaderModule.get() == DE_NULL);
504abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			m_vertexShaderModule = createShaderModule(vk, device, binary, (VkShaderModuleCreateFlags)0);
505abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			module = *m_vertexShaderModule;
506abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			break;
507abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
508abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		case (VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT):
509abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			DE_ASSERT(m_tessControlShaderModule.get() == DE_NULL);
510abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			m_tessControlShaderModule = createShaderModule(vk, device, binary, (VkShaderModuleCreateFlags)0);
511abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			module = *m_tessControlShaderModule;
512abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			break;
513abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
514abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		case (VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT):
515abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			DE_ASSERT(m_tessEvaluationShaderModule.get() == DE_NULL);
516abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			m_tessEvaluationShaderModule = createShaderModule(vk, device, binary, (VkShaderModuleCreateFlags)0);
517abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			module = *m_tessEvaluationShaderModule;
518abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			break;
519abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
520abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		case (VK_SHADER_STAGE_GEOMETRY_BIT):
521abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			DE_ASSERT(m_geometryShaderModule.get() == DE_NULL);
522abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			m_geometryShaderModule = createShaderModule(vk, device, binary, (VkShaderModuleCreateFlags)0);
523abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			module = *m_geometryShaderModule;
524abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			break;
525abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
526abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		case (VK_SHADER_STAGE_FRAGMENT_BIT):
527abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			DE_ASSERT(m_fragmentShaderModule.get() == DE_NULL);
528abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			m_fragmentShaderModule = createShaderModule(vk, device, binary, (VkShaderModuleCreateFlags)0);
529abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			module = *m_fragmentShaderModule;
530abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			break;
531abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
532abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		default:
533abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			DE_FATAL("Invalid shader stage");
534abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			return *this;
535abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	}
536abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
537abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	const VkPipelineShaderStageCreateInfo pipelineShaderStageInfo =
538abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	{
539abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,	// VkStructureType						sType;
540abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		DE_NULL,												// const void*							pNext;
541abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		(VkPipelineShaderStageCreateFlags)0,					// VkPipelineShaderStageCreateFlags		flags;
542abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		stage,													// VkShaderStageFlagBits				stage;
543abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		module,													// VkShaderModule						module;
544abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		"main",													// const char*							pName;
545abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		specInfo,												// const VkSpecializationInfo*			pSpecializationInfo;
546abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	};
547abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
548abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	m_shaderStageFlags |= stage;
549abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	m_shaderStages.push_back(pipelineShaderStageInfo);
550abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
551abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	return *this;
552abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski}
553abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
554abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej JesionowskiGraphicsPipelineBuilder& GraphicsPipelineBuilder::setVertexInputSingleAttribute (const VkFormat vertexFormat, const deUint32 stride)
555abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski{
556abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	const VkVertexInputBindingDescription bindingDesc =
557abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	{
558abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		0u,									// uint32_t				binding;
559abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		stride,								// uint32_t				stride;
560abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		VK_VERTEX_INPUT_RATE_VERTEX,		// VkVertexInputRate	inputRate;
561abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	};
562abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	const VkVertexInputAttributeDescription attributeDesc =
563abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	{
564abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		0u,									// uint32_t			location;
565abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		0u,									// uint32_t			binding;
566abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		vertexFormat,						// VkFormat			format;
567abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		0u,									// uint32_t			offset;
568abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	};
569abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
570abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	m_vertexInputBindings.clear();
571abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	m_vertexInputBindings.push_back(bindingDesc);
572abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
573abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	m_vertexInputAttributes.clear();
574abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	m_vertexInputAttributes.push_back(attributeDesc);
575abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
576abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	return *this;
577abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski}
578abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
579abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowskitemplate<typename T>
580abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowskiinline const T* dataPointer (const std::vector<T>& vec)
581abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski{
582abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	return (vec.size() != 0 ? &vec[0] : DE_NULL);
583abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski}
584abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
585abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej JesionowskiMove<VkPipeline> GraphicsPipelineBuilder::build (const DeviceInterface&	vk,
586abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski												 const VkDevice			device,
587abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski												 const VkPipelineLayout	pipelineLayout,
588abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski												 const VkRenderPass		renderPass)
589abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski{
590abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	const VkPipelineVertexInputStateCreateInfo vertexInputStateInfo =
591abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	{
592abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,		// VkStructureType                             sType;
593abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		DE_NULL,														// const void*                                 pNext;
594abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		(VkPipelineVertexInputStateCreateFlags)0,						// VkPipelineVertexInputStateCreateFlags       flags;
595abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		static_cast<deUint32>(m_vertexInputBindings.size()),			// uint32_t                                    vertexBindingDescriptionCount;
596abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		dataPointer(m_vertexInputBindings),								// const VkVertexInputBindingDescription*      pVertexBindingDescriptions;
597abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		static_cast<deUint32>(m_vertexInputAttributes.size()),			// uint32_t                                    vertexAttributeDescriptionCount;
598abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		dataPointer(m_vertexInputAttributes),							// const VkVertexInputAttributeDescription*    pVertexAttributeDescriptions;
599abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	};
600abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
601abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	const VkPrimitiveTopology topology = (m_shaderStageFlags & VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT) ? VK_PRIMITIVE_TOPOLOGY_PATCH_LIST
602abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski																										 : m_primitiveTopology;
603abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	const VkPipelineInputAssemblyStateCreateInfo pipelineInputAssemblyStateInfo =
604abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	{
605abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,	// VkStructureType                             sType;
606abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		DE_NULL,														// const void*                                 pNext;
607abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		(VkPipelineInputAssemblyStateCreateFlags)0,						// VkPipelineInputAssemblyStateCreateFlags     flags;
608abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		topology,														// VkPrimitiveTopology                         topology;
609abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		VK_FALSE,														// VkBool32                                    primitiveRestartEnable;
610abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	};
611abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
612abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	const VkPipelineTessellationStateCreateInfo pipelineTessellationStateInfo =
613abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	{
614abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO,		// VkStructureType                             sType;
615abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		DE_NULL,														// const void*                                 pNext;
616abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		(VkPipelineTessellationStateCreateFlags)0,						// VkPipelineTessellationStateCreateFlags      flags;
617abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		m_patchControlPoints,											// uint32_t                                    patchControlPoints;
618abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	};
619abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
620abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	const VkViewport viewport = makeViewport(
621abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		0.0f, 0.0f,
622abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		static_cast<float>(m_renderSize.x()), static_cast<float>(m_renderSize.y()),
623abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		0.0f, 1.0f);
624abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
625abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	const VkRect2D scissor = {
626abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		makeOffset2D(0, 0),
627abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		makeExtent2D(m_renderSize.x(), m_renderSize.y()),
628abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	};
629abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
630abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	const VkPipelineViewportStateCreateInfo pipelineViewportStateInfo =
631abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	{
632abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO,	// VkStructureType                             sType;
633abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		DE_NULL,												// const void*                                 pNext;
634abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		(VkPipelineViewportStateCreateFlags)0,					// VkPipelineViewportStateCreateFlags          flags;
635abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		1u,														// uint32_t                                    viewportCount;
636abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		&viewport,												// const VkViewport*                           pViewports;
637abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		1u,														// uint32_t                                    scissorCount;
638abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		&scissor,												// const VkRect2D*                             pScissors;
639abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	};
640abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
641abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	const bool isRasterizationDisabled = ((m_shaderStageFlags & VK_SHADER_STAGE_FRAGMENT_BIT) == 0);
642abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	const VkPipelineRasterizationStateCreateInfo pipelineRasterizationStateInfo =
643abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	{
644abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO,		// VkStructureType                          sType;
645abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		DE_NULL,														// const void*                              pNext;
646abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		(VkPipelineRasterizationStateCreateFlags)0,						// VkPipelineRasterizationStateCreateFlags  flags;
647abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		VK_FALSE,														// VkBool32                                 depthClampEnable;
648abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		isRasterizationDisabled,										// VkBool32                                 rasterizerDiscardEnable;
649abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		VK_POLYGON_MODE_FILL,											// VkPolygonMode							polygonMode;
650abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		m_cullModeFlags,												// VkCullModeFlags							cullMode;
651abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		m_frontFace,													// VkFrontFace								frontFace;
652abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		VK_FALSE,														// VkBool32									depthBiasEnable;
653abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		0.0f,															// float									depthBiasConstantFactor;
654abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		0.0f,															// float									depthBiasClamp;
655abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		0.0f,															// float									depthBiasSlopeFactor;
656abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		1.0f,															// float									lineWidth;
657abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	};
658abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
659abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	const VkPipelineMultisampleStateCreateInfo pipelineMultisampleStateInfo =
660abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	{
661abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,	// VkStructureType							sType;
662abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		DE_NULL,													// const void*								pNext;
663abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		(VkPipelineMultisampleStateCreateFlags)0,					// VkPipelineMultisampleStateCreateFlags	flags;
664abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		VK_SAMPLE_COUNT_1_BIT,										// VkSampleCountFlagBits					rasterizationSamples;
665abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		VK_FALSE,													// VkBool32									sampleShadingEnable;
666abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		0.0f,														// float									minSampleShading;
667abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		DE_NULL,													// const VkSampleMask*						pSampleMask;
668abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		VK_FALSE,													// VkBool32									alphaToCoverageEnable;
669abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		VK_FALSE													// VkBool32									alphaToOneEnable;
670abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	};
671abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
672abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	const VkStencilOpState stencilOpState = makeStencilOpState(
673abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		VK_STENCIL_OP_KEEP,		// stencil fail
674abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		VK_STENCIL_OP_KEEP,		// depth & stencil pass
675abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		VK_STENCIL_OP_KEEP,		// depth only fail
676abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		VK_COMPARE_OP_NEVER,	// compare op
677abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		0u,						// compare mask
678abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		0u,						// write mask
679abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		0u);					// reference
680abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
681abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	const VkPipelineDepthStencilStateCreateInfo pipelineDepthStencilStateInfo =
682abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	{
683abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO,	// VkStructureType							sType;
684abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		DE_NULL,													// const void*								pNext;
685abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		(VkPipelineDepthStencilStateCreateFlags)0,					// VkPipelineDepthStencilStateCreateFlags	flags;
686abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		VK_FALSE,													// VkBool32									depthTestEnable;
687abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		VK_FALSE,													// VkBool32									depthWriteEnable;
688abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		VK_COMPARE_OP_LESS,											// VkCompareOp								depthCompareOp;
689abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		VK_FALSE,													// VkBool32									depthBoundsTestEnable;
690abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		VK_FALSE,													// VkBool32									stencilTestEnable;
691abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		stencilOpState,												// VkStencilOpState							front;
692abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		stencilOpState,												// VkStencilOpState							back;
693abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		0.0f,														// float									minDepthBounds;
694abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		1.0f,														// float									maxDepthBounds;
695abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	};
696abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
697abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	const VkColorComponentFlags colorComponentsAll = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT;
698abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	const VkPipelineColorBlendAttachmentState pipelineColorBlendAttachmentState =
699abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	{
700abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		m_blendEnable,						// VkBool32					blendEnable;
701abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		VK_BLEND_FACTOR_SRC_ALPHA,			// VkBlendFactor			srcColorBlendFactor;
702abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		VK_BLEND_FACTOR_ONE,				// VkBlendFactor			dstColorBlendFactor;
703abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		VK_BLEND_OP_ADD,					// VkBlendOp				colorBlendOp;
704abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		VK_BLEND_FACTOR_SRC_ALPHA,			// VkBlendFactor			srcAlphaBlendFactor;
705abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		VK_BLEND_FACTOR_ONE,				// VkBlendFactor			dstAlphaBlendFactor;
706abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		VK_BLEND_OP_ADD,					// VkBlendOp				alphaBlendOp;
707abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		colorComponentsAll,					// VkColorComponentFlags	colorWriteMask;
708abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	};
709abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
710abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	const VkPipelineColorBlendStateCreateInfo pipelineColorBlendStateInfo =
711abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	{
712abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,	// VkStructureType								sType;
713abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		DE_NULL,													// const void*									pNext;
714abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		(VkPipelineColorBlendStateCreateFlags)0,					// VkPipelineColorBlendStateCreateFlags			flags;
715abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		VK_FALSE,													// VkBool32										logicOpEnable;
716abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		VK_LOGIC_OP_COPY,											// VkLogicOp									logicOp;
717abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		1u,															// deUint32										attachmentCount;
718abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		&pipelineColorBlendAttachmentState,							// const VkPipelineColorBlendAttachmentState*	pAttachments;
719abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		{ 0.0f, 0.0f, 0.0f, 0.0f },									// float										blendConstants[4];
720abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	};
721abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
722abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	const VkGraphicsPipelineCreateInfo graphicsPipelineInfo =
723abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	{
724abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,						// VkStructureType									sType;
725abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		DE_NULL,																// const void*										pNext;
726abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		(VkPipelineCreateFlags)0,												// VkPipelineCreateFlags							flags;
727abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		static_cast<deUint32>(m_shaderStages.size()),							// deUint32											stageCount;
728abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		&m_shaderStages[0],														// const VkPipelineShaderStageCreateInfo*			pStages;
729abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		&vertexInputStateInfo,													// const VkPipelineVertexInputStateCreateInfo*		pVertexInputState;
730abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		&pipelineInputAssemblyStateInfo,										// const VkPipelineInputAssemblyStateCreateInfo*	pInputAssemblyState;
731abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		(m_shaderStageFlags & VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT ? &pipelineTessellationStateInfo : DE_NULL), // const VkPipelineTessellationStateCreateInfo*		pTessellationState;
732abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		(isRasterizationDisabled ? DE_NULL : &pipelineViewportStateInfo),		// const VkPipelineViewportStateCreateInfo*			pViewportState;
733abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		&pipelineRasterizationStateInfo,										// const VkPipelineRasterizationStateCreateInfo*	pRasterizationState;
734abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		(isRasterizationDisabled ? DE_NULL : &pipelineMultisampleStateInfo),	// const VkPipelineMultisampleStateCreateInfo*		pMultisampleState;
735abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		(isRasterizationDisabled ? DE_NULL : &pipelineDepthStencilStateInfo),	// const VkPipelineDepthStencilStateCreateInfo*		pDepthStencilState;
736abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		(isRasterizationDisabled ? DE_NULL : &pipelineColorBlendStateInfo),		// const VkPipelineColorBlendStateCreateInfo*		pColorBlendState;
737abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		DE_NULL,																// const VkPipelineDynamicStateCreateInfo*			pDynamicState;
738abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		pipelineLayout,															// VkPipelineLayout									layout;
739abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		renderPass,																// VkRenderPass										renderPass;
740abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		0u,																		// deUint32											subpass;
741abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		DE_NULL,																// VkPipeline										basePipelineHandle;
742abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		0,																		// deInt32											basePipelineIndex;
743abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	};
744abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
745abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	return createGraphicsPipeline(vk, device, DE_NULL, &graphicsPipelineInfo);
746abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski}
747abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
748abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowskifloat getClampedTessLevel (const SpacingMode mode, const float tessLevel)
749abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski{
750abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	switch (mode)
751abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	{
752abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		case SPACINGMODE_EQUAL:				return de::max(1.0f, tessLevel);
753abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		case SPACINGMODE_FRACTIONAL_ODD:	return de::max(1.0f, tessLevel);
754abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		case SPACINGMODE_FRACTIONAL_EVEN:	return de::max(2.0f, tessLevel);
755abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		default:
756abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			DE_ASSERT(false);
757abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			return 0.0f;
758abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	}
759abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski}
760abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
761abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowskiint getRoundedTessLevel (const SpacingMode mode, const float clampedTessLevel)
762abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski{
763079a481256d63e8498f7adf38a234bfe74bb04dePyry Haulos	static const int minimumMaxTessGenLevel = 64;	//!< Minimum maxTessellationGenerationLevel defined by the spec.
764abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
765abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	int result = (int)deFloatCeil(clampedTessLevel);
766abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
767abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	switch (mode)
768abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	{
769abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		case SPACINGMODE_EQUAL:											break;
770abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		case SPACINGMODE_FRACTIONAL_ODD:	result += 1 - result % 2;	break;
771abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		case SPACINGMODE_FRACTIONAL_EVEN:	result += result % 2;		break;
772abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		default:
773abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			DE_ASSERT(false);
774abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	}
775079a481256d63e8498f7adf38a234bfe74bb04dePyry Haulos	DE_ASSERT(de::inRange<int>(result, 1, minimumMaxTessGenLevel));
776079a481256d63e8498f7adf38a234bfe74bb04dePyry Haulos	DE_UNREF(minimumMaxTessGenLevel);
777abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
778abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	return result;
779abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski}
780abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
781abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowskiint getClampedRoundedTessLevel (const SpacingMode mode, const float tessLevel)
782abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski{
783abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	return getRoundedTessLevel(mode, getClampedTessLevel(mode, tessLevel));
784abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski}
785abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
786abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowskivoid getClampedRoundedTriangleTessLevels (const SpacingMode	spacingMode,
787abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski										  const float*		innerSrc,
788abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski										  const float*		outerSrc,
789abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski										  int*				innerDst,
790abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski										  int*				outerDst)
791abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski{
792abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	innerDst[0] = getClampedRoundedTessLevel(spacingMode, innerSrc[0]);
793abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	for (int i = 0; i < 3; i++)
794abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		outerDst[i] = getClampedRoundedTessLevel(spacingMode, outerSrc[i]);
795abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski}
796abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
797abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowskivoid getClampedRoundedQuadTessLevels (const SpacingMode spacingMode,
798abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski									  const float*		innerSrc,
799abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski									  const float*		outerSrc,
800abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski									  int*				innerDst,
801abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski									  int*				outerDst)
802abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski{
803abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	for (int i = 0; i < 2; i++)
804abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		innerDst[i] = getClampedRoundedTessLevel(spacingMode, innerSrc[i]);
805abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	for (int i = 0; i < 4; i++)
806abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		outerDst[i] = getClampedRoundedTessLevel(spacingMode, outerSrc[i]);
807abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski}
808abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
809abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowskivoid getClampedRoundedIsolineTessLevels (const SpacingMode	spacingMode,
810abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski										 const float*		outerSrc,
811abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski										 int*				outerDst)
812abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski{
813abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	outerDst[0] = getClampedRoundedTessLevel(SPACINGMODE_EQUAL,	outerSrc[0]);
814abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	outerDst[1] = getClampedRoundedTessLevel(spacingMode,		outerSrc[1]);
815abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski}
816abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
817abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowskiint numOuterTessellationLevels (const TessPrimitiveType primType)
818abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski{
819abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	switch (primType)
820abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	{
821abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		case TESSPRIMITIVETYPE_TRIANGLES:	return 3;
822abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		case TESSPRIMITIVETYPE_QUADS:		return 4;
823abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		case TESSPRIMITIVETYPE_ISOLINES:	return 2;
824abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		default:
825abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			DE_ASSERT(false);
826abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			return 0;
827abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	}
828abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski}
829abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
830abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowskibool isPatchDiscarded (const TessPrimitiveType primitiveType, const float* outerLevels)
831abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski{
832abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	const int numOuterLevels = numOuterTessellationLevels(primitiveType);
833abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	for (int i = 0; i < numOuterLevels; i++)
834abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		if (outerLevels[i] <= 0.0f)
835abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			return true;
836abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	return false;
837abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski}
838abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
839abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowskistd::string getTessellationLevelsString (const TessLevels& tessLevels, const TessPrimitiveType primitiveType)
840abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski{
841abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	std::ostringstream str;
842abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	switch (primitiveType)
843abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	{
844abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		case TESSPRIMITIVETYPE_ISOLINES:
845abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			str << "inner: { }, "
846abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski				<< "outer: { " << tessLevels.outer[0] << ", " << tessLevels.outer[1] << " }";
847abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			break;
848abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
849abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		case TESSPRIMITIVETYPE_TRIANGLES:
850abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			str << "inner: { " << tessLevels.inner[0] << " }, "
851abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski				<< "outer: { " << tessLevels.outer[0] << ", " << tessLevels.outer[1] << ", " << tessLevels.outer[2] << " }";
852abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			break;
853abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
854abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		case TESSPRIMITIVETYPE_QUADS:
855abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			str << "inner: { " << tessLevels.inner[0] << ", " << tessLevels.inner[1] << " }, "
856abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski				<< "outer: { " << tessLevels.outer[0] << ", " << tessLevels.outer[1] << ", " << tessLevels.outer[2] << ", " << tessLevels.outer[3] << " }";
857abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			break;
858abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
859abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		default:
860abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			DE_ASSERT(false);
861abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	}
862abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
863abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	return str.str();
864abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski}
865abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
866abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski//! Assumes array sizes inner[2] and outer[4].
867abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowskistd::string getTessellationLevelsString (const float* inner, const float* outer)
868abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski{
869abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	const TessLevels tessLevels =
870abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	{
871abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		{ inner[0], inner[1] },
872abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		{ outer[0], outer[1], outer[2], outer[3] }
873abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	};
874abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	return getTessellationLevelsString(tessLevels, TESSPRIMITIVETYPE_QUADS);
875abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski}
876abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
877abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski// \note The tessellation coordinates generated by this function could break some of the rules given in the spec
878abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski// (e.g. it may not exactly hold that u+v+w == 1.0f, or [uvw] + (1.0f-[uvw]) == 1.0f).
879abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowskistd::vector<tcu::Vec3> generateReferenceTriangleTessCoords (const SpacingMode	spacingMode,
880abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski															const int			inner,
881abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski															const int			outer0,
882abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski															const int			outer1,
883abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski															const int			outer2)
884abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski{
885abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	std::vector<tcu::Vec3> tessCoords;
886abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
887abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	if (inner == 1)
888abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	{
889abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		if (outer0 == 1 && outer1 == 1 && outer2 == 1)
890abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		{
891abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			tessCoords.push_back(tcu::Vec3(1.0f, 0.0f, 0.0f));
892abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			tessCoords.push_back(tcu::Vec3(0.0f, 1.0f, 0.0f));
893abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			tessCoords.push_back(tcu::Vec3(0.0f, 0.0f, 1.0f));
894abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			return tessCoords;
895abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		}
896abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		else
897abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			return generateReferenceTriangleTessCoords(spacingMode, spacingMode == SPACINGMODE_FRACTIONAL_ODD ? 3 : 2,
898abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski													   outer0, outer1, outer2);
899abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	}
900abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	else
901abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	{
902abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		for (int i = 0; i < outer0; i++) { const float v = (float)i / (float)outer0; tessCoords.push_back(tcu::Vec3(    0.0f,        v, 1.0f - v)); }
903abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		for (int i = 0; i < outer1; i++) { const float v = (float)i / (float)outer1; tessCoords.push_back(tcu::Vec3(1.0f - v,     0.0f,        v)); }
904abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		for (int i = 0; i < outer2; i++) { const float v = (float)i / (float)outer2; tessCoords.push_back(tcu::Vec3(       v, 1.0f - v,     0.0f)); }
905abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
906abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		const int numInnerTriangles = inner/2;
907abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		for (int innerTriangleNdx = 0; innerTriangleNdx < numInnerTriangles; innerTriangleNdx++)
908abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		{
909abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			const int curInnerTriangleLevel = inner - 2*(innerTriangleNdx+1);
910abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
911abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			if (curInnerTriangleLevel == 0)
912abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski				tessCoords.push_back(tcu::Vec3(1.0f/3.0f));
913abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			else
914abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			{
915abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski				const float		minUVW		= (float)(2 * (innerTriangleNdx + 1)) / (float)(3 * inner);
916abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski				const float		maxUVW		= 1.0f - 2.0f*minUVW;
917abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski				const tcu::Vec3	corners[3]	=
918abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski				{
919abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski					tcu::Vec3(maxUVW, minUVW, minUVW),
920abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski					tcu::Vec3(minUVW, maxUVW, minUVW),
921abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski					tcu::Vec3(minUVW, minUVW, maxUVW)
922abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski				};
923abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
924abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski				for (int i = 0; i < curInnerTriangleLevel; i++)
925abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski				{
926abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski					const float f = (float)i / (float)curInnerTriangleLevel;
927abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski					for (int j = 0; j < 3; j++)
928abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski						tessCoords.push_back((1.0f - f)*corners[j] + f*corners[(j+1)%3]);
929abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski				}
930abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			}
931abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		}
932abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
933abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		return tessCoords;
934abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	}
935abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski}
936abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
937abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski// \note The tessellation coordinates generated by this function could break some of the rules given in the spec
938abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski// (e.g. it may not exactly hold that [uv] + (1.0f-[uv]) == 1.0f).
939abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowskistd::vector<tcu::Vec3> generateReferenceQuadTessCoords (const SpacingMode	spacingMode,
940abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski														const int			inner0,
941abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski														const int			inner1,
942abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski														const int			outer0,
943abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski														const int			outer1,
944abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski														const int			outer2,
945abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski														const int			outer3)
946abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski{
947abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	std::vector<tcu::Vec3> tessCoords;
948abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
949abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	if (inner0 == 1 || inner1 == 1)
950abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	{
951abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		if (inner0 == 1 && inner1 == 1 && outer0 == 1 && outer1 == 1 && outer2 == 1 && outer3 == 1)
952abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		{
953abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			tessCoords.push_back(tcu::Vec3(0.0f, 0.0f, 0.0f));
954abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			tessCoords.push_back(tcu::Vec3(1.0f, 0.0f, 0.0f));
955abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			tessCoords.push_back(tcu::Vec3(0.0f, 1.0f, 0.0f));
956abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			tessCoords.push_back(tcu::Vec3(1.0f, 1.0f, 0.0f));
957abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			return tessCoords;
958abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		}
959abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		else
960abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			return generateReferenceQuadTessCoords(spacingMode, inner0 > 1 ? inner0 : spacingMode == SPACINGMODE_FRACTIONAL_ODD ? 3 : 2,
961abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski																inner1 > 1 ? inner1 : spacingMode == SPACINGMODE_FRACTIONAL_ODD ? 3 : 2,
962abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski																outer0, outer1, outer2, outer3);
963abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	}
964abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	else
965abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	{
966abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		for (int i = 0; i < outer0; i++) { const float v = (float)i / (float)outer0; tessCoords.push_back(tcu::Vec3(    0.0f,        v, 0.0f)); }
967abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		for (int i = 0; i < outer1; i++) { const float v = (float)i / (float)outer1; tessCoords.push_back(tcu::Vec3(1.0f - v,     0.0f, 0.0f)); }
968abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		for (int i = 0; i < outer2; i++) { const float v = (float)i / (float)outer2; tessCoords.push_back(tcu::Vec3(    1.0f, 1.0f - v, 0.0f)); }
969abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		for (int i = 0; i < outer3; i++) { const float v = (float)i / (float)outer3; tessCoords.push_back(tcu::Vec3(       v,     1.0f, 0.0f)); }
970abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
971abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		for (int innerVtxY = 0; innerVtxY < inner1-1; innerVtxY++)
972abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		for (int innerVtxX = 0; innerVtxX < inner0-1; innerVtxX++)
973abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			tessCoords.push_back(tcu::Vec3((float)(innerVtxX + 1) / (float)inner0,
974abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski										   (float)(innerVtxY + 1) / (float)inner1,
975abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski										   0.0f));
976abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
977abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		return tessCoords;
978abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	}
979abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski}
980abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
981abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski// \note The tessellation coordinates generated by this function could break some of the rules given in the spec
982abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski// (e.g. it may not exactly hold that [uv] + (1.0f-[uv]) == 1.0f).
983abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowskistd::vector<tcu::Vec3> generateReferenceIsolineTessCoords (const int outer0, const int outer1)
984abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski{
985abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	std::vector<tcu::Vec3> tessCoords;
986abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
987abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	for (int y = 0; y < outer0;   y++)
988abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	for (int x = 0; x < outer1+1; x++)
989abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		tessCoords.push_back(tcu::Vec3((float)x / (float)outer1,
990abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski									   (float)y / (float)outer0,
991abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski									   0.0f));
992abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
993abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	return tessCoords;
994abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski}
995abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
996abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowskistatic int referencePointModePrimitiveCount (const TessPrimitiveType primitiveType, const SpacingMode spacingMode, const float* innerLevels, const float* outerLevels)
997abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski{
998abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	if (isPatchDiscarded(primitiveType, outerLevels))
999abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		return 0;
1000abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
1001abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	switch (primitiveType)
1002abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	{
1003abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		case TESSPRIMITIVETYPE_TRIANGLES:
1004abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		{
1005abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			int inner;
1006abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			int outer[3];
1007abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			getClampedRoundedTriangleTessLevels(spacingMode, innerLevels, outerLevels, &inner, &outer[0]);
1008abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			return static_cast<int>(generateReferenceTriangleTessCoords(spacingMode, inner, outer[0], outer[1], outer[2]).size());
1009abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		}
1010abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
1011abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		case TESSPRIMITIVETYPE_QUADS:
1012abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		{
1013abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			int inner[2];
1014abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			int outer[4];
1015abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			getClampedRoundedQuadTessLevels(spacingMode, innerLevels, outerLevels, &inner[0], &outer[0]);
1016abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			return static_cast<int>(generateReferenceQuadTessCoords(spacingMode, inner[0], inner[1], outer[0], outer[1], outer[2], outer[3]).size());
1017abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		}
1018abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
1019abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		case TESSPRIMITIVETYPE_ISOLINES:
1020abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		{
1021abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			int outer[2];
1022abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			getClampedRoundedIsolineTessLevels(spacingMode, &outerLevels[0], &outer[0]);
1023abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			return static_cast<int>(generateReferenceIsolineTessCoords(outer[0], outer[1]).size());
1024abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		}
1025abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
1026abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		default:
1027abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			DE_ASSERT(false);
1028abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			return 0;
1029abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	}
1030abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski}
1031abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
1032abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowskistatic int referenceTriangleNonPointModePrimitiveCount (const SpacingMode spacingMode, const int inner, const int outer0, const int outer1, const int outer2)
1033abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski{
1034abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	if (inner == 1)
1035abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	{
1036abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		if (outer0 == 1 && outer1 == 1 && outer2 == 1)
1037abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			return 1;
1038abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		else
1039abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			return referenceTriangleNonPointModePrimitiveCount(spacingMode, spacingMode == SPACINGMODE_FRACTIONAL_ODD ? 3 : 2,
1040abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski																			outer0, outer1, outer2);
1041abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	}
1042abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	else
1043abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	{
1044abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		int result = outer0 + outer1 + outer2;
1045abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
1046abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		const int numInnerTriangles = inner/2;
1047abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		for (int innerTriangleNdx = 0; innerTriangleNdx < numInnerTriangles; innerTriangleNdx++)
1048abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		{
1049abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			const int curInnerTriangleLevel = inner - 2*(innerTriangleNdx+1);
1050abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
1051abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			if (curInnerTriangleLevel == 1)
1052abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski				result += 4;
1053abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			else
1054abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski				result += 2*3*curInnerTriangleLevel;
1055abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		}
1056abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
1057abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		return result;
1058abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	}
1059abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski}
1060abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
1061abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowskistatic int referenceQuadNonPointModePrimitiveCount (const SpacingMode spacingMode, const int inner0, const int inner1, const int outer0, const int outer1, const int outer2, const int outer3)
1062abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski{
1063abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	if (inner0 == 1 || inner1 == 1)
1064abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	{
1065abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		if (inner0 == 1 && inner1 == 1 && outer0 == 1 && outer1 == 1 && outer2 == 1 && outer3 == 1)
1066abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			return 2;
1067abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		else
1068abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			return referenceQuadNonPointModePrimitiveCount(spacingMode, inner0 > 1 ? inner0 : spacingMode == SPACINGMODE_FRACTIONAL_ODD ? 3 : 2,
1069abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski																		inner1 > 1 ? inner1 : spacingMode == SPACINGMODE_FRACTIONAL_ODD ? 3 : 2,
1070abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski																		outer0, outer1, outer2, outer3);
1071abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	}
1072abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	else
1073abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		return 2*(inner0-2)*(inner1-2) + 2*(inner0-2) + 2*(inner1-2) + outer0+outer1+outer2+outer3;
1074abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski}
1075abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
1076abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowskistatic inline int referenceIsolineNonPointModePrimitiveCount (const int outer0, const int outer1)
1077abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski{
1078abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	return outer0*outer1;
1079abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski}
1080abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
1081abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowskistatic int referenceNonPointModePrimitiveCount (const TessPrimitiveType primitiveType, const SpacingMode spacingMode, const float* innerLevels, const float* outerLevels)
1082abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski{
1083abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	if (isPatchDiscarded(primitiveType, outerLevels))
1084abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		return 0;
1085abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
1086abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	switch (primitiveType)
1087abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	{
1088abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		case TESSPRIMITIVETYPE_TRIANGLES:
1089abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		{
1090abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			int inner;
1091abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			int outer[3];
1092abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			getClampedRoundedTriangleTessLevels(spacingMode, innerLevels, outerLevels, &inner, &outer[0]);
1093abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			return referenceTriangleNonPointModePrimitiveCount(spacingMode, inner, outer[0], outer[1], outer[2]);
1094abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		}
1095abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
1096abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		case TESSPRIMITIVETYPE_QUADS:
1097abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		{
1098abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			int inner[2];
1099abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			int outer[4];
1100abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			getClampedRoundedQuadTessLevels(spacingMode, innerLevels, outerLevels, &inner[0], &outer[0]);
1101abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			return referenceQuadNonPointModePrimitiveCount(spacingMode, inner[0], inner[1], outer[0], outer[1], outer[2], outer[3]);
1102abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		}
1103abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
1104abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		case TESSPRIMITIVETYPE_ISOLINES:
1105abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		{
1106abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			int outer[2];
1107abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			getClampedRoundedIsolineTessLevels(spacingMode, &outerLevels[0], &outer[0]);
1108abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			return referenceIsolineNonPointModePrimitiveCount(outer[0], outer[1]);
1109abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		}
1110abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
1111abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		default:
1112abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			DE_ASSERT(false);
1113abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			return 0;
1114abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	}
1115abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski}
1116abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
1117abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowskiint numVerticesPerPrimitive (const TessPrimitiveType primitiveType, const bool usePointMode)
1118abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski{
1119abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	if (usePointMode)
1120abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		return 1;
1121abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
1122abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	switch (primitiveType)
1123abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	{
1124abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		case TESSPRIMITIVETYPE_TRIANGLES:	return 3;
1125abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		case TESSPRIMITIVETYPE_QUADS:		return 3;  // quads are composed of two triangles
1126abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		case TESSPRIMITIVETYPE_ISOLINES:	return 2;
1127abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		default:
1128abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			DE_ASSERT(false);
1129abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			return 0;
1130abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	}
1131abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski}
1132abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
1133abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowskiint referencePrimitiveCount (const TessPrimitiveType primitiveType, const SpacingMode spacingMode, const bool usePointMode, const float* innerLevels, const float* outerLevels)
1134abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski{
1135abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	return usePointMode ? referencePointModePrimitiveCount		(primitiveType, spacingMode, innerLevels, outerLevels)
1136abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski						: referenceNonPointModePrimitiveCount	(primitiveType, spacingMode, innerLevels, outerLevels);
1137abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski}
1138abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
1139abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski//! In point mode this should return the number of unique vertices, while in non-point mode the maximum theoretical number of verticies.
1140abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski//! Actual implementation will likely return a much smaller number because the shader isn't required to be run for duplicate coordinates.
1141abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowskiint referenceVertexCount (const TessPrimitiveType primitiveType, const SpacingMode spacingMode, const bool usePointMode, const float* innerLevels, const float* outerLevels)
1142abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski{
1143abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	return referencePrimitiveCount(primitiveType, spacingMode, usePointMode, innerLevels, outerLevels)
1144abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		   * numVerticesPerPrimitive(primitiveType, usePointMode);
1145abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski}
1146abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
1147abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowskivoid requireFeatures (const InstanceInterface& vki, const VkPhysicalDevice physDevice, const FeatureFlags flags)
1148abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski{
1149abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	const VkPhysicalDeviceFeatures features = getPhysicalDeviceFeatures(vki, physDevice);
1150abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
1151abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	if (((flags & FEATURE_TESSELLATION_SHADER) != 0) && !features.tessellationShader)
1152abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		throw tcu::NotSupportedError("Tessellation shader not supported");
1153abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
1154abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	if (((flags & FEATURE_GEOMETRY_SHADER) != 0) && !features.geometryShader)
1155abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		throw tcu::NotSupportedError("Geometry shader not supported");
1156abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
1157abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	if (((flags & FEATURE_SHADER_FLOAT_64) != 0) && !features.shaderFloat64)
1158abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		throw tcu::NotSupportedError("Double-precision floats not supported");
1159abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
1160abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	if (((flags & FEATURE_VERTEX_PIPELINE_STORES_AND_ATOMICS) != 0) && !features.vertexPipelineStoresAndAtomics)
1161abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		throw tcu::NotSupportedError("SSBO and image writes not supported in vertex pipeline");
1162abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
1163abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	if (((flags & FEATURE_FRAGMENT_STORES_AND_ATOMICS) != 0) && !features.fragmentStoresAndAtomics)
1164abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		throw tcu::NotSupportedError("SSBO and image writes not supported in fragment shader");
1165abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
1166abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	if (((flags & FEATURE_SHADER_TESSELLATION_AND_GEOMETRY_POINT_SIZE) != 0) && !features.shaderTessellationAndGeometryPointSize)
1167abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		throw tcu::NotSupportedError("Tessellation and geometry shaders don't support PointSize built-in");
1168abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski}
1169abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
1170abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski} // tessellation
1171abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski} // vkt
1172