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