am 656f05e3: (-s ours) am 31801e06: Remove mipmap.cube.projected tests from mustpass...
[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::IVec2            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::IVec2 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,                                                         // VkPipelineTesselationStateCreateFlags    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                                                                                                                 deInt32                  width,
665                                                                                                                 deInt32                  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                 DE_NULL,                                        // VkRenderPass                     renderPass;
788                 0u,                                             // deUint32                         subpass;
789                 DE_NULL,                                        // VkFramebuffer                    framebuffer;
790                 VK_FALSE,                                       // VkBool32                         occlusionQueryEnable;
791                 0u,                                             // VkQueryControlFlags              queryFlags;
792                 0u,                                             // VkQueryPipelineStatisticFlags    pipelineStatistics;
793         };
794
795         VK_CHECK(vk.beginCommandBuffer(*m_cmdBuffer, &cmdBufferBeginInfo));
796
797         vk.cmdResetQueryPool(*m_cmdBuffer, *m_queryPool, 0u, TimestampTest::ENTRY_COUNT);
798
799         deUint32 timestampEntry = 0;
800         for (StageFlagVector::const_iterator it = m_stages.begin(); it != m_stages.end(); it++)
801         {
802                 vk.cmdWriteTimestamp(*m_cmdBuffer, *it, *m_queryPool, timestampEntry++);
803         }
804
805         VK_CHECK(vk.endCommandBuffer(*m_cmdBuffer));
806 }
807
808 tcu::TestStatus TimestampTestInstance::iterate(void)
809 {
810         const DeviceInterface&      vk          = m_context.getDeviceInterface();
811         const VkDevice              vkDevice    = m_context.getDevice();
812         const VkQueue               queue       = m_context.getUniversalQueue();
813
814         configCommandBuffer();
815
816         VK_CHECK(vk.resetFences(vkDevice, 1u, &m_fence.get()));
817
818         const VkSubmitInfo          submitInfo =
819         {
820                 VK_STRUCTURE_TYPE_SUBMIT_INFO,                      // VkStructureType         sType;
821                 DE_NULL,                                            // const void*             pNext;
822                 0u,                                                 // deUint32                waitSemaphoreCount;
823                 DE_NULL,                                            // const VkSemaphore*      pWaitSemaphores;
824                 1u,                                                 // deUint32                commandBufferCount;
825                 &m_cmdBuffer.get(),                                 // const VkCommandBuffer*  pCommandBuffers;
826                 0u,                                                 // deUint32                signalSemaphoreCount;
827                 DE_NULL,                                            // const VkSemaphore*      pSignalSemaphores;
828         };
829         VK_CHECK(vk.queueSubmit(queue, 1u, &submitInfo, *m_fence));
830
831         VK_CHECK(vk.waitForFences(vkDevice, 1u, &m_fence.get(), true, ~(0ull) /* infinity*/));
832
833         // Generate the timestamp mask
834         deUint64                    timestampMask;
835         const std::vector<VkQueueFamilyProperties>   queueProperties = vk::getPhysicalDeviceQueueFamilyProperties(m_context.getInstanceInterface(), m_context.getPhysicalDevice());
836         if(queueProperties[0].timestampValidBits == 0)
837         {
838                 return tcu::TestStatus::fail("Device does not support timestamp!");
839         }
840         else if(queueProperties[0].timestampValidBits == 64)
841         {
842                 timestampMask = 0xFFFFFFFFFFFFFFFF;
843         }
844         else
845         {
846                 timestampMask = (1 << queueProperties[0].timestampValidBits) - 1u;
847         }
848
849         // Get timestamp value from query pool
850         deUint32                    stageSize = (deUint32)m_stages.size();
851
852         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);
853
854         for (deUint32 ndx = 0; ndx < stageSize; ndx++)
855         {
856                 m_timestampValues[ndx] &= timestampMask;
857         }
858
859         return verifyTimestamp();
860 }
861
862 tcu::TestStatus TimestampTestInstance::verifyTimestamp(void)
863 {
864         for (deUint32 first = 0; first < m_stages.size(); first++)
865         {
866                 for (deUint32 second = 0; second < first; second++)
867                 {
868                         if(m_timestampValues[first] < m_timestampValues[second])
869                         {
870                                 return tcu::TestStatus::fail("Latter stage timestamp is smaller than the former stage timestamp.");
871                         }
872                 }
873         }
874
875         return tcu::TestStatus::pass("Timestamp increases steadily.");
876 }
877
878 Move<VkBuffer> TimestampTestInstance::createBufferAndBindMemory(VkDeviceSize size, VkBufferUsageFlags usage, de::MovePtr<Allocation>* pAlloc)
879 {
880         const DeviceInterface&      vk                  = m_context.getDeviceInterface();
881         const VkDevice              vkDevice            = m_context.getDevice();
882         const deUint32              queueFamilyIndex    = m_context.getUniversalQueueFamilyIndex();
883         SimpleAllocator             memAlloc            (vk, vkDevice, getPhysicalDeviceMemoryProperties(m_context.getInstanceInterface(), m_context.getPhysicalDevice()));
884
885         const VkBufferCreateInfo vertexBufferParams =
886         {
887                 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,       // VkStructureType      sType;
888                 DE_NULL,                                    // const void*          pNext;
889                 0u,                                         // VkBufferCreateFlags  flags;
890                 size,                                       // VkDeviceSize         size;
891                 usage,                                      // VkBufferUsageFlags   usage;
892                 VK_SHARING_MODE_EXCLUSIVE,                  // VkSharingMode        sharingMode;
893                 1u,                                         // deUint32             queueFamilyCount;
894                 &queueFamilyIndex                           // const deUint32*      pQueueFamilyIndices;
895         };
896
897         Move<VkBuffer> vertexBuffer = createBuffer(vk, vkDevice, &vertexBufferParams);
898         de::MovePtr<Allocation> vertexBufferAlloc = memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *vertexBuffer), MemoryRequirement::HostVisible);
899
900         VK_CHECK(vk.bindBufferMemory(vkDevice, *vertexBuffer, vertexBufferAlloc->getMemory(), vertexBufferAlloc->getOffset()));
901
902         DE_ASSERT(pAlloc);
903         *pAlloc = vertexBufferAlloc;
904         return vertexBuffer;
905 }
906
907 Move<VkImage> TimestampTestInstance::createImage2DAndBindMemory(VkFormat                          format,
908                                                                                                                                   deInt32                           width,
909                                                                                                                                   deInt32                           height,
910                                                                                                                                   VkBufferUsageFlags                usage,
911                                                                                                                                   VkSampleCountFlagBits             sampleCount,
912                                                                                                                                   de::details::MovePtr<Allocation>* pAlloc)
913 {
914         const DeviceInterface&      vk                  = m_context.getDeviceInterface();
915         const VkDevice              vkDevice            = m_context.getDevice();
916         const deUint32              queueFamilyIndex    = m_context.getUniversalQueueFamilyIndex();
917         SimpleAllocator             memAlloc            (vk, vkDevice, getPhysicalDeviceMemoryProperties(m_context.getInstanceInterface(), m_context.getPhysicalDevice()));
918
919         const VkImageCreateInfo colorImageParams =
920         {
921                 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,                                        // VkStructureType      sType;
922                 DE_NULL,                                                                    // const void*          pNext;
923                 0u,                                                                         // VkImageCreateFlags   flags;
924                 VK_IMAGE_TYPE_2D,                                                           // VkImageType          imageType;
925                 format,                                                                     // VkFormat             format;
926                 { width, height, 1u },                                                      // VkExtent3D           extent;
927                 1u,                                                                         // deUint32             mipLevels;
928                 1u,                                                                         // deUint32             arraySize;
929                 sampleCount,                                                                // deUint32             samples;
930                 VK_IMAGE_TILING_OPTIMAL,                                                    // VkImageTiling        tiling;
931                 usage,                                                                      // VkImageUsageFlags    usage;
932                 VK_SHARING_MODE_EXCLUSIVE,                                                  // VkSharingMode        sharingMode;
933                 1u,                                                                         // deUint32             queueFamilyCount;
934                 &queueFamilyIndex,                                                          // const deUint32*      pQueueFamilyIndices;
935                 VK_IMAGE_LAYOUT_UNDEFINED,                                                  // VkImageLayout        initialLayout;
936         };
937
938         Move<VkImage> image = createImage(vk, vkDevice, &colorImageParams);
939
940         // Allocate and bind image memory
941         de::MovePtr<Allocation> colorImageAlloc = memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, *image), MemoryRequirement::Any);
942         VK_CHECK(vk.bindImageMemory(vkDevice, *image, colorImageAlloc->getMemory(), colorImageAlloc->getOffset()));
943
944         DE_ASSERT(pAlloc);
945         *pAlloc = colorImageAlloc;
946
947         return image;
948 }
949
950 class BasicGraphicsTest : public TimestampTest
951 {
952 public:
953                                                   BasicGraphicsTest(tcu::TestContext&         testContext,
954                                                                                         const std::string&        name,
955                                                                                         const std::string&        description,
956                                                                                         const TimestampTestParam* param)
957                                                           : TimestampTest (testContext, name, description, param)
958                                                           { }
959         virtual               ~BasicGraphicsTest (void) { }
960         virtual void          initPrograms       (SourceCollections&      programCollection) const;
961         virtual TestInstance* createInstance     (Context&                context) const;
962 };
963
964 class BasicGraphicsTestInstance : public TimestampTestInstance
965 {
966 public:
967         enum
968         {
969                 VK_MAX_SHADER_STAGES = 6,
970         };
971                                  BasicGraphicsTestInstance  (Context&              context,
972                                                                                          const StageFlagVector stages,
973                                                                                          const bool            inRenderPass);
974         virtual      ~BasicGraphicsTestInstance (void);
975 protected:
976         virtual void configCommandBuffer        (void);
977         virtual void buildVertexBuffer          (void);
978         virtual void buildRenderPass            (VkFormat colorFormat,
979                                                                                          VkFormat depthFormat);
980         virtual void buildFrameBuffer           (tcu::IVec2 renderSize,
981                                                                                          VkFormat colorFormat,
982                                                                                          VkFormat depthFormat);
983 protected:
984         const tcu::IVec2                    m_renderSize;
985         const VkFormat                      m_colorFormat;
986         const VkFormat                      m_depthFormat;
987
988         Move<VkImage>                       m_colorImage;
989         de::MovePtr<Allocation>             m_colorImageAlloc;
990         Move<VkImage>                       m_depthImage;
991         de::MovePtr<Allocation>             m_depthImageAlloc;
992         Move<VkImageView>                   m_colorAttachmentView;
993         Move<VkImageView>                   m_depthAttachmentView;
994         Move<VkRenderPass>                  m_renderPass;
995         Move<VkFramebuffer>                 m_framebuffer;
996
997         Move<VkBuffer>                      m_vertexBuffer;
998         std::vector<Vertex4RGBA>            m_vertices;
999
1000         SimpleGraphicsPipelineBuilder       m_pipelineBuilder;
1001         Move<VkPipeline>                    m_graphicsPipelines;
1002 };
1003
1004 void BasicGraphicsTest::initPrograms (SourceCollections& programCollection) const
1005 {
1006         programCollection.glslSources.add("color_vert") << glu::VertexSource(
1007                 "#version 310 es\n"
1008                 "layout(location = 0) in vec4 position;\n"
1009                 "layout(location = 1) in vec4 color;\n"
1010                 "layout(location = 0) out highp vec4 vtxColor;\n"
1011                 "void main (void)\n"
1012                 "{\n"
1013                 "  gl_Position = position;\n"
1014                 "  vtxColor = color;\n"
1015                 "}\n");
1016
1017         programCollection.glslSources.add("color_frag") << glu::FragmentSource(
1018                 "#version 310 es\n"
1019                 "layout(location = 0) in highp vec4 vtxColor;\n"
1020                 "layout(location = 0) out highp vec4 fragColor;\n"
1021                 "void main (void)\n"
1022                 "{\n"
1023                 "  fragColor = vtxColor;\n"
1024                 "}\n");
1025 }
1026
1027 TestInstance* BasicGraphicsTest::createInstance(Context& context) const
1028 {
1029         return new BasicGraphicsTestInstance(context,m_stages,m_inRenderPass);
1030 }
1031
1032 void BasicGraphicsTestInstance::buildVertexBuffer(void)
1033 {
1034         const DeviceInterface&      vk       = m_context.getDeviceInterface();
1035         const VkDevice              vkDevice = m_context.getDevice();
1036
1037         // Create vertex buffer
1038         {
1039                 de::MovePtr<Allocation>     bufferAlloc;
1040                 m_vertexBuffer = createBufferAndBindMemory(1024u,VK_BUFFER_USAGE_VERTEX_BUFFER_BIT,&bufferAlloc);
1041
1042                 m_vertices          = createOverlappingQuads();
1043                 // Load vertices into vertex buffer
1044                 deMemcpy(bufferAlloc->getHostPtr(), m_vertices.data(), m_vertices.size() * sizeof(Vertex4RGBA));
1045                 flushMappedMemoryRange(vk, vkDevice, bufferAlloc->getMemory(), bufferAlloc->getOffset(), 1024u);
1046         }
1047 }
1048
1049 void BasicGraphicsTestInstance::buildRenderPass(VkFormat colorFormat, VkFormat depthFormat)
1050 {
1051         const DeviceInterface&      vk       = m_context.getDeviceInterface();
1052         const VkDevice              vkDevice = m_context.getDevice();
1053
1054         // Create render pass
1055         {
1056                 const VkAttachmentDescription colorAttachmentDescription =
1057                 {
1058                         0u,                                                 // VkAttachmentDescriptionFlags    flags;
1059                         colorFormat,                                        // VkFormat                        format;
1060                         VK_SAMPLE_COUNT_1_BIT,                              // VkSampleCountFlagBits           samples;
1061                         VK_ATTACHMENT_LOAD_OP_CLEAR,                        // VkAttachmentLoadOp              loadOp;
1062                         VK_ATTACHMENT_STORE_OP_STORE,                       // VkAttachmentStoreOp             storeOp;
1063                         VK_ATTACHMENT_LOAD_OP_DONT_CARE,                    // VkAttachmentLoadOp              stencilLoadOp;
1064                         VK_ATTACHMENT_STORE_OP_DONT_CARE,                   // VkAttachmentStoreOp             stencilStoreOp;
1065                         VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,           // VkImageLayout                   initialLayout;
1066                         VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,           // VkImageLayout                   finalLayout;
1067                 };
1068
1069                 const VkAttachmentDescription depthAttachmentDescription =
1070                 {
1071                         0u,                                                 // VkAttachmentDescriptionFlags flags;
1072                         depthFormat,                                        // VkFormat                     format;
1073                         VK_SAMPLE_COUNT_1_BIT,                              // VkSampleCountFlagBits        samples;
1074                         VK_ATTACHMENT_LOAD_OP_CLEAR,                        // VkAttachmentLoadOp           loadOp;
1075                         VK_ATTACHMENT_STORE_OP_DONT_CARE,                   // VkAttachmentStoreOp          storeOp;
1076                         VK_ATTACHMENT_LOAD_OP_DONT_CARE,                    // VkAttachmentLoadOp           stencilLoadOp;
1077                         VK_ATTACHMENT_STORE_OP_DONT_CARE,                   // VkAttachmentStoreOp          stencilStoreOp;
1078                         VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,   // VkImageLayout                initialLayout;
1079                         VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,   // VkImageLayout                finalLayout;
1080                 };
1081
1082                 const VkAttachmentDescription attachments[2] =
1083                 {
1084                         colorAttachmentDescription,
1085                         depthAttachmentDescription
1086                 };
1087
1088                 const VkAttachmentReference colorAttachmentReference =
1089                 {
1090                         0u,                                                 // deUint32         attachment;
1091                         VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL            // VkImageLayout    layout;
1092                 };
1093
1094                 const VkAttachmentReference depthAttachmentReference =
1095                 {
1096                         1u,                                                 // deUint32         attachment;
1097                         VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL    // VkImageLayout    layout;
1098                 };
1099
1100                 const VkSubpassDescription subpassDescription =
1101                 {
1102                         0u,                                                 // VkSubpassDescriptionFlags        flags;
1103                         VK_PIPELINE_BIND_POINT_GRAPHICS,                    // VkPipelineBindPoint              pipelineBindPoint;
1104                         0u,                                                 // deUint32                         inputAttachmentCount;
1105                         DE_NULL,                                            // const VkAttachmentReference*     pInputAttachments;
1106                         1u,                                                 // deUint32                         colorAttachmentCount;
1107                         &colorAttachmentReference,                          // const VkAttachmentReference*     pColorAttachments;
1108                         DE_NULL,                                            // const VkAttachmentReference*     pResolveAttachments;
1109                         &depthAttachmentReference,                          // const VkAttachmentReference*     pDepthStencilAttachment;
1110                         0u,                                                 // deUint32                         preserveAttachmentCount;
1111                         DE_NULL                                             // const VkAttachmentReference*     pPreserveAttachments;
1112                 };
1113
1114                 const VkRenderPassCreateInfo renderPassParams =
1115                 {
1116                         VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,          // VkStructureType                  sType;
1117                         DE_NULL,                                            // const void*                      pNext;
1118                         0u,                                                 // VkRenderPassCreateFlags          flags;
1119                         2u,                                                 // deUint32                         attachmentCount;
1120                         attachments,                                        // const VkAttachmentDescription*   pAttachments;
1121                         1u,                                                 // deUint32                         subpassCount;
1122                         &subpassDescription,                                // const VkSubpassDescription*      pSubpasses;
1123                         0u,                                                 // deUint32                         dependencyCount;
1124                         DE_NULL                                             // const VkSubpassDependency*       pDependencies;
1125                 };
1126
1127                 m_renderPass = createRenderPass(vk, vkDevice, &renderPassParams);
1128         }
1129
1130 }
1131
1132 void BasicGraphicsTestInstance::buildFrameBuffer(tcu::IVec2 renderSize, VkFormat colorFormat, VkFormat depthFormat)
1133 {
1134         const DeviceInterface&      vk                   = m_context.getDeviceInterface();
1135         const VkDevice              vkDevice             = m_context.getDevice();
1136         const VkComponentMapping    ComponentMappingRGBA = { VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A};
1137
1138         // Create color image
1139         {
1140                 m_colorImage = createImage2DAndBindMemory(colorFormat,
1141                                                                                                   renderSize.x(),
1142                                                                                                   renderSize.y(),
1143                                                                                                   VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT,
1144                                                                                                   VK_SAMPLE_COUNT_1_BIT,
1145                                                                                                   &m_colorImageAlloc);
1146         }
1147
1148         // Create depth image
1149         {
1150                 m_depthImage = createImage2DAndBindMemory(depthFormat,
1151                                                                                                   renderSize.x(),
1152                                                                                                   renderSize.y(),
1153                                                                                                   VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT,
1154                                                                                                   VK_SAMPLE_COUNT_1_BIT,
1155                                                                                                   &m_depthImageAlloc);
1156         }
1157
1158         // Create color attachment view
1159         {
1160                 const VkImageViewCreateInfo colorAttachmentViewParams =
1161                 {
1162                         VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,       // VkStructureType          sType;
1163                         DE_NULL,                                        // const void*              pNext;
1164                         0u,                                             // VkImageViewCreateFlags   flags;
1165                         *m_colorImage,                                  // VkImage                  image;
1166                         VK_IMAGE_VIEW_TYPE_2D,                          // VkImageViewType          viewType;
1167                         colorFormat,                                    // VkFormat                 format;
1168                         ComponentMappingRGBA,                           // VkComponentMapping       components;
1169                         { VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u },  // VkImageSubresourceRange  subresourceRange;
1170                 };
1171
1172                 m_colorAttachmentView = createImageView(vk, vkDevice, &colorAttachmentViewParams);
1173         }
1174
1175         // Create depth attachment view
1176         {
1177                 const VkImageViewCreateInfo depthAttachmentViewParams =
1178                 {
1179                         VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,       // VkStructureType          sType;
1180                         DE_NULL,                                        // const void*              pNext;
1181                         0u,                                             // VkImageViewCreateFlags   flags;
1182                         *m_depthImage,                                  // VkImage                  image;
1183                         VK_IMAGE_VIEW_TYPE_2D,                          // VkImageViewType          viewType;
1184                         depthFormat,                                    // VkFormat                 format;
1185                         ComponentMappingRGBA,                           // VkComponentMapping       components;
1186                         { VK_IMAGE_ASPECT_DEPTH_BIT, 0u, 1u, 0u, 1u },  // VkImageSubresourceRange  subresourceRange;
1187                 };
1188
1189                 m_depthAttachmentView = createImageView(vk, vkDevice, &depthAttachmentViewParams);
1190         }
1191
1192         // Create framebuffer
1193         {
1194                 const VkImageView attachmentBindInfos[2] =
1195                 {
1196                         *m_colorAttachmentView,
1197                         *m_depthAttachmentView,
1198                 };
1199
1200                 const VkFramebufferCreateInfo framebufferParams =
1201                 {
1202                         VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,          // VkStructureType              sType;
1203                         DE_NULL,                                            // const void*                  pNext;
1204                         0u,                                                 // VkFramebufferCreateFlags     flags;
1205                         *m_renderPass,                                      // VkRenderPass                 renderPass;
1206                         2u,                                                 // deUint32                     attachmentCount;
1207                         attachmentBindInfos,                                // const VkImageView*           pAttachments;
1208                         (deUint32)renderSize.x(),                           // deUint32                     width;
1209                         (deUint32)renderSize.y(),                           // deUint32                     height;
1210                         1u,                                                 // deUint32                     layers;
1211                 };
1212
1213                 m_framebuffer = createFramebuffer(vk, vkDevice, &framebufferParams);
1214         }
1215
1216 }
1217
1218 BasicGraphicsTestInstance::BasicGraphicsTestInstance(Context&              context,
1219                                                                                                          const StageFlagVector stages,
1220                                                                                                          const bool            inRenderPass)
1221                                                                                                          : TimestampTestInstance (context,stages,inRenderPass)
1222                                                                                                          , m_renderSize  (32, 32)
1223                                                                                                          , m_colorFormat (VK_FORMAT_R8G8B8A8_UNORM)
1224                                                                                                          , m_depthFormat (VK_FORMAT_D16_UNORM)
1225                                                                                                          , m_pipelineBuilder (context)
1226 {
1227         buildVertexBuffer();
1228
1229         buildRenderPass(m_colorFormat, m_depthFormat);
1230
1231         buildFrameBuffer(m_renderSize, m_colorFormat, m_depthFormat);
1232
1233         m_pipelineBuilder.bindShaderStage(VK_SHADER_STAGE_VERTEX_BIT, "color_vert", "main");
1234         m_pipelineBuilder.bindShaderStage(VK_SHADER_STAGE_FRAGMENT_BIT, "color_frag", "main");
1235
1236         m_graphicsPipelines = m_pipelineBuilder.buildPipeline(m_renderSize, *m_renderPass);
1237
1238 }
1239
1240 BasicGraphicsTestInstance::~BasicGraphicsTestInstance(void)
1241 {
1242 }
1243
1244 void BasicGraphicsTestInstance::configCommandBuffer(void)
1245 {
1246         const DeviceInterface&      vk                  = m_context.getDeviceInterface();
1247
1248         const VkCommandBufferBeginInfo cmdBufferBeginInfo =
1249         {
1250                 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,    // VkStructureType                  sType;
1251                 DE_NULL,                                        // const void*                      pNext;
1252                 0u,                                             // VkCommandBufferUsageFlags        flags;
1253                 DE_NULL,                                        // VkRenderPass                     renderPass;
1254                 0u,                                             // deUint32                         subpass;
1255                 DE_NULL,                                        // VkFramebuffer                    framebuffer;
1256                 VK_FALSE,                                       // VkBool32                         occlusionQueryEnable;
1257                 0u,                                             // VkQueryControlFlags              queryFlags;
1258                 0u,                                             // VkQueryPipelineStatisticFlags    pipelineStatistics;
1259         };
1260
1261         const VkClearValue attachmentClearValues[2] =
1262         {
1263                 defaultClearValue(m_colorFormat),
1264                 defaultClearValue(m_depthFormat),
1265         };
1266
1267         const VkRenderPassBeginInfo renderPassBeginInfo =
1268         {
1269                 VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,               // VkStructureType      sType;
1270                 DE_NULL,                                                // const void*          pNext;
1271                 *m_renderPass,                                          // VkRenderPass         renderPass;
1272                 *m_framebuffer,                                         // VkFramebuffer        framebuffer;
1273                 { { 0u, 0u }, { m_renderSize.x(), m_renderSize.y() } }, // VkRect2D             renderArea;
1274                 2u,                                                     // deUint32             clearValueCount;
1275                 attachmentClearValues                                   // const VkClearValue*  pClearValues;
1276         };
1277
1278         VK_CHECK(vk.beginCommandBuffer(*m_cmdBuffer, &cmdBufferBeginInfo));
1279
1280         deUint32 stage_count = (deUint32)m_stages.size();
1281
1282         vk.cmdResetQueryPool(*m_cmdBuffer, *m_queryPool, 0u, stage_count);
1283
1284         vk.cmdBeginRenderPass(*m_cmdBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
1285
1286         vk.cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_graphicsPipelines);
1287         VkDeviceSize offsets = 0u;
1288         vk.cmdBindVertexBuffers(*m_cmdBuffer, 0u, 1u, &m_vertexBuffer.get(), &offsets);
1289         vk.cmdDraw(*m_cmdBuffer, (deUint32)m_vertices.size(), 1u, 0u, 0u);
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.cmdEndRenderPass(*m_cmdBuffer);
1301
1302         if(!m_inRenderPass)
1303         {
1304           deUint32 timestampEntry = 0u;
1305           for (StageFlagVector::const_iterator it = m_stages.begin(); it != m_stages.end(); it++)
1306           {
1307                   vk.cmdWriteTimestamp(*m_cmdBuffer, *it, *m_queryPool, timestampEntry++);
1308           }
1309         }
1310
1311         VK_CHECK(vk.endCommandBuffer(*m_cmdBuffer));
1312 }
1313
1314 class AdvGraphicsTest : public BasicGraphicsTest
1315 {
1316 public:
1317                                                   AdvGraphicsTest  (tcu::TestContext&         testContext,
1318                                                                                         const std::string&        name,
1319                                                                                         const std::string&        description,
1320                                                                                         const TimestampTestParam* param)
1321                                                           : BasicGraphicsTest(testContext, name, description, param)
1322                                                           { }
1323         virtual               ~AdvGraphicsTest (void) { }
1324         virtual void          initPrograms     (SourceCollections&        programCollection) const;
1325         virtual TestInstance* createInstance   (Context&                  context) const;
1326 };
1327
1328 class AdvGraphicsTestInstance : public BasicGraphicsTestInstance
1329 {
1330 public:
1331                                  AdvGraphicsTestInstance  (Context&              context,
1332                                                                                    const StageFlagVector stages,
1333                                                                                    const bool            inRenderPass);
1334         virtual      ~AdvGraphicsTestInstance (void);
1335         virtual void configCommandBuffer      (void);
1336 protected:
1337         virtual void featureSupportCheck      (void);
1338 protected:
1339         VkPhysicalDeviceFeatures m_features;
1340         deUint32                 m_draw_count;
1341         Move<VkBuffer>           m_indirectBuffer;
1342 };
1343
1344 void AdvGraphicsTest::initPrograms(SourceCollections& programCollection) const
1345 {
1346         BasicGraphicsTest::initPrograms(programCollection);
1347
1348         programCollection.glslSources.add("dummy_geo") << glu::GeometrySource(
1349                 "#version 450 \n"
1350                 "layout (triangles) in;\n"
1351                 "layout (triangle_strip, max_vertices = 3) out;\n"
1352                 "void main (void)\n"
1353                 "{\n"
1354                 "  for(int ndx=0; ndx<3; ndx++)\n"
1355                 "  {\n"
1356                 "    gl_Position = gl_in[ndx].gl_Position;\n"
1357                 "    EmitVertex();\n"
1358                 "  }\n"
1359                 "  EndPrimitive();\n"
1360                 "}\n");
1361
1362         programCollection.glslSources.add("basic_tcs") << glu::TessellationControlSource(
1363                 "#version 450 \n"
1364                 "layout(vertices = 3) out;\n"
1365                 "in highp vec4 color[];\n"
1366                 "out highp vec4 vtxColor[];\n"
1367                 "void main()\n"
1368                 "{\n"
1369                 "  gl_TessLevelOuter[0] = 4.0;\n"
1370                 "  gl_TessLevelOuter[1] = 4.0;\n"
1371                 "  gl_TessLevelOuter[2] = 4.0;\n"
1372                 "  gl_TessLevelInner[0] = 4.0;\n"
1373                 "  gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;\n"
1374                 "  vtxColor[gl_InvocationID] = color[gl_InvocationID];\n"
1375                 "}\n");
1376
1377         programCollection.glslSources.add("basic_tes") << glu::TessellationEvaluationSource(
1378                 "#version 450 \n"
1379                 "layout(triangles, fractional_even_spacing, ccw) in;\n"
1380                 "in highp vec4 colors[];\n"
1381                 "out highp vec4 vtxColor;\n"
1382                 "void main() \n"
1383                 "{\n"
1384                 "  float u = gl_TessCoord.x;\n"
1385                 "  float v = gl_TessCoord.y;\n"
1386                 "  float w = gl_TessCoord.z;\n"
1387                 "  vec4 pos = vec4(0);\n"
1388                 "  vec4 color = vec4(0);\n"
1389                 "  pos.xyz += u * gl_in[0].gl_Position.xyz;\n"
1390                 "  color.xyz += u * colors[0].xyz;\n"
1391                 "  pos.xyz += v * gl_in[1].gl_Position.xyz;\n"
1392                 "  color.xyz += v * colors[1].xyz;\n"
1393                 "  pos.xyz += w * gl_in[2].gl_Position.xyz;\n"
1394                 "  color.xyz += w * colors[2].xyz;\n"
1395                 "  pos.w = 1.0;\n"
1396                 "  color.w = 1.0;\n"
1397                 "  gl_Position = pos;\n"
1398                 "  vtxColor = color;\n"
1399                 "}\n");
1400 }
1401
1402 TestInstance* AdvGraphicsTest::createInstance(Context& context) const
1403 {
1404         return new AdvGraphicsTestInstance(context,m_stages,m_inRenderPass);
1405 }
1406
1407 void AdvGraphicsTestInstance::featureSupportCheck(void)
1408 {
1409         for (StageFlagVector::const_iterator it = m_stages.begin(); it != m_stages.end(); it++)
1410         {
1411                 switch(*it)
1412                 {
1413                         case VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT:
1414                                 if (m_features.geometryShader == VK_FALSE)
1415                                 {
1416                                         TCU_THROW(NotSupportedError, "Geometry Shader Not Supported");
1417                                 }
1418                                 break;
1419                         case VK_PIPELINE_STAGE_TESSELLATION_CONTROL_SHADER_BIT:
1420                         case VK_PIPELINE_STAGE_TESSELLATION_EVALUATION_SHADER_BIT:
1421                                 if (m_features.tessellationShader == VK_FALSE)
1422                                 {
1423                                         TCU_THROW(NotSupportedError, "Tessellation Not Supported");
1424                                 }
1425                                 break;
1426                         case VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT:
1427                         default:
1428                                 break;
1429                 };
1430         }
1431 }
1432
1433 AdvGraphicsTestInstance::AdvGraphicsTestInstance(Context&              context,
1434                                                                                                  const StageFlagVector stages,
1435                                                                                                  const bool            inRenderPass)
1436         : BasicGraphicsTestInstance(context, stages, inRenderPass)
1437 {
1438         m_features = m_context.getDeviceFeatures();
1439
1440         // If necessary feature is not supported, throw error and fail current test
1441         featureSupportCheck();
1442
1443         if(m_features.geometryShader == VK_TRUE)
1444         {
1445                 m_pipelineBuilder.bindShaderStage(VK_SHADER_STAGE_GEOMETRY_BIT, "dummy_geo", "main");
1446         }
1447
1448         if(m_features.tessellationShader == VK_TRUE)
1449         {
1450                 m_pipelineBuilder.bindShaderStage(VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, "basic_tcs", "main");
1451                 m_pipelineBuilder.bindShaderStage(VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT, "basic_tes", "main");
1452                 m_pipelineBuilder.enableTessellationStage(3);
1453         }
1454
1455         m_graphicsPipelines = m_pipelineBuilder.buildPipeline(m_renderSize, *m_renderPass);
1456
1457         // Prepare the indirect draw buffer
1458         const DeviceInterface&      vk                  = m_context.getDeviceInterface();
1459         const VkDevice              vkDevice            = m_context.getDevice();
1460
1461         if(m_features.multiDrawIndirect == VK_TRUE)
1462         {
1463                 m_draw_count = 2;
1464         }
1465         else
1466         {
1467                 m_draw_count = 1;
1468         }
1469         de::MovePtr<Allocation>     bufferAlloc;
1470         m_indirectBuffer = createBufferAndBindMemory(32u, VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT, &bufferAlloc);
1471
1472         const VkDrawIndirectCommand indirectCmds[] =
1473         {
1474                 {
1475                         12u,                    // deUint32    vertexCount;
1476                         1u,                     // deUint32    instanceCount;
1477                         0u,                     // deUint32    firstVertex;
1478                         0u,                     // deUint32    firstInstance;
1479                 },
1480                 {
1481                         12u,                    // deUint32    vertexCount;
1482                         1u,                     // deUint32    instanceCount;
1483                         11u,                    // deUint32    firstVertex;
1484                         0u,                     // deUint32    firstInstance;
1485                 },
1486         };
1487         // Load data into indirect draw buffer
1488         deMemcpy(bufferAlloc->getHostPtr(), indirectCmds, m_draw_count * sizeof(VkDrawIndirectCommand));
1489         flushMappedMemoryRange(vk, vkDevice, bufferAlloc->getMemory(), bufferAlloc->getOffset(), 32u);
1490
1491 }
1492
1493 AdvGraphicsTestInstance::~AdvGraphicsTestInstance(void)
1494 {
1495 }
1496
1497 void AdvGraphicsTestInstance::configCommandBuffer(void)
1498 {
1499         const DeviceInterface&      vk                  = m_context.getDeviceInterface();
1500
1501         const VkCommandBufferBeginInfo cmdBufferBeginInfo =
1502         {
1503                 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,    // VkStructureType              sType;
1504                 DE_NULL,                                        // const void*                  pNext;
1505                 0u,                                             // VkCommandBufferUsageFlags    flags;
1506                 DE_NULL,                                        // VkRenderPass                 renderPass;
1507                 0u,                                             // deUint32                     subpass;
1508                 DE_NULL,                                        // VkFramebuffer                framebuffer;
1509                 VK_FALSE,                                       // VkBool32                     occlusionQueryEnable;
1510                 0u,                                             // VkQueryControlFlags          queryFlags;
1511                 0u,                                             // VkQueryPipelineStatisticFlags   pipelineStatistics;
1512         };
1513
1514         const VkClearValue attachmentClearValues[2] =
1515         {
1516                 defaultClearValue(m_colorFormat),
1517                 defaultClearValue(m_depthFormat),
1518         };
1519
1520         const VkRenderPassBeginInfo renderPassBeginInfo =
1521         {
1522                 VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,               // VkStructureType      sType;
1523                 DE_NULL,                                                // const void*          pNext;
1524                 *m_renderPass,                                          // VkRenderPass         renderPass;
1525                 *m_framebuffer,                                         // VkFramebuffer        framebuffer;
1526                 { { 0u, 0u }, { m_renderSize.x(), m_renderSize.y() } }, // VkRect2D             renderArea;
1527                 2u,                                                     // deUint32             clearValueCount;
1528                 attachmentClearValues                                   // const VkClearValue*  pClearValues;
1529         };
1530
1531         VK_CHECK(vk.beginCommandBuffer(*m_cmdBuffer, &cmdBufferBeginInfo));
1532
1533         deUint32 stage_count = (deUint32)m_stages.size();
1534
1535         vk.cmdResetQueryPool(*m_cmdBuffer, *m_queryPool, 0u, stage_count);
1536
1537         vk.cmdBeginRenderPass(*m_cmdBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
1538
1539         vk.cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_graphicsPipelines);
1540
1541         VkDeviceSize offsets = 0u;
1542         vk.cmdBindVertexBuffers(*m_cmdBuffer, 0u, 1u, &m_vertexBuffer.get(), &offsets);
1543
1544         vk.cmdDrawIndirect(*m_cmdBuffer, *m_indirectBuffer, 0u, m_draw_count, sizeof(VkDrawIndirectCommand));
1545
1546         if(m_inRenderPass)
1547         {
1548           deUint32 timestampEntry = 0u;
1549           for (StageFlagVector::const_iterator it = m_stages.begin(); it != m_stages.end(); it++)
1550           {
1551                   vk.cmdWriteTimestamp(*m_cmdBuffer, *it, *m_queryPool, timestampEntry++);
1552           }
1553         }
1554
1555         vk.cmdEndRenderPass(*m_cmdBuffer);
1556
1557         if(!m_inRenderPass)
1558         {
1559           deUint32 timestampEntry = 0u;
1560           for (StageFlagVector::const_iterator it = m_stages.begin(); it != m_stages.end(); it++)
1561           {
1562                   vk.cmdWriteTimestamp(*m_cmdBuffer, *it, *m_queryPool, timestampEntry++);
1563           }
1564         }
1565
1566         VK_CHECK(vk.endCommandBuffer(*m_cmdBuffer));
1567
1568 }
1569
1570 class BasicComputeTest : public TimestampTest
1571 {
1572 public:
1573                                                   BasicComputeTest  (tcu::TestContext&         testContext,
1574                                                                                          const std::string&        name,
1575                                                                                          const std::string&        description,
1576                                                                                          const TimestampTestParam* param)
1577                                                           : TimestampTest(testContext, name, description, param)
1578                                                           { }
1579         virtual               ~BasicComputeTest (void) { }
1580         virtual void          initPrograms      (SourceCollections&        programCollection) const;
1581         virtual TestInstance* createInstance    (Context&                  context) const;
1582 };
1583
1584 class BasicComputeTestInstance : public TimestampTestInstance
1585 {
1586 public:
1587                                  BasicComputeTestInstance  (Context&              context,
1588                                                                                         const StageFlagVector stages,
1589                                                                                         const bool            inRenderPass);
1590         virtual      ~BasicComputeTestInstance (void);
1591         virtual void configCommandBuffer       (void);
1592 protected:
1593         Move<VkBuffer>              m_inputBuf;
1594         Move<VkBuffer>              m_outputBuf;
1595
1596         Move<VkDescriptorPool>      m_descriptorPool;
1597         Move<VkDescriptorSet>       m_descriptorSet;
1598         Move<VkDescriptorSetLayout> m_descriptorSetLayout;
1599
1600         Move<VkPipelineLayout>      m_pipelineLayout;
1601         Move<VkShaderModule>        m_computeShaderModule;
1602         Move<VkPipeline>            m_computePipelines;
1603 };
1604
1605 void BasicComputeTest::initPrograms(SourceCollections& programCollection) const
1606 {
1607         TimestampTest::initPrograms(programCollection);
1608
1609         programCollection.glslSources.add("basic_compute") << glu::ComputeSource(
1610                 "#version 310 es\n"
1611                 "layout(local_size_x = 128) in;\n"
1612                 "layout(std430) buffer;\n"
1613                 "layout(binding = 0) readonly buffer Input0\n"
1614                 "{\n"
1615                 "  vec4 elements[];\n"
1616                 "} input_data0;\n"
1617                 "layout(binding = 1) writeonly buffer Output\n"
1618                 "{\n"
1619                 "  vec4 elements[];\n"
1620                 "} output_data;\n"
1621                 "void main()\n"
1622                 "{\n"
1623                 "  uint ident = gl_GlobalInvocationID.x;\n"
1624                 "  output_data.elements[ident] = input_data0.elements[ident] * input_data0.elements[ident];\n"
1625                 "}");
1626 }
1627
1628 TestInstance* BasicComputeTest::createInstance(Context& context) const
1629 {
1630         return new BasicComputeTestInstance(context,m_stages,m_inRenderPass);
1631 }
1632
1633 BasicComputeTestInstance::BasicComputeTestInstance(Context&              context,
1634                                                                                                    const StageFlagVector stages,
1635                                                                                                    const bool            inRenderPass)
1636         : TimestampTestInstance(context, stages, inRenderPass)
1637 {
1638         const DeviceInterface&      vk                  = context.getDeviceInterface();
1639         const VkDevice              vkDevice            = context.getDevice();
1640
1641         // Create buffer object, allocate storage, and generate input data
1642         const VkDeviceSize          size                = sizeof(tcu::Vec4) * 128u;
1643         de::MovePtr<Allocation>     bufferAlloc;
1644         m_inputBuf = createBufferAndBindMemory(size, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, &bufferAlloc);
1645         // Load vertices into buffer
1646         tcu::Vec4* pVec = reinterpret_cast<tcu::Vec4*>(bufferAlloc->getHostPtr());
1647         for (deUint32 ndx = 0u; ndx < 128u; ndx++)
1648         {
1649                 for (deUint32 component = 0u; component < 4u; component++)
1650                 {
1651                         pVec[ndx][component]= (float)(ndx * (component + 1u));
1652                 }
1653         }
1654         flushMappedMemoryRange(vk, vkDevice, bufferAlloc->getMemory(), bufferAlloc->getOffset(), size);
1655     
1656         de::MovePtr<Allocation> dummyAlloc;
1657         m_outputBuf = createBufferAndBindMemory(size, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, &dummyAlloc);
1658         
1659         std::vector<VkDescriptorBufferInfo>        descriptorInfos;
1660         descriptorInfos.push_back(makeDescriptorBufferInfo(*m_inputBuf, 0u, sizeof(tcu::Vec4) * 128u));
1661         descriptorInfos.push_back(makeDescriptorBufferInfo(*m_outputBuf, 0u, sizeof(tcu::Vec4) * 128u));
1662
1663         // Create descriptor set layout
1664         DescriptorSetLayoutBuilder descLayoutBuilder;
1665
1666         for (deUint32 bindingNdx = 0u; bindingNdx < 2u; bindingNdx++)
1667         {
1668                 descLayoutBuilder.addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_SHADER_STAGE_COMPUTE_BIT);
1669         }
1670
1671         m_descriptorSetLayout = descLayoutBuilder.build(vk, vkDevice);
1672
1673         // Create descriptor pool
1674         m_descriptorPool = DescriptorPoolBuilder().addType(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 2).build(vk, vkDevice, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u);
1675
1676         // Create descriptor set
1677         const VkDescriptorSetAllocateInfo descriptorSetAllocInfo =
1678         {
1679                 VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,     // VkStructureType                 sType;
1680                 DE_NULL,                                            // const void*                     pNext;
1681                 *m_descriptorPool,                                  // VkDescriptorPool                descriptorPool;
1682                 1u,                                                 // deUint32                        setLayoutCount;
1683                 &m_descriptorSetLayout.get(),                       // const VkDescriptorSetLayout*    pSetLayouts;
1684         };
1685         m_descriptorSet   = allocateDescriptorSet(vk, vkDevice, &descriptorSetAllocInfo);
1686
1687         DescriptorSetUpdateBuilder  builder;
1688         for (deUint32 descriptorNdx = 0u; descriptorNdx < 2u; descriptorNdx++)
1689         {
1690                 builder.writeSingle(*m_descriptorSet, DescriptorSetUpdateBuilder::Location::binding(descriptorNdx), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &descriptorInfos[descriptorNdx]);
1691         }
1692         builder.update(vk, vkDevice);
1693
1694         // Create compute pipeline layout
1695         const VkPipelineLayoutCreateInfo pipelineLayoutCreateInfo =
1696         {
1697                 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,  // VkStructureType                 sType;
1698                 DE_NULL,                                        // const void*                     pNext;
1699                 0u,                                             // VkPipelineLayoutCreateFlags     flags;
1700                 1u,                                             // deUint32                        setLayoutCount;
1701                 &m_descriptorSetLayout.get(),                   // const VkDescriptorSetLayout*    pSetLayouts;
1702                 0u,                                             // deUint32                        pushConstantRangeCount;
1703                 DE_NULL,                                        // const VkPushConstantRange*      pPushConstantRanges;
1704         };
1705
1706         m_pipelineLayout = createPipelineLayout(vk, vkDevice, &pipelineLayoutCreateInfo);
1707
1708         // Create compute shader
1709         VkShaderModuleCreateInfo shaderModuleCreateInfo =
1710         {
1711                 VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO,                        // VkStructureType             sType;
1712                 DE_NULL,                                                            // const void*                 pNext;
1713                 0u,                                                                 // VkShaderModuleCreateFlags   flags;
1714                 m_context.getBinaryCollection().get("basic_compute").getSize(),     // deUintptr                   codeSize;
1715                 (deUint32*)m_context.getBinaryCollection().get("basic_compute").getBinary(),   // const deUint32*             pCode;
1716
1717         };
1718
1719         m_computeShaderModule = createShaderModule(vk, vkDevice, &shaderModuleCreateInfo);
1720
1721         // Create compute pipeline
1722         const VkPipelineShaderStageCreateInfo stageCreateInfo =
1723         {
1724                 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType                     sType;
1725                 DE_NULL,                                             // const void*                         pNext;
1726                 0u,                                                  // VkPipelineShaderStageCreateFlags    flags;
1727                 VK_SHADER_STAGE_COMPUTE_BIT,                         // VkShaderStageFlagBits               stage;
1728                 *m_computeShaderModule,                              // VkShaderModule                      module;
1729                 "main",                                              // const char*                         pName;
1730                 DE_NULL,                                             // const VkSpecializationInfo*         pSpecializationInfo;
1731         };
1732
1733         const VkComputePipelineCreateInfo pipelineCreateInfo =
1734         {
1735                 VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO,      // VkStructureType                 sType;
1736                 DE_NULL,                                             // const void*                     pNext;
1737                 0u,                                                  // VkPipelineCreateFlags           flags;
1738                 stageCreateInfo,                                     // VkPipelineShaderStageCreateInfo stage;
1739                 *m_pipelineLayout,                                   // VkPipelineLayout                layout;
1740                 (VkPipeline)0,                                       // VkPipeline                      basePipelineHandle;
1741                 0u,                                                  // deInt32                         basePipelineIndex;
1742         };
1743
1744         m_computePipelines = createComputePipeline(vk, vkDevice, (VkPipelineCache)0u, &pipelineCreateInfo);
1745
1746 }
1747
1748 BasicComputeTestInstance::~BasicComputeTestInstance(void)
1749 {
1750 }
1751
1752 void BasicComputeTestInstance::configCommandBuffer(void)
1753 {
1754         const DeviceInterface&     vk                 = m_context.getDeviceInterface();
1755
1756         const VkCommandBufferBeginInfo cmdBufferBeginInfo =
1757         {
1758                 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,    // VkStructureType          sType;
1759                 DE_NULL,                                        // const void*              pNext;
1760                 0u,                                             // VkCmdBufferOptimizeFlags flags;
1761                 DE_NULL,                                        // VkRenderPass             renderPass;
1762                 0u,                                             // deUint32                 subpass;
1763                 DE_NULL,                                        // VkFramebuffer            framebuffer;
1764                 VK_FALSE,                                       // VkBool32                         occlusionQueryEnable;
1765                 0u,                                             // VkQueryControlFlags              queryFlags;
1766                 0u,                                             // VkQueryPipelineStatisticFlags    pipelineStatistics;
1767
1768         };
1769
1770         VK_CHECK(vk.beginCommandBuffer(*m_cmdBuffer, &cmdBufferBeginInfo));
1771
1772         vk.cmdResetQueryPool(*m_cmdBuffer, *m_queryPool, 0u, 1u);
1773
1774         vk.cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *m_computePipelines);
1775         vk.cmdBindDescriptorSets(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *m_pipelineLayout, 0u, 1u, &m_descriptorSet.get(), 0u, DE_NULL);
1776         vk.cmdDispatch(*m_cmdBuffer, 128u, 1u, 1u);
1777
1778         deUint32 timestampEntry = 0u;
1779         for (StageFlagVector::const_iterator it = m_stages.begin(); it != m_stages.end(); it++)
1780         {
1781                 vk.cmdWriteTimestamp(*m_cmdBuffer, *it, *m_queryPool, timestampEntry++);
1782         }
1783
1784         VK_CHECK(vk.endCommandBuffer(*m_cmdBuffer));
1785
1786
1787 }
1788
1789 class TransferTest : public TimestampTest
1790 {
1791 public:
1792                                                   TransferTest   (tcu::TestContext&          testContext,
1793                                                                                   const std::string&         name,
1794                                                                                   const std::string&         description,
1795                                                                                   const TimestampTestParam*  param);
1796         virtual               ~TransferTest  (void) { }
1797         virtual void          initPrograms   (SourceCollections&         programCollection) const;
1798         virtual TestInstance* createInstance (Context&                   context) const;
1799 protected:
1800         TransferMethod        m_method;
1801 };
1802
1803 class TransferTestInstance : public TimestampTestInstance
1804 {
1805 public:
1806                                         TransferTestInstance  (Context&              context,
1807                                                                                    const StageFlagVector stages,
1808                                                                                    const bool            inRenderPass,
1809                                                                                    const TransferMethod  method);
1810         virtual         ~TransferTestInstance (void);
1811         virtual void    configCommandBuffer   (void);
1812 protected:
1813         TransferMethod  m_method;
1814
1815         VkDeviceSize    m_bufSize;
1816         Move<VkBuffer>  m_srcBuffer;
1817         Move<VkBuffer>  m_dstBuffer;
1818
1819         VkFormat        m_imageFormat;
1820         deInt32         m_imageWidth;
1821         deInt32         m_imageHeight;
1822         VkDeviceSize    m_imageSize;
1823         Move<VkImage>   m_srcImage;
1824         Move<VkImage>   m_dstImage;
1825         Move<VkImage>   m_depthImage;
1826         Move<VkImage>   m_msImage;
1827 };
1828
1829 TransferTest::TransferTest(tcu::TestContext&                 testContext,
1830                                                    const std::string&                name,
1831                                                    const std::string&                description,
1832                                                    const TimestampTestParam*         param)
1833         : TimestampTest(testContext, name, description, param)
1834 {
1835         const TransferTimestampTestParam* transferParam = dynamic_cast<const TransferTimestampTestParam*>(param);
1836         m_method = transferParam->getMethod();
1837 }
1838
1839 void TransferTest::initPrograms(SourceCollections& programCollection) const
1840 {
1841         TimestampTest::initPrograms(programCollection);
1842 }
1843
1844 TestInstance* TransferTest::createInstance(Context& context) const
1845 {
1846   return new TransferTestInstance(context, m_stages, m_inRenderPass, m_method);
1847 }
1848
1849 TransferTestInstance::TransferTestInstance(Context&              context,
1850                                                                                    const StageFlagVector stages,
1851                                                                                    const bool            inRenderPass,
1852                                                                                    const TransferMethod  method)
1853         : TimestampTestInstance(context, stages, inRenderPass)
1854         , m_method(method)
1855         , m_bufSize(256u)
1856         , m_imageFormat(VK_FORMAT_R32G32B32A32_SFLOAT)
1857         , m_imageWidth(4u)
1858         , m_imageHeight(4u)
1859         , m_imageSize(256u)
1860 {
1861         const DeviceInterface&      vk                  = context.getDeviceInterface();
1862         const VkDevice              vkDevice            = context.getDevice();
1863
1864         // Create src buffer
1865         de::MovePtr<Allocation>     bufferAlloc;
1866         m_srcBuffer = createBufferAndBindMemory(m_bufSize, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_SRC_BIT, &bufferAlloc);
1867
1868         // Init the source buffer memory
1869         char* pBuf = reinterpret_cast<char*>(bufferAlloc->getHostPtr());
1870         memset(pBuf, 0xFF, sizeof(char)*(size_t)m_bufSize);
1871         flushMappedMemoryRange(vk, vkDevice, bufferAlloc->getMemory(), bufferAlloc->getOffset(), m_bufSize);
1872
1873         // Create dst buffer
1874         de::MovePtr<Allocation>     dummyAlloc;
1875         m_dstBuffer = createBufferAndBindMemory(m_bufSize, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT, &dummyAlloc);
1876
1877         // Create src/dst/depth image
1878         m_srcImage   = createImage2DAndBindMemory(m_imageFormat, m_imageWidth, m_imageHeight,
1879                                                                                           VK_IMAGE_USAGE_STORAGE_BIT | VK_BUFFER_USAGE_TRANSFER_SRC_BIT,
1880                                                                                           VK_SAMPLE_COUNT_1_BIT,
1881                                                                                           &dummyAlloc);
1882         m_dstImage   = createImage2DAndBindMemory(m_imageFormat, m_imageWidth, m_imageHeight,
1883                                                                                           VK_IMAGE_USAGE_STORAGE_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT,
1884                                                                                           VK_SAMPLE_COUNT_1_BIT,
1885                                                                                           &dummyAlloc);
1886         m_depthImage = createImage2DAndBindMemory(VK_FORMAT_D16_UNORM, m_imageWidth, m_imageHeight,
1887                                                                                           VK_IMAGE_USAGE_STORAGE_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT,
1888                                                                                           VK_SAMPLE_COUNT_1_BIT,
1889                                                                                           &dummyAlloc);
1890         m_msImage    = createImage2DAndBindMemory(m_imageFormat, m_imageWidth, m_imageHeight,
1891                                                                                           VK_IMAGE_USAGE_STORAGE_BIT | VK_BUFFER_USAGE_TRANSFER_SRC_BIT,
1892                                                                                           VK_SAMPLE_COUNT_4_BIT,
1893                                                                                           &dummyAlloc);
1894 }
1895
1896 TransferTestInstance::~TransferTestInstance(void)
1897 {
1898 }
1899
1900 void TransferTestInstance::configCommandBuffer(void)
1901 {
1902         const DeviceInterface&      vk                  = m_context.getDeviceInterface();
1903
1904         const VkCommandBufferBeginInfo cmdBufferBeginInfo =
1905         {
1906                 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,    // VkStructureType                  sType;
1907                 DE_NULL,                                        // const void*                      pNext;
1908                 0u,                                             // VkCmdBufferOptimizeFlags         flags;
1909                 DE_NULL,                                        // VkRenderPass                     renderPass;
1910                 0u,                                             // deUint32                         subpass;
1911                 DE_NULL,                                        // VkFramebuffer                    framebuffer;
1912                 VK_FALSE,                                       // VkBool32                         occlusionQueryEnable;
1913                 0u,                                             // VkQueryControlFlags              queryFlags;
1914                 0u,                                             // VkQueryPipelineStatisticFlags    pipelineStatistics;
1915         };
1916
1917         VK_CHECK(vk.beginCommandBuffer(*m_cmdBuffer, &cmdBufferBeginInfo));
1918
1919         // Initialize buffer/image
1920         vk.cmdFillBuffer(*m_cmdBuffer, *m_dstBuffer, 0u, m_bufSize, 0x0);
1921
1922         const VkClearColorValue srcClearValue =
1923         {
1924                 {1.0f, 1.0f, 1.0f, 1.0f}
1925         };
1926         const VkClearColorValue dstClearValue =
1927         {
1928                 {0.0f, 0.0f, 0.0f, 0.0f}
1929         };
1930         const struct VkImageSubresourceRange subRange =
1931         {
1932                 0u,                  // VkImageAspectFlags  aspectMask;
1933                 0u,                  // deUint32            baseMipLevel;
1934                 1u,                  // deUint32            mipLevels;
1935                 0u,                  // deUint32            baseArrayLayer;
1936                 1u,                  // deUint32            arraySize;
1937         };
1938
1939         vk.cmdClearColorImage(*m_cmdBuffer, *m_srcImage, VK_IMAGE_LAYOUT_GENERAL, &srcClearValue, 1u, &subRange);
1940         vk.cmdClearColorImage(*m_cmdBuffer, *m_dstImage, VK_IMAGE_LAYOUT_GENERAL, &dstClearValue, 1u, &subRange);
1941
1942
1943         vk.cmdResetQueryPool(*m_cmdBuffer, *m_queryPool, 0u, 1u);
1944
1945         // Copy Operations
1946         const VkImageSubresourceLayers imgSubResCopy =
1947         {
1948                 VK_IMAGE_ASPECT_COLOR_BIT,              // VkImageAspectFlags  aspectMask;
1949                 0u,                                     // deUint32            mipLevel;
1950                 0u,                                     // deUint32            baseArrayLayer;
1951                 1u,                                     // deUint32            layerCount;
1952         };
1953
1954         const VkOffset3D nullOffset  = {0u, 0u, 0u};
1955         const VkExtent3D imageExtent = {m_imageWidth, m_imageHeight, 1u};
1956         switch(m_method)
1957         {
1958                 case TRANSFER_METHOD_COPY_BUFFER:
1959                         {
1960                                 const VkBufferCopy  copyBufRegion =
1961                                 {
1962                                         0u,      // VkDeviceSize    srcOffset;
1963                                         0u,      // VkDeviceSize    destOffset;
1964                                         512u,    // VkDeviceSize    copySize;
1965                                 };
1966                                 vk.cmdCopyBuffer(*m_cmdBuffer, *m_srcBuffer, *m_dstBuffer, 1u, &copyBufRegion);
1967                                 break;
1968                         }
1969                 case TRANSFER_METHOD_COPY_IMAGE:
1970                         {
1971                                 const VkImageCopy copyImageRegion =
1972                                 {
1973                                         imgSubResCopy,                          // VkImageSubresourceCopy  srcSubresource;
1974                                         nullOffset,                             // VkOffset3D              srcOffset;
1975                                         imgSubResCopy,                          // VkImageSubresourceCopy  destSubresource;
1976                                         nullOffset,                             // VkOffset3D              destOffset;
1977                                         imageExtent,                            // VkExtent3D              extent;
1978
1979                                 };
1980                                 vk.cmdCopyImage(*m_cmdBuffer, *m_srcImage, VK_IMAGE_LAYOUT_GENERAL, *m_dstImage, VK_IMAGE_LAYOUT_GENERAL, 1u, &copyImageRegion);
1981                                 break;
1982                         }
1983                 case TRANSFER_METHOD_COPY_BUFFER_TO_IMAGE:
1984                         {
1985                                 const VkBufferImageCopy bufImageCopy =
1986                                 {
1987                                         0u,                                     // VkDeviceSize            bufferOffset;
1988                                         (deUint32)m_bufSize,                    // deUint32                bufferRowLength;
1989                                         (deUint32)m_imageHeight,                // deUint32                bufferImageHeight;
1990                                         imgSubResCopy,                          // VkImageSubresourceCopy  imageSubresource;
1991                                         nullOffset,                             // VkOffset3D              imageOffset;
1992                                         imageExtent,                            // VkExtent3D              imageExtent;
1993                                 };
1994                                 vk.cmdCopyBufferToImage(*m_cmdBuffer, *m_srcBuffer, *m_dstImage, VK_IMAGE_LAYOUT_GENERAL, 1u, &bufImageCopy);
1995                                 break;
1996                         }
1997                 case TRANSFER_METHOD_COPY_IMAGE_TO_BUFFER:
1998                         {
1999                                 const VkBufferImageCopy imgBufferCopy =
2000                                 {
2001                                         0u,                                     // VkDeviceSize            bufferOffset;
2002                                         (deUint32)m_bufSize,                    // deUint32                bufferRowLength;
2003                                         (deUint32)m_imageHeight,                // deUint32                bufferImageHeight;
2004                                         imgSubResCopy,                          // VkImageSubresourceCopy  imageSubresource;
2005                                         nullOffset,                             // VkOffset3D              imageOffset;
2006                                         imageExtent,                            // VkExtent3D              imageExtent;
2007                                 };
2008                                 vk.cmdCopyImageToBuffer(*m_cmdBuffer, *m_srcImage, VK_IMAGE_LAYOUT_GENERAL, *m_dstBuffer, 1u, &imgBufferCopy);
2009                                 break;
2010                         }
2011                 case TRANSFER_METHOD_BLIT_IMAGE:
2012                         {
2013                                 const VkImageBlit imageBlt =
2014                                 {
2015                                         imgSubResCopy,                          // VkImageSubresourceCopy  srcSubresource;
2016                                         nullOffset,                             // VkOffset3D              srcOffset;
2017                                         imageExtent,                            // VkExtent3D              srcExtent;
2018                                         imgSubResCopy,                          // VkImageSubresourceCopy  destSubresource;
2019                                         nullOffset,                             // VkOffset3D              destOffset;
2020                                         imageExtent,                            // VkExtent3D              destExtent;
2021                                 };
2022                                 vk.cmdBlitImage(*m_cmdBuffer, *m_srcImage, VK_IMAGE_LAYOUT_GENERAL, *m_dstImage, VK_IMAGE_LAYOUT_GENERAL, 1u, &imageBlt, VK_FILTER_NEAREST);
2023                                 break;
2024                         }
2025                 case TRANSFER_METHOD_CLEAR_COLOR_IMAGE:
2026                         {
2027                                 vk.cmdClearColorImage(*m_cmdBuffer, *m_dstImage, VK_IMAGE_LAYOUT_GENERAL, &srcClearValue, 1u, &subRange);
2028                                 break;
2029                         }
2030                 case TRANSFER_METHOD_CLEAR_DEPTH_STENCIL_IMAGE:
2031                         {
2032                                 const VkClearDepthStencilValue clearDSValue =
2033                                 {
2034                                         1.0f,                                   // float       depth;
2035                                         0u,                                     // deUint32    stencil;
2036                                 };
2037                                 vk.cmdClearDepthStencilImage(*m_cmdBuffer, *m_depthImage, VK_IMAGE_LAYOUT_GENERAL, &clearDSValue, 1u, &subRange);
2038                                 break;
2039                         }
2040                 case TRANSFER_METHOD_FILL_BUFFER:
2041                         {
2042                                 vk.cmdFillBuffer(*m_cmdBuffer, *m_dstBuffer, 0u, m_bufSize, 0x0);
2043                                 break;
2044                         }
2045                 case TRANSFER_METHOD_UPDATE_BUFFER:
2046                         {
2047                                 const deUint32 data[] =
2048                                 {
2049                                         0xdeadbeef, 0xabcdef00, 0x12345678
2050                                 };
2051                                 vk.cmdUpdateBuffer(*m_cmdBuffer, *m_dstBuffer, 0x10, sizeof(data), data);
2052                                 break;
2053                         }
2054                 case TRANSFER_METHOD_COPY_QUERY_POOL_RESULTS:
2055                         {
2056                                 vk.cmdWriteTimestamp(*m_cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, *m_queryPool, 0u);
2057                                 vk.cmdCopyQueryPoolResults(*m_cmdBuffer, *m_queryPool, 0u, 1u, *m_dstBuffer, 0u, 8u, VK_QUERY_RESULT_64_BIT | VK_QUERY_RESULT_WAIT_BIT);
2058                                 break;
2059                         }
2060                 case TRANSFER_METHOD_RESOLVE_IMAGE:
2061                         {
2062                                 const VkImageResolve imageResolve =
2063                                 {
2064                                         imgSubResCopy,                              // VkImageSubresourceLayers  srcSubresource;
2065                                         nullOffset,                                 // VkOffset3D                srcOffset;
2066                                         imgSubResCopy,                              // VkImageSubresourceLayers  destSubresource;
2067                                         nullOffset,                                 // VkOffset3D                destOffset;
2068                                         imageExtent,                                // VkExtent3D                extent;
2069                                 };
2070                                 vk.cmdResolveImage(*m_cmdBuffer, *m_msImage, VK_IMAGE_LAYOUT_GENERAL, *m_dstImage, VK_IMAGE_LAYOUT_GENERAL, 1u, &imageResolve);
2071                                 break;
2072                         }
2073                 default:
2074                         DE_FATAL("Unknown Transfer Method!");
2075                         break;
2076         };
2077
2078         deUint32 timestampEntry = 0u;
2079         for (StageFlagVector::const_iterator it = m_stages.begin(); it != m_stages.end(); it++)
2080         {
2081                 vk.cmdWriteTimestamp(*m_cmdBuffer, *it, *m_queryPool, timestampEntry++);
2082         }
2083
2084         VK_CHECK(vk.endCommandBuffer(*m_cmdBuffer));
2085 }
2086
2087 } // anonymous
2088
2089 tcu::TestCaseGroup* createTimestampTests (tcu::TestContext& testCtx)
2090 {
2091         de::MovePtr<tcu::TestCaseGroup> timestampTests (new tcu::TestCaseGroup(testCtx, "timestamp", "timestamp tests"));
2092
2093         // Basic Graphics Tests
2094         {
2095                 de::MovePtr<tcu::TestCaseGroup> basicGraphicsTests (new tcu::TestCaseGroup(testCtx, "basic_graphics_tests", "Record timestamp in different pipeline stages of basic graphics tests"));
2096
2097                 const VkPipelineStageFlagBits basicGraphicsStages0[][2] =
2098                 {
2099                   {VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,   VK_PIPELINE_STAGE_VERTEX_INPUT_BIT},
2100                   {VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,   VK_PIPELINE_STAGE_VERTEX_SHADER_BIT},
2101                   {VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,   VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT},
2102                   {VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,   VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT},
2103                   {VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,   VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT},
2104                   {VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,   VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT},
2105                   {VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,   VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT},
2106                   {VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,   VK_PIPELINE_STAGE_ALL_COMMANDS_BIT},
2107                 };
2108                 for (deUint32 stageNdx = 0u; stageNdx < DE_LENGTH_OF_ARRAY(basicGraphicsStages0); stageNdx++)
2109                 {
2110                         TimestampTestParam param(basicGraphicsStages0[stageNdx], 2u, true);
2111                         basicGraphicsTests->addChild(newTestCase<BasicGraphicsTest>(testCtx, &param));
2112                         param.toggleInRenderPass();
2113                         basicGraphicsTests->addChild(newTestCase<BasicGraphicsTest>(testCtx, &param));
2114                 }
2115
2116                 const VkPipelineStageFlagBits basicGraphicsStages1[][3] =
2117                 {
2118                   {VK_PIPELINE_STAGE_VERTEX_SHADER_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,      VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT},
2119                   {VK_PIPELINE_STAGE_VERTEX_INPUT_BIT,  VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT},
2120                 };
2121                 for (deUint32 stageNdx = 0u; stageNdx < DE_LENGTH_OF_ARRAY(basicGraphicsStages1); stageNdx++)
2122                 {
2123                         TimestampTestParam param(basicGraphicsStages1[stageNdx], 3u, true);
2124                         basicGraphicsTests->addChild(newTestCase<BasicGraphicsTest>(testCtx, &param));
2125                         param.toggleInRenderPass();
2126                         basicGraphicsTests->addChild(newTestCase<BasicGraphicsTest>(testCtx, &param));
2127                 }
2128
2129                 timestampTests->addChild(basicGraphicsTests.release());
2130         }
2131
2132         // Advanced Graphics Tests
2133         {
2134                 de::MovePtr<tcu::TestCaseGroup> advGraphicsTests (new tcu::TestCaseGroup(testCtx, "advanced_graphics_tests", "Record timestamp in different pipeline stages of advanced graphics tests"));
2135
2136                 const VkPipelineStageFlagBits advGraphicsStages[][2] =
2137                 {
2138                         {VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT},
2139                         {VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TESSELLATION_CONTROL_SHADER_BIT},
2140                         {VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TESSELLATION_EVALUATION_SHADER_BIT},
2141                         {VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT},
2142                 };
2143                 for (deUint32 stageNdx = 0u; stageNdx < DE_LENGTH_OF_ARRAY(advGraphicsStages); stageNdx++)
2144                 {
2145                         TimestampTestParam param(advGraphicsStages[stageNdx], 2u, true);
2146                         advGraphicsTests->addChild(newTestCase<AdvGraphicsTest>(testCtx, &param));
2147                         param.toggleInRenderPass();
2148                         advGraphicsTests->addChild(newTestCase<AdvGraphicsTest>(testCtx, &param));
2149                 }
2150
2151                 timestampTests->addChild(advGraphicsTests.release());
2152         }
2153
2154         // Basic Compute Tests
2155         {
2156                 de::MovePtr<tcu::TestCaseGroup> basicComputeTests (new tcu::TestCaseGroup(testCtx, "basic_compute_tests", "Record timestamp for computer stages"));
2157
2158                 const VkPipelineStageFlagBits basicComputeStages[][2] =
2159                 {
2160                         {VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT},
2161                         {VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT},
2162                 };
2163                 for (deUint32 stageNdx = 0u; stageNdx < DE_LENGTH_OF_ARRAY(basicComputeStages); stageNdx++)
2164                 {
2165                         TimestampTestParam param(basicComputeStages[stageNdx], 2u, false);
2166                         basicComputeTests->addChild(newTestCase<BasicComputeTest>(testCtx, &param));
2167                 }
2168
2169                 timestampTests->addChild(basicComputeTests.release());
2170         }
2171
2172         // Transfer Tests
2173         {
2174                 de::MovePtr<tcu::TestCaseGroup> transferTests (new tcu::TestCaseGroup(testCtx, "transfer_tests", "Record timestamp for transfer stages"));
2175
2176                 const VkPipelineStageFlagBits transferStages[][2] =
2177                 {
2178                         {VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT},
2179                         {VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_HOST_BIT},
2180                 };
2181                 for (deUint32 stageNdx = 0u; stageNdx < DE_LENGTH_OF_ARRAY(transferStages); stageNdx++)
2182                 {
2183                         for (deUint32 method = 0u; method < TRANSFER_METHOD_LAST; method++)
2184                         {
2185                                 TransferTimestampTestParam param(transferStages[stageNdx], 2u, false, method);
2186                                 transferTests->addChild(newTestCase<TransferTest>(testCtx, &param));
2187                         }
2188                 }
2189
2190                 timestampTests->addChild(transferTests.release());
2191         }
2192
2193         // Misc Tests
2194         {
2195                 de::MovePtr<tcu::TestCaseGroup> miscTests (new tcu::TestCaseGroup(testCtx, "misc_tests", "Misc tests that can not be categorized to other group."));
2196
2197                 const VkPipelineStageFlagBits miscStages[] = {VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT};
2198                 TimestampTestParam param(miscStages, 1u, false);
2199                 miscTests->addChild(new TimestampTest(testCtx,
2200                                                                                           "timestamp_only",
2201                                                                                           "Only write timestamp command in the commmand buffer",
2202                                                                                           &param));
2203
2204                 timestampTests->addChild(miscTests.release());
2205         }
2206
2207         return timestampTests.release();
2208 }
2209
2210 } // pipeline
2211
2212 } // vkt