Home | History | Annotate | Download | only in vulkan
      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