/*------------------------------------------------------------------------- * Vulkan CTS Framework * -------------------- * * Copyright (c) 2015 Google Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * *//*! * \file * \brief Vulkan object builder utilities. *//*--------------------------------------------------------------------*/ #include "vkBuilderUtil.hpp" #include "vkRefUtil.hpp" namespace vk { // DescriptorSetLayoutBuilder DescriptorSetLayoutBuilder::DescriptorSetLayoutBuilder (void) { } DescriptorSetLayoutBuilder& DescriptorSetLayoutBuilder::addBinding (VkDescriptorType descriptorType, deUint32 descriptorCount, VkShaderStageFlags stageFlags, const VkSampler* pImmutableSamplers) { if (pImmutableSamplers) { const ImmutableSamplerInfo immutableSamplerInfo = { (deUint32)m_bindings.size(), (deUint32)m_immutableSamplers.size() }; m_immutableSamplerInfos.push_back(immutableSamplerInfo); for (size_t descriptorNdx = 0; descriptorNdx < descriptorCount; descriptorNdx++) m_immutableSamplers.push_back(pImmutableSamplers[descriptorNdx]); } // pImmutableSamplers will be updated at build time const VkDescriptorSetLayoutBinding binding = { (deUint32)m_bindings.size(), // binding descriptorType, // descriptorType descriptorCount, // descriptorCount stageFlags, // stageFlags DE_NULL, // pImmutableSamplers }; m_bindings.push_back(binding); return *this; } Move DescriptorSetLayoutBuilder::build (const DeviceInterface& vk, VkDevice device) const { // Create new layout bindings with pImmutableSamplers updated std::vector bindings = m_bindings; for (size_t samplerInfoNdx = 0; samplerInfoNdx < m_immutableSamplerInfos.size(); samplerInfoNdx++) { const ImmutableSamplerInfo& samplerInfo = m_immutableSamplerInfos[samplerInfoNdx]; bindings[samplerInfo.bindingIndex].pImmutableSamplers = &m_immutableSamplers[samplerInfo.samplerBaseIndex]; } const VkDescriptorSetLayoutCreateInfo createInfo = { VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, DE_NULL, (VkDescriptorSetLayoutCreateFlags)0, // flags (deUint32)bindings.size(), // bindingCount (bindings.empty()) ? (DE_NULL) : (bindings.data()), // pBinding }; return createDescriptorSetLayout(vk, device, &createInfo); } // DescriptorPoolBuilder DescriptorPoolBuilder::DescriptorPoolBuilder (void) { } DescriptorPoolBuilder& DescriptorPoolBuilder::addType (VkDescriptorType type, deUint32 numDescriptors) { if (numDescriptors == 0u) { // nothing to do return *this; } else { for (size_t ndx = 0; ndx < m_counts.size(); ++ndx) { if (m_counts[ndx].type == type) { // augment existing requirement m_counts[ndx].descriptorCount += numDescriptors; return *this; } } { // new requirement const VkDescriptorPoolSize typeCount = { type, // type numDescriptors, // numDescriptors }; m_counts.push_back(typeCount); return *this; } } } Move DescriptorPoolBuilder::build (const DeviceInterface& vk, VkDevice device, VkDescriptorPoolCreateFlags flags, deUint32 maxSets) const { const VkDescriptorPoolSize* const typeCountPtr = (m_counts.empty()) ? (DE_NULL) : (&m_counts[0]); const VkDescriptorPoolCreateInfo createInfo = { VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO, DE_NULL, flags, maxSets, (deUint32)m_counts.size(), // poolSizeCount typeCountPtr, // pPoolSizes }; return createDescriptorPool(vk, device, &createInfo); } // DescriptorSetUpdateBuilder DescriptorSetUpdateBuilder::DescriptorSetUpdateBuilder (void) { } DescriptorSetUpdateBuilder& DescriptorSetUpdateBuilder::write (VkDescriptorSet destSet, deUint32 destBinding, deUint32 destArrayElement, deUint32 count, VkDescriptorType descriptorType, const VkDescriptorImageInfo* pImageInfo, const VkDescriptorBufferInfo* pBufferInfo, const VkBufferView* pTexelBufferView) { // pImageInfo, pBufferInfo and pTexelBufferView will be updated when calling update() const VkWriteDescriptorSet writeParams = { VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, DE_NULL, destSet, //!< destSet destBinding, //!< destBinding destArrayElement, //!< destArrayElement count, //!< count descriptorType, //!< descriptorType DE_NULL, DE_NULL, DE_NULL }; m_writes.push_back(writeParams); // Store a copy of pImageInfo, pBufferInfo and pTexelBufferView WriteDescriptorInfo writeInfo; if (pImageInfo) writeInfo.imageInfos.insert(writeInfo.imageInfos.end(), pImageInfo, pImageInfo + count); if (pBufferInfo) writeInfo.bufferInfos.insert(writeInfo.bufferInfos.end(), pBufferInfo, pBufferInfo + count); if (pTexelBufferView) writeInfo.texelBufferViews.insert(writeInfo.texelBufferViews.end(), pTexelBufferView, pTexelBufferView + count); m_writeDescriptorInfos.push_back(writeInfo); return *this; } DescriptorSetUpdateBuilder& DescriptorSetUpdateBuilder::copy (VkDescriptorSet srcSet, deUint32 srcBinding, deUint32 srcArrayElement, VkDescriptorSet destSet, deUint32 destBinding, deUint32 destArrayElement, deUint32 count) { const VkCopyDescriptorSet copyParams = { VK_STRUCTURE_TYPE_COPY_DESCRIPTOR_SET, DE_NULL, srcSet, //!< srcSet srcBinding, //!< srcBinding srcArrayElement, //!< srcArrayElement destSet, //!< destSet destBinding, //!< destBinding destArrayElement, //!< destArrayElement count, //!< count }; m_copies.push_back(copyParams); return *this; } void DescriptorSetUpdateBuilder::update (const DeviceInterface& vk, VkDevice device) const { // Update VkWriteDescriptorSet structures with stored info std::vector writes = m_writes; for (size_t writeNdx = 0; writeNdx < m_writes.size(); writeNdx++) { const WriteDescriptorInfo& writeInfo = m_writeDescriptorInfos[writeNdx]; if (!writeInfo.imageInfos.empty()) writes[writeNdx].pImageInfo = &writeInfo.imageInfos[0]; if (!writeInfo.bufferInfos.empty()) writes[writeNdx].pBufferInfo = &writeInfo.bufferInfos[0]; if (!writeInfo.texelBufferViews.empty()) writes[writeNdx].pTexelBufferView = &writeInfo.texelBufferViews[0]; } const VkWriteDescriptorSet* const writePtr = (m_writes.empty()) ? (DE_NULL) : (&writes[0]); const VkCopyDescriptorSet* const copyPtr = (m_copies.empty()) ? (DE_NULL) : (&m_copies[0]); vk.updateDescriptorSets(device, (deUint32)writes.size(), writePtr, (deUint32)m_copies.size(), copyPtr); } } // vk