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 };
44
45 // Structure containg all property blobs - this simplifies generated code
46 struct AllPropertiesBlobs
47 {
48 VkPhysicalDeviceVulkan11Properties &vk11;
49 VkPhysicalDeviceVulkan12Properties &vk12;
50 #ifndef CTS_USES_VULKANSC
51 VkPhysicalDeviceVulkan13Properties &vk13;
52 VkPhysicalDeviceVulkan14Properties &vk14;
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 PropertyDesc getPropertyDesc(void) const = 0;
65 virtual void **getPropertyTypeNext(void) = 0;
66 virtual void *getPropertyTypeRaw(void) = 0;
67 };
68
69 using PropertyStructWrapperCreator = PropertyStructWrapperBase *(*)(void);
70 struct PropertyStructCreationData
71 {
72 PropertyStructWrapperCreator creatorFunction;
73 const char *name;
74 uint32_t specVersion;
75 };
76
77 template <class PropertyType>
78 class PropertyStructWrapper;
79 template <class PropertyType>
80 PropertyDesc makePropertyDesc(void);
81
82 template <class PropertyType>
createPropertyStructWrapper(void)83 PropertyStructWrapperBase *createPropertyStructWrapper(void)
84 {
85 return new PropertyStructWrapper<PropertyType>(makePropertyDesc<PropertyType>());
86 }
87
88 template <class PropertyType>
89 void initPropertyFromBlob(PropertyType &propertyType, const AllPropertiesBlobs &allPropertiesBlobs);
90
91 template <class PropertyType>
initPropertyFromBlobWrapper(PropertyType & propertyType,const AllPropertiesBlobs & allPropertiesBlobs)92 void initPropertyFromBlobWrapper(PropertyType &propertyType, const AllPropertiesBlobs &allPropertiesBlobs)
93 {
94 initPropertyFromBlob<PropertyType>(propertyType, allPropertiesBlobs);
95 }
96
97 class DeviceProperties
98 {
99 public:
100 DeviceProperties(const InstanceInterface &vki, const uint32_t apiVersion, const VkPhysicalDevice physicalDevice,
101 const std::vector<std::string> &instanceExtensions,
102 const std::vector<std::string> &deviceExtensions);
103
104 ~DeviceProperties(void);
105
106 template <class PropertyType>
107 const PropertyType &getPropertyType(void) const;
108
getCoreProperties2(void) const109 const VkPhysicalDeviceProperties2 &getCoreProperties2(void) const
110 {
111 return m_coreProperties2;
112 }
getVulkan11Properties(void) const113 const VkPhysicalDeviceVulkan11Properties &getVulkan11Properties(void) const
114 {
115 return m_vulkan11Properties;
116 }
getVulkan12Properties(void) const117 const VkPhysicalDeviceVulkan12Properties &getVulkan12Properties(void) const
118 {
119 return m_vulkan12Properties;
120 }
121 #ifndef CTS_USES_VULKANSC
getVulkan13Properties(void) const122 const VkPhysicalDeviceVulkan13Properties &getVulkan13Properties(void) const
123 {
124 return m_vulkan13Properties;
125 }
getVulkan14Properties(void) const126 const VkPhysicalDeviceVulkan14Properties &getVulkan14Properties(void) const
127 {
128 return m_vulkan14Properties;
129 }
130 #endif // CTS_USES_VULKANSC
131 #ifdef CTS_USES_VULKANSC
getVulkanSC10Properties(void) const132 const VkPhysicalDeviceVulkanSC10Properties &getVulkanSC10Properties(void) const
133 {
134 return m_vulkanSC10Properties;
135 }
136 #endif // CTS_USES_VULKANSC
137
138 bool contains(const std::string &property, bool throwIfNotExists = false) const;
139
140 bool isDevicePropertyInitialized(VkStructureType sType) const;
141
142 private:
143 static void addToChainStructWrapper(void ***chainPNextPtr, PropertyStructWrapperBase *structWrapper);
144
145 private:
146 VkPhysicalDeviceProperties2 m_coreProperties2;
147 mutable std::vector<PropertyStructWrapperBase *> m_properties;
148 VkPhysicalDeviceVulkan11Properties m_vulkan11Properties;
149 VkPhysicalDeviceVulkan12Properties m_vulkan12Properties;
150 #ifndef CTS_USES_VULKANSC
151 VkPhysicalDeviceVulkan13Properties m_vulkan13Properties;
152 VkPhysicalDeviceVulkan14Properties m_vulkan14Properties;
153
154 std::vector<VkImageLayout> m_vulkan14CopyLayouts;
155 #endif // CTS_USES_VULKANSC
156 #ifdef CTS_USES_VULKANSC
157 VkPhysicalDeviceVulkanSC10Properties m_vulkanSC10Properties;
158 #endif // CTS_USES_VULKANSC
159 };
160
161 template <class PropertyType>
getPropertyType(void) const162 const PropertyType &DeviceProperties::getPropertyType(void) const
163 {
164 typedef PropertyStructWrapper<PropertyType> *PropertyWrapperPtr;
165
166 const PropertyDesc propDesc = makePropertyDesc<PropertyType>();
167 const VkStructureType sType = propDesc.sType;
168
169 // try to find property by sType
170 for (auto property : m_properties)
171 {
172 if (sType == property->getPropertyDesc().sType)
173 return static_cast<PropertyWrapperPtr>(property)->getPropertyTypeRef();
174 }
175
176 // if initialized property structure was not found create empty one and return it
177 m_properties.push_back(vk::createPropertyStructWrapper<PropertyType>());
178 return static_cast<PropertyWrapperPtr>(m_properties.back())->getPropertyTypeRef();
179 }
180
181 template <class PropertyType>
182 class PropertyStructWrapper : public PropertyStructWrapperBase
183 {
184 public:
PropertyStructWrapper(const PropertyDesc & propertyDesc)185 PropertyStructWrapper(const PropertyDesc &propertyDesc) : m_propertyDesc(propertyDesc)
186 {
187 deMemset(&m_propertyType, 0, sizeof(m_propertyType));
188 m_propertyType.sType = propertyDesc.sType;
189 }
190
initializePropertyFromBlob(const AllPropertiesBlobs & allPropertiesBlobs)191 void initializePropertyFromBlob(const AllPropertiesBlobs &allPropertiesBlobs)
192 {
193 initPropertyFromBlobWrapper(m_propertyType, allPropertiesBlobs);
194 }
195
getPropertyDesc(void) const196 PropertyDesc getPropertyDesc(void) const
197 {
198 return m_propertyDesc;
199 }
getPropertyTypeNext(void)200 void **getPropertyTypeNext(void)
201 {
202 return &m_propertyType.pNext;
203 }
getPropertyTypeRaw(void)204 void *getPropertyTypeRaw(void)
205 {
206 return &m_propertyType;
207 }
getPropertyTypeRef(void)208 PropertyType &getPropertyTypeRef(void)
209 {
210 return m_propertyType;
211 }
212
213 public:
214 // metadata about property structure
215 const PropertyDesc m_propertyDesc;
216
217 // actual vulkan property structure
218 PropertyType m_propertyType;
219 };
220 } // namespace vk
221
222 #endif // _VKDEVICEPROPERTIES_HPP
223