1e5c31af7Sopenharmony_ci/*------------------------------------------------------------------------- 2e5c31af7Sopenharmony_ci * Vulkan CTS Framework 3e5c31af7Sopenharmony_ci * -------------------- 4e5c31af7Sopenharmony_ci * 5e5c31af7Sopenharmony_ci * Copyright (c) 2015 Google Inc. 6e5c31af7Sopenharmony_ci * 7e5c31af7Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 8e5c31af7Sopenharmony_ci * you may not use this file except in compliance with the License. 9e5c31af7Sopenharmony_ci * You may obtain a copy of the License at 10e5c31af7Sopenharmony_ci * 11e5c31af7Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 12e5c31af7Sopenharmony_ci * 13e5c31af7Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 14e5c31af7Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 15e5c31af7Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16e5c31af7Sopenharmony_ci * See the License for the specific language governing permissions and 17e5c31af7Sopenharmony_ci * limitations under the License. 18e5c31af7Sopenharmony_ci * 19e5c31af7Sopenharmony_ci *//*! 20e5c31af7Sopenharmony_ci * \file 21e5c31af7Sopenharmony_ci * \brief Vulkan query utilities. 22e5c31af7Sopenharmony_ci *//*--------------------------------------------------------------------*/ 23e5c31af7Sopenharmony_ci 24e5c31af7Sopenharmony_ci#include "vkQueryUtil.hpp" 25e5c31af7Sopenharmony_ci#include "vkApiVersion.hpp" 26e5c31af7Sopenharmony_ci 27e5c31af7Sopenharmony_ci#include "deMemory.h" 28e5c31af7Sopenharmony_ci#include "deString.h" 29e5c31af7Sopenharmony_ci#include "deSTLUtil.hpp" 30e5c31af7Sopenharmony_ci 31e5c31af7Sopenharmony_ci#include <vector> 32e5c31af7Sopenharmony_ci#include <sstream> 33e5c31af7Sopenharmony_ci#include <memory> 34e5c31af7Sopenharmony_ci#include <map> 35e5c31af7Sopenharmony_ci 36e5c31af7Sopenharmony_cinamespace vk 37e5c31af7Sopenharmony_ci{ 38e5c31af7Sopenharmony_ci 39e5c31af7Sopenharmony_ciusing std::vector; 40e5c31af7Sopenharmony_ci 41e5c31af7Sopenharmony_cinamespace 42e5c31af7Sopenharmony_ci{ 43e5c31af7Sopenharmony_ci 44e5c31af7Sopenharmony_ci#include "vkSupportedExtensions.inl" 45e5c31af7Sopenharmony_ci 46e5c31af7Sopenharmony_ci} 47e5c31af7Sopenharmony_ci 48e5c31af7Sopenharmony_civoid getCoreInstanceExtensions(deUint32 apiVersion, vector<const char*>& dst) 49e5c31af7Sopenharmony_ci{ 50e5c31af7Sopenharmony_ci getCoreInstanceExtensionsImpl(apiVersion, dst); 51e5c31af7Sopenharmony_ci} 52e5c31af7Sopenharmony_ci 53e5c31af7Sopenharmony_civoid getCoreDeviceExtensions(deUint32 apiVersion, vector<const char*>& dst) 54e5c31af7Sopenharmony_ci{ 55e5c31af7Sopenharmony_ci getCoreDeviceExtensionsImpl(apiVersion, dst); 56e5c31af7Sopenharmony_ci} 57e5c31af7Sopenharmony_ci 58e5c31af7Sopenharmony_cibool isCoreInstanceExtension(const deUint32 apiVersion, const std::string& extension) 59e5c31af7Sopenharmony_ci{ 60e5c31af7Sopenharmony_ci vector<const char*> coreExtensions; 61e5c31af7Sopenharmony_ci getCoreInstanceExtensions(apiVersion, coreExtensions); 62e5c31af7Sopenharmony_ci if (de::contains(coreExtensions.begin(), coreExtensions.end(), extension)) 63e5c31af7Sopenharmony_ci return true; 64e5c31af7Sopenharmony_ci 65e5c31af7Sopenharmony_ci return false; 66e5c31af7Sopenharmony_ci} 67e5c31af7Sopenharmony_ci 68e5c31af7Sopenharmony_cibool isCoreDeviceExtension(const deUint32 apiVersion, const std::string& extension) 69e5c31af7Sopenharmony_ci{ 70e5c31af7Sopenharmony_ci vector<const char*> coreExtensions; 71e5c31af7Sopenharmony_ci getCoreDeviceExtensions(apiVersion, coreExtensions); 72e5c31af7Sopenharmony_ci if (de::contains(coreExtensions.begin(), coreExtensions.end(), extension)) 73e5c31af7Sopenharmony_ci return true; 74e5c31af7Sopenharmony_ci 75e5c31af7Sopenharmony_ci return false; 76e5c31af7Sopenharmony_ci} 77e5c31af7Sopenharmony_ci 78e5c31af7Sopenharmony_civector<VkPhysicalDevice> enumeratePhysicalDevices (const InstanceInterface& vk, VkInstance instance) 79e5c31af7Sopenharmony_ci{ 80e5c31af7Sopenharmony_ci deUint32 numDevices = 0; 81e5c31af7Sopenharmony_ci vector<VkPhysicalDevice> devices; 82e5c31af7Sopenharmony_ci 83e5c31af7Sopenharmony_ci VK_CHECK(vk.enumeratePhysicalDevices(instance, &numDevices, DE_NULL)); 84e5c31af7Sopenharmony_ci 85e5c31af7Sopenharmony_ci if (numDevices > 0) 86e5c31af7Sopenharmony_ci { 87e5c31af7Sopenharmony_ci devices.resize(numDevices); 88e5c31af7Sopenharmony_ci VK_CHECK(vk.enumeratePhysicalDevices(instance, &numDevices, &devices[0])); 89e5c31af7Sopenharmony_ci 90e5c31af7Sopenharmony_ci if ((size_t)numDevices != devices.size()) 91e5c31af7Sopenharmony_ci TCU_FAIL("Returned device count changed between queries"); 92e5c31af7Sopenharmony_ci } 93e5c31af7Sopenharmony_ci 94e5c31af7Sopenharmony_ci return devices; 95e5c31af7Sopenharmony_ci} 96e5c31af7Sopenharmony_ci 97e5c31af7Sopenharmony_civector<VkPhysicalDeviceGroupProperties> enumeratePhysicalDeviceGroups(const InstanceInterface& vk, VkInstance instance) 98e5c31af7Sopenharmony_ci{ 99e5c31af7Sopenharmony_ci deUint32 numDeviceGroups = 0; 100e5c31af7Sopenharmony_ci vector<VkPhysicalDeviceGroupProperties> properties; 101e5c31af7Sopenharmony_ci 102e5c31af7Sopenharmony_ci VK_CHECK(vk.enumeratePhysicalDeviceGroups(instance, &numDeviceGroups, DE_NULL)); 103e5c31af7Sopenharmony_ci 104e5c31af7Sopenharmony_ci if (numDeviceGroups > 0) 105e5c31af7Sopenharmony_ci { 106e5c31af7Sopenharmony_ci properties.resize(numDeviceGroups, initVulkanStructure()); 107e5c31af7Sopenharmony_ci VK_CHECK(vk.enumeratePhysicalDeviceGroups(instance, &numDeviceGroups, &properties[0])); 108e5c31af7Sopenharmony_ci 109e5c31af7Sopenharmony_ci if ((size_t)numDeviceGroups != properties.size()) 110e5c31af7Sopenharmony_ci TCU_FAIL("Returned device group count changed between queries"); 111e5c31af7Sopenharmony_ci } 112e5c31af7Sopenharmony_ci return properties; 113e5c31af7Sopenharmony_ci} 114e5c31af7Sopenharmony_ci 115e5c31af7Sopenharmony_civector<VkQueueFamilyProperties> getPhysicalDeviceQueueFamilyProperties (const InstanceInterface& vk, VkPhysicalDevice physicalDevice) 116e5c31af7Sopenharmony_ci{ 117e5c31af7Sopenharmony_ci deUint32 numQueues = 0; 118e5c31af7Sopenharmony_ci vector<VkQueueFamilyProperties> properties; 119e5c31af7Sopenharmony_ci 120e5c31af7Sopenharmony_ci vk.getPhysicalDeviceQueueFamilyProperties(physicalDevice, &numQueues, DE_NULL); 121e5c31af7Sopenharmony_ci 122e5c31af7Sopenharmony_ci if (numQueues > 0) 123e5c31af7Sopenharmony_ci { 124e5c31af7Sopenharmony_ci properties.resize(numQueues); 125e5c31af7Sopenharmony_ci vk.getPhysicalDeviceQueueFamilyProperties(physicalDevice, &numQueues, &properties[0]); 126e5c31af7Sopenharmony_ci 127e5c31af7Sopenharmony_ci if ((size_t)numQueues != properties.size()) 128e5c31af7Sopenharmony_ci TCU_FAIL("Returned queue family count changes between queries"); 129e5c31af7Sopenharmony_ci } 130e5c31af7Sopenharmony_ci 131e5c31af7Sopenharmony_ci return properties; 132e5c31af7Sopenharmony_ci} 133e5c31af7Sopenharmony_ci 134e5c31af7Sopenharmony_ciVkPhysicalDeviceFeatures getPhysicalDeviceFeatures (const InstanceInterface& vk, VkPhysicalDevice physicalDevice) 135e5c31af7Sopenharmony_ci{ 136e5c31af7Sopenharmony_ci VkPhysicalDeviceFeatures features; 137e5c31af7Sopenharmony_ci 138e5c31af7Sopenharmony_ci deMemset(&features, 0, sizeof(features)); 139e5c31af7Sopenharmony_ci 140e5c31af7Sopenharmony_ci vk.getPhysicalDeviceFeatures(physicalDevice, &features); 141e5c31af7Sopenharmony_ci return features; 142e5c31af7Sopenharmony_ci} 143e5c31af7Sopenharmony_ci 144e5c31af7Sopenharmony_ciVkPhysicalDeviceFeatures2 getPhysicalDeviceFeatures2 (const InstanceInterface& vk, VkPhysicalDevice physicalDevice) 145e5c31af7Sopenharmony_ci{ 146e5c31af7Sopenharmony_ci VkPhysicalDeviceFeatures2 features; 147e5c31af7Sopenharmony_ci 148e5c31af7Sopenharmony_ci deMemset(&features, 0, sizeof(features)); 149e5c31af7Sopenharmony_ci features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2; 150e5c31af7Sopenharmony_ci 151e5c31af7Sopenharmony_ci vk.getPhysicalDeviceFeatures2(physicalDevice, &features); 152e5c31af7Sopenharmony_ci return features; 153e5c31af7Sopenharmony_ci} 154e5c31af7Sopenharmony_ci 155e5c31af7Sopenharmony_ciVkPhysicalDeviceVulkan11Features getPhysicalDeviceVulkan11Features (const InstanceInterface& vk, VkPhysicalDevice physicalDevice) 156e5c31af7Sopenharmony_ci{ 157e5c31af7Sopenharmony_ci VkPhysicalDeviceFeatures2 features; 158e5c31af7Sopenharmony_ci VkPhysicalDeviceVulkan11Features vulkan_11_features; 159e5c31af7Sopenharmony_ci 160e5c31af7Sopenharmony_ci deMemset(&features, 0, sizeof(features)); 161e5c31af7Sopenharmony_ci features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2; 162e5c31af7Sopenharmony_ci 163e5c31af7Sopenharmony_ci deMemset(&vulkan_11_features, 0, sizeof(vulkan_11_features)); 164e5c31af7Sopenharmony_ci vulkan_11_features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_FEATURES; 165e5c31af7Sopenharmony_ci 166e5c31af7Sopenharmony_ci features.pNext = &vulkan_11_features; 167e5c31af7Sopenharmony_ci 168e5c31af7Sopenharmony_ci vk.getPhysicalDeviceFeatures2(physicalDevice, &features); 169e5c31af7Sopenharmony_ci return vulkan_11_features; 170e5c31af7Sopenharmony_ci} 171e5c31af7Sopenharmony_ci 172e5c31af7Sopenharmony_ciVkPhysicalDeviceVulkan12Features getPhysicalDeviceVulkan12Features (const InstanceInterface& vk, VkPhysicalDevice physicalDevice) 173e5c31af7Sopenharmony_ci{ 174e5c31af7Sopenharmony_ci VkPhysicalDeviceFeatures2 features; 175e5c31af7Sopenharmony_ci VkPhysicalDeviceVulkan12Features vulkan_12_features; 176e5c31af7Sopenharmony_ci 177e5c31af7Sopenharmony_ci deMemset(&features, 0, sizeof(features)); 178e5c31af7Sopenharmony_ci features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2; 179e5c31af7Sopenharmony_ci 180e5c31af7Sopenharmony_ci deMemset(&vulkan_12_features, 0, sizeof(vulkan_12_features)); 181e5c31af7Sopenharmony_ci vulkan_12_features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_FEATURES; 182e5c31af7Sopenharmony_ci 183e5c31af7Sopenharmony_ci features.pNext = &vulkan_12_features; 184e5c31af7Sopenharmony_ci 185e5c31af7Sopenharmony_ci vk.getPhysicalDeviceFeatures2(physicalDevice, &features); 186e5c31af7Sopenharmony_ci return vulkan_12_features; 187e5c31af7Sopenharmony_ci} 188e5c31af7Sopenharmony_ci 189e5c31af7Sopenharmony_ciVkPhysicalDeviceVulkan11Properties getPhysicalDeviceVulkan11Properties (const InstanceInterface& vk, VkPhysicalDevice physicalDevice) 190e5c31af7Sopenharmony_ci{ 191e5c31af7Sopenharmony_ci VkPhysicalDeviceVulkan11Properties vulkan11properties = initVulkanStructure(); 192e5c31af7Sopenharmony_ci VkPhysicalDeviceProperties2 properties = initVulkanStructure(&vulkan11properties); 193e5c31af7Sopenharmony_ci 194e5c31af7Sopenharmony_ci vk.getPhysicalDeviceProperties2(physicalDevice, &properties); 195e5c31af7Sopenharmony_ci 196e5c31af7Sopenharmony_ci return vulkan11properties; 197e5c31af7Sopenharmony_ci} 198e5c31af7Sopenharmony_ci 199e5c31af7Sopenharmony_ciVkPhysicalDeviceVulkan12Properties getPhysicalDeviceVulkan12Properties (const InstanceInterface& vk, VkPhysicalDevice physicalDevice) 200e5c31af7Sopenharmony_ci{ 201e5c31af7Sopenharmony_ci VkPhysicalDeviceVulkan12Properties vulkan12properties = initVulkanStructure(); 202e5c31af7Sopenharmony_ci VkPhysicalDeviceProperties2 properties = initVulkanStructure(&vulkan12properties); 203e5c31af7Sopenharmony_ci 204e5c31af7Sopenharmony_ci vk.getPhysicalDeviceProperties2(physicalDevice, &properties); 205e5c31af7Sopenharmony_ci 206e5c31af7Sopenharmony_ci return vulkan12properties; 207e5c31af7Sopenharmony_ci} 208e5c31af7Sopenharmony_ci 209e5c31af7Sopenharmony_ci#ifdef CTS_USES_VULKANSC 210e5c31af7Sopenharmony_ciVkPhysicalDeviceVulkanSC10Features getPhysicalDeviceVulkanSC10Features (const InstanceInterface& vk, VkPhysicalDevice physicalDevice) 211e5c31af7Sopenharmony_ci{ 212e5c31af7Sopenharmony_ci VkPhysicalDeviceFeatures2 features; 213e5c31af7Sopenharmony_ci VkPhysicalDeviceVulkanSC10Features vulkanSC10Features; 214e5c31af7Sopenharmony_ci 215e5c31af7Sopenharmony_ci deMemset(&features, 0, sizeof(features)); 216e5c31af7Sopenharmony_ci features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2; 217e5c31af7Sopenharmony_ci 218e5c31af7Sopenharmony_ci deMemset(&vulkanSC10Features, 0, sizeof(vulkanSC10Features)); 219e5c31af7Sopenharmony_ci vulkanSC10Features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_SC_1_0_FEATURES; 220e5c31af7Sopenharmony_ci 221e5c31af7Sopenharmony_ci features.pNext = &vulkanSC10Features; 222e5c31af7Sopenharmony_ci 223e5c31af7Sopenharmony_ci vk.getPhysicalDeviceFeatures2(physicalDevice, &features); 224e5c31af7Sopenharmony_ci return vulkanSC10Features; 225e5c31af7Sopenharmony_ci} 226e5c31af7Sopenharmony_ci 227e5c31af7Sopenharmony_ciVkPhysicalDeviceVulkanSC10Properties getPhysicalDeviceVulkanSC10Properties (const InstanceInterface& vk, VkPhysicalDevice physicalDevice) 228e5c31af7Sopenharmony_ci{ 229e5c31af7Sopenharmony_ci VkPhysicalDeviceVulkanSC10Properties vulkanSC10properties = initVulkanStructure(); 230e5c31af7Sopenharmony_ci VkPhysicalDeviceProperties2 properties = initVulkanStructure(&vulkanSC10properties); 231e5c31af7Sopenharmony_ci 232e5c31af7Sopenharmony_ci vk.getPhysicalDeviceProperties2(physicalDevice, &properties); 233e5c31af7Sopenharmony_ci 234e5c31af7Sopenharmony_ci return vulkanSC10properties; 235e5c31af7Sopenharmony_ci} 236e5c31af7Sopenharmony_ci#endif // CTS_USES_VULKANSC 237e5c31af7Sopenharmony_ci 238e5c31af7Sopenharmony_ciVkPhysicalDeviceProperties getPhysicalDeviceProperties (const InstanceInterface& vk, VkPhysicalDevice physicalDevice) 239e5c31af7Sopenharmony_ci{ 240e5c31af7Sopenharmony_ci VkPhysicalDeviceProperties properties; 241e5c31af7Sopenharmony_ci 242e5c31af7Sopenharmony_ci deMemset(&properties, 0, sizeof(properties)); 243e5c31af7Sopenharmony_ci 244e5c31af7Sopenharmony_ci vk.getPhysicalDeviceProperties(physicalDevice, &properties); 245e5c31af7Sopenharmony_ci return properties; 246e5c31af7Sopenharmony_ci} 247e5c31af7Sopenharmony_ci 248e5c31af7Sopenharmony_ciVkPhysicalDeviceMemoryProperties getPhysicalDeviceMemoryProperties (const InstanceInterface& vk, VkPhysicalDevice physicalDevice) 249e5c31af7Sopenharmony_ci{ 250e5c31af7Sopenharmony_ci VkPhysicalDeviceMemoryProperties properties; 251e5c31af7Sopenharmony_ci 252e5c31af7Sopenharmony_ci deMemset(&properties, 0, sizeof(properties)); 253e5c31af7Sopenharmony_ci 254e5c31af7Sopenharmony_ci vk.getPhysicalDeviceMemoryProperties(physicalDevice, &properties); 255e5c31af7Sopenharmony_ci 256e5c31af7Sopenharmony_ci if (properties.memoryTypeCount > VK_MAX_MEMORY_TYPES) 257e5c31af7Sopenharmony_ci { 258e5c31af7Sopenharmony_ci std::ostringstream msg; 259e5c31af7Sopenharmony_ci msg << "Invalid memoryTypeCount in VkPhysicalDeviceMemoryProperties (got " << properties.memoryTypeCount 260e5c31af7Sopenharmony_ci << ", max " << VK_MAX_MEMORY_TYPES << ")"; 261e5c31af7Sopenharmony_ci TCU_FAIL(msg.str()); 262e5c31af7Sopenharmony_ci } 263e5c31af7Sopenharmony_ci 264e5c31af7Sopenharmony_ci if (properties.memoryHeapCount > VK_MAX_MEMORY_HEAPS) 265e5c31af7Sopenharmony_ci { 266e5c31af7Sopenharmony_ci std::ostringstream msg; 267e5c31af7Sopenharmony_ci msg << "Invalid memoryHeapCount in VkPhysicalDeviceMemoryProperties (got " << properties.memoryHeapCount 268e5c31af7Sopenharmony_ci << ", max " << VK_MAX_MEMORY_HEAPS << ")"; 269e5c31af7Sopenharmony_ci TCU_FAIL(msg.str()); 270e5c31af7Sopenharmony_ci } 271e5c31af7Sopenharmony_ci 272e5c31af7Sopenharmony_ci return properties; 273e5c31af7Sopenharmony_ci} 274e5c31af7Sopenharmony_ci 275e5c31af7Sopenharmony_ciVkFormatProperties getPhysicalDeviceFormatProperties (const InstanceInterface& vk, VkPhysicalDevice physicalDevice, VkFormat format) 276e5c31af7Sopenharmony_ci{ 277e5c31af7Sopenharmony_ci VkFormatProperties properties; 278e5c31af7Sopenharmony_ci 279e5c31af7Sopenharmony_ci deMemset(&properties, 0, sizeof(properties)); 280e5c31af7Sopenharmony_ci 281e5c31af7Sopenharmony_ci vk.getPhysicalDeviceFormatProperties(physicalDevice, format, &properties); 282e5c31af7Sopenharmony_ci return properties; 283e5c31af7Sopenharmony_ci} 284e5c31af7Sopenharmony_ci 285e5c31af7Sopenharmony_ciVkImageFormatProperties getPhysicalDeviceImageFormatProperties (const InstanceInterface& vk, VkPhysicalDevice physicalDevice, VkFormat format, VkImageType type, VkImageTiling tiling, VkImageUsageFlags usage, VkImageCreateFlags flags) 286e5c31af7Sopenharmony_ci{ 287e5c31af7Sopenharmony_ci VkImageFormatProperties properties; 288e5c31af7Sopenharmony_ci 289e5c31af7Sopenharmony_ci deMemset(&properties, 0, sizeof(properties)); 290e5c31af7Sopenharmony_ci 291e5c31af7Sopenharmony_ci VK_CHECK(vk.getPhysicalDeviceImageFormatProperties(physicalDevice, format, type, tiling, usage, flags, &properties)); 292e5c31af7Sopenharmony_ci return properties; 293e5c31af7Sopenharmony_ci} 294e5c31af7Sopenharmony_ci 295e5c31af7Sopenharmony_ci#ifndef CTS_USES_VULKANSC 296e5c31af7Sopenharmony_cistd::vector<VkSparseImageFormatProperties> getPhysicalDeviceSparseImageFormatProperties(const InstanceInterface& vk, VkPhysicalDevice physicalDevice, VkFormat format, VkImageType type, VkSampleCountFlagBits samples, VkImageUsageFlags usage, VkImageTiling tiling) 297e5c31af7Sopenharmony_ci{ 298e5c31af7Sopenharmony_ci deUint32 numProp = 0; 299e5c31af7Sopenharmony_ci vector<VkSparseImageFormatProperties> properties; 300e5c31af7Sopenharmony_ci 301e5c31af7Sopenharmony_ci vk.getPhysicalDeviceSparseImageFormatProperties(physicalDevice, format, type, samples, usage, tiling, &numProp, DE_NULL); 302e5c31af7Sopenharmony_ci 303e5c31af7Sopenharmony_ci if (numProp > 0) 304e5c31af7Sopenharmony_ci { 305e5c31af7Sopenharmony_ci properties.resize(numProp); 306e5c31af7Sopenharmony_ci vk.getPhysicalDeviceSparseImageFormatProperties(physicalDevice, format, type, samples, usage, tiling, &numProp, &properties[0]); 307e5c31af7Sopenharmony_ci 308e5c31af7Sopenharmony_ci if ((size_t)numProp != properties.size()) 309e5c31af7Sopenharmony_ci TCU_FAIL("Returned sparse image properties count changes between queries"); 310e5c31af7Sopenharmony_ci } 311e5c31af7Sopenharmony_ci 312e5c31af7Sopenharmony_ci return properties; 313e5c31af7Sopenharmony_ci} 314e5c31af7Sopenharmony_ci 315e5c31af7Sopenharmony_cistd::vector<VkSparseImageMemoryRequirements> getImageSparseMemoryRequirements(const DeviceInterface& vk, VkDevice device, VkImage image) 316e5c31af7Sopenharmony_ci{ 317e5c31af7Sopenharmony_ci deUint32 requirementsCount = 0; 318e5c31af7Sopenharmony_ci vector<VkSparseImageMemoryRequirements> requirements; 319e5c31af7Sopenharmony_ci 320e5c31af7Sopenharmony_ci vk.getImageSparseMemoryRequirements(device, image, &requirementsCount, DE_NULL); 321e5c31af7Sopenharmony_ci 322e5c31af7Sopenharmony_ci if (requirementsCount > 0) 323e5c31af7Sopenharmony_ci { 324e5c31af7Sopenharmony_ci requirements.resize(requirementsCount); 325e5c31af7Sopenharmony_ci vk.getImageSparseMemoryRequirements(device, image, &requirementsCount, &requirements[0]); 326e5c31af7Sopenharmony_ci 327e5c31af7Sopenharmony_ci if ((size_t)requirementsCount != requirements.size()) 328e5c31af7Sopenharmony_ci TCU_FAIL("Returned sparse image memory requirements count changes between queries"); 329e5c31af7Sopenharmony_ci } 330e5c31af7Sopenharmony_ci 331e5c31af7Sopenharmony_ci return requirements; 332e5c31af7Sopenharmony_ci} 333e5c31af7Sopenharmony_ci 334e5c31af7Sopenharmony_cistd::vector<vk::VkSparseImageMemoryRequirements> getDeviceImageSparseMemoryRequirements (const DeviceInterface& vk, 335e5c31af7Sopenharmony_ci VkDevice device, 336e5c31af7Sopenharmony_ci const VkImageCreateInfo& imageCreateInfo, 337e5c31af7Sopenharmony_ci VkImageAspectFlagBits planeAspect) 338e5c31af7Sopenharmony_ci{ 339e5c31af7Sopenharmony_ci const VkDeviceImageMemoryRequirements info 340e5c31af7Sopenharmony_ci { 341e5c31af7Sopenharmony_ci VK_STRUCTURE_TYPE_DEVICE_IMAGE_MEMORY_REQUIREMENTS, 342e5c31af7Sopenharmony_ci nullptr, 343e5c31af7Sopenharmony_ci &imageCreateInfo, 344e5c31af7Sopenharmony_ci planeAspect 345e5c31af7Sopenharmony_ci }; 346e5c31af7Sopenharmony_ci std::vector<vk::VkSparseImageMemoryRequirements2> requirements; 347e5c31af7Sopenharmony_ci deUint32 count = 0; 348e5c31af7Sopenharmony_ci 349e5c31af7Sopenharmony_ci vk.getDeviceImageSparseMemoryRequirements(device, &info, &count, DE_NULL); 350e5c31af7Sopenharmony_ci 351e5c31af7Sopenharmony_ci if (count > 0) 352e5c31af7Sopenharmony_ci { 353e5c31af7Sopenharmony_ci requirements.resize(count); 354e5c31af7Sopenharmony_ci for (deUint32 i = 0; i < count; ++i) 355e5c31af7Sopenharmony_ci requirements[i] = vk::initVulkanStructure(); 356e5c31af7Sopenharmony_ci vk.getDeviceImageSparseMemoryRequirements(device, &info, &count, requirements.data()); 357e5c31af7Sopenharmony_ci 358e5c31af7Sopenharmony_ci if ((size_t)count != requirements.size()) 359e5c31af7Sopenharmony_ci TCU_FAIL("Returned sparse image memory requirements count changes between queries"); 360e5c31af7Sopenharmony_ci } 361e5c31af7Sopenharmony_ci 362e5c31af7Sopenharmony_ci std::vector<vk::VkSparseImageMemoryRequirements> result(requirements.size()); 363e5c31af7Sopenharmony_ci std::transform(requirements.begin(), requirements.end(), result.begin(), 364e5c31af7Sopenharmony_ci [](const VkSparseImageMemoryRequirements2& item) { return item.memoryRequirements; }); 365e5c31af7Sopenharmony_ci 366e5c31af7Sopenharmony_ci return result; 367e5c31af7Sopenharmony_ci} 368e5c31af7Sopenharmony_ci#endif // CTS_USES_VULKANSC 369e5c31af7Sopenharmony_ci 370e5c31af7Sopenharmony_ciVkMemoryRequirements getBufferMemoryRequirements (const DeviceInterface& vk, VkDevice device, VkBuffer buffer) 371e5c31af7Sopenharmony_ci{ 372e5c31af7Sopenharmony_ci VkMemoryRequirements req; 373e5c31af7Sopenharmony_ci vk.getBufferMemoryRequirements(device, buffer, &req); 374e5c31af7Sopenharmony_ci return req; 375e5c31af7Sopenharmony_ci} 376e5c31af7Sopenharmony_ci 377e5c31af7Sopenharmony_ciVkMemoryRequirements getImageMemoryRequirements (const DeviceInterface& vk, VkDevice device, VkImage image) 378e5c31af7Sopenharmony_ci{ 379e5c31af7Sopenharmony_ci VkMemoryRequirements req; 380e5c31af7Sopenharmony_ci vk.getImageMemoryRequirements(device, image, &req); 381e5c31af7Sopenharmony_ci return req; 382e5c31af7Sopenharmony_ci} 383e5c31af7Sopenharmony_ci 384e5c31af7Sopenharmony_ciVkMemoryRequirements getImagePlaneMemoryRequirements (const DeviceInterface& vkd, 385e5c31af7Sopenharmony_ci VkDevice device, 386e5c31af7Sopenharmony_ci VkImage image, 387e5c31af7Sopenharmony_ci VkImageAspectFlagBits planeAspect) 388e5c31af7Sopenharmony_ci{ 389e5c31af7Sopenharmony_ci VkImageMemoryRequirementsInfo2 coreInfo; 390e5c31af7Sopenharmony_ci VkImagePlaneMemoryRequirementsInfo planeInfo; 391e5c31af7Sopenharmony_ci VkMemoryRequirements2 reqs; 392e5c31af7Sopenharmony_ci 393e5c31af7Sopenharmony_ci deMemset(&coreInfo, 0, sizeof(coreInfo)); 394e5c31af7Sopenharmony_ci deMemset(&planeInfo, 0, sizeof(planeInfo)); 395e5c31af7Sopenharmony_ci deMemset(&reqs, 0, sizeof(reqs)); 396e5c31af7Sopenharmony_ci 397e5c31af7Sopenharmony_ci coreInfo.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_REQUIREMENTS_INFO_2; 398e5c31af7Sopenharmony_ci coreInfo.pNext = &planeInfo; 399e5c31af7Sopenharmony_ci coreInfo.image = image; 400e5c31af7Sopenharmony_ci 401e5c31af7Sopenharmony_ci planeInfo.sType = VK_STRUCTURE_TYPE_IMAGE_PLANE_MEMORY_REQUIREMENTS_INFO; 402e5c31af7Sopenharmony_ci planeInfo.planeAspect = planeAspect; 403e5c31af7Sopenharmony_ci 404e5c31af7Sopenharmony_ci reqs.sType = VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2; 405e5c31af7Sopenharmony_ci 406e5c31af7Sopenharmony_ci vkd.getImageMemoryRequirements2(device, &coreInfo, &reqs); 407e5c31af7Sopenharmony_ci 408e5c31af7Sopenharmony_ci return reqs.memoryRequirements; 409e5c31af7Sopenharmony_ci} 410e5c31af7Sopenharmony_ci 411e5c31af7Sopenharmony_civector<VkLayerProperties> enumerateInstanceLayerProperties (const PlatformInterface& vkp) 412e5c31af7Sopenharmony_ci{ 413e5c31af7Sopenharmony_ci vector<VkLayerProperties> properties; 414e5c31af7Sopenharmony_ci deUint32 numLayers = 0; 415e5c31af7Sopenharmony_ci 416e5c31af7Sopenharmony_ci VK_CHECK(vkp.enumerateInstanceLayerProperties(&numLayers, DE_NULL)); 417e5c31af7Sopenharmony_ci 418e5c31af7Sopenharmony_ci if (numLayers > 0) 419e5c31af7Sopenharmony_ci { 420e5c31af7Sopenharmony_ci properties.resize(numLayers); 421e5c31af7Sopenharmony_ci VK_CHECK(vkp.enumerateInstanceLayerProperties(&numLayers, &properties[0])); 422e5c31af7Sopenharmony_ci TCU_CHECK((size_t)numLayers == properties.size()); 423e5c31af7Sopenharmony_ci } 424e5c31af7Sopenharmony_ci 425e5c31af7Sopenharmony_ci return properties; 426e5c31af7Sopenharmony_ci} 427e5c31af7Sopenharmony_ci 428e5c31af7Sopenharmony_civector<VkExtensionProperties> enumerateInstanceExtensionProperties (const PlatformInterface& vkp, const char* layerName) 429e5c31af7Sopenharmony_ci{ 430e5c31af7Sopenharmony_ci vector<VkExtensionProperties> properties; 431e5c31af7Sopenharmony_ci deUint32 numExtensions = 0; 432e5c31af7Sopenharmony_ci 433e5c31af7Sopenharmony_ci VK_CHECK(vkp.enumerateInstanceExtensionProperties(layerName, &numExtensions, DE_NULL)); 434e5c31af7Sopenharmony_ci 435e5c31af7Sopenharmony_ci if (numExtensions > 0) 436e5c31af7Sopenharmony_ci { 437e5c31af7Sopenharmony_ci properties.resize(numExtensions); 438e5c31af7Sopenharmony_ci VK_CHECK(vkp.enumerateInstanceExtensionProperties(layerName, &numExtensions, &properties[0])); 439e5c31af7Sopenharmony_ci TCU_CHECK((size_t)numExtensions == properties.size()); 440e5c31af7Sopenharmony_ci } 441e5c31af7Sopenharmony_ci 442e5c31af7Sopenharmony_ci return properties; 443e5c31af7Sopenharmony_ci} 444e5c31af7Sopenharmony_ci 445e5c31af7Sopenharmony_civector<VkLayerProperties> enumerateDeviceLayerProperties (const InstanceInterface& vki, VkPhysicalDevice physicalDevice) 446e5c31af7Sopenharmony_ci{ 447e5c31af7Sopenharmony_ci vector<VkLayerProperties> properties; 448e5c31af7Sopenharmony_ci deUint32 numLayers = 0; 449e5c31af7Sopenharmony_ci 450e5c31af7Sopenharmony_ci VK_CHECK(vki.enumerateDeviceLayerProperties(physicalDevice, &numLayers, DE_NULL)); 451e5c31af7Sopenharmony_ci 452e5c31af7Sopenharmony_ci if (numLayers > 0) 453e5c31af7Sopenharmony_ci { 454e5c31af7Sopenharmony_ci properties.resize(numLayers); 455e5c31af7Sopenharmony_ci VK_CHECK(vki.enumerateDeviceLayerProperties(physicalDevice, &numLayers, &properties[0])); 456e5c31af7Sopenharmony_ci TCU_CHECK((size_t)numLayers == properties.size()); 457e5c31af7Sopenharmony_ci } 458e5c31af7Sopenharmony_ci 459e5c31af7Sopenharmony_ci return properties; 460e5c31af7Sopenharmony_ci} 461e5c31af7Sopenharmony_ci 462e5c31af7Sopenharmony_civector<VkExtensionProperties> enumerateDeviceExtensionProperties (const InstanceInterface& vki, VkPhysicalDevice physicalDevice, const char* layerName) 463e5c31af7Sopenharmony_ci{ 464e5c31af7Sopenharmony_ci vector<VkExtensionProperties> properties; 465e5c31af7Sopenharmony_ci deUint32 numExtensions = 0; 466e5c31af7Sopenharmony_ci 467e5c31af7Sopenharmony_ci VK_CHECK(vki.enumerateDeviceExtensionProperties(physicalDevice, layerName, &numExtensions, DE_NULL)); 468e5c31af7Sopenharmony_ci 469e5c31af7Sopenharmony_ci if (numExtensions > 0) 470e5c31af7Sopenharmony_ci { 471e5c31af7Sopenharmony_ci properties.resize(numExtensions); 472e5c31af7Sopenharmony_ci VK_CHECK(vki.enumerateDeviceExtensionProperties(physicalDevice, layerName, &numExtensions, &properties[0])); 473e5c31af7Sopenharmony_ci TCU_CHECK((size_t)numExtensions == properties.size()); 474e5c31af7Sopenharmony_ci } 475e5c31af7Sopenharmony_ci 476e5c31af7Sopenharmony_ci return properties; 477e5c31af7Sopenharmony_ci} 478e5c31af7Sopenharmony_ci 479e5c31af7Sopenharmony_cinamespace 480e5c31af7Sopenharmony_ci{ 481e5c31af7Sopenharmony_ci 482e5c31af7Sopenharmony_ciclass ExtensionPropertiesCache 483e5c31af7Sopenharmony_ci{ 484e5c31af7Sopenharmony_ciprotected: 485e5c31af7Sopenharmony_ci typedef std::pair<const InstanceInterface*, VkPhysicalDevice> key_type; 486e5c31af7Sopenharmony_ci typedef std::unique_ptr<std::vector<VkExtensionProperties>> value_type; 487e5c31af7Sopenharmony_ci 488e5c31af7Sopenharmony_cipublic: 489e5c31af7Sopenharmony_ci ExtensionPropertiesCache () {} 490e5c31af7Sopenharmony_ci 491e5c31af7Sopenharmony_ci const std::vector<VkExtensionProperties>* get (const InstanceInterface& vki, VkPhysicalDevice dev) 492e5c31af7Sopenharmony_ci { 493e5c31af7Sopenharmony_ci const key_type key(&vki, dev); 494e5c31af7Sopenharmony_ci const auto itr = m_cache.find(key); 495e5c31af7Sopenharmony_ci if (itr == m_cache.end()) 496e5c31af7Sopenharmony_ci return nullptr; 497e5c31af7Sopenharmony_ci return itr->second.get(); 498e5c31af7Sopenharmony_ci } 499e5c31af7Sopenharmony_ci 500e5c31af7Sopenharmony_ci void add (const InstanceInterface& vki, VkPhysicalDevice dev, const std::vector<VkExtensionProperties>& vec) 501e5c31af7Sopenharmony_ci { 502e5c31af7Sopenharmony_ci const key_type key(&vki, dev); 503e5c31af7Sopenharmony_ci m_cache[key].reset(new std::vector<VkExtensionProperties>(vec)); 504e5c31af7Sopenharmony_ci } 505e5c31af7Sopenharmony_ci 506e5c31af7Sopenharmony_ciprotected: 507e5c31af7Sopenharmony_ci std::map<key_type, value_type> m_cache; 508e5c31af7Sopenharmony_ci}; 509e5c31af7Sopenharmony_ci 510e5c31af7Sopenharmony_ci} // anonymous namespace 511e5c31af7Sopenharmony_ci 512e5c31af7Sopenharmony_ci// Uses a global cache to avoid copying so many results and obtaining extension lists over and over again. 513e5c31af7Sopenharmony_ciconst std::vector<VkExtensionProperties>& enumerateCachedDeviceExtensionProperties (const InstanceInterface& vki, VkPhysicalDevice physicalDevice) 514e5c31af7Sopenharmony_ci{ 515e5c31af7Sopenharmony_ci // Find extension properties in the cache. 516e5c31af7Sopenharmony_ci static ExtensionPropertiesCache m_extensionPropertiesCache; 517e5c31af7Sopenharmony_ci auto supportedExtensions = m_extensionPropertiesCache.get(vki, physicalDevice); 518e5c31af7Sopenharmony_ci 519e5c31af7Sopenharmony_ci if (!supportedExtensions) 520e5c31af7Sopenharmony_ci { 521e5c31af7Sopenharmony_ci const auto enumeratedExtensions = enumerateDeviceExtensionProperties(vki, physicalDevice, nullptr); 522e5c31af7Sopenharmony_ci m_extensionPropertiesCache.add(vki, physicalDevice, enumeratedExtensions); 523e5c31af7Sopenharmony_ci supportedExtensions = m_extensionPropertiesCache.get(vki, physicalDevice); 524e5c31af7Sopenharmony_ci } 525e5c31af7Sopenharmony_ci 526e5c31af7Sopenharmony_ci return *supportedExtensions; 527e5c31af7Sopenharmony_ci} 528e5c31af7Sopenharmony_ci 529e5c31af7Sopenharmony_cibool isShaderStageSupported (const VkPhysicalDeviceFeatures& deviceFeatures, VkShaderStageFlagBits stage) 530e5c31af7Sopenharmony_ci{ 531e5c31af7Sopenharmony_ci if (stage == VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT || stage == VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT) 532e5c31af7Sopenharmony_ci return deviceFeatures.tessellationShader == VK_TRUE; 533e5c31af7Sopenharmony_ci else if (stage == VK_SHADER_STAGE_GEOMETRY_BIT) 534e5c31af7Sopenharmony_ci return deviceFeatures.geometryShader == VK_TRUE; 535e5c31af7Sopenharmony_ci else 536e5c31af7Sopenharmony_ci return true; 537e5c31af7Sopenharmony_ci} 538e5c31af7Sopenharmony_ci 539e5c31af7Sopenharmony_cibool isCompatible (const VkExtensionProperties& extensionProperties, const RequiredExtension& required) 540e5c31af7Sopenharmony_ci{ 541e5c31af7Sopenharmony_ci if (required.name != extensionProperties.extensionName) 542e5c31af7Sopenharmony_ci return false; 543e5c31af7Sopenharmony_ci 544e5c31af7Sopenharmony_ci if (required.minVersion && required.minVersion.get() > extensionProperties.specVersion) 545e5c31af7Sopenharmony_ci return false; 546e5c31af7Sopenharmony_ci 547e5c31af7Sopenharmony_ci if (required.maxVersion && required.maxVersion.get() < extensionProperties.specVersion) 548e5c31af7Sopenharmony_ci return false; 549e5c31af7Sopenharmony_ci 550e5c31af7Sopenharmony_ci return true; 551e5c31af7Sopenharmony_ci} 552e5c31af7Sopenharmony_ci 553e5c31af7Sopenharmony_cibool isCompatible (const VkLayerProperties& layerProperties, const RequiredLayer& required) 554e5c31af7Sopenharmony_ci{ 555e5c31af7Sopenharmony_ci if (required.name != layerProperties.layerName) 556e5c31af7Sopenharmony_ci return false; 557e5c31af7Sopenharmony_ci 558e5c31af7Sopenharmony_ci if (required.minSpecVersion && required.minSpecVersion.get() > layerProperties.specVersion) 559e5c31af7Sopenharmony_ci return false; 560e5c31af7Sopenharmony_ci 561e5c31af7Sopenharmony_ci if (required.maxSpecVersion && required.maxSpecVersion.get() < layerProperties.specVersion) 562e5c31af7Sopenharmony_ci return false; 563e5c31af7Sopenharmony_ci 564e5c31af7Sopenharmony_ci if (required.minImplVersion && required.minImplVersion.get() > layerProperties.implementationVersion) 565e5c31af7Sopenharmony_ci return false; 566e5c31af7Sopenharmony_ci 567e5c31af7Sopenharmony_ci if (required.maxImplVersion && required.maxImplVersion.get() < layerProperties.implementationVersion) 568e5c31af7Sopenharmony_ci return false; 569e5c31af7Sopenharmony_ci 570e5c31af7Sopenharmony_ci return true; 571e5c31af7Sopenharmony_ci} 572e5c31af7Sopenharmony_ci 573e5c31af7Sopenharmony_cibool isExtensionStructSupported (const std::vector<VkExtensionProperties>& extensions, const RequiredExtension& required) 574e5c31af7Sopenharmony_ci{ 575e5c31af7Sopenharmony_ci return isExtensionStructSupported(extensions.begin(), extensions.end(), required); 576e5c31af7Sopenharmony_ci} 577e5c31af7Sopenharmony_ci 578e5c31af7Sopenharmony_cibool isExtensionStructSupported (const vector<std::string>& extensionStrings, const std::string& extensionName) 579e5c31af7Sopenharmony_ci{ 580e5c31af7Sopenharmony_ci return de::contains(extensionStrings.begin(), extensionStrings.end(), extensionName); 581e5c31af7Sopenharmony_ci} 582e5c31af7Sopenharmony_ci 583e5c31af7Sopenharmony_cibool isInstanceExtensionSupported(const deUint32 instanceVersion, const std::vector<std::string>& extensions, const std::string& required) 584e5c31af7Sopenharmony_ci{ 585e5c31af7Sopenharmony_ci // NOTE: this function is only needed in few cases during creation of context, 586e5c31af7Sopenharmony_ci // dont use it, call Context::isInstanceFunctionalitySupported instead 587e5c31af7Sopenharmony_ci if (isCoreInstanceExtension(instanceVersion, required)) 588e5c31af7Sopenharmony_ci return true; 589e5c31af7Sopenharmony_ci return de::contains(extensions.begin(), extensions.end(), required); 590e5c31af7Sopenharmony_ci} 591e5c31af7Sopenharmony_ci 592e5c31af7Sopenharmony_cibool isLayerSupported (const std::vector<VkLayerProperties>& layers, const RequiredLayer& required) 593e5c31af7Sopenharmony_ci{ 594e5c31af7Sopenharmony_ci return isLayerSupported(layers.begin(), layers.end(), required); 595e5c31af7Sopenharmony_ci} 596e5c31af7Sopenharmony_ci 597e5c31af7Sopenharmony_ciVkQueue getDeviceQueue (const DeviceInterface& vkd, VkDevice device, deUint32 queueFamilyIndex, deUint32 queueIndex) 598e5c31af7Sopenharmony_ci{ 599e5c31af7Sopenharmony_ci VkQueue queue; 600e5c31af7Sopenharmony_ci 601e5c31af7Sopenharmony_ci vkd.getDeviceQueue(device, queueFamilyIndex, queueIndex, &queue); 602e5c31af7Sopenharmony_ci 603e5c31af7Sopenharmony_ci return queue; 604e5c31af7Sopenharmony_ci} 605e5c31af7Sopenharmony_ci 606e5c31af7Sopenharmony_ciVkQueue getDeviceQueue2 (const DeviceInterface& vkd, VkDevice device, const VkDeviceQueueInfo2* queueInfo) 607e5c31af7Sopenharmony_ci{ 608e5c31af7Sopenharmony_ci VkQueue queue; 609e5c31af7Sopenharmony_ci 610e5c31af7Sopenharmony_ci vkd.getDeviceQueue2(device, queueInfo, &queue); 611e5c31af7Sopenharmony_ci 612e5c31af7Sopenharmony_ci return queue; 613e5c31af7Sopenharmony_ci} 614e5c31af7Sopenharmony_ci 615e5c31af7Sopenharmony_ciconst void* findStructureInChain (const void* first, VkStructureType type) 616e5c31af7Sopenharmony_ci{ 617e5c31af7Sopenharmony_ci struct StructureBase 618e5c31af7Sopenharmony_ci { 619e5c31af7Sopenharmony_ci VkStructureType sType; 620e5c31af7Sopenharmony_ci void* pNext; 621e5c31af7Sopenharmony_ci }; 622e5c31af7Sopenharmony_ci 623e5c31af7Sopenharmony_ci const StructureBase* cur = reinterpret_cast<const StructureBase*>(first); 624e5c31af7Sopenharmony_ci 625e5c31af7Sopenharmony_ci while (cur) 626e5c31af7Sopenharmony_ci { 627e5c31af7Sopenharmony_ci if (cur->sType == type) 628e5c31af7Sopenharmony_ci break; 629e5c31af7Sopenharmony_ci else 630e5c31af7Sopenharmony_ci cur = reinterpret_cast<const StructureBase*>(cur->pNext); 631e5c31af7Sopenharmony_ci } 632e5c31af7Sopenharmony_ci 633e5c31af7Sopenharmony_ci return cur; 634e5c31af7Sopenharmony_ci} 635e5c31af7Sopenharmony_ci 636e5c31af7Sopenharmony_civoid* findStructureInChain (void* first, VkStructureType type) 637e5c31af7Sopenharmony_ci{ 638e5c31af7Sopenharmony_ci return const_cast<void*>(findStructureInChain(const_cast<const void*>(first), type)); 639e5c31af7Sopenharmony_ci} 640e5c31af7Sopenharmony_ci 641e5c31af7Sopenharmony_civoid appendStructurePtrToVulkanChain (const void** chainHead, const void* structurePtr) 642e5c31af7Sopenharmony_ci{ 643e5c31af7Sopenharmony_ci struct StructureBase 644e5c31af7Sopenharmony_ci { 645e5c31af7Sopenharmony_ci VkStructureType sType; 646e5c31af7Sopenharmony_ci const void* pNext; 647e5c31af7Sopenharmony_ci }; 648e5c31af7Sopenharmony_ci 649e5c31af7Sopenharmony_ci while (*chainHead != DE_NULL) 650e5c31af7Sopenharmony_ci { 651e5c31af7Sopenharmony_ci StructureBase* ptr = (StructureBase*)(*chainHead); 652e5c31af7Sopenharmony_ci 653e5c31af7Sopenharmony_ci chainHead = &(ptr->pNext); 654e5c31af7Sopenharmony_ci } 655e5c31af7Sopenharmony_ci 656e5c31af7Sopenharmony_ci (*chainHead) = structurePtr; 657e5c31af7Sopenharmony_ci} 658e5c31af7Sopenharmony_ci 659e5c31af7Sopenharmony_ci// getStructureType<T> implementations 660e5c31af7Sopenharmony_ci#include "vkGetStructureTypeImpl.inl" 661e5c31af7Sopenharmony_ci 662e5c31af7Sopenharmony_ci} // vk 663