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 28namespace vk 29{ 30 31// DescriptorSetLayoutBuilder 32 33DescriptorSetLayoutBuilder::DescriptorSetLayoutBuilder (void) 34{ 35} 36 37DescriptorSetLayoutBuilder& 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 69DescriptorSetLayoutBuilder& 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 102Move<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 128DescriptorPoolBuilder::DescriptorPoolBuilder (void) 129{ 130} 131 132DescriptorPoolBuilder& 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 165Move<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 183DescriptorSetUpdateBuilder::DescriptorSetUpdateBuilder (void) 184{ 185} 186 187DescriptorSetUpdateBuilder& 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 230DescriptorSetUpdateBuilder& 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 254void 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 279void DescriptorSetUpdateBuilder::updateWithPush (const DeviceInterface& vk, VkCommandBuffer cmd, VkPipelineBindPoint bindPoint, VkPipelineLayout pipelineLayout, deUint32 setIdx) const 280{ 281 // Update VkWriteDescriptorSet structures with stored info 282 std::vector<VkWriteDescriptorSet> writes = m_writes; 283 284 for (size_t writeNdx = 0; writeNdx < m_writes.size(); writeNdx++) 285 { 286 const WriteDescriptorInfo& writeInfo = m_writeDescriptorInfos[writeNdx]; 287 288 if (!writeInfo.imageInfos.empty()) 289 writes[writeNdx].pImageInfo = &writeInfo.imageInfos[0]; 290 291 if (!writeInfo.bufferInfos.empty()) 292 writes[writeNdx].pBufferInfo = &writeInfo.bufferInfos[0]; 293 294 if (!writeInfo.texelBufferViews.empty()) 295 writes[writeNdx].pTexelBufferView = &writeInfo.texelBufferViews[0]; 296 } 297 298 const VkWriteDescriptorSet* const writePtr = (m_writes.empty()) ? (DE_NULL) : (&writes[0]); 299 300 vk.cmdPushDescriptorSetKHR(cmd, bindPoint, pipelineLayout, setIdx, (deUint32)m_writes.size(), writePtr); 301} 302 303} // vk 304