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