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