Test binding model with multiple descriptor sets
[platform/upstream/VK-GL-CTS.git] / external / vulkancts / framework / vulkan / vkBuilderUtil.cpp
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
33 DescriptorSetLayoutBuilder::DescriptorSetLayoutBuilder (void)
34 {
35 }
36
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
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
102 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
111                 bindings[samplerInfo.bindingIndex].pImmutableSamplers   = &m_immutableSamplers[samplerInfo.samplerBaseIndex];
112         }
113
114         const VkDescriptorSetLayoutCreateInfo           createInfo      =
115         {
116                 VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
117                 DE_NULL,
118                 (VkDescriptorSetLayoutCreateFlags)extraFlags,                   // flags
119                 (deUint32)bindings.size(),                                                              // bindingCount
120                 (bindings.empty()) ? (DE_NULL) : (bindings.data()),             // pBinding
121         };
122
123         return createDescriptorSetLayout(vk, device, &createInfo);
124 }
125
126 // DescriptorPoolBuilder
127
128 DescriptorPoolBuilder::DescriptorPoolBuilder (void)
129 {
130 }
131
132 DescriptorPoolBuilder& DescriptorPoolBuilder::addType (VkDescriptorType type, deUint32 numDescriptors)
133 {
134         if (numDescriptors == 0u)
135         {
136                 // nothing to do
137                 return *this;
138         }
139         else
140         {
141                 for (size_t ndx = 0; ndx < m_counts.size(); ++ndx)
142                 {
143                         if (m_counts[ndx].type == type)
144                         {
145                                 // augment existing requirement
146                                 m_counts[ndx].descriptorCount += numDescriptors;
147                                 return *this;
148                         }
149                 }
150
151                 {
152                         // new requirement
153                         const VkDescriptorPoolSize typeCount =
154                         {
155                                 type,                   // type
156                                 numDescriptors, // numDescriptors
157                         };
158
159                         m_counts.push_back(typeCount);
160                         return *this;
161                 }
162         }
163 }
164
165 Move<VkDescriptorPool> DescriptorPoolBuilder::build (const DeviceInterface& vk, VkDevice device, VkDescriptorPoolCreateFlags flags, deUint32 maxSets) const
166 {
167         const VkDescriptorPoolSize* const       typeCountPtr    = (m_counts.empty()) ? (DE_NULL) : (&m_counts[0]);
168         const VkDescriptorPoolCreateInfo        createInfo              =
169         {
170                 VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
171                 DE_NULL,
172                 flags,
173                 maxSets,
174                 (deUint32)m_counts.size(),              // poolSizeCount
175                 typeCountPtr,                                   // pPoolSizes
176         };
177
178         return createDescriptorPool(vk, device, &createInfo);
179 }
180
181 // DescriptorSetUpdateBuilder
182
183 DescriptorSetUpdateBuilder::DescriptorSetUpdateBuilder (void)
184 {
185 }
186
187 DescriptorSetUpdateBuilder& DescriptorSetUpdateBuilder::write (VkDescriptorSet                                  destSet,
188                                                                                                                            deUint32                                                     destBinding,
189                                                                                                                            deUint32                                                     destArrayElement,
190                                                                                                                            deUint32                                                     count,
191                                                                                                                            VkDescriptorType                                     descriptorType,
192                                                                                                                            const VkDescriptorImageInfo*         pImageInfo,
193                                                                                                                            const VkDescriptorBufferInfo*        pBufferInfo,
194                                                                                                                            const VkBufferView*                          pTexelBufferView)
195 {
196         // pImageInfo, pBufferInfo and pTexelBufferView will be updated when calling update()
197         const VkWriteDescriptorSet writeParams =
198         {
199                 VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
200                 DE_NULL,
201                 destSet,                        //!< destSet
202                 destBinding,            //!< destBinding
203                 destArrayElement,       //!< destArrayElement
204                 count,                          //!< count
205                 descriptorType,         //!< descriptorType
206                 DE_NULL,
207                 DE_NULL,
208                 DE_NULL
209         };
210
211         m_writes.push_back(writeParams);
212
213         // Store a copy of pImageInfo, pBufferInfo and pTexelBufferView
214         WriteDescriptorInfo     writeInfo;
215
216         if (pImageInfo)
217                 writeInfo.imageInfos.insert(writeInfo.imageInfos.end(), pImageInfo, pImageInfo + count);
218
219         if (pBufferInfo)
220                 writeInfo.bufferInfos.insert(writeInfo.bufferInfos.end(), pBufferInfo, pBufferInfo + count);
221
222         if (pTexelBufferView)
223                 writeInfo.texelBufferViews.insert(writeInfo.texelBufferViews.end(), pTexelBufferView, pTexelBufferView + count);
224
225         m_writeDescriptorInfos.push_back(writeInfo);
226
227         return *this;
228 }
229
230 DescriptorSetUpdateBuilder& DescriptorSetUpdateBuilder::copy (VkDescriptorSet   srcSet,
231                                                                                                                           deUint32                      srcBinding,
232                                                                                                                           deUint32                      srcArrayElement,
233                                                                                                                           VkDescriptorSet       destSet,
234                                                                                                                           deUint32                      destBinding,
235                                                                                                                           deUint32                      destArrayElement,
236                                                                                                                           deUint32                      count)
237 {
238         const VkCopyDescriptorSet copyParams =
239         {
240                 VK_STRUCTURE_TYPE_COPY_DESCRIPTOR_SET,
241                 DE_NULL,
242                 srcSet,                         //!< srcSet
243                 srcBinding,                     //!< srcBinding
244                 srcArrayElement,        //!< srcArrayElement
245                 destSet,                        //!< destSet
246                 destBinding,            //!< destBinding
247                 destArrayElement,       //!< destArrayElement
248                 count,                          //!< count
249         };
250         m_copies.push_back(copyParams);
251         return *this;
252 }
253
254 void DescriptorSetUpdateBuilder::update (const DeviceInterface& vk, VkDevice device) const
255 {
256         // Update VkWriteDescriptorSet structures with stored info
257         std::vector<VkWriteDescriptorSet> writes        = m_writes;
258
259         for (size_t writeNdx = 0; writeNdx < m_writes.size(); writeNdx++)
260         {
261                 const WriteDescriptorInfo& writeInfo = m_writeDescriptorInfos[writeNdx];
262
263                 if (!writeInfo.imageInfos.empty())
264                         writes[writeNdx].pImageInfo                     = &writeInfo.imageInfos[0];
265
266                 if (!writeInfo.bufferInfos.empty())
267                         writes[writeNdx].pBufferInfo            = &writeInfo.bufferInfos[0];
268
269                 if (!writeInfo.texelBufferViews.empty())
270                         writes[writeNdx].pTexelBufferView       = &writeInfo.texelBufferViews[0];
271         }
272
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]);
275
276         vk.updateDescriptorSets(device, (deUint32)writes.size(), writePtr, (deUint32)m_copies.size(), copyPtr);
277 }
278
279 void DescriptorSetUpdateBuilder::updateWithPush (const DeviceInterface& vk, VkCommandBuffer cmd, VkPipelineBindPoint bindPoint, VkPipelineLayout pipelineLayout, deUint32 setIdx, deUint32 descriptorIdx, deUint32 numDescriptors) const
280 {
281         // Write all descriptors or just a subset?
282         deUint32                                                        count           = (numDescriptors) ? numDescriptors : (deUint32)m_writes.size();
283
284         // Update VkWriteDescriptorSet structures with stored info
285         std::vector<VkWriteDescriptorSet>       writes          = m_writes;
286
287         for (size_t writeNdx = 0; writeNdx < m_writes.size(); writeNdx++)
288         {
289                 const WriteDescriptorInfo& writeInfo = m_writeDescriptorInfos[writeNdx];
290
291                 if (!writeInfo.imageInfos.empty())
292                         writes[writeNdx].pImageInfo                     = &writeInfo.imageInfos[0];
293
294                 if (!writeInfo.bufferInfos.empty())
295                         writes[writeNdx].pBufferInfo            = &writeInfo.bufferInfos[0];
296
297                 if (!writeInfo.texelBufferViews.empty())
298                         writes[writeNdx].pTexelBufferView       = &writeInfo.texelBufferViews[0];
299         }
300
301         const VkWriteDescriptorSet* const       writePtr        = (m_writes.empty()) ? (DE_NULL) : (&writes[descriptorIdx]);
302
303         vk.cmdPushDescriptorSetKHR(cmd, bindPoint, pipelineLayout, setIdx, count, writePtr);
304 }
305
306 void DescriptorSetUpdateBuilder::clear(void)
307 {
308         m_writeDescriptorInfos.clear();
309         m_writes.clear();
310         m_copies.clear();
311 }
312
313 } // vk