Add testing for sparse D/S/DS images.
[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 deUint32   MAX_RENDER_WIDTH        = 128;
62 static const deUint32   MAX_RENDER_HEIGHT       = 128;
63 static const tcu::Vec4  DEFAULT_CLEAR_COLOR     = tcu::Vec4(0.125f, 0.25f, 0.5f, 1.0f);
64
65 static VkImageViewType textureTypeToImageViewType (TextureBinding::Type type)
66 {
67         switch (type)
68         {
69                 case TextureBinding::TYPE_1D:                   return VK_IMAGE_VIEW_TYPE_1D;
70                 case TextureBinding::TYPE_2D:                   return VK_IMAGE_VIEW_TYPE_2D;
71                 case TextureBinding::TYPE_3D:                   return VK_IMAGE_VIEW_TYPE_3D;
72                 case TextureBinding::TYPE_CUBE_MAP:             return VK_IMAGE_VIEW_TYPE_CUBE;
73                 case TextureBinding::TYPE_1D_ARRAY:             return VK_IMAGE_VIEW_TYPE_1D_ARRAY;
74                 case TextureBinding::TYPE_2D_ARRAY:             return VK_IMAGE_VIEW_TYPE_2D_ARRAY;
75                 case TextureBinding::TYPE_CUBE_ARRAY:   return VK_IMAGE_VIEW_TYPE_CUBE_ARRAY;
76
77                 default:
78                         DE_FATAL("Impossible");
79                         return (VkImageViewType)0;
80         }
81 }
82
83 static VkImageType viewTypeToImageType (VkImageViewType type)
84 {
85         switch (type)
86         {
87                 case VK_IMAGE_VIEW_TYPE_1D:
88                 case VK_IMAGE_VIEW_TYPE_1D_ARRAY:               return VK_IMAGE_TYPE_1D;
89                 case VK_IMAGE_VIEW_TYPE_2D:
90                 case VK_IMAGE_VIEW_TYPE_2D_ARRAY:               return VK_IMAGE_TYPE_2D;
91                 case VK_IMAGE_VIEW_TYPE_3D:                             return VK_IMAGE_TYPE_3D;
92                 case VK_IMAGE_VIEW_TYPE_CUBE:
93                 case VK_IMAGE_VIEW_TYPE_CUBE_ARRAY:             return VK_IMAGE_TYPE_2D;
94
95                 default:
96                         DE_FATAL("Impossible");
97                         return (VkImageType)0;
98         }
99 }
100
101 /*! Gets the next multiple of a given divisor */
102 static deUint32 getNextMultiple (deUint32 divisor, deUint32 value)
103 {
104         if (value % divisor == 0)
105         {
106                 return value;
107         }
108         return value + divisor - (value % divisor);
109 }
110
111 /*! Gets the next value that is multiple of all given divisors */
112 static deUint32 getNextMultiple (const std::vector<deUint32>& divisors, deUint32 value)
113 {
114         deUint32        nextMultiple            = value;
115         bool            nextMultipleFound       = false;
116
117         while (true)
118         {
119                 nextMultipleFound = true;
120
121                 for (size_t divNdx = 0; divNdx < divisors.size(); divNdx++)
122                         nextMultipleFound = nextMultipleFound && (nextMultiple % divisors[divNdx] == 0);
123
124                 if (nextMultipleFound)
125                         break;
126
127                 DE_ASSERT(nextMultiple < ~((deUint32)0u));
128                 nextMultiple = getNextMultiple(divisors[0], nextMultiple + 1);
129         }
130
131         return nextMultiple;
132 }
133
134 } // anonymous
135
136 // QuadGrid.
137
138 class QuadGrid
139 {
140 public:
141                                                                                         QuadGrid                                (int                                                                    gridSize,
142                                                                                                                                          int                                                                    screenWidth,
143                                                                                                                                          int                                                                    screenHeight,
144                                                                                                                                          const tcu::Vec4&                                               constCoords,
145                                                                                                                                          const std::vector<tcu::Mat4>&                  userAttribTransforms,
146                                                                                                                                          const std::vector<TextureBindingSp>&   textures);
147                                                                                         ~QuadGrid                               (void);
148
149         int                                                                             getGridSize                             (void) const { return m_gridSize; }
150         int                                                                             getNumVertices                  (void) const { return m_numVertices; }
151         int                                                                             getNumTriangles                 (void) const { return m_numTriangles; }
152         const tcu::Vec4&                                                getConstCoords                  (void) const { return m_constCoords; }
153         const std::vector<tcu::Mat4>                    getUserAttribTransforms (void) const { return m_userAttribTransforms; }
154         const std::vector<TextureBindingSp>&    getTextures                             (void) const { return m_textures; }
155
156         const tcu::Vec4*                                                getPositions                    (void) const { return &m_positions[0]; }
157         const float*                                                    getAttribOne                    (void) const { return &m_attribOne[0]; }
158         const tcu::Vec4*                                                getCoords                               (void) const { return &m_coords[0]; }
159         const tcu::Vec4*                                                getUnitCoords                   (void) const { return &m_unitCoords[0]; }
160
161         const tcu::Vec4*                                                getUserAttrib                   (int attribNdx) const { return &m_userAttribs[attribNdx][0]; }
162         const deUint16*                                                 getIndices                              (void) const { return &m_indices[0]; }
163
164         tcu::Vec4                                                               getCoords                               (float sx, float sy) const;
165         tcu::Vec4                                                               getUnitCoords                   (float sx, float sy) const;
166
167         int                                                                             getNumUserAttribs               (void) const { return (int)m_userAttribTransforms.size(); }
168         tcu::Vec4                                                               getUserAttrib                   (int attribNdx, float sx, float sy) const;
169
170 private:
171         const int                                                               m_gridSize;
172         const int                                                               m_numVertices;
173         const int                                                               m_numTriangles;
174         const tcu::Vec4                                                 m_constCoords;
175         const std::vector<tcu::Mat4>                    m_userAttribTransforms;
176
177         const std::vector<TextureBindingSp>&    m_textures;
178
179         std::vector<tcu::Vec4>                                  m_screenPos;
180         std::vector<tcu::Vec4>                                  m_positions;
181         std::vector<tcu::Vec4>                                  m_coords;               //!< Near-unit coordinates, roughly [-2.0 .. 2.0].
182         std::vector<tcu::Vec4>                                  m_unitCoords;   //!< Positive-only coordinates [0.0 .. 1.5].
183         std::vector<float>                                              m_attribOne;
184         std::vector<tcu::Vec4>                                  m_userAttribs[ShaderEvalContext::MAX_TEXTURES];
185         std::vector<deUint16>                                   m_indices;
186 };
187
188 QuadGrid::QuadGrid (int                                                                         gridSize,
189                                         int                                                                             width,
190                                         int                                                                             height,
191                                         const tcu::Vec4&                                                constCoords,
192                                         const std::vector<tcu::Mat4>&                   userAttribTransforms,
193                                         const std::vector<TextureBindingSp>&    textures)
194         : m_gridSize                            (gridSize)
195         , m_numVertices                         ((gridSize + 1) * (gridSize + 1))
196         , m_numTriangles                        (gridSize * gridSize * 2)
197         , m_constCoords                         (constCoords)
198         , m_userAttribTransforms        (userAttribTransforms)
199         , m_textures                            (textures)
200 {
201         const tcu::Vec4 viewportScale   ((float)width, (float)height, 0.0f, 0.0f);
202
203         // Compute vertices.
204         m_screenPos.resize(m_numVertices);
205         m_positions.resize(m_numVertices);
206         m_coords.resize(m_numVertices);
207         m_unitCoords.resize(m_numVertices);
208         m_attribOne.resize(m_numVertices);
209
210         // User attributes.
211         for (int attrNdx = 0; attrNdx < DE_LENGTH_OF_ARRAY(m_userAttribs); attrNdx++)
212                 m_userAttribs[attrNdx].resize(m_numVertices);
213
214         for (int y = 0; y < gridSize+1; y++)
215         for (int x = 0; x < gridSize+1; x++)
216         {
217                 float           sx                      = (float)x / (float)gridSize;
218                 float           sy                      = (float)y / (float)gridSize;
219                 float           fx                      = 2.0f * sx - 1.0f;
220                 float           fy                      = 2.0f * sy - 1.0f;
221                 int                     vtxNdx          = ((y * (gridSize+1)) + x);
222
223                 m_positions[vtxNdx]             = tcu::Vec4(fx, fy, 0.0f, 1.0f);
224                 m_coords[vtxNdx]                = getCoords(sx, sy);
225                 m_unitCoords[vtxNdx]    = getUnitCoords(sx, sy);
226                 m_attribOne[vtxNdx]             = 1.0f;
227
228                 m_screenPos[vtxNdx]             = tcu::Vec4(sx, sy, 0.0f, 1.0f) * viewportScale;
229
230                 for (int attribNdx = 0; attribNdx < getNumUserAttribs(); attribNdx++)
231                         m_userAttribs[attribNdx][vtxNdx] = getUserAttrib(attribNdx, sx, sy);
232         }
233
234         // Compute indices.
235         m_indices.resize(3 * m_numTriangles);
236         for (int y = 0; y < gridSize; y++)
237         for (int x = 0; x < gridSize; x++)
238         {
239                 int stride                              = gridSize + 1;
240                 int v00                                 = (y * stride) + x;
241                 int v01                                 = (y * stride) + x + 1;
242                 int v10                                 = ((y+1) * stride) + x;
243                 int v11                                 = ((y+1) * stride) + x + 1;
244
245                 int baseNdx                             = ((y * gridSize) + x) * 6;
246                 m_indices[baseNdx + 0]  = (deUint16)v10;
247                 m_indices[baseNdx + 1]  = (deUint16)v00;
248                 m_indices[baseNdx + 2]  = (deUint16)v01;
249
250                 m_indices[baseNdx + 3]  = (deUint16)v10;
251                 m_indices[baseNdx + 4]  = (deUint16)v01;
252                 m_indices[baseNdx + 5]  = (deUint16)v11;
253         }
254 }
255
256 QuadGrid::~QuadGrid (void)
257 {
258 }
259
260 inline tcu::Vec4 QuadGrid::getCoords (float sx, float sy) const
261 {
262         const float fx = 2.0f * sx - 1.0f;
263         const float fy = 2.0f * sy - 1.0f;
264         return tcu::Vec4(fx, fy, -fx + 0.33f*fy, -0.275f*fx - fy);
265 }
266
267 inline tcu::Vec4 QuadGrid::getUnitCoords (float sx, float sy) const
268 {
269         return tcu::Vec4(sx, sy, 0.33f*sx + 0.5f*sy, 0.5f*sx + 0.25f*sy);
270 }
271
272 inline tcu::Vec4 QuadGrid::getUserAttrib (int attribNdx, float sx, float sy) const
273 {
274         // homogeneous normalized screen-space coordinates
275         return m_userAttribTransforms[attribNdx] * tcu::Vec4(sx, sy, 0.0f, 1.0f);
276 }
277
278 // TextureBinding
279
280 TextureBinding::TextureBinding (const tcu::Archive&     archive,
281                                                                 const char*                     filename,
282                                                                 const Type                      type,
283                                                                 const tcu::Sampler&     sampler)
284         : m_type        (type)
285         , m_sampler     (sampler)
286 {
287         switch(m_type)
288         {
289                 case TYPE_2D: m_binding.tex2D = loadTexture2D(archive, filename).release(); break;
290                 default:
291                         DE_FATAL("Unsupported texture type");
292         }
293 }
294
295 TextureBinding::TextureBinding (const tcu::Texture1D* tex1D, const tcu::Sampler& sampler)
296         : m_type        (TYPE_1D)
297         , m_sampler     (sampler)
298 {
299         m_binding.tex1D = tex1D;
300 }
301
302 TextureBinding::TextureBinding (const tcu::Texture2D* tex2D, const tcu::Sampler& sampler)
303         : m_type        (TYPE_2D)
304         , m_sampler     (sampler)
305 {
306         m_binding.tex2D = tex2D;
307 }
308
309 TextureBinding::TextureBinding (const tcu::Texture3D* tex3D, const tcu::Sampler& sampler)
310         : m_type        (TYPE_3D)
311         , m_sampler     (sampler)
312 {
313         m_binding.tex3D = tex3D;
314 }
315
316 TextureBinding::TextureBinding (const tcu::TextureCube* texCube, const tcu::Sampler& sampler)
317         : m_type        (TYPE_CUBE_MAP)
318         , m_sampler     (sampler)
319 {
320         m_binding.texCube = texCube;
321 }
322
323 TextureBinding::TextureBinding (const tcu::Texture1DArray* tex1DArray, const tcu::Sampler& sampler)
324         : m_type        (TYPE_1D_ARRAY)
325         , m_sampler     (sampler)
326 {
327         m_binding.tex1DArray = tex1DArray;
328 }
329
330 TextureBinding::TextureBinding (const tcu::Texture2DArray* tex2DArray, const tcu::Sampler& sampler)
331         : m_type        (TYPE_2D_ARRAY)
332         , m_sampler     (sampler)
333 {
334         m_binding.tex2DArray = tex2DArray;
335 }
336
337 TextureBinding::TextureBinding (const tcu::TextureCubeArray* texCubeArray, const tcu::Sampler& sampler)
338         : m_type        (TYPE_CUBE_ARRAY)
339         , m_sampler     (sampler)
340 {
341         m_binding.texCubeArray = texCubeArray;
342 }
343
344 TextureBinding::~TextureBinding (void)
345 {
346         switch(m_type)
347         {
348                 case TYPE_1D:                   delete m_binding.tex1D;                 break;
349                 case TYPE_2D:                   delete m_binding.tex2D;                 break;
350                 case TYPE_3D:                   delete m_binding.tex3D;                 break;
351                 case TYPE_CUBE_MAP:             delete m_binding.texCube;               break;
352                 case TYPE_1D_ARRAY:             delete m_binding.tex1DArray;    break;
353                 case TYPE_2D_ARRAY:             delete m_binding.tex2DArray;    break;
354                 case TYPE_CUBE_ARRAY:   delete m_binding.texCubeArray;  break;
355                 default:                                                                                                break;
356         }
357 }
358
359 de::MovePtr<tcu::Texture2D> TextureBinding::loadTexture2D (const tcu::Archive& archive, const char* filename)
360 {
361         tcu::TextureLevel level;
362         tcu::ImageIO::loadImage(level, archive, filename);
363
364         TCU_CHECK_INTERNAL(level.getFormat() == tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8) ||
365                                            level.getFormat() == tcu::TextureFormat(tcu::TextureFormat::RGB, tcu::TextureFormat::UNORM_INT8));
366
367         // \todo [2015-10-08 elecro] for some reason we get better when using RGBA texture even in RGB case, this needs to be investigated
368         de::MovePtr<tcu::Texture2D> texture(new tcu::Texture2D(tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8), level.getWidth(), level.getHeight()));
369
370         // Fill level 0.
371         texture->allocLevel(0);
372         tcu::copy(texture->getLevel(0), level.getAccess());
373
374         return texture;
375 }
376
377 // ShaderEvalContext.
378
379 ShaderEvalContext::ShaderEvalContext (const QuadGrid& quadGrid)
380         : constCoords   (quadGrid.getConstCoords())
381         , isDiscarded   (false)
382         , m_quadGrid    (quadGrid)
383 {
384         const std::vector<TextureBindingSp>& bindings = m_quadGrid.getTextures();
385         DE_ASSERT((int)bindings.size() <= MAX_TEXTURES);
386
387         // Fill in texture array.
388         for (int ndx = 0; ndx < (int)bindings.size(); ndx++)
389         {
390                 const TextureBinding& binding = *bindings[ndx];
391
392                 if (binding.getType() == TextureBinding::TYPE_NONE)
393                         continue;
394
395                 textures[ndx].sampler = binding.getSampler();
396
397                 switch (binding.getType())
398                 {
399                         case TextureBinding::TYPE_1D:                   textures[ndx].tex1D                     = &binding.get1D();                     break;
400                         case TextureBinding::TYPE_2D:                   textures[ndx].tex2D                     = &binding.get2D();                     break;
401                         case TextureBinding::TYPE_3D:                   textures[ndx].tex3D                     = &binding.get3D();                     break;
402                         case TextureBinding::TYPE_CUBE_MAP:             textures[ndx].texCube           = &binding.getCube();           break;
403                         case TextureBinding::TYPE_1D_ARRAY:             textures[ndx].tex1DArray        = &binding.get1DArray();        break;
404                         case TextureBinding::TYPE_2D_ARRAY:             textures[ndx].tex2DArray        = &binding.get2DArray();        break;
405                         case TextureBinding::TYPE_CUBE_ARRAY:   textures[ndx].texCubeArray      = &binding.getCubeArray();      break;
406                         default:
407                                 TCU_THROW(InternalError, "Handling of texture binding type not implemented");
408                 }
409         }
410 }
411
412 ShaderEvalContext::~ShaderEvalContext (void)
413 {
414 }
415
416 void ShaderEvalContext::reset (float sx, float sy)
417 {
418         // Clear old values
419         color           = tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f);
420         isDiscarded     = false;
421
422         // Compute coords
423         coords          = m_quadGrid.getCoords(sx, sy);
424         unitCoords      = m_quadGrid.getUnitCoords(sx, sy);
425
426         // Compute user attributes.
427         const int numAttribs = m_quadGrid.getNumUserAttribs();
428         DE_ASSERT(numAttribs <= MAX_USER_ATTRIBS);
429         for (int attribNdx = 0; attribNdx < numAttribs; attribNdx++)
430                 in[attribNdx] = m_quadGrid.getUserAttrib(attribNdx, sx, sy);
431 }
432
433 tcu::Vec4 ShaderEvalContext::texture2D (int unitNdx, const tcu::Vec2& texCoords)
434 {
435         if (textures[unitNdx].tex2D)
436                 return textures[unitNdx].tex2D->sample(textures[unitNdx].sampler, texCoords.x(), texCoords.y(), 0.0f);
437         else
438                 return tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f);
439 }
440
441 // ShaderEvaluator.
442
443 ShaderEvaluator::ShaderEvaluator (void)
444         : m_evalFunc(DE_NULL)
445 {
446 }
447
448 ShaderEvaluator::ShaderEvaluator (ShaderEvalFunc evalFunc)
449         : m_evalFunc(evalFunc)
450 {
451 }
452
453 ShaderEvaluator::~ShaderEvaluator (void)
454 {
455 }
456
457 void ShaderEvaluator::evaluate (ShaderEvalContext& ctx) const
458 {
459         DE_ASSERT(m_evalFunc);
460         m_evalFunc(ctx);
461 }
462
463 // UniformSetup.
464
465 UniformSetup::UniformSetup (void)
466         : m_setupFunc(DE_NULL)
467 {
468 }
469
470 UniformSetup::UniformSetup (UniformSetupFunc setupFunc)
471         : m_setupFunc(setupFunc)
472 {
473 }
474
475 UniformSetup::~UniformSetup (void)
476 {
477 }
478
479 void UniformSetup::setup (ShaderRenderCaseInstance& instance, const tcu::Vec4& constCoords) const
480 {
481         if (m_setupFunc)
482                 m_setupFunc(instance, constCoords);
483 }
484
485 // ShaderRenderCase.
486
487 ShaderRenderCase::ShaderRenderCase (tcu::TestContext&                   testCtx,
488                                                                         const std::string&                      name,
489                                                                         const std::string&                      description,
490                                                                         const bool                                      isVertexCase,
491                                                                         const ShaderEvalFunc            evalFunc,
492                                                                         const UniformSetup*                     uniformSetup,
493                                                                         const AttributeSetupFunc        attribFunc)
494         : vkt::TestCase         (testCtx, name, description)
495         , m_isVertexCase        (isVertexCase)
496         , m_evaluator           (new ShaderEvaluator(evalFunc))
497         , m_uniformSetup        (uniformSetup ? uniformSetup : new UniformSetup())
498         , m_attribFunc          (attribFunc)
499 {}
500
501 ShaderRenderCase::ShaderRenderCase (tcu::TestContext&                   testCtx,
502                                                                         const std::string&                      name,
503                                                                         const std::string&                      description,
504                                                                         const bool                                      isVertexCase,
505                                                                         const ShaderEvaluator*          evaluator,
506                                                                         const UniformSetup*                     uniformSetup,
507                                                                         const AttributeSetupFunc        attribFunc)
508         : vkt::TestCase         (testCtx, name, description)
509         , m_isVertexCase        (isVertexCase)
510         , m_evaluator           (evaluator)
511         , m_uniformSetup        (uniformSetup ? uniformSetup : new UniformSetup())
512         , m_attribFunc          (attribFunc)
513 {}
514
515 ShaderRenderCase::~ShaderRenderCase (void)
516 {
517 }
518
519 void ShaderRenderCase::initPrograms (vk::SourceCollections& programCollection) const
520 {
521         programCollection.glslSources.add("vert") << glu::VertexSource(m_vertShaderSource);
522         programCollection.glslSources.add("frag") << glu::FragmentSource(m_fragShaderSource);
523 }
524
525 TestInstance* ShaderRenderCase::createInstance (Context& context) const
526 {
527         DE_ASSERT(m_evaluator != DE_NULL);
528         DE_ASSERT(m_uniformSetup != DE_NULL);
529         return new ShaderRenderCaseInstance(context, m_isVertexCase, *m_evaluator, *m_uniformSetup, m_attribFunc);
530 }
531
532 // ShaderRenderCaseInstance.
533
534 ShaderRenderCaseInstance::ShaderRenderCaseInstance (Context& context)
535         : vkt::TestInstance             (context)
536         , m_imageBackingMode    (IMAGE_BACKING_MODE_REGULAR)
537         , m_quadGridSize                (static_cast<deUint32>(GRID_SIZE_DEFAULT_FRAGMENT))
538         , m_sparseContext               (createSparseContext())
539         , m_memAlloc                    (getAllocator())
540         , m_clearColor                  (DEFAULT_CLEAR_COLOR)
541         , m_isVertexCase                (false)
542         , m_vertexShaderName    ("vert")
543         , m_fragmentShaderName  ("frag")
544         , m_renderSize                  (MAX_RENDER_WIDTH, MAX_RENDER_HEIGHT)
545         , m_colorFormat                 (VK_FORMAT_R8G8B8A8_UNORM)
546         , m_evaluator                   (DE_NULL)
547         , m_uniformSetup                (DE_NULL)
548         , m_attribFunc                  (DE_NULL)
549         , m_sampleCount                 (VK_SAMPLE_COUNT_1_BIT)
550 {
551 }
552
553
554 ShaderRenderCaseInstance::ShaderRenderCaseInstance (Context&                                    context,
555                                                                                                         const bool                                      isVertexCase,
556                                                                                                         const ShaderEvaluator&          evaluator,
557                                                                                                         const UniformSetup&                     uniformSetup,
558                                                                                                         const AttributeSetupFunc        attribFunc,
559                                                                                                         const ImageBackingMode          imageBackingMode,
560                                                                                                         const deUint32                          gridSize)
561         : vkt::TestInstance             (context)
562         , m_imageBackingMode    (imageBackingMode)
563         , m_quadGridSize                (gridSize == static_cast<deUint32>(GRID_SIZE_DEFAULTS)
564                                                          ? (isVertexCase
565                                                                 ? static_cast<deUint32>(GRID_SIZE_DEFAULT_VERTEX)
566                                                                 : static_cast<deUint32>(GRID_SIZE_DEFAULT_FRAGMENT))
567                                                          : gridSize)
568         , m_sparseContext               (createSparseContext())
569         , m_memAlloc                    (getAllocator())
570         , m_clearColor                  (DEFAULT_CLEAR_COLOR)
571         , m_isVertexCase                (isVertexCase)
572         , m_vertexShaderName    ("vert")
573         , m_fragmentShaderName  ("frag")
574         , m_renderSize                  (MAX_RENDER_WIDTH, MAX_RENDER_HEIGHT)
575         , m_colorFormat                 (VK_FORMAT_R8G8B8A8_UNORM)
576         , m_evaluator                   (&evaluator)
577         , m_uniformSetup                (&uniformSetup)
578         , m_attribFunc                  (attribFunc)
579         , m_sampleCount                 (VK_SAMPLE_COUNT_1_BIT)
580 {
581 }
582
583 ShaderRenderCaseInstance::ShaderRenderCaseInstance (Context&                                    context,
584                                                                                                         const bool                                      isVertexCase,
585                                                                                                         const ShaderEvaluator*          evaluator,
586                                                                                                         const UniformSetup*                     uniformSetup,
587                                                                                                         const AttributeSetupFunc        attribFunc,
588                                                                                                         const ImageBackingMode          imageBackingMode,
589                                                                                                         const deUint32                          gridSize)
590         : vkt::TestInstance             (context)
591         , m_imageBackingMode    (imageBackingMode)
592         , m_quadGridSize                (gridSize == static_cast<deUint32>(GRID_SIZE_DEFAULTS)
593                                                          ? (isVertexCase
594                                                                 ? static_cast<deUint32>(GRID_SIZE_DEFAULT_VERTEX)
595                                                                 : static_cast<deUint32>(GRID_SIZE_DEFAULT_FRAGMENT))
596                                                          : gridSize)
597         , m_sparseContext               (createSparseContext())
598         , m_memAlloc                    (getAllocator())
599         , m_clearColor                  (DEFAULT_CLEAR_COLOR)
600         , m_isVertexCase                (isVertexCase)
601         , m_vertexShaderName    ("vert")
602         , m_fragmentShaderName  ("frag")
603         , m_renderSize                  (MAX_RENDER_WIDTH, MAX_RENDER_HEIGHT)
604         , m_colorFormat                 (VK_FORMAT_R8G8B8A8_UNORM)
605         , m_evaluator                   (evaluator)
606         , m_uniformSetup                (uniformSetup)
607         , m_attribFunc                  (attribFunc)
608         , m_sampleCount                 (VK_SAMPLE_COUNT_1_BIT)
609 {
610 }
611
612 static deUint32 findQueueFamilyIndexWithCaps (const InstanceInterface& vkInstance, VkPhysicalDevice physicalDevice, VkQueueFlags requiredCaps)
613 {
614         const std::vector<VkQueueFamilyProperties>      queueProps      = getPhysicalDeviceQueueFamilyProperties(vkInstance, physicalDevice);
615
616         for (size_t queueNdx = 0; queueNdx < queueProps.size(); queueNdx++)
617         {
618                 if ((queueProps[queueNdx].queueFlags & requiredCaps) == requiredCaps)
619                         return (deUint32)queueNdx;
620         }
621
622         TCU_THROW(NotSupportedError, "No matching queue found");
623 }
624
625
626 ShaderRenderCaseInstance::SparseContext::SparseContext (vkt::Context& context)
627         : m_context                             (context)
628         , m_queueFamilyIndex    (findQueueFamilyIndexWithCaps(context.getInstanceInterface(), context.getPhysicalDevice(), VK_QUEUE_GRAPHICS_BIT|VK_QUEUE_SPARSE_BINDING_BIT))
629         , m_device                              (createDevice())
630         , m_deviceInterface             (context.getInstanceInterface(), *m_device)
631         , m_queue                               (getDeviceQueue(m_deviceInterface, *m_device, m_queueFamilyIndex, 0))
632         , m_allocator                   (createAllocator())
633 {
634 }
635
636 Move<VkDevice> ShaderRenderCaseInstance::SparseContext::createDevice () const
637 {
638         const InstanceInterface&                                vk                                      = m_context.getInstanceInterface();
639         const VkPhysicalDevice                                  physicalDevice          = m_context.getPhysicalDevice();
640         const VkPhysicalDeviceFeatures                  deviceFeatures          = getPhysicalDeviceFeatures(vk, physicalDevice);
641
642         VkDeviceQueueCreateInfo                                 queueInfo;
643         VkDeviceCreateInfo                                              deviceInfo;
644         const float                                                             queuePriority           = 1.0f;
645
646         deMemset(&queueInfo,    0, sizeof(queueInfo));
647         deMemset(&deviceInfo,   0, sizeof(deviceInfo));
648
649         queueInfo.sType                                                 = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
650         queueInfo.pNext                                                 = DE_NULL;
651         queueInfo.flags                                                 = (VkDeviceQueueCreateFlags)0u;
652         queueInfo.queueFamilyIndex                              = m_queueFamilyIndex;
653         queueInfo.queueCount                                    = 1u;
654         queueInfo.pQueuePriorities                              = &queuePriority;
655
656         deviceInfo.sType                                                = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
657         deviceInfo.pNext                                                = DE_NULL;
658         deviceInfo.queueCreateInfoCount                 = 1u;
659         deviceInfo.pQueueCreateInfos                    = &queueInfo;
660         deviceInfo.enabledExtensionCount                = 0u;
661         deviceInfo.ppEnabledExtensionNames              = DE_NULL;
662         deviceInfo.enabledLayerCount                    = 0u;
663         deviceInfo.ppEnabledLayerNames                  = DE_NULL;
664         deviceInfo.pEnabledFeatures                             = &deviceFeatures;
665
666         return vk::createDevice(vk, physicalDevice, &deviceInfo);
667 }
668
669 vk::Allocator* ShaderRenderCaseInstance::SparseContext::createAllocator () const
670 {
671         const VkPhysicalDeviceMemoryProperties memoryProperties = getPhysicalDeviceMemoryProperties(m_context.getInstanceInterface(), m_context.getPhysicalDevice());
672         return new SimpleAllocator(m_deviceInterface, *m_device, memoryProperties);
673 }
674
675 ShaderRenderCaseInstance::SparseContext* ShaderRenderCaseInstance::createSparseContext (void) const
676 {
677         if (m_imageBackingMode == IMAGE_BACKING_MODE_SPARSE)
678         {
679                 return new SparseContext(m_context);
680         }
681
682         return DE_NULL;
683 }
684
685 vk::Allocator& ShaderRenderCaseInstance::getAllocator (void) const
686 {
687         if (m_imageBackingMode == IMAGE_BACKING_MODE_SPARSE)
688         {
689                 return *m_sparseContext->m_allocator;
690         }
691
692         return m_context.getDefaultAllocator();
693 }
694
695 ShaderRenderCaseInstance::~ShaderRenderCaseInstance (void)
696 {
697 }
698
699 VkDevice ShaderRenderCaseInstance::getDevice (void) const
700 {
701         if (m_imageBackingMode == IMAGE_BACKING_MODE_SPARSE)
702                 return *m_sparseContext->m_device;
703
704         return m_context.getDevice();
705 }
706
707 deUint32 ShaderRenderCaseInstance::getUniversalQueueFamilyIndex (void) const
708 {
709         if (m_imageBackingMode == IMAGE_BACKING_MODE_SPARSE)
710                 return m_sparseContext->m_queueFamilyIndex;
711
712         return m_context.getUniversalQueueFamilyIndex();
713 }
714
715 const DeviceInterface& ShaderRenderCaseInstance::getDeviceInterface (void) const
716 {
717         if (m_imageBackingMode == IMAGE_BACKING_MODE_SPARSE)
718                 return m_sparseContext->m_deviceInterface;
719
720         return m_context.getDeviceInterface();
721 }
722
723 VkQueue ShaderRenderCaseInstance::getUniversalQueue (void) const
724 {
725         if (m_imageBackingMode == IMAGE_BACKING_MODE_SPARSE)
726                 return m_sparseContext->m_queue;
727
728         return m_context.getUniversalQueue();
729 }
730
731 VkPhysicalDevice ShaderRenderCaseInstance::getPhysicalDevice (void) const
732 {
733         // Same in sparse and regular case
734         return m_context.getPhysicalDevice();
735 }
736
737 const InstanceInterface& ShaderRenderCaseInstance::getInstanceInterface (void) const
738 {
739         // Same in sparse and regular case
740         return m_context.getInstanceInterface();
741 }
742
743 tcu::TestStatus ShaderRenderCaseInstance::iterate (void)
744 {
745         setup();
746
747         // Create quad grid.
748         const tcu::UVec2        viewportSize    = getViewportSize();
749         const int                       width                   = viewportSize.x();
750         const int                       height                  = viewportSize.y();
751
752         m_quadGrid                                                      = de::MovePtr<QuadGrid>(new QuadGrid(m_quadGridSize, width, height, getDefaultConstCoords(), m_userAttribTransforms, m_textures));
753
754         // Render result.
755         tcu::Surface            resImage                (width, height);
756
757         render(m_quadGrid->getNumVertices(), m_quadGrid->getNumTriangles(), m_quadGrid->getIndices(), m_quadGrid->getConstCoords());
758         tcu::copy(resImage.getAccess(), m_resultImage.getAccess());
759
760         // Compute reference.
761         tcu::Surface            refImage                (width, height);
762         if (m_isVertexCase)
763                 computeVertexReference(refImage, *m_quadGrid);
764         else
765                 computeFragmentReference(refImage, *m_quadGrid);
766
767         // Compare.
768         const bool                      compareOk               = compareImages(resImage, refImage, 0.2f);
769
770         if (compareOk)
771                 return tcu::TestStatus::pass("Result image matches reference");
772         else
773                 return tcu::TestStatus::fail("Image mismatch");
774 }
775
776 void ShaderRenderCaseInstance::setup (void)
777 {
778         m_resultImage                                   = tcu::TextureLevel();
779         m_descriptorSetLayoutBuilder    = de::MovePtr<DescriptorSetLayoutBuilder>       (new DescriptorSetLayoutBuilder());
780         m_descriptorPoolBuilder                 = de::MovePtr<DescriptorPoolBuilder>            (new DescriptorPoolBuilder());
781         m_descriptorSetUpdateBuilder    = de::MovePtr<DescriptorSetUpdateBuilder>       (new DescriptorSetUpdateBuilder());
782
783         m_uniformInfos.clear();
784         m_vertexBindingDescription.clear();
785         m_vertexAttributeDescription.clear();
786         m_vertexBuffers.clear();
787         m_vertexBufferAllocs.clear();
788         m_pushConstantRanges.clear();
789 }
790
791 void ShaderRenderCaseInstance::setupUniformData (deUint32 bindingLocation, size_t size, const void* dataPtr)
792 {
793         const VkDevice                                  vkDevice                        = getDevice();
794         const DeviceInterface&                  vk                                      = getDeviceInterface();
795         const deUint32                                  queueFamilyIndex        = getUniversalQueueFamilyIndex();
796
797         const VkBufferCreateInfo                uniformBufferParams     =
798         {
799                 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,           // VkStructureType              sType;
800                 DE_NULL,                                                                        // const void*                  pNext;
801                 0u,                                                                                     // VkBufferCreateFlags  flags;
802                 size,                                                                           // VkDeviceSize                 size;
803                 VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT,                     // VkBufferUsageFlags   usage;
804                 VK_SHARING_MODE_EXCLUSIVE,                                      // VkSharingMode                sharingMode;
805                 1u,                                                                                     // deUint32                             queueFamilyCount;
806                 &queueFamilyIndex                                                       // const deUint32*              pQueueFamilyIndices;
807         };
808
809         Move<VkBuffer>                                  buffer                          = createBuffer(vk, vkDevice, &uniformBufferParams);
810         de::MovePtr<Allocation>                 alloc                           = m_memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *buffer), MemoryRequirement::HostVisible);
811         VK_CHECK(vk.bindBufferMemory(vkDevice, *buffer, alloc->getMemory(), alloc->getOffset()));
812
813         deMemcpy(alloc->getHostPtr(), dataPtr, size);
814         flushMappedMemoryRange(vk, vkDevice, alloc->getMemory(), alloc->getOffset(), size);
815
816         de::MovePtr<BufferUniform> uniformInfo(new BufferUniform());
817         uniformInfo->type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
818         uniformInfo->descriptor = makeDescriptorBufferInfo(*buffer, 0u, size);
819         uniformInfo->location = bindingLocation;
820         uniformInfo->buffer = VkBufferSp(new vk::Unique<VkBuffer>(buffer));
821         uniformInfo->alloc = AllocationSp(alloc.release());
822
823         m_uniformInfos.push_back(UniformInfoSp(new de::UniquePtr<UniformInfo>(uniformInfo)));
824 }
825
826 void ShaderRenderCaseInstance::addUniform (deUint32 bindingLocation, vk::VkDescriptorType descriptorType, size_t dataSize, const void* data)
827 {
828         m_descriptorSetLayoutBuilder->addSingleBinding(descriptorType, vk::VK_SHADER_STAGE_ALL);
829         m_descriptorPoolBuilder->addType(descriptorType);
830
831         setupUniformData(bindingLocation, dataSize, data);
832 }
833
834 void ShaderRenderCaseInstance::addAttribute (deUint32           bindingLocation,
835                                                                                          vk::VkFormat   format,
836                                                                                          deUint32               sizePerElement,
837                                                                                          deUint32               count,
838                                                                                          const void*    dataPtr)
839 {
840         // Add binding specification
841         const deUint32                                                  binding                                 = (deUint32)m_vertexBindingDescription.size();
842         const VkVertexInputBindingDescription   bindingDescription              =
843         {
844                 binding,                                                        // deUint32                             binding;
845                 sizePerElement,                                         // deUint32                             stride;
846                 VK_VERTEX_INPUT_RATE_VERTEX                     // VkVertexInputRate    stepRate;
847         };
848
849         m_vertexBindingDescription.push_back(bindingDescription);
850
851         // Add location and format specification
852         const VkVertexInputAttributeDescription attributeDescription    =
853         {
854                 bindingLocation,                        // deUint32     location;
855                 binding,                                        // deUint32     binding;
856                 format,                                         // VkFormat     format;
857                 0u,                                                     // deUint32     offset;
858         };
859
860         m_vertexAttributeDescription.push_back(attributeDescription);
861
862         // Upload data to buffer
863         const VkDevice                                                  vkDevice                                = getDevice();
864         const DeviceInterface&                                  vk                                              = getDeviceInterface();
865         const deUint32                                                  queueFamilyIndex                = getUniversalQueueFamilyIndex();
866
867         const VkDeviceSize                                              inputSize                               = sizePerElement * count;
868         const VkBufferCreateInfo                                vertexBufferParams              =
869         {
870                 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,           // VkStructureType              sType;
871                 DE_NULL,                                                                        // const void*                  pNext;
872                 0u,                                                                                     // VkBufferCreateFlags  flags;
873                 inputSize,                                                                      // VkDeviceSize                 size;
874                 VK_BUFFER_USAGE_VERTEX_BUFFER_BIT,                      // VkBufferUsageFlags   usage;
875                 VK_SHARING_MODE_EXCLUSIVE,                                      // VkSharingMode                sharingMode;
876                 1u,                                                                                     // deUint32                             queueFamilyCount;
877                 &queueFamilyIndex                                                       // const deUint32*              pQueueFamilyIndices;
878         };
879
880         Move<VkBuffer>                                                  buffer                                  = createBuffer(vk, vkDevice, &vertexBufferParams);
881         de::MovePtr<vk::Allocation>                             alloc                                   = m_memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *buffer), MemoryRequirement::HostVisible);
882         VK_CHECK(vk.bindBufferMemory(vkDevice, *buffer, alloc->getMemory(), alloc->getOffset()));
883
884         deMemcpy(alloc->getHostPtr(), dataPtr, (size_t)inputSize);
885         flushMappedMemoryRange(vk, vkDevice, alloc->getMemory(), alloc->getOffset(), inputSize);
886
887         m_vertexBuffers.push_back(VkBufferSp(new vk::Unique<VkBuffer>(buffer)));
888         m_vertexBufferAllocs.push_back(AllocationSp(alloc.release()));
889 }
890
891 void ShaderRenderCaseInstance::useAttribute (deUint32 bindingLocation, BaseAttributeType type)
892 {
893         const EnabledBaseAttribute attribute =
894         {
895                 bindingLocation,        // deUint32                             location;
896                 type                            // BaseAttributeType    type;
897         };
898         m_enabledBaseAttributes.push_back(attribute);
899 }
900
901 void ShaderRenderCaseInstance::setupUniforms (const tcu::Vec4& constCoords)
902 {
903         if (m_uniformSetup)
904                 m_uniformSetup->setup(*this, constCoords);
905 }
906
907 void ShaderRenderCaseInstance::useUniform (deUint32 bindingLocation, BaseUniformType type)
908 {
909         #define UNIFORM_CASE(type, value) case type: addUniform(bindingLocation, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, value); break
910
911         switch(type)
912         {
913                 // Bool
914                 UNIFORM_CASE(UB_FALSE,  0);
915                 UNIFORM_CASE(UB_TRUE,   1);
916
917                 // BVec4
918                 UNIFORM_CASE(UB4_FALSE, tcu::Vec4(0));
919                 UNIFORM_CASE(UB4_TRUE,  tcu::Vec4(1));
920
921                 // Integer
922                 UNIFORM_CASE(UI_ZERO,   0);
923                 UNIFORM_CASE(UI_ONE,    1);
924                 UNIFORM_CASE(UI_TWO,    2);
925                 UNIFORM_CASE(UI_THREE,  3);
926                 UNIFORM_CASE(UI_FOUR,   4);
927                 UNIFORM_CASE(UI_FIVE,   5);
928                 UNIFORM_CASE(UI_SIX,    6);
929                 UNIFORM_CASE(UI_SEVEN,  7);
930                 UNIFORM_CASE(UI_EIGHT,  8);
931                 UNIFORM_CASE(UI_ONEHUNDREDONE, 101);
932
933                 // IVec2
934                 UNIFORM_CASE(UI2_MINUS_ONE,     tcu::IVec2(-1));
935                 UNIFORM_CASE(UI2_ZERO,          tcu::IVec2(0));
936                 UNIFORM_CASE(UI2_ONE,           tcu::IVec2(1));
937                 UNIFORM_CASE(UI2_TWO,           tcu::IVec2(2));
938                 UNIFORM_CASE(UI2_THREE,         tcu::IVec2(3));
939                 UNIFORM_CASE(UI2_FOUR,          tcu::IVec2(4));
940                 UNIFORM_CASE(UI2_FIVE,          tcu::IVec2(5));
941
942                 // IVec3
943                 UNIFORM_CASE(UI3_MINUS_ONE,     tcu::IVec3(-1));
944                 UNIFORM_CASE(UI3_ZERO,          tcu::IVec3(0));
945                 UNIFORM_CASE(UI3_ONE,           tcu::IVec3(1));
946                 UNIFORM_CASE(UI3_TWO,           tcu::IVec3(2));
947                 UNIFORM_CASE(UI3_THREE,         tcu::IVec3(3));
948                 UNIFORM_CASE(UI3_FOUR,          tcu::IVec3(4));
949                 UNIFORM_CASE(UI3_FIVE,          tcu::IVec3(5));
950
951                 // IVec4
952                 UNIFORM_CASE(UI4_MINUS_ONE, tcu::IVec4(-1));
953                 UNIFORM_CASE(UI4_ZERO,          tcu::IVec4(0));
954                 UNIFORM_CASE(UI4_ONE,           tcu::IVec4(1));
955                 UNIFORM_CASE(UI4_TWO,           tcu::IVec4(2));
956                 UNIFORM_CASE(UI4_THREE,         tcu::IVec4(3));
957                 UNIFORM_CASE(UI4_FOUR,          tcu::IVec4(4));
958                 UNIFORM_CASE(UI4_FIVE,          tcu::IVec4(5));
959
960                 // Float
961                 UNIFORM_CASE(UF_ZERO,           0.0f);
962                 UNIFORM_CASE(UF_ONE,            1.0f);
963                 UNIFORM_CASE(UF_TWO,            2.0f);
964                 UNIFORM_CASE(UF_THREE,          3.0f);
965                 UNIFORM_CASE(UF_FOUR,           4.0f);
966                 UNIFORM_CASE(UF_FIVE,           5.0f);
967                 UNIFORM_CASE(UF_SIX,            6.0f);
968                 UNIFORM_CASE(UF_SEVEN,          7.0f);
969                 UNIFORM_CASE(UF_EIGHT,          8.0f);
970
971                 UNIFORM_CASE(UF_HALF,           1.0f / 2.0f);
972                 UNIFORM_CASE(UF_THIRD,          1.0f / 3.0f);
973                 UNIFORM_CASE(UF_FOURTH,         1.0f / 4.0f);
974                 UNIFORM_CASE(UF_FIFTH,          1.0f / 5.0f);
975                 UNIFORM_CASE(UF_SIXTH,          1.0f / 6.0f);
976                 UNIFORM_CASE(UF_SEVENTH,        1.0f / 7.0f);
977                 UNIFORM_CASE(UF_EIGHTH,         1.0f / 8.0f);
978
979                 // Vec2
980                 UNIFORM_CASE(UV2_MINUS_ONE,     tcu::Vec2(-1.0f));
981                 UNIFORM_CASE(UV2_ZERO,          tcu::Vec2(0.0f));
982                 UNIFORM_CASE(UV2_ONE,           tcu::Vec2(1.0f));
983                 UNIFORM_CASE(UV2_TWO,           tcu::Vec2(2.0f));
984                 UNIFORM_CASE(UV2_THREE,         tcu::Vec2(3.0f));
985
986                 UNIFORM_CASE(UV2_HALF,          tcu::Vec2(1.0f / 2.0f));
987
988                 // Vec3
989                 UNIFORM_CASE(UV3_MINUS_ONE,     tcu::Vec3(-1.0f));
990                 UNIFORM_CASE(UV3_ZERO,          tcu::Vec3(0.0f));
991                 UNIFORM_CASE(UV3_ONE,           tcu::Vec3(1.0f));
992                 UNIFORM_CASE(UV3_TWO,           tcu::Vec3(2.0f));
993                 UNIFORM_CASE(UV3_THREE,         tcu::Vec3(3.0f));
994
995                 UNIFORM_CASE(UV3_HALF,          tcu::Vec3(1.0f / 2.0f));
996
997                 // Vec4
998                 UNIFORM_CASE(UV4_MINUS_ONE,     tcu::Vec4(-1.0f));
999                 UNIFORM_CASE(UV4_ZERO,          tcu::Vec4(0.0f));
1000                 UNIFORM_CASE(UV4_ONE,           tcu::Vec4(1.0f));
1001                 UNIFORM_CASE(UV4_TWO,           tcu::Vec4(2.0f));
1002                 UNIFORM_CASE(UV4_THREE,         tcu::Vec4(3.0f));
1003
1004                 UNIFORM_CASE(UV4_HALF,          tcu::Vec4(1.0f / 2.0f));
1005
1006                 UNIFORM_CASE(UV4_BLACK,         tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f));
1007                 UNIFORM_CASE(UV4_GRAY,          tcu::Vec4(0.5f, 0.5f, 0.5f, 1.0f));
1008                 UNIFORM_CASE(UV4_WHITE,         tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f));
1009
1010                 default:
1011                         m_context.getTestContext().getLog() << tcu::TestLog::Message << "Unknown Uniform type: " << type << tcu::TestLog::EndMessage;
1012                         break;
1013         }
1014
1015         #undef UNIFORM_CASE
1016 }
1017
1018 const tcu::UVec2 ShaderRenderCaseInstance::getViewportSize (void) const
1019 {
1020         return tcu::UVec2(de::min(m_renderSize.x(), MAX_RENDER_WIDTH),
1021                                           de::min(m_renderSize.y(), MAX_RENDER_HEIGHT));
1022 }
1023
1024 void ShaderRenderCaseInstance::setSampleCount (VkSampleCountFlagBits sampleCount)
1025 {
1026         m_sampleCount   = sampleCount;
1027 }
1028
1029 bool ShaderRenderCaseInstance::isMultiSampling (void) const
1030 {
1031         return m_sampleCount != VK_SAMPLE_COUNT_1_BIT;
1032 }
1033
1034 void ShaderRenderCaseInstance::uploadImage (const tcu::TextureFormat&                   texFormat,
1035                                                                                         const TextureData&                                      textureData,
1036                                                                                         const tcu::Sampler&                                     refSampler,
1037                                                                                         deUint32                                                        mipLevels,
1038                                                                                         deUint32                                                        arrayLayers,
1039                                                                                         VkImage                                                         destImage)
1040 {
1041         const VkDevice                                  vkDevice                                = getDevice();
1042         const DeviceInterface&                  vk                                              = getDeviceInterface();
1043         const VkQueue                                   queue                                   = getUniversalQueue();
1044         const deUint32                                  queueFamilyIndex                = getUniversalQueueFamilyIndex();
1045
1046         const bool                                              isShadowSampler                 = refSampler.compare != tcu::Sampler::COMPAREMODE_NONE;
1047         const VkImageAspectFlags                aspectMask                              = isShadowSampler ? VK_IMAGE_ASPECT_DEPTH_BIT : VK_IMAGE_ASPECT_COLOR_BIT;
1048         deUint32                                                bufferSize                              = 0u;
1049         Move<VkBuffer>                                  buffer;
1050         de::MovePtr<Allocation>                 bufferAlloc;
1051         Move<VkCommandPool>                             cmdPool;
1052         Move<VkCommandBuffer>                   cmdBuffer;
1053         Move<VkFence>                                   fence;
1054         std::vector<VkBufferImageCopy>  copyRegions;
1055         std::vector<deUint32>                   offsetMultiples;
1056
1057         offsetMultiples.push_back(4u);
1058         offsetMultiples.push_back(texFormat.getPixelSize());
1059
1060         // Calculate buffer size
1061         for (TextureData::const_iterator mit = textureData.begin(); mit != textureData.end(); ++mit)
1062         {
1063                 for (TextureLayerData::const_iterator lit = mit->begin(); lit != mit->end(); ++lit)
1064                 {
1065                         const tcu::ConstPixelBufferAccess&      access  = *lit;
1066
1067                         bufferSize = getNextMultiple(offsetMultiples, bufferSize);
1068                         bufferSize += access.getWidth() * access.getHeight() * access.getDepth() * access.getFormat().getPixelSize();
1069                 }
1070         }
1071
1072         // Create source buffer
1073         {
1074                 const VkBufferCreateInfo bufferParams =
1075                 {
1076                         VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,           // VkStructureType              sType;
1077                         DE_NULL,                                                                        // const void*                  pNext;
1078                         0u,                                                                                     // VkBufferCreateFlags  flags;
1079                         bufferSize,                                                                     // VkDeviceSize                 size;
1080                         VK_BUFFER_USAGE_TRANSFER_SRC_BIT,                       // VkBufferUsageFlags   usage;
1081                         VK_SHARING_MODE_EXCLUSIVE,                                      // VkSharingMode                sharingMode;
1082                         0u,                                                                                     // deUint32                             queueFamilyIndexCount;
1083                         DE_NULL,                                                                        // const deUint32*              pQueueFamilyIndices;
1084                 };
1085
1086                 buffer          = createBuffer(vk, vkDevice, &bufferParams);
1087                 bufferAlloc = m_memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *buffer), MemoryRequirement::HostVisible);
1088                 VK_CHECK(vk.bindBufferMemory(vkDevice, *buffer, bufferAlloc->getMemory(), bufferAlloc->getOffset()));
1089         }
1090
1091         // Create command pool and buffer
1092         cmdPool = createCommandPool(vk, vkDevice, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, queueFamilyIndex);
1093         cmdBuffer = allocateCommandBuffer(vk, vkDevice, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
1094
1095         // Create fence
1096         fence = createFence(vk, vkDevice);
1097
1098         // Barriers for copying buffer to image
1099         const VkBufferMemoryBarrier preBufferBarrier =
1100         {
1101                 VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,        // VkStructureType      sType;
1102                 DE_NULL,                                                                        // const void*          pNext;
1103                 VK_ACCESS_HOST_WRITE_BIT,                                       // VkAccessFlags        srcAccessMask;
1104                 VK_ACCESS_TRANSFER_READ_BIT,                            // VkAccessFlags        dstAccessMask;
1105                 VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                     srcQueueFamilyIndex;
1106                 VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                     dstQueueFamilyIndex;
1107                 *buffer,                                                                        // VkBuffer                     buffer;
1108                 0u,                                                                                     // VkDeviceSize         offset;
1109                 bufferSize                                                                      // VkDeviceSize         size;
1110         };
1111
1112         const VkImageMemoryBarrier preImageBarrier =
1113         {
1114                 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,                 // VkStructureType                      sType;
1115                 DE_NULL,                                                                                // const void*                          pNext;
1116                 0u,                                                                                             // VkAccessFlags                        srcAccessMask;
1117                 VK_ACCESS_TRANSFER_WRITE_BIT,                                   // VkAccessFlags                        dstAccessMask;
1118                 VK_IMAGE_LAYOUT_UNDEFINED,                                              // VkImageLayout                        oldLayout;
1119                 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,                   // VkImageLayout                        newLayout;
1120                 VK_QUEUE_FAMILY_IGNORED,                                                // deUint32                                     srcQueueFamilyIndex;
1121                 VK_QUEUE_FAMILY_IGNORED,                                                // deUint32                                     dstQueueFamilyIndex;
1122                 destImage,                                                                              // VkImage                                      image;
1123                 {                                                                                               // VkImageSubresourceRange      subresourceRange;
1124                         aspectMask,                                                             // VkImageAspect        aspect;
1125                         0u,                                                                             // deUint32                     baseMipLevel;
1126                         mipLevels,                                                              // deUint32                     mipLevels;
1127                         0u,                                                                             // deUint32                     baseArraySlice;
1128                         arrayLayers                                                             // deUint32                     arraySize;
1129                 }
1130         };
1131
1132         const VkImageMemoryBarrier postImageBarrier =
1133         {
1134                 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,                 // VkStructureType                      sType;
1135                 DE_NULL,                                                                                // const void*                          pNext;
1136                 VK_ACCESS_TRANSFER_WRITE_BIT,                                   // VkAccessFlags                        srcAccessMask;
1137                 VK_ACCESS_SHADER_READ_BIT,                                              // VkAccessFlags                        dstAccessMask;
1138                 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,                   // VkImageLayout                        oldLayout;
1139                 VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,               // VkImageLayout                        newLayout;
1140                 VK_QUEUE_FAMILY_IGNORED,                                                // deUint32                                     srcQueueFamilyIndex;
1141                 VK_QUEUE_FAMILY_IGNORED,                                                // deUint32                                     dstQueueFamilyIndex;
1142                 destImage,                                                                              // VkImage                                      image;
1143                 {                                                                                               // VkImageSubresourceRange      subresourceRange;
1144                         aspectMask,                                                             // VkImageAspect        aspect;
1145                         0u,                                                                             // deUint32                     baseMipLevel;
1146                         mipLevels,                                                              // deUint32                     mipLevels;
1147                         0u,                                                                             // deUint32                     baseArraySlice;
1148                         arrayLayers                                                             // deUint32                     arraySize;
1149                 }
1150         };
1151
1152         const VkCommandBufferBeginInfo cmdBufferBeginInfo =
1153         {
1154                 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,    // VkStructureType                                      sType;
1155                 DE_NULL,                                                                                // const void*                                          pNext;
1156                 VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT,    // VkCommandBufferUsageFlags            flags;
1157                 (const VkCommandBufferInheritanceInfo*)DE_NULL,
1158         };
1159
1160         // Get copy regions and write buffer data
1161         {
1162                 deUint32        layerDataOffset         = 0;
1163                 deUint8*        destPtr                         = (deUint8*)bufferAlloc->getHostPtr();
1164
1165                 for (size_t levelNdx = 0; levelNdx < textureData.size(); levelNdx++)
1166                 {
1167                         const TextureLayerData&         layerData       = textureData[levelNdx];
1168
1169                         for (size_t layerNdx = 0; layerNdx < layerData.size(); layerNdx++)
1170                         {
1171                                 layerDataOffset = getNextMultiple(offsetMultiples, layerDataOffset);
1172
1173                                 const tcu::ConstPixelBufferAccess&      access          = layerData[layerNdx];
1174                                 const tcu::PixelBufferAccess            destAccess      (access.getFormat(), access.getSize(), destPtr + layerDataOffset);
1175
1176                                 const VkBufferImageCopy                         layerRegion =
1177                                 {
1178                                         layerDataOffset,                                                // VkDeviceSize                         bufferOffset;
1179                                         (deUint32)access.getWidth(),                    // deUint32                                     bufferRowLength;
1180                                         (deUint32)access.getHeight(),                   // deUint32                                     bufferImageHeight;
1181                                         {                                                                               // VkImageSubresourceLayers     imageSubresource;
1182                                                 aspectMask,                                                             // VkImageAspectFlags           aspectMask;
1183                                                 (deUint32)levelNdx,                                             // uint32_t                                     mipLevel;
1184                                                 (deUint32)layerNdx,                                             // uint32_t                                     baseArrayLayer;
1185                                                 1u                                                                              // uint32_t                                     layerCount;
1186                                         },
1187                                         { 0u, 0u, 0u },                                                 // VkOffset3D                   imageOffset;
1188                                         {                                                                               // VkExtent3D                   imageExtent;
1189                                                 (deUint32)access.getWidth(),
1190                                                 (deUint32)access.getHeight(),
1191                                                 (deUint32)access.getDepth()
1192                                         }
1193                                 };
1194
1195                                 copyRegions.push_back(layerRegion);
1196                                 tcu::copy(destAccess, access);
1197
1198                                 layerDataOffset += access.getWidth() * access.getHeight() * access.getDepth() * access.getFormat().getPixelSize();
1199                         }
1200                 }
1201         }
1202
1203         flushMappedMemoryRange(vk, vkDevice, bufferAlloc->getMemory(), bufferAlloc->getOffset(), bufferSize);
1204
1205         // Copy buffer to image
1206         VK_CHECK(vk.beginCommandBuffer(*cmdBuffer, &cmdBufferBeginInfo));
1207         vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 1, &preBufferBarrier, 1, &preImageBarrier);
1208         vk.cmdCopyBufferToImage(*cmdBuffer, *buffer, destImage, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, (deUint32)copyRegions.size(), copyRegions.data());
1209         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);
1210         VK_CHECK(vk.endCommandBuffer(*cmdBuffer));
1211
1212         const VkSubmitInfo submitInfo =
1213         {
1214                 VK_STRUCTURE_TYPE_SUBMIT_INFO,  // VkStructureType                              sType;
1215                 DE_NULL,                                                // const void*                                  pNext;
1216                 0u,                                                             // deUint32                                             waitSemaphoreCount;
1217                 DE_NULL,                                                // const VkSemaphore*                   pWaitSemaphores;
1218                 DE_NULL,                                                // const VkPipelineStageFlags*  pWaitDstStageMask;
1219                 1u,                                                             // deUint32                                             commandBufferCount;
1220                 &cmdBuffer.get(),                               // const VkCommandBuffer*               pCommandBuffers;
1221                 0u,                                                             // deUint32                                             signalSemaphoreCount;
1222                 DE_NULL                                                 // const VkSemaphore*                   pSignalSemaphores;
1223         };
1224
1225         VK_CHECK(vk.queueSubmit(queue, 1, &submitInfo, *fence));
1226         VK_CHECK(vk.waitForFences(vkDevice, 1, &fence.get(), true, ~(0ull) /* infinity */));
1227 }
1228
1229 void ShaderRenderCaseInstance::clearImage (const tcu::Sampler&                                  refSampler,
1230                                                                                    deUint32                                                             mipLevels,
1231                                                                                    deUint32                                                             arrayLayers,
1232                                                                                    VkImage                                                              destImage)
1233 {
1234         const VkDevice                                  vkDevice                                = m_context.getDevice();
1235         const DeviceInterface&                  vk                                              = m_context.getDeviceInterface();
1236         const VkQueue                                   queue                                   = m_context.getUniversalQueue();
1237         const deUint32                                  queueFamilyIndex                = m_context.getUniversalQueueFamilyIndex();
1238
1239         const bool                                              isShadowSampler                 = refSampler.compare != tcu::Sampler::COMPAREMODE_NONE;
1240         const VkImageAspectFlags                aspectMask                              = isShadowSampler ? VK_IMAGE_ASPECT_DEPTH_BIT : VK_IMAGE_ASPECT_COLOR_BIT;
1241         Move<VkCommandPool>                             cmdPool;
1242         Move<VkCommandBuffer>                   cmdBuffer;
1243         Move<VkFence>                                   fence;
1244
1245         VkClearValue                                    clearValue;
1246         deMemset(&clearValue, 0, sizeof(clearValue));
1247
1248
1249         // Create command pool and buffer
1250         cmdPool         = createCommandPool(vk, vkDevice, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, queueFamilyIndex);
1251         cmdBuffer       = allocateCommandBuffer(vk, vkDevice, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
1252
1253         // Create fence
1254         fence = createFence(vk, vkDevice);
1255
1256         const VkImageMemoryBarrier preImageBarrier =
1257         {
1258                 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,                 // VkStructureType                      sType;
1259                 DE_NULL,                                                                                // const void*                          pNext;
1260                 0u,                                                                                             // VkAccessFlags                        srcAccessMask;
1261                 VK_ACCESS_TRANSFER_WRITE_BIT,                                   // VkAccessFlags                        dstAccessMask;
1262                 VK_IMAGE_LAYOUT_UNDEFINED,                                              // VkImageLayout                        oldLayout;
1263                 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,                   // VkImageLayout                        newLayout;
1264                 VK_QUEUE_FAMILY_IGNORED,                                                // deUint32                                     srcQueueFamilyIndex;
1265                 VK_QUEUE_FAMILY_IGNORED,                                                // deUint32                                     dstQueueFamilyIndex;
1266                 destImage,                                                                              // VkImage                                      image;
1267                 {                                                                                               // VkImageSubresourceRange      subresourceRange;
1268                         aspectMask,                                                             // VkImageAspect        aspect;
1269                         0u,                                                                             // deUint32                     baseMipLevel;
1270                         mipLevels,                                                              // deUint32                     mipLevels;
1271                         0u,                                                                             // deUint32                     baseArraySlice;
1272                         arrayLayers                                                             // deUint32                     arraySize;
1273                 }
1274         };
1275
1276         const VkImageMemoryBarrier postImageBarrier =
1277         {
1278                 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,                 // VkStructureType                      sType;
1279                 DE_NULL,                                                                                // const void*                          pNext;
1280                 VK_ACCESS_TRANSFER_WRITE_BIT,                                   // VkAccessFlags                        srcAccessMask;
1281                 VK_ACCESS_SHADER_READ_BIT,                                              // VkAccessFlags                        dstAccessMask;
1282                 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,                   // VkImageLayout                        oldLayout;
1283                 VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,               // VkImageLayout                        newLayout;
1284                 VK_QUEUE_FAMILY_IGNORED,                                                // deUint32                                     srcQueueFamilyIndex;
1285                 VK_QUEUE_FAMILY_IGNORED,                                                // deUint32                                     dstQueueFamilyIndex;
1286                 destImage,                                                                              // VkImage                                      image;
1287                 {                                                                                               // VkImageSubresourceRange      subresourceRange;
1288                         aspectMask,                                                             // VkImageAspect        aspect;
1289                         0u,                                                                             // deUint32                     baseMipLevel;
1290                         mipLevels,                                                              // deUint32                     mipLevels;
1291                         0u,                                                                             // deUint32                     baseArraySlice;
1292                         arrayLayers                                                             // deUint32                     arraySize;
1293                 }
1294         };
1295
1296         const VkCommandBufferBeginInfo cmdBufferBeginInfo =
1297         {
1298                 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,    // VkStructureType                                      sType;
1299                 DE_NULL,                                                                                // const void*                                          pNext;
1300                 VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT,    // VkCommandBufferUsageFlags            flags;
1301                 (const VkCommandBufferInheritanceInfo*)DE_NULL,
1302         };
1303
1304
1305         const VkImageSubresourceRange clearRange                =
1306         {
1307                 aspectMask,                                                                             // VkImageAspectFlags   aspectMask;
1308                 0u,                                                                                             // deUint32                             baseMipLevel;
1309                 mipLevels,                                                                              // deUint32                             levelCount;
1310                 0u,                                                                                             // deUint32                             baseArrayLayer;
1311                 arrayLayers                                                                             // deUint32                             layerCount;
1312         };
1313
1314         // Copy buffer to image
1315         VK_CHECK(vk.beginCommandBuffer(*cmdBuffer, &cmdBufferBeginInfo));
1316         vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, 1, &preImageBarrier);
1317         if (aspectMask == VK_IMAGE_ASPECT_COLOR_BIT)
1318         {
1319                 vk.cmdClearColorImage(*cmdBuffer, destImage, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &clearValue.color, 1, &clearRange);
1320         }
1321         else
1322         {
1323                 vk.cmdClearDepthStencilImage(*cmdBuffer, destImage, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &clearValue.depthStencil, 1, &clearRange);
1324         }
1325         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);
1326         VK_CHECK(vk.endCommandBuffer(*cmdBuffer));
1327
1328         const VkSubmitInfo submitInfo =
1329         {
1330                 VK_STRUCTURE_TYPE_SUBMIT_INFO,  // VkStructureType                              sType;
1331                 DE_NULL,                                                // const void*                                  pNext;
1332                 0u,                                                             // deUint32                                             waitSemaphoreCount;
1333                 DE_NULL,                                                // const VkSemaphore*                   pWaitSemaphores;
1334                 DE_NULL,                                                // const VkPipelineStageFlags*  pWaitDstStageMask;
1335                 1u,                                                             // deUint32                                             commandBufferCount;
1336                 &cmdBuffer.get(),                               // const VkCommandBuffer*               pCommandBuffers;
1337                 0u,                                                             // deUint32                                             signalSemaphoreCount;
1338                 DE_NULL                                                 // const VkSemaphore*                   pSignalSemaphores;
1339         };
1340
1341         VK_CHECK(vk.queueSubmit(queue, 1, &submitInfo, *fence));
1342         VK_CHECK(vk.waitForFences(vkDevice, 1, &fence.get(), true, ~(0ull) /* infinity */));
1343 }
1344
1345 VkExtent3D mipLevelExtents (const VkExtent3D& baseExtents, const deUint32 mipLevel)
1346 {
1347         VkExtent3D result;
1348
1349         result.width    = std::max(baseExtents.width  >> mipLevel, 1u);
1350         result.height   = std::max(baseExtents.height >> mipLevel, 1u);
1351         result.depth    = std::max(baseExtents.depth  >> mipLevel, 1u);
1352
1353         return result;
1354 }
1355
1356 tcu::UVec3 alignedDivide (const VkExtent3D& extent, const VkExtent3D& divisor)
1357 {
1358         tcu::UVec3 result;
1359
1360         result.x() = extent.width  / divisor.width  + ((extent.width  % divisor.width != 0)  ? 1u : 0u);
1361         result.y() = extent.height / divisor.height + ((extent.height % divisor.height != 0) ? 1u : 0u);
1362         result.z() = extent.depth  / divisor.depth  + ((extent.depth  % divisor.depth != 0)  ? 1u : 0u);
1363
1364         return result;
1365 }
1366
1367 bool isImageSizeSupported (const VkImageType imageType, const tcu::UVec3& imageSize, const vk::VkPhysicalDeviceLimits& limits)
1368 {
1369         switch (imageType)
1370         {
1371                 case VK_IMAGE_TYPE_1D:
1372                         return (imageSize.x() <= limits.maxImageDimension1D
1373                                  && imageSize.y() == 1
1374                                  && imageSize.z() == 1);
1375                 case VK_IMAGE_TYPE_2D:
1376                         return (imageSize.x() <= limits.maxImageDimension2D
1377                                  && imageSize.y() <= limits.maxImageDimension2D
1378                                  && imageSize.z() == 1);
1379                 case VK_IMAGE_TYPE_3D:
1380                         return (imageSize.x() <= limits.maxImageDimension3D
1381                                  && imageSize.y() <= limits.maxImageDimension3D
1382                                  && imageSize.z() <= limits.maxImageDimension3D);
1383                 default:
1384                         DE_FATAL("Unknown image type");
1385                         return false;
1386         }
1387 }
1388
1389 void ShaderRenderCaseInstance::checkSparseSupport (const VkImageCreateInfo& imageInfo) const
1390 {
1391         const InstanceInterface&                instance                = getInstanceInterface();
1392         const VkPhysicalDevice                  physicalDevice  = getPhysicalDevice();
1393         const VkPhysicalDeviceFeatures  deviceFeatures  = getPhysicalDeviceFeatures(instance, physicalDevice);
1394
1395         const std::vector<VkSparseImageFormatProperties> sparseImageFormatPropVec = getPhysicalDeviceSparseImageFormatProperties(
1396                 instance, physicalDevice, imageInfo.format, imageInfo.imageType, imageInfo.samples, imageInfo.usage, imageInfo.tiling);
1397
1398         if (!deviceFeatures.shaderResourceResidency)
1399                 TCU_THROW(NotSupportedError, "Required feature: shaderResourceResidency.");
1400
1401         if (!deviceFeatures.sparseBinding)
1402                 TCU_THROW(NotSupportedError, "Required feature: sparseBinding.");
1403
1404         if (imageInfo.imageType == VK_IMAGE_TYPE_2D && !deviceFeatures.sparseResidencyImage2D)
1405                 TCU_THROW(NotSupportedError, "Required feature: sparseResidencyImage2D.");
1406
1407         if (imageInfo.imageType == VK_IMAGE_TYPE_3D && !deviceFeatures.sparseResidencyImage3D)
1408                 TCU_THROW(NotSupportedError, "Required feature: sparseResidencyImage3D.");
1409
1410         if (sparseImageFormatPropVec.size() == 0)
1411                 TCU_THROW(NotSupportedError, "The image format does not support sparse operations");
1412 }
1413
1414 void ShaderRenderCaseInstance::uploadSparseImage (const tcu::TextureFormat&             texFormat,
1415                                                                                                   const TextureData&                    textureData,
1416                                                                                                   const tcu::Sampler&                   refSampler,
1417                                                                                                   const deUint32                                mipLevels,
1418                                                                                                   const deUint32                                arrayLayers,
1419                                                                                                   const VkImage                                 sparseImage,
1420                                                                                                   const VkImageCreateInfo&              imageCreateInfo,
1421                                                                                                   const tcu::UVec3                              texSize)
1422 {
1423         const VkDevice                                                  vkDevice                                = getDevice();
1424         const DeviceInterface&                                  vk                                              = getDeviceInterface();
1425         const VkPhysicalDevice                                  physicalDevice                  = getPhysicalDevice();
1426         const VkQueue                                                   queue                                   = getUniversalQueue();
1427         const deUint32                                                  queueFamilyIndex                = getUniversalQueueFamilyIndex();
1428         const InstanceInterface&                                instance                                = getInstanceInterface();
1429         const VkPhysicalDeviceProperties                deviceProperties                = getPhysicalDeviceProperties(instance, physicalDevice);
1430         const VkPhysicalDeviceMemoryProperties  deviceMemoryProperties  = getPhysicalDeviceMemoryProperties(instance, physicalDevice);
1431         const bool                                                              isShadowSampler                 = refSampler.compare != tcu::Sampler::COMPAREMODE_NONE;
1432         const VkImageAspectFlags                                aspectMask                              = isShadowSampler ? VK_IMAGE_ASPECT_DEPTH_BIT : VK_IMAGE_ASPECT_COLOR_BIT;
1433
1434         const Unique<VkSemaphore>                               imageMemoryBindSemaphore(createSemaphore(vk, vkDevice));
1435         deUint32                                                                bufferSize                              = 0u;
1436         std::vector<deUint32>                                   offsetMultiples;
1437         offsetMultiples.push_back(4u);
1438         offsetMultiples.push_back(texFormat.getPixelSize());
1439
1440         if (isImageSizeSupported(imageCreateInfo.imageType, texSize, deviceProperties.limits) == false)
1441                 TCU_THROW(NotSupportedError, "Image size not supported for device.");
1442
1443         // Calculate buffer size
1444         for (TextureData::const_iterator mit = textureData.begin(); mit != textureData.end(); ++mit)
1445         {
1446                 for (TextureLayerData::const_iterator lit = mit->begin(); lit != mit->end(); ++lit)
1447                 {
1448                         const tcu::ConstPixelBufferAccess&      access  = *lit;
1449
1450                         bufferSize = getNextMultiple(offsetMultiples, bufferSize);
1451                         bufferSize += access.getWidth() * access.getHeight() * access.getDepth() * access.getFormat().getPixelSize();
1452                 }
1453         }
1454
1455         {
1456                 deUint32 sparseMemoryReqCount = 0;
1457
1458                 vk.getImageSparseMemoryRequirements(vkDevice, sparseImage, &sparseMemoryReqCount, DE_NULL);
1459
1460                 DE_ASSERT(sparseMemoryReqCount != 0);
1461
1462                 std::vector<VkSparseImageMemoryRequirements> sparseImageMemoryRequirements;
1463                 sparseImageMemoryRequirements.resize(sparseMemoryReqCount);
1464
1465                 vk.getImageSparseMemoryRequirements(vkDevice, sparseImage, &sparseMemoryReqCount, &sparseImageMemoryRequirements[0]);
1466
1467                 const deUint32 noMatchFound = ~((deUint32)0);
1468
1469                 deUint32 aspectIndex = noMatchFound;
1470                 for (deUint32 memoryReqNdx = 0; memoryReqNdx < sparseMemoryReqCount; ++memoryReqNdx)
1471                 {
1472                         if (sparseImageMemoryRequirements[memoryReqNdx].formatProperties.aspectMask == aspectMask)
1473                         {
1474                                 aspectIndex = memoryReqNdx;
1475                                 break;
1476                         }
1477                 }
1478
1479                 deUint32 metadataAspectIndex = noMatchFound;
1480                 for (deUint32 memoryReqNdx = 0; memoryReqNdx < sparseMemoryReqCount; ++memoryReqNdx)
1481                 {
1482                         if (sparseImageMemoryRequirements[memoryReqNdx].formatProperties.aspectMask & VK_IMAGE_ASPECT_METADATA_BIT)
1483                         {
1484                                 metadataAspectIndex = memoryReqNdx;
1485                                 break;
1486                         }
1487                 }
1488
1489                 if (aspectIndex == noMatchFound)
1490                         TCU_THROW(NotSupportedError, "Required image aspect not supported.");
1491
1492                 const VkMemoryRequirements      memoryRequirements      = getImageMemoryRequirements(vk, vkDevice, sparseImage);
1493
1494                 deUint32 memoryType = noMatchFound;
1495                 for (deUint32 memoryTypeNdx = 0; memoryTypeNdx < deviceMemoryProperties.memoryTypeCount; ++memoryTypeNdx)
1496                 {
1497                         if ((memoryRequirements.memoryTypeBits & (1u << memoryTypeNdx)) != 0 &&
1498                                 MemoryRequirement::Any.matchesHeap(deviceMemoryProperties.memoryTypes[memoryTypeNdx].propertyFlags))
1499                         {
1500                                 memoryType = memoryTypeNdx;
1501                                 break;
1502                         }
1503                 }
1504
1505                 if (memoryType == noMatchFound)
1506                         TCU_THROW(NotSupportedError, "No matching memory type found.");
1507
1508                 if (memoryRequirements.size > deviceProperties.limits.sparseAddressSpaceSize)
1509                         TCU_THROW(NotSupportedError, "Required memory size for sparse resource exceeds device limits.");
1510
1511                 // Check if the image format supports sparse operations
1512                 const std::vector<VkSparseImageFormatProperties> sparseImageFormatPropVec =
1513                         getPhysicalDeviceSparseImageFormatProperties(instance, physicalDevice, imageCreateInfo.format, imageCreateInfo.imageType, imageCreateInfo.samples, imageCreateInfo.usage, imageCreateInfo.tiling);
1514
1515                 if (sparseImageFormatPropVec.size() == 0)
1516                         TCU_THROW(NotSupportedError, "The image format does not support sparse operations.");
1517
1518                 const VkSparseImageMemoryRequirements           aspectRequirements      = sparseImageMemoryRequirements[aspectIndex];
1519                 const VkExtent3D                                                        imageGranularity        = aspectRequirements.formatProperties.imageGranularity;
1520
1521                 std::vector<VkSparseImageMemoryBind>            imageResidencyMemoryBinds;
1522                 std::vector<VkSparseMemoryBind>                         imageMipTailMemoryBinds;
1523
1524                 for (deUint32 layerNdx = 0; layerNdx < arrayLayers; ++ layerNdx)
1525                 {
1526                         for (deUint32 mipLevelNdx = 0; mipLevelNdx < aspectRequirements.imageMipTailFirstLod; ++mipLevelNdx)
1527                         {
1528                                 const VkExtent3D        mipExtent               = mipLevelExtents(imageCreateInfo.extent, mipLevelNdx);
1529                                 const tcu::UVec3        numSparseBinds  = alignedDivide(mipExtent, imageGranularity);
1530                                 const tcu::UVec3        lastBlockExtent = tcu::UVec3(mipExtent.width  % imageGranularity.width  ? mipExtent.width  % imageGranularity.width  : imageGranularity.width,
1531                                                                                                                                  mipExtent.height % imageGranularity.height ? mipExtent.height % imageGranularity.height : imageGranularity.height,
1532                                                                                                                                  mipExtent.depth  % imageGranularity.depth  ? mipExtent.depth  % imageGranularity.depth  : imageGranularity.depth );
1533
1534                                 for (deUint32 z = 0; z < numSparseBinds.z(); ++z)
1535                                 for (deUint32 y = 0; y < numSparseBinds.y(); ++y)
1536                                 for (deUint32 x = 0; x < numSparseBinds.x(); ++x)
1537                                 {
1538                                         const VkMemoryRequirements allocRequirements =
1539                                         {
1540                                                 // 28.7.5 alignment shows the block size in bytes
1541                                                 memoryRequirements.alignment,           // VkDeviceSize size;
1542                                                 memoryRequirements.alignment,           // VkDeviceSize alignment;
1543                                                 memoryRequirements.memoryTypeBits,      // uint32_t             memoryTypeBits;
1544                                         };
1545
1546                                         de::SharedPtr<Allocation> allocation(m_memAlloc.allocate(allocRequirements, MemoryRequirement::Any).release());
1547
1548                                         m_allocations.push_back(allocation);
1549
1550                                         VkOffset3D offset;
1551                                         offset.x = x*imageGranularity.width;
1552                                         offset.y = y*imageGranularity.height;
1553                                         offset.z = z*imageGranularity.depth;
1554
1555                                         VkExtent3D extent;
1556                                         extent.width    = (x == numSparseBinds.x() - 1) ? lastBlockExtent.x() : imageGranularity.width;
1557                                         extent.height   = (y == numSparseBinds.y() - 1) ? lastBlockExtent.y() : imageGranularity.height;
1558                                         extent.depth    = (z == numSparseBinds.z() - 1) ? lastBlockExtent.z() : imageGranularity.depth;
1559
1560                                         const VkSparseImageMemoryBind imageMemoryBind =
1561                                         {
1562                                                 {
1563                                                         aspectMask,     // VkImageAspectFlags   aspectMask;
1564                                                         mipLevelNdx,// uint32_t                         mipLevel;
1565                                                         layerNdx,       // uint32_t                             arrayLayer;
1566                                                 },                                                      // VkImageSubresource           subresource;
1567                                                 offset,                                         // VkOffset3D                           offset;
1568                                                 extent,                                         // VkExtent3D                           extent;
1569                                                 allocation->getMemory(),        // VkDeviceMemory                       memory;
1570                                                 allocation->getOffset(),        // VkDeviceSize                         memoryOffset;
1571                                                 0u,                                                     // VkSparseMemoryBindFlags      flags;
1572                                         };
1573
1574                                         imageResidencyMemoryBinds.push_back(imageMemoryBind);
1575                                 }
1576                         }
1577
1578                         // Handle MIP tail. There are two cases to consider here:
1579                         //
1580                         // 1) VK_SPARSE_IMAGE_FORMAT_SINGLE_MIPTAIL_BIT is requested by the driver: each layer needs a separate tail.
1581                         // 2) otherwise:                                                            only one tail is needed.
1582                         {
1583                                 if (imageMipTailMemoryBinds.size() == 0 || (aspectRequirements.formatProperties.flags & VK_SPARSE_IMAGE_FORMAT_SINGLE_MIPTAIL_BIT) == 0)
1584                                 {
1585                                         const VkMemoryRequirements allocRequirements =
1586                                         {
1587                                                 aspectRequirements.imageMipTailSize,    // VkDeviceSize size;
1588                                                 memoryRequirements.alignment,                   // VkDeviceSize alignment;
1589                                                 memoryRequirements.memoryTypeBits,              // uint32_t             memoryTypeBits;
1590                                         };
1591
1592                                         const de::SharedPtr<Allocation> allocation(m_memAlloc.allocate(allocRequirements, MemoryRequirement::Any).release());
1593
1594                                         const VkSparseMemoryBind imageMipTailMemoryBind =
1595                                         {
1596                                                 aspectRequirements.imageMipTailOffset + layerNdx * aspectRequirements.imageMipTailStride,       // VkDeviceSize                                 resourceOffset;
1597                                                 aspectRequirements.imageMipTailSize,                                                                                                            // VkDeviceSize                                 size;
1598                                                 allocation->getMemory(),                                                                                                                                        // VkDeviceMemory                               memory;
1599                                                 allocation->getOffset(),                                                                                                                                        // VkDeviceSize                                 memoryOffset;
1600                                                 0u,                                                                                                                                                                                     // VkSparseMemoryBindFlags              flags;
1601                                         };
1602
1603                                         m_allocations.push_back(allocation);
1604                                         imageMipTailMemoryBinds.push_back(imageMipTailMemoryBind);
1605                                 }
1606
1607                                 // Metadata
1608                                 if (metadataAspectIndex != noMatchFound)
1609                                 {
1610                                         const VkSparseImageMemoryRequirements   metadataAspectRequirements = sparseImageMemoryRequirements[metadataAspectIndex];
1611
1612                                         if (imageMipTailMemoryBinds.size() == 1 || (metadataAspectRequirements.formatProperties.flags & VK_SPARSE_IMAGE_FORMAT_SINGLE_MIPTAIL_BIT) == 0)
1613                                         {
1614                                                 const VkMemoryRequirements metadataAllocRequirements =
1615                                                 {
1616                                                         metadataAspectRequirements.imageMipTailSize,    // VkDeviceSize size;
1617                                                         memoryRequirements.alignment,                                   // VkDeviceSize alignment;
1618                                                         memoryRequirements.memoryTypeBits,                              // uint32_t             memoryTypeBits;
1619                                                 };
1620                                                 const de::SharedPtr<Allocation> metadataAllocation(m_memAlloc.allocate(metadataAllocRequirements, MemoryRequirement::Any).release());
1621
1622                                                 const VkSparseMemoryBind metadataMipTailMemoryBind =
1623                                                 {
1624                                                         metadataAspectRequirements.imageMipTailOffset +
1625                                                         layerNdx * metadataAspectRequirements.imageMipTailStride,                       // VkDeviceSize                                 resourceOffset;
1626                                                         metadataAspectRequirements.imageMipTailSize,                                            // VkDeviceSize                                 size;
1627                                                         metadataAllocation->getMemory(),                                                                        // VkDeviceMemory                               memory;
1628                                                         metadataAllocation->getOffset(),                                                                        // VkDeviceSize                                 memoryOffset;
1629                                                         VK_SPARSE_MEMORY_BIND_METADATA_BIT                                                                      // VkSparseMemoryBindFlags              flags;
1630                                                 };
1631
1632                                                 m_allocations.push_back(metadataAllocation);
1633                                                 imageMipTailMemoryBinds.push_back(metadataMipTailMemoryBind);
1634                                         }
1635                                 }
1636                         }
1637                 }
1638
1639                 VkBindSparseInfo bindSparseInfo =
1640                 {
1641                         VK_STRUCTURE_TYPE_BIND_SPARSE_INFO,                     //VkStructureType                                                       sType;
1642                         DE_NULL,                                                                        //const void*                                                           pNext;
1643                         0u,                                                                                     //deUint32                                                                      waitSemaphoreCount;
1644                         DE_NULL,                                                                        //const VkSemaphore*                                            pWaitSemaphores;
1645                         0u,                                                                                     //deUint32                                                                      bufferBindCount;
1646                         DE_NULL,                                                                        //const VkSparseBufferMemoryBindInfo*           pBufferBinds;
1647                         0u,                                                                                     //deUint32                                                                      imageOpaqueBindCount;
1648                         DE_NULL,                                                                        //const VkSparseImageOpaqueMemoryBindInfo*      pImageOpaqueBinds;
1649                         0u,                                                                                     //deUint32                                                                      imageBindCount;
1650                         DE_NULL,                                                                        //const VkSparseImageMemoryBindInfo*            pImageBinds;
1651                         1u,                                                                                     //deUint32                                                                      signalSemaphoreCount;
1652                         &imageMemoryBindSemaphore.get()                         //const VkSemaphore*                                            pSignalSemaphores;
1653                 };
1654
1655                 VkSparseImageMemoryBindInfo                     imageResidencyBindInfo;
1656                 VkSparseImageOpaqueMemoryBindInfo       imageMipTailBindInfo;
1657
1658                 if (imageResidencyMemoryBinds.size() > 0)
1659                 {
1660                         imageResidencyBindInfo.image            = sparseImage;
1661                         imageResidencyBindInfo.bindCount        = static_cast<deUint32>(imageResidencyMemoryBinds.size());
1662                         imageResidencyBindInfo.pBinds           = &imageResidencyMemoryBinds[0];
1663
1664                         bindSparseInfo.imageBindCount           = 1u;
1665                         bindSparseInfo.pImageBinds                      = &imageResidencyBindInfo;
1666                 }
1667
1668                 if (imageMipTailMemoryBinds.size() > 0)
1669                 {
1670                         imageMipTailBindInfo.image = sparseImage;
1671                         imageMipTailBindInfo.bindCount = static_cast<deUint32>(imageMipTailMemoryBinds.size());
1672                         imageMipTailBindInfo.pBinds = &imageMipTailMemoryBinds[0];
1673
1674                         bindSparseInfo.imageOpaqueBindCount = 1u;
1675                         bindSparseInfo.pImageOpaqueBinds = &imageMipTailBindInfo;
1676                 }
1677
1678                 VK_CHECK(vk.queueBindSparse(queue, 1u, &bindSparseInfo, DE_NULL));
1679         }
1680
1681         Move<VkCommandPool>             cmdPool;
1682         Move<VkCommandBuffer>   cmdBuffer;
1683
1684         // Create command pool
1685         cmdPool = createCommandPool(vk, vkDevice, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, queueFamilyIndex);
1686
1687         // Create command buffer
1688         cmdBuffer = allocateCommandBuffer(vk, vkDevice, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
1689
1690         // Create source buffer
1691         const VkBufferCreateInfo bufferParams =
1692         {
1693                 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,           // VkStructureType              sType;
1694                 DE_NULL,                                                                        // const void*                  pNext;
1695                 0u,                                                                                     // VkBufferCreateFlags  flags;
1696                 bufferSize,                                                                     // VkDeviceSize                 size;
1697                 VK_BUFFER_USAGE_TRANSFER_SRC_BIT,                       // VkBufferUsageFlags   usage;
1698                 VK_SHARING_MODE_EXCLUSIVE,                                      // VkSharingMode                sharingMode;
1699                 0u,                                                                                     // deUint32                             queueFamilyIndexCount;
1700                 DE_NULL,                                                                        // const deUint32*              pQueueFamilyIndices;
1701         };
1702
1703         Move<VkBuffer>                                  buffer          = createBuffer(vk, vkDevice, &bufferParams);
1704         de::MovePtr<Allocation>                 bufferAlloc = m_memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *buffer), MemoryRequirement::HostVisible);
1705         VK_CHECK(vk.bindBufferMemory(vkDevice, *buffer, bufferAlloc->getMemory(), bufferAlloc->getOffset()));
1706
1707         // Barriers for copying buffer to image
1708         const VkBufferMemoryBarrier preBufferBarrier =
1709         {
1710                 VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,        // VkStructureType      sType;
1711                 DE_NULL,                                                                        // const void*          pNext;
1712                 VK_ACCESS_HOST_WRITE_BIT,                                       // VkAccessFlags        srcAccessMask;
1713                 VK_ACCESS_TRANSFER_READ_BIT,                            // VkAccessFlags        dstAccessMask;
1714                 VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                     srcQueueFamilyIndex;
1715                 VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                     dstQueueFamilyIndex;
1716                 *buffer,                                                                        // VkBuffer                     buffer;
1717                 0u,                                                                                     // VkDeviceSize         offset;
1718                 bufferSize                                                                      // VkDeviceSize         size;
1719         };
1720
1721         const VkImageMemoryBarrier preImageBarrier =
1722         {
1723                 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,                 // VkStructureType                      sType;
1724                 DE_NULL,                                                                                // const void*                          pNext;
1725                 0u,                                                                                             // VkAccessFlags                        srcAccessMask;
1726                 VK_ACCESS_TRANSFER_WRITE_BIT,                                   // VkAccessFlags                        dstAccessMask;
1727                 VK_IMAGE_LAYOUT_UNDEFINED,                                              // VkImageLayout                        oldLayout;
1728                 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,                   // VkImageLayout                        newLayout;
1729                 VK_QUEUE_FAMILY_IGNORED,                                                // deUint32                                     srcQueueFamilyIndex;
1730                 VK_QUEUE_FAMILY_IGNORED,                                                // deUint32                                     dstQueueFamilyIndex;
1731                 sparseImage,                                                                    // VkImage                                      image;
1732                 {                                                                                               // VkImageSubresourceRange      subresourceRange;
1733                         aspectMask,                                                             // VkImageAspect        aspect;
1734                         0u,                                                                             // deUint32                     baseMipLevel;
1735                         mipLevels,                                                              // deUint32                     mipLevels;
1736                         0u,                                                                             // deUint32                     baseArraySlice;
1737                         arrayLayers                                                             // deUint32                     arraySize;
1738                 }
1739         };
1740
1741         const VkImageMemoryBarrier postImageBarrier =
1742         {
1743                 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,                 // VkStructureType                      sType;
1744                 DE_NULL,                                                                                // const void*                          pNext;
1745                 VK_ACCESS_TRANSFER_WRITE_BIT,                                   // VkAccessFlags                        srcAccessMask;
1746                 VK_ACCESS_SHADER_READ_BIT,                                              // VkAccessFlags                        dstAccessMask;
1747                 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,                   // VkImageLayout                        oldLayout;
1748                 VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,               // VkImageLayout                        newLayout;
1749                 VK_QUEUE_FAMILY_IGNORED,                                                // deUint32                                     srcQueueFamilyIndex;
1750                 VK_QUEUE_FAMILY_IGNORED,                                                // deUint32                                     dstQueueFamilyIndex;
1751                 sparseImage,                                                                    // VkImage                                      image;
1752                 {                                                                                               // VkImageSubresourceRange      subresourceRange;
1753                         aspectMask,                                                             // VkImageAspect        aspect;
1754                         0u,                                                                             // deUint32                     baseMipLevel;
1755                         mipLevels,                                                              // deUint32                     mipLevels;
1756                         0u,                                                                             // deUint32                     baseArraySlice;
1757                         arrayLayers                                                             // deUint32                     arraySize;
1758                 }
1759         };
1760
1761         const VkCommandBufferBeginInfo cmdBufferBeginInfo =
1762         {
1763                 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,    // VkStructureType                                      sType;
1764                 DE_NULL,                                                                                // const void*                                          pNext;
1765                 VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT,    // VkCommandBufferUsageFlags            flags;
1766                 (const VkCommandBufferInheritanceInfo*)DE_NULL,
1767         };
1768
1769         std::vector<VkBufferImageCopy>  copyRegions;
1770         // Get copy regions and write buffer data
1771         {
1772                 deUint32        layerDataOffset         = 0;
1773                 deUint8*        destPtr                         = (deUint8*)bufferAlloc->getHostPtr();
1774
1775                 for (size_t levelNdx = 0; levelNdx < textureData.size(); levelNdx++)
1776                 {
1777                         const TextureLayerData&         layerData       = textureData[levelNdx];
1778
1779                         for (size_t layerNdx = 0; layerNdx < layerData.size(); layerNdx++)
1780                         {
1781                                 layerDataOffset = getNextMultiple(offsetMultiples, layerDataOffset);
1782
1783                                 const tcu::ConstPixelBufferAccess&      access          = layerData[layerNdx];
1784                                 const tcu::PixelBufferAccess            destAccess      (access.getFormat(), access.getSize(), destPtr + layerDataOffset);
1785
1786                                 const VkBufferImageCopy                         layerRegion =
1787                                 {
1788                                         layerDataOffset,                                                // VkDeviceSize                         bufferOffset;
1789                                         (deUint32)access.getWidth(),                    // deUint32                                     bufferRowLength;
1790                                         (deUint32)access.getHeight(),                   // deUint32                                     bufferImageHeight;
1791                                         {                                                                               // VkImageSubresourceLayers     imageSubresource;
1792                                                 aspectMask,                                                             // VkImageAspectFlags           aspectMask;
1793                                                 (deUint32)levelNdx,                                             // uint32_t                                     mipLevel;
1794                                                 (deUint32)layerNdx,                                             // uint32_t                                     baseArrayLayer;
1795                                                 1u                                                                              // uint32_t                                     layerCount;
1796                                         },
1797                                         { 0u, 0u, 0u },                                                 // VkOffset3D                   imageOffset;
1798                                         {                                                                               // VkExtent3D                   imageExtent;
1799                                                 (deUint32)access.getWidth(),
1800                                                 (deUint32)access.getHeight(),
1801                                                 (deUint32)access.getDepth()
1802                                         }
1803                                 };
1804
1805                                 copyRegions.push_back(layerRegion);
1806                                 tcu::copy(destAccess, access);
1807
1808                                 layerDataOffset += access.getWidth() * access.getHeight() * access.getDepth() * access.getFormat().getPixelSize();
1809                         }
1810                 }
1811         }
1812
1813         // Copy buffer to image
1814         VK_CHECK(vk.beginCommandBuffer(*cmdBuffer, &cmdBufferBeginInfo));
1815         vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 1, &preBufferBarrier, 1, &preImageBarrier);
1816         vk.cmdCopyBufferToImage(*cmdBuffer, *buffer, sparseImage, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, (deUint32)copyRegions.size(), copyRegions.data());
1817         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);
1818         VK_CHECK(vk.endCommandBuffer(*cmdBuffer));
1819
1820         const VkPipelineStageFlags pipelineStageFlags = VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT;
1821
1822         const VkSubmitInfo submitInfo =
1823         {
1824                 VK_STRUCTURE_TYPE_SUBMIT_INFO,                  // VkStructureType                              sType;
1825                 DE_NULL,                                                                // const void*                                  pNext;
1826                 1u,                                                                             // deUint32                                             waitSemaphoreCount;
1827                 &imageMemoryBindSemaphore.get(),                // const VkSemaphore*                   pWaitSemaphores;
1828                 &pipelineStageFlags,                                    // const VkPipelineStageFlags*  pWaitDstStageMask;
1829                 1u,                                                                             // deUint32                                             commandBufferCount;
1830                 &cmdBuffer.get(),                                               // const VkCommandBuffer*               pCommandBuffers;
1831                 0u,                                                                             // deUint32                                             signalSemaphoreCount;
1832                 DE_NULL                                                                 // const VkSemaphore*                   pSignalSemaphores;
1833         };
1834
1835         Move<VkFence>   fence = createFence(vk, vkDevice);
1836
1837         try
1838         {
1839                 VK_CHECK(vk.queueSubmit(queue, 1, &submitInfo, *fence));
1840                 VK_CHECK(vk.waitForFences(vkDevice, 1, &fence.get(), true, ~(0ull) /* infinity */));
1841         }
1842         catch (...)
1843         {
1844                 VK_CHECK(vk.deviceWaitIdle(vkDevice));
1845                 throw;
1846         }
1847 }
1848
1849 void ShaderRenderCaseInstance::useSampler (deUint32 bindingLocation, deUint32 textureId)
1850 {
1851         DE_ASSERT(textureId < m_textures.size());
1852
1853         const TextureBinding&                           textureBinding          = *m_textures[textureId];
1854         const TextureBinding::Type                      textureType                     = textureBinding.getType();
1855         const tcu::Sampler&                                     refSampler                      = textureBinding.getSampler();
1856         const TextureBinding::Parameters&       textureParams           = textureBinding.getParameters();
1857         const bool                                                      isMSTexture                     = textureParams.samples != vk::VK_SAMPLE_COUNT_1_BIT;
1858         deUint32                                                        mipLevels                       = 1u;
1859         deUint32                                                        arrayLayers                     = 1u;
1860         tcu::TextureFormat                                      texFormat;
1861         tcu::UVec3                                                      texSize;
1862         TextureData                                                     textureData;
1863
1864         if (textureType == TextureBinding::TYPE_2D)
1865         {
1866                 const tcu::Texture2D&                   texture         = textureBinding.get2D();
1867
1868                 texFormat                                                                       = texture.getFormat();
1869                 texSize                                                                         = tcu::UVec3(texture.getWidth(), texture.getHeight(), 1u);
1870                 mipLevels                                                                       = isMSTexture ? 1u : (deUint32)texture.getNumLevels();
1871                 arrayLayers                                                                     = 1u;
1872
1873                 textureData.resize(mipLevels);
1874
1875                 for (deUint32 level = 0; level < mipLevels; ++level)
1876                 {
1877                         if (texture.isLevelEmpty(level))
1878                                 continue;
1879
1880                         textureData[level].push_back(texture.getLevel(level));
1881                 }
1882         }
1883         else if (textureType == TextureBinding::TYPE_CUBE_MAP)
1884         {
1885                 const tcu::TextureCube&                 texture         = textureBinding.getCube();
1886
1887                 texFormat                                                                       = texture.getFormat();
1888                 texSize                                                                         = tcu::UVec3(texture.getSize(), texture.getSize(), 1u);
1889                 mipLevels                                                                       = isMSTexture ? 1u : (deUint32)texture.getNumLevels();
1890                 arrayLayers                                                                     = 6u;
1891
1892                 static const tcu::CubeFace              cubeFaceMapping[tcu::CUBEFACE_LAST] =
1893                 {
1894                         tcu::CUBEFACE_POSITIVE_X,
1895                         tcu::CUBEFACE_NEGATIVE_X,
1896                         tcu::CUBEFACE_POSITIVE_Y,
1897                         tcu::CUBEFACE_NEGATIVE_Y,
1898                         tcu::CUBEFACE_POSITIVE_Z,
1899                         tcu::CUBEFACE_NEGATIVE_Z
1900                 };
1901
1902                 textureData.resize(mipLevels);
1903
1904                 for (deUint32 level = 0; level < mipLevels; ++level)
1905                 {
1906                         for (int faceNdx = 0; faceNdx < tcu::CUBEFACE_LAST; ++faceNdx)
1907                         {
1908                                 tcu::CubeFace face = cubeFaceMapping[faceNdx];
1909
1910                                 if (texture.isLevelEmpty(face, level))
1911                                         continue;
1912
1913                                 textureData[level].push_back(texture.getLevelFace(level, face));
1914                         }
1915                 }
1916         }
1917         else if (textureType == TextureBinding::TYPE_2D_ARRAY)
1918         {
1919                 const tcu::Texture2DArray&              texture         = textureBinding.get2DArray();
1920
1921                 texFormat                                                                       = texture.getFormat();
1922                 texSize                                                                         = tcu::UVec3(texture.getWidth(), texture.getHeight(), 1u);
1923                 mipLevels                                                                       = isMSTexture ? 1u : (deUint32)texture.getNumLevels();
1924                 arrayLayers                                                                     = (deUint32)texture.getNumLayers();
1925
1926                 textureData.resize(mipLevels);
1927
1928                 for (deUint32 level = 0; level < mipLevels; ++level)
1929                 {
1930                         if (texture.isLevelEmpty(level))
1931                                 continue;
1932
1933                         const tcu::ConstPixelBufferAccess&      levelLayers             = texture.getLevel(level);
1934                         const deUint32                                          layerSize               = levelLayers.getWidth() * levelLayers.getHeight() * levelLayers.getFormat().getPixelSize();
1935
1936                         for (deUint32 layer = 0; layer < arrayLayers; ++layer)
1937                         {
1938                                 const deUint32                                  layerOffset             = layerSize * layer;
1939                                 tcu::ConstPixelBufferAccess             layerData               (levelLayers.getFormat(), levelLayers.getWidth(), levelLayers.getHeight(), 1, (deUint8*)levelLayers.getDataPtr() + layerOffset);
1940                                 textureData[level].push_back(layerData);
1941                         }
1942                 }
1943         }
1944         else if (textureType == TextureBinding::TYPE_3D)
1945         {
1946                 const tcu::Texture3D&                   texture         = textureBinding.get3D();
1947
1948                 texFormat                                                                       = texture.getFormat();
1949                 texSize                                                                         = tcu::UVec3(texture.getWidth(), texture.getHeight(), texture.getDepth());
1950                 mipLevels                                                                       = isMSTexture ? 1u : (deUint32)texture.getNumLevels();
1951                 arrayLayers                                                                     = 1u;
1952
1953                 textureData.resize(mipLevels);
1954
1955                 for (deUint32 level = 0; level < mipLevels; ++level)
1956                 {
1957                         if (texture.isLevelEmpty(level))
1958                                 continue;
1959
1960                         textureData[level].push_back(texture.getLevel(level));
1961                 }
1962         }
1963         else if (textureType == TextureBinding::TYPE_1D)
1964         {
1965                 const tcu::Texture1D&                   texture         = textureBinding.get1D();
1966
1967                 texFormat                                                                       = texture.getFormat();
1968                 texSize                                                                         = tcu::UVec3(texture.getWidth(), 1, 1);
1969                 mipLevels                                                                       = isMSTexture ? 1u : (deUint32)texture.getNumLevels();
1970                 arrayLayers                                                                     = 1u;
1971
1972                 textureData.resize(mipLevels);
1973
1974                 for (deUint32 level = 0; level < mipLevels; ++level)
1975                 {
1976                         if (texture.isLevelEmpty(level))
1977                                 continue;
1978
1979                         textureData[level].push_back(texture.getLevel(level));
1980                 }
1981         }
1982         else if (textureType == TextureBinding::TYPE_1D_ARRAY)
1983         {
1984                 const tcu::Texture1DArray&              texture         = textureBinding.get1DArray();
1985
1986                 texFormat                                                                       = texture.getFormat();
1987                 texSize                                                                         = tcu::UVec3(texture.getWidth(), 1, 1);
1988                 mipLevels                                                                       = isMSTexture ? 1u : (deUint32)texture.getNumLevels();
1989                 arrayLayers                                                                     = (deUint32)texture.getNumLayers();
1990
1991                 textureData.resize(mipLevels);
1992
1993                 for (deUint32 level = 0; level < mipLevels; ++level)
1994                 {
1995                         if (texture.isLevelEmpty(level))
1996                                 continue;
1997
1998                         const tcu::ConstPixelBufferAccess&      levelLayers             = texture.getLevel(level);
1999                         const deUint32                                          layerSize               = levelLayers.getWidth() * levelLayers.getFormat().getPixelSize();
2000
2001                         for (deUint32 layer = 0; layer < arrayLayers; ++layer)
2002                         {
2003                                 const deUint32                                  layerOffset             = layerSize * layer;
2004                                 tcu::ConstPixelBufferAccess             layerData               (levelLayers.getFormat(), levelLayers.getWidth(), 1, 1, (deUint8*)levelLayers.getDataPtr() + layerOffset);
2005                                 textureData[level].push_back(layerData);
2006                         }
2007                 }
2008         }
2009         else if (textureType == TextureBinding::TYPE_CUBE_ARRAY)
2010         {
2011                 const tcu::TextureCubeArray&    texture         = textureBinding.getCubeArray();
2012                 texFormat                                                                       = texture.getFormat();
2013                 texSize                                                                         = tcu::UVec3(texture.getSize(), texture.getSize(), 1);
2014                 mipLevels                                                                       = isMSTexture ? 1u : (deUint32)texture.getNumLevels();
2015                 arrayLayers                                                                     = texture.getDepth();
2016
2017                 textureData.resize(mipLevels);
2018
2019                 for (deUint32 level = 0; level < mipLevels; ++level)
2020                 {
2021                         if (texture.isLevelEmpty(level))
2022                                 continue;
2023
2024                         const tcu::ConstPixelBufferAccess&      levelLayers             = texture.getLevel(level);
2025                         const deUint32                                          layerSize               = levelLayers.getWidth() * levelLayers.getHeight() * levelLayers.getFormat().getPixelSize();
2026
2027                         for (deUint32 layer = 0; layer < arrayLayers; ++layer)
2028                         {
2029                                 const deUint32                                  layerOffset             = layerSize * layer;
2030                                 tcu::ConstPixelBufferAccess             layerData               (levelLayers.getFormat(), levelLayers.getWidth(), levelLayers.getHeight(), 1, (deUint8*)levelLayers.getDataPtr() + layerOffset);
2031                                 textureData[level].push_back(layerData);
2032                         }
2033                 }
2034         }
2035         else
2036         {
2037                 TCU_THROW(InternalError, "Invalid texture type");
2038         }
2039
2040         createSamplerUniform(bindingLocation, textureType, textureBinding.getParameters().initialization, texFormat, texSize, textureData, refSampler, mipLevels, arrayLayers, textureParams);
2041 }
2042
2043 void ShaderRenderCaseInstance::setPushConstantRanges (const deUint32 rangeCount, const vk::VkPushConstantRange* const pcRanges)
2044 {
2045         m_pushConstantRanges.clear();
2046         for (deUint32 i = 0; i < rangeCount; ++i)
2047         {
2048                 m_pushConstantRanges.push_back(pcRanges[i]);
2049         }
2050 }
2051
2052 void ShaderRenderCaseInstance::updatePushConstants (vk::VkCommandBuffer, vk::VkPipelineLayout)
2053 {
2054 }
2055
2056 void ShaderRenderCaseInstance::createSamplerUniform (deUint32                                           bindingLocation,
2057                                                                                                          TextureBinding::Type                   textureType,
2058                                                                                                          TextureBinding::Init                   textureInit,
2059                                                                                                          const tcu::TextureFormat&              texFormat,
2060                                                                                                          const tcu::UVec3                               texSize,
2061                                                                                                          const TextureData&                             textureData,
2062                                                                                                          const tcu::Sampler&                    refSampler,
2063                                                                                                          deUint32                                               mipLevels,
2064                                                                                                          deUint32                                               arrayLayers,
2065                                                                                                          TextureBinding::Parameters             textureParams)
2066 {
2067         const VkDevice                                  vkDevice                        = getDevice();
2068         const DeviceInterface&                  vk                                      = getDeviceInterface();
2069         const deUint32                                  queueFamilyIndex        = getUniversalQueueFamilyIndex();
2070
2071         const bool                                              isShadowSampler         = refSampler.compare != tcu::Sampler::COMPAREMODE_NONE;
2072         const VkImageAspectFlags                aspectMask                      = isShadowSampler ? VK_IMAGE_ASPECT_DEPTH_BIT : VK_IMAGE_ASPECT_COLOR_BIT;
2073         const VkImageViewType                   imageViewType           = textureTypeToImageViewType(textureType);
2074         const VkImageType                               imageType                       = viewTypeToImageType(imageViewType);
2075         const VkFormat                                  format                          = mapTextureFormat(texFormat);
2076         const bool                                              isCube                          = imageViewType == VK_IMAGE_VIEW_TYPE_CUBE || imageViewType == VK_IMAGE_VIEW_TYPE_CUBE_ARRAY;
2077         VkImageCreateFlags                              imageCreateFlags        = isCube ? (VkImageCreateFlags)VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT : (VkImageCreateFlags)0;
2078         VkImageUsageFlags                               imageUsageFlags         = VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
2079         Move<VkImage>                                   vkTexture;
2080         de::MovePtr<Allocation>                 allocation;
2081
2082         if (m_imageBackingMode == IMAGE_BACKING_MODE_SPARSE)
2083         {
2084                 imageCreateFlags |= VK_IMAGE_CREATE_SPARSE_BINDING_BIT | VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT;
2085         }
2086
2087         // Create image
2088         const VkImageCreateInfo                 imageParams =
2089         {
2090                 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,                                                    // VkStructureType                      sType;
2091                 DE_NULL,                                                                                                                // const void*                          pNext;
2092                 imageCreateFlags,                                                                                               // VkImageCreateFlags           flags;
2093                 imageType,                                                                                                              // VkImageType                          imageType;
2094                 format,                                                                                                                 // VkFormat                                     format;
2095                 {                                                                                                                               // VkExtent3D                           extent;
2096                         texSize.x(),
2097                         texSize.y(),
2098                         texSize.z()
2099                 },
2100                 mipLevels,                                                                                                              // deUint32                                     mipLevels;
2101                 arrayLayers,                                                                                                    // deUint32                                     arrayLayers;
2102                 textureParams.samples,                                                                                  // VkSampleCountFlagBits        samples;
2103                 VK_IMAGE_TILING_OPTIMAL,                                                                                // VkImageTiling                        tiling;
2104                 imageUsageFlags,                                                                                                // VkImageUsageFlags            usage;
2105                 VK_SHARING_MODE_EXCLUSIVE,                                                                              // VkSharingMode                        sharingMode;
2106                 1u,                                                                                                                             // deUint32                                     queueFamilyIndexCount;
2107                 &queueFamilyIndex,                                                                                              // const deUint32*                      pQueueFamilyIndices;
2108                 VK_IMAGE_LAYOUT_UNDEFINED                                                                               // VkImageLayout                        initialLayout;
2109         };
2110
2111         if (m_imageBackingMode == IMAGE_BACKING_MODE_SPARSE)
2112         {
2113                 checkSparseSupport(imageParams);
2114         }
2115
2116         vkTexture               = createImage(vk, vkDevice, &imageParams);
2117         allocation              = m_memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, *vkTexture), MemoryRequirement::Any);
2118
2119         if (m_imageBackingMode != IMAGE_BACKING_MODE_SPARSE)
2120         {
2121                 VK_CHECK(vk.bindImageMemory(vkDevice, *vkTexture, allocation->getMemory(), allocation->getOffset()));
2122         }
2123
2124         switch (textureInit)
2125         {
2126                 case TextureBinding::INIT_UPLOAD_DATA:
2127                 {
2128                         // upload*Image functions use cmdCopyBufferToImage, which is invalid for multisample images
2129                         DE_ASSERT(textureParams.samples == VK_SAMPLE_COUNT_1_BIT);
2130
2131                         if (m_imageBackingMode == IMAGE_BACKING_MODE_SPARSE)
2132                         {
2133                                 uploadSparseImage(texFormat, textureData, refSampler, mipLevels, arrayLayers, *vkTexture, imageParams, texSize);
2134                         }
2135                         else
2136                         {
2137                                 // Upload texture data
2138                                 uploadImage(texFormat, textureData, refSampler, mipLevels, arrayLayers, *vkTexture);
2139                         }
2140                         break;
2141                 }
2142                 case TextureBinding::INIT_CLEAR:
2143                         clearImage(refSampler, mipLevels, arrayLayers, *vkTexture);
2144                         break;
2145                 default:
2146                         DE_FATAL("Impossible");
2147         }
2148
2149         // Create sampler
2150         const VkSamplerCreateInfo               samplerParams   = mapSampler(refSampler, texFormat);
2151         Move<VkSampler>                                 sampler                 = createSampler(vk, vkDevice, &samplerParams);
2152         const deUint32                                  baseMipLevel    = textureParams.baseMipLevel;
2153         const vk::VkComponentMapping    components              = textureParams.componentMapping;
2154         const VkImageViewCreateInfo             viewParams              =
2155         {
2156                 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,       // VkStructureType                      sType;
2157                 NULL,                                                                           // const voide*                         pNext;
2158                 0u,                                                                                     // VkImageViewCreateFlags       flags;
2159                 *vkTexture,                                                                     // VkImage                                      image;
2160                 imageViewType,                                                          // VkImageViewType                      viewType;
2161                 format,                                                                         // VkFormat                                     format;
2162                 components,                                                                     // VkChannelMapping                     channels;
2163                 {
2164                         aspectMask,                                             // VkImageAspectFlags   aspectMask;
2165                         baseMipLevel,                                   // deUint32                             baseMipLevel;
2166                         mipLevels - baseMipLevel,               // deUint32                             mipLevels;
2167                         0,                                                              // deUint32                             baseArraySlice;
2168                         arrayLayers                                             // deUint32                             arraySize;
2169                 },                                                                                      // VkImageSubresourceRange      subresourceRange;
2170         };
2171
2172         Move<VkImageView>                               imageView               = createImageView(vk, vkDevice, &viewParams);
2173
2174         const vk::VkDescriptorImageInfo descriptor              =
2175         {
2176                 sampler.get(),                                                          // VkSampler                            sampler;
2177                 imageView.get(),                                                        // VkImageView                          imageView;
2178                 VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,       // VkImageLayout                        imageLayout;
2179         };
2180
2181         de::MovePtr<SamplerUniform> uniform(new SamplerUniform());
2182         uniform->type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
2183         uniform->descriptor = descriptor;
2184         uniform->location = bindingLocation;
2185         uniform->image = VkImageSp(new vk::Unique<VkImage>(vkTexture));
2186         uniform->imageView = VkImageViewSp(new vk::Unique<VkImageView>(imageView));
2187         uniform->sampler = VkSamplerSp(new vk::Unique<VkSampler>(sampler));
2188         uniform->alloc = AllocationSp(allocation.release());
2189
2190         m_descriptorSetLayoutBuilder->addSingleSamplerBinding(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, vk::VK_SHADER_STAGE_ALL, DE_NULL);
2191         m_descriptorPoolBuilder->addType(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER);
2192
2193         m_uniformInfos.push_back(UniformInfoSp(new de::UniquePtr<UniformInfo>(uniform)));
2194 }
2195
2196 void ShaderRenderCaseInstance::setupDefaultInputs (void)
2197 {
2198         /* Configuration of the vertex input attributes:
2199                 a_position   is at location 0
2200                 a_coords     is at location 1
2201                 a_unitCoords is at location 2
2202                 a_one        is at location 3
2203
2204           User attributes starts from at the location 4.
2205         */
2206
2207         DE_ASSERT(m_quadGrid);
2208         const QuadGrid&         quadGrid        = *m_quadGrid;
2209
2210         addAttribute(0u, VK_FORMAT_R32G32B32A32_SFLOAT, sizeof(tcu::Vec4), quadGrid.getNumVertices(), quadGrid.getPositions());
2211         addAttribute(1u, VK_FORMAT_R32G32B32A32_SFLOAT, sizeof(tcu::Vec4), quadGrid.getNumVertices(), quadGrid.getCoords());
2212         addAttribute(2u, VK_FORMAT_R32G32B32A32_SFLOAT, sizeof(tcu::Vec4), quadGrid.getNumVertices(), quadGrid.getUnitCoords());
2213         addAttribute(3u, VK_FORMAT_R32_SFLOAT, sizeof(float), quadGrid.getNumVertices(), quadGrid.getAttribOne());
2214
2215         static const struct
2216         {
2217                 BaseAttributeType       type;
2218                 int                                     userNdx;
2219         } userAttributes[] =
2220         {
2221                 { A_IN0, 0 },
2222                 { A_IN1, 1 },
2223                 { A_IN2, 2 },
2224                 { A_IN3, 3 }
2225         };
2226
2227         static const struct
2228         {
2229                 BaseAttributeType       matrixType;
2230                 int                                     numCols;
2231                 int                                     numRows;
2232         } matrices[] =
2233         {
2234                 { MAT2,         2, 2 },
2235                 { MAT2x3,       2, 3 },
2236                 { MAT2x4,       2, 4 },
2237                 { MAT3x2,       3, 2 },
2238                 { MAT3,         3, 3 },
2239                 { MAT3x4,       3, 4 },
2240                 { MAT4x2,       4, 2 },
2241                 { MAT4x3,       4, 3 },
2242                 { MAT4,         4, 4 }
2243         };
2244
2245         for (size_t attrNdx = 0; attrNdx < m_enabledBaseAttributes.size(); attrNdx++)
2246         {
2247                 for (int userNdx = 0; userNdx < DE_LENGTH_OF_ARRAY(userAttributes); userNdx++)
2248                 {
2249                         if (userAttributes[userNdx].type != m_enabledBaseAttributes[attrNdx].type)
2250                                 continue;
2251
2252                         addAttribute(m_enabledBaseAttributes[attrNdx].location, VK_FORMAT_R32G32B32A32_SFLOAT, sizeof(tcu::Vec4), quadGrid.getNumVertices(), quadGrid.getUserAttrib(userNdx));
2253                 }
2254
2255                 for (int matNdx = 0; matNdx < DE_LENGTH_OF_ARRAY(matrices); matNdx++)
2256                 {
2257
2258                         if (matrices[matNdx].matrixType != m_enabledBaseAttributes[attrNdx].type)
2259                                 continue;
2260
2261                         const int numCols = matrices[matNdx].numCols;
2262
2263                         for (int colNdx = 0; colNdx < numCols; colNdx++)
2264                         {
2265                                 addAttribute(m_enabledBaseAttributes[attrNdx].location + colNdx, VK_FORMAT_R32G32B32A32_SFLOAT, (deUint32)(4 * sizeof(float)), quadGrid.getNumVertices(), quadGrid.getUserAttrib(colNdx));
2266                         }
2267                 }
2268         }
2269 }
2270
2271 void ShaderRenderCaseInstance::render (deUint32                         numVertices,
2272                                                                            deUint32                             numTriangles,
2273                                                                            const deUint16*              indices,
2274                                                                            const tcu::Vec4&             constCoords)
2275 {
2276         render(numVertices, numTriangles * 3, indices, VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, constCoords);
2277 }
2278
2279 void ShaderRenderCaseInstance::render (deUint32                         numVertices,
2280                                                                            deUint32                             numIndices,
2281                                                                            const deUint16*              indices,
2282                                                                            VkPrimitiveTopology  topology,
2283                                                                            const tcu::Vec4&             constCoords)
2284 {
2285         const VkDevice                                                                          vkDevice                                        = getDevice();
2286         const DeviceInterface&                                                          vk                                                      = getDeviceInterface();
2287         const VkQueue                                                                           queue                                           = getUniversalQueue();
2288         const deUint32                                                                          queueFamilyIndex                        = getUniversalQueueFamilyIndex();
2289
2290         vk::Move<vk::VkImage>                                                           colorImage;
2291         de::MovePtr<vk::Allocation>                                                     colorImageAlloc;
2292         vk::Move<vk::VkImageView>                                                       colorImageView;
2293         vk::Move<vk::VkImage>                                                           resolvedImage;
2294         de::MovePtr<vk::Allocation>                                                     resolvedImageAlloc;
2295         vk::Move<vk::VkImageView>                                                       resolvedImageView;
2296         vk::Move<vk::VkRenderPass>                                                      renderPass;
2297         vk::Move<vk::VkFramebuffer>                                                     framebuffer;
2298         vk::Move<vk::VkPipelineLayout>                                          pipelineLayout;
2299         vk::Move<vk::VkPipeline>                                                        graphicsPipeline;
2300         vk::Move<vk::VkShaderModule>                                            vertexShaderModule;
2301         vk::Move<vk::VkShaderModule>                                            fragmentShaderModule;
2302         vk::Move<vk::VkBuffer>                                                          indexBuffer;
2303         de::MovePtr<vk::Allocation>                                                     indexBufferAlloc;
2304         vk::Move<vk::VkDescriptorSetLayout>                                     descriptorSetLayout;
2305         vk::Move<vk::VkDescriptorPool>                                          descriptorPool;
2306         vk::Move<vk::VkDescriptorSet>                                           descriptorSet;
2307         vk::Move<vk::VkCommandPool>                                                     cmdPool;
2308         vk::Move<vk::VkCommandBuffer>                                           cmdBuffer;
2309         vk::Move<vk::VkFence>                                                           fence;
2310
2311         // Create color image
2312         {
2313                 const VkImageUsageFlags imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
2314                 VkImageFormatProperties properties;
2315
2316                 if ((getInstanceInterface().getPhysicalDeviceImageFormatProperties(getPhysicalDevice(),
2317                                                                                                                                                    m_colorFormat,
2318                                                                                                                                                    VK_IMAGE_TYPE_2D,
2319                                                                                                                                                    VK_IMAGE_TILING_OPTIMAL,
2320                                                                                                                                                    imageUsage,
2321                                                                                                                                                    0u,
2322                                                                                                                                                    &properties) == VK_ERROR_FORMAT_NOT_SUPPORTED))
2323                 {
2324                         TCU_THROW(NotSupportedError, "Format not supported");
2325                 }
2326
2327                 if ((properties.sampleCounts & m_sampleCount) != m_sampleCount)
2328                 {
2329                         TCU_THROW(NotSupportedError, "Format not supported");
2330                 }
2331
2332                 const VkImageCreateInfo                                                 colorImageParams                        =
2333                 {
2334                         VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,                                                                            // VkStructureType              sType;
2335                         DE_NULL,                                                                                                                                        // const void*                  pNext;
2336                         0u,                                                                                                                                                     // VkImageCreateFlags   flags;
2337                         VK_IMAGE_TYPE_2D,                                                                                                                       // VkImageType                  imageType;
2338                         m_colorFormat,                                                                                                                          // VkFormat                             format;
2339                         { m_renderSize.x(), m_renderSize.y(), 1u },                                                                     // VkExtent3D                   extent;
2340                         1u,                                                                                                                                                     // deUint32                             mipLevels;
2341                         1u,                                                                                                                                                     // deUint32                             arraySize;
2342                         m_sampleCount,                                                                                                                          // deUint32                             samples;
2343                         VK_IMAGE_TILING_OPTIMAL,                                                                                                        // VkImageTiling                tiling;
2344                         imageUsage,                                                                                                                                     // VkImageUsageFlags    usage;
2345                         VK_SHARING_MODE_EXCLUSIVE,                                                                                                      // VkSharingMode                sharingMode;
2346                         1u,                                                                                                                                                     // deUint32                             queueFamilyCount;
2347                         &queueFamilyIndex,                                                                                                                      // const deUint32*              pQueueFamilyIndices;
2348                         VK_IMAGE_LAYOUT_UNDEFINED,                                                                                                      // VkImageLayout                initialLayout;
2349                 };
2350
2351                 colorImage = createImage(vk, vkDevice, &colorImageParams);
2352
2353                 // Allocate and bind color image memory
2354                 colorImageAlloc = m_memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, *colorImage), MemoryRequirement::Any);
2355                 VK_CHECK(vk.bindImageMemory(vkDevice, *colorImage, colorImageAlloc->getMemory(), colorImageAlloc->getOffset()));
2356         }
2357
2358         // Create color attachment view
2359         {
2360                 const VkImageViewCreateInfo                                             colorImageViewParams            =
2361                 {
2362                         VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,                       // VkStructureType                      sType;
2363                         DE_NULL,                                                                                        // const void*                          pNext;
2364                         0u,                                                                                                     // VkImageViewCreateFlags       flags;
2365                         *colorImage,                                                                            // VkImage                                      image;
2366                         VK_IMAGE_VIEW_TYPE_2D,                                                          // VkImageViewType                      viewType;
2367                         m_colorFormat,                                                                          // VkFormat                                     format;
2368                         {
2369                                 VK_COMPONENT_SWIZZLE_R,                 // VkChannelSwizzle             r;
2370                                 VK_COMPONENT_SWIZZLE_G,                 // VkChannelSwizzle             g;
2371                                 VK_COMPONENT_SWIZZLE_B,                 // VkChannelSwizzle             b;
2372                                 VK_COMPONENT_SWIZZLE_A                  // VkChannelSwizzle             a;
2373                         },                                                                                                      // VkChannelMapping                     channels;
2374                         {
2375                                 VK_IMAGE_ASPECT_COLOR_BIT,              // VkImageAspectFlags   aspectMask;
2376                                 0,                                                              // deUint32                             baseMipLevel;
2377                                 1,                                                              // deUint32                             mipLevels;
2378                                 0,                                                              // deUint32                             baseArraySlice;
2379                                 1                                                               // deUint32                             arraySize;
2380                         },                                                                                                      // VkImageSubresourceRange      subresourceRange;
2381                 };
2382
2383                 colorImageView = createImageView(vk, vkDevice, &colorImageViewParams);
2384         }
2385
2386         if (isMultiSampling())
2387         {
2388                 // Resolved Image
2389                 {
2390                         const VkImageUsageFlags imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
2391                         VkImageFormatProperties properties;
2392
2393                         if ((getInstanceInterface().getPhysicalDeviceImageFormatProperties(getPhysicalDevice(),
2394                                                                                                                                                            m_colorFormat,
2395                                                                                                                                                            VK_IMAGE_TYPE_2D,
2396                                                                                                                                                            VK_IMAGE_TILING_OPTIMAL,
2397                                                                                                                                                            imageUsage,
2398                                                                                                                                                            0,
2399                                                                                                                                                            &properties) == VK_ERROR_FORMAT_NOT_SUPPORTED))
2400                         {
2401                                 TCU_THROW(NotSupportedError, "Format not supported");
2402                         }
2403
2404                         const VkImageCreateInfo                                 imageCreateInfo                 =
2405                         {
2406                                 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,            // VkStructureType                      sType;
2407                                 DE_NULL,                                                                        // const void*                          pNext;
2408                                 0u,                                                                                     // VkImageCreateFlags           flags;
2409                                 VK_IMAGE_TYPE_2D,                                                       // VkImageType                          imageType;
2410                                 m_colorFormat,                                                          // VkFormat                                     format;
2411                                 { m_renderSize.x(),     m_renderSize.y(), 1u }, // VkExtent3D                           extent;
2412                                 1u,                                                                                     // deUint32                                     mipLevels;
2413                                 1u,                                                                                     // deUint32                                     arrayLayers;
2414                                 VK_SAMPLE_COUNT_1_BIT,                                          // VkSampleCountFlagBits        samples;
2415                                 VK_IMAGE_TILING_OPTIMAL,                                        // VkImageTiling                        tiling;
2416                                 imageUsage,                                                                     // VkImageUsageFlags            usage;
2417                                 VK_SHARING_MODE_EXCLUSIVE,                                      // VkSharingMode                        sharingMode;
2418                                 1u,                                                                                     // deUint32                                     queueFamilyIndexCount;
2419                                 &queueFamilyIndex,                                                      // const deUint32*                      pQueueFamilyIndices;
2420                                 VK_IMAGE_LAYOUT_UNDEFINED                                       // VkImageLayout                        initialLayout;
2421                         };
2422
2423                         resolvedImage           = vk::createImage(vk, vkDevice, &imageCreateInfo, DE_NULL);
2424                         resolvedImageAlloc      = m_memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, *resolvedImage), MemoryRequirement::Any);
2425                         VK_CHECK(vk.bindImageMemory(vkDevice, *resolvedImage, resolvedImageAlloc->getMemory(), resolvedImageAlloc->getOffset()));
2426                 }
2427
2428                 // Resolved Image View
2429                 {
2430                         const VkImageViewCreateInfo                             imageViewCreateInfo             =
2431                         {
2432                                 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,       // VkStructureType                              sType;
2433                                 DE_NULL,                                                                        // const void*                                  pNext;
2434                                 0u,                                                                                     // VkImageViewCreateFlags               flags;
2435                                 *resolvedImage,                                                         // VkImage                                              image;
2436                                 VK_IMAGE_VIEW_TYPE_2D,                                          // VkImageViewType                              viewType;
2437                                 m_colorFormat,                                                          // VkFormat                                             format;
2438                                 {
2439                                         VK_COMPONENT_SWIZZLE_R,                                 // VkChannelSwizzle             r;
2440                                         VK_COMPONENT_SWIZZLE_G,                                 // VkChannelSwizzle             g;
2441                                         VK_COMPONENT_SWIZZLE_B,                                 // VkChannelSwizzle             b;
2442                                         VK_COMPONENT_SWIZZLE_A                                  // VkChannelSwizzle             a;
2443                                 },
2444                                 {
2445                                         VK_IMAGE_ASPECT_COLOR_BIT,                                      // VkImageAspectFlags                   aspectMask;
2446                                         0u,                                                                                     // deUint32                                             baseMipLevel;
2447                                         1u,                                                                                     // deUint32                                             mipLevels;
2448                                         0u,                                                                                     // deUint32                                             baseArrayLayer;
2449                                         1u,                                                                                     // deUint32                                             arraySize;
2450                                 },                                                                                      // VkImageSubresourceRange              subresourceRange;
2451                         };
2452
2453                         resolvedImageView = vk::createImageView(vk, vkDevice, &imageViewCreateInfo, DE_NULL);
2454                 }
2455         }
2456
2457         // Create render pass
2458         {
2459                 const VkAttachmentDescription                                   attachmentDescription[]         =
2460                 {
2461                         {
2462                                 (VkAttachmentDescriptionFlags)0,                                        // VkAttachmentDescriptionFlags         flags;
2463                                 m_colorFormat,                                                                          // VkFormat                                                     format;
2464                                 m_sampleCount,                                                                          // deUint32                                                     samples;
2465                                 VK_ATTACHMENT_LOAD_OP_CLEAR,                                            // VkAttachmentLoadOp                           loadOp;
2466                                 VK_ATTACHMENT_STORE_OP_STORE,                                           // VkAttachmentStoreOp                          storeOp;
2467                                 VK_ATTACHMENT_LOAD_OP_DONT_CARE,                                        // VkAttachmentLoadOp                           stencilLoadOp;
2468                                 VK_ATTACHMENT_STORE_OP_DONT_CARE,                                       // VkAttachmentStoreOp                          stencilStoreOp;
2469                                 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,                       // VkImageLayout                                        initialLayout;
2470                                 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,                       // VkImageLayout                                        finalLayout;
2471                         },
2472                         {
2473                                 (VkAttachmentDescriptionFlags)0,                                        // VkAttachmentDescriptionFlags         flags;
2474                                 m_colorFormat,                                                                          // VkFormat                                                     format;
2475                                 VK_SAMPLE_COUNT_1_BIT,                                                          // VkSampleCountFlagBits                        samples;
2476                                 VK_ATTACHMENT_LOAD_OP_DONT_CARE,                                        // VkAttachmentLoadOp                           loadOp;
2477                                 VK_ATTACHMENT_STORE_OP_STORE,                                           // VkAttachmentStoreOp                          storeOp;
2478                                 VK_ATTACHMENT_LOAD_OP_DONT_CARE,                                        // VkAttachmentLoadOp                           stencilLoadOp;
2479                                 VK_ATTACHMENT_STORE_OP_DONT_CARE,                                       // VkAttachmentStoreOp                          stencilStoreOp;
2480                                 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,                       // VkImageLayout                                        initialLayout;
2481                                 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,                       // VkImageLayout                                        finalLayout;
2482                         }
2483                 };
2484
2485                 const VkAttachmentReference                                             attachmentReference                     =
2486                 {
2487                         0u,                                                                                                     // deUint32                     attachment;
2488                         VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL                        // VkImageLayout        layout;
2489                 };
2490
2491                 const VkAttachmentReference                                             resolveAttachmentRef            =
2492                 {
2493                         1u,                                                                                                     // deUint32                     attachment;
2494                         VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL                        // VkImageLayout        layout;
2495                 };
2496
2497                 const VkSubpassDescription                                              subpassDescription                      =
2498                 {
2499                         0u,                                                                                                     // VkSubpassDescriptionFlags    flags;
2500                         VK_PIPELINE_BIND_POINT_GRAPHICS,                                        // VkPipelineBindPoint                  pipelineBindPoint;
2501                         0u,                                                                                                     // deUint32                                             inputCount;
2502                         DE_NULL,                                                                                        // constVkAttachmentReference*  pInputAttachments;
2503                         1u,                                                                                                     // deUint32                                             colorCount;
2504                         &attachmentReference,                                                           // constVkAttachmentReference*  pColorAttachments;
2505                         isMultiSampling() ? &resolveAttachmentRef : DE_NULL,// constVkAttachmentReference*      pResolveAttachments;
2506                         DE_NULL,                                                                                        // VkAttachmentReference                depthStencilAttachment;
2507                         0u,                                                                                                     // deUint32                                             preserveCount;
2508                         DE_NULL                                                                                         // constVkAttachmentReference*  pPreserveAttachments;
2509                 };
2510
2511                 const VkRenderPassCreateInfo                                    renderPassParams                        =
2512                 {
2513                         VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,                      // VkStructureType                                      sType;
2514                         DE_NULL,                                                                                        // const void*                                          pNext;
2515                         0u,                                                                                                     // VkRenderPassCreateFlags                      flags;
2516                         isMultiSampling() ? 2u : 1u,                                            // deUint32                                                     attachmentCount;
2517                         attachmentDescription,                                                          // const VkAttachmentDescription*       pAttachments;
2518                         1u,                                                                                                     // deUint32                                                     subpassCount;
2519                         &subpassDescription,                                                            // const VkSubpassDescription*          pSubpasses;
2520                         0u,                                                                                                     // deUint32                                                     dependencyCount;
2521                         DE_NULL                                                                                         // const VkSubpassDependency*           pDependencies;
2522                 };
2523
2524                 renderPass = createRenderPass(vk, vkDevice, &renderPassParams);
2525         }
2526
2527         // Create framebuffer
2528         {
2529                 const VkImageView                                                               attachments[]                           =
2530                 {
2531                         *colorImageView,
2532                         *resolvedImageView
2533                 };
2534
2535                 const VkFramebufferCreateInfo                                   framebufferParams                       =
2536                 {
2537                         VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,                      // VkStructureType                              sType;
2538                         DE_NULL,                                                                                        // const void*                                  pNext;
2539                         (VkFramebufferCreateFlags)0,
2540                         *renderPass,                                                                            // VkRenderPass                                 renderPass;
2541                         isMultiSampling() ? 2u : 1u,                                            // deUint32                                             attachmentCount;
2542                         attachments,                                                                            // const VkImageView*                   pAttachments;
2543                         (deUint32)m_renderSize.x(),                                                     // deUint32                                             width;
2544                         (deUint32)m_renderSize.y(),                                                     // deUint32                                             height;
2545                         1u                                                                                                      // deUint32                                             layers;
2546                 };
2547
2548                 framebuffer = createFramebuffer(vk, vkDevice, &framebufferParams);
2549         }
2550
2551         // Create descriptors
2552         {
2553                 setupUniforms(constCoords);
2554
2555                 descriptorSetLayout = m_descriptorSetLayoutBuilder->build(vk, vkDevice);
2556                 if (!m_uniformInfos.empty())
2557                 {
2558                         descriptorPool                                                                  = m_descriptorPoolBuilder->build(vk, vkDevice, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u);
2559                         const VkDescriptorSetAllocateInfo       allocInfo       =
2560                         {
2561                                 VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
2562                                 DE_NULL,
2563                                 *descriptorPool,
2564                                 1u,
2565                                 &descriptorSetLayout.get(),
2566                         };
2567
2568                         descriptorSet = allocateDescriptorSet(vk, vkDevice, &allocInfo);
2569                 }
2570
2571                 for (deUint32 i = 0; i < m_uniformInfos.size(); i++)
2572                 {
2573                         const UniformInfo* uniformInfo = m_uniformInfos[i].get()->get();
2574                         deUint32 location = uniformInfo->location;
2575
2576                         if (uniformInfo->type == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER)
2577                         {
2578                                 const BufferUniform*    bufferInfo      = dynamic_cast<const BufferUniform*>(uniformInfo);
2579
2580                                 m_descriptorSetUpdateBuilder->writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(location), uniformInfo->type, &bufferInfo->descriptor);
2581                         }
2582                         else if (uniformInfo->type == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER)
2583                         {
2584                                 const SamplerUniform*   samplerInfo     = dynamic_cast<const SamplerUniform*>(uniformInfo);
2585
2586                                 m_descriptorSetUpdateBuilder->writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(location), uniformInfo->type, &samplerInfo->descriptor);
2587                         }
2588                         else
2589                                 DE_FATAL("Impossible");
2590                 }
2591
2592                 m_descriptorSetUpdateBuilder->update(vk, vkDevice);
2593         }
2594
2595         // Create pipeline layout
2596         {
2597                 const VkPushConstantRange* const                                pcRanges                                        = m_pushConstantRanges.empty() ? DE_NULL : &m_pushConstantRanges[0];
2598                 const VkPipelineLayoutCreateInfo                                pipelineLayoutParams            =
2599                 {
2600                         VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,          // VkStructureType                              sType;
2601                         DE_NULL,                                                                                        // const void*                                  pNext;
2602                         (VkPipelineLayoutCreateFlags)0,
2603                         1u,                                                                                                     // deUint32                                             descriptorSetCount;
2604                         &*descriptorSetLayout,                                                          // const VkDescriptorSetLayout* pSetLayouts;
2605                         deUint32(m_pushConstantRanges.size()),                          // deUint32                                             pushConstantRangeCount;
2606                         pcRanges                                                                                        // const VkPushConstantRange*   pPushConstantRanges;
2607                 };
2608
2609                 pipelineLayout = createPipelineLayout(vk, vkDevice, &pipelineLayoutParams);
2610         }
2611
2612         // Create shaders
2613         {
2614                 vertexShaderModule              = createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get(m_vertexShaderName), 0);
2615                 fragmentShaderModule    = createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get(m_fragmentShaderName), 0);
2616         }
2617
2618         // Create pipeline
2619         {
2620                 const VkPipelineShaderStageCreateInfo                   shaderStageParams[2]            =
2621                 {
2622                         {
2623                                 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,            // VkStructureType                              sType;
2624                                 DE_NULL,                                                                                                        // const void*                                  pNext;
2625                                 (VkPipelineShaderStageCreateFlags)0,
2626                                 VK_SHADER_STAGE_VERTEX_BIT,                                                                     // VkShaderStage                                stage;
2627                                 *vertexShaderModule,                                                                            // VkShader                                             shader;
2628                                 "main",
2629                                 DE_NULL                                                                                                         // const VkSpecializationInfo*  pSpecializationInfo;
2630                         },
2631                         {
2632                                 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,            // VkStructureType                              sType;
2633                                 DE_NULL,                                                                                                        // const void*                                  pNext;
2634                                 (VkPipelineShaderStageCreateFlags)0,
2635                                 VK_SHADER_STAGE_FRAGMENT_BIT,                                                           // VkShaderStage                                stage;
2636                                 *fragmentShaderModule,                                                                          // VkShader                                             shader;
2637                                 "main",
2638                                 DE_NULL                                                                                                         // const VkSpecializationInfo*  pSpecializationInfo;
2639                         }
2640                 };
2641
2642                 // Add test case specific attributes
2643                 if (m_attribFunc)
2644                         m_attribFunc(*this, numVertices);
2645
2646                 // Add base attributes
2647                 setupDefaultInputs();
2648
2649                 const VkPipelineVertexInputStateCreateInfo              vertexInputStateParams          =
2650                 {
2651                         VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,              // VkStructureType                                                      sType;
2652                         DE_NULL,                                                                                                                // const void*                                                          pNext;
2653                         (VkPipelineVertexInputStateCreateFlags)0,
2654                         (deUint32)m_vertexBindingDescription.size(),                                    // deUint32                                                                     bindingCount;
2655                         &m_vertexBindingDescription[0],                                                                 // const VkVertexInputBindingDescription*       pVertexBindingDescriptions;
2656                         (deUint32)m_vertexAttributeDescription.size(),                                  // deUint32                                                                     attributeCount;
2657                         &m_vertexAttributeDescription[0],                                                               // const VkVertexInputAttributeDescription*     pVertexAttributeDescriptions;
2658                 };
2659
2660                 const VkPipelineInputAssemblyStateCreateInfo    inputAssemblyStateParams        =
2661                 {
2662                         VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,    // VkStructureType              sType;
2663                         DE_NULL,                                                                                                                // const void*                  pNext;
2664                         (VkPipelineInputAssemblyStateCreateFlags)0,
2665                         topology,                                                                                                               // VkPrimitiveTopology  topology;
2666                         false                                                                                                                   // VkBool32                             primitiveRestartEnable;
2667                 };
2668
2669                 const VkViewport                                                                viewport                                        =
2670                 {
2671                         0.0f,                                           // float        originX;
2672                         0.0f,                                           // float        originY;
2673                         (float)m_renderSize.x(),        // float        width;
2674                         (float)m_renderSize.y(),        // float        height;
2675                         0.0f,                                           // float        minDepth;
2676                         1.0f                                            // float        maxDepth;
2677                 };
2678
2679                 const VkRect2D                                                                  scissor                                         =
2680                 {
2681                         {
2682                                 0u,                                     // deUint32     x;
2683                                 0u,                                     // deUint32     y;
2684                         },                                                      // VkOffset2D   offset;
2685                         {
2686                                 m_renderSize.x(),       // deUint32     width;
2687                                 m_renderSize.y(),       // deUint32     height;
2688                         },                                                      // VkExtent2D   extent;
2689                 };
2690
2691                 const VkPipelineViewportStateCreateInfo                 viewportStateParams                     =
2692                 {
2693                         VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO,                  // VkStructureType                                              sType;
2694                         DE_NULL,                                                                                                                // const void*                                                  pNext;
2695                         0u,                                                                                                                             // VkPipelineViewportStateCreateFlags   flags;
2696                         1u,                                                                                                                             // deUint32                                                             viewportCount;
2697                         &viewport,                                                                                                              // const VkViewport*                                    pViewports;
2698                         1u,                                                                                                                             // deUint32                                                             scissorsCount;
2699                         &scissor,                                                                                                               // const VkRect2D*                                              pScissors;
2700                 };
2701
2702                 const VkPipelineRasterizationStateCreateInfo    rasterStateParams                       =
2703                 {
2704                         VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO,             // VkStructureType      sType;
2705                         DE_NULL,                                                                                                                // const void*          pNext;
2706                         (VkPipelineRasterizationStateCreateFlags)0,
2707                         false,                                                                                                                  // VkBool32                     depthClipEnable;
2708                         false,                                                                                                                  // VkBool32                     rasterizerDiscardEnable;
2709                         VK_POLYGON_MODE_FILL,                                                                                   // VkFillMode           fillMode;
2710                         VK_CULL_MODE_NONE,                                                                                              // VkCullMode           cullMode;
2711                         VK_FRONT_FACE_COUNTER_CLOCKWISE,                                                                // VkFrontFace          frontFace;
2712                         false,                                                                                                                  // VkBool32                     depthBiasEnable;
2713                         0.0f,                                                                                                                   // float                        depthBias;
2714                         0.0f,                                                                                                                   // float                        depthBiasClamp;
2715                         0.0f,                                                                                                                   // float                        slopeScaledDepthBias;
2716                         1.0f,                                                                                                                   // float                        lineWidth;
2717                 };
2718
2719                 const VkPipelineMultisampleStateCreateInfo              multisampleStateParams =
2720                 {
2721                         VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,               // VkStructureType                                                      sType;
2722                         DE_NULL,                                                                                                                // const void*                                                          pNext;
2723                         0u,                                                                                                                             // VkPipelineMultisampleStateCreateFlags        flags;
2724                         m_sampleCount,                                                                                                  // VkSampleCountFlagBits                                        rasterizationSamples;
2725                         VK_FALSE,                                                                                                               // VkBool32                                                                     sampleShadingEnable;
2726                         0.0f,                                                                                                                   // float                                                                        minSampleShading;
2727                         DE_NULL,                                                                                                                // const VkSampleMask*                                          pSampleMask;
2728                         VK_FALSE,                                                                                                               // VkBool32                                                                     alphaToCoverageEnable;
2729                         VK_FALSE                                                                                                                // VkBool32                                                                     alphaToOneEnable;
2730                 };
2731
2732                 const VkPipelineColorBlendAttachmentState               colorBlendAttachmentState       =
2733                 {
2734                         false,                                                                                                                  // VkBool32                     blendEnable;
2735                         VK_BLEND_FACTOR_ONE,                                                                                    // VkBlend                      srcBlendColor;
2736                         VK_BLEND_FACTOR_ZERO,                                                                                   // VkBlend                      destBlendColor;
2737                         VK_BLEND_OP_ADD,                                                                                                // VkBlendOp            blendOpColor;
2738                         VK_BLEND_FACTOR_ONE,                                                                                    // VkBlend                      srcBlendAlpha;
2739                         VK_BLEND_FACTOR_ZERO,                                                                                   // VkBlend                      destBlendAlpha;
2740                         VK_BLEND_OP_ADD,                                                                                                // VkBlendOp            blendOpAlpha;
2741                         (VK_COLOR_COMPONENT_R_BIT |
2742                          VK_COLOR_COMPONENT_G_BIT |
2743                          VK_COLOR_COMPONENT_B_BIT |
2744                          VK_COLOR_COMPONENT_A_BIT),                                                                             // VkChannelFlags       channelWriteMask;
2745                 };
2746
2747                 const VkPipelineColorBlendStateCreateInfo               colorBlendStateParams           =
2748                 {
2749                         VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,       // VkStructureType                                                              sType;
2750                         DE_NULL,                                                                                                        // const void*                                                                  pNext;
2751                         (VkPipelineColorBlendStateCreateFlags)0,
2752                         false,                                                                                                          // VkBool32                                                                             logicOpEnable;
2753                         VK_LOGIC_OP_COPY,                                                                                       // VkLogicOp                                                                    logicOp;
2754                         1u,                                                                                                                     // deUint32                                                                             attachmentCount;
2755                         &colorBlendAttachmentState,                                                                     // const VkPipelineColorBlendAttachmentState*   pAttachments;
2756                         { 0.0f, 0.0f, 0.0f, 0.0f },                                                                     // float                                                                                blendConst[4];
2757                 };
2758
2759                 const VkGraphicsPipelineCreateInfo                              graphicsPipelineParams          =
2760                 {
2761                         VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,        // VkStructureType                                                                      sType;
2762                         DE_NULL,                                                                                        // const void*                                                                          pNext;
2763                         0u,                                                                                                     // VkPipelineCreateFlags                                                        flags;
2764                         2u,                                                                                                     // deUint32                                                                                     stageCount;
2765                         shaderStageParams,                                                                      // const VkPipelineShaderStageCreateInfo*                       pStages;
2766                         &vertexInputStateParams,                                                        // const VkPipelineVertexInputStateCreateInfo*          pVertexInputState;
2767                         &inputAssemblyStateParams,                                                      // const VkPipelineInputAssemblyStateCreateInfo*        pInputAssemblyState;
2768                         DE_NULL,                                                                                        // const VkPipelineTessellationStateCreateInfo*         pTessellationState;
2769                         &viewportStateParams,                                                           // const VkPipelineViewportStateCreateInfo*                     pViewportState;
2770                         &rasterStateParams,                                                                     // const VkPipelineRasterStateCreateInfo*                       pRasterState;
2771                         &multisampleStateParams,                                                        // const VkPipelineMultisampleStateCreateInfo*          pMultisampleState;
2772                         DE_NULL,                                                                                        // const VkPipelineDepthStencilStateCreateInfo*         pDepthStencilState;
2773                         &colorBlendStateParams,                                                         // const VkPipelineColorBlendStateCreateInfo*           pColorBlendState;
2774                         (const VkPipelineDynamicStateCreateInfo*)DE_NULL,       // const VkPipelineDynamicStateCreateInfo*                      pDynamicState;
2775                         *pipelineLayout,                                                                        // VkPipelineLayout                                                                     layout;
2776                         *renderPass,                                                                            // VkRenderPass                                                                         renderPass;
2777                         0u,                                                                                                     // deUint32                                                                                     subpass;
2778                         0u,                                                                                                     // VkPipeline                                                                           basePipelineHandle;
2779                         0u                                                                                                      // deInt32                                                                                      basePipelineIndex;
2780                 };
2781
2782                 graphicsPipeline = createGraphicsPipeline(vk, vkDevice, DE_NULL, &graphicsPipelineParams);
2783         }
2784
2785         // Create vertex indices buffer
2786         if (numIndices != 0)
2787         {
2788                 const VkDeviceSize                                                              indexBufferSize                 = numIndices * sizeof(deUint16);
2789                 const VkBufferCreateInfo                                                indexBufferParams               =
2790                 {
2791                         VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,           // VkStructureType              sType;
2792                         DE_NULL,                                                                        // const void*                  pNext;
2793                         0u,                                                                                     // VkBufferCreateFlags  flags;
2794                         indexBufferSize,                                                        // VkDeviceSize                 size;
2795                         VK_BUFFER_USAGE_INDEX_BUFFER_BIT,                       // VkBufferUsageFlags   usage;
2796                         VK_SHARING_MODE_EXCLUSIVE,                                      // VkSharingMode                sharingMode;
2797                         1u,                                                                                     // deUint32                             queueFamilyCount;
2798                         &queueFamilyIndex                                                       // const deUint32*              pQueueFamilyIndices;
2799                 };
2800
2801                 indexBuffer                     = createBuffer(vk, vkDevice, &indexBufferParams);
2802                 indexBufferAlloc        = m_memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *indexBuffer), MemoryRequirement::HostVisible);
2803
2804                 VK_CHECK(vk.bindBufferMemory(vkDevice, *indexBuffer, indexBufferAlloc->getMemory(), indexBufferAlloc->getOffset()));
2805
2806                 // Load vertice indices into buffer
2807                 deMemcpy(indexBufferAlloc->getHostPtr(), indices, (size_t)indexBufferSize);
2808                 flushMappedMemoryRange(vk, vkDevice, indexBufferAlloc->getMemory(), indexBufferAlloc->getOffset(), indexBufferSize);
2809         }
2810
2811         // Create command pool
2812         cmdPool = createCommandPool(vk, vkDevice, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, queueFamilyIndex);
2813
2814         // Create command buffer
2815         {
2816                 const VkCommandBufferBeginInfo                                  cmdBufferBeginInfo                      =
2817                 {
2818                         VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,    // VkStructureType                      sType;
2819                         DE_NULL,                                                                                // const void*                          pNext;
2820                         0u,                                                                                             // VkCmdBufferOptimizeFlags     flags;
2821                         (const VkCommandBufferInheritanceInfo*)DE_NULL,
2822                 };
2823
2824                 const VkClearValue                                                              clearValues                                     = makeClearValueColorF32(m_clearColor.x(),
2825                                                                                                                                                                                                                          m_clearColor.y(),
2826                                                                                                                                                                                                                          m_clearColor.z(),
2827                                                                                                                                                                                                                          m_clearColor.w());
2828
2829                 const VkRenderPassBeginInfo                                             renderPassBeginInfo                     =
2830                 {
2831                         VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,                               // VkStructureType              sType;
2832                         DE_NULL,                                                                                                // const void*                  pNext;
2833                         *renderPass,                                                                                    // VkRenderPass                 renderPass;
2834                         *framebuffer,                                                                                   // VkFramebuffer                framebuffer;
2835                         { { 0, 0 },  {m_renderSize.x(), m_renderSize.y() } },   // VkRect2D                             renderArea;
2836                         1,                                                                                                              // deUint32                             clearValueCount;
2837                         &clearValues,                                                                                   // const VkClearValue*  pClearValues;
2838                 };
2839
2840                 cmdBuffer = allocateCommandBuffer(vk, vkDevice, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
2841
2842                 VK_CHECK(vk.beginCommandBuffer(*cmdBuffer, &cmdBufferBeginInfo));
2843
2844                 {
2845                         const VkImageMemoryBarrier                                      imageBarrier                            =
2846                         {
2847                                 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,                                                                         // VkStructureType                      sType;
2848                                 DE_NULL,                                                                                                                                        // const void*                          pNext;
2849                                 0u,                                                                                                                                                     // VkAccessFlags                        srcAccessMask;
2850                                 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,                                                                           // VkAccessFlags                        dstAccessMask;
2851                                 VK_IMAGE_LAYOUT_UNDEFINED,                                                                                                      // VkImageLayout                        oldLayout;
2852                                 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,                                                                       // VkImageLayout                        newLayout;
2853                                 VK_QUEUE_FAMILY_IGNORED,                                                                                                        // deUint32                                     srcQueueFamilyIndex;
2854                                 VK_QUEUE_FAMILY_IGNORED,                                                                                                        // deUint32                                     dstQueueFamilyIndex;
2855                                 *colorImage,                                                                                                                            // VkImage                                      image;
2856                                 {                                                                                                                                                       // VkImageSubresourceRange      subresourceRange;
2857                                         VK_IMAGE_ASPECT_COLOR_BIT,                                                                                              // VkImageAspectFlags           aspectMask;
2858                                         0u,                                                                                                                                             // deUint32                                     baseMipLevel;
2859                                         1u,                                                                                                                                             // deUint32                                     mipLevels;
2860                                         0u,                                                                                                                                             // deUint32                                     baseArrayLayer;
2861                                         1u,                                                                                                                                             // deUint32                                     arraySize;
2862                                 }
2863                         };
2864
2865                         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);
2866
2867                         if (isMultiSampling()) {
2868                                 // add multisample barrier
2869                                 const VkImageMemoryBarrier                              multiSampleImageBarrier         =
2870                                 {
2871                                         VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,                                                                         // VkStructureType                      sType;
2872                                         DE_NULL,                                                                                                                                        // const void*                          pNext;
2873                                         0u,                                                                                                                                                     // VkAccessFlags                        srcAccessMask;
2874                                         VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,                                                                           // VkAccessFlags                        dstAccessMask;
2875                                         VK_IMAGE_LAYOUT_UNDEFINED,                                                                                                      // VkImageLayout                        oldLayout;
2876                                         VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,                                                                       // VkImageLayout                        newLayout;
2877                                         VK_QUEUE_FAMILY_IGNORED,                                                                                                        // deUint32                                     srcQueueFamilyIndex;
2878                                         VK_QUEUE_FAMILY_IGNORED,                                                                                                        // deUint32                                     dstQueueFamilyIndex;
2879                                         *resolvedImage,                                                                                                                         // VkImage                                      image;
2880                                         {                                                                                                                                                       // VkImageSubresourceRange      subresourceRange;
2881                                                 VK_IMAGE_ASPECT_COLOR_BIT,                                                                                              // VkImageAspectFlags           aspectMask;
2882                                                 0u,                                                                                                                                             // deUint32                                     baseMipLevel;
2883                                                 1u,                                                                                                                                             // deUint32                                     mipLevels;
2884                                                 0u,                                                                                                                                             // deUint32                                     baseArrayLayer;
2885                                                 1u,                                                                                                                                             // deUint32                                     arraySize;
2886                                         }
2887                                 };
2888
2889                                 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);
2890                         }
2891                 }
2892
2893                 vk.cmdBeginRenderPass(*cmdBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
2894                 updatePushConstants(*cmdBuffer, *pipelineLayout);
2895                 vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *graphicsPipeline);
2896                 if (!m_uniformInfos.empty())
2897                         vk.cmdBindDescriptorSets(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipelineLayout, 0u, 1, &*descriptorSet, 0u, DE_NULL);
2898
2899                 const deUint32 numberOfVertexAttributes = (deUint32)m_vertexBuffers.size();
2900                 const std::vector<VkDeviceSize> offsets(numberOfVertexAttributes, 0);
2901
2902                 std::vector<VkBuffer> buffers(numberOfVertexAttributes);
2903                 for (size_t i = 0; i < numberOfVertexAttributes; i++)
2904                 {
2905                         buffers[i] = m_vertexBuffers[i].get()->get();
2906                 }
2907
2908                 vk.cmdBindVertexBuffers(*cmdBuffer, 0, numberOfVertexAttributes, &buffers[0], &offsets[0]);
2909                 if (numIndices != 0)
2910                 {
2911                         vk.cmdBindIndexBuffer(*cmdBuffer, *indexBuffer, 0, VK_INDEX_TYPE_UINT16);
2912                         vk.cmdDrawIndexed(*cmdBuffer, numIndices, 1, 0, 0, 0);
2913                 }
2914                 else
2915                         vk.cmdDraw(*cmdBuffer, numVertices,  1, 0, 1);
2916
2917                 vk.cmdEndRenderPass(*cmdBuffer);
2918                 VK_CHECK(vk.endCommandBuffer(*cmdBuffer));
2919         }
2920
2921         // Create fence
2922         fence = createFence(vk, vkDevice);
2923
2924         // Execute Draw
2925         {
2926                 const VkSubmitInfo      submitInfo      =
2927                 {
2928                         VK_STRUCTURE_TYPE_SUBMIT_INFO,
2929                         DE_NULL,
2930                         0u,
2931                         (const VkSemaphore*)DE_NULL,
2932                         (const VkPipelineStageFlags*)DE_NULL,
2933                         1u,
2934                         &cmdBuffer.get(),
2935                         0u,
2936                         (const VkSemaphore*)DE_NULL,
2937                 };
2938
2939                 VK_CHECK(vk.queueSubmit(queue, 1, &submitInfo, *fence));
2940                 VK_CHECK(vk.waitForFences(vkDevice, 1, &fence.get(), true, ~(0ull) /* infinity*/));
2941         }
2942
2943         // Read back the result
2944         {
2945                 const tcu::TextureFormat                                                resultFormat                            = mapVkFormat(m_colorFormat);
2946                 const VkDeviceSize                                                              imageSizeBytes                          = (VkDeviceSize)(resultFormat.getPixelSize() * m_renderSize.x() * m_renderSize.y());
2947                 const VkBufferCreateInfo                                                readImageBufferParams           =
2948                 {
2949                         VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,           //  VkStructureType             sType;
2950                         DE_NULL,                                                                        //  const void*                 pNext;
2951                         0u,                                                                                     //  VkBufferCreateFlags flags;
2952                         imageSizeBytes,                                                         //  VkDeviceSize                size;
2953                         VK_BUFFER_USAGE_TRANSFER_DST_BIT,                       //  VkBufferUsageFlags  usage;
2954                         VK_SHARING_MODE_EXCLUSIVE,                                      //  VkSharingMode               sharingMode;
2955                         1u,                                                                                     //  deUint32                    queueFamilyCount;
2956                         &queueFamilyIndex,                                                      //  const deUint32*             pQueueFamilyIndices;
2957                 };
2958                 const Unique<VkBuffer>                                                  readImageBuffer                         (createBuffer(vk, vkDevice, &readImageBufferParams));
2959                 const de::UniquePtr<Allocation>                                 readImageBufferMemory           (m_memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *readImageBuffer), MemoryRequirement::HostVisible));
2960
2961                 VK_CHECK(vk.bindBufferMemory(vkDevice, *readImageBuffer, readImageBufferMemory->getMemory(), readImageBufferMemory->getOffset()));
2962
2963                 // Copy image to buffer
2964                 const VkCommandBufferBeginInfo                                  cmdBufferBeginInfo                      =
2965                 {
2966                         VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,    // VkStructureType                      sType;
2967                         DE_NULL,                                                                                // const void*                          pNext;
2968                         0u,                                                                                             // VkCmdBufferOptimizeFlags     flags;
2969                         (const VkCommandBufferInheritanceInfo*)DE_NULL,
2970                 };
2971
2972                 const Move<VkCommandBuffer>                                             resultCmdBuffer                         = allocateCommandBuffer(vk, vkDevice, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
2973
2974                 const VkBufferImageCopy                                                 copyParams                                      =
2975                 {
2976                         0u,                                                                                     // VkDeviceSize                 bufferOffset;
2977                         (deUint32)m_renderSize.x(),                                     // deUint32                             bufferRowLength;
2978                         (deUint32)m_renderSize.y(),                                     // deUint32                             bufferImageHeight;
2979                         {
2980                                 VK_IMAGE_ASPECT_COLOR_BIT,                      // VkImageAspect                aspect;
2981                                 0u,                                                                     // deUint32                             mipLevel;
2982                                 0u,                                                                     // deUint32                             arraySlice;
2983                                 1u,                                                                     // deUint32                             arraySize;
2984                         },                                                                                      // VkImageSubresourceCopy       imageSubresource;
2985                         { 0u, 0u, 0u },                                                         // VkOffset3D                   imageOffset;
2986                         { m_renderSize.x(), m_renderSize.y(), 1u }      // VkExtent3D                   imageExtent;
2987                 };
2988                 const VkSubmitInfo                                                              submitInfo                                      =
2989                 {
2990                         VK_STRUCTURE_TYPE_SUBMIT_INFO,
2991                         DE_NULL,
2992                         0u,
2993                         (const VkSemaphore*)DE_NULL,
2994                         (const VkPipelineStageFlags*)DE_NULL,
2995                         1u,
2996                         &resultCmdBuffer.get(),
2997                         0u,
2998                         (const VkSemaphore*)DE_NULL,
2999                 };
3000
3001                 VK_CHECK(vk.beginCommandBuffer(*resultCmdBuffer, &cmdBufferBeginInfo));
3002
3003                 const VkImageMemoryBarrier                                              imageBarrier                            =
3004                 {
3005                         VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,                                                                 // VkStructureType                      sType;
3006                         DE_NULL,                                                                                                                                // const void*                          pNext;
3007                         VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,                                                                   // VkAccessFlags                        srcAccessMask;
3008                         VK_ACCESS_TRANSFER_READ_BIT,                                                                                    // VkAccessFlags                        dstAccessMask;
3009                         VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,                                                               // VkImageLayout                        oldLayout;
3010                         VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,                                                                   // VkImageLayout                        newLayout;
3011                         VK_QUEUE_FAMILY_IGNORED,                                                                                                // deUint32                                     srcQueueFamilyIndex;
3012                         VK_QUEUE_FAMILY_IGNORED,                                                                                                // deUint32                                     dstQueueFamilyIndex;
3013                         isMultiSampling() ? *resolvedImage : *colorImage,                                               // VkImage                                      image;
3014                         {                                                                                                                                               // VkImageSubresourceRange      subresourceRange;
3015                                 VK_IMAGE_ASPECT_COLOR_BIT,                                                                                      // VkImageAspectFlags           aspectMask;
3016                                 0u,                                                                                                                                     // deUint32                                     baseMipLevel;
3017                                 1u,                                                                                                                                     // deUint32                                     mipLevels;
3018                                 0u,                                                                                                                                     // deUint32                                     baseArraySlice;
3019                                 1u                                                                                                                                      // deUint32                                     arraySize;
3020                         }
3021                 };
3022
3023                 const VkBufferMemoryBarrier                                             bufferBarrier                           =
3024                 {
3025                         VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,        // VkStructureType      sType;
3026                         DE_NULL,                                                                        // const void*          pNext;
3027                         VK_ACCESS_TRANSFER_WRITE_BIT,                           // VkAccessFlags        srcAccessMask;
3028                         VK_ACCESS_HOST_READ_BIT,                                        // VkAccessFlags        dstAccessMask;
3029                         VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                     srcQueueFamilyIndex;
3030                         VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                     dstQueueFamilyIndex;
3031                         *readImageBuffer,                                                       // VkBuffer                     buffer;
3032                         0u,                                                                                     // VkDeviceSize         offset;
3033                         imageSizeBytes                                                          // VkDeviceSize         size;
3034                 };
3035
3036                 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);
3037                 vk.cmdCopyImageToBuffer(*resultCmdBuffer, isMultiSampling() ? *resolvedImage : *colorImage, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *readImageBuffer, 1u, &copyParams);
3038                 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);
3039
3040                 VK_CHECK(vk.endCommandBuffer(*resultCmdBuffer));
3041
3042                 VK_CHECK(vk.resetFences(vkDevice, 1, &fence.get()));
3043                 VK_CHECK(vk.queueSubmit(queue, 1, &submitInfo, *fence));
3044                 VK_CHECK(vk.waitForFences(vkDevice, 1, &fence.get(), true, ~(0ull) /* infinity */));
3045
3046                 invalidateMappedMemoryRange(vk, vkDevice, readImageBufferMemory->getMemory(), readImageBufferMemory->getOffset(), imageSizeBytes);
3047
3048                 const tcu::ConstPixelBufferAccess                               resultAccess                            (resultFormat, m_renderSize.x(), m_renderSize.y(), 1, readImageBufferMemory->getHostPtr());
3049
3050                 m_resultImage.setStorage(resultFormat, m_renderSize.x(), m_renderSize.y());
3051                 tcu::copy(m_resultImage.getAccess(), resultAccess);
3052         }
3053 }
3054
3055 void ShaderRenderCaseInstance::computeVertexReference (tcu::Surface& result, const QuadGrid& quadGrid)
3056 {
3057         DE_ASSERT(m_evaluator);
3058
3059         // Buffer info.
3060         const int                               width           = result.getWidth();
3061         const int                               height          = result.getHeight();
3062         const int                               gridSize        = quadGrid.getGridSize();
3063         const int                               stride          = gridSize + 1;
3064         const bool                              hasAlpha        = true; // \todo [2015-09-07 elecro] add correct alpha check
3065         ShaderEvalContext               evalCtx         (quadGrid);
3066
3067         // Evaluate color for each vertex.
3068         std::vector<tcu::Vec4>  colors          ((gridSize + 1) * (gridSize + 1));
3069         for (int y = 0; y < gridSize+1; y++)
3070         for (int x = 0; x < gridSize+1; x++)
3071         {
3072                 const float     sx                      = (float)x / (float)gridSize;
3073                 const float     sy                      = (float)y / (float)gridSize;
3074                 const int       vtxNdx          = ((y * (gridSize+1)) + x);
3075
3076                 evalCtx.reset(sx, sy);
3077                 m_evaluator->evaluate(evalCtx);
3078                 DE_ASSERT(!evalCtx.isDiscarded); // Discard is not available in vertex shader.
3079                 tcu::Vec4 color = evalCtx.color;
3080
3081                 if (!hasAlpha)
3082                         color.w() = 1.0f;
3083
3084                 colors[vtxNdx] = color;
3085         }
3086
3087         // Render quads.
3088         for (int y = 0; y < gridSize; y++)
3089         for (int x = 0; x < gridSize; x++)
3090         {
3091                 const float             x0              = (float)x       / (float)gridSize;
3092                 const float             x1              = (float)(x + 1) / (float)gridSize;
3093                 const float             y0              = (float)y       / (float)gridSize;
3094                 const float             y1              = (float)(y + 1) / (float)gridSize;
3095
3096                 const float             sx0             = x0 * (float)width;
3097                 const float             sx1             = x1 * (float)width;
3098                 const float             sy0             = y0 * (float)height;
3099                 const float             sy1             = y1 * (float)height;
3100                 const float             oosx    = 1.0f / (sx1 - sx0);
3101                 const float             oosy    = 1.0f / (sy1 - sy0);
3102
3103                 const int               ix0             = deCeilFloatToInt32(sx0 - 0.5f);
3104                 const int               ix1             = deCeilFloatToInt32(sx1 - 0.5f);
3105                 const int               iy0             = deCeilFloatToInt32(sy0 - 0.5f);
3106                 const int               iy1             = deCeilFloatToInt32(sy1 - 0.5f);
3107
3108                 const int               v00             = (y * stride) + x;
3109                 const int               v01             = (y * stride) + x + 1;
3110                 const int               v10             = ((y + 1) * stride) + x;
3111                 const int               v11             = ((y + 1) * stride) + x + 1;
3112                 const tcu::Vec4 c00             = colors[v00];
3113                 const tcu::Vec4 c01             = colors[v01];
3114                 const tcu::Vec4 c10             = colors[v10];
3115                 const tcu::Vec4 c11             = colors[v11];
3116
3117                 //printf("(%d,%d) -> (%f..%f, %f..%f) (%d..%d, %d..%d)\n", x, y, sx0, sx1, sy0, sy1, ix0, ix1, iy0, iy1);
3118
3119                 for (int iy = iy0; iy < iy1; iy++)
3120                 for (int ix = ix0; ix < ix1; ix++)
3121                 {
3122                         DE_ASSERT(deInBounds32(ix, 0, width));
3123                         DE_ASSERT(deInBounds32(iy, 0, height));
3124
3125                         const float                     sfx             = (float)ix + 0.5f;
3126                         const float                     sfy             = (float)iy + 0.5f;
3127                         const float                     fx1             = deFloatClamp((sfx - sx0) * oosx, 0.0f, 1.0f);
3128                         const float                     fy1             = deFloatClamp((sfy - sy0) * oosy, 0.0f, 1.0f);
3129
3130                         // Triangle quad interpolation.
3131                         const bool                      tri             = fx1 + fy1 <= 1.0f;
3132                         const float                     tx              = tri ? fx1 : (1.0f-fx1);
3133                         const float                     ty              = tri ? fy1 : (1.0f-fy1);
3134                         const tcu::Vec4&        t0              = tri ? c00 : c11;
3135                         const tcu::Vec4&        t1              = tri ? c01 : c10;
3136                         const tcu::Vec4&        t2              = tri ? c10 : c01;
3137                         const tcu::Vec4         color   = t0 + (t1-t0)*tx + (t2-t0)*ty;
3138
3139                         result.setPixel(ix, iy, tcu::RGBA(color));
3140                 }
3141         }
3142 }
3143
3144 void ShaderRenderCaseInstance::computeFragmentReference (tcu::Surface& result, const QuadGrid& quadGrid)
3145 {
3146         DE_ASSERT(m_evaluator);
3147
3148         // Buffer info.
3149         const int                       width           = result.getWidth();
3150         const int                       height          = result.getHeight();
3151         const bool                      hasAlpha        = true;  // \todo [2015-09-07 elecro] add correct alpha check
3152         ShaderEvalContext       evalCtx         (quadGrid);
3153
3154         // Render.
3155         for (int y = 0; y < height; y++)
3156         for (int x = 0; x < width; x++)
3157         {
3158                 const float sx = ((float)x + 0.5f) / (float)width;
3159                 const float sy = ((float)y + 0.5f) / (float)height;
3160
3161                 evalCtx.reset(sx, sy);
3162                 m_evaluator->evaluate(evalCtx);
3163                 // Select either clear color or computed color based on discarded bit.
3164                 tcu::Vec4 color = evalCtx.isDiscarded ? m_clearColor : evalCtx.color;
3165
3166                 if (!hasAlpha)
3167                         color.w() = 1.0f;
3168
3169                 result.setPixel(x, y, tcu::RGBA(color));
3170         }
3171 }
3172
3173 bool ShaderRenderCaseInstance::compareImages (const tcu::Surface& resImage, const tcu::Surface& refImage, float errorThreshold)
3174 {
3175         return tcu::fuzzyCompare(m_context.getTestContext().getLog(), "ComparisonResult", "Image comparison result", refImage, resImage, errorThreshold, tcu::COMPARE_LOG_EVERYTHING);
3176 }
3177
3178 } // sr
3179 } // vkt