1cddef1bfa42ae565cac554bab0c4fdee1391b73
[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         de::Random(seed).shuffle(instance.inputColors, instance.inputColors+4);
2573         de::Random(seed).shuffle(instance.outputColors, instance.outputColors+4);
2574         const Vec4                                                              vertexData[]                    =
2575         {
2576                 // Upper left corner:
2577                 Vec4(-1.0f, -1.0f, 0.0f, 1.0f), instance.inputColors[0].toVec(),        //1
2578                 Vec4(-0.5f, -1.0f, 0.0f, 1.0f), instance.inputColors[0].toVec(),        //2
2579                 Vec4(-1.0f, -0.5f, 0.0f, 1.0f), instance.inputColors[0].toVec(),        //3
2580
2581                 // Upper right corner:
2582                 Vec4(+0.5f, -1.0f, 0.0f, 1.0f), instance.inputColors[1].toVec(),        //4
2583                 Vec4(+1.0f, -1.0f, 0.0f, 1.0f), instance.inputColors[1].toVec(),        //5
2584                 Vec4(+1.0f, -0.5f, 0.0f, 1.0f), instance.inputColors[1].toVec(),        //6
2585
2586                 // Lower left corner:
2587                 Vec4(-1.0f, +0.5f, 0.0f, 1.0f), instance.inputColors[2].toVec(),        //7
2588                 Vec4(-0.5f, +1.0f, 0.0f, 1.0f), instance.inputColors[2].toVec(),        //8
2589                 Vec4(-1.0f, +1.0f, 0.0f, 1.0f), instance.inputColors[2].toVec(),        //9
2590
2591                 // Lower right corner:
2592                 Vec4(+1.0f, +0.5f, 0.0f, 1.0f), instance.inputColors[3].toVec(),        //10
2593                 Vec4(+1.0f, +1.0f, 0.0f, 1.0f), instance.inputColors[3].toVec(),        //11
2594                 Vec4(+0.5f, +1.0f, 0.0f, 1.0f), instance.inputColors[3].toVec(),        //12
2595
2596                 // The rest is used only renderFullSquare specified. Fills area already filled with clear color
2597                 // Left 1
2598                 Vec4(-1.0f, -0.5f, 0.0f, 1.0f), defaulClearColor,                                       //3
2599                 Vec4(-0.5f, -1.0f, 0.0f, 1.0f), defaulClearColor,                                       //2
2600                 Vec4(-1.0f, +0.5f, 0.0f, 1.0f), defaulClearColor,                                       //7
2601
2602                 // Left 2
2603                 Vec4(-1.0f, +0.5f, 0.0f, 1.0f), defaulClearColor,                                       //7
2604                 Vec4(-0.5f, -1.0f, 0.0f, 1.0f), defaulClearColor,                                       //2
2605                 Vec4(-0.5f, +1.0f, 0.0f, 1.0f), defaulClearColor,                                       //8
2606
2607                 // Left-Center
2608                 Vec4(-0.5f, +1.0f, 0.0f, 1.0f), defaulClearColor,                                       //8
2609                 Vec4(-0.5f, -1.0f, 0.0f, 1.0f), defaulClearColor,                                       //2
2610                 Vec4(+0.5f, -1.0f, 0.0f, 1.0f), defaulClearColor,                                       //4
2611
2612                 // Right-Center
2613                 Vec4(+0.5f, -1.0f, 0.0f, 1.0f), defaulClearColor,                                       //4
2614                 Vec4(+0.5f, +1.0f, 0.0f, 1.0f), defaulClearColor,                                       //12
2615                 Vec4(-0.5f, +1.0f, 0.0f, 1.0f), defaulClearColor,                                       //8
2616
2617                 // Right 2
2618                 Vec4(+0.5f, -1.0f, 0.0f, 1.0f), defaulClearColor,                                       //4
2619                 Vec4(+1.0f, -0.5f, 0.0f, 1.0f), defaulClearColor,                                       //6
2620                 Vec4(+0.5f, +1.0f, 0.0f, 1.0f), defaulClearColor,                                       //12
2621
2622                 // Right 1
2623                 Vec4(+0.5f, +1.0f, 0.0f, 1.0f), defaulClearColor,                                       //12
2624                 Vec4(+1.0f, -0.5f, 0.0f, 1.0f), defaulClearColor,                                       //6
2625                 Vec4(+1.0f, +0.5f, 0.0f, 1.0f), defaulClearColor,                                       //10
2626         };
2627
2628         const size_t                                                    singleVertexDataSize    = 2 * sizeof(Vec4);
2629         const size_t                                                    vertexCount                             = instance.renderFullSquare ? sizeof(vertexData) / singleVertexDataSize : 4*3;
2630         const size_t                                                    vertexDataSize                  = vertexCount * singleVertexDataSize;
2631
2632         Move<VkBuffer>                                                  vertexInputBuffer;
2633         de::MovePtr<Allocation>                                 vertexInputMemory;
2634         Move<VkBuffer>                                                  fragOutputBuffer;
2635         de::MovePtr<Allocation>                                 fragOutputMemory;
2636         Move<VkImage>                                                   fragOutputImage;
2637         de::MovePtr<Allocation>                                 fragOutputImageMemory;
2638         Move<VkImageView>                                               fragOutputImageView;
2639
2640         const VkBufferCreateInfo                                vertexBufferParams              =
2641         {
2642                 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,   //      VkStructureType         sType;
2643                 DE_NULL,                                                                //      const void*                     pNext;
2644                 0u,                                                                             //      VkBufferCreateFlags     flags;
2645                 (VkDeviceSize)vertexDataSize,                   //      VkDeviceSize            size;
2646                 VK_BUFFER_USAGE_VERTEX_BUFFER_BIT,              //      VkBufferUsageFlags      usage;
2647                 VK_SHARING_MODE_EXCLUSIVE,                              //      VkSharingMode           sharingMode;
2648                 1u,                                                                             //      deUint32                        queueFamilyCount;
2649                 &queueFamilyIndex,                                              //      const deUint32*         pQueueFamilyIndices;
2650         };
2651         const Unique<VkBuffer>                                  vertexBuffer                    (createBuffer(vk, device, &vertexBufferParams));
2652         const UniquePtr<Allocation>                             vertexBufferMemory              (allocator.allocate(getBufferMemoryRequirements(vk, device, *vertexBuffer), MemoryRequirement::HostVisible));
2653
2654         VK_CHECK(vk.bindBufferMemory(device, *vertexBuffer, vertexBufferMemory->getMemory(), vertexBufferMemory->getOffset()));
2655
2656         const VkDeviceSize                                              imageSizeBytes                  = (VkDeviceSize)(sizeof(deUint32)*renderSize.x()*renderSize.y());
2657         const VkBufferCreateInfo                                readImageBufferParams   =
2658         {
2659                 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,           //      VkStructureType         sType;
2660                 DE_NULL,                                                                        //      const void*                     pNext;
2661                 0u,                                                                                     //      VkBufferCreateFlags     flags;
2662                 imageSizeBytes,                                                         //      VkDeviceSize            size;
2663                 VK_BUFFER_USAGE_TRANSFER_DST_BIT,                       //      VkBufferUsageFlags      usage;
2664                 VK_SHARING_MODE_EXCLUSIVE,                                      //      VkSharingMode           sharingMode;
2665                 1u,                                                                                     //      deUint32                        queueFamilyCount;
2666                 &queueFamilyIndex,                                                      //      const deUint32*         pQueueFamilyIndices;
2667         };
2668         const Unique<VkBuffer>                                  readImageBuffer                 (createBuffer(vk, device, &readImageBufferParams));
2669         const UniquePtr<Allocation>                             readImageBufferMemory   (allocator.allocate(getBufferMemoryRequirements(vk, device, *readImageBuffer), MemoryRequirement::HostVisible));
2670
2671         VK_CHECK(vk.bindBufferMemory(device, *readImageBuffer, readImageBufferMemory->getMemory(), readImageBufferMemory->getOffset()));
2672
2673         VkImageCreateInfo                                               imageParams                             =
2674         {
2675                 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,                                                                    //      VkStructureType         sType;
2676                 DE_NULL,                                                                                                                                //      const void*                     pNext;
2677                 0u,                                                                                                                                             //      VkImageCreateFlags      flags;
2678                 VK_IMAGE_TYPE_2D,                                                                                                               //      VkImageType                     imageType;
2679                 VK_FORMAT_R8G8B8A8_UNORM,                                                                                               //      VkFormat                        format;
2680                 { renderSize.x(), renderSize.y(), 1 },                                                                  //      VkExtent3D                      extent;
2681                 1u,                                                                                                                                             //      deUint32                        mipLevels;
2682                 1u,                                                                                                                                             //      deUint32                        arraySize;
2683                 VK_SAMPLE_COUNT_1_BIT,                                                                                                  //      deUint32                        samples;
2684                 VK_IMAGE_TILING_OPTIMAL,                                                                                                //      VkImageTiling           tiling;
2685                 VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT|VK_IMAGE_USAGE_TRANSFER_SRC_BIT,    //      VkImageUsageFlags       usage;
2686                 VK_SHARING_MODE_EXCLUSIVE,                                                                                              //      VkSharingMode           sharingMode;
2687                 1u,                                                                                                                                             //      deUint32                        queueFamilyCount;
2688                 &queueFamilyIndex,                                                                                                              //      const deUint32*         pQueueFamilyIndices;
2689                 VK_IMAGE_LAYOUT_UNDEFINED,                                                                                              //      VkImageLayout           initialLayout;
2690         };
2691
2692         const Unique<VkImage>                                   image                                   (createImage(vk, device, &imageParams));
2693         const UniquePtr<Allocation>                             imageMemory                             (allocator.allocate(getImageMemoryRequirements(vk, device, *image), MemoryRequirement::Any));
2694
2695         VK_CHECK(vk.bindImageMemory(device, *image, imageMemory->getMemory(), imageMemory->getOffset()));
2696
2697         if (needInterface)
2698         {
2699                 // The pipeline renders four triangles, each with three vertexes.
2700                 // Test instantialization only provides four data points, each
2701                 // for one triangle. So we need allocate space of three times of
2702                 // input buffer's size.
2703                 vector<deUint8>                                                 inputBufferBytes;
2704                 instance.interfaces.getInputBuffer()->getBytes(inputBufferBytes);
2705
2706                 const deUint32                                                  inputNumBytes                   = deUint32(inputBufferBytes.size() * 3);
2707                 // Create an additional buffer and backing memory for one input variable.
2708                 const VkBufferCreateInfo                                vertexInputParams               =
2709                 {
2710                         VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,           //      VkStructureType         sType;
2711                         DE_NULL,                                                                        //      const void*                     pNext;
2712                         0u,                                                                                     //      VkBufferCreateFlags     flags;
2713                         inputNumBytes,                                                          //      VkDeviceSize            size;
2714                         VK_BUFFER_USAGE_VERTEX_BUFFER_BIT,                      //      VkBufferUsageFlags      usage;
2715                         VK_SHARING_MODE_EXCLUSIVE,                                      //      VkSharingMode           sharingMode;
2716                         1u,                                                                                     //      deUint32                        queueFamilyCount;
2717                         &queueFamilyIndex,                                                      //      const deUint32*         pQueueFamilyIndices;
2718                 };
2719
2720                 vertexInputBuffer = createBuffer(vk, device, &vertexInputParams);
2721                 vertexInputMemory = allocator.allocate(getBufferMemoryRequirements(vk, device, *vertexInputBuffer), MemoryRequirement::HostVisible);
2722                 VK_CHECK(vk.bindBufferMemory(device, *vertexInputBuffer, vertexInputMemory->getMemory(), vertexInputMemory->getOffset()));
2723
2724                 // Create an additional buffer and backing memory for an output variable.
2725                 const VkDeviceSize                                              fragOutputImgSize               = (VkDeviceSize)(instance.interfaces.getOutputType().getNumBytes() * renderSize.x() * renderSize.y());
2726                 const VkBufferCreateInfo                                fragOutputParams                =
2727                 {
2728                         VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,           //      VkStructureType         sType;
2729                         DE_NULL,                                                                        //      const void*                     pNext;
2730                         0u,                                                                                     //      VkBufferCreateFlags     flags;
2731                         fragOutputImgSize,                                                      //      VkDeviceSize            size;
2732                         VK_BUFFER_USAGE_TRANSFER_DST_BIT,                       //      VkBufferUsageFlags      usage;
2733                         VK_SHARING_MODE_EXCLUSIVE,                                      //      VkSharingMode           sharingMode;
2734                         1u,                                                                                     //      deUint32                        queueFamilyCount;
2735                         &queueFamilyIndex,                                                      //      const deUint32*         pQueueFamilyIndices;
2736                 };
2737                 fragOutputBuffer = createBuffer(vk, device, &fragOutputParams);
2738                 fragOutputMemory = allocator.allocate(getBufferMemoryRequirements(vk, device, *fragOutputBuffer), MemoryRequirement::HostVisible);
2739                 VK_CHECK(vk.bindBufferMemory(device, *fragOutputBuffer, fragOutputMemory->getMemory(), fragOutputMemory->getOffset()));
2740
2741                 // Create an additional image and backing memory for attachment.
2742                 // Reuse the previous imageParams since we only need to change the image format.
2743                 imageParams.format              = instance.interfaces.getOutputType().getVkFormat();
2744
2745                 // Check the usage bits on the given image format are supported.
2746                 requireFormatUsageSupport(vkInstance, vkPhysicalDevice, imageParams.format, imageParams.tiling, imageParams.usage);
2747
2748                 fragOutputImage                 = createImage(vk, device, &imageParams);
2749                 fragOutputImageMemory   = allocator.allocate(getImageMemoryRequirements(vk, device, *fragOutputImage), MemoryRequirement::Any);
2750
2751                 VK_CHECK(vk.bindImageMemory(device, *fragOutputImage, fragOutputImageMemory->getMemory(), fragOutputImageMemory->getOffset()));
2752         }
2753
2754         vector<VkAttachmentDescription>                 colorAttDescs;
2755         vector<VkAttachmentReference>                   colorAttRefs;
2756         {
2757                 const VkAttachmentDescription           attDesc                                 =
2758                 {
2759                         0u,                                                                                             //      VkAttachmentDescriptionFlags    flags;
2760                         VK_FORMAT_R8G8B8A8_UNORM,                                               //      VkFormat                                                format;
2761                         VK_SAMPLE_COUNT_1_BIT,                                                  //      deUint32                                                samples;
2762                         VK_ATTACHMENT_LOAD_OP_CLEAR,                                    //      VkAttachmentLoadOp                              loadOp;
2763                         VK_ATTACHMENT_STORE_OP_STORE,                                   //      VkAttachmentStoreOp                             storeOp;
2764                         VK_ATTACHMENT_LOAD_OP_DONT_CARE,                                //      VkAttachmentLoadOp                              stencilLoadOp;
2765                         VK_ATTACHMENT_STORE_OP_DONT_CARE,                               //      VkAttachmentStoreOp                             stencilStoreOp;
2766                         VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,               //      VkImageLayout                                   initialLayout;
2767                         VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,               //      VkImageLayout                                   finalLayout;
2768                 };
2769                 colorAttDescs.push_back(attDesc);
2770
2771                 const VkAttachmentReference                     attRef                                  =
2772                 {
2773                         0u,                                                                                             //      deUint32                attachment;
2774                         VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,               //      VkImageLayout   layout;
2775                 };
2776                 colorAttRefs.push_back(attRef);
2777         }
2778
2779         if (needInterface)
2780         {
2781                 const VkAttachmentDescription           attDesc                                 =
2782                 {
2783                         0u,                                                                                                     //      VkAttachmentDescriptionFlags    flags;
2784                         instance.interfaces.getOutputType().getVkFormat(),      //      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                         1u,                                                                                             //      deUint32                attachment;
2798                         VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,               //      VkImageLayout   layout;
2799                 };
2800                 colorAttRefs.push_back(attRef);
2801         }
2802
2803         VkSubpassDescription                                    subpassDesc                             =
2804         {
2805                 0u,                                                                                             //      VkSubpassDescriptionFlags               flags;
2806                 VK_PIPELINE_BIND_POINT_GRAPHICS,                                //      VkPipelineBindPoint                             pipelineBindPoint;
2807                 0u,                                                                                             //      deUint32                                                inputCount;
2808                 DE_NULL,                                                                                //      const VkAttachmentReference*    pInputAttachments;
2809                 1u,                                                                                             //      deUint32                                                colorCount;
2810                 colorAttRefs.data(),                                                    //      const VkAttachmentReference*    pColorAttachments;
2811                 DE_NULL,                                                                                //      const VkAttachmentReference*    pResolveAttachments;
2812                 DE_NULL,                                                                                //      const VkAttachmentReference*    pDepthStencilAttachment;
2813                 0u,                                                                                             //      deUint32                                                preserveCount;
2814                 DE_NULL,                                                                                //      const VkAttachmentReference*    pPreserveAttachments;
2815
2816         };
2817         VkRenderPassCreateInfo                                  renderPassParams                =
2818         {
2819                 VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,              //      VkStructureType                                 sType;
2820                 DE_NULL,                                                                                //      const void*                                             pNext;
2821                 (VkRenderPassCreateFlags)0,
2822                 1u,                                                                                             //      deUint32                                                attachmentCount;
2823                 colorAttDescs.data(),                                                   //      const VkAttachmentDescription*  pAttachments;
2824                 1u,                                                                                             //      deUint32                                                subpassCount;
2825                 &subpassDesc,                                                                   //      const VkSubpassDescription*             pSubpasses;
2826                 0u,                                                                                             //      deUint32                                                dependencyCount;
2827                 DE_NULL,                                                                                //      const VkSubpassDependency*              pDependencies;
2828         };
2829
2830         if (needInterface)
2831         {
2832                 subpassDesc.colorAttachmentCount += 1;
2833                 renderPassParams.attachmentCount += 1;
2834         }
2835
2836         const Unique<VkRenderPass>                              renderPass                              (createRenderPass(vk, device, &renderPassParams));
2837
2838         const VkImageViewCreateInfo                             colorAttViewParams              =
2839         {
2840                 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,               //      VkStructureType                         sType;
2841                 DE_NULL,                                                                                //      const void*                                     pNext;
2842                 0u,                                                                                             //      VkImageViewCreateFlags          flags;
2843                 *image,                                                                                 //      VkImage                                         image;
2844                 VK_IMAGE_VIEW_TYPE_2D,                                                  //      VkImageViewType                         viewType;
2845                 VK_FORMAT_R8G8B8A8_UNORM,                                               //      VkFormat                                        format;
2846                 {
2847                         VK_COMPONENT_SWIZZLE_R,
2848                         VK_COMPONENT_SWIZZLE_G,
2849                         VK_COMPONENT_SWIZZLE_B,
2850                         VK_COMPONENT_SWIZZLE_A
2851                 },                                                                                              //      VkChannelMapping                        channels;
2852                 {
2853                         VK_IMAGE_ASPECT_COLOR_BIT,                                              //      VkImageAspectFlags      aspectMask;
2854                         0u,                                                                                             //      deUint32                        baseMipLevel;
2855                         1u,                                                                                             //      deUint32                        mipLevels;
2856                         0u,                                                                                             //      deUint32                        baseArrayLayer;
2857                         1u,                                                                                             //      deUint32                        arraySize;
2858                 },                                                                                              //      VkImageSubresourceRange         subresourceRange;
2859         };
2860         const Unique<VkImageView>                               colorAttView                    (createImageView(vk, device, &colorAttViewParams));
2861         const VkImageAspectFlags                                inputImageAspect                = getImageAspectFlags(instance.resources.inputFormat);
2862
2863         vector<VkImageView>                                             attViews;
2864         attViews.push_back(*colorAttView);
2865
2866         // Handle resources requested by the test instantiation.
2867         const deUint32                                                  numInResources                  = static_cast<deUint32>(instance.resources.inputs.size());
2868         const deUint32                                                  numOutResources                 = static_cast<deUint32>(instance.resources.outputs.size());
2869         // These variables should be placed out of the following if block to avoid deallocation after out of scope.
2870         vector<AllocationSp>                                    inResourceMemories;
2871         vector<AllocationSp>                                    outResourceMemories;
2872         vector<BufferHandleSp>                                  inResourceBuffers;
2873         vector<BufferHandleSp>                                  outResourceBuffers;
2874         vector<ImageHandleSp>                                   inResourceImages;
2875         vector<ImageViewHandleSp>                               inResourceImageViews;
2876         vector<SamplerHandleSp>                                 inResourceSamplers;
2877         Move<VkDescriptorPool>                                  descriptorPool;
2878         Move<VkDescriptorSetLayout>                             setLayout;
2879         VkDescriptorSetLayout                                   rawSetLayout                    = DE_NULL;
2880         VkDescriptorSet                                                 rawSet                                  = DE_NULL;
2881
2882         const Unique<VkCommandPool>                             cmdPool                                 (createCommandPool(vk, device, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, queueFamilyIndex));
2883
2884         // Command buffer
2885         const Unique<VkCommandBuffer>                   cmdBuf                                  (allocateCommandBuffer(vk, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
2886
2887         if (numResources != 0)
2888         {
2889                 vector<VkDescriptorSetLayoutBinding>    setLayoutBindings;
2890                 vector<VkDescriptorPoolSize>                    poolSizes;
2891
2892                 setLayoutBindings.reserve(numResources);
2893                 poolSizes.reserve(numResources);
2894
2895                 // Process all input resources.
2896                 for (deUint32 inputNdx = 0; inputNdx < numInResources; ++inputNdx)
2897                 {
2898                         const Resource& resource        = instance.resources.inputs[inputNdx];
2899
2900                         const bool              hasImage        = (resource.getDescriptorType() == VK_DESCRIPTOR_TYPE_STORAGE_IMAGE)    ||
2901                                                                                   (resource.getDescriptorType() == VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE)    ||
2902                                                                                   (resource.getDescriptorType() == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER);
2903
2904                         const bool              hasSampler      = (resource.getDescriptorType() == VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE)    ||
2905                                                                                   (resource.getDescriptorType() == VK_DESCRIPTOR_TYPE_SAMPLER)                  ||
2906                                                                                   (resource.getDescriptorType() == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER);
2907
2908                         // Resource is a buffer
2909                         if (!hasImage && !hasSampler)
2910                         {
2911                                 Move<VkBuffer>                                  resourceBuffer                  = createBufferForResource(vk, device, resource, queueFamilyIndex);
2912                                 de::MovePtr<Allocation>                 resourceMemory                  = allocator.allocate(getBufferMemoryRequirements(vk, device, *resourceBuffer), MemoryRequirement::HostVisible);
2913
2914                                 VK_CHECK(vk.bindBufferMemory(device, *resourceBuffer, resourceMemory->getMemory(), resourceMemory->getOffset()));
2915
2916                                 // Copy data to memory.
2917                                 {
2918                                         const VkMappedMemoryRange               range                                   =
2919                                         {
2920                                                 VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE,                          //      VkStructureType sType;
2921                                                 DE_NULL,                                                                                        //      const void*             pNext;
2922                                                 resourceMemory->getMemory(),                                            //      VkDeviceMemory  mem;
2923                                                 0,                                                                                                      //      VkDeviceSize    offset;
2924                                                 VK_WHOLE_SIZE,                                                                          //      VkDeviceSize    size;
2925                                         };
2926
2927                                         vector<deUint8>                                 resourceBytes;
2928                                         resource.getBytes(resourceBytes);
2929
2930                                         deMemcpy(resourceMemory->getHostPtr(), &resourceBytes.front(), resourceBytes.size());
2931                                         VK_CHECK(vk.flushMappedMemoryRanges(device, 1u, &range));
2932                                 }
2933
2934                                 inResourceMemories.push_back(AllocationSp(resourceMemory.release()));
2935                                 inResourceBuffers.push_back(BufferHandleSp(new BufferHandleUp(resourceBuffer)));
2936                         }
2937                         // Resource is an image
2938                         else if (hasImage)
2939                         {
2940                                 Move<VkBuffer>                                  resourceBuffer                  = createBufferForResource(vk, device, resource, queueFamilyIndex);
2941                                 de::MovePtr<Allocation>                 resourceMemory                  = allocator.allocate(getBufferMemoryRequirements(vk, device, *resourceBuffer), MemoryRequirement::HostVisible);
2942
2943                                 VK_CHECK(vk.bindBufferMemory(device, *resourceBuffer, resourceMemory->getMemory(), resourceMemory->getOffset()));
2944
2945                                 // Copy data to memory.
2946                                 {
2947                                         const VkMappedMemoryRange               range                                   =
2948                                         {
2949                                                 VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE,                          //      VkStructureType sType;
2950                                                 DE_NULL,                                                                                        //      const void*             pNext;
2951                                                 resourceMemory->getMemory(),                                            //      VkDeviceMemory  mem;
2952                                                 0,                                                                                                      //      VkDeviceSize    offset;
2953                                                 VK_WHOLE_SIZE,                                                                          //      VkDeviceSize    size;
2954                                         };
2955
2956                                         vector<deUint8>                                 resourceBytes;
2957                                         resource.getBytes(resourceBytes);
2958
2959                                         deMemcpy(resourceMemory->getHostPtr(), &resourceBytes.front(), resourceBytes.size());
2960                                         VK_CHECK(vk.flushMappedMemoryRanges(device, 1u, &range));
2961                                 }
2962
2963                                 Move<VkImage>                                   resourceImage                   = createImageForResource(vk, device, resource, instance.resources.inputFormat, queueFamilyIndex);
2964                                 de::MovePtr<Allocation>                 resourceImageMemory             = allocator.allocate(getImageMemoryRequirements(vk, device, *resourceImage), MemoryRequirement::Any);
2965
2966                                 VK_CHECK(vk.bindImageMemory(device, *resourceImage, resourceImageMemory->getMemory(), resourceImageMemory->getOffset()));
2967
2968                                 copyBufferToImage(vk, device, queue, *cmdBuf, resourceBuffer.get(), resourceImage.get(), inputImageAspect);
2969
2970                                 inResourceMemories.push_back(AllocationSp(resourceImageMemory.release()));
2971                                 inResourceImages.push_back(ImageHandleSp(new ImageHandleUp(resourceImage)));
2972                         }
2973
2974                         // Prepare descriptor bindings and pool sizes for creating descriptor set layout and pool.
2975                         const VkDescriptorSetLayoutBinding      binding                         =
2976                         {
2977                                 inputNdx,                                                                                       // binding
2978                                 resource.getDescriptorType(),                                           // descriptorType
2979                                 1u,                                                                                                     // descriptorCount
2980                                 VK_SHADER_STAGE_ALL_GRAPHICS,                                           // stageFlags
2981                                 DE_NULL,                                                                                        // pImmutableSamplers
2982                         };
2983                         setLayoutBindings.push_back(binding);
2984
2985                         // Note: the following code doesn't check and unify descriptors of the same type.
2986                         const VkDescriptorPoolSize              poolSize                                =
2987                         {
2988                                 resource.getDescriptorType(),                                           // type
2989                                 1u,                                                                                                     // descriptorCount
2990                         };
2991                         poolSizes.push_back(poolSize);
2992                 }
2993
2994                 // Process all output resources.
2995                 for (deUint32 outputNdx = 0; outputNdx < numOutResources; ++outputNdx)
2996                 {
2997                         const Resource&                                 resource                                = instance.resources.outputs[outputNdx];
2998                         // Create buffer and allocate memory.
2999                         Move<VkBuffer>                                  resourceBuffer                  = createBufferForResource(vk, device, resource, queueFamilyIndex);
3000                         de::MovePtr<Allocation>                 resourceMemory                  = allocator.allocate(getBufferMemoryRequirements(vk, device, *resourceBuffer), MemoryRequirement::HostVisible);
3001                         vector<deUint8>                                 resourceBytes;
3002
3003                         VK_CHECK(vk.bindBufferMemory(device, *resourceBuffer, resourceMemory->getMemory(), resourceMemory->getOffset()));
3004
3005                         // Fill memory with all ones.
3006                         const VkMappedMemoryRange               range                                   =
3007                         {
3008                                 VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE,                          //      VkStructureType sType;
3009                                 DE_NULL,                                                                                        //      const void*             pNext;
3010                                 resourceMemory->getMemory(),                                            //      VkDeviceMemory  mem;
3011                                 0,                                                                                                      //      VkDeviceSize    offset;
3012                                 VK_WHOLE_SIZE,                                                                          //      VkDeviceSize    size;
3013                         };
3014
3015                         resource.getBytes(resourceBytes);
3016                         deMemset((deUint8*)resourceMemory->getHostPtr(), 0xff, resourceBytes.size());
3017                         VK_CHECK(vk.flushMappedMemoryRanges(device, 1u, &range));
3018
3019                         outResourceMemories.push_back(AllocationSp(resourceMemory.release()));
3020                         outResourceBuffers.push_back(BufferHandleSp(new BufferHandleUp(resourceBuffer)));
3021
3022                         // Prepare descriptor bindings and pool sizes for creating descriptor set layout and pool.
3023                         const VkDescriptorSetLayoutBinding      binding                         =
3024                         {
3025                                 numInResources  + outputNdx,                                            // binding
3026                                 resource.getDescriptorType(),                                           // descriptorType
3027                                 1u,                                                                                                     // descriptorCount
3028                                 VK_SHADER_STAGE_ALL_GRAPHICS,                                           // stageFlags
3029                                 DE_NULL,                                                                                        // pImmutableSamplers
3030                         };
3031                         setLayoutBindings.push_back(binding);
3032
3033                         // Note: the following code doesn't check and unify descriptors of the same type.
3034                         const VkDescriptorPoolSize              poolSize                                =
3035                         {
3036                                 resource.getDescriptorType(),                                           // type
3037                                 1u,                                                                                                     // descriptorCount
3038                         };
3039                         poolSizes.push_back(poolSize);
3040                 }
3041
3042                 // Create descriptor set layout, descriptor pool, and allocate descriptor set.
3043                 const VkDescriptorSetLayoutCreateInfo   setLayoutParams         =
3044                 {
3045                         VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,    // sType
3046                         DE_NULL,                                                                                                // pNext
3047                         (VkDescriptorSetLayoutCreateFlags)0,                                    // flags
3048                         numResources,                                                                                   // bindingCount
3049                         setLayoutBindings.data(),                                                               // pBindings
3050                 };
3051                 setLayout                                                                                                       = createDescriptorSetLayout(vk, device, &setLayoutParams);
3052                 rawSetLayout                                                                                            = *setLayout;
3053
3054                 const VkDescriptorPoolCreateInfo                poolParams                      =
3055                 {
3056                         VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,                  // sType
3057                         DE_NULL,                                                                                                // pNext
3058                         (VkDescriptorPoolCreateFlags)0,                                                 // flags
3059                         1u,                                                                                                             // maxSets
3060                         numResources,                                                                                   // poolSizeCount
3061                         poolSizes.data(),                                                                               // pPoolSizes
3062                 };
3063                 descriptorPool                                                                                          = createDescriptorPool(vk, device, &poolParams);
3064
3065                 const VkDescriptorSetAllocateInfo               setAllocParams          =
3066                 {
3067                         VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,                 // sType
3068                         DE_NULL,                                                                                                // pNext
3069                         *descriptorPool,                                                                                // descriptorPool
3070                         1u,                                                                                                             // descriptorSetCount
3071                         &rawSetLayout,                                                                                  // pSetLayouts
3072                 };
3073                 VK_CHECK(vk.allocateDescriptorSets(device, &setAllocParams, &rawSet));
3074
3075                 // Update descriptor set.
3076                 vector<VkWriteDescriptorSet>                    writeSpecs;
3077                 vector<VkDescriptorBufferInfo>                  dBufferInfos;
3078                 vector<VkDescriptorImageInfo>                   dImageInfos;
3079
3080                 writeSpecs.reserve(numResources);
3081                 dBufferInfos.reserve(numResources);
3082                 dImageInfos.reserve(numResources);
3083
3084                 deUint32                                                                imgResourceNdx          = 0u;
3085                 deUint32                                                                bufResourceNdx          = 0u;
3086
3087                 for (deUint32 inputNdx = 0; inputNdx < numInResources; ++inputNdx)
3088                 {
3089                         const Resource& resource        = instance.resources.inputs[inputNdx];
3090
3091                         const bool              hasImage        = (resource.getDescriptorType() == VK_DESCRIPTOR_TYPE_STORAGE_IMAGE)    ||
3092                                                                                   (resource.getDescriptorType() == VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE)    ||
3093                                                                                   (resource.getDescriptorType() == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER);
3094
3095                         const bool              hasSampler      = (resource.getDescriptorType() == VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE)    ||
3096                                                                                   (resource.getDescriptorType() == VK_DESCRIPTOR_TYPE_SAMPLER)                  ||
3097                                                                                   (resource.getDescriptorType() == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER);
3098
3099                         // Create image view and sampler
3100                         if (hasImage || hasSampler)
3101                         {
3102                                 if (resource.getDescriptorType() != VK_DESCRIPTOR_TYPE_SAMPLER)
3103                                 {
3104                                         const VkImageViewCreateInfo     imgViewParams   =
3105                                         {
3106                                                 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,       //      VkStructureType                         sType;
3107                                                 DE_NULL,                                                                        //      const void*                                     pNext;
3108                                                 0u,                                                                                     //      VkImageViewCreateFlags          flags;
3109                                                 **inResourceImages[imgResourceNdx++],           //      VkImage                                         image;
3110                                                 VK_IMAGE_VIEW_TYPE_2D,                                          //      VkImageViewType                         viewType;
3111                                                 instance.resources.inputFormat,                         //      VkFormat                                        format;
3112                                                 {
3113                                                         VK_COMPONENT_SWIZZLE_R,
3114                                                         VK_COMPONENT_SWIZZLE_G,
3115                                                         VK_COMPONENT_SWIZZLE_B,
3116                                                         VK_COMPONENT_SWIZZLE_A
3117                                                 },                                                                                      //      VkComponentMapping                      channels;
3118                                                 {
3119                                                         inputImageAspect,       //      VkImageAspectFlags      aspectMask;
3120                                                         0u,                                     //      deUint32                        baseMipLevel;
3121                                                         1u,                                     //      deUint32                        mipLevels;
3122                                                         0u,                                     //      deUint32                        baseArrayLayer;
3123                                                         1u,                                     //      deUint32                        arraySize;
3124                                                 },                                                                                      //      VkImageSubresourceRange         subresourceRange;
3125                                         };
3126
3127                                         Move<VkImageView>                       imgView                 (createImageView(vk, device, &imgViewParams));
3128                                         inResourceImageViews.push_back(ImageViewHandleSp(new ImageViewHandleUp(imgView)));
3129                                 }
3130
3131                                 if (hasSampler)
3132                                 {
3133                                         const bool                                      hasDepthComponent       = tcu::hasDepthComponent(vk::mapVkFormat(instance.resources.inputFormat).order);
3134                                         const VkSamplerCreateInfo       samplerParams           =
3135                                         {
3136                                                 VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO,          // VkStructureType                      sType;
3137                                                 DE_NULL,                                                                        // const void*                          pNext;
3138                                                 0,                                                                                      // VkSamplerCreateFlags         flags;
3139                                                 VK_FILTER_NEAREST,                                                      // VkFilter                                     magFilter:
3140                                                 VK_FILTER_NEAREST,                                                      // VkFilter                                     minFilter;
3141                                                 VK_SAMPLER_MIPMAP_MODE_NEAREST,                         // VkSamplerMipmapMode          mipmapMode;
3142                                                 VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,          // VkSamplerAddressMode         addressModeU;
3143                                                 VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,          // VkSamplerAddressMode         addressModeV;
3144                                                 VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,          // VkSamplerAddressMode         addressModeW;
3145                                                 0.0f,                                                                           // float                                        mipLodBias;
3146                                                 VK_FALSE,                                                                       // VkBool32                                     anistoropyÉnable;
3147                                                 1.0f,                                                                           // float                                        maxAnisotropy;
3148                                                 (hasDepthComponent) ? VK_TRUE : VK_FALSE,       // VkBool32                                     compareEnable;
3149                                                 VK_COMPARE_OP_LESS,                                                     // VkCompareOp                          compareOp;
3150                                                 0.0f,                                                                           // float                                        minLod;
3151                                                 0.0f,                                                                           // float                                        maxLod;
3152                                                 VK_BORDER_COLOR_INT_OPAQUE_BLACK,                       // VkBorderColor                        borderColor;
3153                                                 VK_FALSE                                                                        // VkBool32                                     unnormalizedCoordinates;
3154                                         };
3155
3156                                         Move<VkSampler>                         sampler                 (createSampler(vk, device, &samplerParams));
3157                                         inResourceSamplers.push_back(SamplerHandleSp(new SamplerHandleUp(sampler)));
3158                                 }
3159                         }
3160
3161                         // Create descriptor buffer and image infos
3162                         switch (resource.getDescriptorType())
3163                         {
3164                                 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
3165                                 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
3166                                 {
3167                                         const VkDescriptorBufferInfo    bufInfo =
3168                                         {
3169                                                 **inResourceBuffers[bufResourceNdx++],                          // buffer
3170                                                 0,                                                                                                      // offset
3171                                                 VK_WHOLE_SIZE,                                                                          // size
3172                                         };
3173                                         dBufferInfos.push_back(bufInfo);
3174                                         break;
3175                                 }
3176                                 case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
3177                                 case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
3178                                 {
3179                                         const VkDescriptorImageInfo             imgInfo =
3180                                         {
3181                                                 DE_NULL,                                                                                                // sampler
3182                                                 **inResourceImageViews.back(),                                                  // imageView
3183                                                 VK_IMAGE_LAYOUT_GENERAL                                                                 // imageLayout
3184                                         };
3185                                         dImageInfos.push_back(imgInfo);
3186                                         break;
3187                                 }
3188                                 case VK_DESCRIPTOR_TYPE_SAMPLER:
3189                                 {
3190                                         const VkDescriptorImageInfo             imgInfo =
3191                                         {
3192                                                 **inResourceSamplers.back(),                                                    // sampler
3193                                                 DE_NULL,                                                                                                // imageView
3194                                                 VK_IMAGE_LAYOUT_GENERAL                                                                 // imageLayout
3195                                         };
3196                                         dImageInfos.push_back(imgInfo);
3197                                         break;
3198                                 }
3199                                 case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
3200                                 {
3201
3202                                         const VkDescriptorImageInfo             imgInfo =
3203                                         {
3204                                                 **inResourceSamplers.back(),                                                    // sampler
3205                                                 **inResourceImageViews.back(),                                                  // imageView
3206                                                 VK_IMAGE_LAYOUT_GENERAL                                                                 // imageLayout
3207                                         };
3208                                         dImageInfos.push_back(imgInfo);
3209                                         break;
3210                                 }
3211                                 default:
3212                                         DE_FATAL("Not implemented");
3213                         }
3214
3215                         const VkWriteDescriptorSet                      writeSpec                       = {
3216                                 VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,                                                 // sType
3217                                 DE_NULL,                                                                                                                // pNext
3218                                 rawSet,                                                                                                                 // dstSet
3219                                 inputNdx,                                                                                                               // binding
3220                                 0,                                                                                                                              // dstArrayElement
3221                                 1u,                                                                                                                             // descriptorCount
3222                                 instance.resources.inputs[inputNdx].getDescriptorType(),                // descriptorType
3223                                 ( (hasImage | hasSampler)       ? &dImageInfos.back()   : DE_NULL),     // pImageInfo
3224                                 (!(hasImage | hasSampler)       ? &dBufferInfos.back()  : DE_NULL),     // pBufferInfo
3225                                 DE_NULL,                                                                                                                // pTexelBufferView
3226                         };
3227                         writeSpecs.push_back(writeSpec);
3228                 }
3229
3230                 for (deUint32 outputNdx = 0; outputNdx < numOutResources; ++outputNdx)
3231                 {
3232                         const VkDescriptorBufferInfo            bufInfo                         =
3233                         {
3234                                 **outResourceBuffers[outputNdx],                                        // buffer
3235                                 0,                                                                                                      // offset
3236                                 VK_WHOLE_SIZE,                                                                          // size
3237                         };
3238                         dBufferInfos.push_back(bufInfo);
3239
3240                         const VkWriteDescriptorSet                      writeSpec                       = {
3241                                 VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,                                         // sType
3242                                 DE_NULL,                                                                                                        // pNext
3243                                 rawSet,                                                                                                         // dstSet
3244                                 numInResources + outputNdx,                                                                     // binding
3245                                 0,                                                                                                                      // dstArrayElement
3246                                 1u,                                                                                                                     // descriptorCount
3247                                 instance.resources.outputs[outputNdx].getDescriptorType(),      // descriptorType
3248                                 DE_NULL,                                                                                                        // pImageInfo
3249                                 &dBufferInfos.back(),                                                                           // pBufferInfo
3250                                 DE_NULL,                                                                                                        // pTexelBufferView
3251                         };
3252                         writeSpecs.push_back(writeSpec);
3253                 }
3254                 vk.updateDescriptorSets(device, numResources, writeSpecs.data(), 0, DE_NULL);
3255         }
3256
3257         // Pipeline layout
3258         VkPipelineLayoutCreateInfo                              pipelineLayoutParams    =
3259         {
3260                 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,                  //      VkStructureType                                 sType;
3261                 DE_NULL,                                                                                                //      const void*                                             pNext;
3262                 (VkPipelineLayoutCreateFlags)0,
3263                 0u,                                                                                                             //      deUint32                                                descriptorSetCount;
3264                 DE_NULL,                                                                                                //      const VkDescriptorSetLayout*    pSetLayouts;
3265                 0u,                                                                                                             //      deUint32                                                pushConstantRangeCount;
3266                 DE_NULL,                                                                                                //      const VkPushConstantRange*              pPushConstantRanges;
3267         };
3268
3269         VkPushConstantRange                                             pushConstantRange               =
3270         {
3271                 VK_SHADER_STAGE_ALL_GRAPHICS,                                                   // VkShaderStageFlags    stageFlags;
3272                 0,                                                                                                              // uint32_t              offset;
3273                 0,                                                                                                              // uint32_t              size;
3274         };
3275         if (hasPushConstants)
3276         {
3277                 vector<deUint8> pushConstantsBytes;
3278                 instance.pushConstants.getBuffer()->getBytes(pushConstantsBytes);
3279
3280                 pushConstantRange.size                                          = static_cast<deUint32>(pushConstantsBytes.size());
3281                 pipelineLayoutParams.pushConstantRangeCount     = 1;
3282                 pipelineLayoutParams.pPushConstantRanges        = &pushConstantRange;
3283         }
3284         if (numResources != 0)
3285         {
3286                 // Update pipeline layout with the descriptor set layout.
3287                 pipelineLayoutParams.setLayoutCount                                                             = 1;
3288                 pipelineLayoutParams.pSetLayouts                                                                = &rawSetLayout;
3289         }
3290         const Unique<VkPipelineLayout>                  pipelineLayout                  (createPipelineLayout(vk, device, &pipelineLayoutParams));
3291
3292         // Pipeline
3293         vector<VkPipelineShaderStageCreateInfo>         shaderStageParams;
3294         // We need these vectors to make sure that information about specialization constants for each stage can outlive createGraphicsPipeline().
3295         vector<vector<VkSpecializationMapEntry> >       specConstantEntries;
3296         vector<VkSpecializationInfo>                            specializationInfos;
3297         if (DE_NULL != instance.resources.verifyBinary)
3298         {
3299                 std::string shaderName;
3300                 switch(instance.customizedStages)
3301                 {
3302                 case    VK_SHADER_STAGE_VERTEX_BIT:
3303                         shaderName= "vert";
3304                         break;
3305                 case    VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT:
3306                         shaderName= "tessc";
3307                         break;
3308                 case    VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT:
3309                         shaderName= "tesse";
3310                         break;
3311                 case    VK_SHADER_STAGE_GEOMETRY_BIT:
3312                         shaderName= "geom";
3313                         break;
3314                 case    VK_SHADER_STAGE_FRAGMENT_BIT:
3315                         shaderName= "frag";
3316                         break;
3317                 default:
3318                         DE_ASSERT(0);
3319                         break;
3320                 }
3321                 const ProgramBinary& binary  = context.getBinaryCollection().get(shaderName);
3322                 if (!instance.resources.verifyBinary(binary))
3323                         return tcu::TestStatus::fail("Binary verification of SPIR-V in the test failed");
3324
3325         }
3326         createPipelineShaderStages(vk, device, instance, context, modules, shaderStageParams);
3327
3328         // And we don't want the reallocation of these vectors to invalidate pointers pointing to their contents.
3329         specConstantEntries.reserve(shaderStageParams.size());
3330         specializationInfos.reserve(shaderStageParams.size());
3331
3332         // Patch the specialization info field in PipelineShaderStageCreateInfos.
3333         for (vector<VkPipelineShaderStageCreateInfo>::iterator stageInfo = shaderStageParams.begin(); stageInfo != shaderStageParams.end(); ++stageInfo)
3334         {
3335                 const StageToSpecConstantMap::const_iterator stageIt = instance.specConstants.find(stageInfo->stage);
3336
3337                 if (stageIt != instance.specConstants.end())
3338                 {
3339                         const size_t                                            numSpecConstants        = stageIt->second.getValuesCount();
3340                         vector<VkSpecializationMapEntry>        entries;
3341                         VkSpecializationInfo                            specInfo;
3342                         size_t                                                          offset                          = 0;
3343
3344                         entries.resize(numSpecConstants);
3345
3346                         // Constant IDs are numbered sequentially starting from 0.
3347                         for (size_t ndx = 0; ndx < numSpecConstants; ++ndx)
3348                         {
3349                                 const size_t valueSize  = stageIt->second.getValueSize(ndx);
3350
3351                                 entries[ndx].constantID = (deUint32)ndx;
3352                                 entries[ndx].offset             = static_cast<deUint32>(offset);
3353                                 entries[ndx].size               = valueSize;
3354
3355                                 offset                                  += valueSize;
3356                         }
3357
3358                         specConstantEntries.push_back(entries);
3359
3360                         specInfo.mapEntryCount  = (deUint32)numSpecConstants;
3361                         specInfo.pMapEntries    = specConstantEntries.back().data();
3362                         specInfo.dataSize               = offset;
3363                         specInfo.pData                  = stageIt->second.getValuesBuffer();
3364                         specializationInfos.push_back(specInfo);
3365
3366                         stageInfo->pSpecializationInfo = &specializationInfos.back();
3367                 }
3368         }
3369         const VkPipelineDepthStencilStateCreateInfo     depthStencilParams              =
3370         {
3371                 VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO,     //      VkStructureType         sType;
3372                 DE_NULL,                                                                                                        //      const void*                     pNext;
3373                 (VkPipelineDepthStencilStateCreateFlags)0,
3374                 DE_FALSE,                                                                                                       //      deUint32                        depthTestEnable;
3375                 DE_FALSE,                                                                                                       //      deUint32                        depthWriteEnable;
3376                 VK_COMPARE_OP_ALWAYS,                                                                           //      VkCompareOp                     depthCompareOp;
3377                 DE_FALSE,                                                                                                       //      deUint32                        depthBoundsTestEnable;
3378                 DE_FALSE,                                                                                                       //      deUint32                        stencilTestEnable;
3379                 {
3380                         VK_STENCIL_OP_KEEP,                                                                                     //      VkStencilOp     stencilFailOp;
3381                         VK_STENCIL_OP_KEEP,                                                                                     //      VkStencilOp     stencilPassOp;
3382                         VK_STENCIL_OP_KEEP,                                                                                     //      VkStencilOp     stencilDepthFailOp;
3383                         VK_COMPARE_OP_ALWAYS,                                                                           //      VkCompareOp     stencilCompareOp;
3384                         0u,                                                                                                                     //      deUint32        stencilCompareMask;
3385                         0u,                                                                                                                     //      deUint32        stencilWriteMask;
3386                         0u,                                                                                                                     //      deUint32        stencilReference;
3387                 },                                                                                                                      //      VkStencilOpState        front;
3388                 {
3389                         VK_STENCIL_OP_KEEP,                                                                                     //      VkStencilOp     stencilFailOp;
3390                         VK_STENCIL_OP_KEEP,                                                                                     //      VkStencilOp     stencilPassOp;
3391                         VK_STENCIL_OP_KEEP,                                                                                     //      VkStencilOp     stencilDepthFailOp;
3392                         VK_COMPARE_OP_ALWAYS,                                                                           //      VkCompareOp     stencilCompareOp;
3393                         0u,                                                                                                                     //      deUint32        stencilCompareMask;
3394                         0u,                                                                                                                     //      deUint32        stencilWriteMask;
3395                         0u,                                                                                                                     //      deUint32        stencilReference;
3396                 },                                                                                                                      //      VkStencilOpState        back;
3397                 -1.0f,                                                                                                          //      float                           minDepthBounds;
3398                 +1.0f,                                                                                                          //      float                           maxDepthBounds;
3399         };
3400         const VkViewport                                                        viewport0                               = makeViewport(renderSize);
3401         const VkRect2D                                                          scissor0                                = makeRect2D(renderSize);
3402         const VkPipelineViewportStateCreateInfo         viewportParams                  =
3403         {
3404                 VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO,          //      VkStructureType         sType;
3405                 DE_NULL,                                                                                                        //      const void*                     pNext;
3406                 (VkPipelineViewportStateCreateFlags)0,
3407                 1u,                                                                                                                     //      deUint32                        viewportCount;
3408                 &viewport0,
3409                 1u,
3410                 &scissor0
3411         };
3412         const VkSampleMask                                                      sampleMask                              = ~0u;
3413         const VkPipelineMultisampleStateCreateInfo      multisampleParams               =
3414         {
3415                 VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,       //      VkStructureType                 sType;
3416                 DE_NULL,                                                                                                        //      const void*                             pNext;
3417                 (VkPipelineMultisampleStateCreateFlags)0,
3418                 VK_SAMPLE_COUNT_1_BIT,                                                                          //      VkSampleCountFlagBits   rasterSamples;
3419                 DE_FALSE,                                                                                                       //      deUint32                                sampleShadingEnable;
3420                 0.0f,                                                                                                           //      float                                   minSampleShading;
3421                 &sampleMask,                                                                                            //      const VkSampleMask*             pSampleMask;
3422                 DE_FALSE,                                                                                                       //      VkBool32                                alphaToCoverageEnable;
3423                 DE_FALSE,                                                                                                       //      VkBool32                                alphaToOneEnable;
3424         };
3425         const VkPipelineRasterizationStateCreateInfo    rasterParams            =
3426         {
3427                 VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO,     //      VkStructureType sType;
3428                 DE_NULL,                                                                                                        //      const void*             pNext;
3429                 (VkPipelineRasterizationStateCreateFlags)0,
3430                 DE_FALSE,                                                                                                       //      deUint32                depthClampEnable;
3431                 DE_FALSE,                                                                                                       //      deUint32                rasterizerDiscardEnable;
3432                 VK_POLYGON_MODE_FILL,                                                                           //      VkFillMode              fillMode;
3433                 VK_CULL_MODE_NONE,                                                                                      //      VkCullMode              cullMode;
3434                 VK_FRONT_FACE_COUNTER_CLOCKWISE,                                                        //      VkFrontFace             frontFace;
3435                 VK_FALSE,                                                                                                       //      VkBool32                depthBiasEnable;
3436                 0.0f,                                                                                                           //      float                   depthBias;
3437                 0.0f,                                                                                                           //      float                   depthBiasClamp;
3438                 0.0f,                                                                                                           //      float                   slopeScaledDepthBias;
3439                 1.0f,                                                                                                           //      float                   lineWidth;
3440         };
3441         const VkPrimitiveTopology topology = hasTessellation? VK_PRIMITIVE_TOPOLOGY_PATCH_LIST: VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
3442         const VkPipelineInputAssemblyStateCreateInfo    inputAssemblyParams     =
3443         {
3444                 VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,    //      VkStructureType         sType;
3445                 DE_NULL,                                                                                                                //      const void*                     pNext;
3446                 (VkPipelineInputAssemblyStateCreateFlags)0,
3447                 topology,                                                                                                               //      VkPrimitiveTopology     topology;
3448                 DE_FALSE,                                                                                                               //      deUint32                        primitiveRestartEnable;
3449         };
3450
3451         vector<VkVertexInputBindingDescription>         vertexBindings;
3452         vector<VkVertexInputAttributeDescription>       vertexAttribs;
3453
3454         const VkVertexInputBindingDescription           vertexBinding0                  =
3455         {
3456                 0u,                                                                     // deUint32                                     binding;
3457                 deUint32(singleVertexDataSize),         // deUint32                                     strideInBytes;
3458                 VK_VERTEX_INPUT_RATE_VERTEX                     // VkVertexInputStepRate        stepRate;
3459         };
3460         vertexBindings.push_back(vertexBinding0);
3461
3462         {
3463                 VkVertexInputAttributeDescription               attr0                                   =
3464                 {
3465                         0u,                                                                     // deUint32     location;
3466                         0u,                                                                     // deUint32     binding;
3467                         VK_FORMAT_R32G32B32A32_SFLOAT,          // VkFormat     format;
3468                         0u                                                                      // deUint32     offsetInBytes;
3469                 };
3470                 vertexAttribs.push_back(attr0);
3471
3472                 VkVertexInputAttributeDescription               attr1                                   =
3473                 {
3474                         1u,                                                                     // deUint32     location;
3475                         0u,                                                                     // deUint32     binding;
3476                         VK_FORMAT_R32G32B32A32_SFLOAT,          // VkFormat     format;
3477                         sizeof(Vec4),                                           // deUint32     offsetInBytes;
3478                 };
3479                 vertexAttribs.push_back(attr1);
3480         };
3481
3482         // If the test instantiation has additional input/output interface variables, we need to create additional bindings.
3483         // Right now we only support one additional input varible for the vertex stage, and that will be bound to binding #1
3484         // with location #2.
3485         if (needInterface)
3486         {
3487                 const VkVertexInputBindingDescription   vertexBinding1                  =
3488                 {
3489                         1u,                                                                                                     // deUint32                                     binding;
3490                         instance.interfaces.getInputType().getNumBytes(),       // deUint32                                     strideInBytes;
3491                         VK_VERTEX_INPUT_RATE_VERTEX                                                     // VkVertexInputStepRate        stepRate;
3492                 };
3493                 vertexBindings.push_back(vertexBinding1);
3494
3495                 VkVertexInputAttributeDescription               attr                                    =
3496                 {
3497                         2u,                                                                                                     // deUint32     location;
3498                         1u,                                                                                                     // deUint32     binding;
3499                         instance.interfaces.getInputType().getVkFormat(),       // VkFormat     format;
3500                         0,                                                                                                      // deUint32     offsetInBytes;
3501                 };
3502                 vertexAttribs.push_back(attr);
3503         }
3504
3505         VkPipelineVertexInputStateCreateInfo            vertexInputStateParams  =
3506         {
3507                 VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,      //      VkStructureType                                                         sType;
3508                 DE_NULL,                                                                                                        //      const void*                                                                     pNext;
3509                 (VkPipelineVertexInputStateCreateFlags)0,
3510                 1u,                                                                                                                     //      deUint32                                                                        bindingCount;
3511                 vertexBindings.data(),                                                                          //      const VkVertexInputBindingDescription*          pVertexBindingDescriptions;
3512                 2u,                                                                                                                     //      deUint32                                                                        attributeCount;
3513                 vertexAttribs.data(),                                                                           //      const VkVertexInputAttributeDescription*        pVertexAttributeDescriptions;
3514         };
3515
3516         if (needInterface)
3517         {
3518                 vertexInputStateParams.vertexBindingDescriptionCount += 1;
3519                 vertexInputStateParams.vertexAttributeDescriptionCount += 1;
3520         }
3521
3522         vector<VkPipelineColorBlendAttachmentState>     attBlendStates;
3523         const VkPipelineColorBlendAttachmentState       attBlendState                   =
3524         {
3525                 DE_FALSE,                                                                                                       //      deUint32                blendEnable;
3526                 VK_BLEND_FACTOR_ONE,                                                                            //      VkBlend                 srcBlendColor;
3527                 VK_BLEND_FACTOR_ZERO,                                                                           //      VkBlend                 destBlendColor;
3528                 VK_BLEND_OP_ADD,                                                                                        //      VkBlendOp               blendOpColor;
3529                 VK_BLEND_FACTOR_ONE,                                                                            //      VkBlend                 srcBlendAlpha;
3530                 VK_BLEND_FACTOR_ZERO,                                                                           //      VkBlend                 destBlendAlpha;
3531                 VK_BLEND_OP_ADD,                                                                                        //      VkBlendOp               blendOpAlpha;
3532                 (VK_COLOR_COMPONENT_R_BIT|
3533                  VK_COLOR_COMPONENT_G_BIT|
3534                  VK_COLOR_COMPONENT_B_BIT|
3535                  VK_COLOR_COMPONENT_A_BIT),                                                                     //      VkChannelFlags  channelWriteMask;
3536         };
3537         attBlendStates.push_back(attBlendState);
3538
3539         if (needInterface)
3540                 attBlendStates.push_back(attBlendState);
3541
3542         VkPipelineColorBlendStateCreateInfo             blendParams                             =
3543         {
3544                 VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,       //      VkStructureType                                                         sType;
3545                 DE_NULL,                                                                                                        //      const void*                                                                     pNext;
3546                 (VkPipelineColorBlendStateCreateFlags)0,
3547                 DE_FALSE,                                                                                                       //      VkBool32                                                                        logicOpEnable;
3548                 VK_LOGIC_OP_COPY,                                                                                       //      VkLogicOp                                                                       logicOp;
3549                 1u,                                                                                                                     //      deUint32                                                                        attachmentCount;
3550                 attBlendStates.data(),                                                                          //      const VkPipelineColorBlendAttachmentState*      pAttachments;
3551                 { 0.0f, 0.0f, 0.0f, 0.0f },                                                                     //      float                                                                           blendConst[4];
3552         };
3553         if (needInterface)
3554         {
3555                 blendParams.attachmentCount += 1;
3556         }
3557         const VkPipelineTessellationStateCreateInfo     tessellationState       =
3558         {
3559                 VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO,
3560                 DE_NULL,
3561                 (VkPipelineTessellationStateCreateFlags)0,
3562                 3u
3563         };
3564
3565         const VkPipelineTessellationStateCreateInfo* tessellationInfo   =       hasTessellation ? &tessellationState: DE_NULL;
3566         const VkGraphicsPipelineCreateInfo              pipelineParams                  =
3567         {
3568                 VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,                //      VkStructureType                                                                 sType;
3569                 DE_NULL,                                                                                                //      const void*                                                                             pNext;
3570                 0u,                                                                                                             //      VkPipelineCreateFlags                                                   flags;
3571                 (deUint32)shaderStageParams.size(),                                             //      deUint32                                                                                stageCount;
3572                 &shaderStageParams[0],                                                                  //      const VkPipelineShaderStageCreateInfo*                  pStages;
3573                 &vertexInputStateParams,                                                                //      const VkPipelineVertexInputStateCreateInfo*             pVertexInputState;
3574                 &inputAssemblyParams,                                                                   //      const VkPipelineInputAssemblyStateCreateInfo*   pInputAssemblyState;
3575                 tessellationInfo,                                                                               //      const VkPipelineTessellationStateCreateInfo*    pTessellationState;
3576                 &viewportParams,                                                                                //      const VkPipelineViewportStateCreateInfo*                pViewportState;
3577                 &rasterParams,                                                                                  //      const VkPipelineRasterStateCreateInfo*                  pRasterState;
3578                 &multisampleParams,                                                                             //      const VkPipelineMultisampleStateCreateInfo*             pMultisampleState;
3579                 &depthStencilParams,                                                                    //      const VkPipelineDepthStencilStateCreateInfo*    pDepthStencilState;
3580                 &blendParams,                                                                                   //      const VkPipelineColorBlendStateCreateInfo*              pColorBlendState;
3581                 (const VkPipelineDynamicStateCreateInfo*)DE_NULL,               //      const VkPipelineDynamicStateCreateInfo*                 pDynamicState;
3582                 *pipelineLayout,                                                                                //      VkPipelineLayout                                                                layout;
3583                 *renderPass,                                                                                    //      VkRenderPass                                                                    renderPass;
3584                 0u,                                                                                                             //      deUint32                                                                                subpass;
3585                 DE_NULL,                                                                                                //      VkPipeline                                                                              basePipelineHandle;
3586                 0u,                                                                                                             //      deInt32                                                                                 basePipelineIndex;
3587         };
3588
3589         const Unique<VkPipeline>                                pipeline                                (createGraphicsPipeline(vk, device, DE_NULL, &pipelineParams));
3590
3591         if (needInterface)
3592         {
3593                 const VkImageViewCreateInfo                     fragOutputViewParams    =
3594                 {
3595                         VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,                       //      VkStructureType                         sType;
3596                         DE_NULL,                                                                                        //      const void*                                     pNext;
3597                         0u,                                                                                                     //      VkImageViewCreateFlags          flags;
3598                         *fragOutputImage,                                                                       //      VkImage                                         image;
3599                         VK_IMAGE_VIEW_TYPE_2D,                                                          //      VkImageViewType                         viewType;
3600                         instance.interfaces.getOutputType().getVkFormat(),      //      VkFormat                                        format;
3601                         {
3602                                 VK_COMPONENT_SWIZZLE_R,
3603                                 VK_COMPONENT_SWIZZLE_G,
3604                                 VK_COMPONENT_SWIZZLE_B,
3605                                 VK_COMPONENT_SWIZZLE_A
3606                         },                                                                                                      //      VkChannelMapping                        channels;
3607                         {
3608                                 VK_IMAGE_ASPECT_COLOR_BIT,                                              //      VkImageAspectFlags      aspectMask;
3609                                 0u,                                                                                             //      deUint32                        baseMipLevel;
3610                                 1u,                                                                                             //      deUint32                        mipLevels;
3611                                 0u,                                                                                             //      deUint32                        baseArrayLayer;
3612                                 1u,                                                                                             //      deUint32                        arraySize;
3613                         },                                                                                                      //      VkImageSubresourceRange         subresourceRange;
3614                 };
3615                 fragOutputImageView = createImageView(vk, device, &fragOutputViewParams);
3616                 attViews.push_back(*fragOutputImageView);
3617         }
3618
3619         // Framebuffer
3620         VkFramebufferCreateInfo                                 framebufferParams               =
3621         {
3622                 VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,                              //      VkStructureType         sType;
3623                 DE_NULL,                                                                                                //      const void*                     pNext;
3624                 (VkFramebufferCreateFlags)0,
3625                 *renderPass,                                                                                    //      VkRenderPass            renderPass;
3626                 1u,                                                                                                             //      deUint32                        attachmentCount;
3627                 attViews.data(),                                                                                //      const VkImageView*      pAttachments;
3628                 (deUint32)renderSize.x(),                                                               //      deUint32                        width;
3629                 (deUint32)renderSize.y(),                                                               //      deUint32                        height;
3630                 1u,                                                                                                             //      deUint32                        layers;
3631         };
3632
3633         if (needInterface)
3634                 framebufferParams.attachmentCount += 1;
3635
3636         const Unique<VkFramebuffer>                             framebuffer                             (createFramebuffer(vk, device, &framebufferParams));
3637
3638         // Record commands
3639         beginCommandBuffer(vk, *cmdBuf);
3640
3641         {
3642                 const VkMemoryBarrier                   vertFlushBarrier        =
3643                 {
3644                         VK_STRUCTURE_TYPE_MEMORY_BARRIER,                       //      VkStructureType         sType;
3645                         DE_NULL,                                                                        //      const void*                     pNext;
3646                         VK_ACCESS_HOST_WRITE_BIT,                                       //      VkMemoryOutputFlags     outputMask;
3647                         VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT,            //      VkMemoryInputFlags      inputMask;
3648                 };
3649                 vector<VkImageMemoryBarrier>    colorAttBarriers;
3650
3651                 VkImageMemoryBarrier                    imgBarrier          =
3652                 {
3653                         VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,         //      VkStructureType                 sType;
3654                         DE_NULL,                                                                        //      const void*                             pNext;
3655                         0u,                                                                                     //      VkMemoryOutputFlags             outputMask;
3656                         VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,           //      VkMemoryInputFlags              inputMask;
3657                         VK_IMAGE_LAYOUT_UNDEFINED,                                      //      VkImageLayout                   oldLayout;
3658                         VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,       //      VkImageLayout                   newLayout;
3659                         queueFamilyIndex,                                                       //      deUint32                                srcQueueFamilyIndex;
3660                         queueFamilyIndex,                                                       //      deUint32                                destQueueFamilyIndex;
3661                         *image,                                                                         //      VkImage                                 image;
3662                         {
3663                                 VK_IMAGE_ASPECT_COLOR_BIT,                                      //      VkImageAspect   aspect;
3664                                 0u,                                                                                     //      deUint32                baseMipLevel;
3665                                 1u,                                                                                     //      deUint32                mipLevels;
3666                                 0u,                                                                                     //      deUint32                baseArraySlice;
3667                                 1u,                                                                                     //      deUint32                arraySize;
3668                         }                                                                                       //      VkImageSubresourceRange subresourceRange;
3669                 };
3670                 colorAttBarriers.push_back(imgBarrier);
3671                 if (needInterface)
3672                 {
3673                         imgBarrier.image = *fragOutputImage;
3674                         colorAttBarriers.push_back(imgBarrier);
3675                         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());
3676                 }
3677                 else
3678                 {
3679                         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());
3680                 }
3681         }
3682
3683         {
3684                 vector<VkClearValue>                    clearValue;
3685                 clearValue.push_back(makeClearValueColorF32(defaulClearColor[0], defaulClearColor[1], defaulClearColor[2], defaulClearColor[3]));
3686                 if (needInterface)
3687                 {
3688                         clearValue.push_back(makeClearValueColorU32(0, 0, 0, 0));
3689                 }
3690                 beginRenderPass(vk, *cmdBuf, *renderPass, *framebuffer, makeRect2D(0, 0, renderSize.x(), renderSize.y()), (deUint32)clearValue.size(), clearValue.data());
3691         }
3692
3693         vk.cmdBindPipeline(*cmdBuf, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipeline);
3694         {
3695                 const VkDeviceSize bindingOffset = 0;
3696                 vk.cmdBindVertexBuffers(*cmdBuf, 0u, 1u, &vertexBuffer.get(), &bindingOffset);
3697         }
3698         if (needInterface)
3699         {
3700                 const VkDeviceSize bindingOffset = 0;
3701                 vk.cmdBindVertexBuffers(*cmdBuf, 1u, 1u, &vertexInputBuffer.get(), &bindingOffset);
3702         }
3703         if (hasPushConstants)
3704         {
3705                 vector<deUint8> pushConstantsBytes;
3706                 instance.pushConstants.getBuffer()->getBytes(pushConstantsBytes);
3707
3708                 const deUint32  size    = static_cast<deUint32>(pushConstantsBytes.size());
3709                 const void*             data    = &pushConstantsBytes.front();
3710
3711                 vk.cmdPushConstants(*cmdBuf, *pipelineLayout, VK_SHADER_STAGE_ALL_GRAPHICS, 0, size, data);
3712         }
3713         if (numResources != 0)
3714         {
3715                 // Bind to set number 0.
3716                 vk.cmdBindDescriptorSets(*cmdBuf, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipelineLayout, 0, 1, &rawSet, 0, DE_NULL);
3717         }
3718         vk.cmdDraw(*cmdBuf, deUint32(vertexCount), 1u /*run pipeline once*/, 0u /*first vertex*/, 0u /*first instanceIndex*/);
3719         endRenderPass(vk, *cmdBuf);
3720
3721         {
3722                 vector<VkImageMemoryBarrier>    renderFinishBarrier;
3723                 VkImageMemoryBarrier                    imgBarrier                              =
3724                 {
3725                         VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,         //      VkStructureType                 sType;
3726                         DE_NULL,                                                                        //      const void*                             pNext;
3727                         VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,           //      VkMemoryOutputFlags             outputMask;
3728                         VK_ACCESS_TRANSFER_READ_BIT,                            //      VkMemoryInputFlags              inputMask;
3729                         VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,       //      VkImageLayout                   oldLayout;
3730                         VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,           //      VkImageLayout                   newLayout;
3731                         queueFamilyIndex,                                                       //      deUint32                                srcQueueFamilyIndex;
3732                         queueFamilyIndex,                                                       //      deUint32                                destQueueFamilyIndex;
3733                         *image,                                                                         //      VkImage                                 image;
3734                         {
3735                                 VK_IMAGE_ASPECT_COLOR_BIT,                                      //      VkImageAspectFlags      aspectMask;
3736                                 0u,                                                                                     //      deUint32                        baseMipLevel;
3737                                 1u,                                                                                     //      deUint32                        mipLevels;
3738                                 0u,                                                                                     //      deUint32                        baseArraySlice;
3739                                 1u,                                                                                     //      deUint32                        arraySize;
3740                         }                                                                                       //      VkImageSubresourceRange subresourceRange;
3741                 };
3742                 renderFinishBarrier.push_back(imgBarrier);
3743
3744                 if (needInterface)
3745                 {
3746                         imgBarrier.image = *fragOutputImage;
3747                         renderFinishBarrier.push_back(imgBarrier);
3748                         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());
3749                 }
3750                 else
3751                 {
3752                         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());
3753                 }
3754         }
3755
3756         {
3757                 const VkBufferImageCopy copyParams      =
3758                 {
3759                         (VkDeviceSize)0u,                                               //      VkDeviceSize                    bufferOffset;
3760                         (deUint32)renderSize.x(),                               //      deUint32                                bufferRowLength;
3761                         (deUint32)renderSize.y(),                               //      deUint32                                bufferImageHeight;
3762                         {
3763                                 VK_IMAGE_ASPECT_COLOR_BIT,                              //      VkImageAspect           aspect;
3764                                 0u,                                                                             //      deUint32                        mipLevel;
3765                                 0u,                                                                             //      deUint32                        arrayLayer;
3766                                 1u,                                                                             //      deUint32                        arraySize;
3767                         },                                                                              //      VkImageSubresourceCopy  imageSubresource;
3768                         { 0u, 0u, 0u },                                                 //      VkOffset3D                              imageOffset;
3769                         { renderSize.x(), renderSize.y(), 1u }  //      VkExtent3D                              imageExtent;
3770                 };
3771                 vk.cmdCopyImageToBuffer(*cmdBuf, *image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *readImageBuffer, 1u, &copyParams);
3772
3773                 if (needInterface)
3774                 {
3775                         vk.cmdCopyImageToBuffer(*cmdBuf, *fragOutputImage, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *fragOutputBuffer, 1u, &copyParams);
3776                 }
3777         }
3778
3779         {
3780                 vector<VkBufferMemoryBarrier> cpFinishBarriers;
3781                 VkBufferMemoryBarrier                   copyFinishBarrier       =
3782                 {
3783                         VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,        //      VkStructureType         sType;
3784                         DE_NULL,                                                                        //      const void*                     pNext;
3785                         VK_ACCESS_TRANSFER_WRITE_BIT,                           //      VkMemoryOutputFlags     outputMask;
3786                         VK_ACCESS_HOST_READ_BIT,                                        //      VkMemoryInputFlags      inputMask;
3787                         queueFamilyIndex,                                                       //      deUint32                        srcQueueFamilyIndex;
3788                         queueFamilyIndex,                                                       //      deUint32                        destQueueFamilyIndex;
3789                         *readImageBuffer,                                                       //      VkBuffer                        buffer;
3790                         0u,                                                                                     //      VkDeviceSize            offset;
3791                         imageSizeBytes                                                          //      VkDeviceSize            size;
3792                 };
3793                 cpFinishBarriers.push_back(copyFinishBarrier);
3794
3795                 if (needInterface)
3796                 {
3797                         copyFinishBarrier.buffer        = *fragOutputBuffer;
3798                         copyFinishBarrier.size          = VK_WHOLE_SIZE;
3799                         cpFinishBarriers.push_back(copyFinishBarrier);
3800
3801                         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);
3802                 }
3803                 else
3804                 {
3805                         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);
3806                 }
3807         }
3808
3809         endCommandBuffer(vk, *cmdBuf);
3810
3811         // Upload vertex data
3812         {
3813                 const VkMappedMemoryRange       range                   =
3814                 {
3815                         VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE,  //      VkStructureType sType;
3816                         DE_NULL,                                                                //      const void*             pNext;
3817                         vertexBufferMemory->getMemory(),                //      VkDeviceMemory  mem;
3818                         0,                                                                              //      VkDeviceSize    offset;
3819                         (VkDeviceSize)vertexDataSize,                   //      VkDeviceSize    size;
3820                 };
3821                 void*                                           vertexBufPtr    = vertexBufferMemory->getHostPtr();
3822
3823                 deMemcpy(vertexBufPtr, &vertexData[0], vertexDataSize);
3824                 VK_CHECK(vk.flushMappedMemoryRanges(device, 1u, &range));
3825         }
3826
3827         if (needInterface)
3828         {
3829                 vector<deUint8> inputBufferBytes;
3830                 instance.interfaces.getInputBuffer()->getBytes(inputBufferBytes);
3831
3832                 const deUint32                          typNumBytes             = instance.interfaces.getInputType().getNumBytes();
3833                 const deUint32                          bufNumBytes             = static_cast<deUint32>(inputBufferBytes.size());
3834
3835                 // Require that the test instantation provides four output values.
3836                 DE_ASSERT(bufNumBytes == 4 * typNumBytes);
3837
3838                 // We have four triangles. Because interpolation happens before executing the fragment shader,
3839                 // we need to provide the same vertex attribute for the same triangle. That means, duplicate each
3840                 // value three times for all four values.
3841
3842                 const deUint8*                          provided                = static_cast<const deUint8*>(&inputBufferBytes.front());
3843                 vector<deUint8>                         data;
3844
3845                 data.reserve(3 * bufNumBytes);
3846
3847                 for (deUint32 offset = 0; offset < bufNumBytes; offset += typNumBytes)
3848                         for (deUint32 vertexNdx = 0; vertexNdx < 3; ++vertexNdx)
3849                                 for (deUint32 byteNdx = 0; byteNdx < typNumBytes; ++byteNdx)
3850                                         data.push_back(provided[offset + byteNdx]);
3851
3852                 deMemcpy(vertexInputMemory->getHostPtr(), data.data(), data.size());
3853
3854                 const VkMappedMemoryRange       range                   =
3855                 {
3856                         VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE,  //      VkStructureType sType;
3857                         DE_NULL,                                                                //      const void*             pNext;
3858                         vertexInputMemory->getMemory(),                 //      VkDeviceMemory  mem;
3859                         0,                                                                              //      VkDeviceSize    offset;
3860                         VK_WHOLE_SIZE,                                                  //      VkDeviceSize    size;
3861                 };
3862
3863                 VK_CHECK(vk.flushMappedMemoryRanges(device, 1u, &range));
3864         }
3865
3866         // Submit & wait for completion
3867         submitCommandsAndWait(vk, device, queue, cmdBuf.get());
3868
3869         const void* imagePtr    = readImageBufferMemory->getHostPtr();
3870         const tcu::ConstPixelBufferAccess pixelBuffer(tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8),
3871                                                                                                   renderSize.x(), renderSize.y(), 1, imagePtr);
3872         // Log image
3873         {
3874                 const VkMappedMemoryRange       range           =
3875                 {
3876                         VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE,  //      VkStructureType sType;
3877                         DE_NULL,                                                                //      const void*             pNext;
3878                         readImageBufferMemory->getMemory(),             //      VkDeviceMemory  mem;
3879                         0,                                                                              //      VkDeviceSize    offset;
3880                         imageSizeBytes,                                                 //      VkDeviceSize    size;
3881                 };
3882
3883                 VK_CHECK(vk.invalidateMappedMemoryRanges(device, 1u, &range));
3884                 context.getTestContext().getLog() << TestLog::Image("Result", "Result", pixelBuffer);
3885         }
3886
3887         if (needInterface)
3888         {
3889                 const VkDeviceSize                      fragOutputImgSize       = (VkDeviceSize)(instance.interfaces.getOutputType().getNumBytes() * renderSize.x() * renderSize.y());
3890                 const VkMappedMemoryRange       range                           =
3891                 {
3892                         VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE,  //      VkStructureType sType;
3893                         DE_NULL,                                                                //      const void*             pNext;
3894                         fragOutputMemory->getMemory(),                  //      VkDeviceMemory  mem;
3895                         0,                                                                              //      VkDeviceSize    offset;
3896                         fragOutputImgSize,                                              //      VkDeviceSize    size;
3897                 };
3898
3899                 VK_CHECK(vk.invalidateMappedMemoryRanges(device, 1u, &range));
3900         }
3901
3902         { // Make sure all output resources are ready.
3903                 for (deUint32 outputNdx = 0; outputNdx < numOutResources; ++outputNdx)
3904                 {
3905                         const VkMappedMemoryRange       range   =
3906                         {
3907                                 VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE,                  //      VkStructureType sType;
3908                                 DE_NULL,                                                                                //      const void*             pNext;
3909                                 outResourceMemories[outputNdx]->getMemory(),    //      VkDeviceMemory  mem;
3910                                 0,                                                                                              //      VkDeviceSize    offset;
3911                                 VK_WHOLE_SIZE,                                                                  //      VkDeviceSize    size;
3912                         };
3913
3914                         VK_CHECK(vk.invalidateMappedMemoryRanges(device, 1u, &range));
3915                 }
3916         }
3917
3918         const RGBA threshold(1, 1, 1, 1);
3919
3920         const RGBA upperLeft(pixelBuffer.getPixel(1, 1));
3921         if (!tcu::compareThreshold(upperLeft, instance.outputColors[0], threshold))
3922                 return TestStatus(instance.failResult, instance.getSpecializedFailMessage("Upper left corner mismatch"));
3923
3924         const RGBA upperRight(pixelBuffer.getPixel(pixelBuffer.getWidth() - 1, 1));
3925         if (!tcu::compareThreshold(upperRight, instance.outputColors[1], threshold))
3926                 return TestStatus(instance.failResult, instance.getSpecializedFailMessage("Upper right corner mismatch"));
3927
3928         const RGBA lowerLeft(pixelBuffer.getPixel(1, pixelBuffer.getHeight() - 1));
3929         if (!tcu::compareThreshold(lowerLeft, instance.outputColors[2], threshold))
3930                 return TestStatus(instance.failResult, instance.getSpecializedFailMessage("Lower left corner mismatch"));
3931
3932         const RGBA lowerRight(pixelBuffer.getPixel(pixelBuffer.getWidth() - 1, pixelBuffer.getHeight() - 1));
3933         if (!tcu::compareThreshold(lowerRight, instance.outputColors[3], threshold))
3934                 return TestStatus(instance.failResult, instance.getSpecializedFailMessage("Lower right corner mismatch"));
3935
3936         // Check that the contents in the ouput variable matches expected.
3937         if (needInterface)
3938         {
3939                 vector<deUint8>                                         inputBufferBytes;
3940                 vector<deUint8>                                         outputBufferBytes;
3941
3942                 instance.interfaces.getInputBuffer()->getBytes(inputBufferBytes);
3943                 instance.interfaces.getOutputBuffer()->getBytes(outputBufferBytes);
3944
3945                 const IFDataType&                                       inputType                               = instance.interfaces.getInputType();
3946                 const IFDataType&                                       outputType                              = instance.interfaces.getOutputType();
3947                 const void*                                                     inputData                               = &inputBufferBytes.front();
3948                 const void*                                                     outputData                              = &outputBufferBytes.front();
3949                 vector<std::pair<int, int> >            positions;
3950                 const tcu::ConstPixelBufferAccess       fragOutputBufferAccess  (outputType.getTextureFormat(), renderSize.x(), renderSize.y(), 1, fragOutputMemory->getHostPtr());
3951
3952                 positions.push_back(std::make_pair(1, 1));
3953                 positions.push_back(std::make_pair(fragOutputBufferAccess.getWidth() - 1, 1));
3954                 positions.push_back(std::make_pair(1, fragOutputBufferAccess.getHeight() - 1));
3955                 positions.push_back(std::make_pair(fragOutputBufferAccess.getWidth() - 1, fragOutputBufferAccess.getHeight() - 1));
3956
3957                 for (deUint32 posNdx = 0; posNdx < positions.size(); ++posNdx)
3958                 {
3959                         const int       x               = positions[posNdx].first;
3960                         const int       y               = positions[posNdx].second;
3961                         bool            equal   = true;
3962
3963                         if (outputType.elementType == NUMBERTYPE_FLOAT32)
3964                         {
3965                                 const float*            expected        = static_cast<const float*>(outputData) + posNdx * outputType.numElements;
3966                                 const float*            actual          = static_cast<const float*>(fragOutputBufferAccess.getPixelPtr(x, y));
3967
3968                                 for (deUint32 eleNdx = 0; eleNdx < outputType.numElements; ++eleNdx)
3969                                         if (!compare32BitFloat(expected[eleNdx], actual[eleNdx], context.getTestContext().getLog()))
3970                                                 equal = false;
3971                         }
3972                         else if (outputType.elementType == NUMBERTYPE_INT32)
3973                         {
3974                                 const deInt32*          expected        = static_cast<const deInt32*>(outputData) + posNdx * outputType.numElements;
3975                                 const deInt32*          actual          = static_cast<const deInt32*>(fragOutputBufferAccess.getPixelPtr(x, y));
3976
3977                                 for (deUint32 eleNdx = 0; eleNdx < outputType.numElements; ++eleNdx)
3978                                         if (expected[eleNdx] != actual[eleNdx])
3979                                                 equal = false;
3980                         }
3981                         else if (outputType.elementType == NUMBERTYPE_UINT32)
3982                         {
3983                                 const deUint32*         expected        = static_cast<const deUint32*>(outputData) + posNdx * outputType.numElements;
3984                                 const deUint32*         actual          = static_cast<const deUint32*>(fragOutputBufferAccess.getPixelPtr(x, y));
3985
3986                                 for (deUint32 eleNdx = 0; eleNdx < outputType.numElements; ++eleNdx)
3987                                         if (expected[eleNdx] != actual[eleNdx])
3988                                                 equal = false;
3989                         }
3990                         else if (outputType.elementType == NUMBERTYPE_FLOAT16 && inputType.elementType == NUMBERTYPE_FLOAT64)
3991                         {
3992                                 const double*           original        = static_cast<const double*>(inputData) + posNdx * outputType.numElements;
3993                                 const deFloat16*        actual          = static_cast<const deFloat16*>(fragOutputBufferAccess.getPixelPtr(x, y));
3994
3995                                 for (deUint32 eleNdx = 0; eleNdx < outputType.numElements; ++eleNdx)
3996                                         if (!compare16BitFloat64(original[eleNdx], actual[eleNdx], instance.interfaces.getRoundingMode(), context.getTestContext().getLog()))
3997                                                 equal = false;
3998                         }
3999                         else if (outputType.elementType == NUMBERTYPE_FLOAT16 && inputType.elementType != NUMBERTYPE_FLOAT64)
4000                         {
4001                                 if (inputType.elementType == NUMBERTYPE_FLOAT16)
4002                                 {
4003                                         const deFloat16*        original        = static_cast<const deFloat16*>(inputData) + posNdx * outputType.numElements;
4004                                         const deFloat16*        actual          = static_cast<const deFloat16*>(fragOutputBufferAccess.getPixelPtr(x, y));
4005
4006                                         for (deUint32 eleNdx = 0; eleNdx < outputType.numElements; ++eleNdx)
4007                                                 if (!compare16BitFloat(original[eleNdx], actual[eleNdx], context.getTestContext().getLog()))
4008                                                         equal = false;
4009                                 }
4010                                 else
4011                                 {
4012                                         const float*            original        = static_cast<const float*>(inputData) + posNdx * outputType.numElements;
4013                                         const deFloat16*        actual          = static_cast<const deFloat16*>(fragOutputBufferAccess.getPixelPtr(x, y));
4014
4015                                         for (deUint32 eleNdx = 0; eleNdx < outputType.numElements; ++eleNdx)
4016                                                 if (!compare16BitFloat(original[eleNdx], actual[eleNdx], instance.interfaces.getRoundingMode(), context.getTestContext().getLog()))
4017                                                         equal = false;
4018                                 }
4019                         }
4020                         else if (outputType.elementType == NUMBERTYPE_INT16)
4021                         {
4022                                 const deInt16*          expected        = static_cast<const deInt16*>(outputData) + posNdx * outputType.numElements;
4023                                 const deInt16*          actual          = static_cast<const deInt16*>(fragOutputBufferAccess.getPixelPtr(x, y));
4024
4025                                 for (deUint32 eleNdx = 0; eleNdx < outputType.numElements; ++eleNdx)
4026                                         if (expected[eleNdx] != actual[eleNdx])
4027                                                 equal = false;
4028                         }
4029                         else if (outputType.elementType == NUMBERTYPE_UINT16)
4030                         {
4031                                 const deUint16*         expected        = static_cast<const deUint16*>(outputData) + posNdx * outputType.numElements;
4032                                 const deUint16*         actual          = static_cast<const deUint16*>(fragOutputBufferAccess.getPixelPtr(x, y));
4033
4034                                 for (deUint32 eleNdx = 0; eleNdx < outputType.numElements; ++eleNdx)
4035                                         if (expected[eleNdx] != actual[eleNdx])
4036                                                 equal = false;
4037                         }
4038                         else if (outputType.elementType == NUMBERTYPE_FLOAT64)
4039                         {
4040                                 const double*           expected        = static_cast<const double*>(outputData) + posNdx * outputType.numElements;
4041                                 const double*           actual          = static_cast<const double*>(fragOutputBufferAccess.getPixelPtr(x, y));
4042
4043                                 for (deUint32 eleNdx = 0; eleNdx < outputType.numElements; ++eleNdx)
4044                                         if (!compare64BitFloat(expected[eleNdx], actual[eleNdx], context.getTestContext().getLog()))
4045                                                 equal = false;
4046                         }
4047                         else {
4048                                 DE_ASSERT(0 && "unhandled type");
4049                         }
4050
4051                         if (!equal)
4052                                 return TestStatus(instance.failResult, instance.getSpecializedFailMessage("fragment output dat point #" + numberToString(posNdx) + " mismatch"));
4053                 }
4054         }
4055
4056         // Check the contents in output resources match with expected.
4057         for (deUint32 outputNdx = 0; outputNdx < numOutResources; ++outputNdx)
4058         {
4059                 const BufferSp& expected = instance.resources.outputs[outputNdx].getBuffer();
4060
4061                 if (instance.resources.verifyIO != DE_NULL)
4062                 {
4063                         if (!(*instance.resources.verifyIO)(instance.resources.inputs, outResourceMemories, instance.resources.outputs, context.getTestContext().getLog()))
4064                                 return tcu::TestStatus::fail("Resource returned doesn't match with expected");
4065                 }
4066                 else
4067                 {
4068                         vector<deUint8> expectedBytes;
4069                         expected->getBytes(expectedBytes);
4070
4071                         if (deMemCmp(&expectedBytes.front(), outResourceMemories[outputNdx]->getHostPtr(), expectedBytes.size()))
4072                                 return tcu::TestStatus::fail("Resource returned doesn't match bitwisely with expected");
4073
4074                 }
4075         }
4076
4077         return TestStatus::pass("Rendered output matches input");
4078 }
4079
4080 const vector<ShaderElement>& getVertFragPipelineStages (void)
4081 {
4082         static vector<ShaderElement> vertFragPipelineStages;
4083         if(vertFragPipelineStages.empty())
4084         {
4085                 vertFragPipelineStages.push_back(ShaderElement("vert", "main", VK_SHADER_STAGE_VERTEX_BIT));
4086                 vertFragPipelineStages.push_back(ShaderElement("frag", "main", VK_SHADER_STAGE_FRAGMENT_BIT));
4087         };
4088         return vertFragPipelineStages;
4089 }
4090
4091 const vector<ShaderElement>& getTessPipelineStages (void)
4092 {
4093         static vector<ShaderElement> tessPipelineStages;
4094         if(tessPipelineStages.empty())
4095         {
4096                 tessPipelineStages.push_back(ShaderElement("vert", "main", VK_SHADER_STAGE_VERTEX_BIT));
4097                 tessPipelineStages.push_back(ShaderElement("tessc", "main", VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT));
4098                 tessPipelineStages.push_back(ShaderElement("tesse", "main", VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT));
4099                 tessPipelineStages.push_back(ShaderElement("frag", "main", VK_SHADER_STAGE_FRAGMENT_BIT));
4100         };
4101         return tessPipelineStages;
4102 }
4103
4104 const vector<ShaderElement>& getGeomPipelineStages (void)
4105 {
4106         static vector<ShaderElement> geomPipelineStages;
4107         if(geomPipelineStages.empty())
4108         {
4109                 geomPipelineStages.push_back(ShaderElement("vert", "main", VK_SHADER_STAGE_VERTEX_BIT));
4110                 geomPipelineStages.push_back(ShaderElement("geom", "main", VK_SHADER_STAGE_GEOMETRY_BIT));
4111                 geomPipelineStages.push_back(ShaderElement("frag", "main", VK_SHADER_STAGE_FRAGMENT_BIT));
4112         };
4113         return geomPipelineStages;
4114 }
4115
4116 // Helper structure used by addTestForStage function.
4117 struct StageData
4118 {
4119         typedef const vector<ShaderElement>& (*GetPipelineStagesFn)();
4120         typedef void (*AddShaderCodeCustomStageFn)(vk::SourceCollections&, InstanceContext);
4121
4122         GetPipelineStagesFn                     getPipelineFn;
4123         AddShaderCodeCustomStageFn      initProgramsFn;
4124
4125         StageData()
4126                 : getPipelineFn(DE_NULL)
4127                 , initProgramsFn(DE_NULL)
4128         {
4129         }
4130
4131         StageData(GetPipelineStagesFn pipelineGetter, AddShaderCodeCustomStageFn programsInitializer)
4132                 : getPipelineFn(pipelineGetter)
4133                 , initProgramsFn(programsInitializer)
4134         {
4135         }
4136 };
4137
4138 // Helper function used by addTestForStage function.
4139 const StageData& getStageData (vk::VkShaderStageFlagBits stage)
4140 {
4141         // Construct map
4142         static map<vk::VkShaderStageFlagBits, StageData> testedStageData;
4143         if(testedStageData.empty())
4144         {
4145                 testedStageData[VK_SHADER_STAGE_VERTEX_BIT]                                      = StageData(getVertFragPipelineStages, addShaderCodeCustomVertex);
4146                 testedStageData[VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT]        = StageData(getTessPipelineStages, addShaderCodeCustomTessControl);
4147                 testedStageData[VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT] = StageData(getTessPipelineStages, addShaderCodeCustomTessEval);
4148                 testedStageData[VK_SHADER_STAGE_GEOMETRY_BIT]                            = StageData(getGeomPipelineStages, addShaderCodeCustomGeometry);
4149                 testedStageData[VK_SHADER_STAGE_FRAGMENT_BIT]                            = StageData(getVertFragPipelineStages, addShaderCodeCustomFragment);
4150         }
4151
4152         return testedStageData[stage];
4153 }
4154
4155 void createTestForStage (vk::VkShaderStageFlagBits      stage,
4156                                                  const std::string&                     name,
4157                                                  const RGBA                                     (&inputColors)[4],
4158                                                  const RGBA                                     (&outputColors)[4],
4159                                                  const map<string, string>&     testCodeFragments,
4160                                                  const SpecConstants&           specConstants,
4161                                                  const PushConstants&           pushConstants,
4162                                                  const GraphicsResources&       resources,
4163                                                  const GraphicsInterfaces&      interfaces,
4164                                                  const vector<string>&          extensions,
4165                                                  const vector<string>&          features,
4166                                                  VulkanFeatures                         vulkanFeatures,
4167                                                  tcu::TestCaseGroup*            tests,
4168                                                  const qpTestResult                     failResult,
4169                                                  const string&                          failMessageTemplate,
4170                                                  const bool                                     renderFullSquare)
4171 {
4172         const StageData&                                stageData                       = getStageData(stage);
4173         DE_ASSERT(stageData.getPipelineFn || stageData.initProgramsFn);
4174         const vector<ShaderElement>&    pipeline                        = stageData.getPipelineFn();
4175
4176         StageToSpecConstantMap                  specConstantMap;
4177         if (!specConstants.empty())
4178                 specConstantMap[stage] = specConstants;
4179
4180         InstanceContext                                 ctx                                     (inputColors, outputColors, testCodeFragments, specConstantMap, pushConstants, resources, interfaces, extensions, features, vulkanFeatures, stage);
4181         for (size_t i = 0; i < pipeline.size(); ++i)
4182         {
4183                 ctx.moduleMap[pipeline[i].moduleName].push_back(std::make_pair(pipeline[i].entryName, pipeline[i].stage));
4184                 ctx.requiredStages = static_cast<VkShaderStageFlagBits>(ctx.requiredStages | pipeline[i].stage);
4185         }
4186
4187         ctx.failResult = failResult;
4188         if (!failMessageTemplate.empty())
4189                 ctx.failMessageTemplate = failMessageTemplate;
4190
4191         ctx.renderFullSquare = renderFullSquare;
4192         addFunctionCaseWithPrograms<InstanceContext>(tests, name, "", stageData.initProgramsFn, runAndVerifyDefaultPipeline, ctx);
4193 }
4194
4195 void createTestsForAllStages (const std::string&                        name,
4196                                                           const RGBA                                    (&inputColors)[4],
4197                                                           const RGBA                                    (&outputColors)[4],
4198                                                           const map<string, string>&    testCodeFragments,
4199                                                           const SpecConstants&                  specConstants,
4200                                                           const PushConstants&                  pushConstants,
4201                                                           const GraphicsResources&              resources,
4202                                                           const GraphicsInterfaces&             interfaces,
4203                                                           const vector<string>&                 extensions,
4204                                                           const vector<string>&                 features,
4205                                                           VulkanFeatures                                vulkanFeatures,
4206                                                           tcu::TestCaseGroup*                   tests,
4207                                                           const qpTestResult                    failResult,
4208                                                           const string&                                 failMessageTemplate)
4209 {
4210         createTestForStage(VK_SHADER_STAGE_VERTEX_BIT, name + "_vert",
4211                                            inputColors, outputColors, testCodeFragments, specConstants, pushConstants, resources,
4212                                            interfaces, extensions, features, vulkanFeatures, tests, failResult, failMessageTemplate);
4213
4214         createTestForStage(VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, name + "_tessc",
4215                                            inputColors, outputColors, testCodeFragments, specConstants, pushConstants, resources,
4216                                            interfaces, extensions, features, vulkanFeatures, tests, failResult, failMessageTemplate);
4217
4218         createTestForStage(VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT, name + "_tesse",
4219                                            inputColors, outputColors, testCodeFragments, specConstants, pushConstants, resources,
4220                                            interfaces, extensions, features, vulkanFeatures, tests, failResult, failMessageTemplate);
4221
4222         createTestForStage(VK_SHADER_STAGE_GEOMETRY_BIT, name + "_geom",
4223                                            inputColors, outputColors, testCodeFragments, specConstants, pushConstants, resources,
4224                                            interfaces, extensions, features, vulkanFeatures, tests, failResult, failMessageTemplate);
4225
4226         createTestForStage(VK_SHADER_STAGE_FRAGMENT_BIT, name + "_frag",
4227                                            inputColors, outputColors, testCodeFragments, specConstants, pushConstants, resources,
4228                                            interfaces, extensions, features, vulkanFeatures, tests, failResult, failMessageTemplate);
4229 }
4230
4231 void addTessCtrlTest (tcu::TestCaseGroup* group, const char* name, const map<string, string>& fragments)
4232 {
4233         RGBA defaultColors[4];
4234         getDefaultColors(defaultColors);
4235
4236         createTestForStage(VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, name,
4237                                            defaultColors, defaultColors, fragments, SpecConstants(), PushConstants(), GraphicsResources(),
4238                                            GraphicsInterfaces(), vector<string>(), vector<string>(), VulkanFeatures(), group);
4239 }
4240
4241 } // SpirVAssembly
4242 } // vkt