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