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