xref: /aosp_15_r20/external/deqp/external/vulkancts/framework/vulkan/vkBuilderUtil.cpp (revision 35238bce31c2a825756842865a792f8cf7f89930)
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,uint32_t descriptorCount,VkShaderStageFlags stageFlags,const VkSampler * pImmutableSamplers)37 DescriptorSetLayoutBuilder &DescriptorSetLayoutBuilder::addBinding(VkDescriptorType descriptorType,
38                                                                    uint32_t descriptorCount,
39                                                                    VkShaderStageFlags stageFlags,
40                                                                    const VkSampler *pImmutableSamplers)
41 {
42     if (pImmutableSamplers)
43     {
44         const ImmutableSamplerInfo immutableSamplerInfo = {(uint32_t)m_bindings.size(),
45                                                            (uint32_t)m_immutableSamplers.size()};
46 
47         m_immutableSamplerInfos.push_back(immutableSamplerInfo);
48 
49         for (size_t descriptorNdx = 0; descriptorNdx < descriptorCount; descriptorNdx++)
50             m_immutableSamplers.push_back(pImmutableSamplers[descriptorNdx]);
51     }
52 
53     // pImmutableSamplers will be updated at build time
54     const VkDescriptorSetLayoutBinding binding = {
55         (uint32_t)m_bindings.size(), // binding
56         descriptorType,              // descriptorType
57         descriptorCount,             // descriptorCount
58         stageFlags,                  // stageFlags
59         DE_NULL,                     // pImmutableSamplers
60     };
61     m_bindings.push_back(binding);
62     return *this;
63 }
64 
addIndexedBinding(VkDescriptorType descriptorType,uint32_t descriptorCount,VkShaderStageFlags stageFlags,uint32_t dstBinding,const VkSampler * pImmutableSamplers)65 DescriptorSetLayoutBuilder &DescriptorSetLayoutBuilder::addIndexedBinding(VkDescriptorType descriptorType,
66                                                                           uint32_t descriptorCount,
67                                                                           VkShaderStageFlags stageFlags,
68                                                                           uint32_t dstBinding,
69                                                                           const VkSampler *pImmutableSamplers)
70 {
71     if (pImmutableSamplers)
72     {
73         const ImmutableSamplerInfo immutableSamplerInfo = {(uint32_t)dstBinding, (uint32_t)m_immutableSamplers.size()};
74 
75         m_immutableSamplerInfos.push_back(immutableSamplerInfo);
76 
77         for (size_t descriptorNdx = 0; descriptorNdx < descriptorCount; descriptorNdx++)
78             m_immutableSamplers.push_back(pImmutableSamplers[descriptorNdx]);
79     }
80 
81     // pImmutableSamplers will be updated at build time
82     const VkDescriptorSetLayoutBinding binding = {
83         dstBinding,      // binding
84         descriptorType,  // descriptorType
85         descriptorCount, // descriptorCount
86         stageFlags,      // stageFlags
87         DE_NULL,         // pImmutableSamplers
88     };
89     m_bindings.push_back(binding);
90     return *this;
91 }
92 
build(const DeviceInterface & vk,VkDevice device,VkDescriptorSetLayoutCreateFlags extraFlags) const93 Move<VkDescriptorSetLayout> DescriptorSetLayoutBuilder::build(const DeviceInterface &vk, VkDevice device,
94                                                               VkDescriptorSetLayoutCreateFlags extraFlags) const
95 {
96     // Create new layout bindings with pImmutableSamplers updated
97     std::vector<VkDescriptorSetLayoutBinding> bindings = m_bindings;
98 
99     for (size_t samplerInfoNdx = 0; samplerInfoNdx < m_immutableSamplerInfos.size(); samplerInfoNdx++)
100     {
101         const ImmutableSamplerInfo &samplerInfo = m_immutableSamplerInfos[samplerInfoNdx];
102         uint32_t bindingNdx                     = 0;
103 
104         while (bindings[bindingNdx].binding != samplerInfo.bindingIndex)
105         {
106             bindingNdx++;
107 
108             if (bindingNdx >= (uint32_t)bindings.size())
109                 DE_FATAL("Immutable sampler not found");
110         }
111 
112         bindings[bindingNdx].pImmutableSamplers = &m_immutableSamplers[samplerInfo.samplerBaseIndex];
113     }
114 
115     const VkDescriptorSetLayoutCreateInfo createInfo = {
116         VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
117         DE_NULL,
118         (VkDescriptorSetLayoutCreateFlags)extraFlags,         // flags
119         (uint32_t)bindings.size(),                            // bindingCount
120         (bindings.empty()) ? (DE_NULL) : (&bindings.front()), // pBinding
121     };
122 
123     return createDescriptorSetLayout(vk, device, &createInfo);
124 }
125 
126 // DescriptorPoolBuilder
127 
DescriptorPoolBuilder(void)128 DescriptorPoolBuilder::DescriptorPoolBuilder(void)
129 {
130 }
131 
addType(VkDescriptorType type,uint32_t numDescriptors)132 DescriptorPoolBuilder &DescriptorPoolBuilder::addType(VkDescriptorType type, uint32_t 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                 type,           // type
155                 numDescriptors, // numDescriptors
156             };
157 
158             m_counts.push_back(typeCount);
159             return *this;
160         }
161     }
162 }
163 
build(const DeviceInterface & vk,VkDevice device,VkDescriptorPoolCreateFlags flags,uint32_t maxSets,const void * pNext) const164 Move<VkDescriptorPool> DescriptorPoolBuilder::build(const DeviceInterface &vk, VkDevice device,
165                                                     VkDescriptorPoolCreateFlags flags, uint32_t maxSets,
166                                                     const void *pNext) const
167 {
168     const VkDescriptorPoolSize *const typeCountPtr = (m_counts.empty()) ? (DE_NULL) : (&m_counts[0]);
169     const VkDescriptorPoolCreateInfo createInfo    = {
170         VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
171         pNext,
172         flags,
173         maxSets,
174         (uint32_t)m_counts.size(), // poolSizeCount
175         typeCountPtr,              // pPoolSizes
176     };
177 
178     return createDescriptorPool(vk, device, &createInfo);
179 }
180 
181 // DescriptorSetUpdateBuilder
182 
DescriptorSetUpdateBuilder(void)183 DescriptorSetUpdateBuilder::DescriptorSetUpdateBuilder(void)
184 {
185 }
186 
write(VkDescriptorSet destSet,uint32_t destBinding,uint32_t destArrayElement,uint32_t count,VkDescriptorType descriptorType,const VkDescriptorImageInfo * pImageInfo,const VkDescriptorBufferInfo * pBufferInfo,const VkBufferView * pTexelBufferView,const void * pNext)187 DescriptorSetUpdateBuilder &DescriptorSetUpdateBuilder::write(VkDescriptorSet destSet, uint32_t destBinding,
188                                                               uint32_t destArrayElement, uint32_t count,
189                                                               VkDescriptorType descriptorType,
190                                                               const VkDescriptorImageInfo *pImageInfo,
191                                                               const VkDescriptorBufferInfo *pBufferInfo,
192                                                               const VkBufferView *pTexelBufferView, const void *pNext)
193 {
194     // pImageInfo, pBufferInfo and pTexelBufferView will be updated when calling update()
195     const VkWriteDescriptorSet writeParams = {VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
196                                               pNext,
197                                               destSet,          //!< destSet
198                                               destBinding,      //!< destBinding
199                                               destArrayElement, //!< destArrayElement
200                                               count,            //!< count
201                                               descriptorType,   //!< descriptorType
202                                               DE_NULL,
203                                               DE_NULL,
204                                               DE_NULL};
205 
206     m_writes.push_back(writeParams);
207 
208     // Store a copy of pImageInfo, pBufferInfo and pTexelBufferView
209     WriteDescriptorInfo writeInfo;
210 
211     if (pImageInfo)
212         writeInfo.imageInfos.insert(writeInfo.imageInfos.end(), pImageInfo, pImageInfo + count);
213 
214     if (pBufferInfo)
215         writeInfo.bufferInfos.insert(writeInfo.bufferInfos.end(), pBufferInfo, pBufferInfo + count);
216 
217     if (pTexelBufferView)
218         writeInfo.texelBufferViews.insert(writeInfo.texelBufferViews.end(), pTexelBufferView, pTexelBufferView + count);
219 
220     m_writeDescriptorInfos.push_back(writeInfo);
221 
222     return *this;
223 }
224 
copy(VkDescriptorSet srcSet,uint32_t srcBinding,uint32_t srcArrayElement,VkDescriptorSet destSet,uint32_t destBinding,uint32_t destArrayElement,uint32_t count)225 DescriptorSetUpdateBuilder &DescriptorSetUpdateBuilder::copy(VkDescriptorSet srcSet, uint32_t srcBinding,
226                                                              uint32_t srcArrayElement, VkDescriptorSet destSet,
227                                                              uint32_t destBinding, uint32_t destArrayElement,
228                                                              uint32_t count)
229 {
230     const VkCopyDescriptorSet copyParams = {
231         VK_STRUCTURE_TYPE_COPY_DESCRIPTOR_SET,
232         DE_NULL,
233         srcSet,           //!< srcSet
234         srcBinding,       //!< srcBinding
235         srcArrayElement,  //!< srcArrayElement
236         destSet,          //!< destSet
237         destBinding,      //!< destBinding
238         destArrayElement, //!< destArrayElement
239         count,            //!< count
240     };
241     m_copies.push_back(copyParams);
242     return *this;
243 }
244 
update(const DeviceInterface & vk,VkDevice device) const245 void DescriptorSetUpdateBuilder::update(const DeviceInterface &vk, VkDevice device) const
246 {
247     // Update VkWriteDescriptorSet structures with stored info
248     std::vector<VkWriteDescriptorSet> writes = m_writes;
249 
250     for (size_t writeNdx = 0; writeNdx < m_writes.size(); writeNdx++)
251     {
252         const WriteDescriptorInfo &writeInfo = m_writeDescriptorInfos[writeNdx];
253 
254         if (!writeInfo.imageInfos.empty())
255             writes[writeNdx].pImageInfo = &writeInfo.imageInfos[0];
256 
257         if (!writeInfo.bufferInfos.empty())
258             writes[writeNdx].pBufferInfo = &writeInfo.bufferInfos[0];
259 
260         if (!writeInfo.texelBufferViews.empty())
261             writes[writeNdx].pTexelBufferView = &writeInfo.texelBufferViews[0];
262     }
263 
264     const VkWriteDescriptorSet *const writePtr = (m_writes.empty()) ? (DE_NULL) : (&writes[0]);
265     const VkCopyDescriptorSet *const copyPtr   = (m_copies.empty()) ? (DE_NULL) : (&m_copies[0]);
266 
267     vk.updateDescriptorSets(device, (uint32_t)writes.size(), writePtr, (uint32_t)m_copies.size(), copyPtr);
268 }
269 
270 #ifndef CTS_USES_VULKANSC
271 
updateWithPush(const DeviceInterface & vk,VkCommandBuffer cmd,VkPipelineBindPoint bindPoint,VkPipelineLayout pipelineLayout,uint32_t setIdx,uint32_t descriptorIdx,uint32_t numDescriptors) const272 void DescriptorSetUpdateBuilder::updateWithPush(const DeviceInterface &vk, VkCommandBuffer cmd,
273                                                 VkPipelineBindPoint bindPoint, VkPipelineLayout pipelineLayout,
274                                                 uint32_t setIdx, uint32_t descriptorIdx, uint32_t numDescriptors) const
275 {
276     // Write all descriptors or just a subset?
277     uint32_t count = (numDescriptors) ? numDescriptors : (uint32_t)m_writes.size();
278 
279     // Update VkWriteDescriptorSet structures with stored info
280     std::vector<VkWriteDescriptorSet> writes = m_writes;
281 
282     for (size_t writeNdx = 0; writeNdx < m_writes.size(); writeNdx++)
283     {
284         const WriteDescriptorInfo &writeInfo = m_writeDescriptorInfos[writeNdx];
285 
286         if (!writeInfo.imageInfos.empty())
287             writes[writeNdx].pImageInfo = &writeInfo.imageInfos[0];
288 
289         if (!writeInfo.bufferInfos.empty())
290             writes[writeNdx].pBufferInfo = &writeInfo.bufferInfos[0];
291 
292         if (!writeInfo.texelBufferViews.empty())
293             writes[writeNdx].pTexelBufferView = &writeInfo.texelBufferViews[0];
294     }
295 
296     const VkWriteDescriptorSet *const writePtr = (m_writes.empty()) ? (DE_NULL) : (&writes[descriptorIdx]);
297 
298     vk.cmdPushDescriptorSetKHR(cmd, bindPoint, pipelineLayout, setIdx, count, writePtr);
299 }
300 
301 #endif // CTS_USES_VULKANSC
302 
clear(void)303 void DescriptorSetUpdateBuilder::clear(void)
304 {
305     m_writeDescriptorInfos.clear();
306     m_writes.clear();
307     m_copies.clear();
308 }
309 
310 } // namespace vk
311