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