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 deUint32 apiVersion,const VkPhysicalDevice physicalDevice,const std::vector<std::string> & instanceExtensions,const std::vector<std::string> & deviceExtensions)29 DeviceProperties::DeviceProperties (const InstanceInterface& vki,
30 const deUint32 apiVersion,
31 const VkPhysicalDevice physicalDevice,
32 const std::vector<std::string>& instanceExtensions,
33 const std::vector<std::string>& deviceExtensions)
34 {
35 m_coreProperties2 = initVulkanStructure();
36 m_vulkan11Properties = initVulkanStructure();
37 m_vulkan12Properties = initVulkanStructure();
38 #ifndef CTS_USES_VULKANSC
39 m_vulkan13Properties = 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 = 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 =
64 {
65 createPropertyStructWrapper<VkPhysicalDeviceSubgroupProperties>(),
66 createPropertyStructWrapper<VkPhysicalDeviceIDProperties>(),
67 createPropertyStructWrapper<VkPhysicalDeviceProtectedMemoryProperties>()
68 };
69
70 for (auto pAddedWithVK : propertiesAddedWithVK)
71 {
72 m_properties.push_back(pAddedWithVK);
73
74 if (!vk12Supported)
75 addToChainStructWrapper(&nextPtr, pAddedWithVK);
76 }
77 }
78
79 // since vk12 we have blob structures combining properties of couple previously
80 // available property structures, that now in vk12 and above must be removed from chain
81 if (vk12Supported)
82 {
83 addToChainVulkanStructure(&nextPtr, m_vulkan11Properties);
84 addToChainVulkanStructure(&nextPtr, m_vulkan12Properties);
85
86 #ifndef CTS_USES_VULKANSC
87 if (vk13Supported)
88 addToChainVulkanStructure(&nextPtr, m_vulkan13Properties);
89 #endif // CTS_USES_VULKANSC
90 }
91
92 std::vector<std::string> allDeviceExtensions = deviceExtensions;
93 #ifdef CTS_USES_VULKANSC
94 // VulkanSC: add missing core extensions to the list
95 std::vector<const char*> coreExtensions;
96 getCoreDeviceExtensions(apiVersion, coreExtensions);
97 for (const auto& coreExt : coreExtensions)
98 if (!de::contains(allDeviceExtensions.begin(), allDeviceExtensions.end(), std::string(coreExt)))
99 allDeviceExtensions.push_back(coreExt);
100 if (vksc10Supported)
101 addToChainVulkanStructure(&nextPtr, m_vulkanSC10Properties);
102 #endif // CTS_USES_VULKANSC
103
104 // iterate over data for all property that are defined in specification
105 for (const auto& propertyStructCreationData : propertyStructCreationArray)
106 {
107 const char* propertyName = propertyStructCreationData.name;
108
109 // check if this property is available on current device.
110 if (de::contains(allDeviceExtensions.begin(), allDeviceExtensions.end(), propertyName))
111 {
112 PropertyStructWrapperBase* p = (*propertyStructCreationData.creatorFunction)();
113 if (p == DE_NULL)
114 continue;
115
116 // if property struct is part of VkPhysicalDeviceVulkan1{1,2}Properties
117 // we dont add it to the chain but store and fill later from blob data
118 bool propertyFilledFromBlob = false;
119 if (vk12Supported)
120 {
121 deUint32 blobApiVersion = getBlobPropertiesVersion(p->getPropertyDesc().sType);
122 if (blobApiVersion)
123 propertyFilledFromBlob = (apiVersion >= blobApiVersion);
124 }
125
126 if (propertyFilledFromBlob)
127 propertiesToFillFromBlob.push_back(p);
128 else
129 {
130 // add to chain
131 addToChainStructWrapper(&nextPtr, p);
132 }
133 m_properties.push_back(p);
134 }
135 }
136
137 vki.getPhysicalDeviceProperties2(physicalDevice, &m_coreProperties2);
138
139 // fill data from VkPhysicalDeviceVulkan1{1,2,3}Properties
140 if (vk12Supported)
141 {
142 AllPropertiesBlobs allBlobs =
143 {
144 m_vulkan11Properties,
145 m_vulkan12Properties,
146 #ifndef CTS_USES_VULKANSC
147 m_vulkan13Properties,
148 #endif // CTS_USES_VULKANSC
149 // add blobs from future vulkan versions here
150 };
151
152 // three properties that were added with vk11 in vk12 were merged to VkPhysicalDeviceVulkan11Properties
153 propertiesToFillFromBlob.insert(propertiesToFillFromBlob.end(), propertiesAddedWithVK.begin(), propertiesAddedWithVK.end());
154
155 for (auto property : propertiesToFillFromBlob)
156 property->initializePropertyFromBlob(allBlobs);
157 }
158 }
159 else
160 m_coreProperties2.properties = getPhysicalDeviceProperties(vki, physicalDevice);
161 }
162
addToChainStructWrapper(void *** chainPNextPtr,PropertyStructWrapperBase * structWrapper)163 void DeviceProperties::addToChainStructWrapper(void*** chainPNextPtr, PropertyStructWrapperBase* structWrapper)
164 {
165 DE_ASSERT(chainPNextPtr != DE_NULL);
166
167 (**chainPNextPtr) = structWrapper->getPropertyTypeRaw();
168 (*chainPNextPtr) = structWrapper->getPropertyTypeNext();
169 }
170
contains(const std::string & property,bool throwIfNotExists) const171 bool DeviceProperties::contains (const std::string& property, bool throwIfNotExists) const
172 {
173 for (const auto f : m_properties)
174 {
175 if (deStringEqual(f->getPropertyDesc().name, property.c_str()))
176 return true;
177 }
178
179 if (throwIfNotExists)
180 TCU_THROW(NotSupportedError, "Property " + property + " is not supported");
181
182 return false;
183 }
184
isDevicePropertyInitialized(VkStructureType sType) const185 bool DeviceProperties::isDevicePropertyInitialized (VkStructureType sType) const
186 {
187 for (const auto f : m_properties)
188 {
189 if (f->getPropertyDesc().sType == sType)
190 return true;
191 }
192 return false;
193 }
194
~DeviceProperties(void)195 DeviceProperties::~DeviceProperties (void)
196 {
197 for (auto p : m_properties)
198 delete p;
199
200 m_properties.clear();
201 }
202
203 } // vk
204
205