• 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,const void * pNext)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 															   const void*						pNext)
205 {
206 	// pImageInfo, pBufferInfo and pTexelBufferView will be updated when calling update()
207 	const VkWriteDescriptorSet writeParams =
208 	{
209 		VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
210 		pNext,
211 		destSet,			//!< destSet
212 		destBinding,		//!< destBinding
213 		destArrayElement,	//!< destArrayElement
214 		count,				//!< count
215 		descriptorType,		//!< descriptorType
216 		DE_NULL,
217 		DE_NULL,
218 		DE_NULL
219 	};
220 
221 	m_writes.push_back(writeParams);
222 
223 	// Store a copy of pImageInfo, pBufferInfo and pTexelBufferView
224 	WriteDescriptorInfo	writeInfo;
225 
226 	if (pImageInfo)
227 		writeInfo.imageInfos.insert(writeInfo.imageInfos.end(), pImageInfo, pImageInfo + count);
228 
229 	if (pBufferInfo)
230 		writeInfo.bufferInfos.insert(writeInfo.bufferInfos.end(), pBufferInfo, pBufferInfo + count);
231 
232 	if (pTexelBufferView)
233 		writeInfo.texelBufferViews.insert(writeInfo.texelBufferViews.end(), pTexelBufferView, pTexelBufferView + count);
234 
235 	m_writeDescriptorInfos.push_back(writeInfo);
236 
237 	return *this;
238 }
239 
copy(VkDescriptorSet srcSet,deUint32 srcBinding,deUint32 srcArrayElement,VkDescriptorSet destSet,deUint32 destBinding,deUint32 destArrayElement,deUint32 count)240 DescriptorSetUpdateBuilder& DescriptorSetUpdateBuilder::copy (VkDescriptorSet	srcSet,
241 															  deUint32			srcBinding,
242 															  deUint32			srcArrayElement,
243 															  VkDescriptorSet	destSet,
244 															  deUint32			destBinding,
245 															  deUint32			destArrayElement,
246 															  deUint32			count)
247 {
248 	const VkCopyDescriptorSet copyParams =
249 	{
250 		VK_STRUCTURE_TYPE_COPY_DESCRIPTOR_SET,
251 		DE_NULL,
252 		srcSet,				//!< srcSet
253 		srcBinding,			//!< srcBinding
254 		srcArrayElement,	//!< srcArrayElement
255 		destSet,			//!< destSet
256 		destBinding,		//!< destBinding
257 		destArrayElement,	//!< destArrayElement
258 		count,				//!< count
259 	};
260 	m_copies.push_back(copyParams);
261 	return *this;
262 }
263 
update(const DeviceInterface & vk,VkDevice device) const264 void DescriptorSetUpdateBuilder::update (const DeviceInterface& vk, VkDevice device) const
265 {
266 	// Update VkWriteDescriptorSet structures with stored info
267 	std::vector<VkWriteDescriptorSet> writes	= m_writes;
268 
269 	for (size_t writeNdx = 0; writeNdx < m_writes.size(); writeNdx++)
270 	{
271 		const WriteDescriptorInfo& writeInfo = m_writeDescriptorInfos[writeNdx];
272 
273 		if (!writeInfo.imageInfos.empty())
274 			writes[writeNdx].pImageInfo			= &writeInfo.imageInfos[0];
275 
276 		if (!writeInfo.bufferInfos.empty())
277 			writes[writeNdx].pBufferInfo		= &writeInfo.bufferInfos[0];
278 
279 		if (!writeInfo.texelBufferViews.empty())
280 			writes[writeNdx].pTexelBufferView	= &writeInfo.texelBufferViews[0];
281 	}
282 
283 	const VkWriteDescriptorSet* const	writePtr	= (m_writes.empty()) ? (DE_NULL) : (&writes[0]);
284 	const VkCopyDescriptorSet* const	copyPtr		= (m_copies.empty()) ? (DE_NULL) : (&m_copies[0]);
285 
286 	vk.updateDescriptorSets(device, (deUint32)writes.size(), writePtr, (deUint32)m_copies.size(), copyPtr);
287 }
288 
updateWithPush(const DeviceInterface & vk,VkCommandBuffer cmd,VkPipelineBindPoint bindPoint,VkPipelineLayout pipelineLayout,deUint32 setIdx,deUint32 descriptorIdx,deUint32 numDescriptors) const289 void DescriptorSetUpdateBuilder::updateWithPush (const DeviceInterface& vk, VkCommandBuffer cmd, VkPipelineBindPoint bindPoint, VkPipelineLayout pipelineLayout, deUint32 setIdx, deUint32 descriptorIdx, deUint32 numDescriptors) const
290 {
291 	// Write all descriptors or just a subset?
292 	deUint32							count		= (numDescriptors) ? numDescriptors : (deUint32)m_writes.size();
293 
294 	// Update VkWriteDescriptorSet structures with stored info
295 	std::vector<VkWriteDescriptorSet>	writes		= m_writes;
296 
297 	for (size_t writeNdx = 0; writeNdx < m_writes.size(); writeNdx++)
298 	{
299 		const WriteDescriptorInfo& writeInfo = m_writeDescriptorInfos[writeNdx];
300 
301 		if (!writeInfo.imageInfos.empty())
302 			writes[writeNdx].pImageInfo			= &writeInfo.imageInfos[0];
303 
304 		if (!writeInfo.bufferInfos.empty())
305 			writes[writeNdx].pBufferInfo		= &writeInfo.bufferInfos[0];
306 
307 		if (!writeInfo.texelBufferViews.empty())
308 			writes[writeNdx].pTexelBufferView	= &writeInfo.texelBufferViews[0];
309 	}
310 
311 	const VkWriteDescriptorSet* const	writePtr	= (m_writes.empty()) ? (DE_NULL) : (&writes[descriptorIdx]);
312 
313 	vk.cmdPushDescriptorSetKHR(cmd, bindPoint, pipelineLayout, setIdx, count, writePtr);
314 }
315 
clear(void)316 void DescriptorSetUpdateBuilder::clear(void)
317 {
318 	m_writeDescriptorInfos.clear();
319 	m_writes.clear();
320 	m_copies.clear();
321 }
322 
323 } // vk
324