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