Merge branch 'jekstrand_renderpass_transfer_bit_fix' into 'master'
[platform/upstream/VK-GL-CTS.git] / external / vulkancts / modules / vulkan / pipeline / vktPipelineTimestampTests.cpp
1 /*------------------------------------------------------------------------
2  * Vulkan Conformance Tests
3  * ------------------------
4  *
5  * Copyright (c) 2015 The Khronos Group Inc.
6  * Copyright (c) 2015 ARM Ltd.
7  *
8  * Permission is hereby granted, free of charge, to any person obtaining a
9  * copy of this software and/or associated documentation files (the
10  * "Materials"), to deal in the Materials without restriction, including
11  * without limitation the rights to use, copy, modify, merge, publish,
12  * distribute, sublicense, and/or sell copies of the Materials, and to
13  * permit persons to whom the Materials are furnished to do so, subject to
14  * the following conditions:
15  *
16  * The above copyright notice(s) and this permission notice shall be included
17  * in all copies or substantial portions of the Materials.
18  *
19  * The Materials are Confidential Information as defined by the
20  * Khronos Membership Agreement until designated non-confidential by Khronos,
21  * at which point this condition clause shall be removed.
22  *
23  * THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
24  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
25  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
26  * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
27  * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
28  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
29  * MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
30  *
31  *//*!
32  * \file
33  * \brief Timestamp Tests
34  *//*--------------------------------------------------------------------*/
35
36 #include "vktPipelineTimestampTests.hpp"
37 #include "vktPipelineClearUtil.hpp"
38 #include "vktPipelineImageUtil.hpp"
39 #include "vktPipelineVertexUtil.hpp"
40 #include "vktPipelineReferenceRenderer.hpp"
41 #include "vktTestCase.hpp"
42 #include "vktTestCaseUtil.hpp"
43 #include "vkImageUtil.hpp"
44 #include "vkMemUtil.hpp"
45 #include "vkPrograms.hpp"
46 #include "vkBuilderUtil.hpp"
47 #include "vkQueryUtil.hpp"
48 #include "vkRef.hpp"
49 #include "vkRefUtil.hpp"
50 #include "tcuImageCompare.hpp"
51 #include "deUniquePtr.hpp"
52 #include "deStringUtil.hpp"
53 #include "deMemory.h"
54 #include "vkTypeUtil.hpp"
55
56 #include <sstream>
57 #include <vector>
58 #include <cctype>
59 #include <locale>
60
61 namespace vkt
62 {
63 namespace pipeline
64 {
65
66 using namespace vk;
67
68 namespace
69 {
70 typedef std::vector<VkPipelineStageFlagBits> StageFlagVector;
71
72 // helper functions
73 #define GEN_DESC_STRING(name,postfix)                                      \
74                 do {                                                               \
75                    for (std::string::size_type ndx = 0; ndx<strlen(#name); ++ndx)  \
76                          if(isDescription && #name[ndx] == '_')                        \
77                            desc << " ";                                                \
78                          else                                                          \
79                            desc << std::tolower(#name[ndx],loc);                       \
80                    if (isDescription)                                              \
81                          desc << " " << #postfix;                                      \
82                    else                                                            \
83                          desc << "_" << #postfix;                                      \
84                 } while (deGetFalse())
85
86 std::string getPipelineStageFlagStr (const VkPipelineStageFlagBits stage,
87                                                                          bool                          isDescription)
88 {
89         std::ostringstream desc;
90         std::locale loc;
91         switch(stage)
92         {
93 #define STAGE_CASE(p)                              \
94                 case VK_PIPELINE_STAGE_##p##_BIT:          \
95                 {                                          \
96                         GEN_DESC_STRING(p, stage);             \
97                         break;                                 \
98                 }
99                 STAGE_CASE(TOP_OF_PIPE);
100                 STAGE_CASE(DRAW_INDIRECT);
101                 STAGE_CASE(VERTEX_INPUT);
102                 STAGE_CASE(VERTEX_SHADER);
103                 STAGE_CASE(TESSELLATION_CONTROL_SHADER);
104                 STAGE_CASE(TESSELLATION_EVALUATION_SHADER);
105                 STAGE_CASE(GEOMETRY_SHADER);
106                 STAGE_CASE(FRAGMENT_SHADER);
107                 STAGE_CASE(EARLY_FRAGMENT_TESTS);
108                 STAGE_CASE(LATE_FRAGMENT_TESTS);
109                 STAGE_CASE(COLOR_ATTACHMENT_OUTPUT);
110                 STAGE_CASE(COMPUTE_SHADER);
111                 STAGE_CASE(TRANSFER);
112                 STAGE_CASE(HOST);
113                 STAGE_CASE(ALL_GRAPHICS);
114                 STAGE_CASE(ALL_COMMANDS);
115 #undef STAGE_CASE
116           default:
117                 desc << "unknown stage!";
118                 DE_FATAL("Unknown Stage!");
119                 break;
120         };
121
122         return desc.str();
123 }
124
125 enum TransferMethod
126 {
127         TRANSFER_METHOD_COPY_BUFFER = 0,
128         TRANSFER_METHOD_COPY_IMAGE,
129         TRANSFER_METHOD_BLIT_IMAGE,
130         TRANSFER_METHOD_COPY_BUFFER_TO_IMAGE,
131         TRANSFER_METHOD_COPY_IMAGE_TO_BUFFER,
132         TRANSFER_METHOD_UPDATE_BUFFER,
133         TRANSFER_METHOD_FILL_BUFFER,
134         TRANSFER_METHOD_CLEAR_COLOR_IMAGE,
135         TRANSFER_METHOD_CLEAR_DEPTH_STENCIL_IMAGE,
136         TRANSFER_METHOD_RESOLVE_IMAGE,
137         TRANSFER_METHOD_COPY_QUERY_POOL_RESULTS,
138         TRANSFER_METHOD_LAST
139 };
140
141 std::string getTransferMethodStr(const TransferMethod method,
142                                                                  bool                 isDescription)
143 {
144         std::ostringstream desc;
145         std::locale loc;
146         switch(method)
147         {
148 #define METHOD_CASE(p)                             \
149                 case TRANSFER_METHOD_##p:                  \
150                 {                                          \
151                         GEN_DESC_STRING(p, method);            \
152                         break;                                 \
153                 }
154           METHOD_CASE(COPY_BUFFER)
155           METHOD_CASE(COPY_IMAGE)
156           METHOD_CASE(BLIT_IMAGE)
157           METHOD_CASE(COPY_BUFFER_TO_IMAGE)
158           METHOD_CASE(COPY_IMAGE_TO_BUFFER)
159           METHOD_CASE(UPDATE_BUFFER)
160           METHOD_CASE(FILL_BUFFER)
161           METHOD_CASE(CLEAR_COLOR_IMAGE)
162           METHOD_CASE(CLEAR_DEPTH_STENCIL_IMAGE)
163           METHOD_CASE(RESOLVE_IMAGE)
164           METHOD_CASE(COPY_QUERY_POOL_RESULTS)
165 #undef METHOD_CASE
166           default:
167                 desc << "unknown method!";
168                 DE_FATAL("Unknown method!");
169                 break;
170         };
171
172         return desc.str();
173 }
174
175 // helper classes
176 class TimestampTestParam
177 {
178 public:
179                                                           TimestampTestParam      (const VkPipelineStageFlagBits* stages,
180                                                                                                            const deUint32                 stageCount,
181                                                                                                            const bool                     inRenderPass);
182                                                           ~TimestampTestParam     (void);
183         virtual const std::string generateTestName        (void) const;
184         virtual const std::string generateTestDescription (void) const;
185         StageFlagVector           getStageVector          (void) const { return m_stageVec; }
186         bool                      getInRenderPass         (void) const { return m_inRenderPass; }
187         void                      toggleInRenderPass      (void)       { m_inRenderPass = !m_inRenderPass; }
188 protected:
189         StageFlagVector           m_stageVec;
190         bool                      m_inRenderPass;
191 };
192
193 TimestampTestParam::TimestampTestParam(const VkPipelineStageFlagBits* stages,
194                                                                            const deUint32                 stageCount,
195                                                                            const bool                     inRenderPass)
196         : m_inRenderPass(inRenderPass)
197 {
198         for (deUint32 ndx = 0; ndx < stageCount; ndx++)
199         {
200                 m_stageVec.push_back(stages[ndx]);
201         }
202 }
203
204 TimestampTestParam::~TimestampTestParam(void)
205 {
206 }
207
208 const std::string TimestampTestParam::generateTestName(void) const
209 {
210         std::string result("");
211
212         for (StageFlagVector::const_iterator it = m_stageVec.begin(); it != m_stageVec.end(); it++)
213         {
214                 if(*it != VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT)
215                 {
216                         result += getPipelineStageFlagStr(*it, false) + '_';
217                 }
218         }
219         if(m_inRenderPass)
220                 result += "in_render_pass";
221         else
222                 result += "out_of_render_pass";
223
224         return result;
225 }
226
227 const std::string TimestampTestParam::generateTestDescription(void) const
228 {
229         std::string result("Record timestamp after ");
230
231         for (StageFlagVector::const_iterator it = m_stageVec.begin(); it != m_stageVec.end(); it++)
232         {
233                 if(*it != VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT)
234                 {
235                         result += getPipelineStageFlagStr(*it, true) + ' ';
236                 }
237         }
238         if(m_inRenderPass)
239                 result += " in the renderpass";
240         else
241                 result += " out of the render pass";
242
243         return result;
244 }
245
246 class TransferTimestampTestParam : public TimestampTestParam
247 {
248 public:
249                                           TransferTimestampTestParam  (const VkPipelineStageFlagBits* stages,
250                                                                                                    const deUint32                 stageCount,
251                                                                                                    const bool                     inRenderPass,
252                                                                                                    const deUint32                 methodNdx);
253                                           ~TransferTimestampTestParam (void)       { }
254         const std::string generateTestName            (void) const;
255         const std::string generateTestDescription     (void) const;
256         TransferMethod    getMethod                   (void) const { return m_method; }
257 protected:
258         TransferMethod    m_method;
259 };
260
261 TransferTimestampTestParam::TransferTimestampTestParam(const VkPipelineStageFlagBits* stages,
262                                                                                                            const deUint32                 stageCount,
263                                                                                                            const bool                     inRenderPass,
264                                                                                                            const deUint32                 methodNdx)
265         : TimestampTestParam(stages, stageCount, inRenderPass)
266 {
267         DE_ASSERT(methodNdx < (deUint32)TRANSFER_METHOD_LAST);
268
269         m_method = (TransferMethod)methodNdx;
270 }
271
272 const std::string TransferTimestampTestParam::generateTestName(void) const
273 {
274         std::string result("");
275
276         for (StageFlagVector::const_iterator it = m_stageVec.begin(); it != m_stageVec.end(); it++)
277         {
278                 if(*it != VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT)
279                 {
280                         result += getPipelineStageFlagStr(*it, false) + '_';
281                 }
282         }
283
284         result += "with_" + getTransferMethodStr(m_method, false);
285
286         return result;
287
288 }
289
290 const std::string TransferTimestampTestParam::generateTestDescription(void) const
291 {
292         std::string result("");
293
294         for (StageFlagVector::const_iterator it = m_stageVec.begin(); it != m_stageVec.end(); it++)
295         {
296                 if(*it != VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT)
297                 {
298                         result += getPipelineStageFlagStr(*it, true) + ' ';
299                 }
300         }
301
302         result += "with " + getTransferMethodStr(m_method, true);
303
304         return result;
305
306 }
307
308 class SimpleGraphicsPipelineBuilder
309 {
310 public:
311                                          SimpleGraphicsPipelineBuilder  (Context&              context);
312                                          ~SimpleGraphicsPipelineBuilder (void) { }
313         void             bindShaderStage                (VkShaderStageFlagBits stage,
314                                                                                                          const char*           source_name,
315                                                                                                          const char*           entry_name);
316         void             enableTessellationStage        (deUint32              patchControlPoints);
317         Move<VkPipeline> buildPipeline                  (tcu::UVec2            renderSize,
318                                                                                                          VkRenderPass          renderPass);
319 protected:
320         enum
321         {
322                 VK_MAX_SHADER_STAGES = 6,
323         };
324
325         Context&                            m_context;
326
327         Move<VkShaderModule>                m_shaderModules[VK_MAX_SHADER_STAGES];
328         deUint32                            m_shaderStageCount;
329         VkPipelineShaderStageCreateInfo     m_shaderStageInfo[VK_MAX_SHADER_STAGES];
330
331         deUint32                            m_patchControlPoints;
332
333         Move<VkPipelineLayout>              m_pipelineLayout;
334         Move<VkPipeline>                    m_graphicsPipelines;
335
336 };
337
338 SimpleGraphicsPipelineBuilder::SimpleGraphicsPipelineBuilder(Context& context)
339         : m_context(context)
340 {
341         m_patchControlPoints = 0;
342         m_shaderStageCount   = 0;
343 }
344
345 void SimpleGraphicsPipelineBuilder::bindShaderStage(VkShaderStageFlagBits stage,
346                                                                                                         const char*           source_name,
347                                                                                                         const char*           entry_name)
348 {
349         const DeviceInterface&  vk        = m_context.getDeviceInterface();
350         const VkDevice          vkDevice  = m_context.getDevice();
351
352         // Create shader module
353         deUint32*               pCode     = (deUint32*)m_context.getBinaryCollection().get(source_name).getBinary();
354         deUint32                codeSize  = (deUint32)m_context.getBinaryCollection().get(source_name).getSize();
355
356         const VkShaderModuleCreateInfo moduleCreateInfo =
357         {
358                 VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO,                // VkStructureType             sType;
359                 DE_NULL,                                                    // const void*                 pNext;
360                 0u,                                                         // VkShaderModuleCreateFlags   flags;
361                 codeSize,                                                   // deUintptr                   codeSize;
362                 pCode,                                                      // const deUint32*             pCode;
363         };
364
365         m_shaderModules[m_shaderStageCount] = createShaderModule(vk, vkDevice, &moduleCreateInfo);
366
367         // Prepare shader stage info
368         m_shaderStageInfo[m_shaderStageCount].sType               = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
369         m_shaderStageInfo[m_shaderStageCount].pNext               = DE_NULL;
370         m_shaderStageInfo[m_shaderStageCount].flags               = 0u;
371         m_shaderStageInfo[m_shaderStageCount].stage               = stage;
372         m_shaderStageInfo[m_shaderStageCount].module              = *m_shaderModules[m_shaderStageCount];
373         m_shaderStageInfo[m_shaderStageCount].pName               = entry_name;
374         m_shaderStageInfo[m_shaderStageCount].pSpecializationInfo = DE_NULL;
375
376         m_shaderStageCount++;
377 }
378
379 Move<VkPipeline> SimpleGraphicsPipelineBuilder::buildPipeline(tcu::UVec2 renderSize, VkRenderPass renderPass)
380 {
381         const DeviceInterface&      vk                  = m_context.getDeviceInterface();
382         const VkDevice              vkDevice            = m_context.getDevice();
383
384         // Create pipeline layout
385         {
386                 const VkPipelineLayoutCreateInfo pipelineLayoutParams =
387                 {
388                         VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,      // VkStructureType                  sType;
389                         DE_NULL,                                            // const void*                      pNext;
390                         0u,                                                 // VkPipelineLayoutCreateFlags      flags;
391                         0u,                                                 // deUint32                         setLayoutCount;
392                         DE_NULL,                                            // const VkDescriptorSetLayout*     pSetLayouts;
393                         0u,                                                 // deUint32                         pushConstantRangeCount;
394                         DE_NULL                                             // const VkPushConstantRange*       pPushConstantRanges;
395                 };
396
397                 m_pipelineLayout = createPipelineLayout(vk, vkDevice, &pipelineLayoutParams);
398         }
399
400         // Create pipeline
401         const VkVertexInputBindingDescription vertexInputBindingDescription =
402         {
403                 0u,                                 // deUint32                 binding;
404                 sizeof(Vertex4RGBA),                // deUint32                 strideInBytes;
405                 VK_VERTEX_INPUT_RATE_VERTEX,        // VkVertexInputRate        inputRate;
406         };
407
408         const VkVertexInputAttributeDescription vertexInputAttributeDescriptions[2] =
409         {
410                 {
411                         0u,                                 // deUint32 location;
412                         0u,                                 // deUint32 binding;
413                         VK_FORMAT_R32G32B32A32_SFLOAT,      // VkFormat format;
414                         0u                                  // deUint32 offsetInBytes;
415                 },
416                 {
417                         1u,                                 // deUint32 location;
418                         0u,                                 // deUint32 binding;
419                         VK_FORMAT_R32G32B32A32_SFLOAT,      // VkFormat format;
420                         DE_OFFSET_OF(Vertex4RGBA, color),   // deUint32 offsetInBytes;
421                 }
422         };
423
424         const VkPipelineVertexInputStateCreateInfo vertexInputStateParams =
425         {
426                 VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,      // VkStructureType                          sType;
427                 DE_NULL,                                                        // const void*                              pNext;
428                 0u,                                                             // VkPipelineVertexInputStateCreateFlags    flags;
429                 1u,                                                             // deUint32                                 vertexBindingDescriptionCount;
430                 &vertexInputBindingDescription,                                 // const VkVertexInputBindingDescription*   pVertexBindingDescriptions;
431                 2u,                                                             // deUint32                                 vertexAttributeDescriptionCount;
432                 vertexInputAttributeDescriptions,                               // const VkVertexInputAttributeDescription* pVertexAttributeDescriptions;
433         };
434
435         const VkPipelineInputAssemblyStateCreateInfo inputAssemblyStateParams =
436         {
437                 VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,    // VkStructureType                          sType;
438                 DE_NULL,                                                        // const void*                              pNext;
439                 0u,                                                             // VkPipelineInputAssemblyStateCreateFlags  flags;
440                 VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST,                            // VkPrimitiveTopology                      topology;
441                 VK_FALSE,                                                       // VkBool32                                 primitiveRestartEnable;
442         };
443
444         const VkViewport viewport =
445         {
446                 0.0f,                       // float    originX;
447                 0.0f,                       // float    originY;
448                 (float)renderSize.x(),      // float    width;
449                 (float)renderSize.y(),      // float    height;
450                 0.0f,                       // float    minDepth;
451                 1.0f                        // float    maxDepth;
452         };
453         const VkRect2D scissor =
454         {
455                 { 0u, 0u },                                                     // VkOffset2D  offset;
456                 { renderSize.x(), renderSize.y() }                              // VkExtent2D  extent;
457         };
458         const VkPipelineViewportStateCreateInfo viewportStateParams =
459         {
460                 VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO,          // VkStructureType                      sType;
461                 DE_NULL,                                                        // const void*                          pNext;
462                 0u,                                                             // VkPipelineViewportStateCreateFlags   flags;
463                 1u,                                                             // deUint32                             viewportCount;
464                 &viewport,                                                      // const VkViewport*                    pViewports;
465                 1u,                                                             // deUint32                             scissorCount;
466                 &scissor                                                        // const VkRect2D*                      pScissors;
467         };
468
469         const VkPipelineRasterizationStateCreateInfo rasterStateParams =
470         {
471                 VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO,     // VkStructureType                          sType;
472                 DE_NULL,                                                        // const void*                              pNext;
473                 0u,                                                             // VkPipelineRasterizationStateCreateFlags  flags;
474                 VK_FALSE,                                                       // VkBool32                                 depthClampEnable;
475                 VK_FALSE,                                                       // VkBool32                                 rasterizerDiscardEnable;
476                 VK_POLYGON_MODE_FILL,                                           // VkPolygonMode                            polygonMode;
477                 VK_CULL_MODE_NONE,                                              // VkCullModeFlags                          cullMode;
478                 VK_FRONT_FACE_COUNTER_CLOCKWISE,                                // VkFrontFace                              frontFace;
479                 VK_FALSE,                                                       // VkBool32                                 depthBiasEnable;
480                 0.0f,                                                           // float                                    depthBiasConstantFactor;
481                 0.0f,                                                           // float                                    depthBiasClamp;
482                 0.0f,                                                           // float                                    depthBiasSlopeFactor;
483                 1.0f,                                                           // float                                    lineWidth;
484         };
485
486         const VkPipelineColorBlendAttachmentState colorBlendAttachmentState =
487         {
488                 VK_FALSE,                                                                   // VkBool32                 blendEnable;
489                 VK_BLEND_FACTOR_ONE,                                                        // VkBlendFactor            srcColorBlendFactor;
490                 VK_BLEND_FACTOR_ZERO,                                                       // VkBlendFactor            dstColorBlendFactor;
491                 VK_BLEND_OP_ADD,                                                            // VkBlendOp                colorBlendOp;
492                 VK_BLEND_FACTOR_ONE,                                                        // VkBlendFactor            srcAlphaBlendFactor;
493                 VK_BLEND_FACTOR_ZERO,                                                       // VkBlendFactor            dstAlphaBlendFactor;
494                 VK_BLEND_OP_ADD,                                                            // VkBlendOp                alphaBlendOp;
495                 VK_COLOR_COMPONENT_R_BIT |
496                 VK_COLOR_COMPONENT_G_BIT |
497                 VK_COLOR_COMPONENT_B_BIT |
498                 VK_COLOR_COMPONENT_A_BIT                                                    // VkColorComponentFlags    colorWriteMask;
499         };
500
501         const VkPipelineColorBlendStateCreateInfo colorBlendStateParams =
502         {
503                 VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,   // VkStructureType                              sType;
504                 DE_NULL,                                                    // const void*                                  pNext;
505                 0u,                                                         // VkPipelineColorBlendStateCreateFlags         flags;
506                 VK_FALSE,                                                   // VkBool32                                     logicOpEnable;
507                 VK_LOGIC_OP_COPY,                                           // VkLogicOp                                    logicOp;
508                 1u,                                                         // deUint32                                     attachmentCount;
509                 &colorBlendAttachmentState,                                 // const VkPipelineColorBlendAttachmentState*   pAttachments;
510                 { 0.0f, 0.0f, 0.0f, 0.0f },                                 // float                                        blendConst[4];
511         };
512
513         const VkPipelineMultisampleStateCreateInfo  multisampleStateParams  =
514         {
515                 VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,   // VkStructureType                          sType;
516                 DE_NULL,                                                    // const void*                              pNext;
517                 0u,                                                         // VkPipelineMultisampleStateCreateFlags    flags;
518                 VK_SAMPLE_COUNT_1_BIT,                                      // VkSampleCountFlagBits                    rasterizationSamples;
519                 VK_FALSE,                                                   // VkBool32                                 sampleShadingEnable;
520                 0.0f,                                                       // float                                    minSampleShading;
521                 DE_NULL,                                                    // const VkSampleMask*                      pSampleMask;
522                 VK_FALSE,                                                   // VkBool32                                 alphaToCoverageEnable;
523                 VK_FALSE,                                                   // VkBool32                                 alphaToOneEnable;
524         };
525
526         const VkPipelineDynamicStateCreateInfo  dynamicStateParams      =
527         {
528                 VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO,       // VkStructureType                      sType;
529                 DE_NULL,                                                    // const void*                          pNext;
530                 0u,                                                         // VkPipelineDynamicStateCreateFlags    flags;
531                 0u,                                                         // deUint32                             dynamicStateCount;
532                 DE_NULL,                                                    // const VkDynamicState*                pDynamicStates;
533         };
534
535         VkPipelineDepthStencilStateCreateInfo depthStencilStateParams =
536         {
537                 VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO, // VkStructureType                          sType;
538                 DE_NULL,                                                    // const void*                              pNext;
539                 0u,                                                         // VkPipelineDepthStencilStateCreateFlags   flags;
540                 VK_TRUE,                                                    // VkBool32                                 depthTestEnable;
541                 VK_TRUE,                                                    // VkBool32                                 depthWriteEnable;
542                 VK_COMPARE_OP_LESS_OR_EQUAL,                                // VkCompareOp                              depthCompareOp;
543                 VK_FALSE,                                                   // VkBool32                                 depthBoundsTestEnable;
544                 VK_FALSE,                                                   // VkBool32                                 stencilTestEnable;
545                 // VkStencilOpState front;
546                 {
547                         VK_STENCIL_OP_KEEP,     // VkStencilOp  failOp;
548                         VK_STENCIL_OP_KEEP,     // VkStencilOp  passOp;
549                         VK_STENCIL_OP_KEEP,     // VkStencilOp  depthFailOp;
550                         VK_COMPARE_OP_NEVER,    // VkCompareOp  compareOp;
551                         0u,                     // deUint32     compareMask;
552                         0u,                     // deUint32     writeMask;
553                         0u,                     // deUint32     reference;
554                 },
555                 // VkStencilOpState back;
556                 {
557                         VK_STENCIL_OP_KEEP,     // VkStencilOp  failOp;
558                         VK_STENCIL_OP_KEEP,     // VkStencilOp  passOp;
559                         VK_STENCIL_OP_KEEP,     // VkStencilOp  depthFailOp;
560                         VK_COMPARE_OP_NEVER,    // VkCompareOp  compareOp;
561                         0u,                     // deUint32     compareMask;
562                         0u,                     // deUint32     writeMask;
563                         0u,                     // deUint32     reference;
564                 },
565                 -1.0f,                                                      // float                                    minDepthBounds;
566                 +1.0f,                                                      // float                                    maxDepthBounds;
567         };
568
569         const VkPipelineTessellationStateCreateInfo* pTessCreateInfo = DE_NULL;
570         if(m_patchControlPoints > 0)
571         {
572                 const VkPipelineTessellationStateCreateInfo tessStateCreateInfo =
573                 {
574                         VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO,  // VkStructureType                          sType;
575                         DE_NULL,                                                    // const void*                              pNext;
576                         0u,                                                         // VkPipelineTessellationStateCreateFlags   flags;
577                         m_patchControlPoints,                                       // deUint32                                 patchControlPoints;
578                 };
579
580                 pTessCreateInfo = &tessStateCreateInfo;
581         }
582
583         const VkGraphicsPipelineCreateInfo graphicsPipelineParams =
584         {
585                 VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,    // VkStructureType                                  sType;
586                 DE_NULL,                                            // const void*                                      pNext;
587                 0u,                                                 // VkPipelineCreateFlags                            flags;
588                 m_shaderStageCount,                                 // deUint32                                         stageCount;
589                 m_shaderStageInfo,                                  // const VkPipelineShaderStageCreateInfo*           pStages;
590                 &vertexInputStateParams,                            // const VkPipelineVertexInputStateCreateInfo*      pVertexInputState;
591                 &inputAssemblyStateParams,                          // const VkPipelineInputAssemblyStateCreateInfo*    pInputAssemblyState;
592                 pTessCreateInfo,                                    // const VkPipelineTessellationStateCreateInfo*     pTessellationState;
593                 &viewportStateParams,                               // const VkPipelineViewportStateCreateInfo*         pViewportState;
594                 &rasterStateParams,                                 // const VkPipelineRasterizationStateCreateInfo*    pRasterState;
595                 &multisampleStateParams,                            // const VkPipelineMultisampleStateCreateInfo*      pMultisampleState;
596                 &depthStencilStateParams,                           // const VkPipelineDepthStencilStateCreateInfo*     pDepthStencilState;
597                 &colorBlendStateParams,                             // const VkPipelineColorBlendStateCreateInfo*       pColorBlendState;
598                 &dynamicStateParams,                                // const VkPipelineDynamicStateCreateInfo*          pDynamicState;
599                 *m_pipelineLayout,                                  // VkPipelineLayout                                 layout;
600                 renderPass,                                         // VkRenderPass                                     renderPass;
601                 0u,                                                 // deUint32                                         subpass;
602                 0u,                                                 // VkPipeline                                       basePipelineHandle;
603                 0,                                                  // deInt32                                          basePipelineIndex;
604         };
605
606         return createGraphicsPipeline(vk, vkDevice, DE_NULL, &graphicsPipelineParams);
607 }
608
609 void SimpleGraphicsPipelineBuilder::enableTessellationStage(deUint32 patchControlPoints)
610 {
611         m_patchControlPoints = patchControlPoints;
612 }
613
614 template <class Test>
615 vkt::TestCase* newTestCase(tcu::TestContext&     testContext,
616                                                    TimestampTestParam*   testParam)
617 {
618         return new Test(testContext,
619                                         testParam->generateTestName().c_str(),
620                                         testParam->generateTestDescription().c_str(),
621                                         testParam);
622 }
623
624 // Test Classes
625 class TimestampTest : public vkt::TestCase
626 {
627 public:
628         enum
629         {
630                 ENTRY_COUNT = 8
631         };
632
633                                                   TimestampTest(tcu::TestContext&         testContext,
634                                                                                 const std::string&        name,
635                                                                                 const std::string&        description,
636                                                                                 const TimestampTestParam* param)
637                                                           : vkt::TestCase  (testContext, name, description)
638                                                           , m_stages       (param->getStageVector())
639                                                           , m_inRenderPass (param->getInRenderPass())
640                                                           { }
641         virtual               ~TimestampTest (void) { }
642         virtual void          initPrograms   (SourceCollections&      programCollection) const;
643         virtual TestInstance* createInstance (Context&                context) const;
644 protected:
645         const StageFlagVector m_stages;
646         const bool            m_inRenderPass;
647 };
648
649 class TimestampTestInstance : public vkt::TestInstance
650 {
651 public:
652                                                         TimestampTestInstance      (Context&                 context,
653                                                                                                                 const StageFlagVector&   stages,
654                                                                                                                 const bool               inRenderPass);
655         virtual                 ~TimestampTestInstance     (void);
656         virtual tcu::TestStatus iterate                    (void);
657 protected:
658         virtual tcu::TestStatus verifyTimestamp            (void);
659         virtual void            configCommandBuffer        (void);
660         Move<VkBuffer>          createBufferAndBindMemory  (VkDeviceSize             size,
661                                                                                                                 VkBufferUsageFlags       usage,
662                                                                                                                 de::MovePtr<Allocation>* pAlloc);
663         Move<VkImage>           createImage2DAndBindMemory (VkFormat                 format,
664                                                                                                                 deUint32                  width,
665                                                                                                                 deUint32                  height,
666                                                                                                                 VkBufferUsageFlags       usage,
667                                                                                                                 VkSampleCountFlagBits    sampleCount,
668                                                                                                                 de::MovePtr<Allocation>* pAlloc);
669 protected:
670         const StageFlagVector   m_stages;
671         bool                    m_inRenderPass;
672
673         Move<VkCommandPool>     m_cmdPool;
674         Move<VkCommandBuffer>   m_cmdBuffer;
675         Move<VkFence>           m_fence;
676         Move<VkQueryPool>       m_queryPool;
677         deUint64*               m_timestampValues;
678 };
679
680 void TimestampTest::initPrograms(SourceCollections& programCollection) const
681 {
682         vkt::TestCase::initPrograms(programCollection);
683 }
684
685 TestInstance* TimestampTest::createInstance(Context& context) const
686 {
687         return new TimestampTestInstance(context,m_stages,m_inRenderPass);
688 }
689
690 TimestampTestInstance::TimestampTestInstance(Context&                context,
691                                                                                          const StageFlagVector&  stages,
692                                                                                          const bool              inRenderPass)
693         : TestInstance  (context)
694         , m_stages      (stages)
695         , m_inRenderPass(inRenderPass)
696 {
697         const DeviceInterface&      vk                  = context.getDeviceInterface();
698         const VkDevice              vkDevice            = context.getDevice();
699         const deUint32              queueFamilyIndex    = context.getUniversalQueueFamilyIndex();
700
701         // Check support for timestamp queries
702         {
703                 const std::vector<VkQueueFamilyProperties>   queueProperties = vk::getPhysicalDeviceQueueFamilyProperties(m_context.getInstanceInterface(), m_context.getPhysicalDevice());
704
705                 DE_ASSERT(queueFamilyIndex < (deUint32)queueProperties.size());
706
707                 if (!queueProperties[queueFamilyIndex].timestampValidBits)
708                         throw tcu::NotSupportedError("Universal queue does not support timestamps");
709         }
710
711         // Create Query Pool
712         {
713                 const VkQueryPoolCreateInfo queryPoolParams =
714                 {
715                    VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO,    // VkStructureType               sType;
716                    DE_NULL,                                     // const void*                   pNext;
717                    0u,                                          // VkQueryPoolCreateFlags        flags;
718                    VK_QUERY_TYPE_TIMESTAMP,                     // VkQueryType                   queryType;
719                    TimestampTest::ENTRY_COUNT,                  // deUint32                      entryCount;
720                    0u,                                          // VkQueryPipelineStatisticFlags pipelineStatistics;
721                 };
722
723                 m_queryPool = createQueryPool(vk, vkDevice, &queryPoolParams);
724         }
725
726         // Create command pool
727         {
728                 const VkCommandPoolCreateInfo cmdPoolParams =
729                 {
730                         VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,   // VkStructureType      sType;
731                         DE_NULL,                                      // const void*          pNext;
732                         VK_COMMAND_POOL_CREATE_TRANSIENT_BIT,         // VkCmdPoolCreateFlags flags;
733                         queueFamilyIndex,                             // deUint32             queueFamilyIndex;
734                 };
735
736                 m_cmdPool = createCommandPool(vk, vkDevice, &cmdPoolParams);
737         }
738
739         // Create command buffer
740         {
741                 const VkCommandBufferAllocateInfo cmdAllocateParams =
742                 {
743                         VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, // VkStructureType         sType;
744                         DE_NULL,                                        // const void*             pNext;
745                         *m_cmdPool,                                     // VkCommandPool           cmdPool;
746                         VK_COMMAND_BUFFER_LEVEL_PRIMARY,                // VkCommandBufferLevel    level;
747                         1u,                                             // deUint32                bufferCount;
748                 };
749
750                 m_cmdBuffer = allocateCommandBuffer(vk, vkDevice, &cmdAllocateParams);
751         }
752
753         // Create fence
754         {
755                 const VkFenceCreateInfo fenceParams =
756                 {
757                         VK_STRUCTURE_TYPE_FENCE_CREATE_INFO,        // VkStructureType      sType;
758                         DE_NULL,                                    // const void*          pNext;
759                         0u,                                         // VkFenceCreateFlags   flags;
760                 };
761
762                 m_fence = createFence(vk, vkDevice, &fenceParams);
763         }
764
765         // alloc timestamp values
766         m_timestampValues = new deUint64[m_stages.size()];
767 }
768
769 TimestampTestInstance::~TimestampTestInstance(void)
770 {
771         if(m_timestampValues)
772         {
773                 delete[] m_timestampValues;
774                 m_timestampValues = NULL;
775         }
776 }
777
778 void TimestampTestInstance::configCommandBuffer(void)
779 {
780         const DeviceInterface&      vk                  = m_context.getDeviceInterface();
781
782         const VkCommandBufferBeginInfo cmdBufferBeginInfo =
783         {
784                 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,    // VkStructureType                  sType;
785                 DE_NULL,                                        // const void*                      pNext;
786                 0u,                                             // VkCommandBufferUsageFlags        flags;
787                 (const VkCommandBufferInheritanceInfo*)DE_NULL,
788         };
789
790         VK_CHECK(vk.beginCommandBuffer(*m_cmdBuffer, &cmdBufferBeginInfo));
791
792         vk.cmdResetQueryPool(*m_cmdBuffer, *m_queryPool, 0u, TimestampTest::ENTRY_COUNT);
793
794         deUint32 timestampEntry = 0;
795         for (StageFlagVector::const_iterator it = m_stages.begin(); it != m_stages.end(); it++)
796         {
797                 vk.cmdWriteTimestamp(*m_cmdBuffer, *it, *m_queryPool, timestampEntry++);
798         }
799
800         VK_CHECK(vk.endCommandBuffer(*m_cmdBuffer));
801 }
802
803 tcu::TestStatus TimestampTestInstance::iterate(void)
804 {
805         const DeviceInterface&      vk          = m_context.getDeviceInterface();
806         const VkDevice              vkDevice    = m_context.getDevice();
807         const VkQueue               queue       = m_context.getUniversalQueue();
808
809         configCommandBuffer();
810
811         VK_CHECK(vk.resetFences(vkDevice, 1u, &m_fence.get()));
812
813         const VkSubmitInfo          submitInfo =
814         {
815                 VK_STRUCTURE_TYPE_SUBMIT_INFO,                      // VkStructureType         sType;
816                 DE_NULL,                                            // const void*             pNext;
817                 0u,                                                 // deUint32                waitSemaphoreCount;
818                 DE_NULL,                                            // const VkSemaphore*      pWaitSemaphores;
819                 (const VkPipelineStageFlags*)DE_NULL,
820                 1u,                                                 // deUint32                commandBufferCount;
821                 &m_cmdBuffer.get(),                                 // const VkCommandBuffer*  pCommandBuffers;
822                 0u,                                                 // deUint32                signalSemaphoreCount;
823                 DE_NULL,                                            // const VkSemaphore*      pSignalSemaphores;
824         };
825         VK_CHECK(vk.queueSubmit(queue, 1u, &submitInfo, *m_fence));
826
827         VK_CHECK(vk.waitForFences(vkDevice, 1u, &m_fence.get(), true, ~(0ull) /* infinity*/));
828
829         // Generate the timestamp mask
830         deUint64                    timestampMask;
831         const std::vector<VkQueueFamilyProperties>   queueProperties = vk::getPhysicalDeviceQueueFamilyProperties(m_context.getInstanceInterface(), m_context.getPhysicalDevice());
832         if(queueProperties[0].timestampValidBits == 0)
833         {
834                 return tcu::TestStatus::fail("Device does not support timestamp!");
835         }
836         else if(queueProperties[0].timestampValidBits == 64)
837         {
838                 timestampMask = 0xFFFFFFFFFFFFFFFF;
839         }
840         else
841         {
842                 timestampMask = (1 << queueProperties[0].timestampValidBits) - 1u;
843         }
844
845         // Get timestamp value from query pool
846         deUint32                    stageSize = (deUint32)m_stages.size();
847
848         vk.getQueryPoolResults(vkDevice, *m_queryPool, 0u, stageSize, sizeof(m_timestampValues), (void*)m_timestampValues, sizeof(deUint64), VK_QUERY_RESULT_64_BIT | VK_QUERY_RESULT_WAIT_BIT);
849
850         for (deUint32 ndx = 0; ndx < stageSize; ndx++)
851         {
852                 m_timestampValues[ndx] &= timestampMask;
853         }
854
855         return verifyTimestamp();
856 }
857
858 tcu::TestStatus TimestampTestInstance::verifyTimestamp(void)
859 {
860         for (deUint32 first = 0; first < m_stages.size(); first++)
861         {
862                 for (deUint32 second = 0; second < first; second++)
863                 {
864                         if(m_timestampValues[first] < m_timestampValues[second])
865                         {
866                                 return tcu::TestStatus::fail("Latter stage timestamp is smaller than the former stage timestamp.");
867                         }
868                 }
869         }
870
871         return tcu::TestStatus::pass("Timestamp increases steadily.");
872 }
873
874 Move<VkBuffer> TimestampTestInstance::createBufferAndBindMemory(VkDeviceSize size, VkBufferUsageFlags usage, de::MovePtr<Allocation>* pAlloc)
875 {
876         const DeviceInterface&      vk                  = m_context.getDeviceInterface();
877         const VkDevice              vkDevice            = m_context.getDevice();
878         const deUint32              queueFamilyIndex    = m_context.getUniversalQueueFamilyIndex();
879         SimpleAllocator             memAlloc            (vk, vkDevice, getPhysicalDeviceMemoryProperties(m_context.getInstanceInterface(), m_context.getPhysicalDevice()));
880
881         const VkBufferCreateInfo vertexBufferParams =
882         {
883                 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,       // VkStructureType      sType;
884                 DE_NULL,                                    // const void*          pNext;
885                 0u,                                         // VkBufferCreateFlags  flags;
886                 size,                                       // VkDeviceSize         size;
887                 usage,                                      // VkBufferUsageFlags   usage;
888                 VK_SHARING_MODE_EXCLUSIVE,                  // VkSharingMode        sharingMode;
889                 1u,                                         // deUint32             queueFamilyCount;
890                 &queueFamilyIndex                           // const deUint32*      pQueueFamilyIndices;
891         };
892
893         Move<VkBuffer> vertexBuffer = createBuffer(vk, vkDevice, &vertexBufferParams);
894         de::MovePtr<Allocation> vertexBufferAlloc = memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *vertexBuffer), MemoryRequirement::HostVisible);
895
896         VK_CHECK(vk.bindBufferMemory(vkDevice, *vertexBuffer, vertexBufferAlloc->getMemory(), vertexBufferAlloc->getOffset()));
897
898         DE_ASSERT(pAlloc);
899         *pAlloc = vertexBufferAlloc;
900         return vertexBuffer;
901 }
902
903 Move<VkImage> TimestampTestInstance::createImage2DAndBindMemory(VkFormat                          format,
904                                                                                                                                 deUint32                          width,
905                                                                                                                                 deUint32                          height,
906                                                                                                                                 VkBufferUsageFlags                usage,
907                                                                                                                                 VkSampleCountFlagBits             sampleCount,
908                                                                                                                                 de::details::MovePtr<Allocation>* pAlloc)
909 {
910         const DeviceInterface&      vk                  = m_context.getDeviceInterface();
911         const VkDevice              vkDevice            = m_context.getDevice();
912         const deUint32              queueFamilyIndex    = m_context.getUniversalQueueFamilyIndex();
913         SimpleAllocator             memAlloc            (vk, vkDevice, getPhysicalDeviceMemoryProperties(m_context.getInstanceInterface(), m_context.getPhysicalDevice()));
914
915         const VkImageCreateInfo colorImageParams =
916         {
917                 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,                                        // VkStructureType      sType;
918                 DE_NULL,                                                                    // const void*          pNext;
919                 0u,                                                                         // VkImageCreateFlags   flags;
920                 VK_IMAGE_TYPE_2D,                                                           // VkImageType          imageType;
921                 format,                                                                     // VkFormat             format;
922                 { width, height, 1u },                                                      // VkExtent3D           extent;
923                 1u,                                                                         // deUint32             mipLevels;
924                 1u,                                                                         // deUint32             arraySize;
925                 sampleCount,                                                                // deUint32             samples;
926                 VK_IMAGE_TILING_OPTIMAL,                                                    // VkImageTiling        tiling;
927                 usage,                                                                      // VkImageUsageFlags    usage;
928                 VK_SHARING_MODE_EXCLUSIVE,                                                  // VkSharingMode        sharingMode;
929                 1u,                                                                         // deUint32             queueFamilyCount;
930                 &queueFamilyIndex,                                                          // const deUint32*      pQueueFamilyIndices;
931                 VK_IMAGE_LAYOUT_UNDEFINED,                                                  // VkImageLayout        initialLayout;
932         };
933
934         Move<VkImage> image = createImage(vk, vkDevice, &colorImageParams);
935
936         // Allocate and bind image memory
937         de::MovePtr<Allocation> colorImageAlloc = memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, *image), MemoryRequirement::Any);
938         VK_CHECK(vk.bindImageMemory(vkDevice, *image, colorImageAlloc->getMemory(), colorImageAlloc->getOffset()));
939
940         DE_ASSERT(pAlloc);
941         *pAlloc = colorImageAlloc;
942
943         return image;
944 }
945
946 class BasicGraphicsTest : public TimestampTest
947 {
948 public:
949                                                   BasicGraphicsTest(tcu::TestContext&         testContext,
950                                                                                         const std::string&        name,
951                                                                                         const std::string&        description,
952                                                                                         const TimestampTestParam* param)
953                                                           : TimestampTest (testContext, name, description, param)
954                                                           { }
955         virtual               ~BasicGraphicsTest (void) { }
956         virtual void          initPrograms       (SourceCollections&      programCollection) const;
957         virtual TestInstance* createInstance     (Context&                context) const;
958 };
959
960 class BasicGraphicsTestInstance : public TimestampTestInstance
961 {
962 public:
963         enum
964         {
965                 VK_MAX_SHADER_STAGES = 6,
966         };
967                                  BasicGraphicsTestInstance  (Context&              context,
968                                                                                          const StageFlagVector stages,
969                                                                                          const bool            inRenderPass);
970         virtual      ~BasicGraphicsTestInstance (void);
971 protected:
972         virtual void configCommandBuffer        (void);
973         virtual void buildVertexBuffer          (void);
974         virtual void buildRenderPass            (VkFormat colorFormat,
975                                                                                          VkFormat depthFormat);
976         virtual void buildFrameBuffer           (tcu::UVec2 renderSize,
977                                                                                          VkFormat colorFormat,
978                                                                                          VkFormat depthFormat);
979 protected:
980         const tcu::UVec2                    m_renderSize;
981         const VkFormat                      m_colorFormat;
982         const VkFormat                      m_depthFormat;
983
984         Move<VkImage>                       m_colorImage;
985         de::MovePtr<Allocation>             m_colorImageAlloc;
986         Move<VkImage>                       m_depthImage;
987         de::MovePtr<Allocation>             m_depthImageAlloc;
988         Move<VkImageView>                   m_colorAttachmentView;
989         Move<VkImageView>                   m_depthAttachmentView;
990         Move<VkRenderPass>                  m_renderPass;
991         Move<VkFramebuffer>                 m_framebuffer;
992
993         Move<VkBuffer>                      m_vertexBuffer;
994         std::vector<Vertex4RGBA>            m_vertices;
995
996         SimpleGraphicsPipelineBuilder       m_pipelineBuilder;
997         Move<VkPipeline>                    m_graphicsPipelines;
998 };
999
1000 void BasicGraphicsTest::initPrograms (SourceCollections& programCollection) const
1001 {
1002         programCollection.glslSources.add("color_vert") << glu::VertexSource(
1003                 "#version 310 es\n"
1004                 "layout(location = 0) in vec4 position;\n"
1005                 "layout(location = 1) in vec4 color;\n"
1006                 "layout(location = 0) out highp vec4 vtxColor;\n"
1007                 "void main (void)\n"
1008                 "{\n"
1009                 "  gl_Position = position;\n"
1010                 "  vtxColor = color;\n"
1011                 "}\n");
1012
1013         programCollection.glslSources.add("color_frag") << glu::FragmentSource(
1014                 "#version 310 es\n"
1015                 "layout(location = 0) in highp vec4 vtxColor;\n"
1016                 "layout(location = 0) out highp vec4 fragColor;\n"
1017                 "void main (void)\n"
1018                 "{\n"
1019                 "  fragColor = vtxColor;\n"
1020                 "}\n");
1021 }
1022
1023 TestInstance* BasicGraphicsTest::createInstance(Context& context) const
1024 {
1025         return new BasicGraphicsTestInstance(context,m_stages,m_inRenderPass);
1026 }
1027
1028 void BasicGraphicsTestInstance::buildVertexBuffer(void)
1029 {
1030         const DeviceInterface&      vk       = m_context.getDeviceInterface();
1031         const VkDevice              vkDevice = m_context.getDevice();
1032
1033         // Create vertex buffer
1034         {
1035                 de::MovePtr<Allocation>     bufferAlloc;
1036                 m_vertexBuffer = createBufferAndBindMemory(1024u,VK_BUFFER_USAGE_VERTEX_BUFFER_BIT,&bufferAlloc);
1037
1038                 m_vertices          = createOverlappingQuads();
1039                 // Load vertices into vertex buffer
1040                 deMemcpy(bufferAlloc->getHostPtr(), m_vertices.data(), m_vertices.size() * sizeof(Vertex4RGBA));
1041                 flushMappedMemoryRange(vk, vkDevice, bufferAlloc->getMemory(), bufferAlloc->getOffset(), 1024u);
1042         }
1043 }
1044
1045 void BasicGraphicsTestInstance::buildRenderPass(VkFormat colorFormat, VkFormat depthFormat)
1046 {
1047         const DeviceInterface&      vk       = m_context.getDeviceInterface();
1048         const VkDevice              vkDevice = m_context.getDevice();
1049
1050         // Create render pass
1051         {
1052                 const VkAttachmentDescription colorAttachmentDescription =
1053                 {
1054                         0u,                                                 // VkAttachmentDescriptionFlags    flags;
1055                         colorFormat,                                        // VkFormat                        format;
1056                         VK_SAMPLE_COUNT_1_BIT,                              // VkSampleCountFlagBits           samples;
1057                         VK_ATTACHMENT_LOAD_OP_CLEAR,                        // VkAttachmentLoadOp              loadOp;
1058                         VK_ATTACHMENT_STORE_OP_STORE,                       // VkAttachmentStoreOp             storeOp;
1059                         VK_ATTACHMENT_LOAD_OP_DONT_CARE,                    // VkAttachmentLoadOp              stencilLoadOp;
1060                         VK_ATTACHMENT_STORE_OP_DONT_CARE,                   // VkAttachmentStoreOp             stencilStoreOp;
1061                         VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,           // VkImageLayout                   initialLayout;
1062                         VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,           // VkImageLayout                   finalLayout;
1063                 };
1064
1065                 const VkAttachmentDescription depthAttachmentDescription =
1066                 {
1067                         0u,                                                 // VkAttachmentDescriptionFlags flags;
1068                         depthFormat,                                        // VkFormat                     format;
1069                         VK_SAMPLE_COUNT_1_BIT,                              // VkSampleCountFlagBits        samples;
1070                         VK_ATTACHMENT_LOAD_OP_CLEAR,                        // VkAttachmentLoadOp           loadOp;
1071                         VK_ATTACHMENT_STORE_OP_DONT_CARE,                   // VkAttachmentStoreOp          storeOp;
1072                         VK_ATTACHMENT_LOAD_OP_DONT_CARE,                    // VkAttachmentLoadOp           stencilLoadOp;
1073                         VK_ATTACHMENT_STORE_OP_DONT_CARE,                   // VkAttachmentStoreOp          stencilStoreOp;
1074                         VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,   // VkImageLayout                initialLayout;
1075                         VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,   // VkImageLayout                finalLayout;
1076                 };
1077
1078                 const VkAttachmentDescription attachments[2] =
1079                 {
1080                         colorAttachmentDescription,
1081                         depthAttachmentDescription
1082                 };
1083
1084                 const VkAttachmentReference colorAttachmentReference =
1085                 {
1086                         0u,                                                 // deUint32         attachment;
1087                         VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL            // VkImageLayout    layout;
1088                 };
1089
1090                 const VkAttachmentReference depthAttachmentReference =
1091                 {
1092                         1u,                                                 // deUint32         attachment;
1093                         VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL    // VkImageLayout    layout;
1094                 };
1095
1096                 const VkSubpassDescription subpassDescription =
1097                 {
1098                         0u,                                                 // VkSubpassDescriptionFlags        flags;
1099                         VK_PIPELINE_BIND_POINT_GRAPHICS,                    // VkPipelineBindPoint              pipelineBindPoint;
1100                         0u,                                                 // deUint32                         inputAttachmentCount;
1101                         DE_NULL,                                            // const VkAttachmentReference*     pInputAttachments;
1102                         1u,                                                 // deUint32                         colorAttachmentCount;
1103                         &colorAttachmentReference,                          // const VkAttachmentReference*     pColorAttachments;
1104                         DE_NULL,                                            // const VkAttachmentReference*     pResolveAttachments;
1105                         &depthAttachmentReference,                          // const VkAttachmentReference*     pDepthStencilAttachment;
1106                         0u,                                                 // deUint32                         preserveAttachmentCount;
1107                         DE_NULL                                             // const VkAttachmentReference*     pPreserveAttachments;
1108                 };
1109
1110                 const VkRenderPassCreateInfo renderPassParams =
1111                 {
1112                         VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,          // VkStructureType                  sType;
1113                         DE_NULL,                                            // const void*                      pNext;
1114                         0u,                                                 // VkRenderPassCreateFlags          flags;
1115                         2u,                                                 // deUint32                         attachmentCount;
1116                         attachments,                                        // const VkAttachmentDescription*   pAttachments;
1117                         1u,                                                 // deUint32                         subpassCount;
1118                         &subpassDescription,                                // const VkSubpassDescription*      pSubpasses;
1119                         0u,                                                 // deUint32                         dependencyCount;
1120                         DE_NULL                                             // const VkSubpassDependency*       pDependencies;
1121                 };
1122
1123                 m_renderPass = createRenderPass(vk, vkDevice, &renderPassParams);
1124         }
1125
1126 }
1127
1128 void BasicGraphicsTestInstance::buildFrameBuffer(tcu::UVec2 renderSize, VkFormat colorFormat, VkFormat depthFormat)
1129 {
1130         const DeviceInterface&      vk                   = m_context.getDeviceInterface();
1131         const VkDevice              vkDevice             = m_context.getDevice();
1132         const VkComponentMapping    ComponentMappingRGBA = { VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A};
1133
1134         // Create color image
1135         {
1136                 m_colorImage = createImage2DAndBindMemory(colorFormat,
1137                                                                                                   renderSize.x(),
1138                                                                                                   renderSize.y(),
1139                                                                                                   VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT,
1140                                                                                                   VK_SAMPLE_COUNT_1_BIT,
1141                                                                                                   &m_colorImageAlloc);
1142         }
1143
1144         // Create depth image
1145         {
1146                 m_depthImage = createImage2DAndBindMemory(depthFormat,
1147                                                                                                   renderSize.x(),
1148                                                                                                   renderSize.y(),
1149                                                                                                   VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT,
1150                                                                                                   VK_SAMPLE_COUNT_1_BIT,
1151                                                                                                   &m_depthImageAlloc);
1152         }
1153
1154         // Create color attachment view
1155         {
1156                 const VkImageViewCreateInfo colorAttachmentViewParams =
1157                 {
1158                         VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,       // VkStructureType          sType;
1159                         DE_NULL,                                        // const void*              pNext;
1160                         0u,                                             // VkImageViewCreateFlags   flags;
1161                         *m_colorImage,                                  // VkImage                  image;
1162                         VK_IMAGE_VIEW_TYPE_2D,                          // VkImageViewType          viewType;
1163                         colorFormat,                                    // VkFormat                 format;
1164                         ComponentMappingRGBA,                           // VkComponentMapping       components;
1165                         { VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u },  // VkImageSubresourceRange  subresourceRange;
1166                 };
1167
1168                 m_colorAttachmentView = createImageView(vk, vkDevice, &colorAttachmentViewParams);
1169         }
1170
1171         // Create depth attachment view
1172         {
1173                 const VkImageViewCreateInfo depthAttachmentViewParams =
1174                 {
1175                         VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,       // VkStructureType          sType;
1176                         DE_NULL,                                        // const void*              pNext;
1177                         0u,                                             // VkImageViewCreateFlags   flags;
1178                         *m_depthImage,                                  // VkImage                  image;
1179                         VK_IMAGE_VIEW_TYPE_2D,                          // VkImageViewType          viewType;
1180                         depthFormat,                                    // VkFormat                 format;
1181                         ComponentMappingRGBA,                           // VkComponentMapping       components;
1182                         { VK_IMAGE_ASPECT_DEPTH_BIT, 0u, 1u, 0u, 1u },  // VkImageSubresourceRange  subresourceRange;
1183                 };
1184
1185                 m_depthAttachmentView = createImageView(vk, vkDevice, &depthAttachmentViewParams);
1186         }
1187
1188         // Create framebuffer
1189         {
1190                 const VkImageView attachmentBindInfos[2] =
1191                 {
1192                         *m_colorAttachmentView,
1193                         *m_depthAttachmentView,
1194                 };
1195
1196                 const VkFramebufferCreateInfo framebufferParams =
1197                 {
1198                         VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,          // VkStructureType              sType;
1199                         DE_NULL,                                            // const void*                  pNext;
1200                         0u,                                                 // VkFramebufferCreateFlags     flags;
1201                         *m_renderPass,                                      // VkRenderPass                 renderPass;
1202                         2u,                                                 // deUint32                     attachmentCount;
1203                         attachmentBindInfos,                                // const VkImageView*           pAttachments;
1204                         (deUint32)renderSize.x(),                           // deUint32                     width;
1205                         (deUint32)renderSize.y(),                           // deUint32                     height;
1206                         1u,                                                 // deUint32                     layers;
1207                 };
1208
1209                 m_framebuffer = createFramebuffer(vk, vkDevice, &framebufferParams);
1210         }
1211
1212 }
1213
1214 BasicGraphicsTestInstance::BasicGraphicsTestInstance(Context&              context,
1215                                                                                                          const StageFlagVector stages,
1216                                                                                                          const bool            inRenderPass)
1217                                                                                                          : TimestampTestInstance (context,stages,inRenderPass)
1218                                                                                                          , m_renderSize  (32, 32)
1219                                                                                                          , m_colorFormat (VK_FORMAT_R8G8B8A8_UNORM)
1220                                                                                                          , m_depthFormat (VK_FORMAT_D16_UNORM)
1221                                                                                                          , m_pipelineBuilder (context)
1222 {
1223         buildVertexBuffer();
1224
1225         buildRenderPass(m_colorFormat, m_depthFormat);
1226
1227         buildFrameBuffer(m_renderSize, m_colorFormat, m_depthFormat);
1228
1229         m_pipelineBuilder.bindShaderStage(VK_SHADER_STAGE_VERTEX_BIT, "color_vert", "main");
1230         m_pipelineBuilder.bindShaderStage(VK_SHADER_STAGE_FRAGMENT_BIT, "color_frag", "main");
1231
1232         m_graphicsPipelines = m_pipelineBuilder.buildPipeline(m_renderSize, *m_renderPass);
1233
1234 }
1235
1236 BasicGraphicsTestInstance::~BasicGraphicsTestInstance(void)
1237 {
1238 }
1239
1240 void BasicGraphicsTestInstance::configCommandBuffer(void)
1241 {
1242         const DeviceInterface&      vk                  = m_context.getDeviceInterface();
1243
1244         const VkCommandBufferBeginInfo cmdBufferBeginInfo =
1245         {
1246                 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,    // VkStructureType                  sType;
1247                 DE_NULL,                                        // const void*                      pNext;
1248                 0u,                                             // VkCommandBufferUsageFlags        flags;
1249                 (const VkCommandBufferInheritanceInfo*)DE_NULL,
1250         };
1251
1252         const VkClearValue attachmentClearValues[2] =
1253         {
1254                 defaultClearValue(m_colorFormat),
1255                 defaultClearValue(m_depthFormat),
1256         };
1257
1258         const VkRenderPassBeginInfo renderPassBeginInfo =
1259         {
1260                 VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,               // VkStructureType      sType;
1261                 DE_NULL,                                                // const void*          pNext;
1262                 *m_renderPass,                                          // VkRenderPass         renderPass;
1263                 *m_framebuffer,                                         // VkFramebuffer        framebuffer;
1264                 { { 0u, 0u }, { m_renderSize.x(), m_renderSize.y() } }, // VkRect2D             renderArea;
1265                 2u,                                                     // deUint32             clearValueCount;
1266                 attachmentClearValues                                   // const VkClearValue*  pClearValues;
1267         };
1268
1269         VK_CHECK(vk.beginCommandBuffer(*m_cmdBuffer, &cmdBufferBeginInfo));
1270
1271         vk.cmdResetQueryPool(*m_cmdBuffer, *m_queryPool, 0u, TimestampTest::ENTRY_COUNT);
1272
1273         vk.cmdBeginRenderPass(*m_cmdBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
1274
1275         vk.cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_graphicsPipelines);
1276         VkDeviceSize offsets = 0u;
1277         vk.cmdBindVertexBuffers(*m_cmdBuffer, 0u, 1u, &m_vertexBuffer.get(), &offsets);
1278         vk.cmdDraw(*m_cmdBuffer, (deUint32)m_vertices.size(), 1u, 0u, 0u);
1279
1280         if(m_inRenderPass)
1281         {
1282           deUint32 timestampEntry = 0u;
1283           for (StageFlagVector::const_iterator it = m_stages.begin(); it != m_stages.end(); it++)
1284           {
1285                   vk.cmdWriteTimestamp(*m_cmdBuffer, *it, *m_queryPool, timestampEntry++);
1286           }
1287         }
1288
1289         vk.cmdEndRenderPass(*m_cmdBuffer);
1290
1291         if(!m_inRenderPass)
1292         {
1293           deUint32 timestampEntry = 0u;
1294           for (StageFlagVector::const_iterator it = m_stages.begin(); it != m_stages.end(); it++)
1295           {
1296                   vk.cmdWriteTimestamp(*m_cmdBuffer, *it, *m_queryPool, timestampEntry++);
1297           }
1298         }
1299
1300         VK_CHECK(vk.endCommandBuffer(*m_cmdBuffer));
1301 }
1302
1303 class AdvGraphicsTest : public BasicGraphicsTest
1304 {
1305 public:
1306                                                   AdvGraphicsTest  (tcu::TestContext&         testContext,
1307                                                                                         const std::string&        name,
1308                                                                                         const std::string&        description,
1309                                                                                         const TimestampTestParam* param)
1310                                                           : BasicGraphicsTest(testContext, name, description, param)
1311                                                           { }
1312         virtual               ~AdvGraphicsTest (void) { }
1313         virtual void          initPrograms     (SourceCollections&        programCollection) const;
1314         virtual TestInstance* createInstance   (Context&                  context) const;
1315 };
1316
1317 class AdvGraphicsTestInstance : public BasicGraphicsTestInstance
1318 {
1319 public:
1320                                  AdvGraphicsTestInstance  (Context&              context,
1321                                                                                    const StageFlagVector stages,
1322                                                                                    const bool            inRenderPass);
1323         virtual      ~AdvGraphicsTestInstance (void);
1324         virtual void configCommandBuffer      (void);
1325 protected:
1326         virtual void featureSupportCheck      (void);
1327 protected:
1328         VkPhysicalDeviceFeatures m_features;
1329         deUint32                 m_draw_count;
1330         Move<VkBuffer>           m_indirectBuffer;
1331 };
1332
1333 void AdvGraphicsTest::initPrograms(SourceCollections& programCollection) const
1334 {
1335         BasicGraphicsTest::initPrograms(programCollection);
1336
1337         programCollection.glslSources.add("dummy_geo") << glu::GeometrySource(
1338                 "#version 450 \n"
1339                 "layout (triangles) in;\n"
1340                 "layout (triangle_strip, max_vertices = 3) out;\n"
1341                 "void main (void)\n"
1342                 "{\n"
1343                 "  for(int ndx=0; ndx<3; ndx++)\n"
1344                 "  {\n"
1345                 "    gl_Position = gl_in[ndx].gl_Position;\n"
1346                 "    EmitVertex();\n"
1347                 "  }\n"
1348                 "  EndPrimitive();\n"
1349                 "}\n");
1350
1351         programCollection.glslSources.add("basic_tcs") << glu::TessellationControlSource(
1352                 "#version 450 \n"
1353                 "layout(vertices = 3) out;\n"
1354                 "in highp vec4 color[];\n"
1355                 "out highp vec4 vtxColor[];\n"
1356                 "void main()\n"
1357                 "{\n"
1358                 "  gl_TessLevelOuter[0] = 4.0;\n"
1359                 "  gl_TessLevelOuter[1] = 4.0;\n"
1360                 "  gl_TessLevelOuter[2] = 4.0;\n"
1361                 "  gl_TessLevelInner[0] = 4.0;\n"
1362                 "  gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;\n"
1363                 "  vtxColor[gl_InvocationID] = color[gl_InvocationID];\n"
1364                 "}\n");
1365
1366         programCollection.glslSources.add("basic_tes") << glu::TessellationEvaluationSource(
1367                 "#version 450 \n"
1368                 "layout(triangles, fractional_even_spacing, ccw) in;\n"
1369                 "in highp vec4 colors[];\n"
1370                 "out highp vec4 vtxColor;\n"
1371                 "void main() \n"
1372                 "{\n"
1373                 "  float u = gl_TessCoord.x;\n"
1374                 "  float v = gl_TessCoord.y;\n"
1375                 "  float w = gl_TessCoord.z;\n"
1376                 "  vec4 pos = vec4(0);\n"
1377                 "  vec4 color = vec4(0);\n"
1378                 "  pos.xyz += u * gl_in[0].gl_Position.xyz;\n"
1379                 "  color.xyz += u * colors[0].xyz;\n"
1380                 "  pos.xyz += v * gl_in[1].gl_Position.xyz;\n"
1381                 "  color.xyz += v * colors[1].xyz;\n"
1382                 "  pos.xyz += w * gl_in[2].gl_Position.xyz;\n"
1383                 "  color.xyz += w * colors[2].xyz;\n"
1384                 "  pos.w = 1.0;\n"
1385                 "  color.w = 1.0;\n"
1386                 "  gl_Position = pos;\n"
1387                 "  vtxColor = color;\n"
1388                 "}\n");
1389 }
1390
1391 TestInstance* AdvGraphicsTest::createInstance(Context& context) const
1392 {
1393         return new AdvGraphicsTestInstance(context,m_stages,m_inRenderPass);
1394 }
1395
1396 void AdvGraphicsTestInstance::featureSupportCheck(void)
1397 {
1398         for (StageFlagVector::const_iterator it = m_stages.begin(); it != m_stages.end(); it++)
1399         {
1400                 switch(*it)
1401                 {
1402                         case VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT:
1403                                 if (m_features.geometryShader == VK_FALSE)
1404                                 {
1405                                         TCU_THROW(NotSupportedError, "Geometry Shader Not Supported");
1406                                 }
1407                                 break;
1408                         case VK_PIPELINE_STAGE_TESSELLATION_CONTROL_SHADER_BIT:
1409                         case VK_PIPELINE_STAGE_TESSELLATION_EVALUATION_SHADER_BIT:
1410                                 if (m_features.tessellationShader == VK_FALSE)
1411                                 {
1412                                         TCU_THROW(NotSupportedError, "Tessellation Not Supported");
1413                                 }
1414                                 break;
1415                         case VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT:
1416                         default:
1417                                 break;
1418                 };
1419         }
1420 }
1421
1422 AdvGraphicsTestInstance::AdvGraphicsTestInstance(Context&              context,
1423                                                                                                  const StageFlagVector stages,
1424                                                                                                  const bool            inRenderPass)
1425         : BasicGraphicsTestInstance(context, stages, inRenderPass)
1426 {
1427         m_features = m_context.getDeviceFeatures();
1428
1429         // If necessary feature is not supported, throw error and fail current test
1430         featureSupportCheck();
1431
1432         if(m_features.geometryShader == VK_TRUE)
1433         {
1434                 m_pipelineBuilder.bindShaderStage(VK_SHADER_STAGE_GEOMETRY_BIT, "dummy_geo", "main");
1435         }
1436
1437         if(m_features.tessellationShader == VK_TRUE)
1438         {
1439                 m_pipelineBuilder.bindShaderStage(VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, "basic_tcs", "main");
1440                 m_pipelineBuilder.bindShaderStage(VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT, "basic_tes", "main");
1441                 m_pipelineBuilder.enableTessellationStage(3);
1442         }
1443
1444         m_graphicsPipelines = m_pipelineBuilder.buildPipeline(m_renderSize, *m_renderPass);
1445
1446         // Prepare the indirect draw buffer
1447         const DeviceInterface&      vk                  = m_context.getDeviceInterface();
1448         const VkDevice              vkDevice            = m_context.getDevice();
1449
1450         if(m_features.multiDrawIndirect == VK_TRUE)
1451         {
1452                 m_draw_count = 2;
1453         }
1454         else
1455         {
1456                 m_draw_count = 1;
1457         }
1458         de::MovePtr<Allocation>     bufferAlloc;
1459         m_indirectBuffer = createBufferAndBindMemory(32u, VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT, &bufferAlloc);
1460
1461         const VkDrawIndirectCommand indirectCmds[] =
1462         {
1463                 {
1464                         12u,                    // deUint32    vertexCount;
1465                         1u,                     // deUint32    instanceCount;
1466                         0u,                     // deUint32    firstVertex;
1467                         0u,                     // deUint32    firstInstance;
1468                 },
1469                 {
1470                         12u,                    // deUint32    vertexCount;
1471                         1u,                     // deUint32    instanceCount;
1472                         11u,                    // deUint32    firstVertex;
1473                         0u,                     // deUint32    firstInstance;
1474                 },
1475         };
1476         // Load data into indirect draw buffer
1477         deMemcpy(bufferAlloc->getHostPtr(), indirectCmds, m_draw_count * sizeof(VkDrawIndirectCommand));
1478         flushMappedMemoryRange(vk, vkDevice, bufferAlloc->getMemory(), bufferAlloc->getOffset(), 32u);
1479
1480 }
1481
1482 AdvGraphicsTestInstance::~AdvGraphicsTestInstance(void)
1483 {
1484 }
1485
1486 void AdvGraphicsTestInstance::configCommandBuffer(void)
1487 {
1488         const DeviceInterface&      vk                  = m_context.getDeviceInterface();
1489
1490         const VkCommandBufferBeginInfo cmdBufferBeginInfo =
1491         {
1492                 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,    // VkStructureType              sType;
1493                 DE_NULL,                                        // const void*                  pNext;
1494                 0u,                                             // VkCommandBufferUsageFlags    flags;
1495                 (const VkCommandBufferInheritanceInfo*)DE_NULL,
1496         };
1497
1498         const VkClearValue attachmentClearValues[2] =
1499         {
1500                 defaultClearValue(m_colorFormat),
1501                 defaultClearValue(m_depthFormat),
1502         };
1503
1504         const VkRenderPassBeginInfo renderPassBeginInfo =
1505         {
1506                 VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,               // VkStructureType      sType;
1507                 DE_NULL,                                                // const void*          pNext;
1508                 *m_renderPass,                                          // VkRenderPass         renderPass;
1509                 *m_framebuffer,                                         // VkFramebuffer        framebuffer;
1510                 { { 0u, 0u }, { m_renderSize.x(), m_renderSize.y() } }, // VkRect2D             renderArea;
1511                 2u,                                                     // deUint32             clearValueCount;
1512                 attachmentClearValues                                   // const VkClearValue*  pClearValues;
1513         };
1514
1515         VK_CHECK(vk.beginCommandBuffer(*m_cmdBuffer, &cmdBufferBeginInfo));
1516
1517         vk.cmdResetQueryPool(*m_cmdBuffer, *m_queryPool, 0u, TimestampTest::ENTRY_COUNT);
1518
1519         vk.cmdBeginRenderPass(*m_cmdBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
1520
1521         vk.cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_graphicsPipelines);
1522
1523         VkDeviceSize offsets = 0u;
1524         vk.cmdBindVertexBuffers(*m_cmdBuffer, 0u, 1u, &m_vertexBuffer.get(), &offsets);
1525
1526         vk.cmdDrawIndirect(*m_cmdBuffer, *m_indirectBuffer, 0u, m_draw_count, sizeof(VkDrawIndirectCommand));
1527
1528         if(m_inRenderPass)
1529         {
1530           deUint32 timestampEntry = 0u;
1531           for (StageFlagVector::const_iterator it = m_stages.begin(); it != m_stages.end(); it++)
1532           {
1533                   vk.cmdWriteTimestamp(*m_cmdBuffer, *it, *m_queryPool, timestampEntry++);
1534           }
1535         }
1536
1537         vk.cmdEndRenderPass(*m_cmdBuffer);
1538
1539         if(!m_inRenderPass)
1540         {
1541           deUint32 timestampEntry = 0u;
1542           for (StageFlagVector::const_iterator it = m_stages.begin(); it != m_stages.end(); it++)
1543           {
1544                   vk.cmdWriteTimestamp(*m_cmdBuffer, *it, *m_queryPool, timestampEntry++);
1545           }
1546         }
1547
1548         VK_CHECK(vk.endCommandBuffer(*m_cmdBuffer));
1549
1550 }
1551
1552 class BasicComputeTest : public TimestampTest
1553 {
1554 public:
1555                                                   BasicComputeTest  (tcu::TestContext&         testContext,
1556                                                                                          const std::string&        name,
1557                                                                                          const std::string&        description,
1558                                                                                          const TimestampTestParam* param)
1559                                                           : TimestampTest(testContext, name, description, param)
1560                                                           { }
1561         virtual               ~BasicComputeTest (void) { }
1562         virtual void          initPrograms      (SourceCollections&        programCollection) const;
1563         virtual TestInstance* createInstance    (Context&                  context) const;
1564 };
1565
1566 class BasicComputeTestInstance : public TimestampTestInstance
1567 {
1568 public:
1569                                  BasicComputeTestInstance  (Context&              context,
1570                                                                                         const StageFlagVector stages,
1571                                                                                         const bool            inRenderPass);
1572         virtual      ~BasicComputeTestInstance (void);
1573         virtual void configCommandBuffer       (void);
1574 protected:
1575         Move<VkBuffer>              m_inputBuf;
1576         Move<VkBuffer>              m_outputBuf;
1577
1578         Move<VkDescriptorPool>      m_descriptorPool;
1579         Move<VkDescriptorSet>       m_descriptorSet;
1580         Move<VkDescriptorSetLayout> m_descriptorSetLayout;
1581
1582         Move<VkPipelineLayout>      m_pipelineLayout;
1583         Move<VkShaderModule>        m_computeShaderModule;
1584         Move<VkPipeline>            m_computePipelines;
1585 };
1586
1587 void BasicComputeTest::initPrograms(SourceCollections& programCollection) const
1588 {
1589         TimestampTest::initPrograms(programCollection);
1590
1591         programCollection.glslSources.add("basic_compute") << glu::ComputeSource(
1592                 "#version 310 es\n"
1593                 "layout(local_size_x = 128) in;\n"
1594                 "layout(std430) buffer;\n"
1595                 "layout(binding = 0) readonly buffer Input0\n"
1596                 "{\n"
1597                 "  vec4 elements[];\n"
1598                 "} input_data0;\n"
1599                 "layout(binding = 1) writeonly buffer Output\n"
1600                 "{\n"
1601                 "  vec4 elements[];\n"
1602                 "} output_data;\n"
1603                 "void main()\n"
1604                 "{\n"
1605                 "  uint ident = gl_GlobalInvocationID.x;\n"
1606                 "  output_data.elements[ident] = input_data0.elements[ident] * input_data0.elements[ident];\n"
1607                 "}");
1608 }
1609
1610 TestInstance* BasicComputeTest::createInstance(Context& context) const
1611 {
1612         return new BasicComputeTestInstance(context,m_stages,m_inRenderPass);
1613 }
1614
1615 BasicComputeTestInstance::BasicComputeTestInstance(Context&              context,
1616                                                                                                    const StageFlagVector stages,
1617                                                                                                    const bool            inRenderPass)
1618         : TimestampTestInstance(context, stages, inRenderPass)
1619 {
1620         const DeviceInterface&      vk                  = context.getDeviceInterface();
1621         const VkDevice              vkDevice            = context.getDevice();
1622
1623         // Create buffer object, allocate storage, and generate input data
1624         const VkDeviceSize          size                = sizeof(tcu::Vec4) * 128u;
1625         de::MovePtr<Allocation>     bufferAlloc;
1626         m_inputBuf = createBufferAndBindMemory(size, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, &bufferAlloc);
1627         // Load vertices into buffer
1628         tcu::Vec4* pVec = reinterpret_cast<tcu::Vec4*>(bufferAlloc->getHostPtr());
1629         for (deUint32 ndx = 0u; ndx < 128u; ndx++)
1630         {
1631                 for (deUint32 component = 0u; component < 4u; component++)
1632                 {
1633                         pVec[ndx][component]= (float)(ndx * (component + 1u));
1634                 }
1635         }
1636         flushMappedMemoryRange(vk, vkDevice, bufferAlloc->getMemory(), bufferAlloc->getOffset(), size);
1637
1638         de::MovePtr<Allocation> dummyAlloc;
1639         m_outputBuf = createBufferAndBindMemory(size, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, &dummyAlloc);
1640
1641         std::vector<VkDescriptorBufferInfo>        descriptorInfos;
1642         descriptorInfos.push_back(makeDescriptorBufferInfo(*m_inputBuf, 0u, sizeof(tcu::Vec4) * 128u));
1643         descriptorInfos.push_back(makeDescriptorBufferInfo(*m_outputBuf, 0u, sizeof(tcu::Vec4) * 128u));
1644
1645         // Create descriptor set layout
1646         DescriptorSetLayoutBuilder descLayoutBuilder;
1647
1648         for (deUint32 bindingNdx = 0u; bindingNdx < 2u; bindingNdx++)
1649         {
1650                 descLayoutBuilder.addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_SHADER_STAGE_COMPUTE_BIT);
1651         }
1652
1653         m_descriptorSetLayout = descLayoutBuilder.build(vk, vkDevice);
1654
1655         // Create descriptor pool
1656         m_descriptorPool = DescriptorPoolBuilder().addType(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 2).build(vk, vkDevice, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u);
1657
1658         // Create descriptor set
1659         const VkDescriptorSetAllocateInfo descriptorSetAllocInfo =
1660         {
1661                 VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,     // VkStructureType                 sType;
1662                 DE_NULL,                                            // const void*                     pNext;
1663                 *m_descriptorPool,                                  // VkDescriptorPool                descriptorPool;
1664                 1u,                                                 // deUint32                        setLayoutCount;
1665                 &m_descriptorSetLayout.get(),                       // const VkDescriptorSetLayout*    pSetLayouts;
1666         };
1667         m_descriptorSet   = allocateDescriptorSet(vk, vkDevice, &descriptorSetAllocInfo);
1668
1669         DescriptorSetUpdateBuilder  builder;
1670         for (deUint32 descriptorNdx = 0u; descriptorNdx < 2u; descriptorNdx++)
1671         {
1672                 builder.writeSingle(*m_descriptorSet, DescriptorSetUpdateBuilder::Location::binding(descriptorNdx), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &descriptorInfos[descriptorNdx]);
1673         }
1674         builder.update(vk, vkDevice);
1675
1676         // Create compute pipeline layout
1677         const VkPipelineLayoutCreateInfo pipelineLayoutCreateInfo =
1678         {
1679                 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,  // VkStructureType                 sType;
1680                 DE_NULL,                                        // const void*                     pNext;
1681                 0u,                                             // VkPipelineLayoutCreateFlags     flags;
1682                 1u,                                             // deUint32                        setLayoutCount;
1683                 &m_descriptorSetLayout.get(),                   // const VkDescriptorSetLayout*    pSetLayouts;
1684                 0u,                                             // deUint32                        pushConstantRangeCount;
1685                 DE_NULL,                                        // const VkPushConstantRange*      pPushConstantRanges;
1686         };
1687
1688         m_pipelineLayout = createPipelineLayout(vk, vkDevice, &pipelineLayoutCreateInfo);
1689
1690         // Create compute shader
1691         VkShaderModuleCreateInfo shaderModuleCreateInfo =
1692         {
1693                 VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO,                        // VkStructureType             sType;
1694                 DE_NULL,                                                            // const void*                 pNext;
1695                 0u,                                                                 // VkShaderModuleCreateFlags   flags;
1696                 m_context.getBinaryCollection().get("basic_compute").getSize(),     // deUintptr                   codeSize;
1697                 (deUint32*)m_context.getBinaryCollection().get("basic_compute").getBinary(),   // const deUint32*             pCode;
1698
1699         };
1700
1701         m_computeShaderModule = createShaderModule(vk, vkDevice, &shaderModuleCreateInfo);
1702
1703         // Create compute pipeline
1704         const VkPipelineShaderStageCreateInfo stageCreateInfo =
1705         {
1706                 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType                     sType;
1707                 DE_NULL,                                             // const void*                         pNext;
1708                 0u,                                                  // VkPipelineShaderStageCreateFlags    flags;
1709                 VK_SHADER_STAGE_COMPUTE_BIT,                         // VkShaderStageFlagBits               stage;
1710                 *m_computeShaderModule,                              // VkShaderModule                      module;
1711                 "main",                                              // const char*                         pName;
1712                 DE_NULL,                                             // const VkSpecializationInfo*         pSpecializationInfo;
1713         };
1714
1715         const VkComputePipelineCreateInfo pipelineCreateInfo =
1716         {
1717                 VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO,      // VkStructureType                 sType;
1718                 DE_NULL,                                             // const void*                     pNext;
1719                 0u,                                                  // VkPipelineCreateFlags           flags;
1720                 stageCreateInfo,                                     // VkPipelineShaderStageCreateInfo stage;
1721                 *m_pipelineLayout,                                   // VkPipelineLayout                layout;
1722                 (VkPipeline)0,                                       // VkPipeline                      basePipelineHandle;
1723                 0u,                                                  // deInt32                         basePipelineIndex;
1724         };
1725
1726         m_computePipelines = createComputePipeline(vk, vkDevice, (VkPipelineCache)0u, &pipelineCreateInfo);
1727
1728 }
1729
1730 BasicComputeTestInstance::~BasicComputeTestInstance(void)
1731 {
1732 }
1733
1734 void BasicComputeTestInstance::configCommandBuffer(void)
1735 {
1736         const DeviceInterface&     vk                 = m_context.getDeviceInterface();
1737
1738         const VkCommandBufferBeginInfo cmdBufferBeginInfo =
1739         {
1740                 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,    // VkStructureType          sType;
1741                 DE_NULL,                                        // const void*              pNext;
1742                 0u,                                             // VkCmdBufferOptimizeFlags flags;
1743                 (const VkCommandBufferInheritanceInfo*)DE_NULL,
1744
1745         };
1746
1747         VK_CHECK(vk.beginCommandBuffer(*m_cmdBuffer, &cmdBufferBeginInfo));
1748
1749         vk.cmdResetQueryPool(*m_cmdBuffer, *m_queryPool, 0u, TimestampTest::ENTRY_COUNT);
1750
1751         vk.cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *m_computePipelines);
1752         vk.cmdBindDescriptorSets(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *m_pipelineLayout, 0u, 1u, &m_descriptorSet.get(), 0u, DE_NULL);
1753         vk.cmdDispatch(*m_cmdBuffer, 128u, 1u, 1u);
1754
1755         deUint32 timestampEntry = 0u;
1756         for (StageFlagVector::const_iterator it = m_stages.begin(); it != m_stages.end(); it++)
1757         {
1758                 vk.cmdWriteTimestamp(*m_cmdBuffer, *it, *m_queryPool, timestampEntry++);
1759         }
1760
1761         VK_CHECK(vk.endCommandBuffer(*m_cmdBuffer));
1762
1763
1764 }
1765
1766 class TransferTest : public TimestampTest
1767 {
1768 public:
1769                                                   TransferTest   (tcu::TestContext&          testContext,
1770                                                                                   const std::string&         name,
1771                                                                                   const std::string&         description,
1772                                                                                   const TimestampTestParam*  param);
1773         virtual               ~TransferTest  (void) { }
1774         virtual void          initPrograms   (SourceCollections&         programCollection) const;
1775         virtual TestInstance* createInstance (Context&                   context) const;
1776 protected:
1777         TransferMethod        m_method;
1778 };
1779
1780 class TransferTestInstance : public TimestampTestInstance
1781 {
1782 public:
1783                                         TransferTestInstance  (Context&              context,
1784                                                                                    const StageFlagVector stages,
1785                                                                                    const bool            inRenderPass,
1786                                                                                    const TransferMethod  method);
1787         virtual         ~TransferTestInstance (void);
1788         virtual void    configCommandBuffer   (void);
1789 protected:
1790         TransferMethod  m_method;
1791
1792         VkDeviceSize    m_bufSize;
1793         Move<VkBuffer>  m_srcBuffer;
1794         Move<VkBuffer>  m_dstBuffer;
1795
1796         VkFormat        m_imageFormat;
1797         deUint32        m_imageWidth;
1798         deUint32        m_imageHeight;
1799         VkDeviceSize    m_imageSize;
1800         Move<VkImage>   m_srcImage;
1801         Move<VkImage>   m_dstImage;
1802         Move<VkImage>   m_depthImage;
1803         Move<VkImage>   m_msImage;
1804 };
1805
1806 TransferTest::TransferTest(tcu::TestContext&                 testContext,
1807                                                    const std::string&                name,
1808                                                    const std::string&                description,
1809                                                    const TimestampTestParam*         param)
1810         : TimestampTest(testContext, name, description, param)
1811 {
1812         const TransferTimestampTestParam* transferParam = dynamic_cast<const TransferTimestampTestParam*>(param);
1813         m_method = transferParam->getMethod();
1814 }
1815
1816 void TransferTest::initPrograms(SourceCollections& programCollection) const
1817 {
1818         TimestampTest::initPrograms(programCollection);
1819 }
1820
1821 TestInstance* TransferTest::createInstance(Context& context) const
1822 {
1823   return new TransferTestInstance(context, m_stages, m_inRenderPass, m_method);
1824 }
1825
1826 TransferTestInstance::TransferTestInstance(Context&              context,
1827                                                                                    const StageFlagVector stages,
1828                                                                                    const bool            inRenderPass,
1829                                                                                    const TransferMethod  method)
1830         : TimestampTestInstance(context, stages, inRenderPass)
1831         , m_method(method)
1832         , m_bufSize(256u)
1833         , m_imageFormat(VK_FORMAT_R32G32B32A32_SFLOAT)
1834         , m_imageWidth(4u)
1835         , m_imageHeight(4u)
1836         , m_imageSize(256u)
1837 {
1838         const DeviceInterface&      vk                  = context.getDeviceInterface();
1839         const VkDevice              vkDevice            = context.getDevice();
1840
1841         // Create src buffer
1842         de::MovePtr<Allocation>     bufferAlloc;
1843         m_srcBuffer = createBufferAndBindMemory(m_bufSize, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_SRC_BIT, &bufferAlloc);
1844
1845         // Init the source buffer memory
1846         char* pBuf = reinterpret_cast<char*>(bufferAlloc->getHostPtr());
1847         memset(pBuf, 0xFF, sizeof(char)*(size_t)m_bufSize);
1848         flushMappedMemoryRange(vk, vkDevice, bufferAlloc->getMemory(), bufferAlloc->getOffset(), m_bufSize);
1849
1850         // Create dst buffer
1851         de::MovePtr<Allocation>     dummyAlloc;
1852         m_dstBuffer = createBufferAndBindMemory(m_bufSize, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT, &dummyAlloc);
1853
1854         // Create src/dst/depth image
1855         m_srcImage   = createImage2DAndBindMemory(m_imageFormat, m_imageWidth, m_imageHeight,
1856                                                                                           VK_IMAGE_USAGE_STORAGE_BIT | VK_BUFFER_USAGE_TRANSFER_SRC_BIT,
1857                                                                                           VK_SAMPLE_COUNT_1_BIT,
1858                                                                                           &dummyAlloc);
1859         m_dstImage   = createImage2DAndBindMemory(m_imageFormat, m_imageWidth, m_imageHeight,
1860                                                                                           VK_IMAGE_USAGE_STORAGE_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT,
1861                                                                                           VK_SAMPLE_COUNT_1_BIT,
1862                                                                                           &dummyAlloc);
1863         m_depthImage = createImage2DAndBindMemory(VK_FORMAT_D16_UNORM, m_imageWidth, m_imageHeight,
1864                                                                                           VK_IMAGE_USAGE_STORAGE_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT,
1865                                                                                           VK_SAMPLE_COUNT_1_BIT,
1866                                                                                           &dummyAlloc);
1867         m_msImage    = createImage2DAndBindMemory(m_imageFormat, m_imageWidth, m_imageHeight,
1868                                                                                           VK_IMAGE_USAGE_STORAGE_BIT | VK_BUFFER_USAGE_TRANSFER_SRC_BIT,
1869                                                                                           VK_SAMPLE_COUNT_4_BIT,
1870                                                                                           &dummyAlloc);
1871 }
1872
1873 TransferTestInstance::~TransferTestInstance(void)
1874 {
1875 }
1876
1877 void TransferTestInstance::configCommandBuffer(void)
1878 {
1879         const DeviceInterface&      vk                  = m_context.getDeviceInterface();
1880
1881         const VkCommandBufferBeginInfo cmdBufferBeginInfo =
1882         {
1883                 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,    // VkStructureType                  sType;
1884                 DE_NULL,                                        // const void*                      pNext;
1885                 0u,                                             // VkCmdBufferOptimizeFlags         flags;
1886                 (const VkCommandBufferInheritanceInfo*)DE_NULL,
1887         };
1888
1889         VK_CHECK(vk.beginCommandBuffer(*m_cmdBuffer, &cmdBufferBeginInfo));
1890
1891         // Initialize buffer/image
1892         vk.cmdFillBuffer(*m_cmdBuffer, *m_dstBuffer, 0u, m_bufSize, 0x0);
1893
1894         const VkClearColorValue srcClearValue =
1895         {
1896                 {1.0f, 1.0f, 1.0f, 1.0f}
1897         };
1898         const VkClearColorValue dstClearValue =
1899         {
1900                 {0.0f, 0.0f, 0.0f, 0.0f}
1901         };
1902         const struct VkImageSubresourceRange subRange =
1903         {
1904                 0u,                  // VkImageAspectFlags  aspectMask;
1905                 0u,                  // deUint32            baseMipLevel;
1906                 1u,                  // deUint32            mipLevels;
1907                 0u,                  // deUint32            baseArrayLayer;
1908                 1u,                  // deUint32            arraySize;
1909         };
1910
1911         vk.cmdClearColorImage(*m_cmdBuffer, *m_srcImage, VK_IMAGE_LAYOUT_GENERAL, &srcClearValue, 1u, &subRange);
1912         vk.cmdClearColorImage(*m_cmdBuffer, *m_dstImage, VK_IMAGE_LAYOUT_GENERAL, &dstClearValue, 1u, &subRange);
1913
1914
1915         vk.cmdResetQueryPool(*m_cmdBuffer, *m_queryPool, 0u, TimestampTest::ENTRY_COUNT);
1916
1917         // Copy Operations
1918         const VkImageSubresourceLayers imgSubResCopy =
1919         {
1920                 VK_IMAGE_ASPECT_COLOR_BIT,              // VkImageAspectFlags  aspectMask;
1921                 0u,                                     // deUint32            mipLevel;
1922                 0u,                                     // deUint32            baseArrayLayer;
1923                 1u,                                     // deUint32            layerCount;
1924         };
1925
1926         const VkOffset3D nullOffset  = {0u, 0u, 0u};
1927         const VkExtent3D imageExtent = {m_imageWidth, m_imageHeight, 1u};
1928         const VkOffset3D imageOffset = {(int)m_imageWidth, (int)m_imageHeight, 1};
1929         switch(m_method)
1930         {
1931                 case TRANSFER_METHOD_COPY_BUFFER:
1932                         {
1933                                 const VkBufferCopy  copyBufRegion =
1934                                 {
1935                                         0u,      // VkDeviceSize    srcOffset;
1936                                         0u,      // VkDeviceSize    destOffset;
1937                                         512u,    // VkDeviceSize    copySize;
1938                                 };
1939                                 vk.cmdCopyBuffer(*m_cmdBuffer, *m_srcBuffer, *m_dstBuffer, 1u, &copyBufRegion);
1940                                 break;
1941                         }
1942                 case TRANSFER_METHOD_COPY_IMAGE:
1943                         {
1944                                 const VkImageCopy copyImageRegion =
1945                                 {
1946                                         imgSubResCopy,                          // VkImageSubresourceCopy  srcSubresource;
1947                                         nullOffset,                             // VkOffset3D              srcOffset;
1948                                         imgSubResCopy,                          // VkImageSubresourceCopy  destSubresource;
1949                                         nullOffset,                             // VkOffset3D              destOffset;
1950                                         imageExtent,                            // VkExtent3D              extent;
1951
1952                                 };
1953                                 vk.cmdCopyImage(*m_cmdBuffer, *m_srcImage, VK_IMAGE_LAYOUT_GENERAL, *m_dstImage, VK_IMAGE_LAYOUT_GENERAL, 1u, &copyImageRegion);
1954                                 break;
1955                         }
1956                 case TRANSFER_METHOD_COPY_BUFFER_TO_IMAGE:
1957                         {
1958                                 const VkBufferImageCopy bufImageCopy =
1959                                 {
1960                                         0u,                                     // VkDeviceSize            bufferOffset;
1961                                         (deUint32)m_bufSize,                    // deUint32                bufferRowLength;
1962                                         (deUint32)m_imageHeight,                // deUint32                bufferImageHeight;
1963                                         imgSubResCopy,                          // VkImageSubresourceCopy  imageSubresource;
1964                                         nullOffset,                             // VkOffset3D              imageOffset;
1965                                         imageExtent,                            // VkExtent3D              imageExtent;
1966                                 };
1967                                 vk.cmdCopyBufferToImage(*m_cmdBuffer, *m_srcBuffer, *m_dstImage, VK_IMAGE_LAYOUT_GENERAL, 1u, &bufImageCopy);
1968                                 break;
1969                         }
1970                 case TRANSFER_METHOD_COPY_IMAGE_TO_BUFFER:
1971                         {
1972                                 const VkBufferImageCopy imgBufferCopy =
1973                                 {
1974                                         0u,                                     // VkDeviceSize            bufferOffset;
1975                                         (deUint32)m_bufSize,                    // deUint32                bufferRowLength;
1976                                         (deUint32)m_imageHeight,                // deUint32                bufferImageHeight;
1977                                         imgSubResCopy,                          // VkImageSubresourceCopy  imageSubresource;
1978                                         nullOffset,                             // VkOffset3D              imageOffset;
1979                                         imageExtent,                            // VkExtent3D              imageExtent;
1980                                 };
1981                                 vk.cmdCopyImageToBuffer(*m_cmdBuffer, *m_srcImage, VK_IMAGE_LAYOUT_GENERAL, *m_dstBuffer, 1u, &imgBufferCopy);
1982                                 break;
1983                         }
1984                 case TRANSFER_METHOD_BLIT_IMAGE:
1985                         {
1986                                 const VkImageBlit imageBlt =
1987                                 {
1988                                         imgSubResCopy,                          // VkImageSubresourceCopy  srcSubresource;
1989                                         {
1990                                                 nullOffset,
1991                                                 imageOffset,
1992                                         },
1993                                         imgSubResCopy,                          // VkImageSubresourceCopy  destSubresource;
1994                                         {
1995                                                 nullOffset,
1996                                                 imageOffset,
1997                                         }
1998                                 };
1999                                 vk.cmdBlitImage(*m_cmdBuffer, *m_srcImage, VK_IMAGE_LAYOUT_GENERAL, *m_dstImage, VK_IMAGE_LAYOUT_GENERAL, 1u, &imageBlt, VK_FILTER_NEAREST);
2000                                 break;
2001                         }
2002                 case TRANSFER_METHOD_CLEAR_COLOR_IMAGE:
2003                         {
2004                                 vk.cmdClearColorImage(*m_cmdBuffer, *m_dstImage, VK_IMAGE_LAYOUT_GENERAL, &srcClearValue, 1u, &subRange);
2005                                 break;
2006                         }
2007                 case TRANSFER_METHOD_CLEAR_DEPTH_STENCIL_IMAGE:
2008                         {
2009                                 const VkClearDepthStencilValue clearDSValue =
2010                                 {
2011                                         1.0f,                                   // float       depth;
2012                                         0u,                                     // deUint32    stencil;
2013                                 };
2014                                 vk.cmdClearDepthStencilImage(*m_cmdBuffer, *m_depthImage, VK_IMAGE_LAYOUT_GENERAL, &clearDSValue, 1u, &subRange);
2015                                 break;
2016                         }
2017                 case TRANSFER_METHOD_FILL_BUFFER:
2018                         {
2019                                 vk.cmdFillBuffer(*m_cmdBuffer, *m_dstBuffer, 0u, m_bufSize, 0x0);
2020                                 break;
2021                         }
2022                 case TRANSFER_METHOD_UPDATE_BUFFER:
2023                         {
2024                                 const deUint32 data[] =
2025                                 {
2026                                         0xdeadbeef, 0xabcdef00, 0x12345678
2027                                 };
2028                                 vk.cmdUpdateBuffer(*m_cmdBuffer, *m_dstBuffer, 0x10, sizeof(data), data);
2029                                 break;
2030                         }
2031                 case TRANSFER_METHOD_COPY_QUERY_POOL_RESULTS:
2032                         {
2033                                 vk.cmdWriteTimestamp(*m_cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, *m_queryPool, 0u);
2034                                 vk.cmdCopyQueryPoolResults(*m_cmdBuffer, *m_queryPool, 0u, 1u, *m_dstBuffer, 0u, 8u, VK_QUERY_RESULT_64_BIT | VK_QUERY_RESULT_WAIT_BIT);
2035                                 vk.cmdResetQueryPool(*m_cmdBuffer, *m_queryPool, 0u, 1u);
2036                                 break;
2037                         }
2038                 case TRANSFER_METHOD_RESOLVE_IMAGE:
2039                         {
2040                                 const VkImageResolve imageResolve =
2041                                 {
2042                                         imgSubResCopy,                              // VkImageSubresourceLayers  srcSubresource;
2043                                         nullOffset,                                 // VkOffset3D                srcOffset;
2044                                         imgSubResCopy,                              // VkImageSubresourceLayers  destSubresource;
2045                                         nullOffset,                                 // VkOffset3D                destOffset;
2046                                         imageExtent,                                // VkExtent3D                extent;
2047                                 };
2048                                 vk.cmdResolveImage(*m_cmdBuffer, *m_msImage, VK_IMAGE_LAYOUT_GENERAL, *m_dstImage, VK_IMAGE_LAYOUT_GENERAL, 1u, &imageResolve);
2049                                 break;
2050                         }
2051                 default:
2052                         DE_FATAL("Unknown Transfer Method!");
2053                         break;
2054         };
2055
2056         deUint32 timestampEntry = 0u;
2057         for (StageFlagVector::const_iterator it = m_stages.begin(); it != m_stages.end(); it++)
2058         {
2059                 vk.cmdWriteTimestamp(*m_cmdBuffer, *it, *m_queryPool, timestampEntry++);
2060         }
2061
2062         VK_CHECK(vk.endCommandBuffer(*m_cmdBuffer));
2063 }
2064
2065 } // anonymous
2066
2067 tcu::TestCaseGroup* createTimestampTests (tcu::TestContext& testCtx)
2068 {
2069         de::MovePtr<tcu::TestCaseGroup> timestampTests (new tcu::TestCaseGroup(testCtx, "timestamp", "timestamp tests"));
2070
2071         // Basic Graphics Tests
2072         {
2073                 de::MovePtr<tcu::TestCaseGroup> basicGraphicsTests (new tcu::TestCaseGroup(testCtx, "basic_graphics_tests", "Record timestamp in different pipeline stages of basic graphics tests"));
2074
2075                 const VkPipelineStageFlagBits basicGraphicsStages0[][2] =
2076                 {
2077                   {VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,   VK_PIPELINE_STAGE_VERTEX_INPUT_BIT},
2078                   {VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,   VK_PIPELINE_STAGE_VERTEX_SHADER_BIT},
2079                   {VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,   VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT},
2080                   {VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,   VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT},
2081                   {VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,   VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT},
2082                   {VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,   VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT},
2083                   {VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,   VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT},
2084                   {VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,   VK_PIPELINE_STAGE_ALL_COMMANDS_BIT},
2085                 };
2086                 for (deUint32 stageNdx = 0u; stageNdx < DE_LENGTH_OF_ARRAY(basicGraphicsStages0); stageNdx++)
2087                 {
2088                         TimestampTestParam param(basicGraphicsStages0[stageNdx], 2u, true);
2089                         basicGraphicsTests->addChild(newTestCase<BasicGraphicsTest>(testCtx, &param));
2090                         param.toggleInRenderPass();
2091                         basicGraphicsTests->addChild(newTestCase<BasicGraphicsTest>(testCtx, &param));
2092                 }
2093
2094                 const VkPipelineStageFlagBits basicGraphicsStages1[][3] =
2095                 {
2096                   {VK_PIPELINE_STAGE_VERTEX_SHADER_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,      VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT},
2097                   {VK_PIPELINE_STAGE_VERTEX_INPUT_BIT,  VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT},
2098                 };
2099                 for (deUint32 stageNdx = 0u; stageNdx < DE_LENGTH_OF_ARRAY(basicGraphicsStages1); stageNdx++)
2100                 {
2101                         TimestampTestParam param(basicGraphicsStages1[stageNdx], 3u, true);
2102                         basicGraphicsTests->addChild(newTestCase<BasicGraphicsTest>(testCtx, &param));
2103                         param.toggleInRenderPass();
2104                         basicGraphicsTests->addChild(newTestCase<BasicGraphicsTest>(testCtx, &param));
2105                 }
2106
2107                 timestampTests->addChild(basicGraphicsTests.release());
2108         }
2109
2110         // Advanced Graphics Tests
2111         {
2112                 de::MovePtr<tcu::TestCaseGroup> advGraphicsTests (new tcu::TestCaseGroup(testCtx, "advanced_graphics_tests", "Record timestamp in different pipeline stages of advanced graphics tests"));
2113
2114                 const VkPipelineStageFlagBits advGraphicsStages[][2] =
2115                 {
2116                         {VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT},
2117                         {VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TESSELLATION_CONTROL_SHADER_BIT},
2118                         {VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TESSELLATION_EVALUATION_SHADER_BIT},
2119                         {VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT},
2120                 };
2121                 for (deUint32 stageNdx = 0u; stageNdx < DE_LENGTH_OF_ARRAY(advGraphicsStages); stageNdx++)
2122                 {
2123                         TimestampTestParam param(advGraphicsStages[stageNdx], 2u, true);
2124                         advGraphicsTests->addChild(newTestCase<AdvGraphicsTest>(testCtx, &param));
2125                         param.toggleInRenderPass();
2126                         advGraphicsTests->addChild(newTestCase<AdvGraphicsTest>(testCtx, &param));
2127                 }
2128
2129                 timestampTests->addChild(advGraphicsTests.release());
2130         }
2131
2132         // Basic Compute Tests
2133         {
2134                 de::MovePtr<tcu::TestCaseGroup> basicComputeTests (new tcu::TestCaseGroup(testCtx, "basic_compute_tests", "Record timestamp for computer stages"));
2135
2136                 const VkPipelineStageFlagBits basicComputeStages[][2] =
2137                 {
2138                         {VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT},
2139                         {VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT},
2140                 };
2141                 for (deUint32 stageNdx = 0u; stageNdx < DE_LENGTH_OF_ARRAY(basicComputeStages); stageNdx++)
2142                 {
2143                         TimestampTestParam param(basicComputeStages[stageNdx], 2u, false);
2144                         basicComputeTests->addChild(newTestCase<BasicComputeTest>(testCtx, &param));
2145                 }
2146
2147                 timestampTests->addChild(basicComputeTests.release());
2148         }
2149
2150         // Transfer Tests
2151         {
2152                 de::MovePtr<tcu::TestCaseGroup> transferTests (new tcu::TestCaseGroup(testCtx, "transfer_tests", "Record timestamp for transfer stages"));
2153
2154                 const VkPipelineStageFlagBits transferStages[][2] =
2155                 {
2156                         {VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT},
2157                         {VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_HOST_BIT},
2158                 };
2159                 for (deUint32 stageNdx = 0u; stageNdx < DE_LENGTH_OF_ARRAY(transferStages); stageNdx++)
2160                 {
2161                         for (deUint32 method = 0u; method < TRANSFER_METHOD_LAST; method++)
2162                         {
2163                                 TransferTimestampTestParam param(transferStages[stageNdx], 2u, false, method);
2164                                 transferTests->addChild(newTestCase<TransferTest>(testCtx, &param));
2165                         }
2166                 }
2167
2168                 timestampTests->addChild(transferTests.release());
2169         }
2170
2171         // Misc Tests
2172         {
2173                 de::MovePtr<tcu::TestCaseGroup> miscTests (new tcu::TestCaseGroup(testCtx, "misc_tests", "Misc tests that can not be categorized to other group."));
2174
2175                 const VkPipelineStageFlagBits miscStages[] = {VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT};
2176                 TimestampTestParam param(miscStages, 1u, false);
2177                 miscTests->addChild(new TimestampTest(testCtx,
2178                                                                                           "timestamp_only",
2179                                                                                           "Only write timestamp command in the commmand buffer",
2180                                                                                           &param));
2181
2182                 timestampTests->addChild(miscTests.release());
2183         }
2184
2185         return timestampTests.release();
2186 }
2187
2188 } // pipeline
2189
2190 } // vkt