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