• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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     m_vulkan14Properties = initVulkanStructure();
40 #endif // CTS_USES_VULKANSC
41 #ifdef CTS_USES_VULKANSC
42     m_vulkanSC10Properties = initVulkanStructure();
43 #endif // CTS_USES_VULKANSC
44 
45     if (isInstanceExtensionSupported(apiVersion, instanceExtensions, "VK_KHR_get_physical_device_properties2"))
46     {
47         const std::vector<VkExtensionProperties> deviceExtensionProperties =
48             enumerateDeviceExtensionProperties(vki, physicalDevice, nullptr);
49         void **nextPtr = &m_coreProperties2.pNext;
50         std::vector<PropertyStructWrapperBase *> propertiesToFillFromBlob;
51         std::vector<PropertyStructWrapperBase *> propertiesAddedWithVK;
52         bool vk11Supported = (apiVersion >= VK_MAKE_API_VERSION(0, 1, 1, 0));
53         bool vk12Supported = (apiVersion >= VK_MAKE_API_VERSION(0, 1, 2, 0));
54 #ifndef CTS_USES_VULKANSC
55         bool vk13Supported = (apiVersion >= VK_MAKE_API_VERSION(0, 1, 3, 0));
56         bool vk14Supported = (apiVersion >= VK_MAKE_API_VERSION(0, 1, 4, 0));
57 #endif // CTS_USES_VULKANSC
58 #ifdef CTS_USES_VULKANSC
59         bool vksc10Supported = (apiVersion >= VK_MAKE_API_VERSION(1, 1, 0, 0));
60 #endif // CTS_USES_VULKANSC
61 
62         // there are 3 properies structures that were added with vk11 (without being first part of extension)
63         if (vk11Supported)
64         {
65             propertiesAddedWithVK = {createPropertyStructWrapper<VkPhysicalDeviceSubgroupProperties>(),
66                                      createPropertyStructWrapper<VkPhysicalDeviceIDProperties>(),
67                                      createPropertyStructWrapper<VkPhysicalDeviceProtectedMemoryProperties>()};
68 
69             for (auto pAddedWithVK : propertiesAddedWithVK)
70             {
71                 m_properties.push_back(pAddedWithVK);
72 
73                 if (!vk12Supported)
74                     addToChainStructWrapper(&nextPtr, pAddedWithVK);
75             }
76         }
77 
78         // since vk12 we have blob structures combining properties of couple previously
79         // available property structures, that now in vk12 and above must be removed from chain
80         if (vk12Supported)
81         {
82             addToChainVulkanStructure(&nextPtr, m_vulkan11Properties);
83             addToChainVulkanStructure(&nextPtr, m_vulkan12Properties);
84 
85 #ifndef CTS_USES_VULKANSC
86             if (vk13Supported)
87                 addToChainVulkanStructure(&nextPtr, m_vulkan13Properties);
88             if (vk14Supported)
89                 addToChainVulkanStructure(&nextPtr, m_vulkan14Properties);
90 #endif // CTS_USES_VULKANSC
91         }
92 
93         std::vector<std::string> allDeviceExtensions = deviceExtensions;
94 #ifdef CTS_USES_VULKANSC
95         // VulkanSC: add missing core extensions to the list
96         std::vector<const char *> coreExtensions;
97         getCoreDeviceExtensions(apiVersion, coreExtensions);
98         for (const auto &coreExt : coreExtensions)
99             if (!de::contains(allDeviceExtensions.begin(), allDeviceExtensions.end(), std::string(coreExt)))
100                 allDeviceExtensions.push_back(coreExt);
101         if (vksc10Supported)
102             addToChainVulkanStructure(&nextPtr, m_vulkanSC10Properties);
103 #endif // CTS_USES_VULKANSC
104 
105         // iterate over data for all property that are defined in specification
106         for (const auto &propertyStructCreationData : propertyStructCreationArray)
107         {
108             const char *propertyName = propertyStructCreationData.name;
109 
110             // check if this property is available on current device.
111             if (de::contains(allDeviceExtensions.begin(), allDeviceExtensions.end(), propertyName) ||
112                 std::string(propertyName) == "core_property")
113             {
114                 PropertyStructWrapperBase *p = (*propertyStructCreationData.creatorFunction)();
115                 if (p == nullptr)
116                     continue;
117 
118 #ifdef CTS_USES_VULKANSC
119                 // m_vulkanSC10Properties was already added above
120                 if (p->getPropertyDesc().sType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_SC_1_0_PROPERTIES)
121                     continue;
122 #endif // CTS_USES_VULKANSC
123 
124                 // if property struct is part of VkPhysicalDeviceVulkan1{1,2,3,4}Properties
125                 // we dont add it to the chain but store and fill later from blob data
126                 bool propertyFilledFromBlob = false;
127                 if (vk12Supported)
128                 {
129                     uint32_t blobApiVersion = getBlobPropertiesVersion(p->getPropertyDesc().sType);
130                     if (blobApiVersion)
131                         propertyFilledFromBlob = (apiVersion >= blobApiVersion);
132                 }
133 
134                 if (propertyFilledFromBlob)
135                     propertiesToFillFromBlob.push_back(p);
136                 else
137                 {
138                     // add to chain
139                     addToChainStructWrapper(&nextPtr, p);
140                 }
141                 m_properties.push_back(p);
142             }
143         }
144 
145 #ifndef CTS_USES_VULKANSC
146         // special handling for the copyDstLayoutCount/pCopyDstLayouts fields
147         // we need to query again to fill allocated arrays with layouts
148         if (vk14Supported)
149         {
150             VkPhysicalDeviceVulkan14Properties vulkan14Properties = initVulkanStructure();
151             VkPhysicalDeviceProperties2 coreProperties2           = initVulkanStructure();
152             coreProperties2.pNext                                 = &vulkan14Properties;
153             vki.getPhysicalDeviceProperties2(physicalDevice, &coreProperties2);
154 
155             m_vulkan14Properties.pCopySrcLayouts = m_vulkan14CopyLayouts.data();
156             m_vulkan14Properties.pCopyDstLayouts =
157                 m_vulkan14CopyLayouts.data() + m_vulkan14Properties.copySrcLayoutCount;
158         }
159 #endif // CTS_USES_VULKANSC
160 
161         vki.getPhysicalDeviceProperties2(physicalDevice, &m_coreProperties2);
162 
163         // fill data from VkPhysicalDeviceVulkan1{1,2,3,4}Properties
164         if (vk12Supported)
165         {
166             AllPropertiesBlobs allBlobs = {
167                 m_vulkan11Properties, m_vulkan12Properties,
168 #ifndef CTS_USES_VULKANSC
169                 m_vulkan13Properties, m_vulkan14Properties,
170 #endif // CTS_USES_VULKANSC
171                 // add blobs from future vulkan versions here
172             };
173 
174             // three properties that were added with vk11 in vk12 were merged to VkPhysicalDeviceVulkan11Properties
175             propertiesToFillFromBlob.insert(propertiesToFillFromBlob.end(), propertiesAddedWithVK.begin(),
176                                             propertiesAddedWithVK.end());
177 
178             for (auto property : propertiesToFillFromBlob)
179                 property->initializePropertyFromBlob(allBlobs);
180         }
181     }
182     else
183         m_coreProperties2.properties = getPhysicalDeviceProperties(vki, physicalDevice);
184 }
185 
addToChainStructWrapper(void *** chainPNextPtr,PropertyStructWrapperBase * structWrapper)186 void DeviceProperties::addToChainStructWrapper(void ***chainPNextPtr, PropertyStructWrapperBase *structWrapper)
187 {
188     DE_ASSERT(chainPNextPtr != nullptr);
189 
190     (**chainPNextPtr) = structWrapper->getPropertyTypeRaw();
191     (*chainPNextPtr)  = structWrapper->getPropertyTypeNext();
192 }
193 
contains(const std::string & property,bool throwIfNotExists) const194 bool DeviceProperties::contains(const std::string &property, bool throwIfNotExists) const
195 {
196     for (const auto f : m_properties)
197     {
198         if (strcmp(f->getPropertyDesc().name, property.c_str()) == 0)
199             return true;
200     }
201 
202     if (throwIfNotExists)
203         TCU_THROW(NotSupportedError, "Property " + property + " is not supported");
204 
205     return false;
206 }
207 
isDevicePropertyInitialized(VkStructureType sType) const208 bool DeviceProperties::isDevicePropertyInitialized(VkStructureType sType) const
209 {
210     for (const auto f : m_properties)
211     {
212         if (f->getPropertyDesc().sType == sType)
213             return true;
214     }
215     return false;
216 }
217 
~DeviceProperties(void)218 DeviceProperties::~DeviceProperties(void)
219 {
220     for (auto p : m_properties)
221         delete p;
222 
223     m_properties.clear();
224 }
225 
226 } // namespace vk
227