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