Merge remote-tracking branch 'goog/upstream-vulkan-cts-next' into vulkan-cts-1.1...
[platform/upstream/VK-GL-CTS.git] / external / vulkancts / modules / vulkan / spirv_assembly / vktSpvAsmGraphicsShaderTestUtil.cpp
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 Graphics pipeline for SPIR-V assembly tests
22  *//*--------------------------------------------------------------------*/
23
24 #include "vktSpvAsmGraphicsShaderTestUtil.hpp"
25
26 #include "tcuFloat.hpp"
27 #include "tcuStringTemplate.hpp"
28
29 #include "vkDefs.hpp"
30 #include "vkMemUtil.hpp"
31 #include "vkPlatform.hpp"
32 #include "vkQueryUtil.hpp"
33 #include "vkRefUtil.hpp"
34 #include "vkTypeUtil.hpp"
35
36 #include "deRandom.hpp"
37
38 namespace vkt
39 {
40 namespace SpirVAssembly
41 {
42
43 using namespace vk;
44 using std::map;
45 using std::string;
46 using std::vector;
47 using tcu::Float16;
48 using tcu::Float32;
49 using tcu::IVec3;
50 using tcu::IVec4;
51 using tcu::RGBA;
52 using tcu::TestLog;
53 using tcu::TestStatus;
54 using tcu::Vec4;
55 using de::UniquePtr;
56 using tcu::StringTemplate;
57 using tcu::Vec4;
58
59 deUint32 IFDataType::getElementNumBytes (void) const
60 {
61         if (elementType < NUMBERTYPE_END32)
62                 return 4;
63
64         return 2;
65 }
66
67 VkFormat IFDataType::getVkFormat (void) const
68 {
69         if (numElements == 1)
70         {
71                 switch (elementType)
72                 {
73                         case NUMBERTYPE_FLOAT32:        return VK_FORMAT_R32_SFLOAT;
74                         case NUMBERTYPE_INT32:          return VK_FORMAT_R32_SINT;
75                         case NUMBERTYPE_UINT32:         return VK_FORMAT_R32_UINT;
76                         case NUMBERTYPE_FLOAT16:        return VK_FORMAT_R16_SFLOAT;
77                         case NUMBERTYPE_INT16:          return VK_FORMAT_R16_SINT;
78                         case NUMBERTYPE_UINT16:         return VK_FORMAT_R16_UINT;
79                         default:                                        break;
80                 }
81         }
82         else if (numElements == 2)
83         {
84                 switch (elementType)
85                 {
86                         case NUMBERTYPE_FLOAT32:        return VK_FORMAT_R32G32_SFLOAT;
87                         case NUMBERTYPE_INT32:          return VK_FORMAT_R32G32_SINT;
88                         case NUMBERTYPE_UINT32:         return VK_FORMAT_R32G32_UINT;
89                         case NUMBERTYPE_FLOAT16:        return VK_FORMAT_R16G16_SFLOAT;
90                         case NUMBERTYPE_INT16:          return VK_FORMAT_R16G16_SINT;
91                         case NUMBERTYPE_UINT16:         return VK_FORMAT_R16G16_UINT;
92                         default:                                        break;
93                 }
94         }
95         else if (numElements == 3)
96         {
97                 switch (elementType)
98                 {
99                         case NUMBERTYPE_FLOAT32:        return VK_FORMAT_R32G32B32_SFLOAT;
100                         case NUMBERTYPE_INT32:          return VK_FORMAT_R32G32B32_SINT;
101                         case NUMBERTYPE_UINT32:         return VK_FORMAT_R32G32B32_UINT;
102                         case NUMBERTYPE_FLOAT16:        return VK_FORMAT_R16G16B16_SFLOAT;
103                         case NUMBERTYPE_INT16:          return VK_FORMAT_R16G16B16_SINT;
104                         case NUMBERTYPE_UINT16:         return VK_FORMAT_R16G16B16_UINT;
105                         default:                                        break;
106                 }
107         }
108         else if (numElements == 4)
109         {
110                 switch (elementType)
111                 {
112                         case NUMBERTYPE_FLOAT32:        return VK_FORMAT_R32G32B32A32_SFLOAT;
113                         case NUMBERTYPE_INT32:          return VK_FORMAT_R32G32B32A32_SINT;
114                         case NUMBERTYPE_UINT32:         return VK_FORMAT_R32G32B32A32_UINT;
115                         case NUMBERTYPE_FLOAT16:        return VK_FORMAT_R16G16B16A16_SFLOAT;
116                         case NUMBERTYPE_INT16:          return VK_FORMAT_R16G16B16A16_SINT;
117                         case NUMBERTYPE_UINT16:         return VK_FORMAT_R16G16B16A16_UINT;
118                         default:                                        break;
119                 }
120         }
121
122         DE_ASSERT(false);
123         return VK_FORMAT_UNDEFINED;
124 }
125
126 tcu::TextureFormat IFDataType::getTextureFormat (void) const
127 {
128         tcu::TextureFormat::ChannelType         ct      = tcu::TextureFormat::CHANNELTYPE_LAST;
129         tcu::TextureFormat::ChannelOrder        co      = tcu::TextureFormat::CHANNELORDER_LAST;
130
131         switch (elementType)
132         {
133                 case NUMBERTYPE_FLOAT32:        ct = tcu::TextureFormat::FLOAT;                         break;
134                 case NUMBERTYPE_INT32:          ct = tcu::TextureFormat::SIGNED_INT32;          break;
135                 case NUMBERTYPE_UINT32:         ct = tcu::TextureFormat::UNSIGNED_INT32;        break;
136                 case NUMBERTYPE_FLOAT16:        ct = tcu::TextureFormat::HALF_FLOAT;            break;
137                 case NUMBERTYPE_INT16:          ct = tcu::TextureFormat::SIGNED_INT16;          break;
138                 case NUMBERTYPE_UINT16:         ct = tcu::TextureFormat::UNSIGNED_INT16;        break;
139                 default:                                        DE_ASSERT(false);
140         }
141
142         switch (numElements)
143         {
144                 case 1:                         co = tcu::TextureFormat::R;                                     break;
145                 case 2:                         co = tcu::TextureFormat::RG;                            break;
146                 case 3:                         co = tcu::TextureFormat::RGB;                           break;
147                 case 4:                         co = tcu::TextureFormat::RGBA;                          break;
148                 default:                        DE_ASSERT(false);
149         }
150
151         return tcu::TextureFormat(co, ct);
152 }
153
154 string IFDataType::str (void) const
155 {
156         string  ret;
157
158         switch (elementType)
159         {
160                 case NUMBERTYPE_FLOAT32:        ret = "f32"; break;
161                 case NUMBERTYPE_INT32:          ret = "i32"; break;
162                 case NUMBERTYPE_UINT32:         ret = "u32"; break;
163                 case NUMBERTYPE_FLOAT16:        ret = "f16"; break;
164                 case NUMBERTYPE_INT16:          ret = "i16"; break;
165                 case NUMBERTYPE_UINT16:         ret = "u16"; break;
166                 default:                                        DE_ASSERT(false);
167         }
168
169         if (numElements == 1)
170                 return ret;
171
172         return string("v") + numberToString(numElements) + ret;
173 }
174
175 VkBufferUsageFlagBits getMatchingBufferUsageFlagBit(VkDescriptorType dType)
176 {
177         switch (dType)
178         {
179                 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER: return VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT;
180                 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER: return VK_BUFFER_USAGE_STORAGE_BUFFER_BIT;
181                 default:                                                                DE_ASSERT(0 && "not implemented");
182         }
183         return (VkBufferUsageFlagBits)0;
184 }
185
186 static void requireFormatUsageSupport(const InstanceInterface& vki, VkPhysicalDevice physicalDevice, VkFormat format, VkImageTiling imageTiling, VkImageUsageFlags requiredUsageFlags)
187 {
188         VkFormatProperties              properties;
189         VkFormatFeatureFlags    tilingFeatures  = 0;
190
191         vki.getPhysicalDeviceFormatProperties(physicalDevice, format, &properties);
192
193         switch (imageTiling)
194         {
195                 case VK_IMAGE_TILING_LINEAR:
196                         tilingFeatures = properties.linearTilingFeatures;
197                         break;
198
199                 case VK_IMAGE_TILING_OPTIMAL:
200                         tilingFeatures = properties.optimalTilingFeatures;
201                         break;
202
203                 default:
204                         DE_ASSERT(false);
205                         break;
206         }
207
208         if ((requiredUsageFlags & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT) != 0)
209         {
210                 if ((tilingFeatures & VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT) == 0)
211                         TCU_THROW(NotSupportedError, "Image format cannot be used as color attachment");
212                 requiredUsageFlags ^= VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
213         }
214
215
216         if ((requiredUsageFlags & VK_IMAGE_USAGE_TRANSFER_SRC_BIT) != 0)
217         {
218                 if ((tilingFeatures & VK_FORMAT_FEATURE_TRANSFER_SRC_BIT_KHR) == 0)
219                         TCU_THROW(NotSupportedError, "Image format cannot be used as transfer source");
220                 requiredUsageFlags ^= VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
221         }
222
223
224         DE_ASSERT(!requiredUsageFlags && "checking other image usage bits not supported yet");
225 }
226
227 InstanceContext::InstanceContext (const RGBA                                            (&inputs)[4],
228                                                                   const RGBA                                            (&outputs)[4],
229                                                                   const map<string, string>&            testCodeFragments_,
230                                                                   const StageToSpecConstantMap&         specConstants_,
231                                                                   const PushConstants&                          pushConsants_,
232                                                                   const GraphicsResources&                      resources_,
233                                                                   const GraphicsInterfaces&                     interfaces_,
234                                                                   const vector<string>&                         extensions_,
235                                                                   const vector<string>&                         features_,
236                                                                   VulkanFeatures                                        vulkanFeatures_,
237                                                                   VkShaderStageFlags                            customizedStages_)
238         : testCodeFragments                             (testCodeFragments_)
239         , specConstants                                 (specConstants_)
240         , hasTessellation                               (false)
241         , requiredStages                                (static_cast<VkShaderStageFlagBits>(0))
242         , requiredDeviceExtensions              (extensions_)
243         , requiredDeviceFeatures                (features_)
244         , requestedFeatures                             (vulkanFeatures_)
245         , pushConstants                                 (pushConsants_)
246         , customizedStages                              (customizedStages_)
247         , resources                                             (resources_)
248         , interfaces                                    (interfaces_)
249         , failResult                                    (QP_TEST_RESULT_FAIL)
250         , failMessageTemplate                   ("${reason}")
251 {
252         inputColors[0]          = inputs[0];
253         inputColors[1]          = inputs[1];
254         inputColors[2]          = inputs[2];
255         inputColors[3]          = inputs[3];
256
257         outputColors[0]         = outputs[0];
258         outputColors[1]         = outputs[1];
259         outputColors[2]         = outputs[2];
260         outputColors[3]         = outputs[3];
261 }
262
263 InstanceContext::InstanceContext (const InstanceContext& other)
264         : moduleMap                                             (other.moduleMap)
265         , testCodeFragments                             (other.testCodeFragments)
266         , specConstants                                 (other.specConstants)
267         , hasTessellation                               (other.hasTessellation)
268         , requiredStages                                (other.requiredStages)
269         , requiredDeviceExtensions              (other.requiredDeviceExtensions)
270         , requiredDeviceFeatures                (other.requiredDeviceFeatures)
271         , requestedFeatures                             (other.requestedFeatures)
272         , pushConstants                                 (other.pushConstants)
273         , customizedStages                              (other.customizedStages)
274         , resources                                             (other.resources)
275         , interfaces                                    (other.interfaces)
276         , failResult                                    (other.failResult)
277         , failMessageTemplate                   (other.failMessageTemplate)
278 {
279         inputColors[0]          = other.inputColors[0];
280         inputColors[1]          = other.inputColors[1];
281         inputColors[2]          = other.inputColors[2];
282         inputColors[3]          = other.inputColors[3];
283
284         outputColors[0]         = other.outputColors[0];
285         outputColors[1]         = other.outputColors[1];
286         outputColors[2]         = other.outputColors[2];
287         outputColors[3]         = other.outputColors[3];
288 }
289
290 string InstanceContext::getSpecializedFailMessage (const string& failureReason)
291 {
292         map<string, string>             parameters;
293         parameters["reason"]    = failureReason;
294         return StringTemplate(failMessageTemplate).specialize(parameters);
295 }
296
297 ShaderElement::ShaderElement (const string&                             moduleName_,
298                                                           const string&                         entryPoint_,
299                                                           VkShaderStageFlagBits         shaderStage_)
300                 : moduleName(moduleName_)
301                 , entryName(entryPoint_)
302                 , stage(shaderStage_)
303 {
304 }
305
306 void getDefaultColors (RGBA (&colors)[4])
307 {
308         colors[0] = RGBA::white();
309         colors[1] = RGBA::red();
310         colors[2] = RGBA::green();
311         colors[3] = RGBA::blue();
312 }
313
314 void getHalfColorsFullAlpha (RGBA (&colors)[4])
315 {
316         colors[0] = RGBA(127, 127, 127, 255);
317         colors[1] = RGBA(127, 0,   0,   255);
318         colors[2] = RGBA(0,       127, 0,       255);
319         colors[3] = RGBA(0,       0,   127, 255);
320 }
321
322 void getInvertedDefaultColors (RGBA (&colors)[4])
323 {
324         colors[0] = RGBA(0,             0,              0,              255);
325         colors[1] = RGBA(0,             255,    255,    255);
326         colors[2] = RGBA(255,   0,              255,    255);
327         colors[3] = RGBA(255,   255,    0,              255);
328 }
329
330 // For the current InstanceContext, constructs the required modules and shader stage create infos.
331 void createPipelineShaderStages (const DeviceInterface&                                         vk,
332                                                                  const VkDevice                                                         vkDevice,
333                                                                  InstanceContext&                                                       instance,
334                                                                  Context&                                                                       context,
335                                                                  vector<ModuleHandleSp>&                                        modules,
336                                                                  vector<VkPipelineShaderStageCreateInfo>&       createInfos)
337 {
338         for (ModuleMap::const_iterator moduleNdx = instance.moduleMap.begin(); moduleNdx != instance.moduleMap.end(); ++moduleNdx)
339         {
340                 const ModuleHandleSp mod(new Unique<VkShaderModule>(createShaderModule(vk, vkDevice, context.getBinaryCollection().get(moduleNdx->first), 0)));
341                 modules.push_back(ModuleHandleSp(mod));
342                 for (vector<EntryToStage>::const_iterator shaderNdx = moduleNdx->second.begin(); shaderNdx != moduleNdx->second.end(); ++shaderNdx)
343                 {
344                         const EntryToStage&                                             stage                   = *shaderNdx;
345                         const VkPipelineShaderStageCreateInfo   shaderParam             =
346                         {
347                                 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,    //      VkStructureType                 sType;
348                                 DE_NULL,                                                                                                //      const void*                             pNext;
349                                 (VkPipelineShaderStageCreateFlags)0,
350                                 stage.second,                                                                                   //      VkShaderStageFlagBits   stage;
351                                 **modules.back(),                                                                               //      VkShaderModule                  module;
352                                 stage.first.c_str(),                                                                    //      const char*                             pName;
353                                 (const VkSpecializationInfo*)DE_NULL,
354                         };
355                         createInfos.push_back(shaderParam);
356                 }
357         }
358 }
359
360 #define SPIRV_ASSEMBLY_TYPES                                                                                                                                    \
361         "%void = OpTypeVoid\n"                                                                                                                                          \
362         "%bool = OpTypeBool\n"                                                                                                                                          \
363                                                                                                                                                                                                 \
364         "%i32 = OpTypeInt 32 1\n"                                                                                                                                       \
365         "%u32 = OpTypeInt 32 0\n"                                                                                                                                       \
366                                                                                                                                                                                                 \
367         "%f32 = OpTypeFloat 32\n"                                                                                                                                       \
368         "%v2i32 = OpTypeVector %i32 2\n"                                                                                                                        \
369         "%v2u32 = OpTypeVector %u32 2\n"                                                                                                                        \
370         "%v2f32 = OpTypeVector %f32 2\n"                                                                                                                        \
371         "%v3f32 = OpTypeVector %f32 3\n"                                                                                                                        \
372         "%v4i32 = OpTypeVector %i32 4\n"                                                                                                                        \
373         "%v4u32 = OpTypeVector %u32 4\n"                                                                                                                        \
374         "%v4f32 = OpTypeVector %f32 4\n"                                                                                                                        \
375         "%v4bool = OpTypeVector %bool 4\n"                                                                                                                      \
376                                                                                                                                                                                                 \
377         "%v4f32_function = OpTypeFunction %v4f32 %v4f32\n"                                                                                      \
378         "%bool_function = OpTypeFunction %bool\n"                                                                                                       \
379         "%fun = OpTypeFunction %void\n"                                                                                                                         \
380                                                                                                                                                                                                 \
381         "%ip_f32 = OpTypePointer Input %f32\n"                                                                                                          \
382         "%ip_i32 = OpTypePointer Input %i32\n"                                                                                                          \
383         "%ip_u32 = OpTypePointer Input %u32\n"                                                                                                          \
384         "%ip_v3f32 = OpTypePointer Input %v3f32\n"                                                                                                      \
385         "%ip_v2f32 = OpTypePointer Input %v2f32\n"                                                                                                      \
386         "%ip_v2i32 = OpTypePointer Input %v2i32\n"                                                                                                      \
387         "%ip_v2u32 = OpTypePointer Input %v2u32\n"                                                                                                      \
388         "%ip_v4f32 = OpTypePointer Input %v4f32\n"                                                                                                      \
389         "%ip_v4i32 = OpTypePointer Input %v4i32\n"                                                                                                      \
390         "%ip_v4u32 = OpTypePointer Input %v4u32\n"                                                                                                      \
391                                                                                                                                                                                                 \
392         "%op_f32 = OpTypePointer Output %f32\n"                                                                                                         \
393         "%op_i32 = OpTypePointer Output %i32\n"                                                                                                         \
394         "%op_u32 = OpTypePointer Output %u32\n"                                                                                                         \
395         "%op_v2f32 = OpTypePointer Output %v2f32\n"                                                                                                     \
396         "%op_v2i32 = OpTypePointer Output %v2i32\n"                                                                                                     \
397         "%op_v2u32 = OpTypePointer Output %v2u32\n"                                                                                                     \
398         "%op_v4f32 = OpTypePointer Output %v4f32\n"                                                                                                     \
399         "%op_v4i32 = OpTypePointer Output %v4i32\n"                                                                                                     \
400         "%op_v4u32 = OpTypePointer Output %v4u32\n"                                                                                                     \
401                                                                                                                                                                                                 \
402         "%fp_f32   = OpTypePointer Function %f32\n"                                                                                                     \
403         "%fp_i32   = OpTypePointer Function %i32\n"                                                                                                     \
404         "%fp_v4f32 = OpTypePointer Function %v4f32\n"
405
406 #define SPIRV_ASSEMBLY_CONSTANTS                                                                                                                                \
407         "%c_f32_1 = OpConstant %f32 1.0\n"                                                                                                                      \
408         "%c_f32_0 = OpConstant %f32 0.0\n"                                                                                                                      \
409         "%c_f32_0_5 = OpConstant %f32 0.5\n"                                                                                                            \
410         "%c_f32_n1  = OpConstant %f32 -1.\n"                                                                                                            \
411         "%c_f32_7 = OpConstant %f32 7.0\n"                                                                                                                      \
412         "%c_f32_8 = OpConstant %f32 8.0\n"                                                                                                                      \
413         "%c_i32_0 = OpConstant %i32 0\n"                                                                                                                        \
414         "%c_i32_1 = OpConstant %i32 1\n"                                                                                                                        \
415         "%c_i32_2 = OpConstant %i32 2\n"                                                                                                                        \
416         "%c_i32_3 = OpConstant %i32 3\n"                                                                                                                        \
417         "%c_i32_4 = OpConstant %i32 4\n"                                                                                                                        \
418         "%c_u32_0 = OpConstant %u32 0\n"                                                                                                                        \
419         "%c_u32_1 = OpConstant %u32 1\n"                                                                                                                        \
420         "%c_u32_2 = OpConstant %u32 2\n"                                                                                                                        \
421         "%c_u32_3 = OpConstant %u32 3\n"                                                                                                                        \
422         "%c_u32_32 = OpConstant %u32 32\n"                                                                                                                      \
423         "%c_u32_4 = OpConstant %u32 4\n"                                                                                                                        \
424         "%c_u32_31_bits = OpConstant %u32 0x7FFFFFFF\n"                                                                                         \
425         "%c_v4f32_1_1_1_1 = OpConstantComposite %v4f32 %c_f32_1 %c_f32_1 %c_f32_1 %c_f32_1\n"           \
426         "%c_v4f32_1_0_0_1 = OpConstantComposite %v4f32 %c_f32_1 %c_f32_0 %c_f32_0 %c_f32_1\n"           \
427         "%c_v4f32_0_5_0_5_0_5_0_5 = OpConstantComposite %v4f32 %c_f32_0_5 %c_f32_0_5 %c_f32_0_5 %c_f32_0_5\n"
428
429 #define SPIRV_ASSEMBLY_ARRAYS                                                                                                                                   \
430         "%a1f32 = OpTypeArray %f32 %c_u32_1\n"                                                                                                          \
431         "%a2f32 = OpTypeArray %f32 %c_u32_2\n"                                                                                                          \
432         "%a3v4f32 = OpTypeArray %v4f32 %c_u32_3\n"                                                                                                      \
433         "%a4f32 = OpTypeArray %f32 %c_u32_4\n"                                                                                                          \
434         "%a32v4f32 = OpTypeArray %v4f32 %c_u32_32\n"                                                                                            \
435         "%ip_a3v4f32 = OpTypePointer Input %a3v4f32\n"                                                                                          \
436         "%ip_a32v4f32 = OpTypePointer Input %a32v4f32\n"                                                                                        \
437         "%op_a2f32 = OpTypePointer Output %a2f32\n"                                                                                                     \
438         "%op_a3v4f32 = OpTypePointer Output %a3v4f32\n"                                                                                         \
439         "%op_a4f32 = OpTypePointer Output %a4f32\n"
440
441 // Creates vertex-shader assembly by specializing a boilerplate StringTemplate
442 // on fragments, which must (at least) map "testfun" to an OpFunction definition
443 // for %test_code that takes and returns a %v4f32.  Boilerplate IDs are prefixed
444 // with "BP_" to avoid collisions with fragments.
445 //
446 // It corresponds roughly to this GLSL:
447 //;
448 // layout(location = 0) in vec4 position;
449 // layout(location = 1) in vec4 color;
450 // layout(location = 1) out highp vec4 vtxColor;
451 // void main (void) { gl_Position = position; vtxColor = test_func(color); }
452 string makeVertexShaderAssembly(const map<string, string>& fragments)
453 {
454 // \todo [2015-11-23 awoloszyn] Remove OpName once these have stabalized
455         static const char vertexShaderBoilerplate[] =
456                 "OpCapability Shader\n"
457                 "OpCapability ClipDistance\n"
458                 "OpCapability CullDistance\n"
459                 "${capability:opt}\n"
460                 "${extension:opt}\n"
461                 "OpMemoryModel Logical GLSL450\n"
462                 "OpEntryPoint Vertex %main \"main\" %BP_stream %BP_position %BP_vtx_color %BP_color %BP_gl_VertexIndex %BP_gl_InstanceIndex ${IF_entrypoint:opt} \n"
463                 "${debug:opt}\n"
464                 "OpName %main \"main\"\n"
465                 "OpName %BP_gl_PerVertex \"gl_PerVertex\"\n"
466                 "OpMemberName %BP_gl_PerVertex 0 \"gl_Position\"\n"
467                 "OpMemberName %BP_gl_PerVertex 1 \"gl_PointSize\"\n"
468                 "OpMemberName %BP_gl_PerVertex 2 \"gl_ClipDistance\"\n"
469                 "OpMemberName %BP_gl_PerVertex 3 \"gl_CullDistance\"\n"
470                 "OpName %test_code \"testfun(vf4;\"\n"
471                 "OpName %BP_stream \"\"\n"
472                 "OpName %BP_position \"position\"\n"
473                 "OpName %BP_vtx_color \"vtxColor\"\n"
474                 "OpName %BP_color \"color\"\n"
475                 "OpName %BP_gl_VertexIndex \"gl_VertexIndex\"\n"
476                 "OpName %BP_gl_InstanceIndex \"gl_InstanceIndex\"\n"
477                 "${moduleprocessed:opt}\n"
478                 "OpMemberDecorate %BP_gl_PerVertex 0 BuiltIn Position\n"
479                 "OpMemberDecorate %BP_gl_PerVertex 1 BuiltIn PointSize\n"
480                 "OpMemberDecorate %BP_gl_PerVertex 2 BuiltIn ClipDistance\n"
481                 "OpMemberDecorate %BP_gl_PerVertex 3 BuiltIn CullDistance\n"
482                 "OpDecorate %BP_gl_PerVertex Block\n"
483                 "OpDecorate %BP_position Location 0\n"
484                 "OpDecorate %BP_vtx_color Location 1\n"
485                 "OpDecorate %BP_color Location 1\n"
486                 "OpDecorate %BP_gl_VertexIndex BuiltIn VertexIndex\n"
487                 "OpDecorate %BP_gl_InstanceIndex BuiltIn InstanceIndex\n"
488                 "${IF_decoration:opt}\n"
489                 "${decoration:opt}\n"
490                 SPIRV_ASSEMBLY_TYPES
491                 SPIRV_ASSEMBLY_CONSTANTS
492                 SPIRV_ASSEMBLY_ARRAYS
493                 "%BP_gl_PerVertex = OpTypeStruct %v4f32 %f32 %a1f32 %a1f32\n"
494                 "%BP_op_gl_PerVertex = OpTypePointer Output %BP_gl_PerVertex\n"
495                 "%BP_stream = OpVariable %BP_op_gl_PerVertex Output\n"
496                 "%BP_position = OpVariable %ip_v4f32 Input\n"
497                 "%BP_vtx_color = OpVariable %op_v4f32 Output\n"
498                 "%BP_color = OpVariable %ip_v4f32 Input\n"
499                 "%BP_gl_VertexIndex = OpVariable %ip_i32 Input\n"
500                 "%BP_gl_InstanceIndex = OpVariable %ip_i32 Input\n"
501                 "${pre_main:opt}\n"
502                 "${IF_variable:opt}\n"
503                 "%main = OpFunction %void None %fun\n"
504                 "%BP_label = OpLabel\n"
505                 "${IF_carryforward:opt}\n"
506                 "%BP_pos = OpLoad %v4f32 %BP_position\n"
507                 "%BP_gl_pos = OpAccessChain %op_v4f32 %BP_stream %c_i32_0\n"
508                 "OpStore %BP_gl_pos %BP_pos\n"
509                 "%BP_col = OpLoad %v4f32 %BP_color\n"
510                 "%BP_col_transformed = OpFunctionCall %v4f32 %test_code %BP_col\n"
511                 "OpStore %BP_vtx_color %BP_col_transformed\n"
512                 "OpReturn\n"
513                 "OpFunctionEnd\n"
514                 "${interface_op_func:opt}\n"
515
516                 "%isUniqueIdZero = OpFunction %bool None %bool_function\n"
517                 "%getId_label = OpLabel\n"
518                 "%vert_id = OpLoad %i32 %BP_gl_VertexIndex\n"
519                 "%is_id_0 = OpIEqual %bool %vert_id %c_i32_0\n"
520                 "OpReturnValue %is_id_0\n"
521                 "OpFunctionEnd\n"
522
523                 "${testfun}\n";
524         return tcu::StringTemplate(vertexShaderBoilerplate).specialize(fragments);
525 }
526
527 // Creates tess-control-shader assembly by specializing a boilerplate
528 // StringTemplate on fragments, which must (at least) map "testfun" to an
529 // OpFunction definition for %test_code that takes and returns a %v4f32.
530 // Boilerplate IDs are prefixed with "BP_" to avoid collisions with fragments.
531 //
532 // It roughly corresponds to the following GLSL.
533 //
534 // #version 450
535 // layout(vertices = 3) out;
536 // layout(location = 1) in vec4 in_color[];
537 // layout(location = 1) out vec4 out_color[];
538 //
539 // void main() {
540 //   out_color[gl_InvocationID] = testfun(in_color[gl_InvocationID]);
541 //   gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;
542 //   if (gl_InvocationID == 0) {
543 //     gl_TessLevelOuter[0] = 1.0;
544 //     gl_TessLevelOuter[1] = 1.0;
545 //     gl_TessLevelOuter[2] = 1.0;
546 //     gl_TessLevelInner[0] = 1.0;
547 //   }
548 // }
549 string makeTessControlShaderAssembly (const map<string, string>& fragments)
550 {
551         static const char tessControlShaderBoilerplate[] =
552                 "OpCapability Tessellation\n"
553                 "OpCapability ClipDistance\n"
554                 "OpCapability CullDistance\n"
555                 "${capability:opt}\n"
556                 "${extension:opt}\n"
557                 "OpMemoryModel Logical GLSL450\n"
558                 "OpEntryPoint TessellationControl %BP_main \"main\" %BP_out_color %BP_gl_InvocationID %BP_gl_PrimitiveID %BP_in_color %BP_gl_out %BP_gl_in %BP_gl_TessLevelOuter %BP_gl_TessLevelInner ${IF_entrypoint:opt} \n"
559                 "OpExecutionMode %BP_main OutputVertices 3\n"
560                 "${debug:opt}\n"
561                 "OpName %BP_main \"main\"\n"
562                 "OpName %test_code \"testfun(vf4;\"\n"
563                 "OpName %BP_out_color \"out_color\"\n"
564                 "OpName %BP_gl_InvocationID \"gl_InvocationID\"\n"
565                 "OpName %BP_gl_PrimitiveID \"gl_PrimitiveID\"\n"
566                 "OpName %BP_in_color \"in_color\"\n"
567                 "OpName %BP_gl_PerVertex \"gl_PerVertex\"\n"
568                 "OpMemberName %BP_gl_PerVertex 0 \"gl_Position\"\n"
569                 "OpMemberName %BP_gl_PerVertex 1 \"gl_PointSize\"\n"
570                 "OpMemberName %BP_gl_PerVertex 2 \"gl_ClipDistance\"\n"
571                 "OpMemberName %BP_gl_PerVertex 3 \"gl_CullDistance\"\n"
572                 "OpName %BP_gl_out \"gl_out\"\n"
573                 "OpName %BP_gl_PVOut \"gl_PerVertex\"\n"
574                 "OpMemberName %BP_gl_PVOut 0 \"gl_Position\"\n"
575                 "OpMemberName %BP_gl_PVOut 1 \"gl_PointSize\"\n"
576                 "OpMemberName %BP_gl_PVOut 2 \"gl_ClipDistance\"\n"
577                 "OpMemberName %BP_gl_PVOut 3 \"gl_CullDistance\"\n"
578                 "OpName %BP_gl_in \"gl_in\"\n"
579                 "OpName %BP_gl_TessLevelOuter \"gl_TessLevelOuter\"\n"
580                 "OpName %BP_gl_TessLevelInner \"gl_TessLevelInner\"\n"
581                 "${moduleprocessed:opt}\n"
582                 "OpDecorate %BP_out_color Location 1\n"
583                 "OpDecorate %BP_gl_InvocationID BuiltIn InvocationId\n"
584                 "OpDecorate %BP_gl_PrimitiveID BuiltIn PrimitiveId\n"
585                 "OpDecorate %BP_in_color Location 1\n"
586                 "OpMemberDecorate %BP_gl_PerVertex 0 BuiltIn Position\n"
587                 "OpMemberDecorate %BP_gl_PerVertex 1 BuiltIn PointSize\n"
588                 "OpMemberDecorate %BP_gl_PerVertex 2 BuiltIn ClipDistance\n"
589                 "OpMemberDecorate %BP_gl_PerVertex 3 BuiltIn CullDistance\n"
590                 "OpDecorate %BP_gl_PerVertex Block\n"
591                 "OpMemberDecorate %BP_gl_PVOut 0 BuiltIn Position\n"
592                 "OpMemberDecorate %BP_gl_PVOut 1 BuiltIn PointSize\n"
593                 "OpMemberDecorate %BP_gl_PVOut 2 BuiltIn ClipDistance\n"
594                 "OpMemberDecorate %BP_gl_PVOut 3 BuiltIn CullDistance\n"
595                 "OpDecorate %BP_gl_PVOut Block\n"
596                 "OpDecorate %BP_gl_TessLevelOuter Patch\n"
597                 "OpDecorate %BP_gl_TessLevelOuter BuiltIn TessLevelOuter\n"
598                 "OpDecorate %BP_gl_TessLevelInner Patch\n"
599                 "OpDecorate %BP_gl_TessLevelInner BuiltIn TessLevelInner\n"
600                 "${IF_decoration:opt}\n"
601                 "${decoration:opt}\n"
602                 SPIRV_ASSEMBLY_TYPES
603                 SPIRV_ASSEMBLY_CONSTANTS
604                 SPIRV_ASSEMBLY_ARRAYS
605                 "%BP_out_color = OpVariable %op_a3v4f32 Output\n"
606                 "%BP_gl_InvocationID = OpVariable %ip_i32 Input\n"
607                 "%BP_gl_PrimitiveID = OpVariable %ip_i32 Input\n"
608                 "%BP_in_color = OpVariable %ip_a32v4f32 Input\n"
609                 "%BP_gl_PerVertex = OpTypeStruct %v4f32 %f32 %a1f32 %a1f32\n"
610                 "%BP_a3_gl_PerVertex = OpTypeArray %BP_gl_PerVertex %c_u32_3\n"
611                 "%BP_op_a3_gl_PerVertex = OpTypePointer Output %BP_a3_gl_PerVertex\n"
612                 "%BP_gl_out = OpVariable %BP_op_a3_gl_PerVertex Output\n"
613                 "%BP_gl_PVOut = OpTypeStruct %v4f32 %f32 %a1f32 %a1f32\n"
614                 "%BP_a32_gl_PVOut = OpTypeArray %BP_gl_PVOut %c_u32_32\n"
615                 "%BP_ip_a32_gl_PVOut = OpTypePointer Input %BP_a32_gl_PVOut\n"
616                 "%BP_gl_in = OpVariable %BP_ip_a32_gl_PVOut Input\n"
617                 "%BP_gl_TessLevelOuter = OpVariable %op_a4f32 Output\n"
618                 "%BP_gl_TessLevelInner = OpVariable %op_a2f32 Output\n"
619                 "${pre_main:opt}\n"
620                 "${IF_variable:opt}\n"
621
622                 "%BP_main = OpFunction %void None %fun\n"
623                 "%BP_label = OpLabel\n"
624                 "%BP_gl_Invoc = OpLoad %i32 %BP_gl_InvocationID\n"
625                 "${IF_carryforward:opt}\n"
626                 "%BP_in_col_loc = OpAccessChain %ip_v4f32 %BP_in_color %BP_gl_Invoc\n"
627                 "%BP_out_col_loc = OpAccessChain %op_v4f32 %BP_out_color %BP_gl_Invoc\n"
628                 "%BP_in_col_val = OpLoad %v4f32 %BP_in_col_loc\n"
629                 "%BP_clr_transformed = OpFunctionCall %v4f32 %test_code %BP_in_col_val\n"
630                 "OpStore %BP_out_col_loc %BP_clr_transformed\n"
631
632                 "%BP_in_pos_loc = OpAccessChain %ip_v4f32 %BP_gl_in %BP_gl_Invoc %c_i32_0\n"
633                 "%BP_out_pos_loc = OpAccessChain %op_v4f32 %BP_gl_out %BP_gl_Invoc %c_i32_0\n"
634                 "%BP_in_pos_val = OpLoad %v4f32 %BP_in_pos_loc\n"
635                 "OpStore %BP_out_pos_loc %BP_in_pos_val\n"
636
637                 "%BP_cmp = OpIEqual %bool %BP_gl_Invoc %c_i32_0\n"
638                 "OpSelectionMerge %BP_merge_label None\n"
639                 "OpBranchConditional %BP_cmp %BP_if_label %BP_merge_label\n"
640                 "%BP_if_label = OpLabel\n"
641                 "%BP_gl_TessLevelOuterPos_0 = OpAccessChain %op_f32 %BP_gl_TessLevelOuter %c_i32_0\n"
642                 "%BP_gl_TessLevelOuterPos_1 = OpAccessChain %op_f32 %BP_gl_TessLevelOuter %c_i32_1\n"
643                 "%BP_gl_TessLevelOuterPos_2 = OpAccessChain %op_f32 %BP_gl_TessLevelOuter %c_i32_2\n"
644                 "%BP_gl_TessLevelInnerPos_0 = OpAccessChain %op_f32 %BP_gl_TessLevelInner %c_i32_0\n"
645                 "OpStore %BP_gl_TessLevelOuterPos_0 %c_f32_1\n"
646                 "OpStore %BP_gl_TessLevelOuterPos_1 %c_f32_1\n"
647                 "OpStore %BP_gl_TessLevelOuterPos_2 %c_f32_1\n"
648                 "OpStore %BP_gl_TessLevelInnerPos_0 %c_f32_1\n"
649                 "OpBranch %BP_merge_label\n"
650                 "%BP_merge_label = OpLabel\n"
651                 "OpReturn\n"
652                 "OpFunctionEnd\n"
653                 "${interface_op_func:opt}\n"
654
655                 "%isUniqueIdZero = OpFunction %bool None %bool_function\n"
656                 "%getId_label = OpLabel\n"
657                 "%invocation_id = OpLoad %i32 %BP_gl_InvocationID\n"
658                 "%primitive_id = OpLoad %i32 %BP_gl_PrimitiveID\n"
659                 "%is_invocation_0 = OpIEqual %bool %invocation_id %c_i32_0\n"
660                 "%is_primitive_0 = OpIEqual %bool %primitive_id %c_i32_0\n"
661                 "%is_id_0 = OpLogicalAnd %bool %is_invocation_0 %is_primitive_0\n"
662                 "OpReturnValue %is_id_0\n"
663                 "OpFunctionEnd\n"
664
665                 "${testfun}\n";
666         return tcu::StringTemplate(tessControlShaderBoilerplate).specialize(fragments);
667 }
668
669 // Creates tess-evaluation-shader assembly by specializing a boilerplate
670 // StringTemplate on fragments, which must (at least) map "testfun" to an
671 // OpFunction definition for %test_code that takes and returns a %v4f32.
672 // Boilerplate IDs are prefixed with "BP_" to avoid collisions with fragments.
673 //
674 // It roughly corresponds to the following glsl.
675 //
676 // #version 450
677 //
678 // layout(triangles, equal_spacing, ccw) in;
679 // layout(location = 1) in vec4 in_color[];
680 // layout(location = 1) out vec4 out_color;
681 //
682 // #define interpolate(val)
683 //   vec4(gl_TessCoord.x) * val[0] + vec4(gl_TessCoord.y) * val[1] +
684 //          vec4(gl_TessCoord.z) * val[2]
685 //
686 // void main() {
687 //   gl_Position = vec4(gl_TessCoord.x) * gl_in[0].gl_Position +
688 //                  vec4(gl_TessCoord.y) * gl_in[1].gl_Position +
689 //                  vec4(gl_TessCoord.z) * gl_in[2].gl_Position;
690 //   out_color = testfun(interpolate(in_color));
691 // }
692 string makeTessEvalShaderAssembly(const map<string, string>& fragments)
693 {
694         static const char tessEvalBoilerplate[] =
695                 "OpCapability Tessellation\n"
696                 "OpCapability ClipDistance\n"
697                 "OpCapability CullDistance\n"
698                 "${capability:opt}\n"
699                 "${extension:opt}\n"
700                 "OpMemoryModel Logical GLSL450\n"
701                 "OpEntryPoint TessellationEvaluation %BP_main \"main\" %BP_stream %BP_gl_TessCoord %BP_gl_PrimitiveID %BP_gl_in %BP_out_color %BP_in_color ${IF_entrypoint:opt} \n"
702                 "OpExecutionMode %BP_main Triangles\n"
703                 "OpExecutionMode %BP_main SpacingEqual\n"
704                 "OpExecutionMode %BP_main VertexOrderCcw\n"
705                 "${debug:opt}\n"
706                 "OpName %BP_main \"main\"\n"
707                 "OpName %test_code \"testfun(vf4;\"\n"
708                 "OpName %BP_gl_PerVertexOut \"gl_PerVertex\"\n"
709                 "OpMemberName %BP_gl_PerVertexOut 0 \"gl_Position\"\n"
710                 "OpMemberName %BP_gl_PerVertexOut 1 \"gl_PointSize\"\n"
711                 "OpMemberName %BP_gl_PerVertexOut 2 \"gl_ClipDistance\"\n"
712                 "OpMemberName %BP_gl_PerVertexOut 3 \"gl_CullDistance\"\n"
713                 "OpName %BP_stream \"\"\n"
714                 "OpName %BP_gl_TessCoord \"gl_TessCoord\"\n"
715                 "OpName %BP_gl_PerVertexIn \"gl_PerVertex\"\n"
716                 "OpName %BP_gl_PrimitiveID \"gl_PrimitiveID\"\n"
717                 "OpMemberName %BP_gl_PerVertexIn 0 \"gl_Position\"\n"
718                 "OpMemberName %BP_gl_PerVertexIn 1 \"gl_PointSize\"\n"
719                 "OpMemberName %BP_gl_PerVertexIn 2 \"gl_ClipDistance\"\n"
720                 "OpMemberName %BP_gl_PerVertexIn 3 \"gl_CullDistance\"\n"
721                 "OpName %BP_gl_in \"gl_in\"\n"
722                 "OpName %BP_out_color \"out_color\"\n"
723                 "OpName %BP_in_color \"in_color\"\n"
724                 "${moduleprocessed:opt}\n"
725                 "OpMemberDecorate %BP_gl_PerVertexOut 0 BuiltIn Position\n"
726                 "OpMemberDecorate %BP_gl_PerVertexOut 1 BuiltIn PointSize\n"
727                 "OpMemberDecorate %BP_gl_PerVertexOut 2 BuiltIn ClipDistance\n"
728                 "OpMemberDecorate %BP_gl_PerVertexOut 3 BuiltIn CullDistance\n"
729                 "OpDecorate %BP_gl_PerVertexOut Block\n"
730                 "OpDecorate %BP_gl_PrimitiveID BuiltIn PrimitiveId\n"
731                 "OpDecorate %BP_gl_TessCoord BuiltIn TessCoord\n"
732                 "OpMemberDecorate %BP_gl_PerVertexIn 0 BuiltIn Position\n"
733                 "OpMemberDecorate %BP_gl_PerVertexIn 1 BuiltIn PointSize\n"
734                 "OpMemberDecorate %BP_gl_PerVertexIn 2 BuiltIn ClipDistance\n"
735                 "OpMemberDecorate %BP_gl_PerVertexIn 3 BuiltIn CullDistance\n"
736                 "OpDecorate %BP_gl_PerVertexIn Block\n"
737                 "OpDecorate %BP_out_color Location 1\n"
738                 "OpDecorate %BP_in_color Location 1\n"
739                 "${IF_decoration:opt}\n"
740                 "${decoration:opt}\n"
741                 SPIRV_ASSEMBLY_TYPES
742                 SPIRV_ASSEMBLY_CONSTANTS
743                 SPIRV_ASSEMBLY_ARRAYS
744                 "%BP_gl_PerVertexOut = OpTypeStruct %v4f32 %f32 %a1f32 %a1f32\n"
745                 "%BP_op_gl_PerVertexOut = OpTypePointer Output %BP_gl_PerVertexOut\n"
746                 "%BP_stream = OpVariable %BP_op_gl_PerVertexOut Output\n"
747                 "%BP_gl_TessCoord = OpVariable %ip_v3f32 Input\n"
748                 "%BP_gl_PrimitiveID = OpVariable %op_i32 Input\n"
749                 "%BP_gl_PerVertexIn = OpTypeStruct %v4f32 %f32 %a1f32 %a1f32\n"
750                 "%BP_a32_gl_PerVertexIn = OpTypeArray %BP_gl_PerVertexIn %c_u32_32\n"
751                 "%BP_ip_a32_gl_PerVertexIn = OpTypePointer Input %BP_a32_gl_PerVertexIn\n"
752                 "%BP_gl_in = OpVariable %BP_ip_a32_gl_PerVertexIn Input\n"
753                 "%BP_out_color = OpVariable %op_v4f32 Output\n"
754                 "%BP_in_color = OpVariable %ip_a32v4f32 Input\n"
755                 "${pre_main:opt}\n"
756                 "${IF_variable:opt}\n"
757                 "%BP_main = OpFunction %void None %fun\n"
758                 "%BP_label = OpLabel\n"
759                 "${IF_carryforward:opt}\n"
760                 "%BP_gl_TC_0 = OpAccessChain %ip_f32 %BP_gl_TessCoord %c_u32_0\n"
761                 "%BP_gl_TC_1 = OpAccessChain %ip_f32 %BP_gl_TessCoord %c_u32_1\n"
762                 "%BP_gl_TC_2 = OpAccessChain %ip_f32 %BP_gl_TessCoord %c_u32_2\n"
763                 "%BP_gl_in_gl_Pos_0 = OpAccessChain %ip_v4f32 %BP_gl_in %c_i32_0 %c_i32_0\n"
764                 "%BP_gl_in_gl_Pos_1 = OpAccessChain %ip_v4f32 %BP_gl_in %c_i32_1 %c_i32_0\n"
765                 "%BP_gl_in_gl_Pos_2 = OpAccessChain %ip_v4f32 %BP_gl_in %c_i32_2 %c_i32_0\n"
766
767                 "%BP_gl_OPos = OpAccessChain %op_v4f32 %BP_stream %c_i32_0\n"
768                 "%BP_in_color_0 = OpAccessChain %ip_v4f32 %BP_in_color %c_i32_0\n"
769                 "%BP_in_color_1 = OpAccessChain %ip_v4f32 %BP_in_color %c_i32_1\n"
770                 "%BP_in_color_2 = OpAccessChain %ip_v4f32 %BP_in_color %c_i32_2\n"
771
772                 "%BP_TC_W_0 = OpLoad %f32 %BP_gl_TC_0\n"
773                 "%BP_TC_W_1 = OpLoad %f32 %BP_gl_TC_1\n"
774                 "%BP_TC_W_2 = OpLoad %f32 %BP_gl_TC_2\n"
775                 "%BP_v4f32_TC_0 = OpCompositeConstruct %v4f32 %BP_TC_W_0 %BP_TC_W_0 %BP_TC_W_0 %BP_TC_W_0\n"
776                 "%BP_v4f32_TC_1 = OpCompositeConstruct %v4f32 %BP_TC_W_1 %BP_TC_W_1 %BP_TC_W_1 %BP_TC_W_1\n"
777                 "%BP_v4f32_TC_2 = OpCompositeConstruct %v4f32 %BP_TC_W_2 %BP_TC_W_2 %BP_TC_W_2 %BP_TC_W_2\n"
778
779                 "%BP_gl_IP_0 = OpLoad %v4f32 %BP_gl_in_gl_Pos_0\n"
780                 "%BP_gl_IP_1 = OpLoad %v4f32 %BP_gl_in_gl_Pos_1\n"
781                 "%BP_gl_IP_2 = OpLoad %v4f32 %BP_gl_in_gl_Pos_2\n"
782
783                 "%BP_IP_W_0 = OpFMul %v4f32 %BP_v4f32_TC_0 %BP_gl_IP_0\n"
784                 "%BP_IP_W_1 = OpFMul %v4f32 %BP_v4f32_TC_1 %BP_gl_IP_1\n"
785                 "%BP_IP_W_2 = OpFMul %v4f32 %BP_v4f32_TC_2 %BP_gl_IP_2\n"
786
787                 "%BP_pos_sum_0 = OpFAdd %v4f32 %BP_IP_W_0 %BP_IP_W_1\n"
788                 "%BP_pos_sum_1 = OpFAdd %v4f32 %BP_pos_sum_0 %BP_IP_W_2\n"
789
790                 "OpStore %BP_gl_OPos %BP_pos_sum_1\n"
791
792                 "%BP_IC_0 = OpLoad %v4f32 %BP_in_color_0\n"
793                 "%BP_IC_1 = OpLoad %v4f32 %BP_in_color_1\n"
794                 "%BP_IC_2 = OpLoad %v4f32 %BP_in_color_2\n"
795
796                 "%BP_IC_W_0 = OpFMul %v4f32 %BP_v4f32_TC_0 %BP_IC_0\n"
797                 "%BP_IC_W_1 = OpFMul %v4f32 %BP_v4f32_TC_1 %BP_IC_1\n"
798                 "%BP_IC_W_2 = OpFMul %v4f32 %BP_v4f32_TC_2 %BP_IC_2\n"
799
800                 "%BP_col_sum_0 = OpFAdd %v4f32 %BP_IC_W_0 %BP_IC_W_1\n"
801                 "%BP_col_sum_1 = OpFAdd %v4f32 %BP_col_sum_0 %BP_IC_W_2\n"
802
803                 "%BP_clr_transformed = OpFunctionCall %v4f32 %test_code %BP_col_sum_1\n"
804
805                 "OpStore %BP_out_color %BP_clr_transformed\n"
806                 "OpReturn\n"
807                 "OpFunctionEnd\n"
808                 "${interface_op_func:opt}\n"
809
810                 "%isUniqueIdZero = OpFunction %bool None %bool_function\n"
811                 "%getId_label = OpLabel\n"
812                 "%primitive_id = OpLoad %i32 %BP_gl_PrimitiveID\n"
813                 "%is_primitive_0 = OpIEqual %bool %primitive_id %c_i32_0\n"
814                 "%TC_0_loc = OpAccessChain %ip_f32 %BP_gl_TessCoord %c_u32_0\n"
815                 "%TC_1_loc = OpAccessChain %ip_f32 %BP_gl_TessCoord %c_u32_1\n"
816                 "%TC_2_loc = OpAccessChain %ip_f32 %BP_gl_TessCoord %c_u32_2\n"
817                 "%TC_W_0 = OpLoad %f32 %TC_0_loc\n"
818                 "%TC_W_1 = OpLoad %f32 %TC_1_loc\n"
819                 "%TC_W_2 = OpLoad %f32 %TC_2_loc\n"
820                 "%is_W_0_1 = OpFOrdEqual %bool %TC_W_0 %c_f32_1\n"
821                 "%is_W_1_0 = OpFOrdEqual %bool %TC_W_1 %c_f32_0\n"
822                 "%is_W_2_0 = OpFOrdEqual %bool %TC_W_2 %c_f32_0\n"
823                 "%is_tessCoord_1_0 = OpLogicalAnd %bool %is_W_0_1 %is_W_1_0\n"
824                 "%is_tessCoord_1_0_0 = OpLogicalAnd %bool %is_tessCoord_1_0 %is_W_2_0\n"
825                 "%is_unique_id_0 = OpLogicalAnd %bool %is_tessCoord_1_0_0 %is_primitive_0\n"
826                 "OpReturnValue %is_unique_id_0\n"
827                 "OpFunctionEnd\n"
828
829                 "${testfun}\n";
830         return tcu::StringTemplate(tessEvalBoilerplate).specialize(fragments);
831 }
832
833 // Creates geometry-shader assembly by specializing a boilerplate StringTemplate
834 // on fragments, which must (at least) map "testfun" to an OpFunction definition
835 // for %test_code that takes and returns a %v4f32.  Boilerplate IDs are prefixed
836 // with "BP_" to avoid collisions with fragments.
837 //
838 // Derived from this GLSL:
839 //
840 // #version 450
841 // layout(triangles) in;
842 // layout(triangle_strip, max_vertices = 3) out;
843 //
844 // layout(location = 1) in vec4 in_color[];
845 // layout(location = 1) out vec4 out_color;
846 //
847 // void main() {
848 //   gl_Position = gl_in[0].gl_Position;
849 //   out_color = test_fun(in_color[0]);
850 //   EmitVertex();
851 //   gl_Position = gl_in[1].gl_Position;
852 //   out_color = test_fun(in_color[1]);
853 //   EmitVertex();
854 //   gl_Position = gl_in[2].gl_Position;
855 //   out_color = test_fun(in_color[2]);
856 //   EmitVertex();
857 //   EndPrimitive();
858 // }
859 string makeGeometryShaderAssembly(const map<string, string>& fragments)
860 {
861         static const char geometryShaderBoilerplate[] =
862                 "OpCapability Geometry\n"
863                 "OpCapability ClipDistance\n"
864                 "OpCapability CullDistance\n"
865                 "${capability:opt}\n"
866                 "${extension:opt}\n"
867                 "OpMemoryModel Logical GLSL450\n"
868                 "OpEntryPoint Geometry %BP_main \"main\" %BP_out_gl_position %BP_gl_PrimitiveID %BP_gl_in %BP_out_color %BP_in_color ${IF_entrypoint:opt} \n"
869                 "OpExecutionMode %BP_main Triangles\n"
870                 "OpExecutionMode %BP_main OutputTriangleStrip\n"
871                 "OpExecutionMode %BP_main OutputVertices 3\n"
872                 "${debug:opt}\n"
873                 "OpName %BP_main \"main\"\n"
874                 "OpName %BP_gl_PrimitiveID \"gl_PrimitiveID\"\n"
875                 "OpName %BP_per_vertex_in \"gl_PerVertex\"\n"
876                 "OpMemberName %BP_per_vertex_in 0 \"gl_Position\"\n"
877                 "OpMemberName %BP_per_vertex_in 1 \"gl_PointSize\"\n"
878                 "OpMemberName %BP_per_vertex_in 2 \"gl_ClipDistance\"\n"
879                 "OpMemberName %BP_per_vertex_in 3 \"gl_CullDistance\"\n"
880                 "OpName %BP_gl_in \"gl_in\"\n"
881                 "OpName %BP_out_color \"out_color\"\n"
882                 "OpName %BP_in_color \"in_color\"\n"
883                 "OpName %test_code \"testfun(vf4;\"\n"
884                 "${moduleprocessed:opt}\n"
885                 "OpDecorate %BP_gl_PrimitiveID BuiltIn PrimitiveId\n"
886                 "OpDecorate %BP_out_gl_position BuiltIn Position\n"
887                 "OpMemberDecorate %BP_per_vertex_in 0 BuiltIn Position\n"
888                 "OpMemberDecorate %BP_per_vertex_in 1 BuiltIn PointSize\n"
889                 "OpMemberDecorate %BP_per_vertex_in 2 BuiltIn ClipDistance\n"
890                 "OpMemberDecorate %BP_per_vertex_in 3 BuiltIn CullDistance\n"
891                 "OpDecorate %BP_per_vertex_in Block\n"
892                 "OpDecorate %BP_out_color Location 1\n"
893                 "OpDecorate %BP_in_color Location 1\n"
894                 "${IF_decoration:opt}\n"
895                 "${decoration:opt}\n"
896                 SPIRV_ASSEMBLY_TYPES
897                 SPIRV_ASSEMBLY_CONSTANTS
898                 SPIRV_ASSEMBLY_ARRAYS
899                 "%BP_per_vertex_in = OpTypeStruct %v4f32 %f32 %a1f32 %a1f32\n"
900                 "%BP_a3_per_vertex_in = OpTypeArray %BP_per_vertex_in %c_u32_3\n"
901                 "%BP_ip_a3_per_vertex_in = OpTypePointer Input %BP_a3_per_vertex_in\n"
902                 "%BP_pp_i32 = OpTypePointer Private %i32\n"
903                 "%BP_pp_v4i32 = OpTypePointer Private %v4i32\n"
904
905                 "%BP_gl_in = OpVariable %BP_ip_a3_per_vertex_in Input\n"
906                 "%BP_out_color = OpVariable %op_v4f32 Output\n"
907                 "%BP_in_color = OpVariable %ip_a3v4f32 Input\n"
908                 "%BP_gl_PrimitiveID = OpVariable %ip_i32 Input\n"
909                 "%BP_out_gl_position = OpVariable %op_v4f32 Output\n"
910                 "%BP_vertexIdInCurrentPatch = OpVariable %BP_pp_v4i32 Private\n"
911                 "${pre_main:opt}\n"
912                 "${IF_variable:opt}\n"
913
914                 "%BP_main = OpFunction %void None %fun\n"
915                 "%BP_label = OpLabel\n"
916
917                 "${IF_carryforward:opt}\n"
918
919                 "%BP_primitiveId = OpLoad %i32 %BP_gl_PrimitiveID\n"
920                 "%BP_addr_vertexIdInCurrentPatch = OpAccessChain %BP_pp_i32 %BP_vertexIdInCurrentPatch %BP_primitiveId\n"
921
922                 "%BP_gl_in_0_gl_position = OpAccessChain %ip_v4f32 %BP_gl_in %c_i32_0 %c_i32_0\n"
923                 "%BP_gl_in_1_gl_position = OpAccessChain %ip_v4f32 %BP_gl_in %c_i32_1 %c_i32_0\n"
924                 "%BP_gl_in_2_gl_position = OpAccessChain %ip_v4f32 %BP_gl_in %c_i32_2 %c_i32_0\n"
925
926                 "%BP_in_position_0 = OpLoad %v4f32 %BP_gl_in_0_gl_position\n"
927                 "%BP_in_position_1 = OpLoad %v4f32 %BP_gl_in_1_gl_position\n"
928                 "%BP_in_position_2 = OpLoad %v4f32 %BP_gl_in_2_gl_position \n"
929
930                 "%BP_in_color_0_ptr = OpAccessChain %ip_v4f32 %BP_in_color %c_i32_0\n"
931                 "%BP_in_color_1_ptr = OpAccessChain %ip_v4f32 %BP_in_color %c_i32_1\n"
932                 "%BP_in_color_2_ptr = OpAccessChain %ip_v4f32 %BP_in_color %c_i32_2\n"
933
934                 "%BP_in_color_0 = OpLoad %v4f32 %BP_in_color_0_ptr\n"
935                 "%BP_in_color_1 = OpLoad %v4f32 %BP_in_color_1_ptr\n"
936                 "%BP_in_color_2 = OpLoad %v4f32 %BP_in_color_2_ptr\n"
937
938                 "OpStore %BP_addr_vertexIdInCurrentPatch %c_i32_0\n"
939                 "%BP_transformed_in_color_0 = OpFunctionCall %v4f32 %test_code %BP_in_color_0\n"
940                 "OpStore %BP_addr_vertexIdInCurrentPatch %c_i32_1\n"
941                 "%BP_transformed_in_color_1 = OpFunctionCall %v4f32 %test_code %BP_in_color_1\n"
942                 "OpStore %BP_addr_vertexIdInCurrentPatch %c_i32_2\n"
943                 "%BP_transformed_in_color_2 = OpFunctionCall %v4f32 %test_code %BP_in_color_2\n"
944
945
946                 "OpStore %BP_out_gl_position %BP_in_position_0\n"
947                 "OpStore %BP_out_color %BP_transformed_in_color_0\n"
948                 "OpEmitVertex\n"
949
950                 "OpStore %BP_out_gl_position %BP_in_position_1\n"
951                 "OpStore %BP_out_color %BP_transformed_in_color_1\n"
952                 "OpEmitVertex\n"
953
954                 "OpStore %BP_out_gl_position %BP_in_position_2\n"
955                 "OpStore %BP_out_color %BP_transformed_in_color_2\n"
956                 "OpEmitVertex\n"
957
958                 "OpEndPrimitive\n"
959                 "OpReturn\n"
960                 "OpFunctionEnd\n"
961                 "${interface_op_func:opt}\n"
962
963                 "%isUniqueIdZero = OpFunction %bool None %bool_function\n"
964                 "%getId_label = OpLabel\n"
965                 "%primitive_id = OpLoad %i32 %BP_gl_PrimitiveID\n"
966                 "%addr_vertexIdInCurrentPatch = OpAccessChain %BP_pp_i32 %BP_vertexIdInCurrentPatch %primitive_id\n"
967                 "%vertexIdInCurrentPatch = OpLoad %i32 %addr_vertexIdInCurrentPatch\n"
968                 "%is_primitive_0 = OpIEqual %bool %primitive_id %c_i32_0\n"
969                 "%is_vertex_0 = OpIEqual %bool %vertexIdInCurrentPatch %c_i32_0\n"
970                 "%is_unique_id_0 = OpLogicalAnd %bool %is_primitive_0 %is_vertex_0\n"
971                 "OpReturnValue %is_unique_id_0\n"
972                 "OpFunctionEnd\n"
973
974                 "${testfun}\n";
975         return tcu::StringTemplate(geometryShaderBoilerplate).specialize(fragments);
976 }
977
978 // Creates fragment-shader assembly by specializing a boilerplate StringTemplate
979 // on fragments, which must (at least) map "testfun" to an OpFunction definition
980 // for %test_code that takes and returns a %v4f32.  Boilerplate IDs are prefixed
981 // with "BP_" to avoid collisions with fragments.
982 //
983 // Derived from this GLSL:
984 //
985 // layout(location = 1) in highp vec4 vtxColor;
986 // layout(location = 0) out highp vec4 fragColor;
987 // highp vec4 testfun(highp vec4 x) { return x; }
988 // void main(void) { fragColor = testfun(vtxColor); }
989 //
990 // with modifications including passing vtxColor by value and ripping out
991 // testfun() definition.
992 string makeFragmentShaderAssembly(const map<string, string>& fragments)
993 {
994         static const char fragmentShaderBoilerplate[] =
995                 "OpCapability Shader\n"
996                 "${capability:opt}\n"
997                 "${extension:opt}\n"
998                 "OpMemoryModel Logical GLSL450\n"
999                 "OpEntryPoint Fragment %BP_main \"main\" %BP_vtxColor %BP_fragColor %BP_gl_FragCoord ${IF_entrypoint:opt} \n"
1000                 "OpExecutionMode %BP_main OriginUpperLeft\n"
1001                 "${debug:opt}\n"
1002                 "OpName %BP_main \"main\"\n"
1003                 "OpName %BP_gl_FragCoord \"fragCoord\"\n"
1004                 "OpName %BP_fragColor \"fragColor\"\n"
1005                 "OpName %BP_vtxColor \"vtxColor\"\n"
1006                 "OpName %test_code \"testfun(vf4;\"\n"
1007                 "${moduleprocessed:opt}\n"
1008                 "OpDecorate %BP_fragColor Location 0\n"
1009                 "OpDecorate %BP_vtxColor Location 1\n"
1010                 "OpDecorate %BP_gl_FragCoord BuiltIn FragCoord\n"
1011                 "${IF_decoration:opt}\n"
1012                 "${decoration:opt}\n"
1013                 SPIRV_ASSEMBLY_TYPES
1014                 SPIRV_ASSEMBLY_CONSTANTS
1015                 SPIRV_ASSEMBLY_ARRAYS
1016                 "%BP_gl_FragCoord = OpVariable %ip_v4f32 Input\n"
1017                 "%BP_fragColor = OpVariable %op_v4f32 Output\n"
1018                 "%BP_vtxColor = OpVariable %ip_v4f32 Input\n"
1019                 "${pre_main:opt}\n"
1020                 "${IF_variable:opt}\n"
1021                 "%BP_main = OpFunction %void None %fun\n"
1022                 "%BP_label_main = OpLabel\n"
1023                 "${IF_carryforward:opt}\n"
1024                 "%BP_tmp1 = OpLoad %v4f32 %BP_vtxColor\n"
1025                 "%BP_tmp2 = OpFunctionCall %v4f32 %test_code %BP_tmp1\n"
1026                 "OpStore %BP_fragColor %BP_tmp2\n"
1027                 "OpReturn\n"
1028                 "OpFunctionEnd\n"
1029                 "${interface_op_func:opt}\n"
1030
1031                 "%isUniqueIdZero = OpFunction %bool None %bool_function\n"
1032                 "%getId_label = OpLabel\n"
1033                 "%loc_x_coord = OpAccessChain %ip_f32 %BP_gl_FragCoord %c_i32_0\n"
1034                 "%loc_y_coord = OpAccessChain %ip_f32 %BP_gl_FragCoord %c_i32_1\n"
1035                 "%x_coord = OpLoad %f32 %loc_x_coord\n"
1036                 "%y_coord = OpLoad %f32 %loc_y_coord\n"
1037                 "%is_x_idx0 = OpFOrdEqual %bool %x_coord %c_f32_0_5\n"
1038                 "%is_y_idx0 = OpFOrdEqual %bool %y_coord %c_f32_0_5\n"
1039                 "%is_frag_0 = OpLogicalAnd %bool %is_x_idx0 %is_y_idx0\n"
1040                 "OpReturnValue %is_frag_0\n"
1041                 "OpFunctionEnd\n"
1042
1043                 "${testfun}\n";
1044         return tcu::StringTemplate(fragmentShaderBoilerplate).specialize(fragments);
1045 }
1046
1047 // Creates mappings from placeholders to pass-through shader code which copies
1048 // the input to the output faithfully.
1049 map<string, string> passthruInterface(const IFDataType& data_type)
1050 {
1051         const string            var_type        = data_type.str();
1052         map<string, string>     fragments       = passthruFragments();
1053         const string            functype        = string("%") + var_type + "_" + var_type + "_function";
1054
1055         fragments["interface_op_func"]  =
1056                 string("%interface_op_func = OpFunction %") + var_type + " None " + functype + "\n"
1057                 "               %io_param1 = OpFunctionParameter %" + var_type + "\n"
1058                 "                %IF_label = OpLabel\n"
1059                 "                            OpReturnValue %io_param1\n"
1060                 "                            OpFunctionEnd\n";
1061         fragments["input_type"]                 = var_type;
1062         fragments["output_type"]                = var_type;
1063         fragments["pre_main"]                   = "";
1064
1065         if (!data_type.elementIs32bit())
1066         {
1067                 if (data_type.elementType == NUMBERTYPE_FLOAT16)
1068                 {
1069                         fragments["pre_main"]   += "%f16 = OpTypeFloat 16\n";
1070                 }
1071                 else if (data_type.elementType == NUMBERTYPE_INT16)
1072                 {
1073                         fragments["pre_main"]   += "%i16 = OpTypeInt 16 1\n";
1074                 }
1075                 else
1076                 {
1077                         fragments["pre_main"]   += "%u16 = OpTypeInt 16 0\n";
1078                 }
1079
1080                 fragments["capability"]         = "OpCapability StorageInputOutput16\n";
1081                 fragments["extension"]          = "OpExtension \"SPV_KHR_16bit_storage\"\n";
1082
1083                 if (data_type.isVector())
1084                 {
1085                         fragments["pre_main"]   += "%" + var_type + " = OpTypeVector %" + IFDataType(1, data_type.elementType).str() + " " + numberToString(data_type.numElements) + "\n";
1086                 }
1087
1088                 fragments["pre_main"]           +=
1089                         "%ip_" + var_type + " = OpTypePointer Input %" + var_type + "\n"
1090                         "%op_" + var_type + " = OpTypePointer Output %" + var_type + "\n";
1091         }
1092
1093         fragments["pre_main"]                   +=
1094                 functype + " = OpTypeFunction %" + var_type + " %" + var_type + "\n"
1095                 "%a3" + var_type + " = OpTypeArray %" + var_type + " %c_i32_3\n"
1096                 "%ip_a3" + var_type + " = OpTypePointer Input %a3" + var_type + "\n"
1097                 "%op_a3" + var_type + " = OpTypePointer Output %a3" + var_type + "\n";
1098
1099         return fragments;
1100 }
1101
1102 // Returns mappings from interface placeholders to their concrete values.
1103 //
1104 // The concrete values should be specialized again to provide ${input_type}
1105 // and ${output_type}.
1106 //
1107 // %ip_${input_type} and %op_${output_type} should also be defined in the final code.
1108 map<string, string> fillInterfacePlaceholderVert (void)
1109 {
1110         map<string, string>     fragments       ;
1111
1112         fragments["IF_entrypoint"]              = "%IF_input %IF_output";
1113         fragments["IF_variable"]                =
1114                 " %IF_input = OpVariable %ip_${input_type} Input\n"
1115                 "%IF_output = OpVariable %op_${output_type} Output\n";
1116         fragments["IF_decoration"]              =
1117                 "OpDecorate  %IF_input Location 2\n"
1118                 "OpDecorate %IF_output Location 2\n";
1119         fragments["IF_carryforward"]    =
1120                 "%IF_input_val = OpLoad %${input_type} %IF_input\n"
1121                 "   %IF_result = OpFunctionCall %${output_type} %interface_op_func %IF_input_val\n"
1122                 "                OpStore %IF_output %IF_result\n";
1123
1124         // Make sure the rest still need to be instantialized.
1125         fragments["capability"]                 = "${capability:opt}";
1126         fragments["extension"]                  = "${extension:opt}";
1127         fragments["debug"]                              = "${debug:opt}";
1128         fragments["decoration"]                 = "${decoration:opt}";
1129         fragments["pre_main"]                   = "${pre_main:opt}";
1130         fragments["testfun"]                    = "${testfun}";
1131         fragments["interface_op_func"]  = "${interface_op_func}";
1132
1133         return fragments;
1134 }
1135
1136 // Returns mappings from interface placeholders to their concrete values.
1137 //
1138 // The concrete values should be specialized again to provide ${input_type}
1139 // and ${output_type}.
1140 //
1141 // %ip_${input_type} and %op_${output_type} should also be defined in the final code.
1142 map<string, string> fillInterfacePlaceholderFrag (void)
1143 {
1144         map<string, string>     fragments       ;
1145
1146         fragments["IF_entrypoint"]              = "%IF_input %IF_output";
1147         fragments["IF_variable"]                =
1148                 " %IF_input = OpVariable %ip_${input_type} Input\n"
1149                 "%IF_output = OpVariable %op_${output_type} Output\n";
1150         fragments["IF_decoration"]              =
1151                 "OpDecorate %IF_input Flat\n"
1152                 "OpDecorate %IF_input Location 2\n"
1153                 "OpDecorate %IF_output Location 1\n";  // Fragment shader should write to location #1.
1154         fragments["IF_carryforward"]    =
1155                 "%IF_input_val = OpLoad %${input_type} %IF_input\n"
1156                 "   %IF_result = OpFunctionCall %${output_type} %interface_op_func %IF_input_val\n"
1157                 "                OpStore %IF_output %IF_result\n";
1158
1159         // Make sure the rest still need to be instantialized.
1160         fragments["capability"]                 = "${capability:opt}";
1161         fragments["extension"]                  = "${extension:opt}";
1162         fragments["debug"]                              = "${debug:opt}";
1163         fragments["decoration"]                 = "${decoration:opt}";
1164         fragments["pre_main"]                   = "${pre_main:opt}";
1165         fragments["testfun"]                    = "${testfun}";
1166         fragments["interface_op_func"]  = "${interface_op_func}";
1167
1168         return fragments;
1169 }
1170
1171 // Returns mappings from interface placeholders to their concrete values.
1172 //
1173 // The concrete values should be specialized again to provide ${input_type}
1174 // and ${output_type}.
1175 //
1176 // %ip_${input_type}, %op_${output_type}, %ip_a3${input_type}, and $op_a3${output_type}
1177 // should also be defined in the final code.
1178 map<string, string> fillInterfacePlaceholderTessCtrl (void)
1179 {
1180         map<string, string>     fragments       ;
1181
1182         fragments["IF_entrypoint"]              = "%IF_input %IF_output";
1183         fragments["IF_variable"]                =
1184                 " %IF_input = OpVariable %ip_a3${input_type} Input\n"
1185                 "%IF_output = OpVariable %op_a3${output_type} Output\n";
1186         fragments["IF_decoration"]              =
1187                 "OpDecorate  %IF_input Location 2\n"
1188                 "OpDecorate %IF_output Location 2\n";
1189         fragments["IF_carryforward"]    =
1190                 " %IF_input_ptr0 = OpAccessChain %ip_${input_type} %IF_input %c_i32_0\n"
1191                 " %IF_input_ptr1 = OpAccessChain %ip_${input_type} %IF_input %c_i32_1\n"
1192                 " %IF_input_ptr2 = OpAccessChain %ip_${input_type} %IF_input %c_i32_2\n"
1193                 "%IF_output_ptr0 = OpAccessChain %op_${output_type} %IF_output %c_i32_0\n"
1194                 "%IF_output_ptr1 = OpAccessChain %op_${output_type} %IF_output %c_i32_1\n"
1195                 "%IF_output_ptr2 = OpAccessChain %op_${output_type} %IF_output %c_i32_2\n"
1196                 "%IF_input_val0 = OpLoad %${input_type} %IF_input_ptr0\n"
1197                 "%IF_input_val1 = OpLoad %${input_type} %IF_input_ptr1\n"
1198                 "%IF_input_val2 = OpLoad %${input_type} %IF_input_ptr2\n"
1199                 "%IF_input_res0 = OpFunctionCall %${output_type} %interface_op_func %IF_input_val0\n"
1200                 "%IF_input_res1 = OpFunctionCall %${output_type} %interface_op_func %IF_input_val1\n"
1201                 "%IF_input_res2 = OpFunctionCall %${output_type} %interface_op_func %IF_input_val2\n"
1202                 "OpStore %IF_output_ptr0 %IF_input_res0\n"
1203                 "OpStore %IF_output_ptr1 %IF_input_res1\n"
1204                 "OpStore %IF_output_ptr2 %IF_input_res2\n";
1205
1206         // Make sure the rest still need to be instantialized.
1207         fragments["capability"]                 = "${capability:opt}";
1208         fragments["extension"]                  = "${extension:opt}";
1209         fragments["debug"]                              = "${debug:opt}";
1210         fragments["decoration"]                 = "${decoration:opt}";
1211         fragments["pre_main"]                   = "${pre_main:opt}";
1212         fragments["testfun"]                    = "${testfun}";
1213         fragments["interface_op_func"]  = "${interface_op_func}";
1214
1215         return fragments;
1216 }
1217
1218 // Returns mappings from interface placeholders to their concrete values.
1219 //
1220 // The concrete values should be specialized again to provide ${input_type}
1221 // and ${output_type}.
1222 //
1223 // %ip_${input_type}, %op_${output_type}, %ip_a3${input_type}, and $op_a3${output_type}
1224 // should also be defined in the final code.
1225 map<string, string> fillInterfacePlaceholderTessEvalGeom (void)
1226 {
1227         map<string, string>     fragments       ;
1228
1229         fragments["IF_entrypoint"]              = "%IF_input %IF_output";
1230         fragments["IF_variable"]                =
1231                 " %IF_input = OpVariable %ip_a3${input_type} Input\n"
1232                 "%IF_output = OpVariable %op_${output_type} Output\n";
1233         fragments["IF_decoration"]              =
1234                 "OpDecorate  %IF_input Location 2\n"
1235                 "OpDecorate %IF_output Location 2\n";
1236         fragments["IF_carryforward"]    =
1237                 // Only get the first value since all three values are the same anyway.
1238                 " %IF_input_ptr0 = OpAccessChain %ip_${input_type} %IF_input %c_i32_0\n"
1239                 " %IF_input_val0 = OpLoad %${input_type} %IF_input_ptr0\n"
1240                 " %IF_input_res0 = OpFunctionCall %${output_type} %interface_op_func %IF_input_val0\n"
1241                 "OpStore %IF_output %IF_input_res0\n";
1242
1243         // Make sure the rest still need to be instantialized.
1244         fragments["capability"]                 = "${capability:opt}";
1245         fragments["extension"]                  = "${extension:opt}";
1246         fragments["debug"]                              = "${debug:opt}";
1247         fragments["decoration"]                 = "${decoration:opt}";
1248         fragments["pre_main"]                   = "${pre_main:opt}";
1249         fragments["testfun"]                    = "${testfun}";
1250         fragments["interface_op_func"]  = "${interface_op_func}";
1251
1252         return fragments;
1253 }
1254
1255 map<string, string> passthruFragments(void)
1256 {
1257         map<string, string> fragments;
1258         fragments["testfun"] =
1259                 // A %test_code function that returns its argument unchanged.
1260                 "%test_code = OpFunction %v4f32 None %v4f32_function\n"
1261                 "%param1 = OpFunctionParameter %v4f32\n"
1262                 "%label_testfun = OpLabel\n"
1263                 "OpReturnValue %param1\n"
1264                 "OpFunctionEnd\n";
1265         return fragments;
1266 }
1267
1268 // Adds shader assembly text to dst.spirvAsmSources for all shader kinds.
1269 // Vertex shader gets custom code from context, the rest are pass-through.
1270 void addShaderCodeCustomVertex (vk::SourceCollections& dst, InstanceContext& context, const SpirVAsmBuildOptions* spirVAsmBuildOptions)
1271 {
1272         SpirvVersion targetSpirvVersion;
1273
1274         if (spirVAsmBuildOptions == DE_NULL)
1275                 targetSpirvVersion = context.resources.spirvVersion;
1276         else
1277                 targetSpirvVersion = spirVAsmBuildOptions->targetVersion;
1278
1279         if (!context.interfaces.empty())
1280         {
1281                 // Inject boilerplate code to wire up additional input/output variables between stages.
1282                 // Just copy the contents in input variable to output variable in all stages except
1283                 // the customized stage.
1284                 dst.spirvAsmSources.add("vert", spirVAsmBuildOptions) << StringTemplate(makeVertexShaderAssembly(fillInterfacePlaceholderVert())).specialize(context.testCodeFragments) << SpirVAsmBuildOptions(targetSpirvVersion);
1285                 dst.spirvAsmSources.add("frag", spirVAsmBuildOptions) << StringTemplate(makeFragmentShaderAssembly(fillInterfacePlaceholderFrag())).specialize(passthruInterface(context.interfaces.getOutputType())) << SpirVAsmBuildOptions(targetSpirvVersion);
1286         } else {
1287                 map<string, string> passthru = passthruFragments();
1288
1289                 dst.spirvAsmSources.add("vert", spirVAsmBuildOptions) << makeVertexShaderAssembly(context.testCodeFragments) << SpirVAsmBuildOptions(targetSpirvVersion);
1290                 dst.spirvAsmSources.add("frag", spirVAsmBuildOptions) << makeFragmentShaderAssembly(passthru) << SpirVAsmBuildOptions(targetSpirvVersion);
1291         }
1292 }
1293
1294 void addShaderCodeCustomVertex (vk::SourceCollections& dst, InstanceContext context)
1295 {
1296         addShaderCodeCustomVertex(dst, context, DE_NULL);
1297 }
1298
1299 // Adds shader assembly text to dst.spirvAsmSources for all shader kinds.
1300 // Tessellation control shader gets custom code from context, the rest are
1301 // pass-through.
1302 void addShaderCodeCustomTessControl(vk::SourceCollections& dst, InstanceContext& context, const SpirVAsmBuildOptions* spirVAsmBuildOptions)
1303 {
1304         SpirvVersion targetSpirvVersion;
1305
1306         if (spirVAsmBuildOptions == DE_NULL)
1307                 targetSpirvVersion = context.resources.spirvVersion;
1308         else
1309                 targetSpirvVersion = spirVAsmBuildOptions->targetVersion;
1310
1311         if (!context.interfaces.empty())
1312         {
1313                 // Inject boilerplate code to wire up additional input/output variables between stages.
1314                 // Just copy the contents in input variable to output variable in all stages except
1315                 // the customized stage.
1316                 dst.spirvAsmSources.add("vert",  spirVAsmBuildOptions) << StringTemplate(makeVertexShaderAssembly(fillInterfacePlaceholderVert())).specialize(passthruInterface(context.interfaces.getInputType())) << SpirVAsmBuildOptions(targetSpirvVersion);
1317                 dst.spirvAsmSources.add("tessc", spirVAsmBuildOptions) << StringTemplate(makeTessControlShaderAssembly(fillInterfacePlaceholderTessCtrl())).specialize(context.testCodeFragments) << SpirVAsmBuildOptions(targetSpirvVersion);
1318                 dst.spirvAsmSources.add("tesse", spirVAsmBuildOptions) << StringTemplate(makeTessEvalShaderAssembly(fillInterfacePlaceholderTessEvalGeom())).specialize(passthruInterface(context.interfaces.getOutputType())) << SpirVAsmBuildOptions(targetSpirvVersion);
1319                 dst.spirvAsmSources.add("frag",  spirVAsmBuildOptions) << StringTemplate(makeFragmentShaderAssembly(fillInterfacePlaceholderFrag())).specialize(passthruInterface(context.interfaces.getOutputType())) << SpirVAsmBuildOptions(targetSpirvVersion);
1320         }
1321         else
1322         {
1323                 map<string, string> passthru = passthruFragments();
1324
1325                 dst.spirvAsmSources.add("vert",  spirVAsmBuildOptions) << makeVertexShaderAssembly(passthru) << SpirVAsmBuildOptions(targetSpirvVersion);
1326                 dst.spirvAsmSources.add("tessc", spirVAsmBuildOptions) << makeTessControlShaderAssembly(context.testCodeFragments) << SpirVAsmBuildOptions(targetSpirvVersion);
1327                 dst.spirvAsmSources.add("tesse", spirVAsmBuildOptions) << makeTessEvalShaderAssembly(passthru) << SpirVAsmBuildOptions(targetSpirvVersion);
1328                 dst.spirvAsmSources.add("frag",  spirVAsmBuildOptions) << makeFragmentShaderAssembly(passthru) << SpirVAsmBuildOptions(targetSpirvVersion);
1329         }
1330 }
1331
1332 void addShaderCodeCustomTessControl (vk::SourceCollections& dst, InstanceContext context)
1333 {
1334         addShaderCodeCustomTessControl(dst, context, DE_NULL);
1335 }
1336
1337 // Adds shader assembly text to dst.spirvAsmSources for all shader kinds.
1338 // Tessellation evaluation shader gets custom code from context, the rest are
1339 // pass-through.
1340 void addShaderCodeCustomTessEval(vk::SourceCollections& dst, InstanceContext& context, const SpirVAsmBuildOptions* spirVAsmBuildOptions)
1341 {
1342         SpirvVersion targetSpirvVersion;
1343
1344         if (spirVAsmBuildOptions == DE_NULL)
1345                 targetSpirvVersion = context.resources.spirvVersion;
1346         else
1347                 targetSpirvVersion = spirVAsmBuildOptions->targetVersion;
1348
1349         if (!context.interfaces.empty())
1350         {
1351                 // Inject boilerplate code to wire up additional input/output variables between stages.
1352                 // Just copy the contents in input variable to output variable in all stages except
1353                 // the customized stage.
1354                 dst.spirvAsmSources.add("vert",  spirVAsmBuildOptions) << StringTemplate(makeVertexShaderAssembly(fillInterfacePlaceholderVert())).specialize(passthruInterface(context.interfaces.getInputType())) << SpirVAsmBuildOptions(targetSpirvVersion);
1355                 dst.spirvAsmSources.add("tessc", spirVAsmBuildOptions) << StringTemplate(makeTessControlShaderAssembly(fillInterfacePlaceholderTessCtrl())).specialize(passthruInterface(context.interfaces.getInputType())) << SpirVAsmBuildOptions(targetSpirvVersion);
1356                 dst.spirvAsmSources.add("tesse", spirVAsmBuildOptions) << StringTemplate(makeTessEvalShaderAssembly(fillInterfacePlaceholderTessEvalGeom())).specialize(context.testCodeFragments) << SpirVAsmBuildOptions(targetSpirvVersion);
1357                 dst.spirvAsmSources.add("frag",  spirVAsmBuildOptions) << StringTemplate(makeFragmentShaderAssembly(fillInterfacePlaceholderFrag())).specialize(passthruInterface(context.interfaces.getOutputType())) << SpirVAsmBuildOptions(targetSpirvVersion);
1358         }
1359         else
1360         {
1361                 map<string, string> passthru = passthruFragments();
1362                 dst.spirvAsmSources.add("vert",  spirVAsmBuildOptions) << makeVertexShaderAssembly(passthru) << SpirVAsmBuildOptions(targetSpirvVersion);
1363                 dst.spirvAsmSources.add("tessc", spirVAsmBuildOptions) << makeTessControlShaderAssembly(passthru) << SpirVAsmBuildOptions(targetSpirvVersion);
1364                 dst.spirvAsmSources.add("tesse", spirVAsmBuildOptions) << makeTessEvalShaderAssembly(context.testCodeFragments) << SpirVAsmBuildOptions(targetSpirvVersion);
1365                 dst.spirvAsmSources.add("frag",  spirVAsmBuildOptions) << makeFragmentShaderAssembly(passthru) << SpirVAsmBuildOptions(targetSpirvVersion);
1366         }
1367 }
1368
1369 void addShaderCodeCustomTessEval (vk::SourceCollections& dst, InstanceContext context)
1370 {
1371         addShaderCodeCustomTessEval(dst, context, DE_NULL);
1372 }
1373
1374 // Adds shader assembly text to dst.spirvAsmSources for all shader kinds.
1375 // Geometry shader gets custom code from context, the rest are pass-through.
1376 void addShaderCodeCustomGeometry (vk::SourceCollections& dst, InstanceContext& context, const SpirVAsmBuildOptions* spirVAsmBuildOptions)
1377 {
1378         SpirvVersion targetSpirvVersion;
1379
1380         if (spirVAsmBuildOptions == DE_NULL)
1381                 targetSpirvVersion = context.resources.spirvVersion;
1382         else
1383                 targetSpirvVersion = spirVAsmBuildOptions->targetVersion;
1384
1385         if (!context.interfaces.empty())
1386         {
1387                 // Inject boilerplate code to wire up additional input/output variables between stages.
1388                 // Just copy the contents in input variable to output variable in all stages except
1389                 // the customized stage.
1390                 dst.spirvAsmSources.add("vert", spirVAsmBuildOptions) << StringTemplate(makeVertexShaderAssembly(fillInterfacePlaceholderVert())).specialize(passthruInterface(context.interfaces.getInputType())) << SpirVAsmBuildOptions(targetSpirvVersion);
1391                 dst.spirvAsmSources.add("geom", spirVAsmBuildOptions) << StringTemplate(makeGeometryShaderAssembly(fillInterfacePlaceholderTessEvalGeom())).specialize(context.testCodeFragments) << SpirVAsmBuildOptions(targetSpirvVersion);
1392                 dst.spirvAsmSources.add("frag", spirVAsmBuildOptions) << StringTemplate(makeFragmentShaderAssembly(fillInterfacePlaceholderFrag())).specialize(passthruInterface(context.interfaces.getOutputType())) << SpirVAsmBuildOptions(targetSpirvVersion);
1393         }
1394         else
1395         {
1396                 map<string, string> passthru = passthruFragments();
1397                 dst.spirvAsmSources.add("vert", spirVAsmBuildOptions) << makeVertexShaderAssembly(passthru) << SpirVAsmBuildOptions(targetSpirvVersion);
1398                 dst.spirvAsmSources.add("geom", spirVAsmBuildOptions) << makeGeometryShaderAssembly(context.testCodeFragments) << SpirVAsmBuildOptions(targetSpirvVersion);
1399                 dst.spirvAsmSources.add("frag", spirVAsmBuildOptions) << makeFragmentShaderAssembly(passthru) << SpirVAsmBuildOptions(targetSpirvVersion);
1400         }
1401 }
1402
1403 void addShaderCodeCustomGeometry (vk::SourceCollections& dst, InstanceContext context)
1404 {
1405         addShaderCodeCustomGeometry(dst, context, DE_NULL);
1406 }
1407
1408 // Adds shader assembly text to dst.spirvAsmSources for all shader kinds.
1409 // Fragment shader gets custom code from context, the rest are pass-through.
1410 void addShaderCodeCustomFragment (vk::SourceCollections& dst, InstanceContext& context, const SpirVAsmBuildOptions* spirVAsmBuildOptions)
1411 {
1412         SpirvVersion targetSpirvVersion;
1413
1414         if (spirVAsmBuildOptions == DE_NULL)
1415                 targetSpirvVersion = context.resources.spirvVersion;
1416         else
1417                 targetSpirvVersion = spirVAsmBuildOptions->targetVersion;
1418
1419         if (!context.interfaces.empty())
1420         {
1421                 // Inject boilerplate code to wire up additional input/output variables between stages.
1422                 // Just copy the contents in input variable to output variable in all stages except
1423                 // the customized stage.
1424                 dst.spirvAsmSources.add("vert", spirVAsmBuildOptions) << StringTemplate(makeVertexShaderAssembly(fillInterfacePlaceholderVert())).specialize(passthruInterface(context.interfaces.getInputType())) << SpirVAsmBuildOptions(targetSpirvVersion);
1425                 dst.spirvAsmSources.add("frag", spirVAsmBuildOptions) << StringTemplate(makeFragmentShaderAssembly(fillInterfacePlaceholderFrag())).specialize(context.testCodeFragments) << SpirVAsmBuildOptions(targetSpirvVersion);
1426         }
1427         else
1428         {
1429                 map<string, string> passthru = passthruFragments();
1430                 dst.spirvAsmSources.add("vert", spirVAsmBuildOptions) << makeVertexShaderAssembly(passthru) << SpirVAsmBuildOptions(targetSpirvVersion);
1431                 dst.spirvAsmSources.add("frag", spirVAsmBuildOptions) << makeFragmentShaderAssembly(context.testCodeFragments) << SpirVAsmBuildOptions(targetSpirvVersion);
1432         }
1433 }
1434
1435 void addShaderCodeCustomFragment (vk::SourceCollections& dst, InstanceContext context)
1436 {
1437         addShaderCodeCustomFragment(dst, context, DE_NULL);
1438 }
1439
1440 void createCombinedModule(vk::SourceCollections& dst, InstanceContext)
1441 {
1442         // \todo [2015-12-07 awoloszyn] Make tessellation / geometry conditional
1443         // \todo [2015-12-07 awoloszyn] Remove OpName and OpMemberName at some point
1444         dst.spirvAsmSources.add("module") <<
1445                 "OpCapability Shader\n"
1446                 "OpCapability ClipDistance\n"
1447                 "OpCapability CullDistance\n"
1448                 "OpCapability Geometry\n"
1449                 "OpCapability Tessellation\n"
1450                 "OpMemoryModel Logical GLSL450\n"
1451
1452                 "OpEntryPoint Vertex %vert_main \"main\" %vert_Position %vert_vtxColor %vert_color %vert_vtxPosition %vert_vertex_id %vert_instance_id\n"
1453                 "OpEntryPoint Geometry %geom_main \"main\" %geom_out_gl_position %geom_gl_in %geom_out_color %geom_in_color\n"
1454                 "OpEntryPoint TessellationControl %tessc_main \"main\" %tessc_out_color %tessc_gl_InvocationID %tessc_in_color %tessc_out_position %tessc_in_position %tessc_gl_TessLevelOuter %tessc_gl_TessLevelInner\n"
1455                 "OpEntryPoint TessellationEvaluation %tesse_main \"main\" %tesse_stream %tesse_gl_tessCoord %tesse_in_position %tesse_out_color %tesse_in_color \n"
1456                 "OpEntryPoint Fragment %frag_main \"main\" %frag_vtxColor %frag_fragColor\n"
1457
1458                 "OpExecutionMode %geom_main Triangles\n"
1459                 "OpExecutionMode %geom_main OutputTriangleStrip\n"
1460                 "OpExecutionMode %geom_main OutputVertices 3\n"
1461
1462                 "OpExecutionMode %tessc_main OutputVertices 3\n"
1463
1464                 "OpExecutionMode %tesse_main Triangles\n"
1465                 "OpExecutionMode %tesse_main SpacingEqual\n"
1466                 "OpExecutionMode %tesse_main VertexOrderCcw\n"
1467
1468                 "OpExecutionMode %frag_main OriginUpperLeft\n"
1469
1470                 "OpName %vert_main \"main\"\n"
1471                 "OpName %vert_vtxPosition \"vtxPosition\"\n"
1472                 "OpName %vert_Position \"position\"\n"
1473                 "OpName %vert_vtxColor \"vtxColor\"\n"
1474                 "OpName %vert_color \"color\"\n"
1475                 "OpName %vert_vertex_id \"gl_VertexIndex\"\n"
1476                 "OpName %vert_instance_id \"gl_InstanceIndex\"\n"
1477                 "OpName %geom_main \"main\"\n"
1478                 "OpName %geom_per_vertex_in \"gl_PerVertex\"\n"
1479                 "OpMemberName %geom_per_vertex_in 0 \"gl_Position\"\n"
1480                 "OpMemberName %geom_per_vertex_in 1 \"gl_PointSize\"\n"
1481                 "OpMemberName %geom_per_vertex_in 2 \"gl_ClipDistance\"\n"
1482                 "OpMemberName %geom_per_vertex_in 3 \"gl_CullDistance\"\n"
1483                 "OpName %geom_gl_in \"gl_in\"\n"
1484                 "OpName %geom_out_color \"out_color\"\n"
1485                 "OpName %geom_in_color \"in_color\"\n"
1486                 "OpName %tessc_main \"main\"\n"
1487                 "OpName %tessc_out_color \"out_color\"\n"
1488                 "OpName %tessc_gl_InvocationID \"gl_InvocationID\"\n"
1489                 "OpName %tessc_in_color \"in_color\"\n"
1490                 "OpName %tessc_out_position \"out_position\"\n"
1491                 "OpName %tessc_in_position \"in_position\"\n"
1492                 "OpName %tessc_gl_TessLevelOuter \"gl_TessLevelOuter\"\n"
1493                 "OpName %tessc_gl_TessLevelInner \"gl_TessLevelInner\"\n"
1494                 "OpName %tesse_main \"main\"\n"
1495                 "OpName %tesse_per_vertex_out \"gl_PerVertex\"\n"
1496                 "OpMemberName %tesse_per_vertex_out 0 \"gl_Position\"\n"
1497                 "OpMemberName %tesse_per_vertex_out 1 \"gl_PointSize\"\n"
1498                 "OpMemberName %tesse_per_vertex_out 2 \"gl_ClipDistance\"\n"
1499                 "OpMemberName %tesse_per_vertex_out 3 \"gl_CullDistance\"\n"
1500                 "OpName %tesse_stream \"\"\n"
1501                 "OpName %tesse_gl_tessCoord \"gl_TessCoord\"\n"
1502                 "OpName %tesse_in_position \"in_position\"\n"
1503                 "OpName %tesse_out_color \"out_color\"\n"
1504                 "OpName %tesse_in_color \"in_color\"\n"
1505                 "OpName %frag_main \"main\"\n"
1506                 "OpName %frag_fragColor \"fragColor\"\n"
1507                 "OpName %frag_vtxColor \"vtxColor\"\n"
1508
1509                 "; Vertex decorations\n"
1510                 "OpDecorate %vert_vtxPosition Location 2\n"
1511                 "OpDecorate %vert_Position Location 0\n"
1512                 "OpDecorate %vert_vtxColor Location 1\n"
1513                 "OpDecorate %vert_color Location 1\n"
1514                 "OpDecorate %vert_vertex_id BuiltIn VertexIndex\n"
1515                 "OpDecorate %vert_instance_id BuiltIn InstanceIndex\n"
1516
1517                 "; Geometry decorations\n"
1518                 "OpDecorate %geom_out_gl_position BuiltIn Position\n"
1519                 "OpMemberDecorate %geom_per_vertex_in 0 BuiltIn Position\n"
1520                 "OpMemberDecorate %geom_per_vertex_in 1 BuiltIn PointSize\n"
1521                 "OpMemberDecorate %geom_per_vertex_in 2 BuiltIn ClipDistance\n"
1522                 "OpMemberDecorate %geom_per_vertex_in 3 BuiltIn CullDistance\n"
1523                 "OpDecorate %geom_per_vertex_in Block\n"
1524                 "OpDecorate %geom_out_color Location 1\n"
1525                 "OpDecorate %geom_in_color Location 1\n"
1526
1527                 "; Tessellation Control decorations\n"
1528                 "OpDecorate %tessc_out_color Location 1\n"
1529                 "OpDecorate %tessc_gl_InvocationID BuiltIn InvocationId\n"
1530                 "OpDecorate %tessc_in_color Location 1\n"
1531                 "OpDecorate %tessc_out_position Location 2\n"
1532                 "OpDecorate %tessc_in_position Location 2\n"
1533                 "OpDecorate %tessc_gl_TessLevelOuter Patch\n"
1534                 "OpDecorate %tessc_gl_TessLevelOuter BuiltIn TessLevelOuter\n"
1535                 "OpDecorate %tessc_gl_TessLevelInner Patch\n"
1536                 "OpDecorate %tessc_gl_TessLevelInner BuiltIn TessLevelInner\n"
1537
1538                 "; Tessellation Evaluation decorations\n"
1539                 "OpMemberDecorate %tesse_per_vertex_out 0 BuiltIn Position\n"
1540                 "OpMemberDecorate %tesse_per_vertex_out 1 BuiltIn PointSize\n"
1541                 "OpMemberDecorate %tesse_per_vertex_out 2 BuiltIn ClipDistance\n"
1542                 "OpMemberDecorate %tesse_per_vertex_out 3 BuiltIn CullDistance\n"
1543                 "OpDecorate %tesse_per_vertex_out Block\n"
1544                 "OpDecorate %tesse_gl_tessCoord BuiltIn TessCoord\n"
1545                 "OpDecorate %tesse_in_position Location 2\n"
1546                 "OpDecorate %tesse_out_color Location 1\n"
1547                 "OpDecorate %tesse_in_color Location 1\n"
1548
1549                 "; Fragment decorations\n"
1550                 "OpDecorate %frag_fragColor Location 0\n"
1551                 "OpDecorate %frag_vtxColor Location 1\n"
1552
1553                 SPIRV_ASSEMBLY_TYPES
1554                 SPIRV_ASSEMBLY_CONSTANTS
1555                 SPIRV_ASSEMBLY_ARRAYS
1556
1557                 "; Vertex Variables\n"
1558                 "%vert_vtxPosition = OpVariable %op_v4f32 Output\n"
1559                 "%vert_Position = OpVariable %ip_v4f32 Input\n"
1560                 "%vert_vtxColor = OpVariable %op_v4f32 Output\n"
1561                 "%vert_color = OpVariable %ip_v4f32 Input\n"
1562                 "%vert_vertex_id = OpVariable %ip_i32 Input\n"
1563                 "%vert_instance_id = OpVariable %ip_i32 Input\n"
1564
1565                 "; Geometry Variables\n"
1566                 "%geom_per_vertex_in = OpTypeStruct %v4f32 %f32 %a1f32 %a1f32\n"
1567                 "%geom_a3_per_vertex_in = OpTypeArray %geom_per_vertex_in %c_u32_3\n"
1568                 "%geom_ip_a3_per_vertex_in = OpTypePointer Input %geom_a3_per_vertex_in\n"
1569                 "%geom_gl_in = OpVariable %geom_ip_a3_per_vertex_in Input\n"
1570                 "%geom_out_color = OpVariable %op_v4f32 Output\n"
1571                 "%geom_in_color = OpVariable %ip_a3v4f32 Input\n"
1572                 "%geom_out_gl_position = OpVariable %op_v4f32 Output\n"
1573
1574                 "; Tessellation Control Variables\n"
1575                 "%tessc_out_color = OpVariable %op_a3v4f32 Output\n"
1576                 "%tessc_gl_InvocationID = OpVariable %ip_i32 Input\n"
1577                 "%tessc_in_color = OpVariable %ip_a32v4f32 Input\n"
1578                 "%tessc_out_position = OpVariable %op_a3v4f32 Output\n"
1579                 "%tessc_in_position = OpVariable %ip_a32v4f32 Input\n"
1580                 "%tessc_gl_TessLevelOuter = OpVariable %op_a4f32 Output\n"
1581                 "%tessc_gl_TessLevelInner = OpVariable %op_a2f32 Output\n"
1582
1583                 "; Tessellation Evaluation Decorations\n"
1584                 "%tesse_per_vertex_out = OpTypeStruct %v4f32 %f32 %a1f32 %a1f32\n"
1585                 "%tesse_op_per_vertex_out = OpTypePointer Output %tesse_per_vertex_out\n"
1586                 "%tesse_stream = OpVariable %tesse_op_per_vertex_out Output\n"
1587                 "%tesse_gl_tessCoord = OpVariable %ip_v3f32 Input\n"
1588                 "%tesse_in_position = OpVariable %ip_a32v4f32 Input\n"
1589                 "%tesse_out_color = OpVariable %op_v4f32 Output\n"
1590                 "%tesse_in_color = OpVariable %ip_a32v4f32 Input\n"
1591
1592                 "; Fragment Variables\n"
1593                 "%frag_fragColor = OpVariable %op_v4f32 Output\n"
1594                 "%frag_vtxColor = OpVariable %ip_v4f32 Input\n"
1595
1596                 "; Vertex Entry\n"
1597                 "%vert_main = OpFunction %void None %fun\n"
1598                 "%vert_label = OpLabel\n"
1599                 "%vert_tmp_position = OpLoad %v4f32 %vert_Position\n"
1600                 "OpStore %vert_vtxPosition %vert_tmp_position\n"
1601                 "%vert_tmp_color = OpLoad %v4f32 %vert_color\n"
1602                 "OpStore %vert_vtxColor %vert_tmp_color\n"
1603                 "OpReturn\n"
1604                 "OpFunctionEnd\n"
1605
1606                 "; Geometry Entry\n"
1607                 "%geom_main = OpFunction %void None %fun\n"
1608                 "%geom_label = OpLabel\n"
1609                 "%geom_gl_in_0_gl_position = OpAccessChain %ip_v4f32 %geom_gl_in %c_i32_0 %c_i32_0\n"
1610                 "%geom_gl_in_1_gl_position = OpAccessChain %ip_v4f32 %geom_gl_in %c_i32_1 %c_i32_0\n"
1611                 "%geom_gl_in_2_gl_position = OpAccessChain %ip_v4f32 %geom_gl_in %c_i32_2 %c_i32_0\n"
1612                 "%geom_in_position_0 = OpLoad %v4f32 %geom_gl_in_0_gl_position\n"
1613                 "%geom_in_position_1 = OpLoad %v4f32 %geom_gl_in_1_gl_position\n"
1614                 "%geom_in_position_2 = OpLoad %v4f32 %geom_gl_in_2_gl_position \n"
1615                 "%geom_in_color_0_ptr = OpAccessChain %ip_v4f32 %geom_in_color %c_i32_0\n"
1616                 "%geom_in_color_1_ptr = OpAccessChain %ip_v4f32 %geom_in_color %c_i32_1\n"
1617                 "%geom_in_color_2_ptr = OpAccessChain %ip_v4f32 %geom_in_color %c_i32_2\n"
1618                 "%geom_in_color_0 = OpLoad %v4f32 %geom_in_color_0_ptr\n"
1619                 "%geom_in_color_1 = OpLoad %v4f32 %geom_in_color_1_ptr\n"
1620                 "%geom_in_color_2 = OpLoad %v4f32 %geom_in_color_2_ptr\n"
1621                 "OpStore %geom_out_gl_position %geom_in_position_0\n"
1622                 "OpStore %geom_out_color %geom_in_color_0\n"
1623                 "OpEmitVertex\n"
1624                 "OpStore %geom_out_gl_position %geom_in_position_1\n"
1625                 "OpStore %geom_out_color %geom_in_color_1\n"
1626                 "OpEmitVertex\n"
1627                 "OpStore %geom_out_gl_position %geom_in_position_2\n"
1628                 "OpStore %geom_out_color %geom_in_color_2\n"
1629                 "OpEmitVertex\n"
1630                 "OpEndPrimitive\n"
1631                 "OpReturn\n"
1632                 "OpFunctionEnd\n"
1633
1634                 "; Tessellation Control Entry\n"
1635                 "%tessc_main = OpFunction %void None %fun\n"
1636                 "%tessc_label = OpLabel\n"
1637                 "%tessc_invocation_id = OpLoad %i32 %tessc_gl_InvocationID\n"
1638                 "%tessc_in_color_ptr = OpAccessChain %ip_v4f32 %tessc_in_color %tessc_invocation_id\n"
1639                 "%tessc_in_position_ptr = OpAccessChain %ip_v4f32 %tessc_in_position %tessc_invocation_id\n"
1640                 "%tessc_in_color_val = OpLoad %v4f32 %tessc_in_color_ptr\n"
1641                 "%tessc_in_position_val = OpLoad %v4f32 %tessc_in_position_ptr\n"
1642                 "%tessc_out_color_ptr = OpAccessChain %op_v4f32 %tessc_out_color %tessc_invocation_id\n"
1643                 "%tessc_out_position_ptr = OpAccessChain %op_v4f32 %tessc_out_position %tessc_invocation_id\n"
1644                 "OpStore %tessc_out_color_ptr %tessc_in_color_val\n"
1645                 "OpStore %tessc_out_position_ptr %tessc_in_position_val\n"
1646                 "%tessc_is_first_invocation = OpIEqual %bool %tessc_invocation_id %c_i32_0\n"
1647                 "OpSelectionMerge %tessc_merge_label None\n"
1648                 "OpBranchConditional %tessc_is_first_invocation %tessc_first_invocation %tessc_merge_label\n"
1649                 "%tessc_first_invocation = OpLabel\n"
1650                 "%tessc_tess_outer_0 = OpAccessChain %op_f32 %tessc_gl_TessLevelOuter %c_i32_0\n"
1651                 "%tessc_tess_outer_1 = OpAccessChain %op_f32 %tessc_gl_TessLevelOuter %c_i32_1\n"
1652                 "%tessc_tess_outer_2 = OpAccessChain %op_f32 %tessc_gl_TessLevelOuter %c_i32_2\n"
1653                 "%tessc_tess_inner = OpAccessChain %op_f32 %tessc_gl_TessLevelInner %c_i32_0\n"
1654                 "OpStore %tessc_tess_outer_0 %c_f32_1\n"
1655                 "OpStore %tessc_tess_outer_1 %c_f32_1\n"
1656                 "OpStore %tessc_tess_outer_2 %c_f32_1\n"
1657                 "OpStore %tessc_tess_inner %c_f32_1\n"
1658                 "OpBranch %tessc_merge_label\n"
1659                 "%tessc_merge_label = OpLabel\n"
1660                 "OpReturn\n"
1661                 "OpFunctionEnd\n"
1662
1663                 "; Tessellation Evaluation Entry\n"
1664                 "%tesse_main = OpFunction %void None %fun\n"
1665                 "%tesse_label = OpLabel\n"
1666                 "%tesse_tc_0_ptr = OpAccessChain %ip_f32 %tesse_gl_tessCoord %c_u32_0\n"
1667                 "%tesse_tc_1_ptr = OpAccessChain %ip_f32 %tesse_gl_tessCoord %c_u32_1\n"
1668                 "%tesse_tc_2_ptr = OpAccessChain %ip_f32 %tesse_gl_tessCoord %c_u32_2\n"
1669                 "%tesse_tc_0 = OpLoad %f32 %tesse_tc_0_ptr\n"
1670                 "%tesse_tc_1 = OpLoad %f32 %tesse_tc_1_ptr\n"
1671                 "%tesse_tc_2 = OpLoad %f32 %tesse_tc_2_ptr\n"
1672                 "%tesse_in_pos_0_ptr = OpAccessChain %ip_v4f32 %tesse_in_position %c_i32_0\n"
1673                 "%tesse_in_pos_1_ptr = OpAccessChain %ip_v4f32 %tesse_in_position %c_i32_1\n"
1674                 "%tesse_in_pos_2_ptr = OpAccessChain %ip_v4f32 %tesse_in_position %c_i32_2\n"
1675                 "%tesse_in_pos_0 = OpLoad %v4f32 %tesse_in_pos_0_ptr\n"
1676                 "%tesse_in_pos_1 = OpLoad %v4f32 %tesse_in_pos_1_ptr\n"
1677                 "%tesse_in_pos_2 = OpLoad %v4f32 %tesse_in_pos_2_ptr\n"
1678                 "%tesse_in_pos_0_weighted = OpVectorTimesScalar %v4f32 %tesse_in_pos_0 %tesse_tc_0\n"
1679                 "%tesse_in_pos_1_weighted = OpVectorTimesScalar %v4f32 %tesse_in_pos_1 %tesse_tc_1\n"
1680                 "%tesse_in_pos_2_weighted = OpVectorTimesScalar %v4f32 %tesse_in_pos_2 %tesse_tc_2\n"
1681                 "%tesse_out_pos_ptr = OpAccessChain %op_v4f32 %tesse_stream %c_i32_0\n"
1682                 "%tesse_in_pos_0_plus_pos_1 = OpFAdd %v4f32 %tesse_in_pos_0_weighted %tesse_in_pos_1_weighted\n"
1683                 "%tesse_computed_out = OpFAdd %v4f32 %tesse_in_pos_0_plus_pos_1 %tesse_in_pos_2_weighted\n"
1684                 "OpStore %tesse_out_pos_ptr %tesse_computed_out\n"
1685                 "%tesse_in_clr_0_ptr = OpAccessChain %ip_v4f32 %tesse_in_color %c_i32_0\n"
1686                 "%tesse_in_clr_1_ptr = OpAccessChain %ip_v4f32 %tesse_in_color %c_i32_1\n"
1687                 "%tesse_in_clr_2_ptr = OpAccessChain %ip_v4f32 %tesse_in_color %c_i32_2\n"
1688                 "%tesse_in_clr_0 = OpLoad %v4f32 %tesse_in_clr_0_ptr\n"
1689                 "%tesse_in_clr_1 = OpLoad %v4f32 %tesse_in_clr_1_ptr\n"
1690                 "%tesse_in_clr_2 = OpLoad %v4f32 %tesse_in_clr_2_ptr\n"
1691                 "%tesse_in_clr_0_weighted = OpVectorTimesScalar %v4f32 %tesse_in_clr_0 %tesse_tc_0\n"
1692                 "%tesse_in_clr_1_weighted = OpVectorTimesScalar %v4f32 %tesse_in_clr_1 %tesse_tc_1\n"
1693                 "%tesse_in_clr_2_weighted = OpVectorTimesScalar %v4f32 %tesse_in_clr_2 %tesse_tc_2\n"
1694                 "%tesse_in_clr_0_plus_col_1 = OpFAdd %v4f32 %tesse_in_clr_0_weighted %tesse_in_clr_1_weighted\n"
1695                 "%tesse_computed_clr = OpFAdd %v4f32 %tesse_in_clr_0_plus_col_1 %tesse_in_clr_2_weighted\n"
1696                 "OpStore %tesse_out_color %tesse_computed_clr\n"
1697                 "OpReturn\n"
1698                 "OpFunctionEnd\n"
1699
1700                 "; Fragment Entry\n"
1701                 "%frag_main = OpFunction %void None %fun\n"
1702                 "%frag_label_main = OpLabel\n"
1703                 "%frag_tmp1 = OpLoad %v4f32 %frag_vtxColor\n"
1704                 "OpStore %frag_fragColor %frag_tmp1\n"
1705                 "OpReturn\n"
1706                 "OpFunctionEnd\n";
1707 }
1708
1709 void createMultipleEntries(vk::SourceCollections& dst, InstanceContext)
1710 {
1711         dst.spirvAsmSources.add("vert") <<
1712         // This module contains 2 vertex shaders. One that is a passthrough
1713         // and a second that inverts the color of the output (1.0 - color).
1714                 "OpCapability Shader\n"
1715                 "OpMemoryModel Logical GLSL450\n"
1716                 "OpEntryPoint Vertex %main \"vert1\" %Position %vtxColor %color %vtxPosition %vertex_id %instance_id\n"
1717                 "OpEntryPoint Vertex %main2 \"vert2\" %Position %vtxColor %color %vtxPosition %vertex_id %instance_id\n"
1718
1719                 "OpName %main \"vert1\"\n"
1720                 "OpName %main2 \"vert2\"\n"
1721                 "OpName %vtxPosition \"vtxPosition\"\n"
1722                 "OpName %Position \"position\"\n"
1723                 "OpName %vtxColor \"vtxColor\"\n"
1724                 "OpName %color \"color\"\n"
1725                 "OpName %vertex_id \"gl_VertexIndex\"\n"
1726                 "OpName %instance_id \"gl_InstanceIndex\"\n"
1727
1728                 "OpDecorate %vtxPosition Location 2\n"
1729                 "OpDecorate %Position Location 0\n"
1730                 "OpDecorate %vtxColor Location 1\n"
1731                 "OpDecorate %color Location 1\n"
1732                 "OpDecorate %vertex_id BuiltIn VertexIndex\n"
1733                 "OpDecorate %instance_id BuiltIn InstanceIndex\n"
1734                 SPIRV_ASSEMBLY_TYPES
1735                 SPIRV_ASSEMBLY_CONSTANTS
1736                 SPIRV_ASSEMBLY_ARRAYS
1737                 "%cval = OpConstantComposite %v4f32 %c_f32_1 %c_f32_1 %c_f32_1 %c_f32_0\n"
1738                 "%vtxPosition = OpVariable %op_v4f32 Output\n"
1739                 "%Position = OpVariable %ip_v4f32 Input\n"
1740                 "%vtxColor = OpVariable %op_v4f32 Output\n"
1741                 "%color = OpVariable %ip_v4f32 Input\n"
1742                 "%vertex_id = OpVariable %ip_i32 Input\n"
1743                 "%instance_id = OpVariable %ip_i32 Input\n"
1744
1745                 "%main = OpFunction %void None %fun\n"
1746                 "%label = OpLabel\n"
1747                 "%tmp_position = OpLoad %v4f32 %Position\n"
1748                 "OpStore %vtxPosition %tmp_position\n"
1749                 "%tmp_color = OpLoad %v4f32 %color\n"
1750                 "OpStore %vtxColor %tmp_color\n"
1751                 "OpReturn\n"
1752                 "OpFunctionEnd\n"
1753
1754                 "%main2 = OpFunction %void None %fun\n"
1755                 "%label2 = OpLabel\n"
1756                 "%tmp_position2 = OpLoad %v4f32 %Position\n"
1757                 "OpStore %vtxPosition %tmp_position2\n"
1758                 "%tmp_color2 = OpLoad %v4f32 %color\n"
1759                 "%tmp_color3 = OpFSub %v4f32 %cval %tmp_color2\n"
1760                 "%tmp_color4 = OpVectorInsertDynamic %v4f32 %tmp_color3 %c_f32_1 %c_i32_3\n"
1761                 "OpStore %vtxColor %tmp_color4\n"
1762                 "OpReturn\n"
1763                 "OpFunctionEnd\n";
1764
1765         dst.spirvAsmSources.add("frag") <<
1766                 // This is a single module that contains 2 fragment shaders.
1767                 // One that passes color through and the other that inverts the output
1768                 // color (1.0 - color).
1769                 "OpCapability Shader\n"
1770                 "OpMemoryModel Logical GLSL450\n"
1771                 "OpEntryPoint Fragment %main \"frag1\" %vtxColor %fragColor\n"
1772                 "OpEntryPoint Fragment %main2 \"frag2\" %vtxColor %fragColor\n"
1773                 "OpExecutionMode %main OriginUpperLeft\n"
1774                 "OpExecutionMode %main2 OriginUpperLeft\n"
1775
1776                 "OpName %main \"frag1\"\n"
1777                 "OpName %main2 \"frag2\"\n"
1778                 "OpName %fragColor \"fragColor\"\n"
1779                 "OpName %vtxColor \"vtxColor\"\n"
1780                 "OpDecorate %fragColor Location 0\n"
1781                 "OpDecorate %vtxColor Location 1\n"
1782                 SPIRV_ASSEMBLY_TYPES
1783                 SPIRV_ASSEMBLY_CONSTANTS
1784                 SPIRV_ASSEMBLY_ARRAYS
1785                 "%cval = OpConstantComposite %v4f32 %c_f32_1 %c_f32_1 %c_f32_1 %c_f32_0\n"
1786                 "%fragColor = OpVariable %op_v4f32 Output\n"
1787                 "%vtxColor = OpVariable %ip_v4f32 Input\n"
1788
1789                 "%main = OpFunction %void None %fun\n"
1790                 "%label_main = OpLabel\n"
1791                 "%tmp1 = OpLoad %v4f32 %vtxColor\n"
1792                 "OpStore %fragColor %tmp1\n"
1793                 "OpReturn\n"
1794                 "OpFunctionEnd\n"
1795
1796                 "%main2 = OpFunction %void None %fun\n"
1797                 "%label_main2 = OpLabel\n"
1798                 "%tmp2 = OpLoad %v4f32 %vtxColor\n"
1799                 "%tmp3 = OpFSub %v4f32 %cval %tmp2\n"
1800                 "%tmp4 = OpVectorInsertDynamic %v4f32 %tmp3 %c_f32_1 %c_i32_3\n"
1801                 "OpStore %fragColor %tmp4\n"
1802                 "OpReturn\n"
1803                 "OpFunctionEnd\n";
1804
1805         dst.spirvAsmSources.add("geom") <<
1806                 "OpCapability Geometry\n"
1807                 "OpCapability ClipDistance\n"
1808                 "OpCapability CullDistance\n"
1809                 "OpMemoryModel Logical GLSL450\n"
1810                 "OpEntryPoint Geometry %geom1_main \"geom1\" %out_gl_position %gl_in %out_color %in_color\n"
1811                 "OpEntryPoint Geometry %geom2_main \"geom2\" %out_gl_position %gl_in %out_color %in_color\n"
1812                 "OpExecutionMode %geom1_main Triangles\n"
1813                 "OpExecutionMode %geom2_main Triangles\n"
1814                 "OpExecutionMode %geom1_main OutputTriangleStrip\n"
1815                 "OpExecutionMode %geom2_main OutputTriangleStrip\n"
1816                 "OpExecutionMode %geom1_main OutputVertices 3\n"
1817                 "OpExecutionMode %geom2_main OutputVertices 3\n"
1818                 "OpName %geom1_main \"geom1\"\n"
1819                 "OpName %geom2_main \"geom2\"\n"
1820                 "OpName %per_vertex_in \"gl_PerVertex\"\n"
1821                 "OpMemberName %per_vertex_in 0 \"gl_Position\"\n"
1822                 "OpMemberName %per_vertex_in 1 \"gl_PointSize\"\n"
1823                 "OpMemberName %per_vertex_in 2 \"gl_ClipDistance\"\n"
1824                 "OpMemberName %per_vertex_in 3 \"gl_CullDistance\"\n"
1825                 "OpName %gl_in \"gl_in\"\n"
1826                 "OpName %out_color \"out_color\"\n"
1827                 "OpName %in_color \"in_color\"\n"
1828                 "OpDecorate %out_gl_position BuiltIn Position\n"
1829                 "OpMemberDecorate %per_vertex_in 0 BuiltIn Position\n"
1830                 "OpMemberDecorate %per_vertex_in 1 BuiltIn PointSize\n"
1831                 "OpMemberDecorate %per_vertex_in 2 BuiltIn ClipDistance\n"
1832                 "OpMemberDecorate %per_vertex_in 3 BuiltIn CullDistance\n"
1833                 "OpDecorate %per_vertex_in Block\n"
1834                 "OpDecorate %out_color Location 1\n"
1835                 "OpDecorate %in_color Location 1\n"
1836                 SPIRV_ASSEMBLY_TYPES
1837                 SPIRV_ASSEMBLY_CONSTANTS
1838                 SPIRV_ASSEMBLY_ARRAYS
1839                 "%cval = OpConstantComposite %v4f32 %c_f32_1 %c_f32_1 %c_f32_1 %c_f32_0\n"
1840                 "%per_vertex_in = OpTypeStruct %v4f32 %f32 %a1f32 %a1f32\n"
1841                 "%a3_per_vertex_in = OpTypeArray %per_vertex_in %c_u32_3\n"
1842                 "%ip_a3_per_vertex_in = OpTypePointer Input %a3_per_vertex_in\n"
1843                 "%gl_in = OpVariable %ip_a3_per_vertex_in Input\n"
1844                 "%out_color = OpVariable %op_v4f32 Output\n"
1845                 "%in_color = OpVariable %ip_a3v4f32 Input\n"
1846                 "%out_gl_position = OpVariable %op_v4f32 Output\n"
1847
1848                 "%geom1_main = OpFunction %void None %fun\n"
1849                 "%geom1_label = OpLabel\n"
1850                 "%geom1_gl_in_0_gl_position = OpAccessChain %ip_v4f32 %gl_in %c_i32_0 %c_i32_0\n"
1851                 "%geom1_gl_in_1_gl_position = OpAccessChain %ip_v4f32 %gl_in %c_i32_1 %c_i32_0\n"
1852                 "%geom1_gl_in_2_gl_position = OpAccessChain %ip_v4f32 %gl_in %c_i32_2 %c_i32_0\n"
1853                 "%geom1_in_position_0 = OpLoad %v4f32 %geom1_gl_in_0_gl_position\n"
1854                 "%geom1_in_position_1 = OpLoad %v4f32 %geom1_gl_in_1_gl_position\n"
1855                 "%geom1_in_position_2 = OpLoad %v4f32 %geom1_gl_in_2_gl_position \n"
1856                 "%geom1_in_color_0_ptr = OpAccessChain %ip_v4f32 %in_color %c_i32_0\n"
1857                 "%geom1_in_color_1_ptr = OpAccessChain %ip_v4f32 %in_color %c_i32_1\n"
1858                 "%geom1_in_color_2_ptr = OpAccessChain %ip_v4f32 %in_color %c_i32_2\n"
1859                 "%geom1_in_color_0 = OpLoad %v4f32 %geom1_in_color_0_ptr\n"
1860                 "%geom1_in_color_1 = OpLoad %v4f32 %geom1_in_color_1_ptr\n"
1861                 "%geom1_in_color_2 = OpLoad %v4f32 %geom1_in_color_2_ptr\n"
1862                 "OpStore %out_gl_position %geom1_in_position_0\n"
1863                 "OpStore %out_color %geom1_in_color_0\n"
1864                 "OpEmitVertex\n"
1865                 "OpStore %out_gl_position %geom1_in_position_1\n"
1866                 "OpStore %out_color %geom1_in_color_1\n"
1867                 "OpEmitVertex\n"
1868                 "OpStore %out_gl_position %geom1_in_position_2\n"
1869                 "OpStore %out_color %geom1_in_color_2\n"
1870                 "OpEmitVertex\n"
1871                 "OpEndPrimitive\n"
1872                 "OpReturn\n"
1873                 "OpFunctionEnd\n"
1874
1875                 "%geom2_main = OpFunction %void None %fun\n"
1876                 "%geom2_label = OpLabel\n"
1877                 "%geom2_gl_in_0_gl_position = OpAccessChain %ip_v4f32 %gl_in %c_i32_0 %c_i32_0\n"
1878                 "%geom2_gl_in_1_gl_position = OpAccessChain %ip_v4f32 %gl_in %c_i32_1 %c_i32_0\n"
1879                 "%geom2_gl_in_2_gl_position = OpAccessChain %ip_v4f32 %gl_in %c_i32_2 %c_i32_0\n"
1880                 "%geom2_in_position_0 = OpLoad %v4f32 %geom2_gl_in_0_gl_position\n"
1881                 "%geom2_in_position_1 = OpLoad %v4f32 %geom2_gl_in_1_gl_position\n"
1882                 "%geom2_in_position_2 = OpLoad %v4f32 %geom2_gl_in_2_gl_position \n"
1883                 "%geom2_in_color_0_ptr = OpAccessChain %ip_v4f32 %in_color %c_i32_0\n"
1884                 "%geom2_in_color_1_ptr = OpAccessChain %ip_v4f32 %in_color %c_i32_1\n"
1885                 "%geom2_in_color_2_ptr = OpAccessChain %ip_v4f32 %in_color %c_i32_2\n"
1886                 "%geom2_in_color_0 = OpLoad %v4f32 %geom2_in_color_0_ptr\n"
1887                 "%geom2_in_color_1 = OpLoad %v4f32 %geom2_in_color_1_ptr\n"
1888                 "%geom2_in_color_2 = OpLoad %v4f32 %geom2_in_color_2_ptr\n"
1889                 "%geom2_transformed_in_color_0 = OpFSub %v4f32 %cval %geom2_in_color_0\n"
1890                 "%geom2_transformed_in_color_1 = OpFSub %v4f32 %cval %geom2_in_color_1\n"
1891                 "%geom2_transformed_in_color_2 = OpFSub %v4f32 %cval %geom2_in_color_2\n"
1892                 "%geom2_transformed_in_color_0_a = OpVectorInsertDynamic %v4f32 %geom2_transformed_in_color_0 %c_f32_1 %c_i32_3\n"
1893                 "%geom2_transformed_in_color_1_a = OpVectorInsertDynamic %v4f32 %geom2_transformed_in_color_1 %c_f32_1 %c_i32_3\n"
1894                 "%geom2_transformed_in_color_2_a = OpVectorInsertDynamic %v4f32 %geom2_transformed_in_color_2 %c_f32_1 %c_i32_3\n"
1895                 "OpStore %out_gl_position %geom2_in_position_0\n"
1896                 "OpStore %out_color %geom2_transformed_in_color_0_a\n"
1897                 "OpEmitVertex\n"
1898                 "OpStore %out_gl_position %geom2_in_position_1\n"
1899                 "OpStore %out_color %geom2_transformed_in_color_1_a\n"
1900                 "OpEmitVertex\n"
1901                 "OpStore %out_gl_position %geom2_in_position_2\n"
1902                 "OpStore %out_color %geom2_transformed_in_color_2_a\n"
1903                 "OpEmitVertex\n"
1904                 "OpEndPrimitive\n"
1905                 "OpReturn\n"
1906                 "OpFunctionEnd\n";
1907
1908         dst.spirvAsmSources.add("tessc") <<
1909                 "OpCapability Tessellation\n"
1910                 "OpMemoryModel Logical GLSL450\n"
1911                 "OpEntryPoint TessellationControl %tessc1_main \"tessc1\" %out_color %gl_InvocationID %in_color %out_position %in_position %gl_TessLevelOuter %gl_TessLevelInner\n"
1912                 "OpEntryPoint TessellationControl %tessc2_main \"tessc2\" %out_color %gl_InvocationID %in_color %out_position %in_position %gl_TessLevelOuter %gl_TessLevelInner\n"
1913                 "OpExecutionMode %tessc1_main OutputVertices 3\n"
1914                 "OpExecutionMode %tessc2_main OutputVertices 3\n"
1915                 "OpName %tessc1_main \"tessc1\"\n"
1916                 "OpName %tessc2_main \"tessc2\"\n"
1917                 "OpName %out_color \"out_color\"\n"
1918                 "OpName %gl_InvocationID \"gl_InvocationID\"\n"
1919                 "OpName %in_color \"in_color\"\n"
1920                 "OpName %out_position \"out_position\"\n"
1921                 "OpName %in_position \"in_position\"\n"
1922                 "OpName %gl_TessLevelOuter \"gl_TessLevelOuter\"\n"
1923                 "OpName %gl_TessLevelInner \"gl_TessLevelInner\"\n"
1924                 "OpDecorate %out_color Location 1\n"
1925                 "OpDecorate %gl_InvocationID BuiltIn InvocationId\n"
1926                 "OpDecorate %in_color Location 1\n"
1927                 "OpDecorate %out_position Location 2\n"
1928                 "OpDecorate %in_position Location 2\n"
1929                 "OpDecorate %gl_TessLevelOuter Patch\n"
1930                 "OpDecorate %gl_TessLevelOuter BuiltIn TessLevelOuter\n"
1931                 "OpDecorate %gl_TessLevelInner Patch\n"
1932                 "OpDecorate %gl_TessLevelInner BuiltIn TessLevelInner\n"
1933                 SPIRV_ASSEMBLY_TYPES
1934                 SPIRV_ASSEMBLY_CONSTANTS
1935                 SPIRV_ASSEMBLY_ARRAYS
1936                 "%cval = OpConstantComposite %v4f32 %c_f32_1 %c_f32_1 %c_f32_1 %c_f32_0\n"
1937                 "%out_color = OpVariable %op_a3v4f32 Output\n"
1938                 "%gl_InvocationID = OpVariable %ip_i32 Input\n"
1939                 "%in_color = OpVariable %ip_a32v4f32 Input\n"
1940                 "%out_position = OpVariable %op_a3v4f32 Output\n"
1941                 "%in_position = OpVariable %ip_a32v4f32 Input\n"
1942                 "%gl_TessLevelOuter = OpVariable %op_a4f32 Output\n"
1943                 "%gl_TessLevelInner = OpVariable %op_a2f32 Output\n"
1944
1945                 "%tessc1_main = OpFunction %void None %fun\n"
1946                 "%tessc1_label = OpLabel\n"
1947                 "%tessc1_invocation_id = OpLoad %i32 %gl_InvocationID\n"
1948                 "%tessc1_in_color_ptr = OpAccessChain %ip_v4f32 %in_color %tessc1_invocation_id\n"
1949                 "%tessc1_in_position_ptr = OpAccessChain %ip_v4f32 %in_position %tessc1_invocation_id\n"
1950                 "%tessc1_in_color_val = OpLoad %v4f32 %tessc1_in_color_ptr\n"
1951                 "%tessc1_in_position_val = OpLoad %v4f32 %tessc1_in_position_ptr\n"
1952                 "%tessc1_out_color_ptr = OpAccessChain %op_v4f32 %out_color %tessc1_invocation_id\n"
1953                 "%tessc1_out_position_ptr = OpAccessChain %op_v4f32 %out_position %tessc1_invocation_id\n"
1954                 "OpStore %tessc1_out_color_ptr %tessc1_in_color_val\n"
1955                 "OpStore %tessc1_out_position_ptr %tessc1_in_position_val\n"
1956                 "%tessc1_is_first_invocation = OpIEqual %bool %tessc1_invocation_id %c_i32_0\n"
1957                 "OpSelectionMerge %tessc1_merge_label None\n"
1958                 "OpBranchConditional %tessc1_is_first_invocation %tessc1_first_invocation %tessc1_merge_label\n"
1959                 "%tessc1_first_invocation = OpLabel\n"
1960                 "%tessc1_tess_outer_0 = OpAccessChain %op_f32 %gl_TessLevelOuter %c_i32_0\n"
1961                 "%tessc1_tess_outer_1 = OpAccessChain %op_f32 %gl_TessLevelOuter %c_i32_1\n"
1962                 "%tessc1_tess_outer_2 = OpAccessChain %op_f32 %gl_TessLevelOuter %c_i32_2\n"
1963                 "%tessc1_tess_inner = OpAccessChain %op_f32 %gl_TessLevelInner %c_i32_0\n"
1964                 "OpStore %tessc1_tess_outer_0 %c_f32_1\n"
1965                 "OpStore %tessc1_tess_outer_1 %c_f32_1\n"
1966                 "OpStore %tessc1_tess_outer_2 %c_f32_1\n"
1967                 "OpStore %tessc1_tess_inner %c_f32_1\n"
1968                 "OpBranch %tessc1_merge_label\n"
1969                 "%tessc1_merge_label = OpLabel\n"
1970                 "OpReturn\n"
1971                 "OpFunctionEnd\n"
1972
1973                 "%tessc2_main = OpFunction %void None %fun\n"
1974                 "%tessc2_label = OpLabel\n"
1975                 "%tessc2_invocation_id = OpLoad %i32 %gl_InvocationID\n"
1976                 "%tessc2_in_color_ptr = OpAccessChain %ip_v4f32 %in_color %tessc2_invocation_id\n"
1977                 "%tessc2_in_position_ptr = OpAccessChain %ip_v4f32 %in_position %tessc2_invocation_id\n"
1978                 "%tessc2_in_color_val = OpLoad %v4f32 %tessc2_in_color_ptr\n"
1979                 "%tessc2_in_position_val = OpLoad %v4f32 %tessc2_in_position_ptr\n"
1980                 "%tessc2_out_color_ptr = OpAccessChain %op_v4f32 %out_color %tessc2_invocation_id\n"
1981                 "%tessc2_out_position_ptr = OpAccessChain %op_v4f32 %out_position %tessc2_invocation_id\n"
1982                 "%tessc2_transformed_color = OpFSub %v4f32 %cval %tessc2_in_color_val\n"
1983                 "%tessc2_transformed_color_a = OpVectorInsertDynamic %v4f32 %tessc2_transformed_color %c_f32_1 %c_i32_3\n"
1984                 "OpStore %tessc2_out_color_ptr %tessc2_transformed_color_a\n"
1985                 "OpStore %tessc2_out_position_ptr %tessc2_in_position_val\n"
1986                 "%tessc2_is_first_invocation = OpIEqual %bool %tessc2_invocation_id %c_i32_0\n"
1987                 "OpSelectionMerge %tessc2_merge_label None\n"
1988                 "OpBranchConditional %tessc2_is_first_invocation %tessc2_first_invocation %tessc2_merge_label\n"
1989                 "%tessc2_first_invocation = OpLabel\n"
1990                 "%tessc2_tess_outer_0 = OpAccessChain %op_f32 %gl_TessLevelOuter %c_i32_0\n"
1991                 "%tessc2_tess_outer_1 = OpAccessChain %op_f32 %gl_TessLevelOuter %c_i32_1\n"
1992                 "%tessc2_tess_outer_2 = OpAccessChain %op_f32 %gl_TessLevelOuter %c_i32_2\n"
1993                 "%tessc2_tess_inner = OpAccessChain %op_f32 %gl_TessLevelInner %c_i32_0\n"
1994                 "OpStore %tessc2_tess_outer_0 %c_f32_1\n"
1995                 "OpStore %tessc2_tess_outer_1 %c_f32_1\n"
1996                 "OpStore %tessc2_tess_outer_2 %c_f32_1\n"
1997                 "OpStore %tessc2_tess_inner %c_f32_1\n"
1998                 "OpBranch %tessc2_merge_label\n"
1999                 "%tessc2_merge_label = OpLabel\n"
2000                 "OpReturn\n"
2001                 "OpFunctionEnd\n";
2002
2003         dst.spirvAsmSources.add("tesse") <<
2004                 "OpCapability Tessellation\n"
2005                 "OpCapability ClipDistance\n"
2006                 "OpCapability CullDistance\n"
2007                 "OpMemoryModel Logical GLSL450\n"
2008                 "OpEntryPoint TessellationEvaluation %tesse1_main \"tesse1\" %stream %gl_tessCoord %in_position %out_color %in_color \n"
2009                 "OpEntryPoint TessellationEvaluation %tesse2_main \"tesse2\" %stream %gl_tessCoord %in_position %out_color %in_color \n"
2010                 "OpExecutionMode %tesse1_main Triangles\n"
2011                 "OpExecutionMode %tesse1_main SpacingEqual\n"
2012                 "OpExecutionMode %tesse1_main VertexOrderCcw\n"
2013                 "OpExecutionMode %tesse2_main Triangles\n"
2014                 "OpExecutionMode %tesse2_main SpacingEqual\n"
2015                 "OpExecutionMode %tesse2_main VertexOrderCcw\n"
2016                 "OpName %tesse1_main \"tesse1\"\n"
2017                 "OpName %tesse2_main \"tesse2\"\n"
2018                 "OpName %per_vertex_out \"gl_PerVertex\"\n"
2019                 "OpMemberName %per_vertex_out 0 \"gl_Position\"\n"
2020                 "OpMemberName %per_vertex_out 1 \"gl_PointSize\"\n"
2021                 "OpMemberName %per_vertex_out 2 \"gl_ClipDistance\"\n"
2022                 "OpMemberName %per_vertex_out 3 \"gl_CullDistance\"\n"
2023                 "OpName %stream \"\"\n"
2024                 "OpName %gl_tessCoord \"gl_TessCoord\"\n"
2025                 "OpName %in_position \"in_position\"\n"
2026                 "OpName %out_color \"out_color\"\n"
2027                 "OpName %in_color \"in_color\"\n"
2028                 "OpMemberDecorate %per_vertex_out 0 BuiltIn Position\n"
2029                 "OpMemberDecorate %per_vertex_out 1 BuiltIn PointSize\n"
2030                 "OpMemberDecorate %per_vertex_out 2 BuiltIn ClipDistance\n"
2031                 "OpMemberDecorate %per_vertex_out 3 BuiltIn CullDistance\n"
2032                 "OpDecorate %per_vertex_out Block\n"
2033                 "OpDecorate %gl_tessCoord BuiltIn TessCoord\n"
2034                 "OpDecorate %in_position Location 2\n"
2035                 "OpDecorate %out_color Location 1\n"
2036                 "OpDecorate %in_color Location 1\n"
2037                 SPIRV_ASSEMBLY_TYPES
2038                 SPIRV_ASSEMBLY_CONSTANTS
2039                 SPIRV_ASSEMBLY_ARRAYS
2040                 "%cval = OpConstantComposite %v4f32 %c_f32_1 %c_f32_1 %c_f32_1 %c_f32_0\n"
2041                 "%per_vertex_out = OpTypeStruct %v4f32 %f32 %a1f32 %a1f32\n"
2042                 "%op_per_vertex_out = OpTypePointer Output %per_vertex_out\n"
2043                 "%stream = OpVariable %op_per_vertex_out Output\n"
2044                 "%gl_tessCoord = OpVariable %ip_v3f32 Input\n"
2045                 "%in_position = OpVariable %ip_a32v4f32 Input\n"
2046                 "%out_color = OpVariable %op_v4f32 Output\n"
2047                 "%in_color = OpVariable %ip_a32v4f32 Input\n"
2048
2049                 "%tesse1_main = OpFunction %void None %fun\n"
2050                 "%tesse1_label = OpLabel\n"
2051                 "%tesse1_tc_0_ptr = OpAccessChain %ip_f32 %gl_tessCoord %c_u32_0\n"
2052                 "%tesse1_tc_1_ptr = OpAccessChain %ip_f32 %gl_tessCoord %c_u32_1\n"
2053                 "%tesse1_tc_2_ptr = OpAccessChain %ip_f32 %gl_tessCoord %c_u32_2\n"
2054                 "%tesse1_tc_0 = OpLoad %f32 %tesse1_tc_0_ptr\n"
2055                 "%tesse1_tc_1 = OpLoad %f32 %tesse1_tc_1_ptr\n"
2056                 "%tesse1_tc_2 = OpLoad %f32 %tesse1_tc_2_ptr\n"
2057                 "%tesse1_in_pos_0_ptr = OpAccessChain %ip_v4f32 %in_position %c_i32_0\n"
2058                 "%tesse1_in_pos_1_ptr = OpAccessChain %ip_v4f32 %in_position %c_i32_1\n"
2059                 "%tesse1_in_pos_2_ptr = OpAccessChain %ip_v4f32 %in_position %c_i32_2\n"
2060                 "%tesse1_in_pos_0 = OpLoad %v4f32 %tesse1_in_pos_0_ptr\n"
2061                 "%tesse1_in_pos_1 = OpLoad %v4f32 %tesse1_in_pos_1_ptr\n"
2062                 "%tesse1_in_pos_2 = OpLoad %v4f32 %tesse1_in_pos_2_ptr\n"
2063                 "%tesse1_in_pos_0_weighted = OpVectorTimesScalar %v4f32 %tesse1_in_pos_0 %tesse1_tc_0\n"
2064                 "%tesse1_in_pos_1_weighted = OpVectorTimesScalar %v4f32 %tesse1_in_pos_1 %tesse1_tc_1\n"
2065                 "%tesse1_in_pos_2_weighted = OpVectorTimesScalar %v4f32 %tesse1_in_pos_2 %tesse1_tc_2\n"
2066                 "%tesse1_out_pos_ptr = OpAccessChain %op_v4f32 %stream %c_i32_0\n"
2067                 "%tesse1_in_pos_0_plus_pos_1 = OpFAdd %v4f32 %tesse1_in_pos_0_weighted %tesse1_in_pos_1_weighted\n"
2068                 "%tesse1_computed_out = OpFAdd %v4f32 %tesse1_in_pos_0_plus_pos_1 %tesse1_in_pos_2_weighted\n"
2069                 "OpStore %tesse1_out_pos_ptr %tesse1_computed_out\n"
2070                 "%tesse1_in_clr_0_ptr = OpAccessChain %ip_v4f32 %in_color %c_i32_0\n"
2071                 "%tesse1_in_clr_1_ptr = OpAccessChain %ip_v4f32 %in_color %c_i32_1\n"
2072                 "%tesse1_in_clr_2_ptr = OpAccessChain %ip_v4f32 %in_color %c_i32_2\n"
2073                 "%tesse1_in_clr_0 = OpLoad %v4f32 %tesse1_in_clr_0_ptr\n"
2074                 "%tesse1_in_clr_1 = OpLoad %v4f32 %tesse1_in_clr_1_ptr\n"
2075                 "%tesse1_in_clr_2 = OpLoad %v4f32 %tesse1_in_clr_2_ptr\n"
2076                 "%tesse1_in_clr_0_weighted = OpVectorTimesScalar %v4f32 %tesse1_in_clr_0 %tesse1_tc_0\n"
2077                 "%tesse1_in_clr_1_weighted = OpVectorTimesScalar %v4f32 %tesse1_in_clr_1 %tesse1_tc_1\n"
2078                 "%tesse1_in_clr_2_weighted = OpVectorTimesScalar %v4f32 %tesse1_in_clr_2 %tesse1_tc_2\n"
2079                 "%tesse1_in_clr_0_plus_col_1 = OpFAdd %v4f32 %tesse1_in_clr_0_weighted %tesse1_in_clr_1_weighted\n"
2080                 "%tesse1_computed_clr = OpFAdd %v4f32 %tesse1_in_clr_0_plus_col_1 %tesse1_in_clr_2_weighted\n"
2081                 "OpStore %out_color %tesse1_computed_clr\n"
2082                 "OpReturn\n"
2083                 "OpFunctionEnd\n"
2084
2085                 "%tesse2_main = OpFunction %void None %fun\n"
2086                 "%tesse2_label = OpLabel\n"
2087                 "%tesse2_tc_0_ptr = OpAccessChain %ip_f32 %gl_tessCoord %c_u32_0\n"
2088                 "%tesse2_tc_1_ptr = OpAccessChain %ip_f32 %gl_tessCoord %c_u32_1\n"
2089                 "%tesse2_tc_2_ptr = OpAccessChain %ip_f32 %gl_tessCoord %c_u32_2\n"
2090                 "%tesse2_tc_0 = OpLoad %f32 %tesse2_tc_0_ptr\n"
2091                 "%tesse2_tc_1 = OpLoad %f32 %tesse2_tc_1_ptr\n"
2092                 "%tesse2_tc_2 = OpLoad %f32 %tesse2_tc_2_ptr\n"
2093                 "%tesse2_in_pos_0_ptr = OpAccessChain %ip_v4f32 %in_position %c_i32_0\n"
2094                 "%tesse2_in_pos_1_ptr = OpAccessChain %ip_v4f32 %in_position %c_i32_1\n"
2095                 "%tesse2_in_pos_2_ptr = OpAccessChain %ip_v4f32 %in_position %c_i32_2\n"
2096                 "%tesse2_in_pos_0 = OpLoad %v4f32 %tesse2_in_pos_0_ptr\n"
2097                 "%tesse2_in_pos_1 = OpLoad %v4f32 %tesse2_in_pos_1_ptr\n"
2098                 "%tesse2_in_pos_2 = OpLoad %v4f32 %tesse2_in_pos_2_ptr\n"
2099                 "%tesse2_in_pos_0_weighted = OpVectorTimesScalar %v4f32 %tesse2_in_pos_0 %tesse2_tc_0\n"
2100                 "%tesse2_in_pos_1_weighted = OpVectorTimesScalar %v4f32 %tesse2_in_pos_1 %tesse2_tc_1\n"
2101                 "%tesse2_in_pos_2_weighted = OpVectorTimesScalar %v4f32 %tesse2_in_pos_2 %tesse2_tc_2\n"
2102                 "%tesse2_out_pos_ptr = OpAccessChain %op_v4f32 %stream %c_i32_0\n"
2103                 "%tesse2_in_pos_0_plus_pos_1 = OpFAdd %v4f32 %tesse2_in_pos_0_weighted %tesse2_in_pos_1_weighted\n"
2104                 "%tesse2_computed_out = OpFAdd %v4f32 %tesse2_in_pos_0_plus_pos_1 %tesse2_in_pos_2_weighted\n"
2105                 "OpStore %tesse2_out_pos_ptr %tesse2_computed_out\n"
2106                 "%tesse2_in_clr_0_ptr = OpAccessChain %ip_v4f32 %in_color %c_i32_0\n"
2107                 "%tesse2_in_clr_1_ptr = OpAccessChain %ip_v4f32 %in_color %c_i32_1\n"
2108                 "%tesse2_in_clr_2_ptr = OpAccessChain %ip_v4f32 %in_color %c_i32_2\n"
2109                 "%tesse2_in_clr_0 = OpLoad %v4f32 %tesse2_in_clr_0_ptr\n"
2110                 "%tesse2_in_clr_1 = OpLoad %v4f32 %tesse2_in_clr_1_ptr\n"
2111                 "%tesse2_in_clr_2 = OpLoad %v4f32 %tesse2_in_clr_2_ptr\n"
2112                 "%tesse2_in_clr_0_weighted = OpVectorTimesScalar %v4f32 %tesse2_in_clr_0 %tesse2_tc_0\n"
2113                 "%tesse2_in_clr_1_weighted = OpVectorTimesScalar %v4f32 %tesse2_in_clr_1 %tesse2_tc_1\n"
2114                 "%tesse2_in_clr_2_weighted = OpVectorTimesScalar %v4f32 %tesse2_in_clr_2 %tesse2_tc_2\n"
2115                 "%tesse2_in_clr_0_plus_col_1 = OpFAdd %v4f32 %tesse2_in_clr_0_weighted %tesse2_in_clr_1_weighted\n"
2116                 "%tesse2_computed_clr = OpFAdd %v4f32 %tesse2_in_clr_0_plus_col_1 %tesse2_in_clr_2_weighted\n"
2117                 "%tesse2_clr_transformed = OpFSub %v4f32 %cval %tesse2_computed_clr\n"
2118                 "%tesse2_clr_transformed_a = OpVectorInsertDynamic %v4f32 %tesse2_clr_transformed %c_f32_1 %c_i32_3\n"
2119                 "OpStore %out_color %tesse2_clr_transformed_a\n"
2120                 "OpReturn\n"
2121                 "OpFunctionEnd\n";
2122 }
2123
2124 bool compare16BitFloat (float original, deUint16 returned, RoundingModeFlags flags, tcu::TestLog& log)
2125 {
2126         // We only support RTE, RTZ, or both.
2127         DE_ASSERT(static_cast<int>(flags) > 0 && static_cast<int>(flags) < 4);
2128
2129         const Float32   originalFloat   (original);
2130         const Float16   returnedFloat   (returned);
2131
2132         // Zero are turned into zero under both RTE and RTZ.
2133         if (originalFloat.isZero())
2134         {
2135                 if (returnedFloat.isZero())
2136                         return true;
2137
2138                 log << TestLog::Message << "Error: expected zero but returned " << returned << TestLog::EndMessage;
2139                 return false;
2140         }
2141
2142         // Any denormalized value input into a shader may be flushed to 0.
2143         if (originalFloat.isDenorm() && returnedFloat.isZero())
2144                 return true;
2145
2146         // Inf are always turned into Inf with the same sign, too.
2147         if (originalFloat.isInf())
2148         {
2149                 if (returnedFloat.isInf() && originalFloat.signBit() == returnedFloat.signBit())
2150                         return true;
2151
2152                 log << TestLog::Message << "Error: expected Inf but returned " << returned << TestLog::EndMessage;
2153                 return false;
2154         }
2155
2156         // NaN are always turned into NaN, too.
2157         if (originalFloat.isNaN())
2158         {
2159                 if (returnedFloat.isNaN())
2160                         return true;
2161
2162                 log << TestLog::Message << "Error: expected NaN but returned " << returned << TestLog::EndMessage;
2163                 return false;
2164         }
2165
2166         // Check all rounding modes
2167         for (int bitNdx = 0; bitNdx < 2; ++bitNdx)
2168         {
2169                 if ((flags & (1u << bitNdx)) == 0)
2170                         continue;       // This rounding mode is not selected.
2171
2172                 const Float16   expectedFloat   (deFloat32To16Round(original, deRoundingMode(bitNdx)));
2173
2174                 // Any denormalized value potentially generated by any instruction in a shader may be flushed to 0.
2175                 if (expectedFloat.isDenorm() && returnedFloat.isZero())
2176                         return true;
2177
2178                 // If not matched in the above cases, they should have the same bit pattern.
2179                 if (expectedFloat.bits() == returnedFloat.bits())
2180                         return true;
2181         }
2182
2183         log << TestLog::Message << "Error: found unmatched 32-bit and 16-bit floats: " << originalFloat.bits() << " vs " << returned << TestLog::EndMessage;
2184         return false;
2185 }
2186
2187 bool compare32BitFloat (float expected, float returned, tcu::TestLog& log)
2188 {
2189         const Float32   expectedFloat   (expected);
2190         const Float32   returnedFloat   (returned);
2191
2192         // Any denormalized value potentially generated by any instruction in a shader may be flushed to 0.
2193         if (expectedFloat.isDenorm() && returnedFloat.isZero())
2194                 return true;
2195
2196         {
2197                 const Float16   originalFloat   (deFloat32To16(expected));
2198
2199                 // Any denormalized value input into a shader may be flushed to 0.
2200                 if (originalFloat.isDenorm() && returnedFloat.isZero())
2201                         return true;
2202         }
2203
2204         if (expectedFloat.isNaN())
2205         {
2206                 if (returnedFloat.isNaN())
2207                         return true;
2208
2209                 log << TestLog::Message << "Error: expected NaN but returned " << returned << TestLog::EndMessage;
2210                 return false;
2211         }
2212
2213         if (returned == expected)
2214                 return true;
2215
2216         log << TestLog::Message << "Error: found unmatched 32-bit float: expected " << expectedFloat.bits() << " vs. returned " << returnedFloat.bits() << TestLog::EndMessage;
2217         return false;
2218 }
2219
2220 Move<VkBuffer> createBufferForResource(const DeviceInterface& vk, const VkDevice vkDevice, const Resource& resource, deUint32 queueFamilyIndex)
2221 {
2222         vector<deUint8> resourceBytes;
2223         resource.second->getBytes(resourceBytes);
2224
2225         const VkBufferCreateInfo        resourceBufferParams    =
2226         {
2227                 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,                                                           // sType
2228                 DE_NULL,                                                                                                                        // pNext
2229                 (VkBufferCreateFlags)0,                                                                                         // flags
2230                 (VkDeviceSize)resourceBytes.size(),                                                                     // size
2231                 (VkBufferUsageFlags)getMatchingBufferUsageFlagBit(resource.first),      // usage
2232                 VK_SHARING_MODE_EXCLUSIVE,                                                                                      // sharingMode
2233                 1u,                                                                                                                                     // queueFamilyCount
2234                 &queueFamilyIndex,                                                                                                      // pQueueFamilyIndices
2235         };
2236
2237         return createBuffer(vk, vkDevice, &resourceBufferParams);
2238 }
2239
2240 TestStatus runAndVerifyDefaultPipeline (Context& context, InstanceContext instance)
2241 {
2242         if (getMinRequiredVulkanVersion(instance.resources.spirvVersion) > context.getUsedApiVersion())
2243         {
2244                 TCU_THROW(NotSupportedError, string("Vulkan higher than or equal to " + getVulkanName(getMinRequiredVulkanVersion(instance.resources.spirvVersion)) + " is required for this test to run").c_str());
2245         }
2246
2247         const InstanceInterface&                                        vkInstance                              = context.getInstanceInterface();
2248         const VkPhysicalDevice                                          vkPhysicalDevice                = context.getPhysicalDevice();
2249         const deUint32                                                          queueFamilyIndex                = context.getUniversalQueueFamilyIndex();
2250         // Create a dedicated logic device with required extensions enabled for this test case.
2251         const tcu::UVec2                                                        renderSize                              (256, 256);
2252         const int                                                                       testSpecificSeed                = 31354125;
2253         const int                                                                       seed                                    = context.getTestContext().getCommandLine().getBaseSeed() ^ testSpecificSeed;
2254         bool                                                                            supportsGeometry                = false;
2255         bool                                                                            supportsTessellation    = false;
2256         bool                                                                            hasTessellation         = false;
2257         const bool                                                                      hasPushConstants                = !instance.pushConstants.empty();
2258         const deUint32                                                          numResources                    = static_cast<deUint32>(instance.resources.inputs.size() + instance.resources.outputs.size());
2259         const bool                                                                      needInterface                   = !instance.interfaces.empty();
2260         const VkPhysicalDeviceFeatures&                         features                                = context.getDeviceFeatures();
2261
2262
2263         supportsGeometry                = features.geometryShader == VK_TRUE;
2264         supportsTessellation    = features.tessellationShader == VK_TRUE;
2265         hasTessellation                 = (instance.requiredStages & VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT) ||
2266                                                                 (instance.requiredStages & VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT);
2267
2268         if (hasTessellation && !supportsTessellation)
2269         {
2270                 TCU_THROW(NotSupportedError, "Tessellation not supported");
2271         }
2272
2273         if ((instance.requiredStages & VK_SHADER_STAGE_GEOMETRY_BIT) &&
2274                 !supportsGeometry)
2275         {
2276                 TCU_THROW(NotSupportedError, "Geometry not supported");
2277         }
2278
2279         {
2280                 for (deUint32 featureNdx = 0; featureNdx < instance.requiredDeviceFeatures.size(); ++featureNdx)
2281                 {
2282                         const string& feature = instance.requiredDeviceFeatures[featureNdx];
2283
2284                         if (feature == "shaderInt16")
2285                         {
2286                                 if (features.shaderInt16 != VK_TRUE)
2287                                         TCU_THROW(NotSupportedError, "Device feature not supported: shaderInt16");
2288                         }
2289                         else if (feature == "shaderInt64")
2290                         {
2291                                 if (features.shaderInt64 != VK_TRUE)
2292                                         TCU_THROW(NotSupportedError, "Device feature not supported: shaderInt64");
2293                         }
2294                         else
2295                         {
2296                                 TCU_THROW(InternalError, (std::string("Unimplemented physical device feature: ") + feature).c_str());
2297                         }
2298                 }
2299         }
2300
2301         // 16bit storage features
2302         {
2303                 if (!is16BitStorageFeaturesSupported(context.getUsedApiVersion(), vkInstance, vkPhysicalDevice, context.getInstanceExtensions(), instance.requestedFeatures.ext16BitStorage))
2304                         TCU_THROW(NotSupportedError, "Requested 16bit storage features not supported");
2305         }
2306
2307         // Variable Pointers features
2308         {
2309                 if (!isVariablePointersFeaturesSupported(context.getUsedApiVersion(), vkInstance, vkPhysicalDevice, context.getInstanceExtensions(), instance.requestedFeatures.extVariablePointers))
2310                         TCU_THROW(NotSupportedError, "Requested Variable Pointer features not supported");
2311
2312                 if (instance.requestedFeatures.extVariablePointers)
2313                 {
2314                         // The device doesn't have the vertexPipelineStoresAndAtomics feature, but the test requires the feature for
2315                         // vertex, tesselation, and geometry stages.
2316                         if (features.vertexPipelineStoresAndAtomics == DE_FALSE &&
2317                                 instance.requestedFeatures.coreFeatures.vertexPipelineStoresAndAtomics == DE_TRUE &&
2318                             (instance.customizedStages & vk::VK_SHADER_STAGE_VERTEX_BIT ||
2319                                  instance.customizedStages & vk::VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT ||
2320                                  instance.customizedStages & vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT ||
2321                                  instance.customizedStages & vk::VK_SHADER_STAGE_GEOMETRY_BIT))
2322                                 TCU_THROW(NotSupportedError, "This VK_KHR_variable_pointers extension test requires vertexPipelineStoresAndAtomics device feature.");
2323
2324                         // The device doesn't have the fragmentStoresAndAtomics feature, but the test requires this feature for the fragment stage.
2325                         if (features.fragmentStoresAndAtomics == DE_FALSE &&
2326                             instance.requestedFeatures.coreFeatures.fragmentStoresAndAtomics == DE_TRUE &&
2327                                 instance.customizedStages & vk::VK_SHADER_STAGE_FRAGMENT_BIT)
2328                                 TCU_THROW(NotSupportedError, "This VK_KHR_variable_pointers extension test requires fragmentStoresAndAtomics device feature.");
2329                 }
2330         }
2331
2332         // defer device and other resource creation until after feature checks
2333         const Unique<VkDevice>                                          vkDevice                                (createDeviceWithExtensions(context, queueFamilyIndex, context.getDeviceExtensions(), instance.requiredDeviceExtensions));
2334         const DeviceDriver                                                      vk                                              (vkInstance, *vkDevice);
2335         const VkQueue                                                           queue                                   = getDeviceQueue(vk, *vkDevice, queueFamilyIndex, 0);
2336         const de::UniquePtr<Allocator>                          allocatorUptr                   (createAllocator(vkInstance, vkPhysicalDevice, vk, *vkDevice));
2337         Allocator&                                                                      allocator                               = *allocatorUptr;
2338         vector<ModuleHandleSp>                                          modules;
2339         map<VkShaderStageFlagBits, VkShaderModule>      moduleByStage;
2340
2341
2342         de::Random(seed).shuffle(instance.inputColors, instance.inputColors+4);
2343         de::Random(seed).shuffle(instance.outputColors, instance.outputColors+4);
2344         const Vec4                                                              vertexData[]                    =
2345         {
2346                 // Upper left corner:
2347                 Vec4(-1.0f, -1.0f, 0.0f, 1.0f), instance.inputColors[0].toVec(),
2348                 Vec4(-0.5f, -1.0f, 0.0f, 1.0f), instance.inputColors[0].toVec(),
2349                 Vec4(-1.0f, -0.5f, 0.0f, 1.0f), instance.inputColors[0].toVec(),
2350
2351                 // Upper right corner:
2352                 Vec4(+0.5f, -1.0f, 0.0f, 1.0f), instance.inputColors[1].toVec(),
2353                 Vec4(+1.0f, -1.0f, 0.0f, 1.0f), instance.inputColors[1].toVec(),
2354                 Vec4(+1.0f, -0.5f, 0.0f, 1.0f), instance.inputColors[1].toVec(),
2355
2356                 // Lower left corner:
2357                 Vec4(-1.0f, +0.5f, 0.0f, 1.0f), instance.inputColors[2].toVec(),
2358                 Vec4(-0.5f, +1.0f, 0.0f, 1.0f), instance.inputColors[2].toVec(),
2359                 Vec4(-1.0f, +1.0f, 0.0f, 1.0f), instance.inputColors[2].toVec(),
2360
2361                 // Lower right corner:
2362                 Vec4(+1.0f, +0.5f, 0.0f, 1.0f), instance.inputColors[3].toVec(),
2363                 Vec4(+1.0f, +1.0f, 0.0f, 1.0f), instance.inputColors[3].toVec(),
2364                 Vec4(+0.5f, +1.0f, 0.0f, 1.0f), instance.inputColors[3].toVec()
2365         };
2366         const size_t                                                    singleVertexDataSize    = 2 * sizeof(Vec4);
2367         const size_t                                                    vertexCount                             = sizeof(vertexData) / singleVertexDataSize;
2368
2369         Move<VkBuffer>                                                  vertexInputBuffer               ;
2370         de::MovePtr<Allocation>                                 vertexInputMemory               ;
2371         Move<VkBuffer>                                                  fragOutputBuffer                ;
2372         de::MovePtr<Allocation>                                 fragOutputMemory                ;
2373         Move<VkImage>                                                   fragOutputImage                 ;
2374         de::MovePtr<Allocation>                                 fragOutputImageMemory   ;
2375         Move<VkImageView>                                               fragOutputImageView             ;
2376
2377         const VkBufferCreateInfo                                vertexBufferParams              =
2378         {
2379                 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,   //      VkStructureType         sType;
2380                 DE_NULL,                                                                //      const void*                     pNext;
2381                 0u,                                                                             //      VkBufferCreateFlags     flags;
2382                 (VkDeviceSize)sizeof(vertexData),               //      VkDeviceSize            size;
2383                 VK_BUFFER_USAGE_VERTEX_BUFFER_BIT,              //      VkBufferUsageFlags      usage;
2384                 VK_SHARING_MODE_EXCLUSIVE,                              //      VkSharingMode           sharingMode;
2385                 1u,                                                                             //      deUint32                        queueFamilyCount;
2386                 &queueFamilyIndex,                                              //      const deUint32*         pQueueFamilyIndices;
2387         };
2388         const Unique<VkBuffer>                                  vertexBuffer                    (createBuffer(vk, *vkDevice, &vertexBufferParams));
2389         const UniquePtr<Allocation>                             vertexBufferMemory              (allocator.allocate(getBufferMemoryRequirements(vk, *vkDevice, *vertexBuffer), MemoryRequirement::HostVisible));
2390
2391         VK_CHECK(vk.bindBufferMemory(*vkDevice, *vertexBuffer, vertexBufferMemory->getMemory(), vertexBufferMemory->getOffset()));
2392
2393         const VkDeviceSize                                              imageSizeBytes                  = (VkDeviceSize)(sizeof(deUint32)*renderSize.x()*renderSize.y());
2394         const VkBufferCreateInfo                                readImageBufferParams   =
2395         {
2396                 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,           //      VkStructureType         sType;
2397                 DE_NULL,                                                                        //      const void*                     pNext;
2398                 0u,                                                                                     //      VkBufferCreateFlags     flags;
2399                 imageSizeBytes,                                                         //      VkDeviceSize            size;
2400                 VK_BUFFER_USAGE_TRANSFER_DST_BIT,                       //      VkBufferUsageFlags      usage;
2401                 VK_SHARING_MODE_EXCLUSIVE,                                      //      VkSharingMode           sharingMode;
2402                 1u,                                                                                     //      deUint32                        queueFamilyCount;
2403                 &queueFamilyIndex,                                                      //      const deUint32*         pQueueFamilyIndices;
2404         };
2405         const Unique<VkBuffer>                                  readImageBuffer                 (createBuffer(vk, *vkDevice, &readImageBufferParams));
2406         const UniquePtr<Allocation>                             readImageBufferMemory   (allocator.allocate(getBufferMemoryRequirements(vk, *vkDevice, *readImageBuffer), MemoryRequirement::HostVisible));
2407
2408         VK_CHECK(vk.bindBufferMemory(*vkDevice, *readImageBuffer, readImageBufferMemory->getMemory(), readImageBufferMemory->getOffset()));
2409
2410         VkImageCreateInfo                                               imageParams                             =
2411         {
2412                 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,                                                                    //      VkStructureType         sType;
2413                 DE_NULL,                                                                                                                                //      const void*                     pNext;
2414                 0u,                                                                                                                                             //      VkImageCreateFlags      flags;
2415                 VK_IMAGE_TYPE_2D,                                                                                                               //      VkImageType                     imageType;
2416                 VK_FORMAT_R8G8B8A8_UNORM,                                                                                               //      VkFormat                        format;
2417                 { renderSize.x(), renderSize.y(), 1 },                                                                  //      VkExtent3D                      extent;
2418                 1u,                                                                                                                                             //      deUint32                        mipLevels;
2419                 1u,                                                                                                                                             //      deUint32                        arraySize;
2420                 VK_SAMPLE_COUNT_1_BIT,                                                                                                  //      deUint32                        samples;
2421                 VK_IMAGE_TILING_OPTIMAL,                                                                                                //      VkImageTiling           tiling;
2422                 VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT|VK_IMAGE_USAGE_TRANSFER_SRC_BIT,    //      VkImageUsageFlags       usage;
2423                 VK_SHARING_MODE_EXCLUSIVE,                                                                                              //      VkSharingMode           sharingMode;
2424                 1u,                                                                                                                                             //      deUint32                        queueFamilyCount;
2425                 &queueFamilyIndex,                                                                                                              //      const deUint32*         pQueueFamilyIndices;
2426                 VK_IMAGE_LAYOUT_UNDEFINED,                                                                                              //      VkImageLayout           initialLayout;
2427         };
2428
2429         const Unique<VkImage>                                   image                                   (createImage(vk, *vkDevice, &imageParams));
2430         const UniquePtr<Allocation>                             imageMemory                             (allocator.allocate(getImageMemoryRequirements(vk, *vkDevice, *image), MemoryRequirement::Any));
2431
2432         VK_CHECK(vk.bindImageMemory(*vkDevice, *image, imageMemory->getMemory(), imageMemory->getOffset()));
2433
2434         if (needInterface)
2435         {
2436                 // The pipeline renders four triangles, each with three vertexes.
2437                 // Test instantialization only provides four data points, each
2438                 // for one triangle. So we need allocate space of three times of
2439                 // input buffer's size.
2440                 vector<deUint8>                                                 inputBufferBytes;
2441                 instance.interfaces.getInputBuffer()->getBytes(inputBufferBytes);
2442
2443                 const deUint32                                                  inputNumBytes                   = deUint32(inputBufferBytes.size() * 3);
2444                 // Create an additional buffer and backing memory for one input variable.
2445                 const VkBufferCreateInfo                                vertexInputParams               =
2446                 {
2447                         VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,           //      VkStructureType         sType;
2448                         DE_NULL,                                                                        //      const void*                     pNext;
2449                         0u,                                                                                     //      VkBufferCreateFlags     flags;
2450                         inputNumBytes,                                                          //      VkDeviceSize            size;
2451                         VK_BUFFER_USAGE_VERTEX_BUFFER_BIT,                      //      VkBufferUsageFlags      usage;
2452                         VK_SHARING_MODE_EXCLUSIVE,                                      //      VkSharingMode           sharingMode;
2453                         1u,                                                                                     //      deUint32                        queueFamilyCount;
2454                         &queueFamilyIndex,                                                      //      const deUint32*         pQueueFamilyIndices;
2455                 };
2456
2457                 vertexInputBuffer = createBuffer(vk, *vkDevice, &vertexInputParams);
2458                 vertexInputMemory = allocator.allocate(getBufferMemoryRequirements(vk, *vkDevice, *vertexInputBuffer), MemoryRequirement::HostVisible);
2459                 VK_CHECK(vk.bindBufferMemory(*vkDevice, *vertexInputBuffer, vertexInputMemory->getMemory(), vertexInputMemory->getOffset()));
2460
2461                 // Create an additional buffer and backing memory for an output variable.
2462                 const VkDeviceSize                                              fragOutputImgSize               = (VkDeviceSize)(instance.interfaces.getOutputType().getNumBytes() * renderSize.x() * renderSize.y());
2463                 const VkBufferCreateInfo                                fragOutputParams                =
2464                 {
2465                         VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,           //      VkStructureType         sType;
2466                         DE_NULL,                                                                        //      const void*                     pNext;
2467                         0u,                                                                                     //      VkBufferCreateFlags     flags;
2468                         fragOutputImgSize,                                                      //      VkDeviceSize            size;
2469                         VK_BUFFER_USAGE_TRANSFER_DST_BIT,                       //      VkBufferUsageFlags      usage;
2470                         VK_SHARING_MODE_EXCLUSIVE,                                      //      VkSharingMode           sharingMode;
2471                         1u,                                                                                     //      deUint32                        queueFamilyCount;
2472                         &queueFamilyIndex,                                                      //      const deUint32*         pQueueFamilyIndices;
2473                 };
2474                 fragOutputBuffer = createBuffer(vk, *vkDevice, &fragOutputParams);
2475                 fragOutputMemory = allocator.allocate(getBufferMemoryRequirements(vk, *vkDevice, *fragOutputBuffer), MemoryRequirement::HostVisible);
2476                 VK_CHECK(vk.bindBufferMemory(*vkDevice, *fragOutputBuffer, fragOutputMemory->getMemory(), fragOutputMemory->getOffset()));
2477
2478                 // Create an additional image and backing memory for attachment.
2479                 // Reuse the previous imageParams since we only need to change the image format.
2480                 imageParams.format              = instance.interfaces.getOutputType().getVkFormat();
2481
2482                 // Check the usage bits on the given image format are supported.
2483                 requireFormatUsageSupport(vkInstance, vkPhysicalDevice, imageParams.format, imageParams.tiling, imageParams.usage);
2484
2485                 fragOutputImage                 = createImage(vk, *vkDevice, &imageParams);
2486                 fragOutputImageMemory   = allocator.allocate(getImageMemoryRequirements(vk, *vkDevice, *fragOutputImage), MemoryRequirement::Any);
2487
2488                 VK_CHECK(vk.bindImageMemory(*vkDevice, *fragOutputImage, fragOutputImageMemory->getMemory(), fragOutputImageMemory->getOffset()));
2489         }
2490
2491         vector<VkAttachmentDescription>                 colorAttDescs                   ;
2492         vector<VkAttachmentReference>                   colorAttRefs                    ;
2493         {
2494                 const VkAttachmentDescription           attDesc                                 =
2495                 {
2496                         0u,                                                                                             //      VkAttachmentDescriptionFlags    flags;
2497                         VK_FORMAT_R8G8B8A8_UNORM,                                               //      VkFormat                                                format;
2498                         VK_SAMPLE_COUNT_1_BIT,                                                  //      deUint32                                                samples;
2499                         VK_ATTACHMENT_LOAD_OP_CLEAR,                                    //      VkAttachmentLoadOp                              loadOp;
2500                         VK_ATTACHMENT_STORE_OP_STORE,                                   //      VkAttachmentStoreOp                             storeOp;
2501                         VK_ATTACHMENT_LOAD_OP_DONT_CARE,                                //      VkAttachmentLoadOp                              stencilLoadOp;
2502                         VK_ATTACHMENT_STORE_OP_DONT_CARE,                               //      VkAttachmentStoreOp                             stencilStoreOp;
2503                         VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,               //      VkImageLayout                                   initialLayout;
2504                         VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,               //      VkImageLayout                                   finalLayout;
2505                 };
2506                 colorAttDescs.push_back(attDesc);
2507
2508                 const VkAttachmentReference                     attRef                                  =
2509                 {
2510                         0u,                                                                                             //      deUint32                attachment;
2511                         VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,               //      VkImageLayout   layout;
2512                 };
2513                 colorAttRefs.push_back(attRef);
2514         }
2515
2516         if (needInterface)
2517         {
2518                 const VkAttachmentDescription           attDesc                                 =
2519                 {
2520                         0u,                                                                                                     //      VkAttachmentDescriptionFlags    flags;
2521                         instance.interfaces.getOutputType().getVkFormat(),      //      VkFormat                                                format;
2522                         VK_SAMPLE_COUNT_1_BIT,                                                          //      deUint32                                                samples;
2523                         VK_ATTACHMENT_LOAD_OP_CLEAR,                                            //      VkAttachmentLoadOp                              loadOp;
2524                         VK_ATTACHMENT_STORE_OP_STORE,                                           //      VkAttachmentStoreOp                             storeOp;
2525                         VK_ATTACHMENT_LOAD_OP_DONT_CARE,                                        //      VkAttachmentLoadOp                              stencilLoadOp;
2526                         VK_ATTACHMENT_STORE_OP_DONT_CARE,                                       //      VkAttachmentStoreOp                             stencilStoreOp;
2527                         VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,                       //      VkImageLayout                                   initialLayout;
2528                         VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,                       //      VkImageLayout                                   finalLayout;
2529                 };
2530                 colorAttDescs.push_back(attDesc);
2531
2532                 const VkAttachmentReference                     attRef                                  =
2533                 {
2534                         1u,                                                                                             //      deUint32                attachment;
2535                         VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,               //      VkImageLayout   layout;
2536                 };
2537                 colorAttRefs.push_back(attRef);
2538         }
2539
2540         VkSubpassDescription                                    subpassDesc                             =
2541         {
2542                 0u,                                                                                             //      VkSubpassDescriptionFlags               flags;
2543                 VK_PIPELINE_BIND_POINT_GRAPHICS,                                //      VkPipelineBindPoint                             pipelineBindPoint;
2544                 0u,                                                                                             //      deUint32                                                inputCount;
2545                 DE_NULL,                                                                                //      const VkAttachmentReference*    pInputAttachments;
2546                 1u,                                                                                             //      deUint32                                                colorCount;
2547                 colorAttRefs.data(),                                                    //      const VkAttachmentReference*    pColorAttachments;
2548                 DE_NULL,                                                                                //      const VkAttachmentReference*    pResolveAttachments;
2549                 DE_NULL,                                                                                //      const VkAttachmentReference*    pDepthStencilAttachment;
2550                 0u,                                                                                             //      deUint32                                                preserveCount;
2551                 DE_NULL,                                                                                //      const VkAttachmentReference*    pPreserveAttachments;
2552
2553         };
2554         VkRenderPassCreateInfo                                  renderPassParams                =
2555         {
2556                 VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,              //      VkStructureType                                 sType;
2557                 DE_NULL,                                                                                //      const void*                                             pNext;
2558                 (VkRenderPassCreateFlags)0,
2559                 1u,                                                                                             //      deUint32                                                attachmentCount;
2560                 colorAttDescs.data(),                                                   //      const VkAttachmentDescription*  pAttachments;
2561                 1u,                                                                                             //      deUint32                                                subpassCount;
2562                 &subpassDesc,                                                                   //      const VkSubpassDescription*             pSubpasses;
2563                 0u,                                                                                             //      deUint32                                                dependencyCount;
2564                 DE_NULL,                                                                                //      const VkSubpassDependency*              pDependencies;
2565         };
2566
2567         if (needInterface)
2568         {
2569                 subpassDesc.colorAttachmentCount += 1;
2570                 renderPassParams.attachmentCount += 1;
2571         }
2572
2573         const Unique<VkRenderPass>                              renderPass                              (createRenderPass(vk, *vkDevice, &renderPassParams));
2574
2575         const VkImageViewCreateInfo                             colorAttViewParams              =
2576         {
2577                 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,               //      VkStructureType                         sType;
2578                 DE_NULL,                                                                                //      const void*                                     pNext;
2579                 0u,                                                                                             //      VkImageViewCreateFlags          flags;
2580                 *image,                                                                                 //      VkImage                                         image;
2581                 VK_IMAGE_VIEW_TYPE_2D,                                                  //      VkImageViewType                         viewType;
2582                 VK_FORMAT_R8G8B8A8_UNORM,                                               //      VkFormat                                        format;
2583                 {
2584                         VK_COMPONENT_SWIZZLE_R,
2585                         VK_COMPONENT_SWIZZLE_G,
2586                         VK_COMPONENT_SWIZZLE_B,
2587                         VK_COMPONENT_SWIZZLE_A
2588                 },                                                                                              //      VkChannelMapping                        channels;
2589                 {
2590                         VK_IMAGE_ASPECT_COLOR_BIT,                                              //      VkImageAspectFlags      aspectMask;
2591                         0u,                                                                                             //      deUint32                        baseMipLevel;
2592                         1u,                                                                                             //      deUint32                        mipLevels;
2593                         0u,                                                                                             //      deUint32                        baseArrayLayer;
2594                         1u,                                                                                             //      deUint32                        arraySize;
2595                 },                                                                                              //      VkImageSubresourceRange         subresourceRange;
2596         };
2597         const Unique<VkImageView>                               colorAttView                    (createImageView(vk, *vkDevice, &colorAttViewParams));
2598
2599         vector<VkImageView>                                             attViews                                ;
2600         attViews.push_back(*colorAttView);
2601
2602         // Handle resources requested by the test instantiation.
2603         const deUint32                                                  numInResources                  = static_cast<deUint32>(instance.resources.inputs.size());
2604         const deUint32                                                  numOutResources                 = static_cast<deUint32>(instance.resources.outputs.size());
2605         // These variables should be placed out of the following if block to avoid deallocation after out of scope.
2606         vector<AllocationSp>                                    inResourceMemories              ;
2607         vector<AllocationSp>                                    outResourceMemories             ;
2608         vector<BufferHandleSp>                                  inResourceBuffers               ;
2609         vector<BufferHandleSp>                                  outResourceBuffers              ;
2610         Move<VkDescriptorPool>                                  descriptorPool                  ;
2611         Move<VkDescriptorSetLayout>                             setLayout                               ;
2612         VkDescriptorSetLayout                                   rawSetLayout                    = DE_NULL;
2613         VkDescriptorSet                                                 rawSet                                  = DE_NULL;
2614
2615         if (numResources != 0)
2616         {
2617                 vector<VkDescriptorSetLayoutBinding>    setLayoutBindings       ;
2618                 vector<VkDescriptorPoolSize>                    poolSizes                       ;
2619
2620                 setLayoutBindings.reserve(numResources);
2621                 poolSizes.reserve(numResources);
2622
2623                 // Process all input resources.
2624                 for (deUint32 inputNdx = 0; inputNdx < numInResources; ++inputNdx)
2625                 {
2626                         const Resource&                                 resource                                = instance.resources.inputs[inputNdx];
2627                         // Create buffer and allocate memory.
2628                         Move<VkBuffer>                                  resourceBuffer                  = createBufferForResource(vk, *vkDevice, resource, queueFamilyIndex);
2629                         de::MovePtr<Allocation>                 resourceMemory                  = allocator.allocate(getBufferMemoryRequirements(vk, *vkDevice, *resourceBuffer), MemoryRequirement::HostVisible);
2630                         vector<deUint8>                                 resourceBytes;
2631
2632                         VK_CHECK(vk.bindBufferMemory(*vkDevice, *resourceBuffer, resourceMemory->getMemory(), resourceMemory->getOffset()));
2633
2634                         // Copy data to memory.
2635                         const VkMappedMemoryRange               range                                   =
2636                         {
2637                                 VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE,                          //      VkStructureType sType;
2638                                 DE_NULL,                                                                                        //      const void*             pNext;
2639                                 resourceMemory->getMemory(),                                            //      VkDeviceMemory  mem;
2640                                 0,                                                                                                      //      VkDeviceSize    offset;
2641                                 VK_WHOLE_SIZE,                                                                          //      VkDeviceSize    size;
2642                         };
2643
2644                         resource.second->getBytes(resourceBytes);
2645                         deMemcpy(resourceMemory->getHostPtr(), &resourceBytes.front(), resourceBytes.size());
2646                         VK_CHECK(vk.flushMappedMemoryRanges(*vkDevice, 1u, &range));
2647
2648                         inResourceMemories.push_back(AllocationSp(resourceMemory.release()));
2649                         inResourceBuffers.push_back(BufferHandleSp(new BufferHandleUp(resourceBuffer)));
2650
2651                         // Prepare descriptor bindings and pool sizes for creating descriptor set layout and pool.
2652                         const VkDescriptorSetLayoutBinding      binding                         =
2653                         {
2654                                 inputNdx,                                                                                       // binding
2655                                 resource.first,                                                                         // descriptorType
2656                                 1u,                                                                                                     // descriptorCount
2657                                 VK_SHADER_STAGE_ALL_GRAPHICS,                                           // stageFlags
2658                                 DE_NULL,                                                                                        // pImmutableSamplers
2659                         };
2660                         setLayoutBindings.push_back(binding);
2661
2662                         // Note: the following code doesn't check and unify descriptors of the same type.
2663                         const VkDescriptorPoolSize              poolSize                                =
2664                         {
2665                                 resource.first,                                                                         // type
2666                                 1u,                                                                                                     // descriptorCount
2667                         };
2668                         poolSizes.push_back(poolSize);
2669                 }
2670
2671                 // Process all output resources.
2672                 for (deUint32 outputNdx = 0; outputNdx < numOutResources; ++outputNdx)
2673                 {
2674                         const Resource&                                 resource                                = instance.resources.outputs[outputNdx];
2675                         // Create buffer and allocate memory.
2676                         Move<VkBuffer>                                  resourceBuffer                  = createBufferForResource(vk, *vkDevice, resource, queueFamilyIndex);
2677                         de::MovePtr<Allocation>                 resourceMemory                  = allocator.allocate(getBufferMemoryRequirements(vk, *vkDevice, *resourceBuffer), MemoryRequirement::HostVisible);
2678                         vector<deUint8>                                 resourceBytes;
2679
2680                         VK_CHECK(vk.bindBufferMemory(*vkDevice, *resourceBuffer, resourceMemory->getMemory(), resourceMemory->getOffset()));
2681
2682                         // Fill memory with all ones.
2683                         const VkMappedMemoryRange               range                                   =
2684                         {
2685                                 VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE,                          //      VkStructureType sType;
2686                                 DE_NULL,                                                                                        //      const void*             pNext;
2687                                 resourceMemory->getMemory(),                                            //      VkDeviceMemory  mem;
2688                                 0,                                                                                                      //      VkDeviceSize    offset;
2689                                 VK_WHOLE_SIZE,                                                                          //      VkDeviceSize    size;
2690                         };
2691
2692                         resource.second->getBytes(resourceBytes);
2693                         deMemset((deUint8*)resourceMemory->getHostPtr(), 0xff, resourceBytes.size());
2694                         VK_CHECK(vk.flushMappedMemoryRanges(*vkDevice, 1u, &range));
2695
2696                         outResourceMemories.push_back(AllocationSp(resourceMemory.release()));
2697                         outResourceBuffers.push_back(BufferHandleSp(new BufferHandleUp(resourceBuffer)));
2698
2699                         // Prepare descriptor bindings and pool sizes for creating descriptor set layout and pool.
2700                         const VkDescriptorSetLayoutBinding      binding                         =
2701                         {
2702                                 numInResources  + outputNdx,                                            // binding
2703                                 resource.first,                                                                         // descriptorType
2704                                 1u,                                                                                                     // descriptorCount
2705                                 VK_SHADER_STAGE_ALL_GRAPHICS,                                           // stageFlags
2706                                 DE_NULL,                                                                                        // pImmutableSamplers
2707                         };
2708                         setLayoutBindings.push_back(binding);
2709
2710                         // Note: the following code doesn't check and unify descriptors of the same type.
2711                         const VkDescriptorPoolSize              poolSize                                =
2712                         {
2713                                 resource.first,                                                                         // type
2714                                 1u,                                                                                                     // descriptorCount
2715                         };
2716                         poolSizes.push_back(poolSize);
2717                 }
2718
2719                 // Create descriptor set layout, descriptor pool, and allocate descriptor set.
2720                 const VkDescriptorSetLayoutCreateInfo   setLayoutParams         =
2721                 {
2722                         VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,    // sType
2723                         DE_NULL,                                                                                                // pNext
2724                         (VkDescriptorSetLayoutCreateFlags)0,                                    // flags
2725                         numResources,                                                                                   // bindingCount
2726                         setLayoutBindings.data(),                                                               // pBindings
2727                 };
2728                 setLayout                                                                                                       = createDescriptorSetLayout(vk, *vkDevice, &setLayoutParams);
2729                 rawSetLayout                                                                                            = *setLayout;
2730
2731                 const VkDescriptorPoolCreateInfo                poolParams                      =
2732                 {
2733                         VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,                  // sType
2734                         DE_NULL,                                                                                                // pNext
2735                         (VkDescriptorPoolCreateFlags)0,                                                 // flags
2736                         1u,                                                                                                             // maxSets
2737                         numResources,                                                                                   // poolSizeCount
2738                         poolSizes.data(),                                                                               // pPoolSizes
2739                 };
2740                 descriptorPool                                                                                          = createDescriptorPool(vk, *vkDevice, &poolParams);
2741
2742                 const VkDescriptorSetAllocateInfo               setAllocParams          =
2743                 {
2744                         VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,                 // sType
2745                         DE_NULL,                                                                                                // pNext
2746                         *descriptorPool,                                                                                // descriptorPool
2747                         1u,                                                                                                             // descriptorSetCount
2748                         &rawSetLayout,                                                                                  // pSetLayouts
2749                 };
2750                 VK_CHECK(vk.allocateDescriptorSets(*vkDevice, &setAllocParams, &rawSet));
2751
2752                 // Update descriptor set.
2753                 vector<VkWriteDescriptorSet>                    writeSpecs                      ;
2754                 vector<VkDescriptorBufferInfo>                  dBufferInfos            ;
2755
2756                 writeSpecs.reserve(numResources);
2757                 dBufferInfos.reserve(numResources);
2758
2759                 for (deUint32 inputNdx = 0; inputNdx < numInResources; ++inputNdx)
2760                 {
2761                         const VkDescriptorBufferInfo            bufInfo                         =
2762                         {
2763                                 **inResourceBuffers[inputNdx],                                          // buffer
2764                                 0,                                                                                                      // offset
2765                                 VK_WHOLE_SIZE,                                                                          // size
2766                         };
2767                         dBufferInfos.push_back(bufInfo);
2768
2769                         const VkWriteDescriptorSet                      writeSpec                       = {
2770                                 VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,                         // sType
2771                                 DE_NULL,                                                                                        // pNext
2772                                 rawSet,                                                                                         // dstSet
2773                                 inputNdx,                                                                                       // binding
2774                                 0,                                                                                                      // dstArrayElement
2775                                 1u,                                                                                                     // descriptorCount
2776                                 instance.resources.inputs[inputNdx].first,                      // descriptorType
2777                                 DE_NULL,                                                                                        // pImageInfo
2778                                 &dBufferInfos.back(),                                                           // pBufferInfo
2779                                 DE_NULL,                                                                                        // pTexelBufferView
2780                         };
2781                         writeSpecs.push_back(writeSpec);
2782                 }
2783                 for (deUint32 outputNdx = 0; outputNdx < numOutResources; ++outputNdx)
2784                 {
2785                         const VkDescriptorBufferInfo            bufInfo                         =
2786                         {
2787                                 **outResourceBuffers[outputNdx],                                        // buffer
2788                                 0,                                                                                                      // offset
2789                                 VK_WHOLE_SIZE,                                                                          // size
2790                         };
2791                         dBufferInfos.push_back(bufInfo);
2792
2793                         const VkWriteDescriptorSet                      writeSpec                       = {
2794                                 VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,                         // sType
2795                                 DE_NULL,                                                                                        // pNext
2796                                 rawSet,                                                                                         // dstSet
2797                                 numInResources + outputNdx,                                                     // binding
2798                                 0,                                                                                                      // dstArrayElement
2799                                 1u,                                                                                                     // descriptorCount
2800                                 instance.resources.outputs[outputNdx].first,            // descriptorType
2801                                 DE_NULL,                                                                                        // pImageInfo
2802                                 &dBufferInfos.back(),                                                           // pBufferInfo
2803                                 DE_NULL,                                                                                        // pTexelBufferView
2804                         };
2805                         writeSpecs.push_back(writeSpec);
2806                 }
2807                 vk.updateDescriptorSets(*vkDevice, numResources, writeSpecs.data(), 0, DE_NULL);
2808         }
2809
2810         // Pipeline layout
2811         VkPipelineLayoutCreateInfo                              pipelineLayoutParams    =
2812         {
2813                 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,                  //      VkStructureType                                 sType;
2814                 DE_NULL,                                                                                                //      const void*                                             pNext;
2815                 (VkPipelineLayoutCreateFlags)0,
2816                 0u,                                                                                                             //      deUint32                                                descriptorSetCount;
2817                 DE_NULL,                                                                                                //      const VkDescriptorSetLayout*    pSetLayouts;
2818                 0u,                                                                                                             //      deUint32                                                pushConstantRangeCount;
2819                 DE_NULL,                                                                                                //      const VkPushConstantRange*              pPushConstantRanges;
2820         };
2821
2822         VkPushConstantRange                                             pushConstantRange               =
2823         {
2824                 VK_SHADER_STAGE_ALL_GRAPHICS,                                                   // VkShaderStageFlags    stageFlags;
2825                 0,                                                                                                              // uint32_t              offset;
2826                 0,                                                                                                              // uint32_t              size;
2827         };
2828         if (hasPushConstants)
2829         {
2830                 vector<deUint8> pushConstantsBytes;
2831                 instance.pushConstants.getBuffer()->getBytes(pushConstantsBytes);
2832
2833                 pushConstantRange.size                                          = static_cast<deUint32>(pushConstantsBytes.size());
2834                 pipelineLayoutParams.pushConstantRangeCount     = 1;
2835                 pipelineLayoutParams.pPushConstantRanges        = &pushConstantRange;
2836         }
2837         if (numResources != 0)
2838         {
2839                 // Update pipeline layout with the descriptor set layout.
2840                 pipelineLayoutParams.setLayoutCount                                                             = 1;
2841                 pipelineLayoutParams.pSetLayouts                                                                = &rawSetLayout;
2842         }
2843         const Unique<VkPipelineLayout>                  pipelineLayout                  (createPipelineLayout(vk, *vkDevice, &pipelineLayoutParams));
2844
2845         // Pipeline
2846         vector<VkPipelineShaderStageCreateInfo>         shaderStageParams;
2847         // We need these vectors to make sure that information about specialization constants for each stage can outlive createGraphicsPipeline().
2848         vector<vector<VkSpecializationMapEntry> >       specConstantEntries;
2849         vector<VkSpecializationInfo>                            specializationInfos;
2850         if (DE_NULL != instance.resources.verifyBinary)
2851         {
2852                 std::string shaderName;
2853                 switch(instance.customizedStages)
2854                 {
2855                 case    VK_SHADER_STAGE_VERTEX_BIT:
2856                         shaderName= "vert";
2857                         break;
2858                 case    VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT:
2859                         shaderName= "tessc";
2860                         break;
2861                 case    VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT:
2862                         shaderName= "tesse";
2863                         break;
2864                 case    VK_SHADER_STAGE_GEOMETRY_BIT:
2865                         shaderName= "geom";
2866                         break;
2867                 case    VK_SHADER_STAGE_FRAGMENT_BIT:
2868                         shaderName= "frag";
2869                         break;
2870                 default:
2871                         DE_ASSERT(0);
2872                         break;
2873                 }
2874                 const ProgramBinary& binary  = context.getBinaryCollection().get(shaderName);
2875                 if (!instance.resources.verifyBinary(binary))
2876                         return tcu::TestStatus::fail("Binary verification of SPIR-V in the test failed");
2877
2878         }
2879         createPipelineShaderStages(vk, *vkDevice, instance, context, modules, shaderStageParams);
2880
2881         // And we don't want the reallocation of these vectors to invalidate pointers pointing to their contents.
2882         specConstantEntries.reserve(shaderStageParams.size());
2883         specializationInfos.reserve(shaderStageParams.size());
2884
2885         // Patch the specialization info field in PipelineShaderStageCreateInfos.
2886         for (vector<VkPipelineShaderStageCreateInfo>::iterator stageInfo = shaderStageParams.begin(); stageInfo != shaderStageParams.end(); ++stageInfo)
2887         {
2888                 const StageToSpecConstantMap::const_iterator stageIt = instance.specConstants.find(stageInfo->stage);
2889
2890                 if (stageIt != instance.specConstants.end())
2891                 {
2892                         const size_t                                            numSpecConstants        = stageIt->second.size();
2893                         vector<VkSpecializationMapEntry>        entries;
2894                         VkSpecializationInfo                            specInfo;
2895
2896                         entries.resize(numSpecConstants);
2897
2898                         // Only support 32-bit integers as spec constants now. And their constant IDs are numbered sequentially starting from 0.
2899                         for (size_t ndx = 0; ndx < numSpecConstants; ++ndx)
2900                         {
2901                                 entries[ndx].constantID = (deUint32)ndx;
2902                                 entries[ndx].offset             = deUint32(ndx * sizeof(deInt32));
2903                                 entries[ndx].size               = sizeof(deInt32);
2904                         }
2905
2906                         specConstantEntries.push_back(entries);
2907
2908                         specInfo.mapEntryCount  = (deUint32)numSpecConstants;
2909                         specInfo.pMapEntries    = specConstantEntries.back().data();
2910                         specInfo.dataSize               = numSpecConstants * sizeof(deInt32);
2911                         specInfo.pData                  = stageIt->second.data();
2912                         specializationInfos.push_back(specInfo);
2913
2914                         stageInfo->pSpecializationInfo = &specializationInfos.back();
2915                 }
2916         }
2917         const VkPipelineDepthStencilStateCreateInfo     depthStencilParams              =
2918         {
2919                 VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO,     //      VkStructureType         sType;
2920                 DE_NULL,                                                                                                        //      const void*                     pNext;
2921                 (VkPipelineDepthStencilStateCreateFlags)0,
2922                 DE_FALSE,                                                                                                       //      deUint32                        depthTestEnable;
2923                 DE_FALSE,                                                                                                       //      deUint32                        depthWriteEnable;
2924                 VK_COMPARE_OP_ALWAYS,                                                                           //      VkCompareOp                     depthCompareOp;
2925                 DE_FALSE,                                                                                                       //      deUint32                        depthBoundsTestEnable;
2926                 DE_FALSE,                                                                                                       //      deUint32                        stencilTestEnable;
2927                 {
2928                         VK_STENCIL_OP_KEEP,                                                                                     //      VkStencilOp     stencilFailOp;
2929                         VK_STENCIL_OP_KEEP,                                                                                     //      VkStencilOp     stencilPassOp;
2930                         VK_STENCIL_OP_KEEP,                                                                                     //      VkStencilOp     stencilDepthFailOp;
2931                         VK_COMPARE_OP_ALWAYS,                                                                           //      VkCompareOp     stencilCompareOp;
2932                         0u,                                                                                                                     //      deUint32        stencilCompareMask;
2933                         0u,                                                                                                                     //      deUint32        stencilWriteMask;
2934                         0u,                                                                                                                     //      deUint32        stencilReference;
2935                 },                                                                                                                      //      VkStencilOpState        front;
2936                 {
2937                         VK_STENCIL_OP_KEEP,                                                                                     //      VkStencilOp     stencilFailOp;
2938                         VK_STENCIL_OP_KEEP,                                                                                     //      VkStencilOp     stencilPassOp;
2939                         VK_STENCIL_OP_KEEP,                                                                                     //      VkStencilOp     stencilDepthFailOp;
2940                         VK_COMPARE_OP_ALWAYS,                                                                           //      VkCompareOp     stencilCompareOp;
2941                         0u,                                                                                                                     //      deUint32        stencilCompareMask;
2942                         0u,                                                                                                                     //      deUint32        stencilWriteMask;
2943                         0u,                                                                                                                     //      deUint32        stencilReference;
2944                 },                                                                                                                      //      VkStencilOpState        back;
2945                 -1.0f,                                                                                                          //      float                           minDepthBounds;
2946                 +1.0f,                                                                                                          //      float                           maxDepthBounds;
2947         };
2948         const VkViewport                                                viewport0                               =
2949         {
2950                 0.0f,                                                                                                           //      float   originX;
2951                 0.0f,                                                                                                           //      float   originY;
2952                 (float)renderSize.x(),                                                                          //      float   width;
2953                 (float)renderSize.y(),                                                                          //      float   height;
2954                 0.0f,                                                                                                           //      float   minDepth;
2955                 1.0f,                                                                                                           //      float   maxDepth;
2956         };
2957         const VkRect2D                                                  scissor0                                =
2958         {
2959                 {
2960                         0u,                                                                                                                     //      deInt32 x;
2961                         0u,                                                                                                                     //      deInt32 y;
2962                 },                                                                                                                      //      VkOffset2D      offset;
2963                 {
2964                         renderSize.x(),                                                                                         //      deInt32 width;
2965                         renderSize.y(),                                                                                         //      deInt32 height;
2966                 },                                                                                                                      //      VkExtent2D      extent;
2967         };
2968         const VkPipelineViewportStateCreateInfo         viewportParams                  =
2969         {
2970                 VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO,          //      VkStructureType         sType;
2971                 DE_NULL,                                                                                                        //      const void*                     pNext;
2972                 (VkPipelineViewportStateCreateFlags)0,
2973                 1u,                                                                                                                     //      deUint32                        viewportCount;
2974                 &viewport0,
2975                 1u,
2976                 &scissor0
2977         };
2978         const VkSampleMask                                                      sampleMask                              = ~0u;
2979         const VkPipelineMultisampleStateCreateInfo      multisampleParams               =
2980         {
2981                 VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,       //      VkStructureType                 sType;
2982                 DE_NULL,                                                                                                        //      const void*                             pNext;
2983                 (VkPipelineMultisampleStateCreateFlags)0,
2984                 VK_SAMPLE_COUNT_1_BIT,                                                                          //      VkSampleCountFlagBits   rasterSamples;
2985                 DE_FALSE,                                                                                                       //      deUint32                                sampleShadingEnable;
2986                 0.0f,                                                                                                           //      float                                   minSampleShading;
2987                 &sampleMask,                                                                                            //      const VkSampleMask*             pSampleMask;
2988                 DE_FALSE,                                                                                                       //      VkBool32                                alphaToCoverageEnable;
2989                 DE_FALSE,                                                                                                       //      VkBool32                                alphaToOneEnable;
2990         };
2991         const VkPipelineRasterizationStateCreateInfo    rasterParams            =
2992         {
2993                 VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO,     //      VkStructureType sType;
2994                 DE_NULL,                                                                                                        //      const void*             pNext;
2995                 (VkPipelineRasterizationStateCreateFlags)0,
2996                 DE_FALSE,                                                                                                       //      deUint32                depthClampEnable;
2997                 DE_FALSE,                                                                                                       //      deUint32                rasterizerDiscardEnable;
2998                 VK_POLYGON_MODE_FILL,                                                                           //      VkFillMode              fillMode;
2999                 VK_CULL_MODE_NONE,                                                                                      //      VkCullMode              cullMode;
3000                 VK_FRONT_FACE_COUNTER_CLOCKWISE,                                                        //      VkFrontFace             frontFace;
3001                 VK_FALSE,                                                                                                       //      VkBool32                depthBiasEnable;
3002                 0.0f,                                                                                                           //      float                   depthBias;
3003                 0.0f,                                                                                                           //      float                   depthBiasClamp;
3004                 0.0f,                                                                                                           //      float                   slopeScaledDepthBias;
3005                 1.0f,                                                                                                           //      float                   lineWidth;
3006         };
3007         const VkPrimitiveTopology topology = hasTessellation? VK_PRIMITIVE_TOPOLOGY_PATCH_LIST: VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
3008         const VkPipelineInputAssemblyStateCreateInfo    inputAssemblyParams     =
3009         {
3010                 VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,    //      VkStructureType         sType;
3011                 DE_NULL,                                                                                                                //      const void*                     pNext;
3012                 (VkPipelineInputAssemblyStateCreateFlags)0,
3013                 topology,                                                                                                               //      VkPrimitiveTopology     topology;
3014                 DE_FALSE,                                                                                                               //      deUint32                        primitiveRestartEnable;
3015         };
3016
3017         vector<VkVertexInputBindingDescription>         vertexBindings;
3018         vector<VkVertexInputAttributeDescription>       vertexAttribs;
3019
3020         const VkVertexInputBindingDescription           vertexBinding0                  =
3021         {
3022                 0u,                                                                     // deUint32                                     binding;
3023                 deUint32(singleVertexDataSize),         // deUint32                                     strideInBytes;
3024                 VK_VERTEX_INPUT_RATE_VERTEX                     // VkVertexInputStepRate        stepRate;
3025         };
3026         vertexBindings.push_back(vertexBinding0);
3027
3028         {
3029                 VkVertexInputAttributeDescription               attr0                                   =
3030                 {
3031                         0u,                                                                     // deUint32     location;
3032                         0u,                                                                     // deUint32     binding;
3033                         VK_FORMAT_R32G32B32A32_SFLOAT,          // VkFormat     format;
3034                         0u                                                                      // deUint32     offsetInBytes;
3035                 };
3036                 vertexAttribs.push_back(attr0);
3037
3038                 VkVertexInputAttributeDescription               attr1                                   =
3039                 {
3040                         1u,                                                                     // deUint32     location;
3041                         0u,                                                                     // deUint32     binding;
3042                         VK_FORMAT_R32G32B32A32_SFLOAT,          // VkFormat     format;
3043                         sizeof(Vec4),                                           // deUint32     offsetInBytes;
3044                 };
3045                 vertexAttribs.push_back(attr1);
3046         };
3047
3048         // If the test instantiation has additional input/output interface variables, we need to create additional bindings.
3049         // Right now we only support one additional input varible for the vertex stage, and that will be bound to binding #1
3050         // with location #2.
3051         if (needInterface)
3052         {
3053                 const VkVertexInputBindingDescription   vertexBinding1                  =
3054                 {
3055                         1u,                                                                                                     // deUint32                                     binding;
3056                         instance.interfaces.getInputType().getNumBytes(),       // deUint32                                     strideInBytes;
3057                         VK_VERTEX_INPUT_RATE_VERTEX                                                     // VkVertexInputStepRate        stepRate;
3058                 };
3059                 vertexBindings.push_back(vertexBinding1);
3060
3061                 VkVertexInputAttributeDescription               attr                                    =
3062                 {
3063                         2u,                                                                                                     // deUint32     location;
3064                         1u,                                                                                                     // deUint32     binding;
3065                         instance.interfaces.getInputType().getVkFormat(),       // VkFormat     format;
3066                         0,                                                                                                      // deUint32     offsetInBytes;
3067                 };
3068                 vertexAttribs.push_back(attr);
3069         }
3070
3071         VkPipelineVertexInputStateCreateInfo            vertexInputStateParams  =
3072         {
3073                 VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,      //      VkStructureType                                                         sType;
3074                 DE_NULL,                                                                                                        //      const void*                                                                     pNext;
3075                 (VkPipelineVertexInputStateCreateFlags)0,
3076                 1u,                                                                                                                     //      deUint32                                                                        bindingCount;
3077                 vertexBindings.data(),                                                                          //      const VkVertexInputBindingDescription*          pVertexBindingDescriptions;
3078                 2u,                                                                                                                     //      deUint32                                                                        attributeCount;
3079                 vertexAttribs.data(),                                                                           //      const VkVertexInputAttributeDescription*        pVertexAttributeDescriptions;
3080         };
3081
3082         if (needInterface)
3083         {
3084                 vertexInputStateParams.vertexBindingDescriptionCount += 1;
3085                 vertexInputStateParams.vertexAttributeDescriptionCount += 1;
3086         }
3087
3088         vector<VkPipelineColorBlendAttachmentState>     attBlendStates                  ;
3089         const VkPipelineColorBlendAttachmentState       attBlendState                   =
3090         {
3091                 DE_FALSE,                                                                                                       //      deUint32                blendEnable;
3092                 VK_BLEND_FACTOR_ONE,                                                                            //      VkBlend                 srcBlendColor;
3093                 VK_BLEND_FACTOR_ZERO,                                                                           //      VkBlend                 destBlendColor;
3094                 VK_BLEND_OP_ADD,                                                                                        //      VkBlendOp               blendOpColor;
3095                 VK_BLEND_FACTOR_ONE,                                                                            //      VkBlend                 srcBlendAlpha;
3096                 VK_BLEND_FACTOR_ZERO,                                                                           //      VkBlend                 destBlendAlpha;
3097                 VK_BLEND_OP_ADD,                                                                                        //      VkBlendOp               blendOpAlpha;
3098                 (VK_COLOR_COMPONENT_R_BIT|
3099                  VK_COLOR_COMPONENT_G_BIT|
3100                  VK_COLOR_COMPONENT_B_BIT|
3101                  VK_COLOR_COMPONENT_A_BIT),                                                                     //      VkChannelFlags  channelWriteMask;
3102         };
3103         attBlendStates.push_back(attBlendState);
3104
3105         if (needInterface)
3106                 attBlendStates.push_back(attBlendState);
3107
3108         VkPipelineColorBlendStateCreateInfo             blendParams                             =
3109         {
3110                 VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,       //      VkStructureType                                                         sType;
3111                 DE_NULL,                                                                                                        //      const void*                                                                     pNext;
3112                 (VkPipelineColorBlendStateCreateFlags)0,
3113                 DE_FALSE,                                                                                                       //      VkBool32                                                                        logicOpEnable;
3114                 VK_LOGIC_OP_COPY,                                                                                       //      VkLogicOp                                                                       logicOp;
3115                 1u,                                                                                                                     //      deUint32                                                                        attachmentCount;
3116                 attBlendStates.data(),                                                                          //      const VkPipelineColorBlendAttachmentState*      pAttachments;
3117                 { 0.0f, 0.0f, 0.0f, 0.0f },                                                                     //      float                                                                           blendConst[4];
3118         };
3119         if (needInterface)
3120         {
3121                 blendParams.attachmentCount += 1;
3122         }
3123         const VkPipelineTessellationStateCreateInfo     tessellationState       =
3124         {
3125                 VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO,
3126                 DE_NULL,
3127                 (VkPipelineTessellationStateCreateFlags)0,
3128                 3u
3129         };
3130
3131         const VkPipelineTessellationStateCreateInfo* tessellationInfo   =       hasTessellation ? &tessellationState: DE_NULL;
3132         const VkGraphicsPipelineCreateInfo              pipelineParams                  =
3133         {
3134                 VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,                //      VkStructureType                                                                 sType;
3135                 DE_NULL,                                                                                                //      const void*                                                                             pNext;
3136                 0u,                                                                                                             //      VkPipelineCreateFlags                                                   flags;
3137                 (deUint32)shaderStageParams.size(),                                             //      deUint32                                                                                stageCount;
3138                 &shaderStageParams[0],                                                                  //      const VkPipelineShaderStageCreateInfo*                  pStages;
3139                 &vertexInputStateParams,                                                                //      const VkPipelineVertexInputStateCreateInfo*             pVertexInputState;
3140                 &inputAssemblyParams,                                                                   //      const VkPipelineInputAssemblyStateCreateInfo*   pInputAssemblyState;
3141                 tessellationInfo,                                                                               //      const VkPipelineTessellationStateCreateInfo*    pTessellationState;
3142                 &viewportParams,                                                                                //      const VkPipelineViewportStateCreateInfo*                pViewportState;
3143                 &rasterParams,                                                                                  //      const VkPipelineRasterStateCreateInfo*                  pRasterState;
3144                 &multisampleParams,                                                                             //      const VkPipelineMultisampleStateCreateInfo*             pMultisampleState;
3145                 &depthStencilParams,                                                                    //      const VkPipelineDepthStencilStateCreateInfo*    pDepthStencilState;
3146                 &blendParams,                                                                                   //      const VkPipelineColorBlendStateCreateInfo*              pColorBlendState;
3147                 (const VkPipelineDynamicStateCreateInfo*)DE_NULL,               //      const VkPipelineDynamicStateCreateInfo*                 pDynamicState;
3148                 *pipelineLayout,                                                                                //      VkPipelineLayout                                                                layout;
3149                 *renderPass,                                                                                    //      VkRenderPass                                                                    renderPass;
3150                 0u,                                                                                                             //      deUint32                                                                                subpass;
3151                 DE_NULL,                                                                                                //      VkPipeline                                                                              basePipelineHandle;
3152                 0u,                                                                                                             //      deInt32                                                                                 basePipelineIndex;
3153         };
3154
3155         const Unique<VkPipeline>                                pipeline                                (createGraphicsPipeline(vk, *vkDevice, DE_NULL, &pipelineParams));
3156
3157         if (needInterface)
3158         {
3159                 const VkImageViewCreateInfo                     fragOutputViewParams    =
3160                 {
3161                         VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,                       //      VkStructureType                         sType;
3162                         DE_NULL,                                                                                        //      const void*                                     pNext;
3163                         0u,                                                                                                     //      VkImageViewCreateFlags          flags;
3164                         *fragOutputImage,                                                                       //      VkImage                                         image;
3165                         VK_IMAGE_VIEW_TYPE_2D,                                                          //      VkImageViewType                         viewType;
3166                         instance.interfaces.getOutputType().getVkFormat(),      //      VkFormat                                        format;
3167                         {
3168                                 VK_COMPONENT_SWIZZLE_R,
3169                                 VK_COMPONENT_SWIZZLE_G,
3170                                 VK_COMPONENT_SWIZZLE_B,
3171                                 VK_COMPONENT_SWIZZLE_A
3172                         },                                                                                                      //      VkChannelMapping                        channels;
3173                         {
3174                                 VK_IMAGE_ASPECT_COLOR_BIT,                                              //      VkImageAspectFlags      aspectMask;
3175                                 0u,                                                                                             //      deUint32                        baseMipLevel;
3176                                 1u,                                                                                             //      deUint32                        mipLevels;
3177                                 0u,                                                                                             //      deUint32                        baseArrayLayer;
3178                                 1u,                                                                                             //      deUint32                        arraySize;
3179                         },                                                                                                      //      VkImageSubresourceRange         subresourceRange;
3180                 };
3181                 fragOutputImageView = createImageView(vk, *vkDevice, &fragOutputViewParams);
3182                 attViews.push_back(*fragOutputImageView);
3183         }
3184
3185         // Framebuffer
3186         VkFramebufferCreateInfo                                 framebufferParams               =
3187         {
3188                 VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,                              //      VkStructureType         sType;
3189                 DE_NULL,                                                                                                //      const void*                     pNext;
3190                 (VkFramebufferCreateFlags)0,
3191                 *renderPass,                                                                                    //      VkRenderPass            renderPass;
3192                 1u,                                                                                                             //      deUint32                        attachmentCount;
3193                 attViews.data(),                                                                                //      const VkImageView*      pAttachments;
3194                 (deUint32)renderSize.x(),                                                               //      deUint32                        width;
3195                 (deUint32)renderSize.y(),                                                               //      deUint32                        height;
3196                 1u,                                                                                                             //      deUint32                        layers;
3197         };
3198
3199         if (needInterface)
3200                 framebufferParams.attachmentCount += 1;
3201
3202         const Unique<VkFramebuffer>                             framebuffer                             (createFramebuffer(vk, *vkDevice, &framebufferParams));
3203
3204         const Unique<VkCommandPool>                             cmdPool                                 (createCommandPool(vk, *vkDevice, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, queueFamilyIndex));
3205
3206         // Command buffer
3207         const Unique<VkCommandBuffer>                   cmdBuf                                  (allocateCommandBuffer(vk, *vkDevice, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
3208
3209         const VkCommandBufferBeginInfo                  cmdBufBeginParams               =
3210         {
3211                 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,                    //      VkStructureType                         sType;
3212                 DE_NULL,                                                                                                //      const void*                                     pNext;
3213                 (VkCommandBufferUsageFlags)0,
3214                 (const VkCommandBufferInheritanceInfo*)DE_NULL,
3215         };
3216
3217         // Record commands
3218         VK_CHECK(vk.beginCommandBuffer(*cmdBuf, &cmdBufBeginParams));
3219
3220         {
3221                 const VkMemoryBarrier                   vertFlushBarrier        =
3222                 {
3223                         VK_STRUCTURE_TYPE_MEMORY_BARRIER,                       //      VkStructureType         sType;
3224                         DE_NULL,                                                                        //      const void*                     pNext;
3225                         VK_ACCESS_HOST_WRITE_BIT,                                       //      VkMemoryOutputFlags     outputMask;
3226                         VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT,            //      VkMemoryInputFlags      inputMask;
3227                 };
3228                 vector<VkImageMemoryBarrier>    colorAttBarriers        ;
3229
3230                 VkImageMemoryBarrier                    imgBarrier          =
3231                 {
3232                         VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,         //      VkStructureType                 sType;
3233                         DE_NULL,                                                                        //      const void*                             pNext;
3234                         0u,                                                                                     //      VkMemoryOutputFlags             outputMask;
3235                         VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,           //      VkMemoryInputFlags              inputMask;
3236                         VK_IMAGE_LAYOUT_UNDEFINED,                                      //      VkImageLayout                   oldLayout;
3237                         VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,       //      VkImageLayout                   newLayout;
3238                         queueFamilyIndex,                                                       //      deUint32                                srcQueueFamilyIndex;
3239                         queueFamilyIndex,                                                       //      deUint32                                destQueueFamilyIndex;
3240                         *image,                                                                         //      VkImage                                 image;
3241                         {
3242                                 VK_IMAGE_ASPECT_COLOR_BIT,                                      //      VkImageAspect   aspect;
3243                                 0u,                                                                                     //      deUint32                baseMipLevel;
3244                                 1u,                                                                                     //      deUint32                mipLevels;
3245                                 0u,                                                                                     //      deUint32                baseArraySlice;
3246                                 1u,                                                                                     //      deUint32                arraySize;
3247                         }                                                                                       //      VkImageSubresourceRange subresourceRange;
3248                 };
3249                 colorAttBarriers.push_back(imgBarrier);
3250                 if (needInterface)
3251                 {
3252                         imgBarrier.image = *fragOutputImage;
3253                         colorAttBarriers.push_back(imgBarrier);
3254                         vk.cmdPipelineBarrier(*cmdBuf, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT, (VkDependencyFlags)0, 1, &vertFlushBarrier, 0, (const VkBufferMemoryBarrier*)DE_NULL, 2, colorAttBarriers.data());
3255                 }
3256                 else
3257                 {
3258                         vk.cmdPipelineBarrier(*cmdBuf, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT, (VkDependencyFlags)0, 1, &vertFlushBarrier, 0, (const VkBufferMemoryBarrier*)DE_NULL, 1, colorAttBarriers.data());
3259                 }
3260         }
3261
3262         {
3263                 vector<VkClearValue>                    clearValue              ;
3264                 clearValue.push_back(makeClearValueColorF32(0.125f, 0.25f, 0.75f, 1.0f));
3265                 if (needInterface)
3266                 {
3267                         clearValue.push_back(makeClearValueColorU32(0, 0, 0, 0));
3268                 }
3269                 VkRenderPassBeginInfo                   passBeginParams =
3270                 {
3271                         VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,                       //      VkStructureType         sType;
3272                         DE_NULL,                                                                                        //      const void*                     pNext;
3273                         *renderPass,                                                                            //      VkRenderPass            renderPass;
3274                         *framebuffer,                                                                           //      VkFramebuffer           framebuffer;
3275                         { { 0, 0 }, { renderSize.x(), renderSize.y() } },       //      VkRect2D                        renderArea;
3276                         1u,                                                                                                     //      deUint32                        clearValueCount;
3277                         clearValue.data(),                                                                      //      const VkClearValue*     pClearValues;
3278                 };
3279                 if (needInterface)
3280                 {
3281                         passBeginParams.clearValueCount += 1;
3282                 }
3283                 vk.cmdBeginRenderPass(*cmdBuf, &passBeginParams, VK_SUBPASS_CONTENTS_INLINE);
3284         }
3285
3286         vk.cmdBindPipeline(*cmdBuf, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipeline);
3287         {
3288                 const VkDeviceSize bindingOffset = 0;
3289                 vk.cmdBindVertexBuffers(*cmdBuf, 0u, 1u, &vertexBuffer.get(), &bindingOffset);
3290         }
3291         if (needInterface)
3292         {
3293                 const VkDeviceSize bindingOffset = 0;
3294                 vk.cmdBindVertexBuffers(*cmdBuf, 1u, 1u, &vertexInputBuffer.get(), &bindingOffset);
3295         }
3296         if (hasPushConstants)
3297         {
3298                 vector<deUint8> pushConstantsBytes;
3299                 instance.pushConstants.getBuffer()->getBytes(pushConstantsBytes);
3300
3301                 const deUint32  size    = static_cast<deUint32>(pushConstantsBytes.size());
3302                 const void*             data    = &pushConstantsBytes.front();
3303
3304                 vk.cmdPushConstants(*cmdBuf, *pipelineLayout, VK_SHADER_STAGE_ALL_GRAPHICS, 0, size, data);
3305         }
3306         if (numResources != 0)
3307         {
3308                 // Bind to set number 0.
3309                 vk.cmdBindDescriptorSets(*cmdBuf, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipelineLayout, 0, 1, &rawSet, 0, DE_NULL);
3310         }
3311         vk.cmdDraw(*cmdBuf, deUint32(vertexCount), 1u /*run pipeline once*/, 0u /*first vertex*/, 0u /*first instanceIndex*/);
3312         vk.cmdEndRenderPass(*cmdBuf);
3313
3314         {
3315                 vector<VkImageMemoryBarrier>    renderFinishBarrier;
3316                 VkImageMemoryBarrier                    imgBarrier                              =
3317                 {
3318                         VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,         //      VkStructureType                 sType;
3319                         DE_NULL,                                                                        //      const void*                             pNext;
3320                         VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,           //      VkMemoryOutputFlags             outputMask;
3321                         VK_ACCESS_TRANSFER_READ_BIT,                            //      VkMemoryInputFlags              inputMask;
3322                         VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,       //      VkImageLayout                   oldLayout;
3323                         VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,           //      VkImageLayout                   newLayout;
3324                         queueFamilyIndex,                                                       //      deUint32                                srcQueueFamilyIndex;
3325                         queueFamilyIndex,                                                       //      deUint32                                destQueueFamilyIndex;
3326                         *image,                                                                         //      VkImage                                 image;
3327                         {
3328                                 VK_IMAGE_ASPECT_COLOR_BIT,                                      //      VkImageAspectFlags      aspectMask;
3329                                 0u,                                                                                     //      deUint32                        baseMipLevel;
3330                                 1u,                                                                                     //      deUint32                        mipLevels;
3331                                 0u,                                                                                     //      deUint32                        baseArraySlice;
3332                                 1u,                                                                                     //      deUint32                        arraySize;
3333                         }                                                                                       //      VkImageSubresourceRange subresourceRange;
3334                 };
3335                 renderFinishBarrier.push_back(imgBarrier);
3336
3337                 if (needInterface)
3338                 {
3339                         imgBarrier.image = *fragOutputImage;
3340                         renderFinishBarrier.push_back(imgBarrier);
3341                         vk.cmdPipelineBarrier(*cmdBuf, VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, 2, renderFinishBarrier.data());
3342                 }
3343                 else
3344                 {
3345                         vk.cmdPipelineBarrier(*cmdBuf, VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, 1, renderFinishBarrier.data());
3346                 }
3347         }
3348
3349         {
3350                 const VkBufferImageCopy copyParams      =
3351                 {
3352                         (VkDeviceSize)0u,                                               //      VkDeviceSize                    bufferOffset;
3353                         (deUint32)renderSize.x(),                               //      deUint32                                bufferRowLength;
3354                         (deUint32)renderSize.y(),                               //      deUint32                                bufferImageHeight;
3355                         {
3356                                 VK_IMAGE_ASPECT_COLOR_BIT,                              //      VkImageAspect           aspect;
3357                                 0u,                                                                             //      deUint32                        mipLevel;
3358                                 0u,                                                                             //      deUint32                        arrayLayer;
3359                                 1u,                                                                             //      deUint32                        arraySize;
3360                         },                                                                              //      VkImageSubresourceCopy  imageSubresource;
3361                         { 0u, 0u, 0u },                                                 //      VkOffset3D                              imageOffset;
3362                         { renderSize.x(), renderSize.y(), 1u }  //      VkExtent3D                              imageExtent;
3363                 };
3364                 vk.cmdCopyImageToBuffer(*cmdBuf, *image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *readImageBuffer, 1u, &copyParams);
3365
3366                 if (needInterface)
3367                 {
3368                         vk.cmdCopyImageToBuffer(*cmdBuf, *fragOutputImage, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *fragOutputBuffer, 1u, &copyParams);
3369                 }
3370         }
3371
3372         {
3373                 vector<VkBufferMemoryBarrier> cpFinishBarriers          ;
3374                 VkBufferMemoryBarrier                   copyFinishBarrier       =
3375                 {
3376                         VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,        //      VkStructureType         sType;
3377                         DE_NULL,                                                                        //      const void*                     pNext;
3378                         VK_ACCESS_TRANSFER_WRITE_BIT,                           //      VkMemoryOutputFlags     outputMask;
3379                         VK_ACCESS_HOST_READ_BIT,                                        //      VkMemoryInputFlags      inputMask;
3380                         queueFamilyIndex,                                                       //      deUint32                        srcQueueFamilyIndex;
3381                         queueFamilyIndex,                                                       //      deUint32                        destQueueFamilyIndex;
3382                         *readImageBuffer,                                                       //      VkBuffer                        buffer;
3383                         0u,                                                                                     //      VkDeviceSize            offset;
3384                         imageSizeBytes                                                          //      VkDeviceSize            size;
3385                 };
3386                 cpFinishBarriers.push_back(copyFinishBarrier);
3387
3388                 if (needInterface)
3389                 {
3390                         copyFinishBarrier.buffer        = *fragOutputBuffer;
3391                         copyFinishBarrier.size          = VK_WHOLE_SIZE;
3392                         cpFinishBarriers.push_back(copyFinishBarrier);
3393
3394                         vk.cmdPipelineBarrier(*cmdBuf, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 2, cpFinishBarriers.data(), 0, (const VkImageMemoryBarrier*)DE_NULL);
3395                 }
3396                 else
3397                 {
3398                         vk.cmdPipelineBarrier(*cmdBuf, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 1, cpFinishBarriers.data(), 0, (const VkImageMemoryBarrier*)DE_NULL);
3399                 }
3400         }
3401
3402         VK_CHECK(vk.endCommandBuffer(*cmdBuf));
3403
3404         // Upload vertex data
3405         {
3406                 const VkMappedMemoryRange       range                   =
3407                 {
3408                         VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE,  //      VkStructureType sType;
3409                         DE_NULL,                                                                //      const void*             pNext;
3410                         vertexBufferMemory->getMemory(),                //      VkDeviceMemory  mem;
3411                         0,                                                                              //      VkDeviceSize    offset;
3412                         (VkDeviceSize)sizeof(vertexData),               //      VkDeviceSize    size;
3413                 };
3414                 void*                                           vertexBufPtr    = vertexBufferMemory->getHostPtr();
3415
3416                 deMemcpy(vertexBufPtr, &vertexData[0], sizeof(vertexData));
3417                 VK_CHECK(vk.flushMappedMemoryRanges(*vkDevice, 1u, &range));
3418         }
3419
3420         if (needInterface)
3421         {
3422                 vector<deUint8> inputBufferBytes;
3423                 instance.interfaces.getInputBuffer()->getBytes(inputBufferBytes);
3424
3425                 const deUint32                          typNumBytes             = instance.interfaces.getInputType().getNumBytes();
3426                 const deUint32                          bufNumBytes             = static_cast<deUint32>(inputBufferBytes.size());
3427
3428                 // Require that the test instantation provides four output values.
3429                 DE_ASSERT(bufNumBytes == 4 * typNumBytes);
3430
3431                 // We have four triangles. Because interpolation happens before executing the fragment shader,
3432                 // we need to provide the same vertex attribute for the same triangle. That means, duplicate each
3433                 // value three times for all four values.
3434
3435                 const deUint8*                          provided                = static_cast<const deUint8*>(&inputBufferBytes.front());
3436                 vector<deUint8>                         data;
3437
3438                 data.reserve(3 * bufNumBytes);
3439
3440                 for (deUint32 offset = 0; offset < bufNumBytes; offset += typNumBytes)
3441                         for (deUint32 vertexNdx = 0; vertexNdx < 3; ++vertexNdx)
3442                                 for (deUint32 byteNdx = 0; byteNdx < typNumBytes; ++byteNdx)
3443                                         data.push_back(provided[offset + byteNdx]);
3444
3445                 deMemcpy(vertexInputMemory->getHostPtr(), data.data(), data.size());
3446
3447                 const VkMappedMemoryRange       range                   =
3448                 {
3449                         VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE,  //      VkStructureType sType;
3450                         DE_NULL,                                                                //      const void*             pNext;
3451                         vertexInputMemory->getMemory(),                 //      VkDeviceMemory  mem;
3452                         0,                                                                              //      VkDeviceSize    offset;
3453                         VK_WHOLE_SIZE,                                                  //      VkDeviceSize    size;
3454                 };
3455
3456                 VK_CHECK(vk.flushMappedMemoryRanges(*vkDevice, 1u, &range));
3457         }
3458
3459         // Submit & wait for completion
3460         {
3461                 const VkFenceCreateInfo fenceParams     =
3462                 {
3463                         VK_STRUCTURE_TYPE_FENCE_CREATE_INFO,    //      VkStructureType         sType;
3464                         DE_NULL,                                                                //      const void*                     pNext;
3465                         0u,                                                                             //      VkFenceCreateFlags      flags;
3466                 };
3467                 const Unique<VkFence>   fence           (createFence(vk, *vkDevice, &fenceParams));
3468                 const VkSubmitInfo              submitInfo      =
3469                 {
3470                         VK_STRUCTURE_TYPE_SUBMIT_INFO,
3471                         DE_NULL,
3472                         0u,
3473                         (const VkSemaphore*)DE_NULL,
3474                         (const VkPipelineStageFlags*)DE_NULL,
3475                         1u,
3476                         &cmdBuf.get(),
3477                         0u,
3478                         (const VkSemaphore*)DE_NULL,
3479                 };
3480
3481                 VK_CHECK(vk.queueSubmit(queue, 1u, &submitInfo, *fence));
3482                 VK_CHECK(vk.waitForFences(*vkDevice, 1u, &fence.get(), DE_TRUE, ~0ull));
3483         }
3484
3485         const void* imagePtr    = readImageBufferMemory->getHostPtr();
3486         const tcu::ConstPixelBufferAccess pixelBuffer(tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8),
3487                                                                                                   renderSize.x(), renderSize.y(), 1, imagePtr);
3488         // Log image
3489         {
3490                 const VkMappedMemoryRange       range           =
3491                 {
3492                         VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE,  //      VkStructureType sType;
3493                         DE_NULL,                                                                //      const void*             pNext;
3494                         readImageBufferMemory->getMemory(),             //      VkDeviceMemory  mem;
3495                         0,                                                                              //      VkDeviceSize    offset;
3496                         imageSizeBytes,                                                 //      VkDeviceSize    size;
3497                 };
3498
3499                 VK_CHECK(vk.invalidateMappedMemoryRanges(*vkDevice, 1u, &range));
3500                 context.getTestContext().getLog() << TestLog::Image("Result", "Result", pixelBuffer);
3501         }
3502
3503         if (needInterface)
3504         {
3505                 const VkDeviceSize                      fragOutputImgSize       = (VkDeviceSize)(instance.interfaces.getOutputType().getNumBytes() * renderSize.x() * renderSize.y());
3506                 const VkMappedMemoryRange       range                           =
3507                 {
3508                         VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE,  //      VkStructureType sType;
3509                         DE_NULL,                                                                //      const void*             pNext;
3510                         fragOutputMemory->getMemory(),                  //      VkDeviceMemory  mem;
3511                         0,                                                                              //      VkDeviceSize    offset;
3512                         fragOutputImgSize,                                              //      VkDeviceSize    size;
3513                 };
3514
3515                 VK_CHECK(vk.invalidateMappedMemoryRanges(*vkDevice, 1u, &range));
3516         }
3517
3518         { // Make sure all output resources are ready.
3519                 for (deUint32 outputNdx = 0; outputNdx < numOutResources; ++outputNdx)
3520                 {
3521                         const VkMappedMemoryRange       range   =
3522                         {
3523                                 VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE,                  //      VkStructureType sType;
3524                                 DE_NULL,                                                                                //      const void*             pNext;
3525                                 outResourceMemories[outputNdx]->getMemory(),    //      VkDeviceMemory  mem;
3526                                 0,                                                                                              //      VkDeviceSize    offset;
3527                                 VK_WHOLE_SIZE,                                                                  //      VkDeviceSize    size;
3528                         };
3529
3530                         VK_CHECK(vk.invalidateMappedMemoryRanges(*vkDevice, 1u, &range));
3531                 }
3532         }
3533
3534         const RGBA threshold(1, 1, 1, 1);
3535
3536         const RGBA upperLeft(pixelBuffer.getPixel(1, 1));
3537         if (!tcu::compareThreshold(upperLeft, instance.outputColors[0], threshold))
3538                 return TestStatus(instance.failResult, instance.getSpecializedFailMessage("Upper left corner mismatch"));
3539
3540         const RGBA upperRight(pixelBuffer.getPixel(pixelBuffer.getWidth() - 1, 1));
3541         if (!tcu::compareThreshold(upperRight, instance.outputColors[1], threshold))
3542                 return TestStatus(instance.failResult, instance.getSpecializedFailMessage("Upper right corner mismatch"));
3543
3544         const RGBA lowerLeft(pixelBuffer.getPixel(1, pixelBuffer.getHeight() - 1));
3545         if (!tcu::compareThreshold(lowerLeft, instance.outputColors[2], threshold))
3546                 return TestStatus(instance.failResult, instance.getSpecializedFailMessage("Lower left corner mismatch"));
3547
3548         const RGBA lowerRight(pixelBuffer.getPixel(pixelBuffer.getWidth() - 1, pixelBuffer.getHeight() - 1));
3549         if (!tcu::compareThreshold(lowerRight, instance.outputColors[3], threshold))
3550                 return TestStatus(instance.failResult, instance.getSpecializedFailMessage("Lower right corner mismatch"));
3551
3552         // Check that the contents in the ouput variable matches expected.
3553         if (needInterface)
3554         {
3555                 vector<deUint8>                                         inputBufferBytes;
3556                 vector<deUint8>                                         outputBufferBytes;
3557
3558                 instance.interfaces.getInputBuffer()->getBytes(inputBufferBytes);
3559                 instance.interfaces.getOutputBuffer()->getBytes(outputBufferBytes);
3560
3561                 const IFDataType&                                       outputType                              = instance.interfaces.getOutputType();
3562                 const void*                                                     inputData                               = &inputBufferBytes.front();
3563                 const void*                                                     outputData                              = &outputBufferBytes.front();
3564                 vector<std::pair<int, int> >            positions;
3565                 const tcu::ConstPixelBufferAccess       fragOutputBufferAccess  (outputType.getTextureFormat(), renderSize.x(), renderSize.y(), 1, fragOutputMemory->getHostPtr());
3566
3567                 positions.push_back(std::make_pair(1, 1));
3568                 positions.push_back(std::make_pair(fragOutputBufferAccess.getWidth() - 1, 1));
3569                 positions.push_back(std::make_pair(1, fragOutputBufferAccess.getHeight() - 1));
3570                 positions.push_back(std::make_pair(fragOutputBufferAccess.getWidth() - 1, fragOutputBufferAccess.getHeight() - 1));
3571
3572                 for (deUint32 posNdx = 0; posNdx < positions.size(); ++posNdx)
3573                 {
3574                         const int       x               = positions[posNdx].first;
3575                         const int       y               = positions[posNdx].second;
3576                         bool            equal   = true;
3577
3578                         if (outputType.elementType == NUMBERTYPE_FLOAT32)
3579                         {
3580                                 const float*            expected        = static_cast<const float*>(outputData) + posNdx * outputType.numElements;
3581                                 const float*            actual          = static_cast<const float*>(fragOutputBufferAccess.getPixelPtr(x, y));
3582
3583                                 for (deUint32 eleNdx = 0; eleNdx < outputType.numElements; ++eleNdx)
3584                                         if (!compare32BitFloat(expected[eleNdx], actual[eleNdx], context.getTestContext().getLog()))
3585                                                 equal = false;
3586                         }
3587                         else if (outputType.elementType == NUMBERTYPE_INT32)
3588                         {
3589                                 const deInt32*          expected        = static_cast<const deInt32*>(outputData) + posNdx * outputType.numElements;
3590                                 const deInt32*          actual          = static_cast<const deInt32*>(fragOutputBufferAccess.getPixelPtr(x, y));
3591
3592                                 for (deUint32 eleNdx = 0; eleNdx < outputType.numElements; ++eleNdx)
3593                                         if (expected[eleNdx] != actual[eleNdx])
3594                                                 equal = false;
3595                         }
3596                         else if (outputType.elementType == NUMBERTYPE_UINT32)
3597                         {
3598                                 const deUint32*         expected        = static_cast<const deUint32*>(outputData) + posNdx * outputType.numElements;
3599                                 const deUint32*         actual          = static_cast<const deUint32*>(fragOutputBufferAccess.getPixelPtr(x, y));
3600
3601                                 for (deUint32 eleNdx = 0; eleNdx < outputType.numElements; ++eleNdx)
3602                                         if (expected[eleNdx] != actual[eleNdx])
3603                                                 equal = false;
3604                         }
3605                         else if (outputType.elementType == NUMBERTYPE_FLOAT16)
3606                         {
3607                                 const float*            original        = static_cast<const float*>(inputData) + posNdx * outputType.numElements;
3608                                 const deFloat16*        actual          = static_cast<const deFloat16*>(fragOutputBufferAccess.getPixelPtr(x, y));
3609
3610                                 for (deUint32 eleNdx = 0; eleNdx < outputType.numElements; ++eleNdx)
3611                                         if (!compare16BitFloat(original[eleNdx], actual[eleNdx], instance.interfaces.getRoundingMode(), context.getTestContext().getLog()))
3612                                                 equal = false;
3613                         }
3614                         else if (outputType.elementType == NUMBERTYPE_INT16)
3615                         {
3616                                 const deInt16*          expected        = static_cast<const deInt16*>(outputData) + posNdx * outputType.numElements;
3617                                 const deInt16*          actual          = static_cast<const deInt16*>(fragOutputBufferAccess.getPixelPtr(x, y));
3618
3619                                 for (deUint32 eleNdx = 0; eleNdx < outputType.numElements; ++eleNdx)
3620                                         if (expected[eleNdx] != actual[eleNdx])
3621                                                 equal = false;
3622                         }
3623                         else if (outputType.elementType == NUMBERTYPE_UINT16)
3624                         {
3625                                 const deUint16*         expected        = static_cast<const deUint16*>(outputData) + posNdx * outputType.numElements;
3626                                 const deUint16*         actual          = static_cast<const deUint16*>(fragOutputBufferAccess.getPixelPtr(x, y));
3627
3628                                 for (deUint32 eleNdx = 0; eleNdx < outputType.numElements; ++eleNdx)
3629                                         if (expected[eleNdx] != actual[eleNdx])
3630                                                 equal = false;
3631                         }
3632                         else {
3633                                 DE_ASSERT(0 && "unhandled type");
3634                         }
3635
3636                         if (!equal)
3637                                 return TestStatus(instance.failResult, instance.getSpecializedFailMessage("fragment output dat point #" + numberToString(posNdx) + " mismatch"));
3638                 }
3639         }
3640
3641         // Check the contents in output resources match with expected.
3642         for (deUint32 outputNdx = 0; outputNdx < numOutResources; ++outputNdx)
3643         {
3644                 const BufferSp& expected = instance.resources.outputs[outputNdx].second;
3645
3646                 if (instance.resources.verifyIO != DE_NULL)
3647                 {
3648                         if (!(*instance.resources.verifyIO)(instance.resources.inputs, outResourceMemories, instance.resources.outputs, context.getTestContext().getLog()))
3649                                 return tcu::TestStatus::fail("Resource returned doesn't match with expected");
3650                 }
3651                 else
3652                 {
3653                         vector<deUint8> expectedBytes;
3654                         expected->getBytes(expectedBytes);
3655
3656                         if (deMemCmp(&expectedBytes.front(), outResourceMemories[outputNdx]->getHostPtr(), expectedBytes.size()))
3657                                 return tcu::TestStatus::fail("Resource returned doesn't match bitwisely with expected");
3658                 }
3659         }
3660
3661         return TestStatus::pass("Rendered output matches input");
3662 }
3663
3664 void createTestsForAllStages (const std::string&                        name,
3665                                                           const RGBA                                    (&inputColors)[4],
3666                                                           const RGBA                                    (&outputColors)[4],
3667                                                           const map<string, string>&    testCodeFragments,
3668                                                           const vector<deInt32>&                specConstants,
3669                                                           const PushConstants&                  pushConstants,
3670                                                           const GraphicsResources&              resources,
3671                                                           const GraphicsInterfaces&             interfaces,
3672                                                           const vector<string>&                 extensions,
3673                                                           const vector<string>&                 features,
3674                                                           VulkanFeatures                                vulkanFeatures,
3675                                                           tcu::TestCaseGroup*                   tests,
3676                                                           const qpTestResult                    failResult,
3677                                                           const string&                                 failMessageTemplate)
3678 {
3679         const ShaderElement             vertFragPipelineStages[]                =
3680         {
3681                 ShaderElement("vert", "main", VK_SHADER_STAGE_VERTEX_BIT),
3682                 ShaderElement("frag", "main", VK_SHADER_STAGE_FRAGMENT_BIT),
3683         };
3684
3685         const ShaderElement             tessPipelineStages[]                    =
3686         {
3687                 ShaderElement("vert", "main", VK_SHADER_STAGE_VERTEX_BIT),
3688                 ShaderElement("tessc", "main", VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT),
3689                 ShaderElement("tesse", "main", VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT),
3690                 ShaderElement("frag", "main", VK_SHADER_STAGE_FRAGMENT_BIT),
3691         };
3692
3693         const ShaderElement             geomPipelineStages[]                            =
3694         {
3695                 ShaderElement("vert", "main", VK_SHADER_STAGE_VERTEX_BIT),
3696                 ShaderElement("geom", "main", VK_SHADER_STAGE_GEOMETRY_BIT),
3697                 ShaderElement("frag", "main", VK_SHADER_STAGE_FRAGMENT_BIT),
3698         };
3699
3700         StageToSpecConstantMap  specConstantMap;
3701
3702         specConstantMap[VK_SHADER_STAGE_VERTEX_BIT] = specConstants;
3703         addFunctionCaseWithPrograms<InstanceContext>(
3704                         tests, name + "_vert", "", addShaderCodeCustomVertex, runAndVerifyDefaultPipeline,
3705                         createInstanceContext(vertFragPipelineStages, inputColors, outputColors, testCodeFragments,
3706                                 specConstantMap, pushConstants, resources, interfaces, extensions, features, vulkanFeatures, vk::VK_SHADER_STAGE_VERTEX_BIT, failResult, failMessageTemplate));
3707
3708         specConstantMap.clear();
3709         specConstantMap[VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT] = specConstants;
3710         addFunctionCaseWithPrograms<InstanceContext>(
3711                         tests, name + "_tessc", "", addShaderCodeCustomTessControl, runAndVerifyDefaultPipeline,
3712                         createInstanceContext(tessPipelineStages, inputColors, outputColors, testCodeFragments,
3713                                 specConstantMap, pushConstants, resources, interfaces, extensions, features, vulkanFeatures, vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, failResult, failMessageTemplate));
3714
3715         specConstantMap.clear();
3716         specConstantMap[VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT] = specConstants;
3717         addFunctionCaseWithPrograms<InstanceContext>(
3718                         tests, name + "_tesse", "", addShaderCodeCustomTessEval, runAndVerifyDefaultPipeline,
3719                         createInstanceContext(tessPipelineStages, inputColors, outputColors, testCodeFragments,
3720                                 specConstantMap, pushConstants, resources, interfaces, extensions, features, vulkanFeatures, vk::VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT, failResult, failMessageTemplate));
3721
3722         specConstantMap.clear();
3723         specConstantMap[VK_SHADER_STAGE_GEOMETRY_BIT] = specConstants;
3724         addFunctionCaseWithPrograms<InstanceContext>(
3725                         tests, name + "_geom", "", addShaderCodeCustomGeometry, runAndVerifyDefaultPipeline,
3726                         createInstanceContext(geomPipelineStages, inputColors, outputColors, testCodeFragments,
3727                                 specConstantMap, pushConstants, resources, interfaces, extensions, features, vulkanFeatures, vk::VK_SHADER_STAGE_GEOMETRY_BIT, failResult, failMessageTemplate));
3728
3729         specConstantMap.clear();
3730         specConstantMap[VK_SHADER_STAGE_FRAGMENT_BIT] = specConstants;
3731         addFunctionCaseWithPrograms<InstanceContext>(
3732                         tests, name + "_frag", "", addShaderCodeCustomFragment, runAndVerifyDefaultPipeline,
3733                         createInstanceContext(vertFragPipelineStages, inputColors, outputColors, testCodeFragments,
3734                                 specConstantMap, pushConstants, resources, interfaces, extensions, features, vulkanFeatures, vk::VK_SHADER_STAGE_FRAGMENT_BIT, failResult, failMessageTemplate));
3735 }
3736
3737 void addTessCtrlTest(tcu::TestCaseGroup* group, const char* name, const map<string, string>& fragments)
3738 {
3739         RGBA defaultColors[4];
3740         getDefaultColors(defaultColors);
3741         const ShaderElement pipelineStages[] =
3742         {
3743                 ShaderElement("vert", "main", VK_SHADER_STAGE_VERTEX_BIT),
3744                 ShaderElement("tessc", "main", VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT),
3745                 ShaderElement("tesse", "main", VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT),
3746                 ShaderElement("frag", "main", VK_SHADER_STAGE_FRAGMENT_BIT),
3747         };
3748
3749         addFunctionCaseWithPrograms<InstanceContext>(
3750                         group, name, "", addShaderCodeCustomTessControl,
3751                         runAndVerifyDefaultPipeline, createInstanceContext(
3752                                 pipelineStages, defaultColors, defaultColors, fragments,
3753                                 StageToSpecConstantMap(), PushConstants(), GraphicsResources(),
3754                                 GraphicsInterfaces(), vector<string>(), vector<string>(),
3755                                 VulkanFeatures(), vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT));
3756 }
3757
3758 } // SpirVAssembly
3759 } // vkt