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