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