1 #ifndef _VKDEVICEPROPERTIES_HPP
2 #define _VKDEVICEPROPERTIES_HPP
3 /*-------------------------------------------------------------------------
4 * Vulkan CTS Framework
5 * --------------------
6 *
7 * Copyright (c) 2019 The Khronos Group Inc.
8 *
9 * Licensed under the Apache License, Version 2.0 (the "License");
10 * you may not use this file except in compliance with the License.
11 * You may obtain a copy of the License at
12 *
13 * http://www.apache.org/licenses/LICENSE-2.0
14 *
15 * Unless required by applicable law or agreed to in writing, software
16 * distributed under the License is distributed on an "AS IS" BASIS,
17 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18 * See the License for the specific language governing permissions and
19 * limitations under the License.
20 *
21 *//*!
22 * \file
23 * \brief Vulkan DeviceProperties class utility.
24 *//*--------------------------------------------------------------------*/
25
26 #include <map>
27 #include <string>
28 #include <utility>
29 #include <vector>
30
31 #include "deMemory.h"
32 #include "vkDefs.hpp"
33
34 namespace vk
35 {
36
37 // Structure describing vulkan property structure
38 struct PropertyDesc
39 {
40 VkStructureType sType;
41 const char *name;
42 const uint32_t specVersion;
43 const uint32_t typeId;
44 };
45
46 // Structure containg all property blobs - this simplifies generated code
47 struct AllPropertiesBlobs
48 {
49 VkPhysicalDeviceVulkan11Properties &vk11;
50 VkPhysicalDeviceVulkan12Properties &vk12;
51 #ifndef CTS_USES_VULKANSC
52 VkPhysicalDeviceVulkan13Properties &vk13;
53 #endif // CTS_USES_VULKANSC
54 // add blobs from future vulkan versions here
55 };
56
57 // Base class for all PropertyStructWrapper specialization
58 struct PropertyStructWrapperBase
59 {
~PropertyStructWrapperBasevk::PropertyStructWrapperBase60 virtual ~PropertyStructWrapperBase(void)
61 {
62 }
63 virtual void initializePropertyFromBlob(const AllPropertiesBlobs &allPropertiesBlobs) = 0;
64 virtual uint32_t getPropertyTypeId(void) const = 0;
65 virtual PropertyDesc getPropertyDesc(void) const = 0;
66 virtual void **getPropertyTypeNext(void) = 0;
67 virtual void *getPropertyTypeRaw(void) = 0;
68 };
69
70 using PropertyStructWrapperCreator = PropertyStructWrapperBase *(*)(void);
71 struct PropertyStructCreationData
72 {
73 PropertyStructWrapperCreator creatorFunction;
74 const char *name;
75 uint32_t specVersion;
76 };
77
78 template <class PropertyType>
79 class PropertyStructWrapper;
80 template <class PropertyType>
81 PropertyDesc makePropertyDesc(void);
82
83 template <class PropertyType>
createPropertyStructWrapper(void)84 PropertyStructWrapperBase *createPropertyStructWrapper(void)
85 {
86 return new PropertyStructWrapper<PropertyType>(makePropertyDesc<PropertyType>());
87 }
88
89 template <class PropertyType>
90 void initPropertyFromBlob(PropertyType &propertyType, const AllPropertiesBlobs &allPropertiesBlobs);
91
92 template <class PropertyType>
initPropertyFromBlobWrapper(PropertyType & propertyType,const AllPropertiesBlobs & allPropertiesBlobs)93 void initPropertyFromBlobWrapper(PropertyType &propertyType, const AllPropertiesBlobs &allPropertiesBlobs)
94 {
95 initPropertyFromBlob<PropertyType>(propertyType, allPropertiesBlobs);
96 }
97
98 class DeviceProperties
99 {
100 public:
101 DeviceProperties(const InstanceInterface &vki, const uint32_t apiVersion, const VkPhysicalDevice physicalDevice,
102 const std::vector<std::string> &instanceExtensions,
103 const std::vector<std::string> &deviceExtensions);
104
105 ~DeviceProperties(void);
106
107 template <class PropertyType>
108 const PropertyType &getPropertyType(void) const;
109
getCoreProperties2(void) const110 const VkPhysicalDeviceProperties2 &getCoreProperties2(void) const
111 {
112 return m_coreProperties2;
113 }
getVulkan11Properties(void) const114 const VkPhysicalDeviceVulkan11Properties &getVulkan11Properties(void) const
115 {
116 return m_vulkan11Properties;
117 }
getVulkan12Properties(void) const118 const VkPhysicalDeviceVulkan12Properties &getVulkan12Properties(void) const
119 {
120 return m_vulkan12Properties;
121 }
122 #ifndef CTS_USES_VULKANSC
getVulkan13Properties(void) const123 const VkPhysicalDeviceVulkan13Properties &getVulkan13Properties(void) const
124 {
125 return m_vulkan13Properties;
126 }
127 #endif // CTS_USES_VULKANSC
128 #ifdef CTS_USES_VULKANSC
getVulkanSC10Properties(void) const129 const VkPhysicalDeviceVulkanSC10Properties &getVulkanSC10Properties(void) const
130 {
131 return m_vulkanSC10Properties;
132 }
133 #endif // CTS_USES_VULKANSC
134
135 bool contains(const std::string &property, bool throwIfNotExists = false) const;
136
137 bool isDevicePropertyInitialized(VkStructureType sType) const;
138
139 private:
140 static void addToChainStructWrapper(void ***chainPNextPtr, PropertyStructWrapperBase *structWrapper);
141
142 private:
143 VkPhysicalDeviceProperties2 m_coreProperties2;
144 mutable std::vector<PropertyStructWrapperBase *> m_properties;
145 VkPhysicalDeviceVulkan11Properties m_vulkan11Properties;
146 VkPhysicalDeviceVulkan12Properties m_vulkan12Properties;
147 #ifndef CTS_USES_VULKANSC
148 VkPhysicalDeviceVulkan13Properties m_vulkan13Properties;
149 #endif // CTS_USES_VULKANSC
150 #ifdef CTS_USES_VULKANSC
151 VkPhysicalDeviceVulkanSC10Properties m_vulkanSC10Properties;
152 #endif // CTS_USES_VULKANSC
153 };
154
155 template <class PropertyType>
getPropertyType(void) const156 const PropertyType &DeviceProperties::getPropertyType(void) const
157 {
158 typedef PropertyStructWrapper<PropertyType> *PropertyWrapperPtr;
159
160 const PropertyDesc propDesc = makePropertyDesc<PropertyType>();
161 const VkStructureType sType = propDesc.sType;
162
163 // try to find property by sType
164 for (auto property : m_properties)
165 {
166 if (sType == property->getPropertyDesc().sType)
167 return static_cast<PropertyWrapperPtr>(property)->getPropertyTypeRef();
168 }
169
170 // try to find property by id that was assigned by gen_framework script
171 const uint32_t propertyId = propDesc.typeId;
172 for (auto property : m_properties)
173 {
174 if (propertyId == property->getPropertyTypeId())
175 return static_cast<PropertyWrapperPtr>(property)->getPropertyTypeRef();
176 }
177
178 // if initialized property structure was not found create empty one and return it
179 m_properties.push_back(vk::createPropertyStructWrapper<PropertyType>());
180 return static_cast<PropertyWrapperPtr>(m_properties.back())->getPropertyTypeRef();
181 }
182
183 template <class PropertyType>
184 class PropertyStructWrapper : public PropertyStructWrapperBase
185 {
186 public:
PropertyStructWrapper(const PropertyDesc & propertyDesc)187 PropertyStructWrapper(const PropertyDesc &propertyDesc) : m_propertyDesc(propertyDesc)
188 {
189 deMemset(&m_propertyType, 0, sizeof(m_propertyType));
190 m_propertyType.sType = propertyDesc.sType;
191 }
192
initializePropertyFromBlob(const AllPropertiesBlobs & allPropertiesBlobs)193 void initializePropertyFromBlob(const AllPropertiesBlobs &allPropertiesBlobs)
194 {
195 initPropertyFromBlobWrapper(m_propertyType, allPropertiesBlobs);
196 }
197
getPropertyTypeId(void) const198 uint32_t getPropertyTypeId(void) const
199 {
200 return m_propertyDesc.typeId;
201 }
getPropertyDesc(void) const202 PropertyDesc getPropertyDesc(void) const
203 {
204 return m_propertyDesc;
205 }
getPropertyTypeNext(void)206 void **getPropertyTypeNext(void)
207 {
208 return &m_propertyType.pNext;
209 }
getPropertyTypeRaw(void)210 void *getPropertyTypeRaw(void)
211 {
212 return &m_propertyType;
213 }
getPropertyTypeRef(void)214 PropertyType &getPropertyTypeRef(void)
215 {
216 return m_propertyType;
217 }
218
219 public:
220 // metadata about property structure
221 const PropertyDesc m_propertyDesc;
222
223 // actual vulkan property structure
224 PropertyType m_propertyType;
225 };
226 } // namespace vk
227
228 #endif // _VKDEVICEPROPERTIES_HPP
229