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