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 std::string(propertyName) == "core_property")
112 {
113 PropertyStructWrapperBase* p = (*propertyStructCreationData.creatorFunction)();
114 if (p == DE_NULL)
115 continue;
116
117 #ifdef CTS_USES_VULKANSC
118 // m_vulkanSC10Properties was already added above
119 if (p->getPropertyDesc().sType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_SC_1_0_PROPERTIES)
120 continue;
121 #endif // CTS_USES_VULKANSC
122
123 // if property struct is part of VkPhysicalDeviceVulkan1{1,2}Properties
124 // we dont add it to the chain but store and fill later from blob data
125 bool propertyFilledFromBlob = false;
126 if (vk12Supported)
127 {
128 deUint32 blobApiVersion = getBlobPropertiesVersion(p->getPropertyDesc().sType);
129 if (blobApiVersion)
130 propertyFilledFromBlob = (apiVersion >= blobApiVersion);
131 }
132
133 if (propertyFilledFromBlob)
134 propertiesToFillFromBlob.push_back(p);
135 else
136 {
137 // add to chain
138 addToChainStructWrapper(&nextPtr, p);
139 }
140 m_properties.push_back(p);
141 }
142 }
143
144 vki.getPhysicalDeviceProperties2(physicalDevice, &m_coreProperties2);
145
146 // fill data from VkPhysicalDeviceVulkan1{1,2,3}Properties
147 if (vk12Supported)
148 {
149 AllPropertiesBlobs allBlobs =
150 {
151 m_vulkan11Properties,
152 m_vulkan12Properties,
153 #ifndef CTS_USES_VULKANSC
154 m_vulkan13Properties,
155 #endif // CTS_USES_VULKANSC
156 // add blobs from future vulkan versions here
157 };
158
159 // three properties that were added with vk11 in vk12 were merged to VkPhysicalDeviceVulkan11Properties
160 propertiesToFillFromBlob.insert(propertiesToFillFromBlob.end(), propertiesAddedWithVK.begin(), propertiesAddedWithVK.end());
161
162 for (auto property : propertiesToFillFromBlob)
163 property->initializePropertyFromBlob(allBlobs);
164 }
165 }
166 else
167 m_coreProperties2.properties = getPhysicalDeviceProperties(vki, physicalDevice);
168 }
169
addToChainStructWrapper(void *** chainPNextPtr,PropertyStructWrapperBase * structWrapper)170 void DeviceProperties::addToChainStructWrapper(void*** chainPNextPtr, PropertyStructWrapperBase* structWrapper)
171 {
172 DE_ASSERT(chainPNextPtr != DE_NULL);
173
174 (**chainPNextPtr) = structWrapper->getPropertyTypeRaw();
175 (*chainPNextPtr) = structWrapper->getPropertyTypeNext();
176 }
177
contains(const std::string & property,bool throwIfNotExists) const178 bool DeviceProperties::contains (const std::string& property, bool throwIfNotExists) const
179 {
180 for (const auto f : m_properties)
181 {
182 if (deStringEqual(f->getPropertyDesc().name, property.c_str()))
183 return true;
184 }
185
186 if (throwIfNotExists)
187 TCU_THROW(NotSupportedError, "Property " + property + " is not supported");
188
189 return false;
190 }
191
isDevicePropertyInitialized(VkStructureType sType) const192 bool DeviceProperties::isDevicePropertyInitialized (VkStructureType sType) const
193 {
194 for (const auto f : m_properties)
195 {
196 if (f->getPropertyDesc().sType == sType)
197 return true;
198 }
199 return false;
200 }
201
~DeviceProperties(void)202 DeviceProperties::~DeviceProperties (void)
203 {
204 for (auto p : m_properties)
205 delete p;
206
207 m_properties.clear();
208 }
209
210 } // vk
211
212