1 // Copyright 2020 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 "VkPipelineCache.hpp"
16 #include <cstring>
17
18 namespace vk {
19
SpecializationInfo(const VkSpecializationInfo * specializationInfo)20 SpecializationInfo::SpecializationInfo(const VkSpecializationInfo *specializationInfo)
21 {
22 if(specializationInfo)
23 {
24 auto ptr = reinterpret_cast<VkSpecializationInfo *>(
25 allocate(sizeof(VkSpecializationInfo), REQUIRED_MEMORY_ALIGNMENT, DEVICE_MEMORY));
26
27 info = std::shared_ptr<VkSpecializationInfo>(ptr, Deleter());
28
29 info->mapEntryCount = specializationInfo->mapEntryCount;
30 if(specializationInfo->mapEntryCount > 0)
31 {
32 size_t entriesSize = specializationInfo->mapEntryCount * sizeof(VkSpecializationMapEntry);
33 VkSpecializationMapEntry *mapEntries = reinterpret_cast<VkSpecializationMapEntry *>(
34 allocate(entriesSize, REQUIRED_MEMORY_ALIGNMENT, DEVICE_MEMORY));
35 memcpy(mapEntries, specializationInfo->pMapEntries, entriesSize);
36 info->pMapEntries = mapEntries;
37 }
38
39 info->dataSize = specializationInfo->dataSize;
40 if(specializationInfo->dataSize > 0)
41 {
42 void *data = allocate(specializationInfo->dataSize, REQUIRED_MEMORY_ALIGNMENT, DEVICE_MEMORY);
43 memcpy(data, specializationInfo->pData, specializationInfo->dataSize);
44 info->pData = data;
45 }
46 else
47 {
48 info->pData = nullptr;
49 }
50 }
51 }
52
operator ()(VkSpecializationInfo * info) const53 void SpecializationInfo::Deleter::operator()(VkSpecializationInfo *info) const
54 {
55 if(info)
56 {
57 deallocate(const_cast<VkSpecializationMapEntry *>(info->pMapEntries), DEVICE_MEMORY);
58 deallocate(const_cast<void *>(info->pData), DEVICE_MEMORY);
59 deallocate(info, DEVICE_MEMORY);
60 }
61 }
62
operator <(const SpecializationInfo & specializationInfo) const63 bool SpecializationInfo::operator<(const SpecializationInfo &specializationInfo) const
64 {
65 // Check that either both or neither keys have specialization info.
66 if((info.get() == nullptr) != (specializationInfo.info.get() == nullptr))
67 {
68 return info.get() == nullptr;
69 }
70
71 if(!info)
72 {
73 ASSERT(!specializationInfo.info);
74 return false;
75 }
76
77 if(info->mapEntryCount != specializationInfo.info->mapEntryCount)
78 {
79 return info->mapEntryCount < specializationInfo.info->mapEntryCount;
80 }
81
82 if(info->dataSize != specializationInfo.info->dataSize)
83 {
84 return info->dataSize < specializationInfo.info->dataSize;
85 }
86
87 if(info->mapEntryCount > 0)
88 {
89 int cmp = memcmp(info->pMapEntries, specializationInfo.info->pMapEntries, info->mapEntryCount * sizeof(VkSpecializationMapEntry));
90 if(cmp != 0)
91 {
92 return cmp < 0;
93 }
94 }
95
96 if(info->dataSize > 0)
97 {
98 int cmp = memcmp(info->pData, specializationInfo.info->pData, info->dataSize);
99 if(cmp != 0)
100 {
101 return cmp < 0;
102 }
103 }
104
105 return false;
106 }
107
108 } // namespace vk
109