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 m_vulkan13Properties = initVulkanStructure();
39
40 if (isInstanceExtensionSupported(apiVersion, instanceExtensions, "VK_KHR_get_physical_device_properties2"))
41 {
42 const std::vector<VkExtensionProperties> deviceExtensionProperties = enumerateDeviceExtensionProperties(vki, physicalDevice, DE_NULL);
43 void** nextPtr = &m_coreProperties2.pNext;
44 std::vector<PropertyStructWrapperBase*> propertiesToFillFromBlob;
45 std::vector<PropertyStructWrapperBase*> propertiesAddedWithVK;
46 bool vk11Supported = (apiVersion >= VK_API_VERSION_1_1);
47 bool vk12Supported = (apiVersion >= VK_API_VERSION_1_2);
48 bool vk13Supported = (apiVersion >= VK_API_VERSION_1_3);
49
50 // there are 3 properies structures that were added with vk11 (without being first part of extension)
51 if (vk11Supported)
52 {
53 propertiesAddedWithVK =
54 {
55 createPropertyStructWrapper<VkPhysicalDeviceSubgroupProperties>(),
56 createPropertyStructWrapper<VkPhysicalDeviceIDProperties>(),
57 createPropertyStructWrapper<VkPhysicalDeviceProtectedMemoryProperties>()
58 };
59
60 for (auto pAddedWithVK : propertiesAddedWithVK)
61 {
62 m_properties.push_back(pAddedWithVK);
63
64 if (!vk12Supported)
65 addToChainStructWrapper(&nextPtr, pAddedWithVK);
66 }
67 }
68
69 // since vk12 we have blob structures combining properties of couple previously
70 // available property structures, that now in vk12 and above must be removed from chain
71 if (vk12Supported)
72 {
73 addToChainVulkanStructure(&nextPtr, m_vulkan11Properties);
74 addToChainVulkanStructure(&nextPtr, m_vulkan12Properties);
75
76 if (vk13Supported)
77 addToChainVulkanStructure(&nextPtr, m_vulkan13Properties);
78 }
79
80 // iterate over data for all property that are defined in specification
81 for (const auto& propertyStructCreationData : propertyStructCreationArray)
82 {
83 const char* propertyName = propertyStructCreationData.name;
84
85 // check if this property is available on current device
86 if (de::contains(deviceExtensions.begin(), deviceExtensions.end(), propertyName))
87 {
88 PropertyStructWrapperBase* p = (*propertyStructCreationData.creatorFunction)();
89 if (p == DE_NULL)
90 continue;
91
92 // if property struct is part of VkPhysicalDeviceVulkan1{1,2}Properties
93 // we dont add it to the chain but store and fill later from blob data
94 bool propertyFilledFromBlob = false;
95 if (vk12Supported)
96 {
97 deUint32 blobApiVersion = getBlobPropertiesVersion(p->getPropertyDesc().sType);
98 if (blobApiVersion)
99 propertyFilledFromBlob = (apiVersion >= blobApiVersion);
100 }
101
102 if (propertyFilledFromBlob)
103 propertiesToFillFromBlob.push_back(p);
104 else
105 {
106 // add to chain
107 addToChainStructWrapper(&nextPtr, p);
108 }
109 m_properties.push_back(p);
110 }
111 }
112
113 vki.getPhysicalDeviceProperties2(physicalDevice, &m_coreProperties2);
114
115 // fill data from VkPhysicalDeviceVulkan1{1,2,3}Properties
116 if (vk12Supported)
117 {
118 AllPropertiesBlobs allBlobs =
119 {
120 m_vulkan11Properties,
121 m_vulkan12Properties,
122 m_vulkan13Properties,
123 // add blobs from future vulkan versions here
124 };
125
126 // three properties that were added with vk11 in vk12 were merged to VkPhysicalDeviceVulkan11Properties
127 propertiesToFillFromBlob.insert(propertiesToFillFromBlob.end(), propertiesAddedWithVK.begin(), propertiesAddedWithVK.end());
128
129 for (auto property : propertiesToFillFromBlob)
130 property->initializePropertyFromBlob(allBlobs);
131 }
132 }
133 else
134 m_coreProperties2.properties = getPhysicalDeviceProperties(vki, physicalDevice);
135 }
136
addToChainStructWrapper(void *** chainPNextPtr,PropertyStructWrapperBase * structWrapper)137 void DeviceProperties::addToChainStructWrapper(void*** chainPNextPtr, PropertyStructWrapperBase* structWrapper)
138 {
139 DE_ASSERT(chainPNextPtr != DE_NULL);
140
141 (**chainPNextPtr) = structWrapper->getPropertyTypeRaw();
142 (*chainPNextPtr) = structWrapper->getPropertyTypeNext();
143 }
144
contains(const std::string & property,bool throwIfNotExists) const145 bool DeviceProperties::contains (const std::string& property, bool throwIfNotExists) const
146 {
147 for (const auto f : m_properties)
148 {
149 if (deStringEqual(f->getPropertyDesc().name, property.c_str()))
150 return true;
151 }
152
153 if (throwIfNotExists)
154 TCU_THROW(NotSupportedError, "Property " + property + " is not supported");
155
156 return false;
157 }
158
isDevicePropertyInitialized(VkStructureType sType) const159 bool DeviceProperties::isDevicePropertyInitialized (VkStructureType sType) const
160 {
161 for (const auto f : m_properties)
162 {
163 if (f->getPropertyDesc().sType == sType)
164 return true;
165 }
166 return false;
167 }
168
~DeviceProperties(void)169 DeviceProperties::~DeviceProperties (void)
170 {
171 for (auto p : m_properties)
172 delete p;
173
174 m_properties.clear();
175 }
176
177 } // vk
178
179