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