xref: /aosp_15_r20/external/swiftshader/src/Vulkan/VkPipelineLayout.cpp (revision 03ce13f70fcc45d86ee91b7ee4cab1936a95046e)
1 // Copyright 2018 The SwiftShader Authors. All Rights Reserved.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //    http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #include "VkPipelineLayout.hpp"
16 
17 #include <algorithm>
18 #include <atomic>
19 
20 namespace vk {
21 
22 static std::atomic<uint32_t> layoutIdentifierSerial = { 1 };  // Start at 1. 0 is invalid/void layout.
23 
PipelineLayout(const VkPipelineLayoutCreateInfo * pCreateInfo,void * mem)24 PipelineLayout::PipelineLayout(const VkPipelineLayoutCreateInfo *pCreateInfo, void *mem)
25     : identifier(layoutIdentifierSerial++)
26     , descriptorSetCount(pCreateInfo->setLayoutCount)
27     , pushConstantRangeCount(pCreateInfo->pushConstantRangeCount)
28 {
29 	Binding *bindingStorage = reinterpret_cast<Binding *>(mem);
30 	uint32_t dynamicOffsetIndex = 0;
31 
32 	descriptorSets[0].bindings = bindingStorage;  // Used in destroy() for deallocation.
33 
34 	for(uint32_t i = 0; i < pCreateInfo->setLayoutCount; i++)
35 	{
36 		if(pCreateInfo->pSetLayouts[i] == VK_NULL_HANDLE)
37 		{
38 			continue;
39 		}
40 		const vk::DescriptorSetLayout *setLayout = vk::Cast(pCreateInfo->pSetLayouts[i]);
41 		uint32_t bindingsArraySize = setLayout->getBindingsArraySize();
42 		descriptorSets[i].bindings = bindingStorage;
43 		bindingStorage += bindingsArraySize;
44 		descriptorSets[i].bindingCount = bindingsArraySize;
45 
46 		for(uint32_t j = 0; j < bindingsArraySize; j++)
47 		{
48 			descriptorSets[i].bindings[j].descriptorType = setLayout->getDescriptorType(j);
49 			descriptorSets[i].bindings[j].offset = setLayout->getBindingOffset(j);
50 			descriptorSets[i].bindings[j].dynamicOffsetIndex = dynamicOffsetIndex;
51 			descriptorSets[i].bindings[j].descriptorCount = setLayout->getDescriptorCount(j);
52 
53 			if(DescriptorSetLayout::IsDescriptorDynamic(descriptorSets[i].bindings[j].descriptorType))
54 			{
55 				dynamicOffsetIndex += setLayout->getDescriptorCount(j);
56 			}
57 		}
58 	}
59 
60 	pushConstantRanges = reinterpret_cast<VkPushConstantRange *>(bindingStorage);
61 	std::copy(pCreateInfo->pPushConstantRanges, pCreateInfo->pPushConstantRanges + pCreateInfo->pushConstantRangeCount, pushConstantRanges);
62 
63 	incRefCount();
64 }
65 
destroy(const VkAllocationCallbacks * pAllocator)66 void PipelineLayout::destroy(const VkAllocationCallbacks *pAllocator)
67 {
68 	vk::freeHostMemory(descriptorSets[0].bindings, pAllocator);  // pushConstantRanges are in the same allocation
69 }
70 
release(const VkAllocationCallbacks * pAllocator)71 bool PipelineLayout::release(const VkAllocationCallbacks *pAllocator)
72 {
73 	if(decRefCount() == 0)
74 	{
75 		vk::freeHostMemory(descriptorSets[0].bindings, pAllocator);  // pushConstantRanges are in the same allocation
76 		return true;
77 	}
78 	return false;
79 }
80 
ComputeRequiredAllocationSize(const VkPipelineLayoutCreateInfo * pCreateInfo)81 size_t PipelineLayout::ComputeRequiredAllocationSize(const VkPipelineLayoutCreateInfo *pCreateInfo)
82 {
83 	uint32_t bindingsCount = 0;
84 	for(uint32_t i = 0; i < pCreateInfo->setLayoutCount; i++)
85 	{
86 		if(pCreateInfo->pSetLayouts[i] == VK_NULL_HANDLE)
87 		{
88 			continue;
89 		}
90 		bindingsCount += vk::Cast(pCreateInfo->pSetLayouts[i])->getBindingsArraySize();
91 	}
92 
93 	return bindingsCount * sizeof(Binding) +                                   // descriptorSets[]
94 	       pCreateInfo->pushConstantRangeCount * sizeof(VkPushConstantRange);  // pushConstantRanges[]
95 }
96 
getDescriptorSetCount() const97 size_t PipelineLayout::getDescriptorSetCount() const
98 {
99 	return descriptorSetCount;
100 }
101 
getBindingCount(uint32_t setNumber) const102 uint32_t PipelineLayout::getBindingCount(uint32_t setNumber) const
103 {
104 	return descriptorSets[setNumber].bindingCount;
105 }
106 
getDynamicOffsetIndex(uint32_t setNumber,uint32_t bindingNumber) const107 uint32_t PipelineLayout::getDynamicOffsetIndex(uint32_t setNumber, uint32_t bindingNumber) const
108 {
109 	ASSERT(setNumber < descriptorSetCount && bindingNumber < descriptorSets[setNumber].bindingCount);
110 	return descriptorSets[setNumber].bindings[bindingNumber].dynamicOffsetIndex;
111 }
112 
getDescriptorCount(uint32_t setNumber,uint32_t bindingNumber) const113 uint32_t PipelineLayout::getDescriptorCount(uint32_t setNumber, uint32_t bindingNumber) const
114 {
115 	ASSERT(setNumber < descriptorSetCount && bindingNumber < descriptorSets[setNumber].bindingCount);
116 	return descriptorSets[setNumber].bindings[bindingNumber].descriptorCount;
117 }
118 
getBindingOffset(uint32_t setNumber,uint32_t bindingNumber) const119 uint32_t PipelineLayout::getBindingOffset(uint32_t setNumber, uint32_t bindingNumber) const
120 {
121 	ASSERT(setNumber < descriptorSetCount && bindingNumber < descriptorSets[setNumber].bindingCount);
122 	return descriptorSets[setNumber].bindings[bindingNumber].offset;
123 }
124 
getDescriptorType(uint32_t setNumber,uint32_t bindingNumber) const125 VkDescriptorType PipelineLayout::getDescriptorType(uint32_t setNumber, uint32_t bindingNumber) const
126 {
127 	ASSERT(setNumber < descriptorSetCount && bindingNumber < descriptorSets[setNumber].bindingCount);
128 	return descriptorSets[setNumber].bindings[bindingNumber].descriptorType;
129 }
130 
getDescriptorSize(uint32_t setNumber,uint32_t bindingNumber) const131 uint32_t PipelineLayout::getDescriptorSize(uint32_t setNumber, uint32_t bindingNumber) const
132 {
133 	return DescriptorSetLayout::GetDescriptorSize(getDescriptorType(setNumber, bindingNumber));
134 }
135 
isDescriptorDynamic(uint32_t setNumber,uint32_t bindingNumber) const136 bool PipelineLayout::isDescriptorDynamic(uint32_t setNumber, uint32_t bindingNumber) const
137 {
138 	return DescriptorSetLayout::IsDescriptorDynamic(getDescriptorType(setNumber, bindingNumber));
139 }
140 
incRefCount()141 uint32_t PipelineLayout::incRefCount()
142 {
143 	return ++refCount;
144 }
145 
decRefCount()146 uint32_t PipelineLayout::decRefCount()
147 {
148 	return --refCount;
149 }
150 
151 }  // namespace vk
152