• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*------------------------------------------------------------------------
2  * Vulkan Conformance Tests
3  * ------------------------
4  *
5  * Copyright (c) 2016 The Khronos Group Inc.
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  *
19  *//*!
20  * \file
21  * \brief Synchronization internally synchronized objects tests
22  *//*--------------------------------------------------------------------*/
23 
24 #include "vktSynchronizationInternallySynchronizedObjectsTests.hpp"
25 #include "vktTestCaseUtil.hpp"
26 #include "vktSynchronizationUtil.hpp"
27 #include "vktCustomInstancesDevices.hpp"
28 
29 #include "vkRef.hpp"
30 #include "tcuDefs.hpp"
31 #include "vkTypeUtil.hpp"
32 #include "vkBarrierUtil.hpp"
33 #include "vkPlatform.hpp"
34 #include "vkBuilderUtil.hpp"
35 #include "vkImageUtil.hpp"
36 #include "vkCmdUtil.hpp"
37 #include "vkObjUtil.hpp"
38 
39 #include "tcuResultCollector.hpp"
40 #include "tcuCommandLine.hpp"
41 
42 #include "deThread.hpp"
43 #include "deMutex.hpp"
44 #include "deSharedPtr.hpp"
45 
46 
47 #include <limits>
48 #include <iterator>
49 
50 namespace vkt
51 {
52 namespace synchronization
53 {
54 namespace
55 {
56 using namespace vk;
57 
58 using std::vector;
59 using std::string;
60 using std::map;
61 using std::exception;
62 using std::ostringstream;
63 
64 using tcu::TestStatus;
65 using tcu::TestContext;
66 using tcu::ResultCollector;
67 using tcu::TestException;
68 
69 using de::UniquePtr;
70 using de::MovePtr;
71 using de::SharedPtr;
72 using de::Mutex;
73 using de::Thread;
74 using de::clamp;
75 
76 enum {EXECUTION_PER_THREAD = 100, BUFFER_ELEMENT_COUNT = 16, BUFFER_SIZE = BUFFER_ELEMENT_COUNT*4 };
77 
78 class MultiQueues
79 {
80 	typedef struct QueueType
81 	{
82 		vector<VkQueue>	queues;
83 		vector<bool>	available;
84 	} Queues;
85 
86 public:
87 
addQueueFamilyIndex(const deUint32 & queueFamilyIndex,const deUint32 & count)88 	inline void		addQueueFamilyIndex		(const deUint32& queueFamilyIndex, const deUint32& count)
89 	{
90 		Queues temp;
91 		vector<bool>::iterator it;
92 		it = temp.available.begin();
93 		temp.available.insert(it, count, false);
94 
95 		temp.queues.resize(count);
96 		m_queues[queueFamilyIndex] = temp;
97 	}
98 
getQueueFamilyIndex(const int index)99 	const deUint32& getQueueFamilyIndex		(const int index)
100 	{
101 		map<deUint32,Queues>::iterator it = m_queues.begin();
102 		advance (it, index);
103 		return it->first;
104 	}
105 
countQueueFamilyIndex(void)106 	inline size_t	countQueueFamilyIndex	(void)
107 	{
108 		return m_queues.size();
109 	}
110 
getQueues(const int index)111 	Queues &		getQueues				(const int index)
112 	{
113 		map<deUint32,Queues>::iterator it = m_queues.begin();
114 		advance (it, index);
115 		return it->second;
116 	}
117 
getFreeQueue(deUint32 & returnQueueFamilyIndex,VkQueue & returnQueues,int & returnQueueIndex)118 	bool			getFreeQueue			(deUint32& returnQueueFamilyIndex, VkQueue& returnQueues, int& returnQueueIndex)
119 	{
120 		for (int queueFamilyIndexNdx = 0 ; queueFamilyIndexNdx < static_cast<int>(m_queues.size()); ++queueFamilyIndexNdx)
121 		{
122 			Queues& queue = m_queues[getQueueFamilyIndex(queueFamilyIndexNdx)];
123 			for (int queueNdx = 0; queueNdx < static_cast<int>(queue.queues.size()); ++queueNdx)
124 			{
125 				m_mutex.lock();
126 				if (queue.available[queueNdx])
127 				{
128 					queue.available[queueNdx]	= false;
129 					returnQueueFamilyIndex		= getQueueFamilyIndex(queueFamilyIndexNdx);
130 					returnQueues				= queue.queues[queueNdx];
131 					returnQueueIndex			= queueNdx;
132 					m_mutex.unlock();
133 					return true;
134 				}
135 				m_mutex.unlock();
136 			}
137 		}
138 		return false;
139 	}
140 
releaseQueue(const deUint32 & queueFamilyIndex,const int & queueIndex)141 	void			releaseQueue			(const deUint32& queueFamilyIndex, const int& queueIndex)
142 	{
143 		m_mutex.lock();
144 		m_queues[queueFamilyIndex].available[queueIndex] = true;
145 		m_mutex.unlock();
146 	}
147 
setDevice(Move<VkDevice> device)148 	inline void		setDevice				(Move<VkDevice> device)
149 	{
150 		m_logicalDevice = device;
151 	}
152 
getDevice(void)153 	inline VkDevice	getDevice				(void)
154 	{
155 		return *m_logicalDevice;
156 	}
157 
158 	MovePtr<Allocator>		m_allocator;
159 protected:
160 	Move<VkDevice>			m_logicalDevice;
161 	map<deUint32,Queues>	m_queues;
162 	Mutex					m_mutex;
163 
164 };
165 
createAllocator(const Context & context,const VkDevice & device)166 MovePtr<Allocator> createAllocator (const Context& context, const VkDevice& device)
167 {
168 	const DeviceInterface&					deviceInterface			= context.getDeviceInterface();
169 	const InstanceInterface&				instance				= context.getInstanceInterface();
170 	const VkPhysicalDevice					physicalDevice			= context.getPhysicalDevice();
171 	const VkPhysicalDeviceMemoryProperties	deviceMemoryProperties	= getPhysicalDeviceMemoryProperties(instance, physicalDevice);
172 
173 	// Create memory allocator for device
174 	return MovePtr<Allocator> (new SimpleAllocator(deviceInterface, device, deviceMemoryProperties));
175 }
176 
checkQueueFlags(const VkQueueFlags & availableFlag,const VkQueueFlags & neededFlag)177 bool checkQueueFlags (const VkQueueFlags& availableFlag, const VkQueueFlags& neededFlag)
178 {
179 	if (VK_QUEUE_TRANSFER_BIT == neededFlag)
180 	{
181 		if ( (availableFlag & VK_QUEUE_GRAPHICS_BIT) == VK_QUEUE_GRAPHICS_BIT ||
182 			 (availableFlag & VK_QUEUE_COMPUTE_BIT)  == VK_QUEUE_COMPUTE_BIT  ||
183 			 (availableFlag & VK_QUEUE_TRANSFER_BIT) == VK_QUEUE_TRANSFER_BIT
184 		   )
185 			return true;
186 	}
187 	else if ((availableFlag & neededFlag) == neededFlag)
188 	{
189 		return true;
190 	}
191 	return false;
192 }
193 
createQueues(const Context & context,const VkQueueFlags & queueFlag)194 MovePtr<MultiQueues> createQueues (const Context& context, const VkQueueFlags& queueFlag)
195 {
196 	const DeviceInterface&					vk						= context.getDeviceInterface();
197 	const InstanceInterface&				instance				= context.getInstanceInterface();
198 	const VkPhysicalDevice					physicalDevice			= context.getPhysicalDevice();
199 	MovePtr<MultiQueues>					moveQueues				(new MultiQueues());
200 	MultiQueues&							queues					= *moveQueues;
201 	VkDeviceCreateInfo						deviceInfo;
202 	VkPhysicalDeviceFeatures				deviceFeatures;
203 	vector<VkQueueFamilyProperties>			queueFamilyProperties;
204 	vector<float>							queuePriorities;
205 	vector<VkDeviceQueueCreateInfo>			queueInfos;
206 
207 	queueFamilyProperties = getPhysicalDeviceQueueFamilyProperties(instance, physicalDevice);
208 
209 	for (deUint32 queuePropertiesNdx = 0; queuePropertiesNdx < queueFamilyProperties.size(); ++queuePropertiesNdx)
210 	{
211 		if (checkQueueFlags(queueFamilyProperties[queuePropertiesNdx].queueFlags, queueFlag))
212 		{
213 			queues.addQueueFamilyIndex(queuePropertiesNdx, queueFamilyProperties[queuePropertiesNdx].queueCount);
214 		}
215 	}
216 
217 	if (queues.countQueueFamilyIndex() == 0)
218 	{
219 		TCU_THROW(NotSupportedError, "Queue not found");
220 	}
221 
222 	{
223 		vector<float>::iterator it				= queuePriorities.begin();
224 		unsigned int			maxQueueCount	= 0;
225 		for (int queueFamilyIndexNdx = 0; queueFamilyIndexNdx < static_cast<int>(queues.countQueueFamilyIndex()); ++queueFamilyIndexNdx)
226 		{
227 			if (queues.getQueues(queueFamilyIndexNdx).queues.size() > maxQueueCount)
228 				maxQueueCount = static_cast<unsigned int>(queues.getQueues(queueFamilyIndexNdx).queues.size());
229 		}
230 		queuePriorities.insert(it, maxQueueCount, 1.0);
231 	}
232 
233 	for (int queueFamilyIndexNdx = 0; queueFamilyIndexNdx < static_cast<int>(queues.countQueueFamilyIndex()); ++queueFamilyIndexNdx)
234 	{
235 		VkDeviceQueueCreateInfo	queueInfo;
236 		const deUint32			queueCount	= static_cast<deUint32>(queues.getQueues(queueFamilyIndexNdx).queues.size());
237 
238 		deMemset(&queueInfo, 0, sizeof(queueInfo));
239 
240 		queueInfo.sType				= VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
241 		queueInfo.pNext				= DE_NULL;
242 		queueInfo.flags				= (VkDeviceQueueCreateFlags)0u;
243 		queueInfo.queueFamilyIndex	= queues.getQueueFamilyIndex(queueFamilyIndexNdx);
244 		queueInfo.queueCount		= queueCount;
245 		queueInfo.pQueuePriorities	= &queuePriorities[0];
246 
247 		queueInfos.push_back(queueInfo);
248 	}
249 
250 	deMemset(&deviceInfo, 0, sizeof(deviceInfo));
251 	instance.getPhysicalDeviceFeatures(physicalDevice, &deviceFeatures);
252 
253 	deviceInfo.sType					= VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
254 	deviceInfo.pNext					= DE_NULL;
255 	deviceInfo.enabledExtensionCount	= 0u;
256 	deviceInfo.ppEnabledExtensionNames	= DE_NULL;
257 	deviceInfo.enabledLayerCount		= 0u;
258 	deviceInfo.ppEnabledLayerNames		= DE_NULL;
259 	deviceInfo.pEnabledFeatures			= &deviceFeatures;
260 	deviceInfo.queueCreateInfoCount		= static_cast<deUint32>(queues.countQueueFamilyIndex());
261 	deviceInfo.pQueueCreateInfos		= &queueInfos[0];
262 
263 	queues.setDevice(createCustomDevice(context.getTestContext().getCommandLine().isValidationEnabled(), context.getPlatformInterface(), context.getInstance(), instance, physicalDevice, &deviceInfo));
264 
265 	for (deUint32 queueFamilyIndex = 0; queueFamilyIndex < queues.countQueueFamilyIndex(); ++queueFamilyIndex)
266 	{
267 		for (deUint32 queueReqNdx = 0; queueReqNdx < queues.getQueues(queueFamilyIndex).queues.size(); ++queueReqNdx)
268 		{
269 			vk.getDeviceQueue(queues.getDevice(), queues.getQueueFamilyIndex(queueFamilyIndex), queueReqNdx, &queues.getQueues(queueFamilyIndex).queues[queueReqNdx]);
270 			queues.getQueues(queueFamilyIndex).available[queueReqNdx]=true;
271 		}
272 	}
273 
274 	queues.m_allocator = createAllocator(context, queues.getDevice());
275 	return moveQueues;
276 }
277 
executeComputePipeline(const Context & context,const VkPipeline & pipeline,const VkPipelineLayout & pipelineLayout,const VkDescriptorSetLayout & descriptorSetLayout,MultiQueues & queues,const deUint32 & shadersExecutions)278 TestStatus executeComputePipeline (const Context& context, const VkPipeline& pipeline, const VkPipelineLayout& pipelineLayout,
279 									const VkDescriptorSetLayout& descriptorSetLayout, MultiQueues& queues, const deUint32& shadersExecutions)
280 {
281 	const DeviceInterface&			vk					= context.getDeviceInterface();
282 	const VkDevice					device				= queues.getDevice();
283 	deUint32						queueFamilyIndex;
284 	VkQueue							queue;
285 	int								queueIndex;
286 	while(!queues.getFreeQueue(queueFamilyIndex, queue, queueIndex)){}
287 
288 	{
289 		const Unique<VkDescriptorPool>	descriptorPool		(DescriptorPoolBuilder()
290 																.addType(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER)
291 																.build(vk, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u));
292 		Buffer							resultBuffer		(vk, device, *queues.m_allocator, makeBufferCreateInfo(BUFFER_SIZE, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT), MemoryRequirement::HostVisible);
293 		const VkBufferMemoryBarrier		bufferBarrier		= makeBufferMemoryBarrier(VK_ACCESS_SHADER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT, *resultBuffer, 0ull, BUFFER_SIZE);
294 		const Unique<VkCommandPool>		cmdPool				(createCommandPool(vk, device, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, queueFamilyIndex));
295 		const Unique<VkCommandBuffer>	cmdBuffer			(makeCommandBuffer(vk, device, *cmdPool));
296 
297 		{
298 			const Allocation& alloc = resultBuffer.getAllocation();
299 			deMemset(alloc.getHostPtr(), 0, BUFFER_SIZE);
300 			flushAlloc(vk, device, alloc);
301 		}
302 
303 		// Start recording commands
304 		beginCommandBuffer(vk, *cmdBuffer);
305 
306 		vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, pipeline);
307 
308 		// Create descriptor set
309 		const Unique<VkDescriptorSet> descriptorSet(makeDescriptorSet(vk, device, *descriptorPool, descriptorSetLayout));
310 
311 		const VkDescriptorBufferInfo resultDescriptorInfo = makeDescriptorBufferInfo(*resultBuffer, 0ull, BUFFER_SIZE);
312 
313 		DescriptorSetUpdateBuilder()
314 			.writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &resultDescriptorInfo)
315 			.update(vk, device);
316 
317 		vk.cmdBindDescriptorSets(*cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, pipelineLayout, 0u, 1u, &descriptorSet.get(), 0u, DE_NULL);
318 
319 		// Dispatch indirect compute command
320 		vk.cmdDispatch(*cmdBuffer, shadersExecutions, 1u, 1u);
321 
322 		vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_PIPELINE_STAGE_HOST_BIT, (VkDependencyFlags)0,
323 								 0, (const VkMemoryBarrier*)DE_NULL,
324 								 1, &bufferBarrier,
325 								 0, (const VkImageMemoryBarrier*)DE_NULL);
326 
327 		// End recording commands
328 		endCommandBuffer(vk, *cmdBuffer);
329 
330 		// Wait for command buffer execution finish
331 		submitCommandsAndWait(vk, device, queue, *cmdBuffer);
332 		queues.releaseQueue(queueFamilyIndex, queueIndex);
333 
334 		{
335 			const Allocation& resultAlloc = resultBuffer.getAllocation();
336 			invalidateAlloc(vk, device, resultAlloc);
337 
338 			const deInt32*	ptr = reinterpret_cast<deInt32*>(resultAlloc.getHostPtr());
339 			for (deInt32 ndx = 0; ndx < BUFFER_ELEMENT_COUNT; ++ndx)
340 			{
341 				if (ptr[ndx] != ndx)
342 				{
343 					return TestStatus::fail("The data don't match");
344 				}
345 			}
346 		}
347 		return TestStatus::pass("Passed");
348 	}
349 }
350 
351 
executeGraphicPipeline(const Context & context,const VkPipeline & pipeline,const VkPipelineLayout & pipelineLayout,const VkDescriptorSetLayout & descriptorSetLayout,MultiQueues & queues,const VkRenderPass & renderPass,const deUint32 shadersExecutions)352 TestStatus executeGraphicPipeline (const Context& context, const VkPipeline& pipeline, const VkPipelineLayout& pipelineLayout,
353 									const VkDescriptorSetLayout& descriptorSetLayout, MultiQueues& queues, const VkRenderPass& renderPass, const deUint32 shadersExecutions)
354 {
355 	const DeviceInterface&			vk					= context.getDeviceInterface();
356 	const VkDevice					device				= queues.getDevice();
357 	deUint32						queueFamilyIndex;
358 	VkQueue							queue;
359 	int								queueIndex;
360 	while(!queues.getFreeQueue(queueFamilyIndex, queue, queueIndex)){}
361 
362 	{
363 		const Unique<VkDescriptorPool>	descriptorPool				(DescriptorPoolBuilder()
364 																		.addType(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER)
365 																		.build(vk, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u));
366 		Move<VkDescriptorSet>			descriptorSet				= makeDescriptorSet(vk, device, *descriptorPool, descriptorSetLayout);
367 		Buffer							resultBuffer				(vk, device, *queues.m_allocator, makeBufferCreateInfo(BUFFER_SIZE, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT), MemoryRequirement::HostVisible);
368 		const VkBufferMemoryBarrier		bufferBarrier				= makeBufferMemoryBarrier(VK_ACCESS_SHADER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT, *resultBuffer, 0ull, BUFFER_SIZE);
369 		const VkFormat					colorFormat					= VK_FORMAT_R8G8B8A8_UNORM;
370 		const VkExtent3D				colorImageExtent			= makeExtent3D(1u, 1u, 1u);
371 		const VkImageSubresourceRange	colorImageSubresourceRange	= makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u);
372 		de::MovePtr<Image>				colorAttachmentImage		= de::MovePtr<Image>(new Image(vk, device, *queues.m_allocator,
373 																		makeImageCreateInfo(VK_IMAGE_TYPE_2D, colorImageExtent, colorFormat, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT),
374 																		MemoryRequirement::Any));
375 		Move<VkImageView>				colorAttachmentView			= makeImageView(vk, device, **colorAttachmentImage, VK_IMAGE_VIEW_TYPE_2D, colorFormat, colorImageSubresourceRange);
376 		Move<VkFramebuffer>				framebuffer					= makeFramebuffer(vk, device, renderPass, *colorAttachmentView, colorImageExtent.width, colorImageExtent.height);
377 		const Unique<VkCommandPool>		cmdPool						(createCommandPool(vk, device, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, queueFamilyIndex));
378 		const Unique<VkCommandBuffer>	cmdBuffer					(makeCommandBuffer(vk, device, *cmdPool));
379 		const VkDescriptorBufferInfo	outputBufferDescriptorInfo	= makeDescriptorBufferInfo(*resultBuffer, 0ull, BUFFER_SIZE);
380 
381 		DescriptorSetUpdateBuilder()
382 			.writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &outputBufferDescriptorInfo)
383 			.update		(vk, device);
384 
385 		{
386 			const Allocation& alloc = resultBuffer.getAllocation();
387 			deMemset(alloc.getHostPtr(), 0, BUFFER_SIZE);
388 			flushAlloc(vk, device, alloc);
389 		}
390 
391 		// Start recording commands
392 		beginCommandBuffer(vk, *cmdBuffer);
393 		// Change color attachment image layout
394 		{
395 			const VkImageMemoryBarrier colorAttachmentLayoutBarrier = makeImageMemoryBarrier(
396 				(VkAccessFlags)0, VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
397 				VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
398 				**colorAttachmentImage, colorImageSubresourceRange);
399 
400 			vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, (VkDependencyFlags)0,
401 				0u, DE_NULL, 0u, DE_NULL, 1u, &colorAttachmentLayoutBarrier);
402 		}
403 
404 		{
405 			const VkRect2D	renderArea	= makeRect2D(1u, 1u);
406 			const tcu::Vec4	clearColor	= tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f);
407 			beginRenderPass(vk, *cmdBuffer, renderPass, *framebuffer, renderArea, clearColor);
408 		}
409 
410 		vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline);
411 		vk.cmdBindDescriptorSets(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipelineLayout, 0u, 1u, &descriptorSet.get(), 0u, DE_NULL);
412 
413 		vk.cmdDraw(*cmdBuffer, shadersExecutions, 1u, 0u, 0u);
414 		endRenderPass(vk, *cmdBuffer);
415 
416 		vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_VERTEX_SHADER_BIT, VK_PIPELINE_STAGE_HOST_BIT, (VkDependencyFlags)0,
417 						0, (const VkMemoryBarrier*)DE_NULL,
418 						1, &bufferBarrier,
419 						0, (const VkImageMemoryBarrier*)DE_NULL);
420 
421 		// End recording commands
422 		endCommandBuffer(vk, *cmdBuffer);
423 
424 		// Wait for command buffer execution finish
425 		submitCommandsAndWait(vk, device, queue, *cmdBuffer);
426 		queues.releaseQueue(queueFamilyIndex, queueIndex);
427 
428 		{
429 			const Allocation& resultAlloc = resultBuffer.getAllocation();
430 			invalidateAlloc(vk, device, resultAlloc);
431 
432 			const deInt32*	ptr = reinterpret_cast<deInt32*>(resultAlloc.getHostPtr());
433 			for (deInt32 ndx = 0; ndx < BUFFER_ELEMENT_COUNT; ++ndx)
434 			{
435 				if (ptr[ndx] != ndx)
436 				{
437 					return TestStatus::fail("The data don't match");
438 				}
439 			}
440 		}
441 		return TestStatus::pass("Passed");
442 	}
443 }
444 
445 
446 class ThreadGroupThread : private Thread
447 {
448 public:
ThreadGroupThread(const Context & context,VkPipelineCache pipelineCache,const VkPipelineLayout & pipelineLayout,const VkDescriptorSetLayout & descriptorSetLayout,MultiQueues & queues,const vector<deUint32> & shadersExecutions)449 							ThreadGroupThread	(const Context& context, VkPipelineCache pipelineCache, const VkPipelineLayout& pipelineLayout,
450 												const VkDescriptorSetLayout& descriptorSetLayout, MultiQueues& queues, const vector<deUint32>& shadersExecutions)
451 								: m_context				(context)
452 								, m_pipelineCache		(pipelineCache)
453 								, m_pipelineLayout		(pipelineLayout)
454 								, m_descriptorSetLayout	(descriptorSetLayout)
455 								, m_queues				(queues)
456 								, m_shadersExecutions	(shadersExecutions)
457 	{
458 	}
459 
~ThreadGroupThread(void)460 	virtual					~ThreadGroupThread	(void)
461 	{
462 	}
463 
getResultCollector(void)464 	ResultCollector&		getResultCollector	(void)
465 	{
466 		return m_resultCollector;
467 	}
468 
469 	using Thread::start;
470 	using Thread::join;
471 
472 protected:
473 	virtual TestStatus		runThread		() = 0;
474 	const Context&							m_context;
475 	VkPipelineCache							m_pipelineCache;
476 	const VkPipelineLayout&					m_pipelineLayout;
477 	const VkDescriptorSetLayout&			m_descriptorSetLayout;
478 	MultiQueues&							m_queues;
479 	const vector<deUint32>&					m_shadersExecutions;
480 
481 private:
482 							ThreadGroupThread	(const ThreadGroupThread&);
483 	ThreadGroupThread&		operator=			(const ThreadGroupThread&);
484 
run(void)485 	void					run					(void)
486 	{
487 		try
488 		{
489 			TestStatus result = runThread();
490 			m_resultCollector.addResult(result.getCode(), result.getDescription());
491 		}
492 		catch (const TestException& e)
493 		{
494 			m_resultCollector.addResult(e.getTestResult(), e.getMessage());
495 		}
496 		catch (const exception& e)
497 		{
498 			m_resultCollector.addResult(QP_TEST_RESULT_FAIL, e.what());
499 		}
500 		catch (...)
501 		{
502 			m_resultCollector.addResult(QP_TEST_RESULT_FAIL, "Exception");
503 		}
504 	}
505 
506 	ResultCollector							m_resultCollector;
507 };
508 
509 class ThreadGroup
510 {
511 	typedef vector<SharedPtr<ThreadGroupThread> >	ThreadVector;
512 public:
ThreadGroup(void)513 							ThreadGroup			(void)
514 	{
515 	}
~ThreadGroup(void)516 							~ThreadGroup		(void)
517 	{
518 	}
519 
add(MovePtr<ThreadGroupThread> thread)520 	void					add					(MovePtr<ThreadGroupThread> thread)
521 	{
522 		m_threads.push_back(SharedPtr<ThreadGroupThread>(thread.release()));
523 	}
524 
run(void)525 	TestStatus				run					(void)
526 	{
527 		ResultCollector	resultCollector;
528 
529 		for (ThreadVector::iterator threadIter = m_threads.begin(); threadIter != m_threads.end(); ++threadIter)
530 			(*threadIter)->start();
531 
532 		for (ThreadVector::iterator threadIter = m_threads.begin(); threadIter != m_threads.end(); ++threadIter)
533 		{
534 			ResultCollector&	threadResult	= (*threadIter)->getResultCollector();
535 			(*threadIter)->join();
536 			resultCollector.addResult(threadResult.getResult(), threadResult.getMessage());
537 		}
538 
539 		return TestStatus(resultCollector.getResult(), resultCollector.getMessage());
540 	}
541 
542 private:
543 	ThreadVector							m_threads;
544 };
545 
546 
547 class CreateComputeThread : public ThreadGroupThread
548 {
549 public:
CreateComputeThread(const Context & context,VkPipelineCache pipelineCache,vector<VkComputePipelineCreateInfo> & pipelineInfo,const VkPipelineLayout & pipelineLayout,const VkDescriptorSetLayout & descriptorSetLayout,MultiQueues & queues,const vector<deUint32> & shadersExecutions)550 			CreateComputeThread	(const Context& context, VkPipelineCache pipelineCache, vector<VkComputePipelineCreateInfo>& pipelineInfo,
551 								const VkPipelineLayout& pipelineLayout, const VkDescriptorSetLayout& descriptorSetLayout,
552 								MultiQueues& queues, const vector<deUint32>& shadersExecutions)
553 				: ThreadGroupThread		(context, pipelineCache, pipelineLayout, descriptorSetLayout, queues, shadersExecutions)
554 				, m_pipelineInfo		(pipelineInfo)
555 	{
556 	}
557 
runThread(void)558 	TestStatus	runThread		(void)
559 	{
560 		ResultCollector		resultCollector;
561 		for (int executionNdx = 0; executionNdx < EXECUTION_PER_THREAD; ++executionNdx)
562 		{
563 			const int shaderNdx					= executionNdx % (int)m_pipelineInfo.size();
564 			const DeviceInterface&	vk			= m_context.getDeviceInterface();
565 			const VkDevice			device		= m_queues.getDevice();
566 			Move<VkPipeline>		pipeline	= createComputePipeline(vk,device,m_pipelineCache, &m_pipelineInfo[shaderNdx]);
567 
568 			TestStatus result = executeComputePipeline(m_context, *pipeline, m_pipelineLayout, m_descriptorSetLayout, m_queues, m_shadersExecutions[shaderNdx]);
569 			resultCollector.addResult(result.getCode(), result.getDescription());
570 		}
571 		return TestStatus(resultCollector.getResult(), resultCollector.getMessage());
572 	}
573 private:
574 	vector<VkComputePipelineCreateInfo>&	m_pipelineInfo;
575 };
576 
577 class CreateGraphicThread : public ThreadGroupThread
578 {
579 public:
CreateGraphicThread(const Context & context,VkPipelineCache pipelineCache,vector<VkGraphicsPipelineCreateInfo> & pipelineInfo,const VkPipelineLayout & pipelineLayout,const VkDescriptorSetLayout & descriptorSetLayout,MultiQueues & queues,const VkRenderPass & renderPass,const vector<deUint32> & shadersExecutions)580 			CreateGraphicThread	(const Context& context, VkPipelineCache pipelineCache, vector<VkGraphicsPipelineCreateInfo>& pipelineInfo,
581 								const VkPipelineLayout& pipelineLayout, const VkDescriptorSetLayout& descriptorSetLayout,
582 								MultiQueues& queues, const VkRenderPass& renderPass, const vector<deUint32>& shadersExecutions)
583 				: ThreadGroupThread		(context, pipelineCache, pipelineLayout, descriptorSetLayout, queues, shadersExecutions)
584 				, m_pipelineInfo		(pipelineInfo)
585 				, m_renderPass			(renderPass)
586 	{}
587 
runThread(void)588 	TestStatus	runThread		(void)
589 	{
590 		ResultCollector		resultCollector;
591 		for (int executionNdx = 0; executionNdx < EXECUTION_PER_THREAD; ++executionNdx)
592 		{
593 			const int shaderNdx					= executionNdx % (int)m_pipelineInfo.size();
594 			const DeviceInterface&	vk			= m_context.getDeviceInterface();
595 			const VkDevice			device		= m_queues.getDevice();
596 			Move<VkPipeline>		pipeline	= createGraphicsPipeline(vk,device, m_pipelineCache, &m_pipelineInfo[shaderNdx]);
597 
598 			TestStatus result = executeGraphicPipeline(m_context, *pipeline, m_pipelineLayout, m_descriptorSetLayout, m_queues, m_renderPass, m_shadersExecutions[shaderNdx]);
599 			resultCollector.addResult(result.getCode(), result.getDescription());
600 		}
601 		return TestStatus(resultCollector.getResult(), resultCollector.getMessage());
602 	}
603 
604 private:
605 	vector<VkGraphicsPipelineCreateInfo>&	m_pipelineInfo;
606 	const VkRenderPass&						m_renderPass;
607 };
608 
609 class PipelineCacheComputeTestInstance  : public TestInstance
610 {
611 	typedef vector<SharedPtr<Unique<VkShaderModule> > > ShaderModuleVector;
612 public:
PipelineCacheComputeTestInstance(Context & context,const vector<deUint32> & shadersExecutions)613 				PipelineCacheComputeTestInstance	(Context& context, const vector<deUint32>& shadersExecutions)
614 					: TestInstance			(context)
615 					, m_shadersExecutions	(shadersExecutions)
616 
617 	{
618 	}
619 
iterate(void)620 	TestStatus	iterate								(void)
621 	{
622 		const DeviceInterface&					vk					= m_context.getDeviceInterface();
623 		MovePtr<MultiQueues>					queues				= createQueues(m_context, VK_QUEUE_COMPUTE_BIT);
624 		const VkDevice							device				= queues->getDevice();
625 		ShaderModuleVector						shaderCompModules	= addShaderModules(device);
626 		Buffer									resultBuffer		(vk, device, *queues->m_allocator, makeBufferCreateInfo(BUFFER_SIZE, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT), MemoryRequirement::HostVisible);
627 		const Move<VkDescriptorSetLayout>		descriptorSetLayout	(DescriptorSetLayoutBuilder()
628 																		.addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_SHADER_STAGE_COMPUTE_BIT)
629 																		.build(vk, device));
630 		const Move<VkPipelineLayout>			pipelineLayout		(makePipelineLayout(vk, device, *descriptorSetLayout));
631 		vector<VkPipelineShaderStageCreateInfo>	shaderStageInfos	= addShaderStageInfo(shaderCompModules);
632 		vector<VkComputePipelineCreateInfo>		pipelineInfo		= addPipelineInfo(*pipelineLayout, shaderStageInfos);
633 		const VkPipelineCacheCreateInfo			pipelineCacheInfo	=
634 																	{
635 																		VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO,	// VkStructureType             sType;
636 																		DE_NULL,										// const void*                 pNext;
637 																		0u,												// VkPipelineCacheCreateFlags  flags;
638 																		0u,												// deUintptr                   initialDataSize;
639 																		DE_NULL,										// const void*                 pInitialData;
640 																	};
641 		Move<VkPipelineCache>					pipelineCache		= createPipelineCache(vk, device, &pipelineCacheInfo);
642 		Move<VkPipeline>						pipeline			= createComputePipeline(vk, device, *pipelineCache, &pipelineInfo[0]);
643 		const deUint32							numThreads			= clamp(deGetNumAvailableLogicalCores(), 4u, 32u);
644 		ThreadGroup								threads;
645 
646 		executeComputePipeline(m_context, *pipeline, *pipelineLayout, *descriptorSetLayout, *queues, m_shadersExecutions[0]);
647 
648 		for (deUint32 ndx = 0; ndx < numThreads; ++ndx)
649 			threads.add(MovePtr<ThreadGroupThread>(new CreateComputeThread(
650 				m_context, *pipelineCache, pipelineInfo, *pipelineLayout, *descriptorSetLayout, *queues, m_shadersExecutions)));
651 
652 		{
653 			TestStatus thread_result = threads.run();
654 			if(thread_result.getCode())
655 			{
656 				return thread_result;
657 			}
658 		}
659 		return TestStatus::pass("Passed");
660 	}
661 
662 private:
addShaderModules(const VkDevice & device)663 	ShaderModuleVector							addShaderModules					(const VkDevice& device)
664 	{
665 		const DeviceInterface&	vk	= m_context.getDeviceInterface();
666 		ShaderModuleVector		shaderCompModules;
667 		shaderCompModules.resize(m_shadersExecutions.size());
668 		for (int shaderNdx = 0; shaderNdx <  static_cast<int>(m_shadersExecutions.size()); ++shaderNdx)
669 		{
670 			ostringstream shaderName;
671 			shaderName<<"compute_"<<shaderNdx;
672 			shaderCompModules[shaderNdx] = SharedPtr<Unique<VkShaderModule> > (new Unique<VkShaderModule>(createShaderModule(vk, device, m_context.getBinaryCollection().get(shaderName.str()), (VkShaderModuleCreateFlags)0)));
673 		}
674 		return shaderCompModules;
675 	}
676 
addShaderStageInfo(const ShaderModuleVector & shaderCompModules)677 	vector<VkPipelineShaderStageCreateInfo>		addShaderStageInfo					(const ShaderModuleVector& shaderCompModules)
678 	{
679 		VkPipelineShaderStageCreateInfo			shaderStageInfo;
680 		vector<VkPipelineShaderStageCreateInfo>	shaderStageInfos;
681 		shaderStageInfo.sType				=	VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
682 		shaderStageInfo.pNext				=	DE_NULL;
683 		shaderStageInfo.flags				=	(VkPipelineShaderStageCreateFlags)0;
684 		shaderStageInfo.stage				=	VK_SHADER_STAGE_COMPUTE_BIT;
685 		shaderStageInfo.pName				=	"main";
686 		shaderStageInfo.pSpecializationInfo	=	DE_NULL;
687 
688 		for (int shaderNdx = 0; shaderNdx <  static_cast<int>(m_shadersExecutions.size()); ++shaderNdx)
689 		{
690 			shaderStageInfo.module = *(*shaderCompModules[shaderNdx]);
691 			shaderStageInfos.push_back(shaderStageInfo);
692 		}
693 		return shaderStageInfos;
694 	}
695 
addPipelineInfo(VkPipelineLayout pipelineLayout,const vector<VkPipelineShaderStageCreateInfo> & shaderStageInfos)696 	vector<VkComputePipelineCreateInfo>		addPipelineInfo						(VkPipelineLayout pipelineLayout, const vector<VkPipelineShaderStageCreateInfo>& shaderStageInfos)
697 	{
698 		vector<VkComputePipelineCreateInfo> pipelineInfos;
699 		VkComputePipelineCreateInfo	computePipelineInfo;
700 									computePipelineInfo.sType				= VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO;
701 									computePipelineInfo.pNext				= DE_NULL;
702 									computePipelineInfo.flags				= (VkPipelineCreateFlags)0;
703 									computePipelineInfo.layout				= pipelineLayout;
704 									computePipelineInfo.basePipelineHandle	= DE_NULL;
705 									computePipelineInfo.basePipelineIndex	= 0;
706 
707 		for (int shaderNdx = 0; shaderNdx < static_cast<int>(m_shadersExecutions.size()); ++shaderNdx)
708 		{
709 			computePipelineInfo.stage = shaderStageInfos[shaderNdx];
710 			pipelineInfos.push_back(computePipelineInfo);
711 		}
712 		return pipelineInfos;
713 	}
714 
715 	const vector<deUint32>	m_shadersExecutions;
716 };
717 
718 class PipelineCacheGraphicTestInstance  : public TestInstance
719 {
720 	typedef vector<SharedPtr<Unique<VkShaderModule> > > ShaderModuleVector;
721 public:
PipelineCacheGraphicTestInstance(Context & context,const vector<deUint32> & shadersExecutions)722 											PipelineCacheGraphicTestInstance	(Context& context, const vector<deUint32>& shadersExecutions)
723 								: TestInstance			(context)
724 								, m_shadersExecutions	(shadersExecutions)
725 
726 	{
727 	}
728 
iterate(void)729 	TestStatus								iterate								(void)
730 	{
731 		requireFeatures(m_context.getInstanceInterface(), m_context.getPhysicalDevice(), FEATURE_VERTEX_PIPELINE_STORES_AND_ATOMICS);
732 
733 		const DeviceInterface&					vk						= m_context.getDeviceInterface();
734 		MovePtr<MultiQueues>					queues					= createQueues (m_context, VK_QUEUE_GRAPHICS_BIT);
735 		const VkDevice							device					= queues->getDevice();
736 		VkFormat								colorFormat				= VK_FORMAT_R8G8B8A8_UNORM;
737 		Move<VkRenderPass>						renderPass				= makeRenderPass(vk, device, colorFormat);
738 		const Move<VkDescriptorSetLayout>		descriptorSetLayout		(DescriptorSetLayoutBuilder()
739 																			.addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_SHADER_STAGE_VERTEX_BIT)
740 																			.build(vk, device));
741 		ShaderModuleVector						shaderGraphicModules	= addShaderModules(device);
742 		const Move<VkPipelineLayout>			pipelineLayout			(makePipelineLayout(vk, device, *descriptorSetLayout));
743 		vector<VkPipelineShaderStageCreateInfo>	shaderStageInfos		= addShaderStageInfo(shaderGraphicModules);
744 		vector<VkGraphicsPipelineCreateInfo>	pipelineInfo			= addPipelineInfo(*pipelineLayout, shaderStageInfos, *renderPass);
745 		const VkPipelineCacheCreateInfo			pipelineCacheInfo		=
746 																		{
747 																			VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO,	// VkStructureType             sType;
748 																			DE_NULL,										// const void*                 pNext;
749 																			0u,												// VkPipelineCacheCreateFlags  flags;
750 																			0u,												// deUintptr                   initialDataSize;
751 																			DE_NULL,										// const void*                 pInitialData;
752 																		};
753 		Move<VkPipelineCache>					pipelineCache			= createPipelineCache(vk, device, &pipelineCacheInfo);
754 		Move<VkPipeline>						pipeline				= createGraphicsPipeline(vk, device, *pipelineCache, &pipelineInfo[0]);
755 		const deUint32							numThreads				= clamp(deGetNumAvailableLogicalCores(), 4u, 32u);
756 		ThreadGroup								threads;
757 
758 		executeGraphicPipeline(m_context, *pipeline, *pipelineLayout, *descriptorSetLayout, *queues, *renderPass, m_shadersExecutions[0]);
759 
760 		for (deUint32 ndx = 0; ndx < numThreads; ++ndx)
761 			threads.add(MovePtr<ThreadGroupThread>(new CreateGraphicThread(
762 				m_context, *pipelineCache, pipelineInfo, *pipelineLayout, *descriptorSetLayout, *queues, *renderPass, m_shadersExecutions)));
763 
764 		{
765 			TestStatus thread_result = threads.run();
766 			if(thread_result.getCode())
767 			{
768 				return thread_result;
769 			}
770 		}
771 		return TestStatus::pass("Passed");
772 	}
773 
774 private:
addShaderModules(const VkDevice & device)775 	ShaderModuleVector						addShaderModules					(const VkDevice& device)
776 	{
777 		const DeviceInterface&	vk					= m_context.getDeviceInterface();
778 		ShaderModuleVector		shaderModules;
779 		shaderModules.resize(m_shadersExecutions.size() + 1);
780 		for (int shaderNdx = 0; shaderNdx <  static_cast<int>(m_shadersExecutions.size()); ++shaderNdx)
781 		{
782 			ostringstream shaderName;
783 			shaderName<<"vert_"<<shaderNdx;
784 			shaderModules[shaderNdx] = SharedPtr<Unique<VkShaderModule> > (new Unique<VkShaderModule>(createShaderModule(vk, device, m_context.getBinaryCollection().get(shaderName.str()), (VkShaderModuleCreateFlags)0)));
785 		}
786 		shaderModules[m_shadersExecutions.size()] = SharedPtr<Unique<VkShaderModule> > (new Unique<VkShaderModule>(createShaderModule(vk, device, m_context.getBinaryCollection().get("frag"), (VkShaderModuleCreateFlags)0)));
787 		return shaderModules;
788 	}
789 
addShaderStageInfo(const ShaderModuleVector & shaderCompModules)790 	vector<VkPipelineShaderStageCreateInfo>	addShaderStageInfo					(const ShaderModuleVector& shaderCompModules)
791 	{
792 		VkPipelineShaderStageCreateInfo			shaderStageInfo;
793 		vector<VkPipelineShaderStageCreateInfo>	shaderStageInfos;
794 		shaderStageInfo.sType				=	VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
795 		shaderStageInfo.pNext				=	DE_NULL;
796 		shaderStageInfo.flags				=	(VkPipelineShaderStageCreateFlags)0;
797 		shaderStageInfo.pName				=	"main";
798 		shaderStageInfo.pSpecializationInfo	=	DE_NULL;
799 
800 		for (int shaderNdx = 0; shaderNdx <  static_cast<int>(m_shadersExecutions.size()); ++shaderNdx)
801 		{
802 			shaderStageInfo.stage	=	VK_SHADER_STAGE_VERTEX_BIT;
803 			shaderStageInfo.module	= *(*shaderCompModules[shaderNdx]);
804 			shaderStageInfos.push_back(shaderStageInfo);
805 
806 			shaderStageInfo.stage	=	VK_SHADER_STAGE_FRAGMENT_BIT;
807 			shaderStageInfo.module	= *(*shaderCompModules[m_shadersExecutions.size()]);
808 			shaderStageInfos.push_back(shaderStageInfo);
809 		}
810 		return shaderStageInfos;
811 	}
812 
addPipelineInfo(VkPipelineLayout pipelineLayout,const vector<VkPipelineShaderStageCreateInfo> & shaderStageInfos,const VkRenderPass & renderPass)813 	vector<VkGraphicsPipelineCreateInfo>	addPipelineInfo						(VkPipelineLayout pipelineLayout, const vector<VkPipelineShaderStageCreateInfo>& shaderStageInfos, const VkRenderPass& renderPass)
814 	{
815 		VkExtent3D								colorImageExtent	= makeExtent3D(1u, 1u, 1u);
816 		vector<VkGraphicsPipelineCreateInfo>	pipelineInfo;
817 
818 		m_vertexInputStateParams.sType								= VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO;
819 		m_vertexInputStateParams.pNext								= DE_NULL;
820 		m_vertexInputStateParams.flags								= 0u;
821 		m_vertexInputStateParams.vertexBindingDescriptionCount		= 0u;
822 		m_vertexInputStateParams.pVertexBindingDescriptions			= DE_NULL;
823 		m_vertexInputStateParams.vertexAttributeDescriptionCount	= 0u;
824 		m_vertexInputStateParams.pVertexAttributeDescriptions		= DE_NULL;
825 
826 		m_inputAssemblyStateParams.sType					= VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO;
827 		m_inputAssemblyStateParams.pNext					= DE_NULL;
828 		m_inputAssemblyStateParams.flags					= 0u;
829 		m_inputAssemblyStateParams.topology					= VK_PRIMITIVE_TOPOLOGY_POINT_LIST;
830 		m_inputAssemblyStateParams.primitiveRestartEnable	= VK_FALSE;
831 
832 		m_viewport.x			= 0.0f;
833 		m_viewport.y			= 0.0f;
834 		m_viewport.width		= (float)colorImageExtent.width;
835 		m_viewport.height		= (float)colorImageExtent.height;
836 		m_viewport.minDepth		= 0.0f;
837 		m_viewport.maxDepth		= 1.0f;
838 
839 		//TODO
840 		m_scissor.offset.x		= 0;
841 		m_scissor.offset.y		= 0;
842 		m_scissor.extent.width	= colorImageExtent.width;
843 		m_scissor.extent.height	= colorImageExtent.height;
844 
845 		m_viewportStateParams.sType			= VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO;
846 		m_viewportStateParams.pNext			= DE_NULL;
847 		m_viewportStateParams.flags			= 0u;
848 		m_viewportStateParams.viewportCount	= 1u;
849 		m_viewportStateParams.pViewports	= &m_viewport;
850 		m_viewportStateParams.scissorCount	= 1u;
851 		m_viewportStateParams.pScissors		= &m_scissor;
852 
853 		m_rasterStateParams.sType					= VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO;
854 		m_rasterStateParams.pNext					= DE_NULL;
855 		m_rasterStateParams.flags					= 0u;
856 		m_rasterStateParams.depthClampEnable		= VK_FALSE;
857 		m_rasterStateParams.rasterizerDiscardEnable	= VK_FALSE;
858 		m_rasterStateParams.polygonMode				= VK_POLYGON_MODE_FILL;
859 		m_rasterStateParams.cullMode				= VK_CULL_MODE_NONE;
860 		m_rasterStateParams.frontFace				= VK_FRONT_FACE_COUNTER_CLOCKWISE;
861 		m_rasterStateParams.depthBiasEnable			= VK_FALSE;
862 		m_rasterStateParams.depthBiasConstantFactor	= 0.0f;
863 		m_rasterStateParams.depthBiasClamp			= 0.0f;
864 		m_rasterStateParams.depthBiasSlopeFactor	= 0.0f;
865 		m_rasterStateParams.lineWidth				= 1.0f;
866 
867 		m_colorBlendAttachmentState.blendEnable			= VK_FALSE;
868 		m_colorBlendAttachmentState.srcColorBlendFactor	= VK_BLEND_FACTOR_ONE;
869 		m_colorBlendAttachmentState.dstColorBlendFactor	= VK_BLEND_FACTOR_ZERO;
870 		m_colorBlendAttachmentState.colorBlendOp		= VK_BLEND_OP_ADD;
871 		m_colorBlendAttachmentState.srcAlphaBlendFactor	= VK_BLEND_FACTOR_ONE;
872 		m_colorBlendAttachmentState.dstAlphaBlendFactor	= VK_BLEND_FACTOR_ZERO;
873 		m_colorBlendAttachmentState.alphaBlendOp		= VK_BLEND_OP_ADD;
874 		m_colorBlendAttachmentState.colorWriteMask		= VK_COLOR_COMPONENT_R_BIT |
875 														  VK_COLOR_COMPONENT_G_BIT |
876 														  VK_COLOR_COMPONENT_B_BIT |
877 														  VK_COLOR_COMPONENT_A_BIT;
878 
879 		m_colorBlendStateParams.sType				= VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO;
880 		m_colorBlendStateParams.pNext				= DE_NULL;
881 		m_colorBlendStateParams.flags				= 0u;
882 		m_colorBlendStateParams.logicOpEnable		= VK_FALSE;
883 		m_colorBlendStateParams.logicOp				= VK_LOGIC_OP_COPY;
884 		m_colorBlendStateParams.attachmentCount		= 1u;
885 		m_colorBlendStateParams.pAttachments		= &m_colorBlendAttachmentState;
886 		m_colorBlendStateParams.blendConstants[0]	= 0.0f;
887 		m_colorBlendStateParams.blendConstants[1]	= 0.0f;
888 		m_colorBlendStateParams.blendConstants[2]	= 0.0f;
889 		m_colorBlendStateParams.blendConstants[3]	= 0.0f;
890 
891 		m_multisampleStateParams.sType					= VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO;
892 		m_multisampleStateParams.pNext					= DE_NULL;
893 		m_multisampleStateParams.flags					= 0u;
894 		m_multisampleStateParams.rasterizationSamples	= VK_SAMPLE_COUNT_1_BIT;
895 		m_multisampleStateParams.sampleShadingEnable	= VK_FALSE;
896 		m_multisampleStateParams.minSampleShading		= 0.0f;
897 		m_multisampleStateParams.pSampleMask			= DE_NULL;
898 		m_multisampleStateParams.alphaToCoverageEnable	= VK_FALSE;
899 		m_multisampleStateParams.alphaToOneEnable		= VK_FALSE;
900 
901 		m_depthStencilStateParams.sType					= VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO;
902 		m_depthStencilStateParams.pNext					= DE_NULL;
903 		m_depthStencilStateParams.flags					= 0u;
904 		m_depthStencilStateParams.depthTestEnable		= VK_TRUE;
905 		m_depthStencilStateParams.depthWriteEnable		= VK_TRUE;
906 		m_depthStencilStateParams.depthCompareOp		= VK_COMPARE_OP_LESS_OR_EQUAL;
907 		m_depthStencilStateParams.depthBoundsTestEnable	= VK_FALSE;
908 		m_depthStencilStateParams.stencilTestEnable		= VK_FALSE;
909 		m_depthStencilStateParams.front.failOp			= VK_STENCIL_OP_KEEP;
910 		m_depthStencilStateParams.front.passOp			= VK_STENCIL_OP_KEEP;
911 		m_depthStencilStateParams.front.depthFailOp		= VK_STENCIL_OP_KEEP;
912 		m_depthStencilStateParams.front.compareOp		= VK_COMPARE_OP_NEVER;
913 		m_depthStencilStateParams.front.compareMask		= 0u;
914 		m_depthStencilStateParams.front.writeMask		= 0u;
915 		m_depthStencilStateParams.front.reference		= 0u;
916 		m_depthStencilStateParams.back.failOp			= VK_STENCIL_OP_KEEP;
917 		m_depthStencilStateParams.back.passOp			= VK_STENCIL_OP_KEEP;
918 		m_depthStencilStateParams.back.depthFailOp		= VK_STENCIL_OP_KEEP;
919 		m_depthStencilStateParams.back.compareOp		= VK_COMPARE_OP_NEVER;
920 		m_depthStencilStateParams.back.compareMask		= 0u;
921 		m_depthStencilStateParams.back.writeMask		= 0u;
922 		m_depthStencilStateParams.back.reference		= 0u;
923 		m_depthStencilStateParams.minDepthBounds		= 0.0f;
924 		m_depthStencilStateParams.maxDepthBounds		= 1.0f;
925 
926 		VkGraphicsPipelineCreateInfo	graphicsPipelineParams	=
927 																{
928 																	VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,	// VkStructureType									sType;
929 																	DE_NULL,											// const void*										pNext;
930 																	0u,													// VkPipelineCreateFlags							flags;
931 																	2u,													// deUint32											stageCount;
932 																	DE_NULL,											// const VkPipelineShaderStageCreateInfo*			pStages;
933 																	&m_vertexInputStateParams,							// const VkPipelineVertexInputStateCreateInfo*		pVertexInputState;
934 																	&m_inputAssemblyStateParams,						// const VkPipelineInputAssemblyStateCreateInfo*	pInputAssemblyState;
935 																	DE_NULL,											// const VkPipelineTessellationStateCreateInfo*		pTessellationState;
936 																	&m_viewportStateParams,								// const VkPipelineViewportStateCreateInfo*			pViewportState;
937 																	&m_rasterStateParams,								// const VkPipelineRasterizationStateCreateInfo*	pRasterState;
938 																	&m_multisampleStateParams,							// const VkPipelineMultisampleStateCreateInfo*		pMultisampleState;
939 																	&m_depthStencilStateParams,							// const VkPipelineDepthStencilStateCreateInfo*		pDepthStencilState;
940 																	&m_colorBlendStateParams,							// const VkPipelineColorBlendStateCreateInfo*		pColorBlendState;
941 																	(const VkPipelineDynamicStateCreateInfo*)DE_NULL,	// const VkPipelineDynamicStateCreateInfo*			pDynamicState;
942 																	pipelineLayout,										// VkPipelineLayout									layout;
943 																	renderPass,											// VkRenderPass										renderPass;
944 																	0u,													// deUint32											subpass;
945 																	DE_NULL,											// VkPipeline										basePipelineHandle;
946 																	0,													// deInt32											basePipelineIndex;
947 																};
948 		for (int shaderNdx = 0; shaderNdx < static_cast<int>(m_shadersExecutions.size()) * 2; shaderNdx+=2)
949 		{
950 			graphicsPipelineParams.pStages = &shaderStageInfos[shaderNdx];
951 			pipelineInfo.push_back(graphicsPipelineParams);
952 		}
953 		return pipelineInfo;
954 	}
955 
956 	const vector<deUint32>					m_shadersExecutions;
957 	VkPipelineVertexInputStateCreateInfo	m_vertexInputStateParams;
958 	VkPipelineInputAssemblyStateCreateInfo	m_inputAssemblyStateParams;
959 	VkViewport								m_viewport;
960 	VkRect2D								m_scissor;
961 	VkPipelineViewportStateCreateInfo		m_viewportStateParams;
962 	VkPipelineRasterizationStateCreateInfo	m_rasterStateParams;
963 	VkPipelineColorBlendAttachmentState		m_colorBlendAttachmentState;
964 	VkPipelineColorBlendStateCreateInfo		m_colorBlendStateParams;
965 	VkPipelineMultisampleStateCreateInfo	m_multisampleStateParams;
966 	VkPipelineDepthStencilStateCreateInfo	m_depthStencilStateParams;
967 };
968 
969 class PipelineCacheComputeTest : public TestCase
970 {
971 public:
PipelineCacheComputeTest(TestContext & testCtx,const string & name,const string & description)972 							PipelineCacheComputeTest	(TestContext&		testCtx,
973 														const string&		name,
974 														const string&		description)
975 								:TestCase	(testCtx, name, description)
976 	{
977 	}
978 
initPrograms(SourceCollections & programCollection) const979 	void					initPrograms				(SourceCollections&	programCollection) const
980 	{
981 		ostringstream buffer;
982 		buffer	<< "layout(set = 0, binding = 0, std430) buffer Output\n"
983 				<< "{\n"
984 				<< "	int result[];\n"
985 				<< "} sb_out;\n";
986 		{
987 			ostringstream src;
988 			src	<< glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_310_ES) << "\n"
989 				<< "\n"
990 				<< "layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
991 				<< "\n"
992 				<< buffer.str()
993 				<< "void main (void)\n"
994 				<< "{\n"
995 				<< "	highp uint ndx = gl_GlobalInvocationID.x;\n"
996 				<< "	sb_out.result[ndx] = int(ndx);\n"
997 				<< "}\n";
998 			programCollection.glslSources.add("compute_0") << glu::ComputeSource(src.str());
999 		}
1000 		{
1001 			ostringstream src;
1002 			src	<< glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_310_ES) << "\n"
1003 				<< "\n"
1004 				<< "layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
1005 				<< "\n"
1006 				<< buffer.str()
1007 				<< "void main (void)\n"
1008 				<< "{\n"
1009 				<< "	for (highp uint ndx = 0u; ndx < "<<BUFFER_ELEMENT_COUNT<<"u; ndx++)\n"
1010 				<< "	{\n"
1011 				<< "		sb_out.result[ndx] = int(ndx);\n"
1012 				<< "	}\n"
1013 				<< "}\n";
1014 			programCollection.glslSources.add("compute_1") << glu::ComputeSource(src.str());
1015 		}
1016 		{
1017 			ostringstream src;
1018 			src	<< glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_310_ES) << "\n"
1019 				<< "\n"
1020 				<< "layout(local_size_x = "<<BUFFER_ELEMENT_COUNT<<", local_size_y = 1, local_size_z = 1) in;\n"
1021 				<< "\n"
1022 				<< buffer.str()
1023 				<< "void main (void)\n"
1024 				<< "{\n"
1025 				<< "	highp uint ndx = gl_LocalInvocationID.x;\n"
1026 				<< "	sb_out.result[ndx] = int(ndx);\n"
1027 				<< "}\n";
1028 			programCollection.glslSources.add("compute_2") << glu::ComputeSource(src.str());
1029 		}
1030 	}
1031 
createInstance(Context & context) const1032 	TestInstance*			createInstance				(Context& context) const
1033 	{
1034 		vector<deUint32>	shadersExecutions;
1035 		shadersExecutions.push_back(16u);	//compute_0
1036 		shadersExecutions.push_back(1u);	//compute_1
1037 		shadersExecutions.push_back(1u);	//compute_2
1038 		return new PipelineCacheComputeTestInstance(context, shadersExecutions);
1039 	}
1040 };
1041 
1042 class PipelineCacheGraphicTest : public TestCase
1043 {
1044 public:
PipelineCacheGraphicTest(TestContext & testCtx,const string & name,const string & description)1045 							PipelineCacheGraphicTest	(TestContext&		testCtx,
1046 														const string&		name,
1047 														const string&		description)
1048 								:TestCase	(testCtx, name, description)
1049 	{
1050 
1051 	}
1052 
initPrograms(SourceCollections & programCollection) const1053 	void					initPrograms				(SourceCollections&	programCollection) const
1054 	{
1055 		ostringstream buffer;
1056 		buffer	<< "layout(set = 0, binding = 0, std430) buffer Output\n"
1057 				<< "{\n"
1058 				<< "	int result[];\n"
1059 				<< "} sb_out;\n";
1060 
1061 		// Vertex
1062 		{
1063 			std::ostringstream src;
1064 			src	<< glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_440) << "\n"
1065 				<< "\n"
1066 				<< buffer.str()
1067 				<< "\n"
1068 				<< "void main (void)\n"
1069 				<< "{\n"
1070 				<< "   sb_out.result[gl_VertexIndex] = int(gl_VertexIndex);\n"
1071 				<< "   gl_PointSize = 1.0f;\n"
1072 				<< "}\n";
1073 			programCollection.glslSources.add("vert_0") << glu::VertexSource(src.str());
1074 		}
1075 		// Vertex
1076 		{
1077 			std::ostringstream src;
1078 			src	<< glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_440) << "\n"
1079 				<< "\n"
1080 				<< buffer.str()
1081 				<< "\n"
1082 				<< "void main (void)\n"
1083 				<< "{\n"
1084 				<< "	for (highp uint ndx = 0u; ndx < "<<BUFFER_ELEMENT_COUNT<<"u; ndx++)\n"
1085 				<< "	{\n"
1086 				<< "		sb_out.result[ndx] = int(ndx);\n"
1087 				<< "	}\n"
1088 				<< "	gl_PointSize = 1.0f;\n"
1089 				<< "}\n";
1090 			programCollection.glslSources.add("vert_1") << glu::VertexSource(src.str());
1091 		}
1092 		// Vertex
1093 		{
1094 			std::ostringstream src;
1095 			src	<< glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_440) << "\n"
1096 				<< "\n"
1097 				<< buffer.str()
1098 				<< "\n"
1099 				<< "void main (void)\n"
1100 				<< "{\n"
1101 				<< "	for (int ndx = "<<BUFFER_ELEMENT_COUNT-1<<"; ndx >= 0; ndx--)\n"
1102 				<< "	{\n"
1103 				<< "		sb_out.result[uint(ndx)] = ndx;\n"
1104 				<< "	}\n"
1105 				<< "	gl_PointSize = 1.0f;\n"
1106 				<< "}\n";
1107 			programCollection.glslSources.add("vert_2") << glu::VertexSource(src.str());
1108 		}
1109 		// Fragment
1110 		{
1111 			std::ostringstream src;
1112 			src	<< glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_440) << "\n"
1113 				<< "\n"
1114 				<< "layout(location = 0) out vec4 o_color;\n"
1115 				<< "\n"
1116 				<< "void main (void)\n"
1117 				<< "{\n"
1118 				<< "    o_color = vec4(1.0);\n"
1119 				<< "}\n";
1120 			programCollection.glslSources.add("frag") << glu::FragmentSource(src.str());
1121 		}
1122 	}
1123 
createInstance(Context & context) const1124 	TestInstance*			createInstance				(Context& context) const
1125 	{
1126 		vector<deUint32>	shadersExecutions;
1127 		shadersExecutions.push_back(16u);	//vert_0
1128 		shadersExecutions.push_back(1u);	//vert_1
1129 		shadersExecutions.push_back(1u);	//vert_2
1130 		return new PipelineCacheGraphicTestInstance(context, shadersExecutions);
1131 	}
1132 };
1133 
1134 
1135 } // anonymous
1136 
createInternallySynchronizedObjects(tcu::TestContext & testCtx)1137 tcu::TestCaseGroup* createInternallySynchronizedObjects (tcu::TestContext& testCtx)
1138 {
1139 	de::MovePtr<tcu::TestCaseGroup> tests(new tcu::TestCaseGroup(testCtx, "internally_synchronized_objects", "Internally synchronized objects"));
1140 	tests->addChild(new PipelineCacheComputeTest(testCtx, "pipeline_cache_compute", "Internally synchronized object VkPipelineCache for compute pipeline is tested"));
1141 	tests->addChild(new PipelineCacheGraphicTest(testCtx, "pipeline_cache_graphics", "Internally synchronized object VkPipelineCache for graphics pipeline is tested"));
1142 	return tests.release();
1143 }
1144 
1145 } // synchronization
1146 } // vkt
1147