• 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 
build(const DeviceInterface & vk,VkDevice device,VkDescriptorSetLayoutCreateFlags extraFlags) const69 Move<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 
DescriptorPoolBuilder(void)95 DescriptorPoolBuilder::DescriptorPoolBuilder (void)
96 {
97 }
98 
addType(VkDescriptorType type,deUint32 numDescriptors)99 DescriptorPoolBuilder& 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 
build(const DeviceInterface & vk,VkDevice device,VkDescriptorPoolCreateFlags flags,deUint32 maxSets) const132 Move<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 
DescriptorSetUpdateBuilder(void)150 DescriptorSetUpdateBuilder::DescriptorSetUpdateBuilder (void)
151 {
152 }
153 
write(VkDescriptorSet destSet,deUint32 destBinding,deUint32 destArrayElement,deUint32 count,VkDescriptorType descriptorType,const VkDescriptorImageInfo * pImageInfo,const VkDescriptorBufferInfo * pBufferInfo,const VkBufferView * pTexelBufferView)154 DescriptorSetUpdateBuilder& 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 
copy(VkDescriptorSet srcSet,deUint32 srcBinding,deUint32 srcArrayElement,VkDescriptorSet destSet,deUint32 destBinding,deUint32 destArrayElement,deUint32 count)197 DescriptorSetUpdateBuilder& 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 
update(const DeviceInterface & vk,VkDevice device) const221 void 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 
updateWithPush(const DeviceInterface & vk,VkCommandBuffer cmd,VkPipelineBindPoint bindPoint,VkPipelineLayout pipelineLayout,deUint32 setIdx) const246 void 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