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 
    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 
    128 DescriptorPoolBuilder::DescriptorPoolBuilder (void)
    129 {
    130 }
    131 
    132 DescriptorPoolBuilder& 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 
    165 Move<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 
    183 DescriptorSetUpdateBuilder::DescriptorSetUpdateBuilder (void)
    184 {
    185 }
    186 
    187 DescriptorSetUpdateBuilder& 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 
    230 DescriptorSetUpdateBuilder& 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 
    254 void 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 
    279 void 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