1/*-------------------------------------------------------------------------
2 * Vulkan CTS Framework
3 * --------------------
4 *
5 * Copyright (c) 2015 Google 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 Vulkan object reference holder utilities.
22 *//*--------------------------------------------------------------------*/
23
24#include "vkRefUtil.hpp"
25
26namespace vk
27{
28
29#include "vkRefUtilImpl.inl"
30
31Move<VkPipeline> createGraphicsPipeline (const DeviceInterface&					vk,
32										 VkDevice								device,
33										 VkPipelineCache						pipelineCache,
34										 const VkGraphicsPipelineCreateInfo*	pCreateInfo,
35										 const VkAllocationCallbacks*			pAllocator)
36{
37	VkPipeline object = 0;
38	VK_CHECK(vk.createGraphicsPipelines(device, pipelineCache, 1u, pCreateInfo, pAllocator, &object));
39	return Move<VkPipeline>(check<VkPipeline>(object), Deleter<VkPipeline>(vk, device, pAllocator));
40}
41
42Move<VkPipeline> createComputePipeline (const DeviceInterface&				vk,
43										VkDevice							device,
44										VkPipelineCache						pipelineCache,
45										const VkComputePipelineCreateInfo*	pCreateInfo,
46										const VkAllocationCallbacks*		pAllocator)
47{
48	VkPipeline object = 0;
49	VK_CHECK(vk.createComputePipelines(device, pipelineCache, 1u, pCreateInfo, pAllocator, &object));
50	return Move<VkPipeline>(check<VkPipeline>(object), Deleter<VkPipeline>(vk, device, pAllocator));
51}
52
53#ifndef CTS_USES_VULKANSC
54
55Move<VkPipeline> createRayTracingPipelineNV (const DeviceInterface&						vk,
56											 VkDevice									device,
57											 VkPipelineCache							pipelineCache,
58											 const VkRayTracingPipelineCreateInfoNV*	pCreateInfo,
59											 const VkAllocationCallbacks*				pAllocator)
60{
61	VkPipeline object = 0;
62	VK_CHECK(vk.createRayTracingPipelinesNV(device, pipelineCache, 1u, pCreateInfo, pAllocator, &object));
63	return Move<VkPipeline>(check<VkPipeline>(object), Deleter<VkPipeline>(vk, device, pAllocator));
64}
65
66Move<VkPipeline> createRayTracingPipelineKHR (const DeviceInterface&					vk,
67											  VkDevice									device,
68											  VkDeferredOperationKHR					deferredOperation,
69											  VkPipelineCache							pipelineCache,
70											  const VkRayTracingPipelineCreateInfoKHR*	pCreateInfo,
71											  const VkAllocationCallbacks*				pAllocator)
72{
73	VkPipeline object = 0;
74	VK_CHECK(vk.createRayTracingPipelinesKHR(device, deferredOperation, pipelineCache, 1u, pCreateInfo, pAllocator, &object));
75	return Move<VkPipeline>(check<VkPipeline>(object), Deleter<VkPipeline>(vk, device, pAllocator));
76}
77
78#endif // CTS_USES_VULKANSC
79
80Move<VkCommandBuffer> allocateCommandBuffer (const DeviceInterface& vk, VkDevice device, const VkCommandBufferAllocateInfo* pAllocateInfo)
81{
82	VkCommandBuffer object = 0;
83	DE_ASSERT(pAllocateInfo->commandBufferCount == 1u);
84	VK_CHECK(vk.allocateCommandBuffers(device, pAllocateInfo, &object));
85	return Move<VkCommandBuffer>(check<VkCommandBuffer>(object), Deleter<VkCommandBuffer>(vk, device, pAllocateInfo->commandPool));
86}
87
88void allocateCommandBuffers (const DeviceInterface& vk, VkDevice device, const VkCommandBufferAllocateInfo* pAllocateInfo, Move<VkCommandBuffer> *pCommandBuffers)
89{
90	VkCommandBufferAllocateInfo allocateInfoCopy = *pAllocateInfo;
91	allocateInfoCopy.commandBufferCount = 1;
92	for (uint32_t i = 0; i < pAllocateInfo->commandBufferCount; ++i) {
93		VkCommandBuffer object = 0;
94		VK_CHECK(vk.allocateCommandBuffers(device, &allocateInfoCopy, &object));
95		pCommandBuffers[i] = Move<VkCommandBuffer>(check<VkCommandBuffer>(object), Deleter<VkCommandBuffer>(vk, device, pAllocateInfo->commandPool));
96	}
97}
98
99Move<VkDescriptorSet> allocateDescriptorSet (const DeviceInterface& vk, VkDevice device, const VkDescriptorSetAllocateInfo* pAllocateInfo)
100{
101	VkDescriptorSet object = 0;
102	DE_ASSERT(pAllocateInfo->descriptorSetCount == 1u);
103	VK_CHECK(vk.allocateDescriptorSets(device, pAllocateInfo, &object));
104	return Move<VkDescriptorSet>(check<VkDescriptorSet>(object), Deleter<VkDescriptorSet>(vk, device, pAllocateInfo->descriptorPool));
105}
106
107Move<VkSemaphore> createSemaphore (const DeviceInterface&		vk,
108								   VkDevice						device,
109								   VkSemaphoreCreateFlags		flags,
110								   const VkAllocationCallbacks*	pAllocator)
111{
112	const VkSemaphoreCreateInfo createInfo =
113	{
114		VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO,
115		DE_NULL,
116
117		flags
118	};
119
120	return createSemaphore(vk, device, &createInfo, pAllocator);
121}
122
123Move<VkSemaphore> createSemaphoreType (const DeviceInterface&		vk,
124									   VkDevice						device,
125									   VkSemaphoreType				type,
126									   VkSemaphoreCreateFlags		flags,
127									   const deUint64				initialValue,
128									   const VkAllocationCallbacks*	pAllocator)
129{
130	const VkSemaphoreTypeCreateInfo	createTypeInfo =
131	{
132		VK_STRUCTURE_TYPE_SEMAPHORE_TYPE_CREATE_INFO,
133		DE_NULL,
134
135		type,
136		initialValue,
137	};
138	const VkSemaphoreCreateInfo		createInfo =
139	{
140		VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO,
141		&createTypeInfo,
142
143		flags
144	};
145
146	return createSemaphore(vk, device, &createInfo, pAllocator);
147}
148
149Move<VkFence> createFence (const DeviceInterface&		vk,
150						   VkDevice						device,
151						   VkFenceCreateFlags			flags,
152						   const VkAllocationCallbacks*	pAllocator)
153{
154	const VkFenceCreateInfo createInfo =
155	{
156		VK_STRUCTURE_TYPE_FENCE_CREATE_INFO,
157		DE_NULL,
158
159		flags
160	};
161
162	return createFence(vk, device, &createInfo, pAllocator);
163}
164
165Move<VkCommandPool> createCommandPool (const DeviceInterface&		vk,
166									   VkDevice						device,
167									   VkCommandPoolCreateFlags		flags,
168									   deUint32						queueFamilyIndex,
169									   const VkAllocationCallbacks*	pAllocator)
170{
171	const VkCommandPoolCreateInfo createInfo =
172	{
173		VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,
174		DE_NULL,
175
176		flags,
177		queueFamilyIndex
178	};
179
180	return createCommandPool(vk, device, &createInfo, pAllocator);
181}
182
183Move<VkCommandBuffer> allocateCommandBuffer (const DeviceInterface&	vk,
184											 VkDevice				device,
185											 VkCommandPool			commandPool,
186											 VkCommandBufferLevel	level)
187{
188	const VkCommandBufferAllocateInfo allocInfo =
189	{
190		VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,
191		DE_NULL,
192
193		commandPool,
194		level,
195		1
196	};
197
198	return allocateCommandBuffer(vk, device, &allocInfo);
199}
200
201Move<VkEvent> createEvent (const DeviceInterface&		vk,
202						   VkDevice						device,
203						   VkEventCreateFlags			flags,
204						   const VkAllocationCallbacks*	pAllocateInfo)
205{
206	const VkEventCreateInfo createInfo =
207	{
208		VK_STRUCTURE_TYPE_EVENT_CREATE_INFO,
209		DE_NULL,
210
211		flags
212	};
213
214	return createEvent(vk, device, &createInfo, pAllocateInfo);
215}
216
217#ifdef CTS_USES_VULKANSC
218
219// add missing function in Vulkan SC, so that we are able to hack into shader module creation
220
221Move<VkShaderModule> createShaderModule(const DeviceInterface& vk, VkDevice device, const VkShaderModuleCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator)
222{
223	VkShaderModule object = 0;
224	VK_CHECK(vk.createShaderModule(device, pCreateInfo, pAllocator, &object));
225	return Move<VkShaderModule>(check<VkShaderModule>(object), Deleter<VkShaderModule>(vk, device, pAllocator));
226}
227
228// stubs for functions removed in Vulkan SC
229
230namespace refdetails
231{
232
233template<>
234void Deleter<VkDeviceMemory>::operator() (VkDeviceMemory obj) const
235{
236	DE_UNREF(obj);
237}
238
239template<>
240void Deleter<VkShaderModule>::operator() (VkShaderModule obj) const
241{
242	DE_UNREF(obj);
243}
244
245template<>
246void Deleter<VkQueryPool>::operator() (VkQueryPool obj) const
247{
248	DE_UNREF(obj);
249}
250
251template<>
252void Deleter<VkDescriptorPool>::operator() (VkDescriptorPool obj) const
253{
254	// vkDestroyDescriptorPool is unsupported in VulkanSC. Instead, reset the descriptor pool
255    // so that any sets allocated from it will be implicitly freed (similar to if it were being
256    // destroyed). Lots of tests rely on sets being implicitly freed.
257	m_deviceIface->resetDescriptorPool(m_device, obj, 0);
258}
259
260template<>
261void Deleter<VkCommandPool>::operator() (VkCommandPool obj) const
262{
263	DE_UNREF(obj);
264}
265
266template<>
267void Deleter<VkSwapchainKHR>::operator() (VkSwapchainKHR obj) const
268{
269	DE_UNREF(obj);
270}
271
272template<>
273void Deleter<VkSemaphoreSciSyncPoolNV>::operator() (VkSemaphoreSciSyncPoolNV obj) const
274{
275	DE_UNREF(obj);
276}
277
278
279} // refdetails
280
281#endif // CTS_USES_VULKANSC
282
283} // vk
284