xref: /aosp_15_r20/external/deqp/external/vulkancts/framework/vulkan/vkQueryUtil.hpp (revision 35238bce31c2a825756842865a792f8cf7f89930)
1 #ifndef _VKQUERYUTIL_HPP
2 #define _VKQUERYUTIL_HPP
3 /*-------------------------------------------------------------------------
4  * Vulkan CTS Framework
5  * --------------------
6  *
7  * Copyright (c) 2015 Google 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 query utilities.
24  *//*--------------------------------------------------------------------*/
25 
26 #include "vkDefs.hpp"
27 #include "tcuMaybe.hpp"
28 #include "deMemory.h"
29 
30 #include <vector>
31 #include <string>
32 
33 namespace vk
34 {
35 
36 // API version introspection
37 
38 void getCoreInstanceExtensions(uint32_t apiVersion, std::vector<const char *> &dst);
39 void getCoreDeviceExtensions(uint32_t apiVersion, std::vector<const char *> &dst);
40 bool isCoreInstanceExtension(const uint32_t apiVersion, const std::string &extension);
41 bool isCoreDeviceExtension(const uint32_t apiVersion, const std::string &extension);
42 
43 // API queries
44 
45 std::vector<VkPhysicalDevice> enumeratePhysicalDevices(const InstanceInterface &vk, VkInstance instance);
46 std::vector<VkPhysicalDeviceGroupProperties> enumeratePhysicalDeviceGroups(const InstanceInterface &vk,
47                                                                            VkInstance instance);
48 std::vector<VkQueueFamilyProperties> getPhysicalDeviceQueueFamilyProperties(const InstanceInterface &vk,
49                                                                             VkPhysicalDevice physicalDevice);
50 VkPhysicalDeviceFeatures getPhysicalDeviceFeatures(const InstanceInterface &vk, VkPhysicalDevice physicalDevice);
51 VkPhysicalDeviceFeatures2 getPhysicalDeviceFeatures2(const InstanceInterface &vk, VkPhysicalDevice physicalDevice);
52 VkPhysicalDeviceVulkan11Features getPhysicalDeviceVulkan11Features(const InstanceInterface &vk,
53                                                                    VkPhysicalDevice physicalDevice);
54 VkPhysicalDeviceVulkan12Features getPhysicalDeviceVulkan12Features(const InstanceInterface &vk,
55                                                                    VkPhysicalDevice physicalDevice);
56 VkPhysicalDeviceVulkan11Properties getPhysicalDeviceVulkan11Properties(const InstanceInterface &vk,
57                                                                        VkPhysicalDevice physicalDevice);
58 VkPhysicalDeviceVulkan12Properties getPhysicalDeviceVulkan12Properties(const InstanceInterface &vk,
59                                                                        VkPhysicalDevice physicalDevice);
60 VkPhysicalDeviceProperties getPhysicalDeviceProperties(const InstanceInterface &vk, VkPhysicalDevice physicalDevice);
61 VkPhysicalDeviceMemoryProperties getPhysicalDeviceMemoryProperties(const InstanceInterface &vk,
62                                                                    VkPhysicalDevice physicalDevice);
63 VkFormatProperties getPhysicalDeviceFormatProperties(const InstanceInterface &vk, VkPhysicalDevice physicalDevice,
64                                                      VkFormat format);
65 VkImageFormatProperties getPhysicalDeviceImageFormatProperties(const InstanceInterface &vk,
66                                                                VkPhysicalDevice physicalDevice, VkFormat format,
67                                                                VkImageType type, VkImageTiling tiling,
68                                                                VkImageUsageFlags usage, VkImageCreateFlags flags);
69 
70 #ifndef CTS_USES_VULKANSC
71 std::vector<VkSparseImageFormatProperties> getPhysicalDeviceSparseImageFormatProperties(
72     const InstanceInterface &vk, VkPhysicalDevice physicalDevice, VkFormat format, VkImageType type,
73     VkSampleCountFlagBits samples, VkImageUsageFlags usage, VkImageTiling tiling);
74 #endif // CTS_USES_VULKANSC
75 #ifdef CTS_USES_VULKANSC
76 VkPhysicalDeviceVulkanSC10Features getPhysicalDeviceVulkanSC10Features(const InstanceInterface &vk,
77                                                                        VkPhysicalDevice physicalDevice);
78 VkPhysicalDeviceVulkanSC10Properties getPhysicalDeviceVulkanSC10Properties(const InstanceInterface &vk,
79                                                                            VkPhysicalDevice physicalDevice);
80 #endif // CTS_USES_VULKANSC
81 VkMemoryRequirements getBufferMemoryRequirements(const DeviceInterface &vk, VkDevice device, VkBuffer buffer);
82 VkMemoryRequirements getImageMemoryRequirements(const DeviceInterface &vk, VkDevice device, VkImage image);
83 VkMemoryRequirements getImagePlaneMemoryRequirements(const DeviceInterface &vk, VkDevice device, VkImage image,
84                                                      VkImageAspectFlagBits planeAspect);
85 #ifndef CTS_USES_VULKANSC
86 std::vector<VkSparseImageMemoryRequirements> getImageSparseMemoryRequirements(const DeviceInterface &vk,
87                                                                               VkDevice device, VkImage image);
88 std::vector<vk::VkSparseImageMemoryRequirements> getDeviceImageSparseMemoryRequirements(
89     const DeviceInterface &vk, VkDevice device, const VkImageCreateInfo &imageCreateInfo,
90     VkImageAspectFlagBits planeAspect);
91 #endif // CTS_USES_VULKANSC
92 
93 std::vector<VkLayerProperties> enumerateInstanceLayerProperties(const PlatformInterface &vkp);
94 std::vector<VkExtensionProperties> enumerateInstanceExtensionProperties(const PlatformInterface &vkp,
95                                                                         const char *layerName);
96 std::vector<VkLayerProperties> enumerateDeviceLayerProperties(const InstanceInterface &vki,
97                                                               VkPhysicalDevice physicalDevice);
98 std::vector<VkExtensionProperties> enumerateDeviceExtensionProperties(const InstanceInterface &vki,
99                                                                       VkPhysicalDevice physicalDevice,
100                                                                       const char *layerName);
101 const std::vector<VkExtensionProperties> &enumerateCachedDeviceExtensionProperties(const InstanceInterface &vki,
102                                                                                    VkPhysicalDevice physicalDevice);
103 
104 VkQueue getDeviceQueue(const DeviceInterface &vkd, VkDevice device, uint32_t queueFamilyIndex, uint32_t queueIndex);
105 VkQueue getDeviceQueue2(const DeviceInterface &vkd, VkDevice device, const VkDeviceQueueInfo2 *queueInfo);
106 
107 // Feature / extension support
108 
109 bool isShaderStageSupported(const VkPhysicalDeviceFeatures &deviceFeatures, VkShaderStageFlagBits stage);
110 
111 struct RequiredExtension
112 {
113     std::string name;
114     tcu::Maybe<uint32_t> minVersion;
115     tcu::Maybe<uint32_t> maxVersion;
116 
RequiredExtensionvk::RequiredExtension117     explicit RequiredExtension(const std::string &name_, tcu::Maybe<uint32_t> minVersion_ = tcu::Nothing,
118                                tcu::Maybe<uint32_t> maxVersion_ = tcu::Nothing)
119         : name(name_)
120         , minVersion(minVersion_)
121         , maxVersion(maxVersion_)
122     {
123     }
124 };
125 
126 struct RequiredLayer
127 {
128     std::string name;
129     tcu::Maybe<uint32_t> minSpecVersion;
130     tcu::Maybe<uint32_t> maxSpecVersion;
131     tcu::Maybe<uint32_t> minImplVersion;
132     tcu::Maybe<uint32_t> maxImplVersion;
133 
RequiredLayervk::RequiredLayer134     explicit RequiredLayer(const std::string &name_, tcu::Maybe<uint32_t> minSpecVersion_ = tcu::Nothing,
135                            tcu::Maybe<uint32_t> maxSpecVersion_ = tcu::Nothing,
136                            tcu::Maybe<uint32_t> minImplVersion_ = tcu::Nothing,
137                            tcu::Maybe<uint32_t> maxImplVersion_ = tcu::Nothing)
138         : name(name_)
139         , minSpecVersion(minSpecVersion_)
140         , maxSpecVersion(maxSpecVersion_)
141         , minImplVersion(minImplVersion_)
142         , maxImplVersion(maxImplVersion_)
143     {
144     }
145 };
146 
147 bool isCompatible(const VkExtensionProperties &extensionProperties, const RequiredExtension &required);
148 bool isCompatible(const VkLayerProperties &layerProperties, const RequiredLayer &required);
149 
150 template <typename ExtensionIterator>
151 bool isExtensionStructSupported(ExtensionIterator begin, ExtensionIterator end, const RequiredExtension &required);
152 bool isExtensionStructSupported(const std::vector<VkExtensionProperties> &extensions,
153                                 const RequiredExtension &required);
154 
155 bool isInstanceExtensionSupported(const uint32_t instanceVersion, const std::vector<std::string> &extensions,
156                                   const std::string &required);
157 
158 template <typename LayerIterator>
159 bool isLayerSupported(LayerIterator begin, LayerIterator end, const RequiredLayer &required);
160 bool isLayerSupported(const std::vector<VkLayerProperties> &layers, const RequiredLayer &required);
161 
162 const void *findStructureInChain(const void *first, VkStructureType type);
163 void *findStructureInChain(void *first, VkStructureType type);
164 
165 template <typename StructType>
166 VkStructureType getStructureType(void);
167 
168 template <typename StructType>
findStructure(const void * first)169 const StructType *findStructure(const void *first)
170 {
171     return reinterpret_cast<const StructType *>(findStructureInChain(first, getStructureType<StructType>()));
172 }
173 
174 template <typename StructType>
findStructure(void * first)175 StructType *findStructure(void *first)
176 {
177     return reinterpret_cast<StructType *>(findStructureInChain(first, getStructureType<StructType>()));
178 }
179 
180 struct initVulkanStructure
181 {
initVulkanStructurevk::initVulkanStructure182     initVulkanStructure(void *pNext = DE_NULL) : m_next(pNext)
183     {
184     }
185 
186     template <class StructType>
operator StructTypevk::initVulkanStructure187     operator StructType()
188     {
189         StructType result;
190 
191         deMemset(&result, 0x00, sizeof(StructType));
192 
193         result.sType = getStructureType<StructType>();
194         result.pNext = m_next;
195 
196         return result;
197     }
198 
199 private:
200     void *m_next;
201 };
202 
203 template <class StructType>
addToChainVulkanStructure(void *** chainPNextPtr,StructType & structType)204 void addToChainVulkanStructure(void ***chainPNextPtr, StructType &structType)
205 {
206     DE_ASSERT(chainPNextPtr != DE_NULL);
207 
208     (**chainPNextPtr) = &structType;
209 
210     (*chainPNextPtr) = &structType.pNext;
211 }
212 
213 template <class StructType>
addToChainVulkanStructure(const void *** chainPNextPtr,StructType & structType)214 void addToChainVulkanStructure(const void ***chainPNextPtr, StructType &structType)
215 {
216     DE_ASSERT(chainPNextPtr != DE_NULL);
217 
218     (**chainPNextPtr) = &structType;
219 
220     (*chainPNextPtr) = &structType.pNext;
221 }
222 
223 struct initVulkanStructureConst
224 {
initVulkanStructureConstvk::initVulkanStructureConst225     initVulkanStructureConst(const void *pNext = DE_NULL) : m_next(pNext)
226     {
227     }
228 
229     template <class StructType>
operator const StructTypevk::initVulkanStructureConst230     operator const StructType()
231     {
232         StructType result;
233 
234         deMemset(&result, 0x00, sizeof(StructType));
235 
236         result.sType = getStructureType<StructType>();
237         result.pNext = const_cast<void *>(m_next);
238 
239         return result;
240     }
241 
242 private:
243     const void *m_next;
244 };
245 
246 struct getPhysicalDeviceExtensionProperties
247 {
getPhysicalDeviceExtensionPropertiesvk::getPhysicalDeviceExtensionProperties248     getPhysicalDeviceExtensionProperties(const InstanceInterface &vki, VkPhysicalDevice physicalDevice)
249         : m_vki(vki)
250         , m_physicalDevice(physicalDevice)
251     {
252     }
253 
254     template <class ExtensionProperties>
operator ExtensionPropertiesvk::getPhysicalDeviceExtensionProperties255     operator ExtensionProperties()
256     {
257         VkPhysicalDeviceProperties2 properties2;
258         ExtensionProperties extensionProperties;
259 
260         deMemset(&extensionProperties, 0x00, sizeof(ExtensionProperties));
261         extensionProperties.sType = getStructureType<ExtensionProperties>();
262 
263         deMemset(&properties2, 0x00, sizeof(properties2));
264         properties2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2;
265         properties2.pNext = &extensionProperties;
266 
267         m_vki.getPhysicalDeviceProperties2(m_physicalDevice, &properties2);
268 
269         return extensionProperties;
270     }
271 
operator VkPhysicalDeviceProperties2vk::getPhysicalDeviceExtensionProperties272     operator VkPhysicalDeviceProperties2()
273     {
274         VkPhysicalDeviceProperties2 properties2;
275 
276         deMemset(&properties2, 0x00, sizeof(properties2));
277         properties2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2;
278 
279         m_vki.getPhysicalDeviceProperties2(m_physicalDevice, &properties2);
280 
281         return properties2;
282     }
283 
284 private:
285     const InstanceInterface &m_vki;
286     const VkPhysicalDevice m_physicalDevice;
287 };
288 
289 // Walks through chain to find empty pNext and assigns what to found pNext
290 void appendStructurePtrToVulkanChain(const void **chainHead, const void *structurePtr);
291 
292 namespace ValidateQueryBits
293 {
294 
295 typedef struct
296 {
297     size_t offset;
298     size_t size;
299 } QueryMemberTableEntry;
300 
301 template <typename Context, typename Interface, typename Type>
302 //!< Return variable initialization validation
validateInitComplete(Context context,void (Interface::* Function)(Context,Type *)const,const Interface & interface,const QueryMemberTableEntry * queryMemberTableEntry)303 bool validateInitComplete(Context context, void (Interface::*Function)(Context, Type *) const,
304                           const Interface &interface, const QueryMemberTableEntry *queryMemberTableEntry)
305 {
306     const QueryMemberTableEntry *iterator;
307     Type vec[2];
308     deMemset(&vec[0], 0x00, sizeof(Type));
309     deMemset(&vec[1], 0xFF, sizeof(Type));
310 
311     (interface.*Function)(context, &vec[0]);
312     (interface.*Function)(context, &vec[1]);
313 
314     for (iterator = queryMemberTableEntry; iterator->size != 0; iterator++)
315     {
316         if (deMemCmp(((uint8_t *)(&vec[0])) + iterator->offset, ((uint8_t *)(&vec[1])) + iterator->offset,
317                      iterator->size) != 0)
318             return false;
319     }
320 
321     return true;
322 }
323 
324 template <typename Type>
325 //!< Return variable initialization validation
validateStructsWithGuard(const QueryMemberTableEntry * queryMemberTableEntry,Type * vec[2],const uint8_t guardValue,const uint32_t guardSize)326 bool validateStructsWithGuard(const QueryMemberTableEntry *queryMemberTableEntry, Type *vec[2],
327                               const uint8_t guardValue, const uint32_t guardSize)
328 {
329     const QueryMemberTableEntry *iterator;
330 
331     for (iterator = queryMemberTableEntry; iterator->size != 0; iterator++)
332     {
333         if (deMemCmp(((uint8_t *)(vec[0])) + iterator->offset, ((uint8_t *)(vec[1])) + iterator->offset,
334                      iterator->size) != 0)
335             return false;
336     }
337 
338     for (uint32_t vecNdx = 0; vecNdx < 2; ++vecNdx)
339     {
340         for (uint32_t ndx = 0; ndx < guardSize; ndx++)
341         {
342             if (((uint8_t *)(vec[vecNdx]))[ndx + sizeof(Type)] != guardValue)
343                 return false;
344         }
345     }
346 
347     return true;
348 }
349 
350 template <typename IterT>
351 //! Overwrite a range of objects with an 8-bit pattern.
fillBits(IterT beg,const IterT end,const uint8_t pattern=0xdeu)352 inline void fillBits(IterT beg, const IterT end, const uint8_t pattern = 0xdeu)
353 {
354     for (; beg < end; ++beg)
355         deMemset(&(*beg), static_cast<int>(pattern), sizeof(*beg));
356 }
357 
358 template <typename IterT>
359 //! Verify that each byte of a range of objects is equal to an 8-bit pattern.
checkBits(IterT beg,const IterT end,const uint8_t pattern=0xdeu)360 bool checkBits(IterT beg, const IterT end, const uint8_t pattern = 0xdeu)
361 {
362     for (; beg < end; ++beg)
363     {
364         const uint8_t *elementBytes = reinterpret_cast<const uint8_t *>(&(*beg));
365         for (std::size_t i = 0u; i < sizeof(*beg); ++i)
366         {
367             if (elementBytes[i] != pattern)
368                 return false;
369         }
370     }
371     return true;
372 }
373 
374 } // namespace ValidateQueryBits
375 
376 // Template implementations
377 
378 template <typename ExtensionIterator>
isExtensionStructSupported(ExtensionIterator begin,ExtensionIterator end,const RequiredExtension & required)379 bool isExtensionStructSupported(ExtensionIterator begin, ExtensionIterator end, const RequiredExtension &required)
380 {
381     for (ExtensionIterator cur = begin; cur != end; ++cur)
382     {
383         if (isCompatible(*cur, required))
384             return true;
385     }
386     return false;
387 }
388 
389 template <typename LayerIterator>
isLayerSupported(LayerIterator begin,LayerIterator end,const RequiredLayer & required)390 bool isLayerSupported(LayerIterator begin, LayerIterator end, const RequiredLayer &required)
391 {
392     for (LayerIterator cur = begin; cur != end; ++cur)
393     {
394         if (isCompatible(*cur, required))
395             return true;
396     }
397     return false;
398 }
399 
400 } // namespace vk
401 
402 #endif // _VKQUERYUTIL_HPP
403