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