Add tests for textureSamples, QueryLevels, and QueryLod
[platform/upstream/VK-GL-CTS.git] / external / vulkancts / modules / vulkan / shaderrender / vktShaderRender.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 ShaderRenderCase
24  *//*--------------------------------------------------------------------*/
25
26 #include "vktShaderRender.hpp"
27
28 #include "tcuImageCompare.hpp"
29 #include "tcuImageIO.hpp"
30 #include "tcuTestLog.hpp"
31 #include "tcuTextureUtil.hpp"
32 #include "tcuSurface.hpp"
33 #include "tcuVector.hpp"
34
35 #include "deFilePath.hpp"
36 #include "deMath.h"
37 #include "deUniquePtr.hpp"
38
39 #include "vkDeviceUtil.hpp"
40 #include "vkImageUtil.hpp"
41 #include "vkPlatform.hpp"
42 #include "vkQueryUtil.hpp"
43 #include "vkRef.hpp"
44 #include "vkRefUtil.hpp"
45 #include "vkStrUtil.hpp"
46 #include "vkTypeUtil.hpp"
47
48 #include <vector>
49 #include <string>
50
51 namespace vkt
52 {
53 namespace sr
54 {
55
56 using namespace vk;
57
58 namespace
59 {
60
61 static const int                GRID_SIZE                       = 64;
62 static const deUint32   MAX_RENDER_WIDTH        = 128;
63 static const deUint32   MAX_RENDER_HEIGHT       = 128;
64 static const tcu::Vec4  DEFAULT_CLEAR_COLOR     = tcu::Vec4(0.125f, 0.25f, 0.5f, 1.0f);
65
66 static VkImageViewType textureTypeToImageViewType (TextureBinding::Type type)
67 {
68         switch (type)
69         {
70                 case TextureBinding::TYPE_1D:                   return VK_IMAGE_VIEW_TYPE_1D;
71                 case TextureBinding::TYPE_2D:                   return VK_IMAGE_VIEW_TYPE_2D;
72                 case TextureBinding::TYPE_3D:                   return VK_IMAGE_VIEW_TYPE_3D;
73                 case TextureBinding::TYPE_CUBE_MAP:             return VK_IMAGE_VIEW_TYPE_CUBE;
74                 case TextureBinding::TYPE_1D_ARRAY:             return VK_IMAGE_VIEW_TYPE_1D_ARRAY;
75                 case TextureBinding::TYPE_2D_ARRAY:             return VK_IMAGE_VIEW_TYPE_2D_ARRAY;
76                 case TextureBinding::TYPE_CUBE_ARRAY:   return VK_IMAGE_VIEW_TYPE_CUBE_ARRAY;
77
78                 default:
79                         DE_FATAL("Impossible");
80                         return (VkImageViewType)0;
81         }
82 }
83
84 static VkImageType viewTypeToImageType (VkImageViewType type)
85 {
86         switch (type)
87         {
88                 case VK_IMAGE_VIEW_TYPE_1D:
89                 case VK_IMAGE_VIEW_TYPE_1D_ARRAY:               return VK_IMAGE_TYPE_1D;
90                 case VK_IMAGE_VIEW_TYPE_2D:
91                 case VK_IMAGE_VIEW_TYPE_2D_ARRAY:               return VK_IMAGE_TYPE_2D;
92                 case VK_IMAGE_VIEW_TYPE_3D:                             return VK_IMAGE_TYPE_3D;
93                 case VK_IMAGE_VIEW_TYPE_CUBE:
94                 case VK_IMAGE_VIEW_TYPE_CUBE_ARRAY:             return VK_IMAGE_TYPE_2D;
95
96                 default:
97                         DE_FATAL("Impossible");
98                         return (VkImageType)0;
99         }
100 }
101
102 /*! Gets the next multiple of a given divisor */
103 static deUint32 getNextMultiple (deUint32 divisor, deUint32 value)
104 {
105         if (value % divisor == 0)
106         {
107                 return value;
108         }
109         return value + divisor - (value % divisor);
110 }
111
112 /*! Gets the next value that is multiple of all given divisors */
113 static deUint32 getNextMultiple (const std::vector<deUint32>& divisors, deUint32 value)
114 {
115         deUint32        nextMultiple            = value;
116         bool            nextMultipleFound       = false;
117
118         while (true)
119         {
120                 nextMultipleFound = true;
121
122                 for (size_t divNdx = 0; divNdx < divisors.size(); divNdx++)
123                         nextMultipleFound = nextMultipleFound && (nextMultiple % divisors[divNdx] == 0);
124
125                 if (nextMultipleFound)
126                         break;
127
128                 DE_ASSERT(nextMultiple < ~((deUint32)0u));
129                 nextMultiple = getNextMultiple(divisors[0], nextMultiple + 1);
130         }
131
132         return nextMultiple;
133 }
134
135 } // anonymous
136
137 // QuadGrid.
138
139 class QuadGrid
140 {
141 public:
142                                                                                         QuadGrid                                (int                                                                    gridSize,
143                                                                                                                                          int                                                                    screenWidth,
144                                                                                                                                          int                                                                    screenHeight,
145                                                                                                                                          const tcu::Vec4&                                               constCoords,
146                                                                                                                                          const std::vector<tcu::Mat4>&                  userAttribTransforms,
147                                                                                                                                          const std::vector<TextureBindingSp>&   textures);
148                                                                                         ~QuadGrid                               (void);
149
150         int                                                                             getGridSize                             (void) const { return m_gridSize; }
151         int                                                                             getNumVertices                  (void) const { return m_numVertices; }
152         int                                                                             getNumTriangles                 (void) const { return m_numTriangles; }
153         const tcu::Vec4&                                                getConstCoords                  (void) const { return m_constCoords; }
154         const std::vector<tcu::Mat4>                    getUserAttribTransforms (void) const { return m_userAttribTransforms; }
155         const std::vector<TextureBindingSp>&    getTextures                             (void) const { return m_textures; }
156
157         const tcu::Vec4*                                                getPositions                    (void) const { return &m_positions[0]; }
158         const float*                                                    getAttribOne                    (void) const { return &m_attribOne[0]; }
159         const tcu::Vec4*                                                getCoords                               (void) const { return &m_coords[0]; }
160         const tcu::Vec4*                                                getUnitCoords                   (void) const { return &m_unitCoords[0]; }
161
162         const tcu::Vec4*                                                getUserAttrib                   (int attribNdx) const { return &m_userAttribs[attribNdx][0]; }
163         const deUint16*                                                 getIndices                              (void) const { return &m_indices[0]; }
164
165         tcu::Vec4                                                               getCoords                               (float sx, float sy) const;
166         tcu::Vec4                                                               getUnitCoords                   (float sx, float sy) const;
167
168         int                                                                             getNumUserAttribs               (void) const { return (int)m_userAttribTransforms.size(); }
169         tcu::Vec4                                                               getUserAttrib                   (int attribNdx, float sx, float sy) const;
170
171 private:
172         const int                                                               m_gridSize;
173         const int                                                               m_numVertices;
174         const int                                                               m_numTriangles;
175         const tcu::Vec4                                                 m_constCoords;
176         const std::vector<tcu::Mat4>                    m_userAttribTransforms;
177
178         const std::vector<TextureBindingSp>&    m_textures;
179
180         std::vector<tcu::Vec4>                                  m_screenPos;
181         std::vector<tcu::Vec4>                                  m_positions;
182         std::vector<tcu::Vec4>                                  m_coords;               //!< Near-unit coordinates, roughly [-2.0 .. 2.0].
183         std::vector<tcu::Vec4>                                  m_unitCoords;   //!< Positive-only coordinates [0.0 .. 1.5].
184         std::vector<float>                                              m_attribOne;
185         std::vector<tcu::Vec4>                                  m_userAttribs[ShaderEvalContext::MAX_TEXTURES];
186         std::vector<deUint16>                                   m_indices;
187 };
188
189 QuadGrid::QuadGrid (int                                                                         gridSize,
190                                         int                                                                             width,
191                                         int                                                                             height,
192                                         const tcu::Vec4&                                                constCoords,
193                                         const std::vector<tcu::Mat4>&                   userAttribTransforms,
194                                         const std::vector<TextureBindingSp>&    textures)
195         : m_gridSize                            (gridSize)
196         , m_numVertices                         ((gridSize + 1) * (gridSize + 1))
197         , m_numTriangles                        (gridSize * gridSize * 2)
198         , m_constCoords                         (constCoords)
199         , m_userAttribTransforms        (userAttribTransforms)
200         , m_textures                            (textures)
201 {
202         const tcu::Vec4 viewportScale   ((float)width, (float)height, 0.0f, 0.0f);
203
204         // Compute vertices.
205         m_screenPos.resize(m_numVertices);
206         m_positions.resize(m_numVertices);
207         m_coords.resize(m_numVertices);
208         m_unitCoords.resize(m_numVertices);
209         m_attribOne.resize(m_numVertices);
210
211         // User attributes.
212         for (int attrNdx = 0; attrNdx < DE_LENGTH_OF_ARRAY(m_userAttribs); attrNdx++)
213                 m_userAttribs[attrNdx].resize(m_numVertices);
214
215         for (int y = 0; y < gridSize+1; y++)
216         for (int x = 0; x < gridSize+1; x++)
217         {
218                 float           sx                      = (float)x / (float)gridSize;
219                 float           sy                      = (float)y / (float)gridSize;
220                 float           fx                      = 2.0f * sx - 1.0f;
221                 float           fy                      = 2.0f * sy - 1.0f;
222                 int                     vtxNdx          = ((y * (gridSize+1)) + x);
223
224                 m_positions[vtxNdx]             = tcu::Vec4(fx, fy, 0.0f, 1.0f);
225                 m_coords[vtxNdx]                = getCoords(sx, sy);
226                 m_unitCoords[vtxNdx]    = getUnitCoords(sx, sy);
227                 m_attribOne[vtxNdx]             = 1.0f;
228
229                 m_screenPos[vtxNdx]             = tcu::Vec4(sx, sy, 0.0f, 1.0f) * viewportScale;
230
231                 for (int attribNdx = 0; attribNdx < getNumUserAttribs(); attribNdx++)
232                         m_userAttribs[attribNdx][vtxNdx] = getUserAttrib(attribNdx, sx, sy);
233         }
234
235         // Compute indices.
236         m_indices.resize(3 * m_numTriangles);
237         for (int y = 0; y < gridSize; y++)
238         for (int x = 0; x < gridSize; x++)
239         {
240                 int stride                              = gridSize + 1;
241                 int v00                                 = (y * stride) + x;
242                 int v01                                 = (y * stride) + x + 1;
243                 int v10                                 = ((y+1) * stride) + x;
244                 int v11                                 = ((y+1) * stride) + x + 1;
245
246                 int baseNdx                             = ((y * gridSize) + x) * 6;
247                 m_indices[baseNdx + 0]  = (deUint16)v10;
248                 m_indices[baseNdx + 1]  = (deUint16)v00;
249                 m_indices[baseNdx + 2]  = (deUint16)v01;
250
251                 m_indices[baseNdx + 3]  = (deUint16)v10;
252                 m_indices[baseNdx + 4]  = (deUint16)v01;
253                 m_indices[baseNdx + 5]  = (deUint16)v11;
254         }
255 }
256
257 QuadGrid::~QuadGrid (void)
258 {
259 }
260
261 inline tcu::Vec4 QuadGrid::getCoords (float sx, float sy) const
262 {
263         const float fx = 2.0f * sx - 1.0f;
264         const float fy = 2.0f * sy - 1.0f;
265         return tcu::Vec4(fx, fy, -fx + 0.33f*fy, -0.275f*fx - fy);
266 }
267
268 inline tcu::Vec4 QuadGrid::getUnitCoords (float sx, float sy) const
269 {
270         return tcu::Vec4(sx, sy, 0.33f*sx + 0.5f*sy, 0.5f*sx + 0.25f*sy);
271 }
272
273 inline tcu::Vec4 QuadGrid::getUserAttrib (int attribNdx, float sx, float sy) const
274 {
275         // homogeneous normalized screen-space coordinates
276         return m_userAttribTransforms[attribNdx] * tcu::Vec4(sx, sy, 0.0f, 1.0f);
277 }
278
279 // TextureBinding
280
281 TextureBinding::TextureBinding (const tcu::Archive&     archive,
282                                                                 const char*                     filename,
283                                                                 const Type                      type,
284                                                                 const tcu::Sampler&     sampler)
285         : m_type        (type)
286         , m_sampler     (sampler)
287 {
288         switch(m_type)
289         {
290                 case TYPE_2D: m_binding.tex2D = loadTexture2D(archive, filename).release(); break;
291                 default:
292                         DE_FATAL("Unsupported texture type");
293         }
294 }
295
296 TextureBinding::TextureBinding (const tcu::Texture1D* tex1D, const tcu::Sampler& sampler)
297         : m_type        (TYPE_1D)
298         , m_sampler     (sampler)
299 {
300         m_binding.tex1D = tex1D;
301 }
302
303 TextureBinding::TextureBinding (const tcu::Texture2D* tex2D, const tcu::Sampler& sampler)
304         : m_type        (TYPE_2D)
305         , m_sampler     (sampler)
306 {
307         m_binding.tex2D = tex2D;
308 }
309
310 TextureBinding::TextureBinding (const tcu::Texture3D* tex3D, const tcu::Sampler& sampler)
311         : m_type        (TYPE_3D)
312         , m_sampler     (sampler)
313 {
314         m_binding.tex3D = tex3D;
315 }
316
317 TextureBinding::TextureBinding (const tcu::TextureCube* texCube, const tcu::Sampler& sampler)
318         : m_type        (TYPE_CUBE_MAP)
319         , m_sampler     (sampler)
320 {
321         m_binding.texCube = texCube;
322 }
323
324 TextureBinding::TextureBinding (const tcu::Texture1DArray* tex1DArray, const tcu::Sampler& sampler)
325         : m_type        (TYPE_1D_ARRAY)
326         , m_sampler     (sampler)
327 {
328         m_binding.tex1DArray = tex1DArray;
329 }
330
331 TextureBinding::TextureBinding (const tcu::Texture2DArray* tex2DArray, const tcu::Sampler& sampler)
332         : m_type        (TYPE_2D_ARRAY)
333         , m_sampler     (sampler)
334 {
335         m_binding.tex2DArray = tex2DArray;
336 }
337
338 TextureBinding::TextureBinding (const tcu::TextureCubeArray* texCubeArray, const tcu::Sampler& sampler)
339         : m_type        (TYPE_CUBE_ARRAY)
340         , m_sampler     (sampler)
341 {
342         m_binding.texCubeArray = texCubeArray;
343 }
344
345 TextureBinding::~TextureBinding (void)
346 {
347         switch(m_type)
348         {
349                 case TYPE_1D:                   delete m_binding.tex1D;                 break;
350                 case TYPE_2D:                   delete m_binding.tex2D;                 break;
351                 case TYPE_3D:                   delete m_binding.tex3D;                 break;
352                 case TYPE_CUBE_MAP:             delete m_binding.texCube;               break;
353                 case TYPE_1D_ARRAY:             delete m_binding.tex1DArray;    break;
354                 case TYPE_2D_ARRAY:             delete m_binding.tex2DArray;    break;
355                 case TYPE_CUBE_ARRAY:   delete m_binding.texCubeArray;  break;
356                 default:                                                                                                break;
357         }
358 }
359
360 de::MovePtr<tcu::Texture2D> TextureBinding::loadTexture2D (const tcu::Archive& archive, const char* filename)
361 {
362         tcu::TextureLevel level;
363         tcu::ImageIO::loadImage(level, archive, filename);
364
365         TCU_CHECK_INTERNAL(level.getFormat() == tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8) ||
366                                            level.getFormat() == tcu::TextureFormat(tcu::TextureFormat::RGB, tcu::TextureFormat::UNORM_INT8));
367
368         // \todo [2015-10-08 elecro] for some reason we get better when using RGBA texture even in RGB case, this needs to be investigated
369         de::MovePtr<tcu::Texture2D> texture(new tcu::Texture2D(tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8), level.getWidth(), level.getHeight()));
370
371         // Fill level 0.
372         texture->allocLevel(0);
373         tcu::copy(texture->getLevel(0), level.getAccess());
374
375         return texture;
376 }
377
378 // ShaderEvalContext.
379
380 ShaderEvalContext::ShaderEvalContext (const QuadGrid& quadGrid)
381         : constCoords   (quadGrid.getConstCoords())
382         , isDiscarded   (false)
383         , m_quadGrid    (quadGrid)
384 {
385         const std::vector<TextureBindingSp>& bindings = m_quadGrid.getTextures();
386         DE_ASSERT((int)bindings.size() <= MAX_TEXTURES);
387
388         // Fill in texture array.
389         for (int ndx = 0; ndx < (int)bindings.size(); ndx++)
390         {
391                 const TextureBinding& binding = *bindings[ndx];
392
393                 if (binding.getType() == TextureBinding::TYPE_NONE)
394                         continue;
395
396                 textures[ndx].sampler = binding.getSampler();
397
398                 switch (binding.getType())
399                 {
400                         case TextureBinding::TYPE_1D:                   textures[ndx].tex1D                     = &binding.get1D();                     break;
401                         case TextureBinding::TYPE_2D:                   textures[ndx].tex2D                     = &binding.get2D();                     break;
402                         case TextureBinding::TYPE_3D:                   textures[ndx].tex3D                     = &binding.get3D();                     break;
403                         case TextureBinding::TYPE_CUBE_MAP:             textures[ndx].texCube           = &binding.getCube();           break;
404                         case TextureBinding::TYPE_1D_ARRAY:             textures[ndx].tex1DArray        = &binding.get1DArray();        break;
405                         case TextureBinding::TYPE_2D_ARRAY:             textures[ndx].tex2DArray        = &binding.get2DArray();        break;
406                         case TextureBinding::TYPE_CUBE_ARRAY:   textures[ndx].texCubeArray      = &binding.getCubeArray();      break;
407                         default:
408                                 TCU_THROW(InternalError, "Handling of texture binding type not implemented");
409                 }
410         }
411 }
412
413 ShaderEvalContext::~ShaderEvalContext (void)
414 {
415 }
416
417 void ShaderEvalContext::reset (float sx, float sy)
418 {
419         // Clear old values
420         color           = tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f);
421         isDiscarded     = false;
422
423         // Compute coords
424         coords          = m_quadGrid.getCoords(sx, sy);
425         unitCoords      = m_quadGrid.getUnitCoords(sx, sy);
426
427         // Compute user attributes.
428         const int numAttribs = m_quadGrid.getNumUserAttribs();
429         DE_ASSERT(numAttribs <= MAX_USER_ATTRIBS);
430         for (int attribNdx = 0; attribNdx < numAttribs; attribNdx++)
431                 in[attribNdx] = m_quadGrid.getUserAttrib(attribNdx, sx, sy);
432 }
433
434 tcu::Vec4 ShaderEvalContext::texture2D (int unitNdx, const tcu::Vec2& texCoords)
435 {
436         if (textures[unitNdx].tex2D)
437                 return textures[unitNdx].tex2D->sample(textures[unitNdx].sampler, texCoords.x(), texCoords.y(), 0.0f);
438         else
439                 return tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f);
440 }
441
442 // ShaderEvaluator.
443
444 ShaderEvaluator::ShaderEvaluator (void)
445         : m_evalFunc(DE_NULL)
446 {
447 }
448
449 ShaderEvaluator::ShaderEvaluator (ShaderEvalFunc evalFunc)
450         : m_evalFunc(evalFunc)
451 {
452 }
453
454 ShaderEvaluator::~ShaderEvaluator (void)
455 {
456 }
457
458 void ShaderEvaluator::evaluate (ShaderEvalContext& ctx) const
459 {
460         DE_ASSERT(m_evalFunc);
461         m_evalFunc(ctx);
462 }
463
464 // UniformSetup.
465
466 UniformSetup::UniformSetup (void)
467         : m_setupFunc(DE_NULL)
468 {
469 }
470
471 UniformSetup::UniformSetup (UniformSetupFunc setupFunc)
472         : m_setupFunc(setupFunc)
473 {
474 }
475
476 UniformSetup::~UniformSetup (void)
477 {
478 }
479
480 void UniformSetup::setup (ShaderRenderCaseInstance& instance, const tcu::Vec4& constCoords) const
481 {
482         if (m_setupFunc)
483                 m_setupFunc(instance, constCoords);
484 }
485
486 // ShaderRenderCase.
487
488 ShaderRenderCase::ShaderRenderCase (tcu::TestContext&                   testCtx,
489                                                                         const std::string&                      name,
490                                                                         const std::string&                      description,
491                                                                         const bool                                      isVertexCase,
492                                                                         const ShaderEvalFunc            evalFunc,
493                                                                         const UniformSetup*                     uniformSetup,
494                                                                         const AttributeSetupFunc        attribFunc)
495         : vkt::TestCase         (testCtx, name, description)
496         , m_isVertexCase        (isVertexCase)
497         , m_evaluator           (new ShaderEvaluator(evalFunc))
498         , m_uniformSetup        (uniformSetup ? uniformSetup : new UniformSetup())
499         , m_attribFunc          (attribFunc)
500 {}
501
502 ShaderRenderCase::ShaderRenderCase (tcu::TestContext&                   testCtx,
503                                                                         const std::string&                      name,
504                                                                         const std::string&                      description,
505                                                                         const bool                                      isVertexCase,
506                                                                         const ShaderEvaluator*          evaluator,
507                                                                         const UniformSetup*                     uniformSetup,
508                                                                         const AttributeSetupFunc        attribFunc)
509         : vkt::TestCase         (testCtx, name, description)
510         , m_isVertexCase        (isVertexCase)
511         , m_evaluator           (evaluator)
512         , m_uniformSetup        (uniformSetup ? uniformSetup : new UniformSetup())
513         , m_attribFunc          (attribFunc)
514 {}
515
516 ShaderRenderCase::~ShaderRenderCase (void)
517 {
518 }
519
520 void ShaderRenderCase::initPrograms (vk::SourceCollections& programCollection) const
521 {
522         programCollection.glslSources.add("vert") << glu::VertexSource(m_vertShaderSource);
523         programCollection.glslSources.add("frag") << glu::FragmentSource(m_fragShaderSource);
524 }
525
526 TestInstance* ShaderRenderCase::createInstance (Context& context) const
527 {
528         DE_ASSERT(m_evaluator != DE_NULL);
529         DE_ASSERT(m_uniformSetup != DE_NULL);
530         return new ShaderRenderCaseInstance(context, m_isVertexCase, *m_evaluator, *m_uniformSetup, m_attribFunc);
531 }
532
533 // ShaderRenderCaseInstance.
534
535 ShaderRenderCaseInstance::ShaderRenderCaseInstance (Context&                                    context,
536                                                                                                         const bool                                      isVertexCase,
537                                                                                                         const ShaderEvaluator&          evaluator,
538                                                                                                         const UniformSetup&                     uniformSetup,
539                                                                                                         const AttributeSetupFunc        attribFunc)
540         : vkt::TestInstance             (context)
541         , m_memAlloc                    (context.getDefaultAllocator())
542         , m_clearColor                  (DEFAULT_CLEAR_COLOR)
543         , m_isVertexCase                (isVertexCase)
544         , m_vertexShaderName    ("vert")
545         , m_fragmentShaderName  ("frag")
546         , m_renderSize                  (128, 128)
547         , m_colorFormat                 (VK_FORMAT_R8G8B8A8_UNORM)
548         , m_evaluator                   (&evaluator)
549         , m_uniformSetup                (&uniformSetup)
550         , m_attribFunc                  (attribFunc)
551         , m_sampleCount                 (VK_SAMPLE_COUNT_1_BIT)
552 {
553 }
554
555 ShaderRenderCaseInstance::ShaderRenderCaseInstance (Context&                                    context,
556                                                                                                         const bool                                      isVertexCase,
557                                                                                                         const ShaderEvaluator*          evaluator,
558                                                                                                         const UniformSetup*                     uniformSetup,
559                                                                                                         const AttributeSetupFunc        attribFunc)
560         : vkt::TestInstance             (context)
561         , m_memAlloc                    (context.getDefaultAllocator())
562         , m_clearColor                  (DEFAULT_CLEAR_COLOR)
563         , m_isVertexCase                (isVertexCase)
564         , m_vertexShaderName    ("vert")
565         , m_fragmentShaderName  ("frag")
566         , m_renderSize                  (128, 128)
567         , m_colorFormat                 (VK_FORMAT_R8G8B8A8_UNORM)
568         , m_evaluator                   (evaluator)
569         , m_uniformSetup                (uniformSetup)
570         , m_attribFunc                  (attribFunc)
571         , m_sampleCount                 (VK_SAMPLE_COUNT_1_BIT)
572 {
573 }
574
575 ShaderRenderCaseInstance::~ShaderRenderCaseInstance (void)
576 {
577 }
578
579 tcu::TestStatus ShaderRenderCaseInstance::iterate (void)
580 {
581         setup();
582
583         // Create quad grid.
584         const tcu::UVec2        viewportSize    = getViewportSize();
585         const int                       width                   = viewportSize.x();
586         const int                       height                  = viewportSize.y();
587
588         m_quadGrid                                                      = de::MovePtr<QuadGrid>(new QuadGrid(m_isVertexCase ? GRID_SIZE : 4, width, height, getDefaultConstCoords(), m_userAttribTransforms, m_textures));
589
590         // Render result.
591         tcu::Surface            resImage                (width, height);
592
593         render(m_quadGrid->getNumVertices(), m_quadGrid->getNumTriangles(), m_quadGrid->getIndices(), m_quadGrid->getConstCoords());
594         tcu::copy(resImage.getAccess(), m_resultImage.getAccess());
595
596         // Compute reference.
597         tcu::Surface            refImage                (width, height);
598         if (m_isVertexCase)
599                 computeVertexReference(refImage, *m_quadGrid);
600         else
601                 computeFragmentReference(refImage, *m_quadGrid);
602
603         // Compare.
604         const bool                      compareOk               = compareImages(resImage, refImage, 0.1f);
605
606         if (compareOk)
607                 return tcu::TestStatus::pass("Result image matches reference");
608         else
609                 return tcu::TestStatus::fail("Image mismatch");
610 }
611
612 void ShaderRenderCaseInstance::setup (void)
613 {
614         m_resultImage                                   = tcu::TextureLevel();
615         m_descriptorSetLayoutBuilder    = de::MovePtr<DescriptorSetLayoutBuilder>       (new DescriptorSetLayoutBuilder());
616         m_descriptorPoolBuilder                 = de::MovePtr<DescriptorPoolBuilder>            (new DescriptorPoolBuilder());
617         m_descriptorSetUpdateBuilder    = de::MovePtr<DescriptorSetUpdateBuilder>       (new DescriptorSetUpdateBuilder());
618
619         m_uniformInfos.clear();
620         m_vertexBindingDescription.clear();
621         m_vertexAttributeDescription.clear();
622         m_vertexBuffers.clear();
623         m_vertexBufferAllocs.clear();
624 }
625
626 void ShaderRenderCaseInstance::setupUniformData (deUint32 bindingLocation, size_t size, const void* dataPtr)
627 {
628         const VkDevice                                  vkDevice                        = m_context.getDevice();
629         const DeviceInterface&                  vk                                      = m_context.getDeviceInterface();
630         const deUint32                                  queueFamilyIndex        = m_context.getUniversalQueueFamilyIndex();
631
632         const VkBufferCreateInfo                uniformBufferParams     =
633         {
634                 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,           // VkStructureType              sType;
635                 DE_NULL,                                                                        // const void*                  pNext;
636                 0u,                                                                                     // VkBufferCreateFlags  flags;
637                 size,                                                                           // VkDeviceSize                 size;
638                 VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT,                     // VkBufferUsageFlags   usage;
639                 VK_SHARING_MODE_EXCLUSIVE,                                      // VkSharingMode                sharingMode;
640                 1u,                                                                                     // deUint32                             queueFamilyCount;
641                 &queueFamilyIndex                                                       // const deUint32*              pQueueFamilyIndices;
642         };
643
644         Move<VkBuffer>                                  buffer                          = createBuffer(vk, vkDevice, &uniformBufferParams);
645         de::MovePtr<Allocation>                 alloc                           = m_memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *buffer), MemoryRequirement::HostVisible);
646         VK_CHECK(vk.bindBufferMemory(vkDevice, *buffer, alloc->getMemory(), alloc->getOffset()));
647
648         deMemcpy(alloc->getHostPtr(), dataPtr, size);
649         flushMappedMemoryRange(vk, vkDevice, alloc->getMemory(), alloc->getOffset(), size);
650
651         de::MovePtr<BufferUniform> uniformInfo(new BufferUniform());
652         uniformInfo->type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
653         uniformInfo->descriptor = makeDescriptorBufferInfo(*buffer, 0u, size);
654         uniformInfo->location = bindingLocation;
655         uniformInfo->buffer = VkBufferSp(new vk::Unique<VkBuffer>(buffer));
656         uniformInfo->alloc = AllocationSp(alloc.release());
657
658         m_uniformInfos.push_back(UniformInfoSp(new de::UniquePtr<UniformInfo>(uniformInfo)));
659 }
660
661 void ShaderRenderCaseInstance::addUniform (deUint32 bindingLocation, vk::VkDescriptorType descriptorType, size_t dataSize, const void* data)
662 {
663         m_descriptorSetLayoutBuilder->addSingleBinding(descriptorType, vk::VK_SHADER_STAGE_ALL);
664         m_descriptorPoolBuilder->addType(descriptorType);
665
666         setupUniformData(bindingLocation, dataSize, data);
667 }
668
669 void ShaderRenderCaseInstance::addAttribute (deUint32           bindingLocation,
670                                                                                          vk::VkFormat   format,
671                                                                                          deUint32               sizePerElement,
672                                                                                          deUint32               count,
673                                                                                          const void*    dataPtr)
674 {
675         // Add binding specification
676         const deUint32                                                  binding                                 = (deUint32)m_vertexBindingDescription.size();
677         const VkVertexInputBindingDescription   bindingDescription              =
678         {
679                 binding,                                                        // deUint32                             binding;
680                 sizePerElement,                                         // deUint32                             stride;
681                 VK_VERTEX_INPUT_RATE_VERTEX                     // VkVertexInputRate    stepRate;
682         };
683
684         m_vertexBindingDescription.push_back(bindingDescription);
685
686         // Add location and format specification
687         const VkVertexInputAttributeDescription attributeDescription    =
688         {
689                 bindingLocation,                        // deUint32     location;
690                 binding,                                        // deUint32     binding;
691                 format,                                         // VkFormat     format;
692                 0u,                                                     // deUint32     offset;
693         };
694
695         m_vertexAttributeDescription.push_back(attributeDescription);
696
697         // Upload data to buffer
698         const VkDevice                                                  vkDevice                                = m_context.getDevice();
699         const DeviceInterface&                                  vk                                              = m_context.getDeviceInterface();
700         const deUint32                                                  queueFamilyIndex                = m_context.getUniversalQueueFamilyIndex();
701
702         const VkDeviceSize                                              inputSize                               = sizePerElement * count;
703         const VkBufferCreateInfo                                vertexBufferParams              =
704         {
705                 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,           // VkStructureType              sType;
706                 DE_NULL,                                                                        // const void*                  pNext;
707                 0u,                                                                                     // VkBufferCreateFlags  flags;
708                 inputSize,                                                                      // VkDeviceSize                 size;
709                 VK_BUFFER_USAGE_VERTEX_BUFFER_BIT,                      // VkBufferUsageFlags   usage;
710                 VK_SHARING_MODE_EXCLUSIVE,                                      // VkSharingMode                sharingMode;
711                 1u,                                                                                     // deUint32                             queueFamilyCount;
712                 &queueFamilyIndex                                                       // const deUint32*              pQueueFamilyIndices;
713         };
714
715         Move<VkBuffer>                                                  buffer                                  = createBuffer(vk, vkDevice, &vertexBufferParams);
716         de::MovePtr<vk::Allocation>                             alloc                                   = m_memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *buffer), MemoryRequirement::HostVisible);
717         VK_CHECK(vk.bindBufferMemory(vkDevice, *buffer, alloc->getMemory(), alloc->getOffset()));
718
719         deMemcpy(alloc->getHostPtr(), dataPtr, (size_t)inputSize);
720         flushMappedMemoryRange(vk, vkDevice, alloc->getMemory(), alloc->getOffset(), inputSize);
721
722         m_vertexBuffers.push_back(VkBufferSp(new vk::Unique<VkBuffer>(buffer)));
723         m_vertexBufferAllocs.push_back(AllocationSp(alloc.release()));
724 }
725
726 void ShaderRenderCaseInstance::useAttribute (deUint32 bindingLocation, BaseAttributeType type)
727 {
728         const EnabledBaseAttribute attribute =
729         {
730                 bindingLocation,        // deUint32                             location;
731                 type                            // BaseAttributeType    type;
732         };
733         m_enabledBaseAttributes.push_back(attribute);
734 }
735
736 void ShaderRenderCaseInstance::setupUniforms (const tcu::Vec4& constCoords)
737 {
738         if (m_uniformSetup)
739                 m_uniformSetup->setup(*this, constCoords);
740 }
741
742 void ShaderRenderCaseInstance::useUniform (deUint32 bindingLocation, BaseUniformType type)
743 {
744         #define UNIFORM_CASE(type, value) case type: addUniform(bindingLocation, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, value); break
745
746         switch(type)
747         {
748                 // Bool
749                 UNIFORM_CASE(UB_FALSE,  0);
750                 UNIFORM_CASE(UB_TRUE,   1);
751
752                 // BVec4
753                 UNIFORM_CASE(UB4_FALSE, tcu::Vec4(0));
754                 UNIFORM_CASE(UB4_TRUE,  tcu::Vec4(1));
755
756                 // Integer
757                 UNIFORM_CASE(UI_ZERO,   0);
758                 UNIFORM_CASE(UI_ONE,    1);
759                 UNIFORM_CASE(UI_TWO,    2);
760                 UNIFORM_CASE(UI_THREE,  3);
761                 UNIFORM_CASE(UI_FOUR,   4);
762                 UNIFORM_CASE(UI_FIVE,   5);
763                 UNIFORM_CASE(UI_SIX,    6);
764                 UNIFORM_CASE(UI_SEVEN,  7);
765                 UNIFORM_CASE(UI_EIGHT,  8);
766                 UNIFORM_CASE(UI_ONEHUNDREDONE, 101);
767
768                 // IVec2
769                 UNIFORM_CASE(UI2_MINUS_ONE,     tcu::IVec2(-1));
770                 UNIFORM_CASE(UI2_ZERO,          tcu::IVec2(0));
771                 UNIFORM_CASE(UI2_ONE,           tcu::IVec2(1));
772                 UNIFORM_CASE(UI2_TWO,           tcu::IVec2(2));
773                 UNIFORM_CASE(UI2_THREE,         tcu::IVec2(3));
774                 UNIFORM_CASE(UI2_FOUR,          tcu::IVec2(4));
775                 UNIFORM_CASE(UI2_FIVE,          tcu::IVec2(5));
776
777                 // IVec3
778                 UNIFORM_CASE(UI3_MINUS_ONE,     tcu::IVec3(-1));
779                 UNIFORM_CASE(UI3_ZERO,          tcu::IVec3(0));
780                 UNIFORM_CASE(UI3_ONE,           tcu::IVec3(1));
781                 UNIFORM_CASE(UI3_TWO,           tcu::IVec3(2));
782                 UNIFORM_CASE(UI3_THREE,         tcu::IVec3(3));
783                 UNIFORM_CASE(UI3_FOUR,          tcu::IVec3(4));
784                 UNIFORM_CASE(UI3_FIVE,          tcu::IVec3(5));
785
786                 // IVec4
787                 UNIFORM_CASE(UI4_MINUS_ONE, tcu::IVec4(-1));
788                 UNIFORM_CASE(UI4_ZERO,          tcu::IVec4(0));
789                 UNIFORM_CASE(UI4_ONE,           tcu::IVec4(1));
790                 UNIFORM_CASE(UI4_TWO,           tcu::IVec4(2));
791                 UNIFORM_CASE(UI4_THREE,         tcu::IVec4(3));
792                 UNIFORM_CASE(UI4_FOUR,          tcu::IVec4(4));
793                 UNIFORM_CASE(UI4_FIVE,          tcu::IVec4(5));
794
795                 // Float
796                 UNIFORM_CASE(UF_ZERO,           0.0f);
797                 UNIFORM_CASE(UF_ONE,            1.0f);
798                 UNIFORM_CASE(UF_TWO,            2.0f);
799                 UNIFORM_CASE(UF_THREE,          3.0f);
800                 UNIFORM_CASE(UF_FOUR,           4.0f);
801                 UNIFORM_CASE(UF_FIVE,           5.0f);
802                 UNIFORM_CASE(UF_SIX,            6.0f);
803                 UNIFORM_CASE(UF_SEVEN,          7.0f);
804                 UNIFORM_CASE(UF_EIGHT,          8.0f);
805
806                 UNIFORM_CASE(UF_HALF,           1.0f / 2.0f);
807                 UNIFORM_CASE(UF_THIRD,          1.0f / 3.0f);
808                 UNIFORM_CASE(UF_FOURTH,         1.0f / 4.0f);
809                 UNIFORM_CASE(UF_FIFTH,          1.0f / 5.0f);
810                 UNIFORM_CASE(UF_SIXTH,          1.0f / 6.0f);
811                 UNIFORM_CASE(UF_SEVENTH,        1.0f / 7.0f);
812                 UNIFORM_CASE(UF_EIGHTH,         1.0f / 8.0f);
813
814                 // Vec2
815                 UNIFORM_CASE(UV2_MINUS_ONE,     tcu::Vec2(-1.0f));
816                 UNIFORM_CASE(UV2_ZERO,          tcu::Vec2(0.0f));
817                 UNIFORM_CASE(UV2_ONE,           tcu::Vec2(1.0f));
818                 UNIFORM_CASE(UV2_TWO,           tcu::Vec2(2.0f));
819                 UNIFORM_CASE(UV2_THREE,         tcu::Vec2(3.0f));
820
821                 UNIFORM_CASE(UV2_HALF,          tcu::Vec2(1.0f / 2.0f));
822
823                 // Vec3
824                 UNIFORM_CASE(UV3_MINUS_ONE,     tcu::Vec3(-1.0f));
825                 UNIFORM_CASE(UV3_ZERO,          tcu::Vec3(0.0f));
826                 UNIFORM_CASE(UV3_ONE,           tcu::Vec3(1.0f));
827                 UNIFORM_CASE(UV3_TWO,           tcu::Vec3(2.0f));
828                 UNIFORM_CASE(UV3_THREE,         tcu::Vec3(3.0f));
829
830                 UNIFORM_CASE(UV3_HALF,          tcu::Vec3(1.0f / 2.0f));
831
832                 // Vec4
833                 UNIFORM_CASE(UV4_MINUS_ONE,     tcu::Vec4(-1.0f));
834                 UNIFORM_CASE(UV4_ZERO,          tcu::Vec4(0.0f));
835                 UNIFORM_CASE(UV4_ONE,           tcu::Vec4(1.0f));
836                 UNIFORM_CASE(UV4_TWO,           tcu::Vec4(2.0f));
837                 UNIFORM_CASE(UV4_THREE,         tcu::Vec4(3.0f));
838
839                 UNIFORM_CASE(UV4_HALF,          tcu::Vec4(1.0f / 2.0f));
840
841                 UNIFORM_CASE(UV4_BLACK,         tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f));
842                 UNIFORM_CASE(UV4_GRAY,          tcu::Vec4(0.5f, 0.5f, 0.5f, 1.0f));
843                 UNIFORM_CASE(UV4_WHITE,         tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f));
844
845                 default:
846                         m_context.getTestContext().getLog() << tcu::TestLog::Message << "Unknown Uniform type: " << type << tcu::TestLog::EndMessage;
847                         break;
848         }
849
850         #undef UNIFORM_CASE
851 }
852
853 const tcu::UVec2 ShaderRenderCaseInstance::getViewportSize (void) const
854 {
855         return tcu::UVec2(de::min(m_renderSize.x(), MAX_RENDER_WIDTH),
856                                           de::min(m_renderSize.y(), MAX_RENDER_HEIGHT));
857 }
858
859 void ShaderRenderCaseInstance::setSampleCount (VkSampleCountFlagBits sampleCount)
860 {
861         m_sampleCount   = sampleCount;
862 }
863
864 bool ShaderRenderCaseInstance::isMultiSampling (void) const
865 {
866         return m_sampleCount != VK_SAMPLE_COUNT_1_BIT;
867 }
868
869 void ShaderRenderCaseInstance::uploadImage (const tcu::TextureFormat&                   texFormat,
870                                                                                         const TextureData&                                      textureData,
871                                                                                         const tcu::Sampler&                                     refSampler,
872                                                                                         deUint32                                                        mipLevels,
873                                                                                         deUint32                                                        arrayLayers,
874                                                                                         VkImage                                                         destImage)
875 {
876         const VkDevice                                  vkDevice                                = m_context.getDevice();
877         const DeviceInterface&                  vk                                              = m_context.getDeviceInterface();
878         const VkQueue                                   queue                                   = m_context.getUniversalQueue();
879         const deUint32                                  queueFamilyIndex                = m_context.getUniversalQueueFamilyIndex();
880
881         const bool                                              isShadowSampler                 = refSampler.compare != tcu::Sampler::COMPAREMODE_NONE;
882         const VkImageAspectFlags                aspectMask                              = isShadowSampler ? VK_IMAGE_ASPECT_DEPTH_BIT : VK_IMAGE_ASPECT_COLOR_BIT;
883         deUint32                                                bufferSize                              = 0u;
884         Move<VkBuffer>                                  buffer;
885         de::MovePtr<Allocation>                 bufferAlloc;
886         Move<VkCommandPool>                             cmdPool;
887         Move<VkCommandBuffer>                   cmdBuffer;
888         Move<VkFence>                                   fence;
889         std::vector<VkBufferImageCopy>  copyRegions;
890         std::vector<deUint32>                   offsetMultiples;
891
892         offsetMultiples.push_back(4u);
893         offsetMultiples.push_back(texFormat.getPixelSize());
894
895         // Calculate buffer size
896         for (TextureData::const_iterator mit = textureData.begin(); mit != textureData.end(); ++mit)
897         {
898                 for (TextureLayerData::const_iterator lit = mit->begin(); lit != mit->end(); ++lit)
899                 {
900                         const tcu::ConstPixelBufferAccess&      access  = *lit;
901
902                         bufferSize = getNextMultiple(offsetMultiples, bufferSize);
903                         bufferSize += access.getWidth() * access.getHeight() * access.getDepth() * access.getFormat().getPixelSize();
904                 }
905         }
906
907         // Create source buffer
908         {
909                 const VkBufferCreateInfo bufferParams =
910                 {
911                         VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,           // VkStructureType              sType;
912                         DE_NULL,                                                                        // const void*                  pNext;
913                         0u,                                                                                     // VkBufferCreateFlags  flags;
914                         bufferSize,                                                                     // VkDeviceSize                 size;
915                         VK_BUFFER_USAGE_TRANSFER_SRC_BIT,                       // VkBufferUsageFlags   usage;
916                         VK_SHARING_MODE_EXCLUSIVE,                                      // VkSharingMode                sharingMode;
917                         0u,                                                                                     // deUint32                             queueFamilyIndexCount;
918                         DE_NULL,                                                                        // const deUint32*              pQueueFamilyIndices;
919                 };
920
921                 buffer          = createBuffer(vk, vkDevice, &bufferParams);
922                 bufferAlloc = m_memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *buffer), MemoryRequirement::HostVisible);
923                 VK_CHECK(vk.bindBufferMemory(vkDevice, *buffer, bufferAlloc->getMemory(), bufferAlloc->getOffset()));
924         }
925
926         // Create command pool and buffer
927         {
928                 const VkCommandPoolCreateInfo cmdPoolParams =
929                 {
930                         VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,             // VkStructureType                      sType;
931                         DE_NULL,                                                                                // const void*                          pNext;
932                         VK_COMMAND_POOL_CREATE_TRANSIENT_BIT,                   // VkCommandPoolCreateFlags     flags;
933                         queueFamilyIndex,                                                               // deUint32                                     queueFamilyIndex;
934                 };
935
936                 cmdPool = createCommandPool(vk, vkDevice, &cmdPoolParams);
937
938                 const VkCommandBufferAllocateInfo cmdBufferAllocateInfo =
939                 {
940                         VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, // VkStructureType                      sType;
941                         DE_NULL,                                                                                // const void*                          pNext;
942                         *cmdPool,                                                                               // VkCommandPool                        commandPool;
943                         VK_COMMAND_BUFFER_LEVEL_PRIMARY,                                // VkCommandBufferLevel         level;
944                         1u,                                                                                             // deUint32                                     bufferCount;
945                 };
946
947                 cmdBuffer = allocateCommandBuffer(vk, vkDevice, &cmdBufferAllocateInfo);
948         }
949
950         // Create fence
951         {
952                 const VkFenceCreateInfo fenceParams =
953                 {
954                         VK_STRUCTURE_TYPE_FENCE_CREATE_INFO,            // VkStructureType              sType;
955                         DE_NULL,                                                                        // const void*                  pNext;
956                         0u                                                                                      // VkFenceCreateFlags   flags;
957                 };
958
959                 fence = createFence(vk, vkDevice, &fenceParams);
960         }
961
962         // Barriers for copying buffer to image
963         const VkBufferMemoryBarrier preBufferBarrier =
964         {
965                 VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,        // VkStructureType      sType;
966                 DE_NULL,                                                                        // const void*          pNext;
967                 VK_ACCESS_HOST_WRITE_BIT,                                       // VkAccessFlags        srcAccessMask;
968                 VK_ACCESS_TRANSFER_READ_BIT,                            // VkAccessFlags        dstAccessMask;
969                 VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                     srcQueueFamilyIndex;
970                 VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                     dstQueueFamilyIndex;
971                 *buffer,                                                                        // VkBuffer                     buffer;
972                 0u,                                                                                     // VkDeviceSize         offset;
973                 bufferSize                                                                      // VkDeviceSize         size;
974         };
975
976         const VkImageMemoryBarrier preImageBarrier =
977         {
978                 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,                 // VkStructureType                      sType;
979                 DE_NULL,                                                                                // const void*                          pNext;
980                 0u,                                                                                             // VkAccessFlags                        srcAccessMask;
981                 VK_ACCESS_TRANSFER_WRITE_BIT,                                   // VkAccessFlags                        dstAccessMask;
982                 VK_IMAGE_LAYOUT_UNDEFINED,                                              // VkImageLayout                        oldLayout;
983                 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,                   // VkImageLayout                        newLayout;
984                 VK_QUEUE_FAMILY_IGNORED,                                                // deUint32                                     srcQueueFamilyIndex;
985                 VK_QUEUE_FAMILY_IGNORED,                                                // deUint32                                     dstQueueFamilyIndex;
986                 destImage,                                                                              // VkImage                                      image;
987                 {                                                                                               // VkImageSubresourceRange      subresourceRange;
988                         aspectMask,                                                             // VkImageAspect        aspect;
989                         0u,                                                                             // deUint32                     baseMipLevel;
990                         mipLevels,                                                              // deUint32                     mipLevels;
991                         0u,                                                                             // deUint32                     baseArraySlice;
992                         arrayLayers                                                             // deUint32                     arraySize;
993                 }
994         };
995
996         const VkImageMemoryBarrier postImageBarrier =
997         {
998                 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,                 // VkStructureType                      sType;
999                 DE_NULL,                                                                                // const void*                          pNext;
1000                 VK_ACCESS_TRANSFER_WRITE_BIT,                                   // VkAccessFlags                        srcAccessMask;
1001                 VK_ACCESS_SHADER_READ_BIT,                                              // VkAccessFlags                        dstAccessMask;
1002                 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,                   // VkImageLayout                        oldLayout;
1003                 VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,               // VkImageLayout                        newLayout;
1004                 VK_QUEUE_FAMILY_IGNORED,                                                // deUint32                                     srcQueueFamilyIndex;
1005                 VK_QUEUE_FAMILY_IGNORED,                                                // deUint32                                     dstQueueFamilyIndex;
1006                 destImage,                                                                              // VkImage                                      image;
1007                 {                                                                                               // VkImageSubresourceRange      subresourceRange;
1008                         aspectMask,                                                             // VkImageAspect        aspect;
1009                         0u,                                                                             // deUint32                     baseMipLevel;
1010                         mipLevels,                                                              // deUint32                     mipLevels;
1011                         0u,                                                                             // deUint32                     baseArraySlice;
1012                         arrayLayers                                                             // deUint32                     arraySize;
1013                 }
1014         };
1015
1016         const VkCommandBufferBeginInfo cmdBufferBeginInfo =
1017         {
1018                 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,    // VkStructureType                                      sType;
1019                 DE_NULL,                                                                                // const void*                                          pNext;
1020                 VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT,    // VkCommandBufferUsageFlags            flags;
1021                 (const VkCommandBufferInheritanceInfo*)DE_NULL,
1022         };
1023
1024         // Get copy regions and write buffer data
1025         {
1026                 deUint32        layerDataOffset         = 0;
1027                 deUint8*        destPtr                         = (deUint8*)bufferAlloc->getHostPtr();
1028
1029                 for (size_t levelNdx = 0; levelNdx < textureData.size(); levelNdx++)
1030                 {
1031                         const TextureLayerData&         layerData       = textureData[levelNdx];
1032
1033                         for (size_t layerNdx = 0; layerNdx < layerData.size(); layerNdx++)
1034                         {
1035                                 layerDataOffset = getNextMultiple(offsetMultiples, layerDataOffset);
1036
1037                                 const tcu::ConstPixelBufferAccess&      access          = layerData[layerNdx];
1038                                 const tcu::PixelBufferAccess            destAccess      (access.getFormat(), access.getSize(), destPtr + layerDataOffset);
1039
1040                                 const VkBufferImageCopy                         layerRegion =
1041                                 {
1042                                         layerDataOffset,                                                // VkDeviceSize                         bufferOffset;
1043                                         (deUint32)access.getWidth(),                    // deUint32                                     bufferRowLength;
1044                                         (deUint32)access.getHeight(),                   // deUint32                                     bufferImageHeight;
1045                                         {                                                                               // VkImageSubresourceLayers     imageSubresource;
1046                                                 aspectMask,                                                             // VkImageAspectFlags           aspectMask;
1047                                                 (deUint32)levelNdx,                                             // uint32_t                                     mipLevel;
1048                                                 (deUint32)layerNdx,                                             // uint32_t                                     baseArrayLayer;
1049                                                 1u                                                                              // uint32_t                                     layerCount;
1050                                         },
1051                                         { 0u, 0u, 0u },                                                 // VkOffset3D                   imageOffset;
1052                                         {                                                                               // VkExtent3D                   imageExtent;
1053                                                 (deUint32)access.getWidth(),
1054                                                 (deUint32)access.getHeight(),
1055                                                 (deUint32)access.getDepth()
1056                                         }
1057                                 };
1058
1059                                 copyRegions.push_back(layerRegion);
1060                                 tcu::copy(destAccess, access);
1061
1062                                 layerDataOffset += access.getWidth() * access.getHeight() * access.getDepth() * access.getFormat().getPixelSize();
1063                         }
1064                 }
1065         }
1066
1067         flushMappedMemoryRange(vk, vkDevice, bufferAlloc->getMemory(), bufferAlloc->getOffset(), bufferSize);
1068
1069         // Copy buffer to image
1070         VK_CHECK(vk.beginCommandBuffer(*cmdBuffer, &cmdBufferBeginInfo));
1071         vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 1, &preBufferBarrier, 1, &preImageBarrier);
1072         vk.cmdCopyBufferToImage(*cmdBuffer, *buffer, destImage, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, (deUint32)copyRegions.size(), copyRegions.data());
1073         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);
1074         VK_CHECK(vk.endCommandBuffer(*cmdBuffer));
1075
1076         const VkSubmitInfo submitInfo =
1077         {
1078                 VK_STRUCTURE_TYPE_SUBMIT_INFO,  // VkStructureType                              sType;
1079                 DE_NULL,                                                // const void*                                  pNext;
1080                 0u,                                                             // deUint32                                             waitSemaphoreCount;
1081                 DE_NULL,                                                // const VkSemaphore*                   pWaitSemaphores;
1082                 DE_NULL,                                                // const VkPipelineStageFlags*  pWaitDstStageMask;
1083                 1u,                                                             // deUint32                                             commandBufferCount;
1084                 &cmdBuffer.get(),                               // const VkCommandBuffer*               pCommandBuffers;
1085                 0u,                                                             // deUint32                                             signalSemaphoreCount;
1086                 DE_NULL                                                 // const VkSemaphore*                   pSignalSemaphores;
1087         };
1088
1089         VK_CHECK(vk.queueSubmit(queue, 1, &submitInfo, *fence));
1090         VK_CHECK(vk.waitForFences(vkDevice, 1, &fence.get(), true, ~(0ull) /* infinity */));
1091 }
1092
1093 void ShaderRenderCaseInstance::useSampler (deUint32 bindingLocation, deUint32 textureId)
1094 {
1095         DE_ASSERT(textureId < m_textures.size());
1096
1097         const TextureBinding&                           textureBinding          = *m_textures[textureId];
1098         const TextureBinding::Type                      textureType                     = textureBinding.getType();
1099         const tcu::Sampler&                                     refSampler                      = textureBinding.getSampler();
1100         const TextureBinding::Parameters&       textureParams           = textureBinding.getParameters();
1101         const bool                                                      isMSTexture                     = textureParams.samples != vk::VK_SAMPLE_COUNT_1_BIT;
1102         deUint32                                                        mipLevels                       = 1u;
1103         deUint32                                                        arrayLayers                     = 1u;
1104         tcu::TextureFormat                                      texFormat;
1105         tcu::IVec3                                                      texSize;
1106         TextureData                                                     textureData;
1107
1108         if (textureType == TextureBinding::TYPE_2D)
1109         {
1110                 const tcu::Texture2D&                   texture         = textureBinding.get2D();
1111
1112                 texFormat                                                                       = texture.getFormat();
1113                 texSize                                                                         = tcu::IVec3(texture.getWidth(), texture.getHeight(), 1u);
1114                 mipLevels                                                                       = isMSTexture ? 1u : (deUint32)texture.getNumLevels();
1115                 arrayLayers                                                                     = 1u;
1116
1117                 textureData.resize(mipLevels);
1118
1119                 for (deUint32 level = 0; level < mipLevels; ++level)
1120                 {
1121                         if (texture.isLevelEmpty(level))
1122                                 continue;
1123
1124                         textureData[level].push_back(texture.getLevel(level));
1125                 }
1126         }
1127         else if (textureType == TextureBinding::TYPE_CUBE_MAP)
1128         {
1129                 const tcu::TextureCube&                 texture         = textureBinding.getCube();
1130
1131                 texFormat                                                                       = texture.getFormat();
1132                 texSize                                                                         = tcu::IVec3(texture.getSize(), texture.getSize(), 1u);
1133                 mipLevels                                                                       = isMSTexture ? 1u : (deUint32)texture.getNumLevels();
1134                 arrayLayers                                                                     = 6u;
1135
1136                 static const tcu::CubeFace              cubeFaceMapping[tcu::CUBEFACE_LAST] =
1137                 {
1138                         tcu::CUBEFACE_POSITIVE_X,
1139                         tcu::CUBEFACE_NEGATIVE_X,
1140                         tcu::CUBEFACE_POSITIVE_Y,
1141                         tcu::CUBEFACE_NEGATIVE_Y,
1142                         tcu::CUBEFACE_POSITIVE_Z,
1143                         tcu::CUBEFACE_NEGATIVE_Z
1144                 };
1145
1146                 textureData.resize(mipLevels);
1147
1148                 for (deUint32 level = 0; level < mipLevels; ++level)
1149                 {
1150                         for (int faceNdx = 0; faceNdx < tcu::CUBEFACE_LAST; ++faceNdx)
1151                         {
1152                                 tcu::CubeFace face = cubeFaceMapping[faceNdx];
1153
1154                                 if (texture.isLevelEmpty(face, level))
1155                                         continue;
1156
1157                                 textureData[level].push_back(texture.getLevelFace(level, face));
1158                         }
1159                 }
1160         }
1161         else if (textureType == TextureBinding::TYPE_2D_ARRAY)
1162         {
1163                 const tcu::Texture2DArray&              texture         = textureBinding.get2DArray();
1164
1165                 texFormat                                                                       = texture.getFormat();
1166                 texSize                                                                         = tcu::IVec3(texture.getWidth(), texture.getHeight(), 1u);
1167                 mipLevels                                                                       = isMSTexture ? 1u : (deUint32)texture.getNumLevels();
1168                 arrayLayers                                                                     = (deUint32)texture.getNumLayers();
1169
1170                 textureData.resize(mipLevels);
1171
1172                 for (deUint32 level = 0; level < mipLevels; ++level)
1173                 {
1174                         if (texture.isLevelEmpty(level))
1175                                 continue;
1176
1177                         const tcu::ConstPixelBufferAccess&      levelLayers             = texture.getLevel(level);
1178                         const deUint32                                          layerSize               = levelLayers.getWidth() * levelLayers.getHeight() * levelLayers.getFormat().getPixelSize();
1179
1180                         for (deUint32 layer = 0; layer < arrayLayers; ++layer)
1181                         {
1182                                 const deUint32                                  layerOffset             = layerSize * layer;
1183                                 tcu::ConstPixelBufferAccess             layerData               (levelLayers.getFormat(), levelLayers.getWidth(), levelLayers.getHeight(), 1, (deUint8*)levelLayers.getDataPtr() + layerOffset);
1184                                 textureData[level].push_back(layerData);
1185                         }
1186                 }
1187         }
1188         else if (textureType == TextureBinding::TYPE_3D)
1189         {
1190                 const tcu::Texture3D&                   texture         = textureBinding.get3D();
1191
1192                 texFormat                                                                       = texture.getFormat();
1193                 texSize                                                                         = tcu::IVec3(texture.getWidth(), texture.getHeight(), texture.getDepth());
1194                 mipLevels                                                                       = isMSTexture ? 1u : (deUint32)texture.getNumLevels();
1195                 arrayLayers                                                                     = 1u;
1196
1197                 textureData.resize(mipLevels);
1198
1199                 for (deUint32 level = 0; level < mipLevels; ++level)
1200                 {
1201                         if (texture.isLevelEmpty(level))
1202                                 continue;
1203
1204                         textureData[level].push_back(texture.getLevel(level));
1205                 }
1206         }
1207         else if (textureType == TextureBinding::TYPE_1D)
1208         {
1209                 const tcu::Texture1D&                   texture         = textureBinding.get1D();
1210
1211                 texFormat                                                                       = texture.getFormat();
1212                 texSize                                                                         = tcu::IVec3(texture.getWidth(), 1, 1);
1213                 mipLevels                                                                       = isMSTexture ? 1u : (deUint32)texture.getNumLevels();
1214                 arrayLayers                                                                     = 1u;
1215
1216                 textureData.resize(mipLevels);
1217
1218                 for (deUint32 level = 0; level < mipLevels; ++level)
1219                 {
1220                         if (texture.isLevelEmpty(level))
1221                                 continue;
1222
1223                         textureData[level].push_back(texture.getLevel(level));
1224                 }
1225         }
1226         else if (textureType == TextureBinding::TYPE_1D_ARRAY)
1227         {
1228                 const tcu::Texture1DArray&              texture         = textureBinding.get1DArray();
1229
1230                 texFormat                                                                       = texture.getFormat();
1231                 texSize                                                                         = tcu::IVec3(texture.getWidth(), 1, 1);
1232                 mipLevels                                                                       = isMSTexture ? 1u : (deUint32)texture.getNumLevels();
1233                 arrayLayers                                                                     = (deUint32)texture.getNumLayers();
1234
1235                 textureData.resize(mipLevels);
1236
1237                 for (deUint32 level = 0; level < mipLevels; ++level)
1238                 {
1239                         if (texture.isLevelEmpty(level))
1240                                 continue;
1241
1242                         const tcu::ConstPixelBufferAccess&      levelLayers             = texture.getLevel(level);
1243                         const deUint32                                          layerSize               = levelLayers.getWidth() * levelLayers.getFormat().getPixelSize();
1244
1245                         for (deUint32 layer = 0; layer < arrayLayers; ++layer)
1246                         {
1247                                 const deUint32                                  layerOffset             = layerSize * layer;
1248                                 tcu::ConstPixelBufferAccess             layerData               (levelLayers.getFormat(), levelLayers.getWidth(), 1, 1, (deUint8*)levelLayers.getDataPtr() + layerOffset);
1249                                 textureData[level].push_back(layerData);
1250                         }
1251                 }
1252         }
1253         else if (textureType == TextureBinding::TYPE_CUBE_ARRAY)
1254         {
1255                 const tcu::TextureCubeArray&    texture         = textureBinding.getCubeArray();
1256                 texFormat                                                                       = texture.getFormat();
1257                 texSize                                                                         = tcu::IVec3(texture.getSize(), texture.getSize(), 1);
1258                 mipLevels                                                                       = isMSTexture ? 1u : (deUint32)texture.getNumLevels();
1259                 arrayLayers                                                                     = texture.getDepth();
1260
1261                 textureData.resize(mipLevels);
1262
1263                 for (deUint32 level = 0; level < mipLevels; ++level)
1264                 {
1265                         if (texture.isLevelEmpty(level))
1266                                 continue;
1267
1268                         const tcu::ConstPixelBufferAccess&      levelLayers             = texture.getLevel(level);
1269                         const deUint32                                          layerSize               = levelLayers.getWidth() * levelLayers.getHeight() * levelLayers.getFormat().getPixelSize();
1270
1271                         for (deUint32 layer = 0; layer < arrayLayers; ++layer)
1272                         {
1273                                 const deUint32                                  layerOffset             = layerSize * layer;
1274                                 tcu::ConstPixelBufferAccess             layerData               (levelLayers.getFormat(), levelLayers.getWidth(), levelLayers.getHeight(), 1, (deUint8*)levelLayers.getDataPtr() + layerOffset);
1275                                 textureData[level].push_back(layerData);
1276                         }
1277                 }
1278         }
1279         else
1280         {
1281                 TCU_THROW(InternalError, "Invalid texture type");
1282         }
1283
1284         createSamplerUniform(bindingLocation, textureType, texFormat, texSize, textureData, refSampler, mipLevels, arrayLayers, textureParams);
1285 }
1286
1287 void ShaderRenderCaseInstance::createSamplerUniform (deUint32                                           bindingLocation,
1288                                                                                                          TextureBinding::Type                   textureType,
1289                                                                                                          const tcu::TextureFormat&              texFormat,
1290                                                                                                          const tcu::IVec3                               texSize,
1291                                                                                                          const TextureData&                             textureData,
1292                                                                                                          const tcu::Sampler&                    refSampler,
1293                                                                                                          deUint32                                               mipLevels,
1294                                                                                                          deUint32                                               arrayLayers,
1295                                                                                                          TextureBinding::Parameters             textureParams)
1296 {
1297         const VkDevice                                  vkDevice                        = m_context.getDevice();
1298         const DeviceInterface&                  vk                                      = m_context.getDeviceInterface();
1299         const deUint32                                  queueFamilyIndex        = m_context.getUniversalQueueFamilyIndex();
1300
1301         const bool                                              isShadowSampler         = refSampler.compare != tcu::Sampler::COMPAREMODE_NONE;
1302         const VkImageAspectFlags                aspectMask                      = isShadowSampler ? VK_IMAGE_ASPECT_DEPTH_BIT : VK_IMAGE_ASPECT_COLOR_BIT;
1303         const VkImageViewType                   imageViewType           = textureTypeToImageViewType(textureType);
1304         const VkImageType                               imageType                       = viewTypeToImageType(imageViewType);
1305         const VkFormat                                  format                          = mapTextureFormat(texFormat);
1306         const bool                                              isCube                          = imageViewType == VK_IMAGE_VIEW_TYPE_CUBE || imageViewType == VK_IMAGE_VIEW_TYPE_CUBE_ARRAY;
1307         const VkImageCreateFlags                imageCreateFlags        = isCube ? (VkImageCreateFlags)VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT : (VkImageCreateFlags)0;
1308         VkImageUsageFlags                               imageUsageFlags         = VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
1309         Move<VkImage>                                   vkTexture;
1310         de::MovePtr<Allocation>                 allocation;
1311
1312         if (isShadowSampler)
1313                 imageUsageFlags |= VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
1314
1315         // Create image
1316         const VkImageCreateInfo                 imageParams =
1317         {
1318                 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,                                                    // VkStructureType                      sType;
1319                 DE_NULL,                                                                                                                // const void*                          pNext;
1320                 imageCreateFlags,                                                                                               // VkImageCreateFlags           flags;
1321                 imageType,                                                                                                              // VkImageType                          imageType;
1322                 format,                                                                                                                 // VkFormat                                     format;
1323                 {                                                                                                                               // VkExtent3D                           extent;
1324                         (deUint32)texSize.x(),
1325                         (deUint32)texSize.y(),
1326                         (deUint32)texSize.z()
1327                 },
1328                 mipLevels,                                                                                                              // deUint32                                     mipLevels;
1329                 arrayLayers,                                                                                                    // deUint32                                     arrayLayers;
1330                 textureParams.samples,                                                                                  // VkSampleCountFlagBits        samples;
1331                 VK_IMAGE_TILING_OPTIMAL,                                                                                // VkImageTiling                        tiling;
1332                 imageUsageFlags,                                                                                                // VkImageUsageFlags            usage;
1333                 VK_SHARING_MODE_EXCLUSIVE,                                                                              // VkSharingMode                        sharingMode;
1334                 1u,                                                                                                                             // deUint32                                     queueFamilyIndexCount;
1335                 &queueFamilyIndex,                                                                                              // const deUint32*                      pQueueFamilyIndices;
1336                 VK_IMAGE_LAYOUT_UNDEFINED                                                                               // VkImageLayout                        initialLayout;
1337         };
1338
1339         vkTexture               = createImage(vk, vkDevice, &imageParams);
1340         allocation              = m_memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, *vkTexture), MemoryRequirement::Any);
1341         VK_CHECK(vk.bindImageMemory(vkDevice, *vkTexture, allocation->getMemory(), allocation->getOffset()));
1342
1343         // Upload texture data
1344         uploadImage(texFormat, textureData, refSampler, mipLevels, arrayLayers, *vkTexture);
1345
1346         // Create sampler
1347         const VkSamplerCreateInfo               samplerParams   = mapSampler(refSampler, texFormat);
1348         Move<VkSampler>                                 sampler                 = createSampler(vk, vkDevice, &samplerParams);
1349         const deUint32                                  baseMipLevel    = textureParams.baseMipLevel;
1350         const vk::VkComponentMapping    components              = textureParams.componentMapping;
1351         const VkImageViewCreateInfo             viewParams              =
1352         {
1353                 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,       // VkStructureType                      sType;
1354                 NULL,                                                                           // const voide*                         pNext;
1355                 0u,                                                                                     // VkImageViewCreateFlags       flags;
1356                 *vkTexture,                                                                     // VkImage                                      image;
1357                 imageViewType,                                                          // VkImageViewType                      viewType;
1358                 format,                                                                         // VkFormat                                     format;
1359                 components,                                                                     // VkChannelMapping                     channels;
1360                 {
1361                         aspectMask,                                             // VkImageAspectFlags   aspectMask;
1362                         baseMipLevel,                                   // deUint32                             baseMipLevel;
1363                         mipLevels - baseMipLevel,               // deUint32                             mipLevels;
1364                         0,                                                              // deUint32                             baseArraySlice;
1365                         arrayLayers                                             // deUint32                             arraySize;
1366                 },                                                                                      // VkImageSubresourceRange      subresourceRange;
1367         };
1368
1369         Move<VkImageView>                               imageView               = createImageView(vk, vkDevice, &viewParams);
1370
1371         const vk::VkDescriptorImageInfo descriptor              =
1372         {
1373                 sampler.get(),                                                          // VkSampler                            sampler;
1374                 imageView.get(),                                                        // VkImageView                          imageView;
1375                 VK_IMAGE_LAYOUT_GENERAL,                                        // VkImageLayout                        imageLayout;
1376         };
1377
1378         de::MovePtr<SamplerUniform> uniform(new SamplerUniform());
1379         uniform->type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
1380         uniform->descriptor = descriptor;
1381         uniform->location = bindingLocation;
1382         uniform->image = VkImageSp(new vk::Unique<VkImage>(vkTexture));
1383         uniform->imageView = VkImageViewSp(new vk::Unique<VkImageView>(imageView));
1384         uniform->sampler = VkSamplerSp(new vk::Unique<VkSampler>(sampler));
1385         uniform->alloc = AllocationSp(allocation.release());
1386
1387         m_descriptorSetLayoutBuilder->addSingleSamplerBinding(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, vk::VK_SHADER_STAGE_ALL, DE_NULL);
1388         m_descriptorPoolBuilder->addType(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER);
1389
1390         m_uniformInfos.push_back(UniformInfoSp(new de::UniquePtr<UniformInfo>(uniform)));
1391 }
1392
1393 void ShaderRenderCaseInstance::setupDefaultInputs (void)
1394 {
1395         /* Configuration of the vertex input attributes:
1396                 a_position   is at location 0
1397                 a_coords     is at location 1
1398                 a_unitCoords is at location 2
1399                 a_one        is at location 3
1400
1401           User attributes starts from at the location 4.
1402         */
1403
1404         DE_ASSERT(m_quadGrid);
1405         const QuadGrid&         quadGrid        = *m_quadGrid;
1406
1407         addAttribute(0u, VK_FORMAT_R32G32B32A32_SFLOAT, sizeof(tcu::Vec4), quadGrid.getNumVertices(), quadGrid.getPositions());
1408         addAttribute(1u, VK_FORMAT_R32G32B32A32_SFLOAT, sizeof(tcu::Vec4), quadGrid.getNumVertices(), quadGrid.getCoords());
1409         addAttribute(2u, VK_FORMAT_R32G32B32A32_SFLOAT, sizeof(tcu::Vec4), quadGrid.getNumVertices(), quadGrid.getUnitCoords());
1410         addAttribute(3u, VK_FORMAT_R32_SFLOAT, sizeof(float), quadGrid.getNumVertices(), quadGrid.getAttribOne());
1411
1412         static const struct
1413         {
1414                 BaseAttributeType       type;
1415                 int                                     userNdx;
1416         } userAttributes[] =
1417         {
1418                 { A_IN0, 0 },
1419                 { A_IN1, 1 },
1420                 { A_IN2, 2 },
1421                 { A_IN3, 3 }
1422         };
1423
1424         static const struct
1425         {
1426                 BaseAttributeType       matrixType;
1427                 int                                     numCols;
1428                 int                                     numRows;
1429         } matrices[] =
1430         {
1431                 { MAT2,         2, 2 },
1432                 { MAT2x3,       2, 3 },
1433                 { MAT2x4,       2, 4 },
1434                 { MAT3x2,       3, 2 },
1435                 { MAT3,         3, 3 },
1436                 { MAT3x4,       3, 4 },
1437                 { MAT4x2,       4, 2 },
1438                 { MAT4x3,       4, 3 },
1439                 { MAT4,         4, 4 }
1440         };
1441
1442         for (size_t attrNdx = 0; attrNdx < m_enabledBaseAttributes.size(); attrNdx++)
1443         {
1444                 for (int userNdx = 0; userNdx < DE_LENGTH_OF_ARRAY(userAttributes); userNdx++)
1445                 {
1446                         if (userAttributes[userNdx].type != m_enabledBaseAttributes[attrNdx].type)
1447                                 continue;
1448
1449                         addAttribute(m_enabledBaseAttributes[attrNdx].location, VK_FORMAT_R32G32B32A32_SFLOAT, sizeof(tcu::Vec4), quadGrid.getNumVertices(), quadGrid.getUserAttrib(userNdx));
1450                 }
1451
1452                 for (int matNdx = 0; matNdx < DE_LENGTH_OF_ARRAY(matrices); matNdx++)
1453                 {
1454
1455                         if (matrices[matNdx].matrixType != m_enabledBaseAttributes[attrNdx].type)
1456                                 continue;
1457
1458                         const int numCols = matrices[matNdx].numCols;
1459
1460                         for (int colNdx = 0; colNdx < numCols; colNdx++)
1461                         {
1462                                 addAttribute(m_enabledBaseAttributes[attrNdx].location + colNdx, VK_FORMAT_R32G32B32A32_SFLOAT, (deUint32)(4 * sizeof(float)), quadGrid.getNumVertices(), quadGrid.getUserAttrib(colNdx));
1463                         }
1464                 }
1465         }
1466 }
1467
1468 void ShaderRenderCaseInstance::render (deUint32                         numVertices,
1469                                                                            deUint32                             numTriangles,
1470                                                                            const deUint16*              indices,
1471                                                                            const tcu::Vec4&             constCoords)
1472 {
1473         const VkDevice                                                                          vkDevice                                        = m_context.getDevice();
1474         const DeviceInterface&                                                          vk                                                      = m_context.getDeviceInterface();
1475         const VkQueue                                                                           queue                                           = m_context.getUniversalQueue();
1476         const deUint32                                                                          queueFamilyIndex                        = m_context.getUniversalQueueFamilyIndex();
1477
1478         vk::Move<vk::VkImage>                                                           colorImage;
1479         de::MovePtr<vk::Allocation>                                                     colorImageAlloc;
1480         vk::Move<vk::VkImageView>                                                       colorImageView;
1481         vk::Move<vk::VkImage>                                                           resolvedImage;
1482         de::MovePtr<vk::Allocation>                                                     resolvedImageAlloc;
1483         vk::Move<vk::VkImageView>                                                       resolvedImageView;
1484         vk::Move<vk::VkRenderPass>                                                      renderPass;
1485         vk::Move<vk::VkFramebuffer>                                                     framebuffer;
1486         vk::Move<vk::VkPipelineLayout>                                          pipelineLayout;
1487         vk::Move<vk::VkPipeline>                                                        graphicsPipeline;
1488         vk::Move<vk::VkShaderModule>                                            vertexShaderModule;
1489         vk::Move<vk::VkShaderModule>                                            fragmentShaderModule;
1490         vk::Move<vk::VkBuffer>                                                          indiceBuffer;
1491         de::MovePtr<vk::Allocation>                                                     indiceBufferAlloc;
1492         vk::Move<vk::VkDescriptorSetLayout>                                     descriptorSetLayout;
1493         vk::Move<vk::VkDescriptorPool>                                          descriptorPool;
1494         vk::Move<vk::VkDescriptorSet>                                           descriptorSet;
1495         vk::Move<vk::VkCommandPool>                                                     cmdPool;
1496         vk::Move<vk::VkCommandBuffer>                                           cmdBuffer;
1497         vk::Move<vk::VkFence>                                                           fence;
1498
1499         // Create color image
1500         {
1501                 const VkImageUsageFlags imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
1502                 VkImageFormatProperties properties;
1503
1504                 if ((m_context.getInstanceInterface().getPhysicalDeviceImageFormatProperties(m_context.getPhysicalDevice(),
1505                                                                                                                                                                          m_colorFormat,
1506                                                                                                                                                                          VK_IMAGE_TYPE_2D,
1507                                                                                                                                                                          VK_IMAGE_TILING_OPTIMAL,
1508                                                                                                                                                                          imageUsage,
1509                                                                                                                                                                          0u,
1510                                                                                                                                                                          &properties) == VK_ERROR_FORMAT_NOT_SUPPORTED))
1511                 {
1512                         TCU_THROW(NotSupportedError, "Format not supported");
1513                 }
1514
1515                 if ((properties.sampleCounts & m_sampleCount) != m_sampleCount)
1516                 {
1517                         TCU_THROW(NotSupportedError, "Format not supported");
1518                 }
1519
1520                 const VkImageCreateInfo                                                 colorImageParams                        =
1521                 {
1522                         VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,                                                                            // VkStructureType              sType;
1523                         DE_NULL,                                                                                                                                        // const void*                  pNext;
1524                         0u,                                                                                                                                                     // VkImageCreateFlags   flags;
1525                         VK_IMAGE_TYPE_2D,                                                                                                                       // VkImageType                  imageType;
1526                         m_colorFormat,                                                                                                                          // VkFormat                             format;
1527                         { m_renderSize.x(), m_renderSize.y(), 1u },                                                                     // VkExtent3D                   extent;
1528                         1u,                                                                                                                                                     // deUint32                             mipLevels;
1529                         1u,                                                                                                                                                     // deUint32                             arraySize;
1530                         m_sampleCount,                                                                                                                          // deUint32                             samples;
1531                         VK_IMAGE_TILING_OPTIMAL,                                                                                                        // VkImageTiling                tiling;
1532                         imageUsage,                                                                                                                                     // VkImageUsageFlags    usage;
1533                         VK_SHARING_MODE_EXCLUSIVE,                                                                                                      // VkSharingMode                sharingMode;
1534                         1u,                                                                                                                                                     // deUint32                             queueFamilyCount;
1535                         &queueFamilyIndex,                                                                                                                      // const deUint32*              pQueueFamilyIndices;
1536                         VK_IMAGE_LAYOUT_UNDEFINED,                                                                                                      // VkImageLayout                initialLayout;
1537                 };
1538
1539                 colorImage = createImage(vk, vkDevice, &colorImageParams);
1540
1541                 // Allocate and bind color image memory
1542                 colorImageAlloc = m_memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, *colorImage), MemoryRequirement::Any);
1543                 VK_CHECK(vk.bindImageMemory(vkDevice, *colorImage, colorImageAlloc->getMemory(), colorImageAlloc->getOffset()));
1544         }
1545
1546         // Create color attachment view
1547         {
1548                 const VkImageViewCreateInfo                                             colorImageViewParams            =
1549                 {
1550                         VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,                       // VkStructureType                      sType;
1551                         DE_NULL,                                                                                        // const void*                          pNext;
1552                         0u,                                                                                                     // VkImageViewCreateFlags       flags;
1553                         *colorImage,                                                                            // VkImage                                      image;
1554                         VK_IMAGE_VIEW_TYPE_2D,                                                          // VkImageViewType                      viewType;
1555                         m_colorFormat,                                                                          // VkFormat                                     format;
1556                         {
1557                                 VK_COMPONENT_SWIZZLE_R,                 // VkChannelSwizzle             r;
1558                                 VK_COMPONENT_SWIZZLE_G,                 // VkChannelSwizzle             g;
1559                                 VK_COMPONENT_SWIZZLE_B,                 // VkChannelSwizzle             b;
1560                                 VK_COMPONENT_SWIZZLE_A                  // VkChannelSwizzle             a;
1561                         },                                                                                                      // VkChannelMapping                     channels;
1562                         {
1563                                 VK_IMAGE_ASPECT_COLOR_BIT,              // VkImageAspectFlags   aspectMask;
1564                                 0,                                                              // deUint32                             baseMipLevel;
1565                                 1,                                                              // deUint32                             mipLevels;
1566                                 0,                                                              // deUint32                             baseArraySlice;
1567                                 1                                                               // deUint32                             arraySize;
1568                         },                                                                                                      // VkImageSubresourceRange      subresourceRange;
1569                 };
1570
1571                 colorImageView = createImageView(vk, vkDevice, &colorImageViewParams);
1572         }
1573
1574         if (isMultiSampling())
1575         {
1576                 // Resolved Image
1577                 {
1578                         const VkImageUsageFlags imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
1579                         VkImageFormatProperties properties;
1580
1581                         if ((m_context.getInstanceInterface().getPhysicalDeviceImageFormatProperties(m_context.getPhysicalDevice(),
1582                                                                                                                                                                                  m_colorFormat,
1583                                                                                                                                                                                  VK_IMAGE_TYPE_2D,
1584                                                                                                                                                                                  VK_IMAGE_TILING_OPTIMAL,
1585                                                                                                                                                                                  imageUsage,
1586                                                                                                                                                                                  0,
1587                                                                                                                                                                                  &properties) == VK_ERROR_FORMAT_NOT_SUPPORTED))
1588                         {
1589                                 TCU_THROW(NotSupportedError, "Format not supported");
1590                         }
1591
1592                         const VkImageCreateInfo                                 imageCreateInfo                 =
1593                         {
1594                                 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,            // VkStructureType                      sType;
1595                                 DE_NULL,                                                                        // const void*                          pNext;
1596                                 0u,                                                                                     // VkImageCreateFlags           flags;
1597                                 VK_IMAGE_TYPE_2D,                                                       // VkImageType                          imageType;
1598                                 m_colorFormat,                                                          // VkFormat                                     format;
1599                                 { m_renderSize.x(),     m_renderSize.y(), 1u }, // VkExtent3D                           extent;
1600                                 1u,                                                                                     // deUint32                                     mipLevels;
1601                                 1u,                                                                                     // deUint32                                     arrayLayers;
1602                                 VK_SAMPLE_COUNT_1_BIT,                                          // VkSampleCountFlagBits        samples;
1603                                 VK_IMAGE_TILING_OPTIMAL,                                        // VkImageTiling                        tiling;
1604                                 imageUsage,                                                                     // VkImageUsageFlags            usage;
1605                                 VK_SHARING_MODE_EXCLUSIVE,                                      // VkSharingMode                        sharingMode;
1606                                 1u,                                                                                     // deUint32                                     queueFamilyIndexCount;
1607                                 &queueFamilyIndex,                                                      // const deUint32*                      pQueueFamilyIndices;
1608                                 VK_IMAGE_LAYOUT_UNDEFINED                                       // VkImageLayout                        initialLayout;
1609                         };
1610
1611                         resolvedImage           = vk::createImage(vk, vkDevice, &imageCreateInfo, DE_NULL);
1612                         resolvedImageAlloc      = m_memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, *resolvedImage), MemoryRequirement::Any);
1613                         VK_CHECK(vk.bindImageMemory(vkDevice, *resolvedImage, resolvedImageAlloc->getMemory(), resolvedImageAlloc->getOffset()));
1614                 }
1615
1616                 // Resolved Image View
1617                 {
1618                         const VkImageViewCreateInfo                             imageViewCreateInfo             =
1619                         {
1620                                 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,       // VkStructureType                              sType;
1621                                 DE_NULL,                                                                        // const void*                                  pNext;
1622                                 0u,                                                                                     // VkImageViewCreateFlags               flags;
1623                                 *resolvedImage,                                                         // VkImage                                              image;
1624                                 VK_IMAGE_VIEW_TYPE_2D,                                          // VkImageViewType                              viewType;
1625                                 m_colorFormat,                                                          // VkFormat                                             format;
1626                                 {
1627                                         VK_COMPONENT_SWIZZLE_R,                                 // VkChannelSwizzle             r;
1628                                         VK_COMPONENT_SWIZZLE_G,                                 // VkChannelSwizzle             g;
1629                                         VK_COMPONENT_SWIZZLE_B,                                 // VkChannelSwizzle             b;
1630                                         VK_COMPONENT_SWIZZLE_A                                  // VkChannelSwizzle             a;
1631                                 },
1632                                 {
1633                                         VK_IMAGE_ASPECT_COLOR_BIT,                                      // VkImageAspectFlags                   aspectMask;
1634                                         0u,                                                                                     // deUint32                                             baseMipLevel;
1635                                         1u,                                                                                     // deUint32                                             mipLevels;
1636                                         0u,                                                                                     // deUint32                                             baseArrayLayer;
1637                                         1u,                                                                                     // deUint32                                             arraySize;
1638                                 },                                                                                      // VkImageSubresourceRange              subresourceRange;
1639                         };
1640
1641                         resolvedImageView = vk::createImageView(vk, vkDevice, &imageViewCreateInfo, DE_NULL);
1642                 }
1643         }
1644
1645         // Create render pass
1646         {
1647                 const VkAttachmentDescription                                   attachmentDescription[]         =
1648                 {
1649                         {
1650                                 (VkAttachmentDescriptionFlags)0,                                        // VkAttachmentDescriptionFlags         flags;
1651                                 m_colorFormat,                                                                          // VkFormat                                                     format;
1652                                 m_sampleCount,                                                                          // deUint32                                                     samples;
1653                                 VK_ATTACHMENT_LOAD_OP_CLEAR,                                            // VkAttachmentLoadOp                           loadOp;
1654                                 VK_ATTACHMENT_STORE_OP_STORE,                                           // VkAttachmentStoreOp                          storeOp;
1655                                 VK_ATTACHMENT_LOAD_OP_DONT_CARE,                                        // VkAttachmentLoadOp                           stencilLoadOp;
1656                                 VK_ATTACHMENT_STORE_OP_DONT_CARE,                                       // VkAttachmentStoreOp                          stencilStoreOp;
1657                                 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,                       // VkImageLayout                                        initialLayout;
1658                                 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,                       // VkImageLayout                                        finalLayout;
1659                         },
1660                         {
1661                                 (VkAttachmentDescriptionFlags)0,                                        // VkAttachmentDescriptionFlags         flags;
1662                                 m_colorFormat,                                                                          // VkFormat                                                     format;
1663                                 VK_SAMPLE_COUNT_1_BIT,                                                          // VkSampleCountFlagBits                        samples;
1664                                 VK_ATTACHMENT_LOAD_OP_CLEAR,                                            // VkAttachmentLoadOp                           loadOp;
1665                                 VK_ATTACHMENT_STORE_OP_STORE,                                           // VkAttachmentStoreOp                          storeOp;
1666                                 VK_ATTACHMENT_LOAD_OP_DONT_CARE,                                        // VkAttachmentLoadOp                           stencilLoadOp;
1667                                 VK_ATTACHMENT_STORE_OP_DONT_CARE,                                       // VkAttachmentStoreOp                          stencilStoreOp;
1668                                 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,                       // VkImageLayout                                        initialLayout;
1669                                 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,                       // VkImageLayout                                        finalLayout;
1670                         }
1671                 };
1672
1673                 const VkAttachmentReference                                             attachmentReference                     =
1674                 {
1675                         0u,                                                                                                     // deUint32                     attachment;
1676                         VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL                        // VkImageLayout        layout;
1677                 };
1678
1679                 const VkAttachmentReference                                             resolveAttachmentRef            =
1680                 {
1681                         1u,                                                                                                     // deUint32                     attachment;
1682                         VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL                        // VkImageLayout        layout;
1683                 };
1684
1685                 const VkSubpassDescription                                              subpassDescription                      =
1686                 {
1687                         0u,                                                                                                     // VkSubpassDescriptionFlags    flags;
1688                         VK_PIPELINE_BIND_POINT_GRAPHICS,                                        // VkPipelineBindPoint                  pipelineBindPoint;
1689                         0u,                                                                                                     // deUint32                                             inputCount;
1690                         DE_NULL,                                                                                        // constVkAttachmentReference*  pInputAttachments;
1691                         1u,                                                                                                     // deUint32                                             colorCount;
1692                         &attachmentReference,                                                           // constVkAttachmentReference*  pColorAttachments;
1693                         isMultiSampling() ? &resolveAttachmentRef : DE_NULL,// constVkAttachmentReference*      pResolveAttachments;
1694                         DE_NULL,                                                                                        // VkAttachmentReference                depthStencilAttachment;
1695                         0u,                                                                                                     // deUint32                                             preserveCount;
1696                         DE_NULL                                                                                         // constVkAttachmentReference*  pPreserveAttachments;
1697                 };
1698
1699                 const VkRenderPassCreateInfo                                    renderPassParams                        =
1700                 {
1701                         VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,                      // VkStructureType                                      sType;
1702                         DE_NULL,                                                                                        // const void*                                          pNext;
1703                         0u,                                                                                                     // VkRenderPassCreateFlags                      flags;
1704                         isMultiSampling() ? 2u : 1u,                                            // deUint32                                                     attachmentCount;
1705                         attachmentDescription,                                                          // const VkAttachmentDescription*       pAttachments;
1706                         1u,                                                                                                     // deUint32                                                     subpassCount;
1707                         &subpassDescription,                                                            // const VkSubpassDescription*          pSubpasses;
1708                         0u,                                                                                                     // deUint32                                                     dependencyCount;
1709                         DE_NULL                                                                                         // const VkSubpassDependency*           pDependencies;
1710                 };
1711
1712                 renderPass = createRenderPass(vk, vkDevice, &renderPassParams);
1713         }
1714
1715         // Create framebuffer
1716         {
1717                 const VkImageView                                                               attachments[]                           =
1718                 {
1719                         *colorImageView,
1720                         *resolvedImageView
1721                 };
1722
1723                 const VkFramebufferCreateInfo                                   framebufferParams                       =
1724                 {
1725                         VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,                      // VkStructureType                              sType;
1726                         DE_NULL,                                                                                        // const void*                                  pNext;
1727                         (VkFramebufferCreateFlags)0,
1728                         *renderPass,                                                                            // VkRenderPass                                 renderPass;
1729                         isMultiSampling() ? 2u : 1u,                                            // deUint32                                             attachmentCount;
1730                         attachments,                                                                            // const VkImageView*                   pAttachments;
1731                         (deUint32)m_renderSize.x(),                                                     // deUint32                                             width;
1732                         (deUint32)m_renderSize.y(),                                                     // deUint32                                             height;
1733                         1u                                                                                                      // deUint32                                             layers;
1734                 };
1735
1736                 framebuffer = createFramebuffer(vk, vkDevice, &framebufferParams);
1737         }
1738
1739         // Create descriptors
1740         {
1741                 setupUniforms(constCoords);
1742
1743                 descriptorSetLayout = m_descriptorSetLayoutBuilder->build(vk, vkDevice);
1744                 if (!m_uniformInfos.empty())
1745                 {
1746                         descriptorPool                                                                  = m_descriptorPoolBuilder->build(vk, vkDevice, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u);
1747                         const VkDescriptorSetAllocateInfo       allocInfo       =
1748                         {
1749                                 VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
1750                                 DE_NULL,
1751                                 *descriptorPool,
1752                                 1u,
1753                                 &descriptorSetLayout.get(),
1754                         };
1755
1756                         descriptorSet = allocateDescriptorSet(vk, vkDevice, &allocInfo);
1757                 }
1758
1759                 for (deUint32 i = 0; i < m_uniformInfos.size(); i++)
1760                 {
1761                         const UniformInfo* uniformInfo = m_uniformInfos[i].get()->get();
1762                         deUint32 location = uniformInfo->location;
1763
1764                         if (uniformInfo->type == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER)
1765                         {
1766                                 const BufferUniform*    bufferInfo      = dynamic_cast<const BufferUniform*>(uniformInfo);
1767
1768                                 m_descriptorSetUpdateBuilder->writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(location), uniformInfo->type, &bufferInfo->descriptor);
1769                         }
1770                         else if (uniformInfo->type == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER)
1771                         {
1772                                 const SamplerUniform*   samplerInfo     = dynamic_cast<const SamplerUniform*>(uniformInfo);
1773
1774                                 m_descriptorSetUpdateBuilder->writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(location), uniformInfo->type, &samplerInfo->descriptor);
1775                         }
1776                         else
1777                                 DE_FATAL("Impossible");
1778                 }
1779
1780                 m_descriptorSetUpdateBuilder->update(vk, vkDevice);
1781         }
1782
1783         // Create pipeline layout
1784         {
1785                 const VkPipelineLayoutCreateInfo                                pipelineLayoutParams            =
1786                 {
1787                         VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,          // VkStructureType                              sType;
1788                         DE_NULL,                                                                                        // const void*                                  pNext;
1789                         (VkPipelineLayoutCreateFlags)0,
1790                         1u,                                                                                                     // deUint32                                             descriptorSetCount;
1791                         &*descriptorSetLayout,                                                          // const VkDescriptorSetLayout* pSetLayouts;
1792                         0u,                                                                                                     // deUint32                                             pushConstantRangeCount;
1793                         DE_NULL                                                                                         // const VkPushConstantRange*   pPushConstantRanges;
1794                 };
1795
1796                 pipelineLayout = createPipelineLayout(vk, vkDevice, &pipelineLayoutParams);
1797         }
1798
1799         // Create shaders
1800         {
1801                 vertexShaderModule              = createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get(m_vertexShaderName), 0);
1802                 fragmentShaderModule    = createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get(m_fragmentShaderName), 0);
1803         }
1804
1805         // Create pipeline
1806         {
1807                 const VkPipelineShaderStageCreateInfo                   shaderStageParams[2]            =
1808                 {
1809                         {
1810                                 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,            // VkStructureType                              sType;
1811                                 DE_NULL,                                                                                                        // const void*                                  pNext;
1812                                 (VkPipelineShaderStageCreateFlags)0,
1813                                 VK_SHADER_STAGE_VERTEX_BIT,                                                                     // VkShaderStage                                stage;
1814                                 *vertexShaderModule,                                                                            // VkShader                                             shader;
1815                                 "main",
1816                                 DE_NULL                                                                                                         // const VkSpecializationInfo*  pSpecializationInfo;
1817                         },
1818                         {
1819                                 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,            // VkStructureType                              sType;
1820                                 DE_NULL,                                                                                                        // const void*                                  pNext;
1821                                 (VkPipelineShaderStageCreateFlags)0,
1822                                 VK_SHADER_STAGE_FRAGMENT_BIT,                                                           // VkShaderStage                                stage;
1823                                 *fragmentShaderModule,                                                                          // VkShader                                             shader;
1824                                 "main",
1825                                 DE_NULL                                                                                                         // const VkSpecializationInfo*  pSpecializationInfo;
1826                         }
1827                 };
1828
1829                 // Add test case specific attributes
1830                 if (m_attribFunc)
1831                         m_attribFunc(*this, numVertices);
1832
1833                 // Add base attributes
1834                 setupDefaultInputs();
1835
1836                 const VkPipelineVertexInputStateCreateInfo              vertexInputStateParams          =
1837                 {
1838                         VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,              // VkStructureType                                                      sType;
1839                         DE_NULL,                                                                                                                // const void*                                                          pNext;
1840                         (VkPipelineVertexInputStateCreateFlags)0,
1841                         (deUint32)m_vertexBindingDescription.size(),                                    // deUint32                                                                     bindingCount;
1842                         &m_vertexBindingDescription[0],                                                                 // const VkVertexInputBindingDescription*       pVertexBindingDescriptions;
1843                         (deUint32)m_vertexAttributeDescription.size(),                                  // deUint32                                                                     attributeCount;
1844                         &m_vertexAttributeDescription[0],                                                               // const VkVertexInputAttributeDescription*     pVertexAttributeDescriptions;
1845                 };
1846
1847                 const VkPipelineInputAssemblyStateCreateInfo    inputAssemblyStateParams        =
1848                 {
1849                         VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,    // VkStructureType              sType;
1850                         DE_NULL,                                                                                                                // const void*                  pNext;
1851                         (VkPipelineInputAssemblyStateCreateFlags)0,
1852                         VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST,                                                    // VkPrimitiveTopology  topology;
1853                         false                                                                                                                   // VkBool32                             primitiveRestartEnable;
1854                 };
1855
1856                 const VkViewport                                                                viewport                                        =
1857                 {
1858                         0.0f,                                           // float        originX;
1859                         0.0f,                                           // float        originY;
1860                         (float)m_renderSize.x(),        // float        width;
1861                         (float)m_renderSize.y(),        // float        height;
1862                         0.0f,                                           // float        minDepth;
1863                         1.0f                                            // float        maxDepth;
1864                 };
1865
1866                 const VkRect2D                                                                  scissor                                         =
1867                 {
1868                         {
1869                                 0u,                                     // deUint32     x;
1870                                 0u,                                     // deUint32     y;
1871                         },                                                      // VkOffset2D   offset;
1872                         {
1873                                 m_renderSize.x(),       // deUint32     width;
1874                                 m_renderSize.y(),       // deUint32     height;
1875                         },                                                      // VkExtent2D   extent;
1876                 };
1877
1878                 const VkPipelineViewportStateCreateInfo                 viewportStateParams                     =
1879                 {
1880                         VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO,                  // VkStructureType                                              sType;
1881                         DE_NULL,                                                                                                                // const void*                                                  pNext;
1882                         0u,                                                                                                                             // VkPipelineViewportStateCreateFlags   flags;
1883                         1u,                                                                                                                             // deUint32                                                             viewportCount;
1884                         &viewport,                                                                                                              // const VkViewport*                                    pViewports;
1885                         1u,                                                                                                                             // deUint32                                                             scissorsCount;
1886                         &scissor,                                                                                                               // const VkRect2D*                                              pScissors;
1887                 };
1888
1889                 const VkPipelineRasterizationStateCreateInfo    rasterStateParams                       =
1890                 {
1891                         VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO,             // VkStructureType      sType;
1892                         DE_NULL,                                                                                                                // const void*          pNext;
1893                         (VkPipelineRasterizationStateCreateFlags)0,
1894                         false,                                                                                                                  // VkBool32                     depthClipEnable;
1895                         false,                                                                                                                  // VkBool32                     rasterizerDiscardEnable;
1896                         VK_POLYGON_MODE_FILL,                                                                                   // VkFillMode           fillMode;
1897                         VK_CULL_MODE_NONE,                                                                                              // VkCullMode           cullMode;
1898                         VK_FRONT_FACE_COUNTER_CLOCKWISE,                                                                // VkFrontFace          frontFace;
1899                         false,                                                                                                                  // VkBool32                     depthBiasEnable;
1900                         0.0f,                                                                                                                   // float                        depthBias;
1901                         0.0f,                                                                                                                   // float                        depthBiasClamp;
1902                         0.0f,                                                                                                                   // float                        slopeScaledDepthBias;
1903                         1.0f,                                                                                                                   // float                        lineWidth;
1904                 };
1905
1906                 const VkPipelineMultisampleStateCreateInfo              multisampleStateParams =
1907                 {
1908                         VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,               // VkStructureType                                                      sType;
1909                         DE_NULL,                                                                                                                // const void*                                                          pNext;
1910                         0u,                                                                                                                             // VkPipelineMultisampleStateCreateFlags        flags;
1911                         m_sampleCount,                                                                                                  // VkSampleCountFlagBits                                        rasterizationSamples;
1912                         VK_FALSE,                                                                                                               // VkBool32                                                                     sampleShadingEnable;
1913                         0.0f,                                                                                                                   // float                                                                        minSampleShading;
1914                         DE_NULL,                                                                                                                // const VkSampleMask*                                          pSampleMask;
1915                         VK_FALSE,                                                                                                               // VkBool32                                                                     alphaToCoverageEnable;
1916                         VK_FALSE                                                                                                                // VkBool32                                                                     alphaToOneEnable;
1917                 };
1918
1919                 const VkPipelineColorBlendAttachmentState               colorBlendAttachmentState       =
1920                 {
1921                         false,                                                                                                                  // VkBool32                     blendEnable;
1922                         VK_BLEND_FACTOR_ONE,                                                                                    // VkBlend                      srcBlendColor;
1923                         VK_BLEND_FACTOR_ZERO,                                                                                   // VkBlend                      destBlendColor;
1924                         VK_BLEND_OP_ADD,                                                                                                // VkBlendOp            blendOpColor;
1925                         VK_BLEND_FACTOR_ONE,                                                                                    // VkBlend                      srcBlendAlpha;
1926                         VK_BLEND_FACTOR_ZERO,                                                                                   // VkBlend                      destBlendAlpha;
1927                         VK_BLEND_OP_ADD,                                                                                                // VkBlendOp            blendOpAlpha;
1928                         (VK_COLOR_COMPONENT_R_BIT |
1929                          VK_COLOR_COMPONENT_G_BIT |
1930                          VK_COLOR_COMPONENT_B_BIT |
1931                          VK_COLOR_COMPONENT_A_BIT),                                                                             // VkChannelFlags       channelWriteMask;
1932                 };
1933
1934                 const VkPipelineColorBlendStateCreateInfo               colorBlendStateParams           =
1935                 {
1936                         VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,       // VkStructureType                                                              sType;
1937                         DE_NULL,                                                                                                        // const void*                                                                  pNext;
1938                         (VkPipelineColorBlendStateCreateFlags)0,
1939                         false,                                                                                                          // VkBool32                                                                             logicOpEnable;
1940                         VK_LOGIC_OP_COPY,                                                                                       // VkLogicOp                                                                    logicOp;
1941                         1u,                                                                                                                     // deUint32                                                                             attachmentCount;
1942                         &colorBlendAttachmentState,                                                                     // const VkPipelineColorBlendAttachmentState*   pAttachments;
1943                         { 0.0f, 0.0f, 0.0f, 0.0f },                                                                     // float                                                                                blendConst[4];
1944                 };
1945
1946                 const VkGraphicsPipelineCreateInfo                              graphicsPipelineParams          =
1947                 {
1948                         VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,        // VkStructureType                                                                      sType;
1949                         DE_NULL,                                                                                        // const void*                                                                          pNext;
1950                         0u,                                                                                                     // VkPipelineCreateFlags                                                        flags;
1951                         2u,                                                                                                     // deUint32                                                                                     stageCount;
1952                         shaderStageParams,                                                                      // const VkPipelineShaderStageCreateInfo*                       pStages;
1953                         &vertexInputStateParams,                                                        // const VkPipelineVertexInputStateCreateInfo*          pVertexInputState;
1954                         &inputAssemblyStateParams,                                                      // const VkPipelineInputAssemblyStateCreateInfo*        pInputAssemblyState;
1955                         DE_NULL,                                                                                        // const VkPipelineTessellationStateCreateInfo*         pTessellationState;
1956                         &viewportStateParams,                                                           // const VkPipelineViewportStateCreateInfo*                     pViewportState;
1957                         &rasterStateParams,                                                                     // const VkPipelineRasterStateCreateInfo*                       pRasterState;
1958                         &multisampleStateParams,                                                        // const VkPipelineMultisampleStateCreateInfo*          pMultisampleState;
1959                         DE_NULL,                                                                                        // const VkPipelineDepthStencilStateCreateInfo*         pDepthStencilState;
1960                         &colorBlendStateParams,                                                         // const VkPipelineColorBlendStateCreateInfo*           pColorBlendState;
1961                         (const VkPipelineDynamicStateCreateInfo*)DE_NULL,       // const VkPipelineDynamicStateCreateInfo*                      pDynamicState;
1962                         *pipelineLayout,                                                                        // VkPipelineLayout                                                                     layout;
1963                         *renderPass,                                                                            // VkRenderPass                                                                         renderPass;
1964                         0u,                                                                                                     // deUint32                                                                                     subpass;
1965                         0u,                                                                                                     // VkPipeline                                                                           basePipelineHandle;
1966                         0u                                                                                                      // deInt32                                                                                      basePipelineIndex;
1967                 };
1968
1969                 graphicsPipeline = createGraphicsPipeline(vk, vkDevice, DE_NULL, &graphicsPipelineParams);
1970         }
1971
1972         // Create vertex indices buffer
1973         {
1974                 const VkDeviceSize                                                              indiceBufferSize                        = numTriangles * 3 * sizeof(deUint16);
1975                 const VkBufferCreateInfo                                                indiceBufferParams                      =
1976                 {
1977                         VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,           // VkStructureType              sType;
1978                         DE_NULL,                                                                        // const void*                  pNext;
1979                         0u,                                                                                     // VkBufferCreateFlags  flags;
1980                         indiceBufferSize,                                                       // VkDeviceSize                 size;
1981                         VK_BUFFER_USAGE_INDEX_BUFFER_BIT,                       // VkBufferUsageFlags   usage;
1982                         VK_SHARING_MODE_EXCLUSIVE,                                      // VkSharingMode                sharingMode;
1983                         1u,                                                                                     // deUint32                             queueFamilyCount;
1984                         &queueFamilyIndex                                                       // const deUint32*              pQueueFamilyIndices;
1985                 };
1986
1987                 indiceBuffer            = createBuffer(vk, vkDevice, &indiceBufferParams);
1988                 indiceBufferAlloc       = m_memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *indiceBuffer), MemoryRequirement::HostVisible);
1989
1990                 VK_CHECK(vk.bindBufferMemory(vkDevice, *indiceBuffer, indiceBufferAlloc->getMemory(), indiceBufferAlloc->getOffset()));
1991
1992                 // Load vertice indices into buffer
1993                 deMemcpy(indiceBufferAlloc->getHostPtr(), indices, (size_t)indiceBufferSize);
1994                 flushMappedMemoryRange(vk, vkDevice, indiceBufferAlloc->getMemory(), indiceBufferAlloc->getOffset(), indiceBufferSize);
1995         }
1996
1997         // Create command pool
1998         {
1999                 const VkCommandPoolCreateInfo                                   cmdPoolParams                           =
2000                 {
2001                         VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,             // VkStructureType              sType;
2002                         DE_NULL,                                                                                // const void*                  pNext;
2003                         VK_COMMAND_POOL_CREATE_TRANSIENT_BIT,                   // VkCmdPoolCreateFlags flags;
2004                         queueFamilyIndex,                                                               // deUint32                             queueFamilyIndex;
2005                 };
2006
2007                 cmdPool = createCommandPool(vk, vkDevice, &cmdPoolParams);
2008         }
2009
2010         // Create command buffer
2011         {
2012                 const VkCommandBufferAllocateInfo                               cmdBufferParams                         =
2013                 {
2014                         VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, // VkStructureType                      sType;
2015                         DE_NULL,                                                                                // const void*                          pNext;
2016                         *cmdPool,                                                                               // VkCmdPool                            cmdPool;
2017                         VK_COMMAND_BUFFER_LEVEL_PRIMARY,                                // VkCmdBufferLevel                     level;
2018                         1u                                                                                              // deUint32                                     bufferCount;
2019                 };
2020
2021                 const VkCommandBufferBeginInfo                                  cmdBufferBeginInfo                      =
2022                 {
2023                         VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,    // VkStructureType                      sType;
2024                         DE_NULL,                                                                                // const void*                          pNext;
2025                         0u,                                                                                             // VkCmdBufferOptimizeFlags     flags;
2026                         (const VkCommandBufferInheritanceInfo*)DE_NULL,
2027                 };
2028
2029                 const VkClearValue                                                              clearValues                                     = makeClearValueColorF32(m_clearColor.x(),
2030                                                                                                                                                                                                                          m_clearColor.y(),
2031                                                                                                                                                                                                                          m_clearColor.z(),
2032                                                                                                                                                                                                                          m_clearColor.w());
2033
2034                 const VkRenderPassBeginInfo                                             renderPassBeginInfo                     =
2035                 {
2036                         VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,                               // VkStructureType              sType;
2037                         DE_NULL,                                                                                                // const void*                  pNext;
2038                         *renderPass,                                                                                    // VkRenderPass                 renderPass;
2039                         *framebuffer,                                                                                   // VkFramebuffer                framebuffer;
2040                         { { 0, 0 },  {m_renderSize.x(), m_renderSize.y() } },   // VkRect2D                             renderArea;
2041                         1,                                                                                                              // deUint32                             clearValueCount;
2042                         &clearValues,                                                                                   // const VkClearValue*  pClearValues;
2043                 };
2044
2045                 cmdBuffer = allocateCommandBuffer(vk, vkDevice, &cmdBufferParams);
2046
2047                 VK_CHECK(vk.beginCommandBuffer(*cmdBuffer, &cmdBufferBeginInfo));
2048
2049                 {
2050                         const VkImageMemoryBarrier                                      imageBarrier                            =
2051                         {
2052                                 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,                                                                         // VkStructureType                      sType;
2053                                 DE_NULL,                                                                                                                                        // const void*                          pNext;
2054                                 0u,                                                                                                                                                     // VkAccessFlags                        srcAccessMask;
2055                                 VK_PIPELINE_STAGE_TRANSFER_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,          // VkAccessFlags                        dstAccessMask;
2056                                 VK_IMAGE_LAYOUT_UNDEFINED,                                                                                                      // VkImageLayout                        oldLayout;
2057                                 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,                                                                       // VkImageLayout                        newLayout;
2058                                 VK_QUEUE_FAMILY_IGNORED,                                                                                                        // deUint32                                     srcQueueFamilyIndex;
2059                                 VK_QUEUE_FAMILY_IGNORED,                                                                                                        // deUint32                                     dstQueueFamilyIndex;
2060                                 *colorImage,                                                                                                                            // VkImage                                      image;
2061                                 {                                                                                                                                                       // VkImageSubresourceRange      subresourceRange;
2062                                         VK_IMAGE_ASPECT_COLOR_BIT,                                                                                              // VkImageAspectFlags           aspectMask;
2063                                         0u,                                                                                                                                             // deUint32                                     baseMipLevel;
2064                                         1u,                                                                                                                                             // deUint32                                     mipLevels;
2065                                         0u,                                                                                                                                             // deUint32                                     baseArrayLayer;
2066                                         1u,                                                                                                                                             // deUint32                                     arraySize;
2067                                 }
2068                         };
2069
2070                         vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, DE_NULL, 1, &imageBarrier);
2071
2072                         if (isMultiSampling()) {
2073                                 // add multisample barrier
2074                                 const VkImageMemoryBarrier                              multiSampleImageBarrier         =
2075                                 {
2076                                         VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,                                                                         // VkStructureType                      sType;
2077                                         DE_NULL,                                                                                                                                        // const void*                          pNext;
2078                                         0u,                                                                                                                                                     // VkAccessFlags                        srcAccessMask;
2079                                         VK_PIPELINE_STAGE_TRANSFER_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,          // VkAccessFlags                        dstAccessMask;
2080                                         VK_IMAGE_LAYOUT_UNDEFINED,                                                                                                      // VkImageLayout                        oldLayout;
2081                                         VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,                                                                       // VkImageLayout                        newLayout;
2082                                         VK_QUEUE_FAMILY_IGNORED,                                                                                                        // deUint32                                     srcQueueFamilyIndex;
2083                                         VK_QUEUE_FAMILY_IGNORED,                                                                                                        // deUint32                                     dstQueueFamilyIndex;
2084                                         *resolvedImage,                                                                                                                         // VkImage                                      image;
2085                                         {                                                                                                                                                       // VkImageSubresourceRange      subresourceRange;
2086                                                 VK_IMAGE_ASPECT_COLOR_BIT,                                                                                              // VkImageAspectFlags           aspectMask;
2087                                                 0u,                                                                                                                                             // deUint32                                     baseMipLevel;
2088                                                 1u,                                                                                                                                             // deUint32                                     mipLevels;
2089                                                 0u,                                                                                                                                             // deUint32                                     baseArrayLayer;
2090                                                 1u,                                                                                                                                             // deUint32                                     arraySize;
2091                                         }
2092                                 };
2093
2094                                 vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, DE_NULL, 1, &multiSampleImageBarrier);
2095                         }
2096                 }
2097
2098                 vk.cmdBeginRenderPass(*cmdBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
2099
2100                 vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *graphicsPipeline);
2101                 if (!m_uniformInfos.empty())
2102                         vk.cmdBindDescriptorSets(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipelineLayout, 0u, 1, &*descriptorSet, 0u, DE_NULL);
2103                 vk.cmdBindIndexBuffer(*cmdBuffer, *indiceBuffer, 0, VK_INDEX_TYPE_UINT16);
2104
2105                 const deUint32 numberOfVertexAttributes = (deUint32)m_vertexBuffers.size();
2106                 const std::vector<VkDeviceSize> offsets(numberOfVertexAttributes, 0);
2107
2108                 std::vector<VkBuffer> buffers(numberOfVertexAttributes);
2109                 for (size_t i = 0; i < numberOfVertexAttributes; i++)
2110                 {
2111                         buffers[i] = m_vertexBuffers[i].get()->get();
2112                 }
2113
2114                 vk.cmdBindVertexBuffers(*cmdBuffer, 0, numberOfVertexAttributes, &buffers[0], &offsets[0]);
2115                 vk.cmdDrawIndexed(*cmdBuffer, numTriangles * 3, 1, 0, 0, 0);
2116
2117                 vk.cmdEndRenderPass(*cmdBuffer);
2118                 VK_CHECK(vk.endCommandBuffer(*cmdBuffer));
2119         }
2120
2121         // Create fence
2122         {
2123                 const VkFenceCreateInfo                                                 fenceParams                                     =
2124                 {
2125                         VK_STRUCTURE_TYPE_FENCE_CREATE_INFO,    // VkStructureType              sType;
2126                         DE_NULL,                                                                // const void*                  pNext;
2127                         0u                                                                              // VkFenceCreateFlags   flags;
2128                 };
2129                 fence = createFence(vk, vkDevice, &fenceParams);
2130         }
2131
2132         // Execute Draw
2133         {
2134                 const VkSubmitInfo      submitInfo      =
2135                 {
2136                         VK_STRUCTURE_TYPE_SUBMIT_INFO,
2137                         DE_NULL,
2138                         0u,
2139                         (const VkSemaphore*)DE_NULL,
2140                         (const VkPipelineStageFlags*)DE_NULL,
2141                         1u,
2142                         &cmdBuffer.get(),
2143                         0u,
2144                         (const VkSemaphore*)DE_NULL,
2145                 };
2146
2147                 VK_CHECK(vk.queueSubmit(queue, 1, &submitInfo, *fence));
2148                 VK_CHECK(vk.waitForFences(vkDevice, 1, &fence.get(), true, ~(0ull) /* infinity*/));
2149         }
2150
2151         // Read back the result
2152         {
2153                 const tcu::TextureFormat                                                resultFormat                            = mapVkFormat(m_colorFormat);
2154                 const VkDeviceSize                                                              imageSizeBytes                          = (VkDeviceSize)(resultFormat.getPixelSize() * m_renderSize.x() * m_renderSize.y());
2155                 const VkBufferCreateInfo                                                readImageBufferParams           =
2156                 {
2157                         VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,           //  VkStructureType             sType;
2158                         DE_NULL,                                                                        //  const void*                 pNext;
2159                         0u,                                                                                     //  VkBufferCreateFlags flags;
2160                         imageSizeBytes,                                                         //  VkDeviceSize                size;
2161                         VK_BUFFER_USAGE_TRANSFER_DST_BIT,                       //  VkBufferUsageFlags  usage;
2162                         VK_SHARING_MODE_EXCLUSIVE,                                      //  VkSharingMode               sharingMode;
2163                         1u,                                                                                     //  deUint32                    queueFamilyCount;
2164                         &queueFamilyIndex,                                                      //  const deUint32*             pQueueFamilyIndices;
2165                 };
2166                 const Unique<VkBuffer>                                                  readImageBuffer                         (createBuffer(vk, vkDevice, &readImageBufferParams));
2167                 const de::UniquePtr<Allocation>                                 readImageBufferMemory           (m_memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *readImageBuffer), MemoryRequirement::HostVisible));
2168
2169                 VK_CHECK(vk.bindBufferMemory(vkDevice, *readImageBuffer, readImageBufferMemory->getMemory(), readImageBufferMemory->getOffset()));
2170
2171                 // Copy image to buffer
2172                 const VkCommandBufferAllocateInfo                               cmdBufferParams                         =
2173                 {
2174                         VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, // VkStructureType                      sType;
2175                         DE_NULL,                                                                                // const void*                          pNext;
2176                         *cmdPool,                                                                               // VkCmdPool                            cmdPool;
2177                         VK_COMMAND_BUFFER_LEVEL_PRIMARY,                                // VkCmdBufferLevel                     level;
2178                         1u                                                                                              // deUint32                                     bufferCount;
2179                 };
2180
2181                 const VkCommandBufferBeginInfo                                  cmdBufferBeginInfo                      =
2182                 {
2183                         VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,    // VkStructureType                      sType;
2184                         DE_NULL,                                                                                // const void*                          pNext;
2185                         0u,                                                                                             // VkCmdBufferOptimizeFlags     flags;
2186                         (const VkCommandBufferInheritanceInfo*)DE_NULL,
2187                 };
2188
2189                 const Move<VkCommandBuffer>                                             resultCmdBuffer                         = allocateCommandBuffer(vk, vkDevice, &cmdBufferParams);
2190
2191                 const VkBufferImageCopy                                                 copyParams                                      =
2192                 {
2193                         0u,                                                                                     // VkDeviceSize                 bufferOffset;
2194                         (deUint32)m_renderSize.x(),                                     // deUint32                             bufferRowLength;
2195                         (deUint32)m_renderSize.y(),                                     // deUint32                             bufferImageHeight;
2196                         {
2197                                 VK_IMAGE_ASPECT_COLOR_BIT,                      // VkImageAspect                aspect;
2198                                 0u,                                                                     // deUint32                             mipLevel;
2199                                 0u,                                                                     // deUint32                             arraySlice;
2200                                 1u,                                                                     // deUint32                             arraySize;
2201                         },                                                                                      // VkImageSubresourceCopy       imageSubresource;
2202                         { 0u, 0u, 0u },                                                         // VkOffset3D                   imageOffset;
2203                         { m_renderSize.x(), m_renderSize.y(), 1u }      // VkExtent3D                   imageExtent;
2204                 };
2205                 const VkSubmitInfo                                                              submitInfo                                      =
2206                 {
2207                         VK_STRUCTURE_TYPE_SUBMIT_INFO,
2208                         DE_NULL,
2209                         0u,
2210                         (const VkSemaphore*)DE_NULL,
2211                         (const VkPipelineStageFlags*)DE_NULL,
2212                         1u,
2213                         &resultCmdBuffer.get(),
2214                         0u,
2215                         (const VkSemaphore*)DE_NULL,
2216                 };
2217
2218                 VK_CHECK(vk.beginCommandBuffer(*resultCmdBuffer, &cmdBufferBeginInfo));
2219
2220                 const VkImageMemoryBarrier                                              imageBarrier                            =
2221                 {
2222                         VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,                                                                 // VkStructureType                      sType;
2223                         DE_NULL,                                                                                                                                // const void*                          pNext;
2224                         VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | VK_ACCESS_TRANSFER_WRITE_BIT,    // VkAccessFlags                        srcAccessMask;
2225                         VK_ACCESS_TRANSFER_READ_BIT | VK_ACCESS_TRANSFER_WRITE_BIT,                             // VkAccessFlags                        dstAccessMask;
2226                         VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,                                                               // VkImageLayout                        oldLayout;
2227                         VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,                                                                   // VkImageLayout                        newLayout;
2228                         VK_QUEUE_FAMILY_IGNORED,                                                                                                // deUint32                                     srcQueueFamilyIndex;
2229                         VK_QUEUE_FAMILY_IGNORED,                                                                                                // deUint32                                     dstQueueFamilyIndex;
2230                         isMultiSampling() ? *resolvedImage : *colorImage,                                               // VkImage                                      image;
2231                         {                                                                                                                                               // VkImageSubresourceRange      subresourceRange;
2232                                 VK_IMAGE_ASPECT_COLOR_BIT,                                                                                      // VkImageAspectFlags           aspectMask;
2233                                 0u,                                                                                                                                     // deUint32                                     baseMipLevel;
2234                                 1u,                                                                                                                                     // deUint32                                     mipLevels;
2235                                 0u,                                                                                                                                     // deUint32                                     baseArraySlice;
2236                                 1u                                                                                                                                      // deUint32                                     arraySize;
2237                         }
2238                 };
2239
2240                 const VkBufferMemoryBarrier                                             bufferBarrier                           =
2241                 {
2242                         VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,        // VkStructureType      sType;
2243                         DE_NULL,                                                                        // const void*          pNext;
2244                         VK_ACCESS_TRANSFER_WRITE_BIT,                           // VkAccessFlags        srcAccessMask;
2245                         VK_ACCESS_HOST_READ_BIT,                                        // VkAccessFlags        dstAccessMask;
2246                         VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                     srcQueueFamilyIndex;
2247                         VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                     dstQueueFamilyIndex;
2248                         *readImageBuffer,                                                       // VkBuffer                     buffer;
2249                         0u,                                                                                     // VkDeviceSize         offset;
2250                         imageSizeBytes                                                          // VkDeviceSize         size;
2251                 };
2252
2253                 vk.cmdPipelineBarrier(*resultCmdBuffer, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, 1, &imageBarrier);
2254                 vk.cmdCopyImageToBuffer(*resultCmdBuffer, isMultiSampling() ? *resolvedImage : *colorImage, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *readImageBuffer, 1u, &copyParams);
2255                 vk.cmdPipelineBarrier(*resultCmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 1, &bufferBarrier, 0, (const VkImageMemoryBarrier*)DE_NULL);
2256
2257                 VK_CHECK(vk.endCommandBuffer(*resultCmdBuffer));
2258
2259                 VK_CHECK(vk.resetFences(vkDevice, 1, &fence.get()));
2260                 VK_CHECK(vk.queueSubmit(queue, 1, &submitInfo, *fence));
2261                 VK_CHECK(vk.waitForFences(vkDevice, 1, &fence.get(), true, ~(0ull) /* infinity */));
2262
2263                 invalidateMappedMemoryRange(vk, vkDevice, readImageBufferMemory->getMemory(), readImageBufferMemory->getOffset(), imageSizeBytes);
2264
2265                 const tcu::ConstPixelBufferAccess                               resultAccess                            (resultFormat, m_renderSize.x(), m_renderSize.y(), 1, readImageBufferMemory->getHostPtr());
2266
2267                 m_resultImage.setStorage(resultFormat, m_renderSize.x(), m_renderSize.y());
2268                 tcu::copy(m_resultImage.getAccess(), resultAccess);
2269         }
2270 }
2271
2272 void ShaderRenderCaseInstance::computeVertexReference (tcu::Surface& result, const QuadGrid& quadGrid)
2273 {
2274         DE_ASSERT(m_evaluator);
2275
2276         // Buffer info.
2277         const int                               width           = result.getWidth();
2278         const int                               height          = result.getHeight();
2279         const int                               gridSize        = quadGrid.getGridSize();
2280         const int                               stride          = gridSize + 1;
2281         const bool                              hasAlpha        = true; // \todo [2015-09-07 elecro] add correct alpha check
2282         ShaderEvalContext               evalCtx         (quadGrid);
2283
2284         // Evaluate color for each vertex.
2285         std::vector<tcu::Vec4>  colors          ((gridSize + 1) * (gridSize + 1));
2286         for (int y = 0; y < gridSize+1; y++)
2287         for (int x = 0; x < gridSize+1; x++)
2288         {
2289                 const float     sx                      = (float)x / (float)gridSize;
2290                 const float     sy                      = (float)y / (float)gridSize;
2291                 const int       vtxNdx          = ((y * (gridSize+1)) + x);
2292
2293                 evalCtx.reset(sx, sy);
2294                 m_evaluator->evaluate(evalCtx);
2295                 DE_ASSERT(!evalCtx.isDiscarded); // Discard is not available in vertex shader.
2296                 tcu::Vec4 color = evalCtx.color;
2297
2298                 if (!hasAlpha)
2299                         color.w() = 1.0f;
2300
2301                 colors[vtxNdx] = color;
2302         }
2303
2304         // Render quads.
2305         for (int y = 0; y < gridSize; y++)
2306         for (int x = 0; x < gridSize; x++)
2307         {
2308                 const float             x0              = (float)x       / (float)gridSize;
2309                 const float             x1              = (float)(x + 1) / (float)gridSize;
2310                 const float             y0              = (float)y       / (float)gridSize;
2311                 const float             y1              = (float)(y + 1) / (float)gridSize;
2312
2313                 const float             sx0             = x0 * (float)width;
2314                 const float             sx1             = x1 * (float)width;
2315                 const float             sy0             = y0 * (float)height;
2316                 const float             sy1             = y1 * (float)height;
2317                 const float             oosx    = 1.0f / (sx1 - sx0);
2318                 const float             oosy    = 1.0f / (sy1 - sy0);
2319
2320                 const int               ix0             = deCeilFloatToInt32(sx0 - 0.5f);
2321                 const int               ix1             = deCeilFloatToInt32(sx1 - 0.5f);
2322                 const int               iy0             = deCeilFloatToInt32(sy0 - 0.5f);
2323                 const int               iy1             = deCeilFloatToInt32(sy1 - 0.5f);
2324
2325                 const int               v00             = (y * stride) + x;
2326                 const int               v01             = (y * stride) + x + 1;
2327                 const int               v10             = ((y + 1) * stride) + x;
2328                 const int               v11             = ((y + 1) * stride) + x + 1;
2329                 const tcu::Vec4 c00             = colors[v00];
2330                 const tcu::Vec4 c01             = colors[v01];
2331                 const tcu::Vec4 c10             = colors[v10];
2332                 const tcu::Vec4 c11             = colors[v11];
2333
2334                 //printf("(%d,%d) -> (%f..%f, %f..%f) (%d..%d, %d..%d)\n", x, y, sx0, sx1, sy0, sy1, ix0, ix1, iy0, iy1);
2335
2336                 for (int iy = iy0; iy < iy1; iy++)
2337                 for (int ix = ix0; ix < ix1; ix++)
2338                 {
2339                         DE_ASSERT(deInBounds32(ix, 0, width));
2340                         DE_ASSERT(deInBounds32(iy, 0, height));
2341
2342                         const float                     sfx             = (float)ix + 0.5f;
2343                         const float                     sfy             = (float)iy + 0.5f;
2344                         const float                     fx1             = deFloatClamp((sfx - sx0) * oosx, 0.0f, 1.0f);
2345                         const float                     fy1             = deFloatClamp((sfy - sy0) * oosy, 0.0f, 1.0f);
2346
2347                         // Triangle quad interpolation.
2348                         const bool                      tri             = fx1 + fy1 <= 1.0f;
2349                         const float                     tx              = tri ? fx1 : (1.0f-fx1);
2350                         const float                     ty              = tri ? fy1 : (1.0f-fy1);
2351                         const tcu::Vec4&        t0              = tri ? c00 : c11;
2352                         const tcu::Vec4&        t1              = tri ? c01 : c10;
2353                         const tcu::Vec4&        t2              = tri ? c10 : c01;
2354                         const tcu::Vec4         color   = t0 + (t1-t0)*tx + (t2-t0)*ty;
2355
2356                         result.setPixel(ix, iy, tcu::RGBA(color));
2357                 }
2358         }
2359 }
2360
2361 void ShaderRenderCaseInstance::computeFragmentReference (tcu::Surface& result, const QuadGrid& quadGrid)
2362 {
2363         DE_ASSERT(m_evaluator);
2364
2365         // Buffer info.
2366         const int                       width           = result.getWidth();
2367         const int                       height          = result.getHeight();
2368         const bool                      hasAlpha        = true;  // \todo [2015-09-07 elecro] add correct alpha check
2369         ShaderEvalContext       evalCtx         (quadGrid);
2370
2371         // Render.
2372         for (int y = 0; y < height; y++)
2373         for (int x = 0; x < width; x++)
2374         {
2375                 const float sx = ((float)x + 0.5f) / (float)width;
2376                 const float sy = ((float)y + 0.5f) / (float)height;
2377
2378                 evalCtx.reset(sx, sy);
2379                 m_evaluator->evaluate(evalCtx);
2380                 // Select either clear color or computed color based on discarded bit.
2381                 tcu::Vec4 color = evalCtx.isDiscarded ? m_clearColor : evalCtx.color;
2382
2383                 if (!hasAlpha)
2384                         color.w() = 1.0f;
2385
2386                 result.setPixel(x, y, tcu::RGBA(color));
2387         }
2388 }
2389
2390 bool ShaderRenderCaseInstance::compareImages (const tcu::Surface& resImage, const tcu::Surface& refImage, float errorThreshold)
2391 {
2392         return tcu::fuzzyCompare(m_context.getTestContext().getLog(), "ComparisonResult", "Image comparison result", refImage, resImage, errorThreshold, tcu::COMPARE_LOG_RESULT);
2393 }
2394
2395 } // sr
2396 } // vkt