blob: 4d12cc5603d05199617ae09190a94dd85b0774af [file] [log] [blame]
Alexis Hetu000df8b2018-10-24 15:22:41 -04001// 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"
Nicolas Capens5ab1f362020-04-22 01:39:36 -040016
17#include <atomic>
Alexis Hetu8c1e8f12019-02-15 16:41:12 -050018#include <cstring>
Alexis Hetu000df8b2018-10-24 15:22:41 -040019
Nicolas Capens157ba262019-12-10 17:49:14 -050020namespace vk {
Alexis Hetu000df8b2018-10-24 15:22:41 -040021
Nicolas Capens5ab1f362020-04-22 01:39:36 -040022static std::atomic<uint32_t> layoutIdentifierSerial = { 1 }; // Start at 1. 0 is invalid/void layout.
23
Ben Clayton2ed93ab2019-12-17 20:38:03 +000024PipelineLayout::PipelineLayout(const VkPipelineLayoutCreateInfo *pCreateInfo, void *mem)
Nicolas Capens5ab1f362020-04-22 01:39:36 -040025 : identifier(layoutIdentifierSerial++)
Nicolas Capensc7d5ec32020-04-22 01:11:37 -040026 , descriptorSetCount(pCreateInfo->setLayoutCount)
Ben Clayton2ed93ab2019-12-17 20:38:03 +000027 , pushConstantRangeCount(pCreateInfo->pushConstantRangeCount)
Alexis Hetu000df8b2018-10-24 15:22:41 -040028{
Nicolas Capens026f7d02020-04-23 23:44:57 -040029 Binding *bindingStorage = reinterpret_cast<Binding *>(mem);
30 uint32_t dynamicOffsetIndex = 0;
Nicolas Capens6f5ff492020-06-01 13:06:52 -040031
32 descriptorSets[0].bindings = bindingStorage; // Used in destroy() for deallocation.
33
Alexis Hetuf630b252019-05-30 09:47:38 -040034 for(uint32_t i = 0; i < pCreateInfo->setLayoutCount; i++)
35 {
Nicolas Capens026f7d02020-04-23 23:44:57 -040036 const vk::DescriptorSetLayout *setLayout = vk::Cast(pCreateInfo->pSetLayouts[i]);
37 uint32_t bindingsArraySize = setLayout->getBindingsArraySize();
38 descriptorSets[i].bindings = bindingStorage;
39 bindingStorage += bindingsArraySize;
Nicolas Capens026f7d02020-04-23 23:44:57 -040040 descriptorSets[i].bindingCount = bindingsArraySize;
41
42 for(uint32_t j = 0; j < bindingsArraySize; j++)
43 {
44 descriptorSets[i].bindings[j].descriptorType = setLayout->getDescriptorType(j);
45 descriptorSets[i].bindings[j].offset = setLayout->getBindingOffset(j);
46 descriptorSets[i].bindings[j].dynamicOffsetIndex = dynamicOffsetIndex;
Nicolas Capenseb682442020-06-01 15:24:52 -040047 descriptorSets[i].bindings[j].descriptorCount = setLayout->getDescriptorCount(j);
Nicolas Capens026f7d02020-04-23 23:44:57 -040048
49 if(DescriptorSetLayout::IsDescriptorDynamic(descriptorSets[i].bindings[j].descriptorType))
50 {
51 dynamicOffsetIndex += setLayout->getDescriptorCount(j);
52 }
53 }
Alexis Hetuf630b252019-05-30 09:47:38 -040054 }
Alexis Hetu8c1e8f12019-02-15 16:41:12 -050055
56 size_t pushConstantRangesSize = pCreateInfo->pushConstantRangeCount * sizeof(VkPushConstantRange);
Nicolas Capens026f7d02020-04-23 23:44:57 -040057 pushConstantRanges = reinterpret_cast<VkPushConstantRange *>(bindingStorage);
Alexis Hetu8c1e8f12019-02-15 16:41:12 -050058 memcpy(pushConstantRanges, pCreateInfo->pPushConstantRanges, pushConstantRangesSize);
Trevor David Black3ad285a2020-05-26 19:28:05 +000059
60 incRefCount();
Alexis Hetu000df8b2018-10-24 15:22:41 -040061}
62
Ben Clayton2ed93ab2019-12-17 20:38:03 +000063void PipelineLayout::destroy(const VkAllocationCallbacks *pAllocator)
Alexis Hetu000df8b2018-10-24 15:22:41 -040064{
Nicolas Capens026f7d02020-04-23 23:44:57 -040065 vk::deallocate(descriptorSets[0].bindings, pAllocator); // pushConstantRanges are in the same allocation
Alexis Hetu000df8b2018-10-24 15:22:41 -040066}
67
Trevor David Black3ad285a2020-05-26 19:28:05 +000068bool PipelineLayout::release(const VkAllocationCallbacks *pAllocator)
69{
70 if(decRefCount() == 0)
71 {
72 vk::deallocate(descriptorSets[0].bindings, pAllocator); // pushConstantRanges are in the same allocation
73 return true;
74 }
75 return false;
76}
77
Ben Clayton2ed93ab2019-12-17 20:38:03 +000078size_t PipelineLayout::ComputeRequiredAllocationSize(const VkPipelineLayoutCreateInfo *pCreateInfo)
Alexis Hetu000df8b2018-10-24 15:22:41 -040079{
Nicolas Capens026f7d02020-04-23 23:44:57 -040080 uint32_t bindingsCount = 0;
81 for(uint32_t i = 0; i < pCreateInfo->setLayoutCount; i++)
82 {
83 bindingsCount += vk::Cast(pCreateInfo->pSetLayouts[i])->getBindingsArraySize();
84 }
85
86 return bindingsCount * sizeof(Binding) + // descriptorSets[]
87 pCreateInfo->pushConstantRangeCount * sizeof(VkPushConstantRange); // pushConstantRanges[]
Alexis Hetu000df8b2018-10-24 15:22:41 -040088}
89
Nicolas Capensc7d5ec32020-04-22 01:11:37 -040090size_t PipelineLayout::getDescriptorSetCount() const
Ben Clayton76e9bc02019-02-26 15:02:18 +000091{
Nicolas Capensc7d5ec32020-04-22 01:11:37 -040092 return descriptorSetCount;
93}
94
Alexis Hetu4f438a52020-06-15 16:13:51 -040095uint32_t PipelineLayout::getBindingCount(uint32_t setNumber) const
96{
97 return descriptorSets[setNumber].bindingCount;
98}
99
Nicolas Capensc7d5ec32020-04-22 01:11:37 -0400100uint32_t PipelineLayout::getDynamicOffsetIndex(uint32_t setNumber, uint32_t bindingNumber) const
101{
Nicolas Capens026f7d02020-04-23 23:44:57 -0400102 ASSERT(setNumber < descriptorSetCount && bindingNumber < descriptorSets[setNumber].bindingCount);
103 return descriptorSets[setNumber].bindings[bindingNumber].dynamicOffsetIndex;
Nicolas Capensc7d5ec32020-04-22 01:11:37 -0400104}
105
Nicolas Capenseb682442020-06-01 15:24:52 -0400106uint32_t PipelineLayout::getDescriptorCount(uint32_t setNumber, uint32_t bindingNumber) const
107{
108 ASSERT(setNumber < descriptorSetCount && bindingNumber < descriptorSets[setNumber].bindingCount);
109 return descriptorSets[setNumber].bindings[bindingNumber].descriptorCount;
110}
111
Nicolas Capensc7d5ec32020-04-22 01:11:37 -0400112uint32_t PipelineLayout::getBindingOffset(uint32_t setNumber, uint32_t bindingNumber) const
113{
Nicolas Capens026f7d02020-04-23 23:44:57 -0400114 ASSERT(setNumber < descriptorSetCount && bindingNumber < descriptorSets[setNumber].bindingCount);
115 return descriptorSets[setNumber].bindings[bindingNumber].offset;
Nicolas Capensc7d5ec32020-04-22 01:11:37 -0400116}
117
118VkDescriptorType PipelineLayout::getDescriptorType(uint32_t setNumber, uint32_t bindingNumber) const
119{
Nicolas Capens026f7d02020-04-23 23:44:57 -0400120 ASSERT(setNumber < descriptorSetCount && bindingNumber < descriptorSets[setNumber].bindingCount);
121 return descriptorSets[setNumber].bindings[bindingNumber].descriptorType;
Nicolas Capensc7d5ec32020-04-22 01:11:37 -0400122}
123
124uint32_t PipelineLayout::getDescriptorSize(uint32_t setNumber, uint32_t bindingNumber) const
125{
126 return DescriptorSetLayout::GetDescriptorSize(getDescriptorType(setNumber, bindingNumber));
127}
128
129bool PipelineLayout::isDescriptorDynamic(uint32_t setNumber, uint32_t bindingNumber) const
130{
131 return DescriptorSetLayout::IsDescriptorDynamic(getDescriptorType(setNumber, bindingNumber));
Ben Clayton76e9bc02019-02-26 15:02:18 +0000132}
133
Trevor David Black3ad285a2020-05-26 19:28:05 +0000134uint32_t PipelineLayout::incRefCount()
135{
136 return ++refCount;
137}
138
139uint32_t PipelineLayout::decRefCount()
140{
141 return --refCount;
142}
143
Nicolas Capens157ba262019-12-10 17:49:14 -0500144} // namespace vk