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