• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*-------------------------------------------------------------------------
2  * Vulkan Conformance Tests
3  * ------------------------
4  *
5  * Copyright (c) 2017 Google Inc.
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  *
19  *//*!
20  * \file
21  * \brief Shader cross-stage interface tests
22  *//*--------------------------------------------------------------------*/
23 
24 #include "vktSpvAsmCrossStageInterfaceTests.hpp"
25 
26 #include "tcuTestLog.hpp"
27 #include "tcuTextureUtil.hpp"
28 #include "tcuImageCompare.hpp"
29 
30 #include "vkDefs.hpp"
31 #include "vkMemUtil.hpp"
32 #include "deSharedPtr.hpp"
33 #include "vkQueryUtil.hpp"
34 #include "vkRefUtil.hpp"
35 #include "vkStrUtil.hpp"
36 #include "vkTypeUtil.hpp"
37 #include "vkImageUtil.hpp"
38 #include "vkCmdUtil.hpp"
39 #include "vkObjUtil.hpp"
40 
41 #include "deUniquePtr.hpp"
42 
43 #include "vktSpvAsmGraphicsShaderTestUtil.hpp"
44 #include "vktTestCaseUtil.hpp"
45 #include "vktTestGroupUtil.hpp"
46 
47 #include <map>
48 #include <vector>
49 
50 namespace vkt
51 {
52 namespace SpirVAssembly
53 {
54 using namespace vk;
55 
56 namespace
57 {
58 using std::string;
59 using std::map;
60 using std::vector;
61 
62 typedef de::SharedPtr<Unique<VkShaderModule> >	ShaderModuleSP;
63 using de::MovePtr;
64 
65 using tcu::Vec4;
66 
67 enum TestType
68 {
69 	TEST_TYPE_FLAT = 0,
70 	TEST_TYPE_NOPERSPECTIVE,
71 	TEST_TYPE_RELAXEDPRECISION,
72 	TEST_TYPE_LAST
73 };
74 
75 struct TestParameters
76 {
TestParametersvkt::SpirVAssembly::__anon308ac4990111::TestParameters77 	TestParameters (TestType q, size_t s)
78 		:testOptions	(s)
79 		,qualifier		(q)
80 	{}
81 	vector<int>		testOptions;
82 	TestType		qualifier;
83 };
84 
makeImageCreateInfo(const VkImageType imageType,const VkExtent3D & extent,const VkFormat format,const VkImageUsageFlags usage,deUint32 queueFamilyIndex)85 VkImageCreateInfo makeImageCreateInfo (const VkImageType imageType, const VkExtent3D& extent, const VkFormat format, const VkImageUsageFlags usage, deUint32 queueFamilyIndex)
86 {
87 	const VkImageCreateInfo imageInfo	=
88 	{
89 		VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,		// VkStructureType			sType;
90 		DE_NULL,									// const void*				pNext;
91 		(VkImageCreateFlags)0,						// VkImageCreateFlags		flags;
92 		imageType,									// VkImageType				imageType;
93 		format,										// VkFormat					format;
94 		{extent.width, extent.height, 1u},			// VkExtent3D				extent;
95 		1u,											// uint32_t					mipLevels;
96 		extent.depth,								// uint32_t					arrayLayers;
97 		VK_SAMPLE_COUNT_1_BIT,						// VkSampleCountFlagBits	samples;
98 		VK_IMAGE_TILING_OPTIMAL,					// VkImageTiling			tiling;
99 		usage,										// VkImageUsageFlags		usage;
100 		VK_SHARING_MODE_EXCLUSIVE,					// VkSharingMode			sharingMode;
101 		1u,											// uint32_t					queueFamilyIndexCount;
102 		&queueFamilyIndex,							// const uint32_t*			pQueueFamilyIndices;
103 		VK_IMAGE_LAYOUT_UNDEFINED,					// VkImageLayout			initialLayout;
104 	};
105 	return imageInfo;
106 }
107 
imageBarrier(const DeviceInterface & vk,const VkCommandBuffer cmdBuffer,const VkImage image,const VkImageSubresourceRange subresourceRange,const VkImageLayout oldLayout,const VkImageLayout newLayout,const VkAccessFlags srcAccessMask,const VkAccessFlags dstAccessMask,const VkPipelineStageFlags srcStageMask,const VkPipelineStageFlags dstStageMask)108 void imageBarrier (const DeviceInterface&			vk,
109 				   const VkCommandBuffer			cmdBuffer,
110 				   const VkImage					image,
111 				   const VkImageSubresourceRange	subresourceRange,
112 				   const VkImageLayout				oldLayout,
113 				   const VkImageLayout				newLayout,
114 				   const VkAccessFlags				srcAccessMask,
115 				   const VkAccessFlags				dstAccessMask,
116 				   const VkPipelineStageFlags		srcStageMask,
117 				   const VkPipelineStageFlags		dstStageMask)
118 {
119 	const VkImageMemoryBarrier		barrier				=
120 	{
121 		VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,	// VkStructureType			sType;
122 		DE_NULL,								// const void*				pNext;
123 		srcAccessMask,							// VkAccessFlags			srcAccessMask;
124 		dstAccessMask,							// VkAccessFlags			dstAccessMask;
125 		oldLayout,								// VkImageLayout			oldLayout;
126 		newLayout,								// VkImageLayout			newLayout;
127 		VK_QUEUE_FAMILY_IGNORED,				// deUint32					srcQueueFamilyIndex;
128 		VK_QUEUE_FAMILY_IGNORED,				// deUint32					dstQueueFamilyIndex;
129 		image,									// VkImage					image;
130 		subresourceRange,						// VkImageSubresourceRange	subresourceRange;
131 	};
132 
133 	vk.cmdPipelineBarrier(cmdBuffer, srcStageMask, dstStageMask, (VkDependencyFlags)0, 0u, (const VkMemoryBarrier*)DE_NULL,
134 		0u, (const VkBufferMemoryBarrier*)DE_NULL,
135 		1u, &barrier);
136 }
137 
138 class CrossStageTestInstance : public TestInstance
139 {
140 public:
CrossStageTestInstance(Context & context,const TestParameters & parameters)141 	CrossStageTestInstance	(Context& context, const TestParameters& parameters)
142 	: TestInstance		(context)
143 	, m_parameters		(parameters)
144 	, m_verticesCount	(4u)
145 	, m_data			(2u * m_verticesCount)
146 	, m_colorFormat		(VK_FORMAT_R8G8B8A8_UNORM)
147 	, m_colorRed		(1.0f, 0.0f, 0.0f, 1.0f)
148 	, m_colorGreen		(0.0f, 1.0f, 0.0f, 1.0f)
149 	{
150 		createVertexData();
151 		m_extent.width	= 51u;
152 		m_extent.height	= 51u;
153 		m_extent.depth	= 1u;
154 	}
155 enum
156 {
157 	DECORATION_IN_VERTEX = 0,
158 	DECORATION_IN_FRAGMENT,
159 	DECORATION_IN_ALL_SHADERS,
160 	DECORATION_LAST
161 };
162 protected:
163 	tcu::TestStatus			iterate					(void);
164 private:
165 	void					createVertexData		(void);
166 	void					makeShaderModule		(map<VkShaderStageFlagBits, ShaderModuleSP>&	shaderModule,
167 													 const VkShaderStageFlagBits					stageFlag,
168 													 const int										optionNdx);
169 
170 	Move<VkPipeline>		makeGraphicsPipeline	(const VkRenderPass								renderPass,
171 													 const VkPipelineLayout							pipelineLayout,
172 													 const VkShaderStageFlagBits					stageFlags,
173 													 map<VkShaderStageFlagBits, ShaderModuleSP>&	shaderModules,
174 													 const VkPrimitiveTopology						primitiveTopology);
175 
176 	bool					checkImage				(VkImage										image,
177 													 VkCommandBuffer								cmdBuffer,
178 													 const string&									description,
179 													 const tcu::Texture2DArray&						referenceFrame);
180 	void					interpolationFill		(tcu::Texture2DArray&							referenceFrame);
181 	void					perspectiveFill			(tcu::Texture2DArray&							referenceFrame);
182 	void					redFill					(tcu::Texture2DArray&							referenceFrame);
183 
184 	const TestParameters	m_parameters;
185 	const deUint32			m_verticesCount;
186 	vector<Vec4>			m_data;
187 	VkExtent3D				m_extent;
188 	const VkFormat			m_colorFormat;
189 	const Vec4				m_colorRed;
190 	const Vec4				m_colorGreen;
191 };
192 
iterate(void)193 tcu::TestStatus CrossStageTestInstance::iterate (void)
194 {
195 	const DeviceInterface&					vk						= m_context.getDeviceInterface();
196 	const VkDevice							vkDevice				= m_context.getDevice();
197 	const VkPhysicalDeviceFeatures&			features				= m_context.getDeviceFeatures();
198 	const bool								supportsGeometry		= features.geometryShader == VK_TRUE;
199 	const bool								supportsTessellation	= features.tessellationShader == VK_TRUE;
200 	const VkDeviceSize						vertexDataSize			= static_cast<VkDeviceSize>(deAlignSize(static_cast<size_t>( m_data.size() * sizeof(Vec4)),
201 																		static_cast<size_t>(m_context.getDeviceProperties().limits.nonCoherentAtomSize)));
202 	const VkBufferCreateInfo				bufferInfo				= makeBufferCreateInfo(vertexDataSize, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT);
203 	Move<VkBuffer>							vertexBuffer			= createBuffer(vk, vkDevice, &bufferInfo);
204 	MovePtr<Allocation>						allocationVertex		= m_context.getDefaultAllocator().allocate(getBufferMemoryRequirements(vk, vkDevice, *vertexBuffer),  MemoryRequirement::HostVisible);
205 
206 	const VkImageSubresourceRange			imageSubresourceRange	= makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u);
207 	const VkImageCreateInfo					colorAttachmentInfo		= makeImageCreateInfo(VK_IMAGE_TYPE_2D, m_extent, m_colorFormat,
208 																		VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT, m_context.getUniversalQueueFamilyIndex());
209 
210 	Move<VkImage>							colorAttachmentImage	= createImage(vk, vkDevice, &colorAttachmentInfo);
211 	MovePtr<Allocation>						allocationAttachment	= m_context.getDefaultAllocator().allocate(getImageMemoryRequirements(vk, vkDevice, *colorAttachmentImage), MemoryRequirement::Any);
212 	VK_CHECK(vk.bindImageMemory(vkDevice, *colorAttachmentImage, allocationAttachment->getMemory(), allocationAttachment->getOffset()));
213 	Move<VkImageView>						colorAttachmentView		= makeImageView(vk, vkDevice, *colorAttachmentImage, VK_IMAGE_VIEW_TYPE_2D, m_colorFormat, imageSubresourceRange);
214 
215 	MovePtr<tcu::Texture2DArray>			referenceImage1			= MovePtr<tcu::Texture2DArray>(new tcu::Texture2DArray(mapVkFormat(m_colorFormat), m_extent.width, m_extent.height, m_extent.depth));
216 	MovePtr<tcu::Texture2DArray>			referenceImage2			= MovePtr<tcu::Texture2DArray>(new tcu::Texture2DArray(mapVkFormat(m_colorFormat), m_extent.width, m_extent.height, m_extent.depth));
217 
218 	// Init host buffer data
219 	VK_CHECK(vk.bindBufferMemory(vkDevice, *vertexBuffer, allocationVertex->getMemory(), allocationVertex->getOffset()));
220 	deMemcpy(allocationVertex->getHostPtr(), m_data.data(), static_cast<size_t>(vertexDataSize));
221 	flushAlloc(vk, vkDevice, *allocationVertex);
222 
223 	Move<VkRenderPass>						renderPass				= makeRenderPass (vk, vkDevice, m_colorFormat);
224 	Move<VkFramebuffer>						frameBuffer				= makeFramebuffer (vk, vkDevice, *renderPass, *colorAttachmentView, m_extent.width, m_extent.height);
225 	Move<VkPipelineLayout>					pipelineLayout			= makePipelineLayout (vk, vkDevice);
226 	Move<VkCommandPool>						cmdPool;
227 	Move<VkCommandBuffer>					cmdBuffer;
228 
229 	// cmdPool
230 	{
231 		const VkCommandPoolCreateInfo cmdPoolParams =
232 		{
233 			VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,			// VkStructureType		sType;
234 			DE_NULL,											// const void*			pNext;
235 			VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT,	// VkCmdPoolCreateFlags	flags;
236 			m_context.getUniversalQueueFamilyIndex(),			// deUint32				queueFamilyIndex;
237 		};
238 		cmdPool = createCommandPool(vk, vkDevice, &cmdPoolParams);
239 	}
240 
241 	// cmdBuffer
242 	{
243 		const VkCommandBufferAllocateInfo cmdBufferAllocateInfo =
244 		{
245 			VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,		// VkStructureType		sType;
246 			DE_NULL,											// const void*			pNext;
247 			*cmdPool,											// VkCommandPool		commandPool;
248 			VK_COMMAND_BUFFER_LEVEL_PRIMARY,					// VkCommandBufferLevel	level;
249 			1u,													// deUint32				bufferCount;
250 		};
251 		cmdBuffer	= allocateCommandBuffer(vk, vkDevice, &cmdBufferAllocateInfo);
252 	}
253 
254 	if (!supportsTessellation)
255 		m_context.getTestContext().getLog() << tcu::TestLog::Message << "Tessellation not supported" << tcu::TestLog::EndMessage;
256 
257 	if (!supportsGeometry)
258 		m_context.getTestContext().getLog() << tcu::TestLog::Message << "Geometry not supported" << tcu::TestLog::EndMessage;
259 
260 	vector<deUint32> shadersStagesFlagsBits;
261 	shadersStagesFlagsBits.push_back(VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT);
262 
263 	if (supportsTessellation)
264 		shadersStagesFlagsBits.push_back(VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT | VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT | VK_SHADER_STAGE_FRAGMENT_BIT);
265 
266 	if (supportsGeometry)
267 		shadersStagesFlagsBits.push_back(VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_GEOMETRY_BIT | VK_SHADER_STAGE_FRAGMENT_BIT);
268 
269 	if (supportsTessellation && supportsGeometry)
270 		shadersStagesFlagsBits.push_back(VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT | VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT | VK_SHADER_STAGE_GEOMETRY_BIT | VK_SHADER_STAGE_FRAGMENT_BIT);
271 
272 	referenceImage1->allocLevel(0);
273 	referenceImage2->allocLevel(0);
274 	switch(m_parameters.qualifier)
275 	{
276 	case TEST_TYPE_FLAT:
277 		interpolationFill(*referenceImage1);
278 		redFill(*referenceImage2);
279 		break;
280 	case TEST_TYPE_NOPERSPECTIVE:
281 		perspectiveFill(*referenceImage1);
282 		interpolationFill(*referenceImage2);
283 		break;
284 	case TEST_TYPE_RELAXEDPRECISION:
285 		interpolationFill(*referenceImage1);
286 		interpolationFill(*referenceImage2);
287 		break;
288 	default:
289 		DE_ASSERT(0);
290 	}
291 
292 	for (deUint32 optionNdx = 0; optionNdx < m_parameters.testOptions.size(); optionNdx++)
293 	for (size_t stagesNdx = 0ull; stagesNdx < shadersStagesFlagsBits.size(); stagesNdx++)
294 	{
295 		map<VkShaderStageFlagBits, ShaderModuleSP>	shaderModule;
296 		string										imageDescription;
297 		const VkClearValue							renderPassClearValue = makeClearValueColor(tcu::Vec4(0.0f));
298 		makeShaderModule(shaderModule, (VkShaderStageFlagBits)shadersStagesFlagsBits[stagesNdx], optionNdx);
299 
300 		Move<VkPipeline>			graphicsPipeline		= makeGraphicsPipeline (*renderPass, *pipelineLayout, (VkShaderStageFlagBits)shadersStagesFlagsBits[stagesNdx], shaderModule, ((VkShaderStageFlagBits)shadersStagesFlagsBits[stagesNdx] & VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT) ? VK_PRIMITIVE_TOPOLOGY_PATCH_LIST : VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP);
301 		const VkDeviceSize			vertexBufferOffset		= 0u;
302 
303 		beginCommandBuffer(vk, *cmdBuffer);
304 
305 		imageBarrier(vk, *cmdBuffer, *colorAttachmentImage, imageSubresourceRange,
306 			VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
307 			0u, VK_ACCESS_TRANSFER_WRITE_BIT,
308 			VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT);
309 
310 		vk.cmdClearColorImage(*cmdBuffer, *colorAttachmentImage,  VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &renderPassClearValue.color, 1, &imageSubresourceRange);
311 
312 		imageBarrier(vk, *cmdBuffer, *colorAttachmentImage, imageSubresourceRange,
313 			VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
314 			VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
315 			VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT);
316 
317 		beginRenderPass(vk, *cmdBuffer, *renderPass, *frameBuffer, makeRect2D(0, 0, m_extent.width, m_extent.height), tcu::Vec4(0.0f));
318 
319 		vk.cmdBindVertexBuffers(*cmdBuffer, 0u, 1u, &(*vertexBuffer), &vertexBufferOffset);
320 
321 		vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *graphicsPipeline);
322 
323 		vk.cmdDraw(*cmdBuffer, m_verticesCount, 1u, 0u, 0u);
324 
325 		endRenderPass(vk, *cmdBuffer);
326 
327 		endCommandBuffer(vk, *cmdBuffer);
328 
329 		submitCommandsAndWait(vk, vkDevice, m_context.getUniversalQueue(), *cmdBuffer);
330 
331 		{
332 			const string geometry		= (VK_SHADER_STAGE_GEOMETRY_BIT & (VkShaderStageFlagBits)shadersStagesFlagsBits[stagesNdx]) ? "Geometry->" : "";
333 			const string tessellation	= ( VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT & (VkShaderStageFlagBits)shadersStagesFlagsBits[stagesNdx]) ? "Tessellation->" : "";
334 			imageDescription = "Pipeline: Vertex->" + tessellation +  geometry + "Fragment | ";
335 		}
336 
337 		if (DECORATION_IN_VERTEX == m_parameters.testOptions[optionNdx])
338 			imageDescription+= "decoration in vertex | ";
339 		if (DECORATION_IN_FRAGMENT == m_parameters.testOptions[optionNdx])
340 			imageDescription+= "decoration in fragment | ";
341 		if (DECORATION_IN_ALL_SHADERS == m_parameters.testOptions[optionNdx])
342 			imageDescription+= "decoration in all shaders | ";
343 
344 		{
345 			bool resultComparison = false;
346 			if (TEST_TYPE_RELAXEDPRECISION == m_parameters.qualifier)
347 			{
348 				resultComparison = checkImage(*colorAttachmentImage, *cmdBuffer, imageDescription+" Expected Pass", *referenceImage1);
349 			}
350 			else
351 			{
352 				if (DECORATION_IN_VERTEX == m_parameters.testOptions[optionNdx])
353 					resultComparison = checkImage(*colorAttachmentImage, *cmdBuffer, imageDescription+" Expected Pass", *referenceImage1);
354 				else if ((VkShaderStageFlagBits)(VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT) == (VkShaderStageFlagBits)shadersStagesFlagsBits[stagesNdx])
355 					resultComparison = checkImage(*colorAttachmentImage, *cmdBuffer, imageDescription+" Expected Pass", *referenceImage2);
356 				else
357 					resultComparison = !checkImage(*colorAttachmentImage, *cmdBuffer, imageDescription+" Expected Fail", *referenceImage1);
358 			}
359 
360 			if(!resultComparison)
361 				return tcu::TestStatus::fail("Fail");
362 		}
363 	}
364 	return tcu::TestStatus::pass("Pass");
365 }
366 
createVertexData(void)367 void CrossStageTestInstance::createVertexData (void)
368 {
369 	int ndx = -1;
370 	if (TEST_TYPE_NOPERSPECTIVE == m_parameters.qualifier)
371 		m_data[++ndx] = Vec4(-2.0f,-2.0f, 1.0f, 2.0f);	//position
372 	else
373 		m_data[++ndx] = Vec4(-1.0f,-1.0f, 1.0f, 1.0f);	//position
374 	m_data[++ndx] = m_colorRed;
375 
376 	if (TEST_TYPE_NOPERSPECTIVE == m_parameters.qualifier)
377 		m_data[++ndx] = Vec4(-2.0f, 2.0f, 1.0f, 2.0f);	//position
378 	else
379 		m_data[++ndx] = Vec4(-1.0f, 1.0f, 1.0f, 1.0f);	//position
380 	m_data[++ndx] = m_colorRed;
381 
382 	m_data[++ndx] = Vec4( 1.0f,-1.0f, 1.0f, 1.0f);	//position
383 	m_data[++ndx] = m_colorGreen;
384 
385 	m_data[++ndx] = Vec4( 1.0f, 1.0f, 1.0f, 1.0f);	//position
386 	m_data[++ndx] = m_colorGreen;
387 }
388 
makeShaderModule(map<VkShaderStageFlagBits,ShaderModuleSP> & shaderModule,const VkShaderStageFlagBits stageFlag,const int optionNdx)389 void CrossStageTestInstance::makeShaderModule (map<VkShaderStageFlagBits, ShaderModuleSP>&	shaderModule,
390 											   const VkShaderStageFlagBits					stageFlag,
391 											   const int									optionNdx)
392 {
393 	const DeviceInterface&	vk			= m_context.getDeviceInterface();
394 	const VkDevice			vkDevice	= m_context.getDevice();
395 
396 	std::ostringstream vertex;
397 	vertex<<"vertex"<<optionNdx;
398 	std::ostringstream fragment;
399 	fragment<<"fragment"<<optionNdx;
400 
401 	if (stageFlag & VK_SHADER_STAGE_VERTEX_BIT)
402 		shaderModule[VK_SHADER_STAGE_VERTEX_BIT] = (ShaderModuleSP(new Unique<VkShaderModule>(createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get(vertex.str()), 0))));
403 
404 	if (stageFlag & VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT)
405 		shaderModule[VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT] = (ShaderModuleSP(new Unique<VkShaderModule>(createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("tessellation_control"), 0))));
406 
407 	if (stageFlag & VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT)
408 		shaderModule[VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT] = (ShaderModuleSP(new Unique<VkShaderModule>(createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("tessellation_evaluation"), 0))));
409 
410 	if (stageFlag & VK_SHADER_STAGE_GEOMETRY_BIT)
411 		shaderModule[VK_SHADER_STAGE_GEOMETRY_BIT] = (ShaderModuleSP(new Unique<VkShaderModule>(createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("geometry"), 0))));
412 
413 	if (stageFlag & VK_SHADER_STAGE_FRAGMENT_BIT)
414 		shaderModule[VK_SHADER_STAGE_FRAGMENT_BIT] = (ShaderModuleSP(new Unique<VkShaderModule>(createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get(fragment.str()), 0))));
415 }
416 
makeGraphicsPipeline(const VkRenderPass renderPass,const VkPipelineLayout pipelineLayout,const VkShaderStageFlagBits shaderFlags,map<VkShaderStageFlagBits,ShaderModuleSP> & shaderModules,const VkPrimitiveTopology primitiveTopology)417 Move<VkPipeline> CrossStageTestInstance::makeGraphicsPipeline (const VkRenderPass							renderPass,
418 															   const VkPipelineLayout						pipelineLayout,
419 															   const VkShaderStageFlagBits					shaderFlags,
420 															   map<VkShaderStageFlagBits, ShaderModuleSP>&	shaderModules,
421 															   const VkPrimitiveTopology					primitiveTopology)
422 {
423 	const DeviceInterface&	vk			= m_context.getDeviceInterface();
424 	const VkDevice			vkDevice	= m_context.getDevice();
425 
426 	const VkVertexInputBindingDescription			vertexInputBindingDescription		=
427 	{
428 		0u,										// binding;
429 		static_cast<deUint32>(2u*sizeof(Vec4)),	// stride;
430 		VK_VERTEX_INPUT_RATE_VERTEX				// inputRate
431 	};
432 
433 	const VkVertexInputAttributeDescription			vertexInputAttributeDescriptions[]	=
434 	{
435 		{
436 			0u,
437 			0u,
438 			VK_FORMAT_R32G32B32A32_SFLOAT,
439 			0u
440 		},	// VertexElementData::position
441 		{
442 			1u,
443 			0u,
444 			VK_FORMAT_R32G32B32A32_SFLOAT,
445 			static_cast<deUint32>(sizeof(tcu::Vec4))
446 		},	// VertexElementData::color
447 	};
448 
449 	const VkPipelineVertexInputStateCreateInfo		vertexInputStateParams				=
450 	{																	// sType;
451 		VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,		// pNext;
452 		NULL,															// flags;
453 		0u,																// vertexBindingDescriptionCount;
454 		1u,																// pVertexBindingDescriptions;
455 		&vertexInputBindingDescription,									// vertexAttributeDescriptionCount;
456 		2u,																// pVertexAttributeDescriptions;
457 		vertexInputAttributeDescriptions
458 	};
459 
460 	const std::vector<VkViewport>					viewports							(1, makeViewport(m_extent));
461 	const std::vector<VkRect2D>						scissors							(1, makeRect2D(m_extent));
462 
463 	VkPipelineDepthStencilStateCreateInfo			depthStencilStateParams				=
464 	{
465 		VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO,	// VkStructureType							sType;
466 		DE_NULL,													// const void*								pNext;
467 		0u,															// VkPipelineDepthStencilStateCreateFlags	flags;
468 		VK_TRUE,													// VkBool32									depthTestEnable;
469 		VK_TRUE,													// VkBool32									depthWriteEnable;
470 		VK_COMPARE_OP_LESS_OR_EQUAL,								// VkCompareOp								depthCompareOp;
471 		VK_FALSE,													// VkBool32									depthBoundsTestEnable;
472 		VK_FALSE,													// VkBool32									stencilTestEnable;
473 		// VkStencilOpState front;
474 		{
475 			VK_STENCIL_OP_KEEP,		// VkStencilOp	failOp;
476 			VK_STENCIL_OP_KEEP,		// VkStencilOp	passOp;
477 			VK_STENCIL_OP_KEEP,		// VkStencilOp	depthFailOp;
478 			VK_COMPARE_OP_NEVER,	// VkCompareOp	compareOp;
479 			0u,						// deUint32		compareMask;
480 			0u,						// deUint32		writeMask;
481 			0u,						// deUint32		reference;
482 		},
483 		// VkStencilOpState back;
484 		{
485 			VK_STENCIL_OP_KEEP,		// VkStencilOp	failOp;
486 			VK_STENCIL_OP_KEEP,		// VkStencilOp	passOp;
487 			VK_STENCIL_OP_KEEP,		// VkStencilOp	depthFailOp;
488 			VK_COMPARE_OP_NEVER,	// VkCompareOp	compareOp;
489 			0u,						// deUint32		compareMask;
490 			0u,						// deUint32		writeMask;
491 			0u,						// deUint32		reference;
492 		},
493 		0.0f,	// float	minDepthBounds;
494 		1.0f,	// float	maxDepthBounds;
495 	};
496 
497 	const VkShaderModule	vertShader			= shaderFlags & VK_SHADER_STAGE_VERTEX_BIT ? **shaderModules[VK_SHADER_STAGE_VERTEX_BIT] : DE_NULL;
498 	const VkShaderModule	tessControlShader	= shaderFlags & VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT ? **shaderModules[VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT] : DE_NULL;
499 	const VkShaderModule	tessEvalShader		= shaderFlags & VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT ? **shaderModules[VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT] : DE_NULL;
500 	const VkShaderModule	geomShader			= shaderFlags & VK_SHADER_STAGE_GEOMETRY_BIT ? **shaderModules[VK_SHADER_STAGE_GEOMETRY_BIT] : DE_NULL;
501 	const VkShaderModule	fragShader			= shaderFlags & VK_SHADER_STAGE_FRAGMENT_BIT ? **shaderModules[VK_SHADER_STAGE_FRAGMENT_BIT] : DE_NULL;
502 
503 	return vk::makeGraphicsPipeline(vk,							// const DeviceInterface&                        vk
504 									vkDevice,					// const VkDevice                                device
505 									pipelineLayout,				// const VkPipelineLayout                        pipelineLayout
506 									vertShader,					// const VkShaderModule                          vertexShaderModule
507 									tessControlShader,			// const VkShaderModule                          tessellationControlShaderModule
508 									tessEvalShader,				// const VkShaderModule                          tessellationEvalShaderModule
509 									geomShader,					// const VkShaderModule                          geometryShaderModule
510 									fragShader,					// const VkShaderModule                          fragmentShaderModule
511 									renderPass,					// const VkRenderPass                            renderPass
512 									viewports,					// const std::vector<VkViewport>&                viewports
513 									scissors,					// const std::vector<VkRect2D>&                  scissors
514 									primitiveTopology,			// const VkPrimitiveTopology                     topology
515 									0u,							// const deUint32                                subpass
516 									4u,							// const deUint32                                patchControlPoints
517 									&vertexInputStateParams,	// const VkPipelineVertexInputStateCreateInfo*   vertexInputStateCreateInfo
518 									DE_NULL,					// const VkPipelineRasterizationStateCreateInfo* rasterizationStateCreateInfo
519 									DE_NULL,					// const VkPipelineMultisampleStateCreateInfo*   multisampleStateCreateInfo
520 									&depthStencilStateParams);	// const VkPipelineDepthStencilStateCreateInfo*  depthStencilStateCreateInfo
521 }
522 
checkImage(VkImage image,VkCommandBuffer cmdBuffer,const string & description,const tcu::Texture2DArray & referenceFrame)523 bool CrossStageTestInstance::checkImage (VkImage image, VkCommandBuffer cmdBuffer, const string& description, const tcu::Texture2DArray& referenceFrame)
524 {
525 	const DeviceInterface&		vk				= m_context.getDeviceInterface();
526 	const VkDevice				vkDevice		= m_context.getDevice();
527 	const int					pixelSize		= referenceFrame.getFormat().getPixelSize();
528 	Move<VkBuffer>				buffer;
529 	MovePtr<Allocation>			bufferAlloc;
530 	vector<deUint8>				pixelAccessData	(m_extent.width * m_extent.height * m_extent.depth * pixelSize);
531 	tcu::PixelBufferAccess		dst				(referenceFrame.getFormat(), m_extent.width, m_extent.height, m_extent.depth, pixelAccessData.data());
532 	const VkDeviceSize			pixelDataSize	= dst.getWidth() * dst.getHeight() * dst.getDepth() * pixelSize;
533 
534 	// Create destination buffer
535 	{
536 		const VkBufferCreateInfo bufferParams =
537 		{
538 			VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,		// VkStructureType		sType;
539 			DE_NULL,									// const void*			pNext;
540 			0u,											// VkBufferCreateFlags	flags;
541 			pixelDataSize,								// VkDeviceSize			size;
542 			VK_BUFFER_USAGE_TRANSFER_DST_BIT,			// VkBufferUsageFlags	usage;
543 			VK_SHARING_MODE_EXCLUSIVE,					// VkSharingMode		sharingMode;
544 			0u,											// deUint32				queueFamilyIndexCount;
545 			DE_NULL,									// const deUint32*		pQueueFamilyIndices;
546 		};
547 
548 		buffer		= createBuffer(vk, vkDevice, &bufferParams);
549 		bufferAlloc	= m_context.getDefaultAllocator().allocate(getBufferMemoryRequirements(vk, vkDevice, *buffer), MemoryRequirement::HostVisible);
550 		VK_CHECK(vk.bindBufferMemory(vkDevice, *buffer, bufferAlloc->getMemory(), bufferAlloc->getOffset()));
551 
552 		deMemset(bufferAlloc->getHostPtr(), 0, static_cast<size_t>(pixelDataSize));
553 		flushAlloc(vk, vkDevice, *bufferAlloc);
554 	}
555 
556 	beginCommandBuffer (vk, cmdBuffer);
557 	copyImageToBuffer(vk, cmdBuffer, image, *buffer, tcu::IVec2(m_extent.width, m_extent.height), 0u, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, m_extent.depth);
558 	endCommandBuffer(vk, cmdBuffer);
559 	submitCommandsAndWait(vk, vkDevice, m_context.getUniversalQueue(), cmdBuffer);
560 
561 	// Read buffer data
562 	invalidateAlloc(vk, vkDevice, *bufferAlloc);
563 	tcu::copy(dst, tcu::ConstPixelBufferAccess(dst.getFormat(), dst.getSize(), bufferAlloc->getHostPtr()));
564 
565 	if (tcu::floatThresholdCompare(m_context.getTestContext().getLog(), "Result", description.c_str(), referenceFrame.getLevel(0), dst, tcu::Vec4(0.05f), tcu::COMPARE_LOG_EVERYTHING))
566 		return true;
567 	return false;
568 }
569 
interpolationFill(tcu::Texture2DArray & referenceFrame)570 void CrossStageTestInstance::interpolationFill (tcu::Texture2DArray& referenceFrame)
571 {
572 	for (deUint32 x = 0u; x < m_extent.width; ++x)
573 	{
574 		float u = static_cast<float>(x)/static_cast<float>(m_extent.width - 1);
575 		const Vec4 resultColor (m_colorRed.x() * (1.0f - u) + m_colorGreen.x() * u,
576 								m_colorRed.y() * (1.0f - u) + m_colorGreen.y() * u,
577 								m_colorRed.z() * (1.0f - u) + m_colorGreen.z() * u,
578 								m_colorRed.w() * (1.0f - u) + m_colorGreen.w() * u);
579 
580 		referenceFrame.getLevel(0).setPixel(resultColor,x,0);
581 	}
582 
583 	for (deUint32 y = 0u; y < m_extent.height; ++y)
584 	{
585 		deMemcpy (referenceFrame.getLevel(0).getPixelPtr(0,y), referenceFrame.getLevel(0).getPixelPtr(0,0), m_extent.width * m_extent.depth* referenceFrame.getFormat().getPixelSize());
586 	}
587 }
588 
perspectiveFill(tcu::Texture2DArray & referenceFrame)589 void CrossStageTestInstance::perspectiveFill (tcu::Texture2DArray& referenceFrame)
590 {
591 	float dynamics = 1.732f;
592 	float dynamicChange = 0.732f / static_cast<float>(m_extent.width);
593 	for (deUint32 x = 0u; x < m_extent.width; ++x)
594 	{
595 		float u = static_cast<float>(x)/static_cast<float>(m_extent.width - 1);
596 		const Vec4 resultColor (m_colorRed.x() * (1.0f - dynamics * u) + m_colorGreen.x() * u* dynamics,
597 								m_colorRed.y() * (1.0f - dynamics * u) + m_colorGreen.y() * u* dynamics,
598 								m_colorRed.z() * (1.0f - dynamics * u) + m_colorGreen.z() * u* dynamics,
599 								m_colorRed.w() * (1.0f - dynamics * u) + m_colorGreen.w() * u* dynamics);
600 		dynamics -= dynamicChange;
601 		if (dynamics < 1.0f)
602 			dynamics = 1.0f;
603 
604 		referenceFrame.getLevel(0).setPixel(resultColor,x,0);
605 	}
606 
607 	for (deUint32 y = 0u; y < m_extent.height; ++y)
608 	{
609 		deMemcpy (referenceFrame.getLevel(0).getPixelPtr(0,y), referenceFrame.getLevel(0).getPixelPtr(0,0), m_extent.width * m_extent.depth* referenceFrame.getFormat().getPixelSize());
610 	}
611 }
612 
redFill(tcu::Texture2DArray & referenceFrame)613 void CrossStageTestInstance::redFill (tcu::Texture2DArray& referenceFrame)
614 {
615 	for (deUint32 x = 0u; x < m_extent.width; ++x)
616 		referenceFrame.getLevel(0).setPixel(m_colorRed,x,0);
617 
618 	for (deUint32 y = 0u; y < m_extent.height; ++y)
619 		deMemcpy (referenceFrame.getLevel(0).getPixelPtr(0,y), referenceFrame.getLevel(0).getPixelPtr(0,0), m_extent.width * m_extent.depth* referenceFrame.getFormat().getPixelSize());
620 }
621 
622 struct Decorations
623 {
Decorationsvkt::SpirVAssembly::__anon308ac4990111::Decorations624 	Decorations()
625 	{};
Decorationsvkt::SpirVAssembly::__anon308ac4990111::Decorations626 	Decorations(const string& f, const string& v, const string& o)
627 		: fragment	(f)
628 		, vertex	(v)
629 		, others	(o)
630 	{};
631 	string fragment;
632 	string vertex;
633 	string others;
634 };
635 
636 class CrossStageBasicTestsCase : public vkt::TestCase
637 {
638 public:
CrossStageBasicTestsCase(tcu::TestContext & context,const char * name,const char * description,const TestParameters & parameters)639 	CrossStageBasicTestsCase (tcu::TestContext &context, const char *name, const char *description, const TestParameters& parameters)
640 		: TestCase			(context, name, description)
641 		, m_parameters		(parameters)
642 	{
643 	}
644 private:
645 	vkt::TestInstance*	createInstance		(vkt::Context& context) const;
646 	void				initPrograms		(SourceCollections& programCollection) const;
647 
648 	const TestParameters	m_parameters;
649 
650 };
651 
createInstance(vkt::Context & context) const652 vkt::TestInstance* CrossStageBasicTestsCase::createInstance (vkt::Context& context) const
653 {
654 	return new CrossStageTestInstance(context, m_parameters);
655 }
656 
initPrograms(SourceCollections & programCollection) const657 void CrossStageBasicTestsCase::initPrograms (SourceCollections& programCollection) const
658 {
659 	vector<Decorations> decorations;
660 	string epsilon = "3e-7";
661 	switch(m_parameters.qualifier)
662 	{
663 	case TEST_TYPE_FLAT:
664 		decorations.push_back(Decorations("",
665 								//Vertex
666 								"OpDecorate %color_out Flat\n"
667 								"OpDecorate %color_in Flat\n"
668 								"OpDecorate %r_float_out Flat\n"
669 								"OpDecorate %rg_float_out Flat\n"
670 								"OpDecorate %rgb_float_out Flat\n"
671 								"OpDecorate %rgba_float_out Flat\n",
672 								""));
673 		decorations.push_back(Decorations(//Fragment
674 								"OpDecorate %color_in Flat\n"
675 								"OpDecorate %r_float_in Flat\n"
676 								"OpDecorate %rg_float_in Flat\n"
677 								"OpDecorate %rgb_float_in Flat\n"
678 								"OpDecorate %rgba_float_in Flat\n",
679 								"",
680 								""));
681 
682 		decorations.push_back(Decorations(//Fragment
683 								"OpDecorate %color_in Flat\n"
684 								"OpDecorate %r_float_in Flat\n"
685 								"OpDecorate %rg_float_in Flat\n"
686 								"OpDecorate %rgb_float_in Flat\n"
687 								"OpDecorate %rgba_float_in Flat\n",
688 								//Vertex
689 								"OpDecorate %color_out Flat\n"
690 								"OpDecorate %color_in Flat\n"
691 								"OpDecorate %r_float_out Flat\n"
692 								"OpDecorate %rg_float_out Flat\n"
693 								"OpDecorate %rgb_float_out Flat\n"
694 								"OpDecorate %rgba_float_out Flat\n",
695 								""));
696 		epsilon = "0.0";
697 		break;
698 	case TEST_TYPE_NOPERSPECTIVE:
699 		decorations.push_back(Decorations("",
700 								//Vertex
701 								"OpDecorate %color_out NoPerspective\n"
702 								"OpDecorate %color_in NoPerspective\n"
703 								"OpDecorate %r_float_out NoPerspective\n"
704 								"OpDecorate %rg_float_out NoPerspective\n"
705 								"OpDecorate %rgb_float_out NoPerspective\n"
706 								"OpDecorate %rgba_float_out NoPerspective\n",
707 								""));
708 
709 		decorations.push_back(Decorations(//Fragment
710 								"OpDecorate %color_in NoPerspective\n"
711 								"OpDecorate %r_float_in NoPerspective\n"
712 								"OpDecorate %rg_float_in NoPerspective\n"
713 								"OpDecorate %rgb_float_in NoPerspective\n"
714 								"OpDecorate %rgba_float_in NoPerspective\n",
715 								"",
716 								""));
717 
718 		decorations.push_back(Decorations(//Fragment
719 								"OpDecorate %color_in NoPerspective\n"
720 								"OpDecorate %r_float_in NoPerspective\n"
721 								"OpDecorate %rg_float_in NoPerspective\n"
722 								"OpDecorate %rgb_float_in NoPerspective\n"
723 								"OpDecorate %rgba_float_in NoPerspective\n",
724 								//Vertex
725 								"OpDecorate %color_out NoPerspective\n"
726 								"OpDecorate %color_in NoPerspective\n"
727 								"OpDecorate %r_float_out NoPerspective\n"
728 								"OpDecorate %rg_float_out NoPerspective\n"
729 								"OpDecorate %rgb_float_out NoPerspective\n"
730 								"OpDecorate %rgba_float_out NoPerspective\n",
731 								//Others
732 								""));
733 		break;
734 	case TEST_TYPE_RELAXEDPRECISION:
735 		decorations.push_back(Decorations(//Fragment
736 								"OpDecorate %color_out RelaxedPrecision\n"
737 								"OpDecorate %color_in RelaxedPrecision\n"
738 								"OpDecorate %r_float_in RelaxedPrecision\n"
739 								"OpDecorate %rg_float_in RelaxedPrecision\n"
740 								"OpDecorate %rgb_float_in RelaxedPrecision\n"
741 								"OpDecorate %rgba_float_in RelaxedPrecision\n",
742 								//Vertex
743 								"OpDecorate %color_out RelaxedPrecision\n"
744 								"OpDecorate %color_in RelaxedPrecision\n"
745 								"OpDecorate %r_float_out RelaxedPrecision\n"
746 								"OpDecorate %rg_float_out RelaxedPrecision\n"
747 								"OpDecorate %rgb_float_out RelaxedPrecision\n"
748 								"OpDecorate %rgba_float_out RelaxedPrecision\n",
749 								//Others
750 								"OpDecorate %color_out RelaxedPrecision\n"
751 								"OpDecorate %color_in RelaxedPrecision\n"
752 								"OpDecorate %r_float_out RelaxedPrecision\n"
753 								"OpDecorate %rg_float_out RelaxedPrecision\n"
754 								"OpDecorate %rgb_float_out RelaxedPrecision\n"
755 								"OpDecorate %rgba_float_out RelaxedPrecision\n"
756 								"OpDecorate %r_float_in RelaxedPrecision\n"
757 								"OpDecorate %rg_float_in RelaxedPrecision\n"
758 								"OpDecorate %rgb_float_in RelaxedPrecision\n"
759 								"OpDecorate %rgba_float_in RelaxedPrecision\n"));
760 		epsilon = "2e-3";
761 		break;
762 	default:
763 		DE_ASSERT(0);
764 	}
765 
766 	//Spir-v spec: decoration flat can be used only in Shader (fragment or vertex)
767 	for (deUint32 ndx = 0; ndx < decorations.size(); ++ndx)
768 	{
769 
770 		/*#version 450
771 		layout(location = 0) in highp vec4 in_position;
772 		layout(location = 1) in vec4 in_color;
773 		layout(location = 0) out vec4 out_color;
774 		layout(location = 1) out float		r_float_out;
775 		layout(location = 2) out vec2		rg_float_out;
776 		layout(location = 3) out vec3		rgb_float_out;
777 		layout(location = 4) out vec4		rgba_float_out;
778 		void main (void)
779 		{
780 			gl_Position = in_position;
781 			out_color = in_color;
782 			r_float_out = in_color.r;
783 			rg_float_out = vec2(in_color.r, in_color.g);
784 			rgb_float_out = vec3(in_color.r, in_color.g,in_color.b);
785 			rgba_float_out = vec4(in_color.r, in_color.g, in_color.b, in_color.a);
786 		}
787 		*/
788 		const string vertexShaderSource =
789 		"; SPIR-V\n"
790 		"; Version: 1.3\n"
791 		"; Generator: Khronos Glslang Reference Front End; 2\n"
792 		"; Bound: 60\n"
793 		"; Schema: 0\n"
794 		"OpCapability Shader\n"
795 		"%1 = OpExtInstImport \"GLSL.std.450\"\n"
796 		"OpMemoryModel Logical GLSL450\n"
797 		"OpEntryPoint Vertex %4 \"main\" %13 %17 %color_out %color_in %r_float_out %rg_float_out %rgb_float_out %rgba_float_out\n"
798 		"OpMemberDecorate %11 0 BuiltIn Position\n"
799 		"OpMemberDecorate %11 1 BuiltIn PointSize\n"
800 		"OpMemberDecorate %11 2 BuiltIn ClipDistance\n"
801 		"OpMemberDecorate %11 3 BuiltIn CullDistance\n"
802 		"OpDecorate %11 Block\n"
803 		"OpDecorate %17 Location 0\n"
804 		"OpDecorate %color_out Location 0\n"
805 		"OpDecorate %color_in Location 1\n"
806 		"OpDecorate %r_float_out Location 1\n"
807 		"OpDecorate %rg_float_out Location 2\n"
808 		"OpDecorate %rgb_float_out Location 3\n"
809 		"OpDecorate %rgba_float_out Location 4\n"
810 		+decorations[ndx].vertex+
811 		"%2 = OpTypeVoid\n"
812 		"%3 = OpTypeFunction %2\n"
813 		"%6 = OpTypeFloat 32\n"
814 		"%7 = OpTypeVector %6 4\n"
815 		"%8 = OpTypeInt 32 0\n"
816 		"%9 = OpConstant %8 1\n"
817 		"%10 = OpTypeArray %6 %9\n"
818 		"%11 = OpTypeStruct %7 %6 %10 %10\n"
819 		"%12 = OpTypePointer Output %11\n"
820 		"%13 = OpVariable %12 Output\n"
821 		"%14 = OpTypeInt 32 1\n"
822 		"%15 = OpConstant %14 0\n"
823 		"%16 = OpTypePointer Input %7\n"
824 		"%17 = OpVariable %16 Input\n"
825 		"%19 = OpTypePointer Output %7\n"
826 		"%color_out = OpVariable %19 Output\n"
827 		"%color_in = OpVariable %16 Input\n"
828 		"%24 = OpTypePointer Output %6\n"
829 		"%r_float_out = OpVariable %24 Output\n"
830 		"%26 = OpConstant %8 0\n"
831 		"%27 = OpTypePointer Input %6\n"
832 		"%30 = OpTypeVector %6 2\n"
833 		"%31 = OpTypePointer Output %30\n"
834 		"%rg_float_out = OpVariable %31 Output\n"
835 		"%38 = OpTypeVector %6 3\n"
836 		"%39 = OpTypePointer Output %38\n"
837 		"%rgb_float_out = OpVariable %39 Output\n"
838 		"%45 = OpConstant %8 2\n"
839 		"%rgba_float_out = OpVariable %19 Output\n"
840 		"%56 = OpConstant %8 3\n"
841 		"%4 = OpFunction %2 None %3\n"
842 		"%5 = OpLabel\n"
843 		"%18 = OpLoad %7 %17\n"
844 		"%20 = OpAccessChain %19 %13 %15\n"
845 		"OpStore %20 %18\n"
846 		"%23 = OpLoad %7 %color_in\n"
847 		"OpStore %color_out %23\n"
848 		"%28 = OpAccessChain %27 %color_in %26\n"
849 		"%29 = OpLoad %6 %28\n"
850 		"OpStore %r_float_out %29\n"
851 		"%33 = OpAccessChain %27 %color_in %26\n"
852 		"%34 = OpLoad %6 %33\n"
853 		"%35 = OpAccessChain %27 %color_in %9\n"
854 		"%36 = OpLoad %6 %35\n"
855 		"%37 = OpCompositeConstruct %30 %34 %36\n"
856 		"OpStore %rg_float_out %37\n"
857 		"%41 = OpAccessChain %27 %color_in %26\n"
858 		"%42 = OpLoad %6 %41\n"
859 		"%43 = OpAccessChain %27 %color_in %9\n"
860 		"%44 = OpLoad %6 %43\n"
861 		"%46 = OpAccessChain %27 %color_in %45\n"
862 		"%47 = OpLoad %6 %46\n"
863 		"%48 = OpCompositeConstruct %38 %42 %44 %47\n"
864 		"OpStore %rgb_float_out %48\n"
865 		"%50 = OpAccessChain %27 %color_in %26\n"
866 		"%51 = OpLoad %6 %50\n"
867 		"%52 = OpAccessChain %27 %color_in %9\n"
868 		"%53 = OpLoad %6 %52\n"
869 		"%54 = OpAccessChain %27 %color_in %45\n"
870 		"%55 = OpLoad %6 %54\n"
871 		"%57 = OpAccessChain %27 %color_in %56\n"
872 		"%58 = OpLoad %6 %57\n"
873 		"%59 = OpCompositeConstruct %7 %51 %53 %55 %58\n"
874 		"OpStore %rgba_float_out %59\n"
875 		"OpReturn\n"
876 		"OpFunctionEnd\n";
877 
878 		/* #version 450
879 		layout(location = 0) out vec4  color_out;
880 		layout(location = 0) in vec4   color_in;
881 		layout(location = 1) in float  r_float_in;
882 		layout(location = 2) in vec2   rg_float_in;
883 		layout(location = 3) in vec3   rgb_float_in;
884 		layout(location = 4) in vec4   rgba_float_in;
885 		void main()
886 		{
887 			float epsilon = 3e-7; // or 0.0 for flat, or 2e-3 for RelaxedPrecision (mediump)
888 			color_out = color_in;
889 			float epsilon_float = max(abs(r_float_in), abs(color_in.r)) * epsilon;
890 			if(abs(r_float_in - color_in.r) > epsilon_float)
891 				color_out.r = 1.0f;
892 			vec2 epsilon_vec2 = max(abs(rg_float_in), abs(color_in.rg)) * epsilon;
893 			if(any(greaterThan(abs(rg_float_in - color_in.rg), epsilon_vec2)))
894 				color_out.rg = vec2(1.0f);
895 			vec3 epsilon_vec3 = max(abs(rgb_float_in), abs(color_in.rgb)) * epsilon;
896 			if(any(greaterThan(abs(rgb_float_in - color_in.rgb), epsilon_vec3)))
897 				color_out.rgb = vec3(1.0f);
898 			vec4 epsilon_vec4 = max(abs(rgba_float_in), abs(color_in.rgba)) * epsilon;
899 			if(any(greaterThan(abs(rgba_float_in - color_in.rgba), epsilon_vec4)))
900 				color_out.rgba = vec4(1.0f);
901 		}
902 		*/
903 
904 		const string fragmentShaderSource =
905 		"; SPIR-V\n"
906 		"; Version: 1.3\n"
907 		"; Generator: Khronos Glslang Reference Front End; 2\n"
908 		"; Bound: 64\n"
909 		"; Schema: 0\n"
910 		"OpCapability Shader\n"
911 		"%1 = OpExtInstImport \"GLSL.std.450\"\n"
912 		"OpMemoryModel Logical GLSL450\n"
913 		"OpEntryPoint Fragment %4 \"main\" %color_out %color_in %r_float_in %rg_float_in %rgb_float_in %rgba_float_in\n"
914 		"OpExecutionMode %4 OriginUpperLeft\n"
915 		"OpDecorate %color_out Location 0\n"
916 		"OpDecorate %color_in Location 0\n"
917 		"OpDecorate %r_float_in Location 1\n"
918 		"OpDecorate %rg_float_in Location 2\n"
919 		"OpDecorate %rgb_float_in Location 3\n"
920 		"OpDecorate %rgba_float_in Location 4\n"
921 		+decorations[ndx].fragment+
922 		"%2 = OpTypeVoid\n"
923 		"%3 = OpTypeFunction %2\n"
924 		"%6 = OpTypeFloat 32\n"
925 		"%7 = OpTypeVector %6 4\n"
926 		"%8 = OpTypePointer Output %7\n"
927 		"%color_out = OpVariable %8 Output\n"
928 		"%10 = OpTypePointer Input %7\n"
929 		"%color_in = OpVariable %10 Input\n"
930 		"%13 = OpTypePointer Input %6\n"
931 		"%r_float_in = OpVariable %13 Input\n"
932 		"%16 = OpTypeInt 32 0\n"
933 		"%17 = OpConstant %16 0\n"
934 		"%20 = OpTypeBool\n"
935 		"%ep = OpConstant %6 " + epsilon + "\n"
936 		"%24 = OpConstant %6 1\n"
937 		"%25 = OpTypePointer Output %6\n"
938 		"%27 = OpTypeVector %6 2\n"
939 		"%28 = OpTypePointer Input %27\n"
940 		"%rg_float_in = OpVariable %28 Input\n"
941 		"%ep2 = OpConstantComposite %27 %ep %ep\n"
942 		"%33 = OpTypeVector %20 2\n"
943 		"%38 = OpConstantComposite %27 %24 %24\n"
944 		"%41 = OpTypeVector %6 3\n"
945 		"%42 = OpTypePointer Input %41\n"
946 		"%rgb_float_in = OpVariable %42 Input\n"
947 		"%ep3 = OpConstantComposite %41 %ep %ep %ep\n"
948 		"%47 = OpTypeVector %20 3\n"
949 		"%52 = OpConstantComposite %41 %24 %24 %24\n"
950 		"%rgba_float_in = OpVariable %10 Input\n"
951 		"%ep4 = OpConstantComposite %7 %ep %ep %ep %ep\n"
952 		"%58 = OpTypeVector %20 4\n"
953 		"%63 = OpConstantComposite %7 %24 %24 %24 %24\n"
954 		"%4 = OpFunction %2 None %3\n"
955 		"%5 = OpLabel\n"
956 		"%12 = OpLoad %7 %color_in\n"
957 		"OpStore %color_out %12\n"
958 		"%15 = OpLoad %6 %r_float_in\n"
959 		"%18 = OpAccessChain %13 %color_in %17\n"
960 		"%19 = OpLoad %6 %18\n"
961 		"%sub = OpFSub %6 %15 %19\n"
962 		"%abs = OpExtInst %6 %1 FAbs %sub\n"
963 		"%ep1abs0 = OpExtInst %6 %1 FAbs %15\n"
964 		"%ep1abs1 = OpExtInst %6 %1 FAbs %19\n"
965 		"%ep1gt = OpFOrdGreaterThan %20 %ep1abs0 %ep1abs1\n"
966 		"%ep1max = OpSelect %6 %ep1gt %ep1abs0 %ep1abs1\n"
967 		"%ep1rel = OpFMul %6 %ep1max %ep\n"
968 		"%cmp = OpFOrdGreaterThan %20 %abs %ep1rel\n"
969 		"OpSelectionMerge %23 None\n"
970 		"OpBranchConditional %cmp %22 %23\n"
971 		"%22 = OpLabel\n"
972 		"%26 = OpAccessChain %25 %color_out %17\n"
973 		"OpStore %26 %24\n"
974 		"OpBranch %23\n"
975 		"%23 = OpLabel\n"
976 		"%30 = OpLoad %27 %rg_float_in\n"
977 		"%31 = OpLoad %7 %color_in\n"
978 		"%32 = OpVectorShuffle %27 %31 %31 0 1\n"
979 		"%sub2 = OpFSub %27 %30 %32\n"
980 		"%abs2 = OpExtInst %27 %1 FAbs %sub2\n"
981 		"%ep2abs0 = OpExtInst %27 %1 FAbs %30\n"
982 		"%ep2abs1 = OpExtInst %27 %1 FAbs %32\n"
983 		"%ep2gt = OpFOrdGreaterThan %33 %ep2abs0 %ep2abs1\n"
984 		"%ep2max = OpSelect %27 %ep2gt %ep2abs0 %ep2abs1\n"
985 		"%ep2rel = OpFMul %27 %ep2max %ep2\n"
986 		"%cmp2 = OpFOrdGreaterThan %33 %abs2 %ep2rel\n"
987 		"%35 = OpAny %20 %cmp2\n"
988 		"OpSelectionMerge %37 None\n"
989 		"OpBranchConditional %35 %36 %37\n"
990 		"%36 = OpLabel\n"
991 		"%39 = OpLoad %7 %color_out\n"
992 		"%40 = OpVectorShuffle %7 %39 %38 4 5 2 3\n"
993 		"OpStore %color_out %40\n"
994 		"OpBranch %37\n"
995 		"%37 = OpLabel\n"
996 		"%44 = OpLoad %41 %rgb_float_in\n"
997 		"%45 = OpLoad %7 %color_in\n"
998 		"%46 = OpVectorShuffle %41 %45 %45 0 1 2\n"
999 		"%sub3 = OpFSub %41 %44 %46\n"
1000 		"%abs3 = OpExtInst %41 %1 FAbs %sub3\n"
1001 		"%ep3abs0 = OpExtInst %41 %1 FAbs %44\n"
1002 		"%ep3abs1 = OpExtInst %41 %1 FAbs %46\n"
1003 		"%ep3gt = OpFOrdGreaterThan %47 %ep3abs0 %ep3abs1\n"
1004 		"%ep3max = OpSelect %41 %ep3gt %ep3abs0 %ep3abs1\n"
1005 		"%ep3rel = OpFMul %41 %ep3max %ep3\n"
1006 		"%cmp3 = OpFOrdGreaterThan %47 %abs3 %ep3rel\n"
1007 		"%49 = OpAny %20 %cmp3\n"
1008 		"OpSelectionMerge %51 None\n"
1009 		"OpBranchConditional %49 %50 %51\n"
1010 		"%50 = OpLabel\n"
1011 		"%53 = OpLoad %7 %color_out\n"
1012 		"%54 = OpVectorShuffle %7 %53 %52 4 5 6 3\n"
1013 		"OpStore %color_out %54\n"
1014 		"OpBranch %51\n"
1015 		"%51 = OpLabel\n"
1016 		"%56 = OpLoad %7 %rgba_float_in\n"
1017 		"%57 = OpLoad %7 %color_in\n"
1018 		"%sub4 = OpFSub %7 %56 %57\n"
1019 		"%abs4 = OpExtInst %7 %1 FAbs %sub4\n"
1020 		"%ep4abs0 = OpExtInst %7 %1 FAbs %56\n"
1021 		"%ep4abs1 = OpExtInst %7 %1 FAbs %57\n"
1022 		"%ep4gt = OpFOrdGreaterThan %58 %ep4abs0 %ep4abs1\n"
1023 		"%ep4max = OpSelect %7 %ep4gt %ep4abs0 %ep4abs1\n"
1024 		"%ep4rel = OpFMul %7 %ep4max %ep4\n"
1025 		"%cmp4 = OpFOrdGreaterThan %58 %abs4 %ep4rel\n"
1026 		"%60 = OpAny %20 %cmp4\n"
1027 		"OpSelectionMerge %62 None\n"
1028 		"OpBranchConditional %60 %61 %62\n"
1029 		"%61 = OpLabel\n"
1030 		"OpStore %color_out %63\n"
1031 		"OpBranch %62\n"
1032 		"%62 = OpLabel\n"
1033 		"OpReturn\n"
1034 		"OpFunctionEnd\n";
1035 
1036 		std::ostringstream vertex;
1037 		vertex << "vertex" << ndx;
1038 		std::ostringstream fragment;
1039 		fragment << "fragment" << ndx;
1040 
1041 		programCollection.spirvAsmSources.add(vertex.str()) << vertexShaderSource;
1042 		programCollection.spirvAsmSources.add(fragment.str()) << fragmentShaderSource;
1043 	}
1044 	{
1045 		/*#version 450
1046 		#extension GL_EXT_tessellation_shader : require
1047 		layout(vertices = 4) out;
1048 		layout(location = 0) in vec4		in_color[];
1049 		layout(location = 1) in float		r_float_in[];
1050 		layout(location = 2) in vec2		rg_float_in[];
1051 		layout(location = 3) in vec3		rgb_float_in[];
1052 		layout(location = 4) in vec4		rgba_float_in[];
1053 		layout(location = 0) out vec4		out_color[];
1054 		layout(location = 1) out float		r_float_out[];
1055 		layout(location = 2) out vec2		rg_float_out[];
1056 		layout(location = 3) out vec3		rgb_float_out[];
1057 		layout(location = 4) out vec4		rgba_float_out[];
1058 		void main (void)
1059 		{
1060 			if ( gl_InvocationID == 0 )
1061 			{
1062 				gl_TessLevelInner[0] = 4.0f;
1063 				gl_TessLevelInner[1] = 4.0f;
1064 				gl_TessLevelOuter[0] = 4.0f;
1065 				gl_TessLevelOuter[1] = 4.0f;
1066 				gl_TessLevelOuter[2] = 4.0f;
1067 				gl_TessLevelOuter[3] = 4.0f;
1068 			}
1069 			out_color[gl_InvocationID] = in_color[gl_InvocationID];
1070 			r_float_out[gl_InvocationID] = r_float_in[gl_InvocationID];
1071 			rg_float_out[gl_InvocationID] = rg_float_in[gl_InvocationID];
1072 			rgb_float_out[gl_InvocationID] = rgb_float_in[gl_InvocationID];
1073 			rgba_float_out[gl_InvocationID] = rgba_float_in[gl_InvocationID];
1074 			gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;
1075 		}*/
1076 
1077 		const string tessellationControlSource =
1078 		"; SPIR-V\n"
1079 		"; Version: 1.3\n"
1080 		"; Generator: Khronos Glslang Reference Front End; 2\n"
1081 		"; Bound: 111\n"
1082 		"; Schema: 0\n"
1083 		"OpCapability Tessellation\n"
1084 		"%1 = OpExtInstImport \"GLSL.std.450\"\n"
1085 		"OpMemoryModel Logical GLSL450\n"
1086 		"OpEntryPoint TessellationControl %4 \"main\" %8 %20 %29 %color_out %color_in %r_float_out %r_float_in %rg_float_out %rg_float_in %rgb_float_out %rgb_float_in %rgba_float_out %rgba_float_in %101 %106\n"
1087 		"OpExecutionMode %4 OutputVertices 4\n"
1088 		"OpDecorate %8 BuiltIn InvocationId\n"
1089 		"OpDecorate %20 Patch\n"
1090 		"OpDecorate %20 BuiltIn TessLevelInner\n"
1091 		"OpDecorate %29 Patch\n"
1092 		"OpDecorate %29 BuiltIn TessLevelOuter\n"
1093 		"OpDecorate %color_out Location 0\n"
1094 		"OpDecorate %color_in Location 0\n"
1095 		"OpDecorate %r_float_out Location 1\n"
1096 		"OpDecorate %r_float_in Location 1\n"
1097 		"OpDecorate %rg_float_out Location 2\n"
1098 		"OpDecorate %rg_float_in Location 2\n"
1099 		"OpDecorate %rgb_float_out Location 3\n"
1100 		"OpDecorate %rgb_float_in Location 3\n"
1101 		"OpDecorate %rgba_float_out Location 4\n"
1102 		"OpDecorate %rgba_float_in Location 4\n"
1103 		+decorations[0].others+
1104 		"OpMemberDecorate %98 0 BuiltIn Position\n"
1105 		"OpMemberDecorate %98 1 BuiltIn PointSize\n"
1106 		"OpMemberDecorate %98 2 BuiltIn ClipDistance\n"
1107 		"OpMemberDecorate %98 3 BuiltIn CullDistance\n"
1108 		"OpDecorate %98 Block\n"
1109 		"OpMemberDecorate %103 0 BuiltIn Position\n"
1110 		"OpMemberDecorate %103 1 BuiltIn PointSize\n"
1111 		"OpMemberDecorate %103 2 BuiltIn ClipDistance\n"
1112 		"OpMemberDecorate %103 3 BuiltIn CullDistance\n"
1113 		"OpDecorate %103 Block\n"
1114 		"%2 = OpTypeVoid\n"
1115 		"%3 = OpTypeFunction %2\n"
1116 		"%6 = OpTypeInt 32 1\n"
1117 		"%7 = OpTypePointer Input %6\n"
1118 		"%8 = OpVariable %7 Input\n"
1119 		"%10 = OpConstant %6 0\n"
1120 		"%11 = OpTypeBool\n"
1121 		"%15 = OpTypeFloat 32\n"
1122 		"%16 = OpTypeInt 32 0\n"
1123 		"%17 = OpConstant %16 2\n"
1124 		"%18 = OpTypeArray %15 %17\n"
1125 		"%19 = OpTypePointer Output %18\n"
1126 		"%20 = OpVariable %19 Output\n"
1127 		"%21 = OpConstant %15 4\n"
1128 		"%22 = OpTypePointer Output %15\n"
1129 		"%24 = OpConstant %6 1\n"
1130 		"%26 = OpConstant %16 4\n"
1131 		"%27 = OpTypeArray %15 %26\n"
1132 		"%28 = OpTypePointer Output %27\n"
1133 		"%29 = OpVariable %28 Output\n"
1134 		"%32 = OpConstant %6 2\n"
1135 		"%34 = OpConstant %6 3\n"
1136 		"%36 = OpTypeVector %15 4\n"
1137 		"%37 = OpTypeArray %36 %26\n"
1138 		"%38 = OpTypePointer Output %37\n"
1139 		"%color_out = OpVariable %38 Output\n"
1140 		"%41 = OpConstant %16 32\n"
1141 		"%42 = OpTypeArray %36 %41\n"
1142 		"%43 = OpTypePointer Input %42\n"
1143 		"%color_in = OpVariable %43 Input\n"
1144 		"%46 = OpTypePointer Input %36\n"
1145 		"%49 = OpTypePointer Output %36\n"
1146 		"%r_float_out = OpVariable %28 Output\n"
1147 		"%53 = OpTypeArray %15 %41\n"
1148 		"%54 = OpTypePointer Input %53\n"
1149 		"%r_float_in = OpVariable %54 Input\n"
1150 		"%57 = OpTypePointer Input %15\n"
1151 		"%61 = OpTypeVector %15 2\n"
1152 		"%62 = OpTypeArray %61 %26\n"
1153 		"%63 = OpTypePointer Output %62\n"
1154 		"%rg_float_out = OpVariable %63 Output\n"
1155 		"%66 = OpTypeArray %61 %41\n"
1156 		"%67 = OpTypePointer Input %66\n"
1157 		"%rg_float_in = OpVariable %67 Input\n"
1158 		"%70 = OpTypePointer Input %61\n"
1159 		"%73 = OpTypePointer Output %61\n"
1160 		"%75 = OpTypeVector %15 3\n"
1161 		"%76 = OpTypeArray %75 %26\n"
1162 		"%77 = OpTypePointer Output %76\n"
1163 		"%rgb_float_out = OpVariable %77 Output\n"
1164 		"%80 = OpTypeArray %75 %41\n"
1165 		"%81 = OpTypePointer Input %80\n"
1166 		"%rgb_float_in = OpVariable %81 Input\n"
1167 		"%84 = OpTypePointer Input %75\n"
1168 		"%87 = OpTypePointer Output %75\n"
1169 		"%rgba_float_out = OpVariable %38 Output\n"
1170 		"%rgba_float_in = OpVariable %43 Input\n"
1171 		"%96 = OpConstant %16 1\n"
1172 		"%97 = OpTypeArray %15 %96\n"
1173 		"%98 = OpTypeStruct %36 %15 %97 %97\n"
1174 		"%99 = OpTypeArray %98 %26\n"
1175 		"%100 = OpTypePointer Output %99\n"
1176 		"%101 = OpVariable %100 Output\n"
1177 		"%103 = OpTypeStruct %36 %15 %97 %97\n"
1178 		"%104 = OpTypeArray %103 %41\n"
1179 		"%105 = OpTypePointer Input %104\n"
1180 		"%106 = OpVariable %105 Input\n"
1181 		"%4 = OpFunction %2 None %3\n"
1182 		"%5 = OpLabel\n"
1183 		"%9 = OpLoad %6 %8\n"
1184 		"%12 = OpIEqual %11 %9 %10\n"
1185 		"OpSelectionMerge %14 None\n"
1186 		"OpBranchConditional %12 %13 %14\n"
1187 		"%13 = OpLabel\n"
1188 		"%23 = OpAccessChain %22 %20 %10\n"
1189 		"OpStore %23 %21\n"
1190 		"%25 = OpAccessChain %22 %20 %24\n"
1191 		"OpStore %25 %21\n"
1192 		"%30 = OpAccessChain %22 %29 %10\n"
1193 		"OpStore %30 %21\n"
1194 		"%31 = OpAccessChain %22 %29 %24\n"
1195 		"OpStore %31 %21\n"
1196 		"%33 = OpAccessChain %22 %29 %32\n"
1197 		"OpStore %33 %21\n"
1198 		"%35 = OpAccessChain %22 %29 %34\n"
1199 		"OpStore %35 %21\n"
1200 		"OpBranch %14\n"
1201 		"%14 = OpLabel\n"
1202 		"%40 = OpLoad %6 %8\n"
1203 		"%45 = OpLoad %6 %8\n"
1204 		"%47 = OpAccessChain %46 %color_in %45\n"
1205 		"%48 = OpLoad %36 %47\n"
1206 		"%50 = OpAccessChain %49 %color_out %40\n"
1207 		"OpStore %50 %48\n"
1208 		"%52 = OpLoad %6 %8\n"
1209 		"%56 = OpLoad %6 %8\n"
1210 		"%58 = OpAccessChain %57 %r_float_in %56\n"
1211 		"%59 = OpLoad %15 %58\n"
1212 		"%60 = OpAccessChain %22 %r_float_out %52\n"
1213 		"OpStore %60 %59\n"
1214 		"%65 = OpLoad %6 %8\n"
1215 		"%69 = OpLoad %6 %8\n"
1216 		"%71 = OpAccessChain %70 %rg_float_in %69\n"
1217 		"%72 = OpLoad %61 %71\n"
1218 		"%74 = OpAccessChain %73 %rg_float_out %65\n"
1219 		"OpStore %74 %72\n"
1220 		"%79 = OpLoad %6 %8\n"
1221 		"%83 = OpLoad %6 %8\n"
1222 		"%85 = OpAccessChain %84 %rgb_float_in %83\n"
1223 		"%86 = OpLoad %75 %85\n"
1224 		"%88 = OpAccessChain %87 %rgb_float_out %79\n"
1225 		"OpStore %88 %86\n"
1226 		"%90 = OpLoad %6 %8\n"
1227 		"%92 = OpLoad %6 %8\n"
1228 		"%93 = OpAccessChain %46 %rgba_float_in %92\n"
1229 		"%94 = OpLoad %36 %93\n"
1230 		"%95 = OpAccessChain %49 %rgba_float_out %90\n"
1231 		"OpStore %95 %94\n"
1232 		"%102 = OpLoad %6 %8\n"
1233 		"%107 = OpLoad %6 %8\n"
1234 		"%108 = OpAccessChain %46 %106 %107 %10\n"
1235 		"%109 = OpLoad %36 %108\n"
1236 		"%110 = OpAccessChain %49 %101 %102 %10\n"
1237 		"OpStore %110 %109\n"
1238 		"OpReturn\n"
1239 		"OpFunctionEnd\n";
1240 
1241 		/*#version 450
1242 		#extension GL_EXT_tessellation_shader : require
1243 		layout( quads, equal_spacing, ccw ) in;
1244 		layout(location = 0) in vec4		in_color[];
1245 		layout(location = 1) in float		r_float_in[];
1246 		layout(location = 2) in vec2		rg_float_in[];
1247 		layout(location = 3) in vec3		rgb_float_in[];
1248 		layout(location = 4) in vec4		rgba_float_in[];
1249 		layout(location = 0) out vec4		out_color;
1250 		layout(location = 1) out float		r_float_out;
1251 		layout(location = 2) out vec2		rg_float_out;
1252 		layout(location = 3) out vec3		rgb_float_out;
1253 		layout(location = 4) out vec4		rgba_float_out;
1254 		void main (void)
1255 		{
1256 			const float u = gl_TessCoord.x;
1257 			const float v = gl_TessCoord.y;
1258 			const float w = gl_TessCoord.z;
1259 			out_color = (1 - u) * (1 - v) * in_color[0] +(1 - u) * v * in_color[1] + u * (1 - v) * in_color[2] + u * v * in_color[3];
1260 			r_float_out = (1 - u) * (1 - v) * r_float_in[0] +(1 - u) * v * r_float_in[1] + u * (1 - v) * r_float_in[2] + u * v * r_float_in[3];
1261 			rg_float_out = (1 - u) * (1 - v) * rg_float_in[0] +(1 - u) * v * rg_float_in[1] + u * (1 - v) * rg_float_in[2] + u * v * rg_float_in[3];
1262 			rgb_float_out = (1 - u) * (1 - v) * rgb_float_in[0] +(1 - u) * v * rgb_float_in[1] + u * (1 - v) * rgb_float_in[2] + u * v * rgb_float_in[3];
1263 			rgba_float_out = (1 - u) * (1 - v) * rgba_float_in[0] +(1 - u) * v * rgba_float_in[1] + u * (1 - v) * rgba_float_in[2] + u * v * rgba_float_in[3];
1264 			gl_Position = (1 - u) * (1 - v) * gl_in[0].gl_Position +(1 - u) * v * gl_in[1].gl_Position + u * (1 - v) * gl_in[2].gl_Position + u * v * gl_in[3].gl_Position;
1265 		}*/
1266 
1267 		const string tessellationEvaluationSource =
1268 		"; SPIR-V\n"
1269 		"; Version: 1.3\n"
1270 		"; Generator: Khronos Glslang Reference Front End; 2\n"
1271 		"; Bound: 253\n"
1272 		"; Schema: 0\n"
1273 		"OpCapability Tessellation\n"
1274 		"%1 = OpExtInstImport \"GLSL.std.450\"\n"
1275 		"OpMemoryModel Logical GLSL450\n"
1276 		"OpEntryPoint TessellationEvaluation %4 \"main\" %11 %color_out %color_in %r_float_out %r_float_in %rg_float_out %rg_float_in %rgb_float_out %rgb_float_in %rgba_float_out %rgba_float_in %216 %225\n"
1277 		"OpExecutionMode %4 Quads\n"
1278 		"OpExecutionMode %4 SpacingEqual\n"
1279 		"OpExecutionMode %4 VertexOrderCcw\n"
1280 		"OpDecorate %11 BuiltIn TessCoord\n"
1281 		"OpDecorate %color_out Location 0\n"
1282 		"OpDecorate %color_in Location 0\n"
1283 		"OpDecorate %r_float_out Location 1\n"
1284 		"OpDecorate %r_float_in Location 1\n"
1285 		"OpDecorate %rg_float_out Location 2\n"
1286 		"OpDecorate %rg_float_in Location 2\n"
1287 		"OpDecorate %rgb_float_out Location 3\n"
1288 		"OpDecorate %rgb_float_in Location 3\n"
1289 		"OpDecorate %rgba_float_out Location 4\n"
1290 		"OpDecorate %rgba_float_in Location 4\n"
1291 		+decorations[0].others+
1292 		"OpMemberDecorate %214 0 BuiltIn Position\n"
1293 		"OpMemberDecorate %214 1 BuiltIn PointSize\n"
1294 		"OpMemberDecorate %214 2 BuiltIn ClipDistance\n"
1295 		"OpMemberDecorate %214 3 BuiltIn CullDistance\n"
1296 		"OpDecorate %214 Block\n"
1297 		"OpMemberDecorate %222 0 BuiltIn Position\n"
1298 		"OpMemberDecorate %222 1 BuiltIn PointSize\n"
1299 		"OpMemberDecorate %222 2 BuiltIn ClipDistance\n"
1300 		"OpMemberDecorate %222 3 BuiltIn CullDistance\n"
1301 		"OpDecorate %222 Block\n"
1302 		"%2 = OpTypeVoid\n"
1303 		"%3 = OpTypeFunction %2\n"
1304 		"%6 = OpTypeFloat 32\n"
1305 		"%7 = OpTypePointer Function %6\n"
1306 		"%9 = OpTypeVector %6 3\n"
1307 		"%10 = OpTypePointer Input %9\n"
1308 		"%11 = OpVariable %10 Input\n"
1309 		"%12 = OpTypeInt 32 0\n"
1310 		"%13 = OpConstant %12 0\n"
1311 		"%14 = OpTypePointer Input %6\n"
1312 		"%18 = OpConstant %12 1\n"
1313 		"%22 = OpConstant %12 2\n"
1314 		"%25 = OpTypeVector %6 4\n"
1315 		"%26 = OpTypePointer Output %25\n"
1316 		"%color_out = OpVariable %26 Output\n"
1317 		"%28 = OpConstant %6 1\n"
1318 		"%34 = OpConstant %12 32\n"
1319 		"%35 = OpTypeArray %25 %34\n"
1320 		"%36 = OpTypePointer Input %35\n"
1321 		"%color_in = OpVariable %36 Input\n"
1322 		"%38 = OpTypeInt 32 1\n"
1323 		"%39 = OpConstant %38 0\n"
1324 		"%40 = OpTypePointer Input %25\n"
1325 		"%48 = OpConstant %38 1\n"
1326 		"%57 = OpConstant %38 2\n"
1327 		"%65 = OpConstant %38 3\n"
1328 		"%70 = OpTypePointer Output %6\n"
1329 		"%r_float_out = OpVariable %70 Output\n"
1330 		"%77 = OpTypeArray %6 %34\n"
1331 		"%78 = OpTypePointer Input %77\n"
1332 		"%r_float_in = OpVariable %78 Input\n"
1333 		"%106 = OpTypeVector %6 2\n"
1334 		"%107 = OpTypePointer Output %106\n"
1335 		"%rg_float_out = OpVariable %107 Output\n"
1336 		"%114 = OpTypeArray %106 %34\n"
1337 		"%115 = OpTypePointer Input %114\n"
1338 		"%rg_float_in = OpVariable %115 Input\n"
1339 		"%117 = OpTypePointer Input %106\n"
1340 		"%144 = OpTypePointer Output %9\n"
1341 		"%rgb_float_out = OpVariable %144 Output\n"
1342 		"%151 = OpTypeArray %9 %34\n"
1343 		"%152 = OpTypePointer Input %151\n"
1344 		"%rgb_float_in = OpVariable %152 Input\n"
1345 		"%rgba_float_out = OpVariable %26 Output\n"
1346 		"%rgba_float_in = OpVariable %36 Input\n"
1347 		"%213 = OpTypeArray %6 %18\n"
1348 		"%214 = OpTypeStruct %25 %6 %213 %213\n"
1349 		"%215 = OpTypePointer Output %214\n"
1350 		"%216 = OpVariable %215 Output\n"
1351 		"%222 = OpTypeStruct %25 %6 %213 %213\n"
1352 		"%223 = OpTypeArray %222 %34\n"
1353 		"%224 = OpTypePointer Input %223\n"
1354 		"%225 = OpVariable %224 Input\n"
1355 		"%4 = OpFunction %2 None %3\n"
1356 		"%5 = OpLabel\n"
1357 		"%8 = OpVariable %7 Function\n"
1358 		"%17 = OpVariable %7 Function\n"
1359 		"%21 = OpVariable %7 Function\n"
1360 		"%15 = OpAccessChain %14 %11 %13\n"
1361 		"%16 = OpLoad %6 %15\n"
1362 		"OpStore %8 %16\n"
1363 		"%19 = OpAccessChain %14 %11 %18\n"
1364 		"%20 = OpLoad %6 %19\n"
1365 		"OpStore %17 %20\n"
1366 		"%23 = OpAccessChain %14 %11 %22\n"
1367 		"%24 = OpLoad %6 %23\n"
1368 		"OpStore %21 %24\n"
1369 		"%29 = OpLoad %6 %8\n"
1370 		"%30 = OpFSub %6 %28 %29\n"
1371 		"%31 = OpLoad %6 %17\n"
1372 		"%32 = OpFSub %6 %28 %31\n"
1373 		"%33 = OpFMul %6 %30 %32\n"
1374 		"%41 = OpAccessChain %40 %color_in %39\n"
1375 		"%42 = OpLoad %25 %41\n"
1376 		"%43 = OpVectorTimesScalar %25 %42 %33\n"
1377 		"%44 = OpLoad %6 %8\n"
1378 		"%45 = OpFSub %6 %28 %44\n"
1379 		"%46 = OpLoad %6 %17\n"
1380 		"%47 = OpFMul %6 %45 %46\n"
1381 		"%49 = OpAccessChain %40 %color_in %48\n"
1382 		"%50 = OpLoad %25 %49\n"
1383 		"%51 = OpVectorTimesScalar %25 %50 %47\n"
1384 		"%52 = OpFAdd %25 %43 %51\n"
1385 		"%53 = OpLoad %6 %8\n"
1386 		"%54 = OpLoad %6 %17\n"
1387 		"%55 = OpFSub %6 %28 %54\n"
1388 		"%56 = OpFMul %6 %53 %55\n"
1389 		"%58 = OpAccessChain %40 %color_in %57\n"
1390 		"%59 = OpLoad %25 %58\n"
1391 		"%60 = OpVectorTimesScalar %25 %59 %56\n"
1392 		"%61 = OpFAdd %25 %52 %60\n"
1393 		"%62 = OpLoad %6 %8\n"
1394 		"%63 = OpLoad %6 %17\n"
1395 		"%64 = OpFMul %6 %62 %63\n"
1396 		"%66 = OpAccessChain %40 %color_in %65\n"
1397 		"%67 = OpLoad %25 %66\n"
1398 		"%68 = OpVectorTimesScalar %25 %67 %64\n"
1399 		"%69 = OpFAdd %25 %61 %68\n"
1400 		"OpStore %color_out %69\n"
1401 		"%72 = OpLoad %6 %8\n"
1402 		"%73 = OpFSub %6 %28 %72\n"
1403 		"%74 = OpLoad %6 %17\n"
1404 		"%75 = OpFSub %6 %28 %74\n"
1405 		"%76 = OpFMul %6 %73 %75\n"
1406 		"%80 = OpAccessChain %14 %r_float_in %39\n"
1407 		"%81 = OpLoad %6 %80\n"
1408 		"%82 = OpFMul %6 %76 %81\n"
1409 		"%83 = OpLoad %6 %8\n"
1410 		"%84 = OpFSub %6 %28 %83\n"
1411 		"%85 = OpLoad %6 %17\n"
1412 		"%86 = OpFMul %6 %84 %85\n"
1413 		"%87 = OpAccessChain %14 %r_float_in %48\n"
1414 		"%88 = OpLoad %6 %87\n"
1415 		"%89 = OpFMul %6 %86 %88\n"
1416 		"%90 = OpFAdd %6 %82 %89\n"
1417 		"%91 = OpLoad %6 %8\n"
1418 		"%92 = OpLoad %6 %17\n"
1419 		"%93 = OpFSub %6 %28 %92\n"
1420 		"%94 = OpFMul %6 %91 %93\n"
1421 		"%95 = OpAccessChain %14 %r_float_in %57\n"
1422 		"%96 = OpLoad %6 %95\n"
1423 		"%97 = OpFMul %6 %94 %96\n"
1424 		"%98 = OpFAdd %6 %90 %97\n"
1425 		"%99 = OpLoad %6 %8\n"
1426 		"%100 = OpLoad %6 %17\n"
1427 		"%101 = OpFMul %6 %99 %100\n"
1428 		"%102 = OpAccessChain %14 %r_float_in %65\n"
1429 		"%103 = OpLoad %6 %102\n"
1430 		"%104 = OpFMul %6 %101 %103\n"
1431 		"%105 = OpFAdd %6 %98 %104\n"
1432 		"OpStore %r_float_out %105\n"
1433 		"%109 = OpLoad %6 %8\n"
1434 		"%110 = OpFSub %6 %28 %109\n"
1435 		"%111 = OpLoad %6 %17\n"
1436 		"%112 = OpFSub %6 %28 %111\n"
1437 		"%113 = OpFMul %6 %110 %112\n"
1438 		"%118 = OpAccessChain %117 %rg_float_in %39\n"
1439 		"%119 = OpLoad %106 %118\n"
1440 		"%120 = OpVectorTimesScalar %106 %119 %113\n"
1441 		"%121 = OpLoad %6 %8\n"
1442 		"%122 = OpFSub %6 %28 %121\n"
1443 		"%123 = OpLoad %6 %17\n"
1444 		"%124 = OpFMul %6 %122 %123\n"
1445 		"%125 = OpAccessChain %117 %rg_float_in %48\n"
1446 		"%126 = OpLoad %106 %125\n"
1447 		"%127 = OpVectorTimesScalar %106 %126 %124\n"
1448 		"%128 = OpFAdd %106 %120 %127\n"
1449 		"%129 = OpLoad %6 %8\n"
1450 		"%130 = OpLoad %6 %17\n"
1451 		"%131 = OpFSub %6 %28 %130\n"
1452 		"%132 = OpFMul %6 %129 %131\n"
1453 		"%133 = OpAccessChain %117 %rg_float_in %57\n"
1454 		"%134 = OpLoad %106 %133\n"
1455 		"%135 = OpVectorTimesScalar %106 %134 %132\n"
1456 		"%136 = OpFAdd %106 %128 %135\n"
1457 		"%137 = OpLoad %6 %8\n"
1458 		"%138 = OpLoad %6 %17\n"
1459 		"%139 = OpFMul %6 %137 %138\n"
1460 		"%140 = OpAccessChain %117 %rg_float_in %65\n"
1461 		"%141 = OpLoad %106 %140\n"
1462 		"%142 = OpVectorTimesScalar %106 %141 %139\n"
1463 		"%143 = OpFAdd %106 %136 %142\n"
1464 		"OpStore %rg_float_out %143\n"
1465 		"%146 = OpLoad %6 %8\n"
1466 		"%147 = OpFSub %6 %28 %146\n"
1467 		"%148 = OpLoad %6 %17\n"
1468 		"%149 = OpFSub %6 %28 %148\n"
1469 		"%150 = OpFMul %6 %147 %149\n"
1470 		"%154 = OpAccessChain %10 %rgb_float_in %39\n"
1471 		"%155 = OpLoad %9 %154\n"
1472 		"%156 = OpVectorTimesScalar %9 %155 %150\n"
1473 		"%157 = OpLoad %6 %8\n"
1474 		"%158 = OpFSub %6 %28 %157\n"
1475 		"%159 = OpLoad %6 %17\n"
1476 		"%160 = OpFMul %6 %158 %159\n"
1477 		"%161 = OpAccessChain %10 %rgb_float_in %48\n"
1478 		"%162 = OpLoad %9 %161\n"
1479 		"%163 = OpVectorTimesScalar %9 %162 %160\n"
1480 		"%164 = OpFAdd %9 %156 %163\n"
1481 		"%165 = OpLoad %6 %8\n"
1482 		"%166 = OpLoad %6 %17\n"
1483 		"%167 = OpFSub %6 %28 %166\n"
1484 		"%168 = OpFMul %6 %165 %167\n"
1485 		"%169 = OpAccessChain %10 %rgb_float_in %57\n"
1486 		"%170 = OpLoad %9 %169\n"
1487 		"%171 = OpVectorTimesScalar %9 %170 %168\n"
1488 		"%172 = OpFAdd %9 %164 %171\n"
1489 		"%173 = OpLoad %6 %8\n"
1490 		"%174 = OpLoad %6 %17\n"
1491 		"%175 = OpFMul %6 %173 %174\n"
1492 		"%176 = OpAccessChain %10 %rgb_float_in %65\n"
1493 		"%177 = OpLoad %9 %176\n"
1494 		"%178 = OpVectorTimesScalar %9 %177 %175\n"
1495 		"%179 = OpFAdd %9 %172 %178\n"
1496 		"OpStore %rgb_float_out %179\n"
1497 		"%181 = OpLoad %6 %8\n"
1498 		"%182 = OpFSub %6 %28 %181\n"
1499 		"%183 = OpLoad %6 %17\n"
1500 		"%184 = OpFSub %6 %28 %183\n"
1501 		"%185 = OpFMul %6 %182 %184\n"
1502 		"%187 = OpAccessChain %40 %rgba_float_in %39\n"
1503 		"%188 = OpLoad %25 %187\n"
1504 		"%189 = OpVectorTimesScalar %25 %188 %185\n"
1505 		"%190 = OpLoad %6 %8\n"
1506 		"%191 = OpFSub %6 %28 %190\n"
1507 		"%192 = OpLoad %6 %17\n"
1508 		"%193 = OpFMul %6 %191 %192\n"
1509 		"%194 = OpAccessChain %40 %rgba_float_in %48\n"
1510 		"%195 = OpLoad %25 %194\n"
1511 		"%196 = OpVectorTimesScalar %25 %195 %193\n"
1512 		"%197 = OpFAdd %25 %189 %196\n"
1513 		"%198 = OpLoad %6 %8\n"
1514 		"%199 = OpLoad %6 %17\n"
1515 		"%200 = OpFSub %6 %28 %199\n"
1516 		"%201 = OpFMul %6 %198 %200\n"
1517 		"%202 = OpAccessChain %40 %rgba_float_in %57\n"
1518 		"%203 = OpLoad %25 %202\n"
1519 		"%204 = OpVectorTimesScalar %25 %203 %201\n"
1520 		"%205 = OpFAdd %25 %197 %204\n"
1521 		"%206 = OpLoad %6 %8\n"
1522 		"%207 = OpLoad %6 %17\n"
1523 		"%208 = OpFMul %6 %206 %207\n"
1524 		"%209 = OpAccessChain %40 %rgba_float_in %65\n"
1525 		"%210 = OpLoad %25 %209\n"
1526 		"%211 = OpVectorTimesScalar %25 %210 %208\n"
1527 		"%212 = OpFAdd %25 %205 %211\n"
1528 		"OpStore %rgba_float_out %212\n"
1529 		"%217 = OpLoad %6 %8\n"
1530 		"%218 = OpFSub %6 %28 %217\n"
1531 		"%219 = OpLoad %6 %17\n"
1532 		"%220 = OpFSub %6 %28 %219\n"
1533 		"%221 = OpFMul %6 %218 %220\n"
1534 		"%226 = OpAccessChain %40 %225 %39 %39\n"
1535 		"%227 = OpLoad %25 %226\n"
1536 		"%228 = OpVectorTimesScalar %25 %227 %221\n"
1537 		"%229 = OpLoad %6 %8\n"
1538 		"%230 = OpFSub %6 %28 %229\n"
1539 		"%231 = OpLoad %6 %17\n"
1540 		"%232 = OpFMul %6 %230 %231\n"
1541 		"%233 = OpAccessChain %40 %225 %48 %39\n"
1542 		"%234 = OpLoad %25 %233\n"
1543 		"%235 = OpVectorTimesScalar %25 %234 %232\n"
1544 		"%236 = OpFAdd %25 %228 %235\n"
1545 		"%237 = OpLoad %6 %8\n"
1546 		"%238 = OpLoad %6 %17\n"
1547 		"%239 = OpFSub %6 %28 %238\n"
1548 		"%240 = OpFMul %6 %237 %239\n"
1549 		"%241 = OpAccessChain %40 %225 %57 %39\n"
1550 		"%242 = OpLoad %25 %241\n"
1551 		"%243 = OpVectorTimesScalar %25 %242 %240\n"
1552 		"%244 = OpFAdd %25 %236 %243\n"
1553 		"%245 = OpLoad %6 %8\n"
1554 		"%246 = OpLoad %6 %17\n"
1555 		"%247 = OpFMul %6 %245 %246\n"
1556 		"%248 = OpAccessChain %40 %225 %65 %39\n"
1557 		"%249 = OpLoad %25 %248\n"
1558 		"%250 = OpVectorTimesScalar %25 %249 %247\n"
1559 		"%251 = OpFAdd %25 %244 %250\n"
1560 		"%252 = OpAccessChain %26 %216 %39\n"
1561 		"OpStore %252 %251\n"
1562 		"OpReturn\n"
1563 		"OpFunctionEnd\n";
1564 		programCollection.spirvAsmSources.add("tessellation_control") << tessellationControlSource;
1565 		programCollection.spirvAsmSources.add("tessellation_evaluation") << tessellationEvaluationSource;
1566 	}
1567 	{
1568 
1569 		/*#version 450
1570 		layout(triangles) in;
1571 		layout(triangle_strip, max_vertices = 3) out;
1572 		layout(location = 0) in vec4    in_color[];
1573 		layout(location = 1) in float   r_float_in[];
1574 		layout(location = 2) in vec2    rg_float_in[];
1575 		layout(location = 3) in vec3    rgb_float_in[];
1576 		layout(location = 4) in vec4    rgba_float_in[];
1577 		layout(location = 0) out vec4   out_color;
1578 		layout(location = 1) out float  r_float_out;
1579 		layout(location = 2) out vec2   rg_float_out;
1580 		layout(location = 3) out vec3   rgb_float_out;
1581 		layout(location = 4) out vec4   rgba_float_out;
1582 		void main (void)
1583 		{
1584 			out_color = in_color[0];
1585 			r_float_out = r_float_in[0];
1586 			rg_float_out = rg_float_in[0];
1587 			rgb_float_out = rgb_float_in[0];
1588 			rgba_float_out = rgba_float_in[0];
1589 			gl_Position = gl_in[0].gl_Position;
1590 			EmitVertex();
1591 			out_color = in_color[1];
1592 			r_float_out = r_float_in[1];
1593 			rg_float_out = rg_float_in[1];
1594 			rgb_float_out = rgb_float_in[1];
1595 			rgba_float_out = rgba_float_in[1];
1596 			gl_Position = gl_in[1].gl_Position;
1597 			EmitVertex();
1598 			out_color = in_color[2];
1599 			r_float_out = r_float_in[2];
1600 			rg_float_out = rg_float_in[2];
1601 			rgb_float_out = rgb_float_in[2];
1602 			rgba_float_out = rgba_float_in[2];
1603 			gl_Position = gl_in[2].gl_Position;
1604 			EmitVertex();
1605 			EndPrimitive();
1606 		}
1607 		*/
1608 		const string geometrySource =
1609 		"; SPIR-V\n"
1610 		"; Version: 1.3\n"
1611 		"; Generator: Khronos Glslang Reference Front End; 2\n"
1612 		"; Bound: 90\n"
1613 		"; Schema: 0\n"
1614 		"OpCapability Geometry\n"
1615 		"%1 = OpExtInstImport \"GLSL.std.450\"\n"
1616 		"OpMemoryModel Logical GLSL450\n"
1617 		"OpEntryPoint Geometry %4 \"main\" %color_out %color_in %r_float_out %r_float_in %rg_float_out %rg_float_in %rgb_float_out %rgb_float_in %rgba_float_out %rgba_float_in %54 %58\n"
1618 		"OpExecutionMode %4 Triangles\n"
1619 		"OpExecutionMode %4 Invocations 1\n"
1620 		"OpExecutionMode %4 OutputTriangleStrip\n"
1621 		"OpExecutionMode %4 OutputVertices 3\n"
1622 		"OpDecorate %color_out Location 0\n"
1623 		"OpDecorate %color_in Location 0\n"
1624 		"OpDecorate %r_float_out Location 1\n"
1625 		"OpDecorate %r_float_in Location 1\n"
1626 		"OpDecorate %rg_float_out Location 2\n"
1627 		"OpDecorate %rg_float_in Location 2\n"
1628 		"OpDecorate %rgb_float_out Location 3\n"
1629 		"OpDecorate %rgb_float_in Location 3\n"
1630 		"OpDecorate %rgba_float_out Location 4\n"
1631 		"OpDecorate %rgba_float_in Location 4\n"
1632 		+decorations[0].others+
1633 		"OpMemberDecorate %52 0 BuiltIn Position\n"
1634 		"OpMemberDecorate %52 1 BuiltIn PointSize\n"
1635 		"OpMemberDecorate %52 2 BuiltIn ClipDistance\n"
1636 		"OpMemberDecorate %52 3 BuiltIn CullDistance\n"
1637 		"OpDecorate %52 Block\n"
1638 		"OpMemberDecorate %55 0 BuiltIn Position\n"
1639 		"OpMemberDecorate %55 1 BuiltIn PointSize\n"
1640 		"OpMemberDecorate %55 2 BuiltIn ClipDistance\n"
1641 		"OpMemberDecorate %55 3 BuiltIn CullDistance\n"
1642 		"OpDecorate %55 Block\n"
1643 		"%2 = OpTypeVoid\n"
1644 		"%3 = OpTypeFunction %2\n"
1645 		"%6 = OpTypeFloat 32\n"
1646 		"%7 = OpTypeVector %6 4\n"
1647 		"%8 = OpTypePointer Output %7\n"
1648 		"%color_out = OpVariable %8 Output\n"
1649 		"%10 = OpTypeInt 32 0\n"
1650 		"%11 = OpConstant %10 3\n"
1651 		"%12 = OpTypeArray %7 %11\n"
1652 		"%13 = OpTypePointer Input %12\n"
1653 		"%color_in = OpVariable %13 Input\n"
1654 		"%15 = OpTypeInt 32 1\n"
1655 		"%16 = OpConstant %15 0\n"
1656 		"%17 = OpTypePointer Input %7\n"
1657 		"%20 = OpTypePointer Output %6\n"
1658 		"%r_float_out = OpVariable %20 Output\n"
1659 		"%22 = OpTypeArray %6 %11\n"
1660 		"%23 = OpTypePointer Input %22\n"
1661 		"%r_float_in = OpVariable %23 Input\n"
1662 		"%25 = OpTypePointer Input %6\n"
1663 		"%28 = OpTypeVector %6 2\n"
1664 		"%29 = OpTypePointer Output %28\n"
1665 		"%rg_float_out = OpVariable %29 Output\n"
1666 		"%31 = OpTypeArray %28 %11\n"
1667 		"%32 = OpTypePointer Input %31\n"
1668 		"%rg_float_in = OpVariable %32 Input\n"
1669 		"%34 = OpTypePointer Input %28\n"
1670 		"%37 = OpTypeVector %6 3\n"
1671 		"%38 = OpTypePointer Output %37\n"
1672 		"%rgb_float_out = OpVariable %38 Output\n"
1673 		"%40 = OpTypeArray %37 %11\n"
1674 		"%41 = OpTypePointer Input %40\n"
1675 		"%rgb_float_in = OpVariable %41 Input\n"
1676 		"%43 = OpTypePointer Input %37\n"
1677 		"%rgba_float_out = OpVariable %8 Output\n"
1678 		"%rgba_float_in = OpVariable %13 Input\n"
1679 		"%50 = OpConstant %10 1\n"
1680 		"%51 = OpTypeArray %6 %50\n"
1681 		"%52 = OpTypeStruct %7 %6 %51 %51\n"
1682 		"%53 = OpTypePointer Output %52\n"
1683 		"%54 = OpVariable %53 Output\n"
1684 		"%55 = OpTypeStruct %7 %6 %51 %51\n"
1685 		"%56 = OpTypeArray %55 %11\n"
1686 		"%57 = OpTypePointer Input %56\n"
1687 		"%58 = OpVariable %57 Input\n"
1688 		"%62 = OpConstant %15 1\n"
1689 		"%76 = OpConstant %15 2\n"
1690 		"%4 = OpFunction %2 None %3\n"
1691 		"%5 = OpLabel\n"
1692 		"%18 = OpAccessChain %17 %color_in %16\n"
1693 		"%19 = OpLoad %7 %18\n"
1694 		"OpStore %color_out %19\n"
1695 		"%26 = OpAccessChain %25 %r_float_in %16\n"
1696 		"%27 = OpLoad %6 %26\n"
1697 		"OpStore %r_float_out %27\n"
1698 		"%35 = OpAccessChain %34 %rg_float_in %16\n"
1699 		"%36 = OpLoad %28 %35\n"
1700 		"OpStore %rg_float_out %36\n"
1701 		"%44 = OpAccessChain %43 %rgb_float_in %16\n"
1702 		"%45 = OpLoad %37 %44\n"
1703 		"OpStore %rgb_float_out %45\n"
1704 		"%48 = OpAccessChain %17 %rgba_float_in %16\n"
1705 		"%49 = OpLoad %7 %48\n"
1706 		"OpStore %rgba_float_out %49\n"
1707 		"%59 = OpAccessChain %17 %58 %16 %16\n"
1708 		"%60 = OpLoad %7 %59\n"
1709 		"%61 = OpAccessChain %8 %54 %16\n"
1710 		"OpStore %61 %60\n"
1711 		"OpEmitVertex\n"
1712 		"%63 = OpAccessChain %17 %color_in %62\n"
1713 		"%64 = OpLoad %7 %63\n"
1714 		"OpStore %color_out %64\n"
1715 		"%65 = OpAccessChain %25 %r_float_in %62\n"
1716 		"%66 = OpLoad %6 %65\n"
1717 		"OpStore %r_float_out %66\n"
1718 		"%67 = OpAccessChain %34 %rg_float_in %62\n"
1719 		"%68 = OpLoad %28 %67\n"
1720 		"OpStore %rg_float_out %68\n"
1721 		"%69 = OpAccessChain %43 %rgb_float_in %62\n"
1722 		"%70 = OpLoad %37 %69\n"
1723 		"OpStore %rgb_float_out %70\n"
1724 		"%71 = OpAccessChain %17 %rgba_float_in %62\n"
1725 		"%72 = OpLoad %7 %71\n"
1726 		"OpStore %rgba_float_out %72\n"
1727 		"%73 = OpAccessChain %17 %58 %62 %16\n"
1728 		"%74 = OpLoad %7 %73\n"
1729 		"%75 = OpAccessChain %8 %54 %16\n"
1730 		"OpStore %75 %74\n"
1731 		"OpEmitVertex\n"
1732 		"%77 = OpAccessChain %17 %color_in %76\n"
1733 		"%78 = OpLoad %7 %77\n"
1734 		"OpStore %color_out %78\n"
1735 		"%79 = OpAccessChain %25 %r_float_in %76\n"
1736 		"%80 = OpLoad %6 %79\n"
1737 		"OpStore %r_float_out %80\n"
1738 		"%81 = OpAccessChain %34 %rg_float_in %76\n"
1739 		"%82 = OpLoad %28 %81\n"
1740 		"OpStore %rg_float_out %82\n"
1741 		"%83 = OpAccessChain %43 %rgb_float_in %76\n"
1742 		"%84 = OpLoad %37 %83\n"
1743 		"OpStore %rgb_float_out %84\n"
1744 		"%85 = OpAccessChain %17 %rgba_float_in %76\n"
1745 		"%86 = OpLoad %7 %85\n"
1746 		"OpStore %rgba_float_out %86\n"
1747 		"%87 = OpAccessChain %17 %58 %76 %16\n"
1748 		"%88 = OpLoad %7 %87\n"
1749 		"%89 = OpAccessChain %8 %54 %16\n"
1750 		"OpStore %89 %88\n"
1751 		"OpEmitVertex\n"
1752 		"OpEndPrimitive\n"
1753 		"OpReturn\n"
1754 		"OpFunctionEnd\n";
1755 		programCollection.spirvAsmSources.add("geometry") << geometrySource;
1756 	}
1757 }
1758 
1759 class CrossStageInterfaceTestsCase : public vkt::TestCase
1760 {
1761 public:
CrossStageInterfaceTestsCase(tcu::TestContext & context,const char * name,const char * description,const TestParameters & parameters)1762 	CrossStageInterfaceTestsCase (tcu::TestContext &context, const char *name, const char *description, const TestParameters& parameters)
1763 		: TestCase			(context, name, description)
1764 		, m_parameters		(parameters)
1765 	{
1766 	}
1767 private:
1768 	vkt::TestInstance*	createInstance		(vkt::Context& context) const;
1769 	void				initPrograms		(SourceCollections& programCollection) const;
1770 
1771 	const TestParameters	m_parameters;
1772 
1773 };
1774 
createInstance(vkt::Context & context) const1775 vkt::TestInstance* CrossStageInterfaceTestsCase::createInstance (vkt::Context& context) const
1776 {
1777 	return new CrossStageTestInstance(context, m_parameters);
1778 }
1779 
initPrograms(SourceCollections & programCollection) const1780 void CrossStageInterfaceTestsCase::initPrograms (SourceCollections& programCollection) const
1781 {
1782 	vector<Decorations> decorations;
1783 	string epsilon = "3e-7";
1784 	switch(m_parameters.qualifier)
1785 	{
1786 	case TEST_TYPE_FLAT:
1787 		decorations.push_back(Decorations("",
1788 								//Vertex
1789 								"OpDecorate %color_out Flat\n"
1790 								"OpDecorate %color_in Flat\n"
1791 								"OpMemberDecorate %block_out 0 Flat\n"
1792 								"OpMemberDecorate %block_out 1 Flat\n",
1793 								""));
1794 		decorations.push_back(Decorations(//Fragment
1795 								"OpDecorate %color_in Flat\n"
1796 								"OpMemberDecorate %block_in 0 Flat\n"
1797 								"OpMemberDecorate %block_in 1 Flat\n",
1798 								"",
1799 								""));
1800 
1801 		decorations.push_back(Decorations(//Fragment
1802 								"OpDecorate %color_in Flat\n"
1803 								"OpMemberDecorate %block_in 0 Flat\n"
1804 								"OpMemberDecorate %block_in 1 Flat\n",
1805 								//Vertex
1806 								"OpDecorate %color_out Flat\n"
1807 								"OpDecorate %color_in Flat\n"
1808 								"OpMemberDecorate %block_out 0 Flat\n"
1809 								"OpMemberDecorate %block_out 1 Flat\n",
1810 								""));
1811 		epsilon = "0.0";
1812 		break;
1813 	case TEST_TYPE_NOPERSPECTIVE:
1814 		decorations.push_back(Decorations("",
1815 								//Vertex
1816 								"OpDecorate %color_out NoPerspective\n"
1817 								"OpDecorate %color_in NoPerspective\n"
1818 								"OpMemberDecorate %block_out 0 NoPerspective\n"
1819 								"OpMemberDecorate %block_out 1 NoPerspective\n",
1820 								""));
1821 
1822 		decorations.push_back(Decorations(//Fragment
1823 								"OpDecorate %color_in NoPerspective\n"
1824 								"OpMemberDecorate %block_in 0 NoPerspective\n"
1825 								"OpMemberDecorate %block_in 1 NoPerspective\n",
1826 								"",
1827 								""));
1828 
1829 		decorations.push_back(Decorations(//Fragment
1830 								"OpDecorate %color_in NoPerspective\n"
1831 								"OpMemberDecorate %block_in 0 NoPerspective\n"
1832 								"OpMemberDecorate %block_in 1 NoPerspective\n",
1833 								//Vertex
1834 								"OpDecorate %color_out NoPerspective\n"
1835 								"OpDecorate %color_in NoPerspective\n"
1836 								"OpMemberDecorate %block_out 0 NoPerspective\n"
1837 								"OpMemberDecorate %block_out 1 NoPerspective\n",
1838 								""));
1839 		break;
1840 	case TEST_TYPE_RELAXEDPRECISION:
1841 		decorations.push_back(Decorations(//Fragment
1842 								"OpDecorate %color_in RelaxedPrecision\n"
1843 								"OpDecorate %color_out RelaxedPrecision\n"
1844 								"OpMemberDecorate %block_in 0 RelaxedPrecision\n"
1845 								"OpMemberDecorate %block_in 1 RelaxedPrecision\n",
1846 								//Vertex
1847 								"OpDecorate %color_out RelaxedPrecision\n"
1848 								"OpDecorate %color_in RelaxedPrecision\n"
1849 								"OpMemberDecorate %block_out 0 RelaxedPrecision\n"
1850 								"OpMemberDecorate %block_out 1 RelaxedPrecision\n",
1851 								//Others
1852 								"OpDecorate %color_out RelaxedPrecision\n"
1853 								"OpDecorate %color_in RelaxedPrecision\n"
1854 								"OpMemberDecorate %block_out 0 RelaxedPrecision\n"
1855 								"OpMemberDecorate %block_out 1 RelaxedPrecision\n"
1856 								"OpMemberDecorate %block_in 0 RelaxedPrecision\n"
1857 								"OpMemberDecorate %block_in 1 RelaxedPrecision\n"));
1858 		epsilon = "2e-3";
1859 		break;
1860 	default:
1861 		DE_ASSERT(0);
1862 	}
1863 
1864 	//Spir-v spec: decoration flat can be used only in Shader (fragment or vertex)
1865 	for (deUint32 ndx = 0; ndx < decorations.size(); ++ndx)
1866 	{
1867 
1868 		/*#version 450
1869 		layout(location = 0) in highp vec4 in_position;
1870 		layout(location = 1) in vec4 in_color;
1871 		layout(location = 0) out vec4 out_color;
1872 		layout(location = 1) out ColorData
1873 		{
1874 		  vec4 colorVec;
1875 		  mat2 colorMat;
1876 		} outData;
1877 		void main (void)
1878 		{
1879 		  gl_Position = in_position;
1880 		  out_color = in_color;
1881 		  outData.colorVec = in_color;
1882 		  outData.colorMat = mat2(in_color.r, in_color.g, in_color.b, in_color.a);
1883 		}
1884 		*/
1885 		const string vertexShaderSource =
1886 		"; SPIR-V\n"
1887 		"; Version: 1.3\n"
1888 		"; Generator: Khronos Glslang Reference Front End; 2\n"
1889 		"; Bound: 51\n"
1890 		"; Schema: 0\n"
1891 		"OpCapability Shader\n"
1892 		"%1 = OpExtInstImport \"GLSL.std.450\"\n"
1893 		"OpMemoryModel Logical GLSL450\n"
1894 		"OpEntryPoint Vertex %4 \"main\" %13 %17 %color_out %color_in %28\n"
1895 		"OpMemberDecorate %11 0 BuiltIn Position\n"
1896 		"OpMemberDecorate %11 1 BuiltIn PointSize\n"
1897 		"OpMemberDecorate %11 2 BuiltIn ClipDistance\n"
1898 		"OpMemberDecorate %11 3 BuiltIn CullDistance\n"
1899 		"OpDecorate %11 Block\n"
1900 		"OpDecorate %17 Location 0\n"
1901 		"OpDecorate %color_out Location 0\n"
1902 		"OpDecorate %color_in Location 1\n"
1903 		"OpDecorate %block_out Block\n"
1904 		"OpDecorate %28 Location 1\n"
1905 		+decorations[ndx].vertex+
1906 		"%2 = OpTypeVoid\n"
1907 		"%3 = OpTypeFunction %2\n"
1908 		"%6 = OpTypeFloat 32\n"
1909 		"%7 = OpTypeVector %6 4\n"
1910 		"%8 = OpTypeInt 32 0\n"
1911 		"%9 = OpConstant %8 1\n"
1912 		"%10 = OpTypeArray %6 %9\n"
1913 		"%11 = OpTypeStruct %7 %6 %10 %10\n"
1914 		"%12 = OpTypePointer Output %11\n"
1915 		"%13 = OpVariable %12 Output\n"
1916 		"%14 = OpTypeInt 32 1\n"
1917 		"%15 = OpConstant %14 0\n"
1918 		"%16 = OpTypePointer Input %7\n"
1919 		"%17 = OpVariable %16 Input\n"
1920 		"%19 = OpTypePointer Output %7\n"
1921 		"%color_out = OpVariable %19 Output\n"
1922 		"%color_in = OpVariable %16 Input\n"
1923 		"%24 = OpTypeVector %6 2\n"
1924 		"%25 = OpTypeMatrix %24 2\n"
1925 		"%block_out = OpTypeStruct %7 %25\n"
1926 		"%27 = OpTypePointer Output %block_out\n"
1927 		"%28 = OpVariable %27 Output\n"
1928 		"%31 = OpConstant %14 1\n"
1929 		"%32 = OpConstant %8 0\n"
1930 		"%33 = OpTypePointer Input %6\n"
1931 		"%38 = OpConstant %8 2\n"
1932 		"%41 = OpConstant %8 3\n"
1933 		"%44 = OpConstant %6 1\n"
1934 		"%45 = OpConstant %6 0\n"
1935 		"%49 = OpTypePointer Output %25\n"
1936 		"%4 = OpFunction %2 None %3\n"
1937 		"%5 = OpLabel\n"
1938 		"%18 = OpLoad %7 %17\n"
1939 		"%20 = OpAccessChain %19 %13 %15\n"
1940 		"OpStore %20 %18\n"
1941 		"%23 = OpLoad %7 %color_in\n"
1942 		"OpStore %color_out %23\n"
1943 		"%29 = OpLoad %7 %color_in\n"
1944 		"%30 = OpAccessChain %19 %28 %15\n"
1945 		"OpStore %30 %29\n"
1946 		"%34 = OpAccessChain %33 %color_in %32\n"
1947 		"%35 = OpLoad %6 %34\n"
1948 		"%36 = OpAccessChain %33 %color_in %9\n"
1949 		"%37 = OpLoad %6 %36\n"
1950 		"%39 = OpAccessChain %33 %color_in %38\n"
1951 		"%40 = OpLoad %6 %39\n"
1952 		"%42 = OpAccessChain %33 %color_in %41\n"
1953 		"%43 = OpLoad %6 %42\n"
1954 		"%46 = OpCompositeConstruct %24 %35 %37\n"
1955 		"%47 = OpCompositeConstruct %24 %40 %43\n"
1956 		"%48 = OpCompositeConstruct %25 %46 %47\n"
1957 		"%50 = OpAccessChain %49 %28 %31\n"
1958 		"OpStore %50 %48\n"
1959 		"OpReturn\n"
1960 		"OpFunctionEnd\n";
1961 
1962 		/* #version 450
1963 		layout(location = 0) in vec4 in_color;
1964 		layout(location = 0) out vec4 out_color;
1965 		layout(location = 1) in ColorData
1966 		{
1967 		  vec4 colorVec;
1968 		  mat2 colorMat;
1969 		} inData;
1970 		void main()
1971 		{
1972 		  float epsilon = 3e-7; // or 0.0 for flat, or 2e-3 for RelaxedPrecision (mediump)
1973 		  out_color = in_color;
1974 		  vec4 epsilon_vec4 = max(abs(inData.colorVec), abs(in_color)) * epsilon;
1975 		  if(any(greaterThan(abs(inData.colorVec - in_color), epsilon_vec4)))
1976 		    out_color.rgba = vec4(1.0f);
1977 		  epsilon_vec4.r = max(abs(inData.colorMat[0][0]), abs(in_color.r)) * epsilon;
1978 		  if(abs(inData.colorMat[0][0] - in_color.r) > epsilon_vec4.r)
1979 		    out_color.rgba = vec4(1.0f);
1980 		  epsilon_vec4.a = max(abs(inData.colorMat[1][1]), abs(in_color.a)) * epsilon;
1981 		  if(abs(inData.colorMat[1][1] - in_color.a) > epsilon_vec4.a)
1982 		    out_color.rgba = vec4(1.0f);
1983 		}
1984 		*/
1985 		const string fragmentShaderSource =
1986 		"; SPIR-V\n"
1987 		"; Version: 1.3\n"
1988 		"; Generator: Khronos Glslang Reference Front End; 2\n"
1989 		"; Bound: 51\n"
1990 		"; Schema: 0\n"
1991 		"OpCapability Shader\n"
1992 		"%1 = OpExtInstImport \"GLSL.std.450\"\n"
1993 		"OpMemoryModel Logical GLSL450\n"
1994 		"OpEntryPoint Fragment %4 \"main\" %color_out %color_in %17\n"
1995 		"OpExecutionMode %4 OriginUpperLeft\n"
1996 		"OpDecorate %color_out Location 0\n"
1997 		"OpDecorate %color_in Location 0\n"
1998 		"OpDecorate %block_in Block\n"
1999 		"OpDecorate %17 Location 1\n"
2000 		+decorations[ndx].fragment+
2001 		"%2 = OpTypeVoid\n"
2002 		"%3 = OpTypeFunction %2\n"
2003 		"%6 = OpTypeFloat 32\n"
2004 		"%7 = OpTypeVector %6 4\n"
2005 		"%8 = OpTypePointer Output %7\n"
2006 		"%color_out = OpVariable %8 Output\n"
2007 		"%10 = OpTypePointer Input %7\n"
2008 		"%color_in = OpVariable %10 Input\n"
2009 		"%13 = OpTypeVector %6 2\n"
2010 		"%14 = OpTypeMatrix %13 2\n"
2011 		"%block_in = OpTypeStruct %7 %14\n"
2012 		"%16 = OpTypePointer Input %block_in\n"
2013 		"%17 = OpVariable %16 Input\n"
2014 		"%18 = OpTypeInt 32 1\n"
2015 		"%19 = OpConstant %18 0\n"
2016 		"%23 = OpTypeBool\n"
2017 		"%24 = OpTypeVector %23 4\n"
2018 		"%ep = OpConstant %6 " + epsilon + "\n"
2019 		"%ep4 = OpConstantComposite %7 %ep %ep %ep %ep\n"
2020 		"%29 = OpConstant %6 1\n"
2021 		"%30 = OpConstantComposite %7 %29 %29 %29 %29\n"
2022 		"%31 = OpConstant %18 1\n"
2023 		"%32 = OpTypeInt 32 0\n"
2024 		"%33 = OpConstant %32 0\n"
2025 		"%34 = OpTypePointer Input %6\n"
2026 		"%42 = OpConstant %32 1\n"
2027 		"%45 = OpConstant %32 3\n"
2028 		"%4 = OpFunction %2 None %3\n"
2029 		"%5 = OpLabel\n"
2030 		"%12 = OpLoad %7 %color_in\n"
2031 		"OpStore %color_out %12\n"
2032 		"%20 = OpAccessChain %10 %17 %19\n"
2033 		"%21 = OpLoad %7 %20\n"
2034 		"%22 = OpLoad %7 %color_in\n"
2035 		"%sub4 = OpFSub %7 %21 %22\n"
2036 		"%abs4 = OpExtInst %7 %1 FAbs %sub4\n"
2037 		"%ep4abs0 = OpExtInst %7 %1 FAbs %21\n"
2038 		"%ep4abs1 = OpExtInst %7 %1 FAbs %22\n"
2039 		"%ep4gt = OpFOrdGreaterThan %24 %ep4abs0 %ep4abs1\n"
2040 		"%ep4max = OpSelect %7 %ep4gt %ep4abs0 %ep4abs1\n"
2041 		"%ep4rel = OpFMul %7 %ep4max %ep4\n"
2042 		"%cmp4 = OpFOrdGreaterThan %24 %abs4 %ep4rel\n"
2043 		"%26 = OpAny %23 %cmp4\n"
2044 		"OpSelectionMerge %28 None\n"
2045 		"OpBranchConditional %26 %27 %28\n"
2046 		"%27 = OpLabel\n"
2047 		"OpStore %color_out %30\n"
2048 		"OpBranch %28\n"
2049 		"%28 = OpLabel\n"
2050 		"%35 = OpAccessChain %34 %17 %31 %19 %33\n"
2051 		"%36 = OpLoad %6 %35\n"
2052 		"%37 = OpAccessChain %34 %color_in %33\n"
2053 		"%38 = OpLoad %6 %37\n"
2054 		"%subr = OpFSub %6 %36 %38\n"
2055 		"%absr = OpExtInst %6 %1 FAbs %subr\n"
2056 		"%ep1abs0 = OpExtInst %6 %1 FAbs %36\n"
2057 		"%ep1abs1 = OpExtInst %6 %1 FAbs %38\n"
2058 		"%ep1gt = OpFOrdGreaterThan %23 %ep1abs0 %ep1abs1\n"
2059 		"%ep1max = OpSelect %6 %ep1gt %ep1abs0 %ep1abs1\n"
2060 		"%ep1rel = OpFMul %6 %ep1max %ep\n"
2061 		"%cmpr = OpFOrdGreaterThan %23 %absr %ep1rel\n"
2062 		"OpSelectionMerge %41 None\n"
2063 		"OpBranchConditional %cmpr %40 %41\n"
2064 		"%40 = OpLabel\n"
2065 		"OpStore %color_out %30\n"
2066 		"OpBranch %41\n"
2067 		"%41 = OpLabel\n"
2068 		"%43 = OpAccessChain %34 %17 %31 %31 %42\n"
2069 		"%44 = OpLoad %6 %43\n"
2070 		"%46 = OpAccessChain %34 %color_in %45\n"
2071 		"%47 = OpLoad %6 %46\n"
2072 		"%suba = OpFSub %6 %44 %47\n"
2073 		"%absa = OpExtInst %6 %1 FAbs %suba\n"
2074 		"%ep1babs0 = OpExtInst %6 %1 FAbs %44\n"
2075 		"%ep1babs1 = OpExtInst %6 %1 FAbs %47\n"
2076 		"%ep1bgt = OpFOrdGreaterThan %23 %ep1babs0 %ep1babs1\n"
2077 		"%ep1bmax = OpSelect %6 %ep1bgt %ep1babs0 %ep1babs1\n"
2078 		"%ep1brel = OpFMul %6 %ep1bmax %ep\n"
2079 		"%cmpa = OpFOrdGreaterThan %23 %absa %ep1brel\n"
2080 		"OpSelectionMerge %50 None\n"
2081 		"OpBranchConditional %cmpa %49 %50\n"
2082 		"%49 = OpLabel\n"
2083 		"OpStore %color_out %30\n"
2084 		"OpBranch %50\n"
2085 		"%50 = OpLabel\n"
2086 		"OpReturn\n"
2087 		"OpFunctionEnd\n";
2088 
2089 		std::ostringstream vertex;
2090 		vertex << "vertex" << ndx;
2091 		std::ostringstream fragment;
2092 		fragment << "fragment" << ndx;
2093 
2094 		programCollection.spirvAsmSources.add(vertex.str()) << vertexShaderSource;
2095 		programCollection.spirvAsmSources.add(fragment.str()) << fragmentShaderSource;
2096 	}
2097 	{
2098 		/*#version 450
2099 		#extension GL_EXT_tessellation_shader : require
2100 		layout(vertices = 4) out;
2101 		layout(location = 0) in vec4		in_color[];
2102 		layout(location = 1) in ColorData
2103 		{
2104 		  vec4 colorVec;
2105 		  mat2 colorMat;
2106 		} inData[];
2107 		layout(location = 0) out vec4		out_color[];
2108 		layout(location = 1) out ColorData
2109 		{
2110 		  vec4 colorVec;
2111 		  mat2 colorMat;
2112 		} outData[];
2113 		void main (void)
2114 		{
2115 			if ( gl_InvocationID == 0 )
2116 			{
2117 				gl_TessLevelInner[0] = 4.0f;
2118 				gl_TessLevelInner[1] = 4.0f;
2119 				gl_TessLevelOuter[0] = 4.0f;
2120 				gl_TessLevelOuter[1] = 4.0f;
2121 				gl_TessLevelOuter[2] = 4.0f;
2122 				gl_TessLevelOuter[3] = 4.0f;
2123 			}
2124 			out_color[gl_InvocationID] = in_color[gl_InvocationID];
2125 			outData[gl_InvocationID].colorVec = inData[gl_InvocationID].colorVec;
2126 			outData[gl_InvocationID].colorMat = inData[gl_InvocationID].colorMat;
2127 			gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;
2128 		}*/
2129 
2130 		const string tessellationControlSource =
2131 		"; SPIR-V\n"
2132 		"; Version: 1.3\n"
2133 		"; Generator: Khronos Glslang Reference Front End; 2\n"
2134 		"; Bound: 88\n"
2135 		"; Schema: 0\n"
2136 		"OpCapability Tessellation\n"
2137 		"%1 = OpExtInstImport \"GLSL.std.450\"\n"
2138 		"OpMemoryModel Logical GLSL450\n"
2139 		"OpEntryPoint TessellationControl %4 \"main\" %8 %20 %29 %color_out %color_in %56 %61 %78 %83\n"
2140 		"OpExecutionMode %4 OutputVertices 4\n"
2141 		"OpDecorate %8 BuiltIn InvocationId\n"
2142 		"OpDecorate %20 Patch\n"
2143 		"OpDecorate %20 BuiltIn TessLevelInner\n"
2144 		"OpDecorate %29 Patch\n"
2145 		"OpDecorate %29 BuiltIn TessLevelOuter\n"
2146 		"OpDecorate %color_out Location 0\n"
2147 		"OpDecorate %color_in Location 0\n"
2148 		"OpDecorate %block_out Block\n"
2149 		"OpDecorate %56 Location 1\n"
2150 		"OpDecorate %block_in Block\n"
2151 		"OpDecorate %61 Location 1\n"
2152 		+decorations[0].others+
2153 		"OpMemberDecorate %75 0 BuiltIn Position\n"
2154 		"OpMemberDecorate %75 1 BuiltIn PointSize\n"
2155 		"OpMemberDecorate %75 2 BuiltIn ClipDistance\n"
2156 		"OpMemberDecorate %75 3 BuiltIn CullDistance\n"
2157 		"OpDecorate %75 Block\n"
2158 		"OpMemberDecorate %80 0 BuiltIn Position\n"
2159 		"OpMemberDecorate %80 1 BuiltIn PointSize\n"
2160 		"OpMemberDecorate %80 2 BuiltIn ClipDistance\n"
2161 		"OpMemberDecorate %80 3 BuiltIn CullDistance\n"
2162 		"OpDecorate %80 Block\n"
2163 		"%2 = OpTypeVoid\n"
2164 		"%3 = OpTypeFunction %2\n"
2165 		"%6 = OpTypeInt 32 1\n"
2166 		"%7 = OpTypePointer Input %6\n"
2167 		"%8 = OpVariable %7 Input\n"
2168 		"%10 = OpConstant %6 0\n"
2169 		"%11 = OpTypeBool\n"
2170 		"%15 = OpTypeFloat 32\n"
2171 		"%16 = OpTypeInt 32 0\n"
2172 		"%17 = OpConstant %16 2\n"
2173 		"%18 = OpTypeArray %15 %17\n"
2174 		"%19 = OpTypePointer Output %18\n"
2175 		"%20 = OpVariable %19 Output\n"
2176 		"%21 = OpConstant %15 4\n"
2177 		"%22 = OpTypePointer Output %15\n"
2178 		"%24 = OpConstant %6 1\n"
2179 		"%26 = OpConstant %16 4\n"
2180 		"%27 = OpTypeArray %15 %26\n"
2181 		"%28 = OpTypePointer Output %27\n"
2182 		"%29 = OpVariable %28 Output\n"
2183 		"%32 = OpConstant %6 2\n"
2184 		"%34 = OpConstant %6 3\n"
2185 		"%36 = OpTypeVector %15 4\n"
2186 		"%37 = OpTypeArray %36 %26\n"
2187 		"%38 = OpTypePointer Output %37\n"
2188 		"%color_out = OpVariable %38 Output\n"
2189 		"%41 = OpConstant %16 32\n"
2190 		"%42 = OpTypeArray %36 %41\n"
2191 		"%43 = OpTypePointer Input %42\n"
2192 		"%color_in = OpVariable %43 Input\n"
2193 		"%46 = OpTypePointer Input %36\n"
2194 		"%49 = OpTypePointer Output %36\n"
2195 		"%51 = OpTypeVector %15 2\n"
2196 		"%52 = OpTypeMatrix %51 2\n"
2197 		"%block_out = OpTypeStruct %36 %52\n"
2198 		"%54 = OpTypeArray %block_out %26\n"
2199 		"%55 = OpTypePointer Output %54\n"
2200 		"%56 = OpVariable %55 Output\n"
2201 		"%block_in = OpTypeStruct %36 %52\n"
2202 		"%59 = OpTypeArray %block_in %41\n"
2203 		"%60 = OpTypePointer Input %59\n"
2204 		"%61 = OpVariable %60 Input\n"
2205 		"%68 = OpTypePointer Input %52\n"
2206 		"%71 = OpTypePointer Output %52\n"
2207 		"%73 = OpConstant %16 1\n"
2208 		"%74 = OpTypeArray %15 %73\n"
2209 		"%75 = OpTypeStruct %36 %15 %74 %74\n"
2210 		"%76 = OpTypeArray %75 %26\n"
2211 		"%77 = OpTypePointer Output %76\n"
2212 		"%78 = OpVariable %77 Output\n"
2213 		"%80 = OpTypeStruct %36 %15 %74 %74\n"
2214 		"%81 = OpTypeArray %80 %41\n"
2215 		"%82 = OpTypePointer Input %81\n"
2216 		"%83 = OpVariable %82 Input\n"
2217 		"%4 = OpFunction %2 None %3\n"
2218 		"%5 = OpLabel\n"
2219 		"%9 = OpLoad %6 %8\n"
2220 		"%12 = OpIEqual %11 %9 %10\n"
2221 		"OpSelectionMerge %14 None\n"
2222 		"OpBranchConditional %12 %13 %14\n"
2223 		"%13 = OpLabel\n"
2224 		"%23 = OpAccessChain %22 %20 %10\n"
2225 		"OpStore %23 %21\n"
2226 		"%25 = OpAccessChain %22 %20 %24\n"
2227 		"OpStore %25 %21\n"
2228 		"%30 = OpAccessChain %22 %29 %10\n"
2229 		"OpStore %30 %21\n"
2230 		"%31 = OpAccessChain %22 %29 %24\n"
2231 		"OpStore %31 %21\n"
2232 		"%33 = OpAccessChain %22 %29 %32\n"
2233 		"OpStore %33 %21\n"
2234 		"%35 = OpAccessChain %22 %29 %34\n"
2235 		"OpStore %35 %21\n"
2236 		"OpBranch %14\n"
2237 		"%14 = OpLabel\n"
2238 		"%40 = OpLoad %6 %8\n"
2239 		"%45 = OpLoad %6 %8\n"
2240 		"%47 = OpAccessChain %46 %color_in %45\n"
2241 		"%48 = OpLoad %36 %47\n"
2242 		"%50 = OpAccessChain %49 %color_out %40\n"
2243 		"OpStore %50 %48\n"
2244 		"%57 = OpLoad %6 %8\n"
2245 		"%62 = OpLoad %6 %8\n"
2246 		"%63 = OpAccessChain %46 %61 %62 %10\n"
2247 		"%64 = OpLoad %36 %63\n"
2248 		"%65 = OpAccessChain %49 %56 %57 %10\n"
2249 		"OpStore %65 %64\n"
2250 		"%66 = OpLoad %6 %8\n"
2251 		"%67 = OpLoad %6 %8\n"
2252 		"%69 = OpAccessChain %68 %61 %67 %24\n"
2253 		"%70 = OpLoad %52 %69\n"
2254 		"%72 = OpAccessChain %71 %56 %66 %24\n"
2255 		"OpStore %72 %70\n"
2256 		"%79 = OpLoad %6 %8\n"
2257 		"%84 = OpLoad %6 %8\n"
2258 		"%85 = OpAccessChain %46 %83 %84 %10\n"
2259 		"%86 = OpLoad %36 %85\n"
2260 		"%87 = OpAccessChain %49 %78 %79 %10\n"
2261 		"OpStore %87 %86\n"
2262 		"OpReturn\n"
2263 		"OpFunctionEnd\n";
2264 
2265 		/*#version 450
2266 		#extension GL_EXT_tessellation_shader : require
2267 		layout( quads, equal_spacing, ccw ) in;
2268 		layout(location = 0) in vec4		in_color[];
2269 		layout(location = 1) in ColorData
2270 		{
2271 		  vec4 colorVec;
2272 		  mat2 colorMat;
2273 		} inData[];
2274 		layout(location = 0) out vec4		out_color;
2275 		layout(location = 1) out ColorData
2276 		{
2277 		  vec4 colorVec;
2278 		  mat2 colorMat;
2279 		} outData;
2280 		void main (void)
2281 		{
2282 			const float u = gl_TessCoord.x;
2283 			const float v = gl_TessCoord.y;
2284 			const float w = gl_TessCoord.z;
2285 			out_color = (1 - u) * (1 - v) * in_color[0] +(1 - u) * v * in_color[1] + u * (1 - v) * in_color[2] + u * v * in_color[3];
2286 			outData.colorVec = (1 - u) * (1 - v) * inData[0].colorVec +(1 - u) * v * inData[1].colorVec + u * (1 - v) * inData[2].colorVec + u * v * inData[3].colorVec;
2287 			outData.colorMat = (1 - u) * (1 - v) * inData[0].colorMat +(1 - u) * v * inData[1].colorMat + u * (1 - v) * inData[2].colorMat + u * v * inData[3].colorMat;
2288 			gl_Position = (1 - u) * (1 - v) * gl_in[0].gl_Position +(1 - u) * v * gl_in[1].gl_Position + u * (1 - v) * gl_in[2].gl_Position + u * v * gl_in[3].gl_Position;
2289 		}*/
2290 
2291 		const string tessellationEvaluationSource =
2292 		"; SPIR-V\n"
2293 		"; Version: 1.3\n"
2294 		"; Generator: Khronos Glslang Reference Front End; 2\n"
2295 		"; Bound: 203\n"
2296 		"; Schema: 0\n"
2297 		"OpCapability Tessellation\n"
2298 		"%1 = OpExtInstImport \"GLSL.std.450\"\n"
2299 		"OpMemoryModel Logical GLSL450\n"
2300 		"OpEntryPoint TessellationEvaluation %4 \"main\" %11 %color_out %color_in %74 %83 %166 %175\n"
2301 		"OpExecutionMode %4 Quads\n"
2302 		"OpExecutionMode %4 SpacingEqual\n"
2303 		"OpExecutionMode %4 VertexOrderCcw\n"
2304 		"OpDecorate %11 BuiltIn TessCoord\n"
2305 		"OpDecorate %color_out Location 0\n"
2306 		"OpDecorate %color_in Location 0\n"
2307 		"OpDecorate %block_out Block\n"
2308 		"OpDecorate %74 Location 1\n"
2309 		"OpDecorate %block_in Block\n"
2310 		"OpDecorate %83 Location 1\n"
2311 		+decorations[0].others+
2312 		"OpMemberDecorate %164 0 BuiltIn Position\n"
2313 		"OpMemberDecorate %164 1 BuiltIn PointSize\n"
2314 		"OpMemberDecorate %164 2 BuiltIn ClipDistance\n"
2315 		"OpMemberDecorate %164 3 BuiltIn CullDistance\n"
2316 		"OpDecorate %164 Block\n"
2317 		"OpMemberDecorate %172 0 BuiltIn Position\n"
2318 		"OpMemberDecorate %172 1 BuiltIn PointSize\n"
2319 		"OpMemberDecorate %172 2 BuiltIn ClipDistance\n"
2320 		"OpMemberDecorate %172 3 BuiltIn CullDistance\n"
2321 		"OpDecorate %172 Block\n"
2322 		"%2 = OpTypeVoid\n"
2323 		"%3 = OpTypeFunction %2\n"
2324 		"%6 = OpTypeFloat 32\n"
2325 		"%7 = OpTypePointer Function %6\n"
2326 		"%9 = OpTypeVector %6 3\n"
2327 		"%10 = OpTypePointer Input %9\n"
2328 		"%11 = OpVariable %10 Input\n"
2329 		"%12 = OpTypeInt 32 0\n"
2330 		"%13 = OpConstant %12 0\n"
2331 		"%14 = OpTypePointer Input %6\n"
2332 		"%18 = OpConstant %12 1\n"
2333 		"%22 = OpConstant %12 2\n"
2334 		"%25 = OpTypeVector %6 4\n"
2335 		"%26 = OpTypePointer Output %25\n"
2336 		"%color_out = OpVariable %26 Output\n"
2337 		"%28 = OpConstant %6 1\n"
2338 		"%34 = OpConstant %12 32\n"
2339 		"%35 = OpTypeArray %25 %34\n"
2340 		"%36 = OpTypePointer Input %35\n"
2341 		"%color_in = OpVariable %36 Input\n"
2342 		"%38 = OpTypeInt 32 1\n"
2343 		"%39 = OpConstant %38 0\n"
2344 		"%40 = OpTypePointer Input %25\n"
2345 		"%48 = OpConstant %38 1\n"
2346 		"%57 = OpConstant %38 2\n"
2347 		"%65 = OpConstant %38 3\n"
2348 		"%70 = OpTypeVector %6 2\n"
2349 		"%71 = OpTypeMatrix %70 2\n"
2350 		"%block_out = OpTypeStruct %25 %71\n"
2351 		"%73 = OpTypePointer Output %block_out\n"
2352 		"%74 = OpVariable %73 Output\n"
2353 		"%block_in = OpTypeStruct %25 %71\n"
2354 		"%81 = OpTypeArray %block_in %34\n"
2355 		"%82 = OpTypePointer Input %81\n"
2356 		"%83 = OpVariable %82 Input\n"
2357 		"%116 = OpTypePointer Input %71\n"
2358 		"%161 = OpTypePointer Output %71\n"
2359 		"%163 = OpTypeArray %6 %18\n"
2360 		"%164 = OpTypeStruct %25 %6 %163 %163\n"
2361 		"%165 = OpTypePointer Output %164\n"
2362 		"%166 = OpVariable %165 Output\n"
2363 		"%172 = OpTypeStruct %25 %6 %163 %163\n"
2364 		"%173 = OpTypeArray %172 %34\n"
2365 		"%174 = OpTypePointer Input %173\n"
2366 		"%175 = OpVariable %174 Input\n"
2367 		"%4 = OpFunction %2 None %3\n"
2368 		"%5 = OpLabel\n"
2369 		"%8 = OpVariable %7 Function\n"
2370 		"%17 = OpVariable %7 Function\n"
2371 		"%21 = OpVariable %7 Function\n"
2372 		"%15 = OpAccessChain %14 %11 %13\n"
2373 		"%16 = OpLoad %6 %15\n"
2374 		"OpStore %8 %16\n"
2375 		"%19 = OpAccessChain %14 %11 %18\n"
2376 		"%20 = OpLoad %6 %19\n"
2377 		"OpStore %17 %20\n"
2378 		"%23 = OpAccessChain %14 %11 %22\n"
2379 		"%24 = OpLoad %6 %23\n"
2380 		"OpStore %21 %24\n"
2381 		"%29 = OpLoad %6 %8\n"
2382 		"%30 = OpFSub %6 %28 %29\n"
2383 		"%31 = OpLoad %6 %17\n"
2384 		"%32 = OpFSub %6 %28 %31\n"
2385 		"%33 = OpFMul %6 %30 %32\n"
2386 		"%41 = OpAccessChain %40 %color_in %39\n"
2387 		"%42 = OpLoad %25 %41\n"
2388 		"%43 = OpVectorTimesScalar %25 %42 %33\n"
2389 		"%44 = OpLoad %6 %8\n"
2390 		"%45 = OpFSub %6 %28 %44\n"
2391 		"%46 = OpLoad %6 %17\n"
2392 		"%47 = OpFMul %6 %45 %46\n"
2393 		"%49 = OpAccessChain %40 %color_in %48\n"
2394 		"%50 = OpLoad %25 %49\n"
2395 		"%51 = OpVectorTimesScalar %25 %50 %47\n"
2396 		"%52 = OpFAdd %25 %43 %51\n"
2397 		"%53 = OpLoad %6 %8\n"
2398 		"%54 = OpLoad %6 %17\n"
2399 		"%55 = OpFSub %6 %28 %54\n"
2400 		"%56 = OpFMul %6 %53 %55\n"
2401 		"%58 = OpAccessChain %40 %color_in %57\n"
2402 		"%59 = OpLoad %25 %58\n"
2403 		"%60 = OpVectorTimesScalar %25 %59 %56\n"
2404 		"%61 = OpFAdd %25 %52 %60\n"
2405 		"%62 = OpLoad %6 %8\n"
2406 		"%63 = OpLoad %6 %17\n"
2407 		"%64 = OpFMul %6 %62 %63\n"
2408 		"%66 = OpAccessChain %40 %color_in %65\n"
2409 		"%67 = OpLoad %25 %66\n"
2410 		"%68 = OpVectorTimesScalar %25 %67 %64\n"
2411 		"%69 = OpFAdd %25 %61 %68\n"
2412 		"OpStore %color_out %69\n"
2413 		"%75 = OpLoad %6 %8\n"
2414 		"%76 = OpFSub %6 %28 %75\n"
2415 		"%77 = OpLoad %6 %17\n"
2416 		"%78 = OpFSub %6 %28 %77\n"
2417 		"%79 = OpFMul %6 %76 %78\n"
2418 		"%84 = OpAccessChain %40 %83 %39 %39\n"
2419 		"%85 = OpLoad %25 %84\n"
2420 		"%86 = OpVectorTimesScalar %25 %85 %79\n"
2421 		"%87 = OpLoad %6 %8\n"
2422 		"%88 = OpFSub %6 %28 %87\n"
2423 		"%89 = OpLoad %6 %17\n"
2424 		"%90 = OpFMul %6 %88 %89\n"
2425 		"%91 = OpAccessChain %40 %83 %48 %39\n"
2426 		"%92 = OpLoad %25 %91\n"
2427 		"%93 = OpVectorTimesScalar %25 %92 %90\n"
2428 		"%94 = OpFAdd %25 %86 %93\n"
2429 		"%95 = OpLoad %6 %8\n"
2430 		"%96 = OpLoad %6 %17\n"
2431 		"%97 = OpFSub %6 %28 %96\n"
2432 		"%98 = OpFMul %6 %95 %97\n"
2433 		"%99 = OpAccessChain %40 %83 %57 %39\n"
2434 		"%100 = OpLoad %25 %99\n"
2435 		"%101 = OpVectorTimesScalar %25 %100 %98\n"
2436 		"%102 = OpFAdd %25 %94 %101\n"
2437 		"%103 = OpLoad %6 %8\n"
2438 		"%104 = OpLoad %6 %17\n"
2439 		"%105 = OpFMul %6 %103 %104\n"
2440 		"%106 = OpAccessChain %40 %83 %65 %39\n"
2441 		"%107 = OpLoad %25 %106\n"
2442 		"%108 = OpVectorTimesScalar %25 %107 %105\n"
2443 		"%109 = OpFAdd %25 %102 %108\n"
2444 		"%110 = OpAccessChain %26 %74 %39\n"
2445 		"OpStore %110 %109\n"
2446 		"%111 = OpLoad %6 %8\n"
2447 		"%112 = OpFSub %6 %28 %111\n"
2448 		"%113 = OpLoad %6 %17\n"
2449 		"%114 = OpFSub %6 %28 %113\n"
2450 		"%115 = OpFMul %6 %112 %114\n"
2451 		"%117 = OpAccessChain %116 %83 %39 %48\n"
2452 		"%118 = OpLoad %71 %117\n"
2453 		"%119 = OpMatrixTimesScalar %71 %118 %115\n"
2454 		"%120 = OpLoad %6 %8\n"
2455 		"%121 = OpFSub %6 %28 %120\n"
2456 		"%122 = OpLoad %6 %17\n"
2457 		"%123 = OpFMul %6 %121 %122\n"
2458 		"%124 = OpAccessChain %116 %83 %48 %48\n"
2459 		"%125 = OpLoad %71 %124\n"
2460 		"%126 = OpMatrixTimesScalar %71 %125 %123\n"
2461 		"%127 = OpCompositeExtract %70 %119 0\n"
2462 		"%128 = OpCompositeExtract %70 %126 0\n"
2463 		"%129 = OpFAdd %70 %127 %128\n"
2464 		"%130 = OpCompositeExtract %70 %119 1\n"
2465 		"%131 = OpCompositeExtract %70 %126 1\n"
2466 		"%132 = OpFAdd %70 %130 %131\n"
2467 		"%133 = OpCompositeConstruct %71 %129 %132\n"
2468 		"%134 = OpLoad %6 %8\n"
2469 		"%135 = OpLoad %6 %17\n"
2470 		"%136 = OpFSub %6 %28 %135\n"
2471 		"%137 = OpFMul %6 %134 %136\n"
2472 		"%138 = OpAccessChain %116 %83 %57 %48\n"
2473 		"%139 = OpLoad %71 %138\n"
2474 		"%140 = OpMatrixTimesScalar %71 %139 %137\n"
2475 		"%141 = OpCompositeExtract %70 %133 0\n"
2476 		"%142 = OpCompositeExtract %70 %140 0\n"
2477 		"%143 = OpFAdd %70 %141 %142\n"
2478 		"%144 = OpCompositeExtract %70 %133 1\n"
2479 		"%145 = OpCompositeExtract %70 %140 1\n"
2480 		"%146 = OpFAdd %70 %144 %145\n"
2481 		"%147 = OpCompositeConstruct %71 %143 %146\n"
2482 		"%148 = OpLoad %6 %8\n"
2483 		"%149 = OpLoad %6 %17\n"
2484 		"%150 = OpFMul %6 %148 %149\n"
2485 		"%151 = OpAccessChain %116 %83 %65 %48\n"
2486 		"%152 = OpLoad %71 %151\n"
2487 		"%153 = OpMatrixTimesScalar %71 %152 %150\n"
2488 		"%154 = OpCompositeExtract %70 %147 0\n"
2489 		"%155 = OpCompositeExtract %70 %153 0\n"
2490 		"%156 = OpFAdd %70 %154 %155\n"
2491 		"%157 = OpCompositeExtract %70 %147 1\n"
2492 		"%158 = OpCompositeExtract %70 %153 1\n"
2493 		"%159 = OpFAdd %70 %157 %158\n"
2494 		"%160 = OpCompositeConstruct %71 %156 %159\n"
2495 		"%162 = OpAccessChain %161 %74 %48\n"
2496 		"OpStore %162 %160\n"
2497 		"%167 = OpLoad %6 %8\n"
2498 		"%168 = OpFSub %6 %28 %167\n"
2499 		"%169 = OpLoad %6 %17\n"
2500 		"%170 = OpFSub %6 %28 %169\n"
2501 		"%171 = OpFMul %6 %168 %170\n"
2502 		"%176 = OpAccessChain %40 %175 %39 %39\n"
2503 		"%177 = OpLoad %25 %176\n"
2504 		"%178 = OpVectorTimesScalar %25 %177 %171\n"
2505 		"%179 = OpLoad %6 %8\n"
2506 		"%180 = OpFSub %6 %28 %179\n"
2507 		"%181 = OpLoad %6 %17\n"
2508 		"%182 = OpFMul %6 %180 %181\n"
2509 		"%183 = OpAccessChain %40 %175 %48 %39\n"
2510 		"%184 = OpLoad %25 %183\n"
2511 		"%185 = OpVectorTimesScalar %25 %184 %182\n"
2512 		"%186 = OpFAdd %25 %178 %185\n"
2513 		"%187 = OpLoad %6 %8\n"
2514 		"%188 = OpLoad %6 %17\n"
2515 		"%189 = OpFSub %6 %28 %188\n"
2516 		"%190 = OpFMul %6 %187 %189\n"
2517 		"%191 = OpAccessChain %40 %175 %57 %39\n"
2518 		"%192 = OpLoad %25 %191\n"
2519 		"%193 = OpVectorTimesScalar %25 %192 %190\n"
2520 		"%194 = OpFAdd %25 %186 %193\n"
2521 		"%195 = OpLoad %6 %8\n"
2522 		"%196 = OpLoad %6 %17\n"
2523 		"%197 = OpFMul %6 %195 %196\n"
2524 		"%198 = OpAccessChain %40 %175 %65 %39\n"
2525 		"%199 = OpLoad %25 %198\n"
2526 		"%200 = OpVectorTimesScalar %25 %199 %197\n"
2527 		"%201 = OpFAdd %25 %194 %200\n"
2528 		"%202 = OpAccessChain %26 %166 %39\n"
2529 		"OpStore %202 %201\n"
2530 		"OpReturn\n"
2531 		"OpFunctionEnd\n";
2532 		programCollection.spirvAsmSources.add("tessellation_control") << tessellationControlSource;
2533 		programCollection.spirvAsmSources.add("tessellation_evaluation") << tessellationEvaluationSource;
2534 	}
2535 	{
2536 
2537 		/*#version 450
2538 		layout(triangles) in;
2539 		layout(triangle_strip, max_vertices = 3) out;
2540 		layout(location = 0) in vec4		in_color[];
2541 		layout(location = 1) in ColorData
2542 		{
2543 		  vec4 colorVec;
2544 		  mat2 colorMat;
2545 		} inData[];
2546 		layout(location = 0) out vec4		out_color;
2547 		layout(location = 1) out ColorData
2548 		{
2549 		  vec4 colorVec;
2550 		  mat2 colorMat;
2551 		} outData;
2552 		void main (void)
2553 		{
2554 			out_color = in_color[0];
2555 			outData.colorVec = inData[0].colorVec;
2556 			outData.colorMat = inData[0].colorMat;
2557 			gl_Position = gl_in[0].gl_Position;
2558 			EmitVertex();
2559 			out_color = in_color[1];
2560 			outData.colorVec = inData[1].colorVec;
2561 			outData.colorMat = inData[1].colorMat;
2562 			gl_Position = gl_in[1].gl_Position;
2563 			EmitVertex();
2564 			out_color = in_color[2];
2565 			outData.colorVec = inData[2].colorVec;
2566 			outData.colorMat = inData[2].colorMat;
2567 			gl_Position = gl_in[2].gl_Position;
2568 			EmitVertex();
2569 			EndPrimitive();
2570 		}*/
2571 		const string geometrySource =
2572 		"; SPIR-V\n"
2573 		"; Version: 1.3\n"
2574 		"; Generator: Khronos Glslang Reference Front End; 2\n"
2575 		"; Bound: 73\n"
2576 		"; Schema: 0\n"
2577 		"OpCapability Geometry\n"
2578 		"%1 = OpExtInstImport \"GLSL.std.450\"\n"
2579 		"OpMemoryModel Logical GLSL450\n"
2580 		"OpEntryPoint Geometry %4 \"main\" %color_out %color_in %24 %28 %42 %46\n"
2581 		"OpExecutionMode %4 Triangles\n"
2582 		"OpExecutionMode %4 Invocations 1\n"
2583 		"OpExecutionMode %4 OutputTriangleStrip\n"
2584 		"OpExecutionMode %4 OutputVertices 3\n"
2585 		"OpDecorate %color_out Location 0\n"
2586 		"OpDecorate %color_in Location 0\n"
2587 		"OpDecorate %block_out Block\n"
2588 		"OpDecorate %24 Location 1\n"
2589 		"OpDecorate %block_in Block\n"
2590 		"OpDecorate %28 Location 1\n"
2591 		+decorations[0].others+
2592 		"OpMemberDecorate %40 0 BuiltIn Position\n"
2593 		"OpMemberDecorate %40 1 BuiltIn PointSize\n"
2594 		"OpMemberDecorate %40 2 BuiltIn ClipDistance\n"
2595 		"OpMemberDecorate %40 3 BuiltIn CullDistance\n"
2596 		"OpDecorate %40 Block\n"
2597 		"OpMemberDecorate %43 0 BuiltIn Position\n"
2598 		"OpMemberDecorate %43 1 BuiltIn PointSize\n"
2599 		"OpMemberDecorate %43 2 BuiltIn ClipDistance\n"
2600 		"OpMemberDecorate %43 3 BuiltIn CullDistance\n"
2601 		"OpDecorate %43 Block\n"
2602 		"%2 = OpTypeVoid\n"
2603 		"%3 = OpTypeFunction %2\n"
2604 		"%6 = OpTypeFloat 32\n"
2605 		"%7 = OpTypeVector %6 4\n"
2606 		"%8 = OpTypePointer Output %7\n"
2607 		"%color_out = OpVariable %8 Output\n"
2608 		"%10 = OpTypeInt 32 0\n"
2609 		"%11 = OpConstant %10 3\n"
2610 		"%12 = OpTypeArray %7 %11\n"
2611 		"%13 = OpTypePointer Input %12\n"
2612 		"%color_in = OpVariable %13 Input\n"
2613 		"%15 = OpTypeInt 32 1\n"
2614 		"%16 = OpConstant %15 0\n"
2615 		"%17 = OpTypePointer Input %7\n"
2616 		"%20 = OpTypeVector %6 2\n"
2617 		"%21 = OpTypeMatrix %20 2\n"
2618 		"%block_out = OpTypeStruct %7 %21\n"
2619 		"%23 = OpTypePointer Output %block_out\n"
2620 		"%24 = OpVariable %23 Output\n"
2621 		"%block_in = OpTypeStruct %7 %21\n"
2622 		"%26 = OpTypeArray %block_in %11\n"
2623 		"%27 = OpTypePointer Input %26\n"
2624 		"%28 = OpVariable %27 Input\n"
2625 		"%32 = OpConstant %15 1\n"
2626 		"%33 = OpTypePointer Input %21\n"
2627 		"%36 = OpTypePointer Output %21\n"
2628 		"%38 = OpConstant %10 1\n"
2629 		"%39 = OpTypeArray %6 %38\n"
2630 		"%40 = OpTypeStruct %7 %6 %39 %39\n"
2631 		"%41 = OpTypePointer Output %40\n"
2632 		"%42 = OpVariable %41 Output\n"
2633 		"%43 = OpTypeStruct %7 %6 %39 %39\n"
2634 		"%44 = OpTypeArray %43 %11\n"
2635 		"%45 = OpTypePointer Input %44\n"
2636 		"%46 = OpVariable %45 Input\n"
2637 		"%61 = OpConstant %15 2\n"
2638 		"%4 = OpFunction %2 None %3\n"
2639 		"%5 = OpLabel\n"
2640 		"%18 = OpAccessChain %17 %color_in %16\n"
2641 		"%19 = OpLoad %7 %18\n"
2642 		"OpStore %color_out %19\n"
2643 		"%29 = OpAccessChain %17 %28 %16 %16\n"
2644 		"%30 = OpLoad %7 %29\n"
2645 		"%31 = OpAccessChain %8 %24 %16\n"
2646 		"OpStore %31 %30\n"
2647 		"%34 = OpAccessChain %33 %28 %16 %32\n"
2648 		"%35 = OpLoad %21 %34\n"
2649 		"%37 = OpAccessChain %36 %24 %32\n"
2650 		"OpStore %37 %35\n"
2651 		"%47 = OpAccessChain %17 %46 %16 %16\n"
2652 		"%48 = OpLoad %7 %47\n"
2653 		"%49 = OpAccessChain %8 %42 %16\n"
2654 		"OpStore %49 %48\n"
2655 		"OpEmitVertex\n"
2656 		"%50 = OpAccessChain %17 %color_in %32\n"
2657 		"%51 = OpLoad %7 %50\n"
2658 		"OpStore %color_out %51\n"
2659 		"%52 = OpAccessChain %17 %28 %32 %16\n"
2660 		"%53 = OpLoad %7 %52\n"
2661 		"%54 = OpAccessChain %8 %24 %16\n"
2662 		"OpStore %54 %53\n"
2663 		"%55 = OpAccessChain %33 %28 %32 %32\n"
2664 		"%56 = OpLoad %21 %55\n"
2665 		"%57 = OpAccessChain %36 %24 %32\n"
2666 		"OpStore %57 %56\n"
2667 		"%58 = OpAccessChain %17 %46 %32 %16\n"
2668 		"%59 = OpLoad %7 %58\n"
2669 		"%60 = OpAccessChain %8 %42 %16\n"
2670 		"OpStore %60 %59\n"
2671 		"OpEmitVertex\n"
2672 		"%62 = OpAccessChain %17 %color_in %61\n"
2673 		"%63 = OpLoad %7 %62\n"
2674 		"OpStore %color_out %63\n"
2675 		"%64 = OpAccessChain %17 %28 %61 %16\n"
2676 		"%65 = OpLoad %7 %64\n"
2677 		"%66 = OpAccessChain %8 %24 %16\n"
2678 		"OpStore %66 %65\n"
2679 		"%67 = OpAccessChain %33 %28 %61 %32\n"
2680 		"%68 = OpLoad %21 %67\n"
2681 		"%69 = OpAccessChain %36 %24 %32\n"
2682 		"OpStore %69 %68\n"
2683 		"%70 = OpAccessChain %17 %46 %61 %16\n"
2684 		"%71 = OpLoad %7 %70\n"
2685 		"%72 = OpAccessChain %8 %42 %16\n"
2686 		"OpStore %72 %71\n"
2687 		"OpEmitVertex\n"
2688 		"OpEndPrimitive\n"
2689 		"OpReturn\n"
2690 		"OpFunctionEnd\n";
2691 		programCollection.spirvAsmSources.add("geometry") << geometrySource;
2692 	}
2693 }
2694 } // anonymous
2695 
createCrossStageInterfaceTests(tcu::TestContext & testCtx)2696 tcu::TestCaseGroup* createCrossStageInterfaceTests (tcu::TestContext& testCtx)
2697 {
2698 	de::MovePtr<tcu::TestCaseGroup>		testGroup(new tcu::TestCaseGroup(testCtx, "cross_stage", ""));
2699 	{
2700 		de::MovePtr<tcu::TestCaseGroup>		basicGroup(new tcu::TestCaseGroup(testCtx, "basic_type", ""));
2701 		de::MovePtr<tcu::TestCaseGroup>		interfaceGroup(new tcu::TestCaseGroup(testCtx, "interface_blocks", ""));
2702 		{
2703 			TestParameters parm(TEST_TYPE_FLAT,3);
2704 			for (int ndx = 0; ndx < CrossStageTestInstance::DECORATION_LAST; ++ndx)
2705 				parm.testOptions[ndx] = ndx;
2706 
2707 			basicGroup->addChild(new CrossStageBasicTestsCase(testCtx, "flat", "", parm));
2708 			interfaceGroup->addChild(new CrossStageInterfaceTestsCase(testCtx, "flat", "", parm));
2709 
2710 			parm.qualifier = TEST_TYPE_NOPERSPECTIVE;
2711 			basicGroup->addChild(new CrossStageBasicTestsCase(testCtx, "no_perspective", "", parm));
2712 			interfaceGroup->addChild(new CrossStageInterfaceTestsCase(testCtx, "no_perspective", "", parm));
2713 		}
2714 
2715 		{
2716 			TestParameters parm(TEST_TYPE_RELAXEDPRECISION,1);
2717 			parm.testOptions[0] = CrossStageTestInstance::DECORATION_IN_ALL_SHADERS;
2718 			basicGroup->addChild(new CrossStageBasicTestsCase(testCtx, "relaxedprecision", "", parm));
2719 			interfaceGroup->addChild(new CrossStageInterfaceTestsCase(testCtx, "relaxedprecision", "", parm));
2720 		}
2721 		testGroup->addChild(basicGroup.release());
2722 		testGroup->addChild(interfaceGroup.release());
2723 	}
2724 
2725 	return testGroup.release();
2726 }
2727 
2728 } // SpirVAssembly
2729 } // vkt
2730