Merge branch 'jekstrand_renderpass_transfer_bit_fix' into 'master'
[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                GRID_SIZE                       = 2;
72 static const deUint32   MAX_RENDER_WIDTH        = 128;
73 static const deUint32   MAX_RENDER_HEIGHT       = 128;
74 static const tcu::Vec4  DEFAULT_CLEAR_COLOR     = 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          (DEFAULT_CLEAR_COLOR)
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::UVec2        viewportSize    = getViewportSize();
495         const int                       width                   = viewportSize.x();
496         const int                       height                  = viewportSize.y();
497
498         QuadGrid                        quadGrid                (m_isVertexCase ? GRID_SIZE : 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::UVec2 ShaderRenderCaseInstance::getViewportSize (void) const
751 {
752         return tcu::UVec2(de::min(m_renderSize.x(), MAX_RENDER_WIDTH),
753                                           de::min(m_renderSize.y(), MAX_RENDER_HEIGHT));
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                 {
773                         (deUint32)texture.getWidth(),
774                         (deUint32)texture.getHeight(),
775                         1u
776                 },                                                                                                                      // VkExtend3D                           extent;
777                 1u,                                                                                                                     // deUint32                                     mipLevels;
778                 1u,                                                                                                                     // deUint32                                     arraySize;
779                 VK_SAMPLE_COUNT_1_BIT,                                                                          // deUint32                                     samples;
780                 tiling,                                                                                                         // VkImageTiling                        tiling;
781                 usage,                                                                                                          // VkImageUsageFlags            usage;
782                 VK_SHARING_MODE_EXCLUSIVE,                                                                      // VkSharingMode                        sharingMode;
783                 1,                                                                                                                      // deuint32                                     queueFamilyCount;
784                 &queueFamilyIndex,                                                                                      // const deUint32*                      pQueueFamilyIndices;
785                 VK_IMAGE_LAYOUT_UNDEFINED,                                                                      // VkImageLayout                        initialLayout;
786         };
787
788         Move<VkImage>                   vkTexture                       = createImage(vk, vkDevice, &imageCreateInfo);
789         return vkTexture;
790 }
791
792 de::MovePtr<Allocation> ShaderRenderCaseInstance::uploadImage2D (const tcu::Texture2D&  refTexture,
793                                                                                                                                  const VkImage&                 vkTexture)
794 {
795         const VkDevice                          vkDevice        = m_context.getDevice();
796         const DeviceInterface&          vk                      = m_context.getDeviceInterface();
797
798         de::MovePtr<Allocation>         allocation      = m_memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, vkTexture), MemoryRequirement::HostVisible);
799         VK_CHECK(vk.bindImageMemory(vkDevice, vkTexture, allocation->getMemory(), allocation->getOffset()));
800
801         const VkImageSubresource        subres                          =
802         {
803                 VK_IMAGE_ASPECT_COLOR_BIT,      // VkImageAspectFlags   aspectMask;
804                 0u,                                                     // deUint32                             mipLevel;
805                 0u                                                      // deUint32                             arraySlice
806         };
807
808         VkSubresourceLayout layout;
809         vk.getImageSubresourceLayout(vkDevice, vkTexture, &subres, &layout);
810
811         tcu::ConstPixelBufferAccess     access          = refTexture.getLevel(0);
812         tcu::PixelBufferAccess          destAccess      (refTexture.getFormat(), refTexture.getWidth(), refTexture.getHeight(), 1, allocation->getHostPtr());
813
814         tcu::copy(destAccess, access);
815
816         flushMappedMemoryRange(vk, vkDevice, allocation->getMemory(), allocation, layout.size);
817
818         return allocation;
819 }
820
821 void ShaderRenderCaseInstance::copyTilingImageToOptimal (const vk::VkImage&     srcImage,
822                                                                                                                  const vk::VkImage&     dstImage,
823                                                                                                                  deUint32                       width,
824                                                                                                                  deUint32                       height)
825 {
826         const VkDevice                                          vkDevice                        = m_context.getDevice();
827         const DeviceInterface&                          vk                                      = m_context.getDeviceInterface();
828         const VkQueue                                           queue                           = m_context.getUniversalQueue();
829         const deUint32                                          queueFamilyIndex        = m_context.getUniversalQueueFamilyIndex();
830
831         // Create command pool
832         const VkCommandPoolCreateInfo           cmdPoolParams           =
833         {
834                 VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,     // VkStructureType              sType;
835                 DE_NULL,                                                                        // const void*                  pNext;
836                 VK_COMMAND_POOL_CREATE_TRANSIENT_BIT,           // VkCmdPoolCreateFlags flags;
837                 queueFamilyIndex,                                                       // deUint32                             queueFamilyIndex;
838         };
839
840         Move<VkCommandPool>                                     cmdPool                         = createCommandPool(vk, vkDevice, &cmdPoolParams);
841
842         // Create command buffer
843         const VkCommandBufferAllocateInfo       cmdBufferParams         =
844         {
845                 VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, // VkStructureType                      sType;
846                 DE_NULL,                                                                                // const void*                          pNext;
847                 *cmdPool,                                                                               // VkCommandPool                        commandPool;
848                 VK_COMMAND_BUFFER_LEVEL_PRIMARY,                                // VkCommandBufferLevel         level;
849                 1u                                                                                              // deUint32                                     bufferCount;
850         };
851
852         const VkCommandBufferUsageFlags         usageFlags                      = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;
853         const VkCommandBufferBeginInfo          cmdBufferBeginInfo      =
854         {
855                 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,    // VkStructureType                              sType;
856                 DE_NULL,                                                                                // const void*                                  pNext;
857                 usageFlags,                                                                             // VkCommandBufferUsageFlags    flags;
858                 (const VkCommandBufferInheritanceInfo*)DE_NULL,
859         };
860
861         Move<VkCommandBuffer>                           cmdBuffer                       = allocateCommandBuffer(vk, vkDevice, &cmdBufferParams);
862
863         VK_CHECK(vk.beginCommandBuffer(*cmdBuffer, &cmdBufferBeginInfo));
864
865         // Add image barriers
866         const VkImageMemoryBarrier                      layoutBarriers[2]       =
867         {
868                 createImageMemoryBarrier(srcImage, (VkAccessFlags)0u, (VkAccessFlags)0u, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL),
869                 createImageMemoryBarrier(dstImage, (VkAccessFlags)0u, VK_ACCESS_TRANSFER_WRITE_BIT, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL)
870         };
871
872         vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, (VkDependencyFlags)0,
873                                                   0, (const VkMemoryBarrier*)DE_NULL,
874                                                   0, (const VkBufferMemoryBarrier*)DE_NULL,
875                                                   DE_LENGTH_OF_ARRAY(layoutBarriers), layoutBarriers);
876
877         // Add image copy
878         const VkImageCopy                               imageCopy                       =
879         {
880                 {
881                         VK_IMAGE_ASPECT_COLOR_BIT,              // VkImageAspect        aspect;
882                         0u,                                                             // deUint32                     mipLevel;
883                         0u,                                                             // deUint32                     arrayLayer;
884                         1u                                                              // deUint32                     arraySize;
885                 },                                                                                      // VkImageSubresourceCopy       srcSubresource;
886                 {
887                         0,                                                              // int32                        x;
888                         0,                                                              // int32                        y;
889                         0                                                               // int32                        z;
890                 },                                                                                      // VkOffset3D                           srcOffset;
891                 {
892                         VK_IMAGE_ASPECT_COLOR_BIT,              // VkImageAspect        aspect;
893                         0u,                                                             // deUint32                     mipLevel;
894                         0u,                                                             // deUint32                     arrayLayer;
895                         1u                                                              // deUint32                     arraySize;
896                 },                                                                                      // VkImageSubresourceCopy       destSubResource;
897                 {
898                         0,                                                              // int32                        x;
899                         0,                                                              // int32                        y;
900                         0                                                               // int32                        z;
901                 },                                                                                      // VkOffset3D                           dstOffset;
902                 {
903                         width,                                                  // int32                        width;
904                         height,                                                 // int32                        height;
905                         1,                                                              // int32                        depth
906                 }       // VkExtent3D                                   extent;
907         };
908
909         vk.cmdCopyImage(*cmdBuffer, srcImage, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, dstImage, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &imageCopy);
910
911         // Add destination barrier
912         const VkImageMemoryBarrier              dstBarrier                      =
913                         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);
914
915         vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, (VkDependencyFlags)0,
916                                                   0, (const VkMemoryBarrier*)DE_NULL,
917                                                   0, (const VkBufferMemoryBarrier*)DE_NULL,
918                                                   1, &dstBarrier);
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                 (const VkPipelineStageFlags*)DE_NULL,
936                 1u,
937                 &cmdBuffer.get(),
938                 0u,
939                 (const VkSemaphore*)DE_NULL,
940         };
941
942
943         // Execute copy
944         VK_CHECK(vk.resetFences(vkDevice, 1, &fence.get()));
945         VK_CHECK(vk.queueSubmit(queue, 1, &submitInfo, *fence));
946         VK_CHECK(vk.waitForFences(vkDevice, 1, &fence.get(), true, ~(0ull) /* infinity*/));
947 }
948
949 void ShaderRenderCaseInstance::useSampler2D (deUint32 bindingLocation, deUint32 textureID)
950 {
951         DE_ASSERT(textureID < m_textures.size());
952
953         const VkDevice                                  vkDevice                = m_context.getDevice();
954         const DeviceInterface&                  vk                              = m_context.getDeviceInterface();
955         const TextureBinding&                   textureBinding  = *m_textures[textureID];
956         const tcu::Texture2D&                   refTexture              = textureBinding.get2D();
957         const tcu::Sampler&                             refSampler              = textureBinding.getSampler();
958         const VkFormat                                  format                  = refTexture.getFormat() == tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8)
959                                                                                                                 ? VK_FORMAT_R8G8B8A8_UNORM
960                                                                                                                 : VK_FORMAT_R8G8B8_UNORM;
961
962         // Create & alloc the image
963         Move<VkImage>                                   vkTexture;
964         de::MovePtr<Allocation>                 allocation;
965
966         if (isSupportedLinearTilingFormat(m_context.getInstanceInterface(), m_context.getPhysicalDevice(), format))
967         {
968                 vkTexture = createImage2D(refTexture, format, VK_IMAGE_USAGE_SAMPLED_BIT, VK_IMAGE_TILING_LINEAR);
969                 allocation = uploadImage2D(refTexture, *vkTexture);
970         }
971         else if (isSupportedOptimalTilingFormat(m_context.getInstanceInterface(), m_context.getPhysicalDevice(), format))
972         {
973                 Move<VkImage>                           stagingTexture  (createImage2D(refTexture, format, VK_IMAGE_USAGE_TRANSFER_SRC_BIT, VK_IMAGE_TILING_LINEAR));
974                 de::MovePtr<Allocation>         stagingAlloc    (uploadImage2D(refTexture, *stagingTexture));
975
976                 const VkImageUsageFlags         dstUsageFlags   = VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT;
977                 vkTexture = createImage2D(refTexture, format, dstUsageFlags, VK_IMAGE_TILING_OPTIMAL);
978                 allocation = m_memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, *vkTexture), MemoryRequirement::Any);
979                 VK_CHECK(vk.bindImageMemory(vkDevice, *vkTexture, allocation->getMemory(), allocation->getOffset()));
980
981                 copyTilingImageToOptimal(*stagingTexture, *vkTexture, refTexture.getWidth(), refTexture.getHeight());
982         }
983         else
984         {
985                 TCU_THROW(InternalError, "Unable to create 2D image");
986         }
987
988         // Create sampler
989         const VkSamplerCreateInfo               samplerParams   = mapSampler(refSampler, refTexture.getFormat());
990         Move<VkSampler>                                 sampler                 = createSampler(vk, vkDevice, &samplerParams);
991
992         const VkImageViewCreateInfo             viewParams              =
993         {
994                 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,       // VkStructureType                      sType;
995                 NULL,                                                                           // const voide*                         pNext;
996                 0u,                                                                                     // VkImageViewCreateFlags       flags;
997                 *vkTexture,                                                                     // VkImage                                      image;
998                 VK_IMAGE_VIEW_TYPE_2D,                                          // VkImageViewType                      viewType;
999                 format,                                                                         // VkFormat                                     format;
1000                 {
1001                         VK_COMPONENT_SWIZZLE_R,                 // VkChannelSwizzle             r;
1002                         VK_COMPONENT_SWIZZLE_G,                 // VkChannelSwizzle             g;
1003                         VK_COMPONENT_SWIZZLE_B,                 // VkChannelSwizzle             b;
1004                         VK_COMPONENT_SWIZZLE_A                  // VkChannelSwizzle             a;
1005                 },                                                                                      // VkChannelMapping                     channels;
1006                 {
1007                         VK_IMAGE_ASPECT_COLOR_BIT,              // VkImageAspectFlags   aspectMask;
1008                         0,                                                              // deUint32                             baseMipLevel;
1009                         1,                                                              // deUint32                             mipLevels;
1010                         0,                                                              // deUint32                             baseArraySlice;
1011                         1                                                               // deUint32                             arraySize;
1012                 },                                                                                      // VkImageSubresourceRange      subresourceRange;
1013         };
1014
1015         Move<VkImageView>                               imageView               = createImageView(vk, vkDevice, &viewParams);
1016
1017         const vk::VkDescriptorImageInfo descriptor              =
1018         {
1019                 sampler.get(),                                                          // VkSampler                            sampler;
1020                 imageView.get(),                                                        // VkImageView                          imageView;
1021                 VK_IMAGE_LAYOUT_GENERAL,                                        // VkImageLayout                        imageLayout;
1022         };
1023
1024         de::MovePtr<SamplerUniform> uniform(new SamplerUniform());
1025         uniform->type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
1026         uniform->descriptor = descriptor;
1027         uniform->location = bindingLocation;
1028         uniform->image = VkImageSp(new vk::Unique<VkImage>(vkTexture));
1029         uniform->imageView = VkImageViewSp(new vk::Unique<VkImageView>(imageView));
1030         uniform->sampler = VkSamplerSp(new vk::Unique<VkSampler>(sampler));
1031         uniform->alloc = AllocationSp(allocation.release());
1032
1033         m_descriptorSetLayoutBuilder.addSingleSamplerBinding(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, vk::VK_SHADER_STAGE_ALL, &uniform->descriptor.sampler);
1034         m_descriptorPoolBuilder.addType(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER);
1035
1036         m_uniformInfos.push_back(UniformInfoSp(new de::UniquePtr<UniformInfo>(uniform)));
1037 }
1038
1039 void ShaderRenderCaseInstance::setupDefaultInputs (const QuadGrid& quadGrid)
1040 {
1041         /* Configuration of the vertex input attributes:
1042                 a_position   is at location 0
1043                 a_coords     is at location 1
1044                 a_unitCoords is at location 2
1045                 a_one        is at location 3
1046
1047           User attributes starts from at the location 4.
1048         */
1049         addAttribute(0u, VK_FORMAT_R32G32B32A32_SFLOAT, sizeof(tcu::Vec4), quadGrid.getNumVertices(), quadGrid.getPositions());
1050         addAttribute(1u, VK_FORMAT_R32G32B32A32_SFLOAT, sizeof(tcu::Vec4), quadGrid.getNumVertices(), quadGrid.getCoords());
1051         addAttribute(2u, VK_FORMAT_R32G32B32A32_SFLOAT, sizeof(tcu::Vec4), quadGrid.getNumVertices(), quadGrid.getUnitCoords());
1052         addAttribute(3u, VK_FORMAT_R32_SFLOAT, sizeof(float), quadGrid.getNumVertices(), quadGrid.getAttribOne());
1053
1054         static const struct
1055         {
1056                 BaseAttributeType       type;
1057                 int                                     userNdx;
1058         } userAttributes[] =
1059         {
1060                 { A_IN0, 0 },
1061                 { A_IN1, 1 },
1062                 { A_IN2, 2 },
1063                 { A_IN3, 3 }
1064         };
1065
1066         static const struct
1067         {
1068                 BaseAttributeType       matrixType;
1069                 int                                     numCols;
1070                 int                                     numRows;
1071         } matrices[] =
1072         {
1073                 { MAT2,         2, 2 },
1074                 { MAT2x3,       2, 3 },
1075                 { MAT2x4,       2, 4 },
1076                 { MAT3x2,       3, 2 },
1077                 { MAT3,         3, 3 },
1078                 { MAT3x4,       3, 4 },
1079                 { MAT4x2,       4, 2 },
1080                 { MAT4x3,       4, 3 },
1081                 { MAT4,         4, 4 }
1082         };
1083
1084         for (size_t attrNdx = 0; attrNdx < m_enabledBaseAttributes.size(); attrNdx++)
1085         {
1086                 for (int userNdx = 0; userNdx < DE_LENGTH_OF_ARRAY(userAttributes); userNdx++)
1087                 {
1088                         if (userAttributes[userNdx].type != m_enabledBaseAttributes[attrNdx].type)
1089                                 continue;
1090
1091                         addAttribute(m_enabledBaseAttributes[attrNdx].location, VK_FORMAT_R32G32B32A32_SFLOAT, sizeof(tcu::Vec4), quadGrid.getNumVertices(), quadGrid.getUserAttrib(userNdx));
1092                 }
1093
1094                 for (int matNdx = 0; matNdx < DE_LENGTH_OF_ARRAY(matrices); matNdx++)
1095                 {
1096
1097                         if (matrices[matNdx].matrixType != m_enabledBaseAttributes[attrNdx].type)
1098                                 continue;
1099
1100                         const int numCols = matrices[matNdx].numCols;
1101
1102                         for (int colNdx = 0; colNdx < numCols; colNdx++)
1103                         {
1104                                 addAttribute(m_enabledBaseAttributes[attrNdx].location + colNdx, VK_FORMAT_R32G32B32A32_SFLOAT, (deUint32)(4 * sizeof(float)), quadGrid.getNumVertices(), quadGrid.getUserAttrib(colNdx));
1105                         }
1106                 }
1107         }
1108 }
1109
1110 void ShaderRenderCaseInstance::render (tcu::Surface& result, const QuadGrid& quadGrid)
1111 {
1112         const VkDevice                                                                          vkDevice                                        = m_context.getDevice();
1113         const DeviceInterface&                                                          vk                                                      = m_context.getDeviceInterface();
1114         const VkQueue                                                                           queue                                           = m_context.getUniversalQueue();
1115         const deUint32                                                                          queueFamilyIndex                        = m_context.getUniversalQueueFamilyIndex();
1116
1117         // Create color image
1118         {
1119                 const VkImageCreateInfo                                                 colorImageParams                        =
1120                 {
1121                         VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,                                                                            // VkStructureType              sType;
1122                         DE_NULL,                                                                                                                                        // const void*                  pNext;
1123                         0u,                                                                                                                                                     // VkImageCreateFlags   flags;
1124                         VK_IMAGE_TYPE_2D,                                                                                                                       // VkImageType                  imageType;
1125                         m_colorFormat,                                                                                                                          // VkFormat                             format;
1126                         { m_renderSize.x(), m_renderSize.y(), 1u },                                                                     // VkExtent3D                   extent;
1127                         1u,                                                                                                                                                     // deUint32                             mipLevels;
1128                         1u,                                                                                                                                                     // deUint32                             arraySize;
1129                         VK_SAMPLE_COUNT_1_BIT,                                                                                                          // deUint32                             samples;
1130                         VK_IMAGE_TILING_OPTIMAL,                                                                                                        // VkImageTiling                tiling;
1131                         VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT,          // VkImageUsageFlags    usage;
1132                         VK_SHARING_MODE_EXCLUSIVE,                                                                                                      // VkSharingMode                sharingMode;
1133                         1u,                                                                                                                                                     // deUint32                             queueFamilyCount;
1134                         &queueFamilyIndex,                                                                                                                      // const deUint32*              pQueueFamilyIndices;
1135                         VK_IMAGE_LAYOUT_UNDEFINED,                                                                                                      // VkImageLayout                initialLayout;
1136                 };
1137
1138                 m_colorImage = createImage(vk, vkDevice, &colorImageParams);
1139
1140                 // Allocate and bind color image memory
1141                 m_colorImageAlloc = m_memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, *m_colorImage), MemoryRequirement::Any);
1142                 VK_CHECK(vk.bindImageMemory(vkDevice, *m_colorImage, m_colorImageAlloc->getMemory(), m_colorImageAlloc->getOffset()));
1143         }
1144
1145         // Create color attachment view
1146         {
1147                 const VkImageViewCreateInfo                                             colorImageViewParams            =
1148                 {
1149                         VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,                       // VkStructureType                      sType;
1150                         DE_NULL,                                                                                        // const void*                          pNext;
1151                         0u,                                                                                                     // VkImageViewCreateFlags       flags;
1152                         *m_colorImage,                                                                          // VkImage                                      image;
1153                         VK_IMAGE_VIEW_TYPE_2D,                                                          // VkImageViewType                      viewType;
1154                         m_colorFormat,                                                                          // VkFormat                                     format;
1155                         {
1156                                 VK_COMPONENT_SWIZZLE_R,                 // VkChannelSwizzle             r;
1157                                 VK_COMPONENT_SWIZZLE_G,                 // VkChannelSwizzle             g;
1158                                 VK_COMPONENT_SWIZZLE_B,                 // VkChannelSwizzle             b;
1159                                 VK_COMPONENT_SWIZZLE_A                  // VkChannelSwizzle             a;
1160                         },                                                                                                      // VkChannelMapping                     channels;
1161                         {
1162                                 VK_IMAGE_ASPECT_COLOR_BIT,              // VkImageAspectFlags   aspectMask;
1163                                 0,                                                              // deUint32                             baseMipLevel;
1164                                 1,                                                              // deUint32                             mipLevels;
1165                                 0,                                                              // deUint32                             baseArraySlice;
1166                                 1                                                               // deUint32                             arraySize;
1167                         },                                                                                                      // VkImageSubresourceRange      subresourceRange;
1168                 };
1169
1170                 m_colorImageView = createImageView(vk, vkDevice, &colorImageViewParams);
1171         }
1172
1173         // Create render pass
1174         {
1175                 const VkAttachmentDescription                                   attachmentDescription           =
1176                 {
1177                         (VkAttachmentDescriptionFlags)0,
1178                         m_colorFormat,                                                                          // VkFormat                                             format;
1179                         VK_SAMPLE_COUNT_1_BIT,                                                          // deUint32                                             samples;
1180                         VK_ATTACHMENT_LOAD_OP_CLEAR,                                            // VkAttachmentLoadOp                   loadOp;
1181                         VK_ATTACHMENT_STORE_OP_STORE,                                           // VkAttachmentStoreOp                  storeOp;
1182                         VK_ATTACHMENT_LOAD_OP_DONT_CARE,                                        // VkAttachmentLoadOp                   stencilLoadOp;
1183                         VK_ATTACHMENT_STORE_OP_DONT_CARE,                                       // VkAttachmentStoreOp                  stencilStoreOp;
1184                         VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,                       // VkImageLayout                                initialLayout;
1185                         VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,                       // VkImageLayout                                finalLayout;
1186                 };
1187
1188                 const VkAttachmentReference                                             attachmentReference                     =
1189                 {
1190                         0u,                                                                                                     // deUint32                     attachment;
1191                         VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL                        // VkImageLayout        layout;
1192                 };
1193
1194                 const VkSubpassDescription                                              subpassDescription                      =
1195                 {
1196                         0u,                                                                                                     // VkSubpassDescriptionFlags    flags;
1197                         VK_PIPELINE_BIND_POINT_GRAPHICS,                                        // VkPipelineBindPoint                  pipelineBindPoint;
1198                         0u,                                                                                                     // deUint32                                             inputCount;
1199                         DE_NULL,                                                                                        // constVkAttachmentReference*  pInputAttachments;
1200                         1u,                                                                                                     // deUint32                                             colorCount;
1201                         &attachmentReference,                                                           // constVkAttachmentReference*  pColorAttachments;
1202                         DE_NULL,                                                                                        // constVkAttachmentReference*  pResolveAttachments;
1203                         DE_NULL,                                                                                        // VkAttachmentReference                depthStencilAttachment;
1204                         0u,                                                                                                     // deUint32                                             preserveCount;
1205                         DE_NULL                                                                                         // constVkAttachmentReference*  pPreserveAttachments;
1206                 };
1207
1208                 const VkRenderPassCreateInfo                                    renderPassParams                        =
1209                 {
1210                         VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,                      // VkStructureType                                      sType;
1211                         DE_NULL,                                                                                        // const void*                                          pNext;
1212                         (VkRenderPassCreateFlags)0,
1213                         1u,                                                                                                     // deUint32                                                     attachmentCount;
1214                         &attachmentDescription,                                                         // const VkAttachmentDescription*       pAttachments;
1215                         1u,                                                                                                     // deUint32                                                     subpassCount;
1216                         &subpassDescription,                                                            // const VkSubpassDescription*          pSubpasses;
1217                         0u,                                                                                                     // deUint32                                                     dependencyCount;
1218                         DE_NULL                                                                                         // const VkSubpassDependency*           pDependencies;
1219                 };
1220
1221                 m_renderPass = createRenderPass(vk, vkDevice, &renderPassParams);
1222         }
1223
1224         // Create framebuffer
1225         {
1226                 const VkFramebufferCreateInfo                                   framebufferParams                       =
1227                 {
1228                         VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,                      // VkStructureType                              sType;
1229                         DE_NULL,                                                                                        // const void*                                  pNext;
1230                         (VkFramebufferCreateFlags)0,
1231                         *m_renderPass,                                                                          // VkRenderPass                                 renderPass;
1232                         1u,                                                                                                     // deUint32                                             attachmentCount;
1233                         &*m_colorImageView,                                                                     // const VkImageView*                   pAttachments;
1234                         (deUint32)m_renderSize.x(),                                                     // deUint32                                             width;
1235                         (deUint32)m_renderSize.y(),                                                     // deUint32                                             height;
1236                         1u                                                                                                      // deUint32                                             layers;
1237                 };
1238
1239                 m_framebuffer = createFramebuffer(vk, vkDevice, &framebufferParams);
1240         }
1241
1242         // Create descriptors
1243         {
1244                 setupUniforms(quadGrid.getConstCoords());
1245
1246                 m_descriptorSetLayout = m_descriptorSetLayoutBuilder.build(vk, vkDevice);
1247                 if (!m_uniformInfos.empty())
1248                 {
1249                         m_descriptorPool                                                                = m_descriptorPoolBuilder.build(vk, vkDevice, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u);
1250                         const VkDescriptorSetAllocateInfo       allocInfo       =
1251                         {
1252                                 VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
1253                                 DE_NULL,
1254                                 *m_descriptorPool,
1255                                 1u,
1256                                 &m_descriptorSetLayout.get(),
1257                         };
1258
1259                         m_descriptorSet = allocateDescriptorSet(vk, vkDevice, &allocInfo);
1260                 }
1261
1262                 for (deUint32 i = 0; i < m_uniformInfos.size(); i++)
1263                 {
1264                         const UniformInfo* uniformInfo = m_uniformInfos[i].get()->get();
1265                         deUint32 location = uniformInfo->location;
1266
1267                         if (uniformInfo->type == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER)
1268                         {
1269                                 const BufferUniform*    bufferInfo      = dynamic_cast<const BufferUniform*>(uniformInfo);
1270
1271                                 m_descriptorSetUpdateBuilder.writeSingle(*m_descriptorSet, DescriptorSetUpdateBuilder::Location::binding(location), uniformInfo->type, &bufferInfo->descriptor);
1272                         }
1273                         else if (uniformInfo->type == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER)
1274                         {
1275                                 const SamplerUniform*   samplerInfo     = dynamic_cast<const SamplerUniform*>(uniformInfo);
1276
1277                                 m_descriptorSetUpdateBuilder.writeSingle(*m_descriptorSet, DescriptorSetUpdateBuilder::Location::binding(location), uniformInfo->type, &samplerInfo->descriptor);
1278                         }
1279                         else
1280                                 DE_FATAL("Impossible");
1281                 }
1282
1283                 m_descriptorSetUpdateBuilder.update(vk, vkDevice);
1284         }
1285
1286         // Create pipeline layout
1287         {
1288                 const VkPipelineLayoutCreateInfo                                pipelineLayoutParams            =
1289                 {
1290                         VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,          // VkStructureType                              sType;
1291                         DE_NULL,                                                                                        // const void*                                  pNext;
1292                         (VkPipelineLayoutCreateFlags)0,
1293                         1u,                                                                                                     // deUint32                                             descriptorSetCount;
1294                         &*m_descriptorSetLayout,                                                        // const VkDescriptorSetLayout* pSetLayouts;
1295                         0u,                                                                                                     // deUint32                                             pushConstantRangeCount;
1296                         DE_NULL                                                                                         // const VkPushConstantRange*   pPushConstantRanges;
1297                 };
1298
1299                 m_pipelineLayout = createPipelineLayout(vk, vkDevice, &pipelineLayoutParams);
1300         }
1301
1302         // Create shaders
1303         {
1304                 m_vertexShaderModule    = createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("vert"), 0);
1305                 m_fragmentShaderModule  = createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("frag"), 0);
1306         }
1307
1308         // Create pipeline
1309         {
1310                 const VkPipelineShaderStageCreateInfo                   shaderStageParams[2]            =
1311                 {
1312                         {
1313                                 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,            // VkStructureType                              sType;
1314                                 DE_NULL,                                                                                                        // const void*                                  pNext;
1315                                 (VkPipelineShaderStageCreateFlags)0,
1316                                 VK_SHADER_STAGE_VERTEX_BIT,                                                                     // VkShaderStage                                stage;
1317                                 *m_vertexShaderModule,                                                                          // VkShader                                             shader;
1318                                 "main",
1319                                 DE_NULL                                                                                                         // const VkSpecializationInfo*  pSpecializationInfo;
1320                         },
1321                         {
1322                                 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,            // VkStructureType                              sType;
1323                                 DE_NULL,                                                                                                        // const void*                                  pNext;
1324                                 (VkPipelineShaderStageCreateFlags)0,
1325                                 VK_SHADER_STAGE_FRAGMENT_BIT,                                                           // VkShaderStage                                stage;
1326                                 *m_fragmentShaderModule,                                                                        // VkShader                                             shader;
1327                                 "main",
1328                                 DE_NULL                                                                                                         // const VkSpecializationInfo*  pSpecializationInfo;
1329                         }
1330                 };
1331
1332                 // Add test case specific attributes
1333                 if (m_attribFunc)
1334                         m_attribFunc(*this, quadGrid.getNumVertices());
1335
1336                 // Add base attributes
1337                 setupDefaultInputs(quadGrid);
1338
1339                 const VkPipelineVertexInputStateCreateInfo              vertexInputStateParams          =
1340                 {
1341                         VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,              // VkStructureType                                                      sType;
1342                         DE_NULL,                                                                                                                // const void*                                                          pNext;
1343                         (VkPipelineVertexInputStateCreateFlags)0,
1344                         (deUint32)m_vertexBindingDescription.size(),                                    // deUint32                                                                     bindingCount;
1345                         &m_vertexBindingDescription[0],                                                                 // const VkVertexInputBindingDescription*       pVertexBindingDescriptions;
1346                         (deUint32)m_vertexattributeDescription.size(),                                  // deUint32                                                                     attributeCount;
1347                         &m_vertexattributeDescription[0],                                                               // const VkVertexInputAttributeDescription*     pVertexAttributeDescriptions;
1348                 };
1349
1350                 const VkPipelineInputAssemblyStateCreateInfo    inputAssemblyStateParams        =
1351                 {
1352                         VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,    // VkStructureType              sType;
1353                         DE_NULL,                                                                                                                // const void*                  pNext;
1354                         (VkPipelineInputAssemblyStateCreateFlags)0,
1355                         VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST,                                                    // VkPrimitiveTopology  topology;
1356                         false                                                                                                                   // VkBool32                             primitiveRestartEnable;
1357                 };
1358
1359                 const VkViewport                                                                viewport                                        =
1360                 {
1361                         0.0f,                                           // float        originX;
1362                         0.0f,                                           // float        originY;
1363                         (float)m_renderSize.x(),        // float        width;
1364                         (float)m_renderSize.y(),        // float        height;
1365                         0.0f,                                           // float        minDepth;
1366                         1.0f                                            // float        maxDepth;
1367                 };
1368
1369                 const VkRect2D                                                                  scissor                                         =
1370                 {
1371                         {
1372                                 0u,                                     // deUint32     x;
1373                                 0u,                                     // deUint32     y;
1374                         },                                                      // VkOffset2D   offset;
1375                         {
1376                                 m_renderSize.x(),       // deUint32     width;
1377                                 m_renderSize.y(),       // deUint32     height;
1378                         },                                                      // VkExtent2D   extent;
1379                 };
1380
1381                 const VkPipelineViewportStateCreateInfo                 viewportStateParams                     =
1382                 {
1383                         VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO,                  // VkStructureType              sType;
1384                         DE_NULL,                                                                                                                // const void*                  pNext;
1385                         (VkPipelineViewportStateCreateFlags)0,
1386                         1u,                                                                                                                             // deUint32                             viewportCount;
1387                         &viewport,                                                                                                              // const VkViewport*    pViewports;
1388                         1u,                                                                                                                             // deUint32                             scissorsCount;
1389                         &scissor,                                                                                                               // const VkRect2D*              pScissors;
1390                 };
1391
1392                 const VkPipelineRasterizationStateCreateInfo    rasterStateParams                       =
1393                 {
1394                         VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO,             // VkStructureType      sType;
1395                         DE_NULL,                                                                                                                // const void*          pNext;
1396                         (VkPipelineRasterizationStateCreateFlags)0,
1397                         false,                                                                                                                  // VkBool32                     depthClipEnable;
1398                         false,                                                                                                                  // VkBool32                     rasterizerDiscardEnable;
1399                         VK_POLYGON_MODE_FILL,                                                                                   // VkFillMode           fillMode;
1400                         VK_CULL_MODE_NONE,                                                                                              // VkCullMode           cullMode;
1401                         VK_FRONT_FACE_COUNTER_CLOCKWISE,                                                                // VkFrontFace          frontFace;
1402                         false,                                                                                                                  // VkBool32                     depthBiasEnable;
1403                         0.0f,                                                                                                                   // float                        depthBias;
1404                         0.0f,                                                                                                                   // float                        depthBiasClamp;
1405                         0.0f,                                                                                                                   // float                        slopeScaledDepthBias;
1406                         1.0f,                                                                                                                   // float                        lineWidth;
1407                 };
1408
1409                 const VkPipelineMultisampleStateCreateInfo              multisampleStateParams =
1410                 {
1411                         VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,               // VkStructureType                                                      sType;
1412                         DE_NULL,                                                                                                                // const void*                                                          pNext;
1413                         0u,                                                                                                                             // VkPipelineMultisampleStateCreateFlags        flags;
1414                         VK_SAMPLE_COUNT_1_BIT,                                                                                  // VkSampleCountFlagBits                                        rasterizationSamples;
1415                         VK_FALSE,                                                                                                               // VkBool32                                                                     sampleShadingEnable;
1416                         0.0f,                                                                                                                   // float                                                                        minSampleShading;
1417                         DE_NULL,                                                                                                                // const VkSampleMask*                                          pSampleMask;
1418                         VK_FALSE,                                                                                                               // VkBool32                                                                     alphaToCoverageEnable;
1419                         VK_FALSE                                                                                                                // VkBool32                                                                     alphaToOneEnable;
1420                 };
1421
1422                 const VkPipelineColorBlendAttachmentState               colorBlendAttachmentState       =
1423                 {
1424                         false,                                                                                                                  // VkBool32                     blendEnable;
1425                         VK_BLEND_FACTOR_ONE,                                                                                    // VkBlend                      srcBlendColor;
1426                         VK_BLEND_FACTOR_ZERO,                                                                                   // VkBlend                      destBlendColor;
1427                         VK_BLEND_OP_ADD,                                                                                                // VkBlendOp            blendOpColor;
1428                         VK_BLEND_FACTOR_ONE,                                                                                    // VkBlend                      srcBlendAlpha;
1429                         VK_BLEND_FACTOR_ZERO,                                                                                   // VkBlend                      destBlendAlpha;
1430                         VK_BLEND_OP_ADD,                                                                                                // VkBlendOp            blendOpAlpha;
1431                         (VK_COLOR_COMPONENT_R_BIT |
1432                          VK_COLOR_COMPONENT_G_BIT |
1433                          VK_COLOR_COMPONENT_B_BIT |
1434                          VK_COLOR_COMPONENT_A_BIT),                                                                             // VkChannelFlags       channelWriteMask;
1435                 };
1436
1437                 const VkPipelineColorBlendStateCreateInfo               colorBlendStateParams           =
1438                 {
1439                         VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,       // VkStructureType                                                              sType;
1440                         DE_NULL,                                                                                                        // const void*                                                                  pNext;
1441                         (VkPipelineColorBlendStateCreateFlags)0,
1442                         false,                                                                                                          // VkBool32                                                                             logicOpEnable;
1443                         VK_LOGIC_OP_COPY,                                                                                       // VkLogicOp                                                                    logicOp;
1444                         1u,                                                                                                                     // deUint32                                                                             attachmentCount;
1445                         &colorBlendAttachmentState,                                                                     // const VkPipelineColorBlendAttachmentState*   pAttachments;
1446                         { 0.0f, 0.0f, 0.0f, 0.0f },                                                                     // float                                                                                blendConst[4];
1447                 };
1448
1449                 const VkPipelineDynamicStateCreateInfo                  dynamicStateInfo                        =
1450                 {
1451                         VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO,           // VkStructureType                              sType;
1452                         DE_NULL,                                                                                                        // const void*                                  pNext;
1453                         (VkPipelineDynamicStateCreateFlags)0,
1454                         0u,                                                                                                                     // deUint32                                             dynamicStateCount;
1455                         DE_NULL                                                                                                         // const VkDynamicState*                pDynamicStates;
1456                 };
1457
1458                 const VkGraphicsPipelineCreateInfo                              graphicsPipelineParams          =
1459                 {
1460                         VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,        // VkStructureType                                                                      sType;
1461                         DE_NULL,                                                                                        // const void*                                                                          pNext;
1462                         0u,                                                                                                     // VkPipelineCreateFlags                                                        flags;
1463                         2u,                                                                                                     // deUint32                                                                                     stageCount;
1464                         shaderStageParams,                                                                      // const VkPipelineShaderStageCreateInfo*                       pStages;
1465                         &vertexInputStateParams,                                                        // const VkPipelineVertexInputStateCreateInfo*          pVertexInputState;
1466                         &inputAssemblyStateParams,                                                      // const VkPipelineInputAssemblyStateCreateInfo*        pInputAssemblyState;
1467                         DE_NULL,                                                                                        // const VkPipelineTessellationStateCreateInfo*         pTessellationState;
1468                         &viewportStateParams,                                                           // const VkPipelineViewportStateCreateInfo*                     pViewportState;
1469                         &rasterStateParams,                                                                     // const VkPipelineRasterStateCreateInfo*                       pRasterState;
1470                         &multisampleStateParams,                                                        // const VkPipelineMultisampleStateCreateInfo*          pMultisampleState;
1471                         DE_NULL,                                                                                        // const VkPipelineDepthStencilStateCreateInfo*         pDepthStencilState;
1472                         &colorBlendStateParams,                                                         // const VkPipelineColorBlendStateCreateInfo*           pColorBlendState;
1473                         &dynamicStateInfo,                                                                      // const VkPipelineDynamicStateCreateInfo*                      pDynamicState;
1474                         *m_pipelineLayout,                                                                      // VkPipelineLayout                                                                     layout;
1475                         *m_renderPass,                                                                          // VkRenderPass                                                                         renderPass;
1476                         0u,                                                                                                     // deUint32                                                                                     subpass;
1477                         0u,                                                                                                     // VkPipeline                                                                           basePipelineHandle;
1478                         0u                                                                                                      // deInt32                                                                                      basePipelineIndex;
1479                 };
1480
1481                 m_graphicsPipeline = createGraphicsPipeline(vk, vkDevice, DE_NULL, &graphicsPipelineParams);
1482         }
1483
1484         // Create vertex indices buffer
1485         {
1486                 const VkDeviceSize                                                              indiceBufferSize                        = quadGrid.getNumTriangles() * 3 * sizeof(deUint16);
1487                 const VkBufferCreateInfo                                                indiceBufferParams                      =
1488                 {
1489                         VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,           // VkStructureType              sType;
1490                         DE_NULL,                                                                        // const void*                  pNext;
1491                         0u,                                                                                     // VkBufferCreateFlags  flags;
1492                         indiceBufferSize,                                                       // VkDeviceSize                 size;
1493                         VK_BUFFER_USAGE_INDEX_BUFFER_BIT,                       // VkBufferUsageFlags   usage;
1494                         VK_SHARING_MODE_EXCLUSIVE,                                      // VkSharingMode                sharingMode;
1495                         1u,                                                                                     // deUint32                             queueFamilyCount;
1496                         &queueFamilyIndex                                                       // const deUint32*              pQueueFamilyIndices;
1497                 };
1498
1499                 m_indiceBuffer          = createBuffer(vk, vkDevice, &indiceBufferParams);
1500                 m_indiceBufferAlloc     = m_memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *m_indiceBuffer), MemoryRequirement::HostVisible);
1501
1502                 VK_CHECK(vk.bindBufferMemory(vkDevice, *m_indiceBuffer, m_indiceBufferAlloc->getMemory(), m_indiceBufferAlloc->getOffset()));
1503
1504                 // Load vertice indices into buffer
1505                 deMemcpy(m_indiceBufferAlloc->getHostPtr(), quadGrid.getIndices(), (size_t)indiceBufferSize);
1506                 flushMappedMemoryRange(vk, vkDevice, m_indiceBufferAlloc->getMemory(), m_indiceBufferAlloc->getOffset(), indiceBufferSize);
1507         }
1508
1509         // Create command pool
1510         {
1511                 const VkCommandPoolCreateInfo                                   cmdPoolParams                           =
1512                 {
1513                         VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,             // VkStructureType              sType;
1514                         DE_NULL,                                                                                // const void*                  pNext;
1515                         VK_COMMAND_POOL_CREATE_TRANSIENT_BIT,                   // VkCmdPoolCreateFlags flags;
1516                         queueFamilyIndex,                                                               // deUint32                             queueFamilyIndex;
1517                 };
1518
1519                 m_cmdPool = createCommandPool(vk, vkDevice, &cmdPoolParams);
1520         }
1521
1522         // Create command buffer
1523         {
1524                 const VkCommandBufferAllocateInfo                               cmdBufferParams                         =
1525                 {
1526                         VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, // VkStructureType                      sType;
1527                         DE_NULL,                                                                                // const void*                          pNext;
1528                         *m_cmdPool,                                                                             // VkCmdPool                            cmdPool;
1529                         VK_COMMAND_BUFFER_LEVEL_PRIMARY,                                // VkCmdBufferLevel                     level;
1530                         1u                                                                                              // deUint32                                     bufferCount;
1531                 };
1532
1533                 const VkCommandBufferBeginInfo                                  cmdBufferBeginInfo                      =
1534                 {
1535                         VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,    // VkStructureType                      sType;
1536                         DE_NULL,                                                                                // const void*                          pNext;
1537                         0u,                                                                                             // VkCmdBufferOptimizeFlags     flags;
1538                         (const VkCommandBufferInheritanceInfo*)DE_NULL,
1539                 };
1540
1541                 const VkClearValue                                                              clearValues                                     = makeClearValueColorF32(m_clearColor.x(),
1542                                                                                                                                                                                                                          m_clearColor.y(),
1543                                                                                                                                                                                                                          m_clearColor.z(),
1544                                                                                                                                                                                                                          m_clearColor.w());
1545
1546                 const VkRenderPassBeginInfo                                             renderPassBeginInfo                     =
1547                 {
1548                         VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,                               // VkStructureType              sType;
1549                         DE_NULL,                                                                                                // const void*                  pNext;
1550                         *m_renderPass,                                                                                  // VkRenderPass                 renderPass;
1551                         *m_framebuffer,                                                                                 // VkFramebuffer                framebuffer;
1552                         { { 0, 0 },  {m_renderSize.x(), m_renderSize.y() } },   // VkRect2D                             renderArea;
1553                         1,                                                                                                              // deUint32                             clearValueCount;
1554                         &clearValues,                                                                                   // const VkClearValue*  pClearValues;
1555                 };
1556
1557                 m_cmdBuffer = allocateCommandBuffer(vk, vkDevice, &cmdBufferParams);
1558
1559                 VK_CHECK(vk.beginCommandBuffer(*m_cmdBuffer, &cmdBufferBeginInfo));
1560
1561                 // Add texture barriers
1562                 std::vector<VkImageMemoryBarrier> barriers;
1563
1564                 for(deUint32 i = 0; i < m_uniformInfos.size(); i++)
1565                 {
1566                         const UniformInfo* uniformInfo = m_uniformInfos[i].get()->get();
1567
1568                         if (uniformInfo->type != VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER)
1569                         {
1570                                 continue;
1571                         }
1572
1573                         const SamplerUniform*           sampler                 = static_cast<const SamplerUniform*>(uniformInfo);
1574
1575                         const VkAccessFlags                     outputMask              = VK_ACCESS_HOST_WRITE_BIT | VK_ACCESS_TRANSFER_WRITE_BIT;
1576                         const VkImageMemoryBarrier      textureBarrier  = createImageMemoryBarrier(sampler->image->get(), outputMask, 0u, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
1577
1578                         barriers.push_back(textureBarrier);
1579                 }
1580
1581                 vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, (VkDependencyFlags)0,
1582                                                           0, (const VkMemoryBarrier*)DE_NULL,
1583                                                           0, (const VkBufferMemoryBarrier*)DE_NULL,
1584                                                           (deUint32)barriers.size(), (barriers.empty() ? (const VkImageMemoryBarrier*)DE_NULL : &barriers[0]));
1585
1586                 vk.cmdBeginRenderPass(*m_cmdBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
1587
1588                 vk.cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_graphicsPipeline);
1589                 if (!m_uniformInfos.empty())
1590                         vk.cmdBindDescriptorSets(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipelineLayout, 0u, 1, &*m_descriptorSet, 0u, DE_NULL);
1591                 vk.cmdBindIndexBuffer(*m_cmdBuffer, *m_indiceBuffer, 0, VK_INDEX_TYPE_UINT16);
1592
1593                 const deUint32 numberOfVertexAttributes = (deUint32)m_vertexBuffers.size();
1594                 const std::vector<VkDeviceSize> offsets(numberOfVertexAttributes, 0);
1595
1596                 std::vector<VkBuffer> buffers(numberOfVertexAttributes);
1597                 for (size_t i = 0; i < numberOfVertexAttributes; i++)
1598                 {
1599                         buffers[i] = m_vertexBuffers[i].get()->get();
1600                 }
1601
1602                 vk.cmdBindVertexBuffers(*m_cmdBuffer, 0, numberOfVertexAttributes, &buffers[0], &offsets[0]);
1603                 vk.cmdDrawIndexed(*m_cmdBuffer, quadGrid.getNumTriangles() * 3, 1, 0, 0, 0);
1604
1605                 vk.cmdEndRenderPass(*m_cmdBuffer);
1606                 VK_CHECK(vk.endCommandBuffer(*m_cmdBuffer));
1607         }
1608
1609         // Create fence
1610         {
1611                 const VkFenceCreateInfo                                                 fenceParams                                     =
1612                 {
1613                         VK_STRUCTURE_TYPE_FENCE_CREATE_INFO,    // VkStructureType              sType;
1614                         DE_NULL,                                                                // const void*                  pNext;
1615                         0u                                                                              // VkFenceCreateFlags   flags;
1616                 };
1617                 m_fence = createFence(vk, vkDevice, &fenceParams);
1618         }
1619
1620         // Execute Draw
1621         {
1622                 const VkSubmitInfo      submitInfo      =
1623                 {
1624                         VK_STRUCTURE_TYPE_SUBMIT_INFO,
1625                         DE_NULL,
1626                         0u,
1627                         (const VkSemaphore*)DE_NULL,
1628                         (const VkPipelineStageFlags*)DE_NULL,
1629                         1u,
1630                         &m_cmdBuffer.get(),
1631                         0u,
1632                         (const VkSemaphore*)DE_NULL,
1633                 };
1634
1635                 VK_CHECK(vk.resetFences(vkDevice, 1, &m_fence.get()));
1636                 VK_CHECK(vk.queueSubmit(queue, 1, &submitInfo, *m_fence));
1637                 VK_CHECK(vk.waitForFences(vkDevice, 1, &m_fence.get(), true, ~(0ull) /* infinity*/));
1638         }
1639
1640         // Read back the result
1641         {
1642                 const VkDeviceSize                                                              imageSizeBytes                          = (VkDeviceSize)(sizeof(deUint32) * m_renderSize.x() * m_renderSize.y());
1643                 const VkBufferCreateInfo                                                readImageBufferParams           =
1644                 {
1645                         VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,           //  VkStructureType             sType;
1646                         DE_NULL,                                                                        //  const void*                 pNext;
1647                         0u,                                                                                     //  VkBufferCreateFlags flags;
1648                         imageSizeBytes,                                                         //  VkDeviceSize                size;
1649                         VK_BUFFER_USAGE_TRANSFER_DST_BIT,                       //  VkBufferUsageFlags  usage;
1650                         VK_SHARING_MODE_EXCLUSIVE,                                      //  VkSharingMode               sharingMode;
1651                         1u,                                                                                     //  deUint32                    queueFamilyCount;
1652                         &queueFamilyIndex,                                                      //  const deUint32*             pQueueFamilyIndices;
1653                 };
1654                 const Unique<VkBuffer>                                                  readImageBuffer                         (createBuffer(vk, vkDevice, &readImageBufferParams));
1655                 const de::UniquePtr<Allocation>                                 readImageBufferMemory           (m_memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *readImageBuffer), MemoryRequirement::HostVisible));
1656
1657                 VK_CHECK(vk.bindBufferMemory(vkDevice, *readImageBuffer, readImageBufferMemory->getMemory(), readImageBufferMemory->getOffset()));
1658
1659                 // Copy image to buffer
1660                 const VkCommandBufferAllocateInfo                               cmdBufferParams                         =
1661                 {
1662                         VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, // VkStructureType                      sType;
1663                         DE_NULL,                                                                                // const void*                          pNext;
1664                         *m_cmdPool,                                                                             // VkCmdPool                            cmdPool;
1665                         VK_COMMAND_BUFFER_LEVEL_PRIMARY,                                // VkCmdBufferLevel                     level;
1666                         1u                                                                                              // deUint32                                     bufferCount;
1667                 };
1668
1669                 const VkCommandBufferBeginInfo                                  cmdBufferBeginInfo                      =
1670                 {
1671                         VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,    // VkStructureType                      sType;
1672                         DE_NULL,                                                                                // const void*                          pNext;
1673                         0u,                                                                                             // VkCmdBufferOptimizeFlags     flags;
1674                         (const VkCommandBufferInheritanceInfo*)DE_NULL,
1675                 };
1676
1677                 const Move<VkCommandBuffer>                                             cmdBuffer                                       = allocateCommandBuffer(vk, vkDevice, &cmdBufferParams);
1678
1679                 const VkBufferImageCopy                                                 copyParams                                      =
1680                 {
1681                         0u,                                                                                     // VkDeviceSize                 bufferOffset;
1682                         (deUint32)m_renderSize.x(),                                     // deUint32                             bufferRowLength;
1683                         (deUint32)m_renderSize.y(),                                     // deUint32                             bufferImageHeight;
1684                         {
1685                                 VK_IMAGE_ASPECT_COLOR_BIT,                      // VkImageAspect                aspect;
1686                                 0u,                                                                     // deUint32                             mipLevel;
1687                                 0u,                                                                     // deUint32                             arraySlice;
1688                                 1u,                                                                     // deUint32                             arraySize;
1689                         },                                                                                      // VkImageSubresourceCopy       imageSubresource;
1690                         { 0u, 0u, 0u },                                                         // VkOffset3D                   imageOffset;
1691                         { m_renderSize.x(), m_renderSize.y(), 1u }      // VkExtent3D                   imageExtent;
1692                 };
1693                 const VkSubmitInfo                                                              submitInfo                                      =
1694                 {
1695                         VK_STRUCTURE_TYPE_SUBMIT_INFO,
1696                         DE_NULL,
1697                         0u,
1698                         (const VkSemaphore*)DE_NULL,
1699                         (const VkPipelineStageFlags*)DE_NULL,
1700                         1u,
1701                         &cmdBuffer.get(),
1702                         0u,
1703                         (const VkSemaphore*)DE_NULL,
1704                 };
1705
1706                 VK_CHECK(vk.beginCommandBuffer(*cmdBuffer, &cmdBufferBeginInfo));
1707                 vk.cmdCopyImageToBuffer(*cmdBuffer, *m_colorImage, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *readImageBuffer, 1u, &copyParams);
1708                 VK_CHECK(vk.endCommandBuffer(*cmdBuffer));
1709
1710                 VK_CHECK(vk.resetFences(vkDevice, 1, &m_fence.get()));
1711                 VK_CHECK(vk.queueSubmit(queue, 1, &submitInfo, *m_fence));
1712                 VK_CHECK(vk.waitForFences(vkDevice, 1, &m_fence.get(), true, ~(0ull) /* infinity */));
1713
1714                 invalidateMappedMemoryRange(vk, vkDevice, readImageBufferMemory->getMemory(), readImageBufferMemory->getOffset(), imageSizeBytes);
1715
1716                 const tcu::TextureFormat                                                resultFormat                            (tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8);
1717                 const tcu::ConstPixelBufferAccess                               resultAccess                            (resultFormat, m_renderSize.x(), m_renderSize.y(), 1, readImageBufferMemory->getHostPtr());
1718
1719                 tcu::copy(result.getAccess(), resultAccess);
1720         }
1721 }
1722
1723 void ShaderRenderCaseInstance::computeVertexReference (tcu::Surface& result, const QuadGrid& quadGrid)
1724 {
1725         // Buffer info.
1726         const int                               width           = result.getWidth();
1727         const int                               height          = result.getHeight();
1728         const int                               gridSize        = quadGrid.getGridSize();
1729         const int                               stride          = gridSize + 1;
1730         const bool                              hasAlpha        = true; // \todo [2015-09-07 elecro] add correct alpha check
1731         ShaderEvalContext               evalCtx         (quadGrid);
1732
1733         // Evaluate color for each vertex.
1734         std::vector<tcu::Vec4>  colors          ((gridSize + 1) * (gridSize + 1));
1735         for (int y = 0; y < gridSize+1; y++)
1736         for (int x = 0; x < gridSize+1; x++)
1737         {
1738                 const float     sx                      = (float)x / (float)gridSize;
1739                 const float     sy                      = (float)y / (float)gridSize;
1740                 const int       vtxNdx          = ((y * (gridSize+1)) + x);
1741
1742                 evalCtx.reset(sx, sy);
1743                 m_evaluator.evaluate(evalCtx);
1744                 DE_ASSERT(!evalCtx.isDiscarded); // Discard is not available in vertex shader.
1745                 tcu::Vec4 color = evalCtx.color;
1746
1747                 if (!hasAlpha)
1748                         color.w() = 1.0f;
1749
1750                 colors[vtxNdx] = color;
1751         }
1752
1753         // Render quads.
1754         for (int y = 0; y < gridSize; y++)
1755         for (int x = 0; x < gridSize; x++)
1756         {
1757                 const float             x0              = (float)x       / (float)gridSize;
1758                 const float             x1              = (float)(x + 1) / (float)gridSize;
1759                 const float             y0              = (float)y       / (float)gridSize;
1760                 const float             y1              = (float)(y + 1) / (float)gridSize;
1761
1762                 const float             sx0             = x0 * (float)width;
1763                 const float             sx1             = x1 * (float)width;
1764                 const float             sy0             = y0 * (float)height;
1765                 const float             sy1             = y1 * (float)height;
1766                 const float             oosx    = 1.0f / (sx1 - sx0);
1767                 const float             oosy    = 1.0f / (sy1 - sy0);
1768
1769                 const int               ix0             = deCeilFloatToInt32(sx0 - 0.5f);
1770                 const int               ix1             = deCeilFloatToInt32(sx1 - 0.5f);
1771                 const int               iy0             = deCeilFloatToInt32(sy0 - 0.5f);
1772                 const int               iy1             = deCeilFloatToInt32(sy1 - 0.5f);
1773
1774                 const int               v00             = (y * stride) + x;
1775                 const int               v01             = (y * stride) + x + 1;
1776                 const int               v10             = ((y + 1) * stride) + x;
1777                 const int               v11             = ((y + 1) * stride) + x + 1;
1778                 const tcu::Vec4 c00             = colors[v00];
1779                 const tcu::Vec4 c01             = colors[v01];
1780                 const tcu::Vec4 c10             = colors[v10];
1781                 const tcu::Vec4 c11             = colors[v11];
1782
1783                 //printf("(%d,%d) -> (%f..%f, %f..%f) (%d..%d, %d..%d)\n", x, y, sx0, sx1, sy0, sy1, ix0, ix1, iy0, iy1);
1784
1785                 for (int iy = iy0; iy < iy1; iy++)
1786                 for (int ix = ix0; ix < ix1; ix++)
1787                 {
1788                         DE_ASSERT(deInBounds32(ix, 0, width));
1789                         DE_ASSERT(deInBounds32(iy, 0, height));
1790
1791                         const float                     sfx             = (float)ix + 0.5f;
1792                         const float                     sfy             = (float)iy + 0.5f;
1793                         const float                     fx1             = deFloatClamp((sfx - sx0) * oosx, 0.0f, 1.0f);
1794                         const float                     fy1             = deFloatClamp((sfy - sy0) * oosy, 0.0f, 1.0f);
1795
1796                         // Triangle quad interpolation.
1797                         const bool                      tri             = fx1 + fy1 <= 1.0f;
1798                         const float                     tx              = tri ? fx1 : (1.0f-fx1);
1799                         const float                     ty              = tri ? fy1 : (1.0f-fy1);
1800                         const tcu::Vec4&        t0              = tri ? c00 : c11;
1801                         const tcu::Vec4&        t1              = tri ? c01 : c10;
1802                         const tcu::Vec4&        t2              = tri ? c10 : c01;
1803                         const tcu::Vec4         color   = t0 + (t1-t0)*tx + (t2-t0)*ty;
1804
1805                         result.setPixel(ix, iy, tcu::RGBA(color));
1806                 }
1807         }
1808 }
1809
1810 void ShaderRenderCaseInstance::computeFragmentReference (tcu::Surface& result, const QuadGrid& quadGrid)
1811 {
1812         // Buffer info.
1813         const int                       width           = result.getWidth();
1814         const int                       height          = result.getHeight();
1815         const bool                      hasAlpha        = true;  // \todo [2015-09-07 elecro] add correct alpha check
1816         ShaderEvalContext       evalCtx         (quadGrid);
1817
1818         // Render.
1819         for (int y = 0; y < height; y++)
1820         for (int x = 0; x < width; x++)
1821         {
1822                 const float sx = ((float)x + 0.5f) / (float)width;
1823                 const float sy = ((float)y + 0.5f) / (float)height;
1824
1825                 evalCtx.reset(sx, sy);
1826                 m_evaluator.evaluate(evalCtx);
1827                 // Select either clear color or computed color based on discarded bit.
1828                 tcu::Vec4 color = evalCtx.isDiscarded ? m_clearColor : evalCtx.color;
1829
1830                 if (!hasAlpha)
1831                         color.w() = 1.0f;
1832
1833                 result.setPixel(x, y, tcu::RGBA(color));
1834         }
1835 }
1836
1837 bool ShaderRenderCaseInstance::compareImages (const tcu::Surface& resImage, const tcu::Surface& refImage, float errorThreshold)
1838 {
1839         return tcu::fuzzyCompare(m_context.getTestContext().getLog(), "ComparisonResult", "Image comparison result", refImage, resImage, errorThreshold, tcu::COMPARE_LOG_RESULT);
1840 }
1841
1842 } // sr
1843 } // vkt