vkBuilderUtil.cpp revision 0a80ec2c33f4483764669cc58ea3010f9c1b855f
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
28namespace vk
29{
30
31// DescriptorSetLayoutBuilder
32
33DescriptorSetLayoutBuilder::DescriptorSetLayoutBuilder (void)
34{
35}
36
37DescriptorSetLayoutBuilder& 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
69Move<VkDescriptorSetLayout> DescriptorSetLayoutBuilder::build (const DeviceInterface& vk, VkDevice device, VkDescriptorSetLayoutCreateFlags extraFlags) const
70{
71	// Create new layout bindings with pImmutableSamplers updated
72	std::vector<VkDescriptorSetLayoutBinding>	bindings	= m_bindings;
73
74	for (size_t samplerInfoNdx = 0; samplerInfoNdx < m_immutableSamplerInfos.size(); samplerInfoNdx++)
75	{
76		const ImmutableSamplerInfo&	samplerInfo	= m_immutableSamplerInfos[samplerInfoNdx];
77
78		bindings[samplerInfo.bindingIndex].pImmutableSamplers	= &m_immutableSamplers[samplerInfo.samplerBaseIndex];
79	}
80
81	const VkDescriptorSetLayoutCreateInfo		createInfo	=
82	{
83		VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
84		DE_NULL,
85		(VkDescriptorSetLayoutCreateFlags)extraFlags,			// flags
86		(deUint32)bindings.size(),								// bindingCount
87		(bindings.empty()) ? (DE_NULL) : (bindings.data()),		// pBinding
88	};
89
90	return createDescriptorSetLayout(vk, device, &createInfo);
91}
92
93// DescriptorPoolBuilder
94
95DescriptorPoolBuilder::DescriptorPoolBuilder (void)
96{
97}
98
99DescriptorPoolBuilder& DescriptorPoolBuilder::addType (VkDescriptorType type, deUint32 numDescriptors)
100{
101	if (numDescriptors == 0u)
102	{
103		// nothing to do
104		return *this;
105	}
106	else
107	{
108		for (size_t ndx = 0; ndx < m_counts.size(); ++ndx)
109		{
110			if (m_counts[ndx].type == type)
111			{
112				// augment existing requirement
113				m_counts[ndx].descriptorCount += numDescriptors;
114				return *this;
115			}
116		}
117
118		{
119			// new requirement
120			const VkDescriptorPoolSize typeCount =
121			{
122				type,			// type
123				numDescriptors,	// numDescriptors
124			};
125
126			m_counts.push_back(typeCount);
127			return *this;
128		}
129	}
130}
131
132Move<VkDescriptorPool> DescriptorPoolBuilder::build (const DeviceInterface& vk, VkDevice device, VkDescriptorPoolCreateFlags flags, deUint32 maxSets) const
133{
134	const VkDescriptorPoolSize* const	typeCountPtr	= (m_counts.empty()) ? (DE_NULL) : (&m_counts[0]);
135	const VkDescriptorPoolCreateInfo	createInfo		=
136	{
137		VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
138		DE_NULL,
139		flags,
140		maxSets,
141		(deUint32)m_counts.size(),		// poolSizeCount
142		typeCountPtr,					// pPoolSizes
143	};
144
145	return createDescriptorPool(vk, device, &createInfo);
146}
147
148// DescriptorSetUpdateBuilder
149
150DescriptorSetUpdateBuilder::DescriptorSetUpdateBuilder (void)
151{
152}
153
154DescriptorSetUpdateBuilder& DescriptorSetUpdateBuilder::write (VkDescriptorSet					destSet,
155															   deUint32							destBinding,
156															   deUint32							destArrayElement,
157															   deUint32							count,
158															   VkDescriptorType					descriptorType,
159															   const VkDescriptorImageInfo*		pImageInfo,
160															   const VkDescriptorBufferInfo*	pBufferInfo,
161															   const VkBufferView*				pTexelBufferView)
162{
163	// pImageInfo, pBufferInfo and pTexelBufferView will be updated when calling update()
164	const VkWriteDescriptorSet writeParams =
165	{
166		VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
167		DE_NULL,
168		destSet,			//!< destSet
169		destBinding,		//!< destBinding
170		destArrayElement,	//!< destArrayElement
171		count,				//!< count
172		descriptorType,		//!< descriptorType
173		DE_NULL,
174		DE_NULL,
175		DE_NULL
176	};
177
178	m_writes.push_back(writeParams);
179
180	// Store a copy of pImageInfo, pBufferInfo and pTexelBufferView
181	WriteDescriptorInfo	writeInfo;
182
183	if (pImageInfo)
184		writeInfo.imageInfos.insert(writeInfo.imageInfos.end(), pImageInfo, pImageInfo + count);
185
186	if (pBufferInfo)
187		writeInfo.bufferInfos.insert(writeInfo.bufferInfos.end(), pBufferInfo, pBufferInfo + count);
188
189	if (pTexelBufferView)
190		writeInfo.texelBufferViews.insert(writeInfo.texelBufferViews.end(), pTexelBufferView, pTexelBufferView + count);
191
192	m_writeDescriptorInfos.push_back(writeInfo);
193
194	return *this;
195}
196
197DescriptorSetUpdateBuilder& DescriptorSetUpdateBuilder::copy (VkDescriptorSet	srcSet,
198															  deUint32			srcBinding,
199															  deUint32			srcArrayElement,
200															  VkDescriptorSet	destSet,
201															  deUint32			destBinding,
202															  deUint32			destArrayElement,
203															  deUint32			count)
204{
205	const VkCopyDescriptorSet copyParams =
206	{
207		VK_STRUCTURE_TYPE_COPY_DESCRIPTOR_SET,
208		DE_NULL,
209		srcSet,				//!< srcSet
210		srcBinding,			//!< srcBinding
211		srcArrayElement,	//!< srcArrayElement
212		destSet,			//!< destSet
213		destBinding,		//!< destBinding
214		destArrayElement,	//!< destArrayElement
215		count,				//!< count
216	};
217	m_copies.push_back(copyParams);
218	return *this;
219}
220
221void DescriptorSetUpdateBuilder::update (const DeviceInterface& vk, VkDevice device) const
222{
223	// Update VkWriteDescriptorSet structures with stored info
224	std::vector<VkWriteDescriptorSet> writes	= m_writes;
225
226	for (size_t writeNdx = 0; writeNdx < m_writes.size(); writeNdx++)
227	{
228		const WriteDescriptorInfo& writeInfo = m_writeDescriptorInfos[writeNdx];
229
230		if (!writeInfo.imageInfos.empty())
231			writes[writeNdx].pImageInfo			= &writeInfo.imageInfos[0];
232
233		if (!writeInfo.bufferInfos.empty())
234			writes[writeNdx].pBufferInfo		= &writeInfo.bufferInfos[0];
235
236		if (!writeInfo.texelBufferViews.empty())
237			writes[writeNdx].pTexelBufferView	= &writeInfo.texelBufferViews[0];
238	}
239
240	const VkWriteDescriptorSet* const	writePtr	= (m_writes.empty()) ? (DE_NULL) : (&writes[0]);
241	const VkCopyDescriptorSet* const	copyPtr		= (m_copies.empty()) ? (DE_NULL) : (&m_copies[0]);
242
243	vk.updateDescriptorSets(device, (deUint32)writes.size(), writePtr, (deUint32)m_copies.size(), copyPtr);
244}
245
246void DescriptorSetUpdateBuilder::updateWithPush (const DeviceInterface& vk, VkCommandBuffer cmd, VkPipelineBindPoint bindPoint, VkPipelineLayout pipelineLayout, deUint32 setIdx) const
247{
248	// Update VkWriteDescriptorSet structures with stored info
249	std::vector<VkWriteDescriptorSet> writes	= m_writes;
250
251	for (size_t writeNdx = 0; writeNdx < m_writes.size(); writeNdx++)
252	{
253		const WriteDescriptorInfo& writeInfo = m_writeDescriptorInfos[writeNdx];
254
255		if (!writeInfo.imageInfos.empty())
256			writes[writeNdx].pImageInfo			= &writeInfo.imageInfos[0];
257
258		if (!writeInfo.bufferInfos.empty())
259			writes[writeNdx].pBufferInfo		= &writeInfo.bufferInfos[0];
260
261		if (!writeInfo.texelBufferViews.empty())
262			writes[writeNdx].pTexelBufferView	= &writeInfo.texelBufferViews[0];
263	}
264
265	const VkWriteDescriptorSet* const	writePtr	= (m_writes.empty()) ? (DE_NULL) : (&writes[0]);
266
267	vk.cmdPushDescriptorSetKHR(cmd, bindPoint, pipelineLayout, setIdx, (deUint32)m_writes.size(), writePtr);
268}
269
270} // vk
271