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