ShaderRenderCase: remove UniquePtr from the AllocationSp typedef and use UniquePtrs...
[platform/upstream/VK-GL-CTS.git] / external / vulkancts / modules / vulkan / shaderrendercase / vktShaderRenderCase.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  *
8  * Permission is hereby granted, free of charge, to any person obtaining a
9  * copy of this software and/or associated documentation files (the
10  * "Materials"), to deal in the Materials without restriction, including
11  * without limitation the rights to use, copy, modify, merge, publish,
12  * distribute, sublicense, and/or sell copies of the Materials, and to
13  * permit persons to whom the Materials are furnished to do so, subject to
14  * the following conditions:
15  *
16  * The above copyright notice(s) and this permission notice shall be included
17  * in all copies or substantial portions of the Materials.
18  *
19  * The Materials are Confidential Information as defined by the
20  * Khronos Membership Agreement until designated non-confidential by Khronos,
21  * at which point this condition clause shall be removed.
22  *
23  * THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
24  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
25  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
26  * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
27  * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
28  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
29  * MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
30  *
31  *//*!
32  * \file
33  * \brief Vulkan ShaderRenderCase
34  *//*--------------------------------------------------------------------*/
35
36 #include "vktShaderRenderCase.hpp"
37
38 #include "tcuImageCompare.hpp"
39 #include "tcuImageIO.hpp"
40 #include "tcuTestLog.hpp"
41 #include "tcuTextureUtil.hpp"
42 #include "tcuSurface.hpp"
43 #include "tcuVector.hpp"
44
45 #include "deFilePath.hpp"
46 #include "deMath.h"
47 #include "deUniquePtr.hpp"
48
49 #include "vkDeviceUtil.hpp"
50 #include "vkImageUtil.hpp"
51 #include "vkPlatform.hpp"
52 #include "vkQueryUtil.hpp"
53 #include "vkRef.hpp"
54 #include "vkRefUtil.hpp"
55 #include "vkStrUtil.hpp"
56
57 #include <vector>
58 #include <string>
59
60 namespace vkt
61 {
62 namespace shaderrendercase
63 {
64
65 using namespace vk;
66
67 static const int                GRID_SIZE                       = 2;
68 static const int                MAX_RENDER_WIDTH        = 128;
69 static const int                MAX_RENDER_HEIGHT       = 112;
70 static const tcu::Vec4  DEFAULT_CLEAR_COLOR     = tcu::Vec4(0.125f, 0.25f, 0.5f, 1.0f);
71
72 static bool isSupportedLinearTilingFormat (const InstanceInterface& instanceInterface, VkPhysicalDevice device, VkFormat format)
73 {
74         VkFormatProperties formatProps;
75
76         VK_CHECK(instanceInterface.getPhysicalDeviceFormatProperties(device, format, &formatProps));
77
78         return (formatProps.linearTilingFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT) != 0u;
79 }
80
81 static bool isSupportedOptimalTilingFormat (const InstanceInterface& instanceInterface, VkPhysicalDevice device, VkFormat format)
82 {
83         VkFormatProperties formatProps;
84
85         VK_CHECK(instanceInterface.getPhysicalDeviceFormatProperties(device, format, &formatProps));
86
87         return (formatProps.linearTilingFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT) != 0u;
88 }
89
90 static VkImageMemoryBarrier createImageMemoryBarrier (const VkImage&            image,
91                                                                                                           VkMemoryOutputFlags   outputMask,
92                                                                                                           VkMemoryInputFlags    inputMask,
93                                                                                                           VkImageLayout                 oldLayout,
94                                                                                                           VkImageLayout                 newLayout)
95 {
96         VkImageMemoryBarrier imageMemoryBarrier =
97         {
98                 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,         // VkStructureType                              sType;
99                 DE_NULL,                                                                        // const void*                                  pNext;
100                 outputMask,                                                                     // VkMemoryOutputFlags                  outputMask;
101                 inputMask,                                                                      // VkMemoryInputFlags                   inputMask;
102                 oldLayout,                                                                      // VkImageLayout                                oldLayout;
103                 newLayout,                                                                      // VkImageLayout                                newLayout;
104                 VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                             srcQueueFamilyIndex;
105                 VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                             dstQueueFamilyIndex;
106                 image,                                                                          // VkImage                                              image;
107                 {
108                         VK_IMAGE_ASPECT_COLOR_BIT,      // VkImageAspectFlags   aspectMask;
109                         0,                                                      // deUint32                             baseMipLevel;
110                         1,                                                      // deUint32                             mipLevels;
111                         0,                                                      // deUint32                             baseArrayLayer;
112                         1                                                       // deUint32                             arraySize;
113                 }                                                                                       // VkImageSubresourceRange              subresourceRange;
114         };
115         return imageMemoryBarrier;
116 }
117
118 // QuadGrid.
119
120 class QuadGrid
121 {
122 public:
123                                                                                         QuadGrid                                (int                                                                    gridSize,
124                                                                                                                                          int                                                                    screenWidth,
125                                                                                                                                          int                                                                    screenHeight,
126                                                                                                                                          const tcu::Vec4&                                               constCoords,
127                                                                                                                                          const std::vector<tcu::Mat4>&                  userAttribTransforms,
128                                                                                                                                          const std::vector<TextureBindingSp>&   textures);
129                                                                                         ~QuadGrid                               (void);
130
131         int                                                                             getGridSize                             (void) const { return m_gridSize; }
132         int                                                                             getNumVertices                  (void) const { return m_numVertices; }
133         int                                                                             getNumTriangles                 (void) const { return m_numTriangles; }
134         const tcu::Vec4&                                                getConstCoords                  (void) const { return m_constCoords; }
135         const std::vector<tcu::Mat4>                    getUserAttribTransforms (void) const { return m_userAttribTransforms; }
136         const std::vector<TextureBindingSp>&    getTextures                             (void) const { return m_textures; }
137
138         const tcu::Vec4*                                                getPositions                    (void) const { return &m_positions[0]; }
139         const float*                                                    getAttribOne                    (void) const { return &m_attribOne[0]; }
140         const tcu::Vec4*                                                getCoords                               (void) const { return &m_coords[0]; }
141         const tcu::Vec4*                                                getUnitCoords                   (void) const { return &m_unitCoords[0]; }
142
143         const tcu::Vec4*                                                getUserAttrib                   (int attribNdx) const { return &m_userAttribs[attribNdx][0]; }
144         const deUint16*                                                 getIndices                              (void) const { return &m_indices[0]; }
145
146         tcu::Vec4                                                               getCoords                               (float sx, float sy) const;
147         tcu::Vec4                                                               getUnitCoords                   (float sx, float sy) const;
148
149         int                                                                             getNumUserAttribs               (void) const { return (int)m_userAttribTransforms.size(); }
150         tcu::Vec4                                                               getUserAttrib                   (int attribNdx, float sx, float sy) const;
151
152 private:
153         const int                                                               m_gridSize;
154         const int                                                               m_numVertices;
155         const int                                                               m_numTriangles;
156         const tcu::Vec4                                                 m_constCoords;
157         const std::vector<tcu::Mat4>                    m_userAttribTransforms;
158
159         const std::vector<TextureBindingSp>&    m_textures;
160
161         std::vector<tcu::Vec4>                                  m_screenPos;
162         std::vector<tcu::Vec4>                                  m_positions;
163         std::vector<tcu::Vec4>                                  m_coords;               //!< Near-unit coordinates, roughly [-2.0 .. 2.0].
164         std::vector<tcu::Vec4>                                  m_unitCoords;   //!< Positive-only coordinates [0.0 .. 1.5].
165         std::vector<float>                                              m_attribOne;
166         std::vector<tcu::Vec4>                                  m_userAttribs[ShaderEvalContext::MAX_TEXTURES];
167         std::vector<deUint16>                                   m_indices;
168 };
169
170 QuadGrid::QuadGrid (int                                                                         gridSize,
171                                         int                                                                             width,
172                                         int                                                                             height,
173                                         const tcu::Vec4&                                                constCoords,
174                                         const std::vector<tcu::Mat4>&                   userAttribTransforms,
175                                         const std::vector<TextureBindingSp>&    textures)
176         : m_gridSize                            (gridSize)
177         , m_numVertices                         ((gridSize + 1) * (gridSize + 1))
178         , m_numTriangles                        (gridSize * gridSize * 2)
179         , m_constCoords                         (constCoords)
180         , m_userAttribTransforms        (userAttribTransforms)
181         , m_textures                            (textures)
182 {
183         const tcu::Vec4 viewportScale   ((float)width, (float)height, 0.0f, 0.0f);
184
185         // Compute vertices.
186         m_screenPos.resize(m_numVertices);
187         m_positions.resize(m_numVertices);
188         m_coords.resize(m_numVertices);
189         m_unitCoords.resize(m_numVertices);
190         m_attribOne.resize(m_numVertices);
191
192         // User attributes.
193         for (int attrNdx = 0; attrNdx < DE_LENGTH_OF_ARRAY(m_userAttribs); attrNdx++)
194                 m_userAttribs[attrNdx].resize(m_numVertices);
195
196         for (int y = 0; y < gridSize+1; y++)
197         for (int x = 0; x < gridSize+1; x++)
198         {
199                 float           sx                      = (float)x / (float)gridSize;
200                 float           sy                      = (float)y / (float)gridSize;
201                 float           fx                      = 2.0f * sx - 1.0f;
202                 float           fy                      = 2.0f * sy - 1.0f;
203                 int                     vtxNdx          = ((y * (gridSize+1)) + x);
204
205                 m_positions[vtxNdx]     = tcu::Vec4(fx, fy, 0.0f, 1.0f);
206                 m_coords[vtxNdx]                = getCoords(sx, sy);
207                 m_unitCoords[vtxNdx]    = getUnitCoords(sx, sy);
208                 m_attribOne[vtxNdx]     = 1.0f;
209
210                 m_screenPos[vtxNdx]             = tcu::Vec4(sx, sy, 0.0f, 1.0f) * viewportScale;
211
212                 for (int attribNdx = 0; attribNdx < getNumUserAttribs(); attribNdx++)
213                         m_userAttribs[attribNdx][vtxNdx] = getUserAttrib(attribNdx, sx, sy);
214         }
215
216         // Compute indices.
217         m_indices.resize(3 * m_numTriangles);
218         for (int y = 0; y < gridSize; y++)
219         for (int x = 0; x < gridSize; x++)
220         {
221                 int stride                              = gridSize + 1;
222                 int v00                                 = (y * stride) + x;
223                 int v01                                 = (y * stride) + x + 1;
224                 int v10                                 = ((y+1) * stride) + x;
225                 int v11                                 = ((y+1) * stride) + x + 1;
226
227                 int baseNdx                     = ((y * gridSize) + x) * 6;
228                 m_indices[baseNdx + 0]  = (deUint16)v10;
229                 m_indices[baseNdx + 1]  = (deUint16)v00;
230                 m_indices[baseNdx + 2]  = (deUint16)v01;
231
232                 m_indices[baseNdx + 3]  = (deUint16)v10;
233                 m_indices[baseNdx + 4]  = (deUint16)v01;
234                 m_indices[baseNdx + 5]  = (deUint16)v11;
235         }
236 }
237
238 QuadGrid::~QuadGrid (void)
239 {
240 }
241
242 inline tcu::Vec4 QuadGrid::getCoords (float sx, float sy) const
243 {
244         const float fx = 2.0f * sx - 1.0f;
245         const float fy = 2.0f * sy - 1.0f;
246         return tcu::Vec4(fx, fy, -fx + 0.33f*fy, -0.275f*fx - fy);
247 }
248
249 inline tcu::Vec4 QuadGrid::getUnitCoords (float sx, float sy) const
250 {
251         return tcu::Vec4(sx, sy, 0.33f*sx + 0.5f*sy, 0.5f*sx + 0.25f*sy);
252 }
253
254 inline tcu::Vec4 QuadGrid::getUserAttrib (int attribNdx, float sx, float sy) const
255 {
256         // homogeneous normalized screen-space coordinates
257         return m_userAttribTransforms[attribNdx] * tcu::Vec4(sx, sy, 0.0f, 1.0f);
258 }
259
260 // TextureBinding
261
262 TextureBinding::TextureBinding (const tcu::Archive&     archive,
263                                                                 const char*                     filename,
264                                                                 const Type                      type,
265                                                                 const tcu::Sampler&     sampler)
266         : m_type        (type)
267         , m_sampler     (sampler)
268 {
269         switch(m_type)
270         {
271                 case TYPE_2D: m_binding.tex2D = loadTexture2D(archive, filename).release(); break;
272                 default:
273                         TCU_FAIL("Unsupported texture type");
274         }
275 }
276
277 TextureBinding::~TextureBinding (void)
278 {
279         switch(m_type)
280         {
281                 case TYPE_2D: delete m_binding.tex2D; break;
282                 default: break;
283         }
284 }
285
286
287 de::MovePtr<tcu::Texture2D> TextureBinding::loadTexture2D (const tcu::Archive& archive, const char* filename)
288 {
289         tcu::TextureLevel level;
290         tcu::ImageIO::loadImage(level, archive, filename);
291
292         TCU_CHECK_INTERNAL(level.getFormat() == tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8) ||
293                                            level.getFormat() == tcu::TextureFormat(tcu::TextureFormat::RGB, tcu::TextureFormat::UNORM_INT8));
294
295         // \todo [2015-10-08 elecro] for some reason we get better when using RGBA texture even in RGB case, this needs to be investigated
296         de::MovePtr<tcu::Texture2D> texture(new tcu::Texture2D(tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8), level.getWidth(), level.getHeight()));
297
298         // Fill level 0.
299         texture->allocLevel(0);
300         tcu::copy(texture->getLevel(0), level.getAccess());
301
302         return texture;
303 }
304
305 // ShaderEvalContext.
306
307 ShaderEvalContext::ShaderEvalContext (const QuadGrid& quadGrid)
308         : constCoords   (quadGrid.getConstCoords())
309         , isDiscarded   (false)
310         , m_quadGrid    (quadGrid)
311 {
312         const std::vector<TextureBindingSp>& bindings = m_quadGrid.getTextures();
313         DE_ASSERT((int)bindings.size() <= MAX_TEXTURES);
314
315         // Fill in texture array.
316         for (int ndx = 0; ndx < (int)bindings.size(); ndx++)
317         {
318                 const TextureBinding& binding = *bindings[ndx];
319
320                 if (binding.getType() == TextureBinding::TYPE_NONE)
321                         continue;
322
323                 textures[ndx].sampler = binding.getSampler();
324
325                 switch (binding.getType())
326                 {
327                         case TextureBinding::TYPE_2D:           textures[ndx].tex2D                     = &binding.get2D();             break;
328                         // \todo [2015-09-07 elecro] Add support for the other binding types
329                         /*
330                         case TextureBinding::TYPE_CUBE_MAP:     textures[ndx].texCube           = binding.getCube();    break;
331                         case TextureBinding::TYPE_2D_ARRAY:     textures[ndx].tex2DArray        = binding.get2DArray(); break;
332                         case TextureBinding::TYPE_3D:           textures[ndx].tex3D                     = binding.get3D();              break;
333                         */
334                         default:
335                                 TCU_THROW(InternalError, "Handling of texture binding type not implemented");
336                 }
337         }
338 }
339
340 ShaderEvalContext::~ShaderEvalContext (void)
341 {
342 }
343
344 void ShaderEvalContext::reset (float sx, float sy)
345 {
346         // Clear old values
347         color           = tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f);
348         isDiscarded     = false;
349
350         // Compute coords
351         coords          = m_quadGrid.getCoords(sx, sy);
352         unitCoords      = m_quadGrid.getUnitCoords(sx, sy);
353
354         // Compute user attributes.
355         const int numAttribs = m_quadGrid.getNumUserAttribs();
356         DE_ASSERT(numAttribs <= MAX_USER_ATTRIBS);
357         for (int attribNdx = 0; attribNdx < numAttribs; attribNdx++)
358                 in[attribNdx] = m_quadGrid.getUserAttrib(attribNdx, sx, sy);
359 }
360
361 tcu::Vec4 ShaderEvalContext::texture2D (int unitNdx, const tcu::Vec2& texCoords)
362 {
363         if (textures[unitNdx].tex2D)
364                 return textures[unitNdx].tex2D->sample(textures[unitNdx].sampler, texCoords.x(), texCoords.y(), 0.0f);
365         else
366                 return tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f);
367 }
368
369 // ShaderEvaluator.
370
371 ShaderEvaluator::ShaderEvaluator (void)
372         : m_evalFunc(DE_NULL)
373 {
374 }
375
376 ShaderEvaluator::ShaderEvaluator (ShaderEvalFunc evalFunc)
377         : m_evalFunc(evalFunc)
378 {
379 }
380
381 ShaderEvaluator::~ShaderEvaluator (void)
382 {
383 }
384
385 void ShaderEvaluator::evaluate (ShaderEvalContext& ctx) const
386 {
387         DE_ASSERT(m_evalFunc);
388         m_evalFunc(ctx);
389 }
390
391 // UniformSetup.
392
393 UniformSetup::UniformSetup (void)
394         : m_setupFunc(DE_NULL)
395 {
396 }
397
398 UniformSetup::UniformSetup (UniformSetupFunc setupFunc)
399         : m_setupFunc(setupFunc)
400 {
401 }
402
403 UniformSetup::~UniformSetup (void)
404 {
405 }
406
407 void UniformSetup::setup (ShaderRenderCaseInstance& instance, const tcu::Vec4& constCoords) const
408 {
409         if (m_setupFunc)
410                 m_setupFunc(instance, constCoords);
411 }
412
413 // ShaderRenderCase.
414
415 ShaderRenderCase::ShaderRenderCase (tcu::TestContext&                   testCtx,
416                                                                         const std::string&                      name,
417                                                                         const std::string&                      description,
418                                                                         const bool                                      isVertexCase,
419                                                                         const ShaderEvalFunc            evalFunc,
420                                                                         const UniformSetup*                     uniformSetup,
421                                                                         const AttributeSetupFunc        attribFunc)
422         : vkt::TestCase         (testCtx, name, description)
423         , m_isVertexCase        (isVertexCase)
424         , m_evaluator           (new ShaderEvaluator(evalFunc))
425         , m_uniformSetup        (uniformSetup ? uniformSetup : new UniformSetup())
426         , m_attribFunc          (attribFunc)
427 {}
428
429 ShaderRenderCase::ShaderRenderCase (tcu::TestContext&                   testCtx,
430                                                                         const std::string&                      name,
431                                                                         const std::string&                      description,
432                                                                         const bool                                      isVertexCase,
433                                                                         const ShaderEvaluator*          evaluator,
434                                                                         const UniformSetup*                     uniformSetup,
435                                                                         const AttributeSetupFunc        attribFunc)
436         : vkt::TestCase         (testCtx, name, description)
437         , m_isVertexCase        (isVertexCase)
438         , m_evaluator           (evaluator)
439         , m_uniformSetup        (uniformSetup ? uniformSetup : new UniformSetup())
440         , m_attribFunc          (attribFunc)
441 {}
442
443 ShaderRenderCase::~ShaderRenderCase (void)
444 {
445 }
446
447 void ShaderRenderCase::initPrograms (vk::SourceCollections& programCollection) const
448 {
449         programCollection.glslSources.add("vert") << glu::VertexSource(m_vertShaderSource);
450         programCollection.glslSources.add("frag") << glu::FragmentSource(m_fragShaderSource);
451 }
452
453 TestInstance* ShaderRenderCase::createInstance (Context& context) const
454 {
455         DE_ASSERT(m_evaluator != DE_NULL);
456         DE_ASSERT(m_uniformSetup != DE_NULL);
457         return new ShaderRenderCaseInstance(context, m_isVertexCase, *m_evaluator, *m_uniformSetup, m_attribFunc);
458 }
459
460 // ShaderRenderCaseInstance.
461
462 ShaderRenderCaseInstance::ShaderRenderCaseInstance (Context&                                    context,
463                                                                                                         const bool                                      isVertexCase,
464                                                                                                         const ShaderEvaluator&          evaluator,
465                                                                                                         const UniformSetup&                     uniformSetup,
466                                                                                                         const AttributeSetupFunc        attribFunc)
467         : vkt::TestInstance     (context)
468         , m_clearColor          (DEFAULT_CLEAR_COLOR)
469         , m_memAlloc            (context.getDefaultAllocator())
470         , m_isVertexCase        (isVertexCase)
471         , m_evaluator           (evaluator)
472         , m_uniformSetup        (uniformSetup)
473         , m_attribFunc          (attribFunc)
474         , m_renderSize          (100, 100)
475         , m_colorFormat         (VK_FORMAT_R8G8B8A8_UNORM)
476 {
477 }
478
479 ShaderRenderCaseInstance::~ShaderRenderCaseInstance (void)
480 {
481 }
482
483 tcu::TestStatus ShaderRenderCaseInstance::iterate (void)
484 {
485         setup();
486
487         // Create quad grid.
488         const tcu::IVec2        viewportSize    = getViewportSize();
489         const int                       width                   = viewportSize.x();
490         const int                       height                  = viewportSize.y();
491
492         QuadGrid                        quadGrid                (m_isVertexCase ? GRID_SIZE : 4, width, height, tcu::Vec4(0.125f, 0.25f, 0.5f, 1.0f), m_userAttribTransforms, m_textures);
493
494         // Render result.
495         tcu::Surface            resImage                (width, height);
496         render(resImage, quadGrid);
497
498         // Compute reference.
499         tcu::Surface            refImage                (width, height);
500         if (m_isVertexCase)
501                 computeVertexReference(refImage, quadGrid);
502         else
503                 computeFragmentReference(refImage, quadGrid);
504
505         // Compare.
506         const bool                      compareOk               = compareImages(resImage, refImage, 0.05f);
507
508         if (compareOk)
509                 return tcu::TestStatus::pass("Result image matches reference");
510         else
511                 return tcu::TestStatus::fail("Image mismatch");
512 }
513
514 void ShaderRenderCaseInstance::setupUniformData (deUint32 bindingLocation, deUint32 size, const void* dataPtr)
515 {
516         const VkDevice                                  vkDevice                        = m_context.getDevice();
517         const DeviceInterface&                  vk                                      = m_context.getDeviceInterface();
518         const deUint32                                  queueFamilyIndex        = m_context.getUniversalQueueFamilyIndex();
519
520         const VkBufferCreateInfo                uniformBufferParams     =
521         {
522                 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,           // VkStructureType              sType;
523                 DE_NULL,                                                                        // const void*                  pNext;
524                 size,                                                                           // VkDeviceSize                 size;
525                 VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT,                     // VkBufferUsageFlags   usage;
526                 0u,                                                                                     // VkBufferCreateFlags  flags;
527                 VK_SHARING_MODE_EXCLUSIVE,                                      // VkSharingMode                sharingMode;
528                 1u,                                                                                     // deUint32                             queueFamilyCount;
529                 &queueFamilyIndex                                                       // const deUint32*              pQueueFamilyIndices;
530         };
531
532         Move<VkBuffer>                                  buffer                          = createBuffer(vk, vkDevice, &uniformBufferParams);
533         de::MovePtr<Allocation>                 alloc                           = m_memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *buffer), MemoryRequirement::HostVisible);
534         VK_CHECK(vk.bindBufferMemory(vkDevice, *buffer, alloc->getMemory(), alloc->getOffset()));
535
536         deMemcpy(alloc->getHostPtr(), dataPtr, size);
537         flushMappedMemoryRange(vk, vkDevice, alloc->getMemory(), alloc->getOffset(), size);
538
539         const VkBufferViewCreateInfo    viewInfo        =
540         {
541                 VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO,      // VkStructureType      sType;
542                 DE_NULL,                                                                        // void*                        pNext;
543                 *buffer,                                                                        // VkBuffer                     buffer;
544                 VK_FORMAT_R32_SFLOAT,                                           // VkFormat     format;
545                 0u,                                                                                     // VkDeviceSize offset;
546                 size,                                                                           // VkDeviceSize range;
547         };
548
549         Move<VkBufferView>                              bufferView                      = createBufferView(vk, vkDevice, &viewInfo);
550
551         // \todo [2015-10-09 elecro] remove the '_hack_padding' variable if the driver support small uniforms,
552         // that is for example one float big uniforms.
553         const deUint32 _hack_padding = size < 4 * sizeof(float) ? (deUint32)(3u * sizeof(float)) : 0u;
554
555         const VkDescriptorInfo                  descriptor                      =
556         {
557                 bufferView.get(),                                                       // VkBufferView                         bufferView;
558                 0,                                                                                      // VkSampler                            sampler;
559                 0,                                                                                      // VkImageView                          imageView;
560                 VK_IMAGE_LAYOUT_UNDEFINED,                                      // VkImageLayout                        imageLayout;
561                 {
562                         *buffer,                                                // VkBuffer             buffer;
563                         0u,                                                             // VkDeviceSize offset;
564                         size + _hack_padding,                   // VkDeviceSize range;
565                 },                                                                                      // VkDescriptorBufferInfo       bufferInfo;
566         };
567
568         de::MovePtr<BufferUniform> uniformInfo(new BufferUniform());
569         uniformInfo->type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
570         uniformInfo->descriptor = descriptor;
571         uniformInfo->location = bindingLocation;
572         uniformInfo->buffer = VkBufferSp(new vk::Unique<VkBuffer>(buffer));
573         uniformInfo->bufferView = VkBufferViewSp(new vk::Unique<VkBufferView>(bufferView));
574         uniformInfo->alloc = AllocationSp(alloc.release());
575
576         m_uniformInfos.push_back(UniformInfoSp(new de::UniquePtr<UniformInfo>(uniformInfo)));
577 }
578
579 void ShaderRenderCaseInstance::addUniform (deUint32 bindingLocation, vk::VkDescriptorType descriptorType, deUint32 dataSize, const void* data)
580 {
581         m_descriptorSetLayoutBuilder.addSingleBinding(descriptorType, vk::VK_SHADER_STAGE_VERTEX_BIT | vk::VK_SHADER_STAGE_FRAGMENT_BIT);
582         m_descriptorPoolBuilder.addType(descriptorType);
583
584         setupUniformData(bindingLocation, dataSize, data);
585 }
586
587 void ShaderRenderCaseInstance::addAttribute (deUint32           bindingLocation,
588                                                                                          vk::VkFormat   format,
589                                                                                          deUint32               sizePerElement,
590                                                                                          deUint32               count,
591                                                                                          const void*    dataPtr)
592 {
593         // Add binding specification
594         const deUint32                                                  binding                                 = (deUint32)m_vertexBindingDescription.size();
595         const VkVertexInputBindingDescription   bindingDescription              =
596         {
597                 binding,                                                        // deUint32                             binding;
598                 sizePerElement,                                         // deUint32                                     strideInBytes;
599                 VK_VERTEX_INPUT_STEP_RATE_VERTEX        // VkVertexInputStepRate        stepRate;
600         };
601
602         m_vertexBindingDescription.push_back(bindingDescription);
603
604         // Add location and format specification
605         const VkVertexInputAttributeDescription attributeDescription    =
606         {
607                 bindingLocation,                        // deUint32     location;
608                 binding,                                        // deUint32     binding;
609                 format,                                         // VkFormat     format;
610                 0u,                                                     // deUint32     offsetInBytes;
611         };
612
613         m_vertexattributeDescription.push_back(attributeDescription);
614
615         // Upload data to buffer
616         const VkDevice                                                  vkDevice                                = m_context.getDevice();
617         const DeviceInterface&                                  vk                                              = m_context.getDeviceInterface();
618         const deUint32                                                  queueFamilyIndex                = m_context.getUniversalQueueFamilyIndex();
619
620         const VkDeviceSize                                              inputSize                               = sizePerElement * count;
621         const VkBufferCreateInfo                                vertexBufferParams              =
622         {
623                 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,           // VkStructureType              sType;
624                 DE_NULL,                                                                        // const void*                  pNext;
625                 inputSize,                                                                      // VkDeviceSize                 size;
626                 VK_BUFFER_USAGE_VERTEX_BUFFER_BIT,                      // VkBufferUsageFlags   usage;
627                 0u,                                                                                     // VkBufferCreateFlags  flags;
628                 VK_SHARING_MODE_EXCLUSIVE,                                      // VkSharingMode                sharingMode;
629                 1u,                                                                                     // deUint32                             queueFamilyCount;
630                 &queueFamilyIndex                                                       // const deUint32*              pQueueFamilyIndices;
631         };
632
633         Move<VkBuffer>                                                  buffer                                  = createBuffer(vk, vkDevice, &vertexBufferParams);
634         de::MovePtr<vk::Allocation>                             alloc                                   = m_memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *buffer), MemoryRequirement::HostVisible);
635         VK_CHECK(vk.bindBufferMemory(vkDevice, *buffer, alloc->getMemory(), alloc->getOffset()));
636
637         deMemcpy(alloc->getHostPtr(), dataPtr, inputSize);
638         flushMappedMemoryRange(vk, vkDevice, alloc->getMemory(), alloc->getOffset(), inputSize);
639
640         m_vertexBuffers.push_back(VkBufferSp(new vk::Unique<VkBuffer>(buffer)));
641         m_vertexBufferAllocs.push_back(AllocationSp(alloc.release()));
642 }
643
644 void ShaderRenderCaseInstance::useAttribute (deUint32 bindingLocation, BaseAttributeType type)
645 {
646         const EnabledBaseAttribute attribute =
647         {
648                 bindingLocation,        // deUint32                             location;
649                 type                            // BaseAttributeType    type;
650         };
651         m_enabledBaseAttributes.push_back(attribute);
652 }
653
654 void ShaderRenderCaseInstance::setup (void)
655 {
656 }
657
658 void ShaderRenderCaseInstance::setupUniforms (const tcu::Vec4& constCoords)
659 {
660         m_uniformSetup.setup(*this, constCoords);
661 }
662
663 void ShaderRenderCaseInstance::useUniform (deUint32 bindingLocation, BaseUniformType type)
664 {
665         #define UNIFORM_CASE(type, value) case type: addUniform(bindingLocation, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, value); break
666
667         switch(type)
668         {
669                 // Bool
670                 UNIFORM_CASE(UB_FALSE,  0);
671                 UNIFORM_CASE(UB_TRUE,   1);
672
673                 // BVec4
674                 UNIFORM_CASE(UB4_FALSE, tcu::Vec4(0));
675                 UNIFORM_CASE(UB4_TRUE,  tcu::Vec4(1));
676
677                 // Integer
678                 UNIFORM_CASE(UI_ZERO,   0);
679                 UNIFORM_CASE(UI_ONE,    1);
680                 UNIFORM_CASE(UI_TWO,    2);
681                 UNIFORM_CASE(UI_THREE,  3);
682                 UNIFORM_CASE(UI_FOUR,   4);
683                 UNIFORM_CASE(UI_FIVE,   5);
684                 UNIFORM_CASE(UI_SIX,    6);
685                 UNIFORM_CASE(UI_SEVEN,  7);
686                 UNIFORM_CASE(UI_EIGHT,  8);
687                 UNIFORM_CASE(UI_ONEHUNDREDONE, 101);
688
689                 // IVec2
690                 UNIFORM_CASE(UI2_MINUS_ONE, tcu::IVec2(-1));
691                 UNIFORM_CASE(UI2_ZERO,          tcu::IVec2(0));
692                 UNIFORM_CASE(UI2_ONE,           tcu::IVec2(1));
693                 UNIFORM_CASE(UI2_TWO,           tcu::IVec2(2));
694                 UNIFORM_CASE(UI2_THREE,         tcu::IVec2(3));
695                 UNIFORM_CASE(UI2_FOUR,          tcu::IVec2(4));
696                 UNIFORM_CASE(UI2_FIVE,          tcu::IVec2(5));
697
698                 // IVec3
699                 UNIFORM_CASE(UI3_MINUS_ONE,     tcu::IVec3(-1));
700                 UNIFORM_CASE(UI3_ZERO,          tcu::IVec3(0));
701                 UNIFORM_CASE(UI3_ONE,           tcu::IVec3(1));
702                 UNIFORM_CASE(UI3_TWO,           tcu::IVec3(2));
703                 UNIFORM_CASE(UI3_THREE,         tcu::IVec3(3));
704                 UNIFORM_CASE(UI3_FOUR,          tcu::IVec3(4));
705                 UNIFORM_CASE(UI3_FIVE,          tcu::IVec3(5));
706
707                 // IVec4
708                 UNIFORM_CASE(UI4_MINUS_ONE, tcu::IVec4(-1));
709                 UNIFORM_CASE(UI4_ZERO,          tcu::IVec4(0));
710                 UNIFORM_CASE(UI4_ONE,           tcu::IVec4(1));
711                 UNIFORM_CASE(UI4_TWO,           tcu::IVec4(2));
712                 UNIFORM_CASE(UI4_THREE,         tcu::IVec4(3));
713                 UNIFORM_CASE(UI4_FOUR,          tcu::IVec4(4));
714                 UNIFORM_CASE(UI4_FIVE,          tcu::IVec4(5));
715
716                 // Float
717                 UNIFORM_CASE(UF_ZERO,           0.0f);
718                 UNIFORM_CASE(UF_ONE,            1.0f);
719                 UNIFORM_CASE(UF_TWO,            2.0f);
720                 UNIFORM_CASE(UF_THREE,          3.0f);
721                 UNIFORM_CASE(UF_FOUR,           4.0f);
722                 UNIFORM_CASE(UF_FIVE,           5.0f);
723                 UNIFORM_CASE(UF_SIX,            6.0f);
724                 UNIFORM_CASE(UF_SEVEN,          7.0f);
725                 UNIFORM_CASE(UF_EIGHT,          8.0f);
726
727                 UNIFORM_CASE(UF_HALF,           1.0f / 2.0f);
728                 UNIFORM_CASE(UF_THIRD,          1.0f / 3.0f);
729                 UNIFORM_CASE(UF_FOURTH,         1.0f / 4.0f);
730                 UNIFORM_CASE(UF_FIFTH,          1.0f / 5.0f);
731                 UNIFORM_CASE(UF_SIXTH,          1.0f / 6.0f);
732                 UNIFORM_CASE(UF_SEVENTH,        1.0f / 7.0f);
733                 UNIFORM_CASE(UF_EIGHTH,         1.0f / 8.0f);
734
735                 // Vec2
736                 UNIFORM_CASE(UV2_MINUS_ONE,     tcu::Vec2(-1.0f));
737                 UNIFORM_CASE(UV2_ZERO,          tcu::Vec2(0.0f));
738                 UNIFORM_CASE(UV2_ONE,           tcu::Vec2(1.0f));
739                 UNIFORM_CASE(UV2_TWO,           tcu::Vec2(2.0f));
740                 UNIFORM_CASE(UV2_THREE,         tcu::Vec2(3.0f));
741
742                 UNIFORM_CASE(UV2_HALF,          tcu::Vec2(1.0f / 2.0f));
743
744                 // Vec3
745                 UNIFORM_CASE(UV3_MINUS_ONE,     tcu::Vec3(-1.0f));
746                 UNIFORM_CASE(UV3_ZERO,          tcu::Vec3(0.0f));
747                 UNIFORM_CASE(UV3_ONE,           tcu::Vec3(1.0f));
748                 UNIFORM_CASE(UV3_TWO,           tcu::Vec3(2.0f));
749                 UNIFORM_CASE(UV3_THREE,         tcu::Vec3(3.0f));
750
751                 UNIFORM_CASE(UV3_HALF,          tcu::Vec3(1.0f / 2.0f));
752
753                 // Vec4
754                 UNIFORM_CASE(UV4_MINUS_ONE,     tcu::Vec4(-1.0f));
755                 UNIFORM_CASE(UV4_ZERO,          tcu::Vec4(0.0f));
756                 UNIFORM_CASE(UV4_ONE,           tcu::Vec4(1.0f));
757                 UNIFORM_CASE(UV4_TWO,           tcu::Vec4(2.0f));
758                 UNIFORM_CASE(UV4_THREE,         tcu::Vec4(3.0f));
759
760                 UNIFORM_CASE(UV4_HALF,          tcu::Vec4(1.0f / 2.0f));
761
762                 UNIFORM_CASE(UV4_BLACK,         tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f));
763                 UNIFORM_CASE(UV4_GRAY,          tcu::Vec4(0.5f, 0.5f, 0.5f, 1.0f));
764                 UNIFORM_CASE(UV4_WHITE,         tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f));
765
766                 default:
767                         m_context.getTestContext().getLog() << tcu::TestLog::Message << "Unknown Uniform type: " << type << tcu::TestLog::EndMessage;
768                         break;
769         }
770
771         #undef UNIFORM_CASE
772 }
773
774 const tcu::IVec2 ShaderRenderCaseInstance::getViewportSize (void) const
775 {
776         return tcu::IVec2(de::min(m_renderSize.x(), MAX_RENDER_WIDTH),
777                                           de::min(m_renderSize.y(), MAX_RENDER_HEIGHT));
778 }
779
780 Move<VkImage> ShaderRenderCaseInstance::createImage2D (const tcu::Texture2D&    texture,
781                                                                                                            const VkFormat                       format,
782                                                                                                            const VkImageUsageFlags      usage,
783                                                                                                            const VkImageTiling          tiling)
784 {
785         const VkDevice                  vkDevice                        = m_context.getDevice();
786         const DeviceInterface&  vk                                      = m_context.getDeviceInterface();
787         const deUint32                  queueFamilyIndex        = m_context.getUniversalQueueFamilyIndex();
788
789         const VkImageCreateInfo imageCreateInfo         =
790         {
791                 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,                                            // VkStructureType                      sType;
792                 DE_NULL,                                                                                                        // const void*                          pnext;
793                 VK_IMAGE_TYPE_2D,                                                                                       // VkImageType                          imageType;
794                 format,                                                                                                         // VkFormat                                     format;
795                 { texture.getWidth(), texture.getHeight(), 1 },                         // VkExtend3D                           extent;
796                 1u,                                                                                                                     // deUint32                                     mipLevels;
797                 1u,                                                                                                                     // deUint32                                     arraySize;
798                 1u,                                                                                                                     // deUint32                                     samples;
799                 tiling,                                                                                                         // VkImageTiling                        tiling;
800                 usage,                                                                                                          // VkImageUsageFlags            usage;
801                 0,                                                                                                                      // VkImageCreateFlags           flags;
802                 VK_SHARING_MODE_EXCLUSIVE,                                                                      // VkSharingMode                        sharingMode;
803                 1,                                                                                                                      // deuint32                                     queueFamilyCount;
804                 &queueFamilyIndex,                                                                                      // const deUint32*                      pQueueFamilyIndices;
805                 VK_IMAGE_LAYOUT_UNDEFINED,                                                                      // VkImageLayout                        initialLayout;
806         };
807
808         Move<VkImage>                   vkTexture                       = createImage(vk, vkDevice, &imageCreateInfo);
809         return vkTexture;
810 }
811
812 de::MovePtr<Allocation> ShaderRenderCaseInstance::uploadImage2D (const tcu::Texture2D&  refTexture,
813                                                                                                                                  const VkImage&                 vkTexture)
814 {
815         const VkDevice                          vkDevice        = m_context.getDevice();
816         const DeviceInterface&          vk                      = m_context.getDeviceInterface();
817
818         de::MovePtr<Allocation>         allocation      = m_memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, vkTexture), MemoryRequirement::HostVisible);
819         VK_CHECK(vk.bindImageMemory(vkDevice, vkTexture, allocation->getMemory(), allocation->getOffset()));
820
821         const VkImageSubresource        subres                          =
822         {
823                 VK_IMAGE_ASPECT_COLOR,                                                  // VkImageAspect                aspect;
824                 0u,                                                                                             // deUint32                             mipLevel;
825                 0u                                                                                              // deUint32                             arraySlice
826         };
827
828         VkSubresourceLayout layout;
829         VK_CHECK(vk.getImageSubresourceLayout(vkDevice, vkTexture, &subres, &layout));
830
831         tcu::ConstPixelBufferAccess     access          = refTexture.getLevel(0);
832         tcu::PixelBufferAccess          destAccess      (refTexture.getFormat(), refTexture.getWidth(), refTexture.getHeight(), 1, allocation->getHostPtr());
833
834         tcu::copy(destAccess, access);
835
836         flushMappedMemoryRange(vk, vkDevice, allocation->getMemory(), allocation, layout.size);
837
838         return allocation;
839 }
840
841 void ShaderRenderCaseInstance::copyTilingImageToOptimal (const vk::VkImage&     srcImage,
842                                                                                                                  const vk::VkImage&     dstImage,
843                                                                                                                  deInt32 width,
844                                                                                                                  deInt32 height)
845 {
846         const VkDevice                                  vkDevice                        = m_context.getDevice();
847         const DeviceInterface&                  vk                                      = m_context.getDeviceInterface();
848         const VkQueue                                   queue                           = m_context.getUniversalQueue();
849         const deUint32                                  queueFamilyIndex        = m_context.getUniversalQueueFamilyIndex();
850
851         // Create command pool
852         const VkCmdPoolCreateInfo               cmdPoolParams           =
853         {
854                 VK_STRUCTURE_TYPE_CMD_POOL_CREATE_INFO,         // VkStructureType              sType;
855                 DE_NULL,                                                                        // const void*                  pNext;
856                 queueFamilyIndex,                                                       // deUint32                             queueFamilyIndex;
857                 VK_CMD_POOL_CREATE_TRANSIENT_BIT                        // VkCmdPoolCreateFlags flags;
858         };
859
860         Move<VkCmdPool>                                 cmdPool                         = createCommandPool(vk, vkDevice, &cmdPoolParams);
861
862         // Create command buffer
863         const VkCmdBufferCreateInfo     cmdBufferParams         =
864         {
865                 VK_STRUCTURE_TYPE_CMD_BUFFER_CREATE_INFO,       // VkStructureType                      sType;
866                 DE_NULL,                                                                        // const void*                          pNext;
867                 *cmdPool,                                                                       // VkCmdPool                            cmdPool;
868                 VK_CMD_BUFFER_LEVEL_PRIMARY,                            // VkCmdBufferLevel                     level;
869                 0u                                                                                      // VkCmdBufferCreateFlags       flags;
870         };
871
872         const VkCmdBufferOptimizeFlags  optimizeFlags           = VK_CMD_BUFFER_OPTIMIZE_SMALL_BATCH_BIT | VK_CMD_BUFFER_OPTIMIZE_ONE_TIME_SUBMIT_BIT;
873         const VkCmdBufferBeginInfo              cmdBufferBeginInfo      =
874         {
875                 VK_STRUCTURE_TYPE_CMD_BUFFER_BEGIN_INFO,        // VkStructureType                      sType;
876                 DE_NULL,                                                                        // const void*                          pNext;
877                 optimizeFlags,                                                          // VkCmdBufferOptimizeFlags     flags;
878                 DE_NULL,                                                                        // VkRenderPass                         renderPass;
879                 0u,                                                                                     // deUint32                                     subpass;
880                 DE_NULL                                                                         // VkFramebuffer                        framebuffer;
881         };
882
883         Move<VkCmdBuffer>                               cmdBuffer                       = createCommandBuffer(vk, vkDevice, &cmdBufferParams);
884
885         VK_CHECK(vk.beginCommandBuffer(*cmdBuffer, &cmdBufferBeginInfo));
886
887         // Add image barriers
888         const VkImageMemoryBarrier              layoutBarriers[2]       =
889         {
890                 createImageMemoryBarrier(srcImage, 0u, 0u, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_SOURCE_OPTIMAL),
891                 createImageMemoryBarrier(dstImage, 0u, VK_MEMORY_INPUT_TRANSFER_BIT, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DESTINATION_OPTIMAL)
892         };
893
894         for (deUint32 barrierNdx = 0; barrierNdx < DE_LENGTH_OF_ARRAY(layoutBarriers); barrierNdx++)
895         {
896                 const VkImageMemoryBarrier* memoryBarrier = &layoutBarriers[barrierNdx];
897                 vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, false, 1, (const void * const*)&memoryBarrier);
898         }
899
900         // Add image copy
901         const VkImageCopy                               imageCopy                       =
902         {
903                 {
904                         VK_IMAGE_ASPECT_COLOR,                  // VkImageAspect        aspect;
905                         0u,                                                             // deUint32                     mipLevel;
906                         0u,                                                             // deUint32                     arrayLayer;
907                         1u                                                              // deUint32                     arraySize;
908                 },                                                                                      // VkImageSubresourceCopy       srcSubresource;
909                 {
910                         0,                                                              // int32                        x;
911                         0,                                                              // int32                        y;
912                         0                                                               // int32                        z;
913                 },                                                                                      // VkOffset3D                           srcOffset;
914                 {
915                         VK_IMAGE_ASPECT_COLOR,                  // VkImageAspect        aspect;
916                         0u,                                                             // deUint32                     mipLevel;
917                         0u,                                                             // deUint32                     arrayLayer;
918                         1u                                                              // deUint32                     arraySize;
919                 },                                                                                      // VkImageSubresourceCopy       destSubResource;
920                 {
921                         0,                                                              // int32                        x;
922                         0,                                                              // int32                        y;
923                         0                                                               // int32                        z;
924                 },                                                                                      // VkOffset3D                           dstOffset;
925                 {
926                         width,                                                  // int32                        width;
927                         height,                                                 // int32                        height;
928                         1,                                                              // int32                        depth
929                 }       // VkExtent3D                                   extent;
930         };
931
932         vk.cmdCopyImage(*cmdBuffer, srcImage, VK_IMAGE_LAYOUT_TRANSFER_SOURCE_OPTIMAL, dstImage, VK_IMAGE_LAYOUT_TRANSFER_DESTINATION_OPTIMAL, 1, &imageCopy);
933
934         // Add destination barrier
935         const VkImageMemoryBarrier              dstBarrier                      =
936                         createImageMemoryBarrier(dstImage, VK_MEMORY_OUTPUT_HOST_WRITE_BIT | VK_MEMORY_OUTPUT_TRANSFER_BIT, 0u, VK_IMAGE_LAYOUT_TRANSFER_DESTINATION_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
937
938         const void* const*                              barrier                         = (const void* const*)&dstBarrier;
939         vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, false, 1, (const void* const*)&barrier);
940
941         VK_CHECK(vk.endCommandBuffer(*cmdBuffer));
942
943         const VkFenceCreateInfo                 fenceParams                     =
944         {
945                 VK_STRUCTURE_TYPE_FENCE_CREATE_INFO,    // VkStructureType              sType;
946                 DE_NULL,                                                                // const void*                  pNext;
947                 0u                                                                              // VkFenceCreateFlags   flags;
948         };
949         Move<VkFence>                                   fence                           = createFence(vk, vkDevice, &fenceParams);
950
951         // Execute copy
952         VK_CHECK(vk.resetFences(vkDevice, 1, &fence.get()));
953         VK_CHECK(vk.queueSubmit(queue, 1, &cmdBuffer.get(), *fence));
954         VK_CHECK(vk.waitForFences(vkDevice, 1, &fence.get(), true, ~(0ull) /* infinity*/));
955 }
956
957 void ShaderRenderCaseInstance::useSampler2D (deUint32 bindingLocation, deUint32 textureID)
958 {
959         DE_ASSERT(textureID < m_textures.size());
960
961         const VkDevice                                  vkDevice                = m_context.getDevice();
962         const DeviceInterface&                  vk                              = m_context.getDeviceInterface();
963         const TextureBinding&                   textureBinding  = *m_textures[textureID];
964         const tcu::Texture2D&                   refTexture              = textureBinding.get2D();
965         const tcu::Sampler&                             refSampler              = textureBinding.getSampler();
966         const VkFormat                                  format                  = refTexture.getFormat() == tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8)
967                                                                                                                 ? VK_FORMAT_R8G8B8A8_UNORM
968                                                                                                                 : VK_FORMAT_R8G8B8_UNORM;
969
970         // Create & alloc the image
971         Move<VkImage>                                   vkTexture;
972         de::MovePtr<Allocation>         allocation;
973
974         if (isSupportedLinearTilingFormat(m_context.getInstanceInterface(), m_context.getPhysicalDevice(), format))
975         {
976                 vkTexture = createImage2D(refTexture, format, VK_IMAGE_USAGE_SAMPLED_BIT, VK_IMAGE_TILING_LINEAR);
977                 allocation = uploadImage2D(refTexture, *vkTexture);
978         }
979         else if (isSupportedOptimalTilingFormat(m_context.getInstanceInterface(), m_context.getPhysicalDevice(), format))
980         {
981                 Move<VkImage>                           stagingTexture  (createImage2D(refTexture, format, VK_IMAGE_USAGE_TRANSFER_SOURCE_BIT, VK_IMAGE_TILING_LINEAR));
982                 de::MovePtr<Allocation>         stagingAlloc    (uploadImage2D(refTexture, *stagingTexture));
983
984                 const VkImageUsageFlags         dstUsageFlags   = VK_IMAGE_USAGE_TRANSFER_DESTINATION_BIT | VK_IMAGE_USAGE_SAMPLED_BIT;
985                 vkTexture = createImage2D(refTexture, format, dstUsageFlags, VK_IMAGE_TILING_OPTIMAL);
986                 allocation = m_memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, *vkTexture), MemoryRequirement::Any);
987                 VK_CHECK(vk.bindImageMemory(vkDevice, *vkTexture, allocation->getMemory(), allocation->getOffset()));
988
989                 copyTilingImageToOptimal(*stagingTexture, *vkTexture, refTexture.getWidth(), refTexture.getHeight());
990         }
991         else
992         {
993                 TCU_THROW(InternalError, "Unable to create 2D image");
994         }
995
996         // Create sampler
997         const bool                                              compareEnabled  = (refSampler.compare != tcu::Sampler::COMPAREMODE_NONE);
998         const VkSamplerCreateInfo               samplerParams   =
999         {
1000                 VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO,                  // VkStructureType      sType;
1001                 DE_NULL,                                                                                // const void*          pNext;
1002                 mapFilterMode(refSampler.magFilter),                    // VkTexFilter          magFilter;
1003                 mapFilterMode(refSampler.minFilter),                    // VkTexFilter          minFilter;
1004                 mapMipmapMode(refSampler.minFilter),                    // VkTexMipmapMode      mipMode;
1005                 mapWrapMode(refSampler.wrapS),                                  // VkTexAddressMode     addressModeU;
1006                 mapWrapMode(refSampler.wrapT),                                  // VkTexAddressMode     addressModeV;
1007                 mapWrapMode(refSampler.wrapR),                                  // VkTexAddressMode     addressModeW;
1008                 refSampler.lodThreshold,                                                // float                        mipLodBias;
1009                 1,                                                                                              // float                        maxAnisotropy;
1010                 compareEnabled,                                                                 // VkBool32                     compareEnable;
1011                 mapCompareMode(refSampler.compare),                             // VkCompareOp          compareOp;
1012                 0.0f,                                                                                   // float                        minLod;
1013                 0.0f,                                                                                   // float                        maxLod;
1014                 VK_BORDER_COLOR_INT_OPAQUE_WHITE,                               // VkBorderColor        boderColor;
1015                 VK_FALSE,                                                                               // VkBool32                     unnormalizerdCoordinates;
1016         };
1017
1018         Move<VkSampler>                                 sampler                 = createSampler(vk, vkDevice, &samplerParams);
1019
1020         const VkImageViewCreateInfo             viewParams              =
1021         {
1022                 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,       // VkStructureType                      sType;
1023                 NULL,                                                                           // const voide*                         pNexŧ;
1024                 *vkTexture,                                                                     // VkImage                                      image;
1025                 VK_IMAGE_VIEW_TYPE_2D,                                          // VkImageViewType                      viewType;
1026                 format,                                                                         // VkFormat                                     format;
1027                 {
1028                         VK_CHANNEL_SWIZZLE_R,                   // VkChannelSwizzle             r;
1029                         VK_CHANNEL_SWIZZLE_G,                   // VkChannelSwizzle             g;
1030                         VK_CHANNEL_SWIZZLE_B,                   // VkChannelSwizzle             b;
1031                         VK_CHANNEL_SWIZZLE_A                    // VkChannelSwizzle             a;
1032                 },                                                                                      // VkChannelMapping                     channels;
1033                 {
1034                         VK_IMAGE_ASPECT_COLOR_BIT,              // VkImageAspectFlags   aspectMask;
1035                         0,                                                              // deUint32                             baseMipLevel;
1036                         1,                                                              // deUint32                             mipLevels;
1037                         0,                                                              // deUint32                             baseArraySlice;
1038                         1                                                               // deUint32                             arraySize;
1039                 },                                                                                      // VkImageSubresourceRange      subresourceRange;
1040                 0u                                                                                      // VkImageViewCreateFlags       flags;
1041         };
1042
1043         Move<VkImageView>                               imageView               = createImageView(vk, vkDevice, &viewParams);
1044
1045         const vk::VkDescriptorInfo              descriptor              =
1046         {
1047                 0,                                                                                      // VkBufferView                         bufferView;
1048                 sampler.get(),                                                          // VkSampler                            sampler;
1049                 imageView.get(),                                                        // VkImageView                          imageView;
1050                 VK_IMAGE_LAYOUT_GENERAL,                                        // VkImageLayout                        imageLayout;
1051                 {0, 0, 0},                                                                                      // VkDescriptorBufferInfo       bufferInfo;
1052         };
1053
1054         de::MovePtr<SamplerUniform> uniform(new SamplerUniform());
1055         uniform->type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
1056         uniform->descriptor = descriptor;
1057         uniform->location = bindingLocation;
1058         uniform->image = VkImageSp(new vk::Unique<VkImage>(vkTexture));
1059         uniform->imageView = VkImageViewSp(new vk::Unique<VkImageView>(imageView));
1060         uniform->sampler = VkSamplerSp(new vk::Unique<VkSampler>(sampler));
1061         uniform->alloc = AllocationSp(allocation.release());
1062
1063         m_descriptorSetLayoutBuilder.addSingleSamplerBinding(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, vk::VK_SHADER_STAGE_FRAGMENT_BIT, &uniform->descriptor.sampler);
1064         m_descriptorPoolBuilder.addType(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER);
1065
1066         m_uniformInfos.push_back(UniformInfoSp(new de::UniquePtr<UniformInfo>(uniform)));
1067 }
1068
1069 void ShaderRenderCaseInstance::setupDefaultInputs (const QuadGrid& quadGrid)
1070 {
1071         /* Configuration of the vertex input attributes:
1072                 a_position   is at location 0
1073                 a_coords     is at location 1
1074                 a_unitCoords is at location 2
1075                 a_one        is at location 3
1076
1077           User attributes starts from at the location 4.
1078         */
1079         addAttribute(0u, VK_FORMAT_R32G32B32A32_SFLOAT, sizeof(tcu::Vec4), quadGrid.getNumVertices(), quadGrid.getPositions());
1080         addAttribute(1u, VK_FORMAT_R32G32B32A32_SFLOAT, sizeof(tcu::Vec4), quadGrid.getNumVertices(), quadGrid.getCoords());
1081         addAttribute(2u, VK_FORMAT_R32G32B32A32_SFLOAT, sizeof(tcu::Vec4), quadGrid.getNumVertices(), quadGrid.getUnitCoords());
1082         addAttribute(3u, VK_FORMAT_R32_SFLOAT, sizeof(float), quadGrid.getNumVertices(), quadGrid.getAttribOne());
1083
1084         static const struct
1085         {
1086                 BaseAttributeType       type;
1087                 int                                     userNdx;
1088         } userAttributes[] =
1089         {
1090                 { A_IN0, 0 },
1091                 { A_IN1, 1 },
1092                 { A_IN2, 2 },
1093                 { A_IN3, 3 }
1094         };
1095
1096         static const struct
1097         {
1098                 BaseAttributeType       matrixType;
1099                 int                                     numCols;
1100                 int                                     numRows;
1101         } matrices[] =
1102         {
1103                 { MAT2,         2, 2 },
1104                 { MAT2x3,       2, 3 },
1105                 { MAT2x4,       2, 4 },
1106                 { MAT3x2,       3, 2 },
1107                 { MAT3,         3, 3 },
1108                 { MAT3x4,       3, 4 },
1109                 { MAT4x2,       4, 2 },
1110                 { MAT4x3,       4, 3 },
1111                 { MAT4,         4, 4 }
1112         };
1113
1114         for (size_t attrNdx = 0; attrNdx < m_enabledBaseAttributes.size(); attrNdx++)
1115         {
1116                 for (int userNdx = 0; userNdx < DE_LENGTH_OF_ARRAY(userAttributes); userNdx++)
1117                 {
1118                         if (userAttributes[userNdx].type != m_enabledBaseAttributes[attrNdx].type)
1119                                 continue;
1120
1121                         addAttribute(m_enabledBaseAttributes[attrNdx].location, VK_FORMAT_R32G32B32A32_SFLOAT, sizeof(tcu::Vec4), quadGrid.getNumVertices(), quadGrid.getUserAttrib(userNdx));
1122                 }
1123
1124                 for (int matNdx = 0; matNdx < DE_LENGTH_OF_ARRAY(matrices); matNdx++)
1125                 {
1126
1127                         if (matrices[matNdx].matrixType != m_enabledBaseAttributes[attrNdx].type)
1128                                 continue;
1129
1130                         const int numCols = matrices[matNdx].numCols;
1131
1132                         for (int colNdx = 0; colNdx < numCols; colNdx++)
1133                         {
1134                                 addAttribute(m_enabledBaseAttributes[attrNdx].location + colNdx, VK_FORMAT_R32G32B32A32_SFLOAT, 4 * sizeof(float), quadGrid.getNumVertices(), quadGrid.getUserAttrib(colNdx));
1135                         }
1136                 }
1137         }
1138 }
1139
1140 void ShaderRenderCaseInstance::render (tcu::Surface& result, const QuadGrid& quadGrid)
1141 {
1142         const VkDevice                                                                          vkDevice                                        = m_context.getDevice();
1143         const DeviceInterface&                                                          vk                                                      = m_context.getDeviceInterface();
1144         const VkQueue                                                                           queue                                           = m_context.getUniversalQueue();
1145         const deUint32                                                                          queueFamilyIndex                        = m_context.getUniversalQueueFamilyIndex();
1146
1147         // Create color image
1148         {
1149                 const VkImageCreateInfo                                                 colorImageParams                        =
1150                 {
1151                         VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,                                                                            // VkStructureType              sType;
1152                         DE_NULL,                                                                                                                                        // const void*                  pNext;
1153                         VK_IMAGE_TYPE_2D,                                                                                                                       // VkImageType                  imageType;
1154                         m_colorFormat,                                                                                                                          // VkFormat                             format;
1155                         { m_renderSize.x(), m_renderSize.y(), 1u },                                                                     // VkExtent3D                   extent;
1156                         1u,                                                                                                                                                     // deUint32                             mipLevels;
1157                         1u,                                                                                                                                                     // deUint32                             arraySize;
1158                         1u,                                                                                                                                                     // deUint32                             samples;
1159                         VK_IMAGE_TILING_OPTIMAL,                                                                                                        // VkImageTiling                tiling;
1160                         VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SOURCE_BIT,       // VkImageUsageFlags    usage;
1161                         0u,                                                                                                                                                     // VkImageCreateFlags   flags;
1162                         VK_SHARING_MODE_EXCLUSIVE,                                                                                                      // VkSharingMode                sharingMode;
1163                         1u,                                                                                                                                                     // deUint32                             queueFamilyCount;
1164                         &queueFamilyIndex,                                                                                                                      // const deUint32*              pQueueFamilyIndices;
1165                         VK_IMAGE_LAYOUT_UNDEFINED,                                                                                                      // VkImageLayout                initialLayout;
1166                 };
1167
1168                 m_colorImage = createImage(vk, vkDevice, &colorImageParams);
1169
1170                 // Allocate and bind color image memory
1171                 m_colorImageAlloc = m_memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, *m_colorImage), MemoryRequirement::Any);
1172                 VK_CHECK(vk.bindImageMemory(vkDevice, *m_colorImage, m_colorImageAlloc->getMemory(), m_colorImageAlloc->getOffset()));
1173         }
1174
1175         // Create color attachment view
1176         {
1177                 const VkImageViewCreateInfo                                             colorImageViewParams            =
1178                 {
1179                         VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,                       // VkStructureType                      sType;
1180                         DE_NULL,                                                                                        // const void*                          pNext;
1181                         *m_colorImage,                                                                          // VkImage                                      image;
1182                         VK_IMAGE_VIEW_TYPE_2D,                                                          // VkImageViewType                      viewType;
1183                         m_colorFormat,                                                                          // VkFormat                                     format;
1184                         {
1185                                 VK_CHANNEL_SWIZZLE_R,                   // VkChannelSwizzle             r;
1186                                 VK_CHANNEL_SWIZZLE_G,                   // VkChannelSwizzle             g;
1187                                 VK_CHANNEL_SWIZZLE_B,                   // VkChannelSwizzle             b;
1188                                 VK_CHANNEL_SWIZZLE_A                    // VkChannelSwizzle             a;
1189                         },                                                                                                      // VkChannelMapping                     channels;
1190                         {
1191                                 VK_IMAGE_ASPECT_COLOR_BIT,              // VkImageAspectFlags   aspectMask;
1192                                 0,                                                              // deUint32                             baseMipLevel;
1193                                 1,                                                              // deUint32                             mipLevels;
1194                                 0,                                                              // deUint32                             baseArraySlice;
1195                                 1                                                               // deUint32                             arraySize;
1196                         },                                                                                                      // VkImageSubresourceRange      subresourceRange;
1197                         0u                                                                                                      // VkImageViewCreateFlags       flags;
1198                 };
1199
1200                 m_colorImageView = createImageView(vk, vkDevice, &colorImageViewParams);
1201         }
1202
1203         // Create render pass
1204         {
1205                 const VkAttachmentDescription                                   attachmentDescription           =
1206                 {
1207                         VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION,                       // VkStructureType                              sType;
1208                         DE_NULL,                                                                                        // const void*                                  pNext;
1209                         m_colorFormat,                                                                          // VkFormat                                             format;
1210                         1u,                                                                                                     // deUint32                                             samples;
1211                         VK_ATTACHMENT_LOAD_OP_CLEAR,                                            // VkAttachmentLoadOp                   loadOp;
1212                         VK_ATTACHMENT_STORE_OP_STORE,                                           // VkAttachmentStoreOp                  storeOp;
1213                         VK_ATTACHMENT_LOAD_OP_DONT_CARE,                                        // VkAttachmentLoadOp                   stencilLoadOp;
1214                         VK_ATTACHMENT_STORE_OP_DONT_CARE,                                       // VkAttachmentStoreOp                  stencilStoreOp;
1215                         VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,                       // VkImageLayout                                initialLayout;
1216                         VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,                       // VkImageLayout                                finalLayout;
1217                         0u,                                                                                                     // VkAttachmentDescriptorFlags  flags;
1218                 };
1219
1220                 const VkAttachmentReference                                             attachmentReference                     =
1221                 {
1222                         0u,                                                                                                     // deUint32                     attachment;
1223                         VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL                        // VkImageLayout        layout;
1224                 };
1225
1226                 const VkSubpassDescription                                              subpassDescription                      =
1227                 {
1228                         VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION,                          // VkStructureType                              sType;
1229                         DE_NULL,                                                                                        // constvoid*                                   pNext;
1230                         VK_PIPELINE_BIND_POINT_GRAPHICS,                                        // VkPipelineBindPoint                  pipelineBindPoint;
1231                         0u,                                                                                                     // VkSubpassDescriptionFlags    flags;
1232                         0u,                                                                                                     // deUint32                                             inputCount;
1233                         DE_NULL,                                                                                        // constVkAttachmentReference*  pInputAttachments;
1234                         1u,                                                                                                     // deUint32                                             colorCount;
1235                         &attachmentReference,                                                           // constVkAttachmentReference*  pColorAttachments;
1236                         DE_NULL,                                                                                        // constVkAttachmentReference*  pResolveAttachments;
1237                         { ~0u, VK_IMAGE_LAYOUT_GENERAL },                                       // VkAttachmentReference                depthStencilAttachment;
1238                         0u,                                                                                                     // deUint32                                             preserveCount;
1239                         DE_NULL                                                                                         // constVkAttachmentReference*  pPreserveAttachments;
1240                 };
1241
1242                 const VkRenderPassCreateInfo                                    renderPassParams                        =
1243                 {
1244                         VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,                      // VkStructureType                                      sType;
1245                         DE_NULL,                                                                                        // const void*                                          pNext;
1246                         1u,                                                                                                     // deUint32                                                     attachmentCount;
1247                         &attachmentDescription,                                                         // const VkAttachmentDescription*       pAttachments;
1248                         1u,                                                                                                     // deUint32                                                     subpassCount;
1249                         &subpassDescription,                                                            // const VkSubpassDescription*          pSubpasses;
1250                         0u,                                                                                                     // deUint32                                                     dependencyCount;
1251                         DE_NULL                                                                                         // const VkSubpassDependency*           pDependencies;
1252                 };
1253
1254                 m_renderPass = createRenderPass(vk, vkDevice, &renderPassParams);
1255         }
1256
1257         // Create framebuffer
1258         {
1259                 const VkFramebufferCreateInfo                                   framebufferParams                       =
1260                 {
1261                         VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,                      // VkStructureType                              sType;
1262                         DE_NULL,                                                                                        // const void*                                  pNext;
1263                         *m_renderPass,                                                                          // VkRenderPass                                 renderPass;
1264                         1u,                                                                                                     // deUint32                                             attachmentCount;
1265                         &*m_colorImageView,                                                                     // const VkImageView*                   pAttachments;
1266                         (deUint32)m_renderSize.x(),                                                     // deUint32                                             width;
1267                         (deUint32)m_renderSize.y(),                                                     // deUint32                                             height;
1268                         1u                                                                                                      // deUint32                                             layers;
1269                 };
1270
1271                 m_framebuffer = createFramebuffer(vk, vkDevice, &framebufferParams);
1272         }
1273
1274         // Create descriptors
1275         {
1276                 setupUniforms(quadGrid.getConstCoords());
1277
1278                 m_descriptorSetLayout = m_descriptorSetLayoutBuilder.build(vk, vkDevice);
1279                 m_descriptorPool = m_descriptorPoolBuilder.build(vk, vkDevice, VK_DESCRIPTOR_POOL_USAGE_ONE_SHOT, 1u);
1280                 m_descriptorSet = allocDescriptorSet(vk, vkDevice, *m_descriptorPool, VK_DESCRIPTOR_SET_USAGE_STATIC, *m_descriptorSetLayout);
1281
1282                 for(deUint32 i = 0; i < m_uniformInfos.size(); i++)
1283                 {
1284                         const UniformInfo* uniformInfo = m_uniformInfos[i].get()->get();
1285                         deUint32 location = uniformInfo->location;
1286                         m_descriptorSetUpdateBuilder.writeSingle(*m_descriptorSet, DescriptorSetUpdateBuilder::Location::binding(location), uniformInfo->type, &uniformInfo->descriptor);
1287                 }
1288
1289                 m_descriptorSetUpdateBuilder.update(vk, vkDevice);
1290         }
1291
1292         // Create pipeline layout
1293         {
1294                 const VkPipelineLayoutCreateInfo                                pipelineLayoutParams            =
1295                 {
1296                         VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,          // VkStructureType                              sType;
1297                         DE_NULL,                                                                                        // const void*                                  pNext;
1298                         1u,                                                                                                     // deUint32                                             descriptorSetCount;
1299                         &*m_descriptorSetLayout,                                                        // const VkDescriptorSetLayout* pSetLayouts;
1300                         0u,                                                                                                     // deUint32                                             pushConstantRangeCount;
1301                         DE_NULL                                                                                         // const VkPushConstantRange*   pPushConstantRanges;
1302                 };
1303
1304                 m_pipelineLayout = createPipelineLayout(vk, vkDevice, &pipelineLayoutParams);
1305         }
1306
1307         // Create shaders
1308         {
1309                 m_vertexShaderModule    = createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("vert"), 0);
1310                 m_fragmentShaderModule  = createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("frag"), 0);
1311
1312                 const VkShaderCreateInfo                                                vertexShaderParams                      =
1313                 {
1314                         VK_STRUCTURE_TYPE_SHADER_CREATE_INFO,                   // VkStructureType              sType;
1315                         DE_NULL,                                                                                // const void*                  pNext;
1316                         *m_vertexShaderModule,                                                  // VkShaderModule               module;
1317                         "main",                                                                                 // const char*                  pName;
1318                         0u,                                                                                             // VkShaderCreateFlags  flags;
1319                         VK_SHADER_STAGE_VERTEX,                                                 // VkShaderStage                stage;
1320                 };
1321
1322                 const VkShaderCreateInfo                                                fragmentShaderParams            =
1323                 {
1324                         VK_STRUCTURE_TYPE_SHADER_CREATE_INFO,                   // VkStructureType              sType;
1325                         DE_NULL,                                                                                // const void*                  pNext;
1326                         *m_fragmentShaderModule,                                                // VkShaderModule               module;
1327                         "main",                                                                                 // const char*                  pName;
1328                         0u,                                                                                             // VkShaderCreateFlags  flags;
1329                         VK_SHADER_STAGE_FRAGMENT,                                               // VkShaderStage                stage;
1330                 };
1331
1332                 m_vertexShader  = createShader(vk, vkDevice, &vertexShaderParams);
1333                 m_fragmentShader= createShader(vk, vkDevice, &fragmentShaderParams);
1334         }
1335
1336         // Create pipeline
1337         {
1338                 const VkPipelineShaderStageCreateInfo                   shaderStageParams[2]            =
1339                 {
1340                         {
1341                                 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,            // VkStructureType                              sType;
1342                                 DE_NULL,                                                                                                        // const void*                                  pNext;
1343                                 VK_SHADER_STAGE_VERTEX,                                                                         // VkShaderStage                                stage;
1344                                 *m_vertexShader,                                                                                        // VkShader                                             shader;
1345                                 DE_NULL                                                                                                         // const VkSpecializationInfo*  pSpecializationInfo;
1346                         },
1347                         {
1348                                 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,            // VkStructureType                              sType;
1349                                 DE_NULL,                                                                                                        // const void*                                  pNext;
1350                                 VK_SHADER_STAGE_FRAGMENT,                                                                       // VkShaderStage                                stage;
1351                                 *m_fragmentShader,                                                                                      // VkShader                                             shader;
1352                                 DE_NULL                                                                                                         // const VkSpecializationInfo*  pSpecializationInfo;
1353                         }
1354                 };
1355
1356                 // Add test case specific attributes
1357                 if (m_attribFunc)
1358                         m_attribFunc(*this, quadGrid.getNumVertices());
1359
1360                 // Add base attributes
1361                 setupDefaultInputs(quadGrid);
1362
1363                 const VkPipelineVertexInputStateCreateInfo              vertexInputStateParams          =
1364                 {
1365                         VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,              // VkStructureType                                                      sType;
1366                         DE_NULL,                                                                                                                // const void*                                                          pNext;
1367                         (deUint32)m_vertexBindingDescription.size(),                                    // deUint32                                                                     bindingCount;
1368                         &m_vertexBindingDescription[0],                                                                 // const VkVertexInputBindingDescription*       pVertexBindingDescriptions;
1369                         (deUint32)m_vertexattributeDescription.size(),                                  // deUint32                                                                     attributeCount;
1370                         &m_vertexattributeDescription[0],                                                               // const VkVertexInputAttributeDescription*     pVertexAttributeDescriptions;
1371                 };
1372
1373                 const VkPipelineInputAssemblyStateCreateInfo    inputAssemblyStateParams        =
1374                 {
1375                         VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,    // VkStructureType              sType;
1376                         DE_NULL,                                                                                                                // const void*                  pNext;
1377                         VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST,                                                    // VkPrimitiveTopology  topology;
1378                         false                                                                                                                   // VkBool32                             primitiveRestartEnable;
1379                 };
1380
1381                 const VkViewport                                                                viewport                                        =
1382                 {
1383                         0.0f,                                           // float        originX;
1384                         0.0f,                                           // float        originY;
1385                         (float)m_renderSize.x(),        // float        width;
1386                         (float)m_renderSize.y(),        // float        height;
1387                         0.0f,                                           // float        minDepth;
1388                         1.0f                                            // float        maxDepth;
1389                 };
1390
1391                 const VkRect2D                                                                  scissor                                         =
1392                 {
1393                         {
1394                                 0u,                                     // deUint32     x;
1395                                 0u,                                     // deUint32     y;
1396                         },                                                      // VkOffset2D   offset;
1397                         {
1398                                 m_renderSize.x(),       // deUint32     width;
1399                                 m_renderSize.y(),       // deUint32     height;
1400                         },                                                      // VkExtent2D   extent;
1401                 };
1402
1403                 const VkPipelineViewportStateCreateInfo                 viewportStateParams                     =
1404                 {
1405                         VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO,                  // VkStructureType              sType;
1406                         DE_NULL,                                                                                                                // const void*                  pNext;
1407                         1u,                                                                                                                             // deUint32                             viewportCount;
1408                         &viewport,                                                                                                              // const VkViewport*    pViewports;
1409                         1u,                                                                                                                             // deUint32                             scissorsCount;
1410                         &scissor,                                                                                                               // const VkRect2D*              pScissors;
1411                 };
1412
1413                 const VkPipelineRasterStateCreateInfo                   rasterStateParams                       =
1414                 {
1415                         VK_STRUCTURE_TYPE_PIPELINE_RASTER_STATE_CREATE_INFO,                    // VkStructureType      sType;
1416                         DE_NULL,                                                                                                                // const void*          pNext;
1417                         false,                                                                                                                  // VkBool32                     depthClipEnable;
1418                         false,                                                                                                                  // VkBool32                     rasterizerDiscardEnable;
1419                         VK_FILL_MODE_SOLID,                                                                                             // VkFillMode           fillMode;
1420                         VK_CULL_MODE_NONE,                                                                                              // VkCullMode           cullMode;
1421                         VK_FRONT_FACE_CCW,                                                                                              // VkFrontFace          frontFace;
1422                         false,                                                                                                                  // VkBool32                     depthBiasEnable;
1423                         0.0f,                                                                                                                   // float                        depthBias;
1424                         0.0f,                                                                                                                   // float                        depthBiasClamp;
1425                         0.0f,                                                                                                                   // float                        slopeScaledDepthBias;
1426                         1.0f,                                                                                                                   // float                        lineWidth;
1427                 };
1428
1429                 const VkPipelineColorBlendAttachmentState               colorBlendAttachmentState       =
1430                 {
1431                         false,                                                                                                                                          // VkBool32                     blendEnable;
1432                         VK_BLEND_ONE,                                                                                                                           // VkBlend                      srcBlendColor;
1433                         VK_BLEND_ZERO,                                                                                                                          // VkBlend                      destBlendColor;
1434                         VK_BLEND_OP_ADD,                                                                                                                        // VkBlendOp            blendOpColor;
1435                         VK_BLEND_ONE,                                                                                                                           // VkBlend                      srcBlendAlpha;
1436                         VK_BLEND_ZERO,                                                                                                                          // VkBlend                      destBlendAlpha;
1437                         VK_BLEND_OP_ADD,                                                                                                                        // VkBlendOp            blendOpAlpha;
1438                         VK_CHANNEL_R_BIT | VK_CHANNEL_G_BIT | VK_CHANNEL_B_BIT | VK_CHANNEL_A_BIT       // VkChannelFlags       channelWriteMask;
1439                 };
1440
1441                 const VkPipelineColorBlendStateCreateInfo               colorBlendStateParams           =
1442                 {
1443                         VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,       // VkStructureType                                                              sType;
1444                         DE_NULL,                                                                                                        // const void*                                                                  pNext;
1445                         false,                                                                                                          // VkBool32                                                                             alphaToCoverageEnable;
1446                         false,                                                                                                          // VkBool32                                                                             alphaToOneEnable;
1447                         false,                                                                                                          // VkBool32                                                                             logicOpEnable;
1448                         VK_LOGIC_OP_COPY,                                                                                       // VkLogicOp                                                                    logicOp;
1449                         1u,                                                                                                                     // deUint32                                                                             attachmentCount;
1450                         &colorBlendAttachmentState,                                                                     // const VkPipelineColorBlendAttachmentState*   pAttachments;
1451                         { 0.0f, 0.0f, 0.0f, 0.0f },                                                                     // float                                                                                blendConst[4];
1452                 };
1453
1454                 const VkPipelineDynamicStateCreateInfo                  dynamicStateInfo                        =
1455                 {
1456                         VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO,           // VkStructureType                              sType;
1457                         DE_NULL,                                                                                                        // const void*                                  pNext;
1458                         0u,                                                                                                                     // deUint32                                             dynamicStateCount;
1459                         DE_NULL                                                                                                         // const VkDynamicState*                pDynamicStates;
1460                 };
1461
1462                 const VkGraphicsPipelineCreateInfo                              graphicsPipelineParams          =
1463                 {
1464                         VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,        // VkStructureType                                                                      sType;
1465                         DE_NULL,                                                                                        // const void*                                                                          pNext;
1466                         2u,                                                                                                     // deUint32                                                                                     stageCount;
1467                         shaderStageParams,                                                                      // const VkPipelineShaderStageCreateInfo*                       pStages;
1468                         &vertexInputStateParams,                                                        // const VkPipelineVertexInputStateCreateInfo*          pVertexInputState;
1469                         &inputAssemblyStateParams,                                                      // const VkPipelineInputAssemblyStateCreateInfo*        pInputAssemblyState;
1470                         DE_NULL,                                                                                        // const VkPipelineTessellationStateCreateInfo*         pTessellationState;
1471                         &viewportStateParams,                                                           // const VkPipelineViewportStateCreateInfo*                     pViewportState;
1472                         &rasterStateParams,                                                                     // const VkPipelineRasterStateCreateInfo*                       pRasterState;
1473                         DE_NULL,                                                                                        // const VkPipelineMultisampleStateCreateInfo*          pMultisampleState;
1474                         DE_NULL,                                                                                        // const VkPipelineDepthStencilStateCreateInfo*         pDepthStencilState;
1475                         &colorBlendStateParams,                                                         // const VkPipelineColorBlendStateCreateInfo*           pColorBlendState;
1476                         &dynamicStateInfo,                                                                      // const VkPipelineDynamicStateCreateInfo*                      pDynamicState;
1477                         0u,                                                                                                     // VkPipelineCreateFlags                                                        flags;
1478                         *m_pipelineLayout,                                                                      // VkPipelineLayout                                                                     layout;
1479                         *m_renderPass,                                                                          // VkRenderPass                                                                         renderPass;
1480                         0u,                                                                                                     // deUint32                                                                                     subpass;
1481                         0u,                                                                                                     // VkPipeline                                                                           basePipelineHandle;
1482                         0u                                                                                                      // deInt32                                                                                      basePipelineIndex;
1483                 };
1484
1485                 m_graphicsPipeline = createGraphicsPipeline(vk, vkDevice, DE_NULL, &graphicsPipelineParams);
1486         }
1487
1488         // Create vertex indices buffer
1489         {
1490                 const VkDeviceSize                                                              indiceBufferSize                        = quadGrid.getNumTriangles() * 3 * sizeof(deUint16);
1491                 const VkBufferCreateInfo                                                indiceBufferParams                      =
1492                 {
1493                         VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,           // VkStructureType              sType;
1494                         DE_NULL,                                                                        // const void*                  pNext;
1495                         indiceBufferSize,                                                       // VkDeviceSize                 size;
1496                         VK_BUFFER_USAGE_INDEX_BUFFER_BIT,                       // VkBufferUsageFlags   usage;
1497                         0u,                                                                                     // VkBufferCreateFlags  flags;
1498                         VK_SHARING_MODE_EXCLUSIVE,                                      // VkSharingMode                sharingMode;
1499                         1u,                                                                                     // deUint32                             queueFamilyCount;
1500                         &queueFamilyIndex                                                       // const deUint32*              pQueueFamilyIndices;
1501                 };
1502
1503                 m_indiceBuffer          = createBuffer(vk, vkDevice, &indiceBufferParams);
1504                 m_indiceBufferAlloc     = m_memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *m_indiceBuffer), MemoryRequirement::HostVisible);
1505
1506                 VK_CHECK(vk.bindBufferMemory(vkDevice, *m_indiceBuffer, m_indiceBufferAlloc->getMemory(), m_indiceBufferAlloc->getOffset()));
1507
1508                 // Load vertice indices into buffer
1509                 deMemcpy(m_indiceBufferAlloc->getHostPtr(), quadGrid.getIndices(), indiceBufferSize);
1510                 flushMappedMemoryRange(vk, vkDevice, m_indiceBufferAlloc->getMemory(), m_indiceBufferAlloc->getOffset(), indiceBufferSize);
1511         }
1512
1513         // Create command pool
1514         {
1515                 const VkCmdPoolCreateInfo                                               cmdPoolParams                           =
1516                 {
1517                         VK_STRUCTURE_TYPE_CMD_POOL_CREATE_INFO,         // VkStructureType              sType;
1518                         DE_NULL,                                                                        // const void*                  pNext;
1519                         queueFamilyIndex,                                                       // deUint32                             queueFamilyIndex;
1520                         VK_CMD_POOL_CREATE_TRANSIENT_BIT                        // VkCmdPoolCreateFlags flags;
1521                 };
1522
1523                 m_cmdPool = createCommandPool(vk, vkDevice, &cmdPoolParams);
1524         }
1525
1526         // Create command buffer
1527         {
1528                 const VkCmdBufferCreateInfo                                             cmdBufferParams                         =
1529                 {
1530                         VK_STRUCTURE_TYPE_CMD_BUFFER_CREATE_INFO,       // VkStructureType                      sType;
1531                         DE_NULL,                                                                        // const void*                          pNext;
1532                         *m_cmdPool,                                                                     // VkCmdPool                            cmdPool;
1533                         VK_CMD_BUFFER_LEVEL_PRIMARY,                            // VkCmdBufferLevel                     level;
1534                         0u                                                                                      // VkCmdBufferCreateFlags       flags;
1535                 };
1536
1537                 const VkCmdBufferBeginInfo                                              cmdBufferBeginInfo                      =
1538                 {
1539                         VK_STRUCTURE_TYPE_CMD_BUFFER_BEGIN_INFO,        // VkStructureType                      sType;
1540                         DE_NULL,                                                                        // const void*                          pNext;
1541                         0u,                                                                                     // VkCmdBufferOptimizeFlags     flags;
1542                         DE_NULL,                                                                        // VkRenderPass                         renderPass;
1543                         0u,                                                                                     // deUint32                                     subpass;
1544                         DE_NULL                                                                         // VkFramebuffer                        framebuffer;
1545                 };
1546
1547                 const VkClearValue                                                              clearValues                                     =
1548                 {
1549                         m_clearColor.x(),
1550                         m_clearColor.y(),
1551                         m_clearColor.z(),
1552                         m_clearColor.w(),
1553                 };
1554
1555                 const VkRenderPassBeginInfo                                             renderPassBeginInfo                     =
1556                 {
1557                         VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO        ,       // VkStructureType              sType;
1558                         DE_NULL,                                                                                // const void*                  pNext;
1559                         *m_renderPass,                                                                  // VkRenderPass                 renderPass;
1560                         *m_framebuffer,                                                                 // VkFramebuffer                framebuffer;
1561                         { 0, 0, m_renderSize.x(), m_renderSize.y() },   // VkRect2D                             renderArea;
1562                         1,                                                                                              // deUint32                             clearValueCount;
1563                         &clearValues,                                                                   // const VkClearValue*  pClearValues;
1564                 };
1565
1566                 m_cmdBuffer = createCommandBuffer(vk, vkDevice, &cmdBufferParams);
1567
1568                 VK_CHECK(vk.beginCommandBuffer(*m_cmdBuffer, &cmdBufferBeginInfo));
1569
1570                 // Add texture barriers
1571                 std::vector<VkImageMemoryBarrier> barriers;
1572                 std::vector<void*> barrierPtrs;
1573
1574                 for(deUint32 i = 0; i < m_uniformInfos.size(); i++)
1575                 {
1576                         const UniformInfo* uniformInfo = m_uniformInfos[i].get()->get();
1577
1578                         if (uniformInfo->type != VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER)
1579                         {
1580                                 continue;
1581                         }
1582
1583                         const SamplerUniform* sampler = static_cast<const SamplerUniform*>(uniformInfo);
1584
1585                         VkMemoryOutputFlags outputMask = VK_MEMORY_OUTPUT_HOST_WRITE_BIT | VK_MEMORY_OUTPUT_TRANSFER_BIT;
1586                         VkImageMemoryBarrier textureBarrier = createImageMemoryBarrier(sampler->image->get(), outputMask, 0u, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
1587
1588                         barriers.push_back(textureBarrier);
1589                         barrierPtrs.push_back((void*)&barriers.back());
1590                 }
1591
1592                 vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, false, (deUint32)barrierPtrs.size(), (barrierPtrs.size() ? (const void * const*)&barrierPtrs[0] : DE_NULL));
1593
1594                 vk.cmdBeginRenderPass(*m_cmdBuffer, &renderPassBeginInfo, VK_RENDER_PASS_CONTENTS_INLINE);
1595
1596                 vk.cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_graphicsPipeline);
1597                 vk.cmdBindDescriptorSets(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipelineLayout, 0u, 1, &*m_descriptorSet, 0u, DE_NULL);
1598                 vk.cmdBindIndexBuffer(*m_cmdBuffer, *m_indiceBuffer, 0, VK_INDEX_TYPE_UINT16);
1599
1600                 const deUint32 numberOfVertexAttributes = (deUint32)m_vertexBuffers.size();
1601                 const std::vector<VkDeviceSize> offsets(numberOfVertexAttributes, 0);
1602
1603                 std::vector<VkBuffer> buffers(numberOfVertexAttributes);
1604                 for (size_t i = 0; i < numberOfVertexAttributes; i++)
1605                 {
1606                         buffers[i] = m_vertexBuffers[i].get()->get();
1607                 }
1608
1609                 vk.cmdBindVertexBuffers(*m_cmdBuffer, 0, numberOfVertexAttributes, &buffers[0], &offsets[0]);
1610                 vk.cmdDrawIndexed(*m_cmdBuffer, quadGrid.getNumTriangles() * 3, 1, 0, 0, 0);
1611
1612                 vk.cmdEndRenderPass(*m_cmdBuffer);
1613                 VK_CHECK(vk.endCommandBuffer(*m_cmdBuffer));
1614         }
1615
1616         // Create fence
1617         {
1618                 const VkFenceCreateInfo                                                 fenceParams                                     =
1619                 {
1620                         VK_STRUCTURE_TYPE_FENCE_CREATE_INFO,    // VkStructureType              sType;
1621                         DE_NULL,                                                                // const void*                  pNext;
1622                         0u                                                                              // VkFenceCreateFlags   flags;
1623                 };
1624                 m_fence = createFence(vk, vkDevice, &fenceParams);
1625         }
1626
1627         // Execute Draw
1628         {
1629                 VK_CHECK(vk.resetFences(vkDevice, 1, &m_fence.get()));
1630                 VK_CHECK(vk.queueSubmit(queue, 1, &m_cmdBuffer.get(), *m_fence));
1631                 VK_CHECK(vk.waitForFences(vkDevice, 1, &m_fence.get(), true, ~(0ull) /* infinity*/));
1632         }
1633
1634         // Read back the result
1635         {
1636                 const VkDeviceSize                                                              imageSizeBytes                          = (VkDeviceSize)(sizeof(deUint32) * m_renderSize.x() * m_renderSize.y());
1637                 const VkBufferCreateInfo                                                readImageBufferParams           =
1638                 {
1639                         VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,           //  VkStructureType             sType;
1640                         DE_NULL,                                                                        //  const void*                 pNext;
1641                         imageSizeBytes,                                                         //  VkDeviceSize                size;
1642                         VK_BUFFER_USAGE_TRANSFER_DESTINATION_BIT,       //  VkBufferUsageFlags  usage;
1643                         0u,                                                                                     //  VkBufferCreateFlags flags;
1644                         VK_SHARING_MODE_EXCLUSIVE,                                      //  VkSharingMode               sharingMode;
1645                         1u,                                                                                     //  deUint32                    queueFamilyCount;
1646                         &queueFamilyIndex,                                                      //  const deUint32*             pQueueFamilyIndices;
1647                 };
1648                 const Unique<VkBuffer>                                                  readImageBuffer                         (createBuffer(vk, vkDevice, &readImageBufferParams));
1649                 const de::UniquePtr<Allocation>                                 readImageBufferMemory           (m_memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *readImageBuffer), MemoryRequirement::HostVisible));
1650
1651                 VK_CHECK(vk.bindBufferMemory(vkDevice, *readImageBuffer, readImageBufferMemory->getMemory(), readImageBufferMemory->getOffset()));
1652
1653                 // Copy image to buffer
1654                 const VkCmdBufferCreateInfo                                             cmdBufferParams                         =
1655                 {
1656                         VK_STRUCTURE_TYPE_CMD_BUFFER_CREATE_INFO,       // VkStructureType                      sType;
1657                         DE_NULL,                                                                        // const void*                          pNext;
1658                         *m_cmdPool,                                                                     // VkCmdPool                            cmdPool;
1659                         VK_CMD_BUFFER_LEVEL_PRIMARY,                            // VkCmdBufferLevel                     level;
1660                         0u                                                                                      // VkCmdBufferCreateFlags       flags;
1661                 };
1662
1663                 const VkCmdBufferBeginInfo                                              cmdBufferBeginInfo                      =
1664                 {
1665                         VK_STRUCTURE_TYPE_CMD_BUFFER_BEGIN_INFO,        // VkStructureType                      sType;
1666                         DE_NULL,                                                                        // const void*                          pNext;
1667                         0u,                                                                                     // VkCmdBufferOptimizeFlags     flags;
1668                         DE_NULL,                                                                        // VkRenderPass                         renderPass;
1669                         0u,                                                                                     // deUint32                                     subpass;
1670                         DE_NULL                                                                         // VkFramebuffer                        framebuffer;
1671                 };
1672
1673                 const Move<VkCmdBuffer>                                                 cmdBuffer                                       = createCommandBuffer(vk, vkDevice, &cmdBufferParams);
1674
1675                 const VkBufferImageCopy                                                 copyParams                                      =
1676                 {
1677                         0u,                                                                                     // VkDeviceSize                 bufferOffset;
1678                         (deUint32)m_renderSize.x(),                                     // deUint32                             bufferRowLength;
1679                         (deUint32)m_renderSize.y(),                                     // deUint32                             bufferImageHeight;
1680                         {
1681                                 VK_IMAGE_ASPECT_COLOR,                          // VkImageAspect                aspect;
1682                                 0u,                                                                     // deUint32                             mipLevel;
1683                                 0u,                                                                     // deUint32                             arraySlice;
1684                                 1u,                                                                     // deUint32                             arraySize;
1685                         },                                                                                      // VkImageSubresourceCopy       imageSubresource;
1686                         { 0u, 0u, 0u },                                                         // VkOffset3D                   imageOffset;
1687                         { m_renderSize.x(), m_renderSize.y(), 1u }      // VkExtent3D                   imageExtent;
1688                 };
1689
1690                 VK_CHECK(vk.beginCommandBuffer(*cmdBuffer, &cmdBufferBeginInfo));
1691                 vk.cmdCopyImageToBuffer(*cmdBuffer, *m_colorImage, VK_IMAGE_LAYOUT_TRANSFER_SOURCE_OPTIMAL, *readImageBuffer, 1u, &copyParams);
1692                 VK_CHECK(vk.endCommandBuffer(*cmdBuffer));
1693
1694                 VK_CHECK(vk.resetFences(vkDevice, 1, &m_fence.get()));
1695                 VK_CHECK(vk.queueSubmit(queue, 1, &cmdBuffer.get(), *m_fence));
1696                 VK_CHECK(vk.waitForFences(vkDevice, 1, &m_fence.get(), true, ~(0ull) /* infinity */));
1697
1698                 invalidateMappedMemoryRange(vk, vkDevice, readImageBufferMemory->getMemory(), readImageBufferMemory->getOffset(), imageSizeBytes);
1699
1700                 const tcu::TextureFormat                                                resultFormat                            (tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8);
1701                 const tcu::ConstPixelBufferAccess                               resultAccess                            (resultFormat, m_renderSize.x(), m_renderSize.y(), 1, readImageBufferMemory->getHostPtr());
1702
1703                 tcu::copy(result.getAccess(), resultAccess);
1704         }
1705 }
1706
1707 void ShaderRenderCaseInstance::computeVertexReference (tcu::Surface& result, const QuadGrid& quadGrid)
1708 {
1709         // Buffer info.
1710         const int                               width           = result.getWidth();
1711         const int                               height          = result.getHeight();
1712         const int                               gridSize        = quadGrid.getGridSize();
1713         const int                               stride          = gridSize + 1;
1714         const bool                              hasAlpha        = true; // \todo [2015-09-07 elecro] add correct alpha check
1715         ShaderEvalContext               evalCtx         (quadGrid);
1716
1717         // Evaluate color for each vertex.
1718         std::vector<tcu::Vec4>  colors          ((gridSize + 1) * (gridSize + 1));
1719         for (int y = 0; y < gridSize+1; y++)
1720         for (int x = 0; x < gridSize+1; x++)
1721         {
1722                 const float     sx                      = (float)x / (float)gridSize;
1723                 const float     sy                      = (float)y / (float)gridSize;
1724                 const int       vtxNdx          = ((y * (gridSize+1)) + x);
1725
1726                 evalCtx.reset(sx, sy);
1727                 m_evaluator.evaluate(evalCtx);
1728                 DE_ASSERT(!evalCtx.isDiscarded); // Discard is not available in vertex shader.
1729                 tcu::Vec4 color = evalCtx.color;
1730
1731                 if (!hasAlpha)
1732                         color.w() = 1.0f;
1733
1734                 colors[vtxNdx] = color;
1735         }
1736
1737         // Render quads.
1738         for (int y = 0; y < gridSize; y++)
1739         for (int x = 0; x < gridSize; x++)
1740         {
1741                 const float             x0              = (float)x       / (float)gridSize;
1742                 const float             x1              = (float)(x + 1) / (float)gridSize;
1743                 const float             y0              = (float)y       / (float)gridSize;
1744                 const float             y1              = (float)(y + 1) / (float)gridSize;
1745
1746                 const float             sx0             = x0 * (float)width;
1747                 const float             sx1             = x1 * (float)width;
1748                 const float             sy0             = y0 * (float)height;
1749                 const float             sy1             = y1 * (float)height;
1750                 const float             oosx    = 1.0f / (sx1 - sx0);
1751                 const float             oosy    = 1.0f / (sy1 - sy0);
1752
1753                 const int               ix0             = deCeilFloatToInt32(sx0 - 0.5f);
1754                 const int               ix1             = deCeilFloatToInt32(sx1 - 0.5f);
1755                 const int               iy0             = deCeilFloatToInt32(sy0 - 0.5f);
1756                 const int               iy1             = deCeilFloatToInt32(sy1 - 0.5f);
1757
1758                 const int               v00             = (y * stride) + x;
1759                 const int               v01             = (y * stride) + x + 1;
1760                 const int               v10             = ((y + 1) * stride) + x;
1761                 const int               v11             = ((y + 1) * stride) + x + 1;
1762                 const tcu::Vec4 c00             = colors[v00];
1763                 const tcu::Vec4 c01             = colors[v01];
1764                 const tcu::Vec4 c10             = colors[v10];
1765                 const tcu::Vec4 c11             = colors[v11];
1766
1767                 //printf("(%d,%d) -> (%f..%f, %f..%f) (%d..%d, %d..%d)\n", x, y, sx0, sx1, sy0, sy1, ix0, ix1, iy0, iy1);
1768
1769                 for (int iy = iy0; iy < iy1; iy++)
1770                 for (int ix = ix0; ix < ix1; ix++)
1771                 {
1772                         DE_ASSERT(deInBounds32(ix, 0, width));
1773                         DE_ASSERT(deInBounds32(iy, 0, height));
1774
1775                         const float                     sfx             = (float)ix + 0.5f;
1776                         const float                     sfy             = (float)iy + 0.5f;
1777                         const float                     fx1             = deFloatClamp((sfx - sx0) * oosx, 0.0f, 1.0f);
1778                         const float                     fy1             = deFloatClamp((sfy - sy0) * oosy, 0.0f, 1.0f);
1779
1780                         // Triangle quad interpolation.
1781                         const bool                      tri             = fx1 + fy1 <= 1.0f;
1782                         const float                     tx              = tri ? fx1 : (1.0f-fx1);
1783                         const float                     ty              = tri ? fy1 : (1.0f-fy1);
1784                         const tcu::Vec4&        t0              = tri ? c00 : c11;
1785                         const tcu::Vec4&        t1              = tri ? c01 : c10;
1786                         const tcu::Vec4&        t2              = tri ? c10 : c01;
1787                         const tcu::Vec4         color   = t0 + (t1-t0)*tx + (t2-t0)*ty;
1788
1789                         result.setPixel(ix, iy, tcu::RGBA(color));
1790                 }
1791         }
1792 }
1793
1794 void ShaderRenderCaseInstance::computeFragmentReference (tcu::Surface& result, const QuadGrid& quadGrid)
1795 {
1796         // Buffer info.
1797         const int                       width           = result.getWidth();
1798         const int                       height          = result.getHeight();
1799         const bool                      hasAlpha        = true;  // \todo [2015-09-07 elecro] add correct alpha check
1800         ShaderEvalContext       evalCtx         (quadGrid);
1801
1802         // Render.
1803         for (int y = 0; y < height; y++)
1804         for (int x = 0; x < width; x++)
1805         {
1806                 const float sx = ((float)x + 0.5f) / (float)width;
1807                 const float sy = ((float)y + 0.5f) / (float)height;
1808
1809                 evalCtx.reset(sx, sy);
1810                 m_evaluator.evaluate(evalCtx);
1811                 // Select either clear color or computed color based on discarded bit.
1812                 tcu::Vec4 color = evalCtx.isDiscarded ? m_clearColor : evalCtx.color;
1813
1814                 if (!hasAlpha)
1815                         color.w() = 1.0f;
1816
1817                 result.setPixel(x, y, tcu::RGBA(color));
1818         }
1819 }
1820
1821 bool ShaderRenderCaseInstance::compareImages (const tcu::Surface& resImage, const tcu::Surface& refImage, float errorThreshold)
1822 {
1823         return tcu::fuzzyCompare(m_context.getTestContext().getLog(), "ComparisonResult", "Image comparison result", refImage, resImage, errorThreshold, tcu::COMPARE_LOG_RESULT);
1824 }
1825
1826 } // shaderrendercase
1827 } // vkt