Refactor vktShaderExecutor
[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         {
1191                 const VkCommandPoolCreateInfo cmdPoolParams =
1192                 {
1193                         VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,                     // VkStructureType              sType;
1194                         DE_NULL,                                                                                        // const void*                  pNext;
1195                         VK_COMMAND_POOL_CREATE_TRANSIENT_BIT,                           // VkCmdPoolCreateFlags flags;
1196                         queueFamilyIndex,                                                                       // deUint32                             queueFamilyIndex;
1197                 };
1198
1199                 cmdPool = createCommandPool(vk, vkDevice, &cmdPoolParams);
1200         }
1201
1202         // Create command buffer
1203         {
1204                 const VkCommandBufferAllocateInfo cmdBufferParams =
1205                 {
1206                         VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, // VkStructureType                      sType;
1207                         DE_NULL,                                                                                // const void*                          pNext;
1208                         *cmdPool,                                                                               // VkCmdPool                            cmdPool;
1209                         VK_COMMAND_BUFFER_LEVEL_PRIMARY,                                // VkCmdBufferLevel                     level;
1210                         1                                                                                               // deUint32                                     bufferCount;
1211                 };
1212
1213                 const VkCommandBufferBeginInfo cmdBufferBeginInfo =
1214                 {
1215                         VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,    // VkStructureType                              sType;
1216                         DE_NULL,                                                                                // const void*                                  pNext;
1217                         0u,                                                                                             // VkCmdBufferOptimizeFlags             flags;
1218                         (const VkCommandBufferInheritanceInfo*)DE_NULL,
1219                 };
1220
1221                 const VkRenderPassBeginInfo renderPassBeginInfo =
1222                 {
1223                         VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,                               // VkStructureType              sType;
1224                         DE_NULL,                                                                                                // const void*                  pNext;
1225                         *renderPass,                                                                                    // VkRenderPass                 renderPass;
1226                         *framebuffer,                                                                                   // VkFramebuffer                framebuffer;
1227                         { { 0, 0 }, { renderSize.x(), renderSize.y() } },               // VkRect2D                             renderArea;
1228                         (deUint32)attachmentClearValues.size(),                                 // deUint32                             attachmentCount;
1229                         &attachmentClearValues[0]                                                               // const VkClearValue*  pAttachmentClearValues;
1230                 };
1231
1232                 cmdBuffer = allocateCommandBuffer(vk, vkDevice, &cmdBufferParams);
1233
1234                 VK_CHECK(vk.beginCommandBuffer(*cmdBuffer, &cmdBufferBeginInfo));
1235
1236                 vk.cmdPipelineBarrier(*cmdBuffer, vk::VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT, vk::VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, (VkDependencyFlags)0,
1237                                                           0, (const VkMemoryBarrier*)DE_NULL,
1238                                                           0, (const VkBufferMemoryBarrier*)DE_NULL,
1239                                                           (deUint32)colorImagePreRenderBarriers.size(), colorImagePreRenderBarriers.empty() ? DE_NULL : &colorImagePreRenderBarriers[0]);
1240                 vk.cmdBeginRenderPass(*cmdBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
1241
1242                 vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *graphicsPipeline);
1243
1244                 if (m_extraResourcesLayout != 0)
1245                 {
1246                         DE_ASSERT(extraResources != 0);
1247                         const VkDescriptorSet   descriptorSets[]        = { *emptyDescriptorSet, extraResources };
1248                         vk.cmdBindDescriptorSets(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipelineLayout, 0u, DE_LENGTH_OF_ARRAY(descriptorSets), descriptorSets, 0u, DE_NULL);
1249                 }
1250                 else
1251                         DE_ASSERT(extraResources == 0);
1252
1253                 const deUint32 numberOfVertexAttributes = (deUint32)m_vertexBuffers.size();
1254
1255                 std::vector<VkDeviceSize> offsets(numberOfVertexAttributes, 0);
1256
1257                 std::vector<VkBuffer> buffers(numberOfVertexAttributes);
1258                 for (size_t i = 0; i < numberOfVertexAttributes; i++)
1259                 {
1260                         buffers[i] = m_vertexBuffers[i].get()->get();
1261                 }
1262
1263                 vk.cmdBindVertexBuffers(*cmdBuffer, 0, numberOfVertexAttributes, &buffers[0], &offsets[0]);
1264                 vk.cmdDraw(*cmdBuffer, (deUint32)positions.size(), 1u, 0u, 0u);
1265
1266                 vk.cmdEndRenderPass(*cmdBuffer);
1267                 vk.cmdPipelineBarrier(*cmdBuffer, vk::VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT, vk::VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, (VkDependencyFlags)0,
1268                                                           0, (const VkMemoryBarrier*)DE_NULL,
1269                                                           0, (const VkBufferMemoryBarrier*)DE_NULL,
1270                                                           (deUint32)colorImagePostRenderBarriers.size(), colorImagePostRenderBarriers.empty() ? DE_NULL : &colorImagePostRenderBarriers[0]);
1271
1272                 VK_CHECK(vk.endCommandBuffer(*cmdBuffer));
1273         }
1274
1275         // Create fence
1276         {
1277                 const VkFenceCreateInfo fenceParams =
1278                 {
1279                         VK_STRUCTURE_TYPE_FENCE_CREATE_INFO,    // VkStructureType              sType;
1280                         DE_NULL,                                                                // const void*                  pNext;
1281                         0u                                                                              // VkFenceCreateFlags   flags;
1282                 };
1283
1284                 fence = createFence(vk, vkDevice, &fenceParams);
1285         }
1286
1287         // Execute Draw
1288         {
1289
1290                 const VkSubmitInfo submitInfo =
1291                 {
1292                         VK_STRUCTURE_TYPE_SUBMIT_INFO,                  // sType
1293                         DE_NULL,                                                                // pNext
1294                         0u,                                                                             // waitSemaphoreCount
1295                         DE_NULL,                                                                // pWaitSemaphores
1296                         (const VkPipelineStageFlags*)DE_NULL,
1297                         1u,                                                                             // commandBufferCount
1298                         &cmdBuffer.get(),                                               // pCommandBuffers
1299                         0u,                                                                             // signalSemaphoreCount
1300                         DE_NULL                                                                 // pSignalSemaphores
1301                 };
1302
1303                 VK_CHECK(vk.resetFences(vkDevice, 1, &fence.get()));
1304                 VK_CHECK(vk.queueSubmit(queue, 1, &submitInfo, *fence));
1305                 VK_CHECK(vk.waitForFences(vkDevice, 1, &fence.get(), DE_TRUE, ~(0ull) /* infinity*/));
1306         }
1307
1308         // Read back result and output
1309         {
1310                 const VkDeviceSize imageSizeBytes = (VkDeviceSize)(4 * sizeof(deUint32) * renderSize.x() * renderSize.y());
1311                 const VkBufferCreateInfo readImageBufferParams =
1312                 {
1313                         VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,           // VkStructureType              sType;
1314                         DE_NULL,                                                                        // const void*                  pNext;
1315                         0u,                                                                                     // VkBufferCreateFlags  flags;
1316                         imageSizeBytes,                                                         // VkDeviceSize                 size;
1317                         VK_BUFFER_USAGE_TRANSFER_DST_BIT,                       // VkBufferUsageFlags   usage;
1318                         VK_SHARING_MODE_EXCLUSIVE,                                      // VkSharingMode                sharingMode;
1319                         1u,                                                                                     // deUint32                             queueFamilyCount;
1320                         &queueFamilyIndex,                                                      // const deUint32*              pQueueFamilyIndices;
1321                 };
1322
1323                 // constants for image copy
1324
1325                 const VkCommandPoolCreateInfo cmdPoolParams =
1326                 {
1327                         VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,     // VkStructureType              sType;
1328                         DE_NULL,                                                                        // const void*                  pNext;
1329                         VK_COMMAND_POOL_CREATE_TRANSIENT_BIT,           // VkCmdPoolCreateFlags flags;
1330                         queueFamilyIndex                                                        // deUint32                             queueFamilyIndex;
1331                 };
1332
1333                 Move<VkCommandPool>     copyCmdPool = createCommandPool(vk, vkDevice, &cmdPoolParams);
1334
1335                 const VkCommandBufferAllocateInfo cmdBufferParams =
1336                 {
1337                         VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, // VkStructureType                      sType;
1338                         DE_NULL,                                                                                // const void*                          pNext;
1339                         *copyCmdPool,                                                                   // VkCmdPool                            cmdPool;
1340                         VK_COMMAND_BUFFER_LEVEL_PRIMARY,                                // VkCmdBufferLevel                     level;
1341                         1u                                                                                              // deUint32                                     bufferCount;
1342                 };
1343
1344                 const VkCommandBufferBeginInfo cmdBufferBeginInfo =
1345                 {
1346                         VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,    // VkStructureType                                      sType;
1347                         DE_NULL,                                                                                // const void*                                          pNext;
1348                         0u,                                                                                             // VkCmdBufferOptimizeFlags                     flags;
1349                         (const VkCommandBufferInheritanceInfo*)DE_NULL,
1350                 };
1351
1352                 const VkBufferImageCopy copyParams =
1353                 {
1354                         0u,                                                                                     // VkDeviceSize                 bufferOffset;
1355                         (deUint32)renderSize.x(),                                       // deUint32                             bufferRowLength;
1356                         (deUint32)renderSize.y(),                                       // deUint32                             bufferImageHeight;
1357                         {
1358                                 VK_IMAGE_ASPECT_COLOR_BIT,                              // VkImageAspect                aspect;
1359                                 0u,                                                                             // deUint32                             mipLevel;
1360                                 0u,                                                                             // deUint32                             arraySlice;
1361                                 1u,                                                                             // deUint32                             arraySize;
1362                         },                                                                                      // VkImageSubresource   imageSubresource;
1363                         { 0u, 0u, 0u },                                                         // VkOffset3D                   imageOffset;
1364                         { renderSize.x(), renderSize.y(), 1u }          // VkExtent3D                   imageExtent;
1365                 };
1366
1367                 // Read back pixels.
1368                 for (int outNdx = 0; outNdx < (int)m_shaderSpec.outputs.size(); ++outNdx)
1369                 {
1370                         const Symbol&                           output                  = m_shaderSpec.outputs[outNdx];
1371                         const int                                       outSize                 = output.varType.getScalarSize();
1372                         const int                                       outVecSize              = glu::getDataTypeNumComponents(output.varType.getBasicType());
1373                         const int                                       outNumLocs              = glu::getDataTypeNumLocations(output.varType.getBasicType());
1374                         deUint32*                                       dstPtrBase              = static_cast<deUint32*>(outputs[outNdx]);
1375                         const int                                       outLocation             = de::lookup(m_outputLayout.locationMap, output.name);
1376
1377                         for (int locNdx = 0; locNdx < outNumLocs; ++locNdx)
1378                         {
1379                                 tcu::TextureLevel                       tmpBuf;
1380                                 const tcu::TextureFormat        format = getRenderbufferFormatForOutput(output.varType, false);
1381                                 const tcu::TextureFormat        readFormat (tcu::TextureFormat::RGBA, format.type);
1382                                 const Unique<VkBuffer>          readImageBuffer(createBuffer(vk, vkDevice, &readImageBufferParams));
1383                                 const de::UniquePtr<Allocation> readImageBufferMemory(memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *readImageBuffer), MemoryRequirement::HostVisible));
1384
1385                                 VK_CHECK(vk.bindBufferMemory(vkDevice, *readImageBuffer, readImageBufferMemory->getMemory(), readImageBufferMemory->getOffset()));
1386
1387                                 // Copy image to buffer
1388                                 {
1389
1390                                         Move<VkCommandBuffer> copyCmdBuffer = allocateCommandBuffer(vk, vkDevice, &cmdBufferParams);
1391
1392                                         const VkSubmitInfo submitInfo =
1393                                         {
1394                                                 VK_STRUCTURE_TYPE_SUBMIT_INFO,
1395                                                 DE_NULL,
1396                                                 0u,
1397                                                 (const VkSemaphore*)DE_NULL,
1398                                                 (const VkPipelineStageFlags*)DE_NULL,
1399                                                 1u,
1400                                                 &copyCmdBuffer.get(),
1401                                                 0u,
1402                                                 (const VkSemaphore*)DE_NULL,
1403                                         };
1404
1405                                         VK_CHECK(vk.beginCommandBuffer(*copyCmdBuffer, &cmdBufferBeginInfo));
1406                                         vk.cmdCopyImageToBuffer(*copyCmdBuffer, colorImages[outLocation + locNdx].get()->get(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *readImageBuffer, 1u, &copyParams);
1407                                         VK_CHECK(vk.endCommandBuffer(*copyCmdBuffer));
1408
1409                                         VK_CHECK(vk.resetFences(vkDevice, 1, &fence.get()));
1410                                         VK_CHECK(vk.queueSubmit(queue, 1, &submitInfo, *fence));
1411                                         VK_CHECK(vk.waitForFences(vkDevice, 1, &fence.get(), true, ~(0ull) /* infinity */));
1412                                 }
1413
1414                                 const VkMappedMemoryRange range =
1415                                 {
1416                                         VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE,  // VkStructureType      sType;
1417                                         DE_NULL,                                                                // const void*          pNext;
1418                                         readImageBufferMemory->getMemory(),             // VkDeviceMemory       mem;
1419                                         0,                                                                              // VkDeviceSize         offset;
1420                                         imageSizeBytes,                                                 // VkDeviceSize         size;
1421                                 };
1422
1423                                 VK_CHECK(vk.invalidateMappedMemoryRanges(vkDevice, 1u, &range));
1424
1425                                 tmpBuf.setStorage(readFormat, renderSize.x(), renderSize.y());
1426
1427                                 const tcu::TextureFormat resultFormat(tcu::TextureFormat::RGBA, format.type);
1428                                 const tcu::ConstPixelBufferAccess resultAccess(resultFormat, renderSize.x(), renderSize.y(), 1, readImageBufferMemory->getHostPtr());
1429
1430                                 tcu::copy(tmpBuf.getAccess(), resultAccess);
1431
1432                                 if (outSize == 4 && outNumLocs == 1)
1433                                         deMemcpy(dstPtrBase, tmpBuf.getAccess().getDataPtr(), numValues * outVecSize * sizeof(deUint32));
1434                                 else
1435                                 {
1436                                         for (int valNdx = 0; valNdx < numValues; valNdx++)
1437                                         {
1438                                                 const deUint32* srcPtr = (const deUint32*)tmpBuf.getAccess().getDataPtr() + valNdx * 4;
1439                                                 deUint32*               dstPtr = &dstPtrBase[outSize * valNdx + outVecSize * locNdx];
1440                                                 deMemcpy(dstPtr, srcPtr, outVecSize * sizeof(deUint32));
1441                                         }
1442                                 }
1443                         }
1444                 }
1445         }
1446 }
1447
1448 // VertexShaderExecutor
1449
1450 class VertexShaderExecutor : public FragmentOutExecutor
1451 {
1452 public:
1453                                                                 VertexShaderExecutor    (Context& context, const ShaderSpec& shaderSpec, VkDescriptorSetLayout extraResourcesLayout);
1454         virtual                                         ~VertexShaderExecutor   (void);
1455
1456         static void                                     generateSources                 (const ShaderSpec& shaderSpec, SourceCollections& dst);
1457 };
1458
1459 VertexShaderExecutor::VertexShaderExecutor (Context& context, const ShaderSpec& shaderSpec, VkDescriptorSetLayout extraResourcesLayout)
1460         : FragmentOutExecutor(context, glu::SHADERTYPE_VERTEX, shaderSpec, extraResourcesLayout)
1461 {
1462 }
1463
1464 VertexShaderExecutor::~VertexShaderExecutor (void)
1465 {
1466 }
1467
1468 void VertexShaderExecutor::generateSources (const ShaderSpec& shaderSpec, SourceCollections& programCollection)
1469 {
1470         const FragmentOutputLayout      outputLayout    (computeFragmentOutputLayout(shaderSpec.outputs));
1471
1472         programCollection.glslSources.add("vert") << glu::VertexSource(generateVertexShader(shaderSpec, "a_", "vtx_out_"));
1473         /* \todo [2015-09-11 hegedusd] set useIntOutputs parameter if needed. */
1474         programCollection.glslSources.add("frag") << glu::FragmentSource(generatePassthroughFragmentShader(shaderSpec, false, outputLayout.locationMap, "vtx_out_", "o_"));
1475 }
1476
1477 // GeometryShaderExecutor
1478
1479 class GeometryShaderExecutor : public FragmentOutExecutor
1480 {
1481 public:
1482                                                                 GeometryShaderExecutor  (Context& context, const ShaderSpec& shaderSpec, VkDescriptorSetLayout extraResourcesLayout);
1483         virtual                                         ~GeometryShaderExecutor (void);
1484
1485         static void                                     generateSources                 (const ShaderSpec& shaderSpec, SourceCollections& programCollection);
1486
1487 };
1488
1489 GeometryShaderExecutor::GeometryShaderExecutor (Context& context, const ShaderSpec& shaderSpec, VkDescriptorSetLayout extraResourcesLayout)
1490         : FragmentOutExecutor(context, glu::SHADERTYPE_GEOMETRY, shaderSpec, extraResourcesLayout)
1491 {
1492         const VkPhysicalDeviceFeatures& features = context.getDeviceFeatures();
1493
1494         if (!features.geometryShader)
1495                 TCU_THROW(NotSupportedError, "Geometry shader type not supported by device");
1496 }
1497
1498 GeometryShaderExecutor::~GeometryShaderExecutor (void)
1499 {
1500 }
1501
1502 void GeometryShaderExecutor::generateSources (const ShaderSpec& shaderSpec, SourceCollections& programCollection)
1503 {
1504         const FragmentOutputLayout      outputLayout    (computeFragmentOutputLayout(shaderSpec.outputs));
1505
1506         programCollection.glslSources.add("vert") << glu::VertexSource(generatePassthroughVertexShader(shaderSpec.inputs, "a_", "vtx_out_"));
1507
1508         programCollection.glslSources.add("geom") << glu::GeometrySource(generateGeometryShader(shaderSpec, "vtx_out_", "geom_out_"));
1509
1510         /* \todo [2015-09-18 rsipka] set useIntOutputs parameter if needed. */
1511         programCollection.glslSources.add("frag") << glu::FragmentSource(generatePassthroughFragmentShader(shaderSpec, false, outputLayout.locationMap, "geom_out_", "o_"));
1512
1513 }
1514
1515 // FragmentShaderExecutor
1516
1517 class FragmentShaderExecutor : public FragmentOutExecutor
1518 {
1519 public:
1520                                                                 FragmentShaderExecutor  (Context& context, const ShaderSpec& shaderSpec, VkDescriptorSetLayout extraResourcesLayout);
1521         virtual                                         ~FragmentShaderExecutor (void);
1522
1523         static void                                     generateSources                 (const ShaderSpec& shaderSpec, SourceCollections& programCollection);
1524
1525 };
1526
1527 FragmentShaderExecutor::FragmentShaderExecutor (Context& context, const ShaderSpec& shaderSpec, VkDescriptorSetLayout extraResourcesLayout)
1528         : FragmentOutExecutor(context, glu::SHADERTYPE_FRAGMENT, shaderSpec, extraResourcesLayout)
1529 {
1530 }
1531
1532 FragmentShaderExecutor::~FragmentShaderExecutor (void)
1533 {
1534 }
1535
1536 void FragmentShaderExecutor::generateSources (const ShaderSpec& shaderSpec, SourceCollections& programCollection)
1537 {
1538         const FragmentOutputLayout      outputLayout    (computeFragmentOutputLayout(shaderSpec.outputs));
1539
1540         programCollection.glslSources.add("vert") << glu::VertexSource(generatePassthroughVertexShader(shaderSpec.inputs, "a_", "vtx_out_"));
1541         /* \todo [2015-09-11 hegedusd] set useIntOutputs parameter if needed. */
1542         programCollection.glslSources.add("frag") << glu::FragmentSource(generateFragmentShader(shaderSpec, false, outputLayout.locationMap, "vtx_out_", "o_"));
1543 }
1544
1545 // Shared utilities for compute and tess executors
1546
1547 static deUint32 getVecStd430ByteAlignment (glu::DataType type)
1548 {
1549         switch (glu::getDataTypeScalarSize(type))
1550         {
1551                 case 1:         return 4u;
1552                 case 2:         return 8u;
1553                 case 3:         return 16u;
1554                 case 4:         return 16u;
1555                 default:
1556                         DE_ASSERT(false);
1557                         return 0u;
1558         }
1559 }
1560
1561 class BufferIoExecutor : public ShaderExecutor
1562 {
1563 public:
1564                                                         BufferIoExecutor        (Context& context, const ShaderSpec& shaderSpec);
1565         virtual                                 ~BufferIoExecutor       (void);
1566
1567 protected:
1568         enum
1569         {
1570                 INPUT_BUFFER_BINDING    = 0,
1571                 OUTPUT_BUFFER_BINDING   = 1,
1572         };
1573
1574         void                                    initBuffers                     (int numValues);
1575         VkBuffer                                getInputBuffer          (void) const            { return *m_inputBuffer;                                        }
1576         VkBuffer                                getOutputBuffer         (void) const            { return *m_outputBuffer;                                       }
1577         deUint32                                getInputStride          (void) const            { return getLayoutStride(m_inputLayout);        }
1578         deUint32                                getOutputStride         (void) const            { return getLayoutStride(m_outputLayout);       }
1579
1580         void                                    uploadInputBuffer       (const void* const* inputPtrs, int numValues);
1581         void                                    readOutputBuffer        (void* const* outputPtrs, int numValues);
1582
1583         static void                             declareBufferBlocks     (std::ostream& src, const ShaderSpec& spec);
1584         static void                             generateExecBufferIo(std::ostream& src, const ShaderSpec& spec, const char* invocationNdxName);
1585
1586 protected:
1587         Move<VkBuffer>                  m_inputBuffer;
1588         Move<VkBuffer>                  m_outputBuffer;
1589
1590 private:
1591         struct VarLayout
1592         {
1593                 deUint32                offset;
1594                 deUint32                stride;
1595                 deUint32                matrixStride;
1596
1597                 VarLayout (void) : offset(0), stride(0), matrixStride(0) {}
1598         };
1599
1600         static void                             computeVarLayout        (const std::vector<Symbol>& symbols, std::vector<VarLayout>* layout);
1601         static deUint32                 getLayoutStride         (const vector<VarLayout>& layout);
1602
1603         static void                             copyToBuffer            (const glu::VarType& varType, const VarLayout& layout, int numValues, const void* srcBasePtr, void* dstBasePtr);
1604         static void                             copyFromBuffer          (const glu::VarType& varType, const VarLayout& layout, int numValues, const void* srcBasePtr, void* dstBasePtr);
1605
1606         de::MovePtr<Allocation> m_inputAlloc;
1607         de::MovePtr<Allocation> m_outputAlloc;
1608
1609         vector<VarLayout>               m_inputLayout;
1610         vector<VarLayout>               m_outputLayout;
1611 };
1612
1613 BufferIoExecutor::BufferIoExecutor (Context& context, const ShaderSpec& shaderSpec)
1614         : ShaderExecutor(context, shaderSpec)
1615 {
1616         computeVarLayout(m_shaderSpec.inputs, &m_inputLayout);
1617         computeVarLayout(m_shaderSpec.outputs, &m_outputLayout);
1618 }
1619
1620 BufferIoExecutor::~BufferIoExecutor (void)
1621 {
1622 }
1623
1624 inline deUint32 BufferIoExecutor::getLayoutStride (const vector<VarLayout>& layout)
1625 {
1626         return layout.empty() ? 0 : layout[0].stride;
1627 }
1628
1629 void BufferIoExecutor::computeVarLayout (const std::vector<Symbol>& symbols, std::vector<VarLayout>* layout)
1630 {
1631         deUint32        maxAlignment    = 0;
1632         deUint32        curOffset               = 0;
1633
1634         DE_ASSERT(layout != DE_NULL);
1635         DE_ASSERT(layout->empty());
1636         layout->resize(symbols.size());
1637
1638         for (size_t varNdx = 0; varNdx < symbols.size(); varNdx++)
1639         {
1640                 const Symbol&           symbol          = symbols[varNdx];
1641                 const glu::DataType     basicType       = symbol.varType.getBasicType();
1642                 VarLayout&                      layoutEntry     = (*layout)[varNdx];
1643
1644                 if (glu::isDataTypeScalarOrVector(basicType))
1645                 {
1646                         const deUint32  alignment       = getVecStd430ByteAlignment(basicType);
1647                         const deUint32  size            = (deUint32)glu::getDataTypeScalarSize(basicType) * (int)sizeof(deUint32);
1648
1649                         curOffset               = (deUint32)deAlign32((int)curOffset, (int)alignment);
1650                         maxAlignment    = de::max(maxAlignment, alignment);
1651
1652                         layoutEntry.offset                      = curOffset;
1653                         layoutEntry.matrixStride        = 0;
1654
1655                         curOffset += size;
1656                 }
1657                 else if (glu::isDataTypeMatrix(basicType))
1658                 {
1659                         const int                               numVecs                 = glu::getDataTypeMatrixNumColumns(basicType);
1660                         const glu::DataType             vecType                 = glu::getDataTypeFloatVec(glu::getDataTypeMatrixNumRows(basicType));
1661                         const deUint32                  vecAlignment    = getVecStd430ByteAlignment(vecType);
1662
1663                         curOffset               = (deUint32)deAlign32((int)curOffset, (int)vecAlignment);
1664                         maxAlignment    = de::max(maxAlignment, vecAlignment);
1665
1666                         layoutEntry.offset                      = curOffset;
1667                         layoutEntry.matrixStride        = vecAlignment;
1668
1669                         curOffset += vecAlignment*numVecs;
1670                 }
1671                 else
1672                         DE_ASSERT(false);
1673         }
1674
1675         {
1676                 const deUint32  totalSize       = (deUint32)deAlign32(curOffset, maxAlignment);
1677
1678                 for (vector<VarLayout>::iterator varIter = layout->begin(); varIter != layout->end(); ++varIter)
1679                         varIter->stride = totalSize;
1680         }
1681 }
1682
1683 void BufferIoExecutor::declareBufferBlocks (std::ostream& src, const ShaderSpec& spec)
1684 {
1685         // Input struct
1686         if (!spec.inputs.empty())
1687         {
1688                 glu::StructType inputStruct("Inputs");
1689                 for (vector<Symbol>::const_iterator symIter = spec.inputs.begin(); symIter != spec.inputs.end(); ++symIter)
1690                         inputStruct.addMember(symIter->name.c_str(), symIter->varType);
1691                 src << glu::declare(&inputStruct) << ";\n";
1692         }
1693
1694         // Output struct
1695         {
1696                 glu::StructType outputStruct("Outputs");
1697                 for (vector<Symbol>::const_iterator symIter = spec.outputs.begin(); symIter != spec.outputs.end(); ++symIter)
1698                         outputStruct.addMember(symIter->name.c_str(), symIter->varType);
1699                 src << glu::declare(&outputStruct) << ";\n";
1700         }
1701
1702         src << "\n";
1703
1704         if (!spec.inputs.empty())
1705         {
1706                 src     << "layout(set = 0, binding = " << int(INPUT_BUFFER_BINDING) << ", std430) buffer InBuffer\n"
1707                         << "{\n"
1708                         << "    Inputs inputs[];\n"
1709                         << "};\n";
1710         }
1711
1712         src     << "layout(set = 0, binding = " << int(OUTPUT_BUFFER_BINDING) << ", std430) buffer OutBuffer\n"
1713                 << "{\n"
1714                 << "    Outputs outputs[];\n"
1715                 << "};\n"
1716                 << "\n";
1717 }
1718
1719 void BufferIoExecutor::generateExecBufferIo (std::ostream& src, const ShaderSpec& spec, const char* invocationNdxName)
1720 {
1721         for (vector<Symbol>::const_iterator symIter = spec.inputs.begin(); symIter != spec.inputs.end(); ++symIter)
1722                 src << "\t" << glu::declare(symIter->varType, symIter->name) << " = inputs[" << invocationNdxName << "]." << symIter->name << ";\n";
1723
1724         for (vector<Symbol>::const_iterator symIter = spec.outputs.begin(); symIter != spec.outputs.end(); ++symIter)
1725                 src << "\t" << glu::declare(symIter->varType, symIter->name) << ";\n";
1726
1727         src << "\n";
1728
1729         {
1730                 std::istringstream      opSrc   (spec.source);
1731                 std::string                     line;
1732
1733                 while (std::getline(opSrc, line))
1734                         src << "\t" << line << "\n";
1735         }
1736
1737         src << "\n";
1738         for (vector<Symbol>::const_iterator symIter = spec.outputs.begin(); symIter != spec.outputs.end(); ++symIter)
1739                 src << "\toutputs[" << invocationNdxName << "]." << symIter->name << " = " << symIter->name << ";\n";
1740 }
1741
1742 void BufferIoExecutor::copyToBuffer (const glu::VarType& varType, const VarLayout& layout, int numValues, const void* srcBasePtr, void* dstBasePtr)
1743 {
1744         if (varType.isBasicType())
1745         {
1746                 const glu::DataType             basicType               = varType.getBasicType();
1747                 const bool                              isMatrix                = glu::isDataTypeMatrix(basicType);
1748                 const int                               scalarSize              = glu::getDataTypeScalarSize(basicType);
1749                 const int                               numVecs                 = isMatrix ? glu::getDataTypeMatrixNumColumns(basicType) : 1;
1750                 const int                               numComps                = scalarSize / numVecs;
1751
1752                 for (int elemNdx = 0; elemNdx < numValues; elemNdx++)
1753                 {
1754                         for (int vecNdx = 0; vecNdx < numVecs; vecNdx++)
1755                         {
1756                                 const int               srcOffset               = (int)sizeof(deUint32) * (elemNdx * scalarSize + vecNdx * numComps);
1757                                 const int               dstOffset               = layout.offset + layout.stride * elemNdx + (isMatrix ? layout.matrixStride * vecNdx : 0);
1758                                 const deUint8*  srcPtr                  = (const deUint8*)srcBasePtr + srcOffset;
1759                                 deUint8*                dstPtr                  = (deUint8*)dstBasePtr + dstOffset;
1760
1761                                 deMemcpy(dstPtr, srcPtr, sizeof(deUint32) * numComps);
1762                         }
1763                 }
1764         }
1765         else
1766                 throw tcu::InternalError("Unsupported type");
1767 }
1768
1769 void BufferIoExecutor::copyFromBuffer (const glu::VarType& varType, const VarLayout& layout, int numValues, const void* srcBasePtr, void* dstBasePtr)
1770 {
1771         if (varType.isBasicType())
1772         {
1773                 const glu::DataType             basicType               = varType.getBasicType();
1774                 const bool                              isMatrix                = glu::isDataTypeMatrix(basicType);
1775                 const int                               scalarSize              = glu::getDataTypeScalarSize(basicType);
1776                 const int                               numVecs                 = isMatrix ? glu::getDataTypeMatrixNumColumns(basicType) : 1;
1777                 const int                               numComps                = scalarSize / numVecs;
1778
1779                 for (int elemNdx = 0; elemNdx < numValues; elemNdx++)
1780                 {
1781                         for (int vecNdx = 0; vecNdx < numVecs; vecNdx++)
1782                         {
1783                                 const int               srcOffset               = layout.offset + layout.stride * elemNdx + (isMatrix ? layout.matrixStride * vecNdx : 0);
1784                                 const int               dstOffset               = (int)sizeof(deUint32) * (elemNdx * scalarSize + vecNdx * numComps);
1785                                 const deUint8*  srcPtr                  = (const deUint8*)srcBasePtr + srcOffset;
1786                                 deUint8*                dstPtr                  = (deUint8*)dstBasePtr + dstOffset;
1787
1788                                 deMemcpy(dstPtr, srcPtr, sizeof(deUint32) * numComps);
1789                         }
1790                 }
1791         }
1792         else
1793                 throw tcu::InternalError("Unsupported type");
1794 }
1795
1796 void BufferIoExecutor::uploadInputBuffer (const void* const* inputPtrs, int numValues)
1797 {
1798         const VkDevice                  vkDevice                        = m_context.getDevice();
1799         const DeviceInterface&  vk                                      = m_context.getDeviceInterface();
1800
1801         const deUint32                  inputStride                     = getLayoutStride(m_inputLayout);
1802         const int                               inputBufferSize         = inputStride * numValues;
1803
1804         if (inputBufferSize == 0)
1805                 return; // No inputs
1806
1807         DE_ASSERT(m_shaderSpec.inputs.size() == m_inputLayout.size());
1808         for (size_t inputNdx = 0; inputNdx < m_shaderSpec.inputs.size(); ++inputNdx)
1809         {
1810                 const glu::VarType&             varType         = m_shaderSpec.inputs[inputNdx].varType;
1811                 const VarLayout&                layout          = m_inputLayout[inputNdx];
1812
1813                 copyToBuffer(varType, layout, numValues, inputPtrs[inputNdx], m_inputAlloc->getHostPtr());
1814         }
1815
1816         flushMappedMemoryRange(vk, vkDevice, m_inputAlloc->getMemory(), m_inputAlloc->getOffset(), inputBufferSize);
1817 }
1818
1819 void BufferIoExecutor::readOutputBuffer (void* const* outputPtrs, int numValues)
1820 {
1821         const VkDevice                  vkDevice                        = m_context.getDevice();
1822         const DeviceInterface&  vk                                      = m_context.getDeviceInterface();
1823
1824         const deUint32                  outputStride            = getLayoutStride(m_outputLayout);
1825         const int                               outputBufferSize        = numValues * outputStride;
1826
1827         DE_ASSERT(outputBufferSize > 0); // At least some outputs are required.
1828
1829         invalidateMappedMemoryRange(vk, vkDevice, m_outputAlloc->getMemory(), m_outputAlloc->getOffset(), outputBufferSize);
1830
1831         DE_ASSERT(m_shaderSpec.outputs.size() == m_outputLayout.size());
1832         for (size_t outputNdx = 0; outputNdx < m_shaderSpec.outputs.size(); ++outputNdx)
1833         {
1834                 const glu::VarType&             varType         = m_shaderSpec.outputs[outputNdx].varType;
1835                 const VarLayout&                layout          = m_outputLayout[outputNdx];
1836
1837                 copyFromBuffer(varType, layout, numValues, m_outputAlloc->getHostPtr(), outputPtrs[outputNdx]);
1838         }
1839 }
1840
1841 void BufferIoExecutor::initBuffers (int numValues)
1842 {
1843         const deUint32                          inputStride                     = getLayoutStride(m_inputLayout);
1844         const deUint32                          outputStride            = getLayoutStride(m_outputLayout);
1845         // Avoid creating zero-sized buffer/memory
1846         const size_t                            inputBufferSize         = numValues * inputStride ? (numValues * inputStride) : 1;
1847         const size_t                            outputBufferSize        = numValues * outputStride;
1848
1849         // Upload data to buffer
1850         const VkDevice                          vkDevice                        = m_context.getDevice();
1851         const DeviceInterface&          vk                                      = m_context.getDeviceInterface();
1852         const deUint32                          queueFamilyIndex        = m_context.getUniversalQueueFamilyIndex();
1853         Allocator&                                      memAlloc                        = m_context.getDefaultAllocator();
1854
1855         const VkBufferCreateInfo inputBufferParams =
1856         {
1857                 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,           // VkStructureType              sType;
1858                 DE_NULL,                                                                        // const void*                  pNext;
1859                 0u,                                                                                     // VkBufferCreateFlags  flags;
1860                 inputBufferSize,                                                        // VkDeviceSize                 size;
1861                 VK_BUFFER_USAGE_STORAGE_BUFFER_BIT,                     // VkBufferUsageFlags   usage;
1862                 VK_SHARING_MODE_EXCLUSIVE,                                      // VkSharingMode                sharingMode;
1863                 1u,                                                                                     // deUint32                             queueFamilyCount;
1864                 &queueFamilyIndex                                                       // const deUint32*              pQueueFamilyIndices;
1865         };
1866
1867         m_inputBuffer = createBuffer(vk, vkDevice, &inputBufferParams);
1868         m_inputAlloc = memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *m_inputBuffer), MemoryRequirement::HostVisible);
1869
1870         VK_CHECK(vk.bindBufferMemory(vkDevice, *m_inputBuffer, m_inputAlloc->getMemory(), m_inputAlloc->getOffset()));
1871
1872         const VkBufferCreateInfo outputBufferParams =
1873         {
1874                 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,           // VkStructureType              sType;
1875                 DE_NULL,                                                                        // const void*                  pNext;
1876                 0u,                                                                                     // VkBufferCreateFlags  flags;
1877                 outputBufferSize,                                                       // VkDeviceSize                 size;
1878                 VK_BUFFER_USAGE_STORAGE_BUFFER_BIT,                     // VkBufferUsageFlags   usage;
1879                 VK_SHARING_MODE_EXCLUSIVE,                                      // VkSharingMode                sharingMode;
1880                 1u,                                                                                     // deUint32                             queueFamilyCount;
1881                 &queueFamilyIndex                                                       // const deUint32*              pQueueFamilyIndices;
1882         };
1883
1884         m_outputBuffer = createBuffer(vk, vkDevice, &outputBufferParams);
1885         m_outputAlloc = memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *m_outputBuffer), MemoryRequirement::HostVisible);
1886
1887         VK_CHECK(vk.bindBufferMemory(vkDevice, *m_outputBuffer, m_outputAlloc->getMemory(), m_outputAlloc->getOffset()));
1888 }
1889
1890 // ComputeShaderExecutor
1891
1892 class ComputeShaderExecutor : public BufferIoExecutor
1893 {
1894 public:
1895                                                 ComputeShaderExecutor   (Context& context, const ShaderSpec& shaderSpec, VkDescriptorSetLayout extraResourcesLayout);
1896         virtual                         ~ComputeShaderExecutor  (void);
1897
1898         static void                     generateSources                 (const ShaderSpec& shaderSpec, SourceCollections& programCollection);
1899
1900         virtual void            execute                                 (int numValues, const void* const* inputs, void* const* outputs, VkDescriptorSet extraResources);
1901
1902 protected:
1903         static std::string      generateComputeShader   (const ShaderSpec& spec);
1904
1905 private:
1906         const VkDescriptorSetLayout                                     m_extraResourcesLayout;
1907 };
1908
1909 ComputeShaderExecutor::ComputeShaderExecutor(Context& context, const ShaderSpec& shaderSpec, VkDescriptorSetLayout extraResourcesLayout)
1910         : BufferIoExecutor                      (context, shaderSpec)
1911         , m_extraResourcesLayout        (extraResourcesLayout)
1912 {
1913 }
1914
1915 ComputeShaderExecutor::~ComputeShaderExecutor   (void)
1916 {
1917 }
1918
1919 std::string ComputeShaderExecutor::generateComputeShader (const ShaderSpec& spec)
1920 {
1921         std::ostringstream src;
1922         src <<  "#version 310 es\n";
1923
1924         if (!spec.globalDeclarations.empty())
1925                 src << spec.globalDeclarations << "\n";
1926
1927         src << "layout(local_size_x = 1) in;\n"
1928                 << "\n";
1929
1930         declareBufferBlocks(src, spec);
1931
1932         src << "void main (void)\n"
1933                 << "{\n"
1934                 << "    uint invocationNdx = gl_NumWorkGroups.x*gl_NumWorkGroups.y*gl_WorkGroupID.z\n"
1935                 << "                       + gl_NumWorkGroups.x*gl_WorkGroupID.y + gl_WorkGroupID.x;\n";
1936
1937         generateExecBufferIo(src, spec, "invocationNdx");
1938
1939         src << "}\n";
1940
1941         return src.str();
1942 }
1943
1944 void ComputeShaderExecutor::generateSources (const ShaderSpec& shaderSpec, SourceCollections& programCollection)
1945 {
1946         programCollection.glslSources.add("compute") << glu::ComputeSource(generateComputeShader(shaderSpec));
1947 }
1948
1949 void ComputeShaderExecutor::execute (int numValues, const void* const* inputs, void* const* outputs, VkDescriptorSet extraResources)
1950 {
1951         const VkDevice                                  vkDevice                                = m_context.getDevice();
1952         const DeviceInterface&                  vk                                              = m_context.getDeviceInterface();
1953         const VkQueue                                   queue                                   = m_context.getUniversalQueue();
1954         const deUint32                                  queueFamilyIndex                = m_context.getUniversalQueueFamilyIndex();
1955
1956         DescriptorPoolBuilder                   descriptorPoolBuilder;
1957         DescriptorSetLayoutBuilder              descriptorSetLayoutBuilder;
1958
1959         Move<VkShaderModule>                    computeShaderModule;
1960         Move<VkPipeline>                                computePipeline;
1961         Move<VkPipelineLayout>                  pipelineLayout;
1962         Move<VkCommandPool>                             cmdPool;
1963         Move<VkDescriptorPool>                  descriptorPool;
1964         Move<VkDescriptorSetLayout>             descriptorSetLayout;
1965         Move<VkDescriptorSet>                   descriptorSet;
1966         const deUint32                                  numDescriptorSets               = (m_extraResourcesLayout != 0) ? 2u : 1u;
1967         Move<VkFence>                                   fence;
1968
1969         DE_ASSERT((m_extraResourcesLayout != 0) == (extraResources != 0));
1970
1971         initBuffers(numValues);
1972
1973         // Setup input buffer & copy data
1974         uploadInputBuffer(inputs, numValues);
1975
1976         // Create command pool
1977         {
1978                 const VkCommandPoolCreateInfo cmdPoolParams =
1979                 {
1980                         VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,             // VkStructureType              sType;
1981                         DE_NULL,                                                                                // const void*                  pNext;
1982                         VK_COMMAND_POOL_CREATE_TRANSIENT_BIT,                   // VkCmdPoolCreateFlags flags;
1983                         queueFamilyIndex                                                                // deUint32                             queueFamilyIndex;
1984                 };
1985
1986                 cmdPool = createCommandPool(vk, vkDevice, &cmdPoolParams);
1987         }
1988
1989         // Create command buffer
1990         const VkCommandBufferAllocateInfo cmdBufferParams =
1991         {
1992                 VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, // VkStructureType                      sType;
1993                 DE_NULL,                                                                                // const void*                          pNext;
1994                 *cmdPool,                                                                               // VkCmdPool                            cmdPool;
1995                 VK_COMMAND_BUFFER_LEVEL_PRIMARY,                                // VkCmdBufferLevel                     level;
1996                 1u                                                                                              // deUint32                                     bufferCount;
1997         };
1998
1999         const VkCommandBufferBeginInfo cmdBufferBeginInfo =
2000         {
2001                 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,    // VkStructureType                                      sType;
2002                 DE_NULL,                                                                                // const void*                                          pNext;
2003                 0u,                                                                                             // VkCmdBufferOptimizeFlags                     flags;
2004                 (const VkCommandBufferInheritanceInfo*)DE_NULL,
2005         };
2006
2007         descriptorSetLayoutBuilder.addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_SHADER_STAGE_COMPUTE_BIT);
2008         descriptorPoolBuilder.addType(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER);
2009         descriptorSetLayoutBuilder.addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_SHADER_STAGE_COMPUTE_BIT);
2010         descriptorPoolBuilder.addType(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER);
2011
2012         descriptorSetLayout = descriptorSetLayoutBuilder.build(vk, vkDevice);
2013         descriptorPool = descriptorPoolBuilder.build(vk, vkDevice, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u);
2014
2015         const VkDescriptorSetAllocateInfo allocInfo =
2016         {
2017                 VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
2018                 DE_NULL,
2019                 *descriptorPool,
2020                 1u,
2021                 &*descriptorSetLayout
2022         };
2023
2024         descriptorSet = allocateDescriptorSet(vk, vkDevice, &allocInfo);
2025
2026         // Create pipeline layout
2027         {
2028                 const VkDescriptorSetLayout                     descriptorSetLayouts[]  =
2029                 {
2030                         *descriptorSetLayout,
2031                         m_extraResourcesLayout
2032                 };
2033                 const VkPipelineLayoutCreateInfo        pipelineLayoutParams    =
2034                 {
2035                         VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,          // VkStructureType                              sType;
2036                         DE_NULL,                                                                                        // const void*                                  pNext;
2037                         (VkPipelineLayoutCreateFlags)0,                                         // VkPipelineLayoutCreateFlags  flags;
2038                         numDescriptorSets,                                                                      // deUint32                                             CdescriptorSetCount;
2039                         descriptorSetLayouts,                                                           // const VkDescriptorSetLayout* pSetLayouts;
2040                         0u,                                                                                                     // deUint32                                             pushConstantRangeCount;
2041                         DE_NULL                                                                                         // const VkPushConstantRange*   pPushConstantRanges;
2042                 };
2043
2044                 pipelineLayout = createPipelineLayout(vk, vkDevice, &pipelineLayoutParams);
2045         }
2046
2047         // Create shaders
2048         {
2049                 computeShaderModule             = createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("compute"), 0);
2050         }
2051
2052         // create pipeline
2053         {
2054                 const VkPipelineShaderStageCreateInfo shaderStageParams[1] =
2055                 {
2056                         {
2057                                 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,            // VkStructureType                                              sType;
2058                                 DE_NULL,                                                                                                        // const void*                                                  pNext;
2059                                 (VkPipelineShaderStageCreateFlags)0u,                                           // VkPipelineShaderStageCreateFlags             flags;
2060                                 VK_SHADER_STAGE_COMPUTE_BIT,                                                            // VkShaderStageFlagsBit                                stage;
2061                                 *computeShaderModule,                                                                           // VkShaderModule                                               shader;
2062                                 "main",                                                                                                         // const char*                                                  pName;
2063                                 DE_NULL                                                                                                         // const VkSpecializationInfo*                  pSpecializationInfo;
2064                         }
2065                 };
2066
2067                 const VkComputePipelineCreateInfo computePipelineParams =
2068                 {
2069                         VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO,         // VkStructureType                                                                      sType;
2070                         DE_NULL,                                                                                        // const void*                                                                          pNext;
2071                         (VkPipelineCreateFlags)0,                                                       // VkPipelineCreateFlags                                                        flags;
2072                         *shaderStageParams,                                                                     // VkPipelineShaderStageCreateInfo                                      cs;
2073                         *pipelineLayout,                                                                        // VkPipelineLayout                                                                     layout;
2074                         0u,                                                                                                     // VkPipeline                                                                           basePipelineHandle;
2075                         0u,                                                                                                     // int32_t                                                                                      basePipelineIndex;
2076                 };
2077
2078                 computePipeline = createComputePipeline(vk, vkDevice, DE_NULL, &computePipelineParams);
2079         }
2080
2081         // Create fence
2082         {
2083                 const VkFenceCreateInfo fenceParams =
2084                 {
2085                         VK_STRUCTURE_TYPE_FENCE_CREATE_INFO,    // VkStructureType              sType;
2086                         DE_NULL,                                                                // const void*                  pNext;
2087                         0u                                                                              // VkFenceCreateFlags   flags;
2088                 };
2089                 fence = createFence(vk, vkDevice, &fenceParams);
2090         }
2091
2092         const int                       maxValuesPerInvocation  = m_context.getDeviceProperties().limits.maxComputeWorkGroupSize[0];
2093         int                                     curOffset                               = 0;
2094         const deUint32          inputStride                             = getInputStride();
2095         const deUint32          outputStride                    = getOutputStride();
2096
2097         while (curOffset < numValues)
2098         {
2099                 Move<VkCommandBuffer>   cmdBuffer;
2100                 const int                               numToExec       = de::min(maxValuesPerInvocation, numValues-curOffset);
2101
2102                 // Update descriptors
2103                 {
2104                         DescriptorSetUpdateBuilder descriptorSetUpdateBuilder;
2105
2106                         const VkDescriptorBufferInfo outputDescriptorBufferInfo =
2107                         {
2108                                 *m_outputBuffer,                                // VkBuffer                     buffer;
2109                                 curOffset * outputStride,               // VkDeviceSize         offset;
2110                                 numToExec * outputStride                // VkDeviceSize         range;
2111                         };
2112
2113                         descriptorSetUpdateBuilder.writeSingle(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding((deUint32)OUTPUT_BUFFER_BINDING), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &outputDescriptorBufferInfo);
2114
2115                         if (inputStride)
2116                         {
2117                                 const VkDescriptorBufferInfo inputDescriptorBufferInfo =
2118                                 {
2119                                         *m_inputBuffer,                                 // VkBuffer                     buffer;
2120                                         curOffset * inputStride,                // VkDeviceSize         offset;
2121                                         numToExec * inputStride                 // VkDeviceSize         range;
2122                                 };
2123
2124                                 descriptorSetUpdateBuilder.writeSingle(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding((deUint32)INPUT_BUFFER_BINDING), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &inputDescriptorBufferInfo);
2125                         }
2126
2127                         descriptorSetUpdateBuilder.update(vk, vkDevice);
2128                 }
2129
2130                 cmdBuffer = allocateCommandBuffer(vk, vkDevice, &cmdBufferParams);
2131                 VK_CHECK(vk.beginCommandBuffer(*cmdBuffer, &cmdBufferBeginInfo));
2132                 vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *computePipeline);
2133
2134                 {
2135                         const VkDescriptorSet   descriptorSets[]        = { *descriptorSet, extraResources };
2136                         vk.cmdBindDescriptorSets(*cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *pipelineLayout, 0u, numDescriptorSets, descriptorSets, 0u, DE_NULL);
2137                 }
2138
2139                 vk.cmdDispatch(*cmdBuffer, numToExec, 1, 1);
2140
2141                 VK_CHECK(vk.endCommandBuffer(*cmdBuffer));
2142
2143                 curOffset += numToExec;
2144
2145                 // Execute
2146                 {
2147                         VK_CHECK(vk.resetFences(vkDevice, 1, &fence.get()));
2148
2149                         const VkSubmitInfo submitInfo =
2150                         {
2151                                 VK_STRUCTURE_TYPE_SUBMIT_INFO,
2152                                 DE_NULL,
2153                                 0u,
2154                                 (const VkSemaphore*)DE_NULL,
2155                                 (const VkPipelineStageFlags*)DE_NULL,
2156                                 1u,
2157                                 &cmdBuffer.get(),
2158                                 0u,
2159                                 (const VkSemaphore*)DE_NULL,
2160                         };
2161
2162                         VK_CHECK(vk.queueSubmit(queue, 1, &submitInfo, *fence));
2163                         VK_CHECK(vk.waitForFences(vkDevice, 1, &fence.get(), true, ~(0ull) /* infinity*/));
2164                 }
2165         }
2166
2167         // Read back data
2168         readOutputBuffer(outputs, numValues);
2169 }
2170
2171 // Tessellation utils
2172
2173 static std::string generateVertexShaderForTess (void)
2174 {
2175         std::ostringstream      src;
2176         src <<  "#version 310 es\n"
2177                 << "void main (void)\n{\n"
2178                 << "    gl_Position = vec4(gl_VertexIndex/2, gl_VertexIndex%2, 0.0, 1.0);\n"
2179                 << "}\n";
2180
2181         return src.str();
2182 }
2183
2184 class TessellationExecutor : public BufferIoExecutor
2185 {
2186 public:
2187                                         TessellationExecutor            (Context& context, const ShaderSpec& shaderSpec, VkDescriptorSetLayout extraResourcesLayout);
2188         virtual                 ~TessellationExecutor           (void);
2189
2190         void                    renderTess                                      (deUint32 numValues, deUint32 vertexCount, deUint32 patchControlPoints, VkDescriptorSet extraResources);
2191
2192 private:
2193         const VkDescriptorSetLayout                                     m_extraResourcesLayout;
2194 };
2195
2196 TessellationExecutor::TessellationExecutor (Context& context, const ShaderSpec& shaderSpec, VkDescriptorSetLayout extraResourcesLayout)
2197         : BufferIoExecutor                      (context, shaderSpec)
2198         , m_extraResourcesLayout        (extraResourcesLayout)
2199 {
2200         const VkPhysicalDeviceFeatures& features = context.getDeviceFeatures();
2201
2202         if (!features.tessellationShader)
2203                 TCU_THROW(NotSupportedError, "Tessellation shader is not supported by device");
2204 }
2205
2206 TessellationExecutor::~TessellationExecutor (void)
2207 {
2208 }
2209
2210 void TessellationExecutor::renderTess (deUint32 numValues, deUint32 vertexCount, deUint32 patchControlPoints, VkDescriptorSet extraResources)
2211 {
2212         const size_t                                            inputBufferSize                         = numValues * getInputStride();
2213         const VkDevice                                          vkDevice                                        = m_context.getDevice();
2214         const DeviceInterface&                          vk                                                      = m_context.getDeviceInterface();
2215         const VkQueue                                           queue                                           = m_context.getUniversalQueue();
2216         const deUint32                                          queueFamilyIndex                        = m_context.getUniversalQueueFamilyIndex();
2217         Allocator&                                                      memAlloc                                        = m_context.getDefaultAllocator();
2218
2219         const tcu::UVec2                                        renderSize                                      (DEFAULT_RENDER_WIDTH, DEFAULT_RENDER_HEIGHT);
2220
2221         Move<VkImage>                                           colorImage;
2222         de::MovePtr<Allocation>                         colorImageAlloc;
2223         VkFormat                                                        colorFormat                                     = VK_FORMAT_R8G8B8A8_UNORM;
2224         Move<VkImageView>                                       colorImageView;
2225
2226         Move<VkRenderPass>                                      renderPass;
2227         Move<VkFramebuffer>                                     framebuffer;
2228         Move<VkPipelineLayout>                          pipelineLayout;
2229         Move<VkPipeline>                                        graphicsPipeline;
2230
2231         Move<VkShaderModule>                            vertexShaderModule;
2232         Move<VkShaderModule>                            tessControlShaderModule;
2233         Move<VkShaderModule>                            tessEvalShaderModule;
2234         Move<VkShaderModule>                            fragmentShaderModule;
2235
2236         Move<VkCommandPool>                                     cmdPool;
2237         Move<VkCommandBuffer>                           cmdBuffer;
2238
2239         Move<VkFence>                                           fence;
2240
2241         Move<VkDescriptorPool>                          descriptorPool;
2242         Move<VkDescriptorSetLayout>                     descriptorSetLayout;
2243         Move<VkDescriptorSet>                           descriptorSet;
2244         const deUint32                                          numDescriptorSets                       = (m_extraResourcesLayout != 0) ? 2u : 1u;
2245
2246         DE_ASSERT((m_extraResourcesLayout != 0) == (extraResources != 0));
2247
2248         // Create color image
2249         {
2250                 const VkImageCreateInfo colorImageParams =
2251                 {
2252                         VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,                                                                            // VkStructureType                      sType;
2253                         DE_NULL,                                                                                                                                        // const void*                          pNext;
2254                         0u,                                                                                                                                                     // VkImageCreateFlags           flags;
2255                         VK_IMAGE_TYPE_2D,                                                                                                                       // VkImageType                          imageType;
2256                         colorFormat,                                                                                                                            // VkFormat                                     format;
2257                         { renderSize.x(), renderSize.y(), 1u },                                                                         // VkExtent3D                           extent;
2258                         1u,                                                                                                                                                     // deUint32                                     mipLevels;
2259                         1u,                                                                                                                                                     // deUint32                                     arraySize;
2260                         VK_SAMPLE_COUNT_1_BIT,                                                                                                          // VkSampleCountFlagBits        samples;
2261                         VK_IMAGE_TILING_OPTIMAL,                                                                                                        // VkImageTiling                        tiling;
2262                         VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT,          // VkImageUsageFlags            usage;
2263                         VK_SHARING_MODE_EXCLUSIVE,                                                                                                      // VkSharingMode                        sharingMode;
2264                         1u,                                                                                                                                                     // deUint32                                     queueFamilyCount;
2265                         &queueFamilyIndex,                                                                                                                      // const deUint32*                      pQueueFamilyIndices;
2266                         VK_IMAGE_LAYOUT_UNDEFINED                                                                                                       // VkImageLayout                        initialLayout;
2267                 };
2268
2269                 colorImage = createImage(vk, vkDevice, &colorImageParams);
2270
2271                 // Allocate and bind color image memory
2272                 colorImageAlloc = memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, *colorImage), MemoryRequirement::Any);
2273                 VK_CHECK(vk.bindImageMemory(vkDevice, *colorImage, colorImageAlloc->getMemory(), colorImageAlloc->getOffset()));
2274         }
2275
2276         // Create color attachment view
2277         {
2278                 const VkImageViewCreateInfo colorImageViewParams =
2279                 {
2280                         VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,                       // VkStructureType                      sType;
2281                         DE_NULL,                                                                                        // const void*                          pNext;
2282                         0u,                                                                                                     // VkImageViewCreateFlags       flags;
2283                         *colorImage,                                                                            // VkImage                                      image;
2284                         VK_IMAGE_VIEW_TYPE_2D,                                                          // VkImageViewType                      viewType;
2285                         colorFormat,                                                                            // VkFormat                                     format;
2286                         {
2287                                 VK_COMPONENT_SWIZZLE_R,                                                 // VkComponentSwizzle           r;
2288                                 VK_COMPONENT_SWIZZLE_G,                                                 // VkComponentSwizzle           g;
2289                                 VK_COMPONENT_SWIZZLE_B,                                                 // VkComponentSwizzle           b;
2290                                 VK_COMPONENT_SWIZZLE_A                                                  // VkComponentSwizzle           a;
2291                         },                                                                                                      // VkComponentsMapping          components;
2292                         {
2293                                 VK_IMAGE_ASPECT_COLOR_BIT,                                              // VkImageAspectFlags           aspectMask;
2294                                 0u,                                                                                             // deUint32                                     baseMipLevel;
2295                                 1u,                                                                                             // deUint32                                     mipLevels;
2296                                 0u,                                                                                             // deUint32                                     baseArraylayer;
2297                                 1u                                                                                              // deUint32                                     layerCount;
2298                         }                                                                                                       // VkImageSubresourceRange      subresourceRange;
2299                 };
2300
2301                 colorImageView = createImageView(vk, vkDevice, &colorImageViewParams);
2302         }
2303
2304         // Create render pass
2305         {
2306                 const VkAttachmentDescription colorAttachmentDescription =
2307                 {
2308                         0u,                                                                                                     // VkAttachmentDescriptorFlags  flags;
2309                         colorFormat,                                                                            // VkFormat                                             format;
2310                         VK_SAMPLE_COUNT_1_BIT,                                                          // VkSampleCountFlagBits                samples;
2311                         VK_ATTACHMENT_LOAD_OP_CLEAR,                                            // VkAttachmentLoadOp                   loadOp;
2312                         VK_ATTACHMENT_STORE_OP_STORE,                                           // VkAttachmentStoreOp                  storeOp;
2313                         VK_ATTACHMENT_LOAD_OP_DONT_CARE,                                        // VkAttachmentLoadOp                   stencilLoadOp;
2314                         VK_ATTACHMENT_STORE_OP_DONT_CARE,                                       // VkAttachmentStoreOp                  stencilStoreOp;
2315                         VK_IMAGE_LAYOUT_UNDEFINED,                                                      // VkImageLayout                                initialLayout;
2316                         VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL                        // VkImageLayout                                finalLayout
2317                 };
2318
2319                 const VkAttachmentDescription attachments[1] =
2320                 {
2321                         colorAttachmentDescription
2322                 };
2323
2324                 const VkAttachmentReference colorAttachmentReference =
2325                 {
2326                         0u,                                                                                                     // deUint32                     attachment;
2327                         VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL                        // VkImageLayout        layout;
2328                 };
2329
2330                 const VkSubpassDescription subpassDescription =
2331                 {
2332                         0u,                                                                                                     // VkSubpassDescriptionFlags    flags;
2333                         VK_PIPELINE_BIND_POINT_GRAPHICS,                                        // VkPipelineBindPoint                  pipelineBindPoint;
2334                         0u,                                                                                                     // deUint32                                             inputCount;
2335                         DE_NULL,                                                                                        // const VkAttachmentReference* pInputAttachments;
2336                         1u,                                                                                                     // deUint32                                             colorCount;
2337                         &colorAttachmentReference,                                                      // const VkAttachmentReference* pColorAttachments;
2338                         DE_NULL,                                                                                        // const VkAttachmentReference* pResolveAttachments;
2339                         DE_NULL,                                                                                        // VkAttachmentReference                depthStencilAttachment;
2340                         0u,                                                                                                     // deUint32                                             preserveCount;
2341                         DE_NULL                                                                                         // const VkAttachmentReference* pPreserveAttachments;
2342                 };
2343
2344                 const VkRenderPassCreateInfo renderPassParams =
2345                 {
2346                         VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,                      // VkStructureType                                      sType;
2347                         DE_NULL,                                                                                        // const void*                                          pNext;
2348                         0u,                                                                                                     // VkRenderPassCreateFlags                      flags;
2349                         1u,                                                                                                     // deUint32                                                     attachmentCount;
2350                         attachments,                                                                            // const VkAttachmentDescription*       pAttachments;
2351                         1u,                                                                                                     // deUint32                                                     subpassCount;
2352                         &subpassDescription,                                                            // const VkSubpassDescription*          pSubpasses;
2353                         0u,                                                                                                     // deUint32                                                     dependencyCount;
2354                         DE_NULL                                                                                         // const VkSubpassDependency*           pDependencies;
2355                 };
2356
2357                 renderPass = createRenderPass(vk, vkDevice, &renderPassParams);
2358         }
2359
2360         // Create framebuffer
2361         {
2362                 const VkFramebufferCreateInfo framebufferParams =
2363                 {
2364                         VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,                      // VkStructureType                              sType;
2365                         DE_NULL,                                                                                        // const void*                                  pNext;
2366                         0u,                                                                                                     // VkFramebufferCreateFlags             flags;
2367                         *renderPass,                                                                            // VkRenderPass                                 renderPass;
2368                         1u,                                                                                                     // deUint32                                             attachmentCount;
2369                         &*colorImageView,                                                                       // const VkAttachmentBindInfo*  pAttachments;
2370                         (deUint32)renderSize.x(),                                                       // deUint32                                             width;
2371                         (deUint32)renderSize.y(),                                                       // deUint32                                             height;
2372                         1u                                                                                                      // deUint32                                             layers;
2373                 };
2374
2375                 framebuffer = createFramebuffer(vk, vkDevice, &framebufferParams);
2376         }
2377
2378         // Create descriptors
2379         {
2380                 DescriptorPoolBuilder           descriptorPoolBuilder;
2381                 DescriptorSetLayoutBuilder      descriptorSetLayoutBuilder;
2382
2383                 descriptorSetLayoutBuilder.addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_SHADER_STAGE_ALL);
2384                 descriptorPoolBuilder.addType(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER);
2385                 descriptorSetLayoutBuilder.addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_SHADER_STAGE_ALL);
2386                 descriptorPoolBuilder.addType(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER);
2387
2388                 descriptorSetLayout     = descriptorSetLayoutBuilder.build(vk, vkDevice);
2389                 descriptorPool          = descriptorPoolBuilder.build(vk, vkDevice, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u);
2390
2391                 const VkDescriptorSetAllocateInfo allocInfo =
2392                 {
2393                         VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
2394                         DE_NULL,
2395                         *descriptorPool,
2396                         1u,
2397                         &*descriptorSetLayout
2398                 };
2399
2400                 descriptorSet = allocateDescriptorSet(vk, vkDevice, &allocInfo);
2401                 // Update descriptors
2402                 {
2403                         DescriptorSetUpdateBuilder descriptorSetUpdateBuilder;
2404                         const VkDescriptorBufferInfo outputDescriptorBufferInfo =
2405                         {
2406                                 *m_outputBuffer,                                // VkBuffer                     buffer;
2407                                 0u,                                                             // VkDeviceSize         offset;
2408                                 VK_WHOLE_SIZE                                   // VkDeviceSize         range;
2409                         };
2410
2411                         descriptorSetUpdateBuilder.writeSingle(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding((deUint32)OUTPUT_BUFFER_BINDING), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &outputDescriptorBufferInfo);
2412
2413                         VkDescriptorBufferInfo inputDescriptorBufferInfo =
2414                         {
2415                                 0,                                                      // VkBuffer                     buffer;
2416                                 0u,                                                     // VkDeviceSize         offset;
2417                                 VK_WHOLE_SIZE                           // VkDeviceSize         range;
2418                         };
2419
2420                         if (inputBufferSize > 0)
2421                         {
2422                                 inputDescriptorBufferInfo.buffer = *m_inputBuffer;
2423
2424                                 descriptorSetUpdateBuilder.writeSingle(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding((deUint32)INPUT_BUFFER_BINDING), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &inputDescriptorBufferInfo);
2425                         }
2426
2427                         descriptorSetUpdateBuilder.update(vk, vkDevice);
2428                 }
2429         }
2430
2431         // Create pipeline layout
2432         {
2433                 const VkDescriptorSetLayout                     descriptorSetLayouts[]          =
2434                 {
2435                         *descriptorSetLayout,
2436                         m_extraResourcesLayout
2437                 };
2438                 const VkPipelineLayoutCreateInfo pipelineLayoutParams =
2439                 {
2440                         VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,          // VkStructureType                              sType;
2441                         DE_NULL,                                                                                        // const void*                                  pNext;
2442                         (VkPipelineLayoutCreateFlags)0,                                         // VkPipelineLayoutCreateFlags  flags;
2443                         numDescriptorSets,                                                                      // deUint32                                             descriptorSetCount;
2444                         descriptorSetLayouts,                                                           // const VkDescriptorSetLayout* pSetLayouts;
2445                         0u,                                                                                                     // deUint32                                             pushConstantRangeCount;
2446                         DE_NULL                                                                                         // const VkPushConstantRange*   pPushConstantRanges;
2447                 };
2448
2449                 pipelineLayout = createPipelineLayout(vk, vkDevice, &pipelineLayoutParams);
2450         }
2451
2452         // Create shader modules
2453         {
2454                 vertexShaderModule              = createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("vert"), 0);
2455                 tessControlShaderModule = createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("tess_control"), 0);
2456                 tessEvalShaderModule    = createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("tess_eval"), 0);
2457                 fragmentShaderModule    = createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("frag"), 0);
2458         }
2459
2460         // Create pipeline
2461         {
2462                 const VkPipelineShaderStageCreateInfo shaderStageParams[4] =
2463                 {
2464                         {
2465                                 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,            // VkStructureType                                              sType;
2466                                 DE_NULL,                                                                                                        // const void*                                                  pNext;
2467                                 (VkPipelineShaderStageCreateFlags)0,                                            // VkPipelineShaderStageCreateFlags             flags;
2468                                 VK_SHADER_STAGE_VERTEX_BIT,                                                                     // VkShaderStageFlagBit                                 stage;
2469                                 *vertexShaderModule,                                                                            // VkShaderModule                                               shader;
2470                                 "main",                                                                                                         // const char*                                                  pName;
2471                                 DE_NULL                                                                                                         // const VkSpecializationInfo*                  pSpecializationInfo;
2472                         },
2473                         {
2474                                 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,            // VkStructureType                                              sType;
2475                                 DE_NULL,                                                                                                        // const void*                                                  pNext;
2476                                 (VkPipelineShaderStageCreateFlags)0,                                            // VkPipelineShaderStageCreateFlags             flags;
2477                                 VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT,                                       // VkShaderStageFlagBit                                 stage;
2478                                 *tessControlShaderModule,                                                                       // VkShaderModule                                               shader;
2479                                 "main",                                                                                                         // const char*                                                  pName;
2480                                 DE_NULL                                                                                                         // const VkSpecializationInfo*                  pSpecializationInfo;
2481                         },
2482                         {
2483                                 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,            // VkStructureType                                              sType;
2484                                 DE_NULL,                                                                                                        // const void*                                                  pNext;
2485                                 (VkPipelineShaderStageCreateFlags)0,                                            // VkPipelineShaderStageCreateFlags             flags;
2486                                 VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT,                            // VkShaderStageFlagBit                                 stage;
2487                                 *tessEvalShaderModule,                                                                          // VkShaderModule                                               shader;
2488                                 "main",                                                                                                         // const char*                                                  pName;
2489                                 DE_NULL                                                                                                         // const VkSpecializationInfo*                  pSpecializationInfo;
2490                         },
2491                         {
2492                                 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,            // VkStructureType                                              sType;
2493                                 DE_NULL,                                                                                                        // const void*                                                  pNext;
2494                                 (VkPipelineShaderStageCreateFlags)0,                                            // VkPipelineShaderStageCreateFlags             flags;
2495                                 VK_SHADER_STAGE_FRAGMENT_BIT,                                                           // VkShaderStageFlagBit                                 stage;
2496                                 *fragmentShaderModule,                                                                          // VkShaderModule                                               shader;
2497                                 "main",                                                                                                         // const char*                                                  pName;
2498                                 DE_NULL                                                                                                         // const VkSpecializationInfo*                  pSpecializationInfo;
2499                         }
2500                 };
2501
2502                 const VkPipelineVertexInputStateCreateInfo vertexInputStateParams =
2503                 {
2504                         VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,              // VkStructureType                                                      sType;
2505                         DE_NULL,                                                                                                                // const void*                                                          pNext;
2506                         (VkPipelineVertexInputStateCreateFlags)0,                                               // VkPipelineVertexInputStateCreateFlags        flags;
2507                         0u,                                                                                                                             // deUint32                                                                     bindingCount;
2508                         DE_NULL,                                                                                                                // const VkVertexInputBindingDescription*       pVertexBindingDescriptions;
2509                         0u,                                                                                                                             // deUint32                                                                     attributeCount;
2510                         DE_NULL,                                                                                                                // const VkVertexInputAttributeDescription*     pvertexAttributeDescriptions;
2511                 };
2512
2513                 const VkPipelineInputAssemblyStateCreateInfo inputAssemblyStateParams =
2514                 {
2515                         VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,    // VkStructureType                                              sType;
2516                         DE_NULL,                                                                                                                // const void*                                                  pNext;
2517                         (VkPipelineShaderStageCreateFlags)0,                                                    // VkPipelineShaderStageCreateFlags     flags;
2518                         VK_PRIMITIVE_TOPOLOGY_PATCH_LIST,                                                               // VkPrimitiveTopology                                  topology;
2519                         DE_FALSE                                                                                                                // VkBool32                                                             primitiveRestartEnable;
2520                 };
2521
2522                 struct VkPipelineTessellationStateCreateInfo tessellationStateParams =
2523                 {
2524                         VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO,              // VkStructureType                                                      sType;
2525                         DE_NULL,                                                                                                                // const void*                                                          pNext;
2526                         (VkPipelineTessellationStateCreateFlags)0,                                              // VkPipelineTessellationStateCreateFlags       flags;
2527                         patchControlPoints                                                                                              // uint32_t                                                                     patchControlPoints;
2528                 };
2529
2530                 const VkViewport viewport =
2531                 {
2532                         0.0f,                                           // float        originX;
2533                         0.0f,                                           // float        originY;
2534                         (float)renderSize.x(),          // float        width;
2535                         (float)renderSize.y(),          // float        height;
2536                         0.0f,                                           // float        minDepth;
2537                         1.0f                                            // float        maxDepth;
2538                 };
2539
2540                 const VkRect2D scissor =
2541                 {
2542                         {
2543                                 0u,                                             // deUint32     x;
2544                                 0u,                                             // deUint32     y;
2545                         },                                                      // VkOffset2D   offset;
2546                         {
2547                                 renderSize.x(),                 // deUint32     width;
2548                                 renderSize.y(),                 // deUint32     height;
2549                         },                                                      // VkExtent2D   extent;
2550                 };
2551
2552                 const VkPipelineViewportStateCreateInfo viewportStateParams =
2553                 {
2554                         VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO,  // VkStructureType                                              sType;
2555                         DE_NULL,                                                                                                // const void*                                                  pNext;
2556                         (VkPipelineViewportStateCreateFlags)0,                                  // VkPipelineViewPortStateCreateFlags   flags;
2557                         1u,                                                                                                             // deUint32                                                             viewportCount;
2558                         &viewport,                                                                                              // const VkViewport*                                    pViewports;
2559                         1u,                                                                                                             // deUint32                                                             scissorsCount;
2560                         &scissor                                                                                                // const VkRect2D*                                              pScissors;
2561                 };
2562
2563                 const VkPipelineRasterizationStateCreateInfo rasterStateParams =
2564                 {
2565                         VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO,             // VkStructureType                                                      sType;
2566                         DE_NULL,                                                                                                                // const void*                                                          pNext;
2567                         (VkPipelineRasterizationStateCreateFlags)0,                                             // VkPipelineRasterizationStageCreateFlags      flags;
2568                         VK_FALSE,                                                                                                               // VkBool32                                                                     depthClipEnable;
2569                         VK_FALSE,                                                                                                               // VkBool32                                                                     rasterizerDiscardEnable;
2570                         VK_POLYGON_MODE_FILL,                                                                                   // VkPolygonMode                                                        polygonMode;
2571                         VK_CULL_MODE_NONE,                                                                                              // VkCullMode                                                           cullMode;
2572                         VK_FRONT_FACE_COUNTER_CLOCKWISE,                                                                // VkFrontFace                                                          frontFace;
2573                         VK_FALSE,                                                                                                               // VkBool32                                                                     depthBiasEnable;
2574                         0.0f,                                                                                                                   // float                                                                        depthBias;
2575                         0.0f,                                                                                                                   // float                                                                        depthBiasClamp;
2576                         0.0f,                                                                                                                   // float                                                                        slopeScaledDepthBias;
2577                         1.0f                                                                                                                    // float                                                                        lineWidth;
2578                 };
2579
2580                 const VkPipelineMultisampleStateCreateInfo multisampleStateParams =
2581                 {
2582                         VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,               // VkStructureType                                                      sType;
2583                         DE_NULL,                                                                                                                // const void*                                                          pNext;
2584                         0u,                                                                                                                             // VkPipelineMultisampleStateCreateFlags        flags;
2585                         VK_SAMPLE_COUNT_1_BIT,                                                                                  // VkSampleCountFlagBits                                        rasterizationSamples;
2586                         VK_FALSE,                                                                                                               // VkBool32                                                                     sampleShadingEnable;
2587                         0.0f,                                                                                                                   // float                                                                        minSampleShading;
2588                         DE_NULL,                                                                                                                // const VkSampleMask*                                          pSampleMask;
2589                         VK_FALSE,                                                                                                               // VkBool32                                                                     alphaToCoverageEnable;
2590                         VK_FALSE                                                                                                                // VkBool32                                                                     alphaToOneEnable;
2591                 };
2592
2593                 const VkPipelineColorBlendAttachmentState colorBlendAttachmentState =
2594                 {
2595                         VK_FALSE,                                               // VkBool32                                     blendEnable;
2596                         VK_BLEND_FACTOR_ONE,                    // VkBlendFactor                        srcBlendColor;
2597                         VK_BLEND_FACTOR_ZERO,                   // VkBlendFactor                        destBlendColor;
2598                         VK_BLEND_OP_ADD,                                // VkBlendOp                            blendOpColor;
2599                         VK_BLEND_FACTOR_ONE,                    // VkBlendFactor                        srcBlendAlpha;
2600                         VK_BLEND_FACTOR_ZERO,                   // VkBlendFactor                        destBlendAlpha;
2601                         VK_BLEND_OP_ADD,                                // VkBlendOp                            blendOpAlpha;
2602                         (VK_COLOR_COMPONENT_R_BIT |
2603                          VK_COLOR_COMPONENT_G_BIT |
2604                          VK_COLOR_COMPONENT_B_BIT |
2605                          VK_COLOR_COMPONENT_A_BIT)              // VkColorComponentFlags        colorWriteMask;
2606                 };
2607
2608                 const VkPipelineColorBlendStateCreateInfo colorBlendStateParams =
2609                 {
2610                         VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,       // VkStructureType                                                              sType;
2611                         DE_NULL,                                                                                                        // const void*                                                                  pNext;
2612                         (VkPipelineColorBlendStateCreateFlags)0,                                        // VkPipelineColorBlendStateCreateFlags                 flags
2613                         VK_FALSE,                                                                                                       // VkBool32                                                                             logicOpEnable;
2614                         VK_LOGIC_OP_COPY,                                                                                       // VkLogicOp                                                                    logicOp;
2615                         1u,                                                                                                                     // deUint32                                                                             attachmentCount;
2616                         &colorBlendAttachmentState,                                                                     // const VkPipelineColorBlendAttachmentState*   pAttachments;
2617                         { 0.0f, 0.0f, 0.0f, 0.0f }                                                                      // float                                                                                blendConst[4];
2618                 };
2619
2620                 const VkGraphicsPipelineCreateInfo graphicsPipelineParams =
2621                 {
2622                         VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,        // VkStructureType                                                                      sType;
2623                         DE_NULL,                                                                                        // const void*                                                                          pNext;
2624                         0u,                                                                                                     // VkPipelineCreateFlags                                                        flags;
2625                         4u,                                                                                                     // deUint32                                                                                     stageCount;
2626                         shaderStageParams,                                                                      // const VkPipelineShaderStageCreateInfo*                       pStages;
2627                         &vertexInputStateParams,                                                        // const VkPipelineVertexInputStateCreateInfo*          pVertexInputState;
2628                         &inputAssemblyStateParams,                                                      // const VkPipelineInputAssemblyStateCreateInfo*        pInputAssemblyState;
2629                         &tessellationStateParams,                                                       // const VkPipelineTessellationStateCreateInfo*         pTessellationState;
2630                         &viewportStateParams,                                                           // const VkPipelineViewportStateCreateInfo*                     pViewportState;
2631                         &rasterStateParams,                                                                     // const VkPipelineRasterStateCreateInfo*                       pRasterState;
2632                         &multisampleStateParams,                                                        // const VkPipelineMultisampleStateCreateInfo*          pMultisampleState;
2633                         DE_NULL,                                                                                        // const VkPipelineDepthStencilStateCreateInfo*         pDepthStencilState;
2634                         &colorBlendStateParams,                                                         // const VkPipelineColorBlendStateCreateInfo*           pColorBlendState;
2635                         (const VkPipelineDynamicStateCreateInfo*)DE_NULL,       // const VkPipelineDynamicStateCreateInfo*                      pDynamicState;
2636                         *pipelineLayout,                                                                        // VkPipelineLayout                                                                     layout;
2637                         *renderPass,                                                                            // VkRenderPass                                                                         renderPass;
2638                         0u,                                                                                                     // deUint32                                                                                     subpass;
2639                         0u,                                                                                                     // VkPipeline                                                                           basePipelineHandle;
2640                         0u                                                                                                      // deInt32                                                                                      basePipelineIndex;
2641                 };
2642
2643                 graphicsPipeline = createGraphicsPipeline(vk, vkDevice, DE_NULL, &graphicsPipelineParams);
2644         }
2645
2646         // Create command pool
2647         {
2648                 const VkCommandPoolCreateInfo cmdPoolParams =
2649                 {
2650                         VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,             // VkStructureType              sType;
2651                         DE_NULL,                                                                                // const void*                  pNext;
2652                         VK_COMMAND_POOL_CREATE_TRANSIENT_BIT,                   // VkCmdPoolCreateFlags flags;
2653                         queueFamilyIndex,                                                               // deUint32                             queueFamilyIndex;
2654                 };
2655
2656                 cmdPool = createCommandPool(vk, vkDevice, &cmdPoolParams);
2657         }
2658
2659         // Create command buffer
2660         {
2661                 const VkCommandBufferAllocateInfo cmdBufferParams =
2662                 {
2663                         VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, // VkStructureType                      sType;
2664                         DE_NULL,                                                                                // const void*                          pNext;
2665                         *cmdPool,                                                                               // VkCmdPool                            cmdPool;
2666                         VK_COMMAND_BUFFER_LEVEL_PRIMARY,                                // VkCmdBufferLevel                     level;
2667                         1u                                                                                              // uint32_t                                     bufferCount;
2668                 };
2669
2670                 const VkCommandBufferBeginInfo cmdBufferBeginInfo =
2671                 {
2672                         VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,    // VkStructureType                                      sType;
2673                         DE_NULL,                                                                                // const void*                                          pNext;
2674                         0u,                                                                                             // VkCmdBufferOptimizeFlags                     flags;
2675                         (const VkCommandBufferInheritanceInfo*)DE_NULL,
2676                 };
2677
2678                 const VkClearValue clearValues[1] =
2679                 {
2680                         getDefaultClearColor()
2681                 };
2682
2683                 const VkRenderPassBeginInfo renderPassBeginInfo =
2684                 {
2685                         VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,                               // VkStructureType              sType;
2686                         DE_NULL,                                                                                                // const void*                  pNext;
2687                         *renderPass,                                                                                    // VkRenderPass                 renderPass;
2688                         *framebuffer,                                                                                   // VkFramebuffer                framebuffer;
2689                         { { 0, 0 }, { renderSize.x(), renderSize.y() } },               // VkRect2D                             renderArea;
2690                         1,                                                                                                              // deUint32                             attachmentCount;
2691                         clearValues                                                                                             // const VkClearValue*  pClearValues;
2692                 };
2693
2694                 cmdBuffer = allocateCommandBuffer(vk, vkDevice, &cmdBufferParams);
2695
2696                 VK_CHECK(vk.beginCommandBuffer(*cmdBuffer, &cmdBufferBeginInfo));
2697
2698                 vk.cmdBeginRenderPass(*cmdBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
2699
2700                 vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *graphicsPipeline);
2701
2702                 {
2703                         const VkDescriptorSet   descriptorSets[]        = { *descriptorSet, extraResources };
2704                         vk.cmdBindDescriptorSets(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipelineLayout, 0u, numDescriptorSets, descriptorSets, 0u, DE_NULL);
2705                 }
2706
2707                 vk.cmdDraw(*cmdBuffer, vertexCount, 1, 0, 0);
2708
2709                 vk.cmdEndRenderPass(*cmdBuffer);
2710                 VK_CHECK(vk.endCommandBuffer(*cmdBuffer));
2711         }
2712
2713         // Create fence
2714         {
2715                 const VkFenceCreateInfo fenceParams =
2716                 {
2717                         VK_STRUCTURE_TYPE_FENCE_CREATE_INFO,    // VkStructureType              sType;
2718                         DE_NULL,                                                                // const void*                  pNext;
2719                         0u                                                                              // VkFenceCreateFlags   flags;
2720                 };
2721                 fence = createFence(vk, vkDevice, &fenceParams);
2722         }
2723
2724         // Execute Draw
2725         {
2726                 VK_CHECK(vk.resetFences(vkDevice, 1, &fence.get()));
2727                 const VkSubmitInfo submitInfo =
2728                 {
2729                         VK_STRUCTURE_TYPE_SUBMIT_INFO,
2730                         DE_NULL,
2731                         0u,
2732                         (const VkSemaphore*)0,
2733                         (const VkPipelineStageFlags*)DE_NULL,
2734                         1u,
2735                         &cmdBuffer.get(),
2736                         0u,
2737                         (const VkSemaphore*)0,
2738                 };
2739                 VK_CHECK(vk.queueSubmit(queue, 1, &submitInfo, *fence));
2740                 VK_CHECK(vk.waitForFences(vkDevice, 1, &fence.get(), true, ~(0ull) /* infinity*/));
2741         }
2742 }
2743
2744 // TessControlExecutor
2745
2746 class TessControlExecutor : public TessellationExecutor
2747 {
2748 public:
2749                                                 TessControlExecutor                     (Context& context, const ShaderSpec& shaderSpec, VkDescriptorSetLayout extraResourcesLayout);
2750         virtual                         ~TessControlExecutor            (void);
2751
2752         static void                     generateSources                         (const ShaderSpec& shaderSpec, SourceCollections& programCollection);
2753
2754         virtual void            execute                                         (int numValues, const void* const* inputs, void* const* outputs, VkDescriptorSet extraResources);
2755
2756 protected:
2757         static std::string      generateTessControlShader       (const ShaderSpec& shaderSpec);
2758 };
2759
2760 TessControlExecutor::TessControlExecutor (Context& context, const ShaderSpec& shaderSpec, VkDescriptorSetLayout extraResourcesLayout)
2761         : TessellationExecutor(context, shaderSpec, extraResourcesLayout)
2762 {
2763 }
2764
2765 TessControlExecutor::~TessControlExecutor (void)
2766 {
2767 }
2768
2769 std::string TessControlExecutor::generateTessControlShader (const ShaderSpec& shaderSpec)
2770 {
2771         std::ostringstream src;
2772         src <<  "#version 310 es\n"
2773                         "#extension GL_EXT_tessellation_shader : require\n\n";
2774
2775         if (!shaderSpec.globalDeclarations.empty())
2776                 src << shaderSpec.globalDeclarations << "\n";
2777
2778         src << "\nlayout(vertices = 1) out;\n\n";
2779
2780         declareBufferBlocks(src, shaderSpec);
2781
2782         src << "void main (void)\n{\n";
2783
2784         for (int ndx = 0; ndx < 2; ndx++)
2785                 src << "\tgl_TessLevelInner[" << ndx << "] = 1.0;\n";
2786
2787         for (int ndx = 0; ndx < 4; ndx++)
2788                 src << "\tgl_TessLevelOuter[" << ndx << "] = 1.0;\n";
2789
2790         src << "\n"
2791                 << "\thighp uint invocationId = uint(gl_PrimitiveID);\n";
2792
2793         generateExecBufferIo(src, shaderSpec, "invocationId");
2794
2795         src << "}\n";
2796
2797         return src.str();
2798 }
2799
2800 static std::string generateEmptyTessEvalShader ()
2801 {
2802         std::ostringstream src;
2803
2804         src <<  "#version 310 es\n"
2805                         "#extension GL_EXT_tessellation_shader : require\n\n";
2806
2807         src << "layout(triangles, ccw) in;\n";
2808
2809         src << "\nvoid main (void)\n{\n"
2810                 << "\tgl_Position = vec4(gl_TessCoord.xy, 0.0, 1.0);\n"
2811                 << "}\n";
2812
2813         return src.str();
2814 }
2815
2816 void TessControlExecutor::generateSources (const ShaderSpec& shaderSpec, SourceCollections& programCollection)
2817 {
2818         programCollection.glslSources.add("vert") << glu::VertexSource(generateVertexShaderForTess());
2819         programCollection.glslSources.add("tess_control") << glu::TessellationControlSource(generateTessControlShader(shaderSpec));
2820         programCollection.glslSources.add("tess_eval") << glu::TessellationEvaluationSource(generateEmptyTessEvalShader());
2821         programCollection.glslSources.add("frag") << glu::FragmentSource(generateEmptyFragmentSource());
2822 }
2823
2824 void TessControlExecutor::execute (int numValues, const void* const* inputs, void* const* outputs, VkDescriptorSet extraResources)
2825 {
2826         const deUint32  patchSize       = 3;
2827
2828         initBuffers(numValues);
2829
2830         // Setup input buffer & copy data
2831         uploadInputBuffer(inputs, numValues);
2832
2833         renderTess(numValues, patchSize * numValues, patchSize, extraResources);
2834
2835         // Read back data
2836         readOutputBuffer(outputs, numValues);
2837 }
2838
2839 // TessEvaluationExecutor
2840
2841 class TessEvaluationExecutor : public TessellationExecutor
2842 {
2843 public:
2844                                                 TessEvaluationExecutor  (Context& context, const ShaderSpec& shaderSpec, VkDescriptorSetLayout extraResourcesLayout);
2845         virtual                         ~TessEvaluationExecutor (void);
2846
2847         static void                     generateSources                 (const ShaderSpec& shaderSpec, SourceCollections& programCollection);
2848
2849         virtual void            execute                                 (int numValues, const void* const* inputs, void* const* outputs, VkDescriptorSet extraResources);
2850
2851 protected:
2852         static std::string      generateTessEvalShader  (const ShaderSpec& shaderSpec);
2853 };
2854
2855 TessEvaluationExecutor::TessEvaluationExecutor (Context& context, const ShaderSpec& shaderSpec, VkDescriptorSetLayout extraResourcesLayout)
2856         : TessellationExecutor (context, shaderSpec, extraResourcesLayout)
2857 {
2858 }
2859
2860 TessEvaluationExecutor::~TessEvaluationExecutor (void)
2861 {
2862 }
2863
2864 static std::string generatePassthroughTessControlShader (void)
2865 {
2866         std::ostringstream src;
2867
2868         src <<  "#version 310 es\n"
2869                         "#extension GL_EXT_tessellation_shader : require\n\n";
2870
2871         src << "layout(vertices = 1) out;\n\n";
2872
2873         src << "void main (void)\n{\n";
2874
2875         for (int ndx = 0; ndx < 2; ndx++)
2876                 src << "\tgl_TessLevelInner[" << ndx << "] = 1.0;\n";
2877
2878         for (int ndx = 0; ndx < 4; ndx++)
2879                 src << "\tgl_TessLevelOuter[" << ndx << "] = 1.0;\n";
2880
2881         src << "}\n";
2882
2883         return src.str();
2884 }
2885
2886 std::string TessEvaluationExecutor::generateTessEvalShader (const ShaderSpec& shaderSpec)
2887 {
2888         std::ostringstream src;
2889
2890         src <<  "#version 310 es\n"
2891                         "#extension GL_EXT_tessellation_shader : require\n\n";
2892
2893         if (!shaderSpec.globalDeclarations.empty())
2894                 src << shaderSpec.globalDeclarations << "\n";
2895
2896         src << "\n";
2897
2898         src << "layout(isolines, equal_spacing) in;\n\n";
2899
2900         declareBufferBlocks(src, shaderSpec);
2901
2902         src << "void main (void)\n{\n"
2903                 << "\tgl_Position = vec4(gl_TessCoord.x, 0.0, 0.0, 1.0);\n"
2904                 << "\thighp uint invocationId = uint(gl_PrimitiveID)*2u + (gl_TessCoord.x > 0.5 ? 1u : 0u);\n";
2905
2906         generateExecBufferIo(src, shaderSpec, "invocationId");
2907
2908         src     << "}\n";
2909
2910         return src.str();
2911 }
2912
2913 void TessEvaluationExecutor::generateSources (const ShaderSpec& shaderSpec, SourceCollections& programCollection)
2914 {
2915         programCollection.glslSources.add("vert") << glu::VertexSource(generateVertexShaderForTess());
2916         programCollection.glslSources.add("tess_control") << glu::TessellationControlSource(generatePassthroughTessControlShader());
2917         programCollection.glslSources.add("tess_eval") << glu::TessellationEvaluationSource(generateTessEvalShader(shaderSpec));
2918         programCollection.glslSources.add("frag") << glu::FragmentSource(generateEmptyFragmentSource());
2919 }
2920
2921 void TessEvaluationExecutor::execute (int numValues, const void* const* inputs, void* const* outputs, VkDescriptorSet extraResources)
2922 {
2923         const int       patchSize               = 2;
2924         const int       alignedValues   = deAlign32(numValues, patchSize);
2925
2926         // Initialize buffers with aligned value count to make room for padding
2927         initBuffers(alignedValues);
2928
2929         // Setup input buffer & copy data
2930         uploadInputBuffer(inputs, numValues);
2931
2932         renderTess((deUint32)alignedValues, (deUint32)alignedValues, (deUint32)patchSize, extraResources);
2933
2934         // Read back data
2935         readOutputBuffer(outputs, numValues);
2936 }
2937
2938 } // anonymous
2939
2940 // ShaderExecutor
2941
2942 ShaderExecutor::~ShaderExecutor (void)
2943 {
2944 }
2945
2946 // Utilities
2947
2948 void generateSources (glu::ShaderType shaderType, const ShaderSpec& shaderSpec, vk::SourceCollections& dst)
2949 {
2950         switch (shaderType)
2951         {
2952                 case glu::SHADERTYPE_VERTEX:                                    VertexShaderExecutor::generateSources   (shaderSpec, dst);      break;
2953                 case glu::SHADERTYPE_TESSELLATION_CONTROL:              TessControlExecutor::generateSources    (shaderSpec, dst);      break;
2954                 case glu::SHADERTYPE_TESSELLATION_EVALUATION:   TessEvaluationExecutor::generateSources (shaderSpec, dst);      break;
2955                 case glu::SHADERTYPE_GEOMETRY:                                  GeometryShaderExecutor::generateSources (shaderSpec, dst);      break;
2956                 case glu::SHADERTYPE_FRAGMENT:                                  FragmentShaderExecutor::generateSources (shaderSpec, dst);      break;
2957                 case glu::SHADERTYPE_COMPUTE:                                   ComputeShaderExecutor::generateSources  (shaderSpec, dst);      break;
2958                 default:
2959                         TCU_THROW(InternalError, "Unsupported shader type");
2960         }
2961 }
2962
2963 ShaderExecutor* createExecutor (Context& context, glu::ShaderType shaderType, const ShaderSpec& shaderSpec, VkDescriptorSetLayout extraResourcesLayout)
2964 {
2965         switch (shaderType)
2966         {
2967                 case glu::SHADERTYPE_VERTEX:                                    return new VertexShaderExecutor         (context, shaderSpec, extraResourcesLayout);
2968                 case glu::SHADERTYPE_TESSELLATION_CONTROL:              return new TessControlExecutor          (context, shaderSpec, extraResourcesLayout);
2969                 case glu::SHADERTYPE_TESSELLATION_EVALUATION:   return new TessEvaluationExecutor       (context, shaderSpec, extraResourcesLayout);
2970                 case glu::SHADERTYPE_GEOMETRY:                                  return new GeometryShaderExecutor       (context, shaderSpec, extraResourcesLayout);
2971                 case glu::SHADERTYPE_FRAGMENT:                                  return new FragmentShaderExecutor       (context, shaderSpec, extraResourcesLayout);
2972                 case glu::SHADERTYPE_COMPUTE:                                   return new ComputeShaderExecutor        (context, shaderSpec, extraResourcesLayout);
2973                 default:
2974                         TCU_THROW(InternalError, "Unsupported shader type");
2975         }
2976 }
2977
2978 } // shaderexecutor
2979 } // vkt