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