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