1 /*-------------------------------------------------------------------------
5 * Copyright (c) 2015 Google Inc.
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
11 * http://www.apache.org/licenses/LICENSE-2.0
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.
21 * \brief Vulkan object builder utilities.
22 *//*--------------------------------------------------------------------*/
24 #include "vkBuilderUtil.hpp"
26 #include "vkRefUtil.hpp"
31 // DescriptorSetLayoutBuilder
33 DescriptorSetLayoutBuilder::DescriptorSetLayoutBuilder (void)
37 DescriptorSetLayoutBuilder& DescriptorSetLayoutBuilder::addBinding (VkDescriptorType descriptorType,
38 deUint32 descriptorCount,
39 VkShaderStageFlags stageFlags,
40 const VkSampler* pImmutableSamplers)
42 if (pImmutableSamplers)
44 const ImmutableSamplerInfo immutableSamplerInfo =
46 (deUint32)m_bindings.size(),
47 (deUint32)m_immutableSamplers.size()
50 m_immutableSamplerInfos.push_back(immutableSamplerInfo);
52 for (size_t descriptorNdx = 0; descriptorNdx < descriptorCount; descriptorNdx++)
53 m_immutableSamplers.push_back(pImmutableSamplers[descriptorNdx]);
56 // pImmutableSamplers will be updated at build time
57 const VkDescriptorSetLayoutBinding binding =
59 (deUint32)m_bindings.size(), // binding
60 descriptorType, // descriptorType
61 descriptorCount, // descriptorCount
62 stageFlags, // stageFlags
63 DE_NULL, // pImmutableSamplers
65 m_bindings.push_back(binding);
69 DescriptorSetLayoutBuilder& DescriptorSetLayoutBuilder::addIndexedBinding (VkDescriptorType descriptorType,
70 deUint32 descriptorCount,
71 VkShaderStageFlags stageFlags,
73 const VkSampler* pImmutableSamplers)
75 if (pImmutableSamplers)
77 const ImmutableSamplerInfo immutableSamplerInfo =
80 (deUint32)m_immutableSamplers.size()
83 m_immutableSamplerInfos.push_back(immutableSamplerInfo);
85 for (size_t descriptorNdx = 0; descriptorNdx < descriptorCount; descriptorNdx++)
86 m_immutableSamplers.push_back(pImmutableSamplers[descriptorNdx]);
89 // pImmutableSamplers will be updated at build time
90 const VkDescriptorSetLayoutBinding binding =
92 dstBinding, // binding
93 descriptorType, // descriptorType
94 descriptorCount, // descriptorCount
95 stageFlags, // stageFlags
96 DE_NULL, // pImmutableSamplers
98 m_bindings.push_back(binding);
102 Move<VkDescriptorSetLayout> DescriptorSetLayoutBuilder::build (const DeviceInterface& vk, VkDevice device, VkDescriptorSetLayoutCreateFlags extraFlags) const
104 // Create new layout bindings with pImmutableSamplers updated
105 std::vector<VkDescriptorSetLayoutBinding> bindings = m_bindings;
107 for (size_t samplerInfoNdx = 0; samplerInfoNdx < m_immutableSamplerInfos.size(); samplerInfoNdx++)
109 const ImmutableSamplerInfo& samplerInfo = m_immutableSamplerInfos[samplerInfoNdx];
111 bindings[samplerInfo.bindingIndex].pImmutableSamplers = &m_immutableSamplers[samplerInfo.samplerBaseIndex];
114 const VkDescriptorSetLayoutCreateInfo createInfo =
116 VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
118 (VkDescriptorSetLayoutCreateFlags)extraFlags, // flags
119 (deUint32)bindings.size(), // bindingCount
120 (bindings.empty()) ? (DE_NULL) : (bindings.data()), // pBinding
123 return createDescriptorSetLayout(vk, device, &createInfo);
126 // DescriptorPoolBuilder
128 DescriptorPoolBuilder::DescriptorPoolBuilder (void)
132 DescriptorPoolBuilder& DescriptorPoolBuilder::addType (VkDescriptorType type, deUint32 numDescriptors)
134 if (numDescriptors == 0u)
141 for (size_t ndx = 0; ndx < m_counts.size(); ++ndx)
143 if (m_counts[ndx].type == type)
145 // augment existing requirement
146 m_counts[ndx].descriptorCount += numDescriptors;
153 const VkDescriptorPoolSize typeCount =
156 numDescriptors, // numDescriptors
159 m_counts.push_back(typeCount);
165 Move<VkDescriptorPool> DescriptorPoolBuilder::build (const DeviceInterface& vk, VkDevice device, VkDescriptorPoolCreateFlags flags, deUint32 maxSets) const
167 const VkDescriptorPoolSize* const typeCountPtr = (m_counts.empty()) ? (DE_NULL) : (&m_counts[0]);
168 const VkDescriptorPoolCreateInfo createInfo =
170 VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
174 (deUint32)m_counts.size(), // poolSizeCount
175 typeCountPtr, // pPoolSizes
178 return createDescriptorPool(vk, device, &createInfo);
181 // DescriptorSetUpdateBuilder
183 DescriptorSetUpdateBuilder::DescriptorSetUpdateBuilder (void)
187 DescriptorSetUpdateBuilder& DescriptorSetUpdateBuilder::write (VkDescriptorSet destSet,
188 deUint32 destBinding,
189 deUint32 destArrayElement,
191 VkDescriptorType descriptorType,
192 const VkDescriptorImageInfo* pImageInfo,
193 const VkDescriptorBufferInfo* pBufferInfo,
194 const VkBufferView* pTexelBufferView)
196 // pImageInfo, pBufferInfo and pTexelBufferView will be updated when calling update()
197 const VkWriteDescriptorSet writeParams =
199 VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
201 destSet, //!< destSet
202 destBinding, //!< destBinding
203 destArrayElement, //!< destArrayElement
205 descriptorType, //!< descriptorType
211 m_writes.push_back(writeParams);
213 // Store a copy of pImageInfo, pBufferInfo and pTexelBufferView
214 WriteDescriptorInfo writeInfo;
217 writeInfo.imageInfos.insert(writeInfo.imageInfos.end(), pImageInfo, pImageInfo + count);
220 writeInfo.bufferInfos.insert(writeInfo.bufferInfos.end(), pBufferInfo, pBufferInfo + count);
222 if (pTexelBufferView)
223 writeInfo.texelBufferViews.insert(writeInfo.texelBufferViews.end(), pTexelBufferView, pTexelBufferView + count);
225 m_writeDescriptorInfos.push_back(writeInfo);
230 DescriptorSetUpdateBuilder& DescriptorSetUpdateBuilder::copy (VkDescriptorSet srcSet,
232 deUint32 srcArrayElement,
233 VkDescriptorSet destSet,
234 deUint32 destBinding,
235 deUint32 destArrayElement,
238 const VkCopyDescriptorSet copyParams =
240 VK_STRUCTURE_TYPE_COPY_DESCRIPTOR_SET,
243 srcBinding, //!< srcBinding
244 srcArrayElement, //!< srcArrayElement
245 destSet, //!< destSet
246 destBinding, //!< destBinding
247 destArrayElement, //!< destArrayElement
250 m_copies.push_back(copyParams);
254 void DescriptorSetUpdateBuilder::update (const DeviceInterface& vk, VkDevice device) const
256 // Update VkWriteDescriptorSet structures with stored info
257 std::vector<VkWriteDescriptorSet> writes = m_writes;
259 for (size_t writeNdx = 0; writeNdx < m_writes.size(); writeNdx++)
261 const WriteDescriptorInfo& writeInfo = m_writeDescriptorInfos[writeNdx];
263 if (!writeInfo.imageInfos.empty())
264 writes[writeNdx].pImageInfo = &writeInfo.imageInfos[0];
266 if (!writeInfo.bufferInfos.empty())
267 writes[writeNdx].pBufferInfo = &writeInfo.bufferInfos[0];
269 if (!writeInfo.texelBufferViews.empty())
270 writes[writeNdx].pTexelBufferView = &writeInfo.texelBufferViews[0];
273 const VkWriteDescriptorSet* const writePtr = (m_writes.empty()) ? (DE_NULL) : (&writes[0]);
274 const VkCopyDescriptorSet* const copyPtr = (m_copies.empty()) ? (DE_NULL) : (&m_copies[0]);
276 vk.updateDescriptorSets(device, (deUint32)writes.size(), writePtr, (deUint32)m_copies.size(), copyPtr);
279 void DescriptorSetUpdateBuilder::updateWithPush (const DeviceInterface& vk, VkCommandBuffer cmd, VkPipelineBindPoint bindPoint, VkPipelineLayout pipelineLayout, deUint32 setIdx, deUint32 descriptorIdx, deUint32 numDescriptors) const
281 // Write all descriptors or just a subset?
282 deUint32 count = (numDescriptors) ? numDescriptors : (deUint32)m_writes.size();
284 // Update VkWriteDescriptorSet structures with stored info
285 std::vector<VkWriteDescriptorSet> writes = m_writes;
287 for (size_t writeNdx = 0; writeNdx < m_writes.size(); writeNdx++)
289 const WriteDescriptorInfo& writeInfo = m_writeDescriptorInfos[writeNdx];
291 if (!writeInfo.imageInfos.empty())
292 writes[writeNdx].pImageInfo = &writeInfo.imageInfos[0];
294 if (!writeInfo.bufferInfos.empty())
295 writes[writeNdx].pBufferInfo = &writeInfo.bufferInfos[0];
297 if (!writeInfo.texelBufferViews.empty())
298 writes[writeNdx].pTexelBufferView = &writeInfo.texelBufferViews[0];
301 const VkWriteDescriptorSet* const writePtr = (m_writes.empty()) ? (DE_NULL) : (&writes[descriptorIdx]);
303 vk.cmdPushDescriptorSetKHR(cmd, bindPoint, pipelineLayout, setIdx, count, writePtr);
306 void DescriptorSetUpdateBuilder::clear(void)
308 m_writeDescriptorInfos.clear();