Modify spirv_assembly tests adding dependency on 16bit_storage extension
[platform/upstream/VK-GL-CTS.git] / external / vulkancts / modules / vulkan / shaderexecutor / vktShaderExecutor.cpp
1 /*------------------------------------------------------------------------
2  * Vulkan Conformance Tests
3  * ------------------------
4  *
5  * Copyright (c) 2015 The Khronos Group Inc.
6  * Copyright (c) 2015 Samsung Electronics Co., Ltd.
7  * Copyright (c) 2016 The Android Open Source Project
8  *
9  * Licensed under the Apache License, Version 2.0 (the "License");
10  * you may not use this file except in compliance with the License.
11  * You may obtain a copy of the License at
12  *
13  *      http://www.apache.org/licenses/LICENSE-2.0
14  *
15  * Unless required by applicable law or agreed to in writing, software
16  * distributed under the License is distributed on an "AS IS" BASIS,
17  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18  * See the License for the specific language governing permissions and
19  * limitations under the License.
20  *
21  *//*!
22  * \file
23  * \brief Vulkan ShaderExecutor
24  *//*--------------------------------------------------------------------*/
25
26 #include "vktShaderExecutor.hpp"
27
28 #include "vkMemUtil.hpp"
29 #include "vkRef.hpp"
30 #include "vkPrograms.hpp"
31 #include "vkRefUtil.hpp"
32 #include "vkTypeUtil.hpp"
33 #include "vkQueryUtil.hpp"
34 #include "vkBuilderUtil.hpp"
35
36 #include "gluShaderUtil.hpp"
37
38 #include "tcuVector.hpp"
39 #include "tcuTestLog.hpp"
40 #include "tcuTextureUtil.hpp"
41
42 #include "deUniquePtr.hpp"
43 #include "deStringUtil.hpp"
44 #include "deSharedPtr.hpp"
45
46 #include <map>
47 #include <sstream>
48 #include <iostream>
49
50 using std::vector;
51 using namespace vk;
52
53 namespace vkt
54 {
55 namespace shaderexecutor
56 {
57 namespace
58 {
59
60 enum
61 {
62         DEFAULT_RENDER_WIDTH    = 100,
63         DEFAULT_RENDER_HEIGHT   = 100,
64 };
65
66 // Common typedefs
67
68 typedef de::SharedPtr<Unique<VkImage> >         VkImageSp;
69 typedef de::SharedPtr<Unique<VkImageView> >     VkImageViewSp;
70 typedef de::SharedPtr<Unique<VkBuffer> >        VkBufferSp;
71 typedef de::SharedPtr<Allocation>                       AllocationSp;
72
73 // Shader utilities
74
75 static VkClearValue     getDefaultClearColor (void)
76 {
77         return makeClearValueColorF32(0.125f, 0.25f, 0.5f, 1.0f);
78 }
79
80 static std::string generateEmptyFragmentSource (void)
81 {
82         std::ostringstream src;
83
84         src << "#version 310 es\n"
85                    "layout(location=0) out highp vec4 o_color;\n";
86
87         src << "void main (void)\n{\n";
88         src << "        o_color = vec4(0.0);\n";
89         src << "}\n";
90
91         return src.str();
92 }
93
94 static std::string generatePassthroughVertexShader (const std::vector<Symbol>& inputs, const char* inputPrefix, const char* outputPrefix)
95 {
96
97         std::ostringstream      src;
98         int                                     location        = 0;
99
100         src << "#version 310 es\n"
101                    "layout(location = " << location << ") in highp vec4 a_position;\n";
102
103         for (vector<Symbol>::const_iterator input = inputs.begin(); input != inputs.end(); ++input)
104         {
105                 location++;
106                 src << "layout(location = "<< location << ") in " << glu::declare(input->varType, inputPrefix + input->name) << ";\n"
107                         << "layout(location = " << location - 1 << ") flat out " << glu::declare(input->varType, outputPrefix + input->name) << ";\n";
108         }
109
110         src << "\nvoid main (void)\n{\n"
111                 << "    gl_Position = a_position;\n"
112                 << "    gl_PointSize = 1.0;\n";
113
114         for (vector<Symbol>::const_iterator input = inputs.begin(); input != inputs.end(); ++input)
115                 src << "\t" << outputPrefix << input->name << " = " << inputPrefix << input->name << ";\n";
116
117         src << "}\n";
118
119         return src.str();
120 }
121
122 static std::string generateVertexShader (const ShaderSpec& shaderSpec, const std::string& inputPrefix, const std::string& outputPrefix)
123 {
124         DE_ASSERT(!inputPrefix.empty() && !outputPrefix.empty());
125
126         std::ostringstream      src;
127
128         src << glu::getGLSLVersionDeclaration(shaderSpec.glslVersion) << "\n";
129
130         if (!shaderSpec.globalDeclarations.empty())
131                 src << shaderSpec.globalDeclarations << "\n";
132
133         src << "layout(location = 0) in highp vec4 a_position;\n";
134
135         int locationNumber = 1;
136         for (vector<Symbol>::const_iterator input = shaderSpec.inputs.begin(); input != shaderSpec.inputs.end(); ++input, ++locationNumber)
137                 src <<  "layout(location = " << locationNumber << ") in " << glu::declare(input->varType, inputPrefix + input->name) << ";\n";
138
139         locationNumber = 0;
140         for (vector<Symbol>::const_iterator output = shaderSpec.outputs.begin(); output != shaderSpec.outputs.end(); ++output, ++locationNumber)
141         {
142                 DE_ASSERT(output->varType.isBasicType());
143
144                 if (glu::isDataTypeBoolOrBVec(output->varType.getBasicType()))
145                 {
146                         const int                               vecSize         = glu::getDataTypeScalarSize(output->varType.getBasicType());
147                         const glu::DataType             intBaseType     = vecSize > 1 ? glu::getDataTypeIntVec(vecSize) : glu::TYPE_INT;
148                         const glu::VarType              intType         (intBaseType, glu::PRECISION_HIGHP);
149
150                         src << "layout(location = " << locationNumber << ") flat out " << glu::declare(intType, outputPrefix + output->name) << ";\n";
151                 }
152                 else
153                         src << "layout(location = " << locationNumber << ") flat out " << glu::declare(output->varType, outputPrefix + output->name) << ";\n";
154         }
155
156         src << "\n"
157                 << "void main (void)\n"
158                 << "{\n"
159                 << "    gl_Position = a_position;\n"
160                 << "    gl_PointSize = 1.0;\n";
161
162         // Declare & fetch local input variables
163         for (vector<Symbol>::const_iterator input = shaderSpec.inputs.begin(); input != shaderSpec.inputs.end(); ++input)
164                 src << "\t" << glu::declare(input->varType, input->name) << " = " << inputPrefix << input->name << ";\n";
165
166         // Declare local output variables
167         for (vector<Symbol>::const_iterator output = shaderSpec.outputs.begin(); output != shaderSpec.outputs.end(); ++output)
168                 src << "\t" << glu::declare(output->varType, output->name) << ";\n";
169
170         // Operation - indented to correct level.
171         {
172                 std::istringstream      opSrc   (shaderSpec.source);
173                 std::string                     line;
174
175                 while (std::getline(opSrc, line))
176                         src << "\t" << line << "\n";
177         }
178
179         // Assignments to outputs.
180         for (vector<Symbol>::const_iterator output = shaderSpec.outputs.begin(); output != shaderSpec.outputs.end(); ++output)
181         {
182                 if (glu::isDataTypeBoolOrBVec(output->varType.getBasicType()))
183                 {
184                         const int                               vecSize         = glu::getDataTypeScalarSize(output->varType.getBasicType());
185                         const glu::DataType             intBaseType     = vecSize > 1 ? glu::getDataTypeIntVec(vecSize) : glu::TYPE_INT;
186
187                         src << "\t" << outputPrefix << output->name << " = " << glu::getDataTypeName(intBaseType) << "(" << output->name << ");\n";
188                 }
189                 else
190                         src << "\t" << outputPrefix << output->name << " = " << output->name << ";\n";
191         }
192
193         src << "}\n";
194
195         return src.str();
196 }
197
198 struct FragmentOutputLayout
199 {
200         std::vector<const Symbol*>              locationSymbols;                //! Symbols by location
201         std::map<std::string, int>              locationMap;                    //! Map from symbol name to start location
202 };
203
204 static void generateFragShaderOutputDecl (std::ostream& src, const ShaderSpec& shaderSpec, bool useIntOutputs, const std::map<std::string, int>& outLocationMap, const std::string& outputPrefix)
205 {
206         for (int outNdx = 0; outNdx < (int)shaderSpec.outputs.size(); ++outNdx)
207         {
208                 const Symbol&                           output          = shaderSpec.outputs[outNdx];
209                 const int                                       location        = de::lookup(outLocationMap, output.name);
210                 const std::string                       outVarName      = outputPrefix + output.name;
211                 glu::VariableDeclaration        decl            (output.varType, outVarName, glu::STORAGE_OUT, glu::INTERPOLATION_LAST, glu::Layout(location));
212
213                 TCU_CHECK_INTERNAL(output.varType.isBasicType());
214
215                 if (useIntOutputs && glu::isDataTypeFloatOrVec(output.varType.getBasicType()))
216                 {
217                         const int                       vecSize                 = glu::getDataTypeScalarSize(output.varType.getBasicType());
218                         const glu::DataType     uintBasicType   = vecSize > 1 ? glu::getDataTypeUintVec(vecSize) : glu::TYPE_UINT;
219                         const glu::VarType      uintType                (uintBasicType, glu::PRECISION_HIGHP);
220
221                         decl.varType = uintType;
222                         src << decl << ";\n";
223                 }
224                 else if (glu::isDataTypeBoolOrBVec(output.varType.getBasicType()))
225                 {
226                         const int                       vecSize                 = glu::getDataTypeScalarSize(output.varType.getBasicType());
227                         const glu::DataType     intBasicType    = vecSize > 1 ? glu::getDataTypeIntVec(vecSize) : glu::TYPE_INT;
228                         const glu::VarType      intType                 (intBasicType, glu::PRECISION_HIGHP);
229
230                         decl.varType = intType;
231                         src << decl << ";\n";
232                 }
233                 else if (glu::isDataTypeMatrix(output.varType.getBasicType()))
234                 {
235                         const int                       vecSize                 = glu::getDataTypeMatrixNumRows(output.varType.getBasicType());
236                         const int                       numVecs                 = glu::getDataTypeMatrixNumColumns(output.varType.getBasicType());
237                         const glu::DataType     uintBasicType   = glu::getDataTypeUintVec(vecSize);
238                         const glu::VarType      uintType                (uintBasicType, glu::PRECISION_HIGHP);
239
240                         decl.varType = uintType;
241                         for (int vecNdx = 0; vecNdx < numVecs; ++vecNdx)
242                         {
243                                 decl.name                               = outVarName + "_" + de::toString(vecNdx);
244                                 decl.layout.location    = location + vecNdx;
245                                 src << decl << ";\n";
246                         }
247                 }
248                 else
249                         src << decl << ";\n";
250         }
251 }
252
253 static void generateFragShaderOutAssign (std::ostream& src, const ShaderSpec& shaderSpec, bool useIntOutputs, const std::string& valuePrefix, const std::string& outputPrefix)
254 {
255         for (vector<Symbol>::const_iterator output = shaderSpec.outputs.begin(); output != shaderSpec.outputs.end(); ++output)
256         {
257                 if (useIntOutputs && glu::isDataTypeFloatOrVec(output->varType.getBasicType()))
258                         src << "        o_" << output->name << " = floatBitsToUint(" << valuePrefix << output->name << ");\n";
259                 else if (glu::isDataTypeMatrix(output->varType.getBasicType()))
260                 {
261                         const int       numVecs         = glu::getDataTypeMatrixNumColumns(output->varType.getBasicType());
262
263                         for (int vecNdx = 0; vecNdx < numVecs; ++vecNdx)
264                                 if (useIntOutputs)
265                                         src << "\t" << outputPrefix << output->name << "_" << vecNdx << " = floatBitsToUint(" << valuePrefix << output->name << "[" << vecNdx << "]);\n";
266                                 else
267                                         src << "\t" << outputPrefix << output->name << "_" << vecNdx << " = " << valuePrefix << output->name << "[" << vecNdx << "];\n";
268                 }
269                 else if (glu::isDataTypeBoolOrBVec(output->varType.getBasicType()))
270                 {
271                         const int                               vecSize         = glu::getDataTypeScalarSize(output->varType.getBasicType());
272                         const glu::DataType             intBaseType     = vecSize > 1 ? glu::getDataTypeIntVec(vecSize) : glu::TYPE_INT;
273
274                         src << "\t" << outputPrefix << output->name << " = " << glu::getDataTypeName(intBaseType) << "(" << valuePrefix << output->name << ");\n";
275                 }
276                 else
277                         src << "\t" << outputPrefix << output->name << " = " << valuePrefix << output->name << ";\n";
278         }
279 }
280
281 static std::string generatePassthroughFragmentShader (const ShaderSpec& shaderSpec, bool useIntOutputs, const std::map<std::string, int>& outLocationMap, const std::string& inputPrefix, const std::string& outputPrefix)
282 {
283         std::ostringstream      src;
284
285         src <<"#version 310 es\n";
286
287         if (!shaderSpec.globalDeclarations.empty())
288                 src << shaderSpec.globalDeclarations << "\n";
289
290         int locationNumber = 0;
291         for (vector<Symbol>::const_iterator output = shaderSpec.outputs.begin(); output != shaderSpec.outputs.end(); ++output, ++locationNumber)
292         {
293                 if (glu::isDataTypeBoolOrBVec(output->varType.getBasicType()))
294                 {
295                         const int                               vecSize         = glu::getDataTypeScalarSize(output->varType.getBasicType());
296                         const glu::DataType             intBaseType     = vecSize > 1 ? glu::getDataTypeIntVec(vecSize) : glu::TYPE_INT;
297                         const glu::VarType              intType         (intBaseType, glu::PRECISION_HIGHP);
298
299                         src << "layout(location = " << locationNumber << ") flat in " << glu::declare(intType, inputPrefix + output->name) << ";\n";
300                 }
301                 else
302                         src << "layout(location = " << locationNumber << ") flat in " << glu::declare(output->varType, inputPrefix + output->name) << ";\n";
303         }
304
305         generateFragShaderOutputDecl(src, shaderSpec, useIntOutputs, outLocationMap, outputPrefix);
306
307         src << "\nvoid main (void)\n{\n";
308
309         generateFragShaderOutAssign(src, shaderSpec, useIntOutputs, inputPrefix, outputPrefix);
310
311         src << "}\n";
312
313         return src.str();
314 }
315
316 static std::string generateGeometryShader (const ShaderSpec& shaderSpec, const std::string& inputPrefix, const std::string& outputPrefix)
317 {
318         DE_ASSERT(!inputPrefix.empty() && !outputPrefix.empty());
319
320         std::ostringstream      src;
321
322         src << glu::getGLSLVersionDeclaration(shaderSpec.glslVersion) << "\n";
323
324         if (shaderSpec.glslVersion == glu::GLSL_VERSION_310_ES)
325                 src << "#extension GL_EXT_geometry_shader : require\n";
326
327         if (!shaderSpec.globalDeclarations.empty())
328                 src << shaderSpec.globalDeclarations << "\n";
329
330         src << "layout(points) in;\n"
331                 << "layout(points, max_vertices = 1) out;\n";
332
333         int locationNumber = 0;
334         for (vector<Symbol>::const_iterator input = shaderSpec.inputs.begin(); input != shaderSpec.inputs.end(); ++input, ++locationNumber)
335                 src << "layout(location = " << locationNumber << ") flat in " << glu::declare(input->varType, inputPrefix + input->name) << "[];\n";
336
337         locationNumber = 0;
338         for (vector<Symbol>::const_iterator output = shaderSpec.outputs.begin(); output != shaderSpec.outputs.end(); ++output, ++locationNumber)
339         {
340                 DE_ASSERT(output->varType.isBasicType());
341
342                 if (glu::isDataTypeBoolOrBVec(output->varType.getBasicType()))
343                 {
344                         const int                               vecSize         = glu::getDataTypeScalarSize(output->varType.getBasicType());
345                         const glu::DataType             intBaseType     = vecSize > 1 ? glu::getDataTypeIntVec(vecSize) : glu::TYPE_INT;
346                         const glu::VarType              intType         (intBaseType, glu::PRECISION_HIGHP);
347
348                         src << "layout(location = " << locationNumber << ") flat out " << glu::declare(intType, outputPrefix + output->name) << ";\n";
349                 }
350                 else
351                         src << "layout(location = " << locationNumber << ") flat out " << glu::declare(output->varType, outputPrefix + output->name) << ";\n";
352         }
353
354         src << "\n"
355                 << "void main (void)\n"
356                 << "{\n"
357                 << "    gl_Position = gl_in[0].gl_Position;\n\n";
358
359         // Fetch input variables
360         for (vector<Symbol>::const_iterator input = shaderSpec.inputs.begin(); input != shaderSpec.inputs.end(); ++input)
361                 src << "\t" << glu::declare(input->varType, input->name) << " = " << inputPrefix << input->name << "[0];\n";
362
363         // Declare local output variables.
364         for (vector<Symbol>::const_iterator output = shaderSpec.outputs.begin(); output != shaderSpec.outputs.end(); ++output)
365                 src << "\t" << glu::declare(output->varType, output->name) << ";\n";
366
367         src << "\n";
368
369         // Operation - indented to correct level.
370         {
371                 std::istringstream      opSrc   (shaderSpec.source);
372                 std::string                     line;
373
374                 while (std::getline(opSrc, line))
375                         src << "\t" << line << "\n";
376         }
377
378         // Assignments to outputs.
379         for (vector<Symbol>::const_iterator output = shaderSpec.outputs.begin(); output != shaderSpec.outputs.end(); ++output)
380         {
381                 if (glu::isDataTypeBoolOrBVec(output->varType.getBasicType()))
382                 {
383                         const int                               vecSize         = glu::getDataTypeScalarSize(output->varType.getBasicType());
384                         const glu::DataType             intBaseType     = vecSize > 1 ? glu::getDataTypeIntVec(vecSize) : glu::TYPE_INT;
385
386                         src << "\t" << outputPrefix << output->name << " = " << glu::getDataTypeName(intBaseType) << "(" << output->name << ");\n";
387                 }
388                 else
389                         src << "\t" << outputPrefix << output->name << " = " << output->name << ";\n";
390         }
391
392         src << "        EmitVertex();\n"
393                 << "    EndPrimitive();\n"
394                 << "}\n";
395
396         return src.str();
397 }
398
399 static std::string generateFragmentShader (const ShaderSpec& shaderSpec, bool useIntOutputs, const std::map<std::string, int>& outLocationMap, const std::string& inputPrefix, const std::string& outputPrefix)
400 {
401         std::ostringstream src;
402         src << glu::getGLSLVersionDeclaration(shaderSpec.glslVersion) << "\n";
403         if (!shaderSpec.globalDeclarations.empty())
404                 src << shaderSpec.globalDeclarations << "\n";
405
406         int locationNumber = 0;
407         for (vector<Symbol>::const_iterator input = shaderSpec.inputs.begin(); input != shaderSpec.inputs.end(); ++input, ++locationNumber)
408                 src << "layout(location = " << locationNumber << ") flat in " << glu::declare(input->varType, inputPrefix + input->name) << ";\n";
409
410         generateFragShaderOutputDecl(src, shaderSpec, useIntOutputs, outLocationMap, outputPrefix);
411
412         src << "\nvoid main (void)\n{\n";
413
414         // Declare & fetch local input variables
415         for (vector<Symbol>::const_iterator input = shaderSpec.inputs.begin(); input != shaderSpec.inputs.end(); ++input)
416                 src << "\t" << glu::declare(input->varType, input->name) << " = " << inputPrefix << input->name << ";\n";
417
418         // Declare output variables
419         for (vector<Symbol>::const_iterator output = shaderSpec.outputs.begin(); output != shaderSpec.outputs.end(); ++output)
420                 src << "\t" << glu::declare(output->varType, output->name) << ";\n";
421
422         // Operation - indented to correct level.
423         {
424                 std::istringstream      opSrc   (shaderSpec.source);
425                 std::string                     line;
426
427                 while (std::getline(opSrc, line))
428                         src << "\t" << line << "\n";
429         }
430
431         generateFragShaderOutAssign(src, shaderSpec, useIntOutputs, "", outputPrefix);
432
433         src << "}\n";
434
435         return src.str();
436 }
437
438 // FragmentOutExecutor
439
440 class FragmentOutExecutor : public ShaderExecutor
441 {
442 public:
443                                                                                                                 FragmentOutExecutor             (Context& context, glu::ShaderType shaderType, const ShaderSpec& shaderSpec, VkDescriptorSetLayout extraResourcesLayout);
444         virtual                                                                                         ~FragmentOutExecutor    (void);
445
446         virtual void                                                                            execute                                 (int                                    numValues,
447                                                                                                                                                                  const void* const*             inputs,
448                                                                                                                                                                  void* const*                   outputs,
449                                                                                                                                                                  VkDescriptorSet                extraResources);
450
451 protected:
452         const glu::ShaderType                                                           m_shaderType;
453         const FragmentOutputLayout                                                      m_outputLayout;
454
455 private:
456         void                                                                                            bindAttributes                  (int                                    numValues,
457                                                                                                                                                                  const void* const*             inputs);
458
459         void                                                                                            addAttribute                    (deUint32                               bindingLocation,
460                                                                                                                                                                  VkFormat                               format,
461                                                                                                                                                                  deUint32                               sizePerElement,
462                                                                                                                                                                  deUint32                               count,
463                                                                                                                                                                  const void*                    dataPtr);
464         // reinit render data members
465         virtual void                                                                            clearRenderData                 (void);
466
467         const VkDescriptorSetLayout                                                     m_extraResourcesLayout;
468
469         std::vector<VkVertexInputBindingDescription>            m_vertexBindingDescriptions;
470         std::vector<VkVertexInputAttributeDescription>          m_vertexAttributeDescriptions;
471         std::vector<VkBufferSp>                                                         m_vertexBuffers;
472         std::vector<AllocationSp>                                                       m_vertexBufferAllocs;
473 };
474
475 static FragmentOutputLayout computeFragmentOutputLayout (const std::vector<Symbol>& symbols)
476 {
477         FragmentOutputLayout    ret;
478         int                                             location        = 0;
479
480         for (std::vector<Symbol>::const_iterator it = symbols.begin(); it != symbols.end(); ++it)
481         {
482                 const int       numLocations    = glu::getDataTypeNumLocations(it->varType.getBasicType());
483
484                 TCU_CHECK_INTERNAL(!de::contains(ret.locationMap, it->name));
485                 de::insert(ret.locationMap, it->name, location);
486                 location += numLocations;
487
488                 for (int ndx = 0; ndx < numLocations; ++ndx)
489                         ret.locationSymbols.push_back(&*it);
490         }
491
492         return ret;
493 }
494
495 FragmentOutExecutor::FragmentOutExecutor (Context& context, glu::ShaderType shaderType, const ShaderSpec& shaderSpec, VkDescriptorSetLayout extraResourcesLayout)
496         : ShaderExecutor                        (context, shaderSpec)
497         , m_shaderType                          (shaderType)
498         , m_outputLayout                        (computeFragmentOutputLayout(m_shaderSpec.outputs))
499         , m_extraResourcesLayout        (extraResourcesLayout)
500 {
501 }
502
503 FragmentOutExecutor::~FragmentOutExecutor (void)
504 {
505 }
506
507 static std::vector<tcu::Vec2> computeVertexPositions (int numValues, const tcu::IVec2& renderSize)
508 {
509         std::vector<tcu::Vec2> positions(numValues);
510         for (int valNdx = 0; valNdx < numValues; valNdx++)
511         {
512                 const int               ix              = valNdx % renderSize.x();
513                 const int               iy              = valNdx / renderSize.x();
514                 const float             fx              = -1.0f + 2.0f*((float(ix) + 0.5f) / float(renderSize.x()));
515                 const float             fy              = -1.0f + 2.0f*((float(iy) + 0.5f) / float(renderSize.y()));
516
517                 positions[valNdx] = tcu::Vec2(fx, fy);
518         }
519
520         return positions;
521 }
522
523 static tcu::TextureFormat getRenderbufferFormatForOutput (const glu::VarType& outputType, bool useIntOutputs)
524 {
525         const tcu::TextureFormat::ChannelOrder channelOrderMap[] =
526         {
527                 tcu::TextureFormat::R,
528                 tcu::TextureFormat::RG,
529                 tcu::TextureFormat::RGBA,       // No RGB variants available.
530                 tcu::TextureFormat::RGBA
531         };
532
533         const glu::DataType                                     basicType               = outputType.getBasicType();
534         const int                                                       numComps                = glu::getDataTypeNumComponents(basicType);
535         tcu::TextureFormat::ChannelType         channelType;
536
537         switch (glu::getDataTypeScalarType(basicType))
538         {
539                 case glu::TYPE_UINT:    channelType = tcu::TextureFormat::UNSIGNED_INT32;                                                                                               break;
540                 case glu::TYPE_INT:             channelType = tcu::TextureFormat::SIGNED_INT32;                                                                                                 break;
541                 case glu::TYPE_BOOL:    channelType = tcu::TextureFormat::SIGNED_INT32;                                                                                                 break;
542                 case glu::TYPE_FLOAT:   channelType = useIntOutputs ? tcu::TextureFormat::UNSIGNED_INT32 : tcu::TextureFormat::FLOAT;   break;
543                 default:
544                         throw tcu::InternalError("Invalid output type");
545         }
546
547         DE_ASSERT(de::inRange<int>(numComps, 1, DE_LENGTH_OF_ARRAY(channelOrderMap)));
548
549         return tcu::TextureFormat(channelOrderMap[numComps-1], channelType);
550 }
551
552 static VkFormat getAttributeFormat (const glu::DataType dataType)
553 {
554         switch (dataType)
555         {
556                 case glu::TYPE_FLOAT:                   return VK_FORMAT_R32_SFLOAT;
557                 case glu::TYPE_FLOAT_VEC2:              return VK_FORMAT_R32G32_SFLOAT;
558                 case glu::TYPE_FLOAT_VEC3:              return VK_FORMAT_R32G32B32_SFLOAT;
559                 case glu::TYPE_FLOAT_VEC4:              return VK_FORMAT_R32G32B32A32_SFLOAT;
560
561                 case glu::TYPE_INT:                             return VK_FORMAT_R32_SINT;
562                 case glu::TYPE_INT_VEC2:                return VK_FORMAT_R32G32_SINT;
563                 case glu::TYPE_INT_VEC3:                return VK_FORMAT_R32G32B32_SINT;
564                 case glu::TYPE_INT_VEC4:                return VK_FORMAT_R32G32B32A32_SINT;
565
566                 case glu::TYPE_UINT:                    return VK_FORMAT_R32_UINT;
567                 case glu::TYPE_UINT_VEC2:               return VK_FORMAT_R32G32_UINT;
568                 case glu::TYPE_UINT_VEC3:               return VK_FORMAT_R32G32B32_UINT;
569                 case glu::TYPE_UINT_VEC4:               return VK_FORMAT_R32G32B32A32_UINT;
570
571                 case glu::TYPE_FLOAT_MAT2:              return VK_FORMAT_R32G32_SFLOAT;
572                 case glu::TYPE_FLOAT_MAT2X3:    return VK_FORMAT_R32G32B32_SFLOAT;
573                 case glu::TYPE_FLOAT_MAT2X4:    return VK_FORMAT_R32G32B32A32_SFLOAT;
574                 case glu::TYPE_FLOAT_MAT3X2:    return VK_FORMAT_R32G32_SFLOAT;
575                 case glu::TYPE_FLOAT_MAT3:              return VK_FORMAT_R32G32B32_SFLOAT;
576                 case glu::TYPE_FLOAT_MAT3X4:    return VK_FORMAT_R32G32B32A32_SFLOAT;
577                 case glu::TYPE_FLOAT_MAT4X2:    return VK_FORMAT_R32G32_SFLOAT;
578                 case glu::TYPE_FLOAT_MAT4X3:    return VK_FORMAT_R32G32B32_SFLOAT;
579                 case glu::TYPE_FLOAT_MAT4:              return VK_FORMAT_R32G32B32A32_SFLOAT;
580                 default:
581                         DE_ASSERT(false);
582                         return VK_FORMAT_UNDEFINED;
583         }
584 }
585
586 void FragmentOutExecutor::addAttribute (deUint32 bindingLocation, VkFormat format, deUint32 sizePerElement, deUint32 count, const void* dataPtr)
587 {
588         // Add binding specification
589         const deUint32                                                  binding = (deUint32)m_vertexBindingDescriptions.size();
590         const VkVertexInputBindingDescription   bindingDescription =
591         {
592                 binding,
593                 sizePerElement,
594                 VK_VERTEX_INPUT_RATE_VERTEX
595         };
596
597         m_vertexBindingDescriptions.push_back(bindingDescription);
598
599         // Add location and format specification
600         const VkVertexInputAttributeDescription attributeDescription =
601         {
602                 bindingLocation,                        // deUint32     location;
603                 binding,                                        // deUint32     binding;
604                 format,                                         // VkFormat     format;
605                 0u,                                                     // deUint32     offsetInBytes;
606         };
607
608         m_vertexAttributeDescriptions.push_back(attributeDescription);
609
610         // Upload data to buffer
611         const VkDevice                          vkDevice                        = m_context.getDevice();
612         const DeviceInterface&          vk                                      = m_context.getDeviceInterface();
613         const deUint32                          queueFamilyIndex        = m_context.getUniversalQueueFamilyIndex();
614
615         const VkDeviceSize                      inputSize                       = sizePerElement * count;
616         const VkBufferCreateInfo        vertexBufferParams      =
617         {
618                 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,           // VkStructureType              sType;
619                 DE_NULL,                                                                        // const void*                  pNext;
620                 0u,                                                                                     // VkBufferCreateFlags  flags;
621                 inputSize,                                                                      // VkDeviceSize                 size;
622                 VK_BUFFER_USAGE_VERTEX_BUFFER_BIT,                      // VkBufferUsageFlags   usage;
623                 VK_SHARING_MODE_EXCLUSIVE,                                      // VkSharingMode                sharingMode;
624                 1u,                                                                                     // deUint32                             queueFamilyCount;
625                 &queueFamilyIndex                                                       // const deUint32*              pQueueFamilyIndices;
626         };
627
628         Move<VkBuffer>                  buffer  = createBuffer(vk, vkDevice, &vertexBufferParams);
629         de::MovePtr<Allocation> alloc   = m_context.getDefaultAllocator().allocate(getBufferMemoryRequirements(vk, vkDevice, *buffer), MemoryRequirement::HostVisible);
630
631         VK_CHECK(vk.bindBufferMemory(vkDevice, *buffer, alloc->getMemory(), alloc->getOffset()));
632
633         deMemcpy(alloc->getHostPtr(), dataPtr, (size_t)inputSize);
634         flushMappedMemoryRange(vk, vkDevice, alloc->getMemory(), alloc->getOffset(), inputSize);
635
636         m_vertexBuffers.push_back(de::SharedPtr<Unique<VkBuffer> >(new Unique<VkBuffer>(buffer)));
637         m_vertexBufferAllocs.push_back(AllocationSp(alloc.release()));
638 }
639
640 void FragmentOutExecutor::bindAttributes (int numValues, const void* const* inputs)
641 {
642         // Input attributes
643         for (int inputNdx = 0; inputNdx < (int)m_shaderSpec.inputs.size(); inputNdx++)
644         {
645                 const Symbol&           symbol                  = m_shaderSpec.inputs[inputNdx];
646                 const void*                     ptr                             = inputs[inputNdx];
647                 const glu::DataType     basicType               = symbol.varType.getBasicType();
648                 const int                       vecSize                 = glu::getDataTypeScalarSize(basicType);
649                 const VkFormat          format                  = getAttributeFormat(basicType);
650                 int                                     elementSize             = 0;
651                 int                                     numAttrsToAdd   = 1;
652
653                 if (glu::isDataTypeFloatOrVec(basicType))
654                         elementSize = sizeof(float);
655                 else if (glu::isDataTypeIntOrIVec(basicType))
656                         elementSize = sizeof(int);
657                 else if (glu::isDataTypeUintOrUVec(basicType))
658                         elementSize = sizeof(deUint32);
659                 else if (glu::isDataTypeMatrix(basicType))
660                 {
661                         int             numRows = glu::getDataTypeMatrixNumRows(basicType);
662                         int             numCols = glu::getDataTypeMatrixNumColumns(basicType);
663
664                         elementSize = numRows * numCols * (int)sizeof(float);
665                         numAttrsToAdd = numCols;
666                 }
667                 else
668                         DE_ASSERT(false);
669
670                 // add attributes, in case of matrix every column is binded as an attribute
671                 for (int attrNdx = 0; attrNdx < numAttrsToAdd; attrNdx++)
672                 {
673                         addAttribute((deUint32)m_vertexBindingDescriptions.size(), format, elementSize * vecSize, numValues, ptr);
674                 }
675         }
676 }
677
678 void FragmentOutExecutor::clearRenderData (void)
679 {
680         m_vertexBindingDescriptions.clear();
681         m_vertexAttributeDescriptions.clear();
682         m_vertexBuffers.clear();
683         m_vertexBufferAllocs.clear();
684 }
685
686 static Move<VkDescriptorSetLayout> createEmptyDescriptorSetLayout (const DeviceInterface& vkd, VkDevice device)
687 {
688         const VkDescriptorSetLayoutCreateInfo   createInfo      =
689         {
690                 VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
691                 DE_NULL,
692                 (VkDescriptorSetLayoutCreateFlags)0,
693                 0u,
694                 DE_NULL,
695         };
696         return createDescriptorSetLayout(vkd, device, &createInfo);
697 }
698
699 static Move<VkDescriptorPool> createDummyDescriptorPool (const DeviceInterface& vkd, VkDevice device)
700 {
701         const VkDescriptorPoolSize                      dummySize       =
702         {
703                 VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
704                 1u,
705         };
706         const VkDescriptorPoolCreateInfo        createInfo      =
707         {
708                 VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
709                 DE_NULL,
710                 (VkDescriptorPoolCreateFlags)VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT,
711                 1u,
712                 1u,
713                 &dummySize
714         };
715         return createDescriptorPool(vkd, device, &createInfo);
716 }
717
718 static Move<VkDescriptorSet> allocateSingleDescriptorSet (const DeviceInterface& vkd, VkDevice device, VkDescriptorPool pool, VkDescriptorSetLayout layout)
719 {
720         const VkDescriptorSetAllocateInfo       allocInfo       =
721         {
722                 VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
723                 DE_NULL,
724                 pool,
725                 1u,
726                 &layout,
727         };
728         return allocateDescriptorSet(vkd, device, &allocInfo);
729 }
730
731 void FragmentOutExecutor::execute (int numValues, const void* const* inputs, void* const* outputs, VkDescriptorSet extraResources)
732 {
733         const VkDevice                                                                          vkDevice                                = m_context.getDevice();
734         const DeviceInterface&                                                          vk                                              = m_context.getDeviceInterface();
735         const VkQueue                                                                           queue                                   = m_context.getUniversalQueue();
736         const deUint32                                                                          queueFamilyIndex                = m_context.getUniversalQueueFamilyIndex();
737         Allocator&                                                                                      memAlloc                                = m_context.getDefaultAllocator();
738
739         const deUint32                                                                          renderSizeX                             = de::min(static_cast<deUint32>(DEFAULT_RENDER_WIDTH), (deUint32)numValues);
740         const deUint32                                                                          renderSizeY                             = ((deUint32)numValues / renderSizeX) + (((deUint32)numValues % renderSizeX != 0) ? 1u : 0u);
741         const tcu::UVec2                                                                        renderSize                              (renderSizeX, renderSizeY);
742         std::vector<tcu::Vec2>                                                          positions;
743
744         const bool                                                                                      useGeometryShader               = m_shaderType == glu::SHADERTYPE_GEOMETRY;
745
746         std::vector<VkImageSp>                                                          colorImages;
747         std::vector<VkImageMemoryBarrier>                                       colorImagePreRenderBarriers;
748         std::vector<VkImageMemoryBarrier>                                       colorImagePostRenderBarriers;
749         std::vector<AllocationSp>                                                       colorImageAllocs;
750         std::vector<VkAttachmentDescription>                            attachments;
751         std::vector<VkClearValue>                                                       attachmentClearValues;
752         std::vector<VkImageViewSp>                                                      colorImageViews;
753
754         std::vector<VkPipelineColorBlendAttachmentState>        colorBlendAttachmentStates;
755         std::vector<VkAttachmentReference>                                      colorAttachmentReferences;
756
757         Move<VkRenderPass>                                                                      renderPass;
758         Move<VkFramebuffer>                                                                     framebuffer;
759         Move<VkPipelineLayout>                                                          pipelineLayout;
760         Move<VkPipeline>                                                                        graphicsPipeline;
761
762         Move<VkShaderModule>                                                            vertexShaderModule;
763         Move<VkShaderModule>                                                            geometryShaderModule;
764         Move<VkShaderModule>                                                            fragmentShaderModule;
765
766         Move<VkCommandPool>                                                                     cmdPool;
767         Move<VkCommandBuffer>                                                           cmdBuffer;
768
769         Move<VkFence>                                                                           fence;
770
771         Unique<VkDescriptorSetLayout>                                           emptyDescriptorSetLayout        (createEmptyDescriptorSetLayout(vk, vkDevice));
772         Unique<VkDescriptorPool>                                                        dummyDescriptorPool                     (createDummyDescriptorPool(vk, vkDevice));
773         Unique<VkDescriptorSet>                                                         emptyDescriptorSet                      (allocateSingleDescriptorSet(vk, vkDevice, *dummyDescriptorPool, *emptyDescriptorSetLayout));
774
775         clearRenderData();
776
777         // Compute positions - 1px points are used to drive fragment shading.
778         positions = computeVertexPositions(numValues, renderSize.cast<int>());
779
780         // Bind attributes
781         addAttribute(0u, VK_FORMAT_R32G32_SFLOAT, sizeof(tcu::Vec2), (deUint32)positions.size(), &positions[0]);
782         bindAttributes(numValues, inputs);
783
784         // Create color images
785         {
786                 const VkPipelineColorBlendAttachmentState colorBlendAttachmentState =
787                 {
788                         VK_FALSE,                                                                                                                                       // VkBool32                                             blendEnable;
789                         VK_BLEND_FACTOR_ONE,                                                                                                            // VkBlendFactor                                srcColorBlendFactor;
790                         VK_BLEND_FACTOR_ZERO,                                                                                                           // VkBlendFactor                                dstColorBlendFactor;
791                         VK_BLEND_OP_ADD,                                                                                                                        // VkBlendOp                                    blendOpColor;
792                         VK_BLEND_FACTOR_ONE,                                                                                                            // VkBlendFactor                                srcAlphaBlendFactor;
793                         VK_BLEND_FACTOR_ZERO,                                                                                                           // VkBlendFactor                                destAlphaBlendFactor;
794                         VK_BLEND_OP_ADD,                                                                                                                        // VkBlendOp                                    blendOpAlpha;
795                         (VK_COLOR_COMPONENT_R_BIT |
796                          VK_COLOR_COMPONENT_G_BIT |
797                          VK_COLOR_COMPONENT_B_BIT |
798                          VK_COLOR_COMPONENT_A_BIT)                                                                                                      // VkColorComponentFlags                colorWriteMask;
799                 };
800
801                 for (int outNdx = 0; outNdx < (int)m_outputLayout.locationSymbols.size(); ++outNdx)
802                 {
803                         const bool              isFloat         = isDataTypeFloatOrVec(m_shaderSpec.outputs[outNdx].varType.getBasicType());
804                         const bool              isSigned        = isDataTypeIntOrIVec (m_shaderSpec.outputs[outNdx].varType.getBasicType());
805                         const bool              isBool          = isDataTypeBoolOrBVec(m_shaderSpec.outputs[outNdx].varType.getBasicType());
806                         const VkFormat  colorFormat = isFloat ? VK_FORMAT_R32G32B32A32_SFLOAT : (isSigned || isBool ? VK_FORMAT_R32G32B32A32_SINT : VK_FORMAT_R32G32B32A32_UINT);
807
808                         const VkImageCreateInfo  colorImageParams =
809                         {
810                                 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,                                                                            // VkStructureType                              sType;
811                                 DE_NULL,                                                                                                                                        // const void*                                  pNext;
812                                 0u,                                                                                                                                                     // VkImageCreateFlags                   flags;
813                                 VK_IMAGE_TYPE_2D,                                                                                                                       // VkImageType                                  imageType;
814                                 colorFormat,                                                                                                                            // VkFormat                                             format;
815                                 { renderSize.x(), renderSize.y(), 1u },                                                                         // VkExtent3D                                   extent;
816                                 1u,                                                                                                                                                     // deUint32                                             mipLevels;
817                                 1u,                                                                                                                                                     // deUint32                                             arraySize;
818                                 VK_SAMPLE_COUNT_1_BIT,                                                                                                          // VkSampleCountFlagBits                samples;
819                                 VK_IMAGE_TILING_OPTIMAL,                                                                                                        // VkImageTiling                                tiling;
820                                 VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT,          // VkImageUsageFlags                    usage;
821                                 VK_SHARING_MODE_EXCLUSIVE,                                                                                                      // VkSharingMode                                sharingMode;
822                                 1u,                                                                                                                                                     // deUint32                                             queueFamilyCount;
823                                 &queueFamilyIndex,                                                                                                                      // const deUint32*                              pQueueFamilyIndices;
824                                 VK_IMAGE_LAYOUT_UNDEFINED,                                                                                                      // VkImageLayout                                initialLayout;
825                         };
826
827                         const VkAttachmentDescription colorAttachmentDescription =
828                         {
829                                 0u,                                                                                                                                                     // VkAttachmentDescriptorFlags  flags;
830                                 colorFormat,                                                                                                                            // VkFormat                                             format;
831                                 VK_SAMPLE_COUNT_1_BIT,                                                                                                          // VkSampleCountFlagBits                samples;
832                                 VK_ATTACHMENT_LOAD_OP_CLEAR,                                                                                            // VkAttachmentLoadOp                   loadOp;
833                                 VK_ATTACHMENT_STORE_OP_STORE,                                                                                           // VkAttachmentStoreOp                  storeOp;
834                                 VK_ATTACHMENT_LOAD_OP_DONT_CARE,                                                                                        // VkAttachmentLoadOp                   stencilLoadOp;
835                                 VK_ATTACHMENT_STORE_OP_DONT_CARE,                                                                                       // VkAttachmentStoreOp                  stencilStoreOp;
836                                 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,                                                                       // VkImageLayout                                initialLayout;
837                                 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,                                                                       // VkImageLayout                                finalLayout;
838                         };
839
840                         Move<VkImage> colorImage = createImage(vk, vkDevice, &colorImageParams);
841                         colorImages.push_back(de::SharedPtr<Unique<VkImage> >(new Unique<VkImage>(colorImage)));
842                         attachmentClearValues.push_back(getDefaultClearColor());
843
844                         // Allocate and bind color image memory
845                         {
846                                 de::MovePtr<Allocation> colorImageAlloc = memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, *((const VkImage*) colorImages.back().get())), MemoryRequirement::Any);
847                                 VK_CHECK(vk.bindImageMemory(vkDevice, colorImages.back().get()->get(), colorImageAlloc->getMemory(), colorImageAlloc->getOffset()));
848                                 colorImageAllocs.push_back(de::SharedPtr<Allocation>(colorImageAlloc.release()));
849
850                                 attachments.push_back(colorAttachmentDescription);
851                                 colorBlendAttachmentStates.push_back(colorBlendAttachmentState);
852
853                                 const VkAttachmentReference colorAttachmentReference =
854                                 {
855                                         (deUint32) (colorImages.size() - 1),                    //      deUint32                attachment;
856                                         VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL                //      VkImageLayout   layout;
857                                 };
858
859                                 colorAttachmentReferences.push_back(colorAttachmentReference);
860                         }
861
862                         // Create color attachment view
863                         {
864                                 const VkImageViewCreateInfo colorImageViewParams =
865                                 {
866                                         VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,                       // VkStructureType                      sType;
867                                         DE_NULL,                                                                                        // const void*                          pNext;
868                                         0u,                                                                                                     // VkImageViewCreateFlags       flags;
869                                         colorImages.back().get()->get(),                                        // VkImage                                      image;
870                                         VK_IMAGE_VIEW_TYPE_2D,                                                          // VkImageViewType                      viewType;
871                                         colorFormat,                                                                            // VkFormat                                     format;
872                                         {
873                                                 VK_COMPONENT_SWIZZLE_R,                                                 // VkComponentSwizzle           r;
874                                                 VK_COMPONENT_SWIZZLE_G,                                                 // VkComponentSwizzle           g;
875                                                 VK_COMPONENT_SWIZZLE_B,                                                 // VkComponentSwizzle           b;
876                                                 VK_COMPONENT_SWIZZLE_A                                                  // VkComponentSwizzle           a;
877                                         },                                                                                                      // VkComponentMapping           components;
878                                         {
879                                                 VK_IMAGE_ASPECT_COLOR_BIT,                                              // VkImageAspectFlags           aspectMask;
880                                                 0u,                                                                                             // deUint32                                     baseMipLevel;
881                                                 1u,                                                                                             // deUint32                                     mipLevels;
882                                                 0u,                                                                                             // deUint32                                     baseArraySlice;
883                                                 1u                                                                                              // deUint32                                     arraySize;
884                                         }                                                                                                       // VkImageSubresourceRange      subresourceRange;
885                                 };
886
887                                 Move<VkImageView> colorImageView = createImageView(vk, vkDevice, &colorImageViewParams);
888                                 colorImageViews.push_back(de::SharedPtr<Unique<VkImageView> >(new Unique<VkImageView>(colorImageView)));
889
890                                 const VkImageMemoryBarrier      colorImagePreRenderBarrier =
891                                 {
892                                         VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,                                 // sType
893                                         DE_NULL,                                                                                                // pNext
894                                         0u,                                                                                                             // srcAccessMask
895                                         (VK_ACCESS_COLOR_ATTACHMENT_READ_BIT |
896                                         VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT),                                  // dstAccessMask
897                                         VK_IMAGE_LAYOUT_UNDEFINED,                                                              // oldLayout
898                                         VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,                               // newLayout
899                                         VK_QUEUE_FAMILY_IGNORED,                                                                // srcQueueFamilyIndex
900                                         VK_QUEUE_FAMILY_IGNORED,                                                                // dstQueueFamilyIndex
901                                         colorImages.back().get()->get(),                                                // image
902                                         {
903                                                 VK_IMAGE_ASPECT_COLOR_BIT,                                                              // aspectMask
904                                                 0u,                                                                                                             // baseMipLevel
905                                                 1u,                                                                                                             // levelCount
906                                                 0u,                                                                                                             // baseArrayLayer
907                                                 1u,                                                                                                             // layerCount
908                                         }                                                                                                               // subresourceRange
909                                 };
910                                 colorImagePreRenderBarriers.push_back(colorImagePreRenderBarrier);
911
912                                 const VkImageMemoryBarrier      colorImagePostRenderBarrier =
913                                 {
914                                         VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,                                 // sType
915                                         DE_NULL,                                                                                                // pNext
916                                         (VK_ACCESS_COLOR_ATTACHMENT_READ_BIT |
917                                         VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT),                                  // srcAccessMask
918                                         VK_ACCESS_TRANSFER_READ_BIT,                                                    // dstAccessMask
919                                         VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,                               // oldLayout
920                                         VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,                                   // newLayout
921                                         VK_QUEUE_FAMILY_IGNORED,                                                                // srcQueueFamilyIndex
922                                         VK_QUEUE_FAMILY_IGNORED,                                                                // dstQueueFamilyIndex
923                                         colorImages.back().get()->get(),                                                // image
924                                         {
925                                                 VK_IMAGE_ASPECT_COLOR_BIT,                                                              // aspectMask
926                                                 0u,                                                                                                             // baseMipLevel
927                                                 1u,                                                                                                             // levelCount
928                                                 0u,                                                                                                             // baseArrayLayer
929                                                 1u,                                                                                                             // layerCount
930                                         }                                                                                                               // subresourceRange
931                                 };
932                                 colorImagePostRenderBarriers.push_back(colorImagePostRenderBarrier);
933                         }
934                 }
935         }
936
937         // Create render pass
938         {
939                 const VkSubpassDescription subpassDescription =
940                 {
941                         0u,                                                                                                     // VkSubpassDescriptionFlags    flags;
942                         VK_PIPELINE_BIND_POINT_GRAPHICS,                                        // VkPipelineBindPoint                  pipelineBindPoint;
943                         0u,                                                                                                     // deUint32                                             inputCount;
944                         DE_NULL,                                                                                        // const VkAttachmentReference* pInputAttachments;
945                         (deUint32)colorImages.size(),                                           // deUint32                                             colorCount;
946                         &colorAttachmentReferences[0],                                          // const VkAttachmentReference* colorAttachments;
947                         DE_NULL,                                                                                        // const VkAttachmentReference* resolveAttachments;
948                         DE_NULL,                                                                                        // VkAttachmentReference                depthStencilAttachment;
949                         0u,                                                                                                     // deUint32                                             preserveCount;
950                         DE_NULL                                                                                         // const VkAttachmentReference* pPreserveAttachments;
951                 };
952
953                 const VkRenderPassCreateInfo renderPassParams =
954                 {
955                         VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,                      // VkStructureType                                      sType;
956                         DE_NULL,                                                                                        // const void*                                          pNext;
957                         (VkRenderPassCreateFlags)0,                                                     // VkRenderPassCreateFlags                      flags;
958                         (deUint32)attachments.size(),                                           // deUint32                                                     attachmentCount;
959                         &attachments[0],                                                                        // const VkAttachmentDescription*       pAttachments;
960                         1u,                                                                                                     // deUint32                                                     subpassCount;
961                         &subpassDescription,                                                            // const VkSubpassDescription*          pSubpasses;
962                         0u,                                                                                                     // deUint32                                                     dependencyCount;
963                         DE_NULL                                                                                         // const VkSubpassDependency*           pDependencies;
964                 };
965
966                 renderPass = createRenderPass(vk, vkDevice, &renderPassParams);
967         }
968
969         // Create framebuffer
970         {
971                 std::vector<VkImageView> views(colorImageViews.size());
972                 for (size_t i = 0; i < colorImageViews.size(); i++)
973                 {
974                         views[i] = colorImageViews[i].get()->get();
975                 }
976
977                 const VkFramebufferCreateInfo framebufferParams =
978                 {
979                         VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,                      // VkStructureType                              sType;
980                         DE_NULL,                                                                                        // const void*                                  pNext;
981                         0u,                                                                                                     // VkFramebufferCreateFlags             flags;
982                         *renderPass,                                                                            // VkRenderPass                                 renderPass;
983                         (deUint32)views.size(),                                                         // deUint32                                             attachmentCount;
984                         &views[0],                                                                                      // const VkImageView*                   pAttachments;
985                         (deUint32)renderSize.x(),                                                       // deUint32                                             width;
986                         (deUint32)renderSize.y(),                                                       // deUint32                                             height;
987                         1u                                                                                                      // deUint32                                             layers;
988                 };
989
990                 framebuffer = createFramebuffer(vk, vkDevice, &framebufferParams);
991         }
992
993         // Create pipeline layout
994         {
995                 const VkDescriptorSetLayout                     setLayouts[]                    =
996                 {
997                         *emptyDescriptorSetLayout,
998                         m_extraResourcesLayout
999                 };
1000                 const VkPipelineLayoutCreateInfo        pipelineLayoutParams    =
1001                 {
1002                         VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,          // VkStructureType                              sType;
1003                         DE_NULL,                                                                                        // const void*                                  pNext;
1004                         (VkPipelineLayoutCreateFlags)0,                                         // VkPipelineLayoutCreateFlags  flags;
1005                         (m_extraResourcesLayout != 0 ? 2u : 0u),                        // deUint32                                             descriptorSetCount;
1006                         setLayouts,                                                                                     // const VkDescriptorSetLayout* pSetLayouts;
1007                         0u,                                                                                                     // deUint32                                             pushConstantRangeCount;
1008                         DE_NULL                                                                                         // const VkPushConstantRange*   pPushConstantRanges;
1009                 };
1010
1011                 pipelineLayout = createPipelineLayout(vk, vkDevice, &pipelineLayoutParams);
1012         }
1013
1014         // Create shaders
1015         {
1016                 vertexShaderModule              = createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("vert"), 0);
1017                 fragmentShaderModule    = createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("frag"), 0);
1018
1019                 if (useGeometryShader)
1020                 {
1021                         geometryShaderModule = createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("geom"), 0);
1022                 }
1023         }
1024
1025         // Create pipeline
1026         {
1027                 std::vector<VkPipelineShaderStageCreateInfo> shaderStageParams;
1028
1029                 const VkPipelineShaderStageCreateInfo vertexShaderStageParams =
1030                 {
1031                         VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,            // VkStructureType                                              sType;
1032                         DE_NULL,                                                                                                        // const void*                                                  pNext;
1033                         (VkPipelineShaderStageCreateFlags)0,                                            // VkPipelineShaderStageCreateFlags             flags;
1034                         VK_SHADER_STAGE_VERTEX_BIT,                                                                     // VkShaderStageFlagBits                                stage;
1035                         *vertexShaderModule,                                                                            // VkShaderModule                                               module;
1036                         "main",                                                                                                         // const char*                                                  pName;
1037                         DE_NULL                                                                                                         // const VkSpecializationInfo*                  pSpecializationInfo;
1038                 };
1039
1040                 const VkPipelineShaderStageCreateInfo fragmentShaderStageParams =
1041                 {
1042                         VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,            // VkStructureType                                              sType;
1043                         DE_NULL,                                                                                                        // const void*                                                  pNext;
1044                         (VkPipelineShaderStageCreateFlags)0,                                            // VkPipelineShaderStageCreateFlags             flags;
1045                         VK_SHADER_STAGE_FRAGMENT_BIT,                                                           // VkShaderStageFlagBits                                stage;
1046                         *fragmentShaderModule,                                                                          // VkShaderModule                                               module;
1047                         "main",                                                                                                         // const char*                                                  pName;
1048                         DE_NULL                                                                                                         // const VkSpecializationInfo*                  pSpecializationInfo;
1049                 };
1050
1051                 shaderStageParams.push_back(vertexShaderStageParams);
1052                 shaderStageParams.push_back(fragmentShaderStageParams);
1053
1054                 if (useGeometryShader)
1055                 {
1056                         const VkPipelineShaderStageCreateInfo geometryShaderStageParams =
1057                         {
1058                                 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,            // VkStructureType                                              sType;
1059                                 DE_NULL,                                                                                                        // const void*                                                  pNext;
1060                                 (VkPipelineShaderStageCreateFlags)0,                                            // VkPipelineShaderStageCreateFlags             flags;
1061                                 VK_SHADER_STAGE_GEOMETRY_BIT,                                                           // VkShaderStageFlagBits                                stage;
1062                                 *geometryShaderModule,                                                                          // VkShaderModule                                               module;
1063                                 "main",                                                                                                         // VkShader                                                             shader;
1064                                 DE_NULL                                                                                                         // const VkSpecializationInfo*                  pSpecializationInfo;
1065                         };
1066
1067                         shaderStageParams.push_back(geometryShaderStageParams);
1068                 }
1069
1070                 const VkPipelineVertexInputStateCreateInfo vertexInputStateParams =
1071                 {
1072                         VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,      // VkStructureType                                                              sType;
1073                         DE_NULL,                                                                                                        // const void*                                                                  pNext;
1074                         (VkPipelineVertexInputStateCreateFlags)0,                                       // VkPipelineVertexInputStateCreateFlags                flags;
1075                         (deUint32)m_vertexBindingDescriptions.size(),                           // deUint32                                                                             bindingCount;
1076                         &m_vertexBindingDescriptions[0],                                                        // const VkVertexInputBindingDescription*               pVertexBindingDescriptions;
1077                         (deUint32)m_vertexAttributeDescriptions.size(),                         // deUint32                                                                             attributeCount;
1078                         &m_vertexAttributeDescriptions[0],                                                      // const VkVertexInputAttributeDescription*             pvertexAttributeDescriptions;
1079                 };
1080
1081                 const VkPipelineInputAssemblyStateCreateInfo inputAssemblyStateParams =
1082                 {
1083                         VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,    // VkStructureType                                                      sType;
1084                         DE_NULL,                                                                                                                // const void*                                                          pNext;
1085                         (VkPipelineInputAssemblyStateCreateFlags)0,                                             // VkPipelineInputAssemblyStateCreateFlags      flags;
1086                         VK_PRIMITIVE_TOPOLOGY_POINT_LIST,                                                               // VkPrimitiveTopology                                          topology;
1087                         DE_FALSE                                                                                                                // VkBool32                                                                     primitiveRestartEnable;
1088                 };
1089
1090                 const VkViewport viewport =
1091                 {
1092                         0.0f,                                           // float        originX;
1093                         0.0f,                                           // float        originY;
1094                         (float)renderSize.x(),          // float        width;
1095                         (float)renderSize.y(),          // float        height;
1096                         0.0f,                                           // float        minDepth;
1097                         1.0f                                            // float        maxDepth;
1098                 };
1099
1100                 const VkRect2D scissor =
1101                 {
1102                         {
1103                                 0u,                                             // deUint32     x;
1104                                 0u,                                             // deUint32     y;
1105                         },                                                      // VkOffset2D   offset;
1106                         {
1107                                 renderSize.x(),                 // deUint32     width;
1108                                 renderSize.y(),                 // deUint32     height;
1109                         },                                                      // VkExtent2D   extent;
1110                 };
1111
1112                 const VkPipelineViewportStateCreateInfo viewportStateParams =
1113                 {
1114                         VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO,  // VkStructureType                                                                              sType;
1115                         DE_NULL,                                                                                                // const void*                                                                                  pNext;
1116                         0u,                                                                                                             // VkPipelineViewportStateCreateFlags                                   flags;
1117                         1u,                                                                                                             // deUint32                                                                                             viewportCount;
1118                         &viewport,                                                                                              // const VkViewport*                                                                    pViewports;
1119                         1u,                                                                                                             // deUint32                                                                                             scissorsCount;
1120                         &scissor                                                                                                // const VkRect2D*                                                                              pScissors;
1121                 };
1122
1123                 const VkPipelineRasterizationStateCreateInfo rasterStateParams =
1124                 {
1125                         VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO,             // VkStructureType                                                              sType;
1126                         DE_NULL,                                                                                                                // const void*                                                                  pNext;
1127                         (VkPipelineRasterizationStateCreateFlags)0u,                                    //VkPipelineRasterizationStateCreateFlags               flags;
1128                         VK_FALSE,                                                                                                               // VkBool32                                                                             depthClipEnable;
1129                         VK_FALSE,                                                                                                               // VkBool32                                                                             rasterizerDiscardEnable;
1130                         VK_POLYGON_MODE_FILL,                                                                                   // VkPolygonMode                                                                polygonMode;
1131                         VK_CULL_MODE_NONE,                                                                                              // VkCullModeFlags                                                              cullMode;
1132                         VK_FRONT_FACE_COUNTER_CLOCKWISE,                                                                // VkFrontFace                                                                  frontFace;
1133                         VK_FALSE,                                                                                                               // VkBool32                                                                             depthBiasEnable;
1134                         0.0f,                                                                                                                   // float                                                                                depthBias;
1135                         0.0f,                                                                                                                   // float                                                                                depthBiasClamp;
1136                         0.0f,                                                                                                                   // float                                                                                slopeScaledDepthBias;
1137                         1.0f                                                                                                                    // float                                                                                lineWidth;
1138                 };
1139
1140                 const VkPipelineMultisampleStateCreateInfo multisampleStateParams =
1141                 {
1142                         VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,               // VkStructureType                                                      sType;
1143                         DE_NULL,                                                                                                                // const void*                                                          pNext;
1144                         0u,                                                                                                                             // VkPipelineMultisampleStateCreateFlags        flags;
1145                         VK_SAMPLE_COUNT_1_BIT,                                                                                  // VkSampleCountFlagBits                                        rasterizationSamples;
1146                         VK_FALSE,                                                                                                               // VkBool32                                                                     sampleShadingEnable;
1147                         0.0f,                                                                                                                   // float                                                                        minSampleShading;
1148                         DE_NULL,                                                                                                                // const VkSampleMask*                                          pSampleMask;
1149                         VK_FALSE,                                                                                                               // VkBool32                                                                     alphaToCoverageEnable;
1150                         VK_FALSE                                                                                                                // VkBool32                                                                     alphaToOneEnable;
1151                 };
1152
1153                 const VkPipelineColorBlendStateCreateInfo colorBlendStateParams =
1154                 {
1155                         VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,               // VkStructureType                                                              sType;
1156                         DE_NULL,                                                                                                                // const void*                                                                  pNext;
1157                         (VkPipelineColorBlendStateCreateFlags)0,                                                // VkPipelineColorBlendStateCreateFlags                 flags;
1158                         VK_FALSE,                                                                                                               // VkBool32                                                                             logicOpEnable;
1159                         VK_LOGIC_OP_COPY,                                                                                               // VkLogicOp                                                                    logicOp;
1160                         (deUint32)colorBlendAttachmentStates.size(),                                    // deUint32                                                                             attachmentCount;
1161                         &colorBlendAttachmentStates[0],                                                                 // const VkPipelineColorBlendAttachmentState*   pAttachments;
1162                         { 0.0f, 0.0f, 0.0f, 0.0f }                                                                              // float                                                                                blendConst[4];
1163                 };
1164
1165                 const VkGraphicsPipelineCreateInfo graphicsPipelineParams =
1166                 {
1167                         VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,        // VkStructureType                                                                      sType;
1168                         DE_NULL,                                                                                        // const void*                                                                          pNext;
1169                         (VkPipelineCreateFlags)0,                                                       // VkPipelineCreateFlags                                                        flags;
1170                         (deUint32)shaderStageParams.size(),                                     // deUint32                                                                                     stageCount;
1171                         &shaderStageParams[0],                                                          // const VkPipelineShaderStageCreateInfo*                       pStages;
1172                         &vertexInputStateParams,                                                        // const VkPipelineVertexInputStateCreateInfo*          pVertexInputState;
1173                         &inputAssemblyStateParams,                                                      // const VkPipelineInputAssemblyStateCreateInfo*        pInputAssemblyState;
1174                         DE_NULL,                                                                                        // const VkPipelineTessellationStateCreateInfo*         pTessellationState;
1175                         &viewportStateParams,                                                           // const VkPipelineViewportStateCreateInfo*                     pViewportState;
1176                         &rasterStateParams,                                                                     // const VkPipelineRasterStateCreateInfo*                       pRasterState;
1177                         &multisampleStateParams,                                                        // const VkPipelineMultisampleStateCreateInfo*          pMultisampleState;
1178                         DE_NULL,                                                                                        // const VkPipelineDepthStencilStateCreateInfo*         pDepthStencilState;
1179                         &colorBlendStateParams,                                                         // const VkPipelineColorBlendStateCreateInfo*           pColorBlendState;
1180                         (const VkPipelineDynamicStateCreateInfo*)DE_NULL,       // const VkPipelineDynamicStateCreateInfo*                      pDynamicState;
1181                         *pipelineLayout,                                                                        // VkPipelineLayout                                                                     layout;
1182                         *renderPass,                                                                            // VkRenderPass                                                                         renderPass;
1183                         0u,                                                                                                     // deUint32                                                                                     subpass;
1184                         0u,                                                                                                     // VkPipeline                                                                           basePipelineHandle;
1185                         0u                                                                                                      // deInt32                                                                                      basePipelineIndex;
1186                 };
1187
1188                 graphicsPipeline = createGraphicsPipeline(vk, vkDevice, DE_NULL, &graphicsPipelineParams);
1189         }
1190
1191         // Create command pool
1192         cmdPool = createCommandPool(vk, vkDevice, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, queueFamilyIndex);
1193
1194         // Create command buffer
1195         {
1196                 const VkCommandBufferBeginInfo cmdBufferBeginInfo =
1197                 {
1198                         VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,    // VkStructureType                              sType;
1199                         DE_NULL,                                                                                // const void*                                  pNext;
1200                         0u,                                                                                             // VkCmdBufferOptimizeFlags             flags;
1201                         (const VkCommandBufferInheritanceInfo*)DE_NULL,
1202                 };
1203
1204                 const VkRenderPassBeginInfo renderPassBeginInfo =
1205                 {
1206                         VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,                               // VkStructureType              sType;
1207                         DE_NULL,                                                                                                // const void*                  pNext;
1208                         *renderPass,                                                                                    // VkRenderPass                 renderPass;
1209                         *framebuffer,                                                                                   // VkFramebuffer                framebuffer;
1210                         { { 0, 0 }, { renderSize.x(), renderSize.y() } },               // VkRect2D                             renderArea;
1211                         (deUint32)attachmentClearValues.size(),                                 // deUint32                             attachmentCount;
1212                         &attachmentClearValues[0]                                                               // const VkClearValue*  pAttachmentClearValues;
1213                 };
1214
1215                 cmdBuffer = allocateCommandBuffer(vk, vkDevice, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
1216
1217                 VK_CHECK(vk.beginCommandBuffer(*cmdBuffer, &cmdBufferBeginInfo));
1218
1219                 vk.cmdPipelineBarrier(*cmdBuffer, vk::VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, vk::VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, (VkDependencyFlags)0,
1220                                                           0, (const VkMemoryBarrier*)DE_NULL,
1221                                                           0, (const VkBufferMemoryBarrier*)DE_NULL,
1222                                                           (deUint32)colorImagePreRenderBarriers.size(), colorImagePreRenderBarriers.empty() ? DE_NULL : &colorImagePreRenderBarriers[0]);
1223                 vk.cmdBeginRenderPass(*cmdBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
1224
1225                 vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *graphicsPipeline);
1226
1227                 if (m_extraResourcesLayout != 0)
1228                 {
1229                         DE_ASSERT(extraResources != 0);
1230                         const VkDescriptorSet   descriptorSets[]        = { *emptyDescriptorSet, extraResources };
1231                         vk.cmdBindDescriptorSets(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipelineLayout, 0u, DE_LENGTH_OF_ARRAY(descriptorSets), descriptorSets, 0u, DE_NULL);
1232                 }
1233                 else
1234                         DE_ASSERT(extraResources == 0);
1235
1236                 const deUint32 numberOfVertexAttributes = (deUint32)m_vertexBuffers.size();
1237
1238                 std::vector<VkDeviceSize> offsets(numberOfVertexAttributes, 0);
1239
1240                 std::vector<VkBuffer> buffers(numberOfVertexAttributes);
1241                 for (size_t i = 0; i < numberOfVertexAttributes; i++)
1242                 {
1243                         buffers[i] = m_vertexBuffers[i].get()->get();
1244                 }
1245
1246                 vk.cmdBindVertexBuffers(*cmdBuffer, 0, numberOfVertexAttributes, &buffers[0], &offsets[0]);
1247                 vk.cmdDraw(*cmdBuffer, (deUint32)positions.size(), 1u, 0u, 0u);
1248
1249                 vk.cmdEndRenderPass(*cmdBuffer);
1250                 vk.cmdPipelineBarrier(*cmdBuffer, vk::VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, vk::VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0,
1251                                                           0, (const VkMemoryBarrier*)DE_NULL,
1252                                                           0, (const VkBufferMemoryBarrier*)DE_NULL,
1253                                                           (deUint32)colorImagePostRenderBarriers.size(), colorImagePostRenderBarriers.empty() ? DE_NULL : &colorImagePostRenderBarriers[0]);
1254
1255                 VK_CHECK(vk.endCommandBuffer(*cmdBuffer));
1256         }
1257
1258         // Create fence
1259         fence = createFence(vk, vkDevice);
1260
1261         // Execute Draw
1262         {
1263
1264                 const VkSubmitInfo submitInfo =
1265                 {
1266                         VK_STRUCTURE_TYPE_SUBMIT_INFO,                  // sType
1267                         DE_NULL,                                                                // pNext
1268                         0u,                                                                             // waitSemaphoreCount
1269                         DE_NULL,                                                                // pWaitSemaphores
1270                         (const VkPipelineStageFlags*)DE_NULL,
1271                         1u,                                                                             // commandBufferCount
1272                         &cmdBuffer.get(),                                               // pCommandBuffers
1273                         0u,                                                                             // signalSemaphoreCount
1274                         DE_NULL                                                                 // pSignalSemaphores
1275                 };
1276
1277                 VK_CHECK(vk.resetFences(vkDevice, 1, &fence.get()));
1278                 VK_CHECK(vk.queueSubmit(queue, 1, &submitInfo, *fence));
1279                 VK_CHECK(vk.waitForFences(vkDevice, 1, &fence.get(), DE_TRUE, ~(0ull) /* infinity*/));
1280         }
1281
1282         // Read back result and output
1283         {
1284                 const VkDeviceSize imageSizeBytes = (VkDeviceSize)(4 * sizeof(deUint32) * renderSize.x() * renderSize.y());
1285                 const VkBufferCreateInfo readImageBufferParams =
1286                 {
1287                         VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,           // VkStructureType              sType;
1288                         DE_NULL,                                                                        // const void*                  pNext;
1289                         0u,                                                                                     // VkBufferCreateFlags  flags;
1290                         imageSizeBytes,                                                         // VkDeviceSize                 size;
1291                         VK_BUFFER_USAGE_TRANSFER_DST_BIT,                       // VkBufferUsageFlags   usage;
1292                         VK_SHARING_MODE_EXCLUSIVE,                                      // VkSharingMode                sharingMode;
1293                         1u,                                                                                     // deUint32                             queueFamilyCount;
1294                         &queueFamilyIndex,                                                      // const deUint32*              pQueueFamilyIndices;
1295                 };
1296
1297                 // constants for image copy
1298                 Move<VkCommandPool>     copyCmdPool = createCommandPool(vk, vkDevice, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, queueFamilyIndex);
1299
1300                 const VkCommandBufferBeginInfo cmdBufferBeginInfo =
1301                 {
1302                         VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,    // VkStructureType                                      sType;
1303                         DE_NULL,                                                                                // const void*                                          pNext;
1304                         0u,                                                                                             // VkCmdBufferOptimizeFlags                     flags;
1305                         (const VkCommandBufferInheritanceInfo*)DE_NULL,
1306                 };
1307
1308                 const VkBufferImageCopy copyParams =
1309                 {
1310                         0u,                                                                                     // VkDeviceSize                 bufferOffset;
1311                         (deUint32)renderSize.x(),                                       // deUint32                             bufferRowLength;
1312                         (deUint32)renderSize.y(),                                       // deUint32                             bufferImageHeight;
1313                         {
1314                                 VK_IMAGE_ASPECT_COLOR_BIT,                              // VkImageAspect                aspect;
1315                                 0u,                                                                             // deUint32                             mipLevel;
1316                                 0u,                                                                             // deUint32                             arraySlice;
1317                                 1u,                                                                             // deUint32                             arraySize;
1318                         },                                                                                      // VkImageSubresource   imageSubresource;
1319                         { 0u, 0u, 0u },                                                         // VkOffset3D                   imageOffset;
1320                         { renderSize.x(), renderSize.y(), 1u }          // VkExtent3D                   imageExtent;
1321                 };
1322
1323                 // Read back pixels.
1324                 for (int outNdx = 0; outNdx < (int)m_shaderSpec.outputs.size(); ++outNdx)
1325                 {
1326                         const Symbol&                           output                  = m_shaderSpec.outputs[outNdx];
1327                         const int                                       outSize                 = output.varType.getScalarSize();
1328                         const int                                       outVecSize              = glu::getDataTypeNumComponents(output.varType.getBasicType());
1329                         const int                                       outNumLocs              = glu::getDataTypeNumLocations(output.varType.getBasicType());
1330                         deUint32*                                       dstPtrBase              = static_cast<deUint32*>(outputs[outNdx]);
1331                         const int                                       outLocation             = de::lookup(m_outputLayout.locationMap, output.name);
1332
1333                         for (int locNdx = 0; locNdx < outNumLocs; ++locNdx)
1334                         {
1335                                 tcu::TextureLevel                       tmpBuf;
1336                                 const tcu::TextureFormat        format = getRenderbufferFormatForOutput(output.varType, false);
1337                                 const tcu::TextureFormat        readFormat (tcu::TextureFormat::RGBA, format.type);
1338                                 const Unique<VkBuffer>          readImageBuffer(createBuffer(vk, vkDevice, &readImageBufferParams));
1339                                 const de::UniquePtr<Allocation> readImageBufferMemory(memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *readImageBuffer), MemoryRequirement::HostVisible));
1340
1341                                 VK_CHECK(vk.bindBufferMemory(vkDevice, *readImageBuffer, readImageBufferMemory->getMemory(), readImageBufferMemory->getOffset()));
1342
1343                                 // Copy image to buffer
1344                                 {
1345
1346                                         Move<VkCommandBuffer> copyCmdBuffer = allocateCommandBuffer(vk, vkDevice, *copyCmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
1347
1348                                         const VkSubmitInfo submitInfo =
1349                                         {
1350                                                 VK_STRUCTURE_TYPE_SUBMIT_INFO,
1351                                                 DE_NULL,
1352                                                 0u,
1353                                                 (const VkSemaphore*)DE_NULL,
1354                                                 (const VkPipelineStageFlags*)DE_NULL,
1355                                                 1u,
1356                                                 &copyCmdBuffer.get(),
1357                                                 0u,
1358                                                 (const VkSemaphore*)DE_NULL,
1359                                         };
1360
1361                                         VK_CHECK(vk.beginCommandBuffer(*copyCmdBuffer, &cmdBufferBeginInfo));
1362                                         vk.cmdCopyImageToBuffer(*copyCmdBuffer, colorImages[outLocation + locNdx].get()->get(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *readImageBuffer, 1u, &copyParams);
1363                                         VK_CHECK(vk.endCommandBuffer(*copyCmdBuffer));
1364
1365                                         VK_CHECK(vk.resetFences(vkDevice, 1, &fence.get()));
1366                                         VK_CHECK(vk.queueSubmit(queue, 1, &submitInfo, *fence));
1367                                         VK_CHECK(vk.waitForFences(vkDevice, 1, &fence.get(), true, ~(0ull) /* infinity */));
1368                                 }
1369
1370                                 const VkMappedMemoryRange range =
1371                                 {
1372                                         VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE,  // VkStructureType      sType;
1373                                         DE_NULL,                                                                // const void*          pNext;
1374                                         readImageBufferMemory->getMemory(),             // VkDeviceMemory       mem;
1375                                         0,                                                                              // VkDeviceSize         offset;
1376                                         imageSizeBytes,                                                 // VkDeviceSize         size;
1377                                 };
1378
1379                                 VK_CHECK(vk.invalidateMappedMemoryRanges(vkDevice, 1u, &range));
1380
1381                                 tmpBuf.setStorage(readFormat, renderSize.x(), renderSize.y());
1382
1383                                 const tcu::TextureFormat resultFormat(tcu::TextureFormat::RGBA, format.type);
1384                                 const tcu::ConstPixelBufferAccess resultAccess(resultFormat, renderSize.x(), renderSize.y(), 1, readImageBufferMemory->getHostPtr());
1385
1386                                 tcu::copy(tmpBuf.getAccess(), resultAccess);
1387
1388                                 if (outSize == 4 && outNumLocs == 1)
1389                                         deMemcpy(dstPtrBase, tmpBuf.getAccess().getDataPtr(), numValues * outVecSize * sizeof(deUint32));
1390                                 else
1391                                 {
1392                                         for (int valNdx = 0; valNdx < numValues; valNdx++)
1393                                         {
1394                                                 const deUint32* srcPtr = (const deUint32*)tmpBuf.getAccess().getDataPtr() + valNdx * 4;
1395                                                 deUint32*               dstPtr = &dstPtrBase[outSize * valNdx + outVecSize * locNdx];
1396                                                 deMemcpy(dstPtr, srcPtr, outVecSize * sizeof(deUint32));
1397                                         }
1398                                 }
1399                         }
1400                 }
1401         }
1402 }
1403
1404 // VertexShaderExecutor
1405
1406 class VertexShaderExecutor : public FragmentOutExecutor
1407 {
1408 public:
1409                                                                 VertexShaderExecutor    (Context& context, const ShaderSpec& shaderSpec, VkDescriptorSetLayout extraResourcesLayout);
1410         virtual                                         ~VertexShaderExecutor   (void);
1411
1412         static void                                     generateSources                 (const ShaderSpec& shaderSpec, SourceCollections& dst);
1413 };
1414
1415 VertexShaderExecutor::VertexShaderExecutor (Context& context, const ShaderSpec& shaderSpec, VkDescriptorSetLayout extraResourcesLayout)
1416         : FragmentOutExecutor(context, glu::SHADERTYPE_VERTEX, shaderSpec, extraResourcesLayout)
1417 {
1418 }
1419
1420 VertexShaderExecutor::~VertexShaderExecutor (void)
1421 {
1422 }
1423
1424 void VertexShaderExecutor::generateSources (const ShaderSpec& shaderSpec, SourceCollections& programCollection)
1425 {
1426         const FragmentOutputLayout      outputLayout    (computeFragmentOutputLayout(shaderSpec.outputs));
1427
1428         programCollection.glslSources.add("vert") << glu::VertexSource(generateVertexShader(shaderSpec, "a_", "vtx_out_")) << shaderSpec.buildOptions;
1429         /* \todo [2015-09-11 hegedusd] set useIntOutputs parameter if needed. */
1430         programCollection.glslSources.add("frag") << glu::FragmentSource(generatePassthroughFragmentShader(shaderSpec, false, outputLayout.locationMap, "vtx_out_", "o_")) << shaderSpec.buildOptions;
1431 }
1432
1433 // GeometryShaderExecutor
1434
1435 class GeometryShaderExecutor : public FragmentOutExecutor
1436 {
1437 public:
1438                                                                 GeometryShaderExecutor  (Context& context, const ShaderSpec& shaderSpec, VkDescriptorSetLayout extraResourcesLayout);
1439         virtual                                         ~GeometryShaderExecutor (void);
1440
1441         static void                                     generateSources                 (const ShaderSpec& shaderSpec, SourceCollections& programCollection);
1442
1443 };
1444
1445 GeometryShaderExecutor::GeometryShaderExecutor (Context& context, const ShaderSpec& shaderSpec, VkDescriptorSetLayout extraResourcesLayout)
1446         : FragmentOutExecutor(context, glu::SHADERTYPE_GEOMETRY, shaderSpec, extraResourcesLayout)
1447 {
1448         const VkPhysicalDeviceFeatures& features = context.getDeviceFeatures();
1449
1450         if (!features.geometryShader)
1451                 TCU_THROW(NotSupportedError, "Geometry shader type not supported by device");
1452 }
1453
1454 GeometryShaderExecutor::~GeometryShaderExecutor (void)
1455 {
1456 }
1457
1458 void GeometryShaderExecutor::generateSources (const ShaderSpec& shaderSpec, SourceCollections& programCollection)
1459 {
1460         const FragmentOutputLayout      outputLayout    (computeFragmentOutputLayout(shaderSpec.outputs));
1461
1462         programCollection.glslSources.add("vert") << glu::VertexSource(generatePassthroughVertexShader(shaderSpec.inputs, "a_", "vtx_out_")) << shaderSpec.buildOptions;
1463
1464         programCollection.glslSources.add("geom") << glu::GeometrySource(generateGeometryShader(shaderSpec, "vtx_out_", "geom_out_")) << shaderSpec.buildOptions;
1465
1466         /* \todo [2015-09-18 rsipka] set useIntOutputs parameter if needed. */
1467         programCollection.glslSources.add("frag") << glu::FragmentSource(generatePassthroughFragmentShader(shaderSpec, false, outputLayout.locationMap, "geom_out_", "o_")) << shaderSpec.buildOptions;
1468
1469 }
1470
1471 // FragmentShaderExecutor
1472
1473 class FragmentShaderExecutor : public FragmentOutExecutor
1474 {
1475 public:
1476                                                                 FragmentShaderExecutor  (Context& context, const ShaderSpec& shaderSpec, VkDescriptorSetLayout extraResourcesLayout);
1477         virtual                                         ~FragmentShaderExecutor (void);
1478
1479         static void                                     generateSources                 (const ShaderSpec& shaderSpec, SourceCollections& programCollection);
1480
1481 };
1482
1483 FragmentShaderExecutor::FragmentShaderExecutor (Context& context, const ShaderSpec& shaderSpec, VkDescriptorSetLayout extraResourcesLayout)
1484         : FragmentOutExecutor(context, glu::SHADERTYPE_FRAGMENT, shaderSpec, extraResourcesLayout)
1485 {
1486 }
1487
1488 FragmentShaderExecutor::~FragmentShaderExecutor (void)
1489 {
1490 }
1491
1492 void FragmentShaderExecutor::generateSources (const ShaderSpec& shaderSpec, SourceCollections& programCollection)
1493 {
1494         const FragmentOutputLayout      outputLayout    (computeFragmentOutputLayout(shaderSpec.outputs));
1495
1496         programCollection.glslSources.add("vert") << glu::VertexSource(generatePassthroughVertexShader(shaderSpec.inputs, "a_", "vtx_out_")) << shaderSpec.buildOptions;
1497         /* \todo [2015-09-11 hegedusd] set useIntOutputs parameter if needed. */
1498         programCollection.glslSources.add("frag") << glu::FragmentSource(generateFragmentShader(shaderSpec, false, outputLayout.locationMap, "vtx_out_", "o_")) << shaderSpec.buildOptions;
1499 }
1500
1501 // Shared utilities for compute and tess executors
1502
1503 static deUint32 getVecStd430ByteAlignment (glu::DataType type)
1504 {
1505         switch (glu::getDataTypeScalarSize(type))
1506         {
1507                 case 1:         return 4u;
1508                 case 2:         return 8u;
1509                 case 3:         return 16u;
1510                 case 4:         return 16u;
1511                 default:
1512                         DE_ASSERT(false);
1513                         return 0u;
1514         }
1515 }
1516
1517 class BufferIoExecutor : public ShaderExecutor
1518 {
1519 public:
1520                                                         BufferIoExecutor        (Context& context, const ShaderSpec& shaderSpec);
1521         virtual                                 ~BufferIoExecutor       (void);
1522
1523 protected:
1524         enum
1525         {
1526                 INPUT_BUFFER_BINDING    = 0,
1527                 OUTPUT_BUFFER_BINDING   = 1,
1528         };
1529
1530         void                                    initBuffers                     (int numValues);
1531         VkBuffer                                getInputBuffer          (void) const            { return *m_inputBuffer;                                        }
1532         VkBuffer                                getOutputBuffer         (void) const            { return *m_outputBuffer;                                       }
1533         deUint32                                getInputStride          (void) const            { return getLayoutStride(m_inputLayout);        }
1534         deUint32                                getOutputStride         (void) const            { return getLayoutStride(m_outputLayout);       }
1535
1536         void                                    uploadInputBuffer       (const void* const* inputPtrs, int numValues);
1537         void                                    readOutputBuffer        (void* const* outputPtrs, int numValues);
1538
1539         static void                             declareBufferBlocks     (std::ostream& src, const ShaderSpec& spec);
1540         static void                             generateExecBufferIo(std::ostream& src, const ShaderSpec& spec, const char* invocationNdxName);
1541
1542 protected:
1543         Move<VkBuffer>                  m_inputBuffer;
1544         Move<VkBuffer>                  m_outputBuffer;
1545
1546 private:
1547         struct VarLayout
1548         {
1549                 deUint32                offset;
1550                 deUint32                stride;
1551                 deUint32                matrixStride;
1552
1553                 VarLayout (void) : offset(0), stride(0), matrixStride(0) {}
1554         };
1555
1556         static void                             computeVarLayout        (const std::vector<Symbol>& symbols, std::vector<VarLayout>* layout);
1557         static deUint32                 getLayoutStride         (const vector<VarLayout>& layout);
1558
1559         static void                             copyToBuffer            (const glu::VarType& varType, const VarLayout& layout, int numValues, const void* srcBasePtr, void* dstBasePtr);
1560         static void                             copyFromBuffer          (const glu::VarType& varType, const VarLayout& layout, int numValues, const void* srcBasePtr, void* dstBasePtr);
1561
1562         de::MovePtr<Allocation> m_inputAlloc;
1563         de::MovePtr<Allocation> m_outputAlloc;
1564
1565         vector<VarLayout>               m_inputLayout;
1566         vector<VarLayout>               m_outputLayout;
1567 };
1568
1569 BufferIoExecutor::BufferIoExecutor (Context& context, const ShaderSpec& shaderSpec)
1570         : ShaderExecutor(context, shaderSpec)
1571 {
1572         computeVarLayout(m_shaderSpec.inputs, &m_inputLayout);
1573         computeVarLayout(m_shaderSpec.outputs, &m_outputLayout);
1574 }
1575
1576 BufferIoExecutor::~BufferIoExecutor (void)
1577 {
1578 }
1579
1580 inline deUint32 BufferIoExecutor::getLayoutStride (const vector<VarLayout>& layout)
1581 {
1582         return layout.empty() ? 0 : layout[0].stride;
1583 }
1584
1585 void BufferIoExecutor::computeVarLayout (const std::vector<Symbol>& symbols, std::vector<VarLayout>* layout)
1586 {
1587         deUint32        maxAlignment    = 0;
1588         deUint32        curOffset               = 0;
1589
1590         DE_ASSERT(layout != DE_NULL);
1591         DE_ASSERT(layout->empty());
1592         layout->resize(symbols.size());
1593
1594         for (size_t varNdx = 0; varNdx < symbols.size(); varNdx++)
1595         {
1596                 const Symbol&           symbol          = symbols[varNdx];
1597                 const glu::DataType     basicType       = symbol.varType.getBasicType();
1598                 VarLayout&                      layoutEntry     = (*layout)[varNdx];
1599
1600                 if (glu::isDataTypeScalarOrVector(basicType))
1601                 {
1602                         const deUint32  alignment       = getVecStd430ByteAlignment(basicType);
1603                         const deUint32  size            = (deUint32)glu::getDataTypeScalarSize(basicType) * (int)sizeof(deUint32);
1604
1605                         curOffset               = (deUint32)deAlign32((int)curOffset, (int)alignment);
1606                         maxAlignment    = de::max(maxAlignment, alignment);
1607
1608                         layoutEntry.offset                      = curOffset;
1609                         layoutEntry.matrixStride        = 0;
1610
1611                         curOffset += size;
1612                 }
1613                 else if (glu::isDataTypeMatrix(basicType))
1614                 {
1615                         const int                               numVecs                 = glu::getDataTypeMatrixNumColumns(basicType);
1616                         const glu::DataType             vecType                 = glu::getDataTypeFloatVec(glu::getDataTypeMatrixNumRows(basicType));
1617                         const deUint32                  vecAlignment    = getVecStd430ByteAlignment(vecType);
1618
1619                         curOffset               = (deUint32)deAlign32((int)curOffset, (int)vecAlignment);
1620                         maxAlignment    = de::max(maxAlignment, vecAlignment);
1621
1622                         layoutEntry.offset                      = curOffset;
1623                         layoutEntry.matrixStride        = vecAlignment;
1624
1625                         curOffset += vecAlignment*numVecs;
1626                 }
1627                 else
1628                         DE_ASSERT(false);
1629         }
1630
1631         {
1632                 const deUint32  totalSize       = (deUint32)deAlign32(curOffset, maxAlignment);
1633
1634                 for (vector<VarLayout>::iterator varIter = layout->begin(); varIter != layout->end(); ++varIter)
1635                         varIter->stride = totalSize;
1636         }
1637 }
1638
1639 void BufferIoExecutor::declareBufferBlocks (std::ostream& src, const ShaderSpec& spec)
1640 {
1641         // Input struct
1642         if (!spec.inputs.empty())
1643         {
1644                 glu::StructType inputStruct("Inputs");
1645                 for (vector<Symbol>::const_iterator symIter = spec.inputs.begin(); symIter != spec.inputs.end(); ++symIter)
1646                         inputStruct.addMember(symIter->name.c_str(), symIter->varType);
1647                 src << glu::declare(&inputStruct) << ";\n";
1648         }
1649
1650         // Output struct
1651         {
1652                 glu::StructType outputStruct("Outputs");
1653                 for (vector<Symbol>::const_iterator symIter = spec.outputs.begin(); symIter != spec.outputs.end(); ++symIter)
1654                         outputStruct.addMember(symIter->name.c_str(), symIter->varType);
1655                 src << glu::declare(&outputStruct) << ";\n";
1656         }
1657
1658         src << "\n";
1659
1660         if (!spec.inputs.empty())
1661         {
1662                 src     << "layout(set = 0, binding = " << int(INPUT_BUFFER_BINDING) << ", std430) buffer InBuffer\n"
1663                         << "{\n"
1664                         << "    Inputs inputs[];\n"
1665                         << "};\n";
1666         }
1667
1668         src     << "layout(set = 0, binding = " << int(OUTPUT_BUFFER_BINDING) << ", std430) buffer OutBuffer\n"
1669                 << "{\n"
1670                 << "    Outputs outputs[];\n"
1671                 << "};\n"
1672                 << "\n";
1673 }
1674
1675 void BufferIoExecutor::generateExecBufferIo (std::ostream& src, const ShaderSpec& spec, const char* invocationNdxName)
1676 {
1677         for (vector<Symbol>::const_iterator symIter = spec.inputs.begin(); symIter != spec.inputs.end(); ++symIter)
1678                 src << "\t" << glu::declare(symIter->varType, symIter->name) << " = inputs[" << invocationNdxName << "]." << symIter->name << ";\n";
1679
1680         for (vector<Symbol>::const_iterator symIter = spec.outputs.begin(); symIter != spec.outputs.end(); ++symIter)
1681                 src << "\t" << glu::declare(symIter->varType, symIter->name) << ";\n";
1682
1683         src << "\n";
1684
1685         {
1686                 std::istringstream      opSrc   (spec.source);
1687                 std::string                     line;
1688
1689                 while (std::getline(opSrc, line))
1690                         src << "\t" << line << "\n";
1691         }
1692
1693         src << "\n";
1694         for (vector<Symbol>::const_iterator symIter = spec.outputs.begin(); symIter != spec.outputs.end(); ++symIter)
1695                 src << "\toutputs[" << invocationNdxName << "]." << symIter->name << " = " << symIter->name << ";\n";
1696 }
1697
1698 void BufferIoExecutor::copyToBuffer (const glu::VarType& varType, const VarLayout& layout, int numValues, const void* srcBasePtr, void* dstBasePtr)
1699 {
1700         if (varType.isBasicType())
1701         {
1702                 const glu::DataType             basicType               = varType.getBasicType();
1703                 const bool                              isMatrix                = glu::isDataTypeMatrix(basicType);
1704                 const int                               scalarSize              = glu::getDataTypeScalarSize(basicType);
1705                 const int                               numVecs                 = isMatrix ? glu::getDataTypeMatrixNumColumns(basicType) : 1;
1706                 const int                               numComps                = scalarSize / numVecs;
1707
1708                 for (int elemNdx = 0; elemNdx < numValues; elemNdx++)
1709                 {
1710                         for (int vecNdx = 0; vecNdx < numVecs; vecNdx++)
1711                         {
1712                                 const int               srcOffset               = (int)sizeof(deUint32) * (elemNdx * scalarSize + vecNdx * numComps);
1713                                 const int               dstOffset               = layout.offset + layout.stride * elemNdx + (isMatrix ? layout.matrixStride * vecNdx : 0);
1714                                 const deUint8*  srcPtr                  = (const deUint8*)srcBasePtr + srcOffset;
1715                                 deUint8*                dstPtr                  = (deUint8*)dstBasePtr + dstOffset;
1716
1717                                 deMemcpy(dstPtr, srcPtr, sizeof(deUint32) * numComps);
1718                         }
1719                 }
1720         }
1721         else
1722                 throw tcu::InternalError("Unsupported type");
1723 }
1724
1725 void BufferIoExecutor::copyFromBuffer (const glu::VarType& varType, const VarLayout& layout, int numValues, const void* srcBasePtr, void* dstBasePtr)
1726 {
1727         if (varType.isBasicType())
1728         {
1729                 const glu::DataType             basicType               = varType.getBasicType();
1730                 const bool                              isMatrix                = glu::isDataTypeMatrix(basicType);
1731                 const int                               scalarSize              = glu::getDataTypeScalarSize(basicType);
1732                 const int                               numVecs                 = isMatrix ? glu::getDataTypeMatrixNumColumns(basicType) : 1;
1733                 const int                               numComps                = scalarSize / numVecs;
1734
1735                 for (int elemNdx = 0; elemNdx < numValues; elemNdx++)
1736                 {
1737                         for (int vecNdx = 0; vecNdx < numVecs; vecNdx++)
1738                         {
1739                                 const int               srcOffset               = layout.offset + layout.stride * elemNdx + (isMatrix ? layout.matrixStride * vecNdx : 0);
1740                                 const int               dstOffset               = (int)sizeof(deUint32) * (elemNdx * scalarSize + vecNdx * numComps);
1741                                 const deUint8*  srcPtr                  = (const deUint8*)srcBasePtr + srcOffset;
1742                                 deUint8*                dstPtr                  = (deUint8*)dstBasePtr + dstOffset;
1743
1744                                 deMemcpy(dstPtr, srcPtr, sizeof(deUint32) * numComps);
1745                         }
1746                 }
1747         }
1748         else
1749                 throw tcu::InternalError("Unsupported type");
1750 }
1751
1752 void BufferIoExecutor::uploadInputBuffer (const void* const* inputPtrs, int numValues)
1753 {
1754         const VkDevice                  vkDevice                        = m_context.getDevice();
1755         const DeviceInterface&  vk                                      = m_context.getDeviceInterface();
1756
1757         const deUint32                  inputStride                     = getLayoutStride(m_inputLayout);
1758         const int                               inputBufferSize         = inputStride * numValues;
1759
1760         if (inputBufferSize == 0)
1761                 return; // No inputs
1762
1763         DE_ASSERT(m_shaderSpec.inputs.size() == m_inputLayout.size());
1764         for (size_t inputNdx = 0; inputNdx < m_shaderSpec.inputs.size(); ++inputNdx)
1765         {
1766                 const glu::VarType&             varType         = m_shaderSpec.inputs[inputNdx].varType;
1767                 const VarLayout&                layout          = m_inputLayout[inputNdx];
1768
1769                 copyToBuffer(varType, layout, numValues, inputPtrs[inputNdx], m_inputAlloc->getHostPtr());
1770         }
1771
1772         flushMappedMemoryRange(vk, vkDevice, m_inputAlloc->getMemory(), m_inputAlloc->getOffset(), inputBufferSize);
1773 }
1774
1775 void BufferIoExecutor::readOutputBuffer (void* const* outputPtrs, int numValues)
1776 {
1777         const VkDevice                  vkDevice                        = m_context.getDevice();
1778         const DeviceInterface&  vk                                      = m_context.getDeviceInterface();
1779
1780         const deUint32                  outputStride            = getLayoutStride(m_outputLayout);
1781         const int                               outputBufferSize        = numValues * outputStride;
1782
1783         DE_ASSERT(outputBufferSize > 0); // At least some outputs are required.
1784
1785         invalidateMappedMemoryRange(vk, vkDevice, m_outputAlloc->getMemory(), m_outputAlloc->getOffset(), outputBufferSize);
1786
1787         DE_ASSERT(m_shaderSpec.outputs.size() == m_outputLayout.size());
1788         for (size_t outputNdx = 0; outputNdx < m_shaderSpec.outputs.size(); ++outputNdx)
1789         {
1790                 const glu::VarType&             varType         = m_shaderSpec.outputs[outputNdx].varType;
1791                 const VarLayout&                layout          = m_outputLayout[outputNdx];
1792
1793                 copyFromBuffer(varType, layout, numValues, m_outputAlloc->getHostPtr(), outputPtrs[outputNdx]);
1794         }
1795 }
1796
1797 void BufferIoExecutor::initBuffers (int numValues)
1798 {
1799         const deUint32                          inputStride                     = getLayoutStride(m_inputLayout);
1800         const deUint32                          outputStride            = getLayoutStride(m_outputLayout);
1801         // Avoid creating zero-sized buffer/memory
1802         const size_t                            inputBufferSize         = numValues * inputStride ? (numValues * inputStride) : 1;
1803         const size_t                            outputBufferSize        = numValues * outputStride;
1804
1805         // Upload data to buffer
1806         const VkDevice                          vkDevice                        = m_context.getDevice();
1807         const DeviceInterface&          vk                                      = m_context.getDeviceInterface();
1808         const deUint32                          queueFamilyIndex        = m_context.getUniversalQueueFamilyIndex();
1809         Allocator&                                      memAlloc                        = m_context.getDefaultAllocator();
1810
1811         const VkBufferCreateInfo inputBufferParams =
1812         {
1813                 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,           // VkStructureType              sType;
1814                 DE_NULL,                                                                        // const void*                  pNext;
1815                 0u,                                                                                     // VkBufferCreateFlags  flags;
1816                 inputBufferSize,                                                        // VkDeviceSize                 size;
1817                 VK_BUFFER_USAGE_STORAGE_BUFFER_BIT,                     // VkBufferUsageFlags   usage;
1818                 VK_SHARING_MODE_EXCLUSIVE,                                      // VkSharingMode                sharingMode;
1819                 1u,                                                                                     // deUint32                             queueFamilyCount;
1820                 &queueFamilyIndex                                                       // const deUint32*              pQueueFamilyIndices;
1821         };
1822
1823         m_inputBuffer = createBuffer(vk, vkDevice, &inputBufferParams);
1824         m_inputAlloc = memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *m_inputBuffer), MemoryRequirement::HostVisible);
1825
1826         VK_CHECK(vk.bindBufferMemory(vkDevice, *m_inputBuffer, m_inputAlloc->getMemory(), m_inputAlloc->getOffset()));
1827
1828         const VkBufferCreateInfo outputBufferParams =
1829         {
1830                 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,           // VkStructureType              sType;
1831                 DE_NULL,                                                                        // const void*                  pNext;
1832                 0u,                                                                                     // VkBufferCreateFlags  flags;
1833                 outputBufferSize,                                                       // VkDeviceSize                 size;
1834                 VK_BUFFER_USAGE_STORAGE_BUFFER_BIT,                     // VkBufferUsageFlags   usage;
1835                 VK_SHARING_MODE_EXCLUSIVE,                                      // VkSharingMode                sharingMode;
1836                 1u,                                                                                     // deUint32                             queueFamilyCount;
1837                 &queueFamilyIndex                                                       // const deUint32*              pQueueFamilyIndices;
1838         };
1839
1840         m_outputBuffer = createBuffer(vk, vkDevice, &outputBufferParams);
1841         m_outputAlloc = memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *m_outputBuffer), MemoryRequirement::HostVisible);
1842
1843         VK_CHECK(vk.bindBufferMemory(vkDevice, *m_outputBuffer, m_outputAlloc->getMemory(), m_outputAlloc->getOffset()));
1844 }
1845
1846 // ComputeShaderExecutor
1847
1848 class ComputeShaderExecutor : public BufferIoExecutor
1849 {
1850 public:
1851                                                 ComputeShaderExecutor   (Context& context, const ShaderSpec& shaderSpec, VkDescriptorSetLayout extraResourcesLayout);
1852         virtual                         ~ComputeShaderExecutor  (void);
1853
1854         static void                     generateSources                 (const ShaderSpec& shaderSpec, SourceCollections& programCollection);
1855
1856         virtual void            execute                                 (int numValues, const void* const* inputs, void* const* outputs, VkDescriptorSet extraResources);
1857
1858 protected:
1859         static std::string      generateComputeShader   (const ShaderSpec& spec);
1860
1861 private:
1862         const VkDescriptorSetLayout                                     m_extraResourcesLayout;
1863 };
1864
1865 ComputeShaderExecutor::ComputeShaderExecutor(Context& context, const ShaderSpec& shaderSpec, VkDescriptorSetLayout extraResourcesLayout)
1866         : BufferIoExecutor                      (context, shaderSpec)
1867         , m_extraResourcesLayout        (extraResourcesLayout)
1868 {
1869 }
1870
1871 ComputeShaderExecutor::~ComputeShaderExecutor   (void)
1872 {
1873 }
1874
1875 std::string ComputeShaderExecutor::generateComputeShader (const ShaderSpec& spec)
1876 {
1877         std::ostringstream src;
1878         src << glu::getGLSLVersionDeclaration(spec.glslVersion) << "\n";
1879
1880         if (!spec.globalDeclarations.empty())
1881                 src << spec.globalDeclarations << "\n";
1882
1883         src << "layout(local_size_x = 1) in;\n"
1884                 << "\n";
1885
1886         declareBufferBlocks(src, spec);
1887
1888         src << "void main (void)\n"
1889                 << "{\n"
1890                 << "    uint invocationNdx = gl_NumWorkGroups.x*gl_NumWorkGroups.y*gl_WorkGroupID.z\n"
1891                 << "                       + gl_NumWorkGroups.x*gl_WorkGroupID.y + gl_WorkGroupID.x;\n";
1892
1893         generateExecBufferIo(src, spec, "invocationNdx");
1894
1895         src << "}\n";
1896
1897         return src.str();
1898 }
1899
1900 void ComputeShaderExecutor::generateSources (const ShaderSpec& shaderSpec, SourceCollections& programCollection)
1901 {
1902         programCollection.glslSources.add("compute") << glu::ComputeSource(generateComputeShader(shaderSpec)) << shaderSpec.buildOptions;
1903 }
1904
1905 void ComputeShaderExecutor::execute (int numValues, const void* const* inputs, void* const* outputs, VkDescriptorSet extraResources)
1906 {
1907         const VkDevice                                  vkDevice                                = m_context.getDevice();
1908         const DeviceInterface&                  vk                                              = m_context.getDeviceInterface();
1909         const VkQueue                                   queue                                   = m_context.getUniversalQueue();
1910         const deUint32                                  queueFamilyIndex                = m_context.getUniversalQueueFamilyIndex();
1911
1912         DescriptorPoolBuilder                   descriptorPoolBuilder;
1913         DescriptorSetLayoutBuilder              descriptorSetLayoutBuilder;
1914
1915         Move<VkShaderModule>                    computeShaderModule;
1916         Move<VkPipeline>                                computePipeline;
1917         Move<VkPipelineLayout>                  pipelineLayout;
1918         Move<VkCommandPool>                             cmdPool;
1919         Move<VkDescriptorPool>                  descriptorPool;
1920         Move<VkDescriptorSetLayout>             descriptorSetLayout;
1921         Move<VkDescriptorSet>                   descriptorSet;
1922         const deUint32                                  numDescriptorSets               = (m_extraResourcesLayout != 0) ? 2u : 1u;
1923         Move<VkFence>                                   fence;
1924
1925         DE_ASSERT((m_extraResourcesLayout != 0) == (extraResources != 0));
1926
1927         initBuffers(numValues);
1928
1929         // Setup input buffer & copy data
1930         uploadInputBuffer(inputs, numValues);
1931
1932         // Create command pool
1933         cmdPool = createCommandPool(vk, vkDevice, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, queueFamilyIndex);
1934
1935         // Create command buffer
1936         const VkCommandBufferBeginInfo cmdBufferBeginInfo =
1937         {
1938                 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,    // VkStructureType                                      sType;
1939                 DE_NULL,                                                                                // const void*                                          pNext;
1940                 0u,                                                                                             // VkCmdBufferOptimizeFlags                     flags;
1941                 (const VkCommandBufferInheritanceInfo*)DE_NULL,
1942         };
1943
1944         descriptorSetLayoutBuilder.addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_SHADER_STAGE_COMPUTE_BIT);
1945         descriptorPoolBuilder.addType(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER);
1946         descriptorSetLayoutBuilder.addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_SHADER_STAGE_COMPUTE_BIT);
1947         descriptorPoolBuilder.addType(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER);
1948
1949         descriptorSetLayout = descriptorSetLayoutBuilder.build(vk, vkDevice);
1950         descriptorPool = descriptorPoolBuilder.build(vk, vkDevice, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u);
1951
1952         const VkDescriptorSetAllocateInfo allocInfo =
1953         {
1954                 VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
1955                 DE_NULL,
1956                 *descriptorPool,
1957                 1u,
1958                 &*descriptorSetLayout
1959         };
1960
1961         descriptorSet = allocateDescriptorSet(vk, vkDevice, &allocInfo);
1962
1963         // Create pipeline layout
1964         {
1965                 const VkDescriptorSetLayout                     descriptorSetLayouts[]  =
1966                 {
1967                         *descriptorSetLayout,
1968                         m_extraResourcesLayout
1969                 };
1970                 const VkPipelineLayoutCreateInfo        pipelineLayoutParams    =
1971                 {
1972                         VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,          // VkStructureType                              sType;
1973                         DE_NULL,                                                                                        // const void*                                  pNext;
1974                         (VkPipelineLayoutCreateFlags)0,                                         // VkPipelineLayoutCreateFlags  flags;
1975                         numDescriptorSets,                                                                      // deUint32                                             CdescriptorSetCount;
1976                         descriptorSetLayouts,                                                           // const VkDescriptorSetLayout* pSetLayouts;
1977                         0u,                                                                                                     // deUint32                                             pushConstantRangeCount;
1978                         DE_NULL                                                                                         // const VkPushConstantRange*   pPushConstantRanges;
1979                 };
1980
1981                 pipelineLayout = createPipelineLayout(vk, vkDevice, &pipelineLayoutParams);
1982         }
1983
1984         // Create shaders
1985         {
1986                 computeShaderModule             = createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("compute"), 0);
1987         }
1988
1989         // create pipeline
1990         {
1991                 const VkPipelineShaderStageCreateInfo shaderStageParams[1] =
1992                 {
1993                         {
1994                                 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,            // VkStructureType                                              sType;
1995                                 DE_NULL,                                                                                                        // const void*                                                  pNext;
1996                                 (VkPipelineShaderStageCreateFlags)0u,                                           // VkPipelineShaderStageCreateFlags             flags;
1997                                 VK_SHADER_STAGE_COMPUTE_BIT,                                                            // VkShaderStageFlagsBit                                stage;
1998                                 *computeShaderModule,                                                                           // VkShaderModule                                               shader;
1999                                 "main",                                                                                                         // const char*                                                  pName;
2000                                 DE_NULL                                                                                                         // const VkSpecializationInfo*                  pSpecializationInfo;
2001                         }
2002                 };
2003
2004                 const VkComputePipelineCreateInfo computePipelineParams =
2005                 {
2006                         VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO,         // VkStructureType                                                                      sType;
2007                         DE_NULL,                                                                                        // const void*                                                                          pNext;
2008                         (VkPipelineCreateFlags)0,                                                       // VkPipelineCreateFlags                                                        flags;
2009                         *shaderStageParams,                                                                     // VkPipelineShaderStageCreateInfo                                      cs;
2010                         *pipelineLayout,                                                                        // VkPipelineLayout                                                                     layout;
2011                         0u,                                                                                                     // VkPipeline                                                                           basePipelineHandle;
2012                         0u,                                                                                                     // int32_t                                                                                      basePipelineIndex;
2013                 };
2014
2015                 computePipeline = createComputePipeline(vk, vkDevice, DE_NULL, &computePipelineParams);
2016         }
2017
2018         // Create fence
2019         fence = createFence(vk, vkDevice);
2020
2021         const int                       maxValuesPerInvocation  = m_context.getDeviceProperties().limits.maxComputeWorkGroupSize[0];
2022         int                                     curOffset                               = 0;
2023         const deUint32          inputStride                             = getInputStride();
2024         const deUint32          outputStride                    = getOutputStride();
2025
2026         while (curOffset < numValues)
2027         {
2028                 Move<VkCommandBuffer>   cmdBuffer;
2029                 const int                               numToExec       = de::min(maxValuesPerInvocation, numValues-curOffset);
2030
2031                 // Update descriptors
2032                 {
2033                         DescriptorSetUpdateBuilder descriptorSetUpdateBuilder;
2034
2035                         const VkDescriptorBufferInfo outputDescriptorBufferInfo =
2036                         {
2037                                 *m_outputBuffer,                                // VkBuffer                     buffer;
2038                                 curOffset * outputStride,               // VkDeviceSize         offset;
2039                                 numToExec * outputStride                // VkDeviceSize         range;
2040                         };
2041
2042                         descriptorSetUpdateBuilder.writeSingle(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding((deUint32)OUTPUT_BUFFER_BINDING), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &outputDescriptorBufferInfo);
2043
2044                         if (inputStride)
2045                         {
2046                                 const VkDescriptorBufferInfo inputDescriptorBufferInfo =
2047                                 {
2048                                         *m_inputBuffer,                                 // VkBuffer                     buffer;
2049                                         curOffset * inputStride,                // VkDeviceSize         offset;
2050                                         numToExec * inputStride                 // VkDeviceSize         range;
2051                                 };
2052
2053                                 descriptorSetUpdateBuilder.writeSingle(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding((deUint32)INPUT_BUFFER_BINDING), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &inputDescriptorBufferInfo);
2054                         }
2055
2056                         descriptorSetUpdateBuilder.update(vk, vkDevice);
2057                 }
2058
2059                 cmdBuffer = allocateCommandBuffer(vk, vkDevice, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
2060                 VK_CHECK(vk.beginCommandBuffer(*cmdBuffer, &cmdBufferBeginInfo));
2061                 vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *computePipeline);
2062
2063                 {
2064                         const VkDescriptorSet   descriptorSets[]        = { *descriptorSet, extraResources };
2065                         vk.cmdBindDescriptorSets(*cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *pipelineLayout, 0u, numDescriptorSets, descriptorSets, 0u, DE_NULL);
2066                 }
2067
2068                 vk.cmdDispatch(*cmdBuffer, numToExec, 1, 1);
2069
2070                 VK_CHECK(vk.endCommandBuffer(*cmdBuffer));
2071
2072                 curOffset += numToExec;
2073
2074                 // Execute
2075                 {
2076                         VK_CHECK(vk.resetFences(vkDevice, 1, &fence.get()));
2077
2078                         const VkSubmitInfo submitInfo =
2079                         {
2080                                 VK_STRUCTURE_TYPE_SUBMIT_INFO,
2081                                 DE_NULL,
2082                                 0u,
2083                                 (const VkSemaphore*)DE_NULL,
2084                                 (const VkPipelineStageFlags*)DE_NULL,
2085                                 1u,
2086                                 &cmdBuffer.get(),
2087                                 0u,
2088                                 (const VkSemaphore*)DE_NULL,
2089                         };
2090
2091                         VK_CHECK(vk.queueSubmit(queue, 1, &submitInfo, *fence));
2092                         VK_CHECK(vk.waitForFences(vkDevice, 1, &fence.get(), true, ~(0ull) /* infinity*/));
2093                 }
2094         }
2095
2096         // Read back data
2097         readOutputBuffer(outputs, numValues);
2098 }
2099
2100 // Tessellation utils
2101
2102 static std::string generateVertexShaderForTess (void)
2103 {
2104         std::ostringstream      src;
2105         src << "#version 310 es\n"
2106                 << "void main (void)\n{\n"
2107                 << "    gl_Position = vec4(gl_VertexIndex/2, gl_VertexIndex%2, 0.0, 1.0);\n"
2108                 << "}\n";
2109
2110         return src.str();
2111 }
2112
2113 class TessellationExecutor : public BufferIoExecutor
2114 {
2115 public:
2116                                         TessellationExecutor            (Context& context, const ShaderSpec& shaderSpec, VkDescriptorSetLayout extraResourcesLayout);
2117         virtual                 ~TessellationExecutor           (void);
2118
2119         void                    renderTess                                      (deUint32 numValues, deUint32 vertexCount, deUint32 patchControlPoints, VkDescriptorSet extraResources);
2120
2121 private:
2122         const VkDescriptorSetLayout                                     m_extraResourcesLayout;
2123 };
2124
2125 TessellationExecutor::TessellationExecutor (Context& context, const ShaderSpec& shaderSpec, VkDescriptorSetLayout extraResourcesLayout)
2126         : BufferIoExecutor                      (context, shaderSpec)
2127         , m_extraResourcesLayout        (extraResourcesLayout)
2128 {
2129         const VkPhysicalDeviceFeatures& features = context.getDeviceFeatures();
2130
2131         if (!features.tessellationShader)
2132                 TCU_THROW(NotSupportedError, "Tessellation shader is not supported by device");
2133 }
2134
2135 TessellationExecutor::~TessellationExecutor (void)
2136 {
2137 }
2138
2139 void TessellationExecutor::renderTess (deUint32 numValues, deUint32 vertexCount, deUint32 patchControlPoints, VkDescriptorSet extraResources)
2140 {
2141         const size_t                                            inputBufferSize                         = numValues * getInputStride();
2142         const VkDevice                                          vkDevice                                        = m_context.getDevice();
2143         const DeviceInterface&                          vk                                                      = m_context.getDeviceInterface();
2144         const VkQueue                                           queue                                           = m_context.getUniversalQueue();
2145         const deUint32                                          queueFamilyIndex                        = m_context.getUniversalQueueFamilyIndex();
2146         Allocator&                                                      memAlloc                                        = m_context.getDefaultAllocator();
2147
2148         const tcu::UVec2                                        renderSize                                      (DEFAULT_RENDER_WIDTH, DEFAULT_RENDER_HEIGHT);
2149
2150         Move<VkImage>                                           colorImage;
2151         de::MovePtr<Allocation>                         colorImageAlloc;
2152         VkFormat                                                        colorFormat                                     = VK_FORMAT_R8G8B8A8_UNORM;
2153         Move<VkImageView>                                       colorImageView;
2154
2155         Move<VkRenderPass>                                      renderPass;
2156         Move<VkFramebuffer>                                     framebuffer;
2157         Move<VkPipelineLayout>                          pipelineLayout;
2158         Move<VkPipeline>                                        graphicsPipeline;
2159
2160         Move<VkShaderModule>                            vertexShaderModule;
2161         Move<VkShaderModule>                            tessControlShaderModule;
2162         Move<VkShaderModule>                            tessEvalShaderModule;
2163         Move<VkShaderModule>                            fragmentShaderModule;
2164
2165         Move<VkCommandPool>                                     cmdPool;
2166         Move<VkCommandBuffer>                           cmdBuffer;
2167
2168         Move<VkFence>                                           fence;
2169
2170         Move<VkDescriptorPool>                          descriptorPool;
2171         Move<VkDescriptorSetLayout>                     descriptorSetLayout;
2172         Move<VkDescriptorSet>                           descriptorSet;
2173         const deUint32                                          numDescriptorSets                       = (m_extraResourcesLayout != 0) ? 2u : 1u;
2174
2175         DE_ASSERT((m_extraResourcesLayout != 0) == (extraResources != 0));
2176
2177         // Create color image
2178         {
2179                 const VkImageCreateInfo colorImageParams =
2180                 {
2181                         VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,                                                                            // VkStructureType                      sType;
2182                         DE_NULL,                                                                                                                                        // const void*                          pNext;
2183                         0u,                                                                                                                                                     // VkImageCreateFlags           flags;
2184                         VK_IMAGE_TYPE_2D,                                                                                                                       // VkImageType                          imageType;
2185                         colorFormat,                                                                                                                            // VkFormat                                     format;
2186                         { renderSize.x(), renderSize.y(), 1u },                                                                         // VkExtent3D                           extent;
2187                         1u,                                                                                                                                                     // deUint32                                     mipLevels;
2188                         1u,                                                                                                                                                     // deUint32                                     arraySize;
2189                         VK_SAMPLE_COUNT_1_BIT,                                                                                                          // VkSampleCountFlagBits        samples;
2190                         VK_IMAGE_TILING_OPTIMAL,                                                                                                        // VkImageTiling                        tiling;
2191                         VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT,          // VkImageUsageFlags            usage;
2192                         VK_SHARING_MODE_EXCLUSIVE,                                                                                                      // VkSharingMode                        sharingMode;
2193                         1u,                                                                                                                                                     // deUint32                                     queueFamilyCount;
2194                         &queueFamilyIndex,                                                                                                                      // const deUint32*                      pQueueFamilyIndices;
2195                         VK_IMAGE_LAYOUT_UNDEFINED                                                                                                       // VkImageLayout                        initialLayout;
2196                 };
2197
2198                 colorImage = createImage(vk, vkDevice, &colorImageParams);
2199
2200                 // Allocate and bind color image memory
2201                 colorImageAlloc = memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, *colorImage), MemoryRequirement::Any);
2202                 VK_CHECK(vk.bindImageMemory(vkDevice, *colorImage, colorImageAlloc->getMemory(), colorImageAlloc->getOffset()));
2203         }
2204
2205         // Create color attachment view
2206         {
2207                 const VkImageViewCreateInfo colorImageViewParams =
2208                 {
2209                         VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,                       // VkStructureType                      sType;
2210                         DE_NULL,                                                                                        // const void*                          pNext;
2211                         0u,                                                                                                     // VkImageViewCreateFlags       flags;
2212                         *colorImage,                                                                            // VkImage                                      image;
2213                         VK_IMAGE_VIEW_TYPE_2D,                                                          // VkImageViewType                      viewType;
2214                         colorFormat,                                                                            // VkFormat                                     format;
2215                         {
2216                                 VK_COMPONENT_SWIZZLE_R,                                                 // VkComponentSwizzle           r;
2217                                 VK_COMPONENT_SWIZZLE_G,                                                 // VkComponentSwizzle           g;
2218                                 VK_COMPONENT_SWIZZLE_B,                                                 // VkComponentSwizzle           b;
2219                                 VK_COMPONENT_SWIZZLE_A                                                  // VkComponentSwizzle           a;
2220                         },                                                                                                      // VkComponentsMapping          components;
2221                         {
2222                                 VK_IMAGE_ASPECT_COLOR_BIT,                                              // VkImageAspectFlags           aspectMask;
2223                                 0u,                                                                                             // deUint32                                     baseMipLevel;
2224                                 1u,                                                                                             // deUint32                                     mipLevels;
2225                                 0u,                                                                                             // deUint32                                     baseArraylayer;
2226                                 1u                                                                                              // deUint32                                     layerCount;
2227                         }                                                                                                       // VkImageSubresourceRange      subresourceRange;
2228                 };
2229
2230                 colorImageView = createImageView(vk, vkDevice, &colorImageViewParams);
2231         }
2232
2233         // Create render pass
2234         {
2235                 const VkAttachmentDescription colorAttachmentDescription =
2236                 {
2237                         0u,                                                                                                     // VkAttachmentDescriptorFlags  flags;
2238                         colorFormat,                                                                            // VkFormat                                             format;
2239                         VK_SAMPLE_COUNT_1_BIT,                                                          // VkSampleCountFlagBits                samples;
2240                         VK_ATTACHMENT_LOAD_OP_CLEAR,                                            // VkAttachmentLoadOp                   loadOp;
2241                         VK_ATTACHMENT_STORE_OP_STORE,                                           // VkAttachmentStoreOp                  storeOp;
2242                         VK_ATTACHMENT_LOAD_OP_DONT_CARE,                                        // VkAttachmentLoadOp                   stencilLoadOp;
2243                         VK_ATTACHMENT_STORE_OP_DONT_CARE,                                       // VkAttachmentStoreOp                  stencilStoreOp;
2244                         VK_IMAGE_LAYOUT_UNDEFINED,                                                      // VkImageLayout                                initialLayout;
2245                         VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL                        // VkImageLayout                                finalLayout
2246                 };
2247
2248                 const VkAttachmentDescription attachments[1] =
2249                 {
2250                         colorAttachmentDescription
2251                 };
2252
2253                 const VkAttachmentReference colorAttachmentReference =
2254                 {
2255                         0u,                                                                                                     // deUint32                     attachment;
2256                         VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL                        // VkImageLayout        layout;
2257                 };
2258
2259                 const VkSubpassDescription subpassDescription =
2260                 {
2261                         0u,                                                                                                     // VkSubpassDescriptionFlags    flags;
2262                         VK_PIPELINE_BIND_POINT_GRAPHICS,                                        // VkPipelineBindPoint                  pipelineBindPoint;
2263                         0u,                                                                                                     // deUint32                                             inputCount;
2264                         DE_NULL,                                                                                        // const VkAttachmentReference* pInputAttachments;
2265                         1u,                                                                                                     // deUint32                                             colorCount;
2266                         &colorAttachmentReference,                                                      // const VkAttachmentReference* pColorAttachments;
2267                         DE_NULL,                                                                                        // const VkAttachmentReference* pResolveAttachments;
2268                         DE_NULL,                                                                                        // VkAttachmentReference                depthStencilAttachment;
2269                         0u,                                                                                                     // deUint32                                             preserveCount;
2270                         DE_NULL                                                                                         // const VkAttachmentReference* pPreserveAttachments;
2271                 };
2272
2273                 const VkRenderPassCreateInfo renderPassParams =
2274                 {
2275                         VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,                      // VkStructureType                                      sType;
2276                         DE_NULL,                                                                                        // const void*                                          pNext;
2277                         0u,                                                                                                     // VkRenderPassCreateFlags                      flags;
2278                         1u,                                                                                                     // deUint32                                                     attachmentCount;
2279                         attachments,                                                                            // const VkAttachmentDescription*       pAttachments;
2280                         1u,                                                                                                     // deUint32                                                     subpassCount;
2281                         &subpassDescription,                                                            // const VkSubpassDescription*          pSubpasses;
2282                         0u,                                                                                                     // deUint32                                                     dependencyCount;
2283                         DE_NULL                                                                                         // const VkSubpassDependency*           pDependencies;
2284                 };
2285
2286                 renderPass = createRenderPass(vk, vkDevice, &renderPassParams);
2287         }
2288
2289         // Create framebuffer
2290         {
2291                 const VkFramebufferCreateInfo framebufferParams =
2292                 {
2293                         VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,                      // VkStructureType                              sType;
2294                         DE_NULL,                                                                                        // const void*                                  pNext;
2295                         0u,                                                                                                     // VkFramebufferCreateFlags             flags;
2296                         *renderPass,                                                                            // VkRenderPass                                 renderPass;
2297                         1u,                                                                                                     // deUint32                                             attachmentCount;
2298                         &*colorImageView,                                                                       // const VkAttachmentBindInfo*  pAttachments;
2299                         (deUint32)renderSize.x(),                                                       // deUint32                                             width;
2300                         (deUint32)renderSize.y(),                                                       // deUint32                                             height;
2301                         1u                                                                                                      // deUint32                                             layers;
2302                 };
2303
2304                 framebuffer = createFramebuffer(vk, vkDevice, &framebufferParams);
2305         }
2306
2307         // Create descriptors
2308         {
2309                 DescriptorPoolBuilder           descriptorPoolBuilder;
2310                 DescriptorSetLayoutBuilder      descriptorSetLayoutBuilder;
2311
2312                 descriptorSetLayoutBuilder.addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_SHADER_STAGE_ALL);
2313                 descriptorPoolBuilder.addType(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER);
2314                 descriptorSetLayoutBuilder.addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_SHADER_STAGE_ALL);
2315                 descriptorPoolBuilder.addType(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER);
2316
2317                 descriptorSetLayout     = descriptorSetLayoutBuilder.build(vk, vkDevice);
2318                 descriptorPool          = descriptorPoolBuilder.build(vk, vkDevice, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u);
2319
2320                 const VkDescriptorSetAllocateInfo allocInfo =
2321                 {
2322                         VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
2323                         DE_NULL,
2324                         *descriptorPool,
2325                         1u,
2326                         &*descriptorSetLayout
2327                 };
2328
2329                 descriptorSet = allocateDescriptorSet(vk, vkDevice, &allocInfo);
2330                 // Update descriptors
2331                 {
2332                         DescriptorSetUpdateBuilder descriptorSetUpdateBuilder;
2333                         const VkDescriptorBufferInfo outputDescriptorBufferInfo =
2334                         {
2335                                 *m_outputBuffer,                                // VkBuffer                     buffer;
2336                                 0u,                                                             // VkDeviceSize         offset;
2337                                 VK_WHOLE_SIZE                                   // VkDeviceSize         range;
2338                         };
2339
2340                         descriptorSetUpdateBuilder.writeSingle(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding((deUint32)OUTPUT_BUFFER_BINDING), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &outputDescriptorBufferInfo);
2341
2342                         VkDescriptorBufferInfo inputDescriptorBufferInfo =
2343                         {
2344                                 0,                                                      // VkBuffer                     buffer;
2345                                 0u,                                                     // VkDeviceSize         offset;
2346                                 VK_WHOLE_SIZE                           // VkDeviceSize         range;
2347                         };
2348
2349                         if (inputBufferSize > 0)
2350                         {
2351                                 inputDescriptorBufferInfo.buffer = *m_inputBuffer;
2352
2353                                 descriptorSetUpdateBuilder.writeSingle(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding((deUint32)INPUT_BUFFER_BINDING), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &inputDescriptorBufferInfo);
2354                         }
2355
2356                         descriptorSetUpdateBuilder.update(vk, vkDevice);
2357                 }
2358         }
2359
2360         // Create pipeline layout
2361         {
2362                 const VkDescriptorSetLayout                     descriptorSetLayouts[]          =
2363                 {
2364                         *descriptorSetLayout,
2365                         m_extraResourcesLayout
2366                 };
2367                 const VkPipelineLayoutCreateInfo pipelineLayoutParams =
2368                 {
2369                         VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,          // VkStructureType                              sType;
2370                         DE_NULL,                                                                                        // const void*                                  pNext;
2371                         (VkPipelineLayoutCreateFlags)0,                                         // VkPipelineLayoutCreateFlags  flags;
2372                         numDescriptorSets,                                                                      // deUint32                                             descriptorSetCount;
2373                         descriptorSetLayouts,                                                           // const VkDescriptorSetLayout* pSetLayouts;
2374                         0u,                                                                                                     // deUint32                                             pushConstantRangeCount;
2375                         DE_NULL                                                                                         // const VkPushConstantRange*   pPushConstantRanges;
2376                 };
2377
2378                 pipelineLayout = createPipelineLayout(vk, vkDevice, &pipelineLayoutParams);
2379         }
2380
2381         // Create shader modules
2382         {
2383                 vertexShaderModule              = createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("vert"), 0);
2384                 tessControlShaderModule = createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("tess_control"), 0);
2385                 tessEvalShaderModule    = createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("tess_eval"), 0);
2386                 fragmentShaderModule    = createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("frag"), 0);
2387         }
2388
2389         // Create pipeline
2390         {
2391                 const VkPipelineShaderStageCreateInfo shaderStageParams[4] =
2392                 {
2393                         {
2394                                 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,            // VkStructureType                                              sType;
2395                                 DE_NULL,                                                                                                        // const void*                                                  pNext;
2396                                 (VkPipelineShaderStageCreateFlags)0,                                            // VkPipelineShaderStageCreateFlags             flags;
2397                                 VK_SHADER_STAGE_VERTEX_BIT,                                                                     // VkShaderStageFlagBit                                 stage;
2398                                 *vertexShaderModule,                                                                            // VkShaderModule                                               shader;
2399                                 "main",                                                                                                         // const char*                                                  pName;
2400                                 DE_NULL                                                                                                         // const VkSpecializationInfo*                  pSpecializationInfo;
2401                         },
2402                         {
2403                                 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,            // VkStructureType                                              sType;
2404                                 DE_NULL,                                                                                                        // const void*                                                  pNext;
2405                                 (VkPipelineShaderStageCreateFlags)0,                                            // VkPipelineShaderStageCreateFlags             flags;
2406                                 VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT,                                       // VkShaderStageFlagBit                                 stage;
2407                                 *tessControlShaderModule,                                                                       // VkShaderModule                                               shader;
2408                                 "main",                                                                                                         // const char*                                                  pName;
2409                                 DE_NULL                                                                                                         // const VkSpecializationInfo*                  pSpecializationInfo;
2410                         },
2411                         {
2412                                 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,            // VkStructureType                                              sType;
2413                                 DE_NULL,                                                                                                        // const void*                                                  pNext;
2414                                 (VkPipelineShaderStageCreateFlags)0,                                            // VkPipelineShaderStageCreateFlags             flags;
2415                                 VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT,                            // VkShaderStageFlagBit                                 stage;
2416                                 *tessEvalShaderModule,                                                                          // VkShaderModule                                               shader;
2417                                 "main",                                                                                                         // const char*                                                  pName;
2418                                 DE_NULL                                                                                                         // const VkSpecializationInfo*                  pSpecializationInfo;
2419                         },
2420                         {
2421                                 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,            // VkStructureType                                              sType;
2422                                 DE_NULL,                                                                                                        // const void*                                                  pNext;
2423                                 (VkPipelineShaderStageCreateFlags)0,                                            // VkPipelineShaderStageCreateFlags             flags;
2424                                 VK_SHADER_STAGE_FRAGMENT_BIT,                                                           // VkShaderStageFlagBit                                 stage;
2425                                 *fragmentShaderModule,                                                                          // VkShaderModule                                               shader;
2426                                 "main",                                                                                                         // const char*                                                  pName;
2427                                 DE_NULL                                                                                                         // const VkSpecializationInfo*                  pSpecializationInfo;
2428                         }
2429                 };
2430
2431                 const VkPipelineVertexInputStateCreateInfo vertexInputStateParams =
2432                 {
2433                         VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,              // VkStructureType                                                      sType;
2434                         DE_NULL,                                                                                                                // const void*                                                          pNext;
2435                         (VkPipelineVertexInputStateCreateFlags)0,                                               // VkPipelineVertexInputStateCreateFlags        flags;
2436                         0u,                                                                                                                             // deUint32                                                                     bindingCount;
2437                         DE_NULL,                                                                                                                // const VkVertexInputBindingDescription*       pVertexBindingDescriptions;
2438                         0u,                                                                                                                             // deUint32                                                                     attributeCount;
2439                         DE_NULL,                                                                                                                // const VkVertexInputAttributeDescription*     pvertexAttributeDescriptions;
2440                 };
2441
2442                 const VkPipelineInputAssemblyStateCreateInfo inputAssemblyStateParams =
2443                 {
2444                         VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,    // VkStructureType                                              sType;
2445                         DE_NULL,                                                                                                                // const void*                                                  pNext;
2446                         (VkPipelineShaderStageCreateFlags)0,                                                    // VkPipelineShaderStageCreateFlags     flags;
2447                         VK_PRIMITIVE_TOPOLOGY_PATCH_LIST,                                                               // VkPrimitiveTopology                                  topology;
2448                         DE_FALSE                                                                                                                // VkBool32                                                             primitiveRestartEnable;
2449                 };
2450
2451                 struct VkPipelineTessellationStateCreateInfo tessellationStateParams =
2452                 {
2453                         VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO,              // VkStructureType                                                      sType;
2454                         DE_NULL,                                                                                                                // const void*                                                          pNext;
2455                         (VkPipelineTessellationStateCreateFlags)0,                                              // VkPipelineTessellationStateCreateFlags       flags;
2456                         patchControlPoints                                                                                              // uint32_t                                                                     patchControlPoints;
2457                 };
2458
2459                 const VkViewport viewport =
2460                 {
2461                         0.0f,                                           // float        originX;
2462                         0.0f,                                           // float        originY;
2463                         (float)renderSize.x(),          // float        width;
2464                         (float)renderSize.y(),          // float        height;
2465                         0.0f,                                           // float        minDepth;
2466                         1.0f                                            // float        maxDepth;
2467                 };
2468
2469                 const VkRect2D scissor =
2470                 {
2471                         {
2472                                 0u,                                             // deUint32     x;
2473                                 0u,                                             // deUint32     y;
2474                         },                                                      // VkOffset2D   offset;
2475                         {
2476                                 renderSize.x(),                 // deUint32     width;
2477                                 renderSize.y(),                 // deUint32     height;
2478                         },                                                      // VkExtent2D   extent;
2479                 };
2480
2481                 const VkPipelineViewportStateCreateInfo viewportStateParams =
2482                 {
2483                         VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO,  // VkStructureType                                              sType;
2484                         DE_NULL,                                                                                                // const void*                                                  pNext;
2485                         (VkPipelineViewportStateCreateFlags)0,                                  // VkPipelineViewPortStateCreateFlags   flags;
2486                         1u,                                                                                                             // deUint32                                                             viewportCount;
2487                         &viewport,                                                                                              // const VkViewport*                                    pViewports;
2488                         1u,                                                                                                             // deUint32                                                             scissorsCount;
2489                         &scissor                                                                                                // const VkRect2D*                                              pScissors;
2490                 };
2491
2492                 const VkPipelineRasterizationStateCreateInfo rasterStateParams =
2493                 {
2494                         VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO,             // VkStructureType                                                      sType;
2495                         DE_NULL,                                                                                                                // const void*                                                          pNext;
2496                         (VkPipelineRasterizationStateCreateFlags)0,                                             // VkPipelineRasterizationStageCreateFlags      flags;
2497                         VK_FALSE,                                                                                                               // VkBool32                                                                     depthClipEnable;
2498                         VK_FALSE,                                                                                                               // VkBool32                                                                     rasterizerDiscardEnable;
2499                         VK_POLYGON_MODE_FILL,                                                                                   // VkPolygonMode                                                        polygonMode;
2500                         VK_CULL_MODE_NONE,                                                                                              // VkCullMode                                                           cullMode;
2501                         VK_FRONT_FACE_COUNTER_CLOCKWISE,                                                                // VkFrontFace                                                          frontFace;
2502                         VK_FALSE,                                                                                                               // VkBool32                                                                     depthBiasEnable;
2503                         0.0f,                                                                                                                   // float                                                                        depthBias;
2504                         0.0f,                                                                                                                   // float                                                                        depthBiasClamp;
2505                         0.0f,                                                                                                                   // float                                                                        slopeScaledDepthBias;
2506                         1.0f                                                                                                                    // float                                                                        lineWidth;
2507                 };
2508
2509                 const VkPipelineMultisampleStateCreateInfo multisampleStateParams =
2510                 {
2511                         VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,               // VkStructureType                                                      sType;
2512                         DE_NULL,                                                                                                                // const void*                                                          pNext;
2513                         0u,                                                                                                                             // VkPipelineMultisampleStateCreateFlags        flags;
2514                         VK_SAMPLE_COUNT_1_BIT,                                                                                  // VkSampleCountFlagBits                                        rasterizationSamples;
2515                         VK_FALSE,                                                                                                               // VkBool32                                                                     sampleShadingEnable;
2516                         0.0f,                                                                                                                   // float                                                                        minSampleShading;
2517                         DE_NULL,                                                                                                                // const VkSampleMask*                                          pSampleMask;
2518                         VK_FALSE,                                                                                                               // VkBool32                                                                     alphaToCoverageEnable;
2519                         VK_FALSE                                                                                                                // VkBool32                                                                     alphaToOneEnable;
2520                 };
2521
2522                 const VkPipelineColorBlendAttachmentState colorBlendAttachmentState =
2523                 {
2524                         VK_FALSE,                                               // VkBool32                                     blendEnable;
2525                         VK_BLEND_FACTOR_ONE,                    // VkBlendFactor                        srcBlendColor;
2526                         VK_BLEND_FACTOR_ZERO,                   // VkBlendFactor                        destBlendColor;
2527                         VK_BLEND_OP_ADD,                                // VkBlendOp                            blendOpColor;
2528                         VK_BLEND_FACTOR_ONE,                    // VkBlendFactor                        srcBlendAlpha;
2529                         VK_BLEND_FACTOR_ZERO,                   // VkBlendFactor                        destBlendAlpha;
2530                         VK_BLEND_OP_ADD,                                // VkBlendOp                            blendOpAlpha;
2531                         (VK_COLOR_COMPONENT_R_BIT |
2532                          VK_COLOR_COMPONENT_G_BIT |
2533                          VK_COLOR_COMPONENT_B_BIT |
2534                          VK_COLOR_COMPONENT_A_BIT)              // VkColorComponentFlags        colorWriteMask;
2535                 };
2536
2537                 const VkPipelineColorBlendStateCreateInfo colorBlendStateParams =
2538                 {
2539                         VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,       // VkStructureType                                                              sType;
2540                         DE_NULL,                                                                                                        // const void*                                                                  pNext;
2541                         (VkPipelineColorBlendStateCreateFlags)0,                                        // VkPipelineColorBlendStateCreateFlags                 flags
2542                         VK_FALSE,                                                                                                       // VkBool32                                                                             logicOpEnable;
2543                         VK_LOGIC_OP_COPY,                                                                                       // VkLogicOp                                                                    logicOp;
2544                         1u,                                                                                                                     // deUint32                                                                             attachmentCount;
2545                         &colorBlendAttachmentState,                                                                     // const VkPipelineColorBlendAttachmentState*   pAttachments;
2546                         { 0.0f, 0.0f, 0.0f, 0.0f }                                                                      // float                                                                                blendConst[4];
2547                 };
2548
2549                 const VkGraphicsPipelineCreateInfo graphicsPipelineParams =
2550                 {
2551                         VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,        // VkStructureType                                                                      sType;
2552                         DE_NULL,                                                                                        // const void*                                                                          pNext;
2553                         0u,                                                                                                     // VkPipelineCreateFlags                                                        flags;
2554                         4u,                                                                                                     // deUint32                                                                                     stageCount;
2555                         shaderStageParams,                                                                      // const VkPipelineShaderStageCreateInfo*                       pStages;
2556                         &vertexInputStateParams,                                                        // const VkPipelineVertexInputStateCreateInfo*          pVertexInputState;
2557                         &inputAssemblyStateParams,                                                      // const VkPipelineInputAssemblyStateCreateInfo*        pInputAssemblyState;
2558                         &tessellationStateParams,                                                       // const VkPipelineTessellationStateCreateInfo*         pTessellationState;
2559                         &viewportStateParams,                                                           // const VkPipelineViewportStateCreateInfo*                     pViewportState;
2560                         &rasterStateParams,                                                                     // const VkPipelineRasterStateCreateInfo*                       pRasterState;
2561                         &multisampleStateParams,                                                        // const VkPipelineMultisampleStateCreateInfo*          pMultisampleState;
2562                         DE_NULL,                                                                                        // const VkPipelineDepthStencilStateCreateInfo*         pDepthStencilState;
2563                         &colorBlendStateParams,                                                         // const VkPipelineColorBlendStateCreateInfo*           pColorBlendState;
2564                         (const VkPipelineDynamicStateCreateInfo*)DE_NULL,       // const VkPipelineDynamicStateCreateInfo*                      pDynamicState;
2565                         *pipelineLayout,                                                                        // VkPipelineLayout                                                                     layout;
2566                         *renderPass,                                                                            // VkRenderPass                                                                         renderPass;
2567                         0u,                                                                                                     // deUint32                                                                                     subpass;
2568                         0u,                                                                                                     // VkPipeline                                                                           basePipelineHandle;
2569                         0u                                                                                                      // deInt32                                                                                      basePipelineIndex;
2570                 };
2571
2572                 graphicsPipeline = createGraphicsPipeline(vk, vkDevice, DE_NULL, &graphicsPipelineParams);
2573         }
2574
2575         // Create command pool
2576         cmdPool = createCommandPool(vk, vkDevice, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, queueFamilyIndex);
2577
2578         // Create command buffer
2579         {
2580                 const VkCommandBufferBeginInfo cmdBufferBeginInfo =
2581                 {
2582                         VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,    // VkStructureType                                      sType;
2583                         DE_NULL,                                                                                // const void*                                          pNext;
2584                         0u,                                                                                             // VkCmdBufferOptimizeFlags                     flags;
2585                         (const VkCommandBufferInheritanceInfo*)DE_NULL,
2586                 };
2587
2588                 const VkClearValue clearValues[1] =
2589                 {
2590                         getDefaultClearColor()
2591                 };
2592
2593                 const VkRenderPassBeginInfo renderPassBeginInfo =
2594                 {
2595                         VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,                               // VkStructureType              sType;
2596                         DE_NULL,                                                                                                // const void*                  pNext;
2597                         *renderPass,                                                                                    // VkRenderPass                 renderPass;
2598                         *framebuffer,                                                                                   // VkFramebuffer                framebuffer;
2599                         { { 0, 0 }, { renderSize.x(), renderSize.y() } },               // VkRect2D                             renderArea;
2600                         1,                                                                                                              // deUint32                             attachmentCount;
2601                         clearValues                                                                                             // const VkClearValue*  pClearValues;
2602                 };
2603
2604                 cmdBuffer = allocateCommandBuffer(vk, vkDevice, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
2605
2606                 VK_CHECK(vk.beginCommandBuffer(*cmdBuffer, &cmdBufferBeginInfo));
2607
2608                 vk.cmdBeginRenderPass(*cmdBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
2609
2610                 vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *graphicsPipeline);
2611
2612                 {
2613                         const VkDescriptorSet   descriptorSets[]        = { *descriptorSet, extraResources };
2614                         vk.cmdBindDescriptorSets(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipelineLayout, 0u, numDescriptorSets, descriptorSets, 0u, DE_NULL);
2615                 }
2616
2617                 vk.cmdDraw(*cmdBuffer, vertexCount, 1, 0, 0);
2618
2619                 vk.cmdEndRenderPass(*cmdBuffer);
2620                 VK_CHECK(vk.endCommandBuffer(*cmdBuffer));
2621         }
2622
2623         // Create fence
2624         fence = createFence(vk, vkDevice);
2625
2626         // Execute Draw
2627         {
2628                 VK_CHECK(vk.resetFences(vkDevice, 1, &fence.get()));
2629                 const VkSubmitInfo submitInfo =
2630                 {
2631                         VK_STRUCTURE_TYPE_SUBMIT_INFO,
2632                         DE_NULL,
2633                         0u,
2634                         (const VkSemaphore*)0,
2635                         (const VkPipelineStageFlags*)DE_NULL,
2636                         1u,
2637                         &cmdBuffer.get(),
2638                         0u,
2639                         (const VkSemaphore*)0,
2640                 };
2641                 VK_CHECK(vk.queueSubmit(queue, 1, &submitInfo, *fence));
2642                 VK_CHECK(vk.waitForFences(vkDevice, 1, &fence.get(), true, ~(0ull) /* infinity*/));
2643         }
2644 }
2645
2646 // TessControlExecutor
2647
2648 class TessControlExecutor : public TessellationExecutor
2649 {
2650 public:
2651                                                 TessControlExecutor                     (Context& context, const ShaderSpec& shaderSpec, VkDescriptorSetLayout extraResourcesLayout);
2652         virtual                         ~TessControlExecutor            (void);
2653
2654         static void                     generateSources                         (const ShaderSpec& shaderSpec, SourceCollections& programCollection);
2655
2656         virtual void            execute                                         (int numValues, const void* const* inputs, void* const* outputs, VkDescriptorSet extraResources);
2657
2658 protected:
2659         static std::string      generateTessControlShader       (const ShaderSpec& shaderSpec);
2660 };
2661
2662 TessControlExecutor::TessControlExecutor (Context& context, const ShaderSpec& shaderSpec, VkDescriptorSetLayout extraResourcesLayout)
2663         : TessellationExecutor(context, shaderSpec, extraResourcesLayout)
2664 {
2665 }
2666
2667 TessControlExecutor::~TessControlExecutor (void)
2668 {
2669 }
2670
2671 std::string TessControlExecutor::generateTessControlShader (const ShaderSpec& shaderSpec)
2672 {
2673         std::ostringstream src;
2674         src << glu::getGLSLVersionDeclaration(shaderSpec.glslVersion) << "\n";
2675
2676         if (shaderSpec.glslVersion == glu::GLSL_VERSION_310_ES)
2677                 src << "#extension GL_EXT_tessellation_shader : require\n\n";
2678
2679         if (!shaderSpec.globalDeclarations.empty())
2680                 src << shaderSpec.globalDeclarations << "\n";
2681
2682         src << "\nlayout(vertices = 1) out;\n\n";
2683
2684         declareBufferBlocks(src, shaderSpec);
2685
2686         src << "void main (void)\n{\n";
2687
2688         for (int ndx = 0; ndx < 2; ndx++)
2689                 src << "\tgl_TessLevelInner[" << ndx << "] = 1.0;\n";
2690
2691         for (int ndx = 0; ndx < 4; ndx++)
2692                 src << "\tgl_TessLevelOuter[" << ndx << "] = 1.0;\n";
2693
2694         src << "\n"
2695                 << "\thighp uint invocationId = uint(gl_PrimitiveID);\n";
2696
2697         generateExecBufferIo(src, shaderSpec, "invocationId");
2698
2699         src << "}\n";
2700
2701         return src.str();
2702 }
2703
2704 static std::string generateEmptyTessEvalShader ()
2705 {
2706         std::ostringstream src;
2707
2708         src << "#version 310 es\n"
2709                    "#extension GL_EXT_tessellation_shader : require\n\n";
2710
2711         src << "layout(triangles, ccw) in;\n";
2712
2713         src << "\nvoid main (void)\n{\n"
2714                 << "\tgl_Position = vec4(gl_TessCoord.xy, 0.0, 1.0);\n"
2715                 << "}\n";
2716
2717         return src.str();
2718 }
2719
2720 void TessControlExecutor::generateSources (const ShaderSpec& shaderSpec, SourceCollections& programCollection)
2721 {
2722         programCollection.glslSources.add("vert") << glu::VertexSource(generateVertexShaderForTess()) << shaderSpec.buildOptions;
2723         programCollection.glslSources.add("tess_control") << glu::TessellationControlSource(generateTessControlShader(shaderSpec)) << shaderSpec.buildOptions;
2724         programCollection.glslSources.add("tess_eval") << glu::TessellationEvaluationSource(generateEmptyTessEvalShader()) << shaderSpec.buildOptions;
2725         programCollection.glslSources.add("frag") << glu::FragmentSource(generateEmptyFragmentSource()) << shaderSpec.buildOptions;
2726 }
2727
2728 void TessControlExecutor::execute (int numValues, const void* const* inputs, void* const* outputs, VkDescriptorSet extraResources)
2729 {
2730         const deUint32  patchSize       = 3;
2731
2732         initBuffers(numValues);
2733
2734         // Setup input buffer & copy data
2735         uploadInputBuffer(inputs, numValues);
2736
2737         renderTess(numValues, patchSize * numValues, patchSize, extraResources);
2738
2739         // Read back data
2740         readOutputBuffer(outputs, numValues);
2741 }
2742
2743 // TessEvaluationExecutor
2744
2745 class TessEvaluationExecutor : public TessellationExecutor
2746 {
2747 public:
2748                                                 TessEvaluationExecutor  (Context& context, const ShaderSpec& shaderSpec, VkDescriptorSetLayout extraResourcesLayout);
2749         virtual                         ~TessEvaluationExecutor (void);
2750
2751         static void                     generateSources                 (const ShaderSpec& shaderSpec, SourceCollections& programCollection);
2752
2753         virtual void            execute                                 (int numValues, const void* const* inputs, void* const* outputs, VkDescriptorSet extraResources);
2754
2755 protected:
2756         static std::string      generateTessEvalShader  (const ShaderSpec& shaderSpec);
2757 };
2758
2759 TessEvaluationExecutor::TessEvaluationExecutor (Context& context, const ShaderSpec& shaderSpec, VkDescriptorSetLayout extraResourcesLayout)
2760         : TessellationExecutor (context, shaderSpec, extraResourcesLayout)
2761 {
2762 }
2763
2764 TessEvaluationExecutor::~TessEvaluationExecutor (void)
2765 {
2766 }
2767
2768 static std::string generatePassthroughTessControlShader (void)
2769 {
2770         std::ostringstream src;
2771
2772         src << "#version 310 es\n"
2773                    "#extension GL_EXT_tessellation_shader : require\n\n";
2774
2775         src << "layout(vertices = 1) out;\n\n";
2776
2777         src << "void main (void)\n{\n";
2778
2779         for (int ndx = 0; ndx < 2; ndx++)
2780                 src << "\tgl_TessLevelInner[" << ndx << "] = 1.0;\n";
2781
2782         for (int ndx = 0; ndx < 4; ndx++)
2783                 src << "\tgl_TessLevelOuter[" << ndx << "] = 1.0;\n";
2784
2785         src << "}\n";
2786
2787         return src.str();
2788 }
2789
2790 std::string TessEvaluationExecutor::generateTessEvalShader (const ShaderSpec& shaderSpec)
2791 {
2792         std::ostringstream src;
2793
2794         src << glu::getGLSLVersionDeclaration(shaderSpec.glslVersion) << "\n";
2795
2796         if (shaderSpec.glslVersion == glu::GLSL_VERSION_310_ES)
2797                 src << "#extension GL_EXT_tessellation_shader : require\n\n";
2798
2799         if (!shaderSpec.globalDeclarations.empty())
2800                 src << shaderSpec.globalDeclarations << "\n";
2801
2802         src << "\n";
2803
2804         src << "layout(isolines, equal_spacing) in;\n\n";
2805
2806         declareBufferBlocks(src, shaderSpec);
2807
2808         src << "void main (void)\n{\n"
2809                 << "\tgl_Position = vec4(gl_TessCoord.x, 0.0, 0.0, 1.0);\n"
2810                 << "\thighp uint invocationId = uint(gl_PrimitiveID)*2u + (gl_TessCoord.x > 0.5 ? 1u : 0u);\n";
2811
2812         generateExecBufferIo(src, shaderSpec, "invocationId");
2813
2814         src     << "}\n";
2815
2816         return src.str();
2817 }
2818
2819 void TessEvaluationExecutor::generateSources (const ShaderSpec& shaderSpec, SourceCollections& programCollection)
2820 {
2821         programCollection.glslSources.add("vert") << glu::VertexSource(generateVertexShaderForTess()) << shaderSpec.buildOptions;
2822         programCollection.glslSources.add("tess_control") << glu::TessellationControlSource(generatePassthroughTessControlShader()) << shaderSpec.buildOptions;
2823         programCollection.glslSources.add("tess_eval") << glu::TessellationEvaluationSource(generateTessEvalShader(shaderSpec)) << shaderSpec.buildOptions;
2824         programCollection.glslSources.add("frag") << glu::FragmentSource(generateEmptyFragmentSource()) << shaderSpec.buildOptions;
2825 }
2826
2827 void TessEvaluationExecutor::execute (int numValues, const void* const* inputs, void* const* outputs, VkDescriptorSet extraResources)
2828 {
2829         const int       patchSize               = 2;
2830         const int       alignedValues   = deAlign32(numValues, patchSize);
2831
2832         // Initialize buffers with aligned value count to make room for padding
2833         initBuffers(alignedValues);
2834
2835         // Setup input buffer & copy data
2836         uploadInputBuffer(inputs, numValues);
2837
2838         renderTess((deUint32)alignedValues, (deUint32)alignedValues, (deUint32)patchSize, extraResources);
2839
2840         // Read back data
2841         readOutputBuffer(outputs, numValues);
2842 }
2843
2844 } // anonymous
2845
2846 // ShaderExecutor
2847
2848 ShaderExecutor::~ShaderExecutor (void)
2849 {
2850 }
2851
2852 // Utilities
2853
2854 void generateSources (glu::ShaderType shaderType, const ShaderSpec& shaderSpec, vk::SourceCollections& dst)
2855 {
2856         switch (shaderType)
2857         {
2858                 case glu::SHADERTYPE_VERTEX:                                    VertexShaderExecutor::generateSources   (shaderSpec, dst);      break;
2859                 case glu::SHADERTYPE_TESSELLATION_CONTROL:              TessControlExecutor::generateSources    (shaderSpec, dst);      break;
2860                 case glu::SHADERTYPE_TESSELLATION_EVALUATION:   TessEvaluationExecutor::generateSources (shaderSpec, dst);      break;
2861                 case glu::SHADERTYPE_GEOMETRY:                                  GeometryShaderExecutor::generateSources (shaderSpec, dst);      break;
2862                 case glu::SHADERTYPE_FRAGMENT:                                  FragmentShaderExecutor::generateSources (shaderSpec, dst);      break;
2863                 case glu::SHADERTYPE_COMPUTE:                                   ComputeShaderExecutor::generateSources  (shaderSpec, dst);      break;
2864                 default:
2865                         TCU_THROW(InternalError, "Unsupported shader type");
2866         }
2867 }
2868
2869 ShaderExecutor* createExecutor (Context& context, glu::ShaderType shaderType, const ShaderSpec& shaderSpec, VkDescriptorSetLayout extraResourcesLayout)
2870 {
2871         switch (shaderType)
2872         {
2873                 case glu::SHADERTYPE_VERTEX:                                    return new VertexShaderExecutor         (context, shaderSpec, extraResourcesLayout);
2874                 case glu::SHADERTYPE_TESSELLATION_CONTROL:              return new TessControlExecutor          (context, shaderSpec, extraResourcesLayout);
2875                 case glu::SHADERTYPE_TESSELLATION_EVALUATION:   return new TessEvaluationExecutor       (context, shaderSpec, extraResourcesLayout);
2876                 case glu::SHADERTYPE_GEOMETRY:                                  return new GeometryShaderExecutor       (context, shaderSpec, extraResourcesLayout);
2877                 case glu::SHADERTYPE_FRAGMENT:                                  return new FragmentShaderExecutor       (context, shaderSpec, extraResourcesLayout);
2878                 case glu::SHADERTYPE_COMPUTE:                                   return new ComputeShaderExecutor        (context, shaderSpec, extraResourcesLayout);
2879                 default:
2880                         TCU_THROW(InternalError, "Unsupported shader type");
2881         }
2882 }
2883
2884 } // shaderexecutor
2885 } // vkt