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