• 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 semaphore basic tests
22  *//*--------------------------------------------------------------------*/
23 
24 #include "vktSynchronizationBasicSemaphoreTests.hpp"
25 #include "vktTestCaseUtil.hpp"
26 #include "vktSynchronizationUtil.hpp"
27 
28 #include "vkDefs.hpp"
29 #include "vkPlatform.hpp"
30 #include "vkQueryUtil.hpp"
31 
32 
33 #include "vkRef.hpp"
34 
35 namespace vkt
36 {
37 namespace synchronization
38 {
39 namespace
40 {
41 
42 using namespace vk;
43 
44 #define FENCE_WAIT	~0ull
45 
basicOneQueueCase(Context & context)46 tcu::TestStatus basicOneQueueCase (Context& context)
47 {
48 	const DeviceInterface&			vk					= context.getDeviceInterface();
49 	const VkDevice					device				= context.getDevice();
50 	const VkQueue					queue				= context.getUniversalQueue();
51 	const deUint32					queueFamilyIndex	= context.getUniversalQueueFamilyIndex();
52 	const VkSemaphoreCreateInfo		semaphoreInfo		=
53 														{
54 															VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO,	//VkStructureType			sType;
55 															DE_NULL,									//const void*				pNext;
56 															0u											//VkSemaphoreCreateFlags	flags;
57 														};
58 	const Unique<VkSemaphore>		semaphore			(createSemaphore (vk, device, &semaphoreInfo, DE_NULL));
59 	const Unique<VkCommandPool>		cmdPool				(makeCommandPool(vk, device, queueFamilyIndex));
60 	const Unique<VkCommandBuffer>	cmdBuffer			(makeCommandBuffer(vk, device, *cmdPool));
61 	const VkCommandBufferBeginInfo	info				=
62 														{
63 															VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,	// VkStructureType                          sType;
64 															DE_NULL,										// const void*                              pNext;
65 															VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT,	// VkCommandBufferUsageFlags                flags;
66 															DE_NULL,										// const VkCommandBufferInheritanceInfo*    pInheritanceInfo;
67 														};
68 	const VkPipelineStageFlags		stageBits[]			= { VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT };
69 	const VkSubmitInfo				submitInfo[2]		=
70 														{
71 															{
72 																VK_STRUCTURE_TYPE_SUBMIT_INFO,		// VkStructureType			sType;
73 																DE_NULL,							// const void*				pNext;
74 																0u,									// deUint32					waitSemaphoreCount;
75 																DE_NULL,							// const VkSemaphore*		pWaitSemaphores;
76 																(const VkPipelineStageFlags*)DE_NULL,
77 																1u,									// deUint32					commandBufferCount;
78 																&cmdBuffer.get(),					// const VkCommandBuffer*	pCommandBuffers;
79 																1u,									// deUint32					signalSemaphoreCount;
80 																&semaphore.get(),					// const VkSemaphore*		pSignalSemaphores;
81 															},
82 															{
83 																VK_STRUCTURE_TYPE_SUBMIT_INFO,		// VkStructureType				sType;
84 																DE_NULL,							// const void*					pNext;
85 																1u,									// deUint32						waitSemaphoreCount;
86 																&semaphore.get(),					// const VkSemaphore*			pWaitSemaphores;
87 																stageBits,							// const VkPipelineStageFlags*	pWaitDstStageMask;
88 																1u,									// deUint32						commandBufferCount;
89 																&cmdBuffer.get(),					// const VkCommandBuffer*		pCommandBuffers;
90 																0u,									// deUint32						signalSemaphoreCount;
91 																DE_NULL,							// const VkSemaphore*			pSignalSemaphores;
92 															}
93 														};
94 	const VkFenceCreateInfo			fenceInfo			=
95 														{
96 															VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, // VkStructureType		sType;
97 															DE_NULL,							 // const void*			pNext;
98 															0u,									 // VkFenceCreateFlags	flags;
99 														};
100 	const Unique<VkFence>			fence				(createFence(vk, device, &fenceInfo));
101 
102 	VK_CHECK(vk.beginCommandBuffer(*cmdBuffer, &info));
103 	endCommandBuffer(vk, *cmdBuffer);
104 	VK_CHECK(vk.queueSubmit(queue, 2u, submitInfo, *fence));
105 
106 	if (VK_SUCCESS != vk.waitForFences(device, 1u, &fence.get(), DE_TRUE, FENCE_WAIT))
107 		return tcu::TestStatus::fail("Basic semaphore tests with one queue failed");
108 
109 	return tcu::TestStatus::pass("Basic semaphore tests with one queue passed");
110 }
111 
basicMultiQueueCase(Context & context)112 tcu::TestStatus basicMultiQueueCase (Context& context)
113 {
114 	enum {NO_MATCH_FOUND = ~((deUint32)0)};
115 	enum QueuesIndexes {FIRST = 0, SECOND, COUNT};
116 
117 	struct Queues
118 	{
119 		VkQueue		queue;
120 		deUint32	queueFamilyIndex;
121 	};
122 
123 
124 	const DeviceInterface&					vk							= context.getDeviceInterface();
125 	const InstanceInterface&				instance					= context.getInstanceInterface();
126 	const VkPhysicalDevice					physicalDevice				= context.getPhysicalDevice();
127 	vk::Move<vk::VkDevice>					logicalDevice;
128 	std::vector<VkQueueFamilyProperties>	queueFamilyProperties;
129 	VkDeviceCreateInfo						deviceInfo;
130 	VkPhysicalDeviceFeatures				deviceFeatures;
131 	const float								queuePriorities[COUNT]		= {1.0f, 1.0f};
132 	VkDeviceQueueCreateInfo					queueInfos[COUNT];
133 	Queues									queues[COUNT]				=
134 																		{
135 																			{DE_NULL, (deUint32)NO_MATCH_FOUND},
136 																			{DE_NULL, (deUint32)NO_MATCH_FOUND}
137 																		};
138 	const VkCommandBufferBeginInfo			info						=
139 																		{
140 																			VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,	// VkStructureType                          sType;
141 																			DE_NULL,										// const void*                              pNext;
142 																			VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT,	// VkCommandBufferUsageFlags                flags;
143 																			DE_NULL,										// const VkCommandBufferInheritanceInfo*    pInheritanceInfo;
144 																		};
145 	const VkSemaphoreCreateInfo				semaphoreInfo				=
146 																		{
147 																			VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO,	//VkStructureType			sType;
148 																			DE_NULL,									//const void*				pNext;
149 																			0u											//VkSemaphoreCreateFlags	flags;
150 																		};
151 	Move<VkSemaphore>						semaphore;
152 	Move<VkCommandPool>						cmdPool[COUNT];
153 	Move<VkCommandBuffer>					cmdBuffer[COUNT];
154 	const VkPipelineStageFlags				stageBits[]					= { VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT };
155 	VkSubmitInfo							submitInfo[COUNT];
156 	const VkFenceCreateInfo					fenceInfo					=
157 																		{
158 																			VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, // VkStructureType		sType;
159 																			DE_NULL,							 // const void*			pNext;
160 																			0u,									 // VkFenceCreateFlags	flags;
161 																		};
162 	Move<VkFence>							fence[COUNT];
163 
164 	queueFamilyProperties = getPhysicalDeviceQueueFamilyProperties(instance, physicalDevice);
165 
166 	for (deUint32 queueNdx = 0; queueNdx < queueFamilyProperties.size(); ++queueNdx)
167 	{
168 		if (NO_MATCH_FOUND == queues[FIRST].queueFamilyIndex)
169 			queues[FIRST].queueFamilyIndex = queueNdx;
170 
171 		if (queues[FIRST].queueFamilyIndex != queueNdx || queueFamilyProperties[queueNdx].queueCount > 1u)
172 		{
173 			queues[SECOND].queueFamilyIndex = queueNdx;
174 			break;
175 		}
176 	}
177 
178 	if (queues[FIRST].queueFamilyIndex == NO_MATCH_FOUND || queues[SECOND].queueFamilyIndex == NO_MATCH_FOUND)
179 		TCU_THROW(NotSupportedError, "Queues couldn't be created");
180 
181 	for (int queueNdx = 0; queueNdx < COUNT; ++queueNdx)
182 	{
183 		VkDeviceQueueCreateInfo queueInfo;
184 		deMemset(&queueInfo, 0, sizeof(queueInfo));
185 
186 		queueInfo.sType				= VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
187 		queueInfo.pNext				= DE_NULL;
188 		queueInfo.flags				= (VkDeviceQueueCreateFlags)0u;
189 		queueInfo.queueFamilyIndex	= queues[queueNdx].queueFamilyIndex;
190 		queueInfo.queueCount		= (queues[FIRST].queueFamilyIndex == queues[SECOND].queueFamilyIndex) ? 2 : 1;
191 		queueInfo.pQueuePriorities	= queuePriorities;
192 
193 		queueInfos[queueNdx]		= queueInfo;
194 
195 		if (queues[FIRST].queueFamilyIndex == queues[SECOND].queueFamilyIndex)
196 			break;
197 	}
198 
199 	deMemset(&deviceInfo, 0, sizeof(deviceInfo));
200 	instance.getPhysicalDeviceFeatures(physicalDevice, &deviceFeatures);
201 
202 	deviceInfo.sType					= VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
203 	deviceInfo.pNext					= DE_NULL;
204 	deviceInfo.enabledExtensionCount	= 0u;
205 	deviceInfo.ppEnabledExtensionNames	= DE_NULL;
206 	deviceInfo.enabledLayerCount		= 0u;
207 	deviceInfo.ppEnabledLayerNames		= DE_NULL;
208 	deviceInfo.pEnabledFeatures			= &deviceFeatures;
209 	deviceInfo.queueCreateInfoCount		= (queues[FIRST].queueFamilyIndex == queues[SECOND].queueFamilyIndex) ? 1 : COUNT;
210 	deviceInfo.pQueueCreateInfos		= queueInfos;
211 
212 	logicalDevice = vk::createDevice(instance, physicalDevice, &deviceInfo);
213 
214 	for (deUint32 queueReqNdx = 0; queueReqNdx < COUNT; ++queueReqNdx)
215 	{
216 		if (queues[FIRST].queueFamilyIndex == queues[SECOND].queueFamilyIndex)
217 			vk.getDeviceQueue(*logicalDevice, queues[queueReqNdx].queueFamilyIndex, queueReqNdx, &queues[queueReqNdx].queue);
218 		else
219 			vk.getDeviceQueue(*logicalDevice, queues[queueReqNdx].queueFamilyIndex, 0u, &queues[queueReqNdx].queue);
220 	}
221 
222 	semaphore			= (createSemaphore (vk,*logicalDevice, &semaphoreInfo, DE_NULL));
223 	cmdPool[FIRST]		= (makeCommandPool(vk, *logicalDevice, queues[FIRST].queueFamilyIndex));
224 	cmdPool[SECOND]		= (makeCommandPool(vk, *logicalDevice, queues[SECOND].queueFamilyIndex));
225 	cmdBuffer[FIRST]	= (makeCommandBuffer(vk, *logicalDevice, *cmdPool[FIRST]));
226 	cmdBuffer[SECOND]	= (makeCommandBuffer(vk, *logicalDevice, *cmdPool[SECOND]));
227 
228 	submitInfo[FIRST].sType					= VK_STRUCTURE_TYPE_SUBMIT_INFO;
229 	submitInfo[FIRST].pNext					= DE_NULL;
230 	submitInfo[FIRST].waitSemaphoreCount	= 0u;
231 	submitInfo[FIRST].pWaitSemaphores		= DE_NULL;
232 	submitInfo[FIRST].pWaitDstStageMask		= (const VkPipelineStageFlags*)DE_NULL;
233 	submitInfo[FIRST].commandBufferCount	= 1u;
234 	submitInfo[FIRST].pCommandBuffers		= &cmdBuffer[FIRST].get();
235 	submitInfo[FIRST].signalSemaphoreCount	= 1u;
236 	submitInfo[FIRST].pSignalSemaphores		= &semaphore.get();
237 
238 	submitInfo[SECOND].sType					= VK_STRUCTURE_TYPE_SUBMIT_INFO;
239 	submitInfo[SECOND].pNext					= DE_NULL;
240 	submitInfo[SECOND].waitSemaphoreCount		= 1u;
241 	submitInfo[SECOND].pWaitSemaphores			= &semaphore.get();
242 	submitInfo[SECOND].pWaitDstStageMask		= stageBits;
243 	submitInfo[SECOND].commandBufferCount		= 1u;
244 	submitInfo[SECOND].pCommandBuffers			= &cmdBuffer[SECOND].get();
245 	submitInfo[SECOND].signalSemaphoreCount		= 0u;
246 	submitInfo[SECOND].pSignalSemaphores		= DE_NULL;
247 
248 	VK_CHECK(vk.beginCommandBuffer(*cmdBuffer[FIRST], &info));
249 	endCommandBuffer(vk, *cmdBuffer[FIRST]);
250 	VK_CHECK(vk.beginCommandBuffer(*cmdBuffer[SECOND], &info));
251 	endCommandBuffer(vk, *cmdBuffer[SECOND]);
252 
253 	fence[FIRST]  = (createFence(vk, *logicalDevice, &fenceInfo));
254 	fence[SECOND] = (createFence(vk, *logicalDevice, &fenceInfo));
255 
256 	VK_CHECK(vk.queueSubmit(queues[FIRST].queue, 1u, &submitInfo[FIRST], *fence[FIRST]));
257 	VK_CHECK(vk.queueSubmit(queues[SECOND].queue, 1u, &submitInfo[SECOND], *fence[SECOND]));
258 
259 	if (VK_SUCCESS != vk.waitForFences(*logicalDevice, 1u, &fence[FIRST].get(), DE_TRUE, FENCE_WAIT))
260 		return tcu::TestStatus::fail("Basic semaphore tests with multi queue failed");
261 
262 	if (VK_SUCCESS != vk.waitForFences(*logicalDevice, 1u, &fence[SECOND].get(), DE_TRUE, FENCE_WAIT))
263 		return tcu::TestStatus::fail("Basic semaphore tests with multi queue failed");
264 
265 	{
266 		VkSubmitInfo swapInfo				= submitInfo[SECOND];
267 		submitInfo[SECOND]					= submitInfo[FIRST];
268 		submitInfo[FIRST]					= swapInfo;
269 		submitInfo[SECOND].pCommandBuffers	= &cmdBuffer[SECOND].get();
270 		submitInfo[FIRST].pCommandBuffers	= &cmdBuffer[FIRST].get();
271 	}
272 
273 	VK_CHECK(vk.resetFences(*logicalDevice, 1u, &fence[FIRST].get()));
274 	VK_CHECK(vk.resetFences(*logicalDevice, 1u, &fence[SECOND].get()));
275 
276 	VK_CHECK(vk.queueSubmit(queues[SECOND].queue, 1u, &submitInfo[SECOND], *fence[SECOND]));
277 	VK_CHECK(vk.queueSubmit(queues[FIRST].queue, 1u, &submitInfo[FIRST], *fence[FIRST]));
278 
279 	if (VK_SUCCESS != vk.waitForFences(*logicalDevice, 1u, &fence[FIRST].get(), DE_TRUE, FENCE_WAIT))
280 		return tcu::TestStatus::fail("Basic semaphore tests with multi queue failed");
281 
282 	if (VK_SUCCESS != vk.waitForFences(*logicalDevice, 1u, &fence[SECOND].get(), DE_TRUE, FENCE_WAIT))
283 		return tcu::TestStatus::fail("Basic semaphore tests with multi queue failed");
284 
285 	return tcu::TestStatus::pass("Basic semaphore tests with multi queue passed");
286 }
287 
288 } // anonymous
289 
createBasicSemaphoreTests(tcu::TestContext & testCtx)290 tcu::TestCaseGroup* createBasicSemaphoreTests (tcu::TestContext& testCtx)
291 {
292 	de::MovePtr<tcu::TestCaseGroup> basicTests(new tcu::TestCaseGroup(testCtx, "semaphore", "Basic semaphore tests"));
293 	addFunctionCase(basicTests.get(), "one_queue",   "Basic semaphore tests with one queue",   basicOneQueueCase);
294 	addFunctionCase(basicTests.get(), "multi_queue", "Basic semaphore tests with multi queue", basicMultiQueueCase);
295 
296 	return basicTests.release();
297 }
298 
299 } // synchronization
300 } // vkt
301