xref: /aosp_15_r20/external/deqp/external/vulkancts/framework/vulkan/vkDeviceProperties.cpp (revision 35238bce31c2a825756842865a792f8cf7f89930)
1 /*-------------------------------------------------------------------------
2  * Vulkan CTS
3  * ----------
4  *
5  * Copyright (c) 2019 The Khronos Group 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 #include "deSTLUtil.hpp"
21 #include "deString.h"
22 #include "vkQueryUtil.hpp"
23 #include "vkDeviceProperties.inl"
24 #include "vkDeviceProperties.hpp"
25 
26 namespace vk
27 {
28 
DeviceProperties(const InstanceInterface & vki,const uint32_t apiVersion,const VkPhysicalDevice physicalDevice,const std::vector<std::string> & instanceExtensions,const std::vector<std::string> & deviceExtensions)29 DeviceProperties::DeviceProperties(const InstanceInterface &vki, const uint32_t apiVersion,
30                                    const VkPhysicalDevice physicalDevice,
31                                    const std::vector<std::string> &instanceExtensions,
32                                    const std::vector<std::string> &deviceExtensions)
33 {
34     m_coreProperties2    = initVulkanStructure();
35     m_vulkan11Properties = initVulkanStructure();
36     m_vulkan12Properties = initVulkanStructure();
37 #ifndef CTS_USES_VULKANSC
38     m_vulkan13Properties = initVulkanStructure();
39 #endif // CTS_USES_VULKANSC
40 #ifdef CTS_USES_VULKANSC
41     m_vulkanSC10Properties = initVulkanStructure();
42 #endif // CTS_USES_VULKANSC
43 
44     if (isInstanceExtensionSupported(apiVersion, instanceExtensions, "VK_KHR_get_physical_device_properties2"))
45     {
46         const std::vector<VkExtensionProperties> deviceExtensionProperties =
47             enumerateDeviceExtensionProperties(vki, physicalDevice, DE_NULL);
48         void **nextPtr = &m_coreProperties2.pNext;
49         std::vector<PropertyStructWrapperBase *> propertiesToFillFromBlob;
50         std::vector<PropertyStructWrapperBase *> propertiesAddedWithVK;
51         bool vk11Supported = (apiVersion >= VK_MAKE_API_VERSION(0, 1, 1, 0));
52         bool vk12Supported = (apiVersion >= VK_MAKE_API_VERSION(0, 1, 2, 0));
53 #ifndef CTS_USES_VULKANSC
54         bool vk13Supported = (apiVersion >= VK_MAKE_API_VERSION(0, 1, 3, 0));
55 #endif // CTS_USES_VULKANSC
56 #ifdef CTS_USES_VULKANSC
57         bool vksc10Supported = (apiVersion >= VK_MAKE_API_VERSION(1, 1, 0, 0));
58 #endif // CTS_USES_VULKANSC
59 
60         // there are 3 properies structures that were added with vk11 (without being first part of extension)
61         if (vk11Supported)
62         {
63             propertiesAddedWithVK = {createPropertyStructWrapper<VkPhysicalDeviceSubgroupProperties>(),
64                                      createPropertyStructWrapper<VkPhysicalDeviceIDProperties>(),
65                                      createPropertyStructWrapper<VkPhysicalDeviceProtectedMemoryProperties>()};
66 
67             for (auto pAddedWithVK : propertiesAddedWithVK)
68             {
69                 m_properties.push_back(pAddedWithVK);
70 
71                 if (!vk12Supported)
72                     addToChainStructWrapper(&nextPtr, pAddedWithVK);
73             }
74         }
75 
76         // since vk12 we have blob structures combining properties of couple previously
77         // available property structures, that now in vk12 and above must be removed from chain
78         if (vk12Supported)
79         {
80             addToChainVulkanStructure(&nextPtr, m_vulkan11Properties);
81             addToChainVulkanStructure(&nextPtr, m_vulkan12Properties);
82 
83 #ifndef CTS_USES_VULKANSC
84             if (vk13Supported)
85                 addToChainVulkanStructure(&nextPtr, m_vulkan13Properties);
86 #endif // CTS_USES_VULKANSC
87         }
88 
89         std::vector<std::string> allDeviceExtensions = deviceExtensions;
90 #ifdef CTS_USES_VULKANSC
91         // VulkanSC: add missing core extensions to the list
92         std::vector<const char *> coreExtensions;
93         getCoreDeviceExtensions(apiVersion, coreExtensions);
94         for (const auto &coreExt : coreExtensions)
95             if (!de::contains(allDeviceExtensions.begin(), allDeviceExtensions.end(), std::string(coreExt)))
96                 allDeviceExtensions.push_back(coreExt);
97         if (vksc10Supported)
98             addToChainVulkanStructure(&nextPtr, m_vulkanSC10Properties);
99 #endif // CTS_USES_VULKANSC
100 
101         // iterate over data for all property that are defined in specification
102         for (const auto &propertyStructCreationData : propertyStructCreationArray)
103         {
104             const char *propertyName = propertyStructCreationData.name;
105 
106             // check if this property is available on current device.
107             if (de::contains(allDeviceExtensions.begin(), allDeviceExtensions.end(), propertyName) ||
108                 std::string(propertyName) == "core_property")
109             {
110                 PropertyStructWrapperBase *p = (*propertyStructCreationData.creatorFunction)();
111                 if (p == DE_NULL)
112                     continue;
113 
114 #ifdef CTS_USES_VULKANSC
115                 // m_vulkanSC10Properties was already added above
116                 if (p->getPropertyDesc().sType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_SC_1_0_PROPERTIES)
117                     continue;
118 #endif // CTS_USES_VULKANSC
119 
120                 // if property struct is part of VkPhysicalDeviceVulkan1{1,2}Properties
121                 // we dont add it to the chain but store and fill later from blob data
122                 bool propertyFilledFromBlob = false;
123                 if (vk12Supported)
124                 {
125                     uint32_t blobApiVersion = getBlobPropertiesVersion(p->getPropertyDesc().sType);
126                     if (blobApiVersion)
127                         propertyFilledFromBlob = (apiVersion >= blobApiVersion);
128                 }
129 
130                 if (propertyFilledFromBlob)
131                     propertiesToFillFromBlob.push_back(p);
132                 else
133                 {
134                     // add to chain
135                     addToChainStructWrapper(&nextPtr, p);
136                 }
137                 m_properties.push_back(p);
138             }
139         }
140 
141         vki.getPhysicalDeviceProperties2(physicalDevice, &m_coreProperties2);
142 
143         // fill data from VkPhysicalDeviceVulkan1{1,2,3}Properties
144         if (vk12Supported)
145         {
146             AllPropertiesBlobs allBlobs = {
147                 m_vulkan11Properties, m_vulkan12Properties,
148 #ifndef CTS_USES_VULKANSC
149                 m_vulkan13Properties,
150 #endif // CTS_USES_VULKANSC
151                 // add blobs from future vulkan versions here
152             };
153 
154             // three properties that were added with vk11 in vk12 were merged to VkPhysicalDeviceVulkan11Properties
155             propertiesToFillFromBlob.insert(propertiesToFillFromBlob.end(), propertiesAddedWithVK.begin(),
156                                             propertiesAddedWithVK.end());
157 
158             for (auto property : propertiesToFillFromBlob)
159                 property->initializePropertyFromBlob(allBlobs);
160         }
161     }
162     else
163         m_coreProperties2.properties = getPhysicalDeviceProperties(vki, physicalDevice);
164 }
165 
addToChainStructWrapper(void *** chainPNextPtr,PropertyStructWrapperBase * structWrapper)166 void DeviceProperties::addToChainStructWrapper(void ***chainPNextPtr, PropertyStructWrapperBase *structWrapper)
167 {
168     DE_ASSERT(chainPNextPtr != DE_NULL);
169 
170     (**chainPNextPtr) = structWrapper->getPropertyTypeRaw();
171     (*chainPNextPtr)  = structWrapper->getPropertyTypeNext();
172 }
173 
contains(const std::string & property,bool throwIfNotExists) const174 bool DeviceProperties::contains(const std::string &property, bool throwIfNotExists) const
175 {
176     for (const auto f : m_properties)
177     {
178         if (deStringEqual(f->getPropertyDesc().name, property.c_str()))
179             return true;
180     }
181 
182     if (throwIfNotExists)
183         TCU_THROW(NotSupportedError, "Property " + property + " is not supported");
184 
185     return false;
186 }
187 
isDevicePropertyInitialized(VkStructureType sType) const188 bool DeviceProperties::isDevicePropertyInitialized(VkStructureType sType) const
189 {
190     for (const auto f : m_properties)
191     {
192         if (f->getPropertyDesc().sType == sType)
193             return true;
194     }
195     return false;
196 }
197 
~DeviceProperties(void)198 DeviceProperties::~DeviceProperties(void)
199 {
200     for (auto p : m_properties)
201         delete p;
202 
203     m_properties.clear();
204 }
205 
206 } // namespace vk
207