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