1 /*-------------------------------------------------------------------------
2 * Vulkan CTS Framework
3 * --------------------
4 *
5 * Copyright (c) 2015 Google 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 * \file
21 * \brief Vulkan query utilities.
22 *//*--------------------------------------------------------------------*/
23
24 #include "vkQueryUtil.hpp"
25 #include "vkApiVersion.hpp"
26
27 #include "deMemory.h"
28 #include "deString.h"
29 #include "deSTLUtil.hpp"
30
31 #include <vector>
32 #include <sstream>
33
34 namespace vk
35 {
36
37 using std::vector;
38
39 namespace
40 {
41
42 #include "vkSupportedExtensions.inl"
43
44 }
45
getCoreInstanceExtensions(deUint32 apiVersion,vector<const char * > & dst)46 void getCoreInstanceExtensions(deUint32 apiVersion, vector<const char*>& dst)
47 {
48 getCoreInstanceExtensionsImpl(apiVersion, dst);
49 }
50
getCoreDeviceExtensions(deUint32 apiVersion,vector<const char * > & dst)51 void getCoreDeviceExtensions(deUint32 apiVersion, vector<const char*>& dst)
52 {
53 getCoreDeviceExtensionsImpl(apiVersion, dst);
54 }
55
isCoreInstanceExtension(const deUint32 apiVersion,const std::string & extension)56 bool isCoreInstanceExtension(const deUint32 apiVersion, const std::string& extension)
57 {
58 vector<const char*> coreExtensions;
59 getCoreInstanceExtensions(apiVersion, coreExtensions);
60 if (de::contains(coreExtensions.begin(), coreExtensions.end(), extension))
61 return true;
62
63 return false;
64 }
65
isCoreDeviceExtension(const deUint32 apiVersion,const std::string & extension)66 bool isCoreDeviceExtension(const deUint32 apiVersion, const std::string& extension)
67 {
68 vector<const char*> coreExtensions;
69 getCoreDeviceExtensions(apiVersion, coreExtensions);
70 if (de::contains(coreExtensions.begin(), coreExtensions.end(), extension))
71 return true;
72
73 return false;
74 }
75
enumeratePhysicalDevices(const InstanceInterface & vk,VkInstance instance)76 vector<VkPhysicalDevice> enumeratePhysicalDevices (const InstanceInterface& vk, VkInstance instance)
77 {
78 deUint32 numDevices = 0;
79 vector<VkPhysicalDevice> devices;
80
81 VK_CHECK(vk.enumeratePhysicalDevices(instance, &numDevices, DE_NULL));
82
83 if (numDevices > 0)
84 {
85 devices.resize(numDevices);
86 VK_CHECK(vk.enumeratePhysicalDevices(instance, &numDevices, &devices[0]));
87
88 if ((size_t)numDevices != devices.size())
89 TCU_FAIL("Returned device count changed between queries");
90 }
91
92 return devices;
93 }
94
enumeratePhysicalDeviceGroups(const InstanceInterface & vk,VkInstance instance)95 vector<VkPhysicalDeviceGroupProperties> enumeratePhysicalDeviceGroups(const InstanceInterface& vk, VkInstance instance)
96 {
97 deUint32 numDeviceGroups = 0;
98 vector<VkPhysicalDeviceGroupProperties> properties;
99
100 VK_CHECK(vk.enumeratePhysicalDeviceGroups(instance, &numDeviceGroups, DE_NULL));
101
102 if (numDeviceGroups > 0)
103 {
104 properties.resize(numDeviceGroups);
105 for (deUint32 i = 0; i < numDeviceGroups; i++)
106 {
107 properties[i].sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_GROUP_PROPERTIES;
108 properties[i].pNext = DE_NULL;
109 }
110 VK_CHECK(vk.enumeratePhysicalDeviceGroups(instance, &numDeviceGroups, &properties[0]));
111
112 if ((size_t)numDeviceGroups != properties.size())
113 TCU_FAIL("Returned device group count changed between queries");
114 }
115 return properties;
116 }
117
getPhysicalDeviceQueueFamilyProperties(const InstanceInterface & vk,VkPhysicalDevice physicalDevice)118 vector<VkQueueFamilyProperties> getPhysicalDeviceQueueFamilyProperties (const InstanceInterface& vk, VkPhysicalDevice physicalDevice)
119 {
120 deUint32 numQueues = 0;
121 vector<VkQueueFamilyProperties> properties;
122
123 vk.getPhysicalDeviceQueueFamilyProperties(physicalDevice, &numQueues, DE_NULL);
124
125 if (numQueues > 0)
126 {
127 properties.resize(numQueues);
128 vk.getPhysicalDeviceQueueFamilyProperties(physicalDevice, &numQueues, &properties[0]);
129
130 if ((size_t)numQueues != properties.size())
131 TCU_FAIL("Returned queue family count changes between queries");
132 }
133
134 return properties;
135 }
136
getPhysicalDeviceFeatures(const InstanceInterface & vk,VkPhysicalDevice physicalDevice)137 VkPhysicalDeviceFeatures getPhysicalDeviceFeatures (const InstanceInterface& vk, VkPhysicalDevice physicalDevice)
138 {
139 VkPhysicalDeviceFeatures features;
140
141 deMemset(&features, 0, sizeof(features));
142
143 vk.getPhysicalDeviceFeatures(physicalDevice, &features);
144 return features;
145 }
146
getPhysicalDeviceFeatures2(const InstanceInterface & vk,VkPhysicalDevice physicalDevice)147 VkPhysicalDeviceFeatures2 getPhysicalDeviceFeatures2 (const InstanceInterface& vk, VkPhysicalDevice physicalDevice)
148 {
149 VkPhysicalDeviceFeatures2 features;
150
151 deMemset(&features, 0, sizeof(features));
152 features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2;
153
154 vk.getPhysicalDeviceFeatures2(physicalDevice, &features);
155 return features;
156 }
157
getPhysicalDeviceVulkan11Features(const InstanceInterface & vk,VkPhysicalDevice physicalDevice)158 VkPhysicalDeviceVulkan11Features getPhysicalDeviceVulkan11Features (const InstanceInterface& vk, VkPhysicalDevice physicalDevice)
159 {
160 VkPhysicalDeviceFeatures2 features;
161 VkPhysicalDeviceVulkan11Features vulkan_11_features;
162
163 deMemset(&features, 0, sizeof(features));
164 features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2;
165
166 deMemset(&vulkan_11_features, 0, sizeof(vulkan_11_features));
167 vulkan_11_features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_FEATURES;
168
169 features.pNext = &vulkan_11_features;
170
171 vk.getPhysicalDeviceFeatures2(physicalDevice, &features);
172 return vulkan_11_features;
173 }
174
getPhysicalDeviceVulkan12Features(const InstanceInterface & vk,VkPhysicalDevice physicalDevice)175 VkPhysicalDeviceVulkan12Features getPhysicalDeviceVulkan12Features (const InstanceInterface& vk, VkPhysicalDevice physicalDevice)
176 {
177 VkPhysicalDeviceFeatures2 features;
178 VkPhysicalDeviceVulkan12Features vulkan_12_features;
179
180 deMemset(&features, 0, sizeof(features));
181 features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2;
182
183 deMemset(&vulkan_12_features, 0, sizeof(vulkan_12_features));
184 vulkan_12_features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_FEATURES;
185
186 features.pNext = &vulkan_12_features;
187
188 vk.getPhysicalDeviceFeatures2(physicalDevice, &features);
189 return vulkan_12_features;
190 }
191
getPhysicalDeviceVulkan11Properties(const InstanceInterface & vk,VkPhysicalDevice physicalDevice)192 VkPhysicalDeviceVulkan11Properties getPhysicalDeviceVulkan11Properties (const InstanceInterface& vk, VkPhysicalDevice physicalDevice)
193 {
194 VkPhysicalDeviceVulkan11Properties vulkan11properties = initVulkanStructure();
195 VkPhysicalDeviceProperties2 properties = initVulkanStructure(&vulkan11properties);
196
197 vk.getPhysicalDeviceProperties2(physicalDevice, &properties);
198
199 return vulkan11properties;
200 }
201
getPhysicalDeviceVulkan12Properties(const InstanceInterface & vk,VkPhysicalDevice physicalDevice)202 VkPhysicalDeviceVulkan12Properties getPhysicalDeviceVulkan12Properties (const InstanceInterface& vk, VkPhysicalDevice physicalDevice)
203 {
204 VkPhysicalDeviceVulkan12Properties vulkan12properties = initVulkanStructure();
205 VkPhysicalDeviceProperties2 properties = initVulkanStructure(&vulkan12properties);
206
207 vk.getPhysicalDeviceProperties2(physicalDevice, &properties);
208
209 return vulkan12properties;
210 }
211
getPhysicalDeviceProperties(const InstanceInterface & vk,VkPhysicalDevice physicalDevice)212 VkPhysicalDeviceProperties getPhysicalDeviceProperties (const InstanceInterface& vk, VkPhysicalDevice physicalDevice)
213 {
214 VkPhysicalDeviceProperties properties;
215
216 deMemset(&properties, 0, sizeof(properties));
217
218 vk.getPhysicalDeviceProperties(physicalDevice, &properties);
219 return properties;
220 }
221
getPhysicalDeviceMemoryProperties(const InstanceInterface & vk,VkPhysicalDevice physicalDevice)222 VkPhysicalDeviceMemoryProperties getPhysicalDeviceMemoryProperties (const InstanceInterface& vk, VkPhysicalDevice physicalDevice)
223 {
224 VkPhysicalDeviceMemoryProperties properties;
225
226 deMemset(&properties, 0, sizeof(properties));
227
228 vk.getPhysicalDeviceMemoryProperties(physicalDevice, &properties);
229
230 if (properties.memoryTypeCount > VK_MAX_MEMORY_TYPES)
231 {
232 std::ostringstream msg;
233 msg << "Invalid memoryTypeCount in VkPhysicalDeviceMemoryProperties (got " << properties.memoryTypeCount
234 << ", max " << VK_MAX_MEMORY_TYPES << ")";
235 TCU_FAIL(msg.str());
236 }
237
238 if (properties.memoryHeapCount > VK_MAX_MEMORY_HEAPS)
239 {
240 std::ostringstream msg;
241 msg << "Invalid memoryHeapCount in VkPhysicalDeviceMemoryProperties (got " << properties.memoryHeapCount
242 << ", max " << VK_MAX_MEMORY_HEAPS << ")";
243 TCU_FAIL(msg.str());
244 }
245
246 return properties;
247 }
248
getPhysicalDeviceFormatProperties(const InstanceInterface & vk,VkPhysicalDevice physicalDevice,VkFormat format)249 VkFormatProperties getPhysicalDeviceFormatProperties (const InstanceInterface& vk, VkPhysicalDevice physicalDevice, VkFormat format)
250 {
251 VkFormatProperties properties;
252
253 deMemset(&properties, 0, sizeof(properties));
254
255 vk.getPhysicalDeviceFormatProperties(physicalDevice, format, &properties);
256 return properties;
257 }
258
getPhysicalDeviceImageFormatProperties(const InstanceInterface & vk,VkPhysicalDevice physicalDevice,VkFormat format,VkImageType type,VkImageTiling tiling,VkImageUsageFlags usage,VkImageCreateFlags flags)259 VkImageFormatProperties getPhysicalDeviceImageFormatProperties (const InstanceInterface& vk, VkPhysicalDevice physicalDevice, VkFormat format, VkImageType type, VkImageTiling tiling, VkImageUsageFlags usage, VkImageCreateFlags flags)
260 {
261 VkImageFormatProperties properties;
262
263 deMemset(&properties, 0, sizeof(properties));
264
265 VK_CHECK(vk.getPhysicalDeviceImageFormatProperties(physicalDevice, format, type, tiling, usage, flags, &properties));
266 return properties;
267 }
268
getPhysicalDeviceSparseImageFormatProperties(const InstanceInterface & vk,VkPhysicalDevice physicalDevice,VkFormat format,VkImageType type,VkSampleCountFlagBits samples,VkImageUsageFlags usage,VkImageTiling tiling)269 std::vector<VkSparseImageFormatProperties> getPhysicalDeviceSparseImageFormatProperties(const InstanceInterface& vk, VkPhysicalDevice physicalDevice, VkFormat format, VkImageType type, VkSampleCountFlagBits samples, VkImageUsageFlags usage, VkImageTiling tiling)
270 {
271 deUint32 numProp = 0;
272 vector<VkSparseImageFormatProperties> properties;
273
274 vk.getPhysicalDeviceSparseImageFormatProperties(physicalDevice, format, type, samples, usage, tiling, &numProp, DE_NULL);
275
276 if (numProp > 0)
277 {
278 properties.resize(numProp);
279 vk.getPhysicalDeviceSparseImageFormatProperties(physicalDevice, format, type, samples, usage, tiling, &numProp, &properties[0]);
280
281 if ((size_t)numProp != properties.size())
282 TCU_FAIL("Returned sparse image properties count changes between queries");
283 }
284
285 return properties;
286 }
287
getImageSparseMemoryRequirements(const DeviceInterface & vk,VkDevice device,VkImage image)288 std::vector<VkSparseImageMemoryRequirements> getImageSparseMemoryRequirements(const DeviceInterface& vk, VkDevice device, VkImage image)
289 {
290 deUint32 requirementsCount = 0;
291 vector<VkSparseImageMemoryRequirements> requirements;
292
293 vk.getImageSparseMemoryRequirements(device, image, &requirementsCount, DE_NULL);
294
295 if (requirementsCount > 0)
296 {
297 requirements.resize(requirementsCount);
298 vk.getImageSparseMemoryRequirements(device, image, &requirementsCount, &requirements[0]);
299
300 if ((size_t)requirementsCount != requirements.size())
301 TCU_FAIL("Returned sparse image memory requirements count changes between queries");
302 }
303
304 return requirements;
305 }
306
getBufferMemoryRequirements(const DeviceInterface & vk,VkDevice device,VkBuffer buffer)307 VkMemoryRequirements getBufferMemoryRequirements (const DeviceInterface& vk, VkDevice device, VkBuffer buffer)
308 {
309 VkMemoryRequirements req;
310 vk.getBufferMemoryRequirements(device, buffer, &req);
311 return req;
312 }
313
getImageMemoryRequirements(const DeviceInterface & vk,VkDevice device,VkImage image)314 VkMemoryRequirements getImageMemoryRequirements (const DeviceInterface& vk, VkDevice device, VkImage image)
315 {
316 VkMemoryRequirements req;
317 vk.getImageMemoryRequirements(device, image, &req);
318 return req;
319 }
320
getImagePlaneMemoryRequirements(const DeviceInterface & vkd,VkDevice device,VkImage image,VkImageAspectFlagBits planeAspect)321 VkMemoryRequirements getImagePlaneMemoryRequirements (const DeviceInterface& vkd,
322 VkDevice device,
323 VkImage image,
324 VkImageAspectFlagBits planeAspect)
325 {
326 VkImageMemoryRequirementsInfo2 coreInfo;
327 VkImagePlaneMemoryRequirementsInfo planeInfo;
328 VkMemoryRequirements2 reqs;
329
330 deMemset(&coreInfo, 0, sizeof(coreInfo));
331 deMemset(&planeInfo, 0, sizeof(planeInfo));
332 deMemset(&reqs, 0, sizeof(reqs));
333
334 coreInfo.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_REQUIREMENTS_INFO_2;
335 coreInfo.pNext = &planeInfo;
336 coreInfo.image = image;
337
338 planeInfo.sType = VK_STRUCTURE_TYPE_IMAGE_PLANE_MEMORY_REQUIREMENTS_INFO;
339 planeInfo.planeAspect = planeAspect;
340
341 reqs.sType = VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2;
342
343 vkd.getImageMemoryRequirements2(device, &coreInfo, &reqs);
344
345 return reqs.memoryRequirements;
346 }
347
enumerateInstanceLayerProperties(const PlatformInterface & vkp)348 vector<VkLayerProperties> enumerateInstanceLayerProperties (const PlatformInterface& vkp)
349 {
350 vector<VkLayerProperties> properties;
351 deUint32 numLayers = 0;
352
353 VK_CHECK(vkp.enumerateInstanceLayerProperties(&numLayers, DE_NULL));
354
355 if (numLayers > 0)
356 {
357 properties.resize(numLayers);
358 VK_CHECK(vkp.enumerateInstanceLayerProperties(&numLayers, &properties[0]));
359 TCU_CHECK((size_t)numLayers == properties.size());
360 }
361
362 return properties;
363 }
364
enumerateInstanceExtensionProperties(const PlatformInterface & vkp,const char * layerName)365 vector<VkExtensionProperties> enumerateInstanceExtensionProperties (const PlatformInterface& vkp, const char* layerName)
366 {
367 vector<VkExtensionProperties> properties;
368 deUint32 numExtensions = 0;
369
370 VK_CHECK(vkp.enumerateInstanceExtensionProperties(layerName, &numExtensions, DE_NULL));
371
372 if (numExtensions > 0)
373 {
374 properties.resize(numExtensions);
375 VK_CHECK(vkp.enumerateInstanceExtensionProperties(layerName, &numExtensions, &properties[0]));
376 TCU_CHECK((size_t)numExtensions == properties.size());
377 }
378
379 return properties;
380 }
381
enumerateDeviceLayerProperties(const InstanceInterface & vki,VkPhysicalDevice physicalDevice)382 vector<VkLayerProperties> enumerateDeviceLayerProperties (const InstanceInterface& vki, VkPhysicalDevice physicalDevice)
383 {
384 vector<VkLayerProperties> properties;
385 deUint32 numLayers = 0;
386
387 VK_CHECK(vki.enumerateDeviceLayerProperties(physicalDevice, &numLayers, DE_NULL));
388
389 if (numLayers > 0)
390 {
391 properties.resize(numLayers);
392 VK_CHECK(vki.enumerateDeviceLayerProperties(physicalDevice, &numLayers, &properties[0]));
393 TCU_CHECK((size_t)numLayers == properties.size());
394 }
395
396 return properties;
397 }
398
enumerateDeviceExtensionProperties(const InstanceInterface & vki,VkPhysicalDevice physicalDevice,const char * layerName)399 vector<VkExtensionProperties> enumerateDeviceExtensionProperties (const InstanceInterface& vki, VkPhysicalDevice physicalDevice, const char* layerName)
400 {
401 vector<VkExtensionProperties> properties;
402 deUint32 numExtensions = 0;
403
404 VK_CHECK(vki.enumerateDeviceExtensionProperties(physicalDevice, layerName, &numExtensions, DE_NULL));
405
406 if (numExtensions > 0)
407 {
408 properties.resize(numExtensions);
409 VK_CHECK(vki.enumerateDeviceExtensionProperties(physicalDevice, layerName, &numExtensions, &properties[0]));
410 TCU_CHECK((size_t)numExtensions == properties.size());
411 }
412
413 return properties;
414 }
415
isShaderStageSupported(const VkPhysicalDeviceFeatures & deviceFeatures,VkShaderStageFlagBits stage)416 bool isShaderStageSupported (const VkPhysicalDeviceFeatures& deviceFeatures, VkShaderStageFlagBits stage)
417 {
418 if (stage == VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT || stage == VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT)
419 return deviceFeatures.tessellationShader == VK_TRUE;
420 else if (stage == VK_SHADER_STAGE_GEOMETRY_BIT)
421 return deviceFeatures.geometryShader == VK_TRUE;
422 else
423 return true;
424 }
425
isCompatible(const VkExtensionProperties & extensionProperties,const RequiredExtension & required)426 bool isCompatible (const VkExtensionProperties& extensionProperties, const RequiredExtension& required)
427 {
428 if (required.name != extensionProperties.extensionName)
429 return false;
430
431 if (required.minVersion && required.minVersion.get() > extensionProperties.specVersion)
432 return false;
433
434 if (required.maxVersion && required.maxVersion.get() < extensionProperties.specVersion)
435 return false;
436
437 return true;
438 }
439
isCompatible(const VkLayerProperties & layerProperties,const RequiredLayer & required)440 bool isCompatible (const VkLayerProperties& layerProperties, const RequiredLayer& required)
441 {
442 if (required.name != layerProperties.layerName)
443 return false;
444
445 if (required.minSpecVersion && required.minSpecVersion.get() > layerProperties.specVersion)
446 return false;
447
448 if (required.maxSpecVersion && required.maxSpecVersion.get() < layerProperties.specVersion)
449 return false;
450
451 if (required.minImplVersion && required.minImplVersion.get() > layerProperties.implementationVersion)
452 return false;
453
454 if (required.maxImplVersion && required.maxImplVersion.get() < layerProperties.implementationVersion)
455 return false;
456
457 return true;
458 }
459
isExtensionSupported(const std::vector<VkExtensionProperties> & extensions,const RequiredExtension & required)460 bool isExtensionSupported (const std::vector<VkExtensionProperties>& extensions, const RequiredExtension& required)
461 {
462 return isExtensionSupported(extensions.begin(), extensions.end(), required);
463 }
464
isExtensionSupported(const vector<std::string> & extensionStrings,const std::string & extensionName)465 bool isExtensionSupported (const vector<std::string>& extensionStrings, const std::string& extensionName)
466 {
467 return de::contains(extensionStrings.begin(), extensionStrings.end(), extensionName);
468 }
469
isInstanceExtensionSupported(const deUint32 instanceVersion,const std::vector<std::string> & extensions,const std::string & required)470 bool isInstanceExtensionSupported(const deUint32 instanceVersion, const std::vector<std::string>& extensions, const std::string& required)
471 {
472 // NOTE: this function is only needed in few cases during creation of context,
473 // dont use it, call Context::isInstanceFunctionalitySupported instead
474 if (isCoreInstanceExtension(instanceVersion, required))
475 return true;
476 return de::contains(extensions.begin(), extensions.end(), required);
477 }
478
isLayerSupported(const std::vector<VkLayerProperties> & layers,const RequiredLayer & required)479 bool isLayerSupported (const std::vector<VkLayerProperties>& layers, const RequiredLayer& required)
480 {
481 return isLayerSupported(layers.begin(), layers.end(), required);
482 }
483
getDeviceQueue(const DeviceInterface & vkd,VkDevice device,deUint32 queueFamilyIndex,deUint32 queueIndex)484 VkQueue getDeviceQueue (const DeviceInterface& vkd, VkDevice device, deUint32 queueFamilyIndex, deUint32 queueIndex)
485 {
486 VkQueue queue;
487
488 vkd.getDeviceQueue(device, queueFamilyIndex, queueIndex, &queue);
489
490 return queue;
491 }
492
getDeviceQueue2(const DeviceInterface & vkd,VkDevice device,const VkDeviceQueueInfo2 * queueInfo)493 VkQueue getDeviceQueue2 (const DeviceInterface& vkd, VkDevice device, const VkDeviceQueueInfo2* queueInfo)
494 {
495 VkQueue queue;
496
497 vkd.getDeviceQueue2(device, queueInfo, &queue);
498
499 return queue;
500 }
501
findStructureInChain(const void * first,VkStructureType type)502 const void* findStructureInChain (const void* first, VkStructureType type)
503 {
504 struct StructureBase
505 {
506 VkStructureType sType;
507 void* pNext;
508 };
509
510 const StructureBase* cur = reinterpret_cast<const StructureBase*>(first);
511
512 while (cur)
513 {
514 if (cur->sType == type)
515 break;
516 else
517 cur = reinterpret_cast<const StructureBase*>(cur->pNext);
518 }
519
520 return cur;
521 }
522
findStructureInChain(void * first,VkStructureType type)523 void* findStructureInChain (void* first, VkStructureType type)
524 {
525 return const_cast<void*>(findStructureInChain(const_cast<const void*>(first), type));
526 }
527
appendStructurePtrToVulkanChain(const void ** chainHead,const void * structurePtr)528 void appendStructurePtrToVulkanChain (const void** chainHead, const void* structurePtr)
529 {
530 struct StructureBase
531 {
532 VkStructureType sType;
533 const void* pNext;
534 };
535
536 while (*chainHead != DE_NULL)
537 {
538 StructureBase* ptr = (StructureBase*)(*chainHead);
539
540 chainHead = &(ptr->pNext);
541 }
542
543 (*chainHead) = structurePtr;
544 }
545
546 // getStructureType<T> implementations
547 #include "vkGetStructureTypeImpl.inl"
548
549 } // vk
550