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 DescriptorSetLayoutBuilder& 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 
    102 Move<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 		deUint32					bindingNdx	= 0;
    111 
    112 		while (bindings[bindingNdx].binding != samplerInfo.bindingIndex)
    113 		{
    114 			bindingNdx++;
    115 
    116 			if (bindingNdx >= (deUint32)bindings.size())
    117 				DE_FATAL("Immutable sampler not found");
    118 		}
    119 
    120 		bindings[bindingNdx].pImmutableSamplers = &m_immutableSamplers[samplerInfo.samplerBaseIndex];
    121 	}
    122 
    123 	const VkDescriptorSetLayoutCreateInfo		createInfo	=
    124 	{
    125 		VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
    126 		DE_NULL,
    127 		(VkDescriptorSetLayoutCreateFlags)extraFlags,			// flags
    128 		(deUint32)bindings.size(),								// bindingCount
    129 		(bindings.empty()) ? (DE_NULL) : (&bindings.front()),	// pBinding
    130 	};
    131 
    132 	return createDescriptorSetLayout(vk, device, &createInfo);
    133 }
    134 
    135 // DescriptorPoolBuilder
    136 
    137 DescriptorPoolBuilder::DescriptorPoolBuilder (void)
    138 {
    139 }
    140 
    141 DescriptorPoolBuilder& DescriptorPoolBuilder::addType (VkDescriptorType type, deUint32 numDescriptors)
    142 {
    143 	if (numDescriptors == 0u)
    144 	{
    145 		// nothing to do
    146 		return *this;
    147 	}
    148 	else
    149 	{
    150 		for (size_t ndx = 0; ndx < m_counts.size(); ++ndx)
    151 		{
    152 			if (m_counts[ndx].type == type)
    153 			{
    154 				// augment existing requirement
    155 				m_counts[ndx].descriptorCount += numDescriptors;
    156 				return *this;
    157 			}
    158 		}
    159 
    160 		{
    161 			// new requirement
    162 			const VkDescriptorPoolSize typeCount =
    163 			{
    164 				type,			// type
    165 				numDescriptors,	// numDescriptors
    166 			};
    167 
    168 			m_counts.push_back(typeCount);
    169 			return *this;
    170 		}
    171 	}
    172 }
    173 
    174 Move<VkDescriptorPool> DescriptorPoolBuilder::build (const DeviceInterface& vk, VkDevice device, VkDescriptorPoolCreateFlags flags, deUint32 maxSets, const void *pNext) const
    175 {
    176 	const VkDescriptorPoolSize* const	typeCountPtr	= (m_counts.empty()) ? (DE_NULL) : (&m_counts[0]);
    177 	const VkDescriptorPoolCreateInfo	createInfo		=
    178 	{
    179 		VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
    180 		pNext,
    181 		flags,
    182 		maxSets,
    183 		(deUint32)m_counts.size(),		// poolSizeCount
    184 		typeCountPtr,					// pPoolSizes
    185 	};
    186 
    187 	return createDescriptorPool(vk, device, &createInfo);
    188 }
    189 
    190 // DescriptorSetUpdateBuilder
    191 
    192 DescriptorSetUpdateBuilder::DescriptorSetUpdateBuilder (void)
    193 {
    194 }
    195 
    196 DescriptorSetUpdateBuilder& DescriptorSetUpdateBuilder::write (VkDescriptorSet					destSet,
    197 															   deUint32							destBinding,
    198 															   deUint32							destArrayElement,
    199 															   deUint32							count,
    200 															   VkDescriptorType					descriptorType,
    201 															   const VkDescriptorImageInfo*		pImageInfo,
    202 															   const VkDescriptorBufferInfo*	pBufferInfo,
    203 															   const VkBufferView*				pTexelBufferView)
    204 {
    205 	// pImageInfo, pBufferInfo and pTexelBufferView will be updated when calling update()
    206 	const VkWriteDescriptorSet writeParams =
    207 	{
    208 		VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
    209 		DE_NULL,
    210 		destSet,			//!< destSet
    211 		destBinding,		//!< destBinding
    212 		destArrayElement,	//!< destArrayElement
    213 		count,				//!< count
    214 		descriptorType,		//!< descriptorType
    215 		DE_NULL,
    216 		DE_NULL,
    217 		DE_NULL
    218 	};
    219 
    220 	m_writes.push_back(writeParams);
    221 
    222 	// Store a copy of pImageInfo, pBufferInfo and pTexelBufferView
    223 	WriteDescriptorInfo	writeInfo;
    224 
    225 	if (pImageInfo)
    226 		writeInfo.imageInfos.insert(writeInfo.imageInfos.end(), pImageInfo, pImageInfo + count);
    227 
    228 	if (pBufferInfo)
    229 		writeInfo.bufferInfos.insert(writeInfo.bufferInfos.end(), pBufferInfo, pBufferInfo + count);
    230 
    231 	if (pTexelBufferView)
    232 		writeInfo.texelBufferViews.insert(writeInfo.texelBufferViews.end(), pTexelBufferView, pTexelBufferView + count);
    233 
    234 	m_writeDescriptorInfos.push_back(writeInfo);
    235 
    236 	return *this;
    237 }
    238 
    239 DescriptorSetUpdateBuilder& DescriptorSetUpdateBuilder::copy (VkDescriptorSet	srcSet,
    240 															  deUint32			srcBinding,
    241 															  deUint32			srcArrayElement,
    242 															  VkDescriptorSet	destSet,
    243 															  deUint32			destBinding,
    244 															  deUint32			destArrayElement,
    245 															  deUint32			count)
    246 {
    247 	const VkCopyDescriptorSet copyParams =
    248 	{
    249 		VK_STRUCTURE_TYPE_COPY_DESCRIPTOR_SET,
    250 		DE_NULL,
    251 		srcSet,				//!< srcSet
    252 		srcBinding,			//!< srcBinding
    253 		srcArrayElement,	//!< srcArrayElement
    254 		destSet,			//!< destSet
    255 		destBinding,		//!< destBinding
    256 		destArrayElement,	//!< destArrayElement
    257 		count,				//!< count
    258 	};
    259 	m_copies.push_back(copyParams);
    260 	return *this;
    261 }
    262 
    263 void DescriptorSetUpdateBuilder::update (const DeviceInterface& vk, VkDevice device) const
    264 {
    265 	// Update VkWriteDescriptorSet structures with stored info
    266 	std::vector<VkWriteDescriptorSet> writes	= m_writes;
    267 
    268 	for (size_t writeNdx = 0; writeNdx < m_writes.size(); writeNdx++)
    269 	{
    270 		const WriteDescriptorInfo& writeInfo = m_writeDescriptorInfos[writeNdx];
    271 
    272 		if (!writeInfo.imageInfos.empty())
    273 			writes[writeNdx].pImageInfo			= &writeInfo.imageInfos[0];
    274 
    275 		if (!writeInfo.bufferInfos.empty())
    276 			writes[writeNdx].pBufferInfo		= &writeInfo.bufferInfos[0];
    277 
    278 		if (!writeInfo.texelBufferViews.empty())
    279 			writes[writeNdx].pTexelBufferView	= &writeInfo.texelBufferViews[0];
    280 	}
    281 
    282 	const VkWriteDescriptorSet* const	writePtr	= (m_writes.empty()) ? (DE_NULL) : (&writes[0]);
    283 	const VkCopyDescriptorSet* const	copyPtr		= (m_copies.empty()) ? (DE_NULL) : (&m_copies[0]);
    284 
    285 	vk.updateDescriptorSets(device, (deUint32)writes.size(), writePtr, (deUint32)m_copies.size(), copyPtr);
    286 }
    287 
    288 void DescriptorSetUpdateBuilder::updateWithPush (const DeviceInterface& vk, VkCommandBuffer cmd, VkPipelineBindPoint bindPoint, VkPipelineLayout pipelineLayout, deUint32 setIdx, deUint32 descriptorIdx, deUint32 numDescriptors) const
    289 {
    290 	// Write all descriptors or just a subset?
    291 	deUint32							count		= (numDescriptors) ? numDescriptors : (deUint32)m_writes.size();
    292 
    293 	// Update VkWriteDescriptorSet structures with stored info
    294 	std::vector<VkWriteDescriptorSet>	writes		= m_writes;
    295 
    296 	for (size_t writeNdx = 0; writeNdx < m_writes.size(); writeNdx++)
    297 	{
    298 		const WriteDescriptorInfo& writeInfo = m_writeDescriptorInfos[writeNdx];
    299 
    300 		if (!writeInfo.imageInfos.empty())
    301 			writes[writeNdx].pImageInfo			= &writeInfo.imageInfos[0];
    302 
    303 		if (!writeInfo.bufferInfos.empty())
    304 			writes[writeNdx].pBufferInfo		= &writeInfo.bufferInfos[0];
    305 
    306 		if (!writeInfo.texelBufferViews.empty())
    307 			writes[writeNdx].pTexelBufferView	= &writeInfo.texelBufferViews[0];
    308 	}
    309 
    310 	const VkWriteDescriptorSet* const	writePtr	= (m_writes.empty()) ? (DE_NULL) : (&writes[descriptorIdx]);
    311 
    312 	vk.cmdPushDescriptorSetKHR(cmd, bindPoint, pipelineLayout, setIdx, count, writePtr);
    313 }
    314 
    315 void DescriptorSetUpdateBuilder::clear(void)
    316 {
    317 	m_writeDescriptorInfos.clear();
    318 	m_writes.clear();
    319 	m_copies.clear();
    320 }
    321 
    322 } // vk
    323