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