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