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