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