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