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