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 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 95 DescriptorPoolBuilder::DescriptorPoolBuilder (void) 96 { 97 } 98 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 132 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 150 DescriptorSetUpdateBuilder::DescriptorSetUpdateBuilder (void) 151 { 152 } 153 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 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 221 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 246 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