• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 builder utilities.
22  *//*--------------------------------------------------------------------*/
23 
24 #include "vkBuilderUtil.hpp"
25 
26 #include "vkRefUtil.hpp"
27 
28 namespace vk
29 {
30 
31 // DescriptorSetLayoutBuilder
32 
DescriptorSetLayoutBuilder(void)33 DescriptorSetLayoutBuilder::DescriptorSetLayoutBuilder (void)
34 {
35 }
36 
addBinding(VkDescriptorType descriptorType,deUint32 descriptorCount,VkShaderStageFlags stageFlags,const VkSampler * pImmutableSamplers)37 DescriptorSetLayoutBuilder& DescriptorSetLayoutBuilder::addBinding (VkDescriptorType	descriptorType,
38 																	deUint32			descriptorCount,
39 																	VkShaderStageFlags	stageFlags,
40 																	const VkSampler*	pImmutableSamplers)
41 {
42 	if (pImmutableSamplers)
43 	{
44 		const ImmutableSamplerInfo immutableSamplerInfo =
45 		{
46 			(deUint32)m_bindings.size(),
47 			(deUint32)m_immutableSamplers.size()
48 		};
49 
50 		m_immutableSamplerInfos.push_back(immutableSamplerInfo);
51 
52 		for (size_t descriptorNdx = 0; descriptorNdx < descriptorCount; descriptorNdx++)
53 			m_immutableSamplers.push_back(pImmutableSamplers[descriptorNdx]);
54 	}
55 
56 	// pImmutableSamplers will be updated at build time
57 	const VkDescriptorSetLayoutBinding binding =
58 	{
59 		(deUint32)m_bindings.size(),	// binding
60 		descriptorType,					// descriptorType
61 		descriptorCount,				// descriptorCount
62 		stageFlags,						// stageFlags
63 		DE_NULL,						// pImmutableSamplers
64 	};
65 	m_bindings.push_back(binding);
66 	return *this;
67 }
68 
addIndexedBinding(VkDescriptorType descriptorType,deUint32 descriptorCount,VkShaderStageFlags stageFlags,deUint32 dstBinding,const VkSampler * pImmutableSamplers)69 DescriptorSetLayoutBuilder& DescriptorSetLayoutBuilder::addIndexedBinding (VkDescriptorType		descriptorType,
70 																		   deUint32				descriptorCount,
71 																		   VkShaderStageFlags	stageFlags,
72 																		   deUint32				dstBinding,
73 																		   const VkSampler*		pImmutableSamplers)
74 {
75 	if (pImmutableSamplers)
76 	{
77 		const ImmutableSamplerInfo immutableSamplerInfo =
78 		{
79 			(deUint32)dstBinding,
80 			(deUint32)m_immutableSamplers.size()
81 		};
82 
83 		m_immutableSamplerInfos.push_back(immutableSamplerInfo);
84 
85 		for (size_t descriptorNdx = 0; descriptorNdx < descriptorCount; descriptorNdx++)
86 			m_immutableSamplers.push_back(pImmutableSamplers[descriptorNdx]);
87 	}
88 
89 	// pImmutableSamplers will be updated at build time
90 	const VkDescriptorSetLayoutBinding binding =
91 	{
92 		dstBinding,						// binding
93 		descriptorType,					// descriptorType
94 		descriptorCount,				// descriptorCount
95 		stageFlags,						// stageFlags
96 		DE_NULL,						// pImmutableSamplers
97 	};
98 	m_bindings.push_back(binding);
99 	return *this;
100 }
101 
build(const DeviceInterface & vk,VkDevice device,VkDescriptorSetLayoutCreateFlags extraFlags) const102 Move<VkDescriptorSetLayout> DescriptorSetLayoutBuilder::build (const DeviceInterface& vk, VkDevice device, VkDescriptorSetLayoutCreateFlags extraFlags) const
103 {
104 	// Create new layout bindings with pImmutableSamplers updated
105 	std::vector<VkDescriptorSetLayoutBinding>	bindings	= m_bindings;
106 
107 	for (size_t samplerInfoNdx = 0; samplerInfoNdx < m_immutableSamplerInfos.size(); samplerInfoNdx++)
108 	{
109 		const ImmutableSamplerInfo&	samplerInfo	= m_immutableSamplerInfos[samplerInfoNdx];
110 		deUint32					bindingNdx	= 0;
111 
112 		while (bindings[bindingNdx].binding != samplerInfo.bindingIndex)
113 		{
114 			bindingNdx++;
115 
116 			if (bindingNdx >= (deUint32)bindings.size())
117 				DE_FATAL("Immutable sampler not found");
118 		}
119 
120 		bindings[bindingNdx].pImmutableSamplers = &m_immutableSamplers[samplerInfo.samplerBaseIndex];
121 	}
122 
123 	const VkDescriptorSetLayoutCreateInfo		createInfo	=
124 	{
125 		VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
126 		DE_NULL,
127 		(VkDescriptorSetLayoutCreateFlags)extraFlags,			// flags
128 		(deUint32)bindings.size(),								// bindingCount
129 		(bindings.empty()) ? (DE_NULL) : (&bindings.front()),	// pBinding
130 	};
131 
132 	return createDescriptorSetLayout(vk, device, &createInfo);
133 }
134 
135 // DescriptorPoolBuilder
136 
DescriptorPoolBuilder(void)137 DescriptorPoolBuilder::DescriptorPoolBuilder (void)
138 {
139 }
140 
addType(VkDescriptorType type,deUint32 numDescriptors)141 DescriptorPoolBuilder& DescriptorPoolBuilder::addType (VkDescriptorType type, deUint32 numDescriptors)
142 {
143 	if (numDescriptors == 0u)
144 	{
145 		// nothing to do
146 		return *this;
147 	}
148 	else
149 	{
150 		for (size_t ndx = 0; ndx < m_counts.size(); ++ndx)
151 		{
152 			if (m_counts[ndx].type == type)
153 			{
154 				// augment existing requirement
155 				m_counts[ndx].descriptorCount += numDescriptors;
156 				return *this;
157 			}
158 		}
159 
160 		{
161 			// new requirement
162 			const VkDescriptorPoolSize typeCount =
163 			{
164 				type,			// type
165 				numDescriptors,	// numDescriptors
166 			};
167 
168 			m_counts.push_back(typeCount);
169 			return *this;
170 		}
171 	}
172 }
173 
build(const DeviceInterface & vk,VkDevice device,VkDescriptorPoolCreateFlags flags,deUint32 maxSets,const void * pNext) const174 Move<VkDescriptorPool> DescriptorPoolBuilder::build (const DeviceInterface& vk, VkDevice device, VkDescriptorPoolCreateFlags flags, deUint32 maxSets, const void *pNext) const
175 {
176 	const VkDescriptorPoolSize* const	typeCountPtr	= (m_counts.empty()) ? (DE_NULL) : (&m_counts[0]);
177 	const VkDescriptorPoolCreateInfo	createInfo		=
178 	{
179 		VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
180 		pNext,
181 		flags,
182 		maxSets,
183 		(deUint32)m_counts.size(),		// poolSizeCount
184 		typeCountPtr,					// pPoolSizes
185 	};
186 
187 	return createDescriptorPool(vk, device, &createInfo);
188 }
189 
190 // DescriptorSetUpdateBuilder
191 
DescriptorSetUpdateBuilder(void)192 DescriptorSetUpdateBuilder::DescriptorSetUpdateBuilder (void)
193 {
194 }
195 
write(VkDescriptorSet destSet,deUint32 destBinding,deUint32 destArrayElement,deUint32 count,VkDescriptorType descriptorType,const VkDescriptorImageInfo * pImageInfo,const VkDescriptorBufferInfo * pBufferInfo,const VkBufferView * pTexelBufferView)196 DescriptorSetUpdateBuilder& DescriptorSetUpdateBuilder::write (VkDescriptorSet					destSet,
197 															   deUint32							destBinding,
198 															   deUint32							destArrayElement,
199 															   deUint32							count,
200 															   VkDescriptorType					descriptorType,
201 															   const VkDescriptorImageInfo*		pImageInfo,
202 															   const VkDescriptorBufferInfo*	pBufferInfo,
203 															   const VkBufferView*				pTexelBufferView)
204 {
205 	// pImageInfo, pBufferInfo and pTexelBufferView will be updated when calling update()
206 	const VkWriteDescriptorSet writeParams =
207 	{
208 		VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
209 		DE_NULL,
210 		destSet,			//!< destSet
211 		destBinding,		//!< destBinding
212 		destArrayElement,	//!< destArrayElement
213 		count,				//!< count
214 		descriptorType,		//!< descriptorType
215 		DE_NULL,
216 		DE_NULL,
217 		DE_NULL
218 	};
219 
220 	m_writes.push_back(writeParams);
221 
222 	// Store a copy of pImageInfo, pBufferInfo and pTexelBufferView
223 	WriteDescriptorInfo	writeInfo;
224 
225 	if (pImageInfo)
226 		writeInfo.imageInfos.insert(writeInfo.imageInfos.end(), pImageInfo, pImageInfo + count);
227 
228 	if (pBufferInfo)
229 		writeInfo.bufferInfos.insert(writeInfo.bufferInfos.end(), pBufferInfo, pBufferInfo + count);
230 
231 	if (pTexelBufferView)
232 		writeInfo.texelBufferViews.insert(writeInfo.texelBufferViews.end(), pTexelBufferView, pTexelBufferView + count);
233 
234 	m_writeDescriptorInfos.push_back(writeInfo);
235 
236 	return *this;
237 }
238 
copy(VkDescriptorSet srcSet,deUint32 srcBinding,deUint32 srcArrayElement,VkDescriptorSet destSet,deUint32 destBinding,deUint32 destArrayElement,deUint32 count)239 DescriptorSetUpdateBuilder& DescriptorSetUpdateBuilder::copy (VkDescriptorSet	srcSet,
240 															  deUint32			srcBinding,
241 															  deUint32			srcArrayElement,
242 															  VkDescriptorSet	destSet,
243 															  deUint32			destBinding,
244 															  deUint32			destArrayElement,
245 															  deUint32			count)
246 {
247 	const VkCopyDescriptorSet copyParams =
248 	{
249 		VK_STRUCTURE_TYPE_COPY_DESCRIPTOR_SET,
250 		DE_NULL,
251 		srcSet,				//!< srcSet
252 		srcBinding,			//!< srcBinding
253 		srcArrayElement,	//!< srcArrayElement
254 		destSet,			//!< destSet
255 		destBinding,		//!< destBinding
256 		destArrayElement,	//!< destArrayElement
257 		count,				//!< count
258 	};
259 	m_copies.push_back(copyParams);
260 	return *this;
261 }
262 
update(const DeviceInterface & vk,VkDevice device) const263 void DescriptorSetUpdateBuilder::update (const DeviceInterface& vk, VkDevice device) const
264 {
265 	// Update VkWriteDescriptorSet structures with stored info
266 	std::vector<VkWriteDescriptorSet> writes	= m_writes;
267 
268 	for (size_t writeNdx = 0; writeNdx < m_writes.size(); writeNdx++)
269 	{
270 		const WriteDescriptorInfo& writeInfo = m_writeDescriptorInfos[writeNdx];
271 
272 		if (!writeInfo.imageInfos.empty())
273 			writes[writeNdx].pImageInfo			= &writeInfo.imageInfos[0];
274 
275 		if (!writeInfo.bufferInfos.empty())
276 			writes[writeNdx].pBufferInfo		= &writeInfo.bufferInfos[0];
277 
278 		if (!writeInfo.texelBufferViews.empty())
279 			writes[writeNdx].pTexelBufferView	= &writeInfo.texelBufferViews[0];
280 	}
281 
282 	const VkWriteDescriptorSet* const	writePtr	= (m_writes.empty()) ? (DE_NULL) : (&writes[0]);
283 	const VkCopyDescriptorSet* const	copyPtr		= (m_copies.empty()) ? (DE_NULL) : (&m_copies[0]);
284 
285 	vk.updateDescriptorSets(device, (deUint32)writes.size(), writePtr, (deUint32)m_copies.size(), copyPtr);
286 }
287 
updateWithPush(const DeviceInterface & vk,VkCommandBuffer cmd,VkPipelineBindPoint bindPoint,VkPipelineLayout pipelineLayout,deUint32 setIdx,deUint32 descriptorIdx,deUint32 numDescriptors) const288 void DescriptorSetUpdateBuilder::updateWithPush (const DeviceInterface& vk, VkCommandBuffer cmd, VkPipelineBindPoint bindPoint, VkPipelineLayout pipelineLayout, deUint32 setIdx, deUint32 descriptorIdx, deUint32 numDescriptors) const
289 {
290 	// Write all descriptors or just a subset?
291 	deUint32							count		= (numDescriptors) ? numDescriptors : (deUint32)m_writes.size();
292 
293 	// Update VkWriteDescriptorSet structures with stored info
294 	std::vector<VkWriteDescriptorSet>	writes		= m_writes;
295 
296 	for (size_t writeNdx = 0; writeNdx < m_writes.size(); writeNdx++)
297 	{
298 		const WriteDescriptorInfo& writeInfo = m_writeDescriptorInfos[writeNdx];
299 
300 		if (!writeInfo.imageInfos.empty())
301 			writes[writeNdx].pImageInfo			= &writeInfo.imageInfos[0];
302 
303 		if (!writeInfo.bufferInfos.empty())
304 			writes[writeNdx].pBufferInfo		= &writeInfo.bufferInfos[0];
305 
306 		if (!writeInfo.texelBufferViews.empty())
307 			writes[writeNdx].pTexelBufferView	= &writeInfo.texelBufferViews[0];
308 	}
309 
310 	const VkWriteDescriptorSet* const	writePtr	= (m_writes.empty()) ? (DE_NULL) : (&writes[descriptorIdx]);
311 
312 	vk.cmdPushDescriptorSetKHR(cmd, bindPoint, pipelineLayout, setIdx, count, writePtr);
313 }
314 
clear(void)315 void DescriptorSetUpdateBuilder::clear(void)
316 {
317 	m_writeDescriptorInfos.clear();
318 	m_writes.clear();
319 	m_copies.clear();
320 }
321 
322 } // vk
323