xref: /aosp_15_r20/external/deqp/external/vulkancts/framework/vulkan/vkApiVersion.cpp (revision 35238bce31c2a825756842865a792f8cf7f89930)
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 api version.
22  *//*--------------------------------------------------------------------*/
23 
24 #include "vkApiVersion.hpp"
25 #include <vector>
26 #include <set>
27 #include <algorithm>
28 
29 namespace vk
30 {
31 
unpackVersion(uint32_t version)32 ApiVersion unpackVersion(uint32_t version)
33 {
34     return ApiVersion(VK_API_VERSION_VARIANT(version), VK_API_VERSION_MAJOR(version), VK_API_VERSION_MINOR(version),
35                       VK_API_VERSION_PATCH(version));
36 }
37 
pack(const ApiVersion & version)38 uint32_t pack(const ApiVersion &version)
39 {
40     DE_ASSERT((version.variantNum & ~0x7) == 0);
41     DE_ASSERT((version.majorNum & ~0x7F) == 0);
42     DE_ASSERT((version.minorNum & ~0x3FF) == 0);
43     DE_ASSERT((version.patchNum & ~0xFFF) == 0);
44 
45     return (version.variantNum << 29) | (version.majorNum << 22) | (version.minorNum << 12) | version.patchNum;
46 }
47 
apiVersionClearPatch(uint32_t version)48 uint32_t apiVersionClearPatch(uint32_t version)
49 {
50     return version & ~0xFFF;
51 }
52 
53 // Direct acyclic graph of Vulkan API versions and its predecessors.
54 // At the moment it's linear ( 0.1.0.0 < 0.1.1.0 < 0.1.2.0 < 1.1.0.0 ).
55 // But with the introduction of Vulkan 1.3 it won't be, because Vulkan 1.2 will have 2 successors orthogonal to each other.
56 // Moreover - when in the future new Vulkan SC 1.1 version will be created - it's possible that
57 // it will have 2 predecessors : Vulkan SC 1.0 and Vulkan 1.3 ( or later version - it's just example )
58 // When it happens : two new predecessors will look like this:
59 //    { VK_MAKE_API_VERSION(1, 1, 1, 0), VK_MAKE_API_VERSION(1, 1, 0, 0) },
60 //    { VK_MAKE_API_VERSION(1, 1, 1, 0), VK_MAKE_API_VERSION(0, 1, 3, 0) },
61 
62 const static std::vector<std::pair<uint32_t, uint32_t>> apiVersionPredecessors = {
63     {VK_MAKE_API_VERSION(0, 1, 0, 0), 0},
64     {VK_MAKE_API_VERSION(0, 1, 1, 0), VK_MAKE_API_VERSION(0, 1, 0, 0)},
65     {VK_MAKE_API_VERSION(0, 1, 2, 0), VK_MAKE_API_VERSION(0, 1, 1, 0)},
66     {VK_MAKE_API_VERSION(1, 1, 0, 0), VK_MAKE_API_VERSION(0, 1, 2, 0)},
67     {VK_MAKE_API_VERSION(0, 1, 3, 0), VK_MAKE_API_VERSION(0, 1, 2, 0)},
68     {VK_MAKE_API_VERSION(0, 1, 4, 0), VK_MAKE_API_VERSION(0, 1, 3, 0)},
69 };
70 
isApiVersionEqual(uint32_t lhs,uint32_t rhs)71 bool isApiVersionEqual(uint32_t lhs, uint32_t rhs)
72 {
73     uint32_t lhsp = apiVersionClearPatch(lhs);
74     uint32_t rhsp = apiVersionClearPatch(rhs);
75     return lhsp == rhsp;
76 }
77 
isApiVersionPredecessor(uint32_t version,uint32_t predVersion)78 bool isApiVersionPredecessor(uint32_t version, uint32_t predVersion)
79 {
80     std::vector<uint32_t> versions;
81     versions.push_back(apiVersionClearPatch(version));
82 
83     uint32_t p = apiVersionClearPatch(predVersion);
84 
85     while (!versions.empty())
86     {
87         uint32_t v = versions.back();
88         versions.pop_back();
89 
90         for (auto it = begin(apiVersionPredecessors); it != end(apiVersionPredecessors); ++it)
91         {
92             if (it->first != v)
93                 continue;
94             if (it->second == p)
95                 return true;
96             versions.push_back(it->second);
97         }
98     }
99     return false;
100 }
101 
isApiVersionSupported(uint32_t yourVersion,uint32_t versionInQuestion)102 bool isApiVersionSupported(uint32_t yourVersion, uint32_t versionInQuestion)
103 {
104     if (isApiVersionEqual(yourVersion, versionInQuestion))
105         return true;
106     return isApiVersionPredecessor(yourVersion, versionInQuestion);
107 }
108 
minVulkanAPIVersion(uint32_t lhs,uint32_t rhs)109 uint32_t minVulkanAPIVersion(uint32_t lhs, uint32_t rhs)
110 {
111     uint32_t lhsp = apiVersionClearPatch(lhs);
112     uint32_t rhsp = apiVersionClearPatch(rhs);
113     if (lhsp == rhsp)
114         return de::min(lhs, rhs);
115     if (isApiVersionPredecessor(rhs, lhs))
116         return lhs;
117     if (isApiVersionPredecessor(lhs, rhs))
118         return rhs;
119     // both versions are located in different DAG paths - we will return common predecessor
120     static std::vector<uint32_t> commonPredecessors;
121     if (commonPredecessors.empty())
122     {
123         std::set<uint32_t> pred;
124         for (auto it = begin(apiVersionPredecessors); it != end(apiVersionPredecessors); ++it)
125         {
126             if (pred.find(it->second) != end(pred))
127                 commonPredecessors.push_back(it->second);
128             pred.insert(it->second);
129         }
130         std::sort(begin(commonPredecessors), end(commonPredecessors),
131                   [](uint32_t xlhs, uint32_t xrhs) { return isApiVersionPredecessor(xrhs, xlhs); });
132     }
133     for (auto it = begin(commonPredecessors); it != end(commonPredecessors); ++it)
134         if (isApiVersionPredecessor(rhs, *it) && isApiVersionPredecessor(lhs, *it))
135             return *it;
136 
137 #ifndef CTS_USES_VULKANSC
138     // If we got to this point, it means we are dealing with an unknown version.
139     // We assume it to be valid, and we default to VK_API_MAX_FRAMEWORK_VERSION which is generated from the spec.
140     return VK_API_MAX_FRAMEWORK_VERSION;
141 #else
142     return VKSC_API_MAX_FRAMEWORK_VERSION;
143 #endif
144 }
145 
146 } // namespace vk
147