Home | History | Annotate | Download | only in Vulkan
      1 // Copyright 2018 The SwiftShader Authors. All Rights Reserved.
      2 //
      3 // Licensed under the Apache License, Version 2.0 (the "License");
      4 // you may not use this file except in compliance with the License.
      5 // You may obtain a copy of the License at
      6 //
      7 //    http://www.apache.org/licenses/LICENSE-2.0
      8 //
      9 // Unless required by applicable law or agreed to in writing, software
     10 // distributed under the License is distributed on an "AS IS" BASIS,
     11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     12 // See the License for the specific language governing permissions and
     13 // limitations under the License.
     14 
     15 #include "VkBuffer.hpp"
     16 #include "VkBufferView.hpp"
     17 #include "VkCommandBuffer.hpp"
     18 #include "VkCommandPool.hpp"
     19 #include "VkConfig.h"
     20 #include "VkDebug.hpp"
     21 #include "VkDescriptorPool.hpp"
     22 #include "VkDescriptorSetLayout.hpp"
     23 #include "VkDestroy.h"
     24 #include "VkDevice.hpp"
     25 #include "VkDeviceMemory.hpp"
     26 #include "VkEvent.hpp"
     27 #include "VkFence.hpp"
     28 #include "VkFramebuffer.hpp"
     29 #include "VkGetProcAddress.h"
     30 #include "VkImage.hpp"
     31 #include "VkImageView.hpp"
     32 #include "VkInstance.hpp"
     33 #include "VkPhysicalDevice.hpp"
     34 #include "VkPipeline.hpp"
     35 #include "VkPipelineCache.hpp"
     36 #include "VkPipelineLayout.hpp"
     37 #include "VkQueryPool.hpp"
     38 #include "VkQueue.hpp"
     39 #include "VkSampler.hpp"
     40 #include "VkSemaphore.hpp"
     41 #include "VkShaderModule.hpp"
     42 #include "VkRenderPass.hpp"
     43 
     44 #include <algorithm>
     45 #include <cstring>
     46 #include <string>
     47 
     48 extern "C"
     49 {
     50 VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vk_icdGetInstanceProcAddr(VkInstance instance, const char* pName)
     51 {
     52 	TRACE("(VkInstance instance = 0x%X, const char* pName = 0x%X)", instance, pName);
     53 
     54 	return vk::GetInstanceProcAddr(instance, pName);
     55 }
     56 
     57 VKAPI_ATTR VkResult VKAPI_CALL vkCreateInstance(const VkInstanceCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkInstance* pInstance)
     58 {
     59 	TRACE("(const VkInstanceCreateInfo* pCreateInfo = 0x%X, const VkAllocationCallbacks* pAllocator = 0x%X, VkInstance* pInstance = 0x%X)",
     60 			pCreateInfo, pAllocator, pInstance);
     61 
     62 	if(pCreateInfo->enabledLayerCount)
     63 	{
     64 		UNIMPLEMENTED();
     65 	}
     66 
     67 	if(pCreateInfo->enabledExtensionCount)
     68 	{
     69 		UNIMPLEMENTED();
     70 	}
     71 
     72 	if(pCreateInfo->pNext)
     73 	{
     74 		switch(*reinterpret_cast<const VkStructureType*>(pCreateInfo->pNext))
     75 		{
     76 		case VK_STRUCTURE_TYPE_LOADER_INSTANCE_CREATE_INFO:
     77 			// According to the Vulkan spec, section 2.7.2. Implicit Valid Usage:
     78 			// "The values VK_STRUCTURE_TYPE_LOADER_INSTANCE_CREATE_INFO and
     79 			//  VK_STRUCTURE_TYPE_LOADER_DEVICE_CREATE_INFO are reserved for
     80 			//  internal use by the loader, and do not have corresponding
     81 			//  Vulkan structures in this Specification."
     82 			break;
     83 		default:
     84 			UNIMPLEMENTED();
     85 		}
     86 	}
     87 
     88 	*pInstance = VK_NULL_HANDLE;
     89 	VkPhysicalDevice physicalDevice = VK_NULL_HANDLE;
     90 
     91 	VkResult result = vk::DispatchablePhysicalDevice::Create(pAllocator, pCreateInfo, &physicalDevice);
     92 	if(result != VK_SUCCESS)
     93 	{
     94 		return result;
     95 	}
     96 
     97 	vk::Instance::CreateInfo info =
     98 	{
     99 		pCreateInfo,
    100 		physicalDevice
    101 	};
    102 
    103 	result = vk::DispatchableInstance::Create(pAllocator, &info, pInstance);
    104 	if(result != VK_SUCCESS)
    105 	{
    106 		vk::destroy(physicalDevice, pAllocator);
    107 		return result;
    108 	}
    109 
    110 	return result;
    111 }
    112 
    113 VKAPI_ATTR void VKAPI_CALL vkDestroyInstance(VkInstance instance, const VkAllocationCallbacks* pAllocator)
    114 {
    115 	TRACE("(VkInstance instance = 0x%X, const VkAllocationCallbacks* pAllocator = 0x%X)", instance, pAllocator);
    116 
    117 	vk::destroy(instance, pAllocator);
    118 }
    119 
    120 VKAPI_ATTR VkResult VKAPI_CALL vkEnumeratePhysicalDevices(VkInstance instance, uint32_t* pPhysicalDeviceCount, VkPhysicalDevice* pPhysicalDevices)
    121 {
    122 	TRACE("(VkInstance instance = 0x%X, uint32_t* pPhysicalDeviceCount = 0x%X, VkPhysicalDevice* pPhysicalDevices = 0x%X)",
    123 		    instance, pPhysicalDeviceCount, pPhysicalDevices);
    124 
    125 	if(!pPhysicalDevices)
    126 	{
    127 		*pPhysicalDeviceCount = vk::Cast(instance)->getPhysicalDeviceCount();
    128 	}
    129 	else
    130 	{
    131 		vk::Cast(instance)->getPhysicalDevices(*pPhysicalDeviceCount, pPhysicalDevices);
    132 	}
    133 
    134 	return VK_SUCCESS;
    135 }
    136 
    137 VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceFeatures(VkPhysicalDevice physicalDevice, VkPhysicalDeviceFeatures* pFeatures)
    138 {
    139 	TRACE("(VkPhysicalDevice physicalDevice = 0x%X, VkPhysicalDeviceFeatures* pFeatures = 0x%X)",
    140 			physicalDevice, pFeatures);
    141 
    142 	*pFeatures = vk::Cast(physicalDevice)->getFeatures();
    143 }
    144 
    145 VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceFormatProperties(VkPhysicalDevice physicalDevice, VkFormat format, VkFormatProperties* pFormatProperties)
    146 {
    147 	TRACE("GetPhysicalDeviceFormatProperties(VkPhysicalDevice physicalDevice = 0x%X, VkFormat format = %d, VkFormatProperties* pFormatProperties = 0x%X)",
    148 			physicalDevice, (int)format, pFormatProperties);
    149 
    150 	vk::Cast(physicalDevice)->getFormatProperties(format, pFormatProperties);
    151 }
    152 
    153 VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceImageFormatProperties(VkPhysicalDevice physicalDevice, VkFormat format, VkImageType type, VkImageTiling tiling, VkImageUsageFlags usage, VkImageCreateFlags flags, VkImageFormatProperties* pImageFormatProperties)
    154 {
    155 	TRACE("(VkPhysicalDevice physicalDevice = 0x%X, VkFormat format = %d, VkImageType type = %d, VkImageTiling tiling = %d, VkImageUsageFlags usage = %d, VkImageCreateFlags flags = %d, VkImageFormatProperties* pImageFormatProperties = 0x%X)",
    156 			physicalDevice, (int)format, (int)type, (int)tiling, usage, flags, pImageFormatProperties);
    157 
    158 	VkFormatProperties properties;
    159 	vk::Cast(physicalDevice)->getFormatProperties(format, &properties);
    160 
    161 	switch (tiling)
    162 	{
    163 	case VK_IMAGE_TILING_LINEAR:
    164 		if (properties.linearTilingFeatures == 0) return VK_ERROR_FORMAT_NOT_SUPPORTED;
    165 		break;
    166 
    167 	case VK_IMAGE_TILING_OPTIMAL:
    168 		if (properties.optimalTilingFeatures == 0) return VK_ERROR_FORMAT_NOT_SUPPORTED;
    169 		break;
    170 
    171 	default:
    172 		UNIMPLEMENTED();
    173 	}
    174 
    175 	vk::Cast(physicalDevice)->getImageFormatProperties(format, type, tiling, usage, flags, pImageFormatProperties);
    176 
    177 	return VK_SUCCESS;
    178 }
    179 
    180 VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceProperties(VkPhysicalDevice physicalDevice, VkPhysicalDeviceProperties* pProperties)
    181 {
    182 	TRACE("(VkPhysicalDevice physicalDevice = 0x%X, VkPhysicalDeviceProperties* pProperties = 0x%X)",
    183 		    physicalDevice, pProperties);
    184 
    185 	*pProperties = vk::Cast(physicalDevice)->getProperties();
    186 }
    187 
    188 VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceQueueFamilyProperties(VkPhysicalDevice physicalDevice, uint32_t* pQueueFamilyPropertyCount, VkQueueFamilyProperties* pQueueFamilyProperties)
    189 {
    190 	TRACE("(VkPhysicalDevice physicalDevice = 0x%X, uint32_t* pQueueFamilyPropertyCount = 0x%X, VkQueueFamilyProperties* pQueueFamilyProperties = 0x%X))", physicalDevice, pQueueFamilyPropertyCount, pQueueFamilyProperties);
    191 
    192 	if(!pQueueFamilyProperties)
    193 	{
    194 		*pQueueFamilyPropertyCount = vk::Cast(physicalDevice)->getQueueFamilyPropertyCount();
    195 	}
    196 	else
    197 	{
    198 		vk::Cast(physicalDevice)->getQueueFamilyProperties(*pQueueFamilyPropertyCount, pQueueFamilyProperties);
    199 	}
    200 }
    201 
    202 VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceMemoryProperties(VkPhysicalDevice physicalDevice, VkPhysicalDeviceMemoryProperties* pMemoryProperties)
    203 {
    204 	TRACE("(VkPhysicalDevice physicalDevice = 0x%X, VkPhysicalDeviceMemoryProperties* pMemoryProperties = 0x%X)", physicalDevice, pMemoryProperties);
    205 
    206 	*pMemoryProperties = vk::Cast(physicalDevice)->getMemoryProperties();
    207 }
    208 
    209 VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vkGetInstanceProcAddr(VkInstance instance, const char* pName)
    210 {
    211 	TRACE("(VkInstance instance = 0x%X, const char* pName = 0x%X)", instance, pName);
    212 
    213 	return vk::GetInstanceProcAddr(instance, pName);
    214 }
    215 
    216 VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vkGetDeviceProcAddr(VkDevice device, const char* pName)
    217 {
    218 	TRACE("(VkDevice device = 0x%X, const char* pName = 0x%X)", device, pName);
    219 
    220 	return vk::GetDeviceProcAddr(device, pName);
    221 }
    222 
    223 VKAPI_ATTR VkResult VKAPI_CALL vkCreateDevice(VkPhysicalDevice physicalDevice, const VkDeviceCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkDevice* pDevice)
    224 {
    225 	TRACE("(VkPhysicalDevice physicalDevice = 0x%X, const VkDeviceCreateInfo* pCreateInfo = 0x%X, const VkAllocationCallbacks* pAllocator = 0x%X, VkDevice* pDevice = 0x%X)",
    226 		physicalDevice, pCreateInfo, pAllocator, pDevice);
    227 
    228 	if(pCreateInfo->enabledLayerCount)
    229 	{
    230 		// "The ppEnabledLayerNames and enabledLayerCount members of VkDeviceCreateInfo are deprecated and their values must be ignored by implementations."
    231 		UNIMPLEMENTED();   // TODO(b/119321052): UNIMPLEMENTED() should be used only for features that must still be implemented. Use a more informational macro here.
    232 	}
    233 
    234 	const VkBaseInStructure* extensionCreateInfo = reinterpret_cast<const VkBaseInStructure*>(pCreateInfo->pNext);
    235 
    236 	while(extensionCreateInfo)
    237 	{
    238 		switch(extensionCreateInfo->sType)
    239 		{
    240 		case VK_STRUCTURE_TYPE_LOADER_DEVICE_CREATE_INFO:
    241 			// According to the Vulkan spec, section 2.7.2. Implicit Valid Usage:
    242 			// "The values VK_STRUCTURE_TYPE_LOADER_INSTANCE_CREATE_INFO and
    243 			//  VK_STRUCTURE_TYPE_LOADER_DEVICE_CREATE_INFO are reserved for
    244 			//  internal use by the loader, and do not have corresponding
    245 			//  Vulkan structures in this Specification."
    246 			break;
    247 		case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2:
    248 			{
    249 				ASSERT(!pCreateInfo->pEnabledFeatures);   // "If the pNext chain includes a VkPhysicalDeviceFeatures2 structure, then pEnabledFeatures must be NULL"
    250 
    251 				const VkPhysicalDeviceFeatures2* physicalDeviceFeatures2 = reinterpret_cast<const VkPhysicalDeviceFeatures2*>(extensionCreateInfo);
    252 
    253 				if(!vk::Cast(physicalDevice)->hasFeatures(physicalDeviceFeatures2->features))
    254 				{
    255 					return VK_ERROR_FEATURE_NOT_PRESENT;
    256 				}
    257 			}
    258 			break;
    259 		case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLER_YCBCR_CONVERSION_FEATURES:
    260 			{
    261 				const VkPhysicalDeviceSamplerYcbcrConversionFeatures* samplerYcbcrConversionFeatures = reinterpret_cast<const VkPhysicalDeviceSamplerYcbcrConversionFeatures*>(extensionCreateInfo);
    262 
    263 				if(samplerYcbcrConversionFeatures->samplerYcbcrConversion == VK_TRUE)
    264 				{
    265 					return VK_ERROR_FEATURE_NOT_PRESENT;
    266 				}
    267 			}
    268 			break;
    269 		case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_16BIT_STORAGE_FEATURES:
    270 			{
    271 				const VkPhysicalDevice16BitStorageFeatures* storage16BitFeatures = reinterpret_cast<const VkPhysicalDevice16BitStorageFeatures*>(extensionCreateInfo);
    272 
    273 				if(storage16BitFeatures->storageBuffer16BitAccess == VK_TRUE ||
    274 				   storage16BitFeatures->uniformAndStorageBuffer16BitAccess == VK_TRUE ||
    275 				   storage16BitFeatures->storagePushConstant16 == VK_TRUE ||
    276 				   storage16BitFeatures->storageInputOutput16 == VK_TRUE)
    277 				{
    278 					return VK_ERROR_FEATURE_NOT_PRESENT;
    279 				}
    280 			}
    281 			break;
    282 		case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VARIABLE_POINTER_FEATURES:
    283 			{
    284 				const VkPhysicalDeviceVariablePointerFeatures* variablePointerFeatures = reinterpret_cast<const VkPhysicalDeviceVariablePointerFeatures*>(extensionCreateInfo);
    285 
    286 				if(variablePointerFeatures->variablePointersStorageBuffer == VK_TRUE ||
    287 				   variablePointerFeatures->variablePointers == VK_TRUE)
    288 				{
    289 					return VK_ERROR_FEATURE_NOT_PRESENT;
    290 				}
    291 			}
    292 			break;
    293 		case VK_STRUCTURE_TYPE_DEVICE_GROUP_DEVICE_CREATE_INFO:
    294 			{
    295 				const VkDeviceGroupDeviceCreateInfo* groupDeviceCreateInfo = reinterpret_cast<const VkDeviceGroupDeviceCreateInfo*>(extensionCreateInfo);
    296 
    297 				if((groupDeviceCreateInfo->physicalDeviceCount != 1) ||
    298 				   (groupDeviceCreateInfo->pPhysicalDevices[0] != physicalDevice))
    299 				{
    300 					return VK_ERROR_FEATURE_NOT_PRESENT;
    301 				}
    302 			}
    303 			break;
    304 		default:
    305 			// "the [driver] must skip over, without processing (other than reading the sType and pNext members) any structures in the chain with sType values not defined by [supported extenions]"
    306 			UNIMPLEMENTED();   // TODO(b/119321052): UNIMPLEMENTED() should be used only for features that must still be implemented. Use a more informational macro here.
    307 			break;
    308 		}
    309 
    310 		extensionCreateInfo = extensionCreateInfo->pNext;
    311 	}
    312 
    313 	ASSERT(pCreateInfo->queueCreateInfoCount > 0);
    314 
    315 	if(pCreateInfo->pEnabledFeatures)
    316 	{
    317 		if(!vk::Cast(physicalDevice)->hasFeatures(*(pCreateInfo->pEnabledFeatures)))
    318 		{
    319 			UNIMPLEMENTED();
    320 			return VK_ERROR_FEATURE_NOT_PRESENT;
    321 		}
    322 	}
    323 
    324 	uint32_t queueFamilyPropertyCount = vk::Cast(physicalDevice)->getQueueFamilyPropertyCount();
    325 
    326 	for(uint32_t i = 0; i < pCreateInfo->queueCreateInfoCount; i++)
    327 	{
    328 		const VkDeviceQueueCreateInfo& queueCreateInfo = pCreateInfo->pQueueCreateInfos[i];
    329 		if(queueCreateInfo.pNext || queueCreateInfo.flags)
    330 		{
    331 			UNIMPLEMENTED();
    332 		}
    333 
    334 		ASSERT(queueCreateInfo.queueFamilyIndex < queueFamilyPropertyCount);
    335 		(void)queueFamilyPropertyCount; // Silence unused variable warning
    336 	}
    337 
    338 	vk::Device::CreateInfo deviceCreateInfo =
    339 	{
    340 		pCreateInfo,
    341 		physicalDevice
    342 	};
    343 
    344 	return vk::DispatchableDevice::Create(pAllocator, &deviceCreateInfo, pDevice);
    345 }
    346 
    347 VKAPI_ATTR void VKAPI_CALL vkDestroyDevice(VkDevice device, const VkAllocationCallbacks* pAllocator)
    348 {
    349 	TRACE("(VkDevice device = 0x%X, const VkAllocationCallbacks* pAllocator = 0x%X)", device, pAllocator);
    350 
    351 	vk::destroy(device, pAllocator);
    352 }
    353 
    354 VKAPI_ATTR VkResult VKAPI_CALL vkEnumerateInstanceExtensionProperties(const char* pLayerName, uint32_t* pPropertyCount, VkExtensionProperties* pProperties)
    355 {
    356 	TRACE("(const char* pLayerName = 0x%X, uint32_t* pPropertyCount = 0x%X, VkExtensionProperties* pProperties = 0x%X)",
    357 	      pLayerName, pPropertyCount, pProperties);
    358 
    359 	static VkExtensionProperties extensionProperties[] =
    360 	{
    361 		{ VK_KHR_DEVICE_GROUP_CREATION_EXTENSION_NAME, VK_KHR_DEVICE_GROUP_CREATION_SPEC_VERSION },
    362 		{ VK_KHR_EXTERNAL_FENCE_CAPABILITIES_EXTENSION_NAME, VK_KHR_EXTERNAL_FENCE_CAPABILITIES_SPEC_VERSION },
    363 		{ VK_KHR_EXTERNAL_MEMORY_CAPABILITIES_EXTENSION_NAME, VK_KHR_EXTERNAL_MEMORY_CAPABILITIES_SPEC_VERSION },
    364 		{ VK_KHR_EXTERNAL_SEMAPHORE_CAPABILITIES_EXTENSION_NAME, VK_KHR_EXTERNAL_SEMAPHORE_CAPABILITIES_SPEC_VERSION },
    365 		{ VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME, VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_SPEC_VERSION },
    366 	};
    367 
    368 	uint32_t extensionPropertiesCount = sizeof(extensionProperties) / sizeof(extensionProperties[0]);
    369 
    370 	if(!pProperties)
    371 	{
    372 		*pPropertyCount = extensionPropertiesCount;
    373 		return VK_SUCCESS;
    374 	}
    375 
    376 	for(uint32_t i = 0; i < std::min(*pPropertyCount, extensionPropertiesCount); i++)
    377 	{
    378 		pProperties[i] = extensionProperties[i];
    379 	}
    380 
    381 	return (*pPropertyCount < extensionPropertiesCount) ? VK_INCOMPLETE : VK_SUCCESS;
    382 }
    383 
    384 VKAPI_ATTR VkResult VKAPI_CALL vkEnumerateDeviceExtensionProperties(VkPhysicalDevice physicalDevice, const char* pLayerName, uint32_t* pPropertyCount, VkExtensionProperties* pProperties)
    385 {
    386 	TRACE("(VkPhysicalDevice physicalDevice = 0x%X, const char* pLayerName, uint32_t* pPropertyCount = 0x%X, VkExtensionProperties* pProperties = 0x%X)", physicalDevice, pPropertyCount, pProperties);
    387 
    388 	static VkExtensionProperties extensionProperties[] =
    389 	{
    390 		{ VK_KHR_16BIT_STORAGE_EXTENSION_NAME, VK_KHR_16BIT_STORAGE_SPEC_VERSION },
    391 		{ VK_KHR_BIND_MEMORY_2_EXTENSION_NAME, VK_KHR_BIND_MEMORY_2_SPEC_VERSION },
    392 		{ VK_KHR_DEDICATED_ALLOCATION_EXTENSION_NAME, VK_KHR_DEDICATED_ALLOCATION_SPEC_VERSION },
    393 		{ VK_KHR_DESCRIPTOR_UPDATE_TEMPLATE_EXTENSION_NAME, VK_KHR_DESCRIPTOR_UPDATE_TEMPLATE_SPEC_VERSION },
    394 		{ VK_KHR_DEVICE_GROUP_EXTENSION_NAME,  VK_KHR_DEVICE_GROUP_SPEC_VERSION },
    395 		{ VK_KHR_EXTERNAL_FENCE_EXTENSION_NAME, VK_KHR_EXTERNAL_FENCE_SPEC_VERSION },
    396 		{ VK_KHR_EXTERNAL_MEMORY_EXTENSION_NAME, VK_KHR_EXTERNAL_MEMORY_SPEC_VERSION },
    397 		{ VK_KHR_EXTERNAL_SEMAPHORE_EXTENSION_NAME, VK_KHR_EXTERNAL_SEMAPHORE_SPEC_VERSION },
    398 		{ VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME, VK_KHR_GET_MEMORY_REQUIREMENTS_2_SPEC_VERSION },
    399 		{ VK_KHR_MAINTENANCE1_EXTENSION_NAME, VK_KHR_MAINTENANCE1_SPEC_VERSION },
    400 		{ VK_KHR_MAINTENANCE2_EXTENSION_NAME, VK_KHR_MAINTENANCE2_SPEC_VERSION },
    401 		{ VK_KHR_MAINTENANCE3_EXTENSION_NAME, VK_KHR_MAINTENANCE3_SPEC_VERSION },
    402 		{ VK_KHR_MULTIVIEW_EXTENSION_NAME, VK_KHR_MULTIVIEW_SPEC_VERSION },
    403 		{ VK_KHR_RELAXED_BLOCK_LAYOUT_EXTENSION_NAME, VK_KHR_RELAXED_BLOCK_LAYOUT_SPEC_VERSION },
    404 		{ VK_KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME, VK_KHR_SAMPLER_YCBCR_CONVERSION_SPEC_VERSION },
    405 		{ VK_KHR_SHADER_DRAW_PARAMETERS_EXTENSION_NAME, VK_KHR_SHADER_DRAW_PARAMETERS_SPEC_VERSION },
    406 		{ VK_KHR_STORAGE_BUFFER_STORAGE_CLASS_EXTENSION_NAME, VK_KHR_STORAGE_BUFFER_STORAGE_CLASS_SPEC_VERSION },
    407 		{ VK_KHR_VARIABLE_POINTERS_EXTENSION_NAME, VK_KHR_VARIABLE_POINTERS_SPEC_VERSION },
    408 	};
    409 
    410 	uint32_t extensionPropertiesCount = sizeof(extensionProperties) / sizeof(extensionProperties[0]);
    411 
    412 	if(!pProperties)
    413 	{
    414 		*pPropertyCount = extensionPropertiesCount;
    415 		return VK_SUCCESS;
    416 	}
    417 
    418 	for(uint32_t i = 0; i < std::min(*pPropertyCount, extensionPropertiesCount); i++)
    419 	{
    420 		pProperties[i] = extensionProperties[i];
    421 	}
    422 
    423 	return (*pPropertyCount < extensionPropertiesCount) ? VK_INCOMPLETE : VK_SUCCESS;
    424 }
    425 
    426 VKAPI_ATTR VkResult VKAPI_CALL vkEnumerateInstanceLayerProperties(uint32_t* pPropertyCount, VkLayerProperties* pProperties)
    427 {
    428 	TRACE("(uint32_t* pPropertyCount = 0x%X, VkLayerProperties* pProperties = 0x%X)", pPropertyCount, pProperties);
    429 
    430 	if(!pProperties)
    431 	{
    432 		*pPropertyCount = 0;
    433 		return VK_SUCCESS;
    434 	}
    435 
    436 	return VK_SUCCESS;
    437 }
    438 
    439 VKAPI_ATTR VkResult VKAPI_CALL vkEnumerateDeviceLayerProperties(VkPhysicalDevice physicalDevice, uint32_t* pPropertyCount, VkLayerProperties* pProperties)
    440 {
    441 	TRACE("(VkPhysicalDevice physicalDevice = 0x%X, uint32_t* pPropertyCount = 0x%X, VkLayerProperties* pProperties = 0x%X)", physicalDevice, pPropertyCount, pProperties);
    442 
    443 	if(!pProperties)
    444 	{
    445 		*pPropertyCount = 0;
    446 		return VK_SUCCESS;
    447 	}
    448 
    449 	return VK_SUCCESS;
    450 }
    451 
    452 VKAPI_ATTR void VKAPI_CALL vkGetDeviceQueue(VkDevice device, uint32_t queueFamilyIndex, uint32_t queueIndex, VkQueue* pQueue)
    453 {
    454 	TRACE("(VkDevice device = 0x%X, uint32_t queueFamilyIndex = %d, uint32_t queueIndex = %d, VkQueue* pQueue = 0x%X)",
    455 		    device, queueFamilyIndex, queueIndex, pQueue);
    456 
    457 	*pQueue = vk::Cast(device)->getQueue(queueFamilyIndex, queueIndex);
    458 }
    459 
    460 VKAPI_ATTR VkResult VKAPI_CALL vkQueueSubmit(VkQueue queue, uint32_t submitCount, const VkSubmitInfo* pSubmits, VkFence fence)
    461 {
    462 	TRACE("(VkQueue queue = 0x%X, uint32_t submitCount = %d, const VkSubmitInfo* pSubmits = 0x%X, VkFence fence = 0x%X)",
    463 	      queue, submitCount, pSubmits, fence);
    464 
    465 	vk::Cast(queue)->submit(submitCount, pSubmits, fence);
    466 
    467 	return VK_SUCCESS;
    468 }
    469 
    470 VKAPI_ATTR VkResult VKAPI_CALL vkQueueWaitIdle(VkQueue queue)
    471 {
    472 	TRACE("(VkQueue queue = 0x%X)", queue);
    473 
    474 	vk::Cast(queue)->waitIdle();
    475 
    476 	return VK_SUCCESS;
    477 }
    478 
    479 VKAPI_ATTR VkResult VKAPI_CALL vkDeviceWaitIdle(VkDevice device)
    480 {
    481 	TRACE("(VkDevice device = 0x%X)", device);
    482 
    483 	vk::Cast(device)->waitIdle();
    484 
    485 	return VK_SUCCESS;
    486 }
    487 
    488 VKAPI_ATTR VkResult VKAPI_CALL vkAllocateMemory(VkDevice device, const VkMemoryAllocateInfo* pAllocateInfo, const VkAllocationCallbacks* pAllocator, VkDeviceMemory* pMemory)
    489 {
    490 	TRACE("(VkDevice device = 0x%X, const VkMemoryAllocateInfo* pAllocateInfo = 0x%X, const VkAllocationCallbacks* pAllocator = 0x%X, VkDeviceMemory* pMemory = 0x%X)",
    491 		    device, pAllocateInfo, pAllocator, pMemory);
    492 
    493 	const VkBaseOutStructure* allocationInfo = reinterpret_cast<const VkBaseOutStructure*>(pAllocateInfo->pNext);
    494 	while(allocationInfo)
    495 	{
    496 		switch(allocationInfo->sType)
    497 		{
    498 		case VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO:
    499 			// This can safely be ignored, as the Vulkan spec mentions:
    500 			// "If the pNext chain includes a VkMemoryDedicatedAllocateInfo structure, then that structure
    501 			//  includes a handle of the sole buffer or image resource that the memory *can* be bound to."
    502 			break;
    503 		default:
    504 			UNIMPLEMENTED();
    505 			break;
    506 		}
    507 
    508 		allocationInfo = allocationInfo->pNext;
    509 	}
    510 
    511 	VkResult result = vk::DeviceMemory::Create(pAllocator, pAllocateInfo, pMemory);
    512 	if(result != VK_SUCCESS)
    513 	{
    514 		return result;
    515 	}
    516 
    517 	// Make sure the memory allocation is done now so that OOM errors can be checked now
    518 	result = vk::Cast(*pMemory)->allocate();
    519 	if(result != VK_SUCCESS)
    520 	{
    521 		vk::destroy(*pMemory, pAllocator);
    522 		*pMemory = VK_NULL_HANDLE;
    523 	}
    524 
    525 	return result;
    526 }
    527 
    528 VKAPI_ATTR void VKAPI_CALL vkFreeMemory(VkDevice device, VkDeviceMemory memory, const VkAllocationCallbacks* pAllocator)
    529 {
    530 	TRACE("(VkDevice device = 0x%X, VkDeviceMemory memory = 0x%X, const VkAllocationCallbacks* pAllocator = 0x%X)",
    531 		    device, memory, pAllocator);
    532 
    533 	vk::destroy(memory, pAllocator);
    534 }
    535 
    536 VKAPI_ATTR VkResult VKAPI_CALL vkMapMemory(VkDevice device, VkDeviceMemory memory, VkDeviceSize offset, VkDeviceSize size, VkMemoryMapFlags flags, void** ppData)
    537 {
    538 	TRACE("(VkDevice device = 0x%X, VkDeviceMemory memory = 0x%X, VkDeviceSize offset = %d, VkDeviceSize size = %d, VkMemoryMapFlags flags = 0x%X, void** ppData = 0x%X)",
    539 		    device, memory, offset, size, flags, ppData);
    540 
    541 	return vk::Cast(memory)->map(offset, size, ppData);
    542 }
    543 
    544 VKAPI_ATTR void VKAPI_CALL vkUnmapMemory(VkDevice device, VkDeviceMemory memory)
    545 {
    546 	TRACE("(VkDevice device = 0x%X, VkDeviceMemory memory = 0x%X)", device, memory);
    547 
    548 	// Noop, memory will be released when the DeviceMemory object is released
    549 }
    550 
    551 VKAPI_ATTR VkResult VKAPI_CALL vkFlushMappedMemoryRanges(VkDevice device, uint32_t memoryRangeCount, const VkMappedMemoryRange* pMemoryRanges)
    552 {
    553 	TRACE("(VkDevice device = 0x%X, uint32_t memoryRangeCount = %d, const VkMappedMemoryRange* pMemoryRanges = 0x%X)",
    554 		    device, memoryRangeCount, pMemoryRanges);
    555 
    556 	// Noop, host and device memory are the same to SwiftShader
    557 
    558 	return VK_SUCCESS;
    559 }
    560 
    561 VKAPI_ATTR VkResult VKAPI_CALL vkInvalidateMappedMemoryRanges(VkDevice device, uint32_t memoryRangeCount, const VkMappedMemoryRange* pMemoryRanges)
    562 {
    563 	TRACE("(VkDevice device = 0x%X, uint32_t memoryRangeCount = %d, const VkMappedMemoryRange* pMemoryRanges = 0x%X)",
    564 		    device, memoryRangeCount, pMemoryRanges);
    565 
    566 	// Noop, host and device memory are the same to SwiftShader
    567 
    568 	return VK_SUCCESS;
    569 }
    570 
    571 VKAPI_ATTR void VKAPI_CALL vkGetDeviceMemoryCommitment(VkDevice pDevice, VkDeviceMemory pMemory, VkDeviceSize* pCommittedMemoryInBytes)
    572 {
    573 	TRACE("(VkDevice device = 0x%X, VkDeviceMemory memory = 0x%X, VkDeviceSize* pCommittedMemoryInBytes = 0x%X)",
    574 	      pDevice, pMemory, pCommittedMemoryInBytes);
    575 
    576 	auto memory = vk::Cast(pMemory);
    577 
    578 #if !defined(NDEBUG) || defined(DCHECK_ALWAYS_ON)
    579 	const auto& memoryProperties = vk::Cast(vk::Cast(pDevice)->getPhysicalDevice())->getMemoryProperties();
    580 	uint32_t typeIndex = memory->getMemoryTypeIndex();
    581 	ASSERT(typeIndex < memoryProperties.memoryTypeCount);
    582 	ASSERT(memoryProperties.memoryTypes[typeIndex].propertyFlags & VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT);
    583 #endif
    584 
    585 	*pCommittedMemoryInBytes = memory->getCommittedMemoryInBytes();
    586 }
    587 
    588 VKAPI_ATTR VkResult VKAPI_CALL vkBindBufferMemory(VkDevice device, VkBuffer buffer, VkDeviceMemory memory, VkDeviceSize memoryOffset)
    589 {
    590 	TRACE("(VkDevice device = 0x%X, VkBuffer buffer = 0x%X, VkDeviceMemory memory = 0x%X, VkDeviceSize memoryOffset = %d)",
    591 		    device, buffer, memory, memoryOffset);
    592 
    593 	vk::Cast(buffer)->bind(memory, memoryOffset);
    594 
    595 	return VK_SUCCESS;
    596 }
    597 
    598 VKAPI_ATTR VkResult VKAPI_CALL vkBindImageMemory(VkDevice device, VkImage image, VkDeviceMemory memory, VkDeviceSize memoryOffset)
    599 {
    600 	TRACE("(VkDevice device = 0x%X, VkImage image = 0x%X, VkDeviceMemory memory = 0x%X, VkDeviceSize memoryOffset = %d)",
    601 		    device, image, memory, memoryOffset);
    602 
    603 	vk::Cast(image)->bind(memory, memoryOffset);
    604 
    605 	return VK_SUCCESS;
    606 }
    607 
    608 VKAPI_ATTR void VKAPI_CALL vkGetBufferMemoryRequirements(VkDevice device, VkBuffer buffer, VkMemoryRequirements* pMemoryRequirements)
    609 {
    610 	TRACE("(VkDevice device = 0x%X, VkBuffer buffer = 0x%X, VkMemoryRequirements* pMemoryRequirements = 0x%X)",
    611 		    device, buffer, pMemoryRequirements);
    612 
    613 	*pMemoryRequirements = vk::Cast(buffer)->getMemoryRequirements();
    614 }
    615 
    616 VKAPI_ATTR void VKAPI_CALL vkGetImageMemoryRequirements(VkDevice device, VkImage image, VkMemoryRequirements* pMemoryRequirements)
    617 {
    618 	TRACE("(VkDevice device = 0x%X, VkImage image = 0x%X, VkMemoryRequirements* pMemoryRequirements = 0x%X)",
    619 		    device, image, pMemoryRequirements);
    620 
    621 	*pMemoryRequirements = vk::Cast(image)->getMemoryRequirements();
    622 }
    623 
    624 VKAPI_ATTR void VKAPI_CALL vkGetImageSparseMemoryRequirements(VkDevice device, VkImage image, uint32_t* pSparseMemoryRequirementCount, VkSparseImageMemoryRequirements* pSparseMemoryRequirements)
    625 {
    626 	TRACE("(VkDevice device, VkImage image, uint32_t* pSparseMemoryRequirementCount, VkSparseImageMemoryRequirements* pSparseMemoryRequirements)",
    627 	      device, image, pSparseMemoryRequirementCount, pSparseMemoryRequirements);
    628 
    629 	// The 'sparseBinding' feature is not supported, so images can not be created with the VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT flag.
    630 	// "If the image was not created with VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT then pSparseMemoryRequirementCount will be set to zero and pSparseMemoryRequirements will not be written to."
    631 	*pSparseMemoryRequirementCount = 0;
    632 }
    633 
    634 VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceSparseImageFormatProperties(VkPhysicalDevice physicalDevice, VkFormat format, VkImageType type, VkSampleCountFlagBits samples, VkImageUsageFlags usage, VkImageTiling tiling, uint32_t* pPropertyCount, VkSparseImageFormatProperties* pProperties)
    635 {
    636 	TRACE("()");
    637 	UNIMPLEMENTED();
    638 }
    639 
    640 VKAPI_ATTR VkResult VKAPI_CALL vkQueueBindSparse(VkQueue queue, uint32_t bindInfoCount, const VkBindSparseInfo* pBindInfo, VkFence fence)
    641 {
    642 	TRACE("()");
    643 	UNIMPLEMENTED();
    644 	return VK_SUCCESS;
    645 }
    646 
    647 VKAPI_ATTR VkResult VKAPI_CALL vkCreateFence(VkDevice device, const VkFenceCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkFence* pFence)
    648 {
    649 	TRACE("(VkDevice device = 0x%X, const VkFenceCreateInfo* pCreateInfo = 0x%X, const VkAllocationCallbacks* pAllocator = 0x%X, VkFence* pFence = 0x%X)",
    650 		    device, pCreateInfo, pAllocator, pFence);
    651 
    652 	if(pCreateInfo->pNext)
    653 	{
    654 		UNIMPLEMENTED();
    655 	}
    656 
    657 	return vk::Fence::Create(pAllocator, pCreateInfo, pFence);
    658 }
    659 
    660 VKAPI_ATTR void VKAPI_CALL vkDestroyFence(VkDevice device, VkFence fence, const VkAllocationCallbacks* pAllocator)
    661 {
    662 	TRACE("(VkDevice device = 0x%X, VkFence fence = 0x%X, const VkAllocationCallbacks* pAllocator = 0x%X)",
    663 		    device, fence, pAllocator);
    664 
    665 
    666 	vk::destroy(fence, pAllocator);
    667 }
    668 
    669 VKAPI_ATTR VkResult VKAPI_CALL vkResetFences(VkDevice device, uint32_t fenceCount, const VkFence* pFences)
    670 {
    671 	TRACE("(VkDevice device = 0x%X, uint32_t fenceCount = %d, const VkFence* pFences = 0x%X)",
    672 	      device, fenceCount, pFences);
    673 
    674 	for(uint32_t i = 0; i < fenceCount; i++)
    675 	{
    676 		vk::Cast(pFences[i])->reset();
    677 	}
    678 
    679 	return VK_SUCCESS;
    680 }
    681 
    682 VKAPI_ATTR VkResult VKAPI_CALL vkGetFenceStatus(VkDevice device, VkFence fence)
    683 {
    684 	TRACE("(VkDevice device = 0x%X, VkFence fence = 0x%X)", device, fence);
    685 
    686 	return vk::Cast(fence)->getStatus();
    687 }
    688 
    689 VKAPI_ATTR VkResult VKAPI_CALL vkWaitForFences(VkDevice device, uint32_t fenceCount, const VkFence* pFences, VkBool32 waitAll, uint64_t timeout)
    690 {
    691 	TRACE("(VkDevice device = 0x%X, uint32_t fenceCount = %d, const VkFence* pFences = 0x%X, VkBool32 waitAll = %d, uint64_t timeout = %d)",
    692 		device, fenceCount, pFences, waitAll, timeout);
    693 
    694 	vk::Cast(device)->waitForFences(fenceCount, pFences, waitAll, timeout);
    695 
    696 	return VK_SUCCESS;
    697 }
    698 
    699 VKAPI_ATTR VkResult VKAPI_CALL vkCreateSemaphore(VkDevice device, const VkSemaphoreCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSemaphore* pSemaphore)
    700 {
    701 	TRACE("(VkDevice device = 0x%X, const VkSemaphoreCreateInfo* pCreateInfo = 0x%X, const VkAllocationCallbacks* pAllocator = 0x%X, VkSemaphore* pSemaphore = 0x%X)",
    702 	      device, pCreateInfo, pAllocator, pSemaphore);
    703 
    704 	if(pCreateInfo->pNext || pCreateInfo->flags)
    705 	{
    706 		UNIMPLEMENTED();
    707 	}
    708 
    709 	return vk::Semaphore::Create(pAllocator, pCreateInfo, pSemaphore);
    710 }
    711 
    712 VKAPI_ATTR void VKAPI_CALL vkDestroySemaphore(VkDevice device, VkSemaphore semaphore, const VkAllocationCallbacks* pAllocator)
    713 {
    714 	TRACE("(VkDevice device = 0x%X, VkSemaphore semaphore = 0x%X, const VkAllocationCallbacks* pAllocator = 0x%X)",
    715 	      device, semaphore, pAllocator);
    716 
    717 	vk::destroy(semaphore, pAllocator);
    718 }
    719 
    720 VKAPI_ATTR VkResult VKAPI_CALL vkCreateEvent(VkDevice device, const VkEventCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkEvent* pEvent)
    721 {
    722 	TRACE("(VkDevice device = 0x%X, const VkEventCreateInfo* pCreateInfo = 0x%X, const VkAllocationCallbacks* pAllocator = 0x%X, VkEvent* pEvent = 0x%X)",
    723 	      device, pCreateInfo, pAllocator, pEvent);
    724 
    725 	if(pCreateInfo->pNext || pCreateInfo->flags)
    726 	{
    727 		UNIMPLEMENTED();
    728 	}
    729 
    730 	return vk::Event::Create(pAllocator, pCreateInfo, pEvent);
    731 }
    732 
    733 VKAPI_ATTR void VKAPI_CALL vkDestroyEvent(VkDevice device, VkEvent event, const VkAllocationCallbacks* pAllocator)
    734 {
    735 	TRACE("(VkDevice device = 0x%X, VkEvent event = 0x%X, const VkAllocationCallbacks* pAllocator = 0x%X)",
    736 	      device, event, pAllocator);
    737 
    738 	vk::destroy(event, pAllocator);
    739 }
    740 
    741 VKAPI_ATTR VkResult VKAPI_CALL vkGetEventStatus(VkDevice device, VkEvent event)
    742 {
    743 	TRACE("(VkDevice device = 0x%X, VkEvent event = 0x%X)", device, event);
    744 
    745 	return vk::Cast(event)->getStatus();
    746 }
    747 
    748 VKAPI_ATTR VkResult VKAPI_CALL vkSetEvent(VkDevice device, VkEvent event)
    749 {
    750 	TRACE("(VkDevice device = 0x%X, VkEvent event = 0x%X)", device, event);
    751 
    752 	vk::Cast(event)->signal();
    753 
    754 	return VK_SUCCESS;
    755 }
    756 
    757 VKAPI_ATTR VkResult VKAPI_CALL vkResetEvent(VkDevice device, VkEvent event)
    758 {
    759 	TRACE("(VkDevice device = 0x%X, VkEvent event = 0x%X)", device, event);
    760 
    761 	vk::Cast(event)->reset();
    762 
    763 	return VK_SUCCESS;
    764 }
    765 
    766 VKAPI_ATTR VkResult VKAPI_CALL vkCreateQueryPool(VkDevice device, const VkQueryPoolCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkQueryPool* pQueryPool)
    767 {
    768 	TRACE("(VkDevice device = 0x%X, const VkQueryPoolCreateInfo* pCreateInfo = 0x%X, const VkAllocationCallbacks* pAllocator = 0x%X, VkQueryPool* pQueryPool = 0x%X)",
    769 	      device, pCreateInfo, pAllocator, pQueryPool);
    770 
    771 	if(pCreateInfo->pNext || pCreateInfo->flags)
    772 	{
    773 		UNIMPLEMENTED();
    774 	}
    775 
    776 	return vk::QueryPool::Create(pAllocator, pCreateInfo, pQueryPool);
    777 }
    778 
    779 VKAPI_ATTR void VKAPI_CALL vkDestroyQueryPool(VkDevice device, VkQueryPool queryPool, const VkAllocationCallbacks* pAllocator)
    780 {
    781 	TRACE("(VkDevice device = 0x%X, VkQueryPool queryPool = 0x%X, const VkAllocationCallbacks* pAllocator = 0x%X)",
    782 	      device, queryPool, pAllocator);
    783 
    784 	vk::destroy(queryPool, pAllocator);
    785 }
    786 
    787 VKAPI_ATTR VkResult VKAPI_CALL vkGetQueryPoolResults(VkDevice device, VkQueryPool queryPool, uint32_t firstQuery, uint32_t queryCount, size_t dataSize, void* pData, VkDeviceSize stride, VkQueryResultFlags flags)
    788 {
    789 	TRACE("(VkDevice device = 0x%X, VkQueryPool queryPool = 0x%X, uint32_t firstQuery = %d, uint32_t queryCount = %d, size_t dataSize = %d, void* pData = 0x%X, VkDeviceSize stride = 0x%X, VkQueryResultFlags flags = %d)",
    790 	      device, queryPool, firstQuery, queryCount, dataSize, pData, stride, flags);
    791 
    792 	vk::Cast(queryPool)->getResults(firstQuery, queryCount, dataSize, pData, stride, flags);
    793 
    794 	return VK_SUCCESS;
    795 }
    796 
    797 VKAPI_ATTR VkResult VKAPI_CALL vkCreateBuffer(VkDevice device, const VkBufferCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkBuffer* pBuffer)
    798 {
    799 	TRACE("(VkDevice device = 0x%X, const VkBufferCreateInfo* pCreateInfo = 0x%X, const VkAllocationCallbacks* pAllocator = 0x%X, VkBuffer* pBuffer = 0x%X)",
    800 		    device, pCreateInfo, pAllocator, pBuffer);
    801 
    802 	if(pCreateInfo->pNext)
    803 	{
    804 		UNIMPLEMENTED();
    805 	}
    806 
    807 	return vk::Buffer::Create(pAllocator, pCreateInfo, pBuffer);
    808 }
    809 
    810 VKAPI_ATTR void VKAPI_CALL vkDestroyBuffer(VkDevice device, VkBuffer buffer, const VkAllocationCallbacks* pAllocator)
    811 {
    812 	TRACE("(VkDevice device = 0x%X, VkBuffer buffer = 0x%X, const VkAllocationCallbacks* pAllocator = 0x%X)",
    813 		    device, buffer, pAllocator);
    814 
    815 	vk::destroy(buffer, pAllocator);
    816 }
    817 
    818 VKAPI_ATTR VkResult VKAPI_CALL vkCreateBufferView(VkDevice device, const VkBufferViewCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkBufferView* pView)
    819 {
    820 	TRACE("(VkDevice device, const VkBufferViewCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkBufferView* pView)",
    821 		device, pCreateInfo, pAllocator, pView);
    822 
    823 	if(pCreateInfo->pNext || pCreateInfo->flags)
    824 	{
    825 		UNIMPLEMENTED();
    826 	}
    827 
    828 	return vk::BufferView::Create(pAllocator, pCreateInfo, pView);
    829 }
    830 
    831 VKAPI_ATTR void VKAPI_CALL vkDestroyBufferView(VkDevice device, VkBufferView bufferView, const VkAllocationCallbacks* pAllocator)
    832 {
    833 	TRACE("(VkDevice device, VkBufferView bufferView, const VkAllocationCallbacks* pAllocator)",
    834 	      device, bufferView, pAllocator);
    835 
    836 	vk::destroy(bufferView, pAllocator);
    837 }
    838 
    839 VKAPI_ATTR VkResult VKAPI_CALL vkCreateImage(VkDevice device, const VkImageCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkImage* pImage)
    840 {
    841 	TRACE("(VkDevice device = 0x%X, const VkImageCreateInfo* pCreateInfo = 0x%X, const VkAllocationCallbacks* pAllocator = 0x%X, VkImage* pImage = 0x%X)",
    842 		    device, pCreateInfo, pAllocator, pImage);
    843 
    844 	if(pCreateInfo->pNext)
    845 	{
    846 		UNIMPLEMENTED();
    847 	}
    848 
    849 	return vk::Image::Create(pAllocator, pCreateInfo, pImage);
    850 }
    851 
    852 VKAPI_ATTR void VKAPI_CALL vkDestroyImage(VkDevice device, VkImage image, const VkAllocationCallbacks* pAllocator)
    853 {
    854 	TRACE("(VkDevice device = 0x%X, VkImage image = 0x%X, const VkAllocationCallbacks* pAllocator = 0x%X)",
    855 		    device, image, pAllocator);
    856 
    857 	vk::destroy(image, pAllocator);
    858 }
    859 
    860 VKAPI_ATTR void VKAPI_CALL vkGetImageSubresourceLayout(VkDevice device, VkImage image, const VkImageSubresource* pSubresource, VkSubresourceLayout* pLayout)
    861 {
    862 	TRACE("(VkDevice device, VkImage image, const VkImageSubresource* pSubresource, VkSubresourceLayout* pLayout)",
    863 		device, image, pSubresource, pLayout);
    864 
    865 	vk::Cast(image)->getSubresourceLayout(pSubresource, pLayout);
    866 }
    867 
    868 VKAPI_ATTR VkResult VKAPI_CALL vkCreateImageView(VkDevice device, const VkImageViewCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkImageView* pView)
    869 {
    870 	TRACE("(VkDevice device = 0x%X, const VkImageViewCreateInfo* pCreateInfo = 0x%X, const VkAllocationCallbacks* pAllocator = 0x%X, VkImageView* pView = 0x%X)",
    871 		    device, pCreateInfo, pAllocator, pView);
    872 
    873 	if(pCreateInfo->pNext || pCreateInfo->flags)
    874 	{
    875 		UNIMPLEMENTED();
    876 	}
    877 
    878 	return vk::ImageView::Create(pAllocator, pCreateInfo, pView);
    879 }
    880 
    881 VKAPI_ATTR void VKAPI_CALL vkDestroyImageView(VkDevice device, VkImageView imageView, const VkAllocationCallbacks* pAllocator)
    882 {
    883 	TRACE("(VkDevice device = 0x%X, VkImageView imageView = 0x%X, const VkAllocationCallbacks* pAllocator = 0x%X)",
    884 	      device, imageView, pAllocator);
    885 
    886 	vk::destroy(imageView, pAllocator);
    887 }
    888 
    889 VKAPI_ATTR VkResult VKAPI_CALL vkCreateShaderModule(VkDevice device, const VkShaderModuleCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkShaderModule* pShaderModule)
    890 {
    891 	TRACE("(VkDevice device = 0x%X, const VkShaderModuleCreateInfo* pCreateInfo = 0x%X, const VkAllocationCallbacks* pAllocator = 0x%X, VkShaderModule* pShaderModule = 0x%X)",
    892 		    device, pCreateInfo, pAllocator, pShaderModule);
    893 
    894 	if(pCreateInfo->pNext || pCreateInfo->flags)
    895 	{
    896 		UNIMPLEMENTED();
    897 	}
    898 
    899 	return vk::ShaderModule::Create(pAllocator, pCreateInfo, pShaderModule);
    900 }
    901 
    902 VKAPI_ATTR void VKAPI_CALL vkDestroyShaderModule(VkDevice device, VkShaderModule shaderModule, const VkAllocationCallbacks* pAllocator)
    903 {
    904 	TRACE("(VkDevice device = 0x%X, VkShaderModule shaderModule = 0x%X, const VkAllocationCallbacks* pAllocator = 0x%X)",
    905 		    device, shaderModule, pAllocator);
    906 
    907 	vk::destroy(shaderModule, pAllocator);
    908 }
    909 
    910 VKAPI_ATTR VkResult VKAPI_CALL vkCreatePipelineCache(VkDevice device, const VkPipelineCacheCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkPipelineCache* pPipelineCache)
    911 {
    912 	TRACE("(VkDevice device, const VkPipelineCacheCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkPipelineCache* pPipelineCache)",
    913 	      device, pCreateInfo, pAllocator, pPipelineCache);
    914 
    915 	if(pCreateInfo->pNext || pCreateInfo->flags)
    916 	{
    917 		UNIMPLEMENTED();
    918 	}
    919 
    920 	return vk::PipelineCache::Create(pAllocator, pCreateInfo, pPipelineCache);
    921 }
    922 
    923 VKAPI_ATTR void VKAPI_CALL vkDestroyPipelineCache(VkDevice device, VkPipelineCache pipelineCache, const VkAllocationCallbacks* pAllocator)
    924 {
    925 	TRACE("(VkDevice device, VkPipelineCache pipelineCache, const VkAllocationCallbacks* pAllocator)",
    926 	      device, pipelineCache, pAllocator);
    927 
    928 	vk::destroy(pipelineCache, pAllocator);
    929 }
    930 
    931 VKAPI_ATTR VkResult VKAPI_CALL vkGetPipelineCacheData(VkDevice device, VkPipelineCache pipelineCache, size_t* pDataSize, void* pData)
    932 {
    933 	TRACE("()");
    934 	UNIMPLEMENTED();
    935 	return VK_SUCCESS;
    936 }
    937 
    938 VKAPI_ATTR VkResult VKAPI_CALL vkMergePipelineCaches(VkDevice device, VkPipelineCache dstCache, uint32_t srcCacheCount, const VkPipelineCache* pSrcCaches)
    939 {
    940 	TRACE("()");
    941 	UNIMPLEMENTED();
    942 	return VK_SUCCESS;
    943 }
    944 
    945 VKAPI_ATTR VkResult VKAPI_CALL vkCreateGraphicsPipelines(VkDevice device, VkPipelineCache pipelineCache, uint32_t createInfoCount, const VkGraphicsPipelineCreateInfo* pCreateInfos, const VkAllocationCallbacks* pAllocator, VkPipeline* pPipelines)
    946 {
    947 	TRACE("(VkDevice device = 0x%X, VkPipelineCache pipelineCache = 0x%X, uint32_t createInfoCount = %d, const VkGraphicsPipelineCreateInfo* pCreateInfos, const VkAllocationCallbacks* pAllocator = 0x%X, VkPipeline* pPipelines = 0x%X)",
    948 		    device, pipelineCache, createInfoCount, pCreateInfos, pAllocator, pPipelines);
    949 
    950 	// TODO (b/123588002): Optimize based on pipelineCache.
    951 
    952 	VkResult errorResult = VK_SUCCESS;
    953 	for(uint32_t i = 0; i < createInfoCount; i++)
    954 	{
    955 		VkResult result = vk::GraphicsPipeline::Create(pAllocator, &pCreateInfos[i], &pPipelines[i]);
    956 		if(result != VK_SUCCESS)
    957 		{
    958 			// According to the Vulkan spec, section 9.4. Multiple Pipeline Creation
    959 			// "When an application attempts to create many pipelines in a single command,
    960 			//  it is possible that some subset may fail creation. In that case, the
    961 			//  corresponding entries in the pPipelines output array will be filled with
    962 			//  VK_NULL_HANDLE values. If any pipeline fails creation (for example, due to
    963 			//  out of memory errors), the vkCreate*Pipelines commands will return an
    964 			//  error code. The implementation will attempt to create all pipelines, and
    965 			//  only return VK_NULL_HANDLE values for those that actually failed."
    966 			pPipelines[i] = VK_NULL_HANDLE;
    967 			errorResult = result;
    968 		}
    969 		else
    970 		{
    971 			static_cast<vk::GraphicsPipeline*>(vk::Cast(pPipelines[i]))->compileShaders(pAllocator, &pCreateInfos[i]);
    972 		}
    973 	}
    974 
    975 	return errorResult;
    976 }
    977 
    978 VKAPI_ATTR VkResult VKAPI_CALL vkCreateComputePipelines(VkDevice device, VkPipelineCache pipelineCache, uint32_t createInfoCount, const VkComputePipelineCreateInfo* pCreateInfos, const VkAllocationCallbacks* pAllocator, VkPipeline* pPipelines)
    979 {
    980 	TRACE("(VkDevice device = 0x%X, VkPipelineCache pipelineCache = 0x%X, uint32_t createInfoCount = %d, const VkComputePipelineCreateInfo* pCreateInfos, const VkAllocationCallbacks* pAllocator = 0x%X, VkPipeline* pPipelines = 0x%X)",
    981 		device, pipelineCache, createInfoCount, pCreateInfos, pAllocator, pPipelines);
    982 
    983 	// TODO (b/123588002): Optimize based on pipelineCache.
    984 
    985 	VkResult errorResult = VK_SUCCESS;
    986 	for(uint32_t i = 0; i < createInfoCount; i++)
    987 	{
    988 		VkResult result = vk::ComputePipeline::Create(pAllocator, &pCreateInfos[i], &pPipelines[i]);
    989 		if(result != VK_SUCCESS)
    990 		{
    991 			// According to the Vulkan spec, section 9.4. Multiple Pipeline Creation
    992 			// "When an application attempts to create many pipelines in a single command,
    993 			//  it is possible that some subset may fail creation. In that case, the
    994 			//  corresponding entries in the pPipelines output array will be filled with
    995 			//  VK_NULL_HANDLE values. If any pipeline fails creation (for example, due to
    996 			//  out of memory errors), the vkCreate*Pipelines commands will return an
    997 			//  error code. The implementation will attempt to create all pipelines, and
    998 			//  only return VK_NULL_HANDLE values for those that actually failed."
    999 			pPipelines[i] = VK_NULL_HANDLE;
   1000 			errorResult = result;
   1001 		}
   1002 	}
   1003 
   1004 	return errorResult;
   1005 }
   1006 
   1007 VKAPI_ATTR void VKAPI_CALL vkDestroyPipeline(VkDevice device, VkPipeline pipeline, const VkAllocationCallbacks* pAllocator)
   1008 {
   1009 	TRACE("(VkDevice device = 0x%X, VkPipeline pipeline = 0x%X, const VkAllocationCallbacks* pAllocator = 0x%X)",
   1010 		    device, pipeline, pAllocator);
   1011 
   1012 	vk::destroy(pipeline, pAllocator);
   1013 }
   1014 
   1015 VKAPI_ATTR VkResult VKAPI_CALL vkCreatePipelineLayout(VkDevice device, const VkPipelineLayoutCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkPipelineLayout* pPipelineLayout)
   1016 {
   1017 	TRACE("(VkDevice device = 0x%X, const VkPipelineLayoutCreateInfo* pCreateInfo = 0x%X, const VkAllocationCallbacks* pAllocator = 0x%X, VkPipelineLayout* pPipelineLayout = 0x%X)",
   1018 		    device, pCreateInfo, pAllocator, pPipelineLayout);
   1019 
   1020 	if(pCreateInfo->pNext || pCreateInfo->flags)
   1021 	{
   1022 		UNIMPLEMENTED();
   1023 	}
   1024 
   1025 	return vk::PipelineLayout::Create(pAllocator, pCreateInfo, pPipelineLayout);
   1026 }
   1027 
   1028 VKAPI_ATTR void VKAPI_CALL vkDestroyPipelineLayout(VkDevice device, VkPipelineLayout pipelineLayout, const VkAllocationCallbacks* pAllocator)
   1029 {
   1030 	TRACE("(VkDevice device = 0x%X, VkPipelineLayout pipelineLayout = 0x%X, const VkAllocationCallbacks* pAllocator = 0x%X)",
   1031 		    device, pipelineLayout, pAllocator);
   1032 
   1033 	vk::destroy(pipelineLayout, pAllocator);
   1034 }
   1035 
   1036 VKAPI_ATTR VkResult VKAPI_CALL vkCreateSampler(VkDevice device, const VkSamplerCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSampler* pSampler)
   1037 {
   1038 	TRACE("(VkDevice device = 0x%X, const VkSamplerCreateInfo* pCreateInfo = 0x%X, const VkAllocationCallbacks* pAllocator = 0x%X, VkSampler* pSampler = 0x%X)",
   1039 		    device, pCreateInfo, pAllocator, pSampler);
   1040 
   1041 	if(pCreateInfo->pNext || pCreateInfo->flags)
   1042 	{
   1043 		UNIMPLEMENTED();
   1044 	}
   1045 
   1046 	return vk::Sampler::Create(pAllocator, pCreateInfo, pSampler);
   1047 }
   1048 
   1049 VKAPI_ATTR void VKAPI_CALL vkDestroySampler(VkDevice device, VkSampler sampler, const VkAllocationCallbacks* pAllocator)
   1050 {
   1051 	TRACE("(VkDevice device = 0x%X, VkSampler sampler = 0x%X, const VkAllocationCallbacks* pAllocator = 0x%X)",
   1052 		    device, sampler, pAllocator);
   1053 
   1054 	vk::destroy(sampler, pAllocator);
   1055 }
   1056 
   1057 VKAPI_ATTR VkResult VKAPI_CALL vkCreateDescriptorSetLayout(VkDevice device, const VkDescriptorSetLayoutCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkDescriptorSetLayout* pSetLayout)
   1058 {
   1059 	TRACE("(VkDevice device = 0x%X, const VkDescriptorSetLayoutCreateInfo* pCreateInfo = 0x%X, const VkAllocationCallbacks* pAllocator = 0x%X, VkDescriptorSetLayout* pSetLayout = 0x%X)",
   1060 	      device, pCreateInfo, pAllocator, pSetLayout);
   1061 
   1062 	if(pCreateInfo->pNext)
   1063 	{
   1064 		UNIMPLEMENTED();
   1065 	}
   1066 
   1067 	return vk::DescriptorSetLayout::Create(pAllocator, pCreateInfo, pSetLayout);
   1068 }
   1069 
   1070 VKAPI_ATTR void VKAPI_CALL vkDestroyDescriptorSetLayout(VkDevice device, VkDescriptorSetLayout descriptorSetLayout, const VkAllocationCallbacks* pAllocator)
   1071 {
   1072 	TRACE("(VkDevice device = 0x%X, VkDescriptorSetLayout descriptorSetLayout = 0x%X, const VkAllocationCallbacks* pAllocator = 0x%X)",
   1073 	      device, descriptorSetLayout, pAllocator);
   1074 
   1075 	vk::destroy(descriptorSetLayout, pAllocator);
   1076 }
   1077 
   1078 VKAPI_ATTR VkResult VKAPI_CALL vkCreateDescriptorPool(VkDevice device, const VkDescriptorPoolCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkDescriptorPool* pDescriptorPool)
   1079 {
   1080 	TRACE("(VkDevice device = 0x%X, const VkDescriptorPoolCreateInfo* pCreateInfo = 0x%X, const VkAllocationCallbacks* pAllocator = 0x%X, VkDescriptorPool* pDescriptorPool = 0x%X)",
   1081 	      device, pCreateInfo, pAllocator, pDescriptorPool);
   1082 
   1083 	if(pCreateInfo->pNext)
   1084 	{
   1085 		UNIMPLEMENTED();
   1086 	}
   1087 
   1088 	return vk::DescriptorPool::Create(pAllocator, pCreateInfo, pDescriptorPool);
   1089 }
   1090 
   1091 VKAPI_ATTR void VKAPI_CALL vkDestroyDescriptorPool(VkDevice device, VkDescriptorPool descriptorPool, const VkAllocationCallbacks* pAllocator)
   1092 {
   1093 	TRACE("(VkDevice device = 0x%X, VkDescriptorPool descriptorPool = 0x%X, const VkAllocationCallbacks* pAllocator = 0x%X)",
   1094 	      device, descriptorPool, pAllocator);
   1095 
   1096 	vk::destroy(descriptorPool, pAllocator);
   1097 }
   1098 
   1099 VKAPI_ATTR VkResult VKAPI_CALL vkResetDescriptorPool(VkDevice device, VkDescriptorPool descriptorPool, VkDescriptorPoolResetFlags flags)
   1100 {
   1101 	TRACE("(VkDevice device = 0x%X, VkDescriptorPool descriptorPool = 0x%X, VkDescriptorPoolResetFlags flags = 0x%X)",
   1102 		device, descriptorPool, flags);
   1103 
   1104 	if(flags)
   1105 	{
   1106 		UNIMPLEMENTED();
   1107 	}
   1108 
   1109 	return vk::Cast(descriptorPool)->reset();
   1110 }
   1111 
   1112 VKAPI_ATTR VkResult VKAPI_CALL vkAllocateDescriptorSets(VkDevice device, const VkDescriptorSetAllocateInfo* pAllocateInfo, VkDescriptorSet* pDescriptorSets)
   1113 {
   1114 	TRACE("(VkDevice device = 0x%X, const VkDescriptorSetAllocateInfo* pAllocateInfo = 0x%X, VkDescriptorSet* pDescriptorSets = 0x%X)",
   1115 		device, pAllocateInfo, pDescriptorSets);
   1116 
   1117 	if(pAllocateInfo->pNext)
   1118 	{
   1119 		UNIMPLEMENTED();
   1120 	}
   1121 
   1122 	return vk::Cast(pAllocateInfo->descriptorPool)->allocateSets(
   1123 		pAllocateInfo->descriptorSetCount, pAllocateInfo->pSetLayouts, pDescriptorSets);
   1124 }
   1125 
   1126 VKAPI_ATTR VkResult VKAPI_CALL vkFreeDescriptorSets(VkDevice device, VkDescriptorPool descriptorPool, uint32_t descriptorSetCount, const VkDescriptorSet* pDescriptorSets)
   1127 {
   1128 	TRACE("(VkDevice device = 0x%X, VkDescriptorPool descriptorPool = 0x%X, uint32_t descriptorSetCount = %d, const VkDescriptorSet* pDescriptorSets = 0x%X)",
   1129 		device, descriptorPool, descriptorSetCount, pDescriptorSets);
   1130 
   1131 	vk::Cast(descriptorPool)->freeSets(descriptorSetCount, pDescriptorSets);
   1132 
   1133 	return VK_SUCCESS;
   1134 }
   1135 
   1136 VKAPI_ATTR void VKAPI_CALL vkUpdateDescriptorSets(VkDevice device, uint32_t descriptorWriteCount, const VkWriteDescriptorSet* pDescriptorWrites, uint32_t descriptorCopyCount, const VkCopyDescriptorSet* pDescriptorCopies)
   1137 {
   1138 	TRACE("()");
   1139 	UNIMPLEMENTED();
   1140 }
   1141 
   1142 VKAPI_ATTR VkResult VKAPI_CALL vkCreateFramebuffer(VkDevice device, const VkFramebufferCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkFramebuffer* pFramebuffer)
   1143 {
   1144 	TRACE("(VkDevice device = 0x%X, const VkFramebufferCreateInfo* pCreateInfo = 0x%X, const VkAllocationCallbacks* pAllocator = 0x%X, VkFramebuffer* pFramebuffer = 0x%X)",
   1145 		    device, pCreateInfo, pAllocator, pFramebuffer);
   1146 
   1147 	if(pCreateInfo->pNext || pCreateInfo->flags)
   1148 	{
   1149 		UNIMPLEMENTED();
   1150 	}
   1151 
   1152 	return vk::Framebuffer::Create(pAllocator, pCreateInfo, pFramebuffer);
   1153 }
   1154 
   1155 VKAPI_ATTR void VKAPI_CALL vkDestroyFramebuffer(VkDevice device, VkFramebuffer framebuffer, const VkAllocationCallbacks* pAllocator)
   1156 {
   1157 	TRACE("(VkDevice device = 0x%X, VkFramebuffer framebuffer = 0x%X, const VkAllocationCallbacks* pAllocator = 0x%X)");
   1158 
   1159 	vk::destroy(framebuffer, pAllocator);
   1160 }
   1161 
   1162 VKAPI_ATTR VkResult VKAPI_CALL vkCreateRenderPass(VkDevice device, const VkRenderPassCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkRenderPass* pRenderPass)
   1163 {
   1164 	TRACE("(VkDevice device = 0x%X, const VkRenderPassCreateInfo* pCreateInfo = 0x%X, const VkAllocationCallbacks* pAllocator = 0x%X, VkRenderPass* pRenderPass = 0x%X)",
   1165 		    device, pCreateInfo, pAllocator, pRenderPass);
   1166 
   1167 	if(pCreateInfo->pNext || pCreateInfo->flags)
   1168 	{
   1169 		UNIMPLEMENTED();
   1170 	}
   1171 
   1172 	return vk::RenderPass::Create(pAllocator, pCreateInfo, pRenderPass);
   1173 }
   1174 
   1175 VKAPI_ATTR void VKAPI_CALL vkDestroyRenderPass(VkDevice device, VkRenderPass renderPass, const VkAllocationCallbacks* pAllocator)
   1176 {
   1177 	TRACE("(VkDevice device = 0x%X, VkRenderPass renderPass = 0x%X, const VkAllocationCallbacks* pAllocator = 0x%X)",
   1178 		    device, renderPass, pAllocator);
   1179 
   1180 	vk::destroy(renderPass, pAllocator);
   1181 }
   1182 
   1183 VKAPI_ATTR void VKAPI_CALL vkGetRenderAreaGranularity(VkDevice device, VkRenderPass renderPass, VkExtent2D* pGranularity)
   1184 {
   1185 	TRACE("()");
   1186 	UNIMPLEMENTED();
   1187 }
   1188 
   1189 VKAPI_ATTR VkResult VKAPI_CALL vkCreateCommandPool(VkDevice device, const VkCommandPoolCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkCommandPool* pCommandPool)
   1190 {
   1191 	TRACE("(VkDevice device = 0x%X, const VkCommandPoolCreateInfo* pCreateInfo = 0x%X, const VkAllocationCallbacks* pAllocator = 0x%X, VkCommandPool* pCommandPool = 0x%X)",
   1192 		    device, pCreateInfo, pAllocator, pCommandPool);
   1193 
   1194 	if(pCreateInfo->pNext)
   1195 	{
   1196 		UNIMPLEMENTED();
   1197 	}
   1198 
   1199 	return vk::CommandPool::Create(pAllocator, pCreateInfo, pCommandPool);
   1200 }
   1201 
   1202 VKAPI_ATTR void VKAPI_CALL vkDestroyCommandPool(VkDevice device, VkCommandPool commandPool, const VkAllocationCallbacks* pAllocator)
   1203 {
   1204 	TRACE("(VkDevice device = 0x%X, VkCommandPool commandPool = 0x%X, const VkAllocationCallbacks* pAllocator = 0x%X)",
   1205 		    device, commandPool, pAllocator);
   1206 
   1207 	vk::destroy(commandPool, pAllocator);
   1208 }
   1209 
   1210 VKAPI_ATTR VkResult VKAPI_CALL vkResetCommandPool(VkDevice device, VkCommandPool commandPool, VkCommandPoolResetFlags flags)
   1211 {
   1212 	TRACE("(VkDevice device = 0x%X, VkCommandPool commandPool = 0x%X, VkCommandPoolResetFlags flags = %d )",
   1213 		device, commandPool, flags);
   1214 
   1215 	return vk::Cast(commandPool)->reset(flags);
   1216 }
   1217 
   1218 VKAPI_ATTR VkResult VKAPI_CALL vkAllocateCommandBuffers(VkDevice device, const VkCommandBufferAllocateInfo* pAllocateInfo, VkCommandBuffer* pCommandBuffers)
   1219 {
   1220 	TRACE("(VkDevice device = 0x%X, const VkCommandBufferAllocateInfo* pAllocateInfo = 0x%X, VkCommandBuffer* pCommandBuffers = 0x%X)",
   1221 		    device, pAllocateInfo, pCommandBuffers);
   1222 
   1223 	if(pAllocateInfo->pNext)
   1224 	{
   1225 		UNIMPLEMENTED();
   1226 	}
   1227 
   1228 	return vk::Cast(pAllocateInfo->commandPool)->allocateCommandBuffers(
   1229 		pAllocateInfo->level, pAllocateInfo->commandBufferCount, pCommandBuffers);
   1230 }
   1231 
   1232 VKAPI_ATTR void VKAPI_CALL vkFreeCommandBuffers(VkDevice device, VkCommandPool commandPool, uint32_t commandBufferCount, const VkCommandBuffer* pCommandBuffers)
   1233 {
   1234 	TRACE("(VkDevice device = 0x%X, VkCommandPool commandPool = 0x%X, uint32_t commandBufferCount = %d, const VkCommandBuffer* pCommandBuffers = 0x%X)",
   1235 		    device, commandPool, commandBufferCount, pCommandBuffers);
   1236 
   1237 	vk::Cast(commandPool)->freeCommandBuffers(commandBufferCount, pCommandBuffers);
   1238 }
   1239 
   1240 VKAPI_ATTR VkResult VKAPI_CALL vkBeginCommandBuffer(VkCommandBuffer commandBuffer, const VkCommandBufferBeginInfo* pBeginInfo)
   1241 {
   1242 	TRACE("(VkCommandBuffer commandBuffer = 0x%X, const VkCommandBufferBeginInfo* pBeginInfo = 0x%X)",
   1243 		    commandBuffer, pBeginInfo);
   1244 
   1245 	if(pBeginInfo->pNext)
   1246 	{
   1247 		UNIMPLEMENTED();
   1248 	}
   1249 
   1250 	return vk::Cast(commandBuffer)->begin(pBeginInfo->flags, pBeginInfo->pInheritanceInfo);
   1251 }
   1252 
   1253 VKAPI_ATTR VkResult VKAPI_CALL vkEndCommandBuffer(VkCommandBuffer commandBuffer)
   1254 {
   1255 	TRACE("(VkCommandBuffer commandBuffer = 0x%X)", commandBuffer);
   1256 
   1257 	return vk::Cast(commandBuffer)->end();
   1258 }
   1259 
   1260 VKAPI_ATTR VkResult VKAPI_CALL vkResetCommandBuffer(VkCommandBuffer commandBuffer, VkCommandBufferResetFlags flags)
   1261 {
   1262 	TRACE("VkCommandBuffer commandBuffer = 0x%X, VkCommandBufferResetFlags flags = %d", commandBuffer, flags);
   1263 
   1264 	return vk::Cast(commandBuffer)->reset(flags);
   1265 }
   1266 
   1267 VKAPI_ATTR void VKAPI_CALL vkCmdBindPipeline(VkCommandBuffer commandBuffer, VkPipelineBindPoint pipelineBindPoint, VkPipeline pipeline)
   1268 {
   1269 	TRACE("(VkCommandBuffer commandBuffer = 0x%X, VkPipelineBindPoint pipelineBindPoint = %d, VkPipeline pipeline = 0x%X)",
   1270 		    commandBuffer, pipelineBindPoint, pipeline);
   1271 
   1272 	vk::Cast(commandBuffer)->bindPipeline(pipelineBindPoint, pipeline);
   1273 }
   1274 
   1275 VKAPI_ATTR void VKAPI_CALL vkCmdSetViewport(VkCommandBuffer commandBuffer, uint32_t firstViewport, uint32_t viewportCount, const VkViewport* pViewports)
   1276 {
   1277 	TRACE("(VkCommandBuffer commandBuffer = 0x%X, uint32_t firstViewport = %d, uint32_t viewportCount = %d, const VkViewport* pViewports = 0x%X)",
   1278 	      commandBuffer, firstViewport, viewportCount, pViewports);
   1279 
   1280 	vk::Cast(commandBuffer)->setViewport(firstViewport, viewportCount, pViewports);
   1281 }
   1282 
   1283 VKAPI_ATTR void VKAPI_CALL vkCmdSetScissor(VkCommandBuffer commandBuffer, uint32_t firstScissor, uint32_t scissorCount, const VkRect2D* pScissors)
   1284 {
   1285 	TRACE("(VkCommandBuffer commandBuffer = 0x%X, uint32_t firstScissor = %d, uint32_t scissorCount = %d, const VkRect2D* pScissors = 0x%X)",
   1286 	      commandBuffer, firstScissor, scissorCount, pScissors);
   1287 
   1288 	vk::Cast(commandBuffer)->setScissor(firstScissor, scissorCount, pScissors);
   1289 }
   1290 
   1291 VKAPI_ATTR void VKAPI_CALL vkCmdSetLineWidth(VkCommandBuffer commandBuffer, float lineWidth)
   1292 {
   1293 	TRACE("(VkCommandBuffer commandBuffer = 0x%X, float lineWidth = %f)", commandBuffer, lineWidth);
   1294 
   1295 	vk::Cast(commandBuffer)->setLineWidth(lineWidth);
   1296 }
   1297 
   1298 VKAPI_ATTR void VKAPI_CALL vkCmdSetDepthBias(VkCommandBuffer commandBuffer, float depthBiasConstantFactor, float depthBiasClamp, float depthBiasSlopeFactor)
   1299 {
   1300 	TRACE("(VkCommandBuffer commandBuffer = 0x%X, float depthBiasConstantFactor = %f, float depthBiasClamp = %f, float depthBiasSlopeFactor = %f)",
   1301 	      commandBuffer, depthBiasConstantFactor, depthBiasClamp, depthBiasSlopeFactor);
   1302 
   1303 	vk::Cast(commandBuffer)->setDepthBias(depthBiasConstantFactor, depthBiasClamp, depthBiasSlopeFactor);
   1304 }
   1305 
   1306 VKAPI_ATTR void VKAPI_CALL vkCmdSetBlendConstants(VkCommandBuffer commandBuffer, const float blendConstants[4])
   1307 {
   1308 	TRACE("(VkCommandBuffer commandBuffer = 0x%X, const float blendConstants[4] = {%f, %f, %f, %f})",
   1309 	      commandBuffer, blendConstants[0], blendConstants[1], blendConstants[2], blendConstants[3]);
   1310 
   1311 	vk::Cast(commandBuffer)->setBlendConstants(blendConstants);
   1312 }
   1313 
   1314 VKAPI_ATTR void VKAPI_CALL vkCmdSetDepthBounds(VkCommandBuffer commandBuffer, float minDepthBounds, float maxDepthBounds)
   1315 {
   1316 	TRACE("(VkCommandBuffer commandBuffer = 0x%X, float minDepthBounds = %f, float maxDepthBounds = %f)",
   1317 	      commandBuffer, minDepthBounds, maxDepthBounds);
   1318 
   1319 	vk::Cast(commandBuffer)->setDepthBounds(minDepthBounds, maxDepthBounds);
   1320 }
   1321 
   1322 VKAPI_ATTR void VKAPI_CALL vkCmdSetStencilCompareMask(VkCommandBuffer commandBuffer, VkStencilFaceFlags faceMask, uint32_t compareMask)
   1323 {
   1324 	TRACE("(VkCommandBuffer commandBuffer = 0x%X, VkStencilFaceFlags faceMask = %d, uint32_t compareMask = %d)",
   1325 	      commandBuffer, faceMask, compareMask);
   1326 
   1327 	vk::Cast(commandBuffer)->setStencilCompareMask(faceMask, compareMask);
   1328 }
   1329 
   1330 VKAPI_ATTR void VKAPI_CALL vkCmdSetStencilWriteMask(VkCommandBuffer commandBuffer, VkStencilFaceFlags faceMask, uint32_t writeMask)
   1331 {
   1332 	TRACE("(VkCommandBuffer commandBuffer = 0x%X, VkStencilFaceFlags faceMask = %d, uint32_t writeMask = %d)",
   1333 	      commandBuffer, faceMask, writeMask);
   1334 
   1335 	vk::Cast(commandBuffer)->setStencilWriteMask(faceMask, writeMask);
   1336 }
   1337 
   1338 VKAPI_ATTR void VKAPI_CALL vkCmdSetStencilReference(VkCommandBuffer commandBuffer, VkStencilFaceFlags faceMask, uint32_t reference)
   1339 {
   1340 	TRACE("(VkCommandBuffer commandBuffer = 0x%X, VkStencilFaceFlags faceMask = %d, uint32_t reference = %d)",
   1341 	      commandBuffer, faceMask, reference);
   1342 
   1343 	vk::Cast(commandBuffer)->setStencilReference(faceMask, reference);
   1344 }
   1345 
   1346 VKAPI_ATTR void VKAPI_CALL vkCmdBindDescriptorSets(VkCommandBuffer commandBuffer, VkPipelineBindPoint pipelineBindPoint, VkPipelineLayout layout, uint32_t firstSet, uint32_t descriptorSetCount, const VkDescriptorSet* pDescriptorSets, uint32_t dynamicOffsetCount, const uint32_t* pDynamicOffsets)
   1347 {
   1348 	TRACE("(VkCommandBuffer commandBuffer = 0x%X, VkPipelineBindPoint pipelineBindPoint = %d, VkPipelineLayout layout = 0x%X, uint32_t firstSet = %d, uint32_t descriptorSetCount = %d, const VkDescriptorSet* pDescriptorSets = 0x%X, uint32_t dynamicOffsetCount = %d, const uint32_t* pDynamicOffsets = 0x%X)",
   1349 	      commandBuffer, pipelineBindPoint, layout, firstSet, descriptorSetCount, pDescriptorSets, dynamicOffsetCount, pDynamicOffsets);
   1350 
   1351 	vk::Cast(commandBuffer)->bindDescriptorSets(pipelineBindPoint, layout, firstSet, descriptorSetCount, pDescriptorSets, dynamicOffsetCount, pDynamicOffsets);
   1352 }
   1353 
   1354 VKAPI_ATTR void VKAPI_CALL vkCmdBindIndexBuffer(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, VkIndexType indexType)
   1355 {
   1356 	TRACE("(VkCommandBuffer commandBuffer = 0x%X, VkBuffer buffer = 0x%X, VkDeviceSize offset = %d, VkIndexType indexType = %d)",
   1357 	      commandBuffer, buffer, offset, indexType);
   1358 
   1359 	vk::Cast(commandBuffer)->bindIndexBuffer(buffer, offset, indexType);
   1360 }
   1361 
   1362 VKAPI_ATTR void VKAPI_CALL vkCmdBindVertexBuffers(VkCommandBuffer commandBuffer, uint32_t firstBinding, uint32_t bindingCount, const VkBuffer* pBuffers, const VkDeviceSize* pOffsets)
   1363 {
   1364 	TRACE("(VkCommandBuffer commandBuffer = 0x%X, uint32_t firstBinding = %d, uint32_t bindingCount = %d, const VkBuffer* pBuffers = 0x%X, const VkDeviceSize* pOffsets = 0x%X)",
   1365 		    commandBuffer, firstBinding, bindingCount, pBuffers, pOffsets);
   1366 
   1367 	vk::Cast(commandBuffer)->bindVertexBuffers(firstBinding, bindingCount, pBuffers, pOffsets);
   1368 }
   1369 
   1370 VKAPI_ATTR void VKAPI_CALL vkCmdDraw(VkCommandBuffer commandBuffer, uint32_t vertexCount, uint32_t instanceCount, uint32_t firstVertex, uint32_t firstInstance)
   1371 {
   1372 	TRACE("(VkCommandBuffer commandBuffer = 0x%X, uint32_t vertexCount = %d, uint32_t instanceCount = %d, uint32_t firstVertex = %d, uint32_t firstInstance = %d)",
   1373 		    commandBuffer, vertexCount, instanceCount, firstVertex, firstInstance);
   1374 
   1375 	vk::Cast(commandBuffer)->draw(vertexCount, instanceCount, firstVertex, firstInstance);
   1376 }
   1377 
   1378 VKAPI_ATTR void VKAPI_CALL vkCmdDrawIndexed(VkCommandBuffer commandBuffer, uint32_t indexCount, uint32_t instanceCount, uint32_t firstIndex, int32_t vertexOffset, uint32_t firstInstance)
   1379 {
   1380 	TRACE("(VkCommandBuffer commandBuffer = 0x%X, uint32_t indexCount = %d, uint32_t instanceCount = %d, uint32_t firstIndex = %d, int32_t vertexOffset = %d, uint32_t firstInstance = %d)",
   1381 		    commandBuffer, indexCount, instanceCount, firstIndex, vertexOffset, firstInstance);
   1382 
   1383 	vk::Cast(commandBuffer)->drawIndexed(indexCount, instanceCount, firstIndex, vertexOffset, firstInstance);
   1384 }
   1385 
   1386 VKAPI_ATTR void VKAPI_CALL vkCmdDrawIndirect(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, uint32_t drawCount, uint32_t stride)
   1387 {
   1388 	TRACE("(VkCommandBuffer commandBuffer = 0x%X, VkBuffer buffer = 0x%X, VkDeviceSize offset = %d, uint32_t drawCount = %d, uint32_t stride = %d)",
   1389 		    commandBuffer, buffer, offset, drawCount, stride);
   1390 
   1391 	vk::Cast(commandBuffer)->drawIndirect(buffer, offset, drawCount, stride);
   1392 }
   1393 
   1394 VKAPI_ATTR void VKAPI_CALL vkCmdDrawIndexedIndirect(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, uint32_t drawCount, uint32_t stride)
   1395 {
   1396 	TRACE("(VkCommandBuffer commandBuffer = 0x%X, VkBuffer buffer = 0x%X, VkDeviceSize offset = %d, uint32_t drawCount = %d, uint32_t stride = %d)",
   1397 		    commandBuffer, buffer, offset, drawCount, stride);
   1398 
   1399 	vk::Cast(commandBuffer)->drawIndexedIndirect(buffer, offset, drawCount, stride);
   1400 }
   1401 
   1402 VKAPI_ATTR void VKAPI_CALL vkCmdDispatch(VkCommandBuffer commandBuffer, uint32_t groupCountX, uint32_t groupCountY, uint32_t groupCountZ)
   1403 {
   1404 	TRACE("(VkCommandBuffer commandBuffer = 0x%X, uint32_t groupCountX = %d, uint32_t groupCountY = %d, uint32_t groupCountZ = %d)",
   1405 	      commandBuffer, groupCountX, groupCountY, groupCountZ);
   1406 
   1407 	vk::Cast(commandBuffer)->dispatch(groupCountX, groupCountY, groupCountZ);
   1408 }
   1409 
   1410 VKAPI_ATTR void VKAPI_CALL vkCmdDispatchIndirect(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset)
   1411 {
   1412 	TRACE("(VkCommandBuffer commandBuffer = 0x%X, VkBuffer buffer = 0x%X, VkDeviceSize offset = %d)",
   1413 	      commandBuffer, buffer, offset);
   1414 
   1415 	vk::Cast(commandBuffer)->dispatchIndirect(buffer, offset);
   1416 }
   1417 
   1418 VKAPI_ATTR void VKAPI_CALL vkCmdCopyBuffer(VkCommandBuffer commandBuffer, VkBuffer srcBuffer, VkBuffer dstBuffer, uint32_t regionCount, const VkBufferCopy* pRegions)
   1419 {
   1420 	TRACE("(VkCommandBuffer commandBuffer = 0x%X, VkBuffer srcBuffer = 0x%X, VkBuffer dstBuffer = 0x%X, uint32_t regionCount = %d, const VkBufferCopy* pRegions = 0x%X)",
   1421 	      commandBuffer, srcBuffer, dstBuffer, regionCount, pRegions);
   1422 
   1423 	vk::Cast(commandBuffer)->copyBuffer(srcBuffer, dstBuffer, regionCount, pRegions);
   1424 }
   1425 
   1426 VKAPI_ATTR void VKAPI_CALL vkCmdCopyImage(VkCommandBuffer commandBuffer, VkImage srcImage, VkImageLayout srcImageLayout, VkImage dstImage, VkImageLayout dstImageLayout, uint32_t regionCount, const VkImageCopy* pRegions)
   1427 {
   1428 	TRACE("(VkCommandBuffer commandBuffer = 0x%X, VkImage srcImage = 0x%X, VkImageLayout srcImageLayout = %d, VkImage dstImage = 0x%X, VkImageLayout dstImageLayout = %d, uint32_t regionCount = %d, const VkImageCopy* pRegions = 0x%X)",
   1429 	      commandBuffer, srcImage, srcImageLayout, dstImage, dstImageLayout, regionCount, pRegions);
   1430 
   1431 	vk::Cast(commandBuffer)->copyImage(srcImage, srcImageLayout, dstImage, dstImageLayout, regionCount, pRegions);
   1432 }
   1433 
   1434 VKAPI_ATTR void VKAPI_CALL vkCmdBlitImage(VkCommandBuffer commandBuffer, VkImage srcImage, VkImageLayout srcImageLayout, VkImage dstImage, VkImageLayout dstImageLayout, uint32_t regionCount, const VkImageBlit* pRegions, VkFilter filter)
   1435 {
   1436 	TRACE("(VkCommandBuffer commandBuffer = 0x%X, VkImage srcImage = 0x%X, VkImageLayout srcImageLayout = %d, VkImage dstImage = 0x%X, VkImageLayout dstImageLayout = %d, uint32_t regionCount = %d, const VkImageBlit* pRegions = 0x%X, VkFilter filter = %d)",
   1437 	      commandBuffer, srcImage, srcImageLayout, dstImage, dstImageLayout, regionCount, pRegions, filter);
   1438 
   1439 	vk::Cast(commandBuffer)->blitImage(srcImage, srcImageLayout, dstImage, dstImageLayout, regionCount, pRegions, filter);
   1440 }
   1441 
   1442 VKAPI_ATTR void VKAPI_CALL vkCmdCopyBufferToImage(VkCommandBuffer commandBuffer, VkBuffer srcBuffer, VkImage dstImage, VkImageLayout dstImageLayout, uint32_t regionCount, const VkBufferImageCopy* pRegions)
   1443 {
   1444 	TRACE("(VkCommandBuffer commandBuffer = 0x%X, VkBuffer srcBuffer = 0x%X, VkImage dstImage = 0x%X, VkImageLayout dstImageLayout = %d, uint32_t regionCount = %d, const VkBufferImageCopy* pRegions = 0x%X)",
   1445 	      commandBuffer, srcBuffer, dstImage, dstImageLayout, regionCount, pRegions);
   1446 
   1447 	vk::Cast(commandBuffer)->copyBufferToImage(srcBuffer, dstImage, dstImageLayout, regionCount, pRegions);
   1448 }
   1449 
   1450 VKAPI_ATTR void VKAPI_CALL vkCmdCopyImageToBuffer(VkCommandBuffer commandBuffer, VkImage srcImage, VkImageLayout srcImageLayout, VkBuffer dstBuffer, uint32_t regionCount, const VkBufferImageCopy* pRegions)
   1451 {
   1452 	TRACE("(VkCommandBuffer commandBuffer = 0x%X, VkImage srcImage = 0x%X, VkImageLayout srcImageLayout = %d, VkBuffer dstBuffer = 0x%X, uint32_t regionCount = %d, const VkBufferImageCopy* pRegions = 0x%X)",
   1453 		    commandBuffer, srcImage, srcImageLayout, dstBuffer, regionCount, pRegions);
   1454 
   1455 	vk::Cast(commandBuffer)->copyImageToBuffer(srcImage, srcImageLayout, dstBuffer, regionCount, pRegions);
   1456 }
   1457 
   1458 VKAPI_ATTR void VKAPI_CALL vkCmdUpdateBuffer(VkCommandBuffer commandBuffer, VkBuffer dstBuffer, VkDeviceSize dstOffset, VkDeviceSize dataSize, const void* pData)
   1459 {
   1460 	TRACE("(VkCommandBuffer commandBuffer = 0x%X, VkBuffer dstBuffer = 0x%X, VkDeviceSize dstOffset = %d, VkDeviceSize dataSize = %d, const void* pData = 0x%X)",
   1461 	      commandBuffer, dstBuffer, dstOffset, dataSize, pData);
   1462 
   1463 	vk::Cast(commandBuffer)->updateBuffer(dstBuffer, dstOffset, dataSize, pData);
   1464 }
   1465 
   1466 VKAPI_ATTR void VKAPI_CALL vkCmdFillBuffer(VkCommandBuffer commandBuffer, VkBuffer dstBuffer, VkDeviceSize dstOffset, VkDeviceSize size, uint32_t data)
   1467 {
   1468 	TRACE("(VkCommandBuffer commandBuffer = 0x%X, VkBuffer dstBuffer = 0x%X, VkDeviceSize dstOffset = %d, VkDeviceSize size = %d, uint32_t data = %d)",
   1469 	      commandBuffer, dstBuffer, dstOffset, size, data);
   1470 
   1471 	vk::Cast(commandBuffer)->fillBuffer(dstBuffer, dstOffset, size, data);
   1472 }
   1473 
   1474 VKAPI_ATTR void VKAPI_CALL vkCmdClearColorImage(VkCommandBuffer commandBuffer, VkImage image, VkImageLayout imageLayout, const VkClearColorValue* pColor, uint32_t rangeCount, const VkImageSubresourceRange* pRanges)
   1475 {
   1476 	TRACE("(VkCommandBuffer commandBuffer = 0x%X, VkImage image = 0x%X, VkImageLayout imageLayout = %d, const VkClearColorValue* pColor = 0x%X, uint32_t rangeCount = %d, const VkImageSubresourceRange* pRanges = 0x%X)",
   1477 	      commandBuffer, image, imageLayout, pColor, rangeCount, pRanges);
   1478 
   1479 	vk::Cast(commandBuffer)->clearColorImage(image, imageLayout, pColor, rangeCount, pRanges);
   1480 }
   1481 
   1482 VKAPI_ATTR void VKAPI_CALL vkCmdClearDepthStencilImage(VkCommandBuffer commandBuffer, VkImage image, VkImageLayout imageLayout, const VkClearDepthStencilValue* pDepthStencil, uint32_t rangeCount, const VkImageSubresourceRange* pRanges)
   1483 {
   1484 	TRACE("(VkCommandBuffer commandBuffer = 0x%X, VkImage image = 0x%X, VkImageLayout imageLayout = %d, const VkClearDepthStencilValue* pDepthStencil = 0x%X, uint32_t rangeCount = %d, const VkImageSubresourceRange* pRanges = 0x%X)",
   1485 	      commandBuffer, image, imageLayout, pDepthStencil, rangeCount, pRanges);
   1486 
   1487 	vk::Cast(commandBuffer)->clearDepthStencilImage(image, imageLayout, pDepthStencil, rangeCount, pRanges);
   1488 }
   1489 
   1490 VKAPI_ATTR void VKAPI_CALL vkCmdClearAttachments(VkCommandBuffer commandBuffer, uint32_t attachmentCount, const VkClearAttachment* pAttachments, uint32_t rectCount, const VkClearRect* pRects)
   1491 {
   1492 	TRACE("(VkCommandBuffer commandBuffer = 0x%X, uint32_t attachmentCount = %d, const VkClearAttachment* pAttachments = 0x%X, uint32_t rectCount = %d, const VkClearRect* pRects = 0x%X)",
   1493 	      commandBuffer, attachmentCount, pAttachments, rectCount,  pRects);
   1494 
   1495 	vk::Cast(commandBuffer)->clearAttachments(attachmentCount, pAttachments, rectCount, pRects);
   1496 }
   1497 
   1498 VKAPI_ATTR void VKAPI_CALL vkCmdResolveImage(VkCommandBuffer commandBuffer, VkImage srcImage, VkImageLayout srcImageLayout, VkImage dstImage, VkImageLayout dstImageLayout, uint32_t regionCount, const VkImageResolve* pRegions)
   1499 {
   1500 	TRACE("(VkCommandBuffer commandBuffer = 0x%X, VkImage srcImage = 0x%X, VkImageLayout srcImageLayout = %d, VkImage dstImage = 0x%X, VkImageLayout dstImageLayout = %d, uint32_t regionCount = %d, const VkImageResolve* pRegions = 0x%X)",
   1501 	      commandBuffer, srcImage, srcImageLayout, dstImage, dstImageLayout, regionCount, pRegions);
   1502 
   1503 	vk::Cast(commandBuffer)->resolveImage(srcImage, srcImageLayout, dstImage, dstImageLayout, regionCount, pRegions);
   1504 }
   1505 
   1506 VKAPI_ATTR void VKAPI_CALL vkCmdSetEvent(VkCommandBuffer commandBuffer, VkEvent event, VkPipelineStageFlags stageMask)
   1507 {
   1508 	TRACE("(VkCommandBuffer commandBuffer = 0x%X, VkEvent event = 0x%X, VkPipelineStageFlags stageMask = %d)",
   1509 	      commandBuffer, event, stageMask);
   1510 
   1511 	vk::Cast(commandBuffer)->setEvent(event, stageMask);
   1512 }
   1513 
   1514 VKAPI_ATTR void VKAPI_CALL vkCmdResetEvent(VkCommandBuffer commandBuffer, VkEvent event, VkPipelineStageFlags stageMask)
   1515 {
   1516 	TRACE("(VkCommandBuffer commandBuffer = 0x%X, VkEvent event = 0x%X, VkPipelineStageFlags stageMask = %d)",
   1517 	      commandBuffer, event, stageMask);
   1518 
   1519 	vk::Cast(commandBuffer)->resetEvent(event, stageMask);
   1520 }
   1521 
   1522 VKAPI_ATTR void VKAPI_CALL vkCmdWaitEvents(VkCommandBuffer commandBuffer, uint32_t eventCount, const VkEvent* pEvents, VkPipelineStageFlags srcStageMask, VkPipelineStageFlags dstStageMask, uint32_t memoryBarrierCount, const VkMemoryBarrier* pMemoryBarriers, uint32_t bufferMemoryBarrierCount, const VkBufferMemoryBarrier* pBufferMemoryBarriers, uint32_t imageMemoryBarrierCount, const VkImageMemoryBarrier* pImageMemoryBarriers)
   1523 {
   1524 	TRACE("(VkCommandBuffer commandBuffer = 0x%X, uint32_t eventCount = %d, const VkEvent* pEvents = 0x%X, VkPipelineStageFlags srcStageMask = %d, VkPipelineStageFlags dstStageMask = %d, uint32_t memoryBarrierCount = %d, const VkMemoryBarrier* pMemoryBarriers = 0x%X, uint32_t bufferMemoryBarrierCount = %d, const VkBufferMemoryBarrier* pBufferMemoryBarriers = 0x%X, uint32_t imageMemoryBarrierCount = %d, const VkImageMemoryBarrier* pImageMemoryBarriers = 0x%X)",
   1525 	      commandBuffer, eventCount, pEvents, srcStageMask, dstStageMask, memoryBarrierCount, pMemoryBarriers, bufferMemoryBarrierCount, pBufferMemoryBarriers, imageMemoryBarrierCount, pImageMemoryBarriers);
   1526 
   1527 	vk::Cast(commandBuffer)->waitEvents(eventCount, pEvents, srcStageMask, dstStageMask, memoryBarrierCount, pMemoryBarriers, bufferMemoryBarrierCount, pBufferMemoryBarriers, imageMemoryBarrierCount, pImageMemoryBarriers);
   1528 }
   1529 
   1530 VKAPI_ATTR void VKAPI_CALL vkCmdPipelineBarrier(VkCommandBuffer commandBuffer, VkPipelineStageFlags srcStageMask, VkPipelineStageFlags dstStageMask, VkDependencyFlags dependencyFlags, uint32_t memoryBarrierCount, const VkMemoryBarrier* pMemoryBarriers, uint32_t bufferMemoryBarrierCount, const VkBufferMemoryBarrier* pBufferMemoryBarriers, uint32_t imageMemoryBarrierCount, const VkImageMemoryBarrier* pImageMemoryBarriers)
   1531 {
   1532 	TRACE("(VkCommandBuffer commandBuffer = 0x%X, VkPipelineStageFlags srcStageMask = 0x%X, VkPipelineStageFlags dstStageMask = 0x%X, VkDependencyFlags dependencyFlags = %d, uint32_t memoryBarrierCount = %d, onst VkMemoryBarrier* pMemoryBarriers = 0x%X,"
   1533 	      " uint32_t bufferMemoryBarrierCount = %d, const VkBufferMemoryBarrier* pBufferMemoryBarriers = 0x%X, uint32_t imageMemoryBarrierCount = %d, const VkImageMemoryBarrier* pImageMemoryBarriers = 0x%X)",
   1534 	      commandBuffer, srcStageMask, dstStageMask, dependencyFlags, memoryBarrierCount, pMemoryBarriers, bufferMemoryBarrierCount, pBufferMemoryBarriers, imageMemoryBarrierCount, pImageMemoryBarriers);
   1535 
   1536 	vk::Cast(commandBuffer)->pipelineBarrier(srcStageMask, dstStageMask, dependencyFlags,
   1537 	                                         memoryBarrierCount, pMemoryBarriers,
   1538 	                                         bufferMemoryBarrierCount, pBufferMemoryBarriers,
   1539 	                                         imageMemoryBarrierCount, pImageMemoryBarriers);
   1540 }
   1541 
   1542 VKAPI_ATTR void VKAPI_CALL vkCmdBeginQuery(VkCommandBuffer commandBuffer, VkQueryPool queryPool, uint32_t query, VkQueryControlFlags flags)
   1543 {
   1544 	TRACE("(VkCommandBuffer commandBuffer = 0x%X, VkQueryPool queryPool = 0x%X, uint32_t query = %d, VkQueryControlFlags flags = %d)",
   1545 	      commandBuffer, queryPool, query, flags);
   1546 
   1547 	vk::Cast(commandBuffer)->beginQuery(queryPool, query, flags);
   1548 }
   1549 
   1550 VKAPI_ATTR void VKAPI_CALL vkCmdEndQuery(VkCommandBuffer commandBuffer, VkQueryPool queryPool, uint32_t query)
   1551 {
   1552 	TRACE("(VkCommandBuffer commandBuffer = 0x%X, VkQueryPool queryPool = 0x%X, uint32_t query = %d)",
   1553 	      commandBuffer, queryPool, query);
   1554 
   1555 	vk::Cast(commandBuffer)->endQuery(queryPool, query);
   1556 }
   1557 
   1558 VKAPI_ATTR void VKAPI_CALL vkCmdResetQueryPool(VkCommandBuffer commandBuffer, VkQueryPool queryPool, uint32_t firstQuery, uint32_t queryCount)
   1559 {
   1560 	TRACE("(VkCommandBuffer commandBuffer = 0x%X, VkQueryPool queryPool = 0x%X, uint32_t firstQuery = %d, uint32_t queryCount = %d)",
   1561 	      commandBuffer, queryPool, firstQuery, queryCount);
   1562 
   1563 	vk::Cast(commandBuffer)->resetQueryPool(queryPool, firstQuery, queryCount);
   1564 }
   1565 
   1566 VKAPI_ATTR void VKAPI_CALL vkCmdWriteTimestamp(VkCommandBuffer commandBuffer, VkPipelineStageFlagBits pipelineStage, VkQueryPool queryPool, uint32_t query)
   1567 {
   1568 	TRACE("(VkCommandBuffer commandBuffer = 0x%X, VkPipelineStageFlagBits pipelineStage = %d, VkQueryPool queryPool = 0x%X, uint32_t query = %d)",
   1569 	      commandBuffer, pipelineStage, queryPool, query);
   1570 
   1571 	vk::Cast(commandBuffer)->writeTimestamp(pipelineStage, queryPool, query);
   1572 }
   1573 
   1574 VKAPI_ATTR void VKAPI_CALL vkCmdCopyQueryPoolResults(VkCommandBuffer commandBuffer, VkQueryPool queryPool, uint32_t firstQuery, uint32_t queryCount, VkBuffer dstBuffer, VkDeviceSize dstOffset, VkDeviceSize stride, VkQueryResultFlags flags)
   1575 {
   1576 	TRACE("(VkCommandBuffer commandBuffer = 0x%X, VkQueryPool queryPool = 0x%X, uint32_t firstQuery = %d, uint32_t queryCount = %d, VkBuffer dstBuffer = 0x%X, VkDeviceSize dstOffset = %d, VkDeviceSize stride = %d, VkQueryResultFlags flags = %d)",
   1577 	      commandBuffer, queryPool, firstQuery, queryCount, dstBuffer, dstOffset, stride, flags);
   1578 
   1579 	vk::Cast(commandBuffer)->copyQueryPoolResults(queryPool, firstQuery, queryCount, dstBuffer, dstOffset, stride, flags);
   1580 }
   1581 
   1582 VKAPI_ATTR void VKAPI_CALL vkCmdPushConstants(VkCommandBuffer commandBuffer, VkPipelineLayout layout, VkShaderStageFlags stageFlags, uint32_t offset, uint32_t size, const void* pValues)
   1583 {
   1584 	TRACE("(VkCommandBuffer commandBuffer = 0x%X, VkPipelineLayout layout = 0x%X, VkShaderStageFlags stageFlags = %d, uint32_t offset = %d, uint32_t size = %d, const void* pValues = 0x%X)",
   1585 	      commandBuffer, layout, stageFlags, offset, size, pValues);
   1586 
   1587 	vk::Cast(commandBuffer)->pushConstants(layout, stageFlags, offset, size, pValues);
   1588 }
   1589 
   1590 VKAPI_ATTR void VKAPI_CALL vkCmdBeginRenderPass(VkCommandBuffer commandBuffer, const VkRenderPassBeginInfo* pRenderPassBegin, VkSubpassContents contents)
   1591 {
   1592 	TRACE("(VkCommandBuffer commandBuffer = 0x%X, const VkRenderPassBeginInfo* pRenderPassBegin = 0x%X, VkSubpassContents contents = %d)",
   1593 	      commandBuffer, pRenderPassBegin, contents);
   1594 
   1595 	if(pRenderPassBegin->pNext)
   1596 	{
   1597 		UNIMPLEMENTED();
   1598 	}
   1599 
   1600 	vk::Cast(commandBuffer)->beginRenderPass(pRenderPassBegin->renderPass, pRenderPassBegin->framebuffer,
   1601 	                                         pRenderPassBegin->renderArea, pRenderPassBegin->clearValueCount,
   1602 	                                         pRenderPassBegin->pClearValues, contents);
   1603 }
   1604 
   1605 VKAPI_ATTR void VKAPI_CALL vkCmdNextSubpass(VkCommandBuffer commandBuffer, VkSubpassContents contents)
   1606 {
   1607 	TRACE("(VkCommandBuffer commandBuffer = 0x%X, VkSubpassContents contents = %d)",
   1608 	      commandBuffer, contents);
   1609 
   1610 	vk::Cast(commandBuffer)->nextSubpass(contents);
   1611 }
   1612 
   1613 VKAPI_ATTR void VKAPI_CALL vkCmdEndRenderPass(VkCommandBuffer commandBuffer)
   1614 {
   1615 	TRACE("(VkCommandBuffer commandBuffer = 0x%X)", commandBuffer);
   1616 
   1617 	vk::Cast(commandBuffer)->endRenderPass();
   1618 }
   1619 
   1620 VKAPI_ATTR void VKAPI_CALL vkCmdExecuteCommands(VkCommandBuffer commandBuffer, uint32_t commandBufferCount, const VkCommandBuffer* pCommandBuffers)
   1621 {
   1622 	TRACE("(VkCommandBuffer commandBuffer = 0x%X, uint32_t commandBufferCount = %d, const VkCommandBuffer* pCommandBuffers = 0x%X)",
   1623 	      commandBuffer, commandBufferCount, pCommandBuffers);
   1624 
   1625 	vk::Cast(commandBuffer)->executeCommands(commandBufferCount, pCommandBuffers);
   1626 }
   1627 
   1628 VKAPI_ATTR VkResult VKAPI_CALL vkEnumerateInstanceVersion(uint32_t* pApiVersion)
   1629 {
   1630 	TRACE("(uint32_t* pApiVersion = 0x%X)", pApiVersion);
   1631 	*pApiVersion = vk::API_VERSION;
   1632 	return VK_SUCCESS;
   1633 }
   1634 
   1635 VKAPI_ATTR VkResult VKAPI_CALL vkBindBufferMemory2(VkDevice device, uint32_t bindInfoCount, const VkBindBufferMemoryInfo* pBindInfos)
   1636 {
   1637 	TRACE("(VkDevice device = 0x%X, uint32_t bindInfoCount = %d, const VkBindBufferMemoryInfo* pBindInfos = 0x%X)",
   1638 	      device, bindInfoCount, pBindInfos);
   1639 
   1640 	for(uint32_t i = 0; i < bindInfoCount; i++)
   1641 	{
   1642 		if(pBindInfos[i].pNext)
   1643 		{
   1644 			UNIMPLEMENTED();
   1645 		}
   1646 
   1647 		vk::Cast(pBindInfos[i].buffer)->bind(pBindInfos[i].memory, pBindInfos[i].memoryOffset);
   1648 	}
   1649 
   1650 	return VK_SUCCESS;
   1651 }
   1652 
   1653 VKAPI_ATTR VkResult VKAPI_CALL vkBindImageMemory2(VkDevice device, uint32_t bindInfoCount, const VkBindImageMemoryInfo* pBindInfos)
   1654 {
   1655 	TRACE("()");
   1656 	UNIMPLEMENTED();
   1657 	return VK_SUCCESS;
   1658 }
   1659 
   1660 VKAPI_ATTR void VKAPI_CALL vkGetDeviceGroupPeerMemoryFeatures(VkDevice device, uint32_t heapIndex, uint32_t localDeviceIndex, uint32_t remoteDeviceIndex, VkPeerMemoryFeatureFlags* pPeerMemoryFeatures)
   1661 {
   1662 	TRACE("(VkDevice device = 0x%X, uint32_t heapIndex = %d, uint32_t localDeviceIndex = %d, uint32_t remoteDeviceIndex = %d, VkPeerMemoryFeatureFlags* pPeerMemoryFeatures = 0x%X)",
   1663 	      device, heapIndex, localDeviceIndex, remoteDeviceIndex, pPeerMemoryFeatures);
   1664 
   1665 	ASSERT(localDeviceIndex != remoteDeviceIndex); // "localDeviceIndex must not equal remoteDeviceIndex"
   1666 	UNREACHABLE(remoteDeviceIndex);   // Only one physical device is supported, and since the device indexes can't be equal, this should never be called.
   1667 }
   1668 
   1669 VKAPI_ATTR void VKAPI_CALL vkCmdSetDeviceMask(VkCommandBuffer commandBuffer, uint32_t deviceMask)
   1670 {
   1671 	TRACE("()");
   1672 	UNIMPLEMENTED();
   1673 }
   1674 
   1675 VKAPI_ATTR void VKAPI_CALL vkCmdDispatchBase(VkCommandBuffer commandBuffer, uint32_t baseGroupX, uint32_t baseGroupY, uint32_t baseGroupZ, uint32_t groupCountX, uint32_t groupCountY, uint32_t groupCountZ)
   1676 {
   1677 	TRACE("()");
   1678 	UNIMPLEMENTED();
   1679 }
   1680 
   1681 VKAPI_ATTR VkResult VKAPI_CALL vkEnumeratePhysicalDeviceGroups(VkInstance instance, uint32_t* pPhysicalDeviceGroupCount, VkPhysicalDeviceGroupProperties* pPhysicalDeviceGroupProperties)
   1682 {
   1683 	TRACE("VkInstance instance = 0x%X, uint32_t* pPhysicalDeviceGroupCount = 0x%X, VkPhysicalDeviceGroupProperties* pPhysicalDeviceGroupProperties = 0x%X",
   1684 	      instance, pPhysicalDeviceGroupCount, pPhysicalDeviceGroupProperties);
   1685 
   1686 	if(!pPhysicalDeviceGroupProperties)
   1687 	{
   1688 		*pPhysicalDeviceGroupCount = vk::Cast(instance)->getPhysicalDeviceGroupCount();
   1689 	}
   1690 	else
   1691 	{
   1692 		vk::Cast(instance)->getPhysicalDeviceGroups(*pPhysicalDeviceGroupCount, pPhysicalDeviceGroupProperties);
   1693 	}
   1694 
   1695 	return VK_SUCCESS;
   1696 }
   1697 
   1698 VKAPI_ATTR void VKAPI_CALL vkGetImageMemoryRequirements2(VkDevice device, const VkImageMemoryRequirementsInfo2* pInfo, VkMemoryRequirements2* pMemoryRequirements)
   1699 {
   1700 	TRACE("(VkDevice device = 0x%X, const VkImageMemoryRequirementsInfo2* pInfo = 0x%X, VkMemoryRequirements2* pMemoryRequirements = 0x%X)",
   1701 	      device, pInfo, pMemoryRequirements);
   1702 
   1703 	if(pInfo->pNext || pMemoryRequirements->pNext)
   1704 	{
   1705 		UNIMPLEMENTED();
   1706 	}
   1707 
   1708 	vkGetImageMemoryRequirements(device, pInfo->image, &(pMemoryRequirements->memoryRequirements));
   1709 }
   1710 
   1711 VKAPI_ATTR void VKAPI_CALL vkGetBufferMemoryRequirements2(VkDevice device, const VkBufferMemoryRequirementsInfo2* pInfo, VkMemoryRequirements2* pMemoryRequirements)
   1712 {
   1713 	TRACE("(VkDevice device = 0x%X, const VkBufferMemoryRequirementsInfo2* pInfo = 0x%X, VkMemoryRequirements2* pMemoryRequirements = 0x%X)",
   1714 	      device, pInfo, pMemoryRequirements);
   1715 
   1716 	if(pInfo->pNext || pMemoryRequirements->pNext)
   1717 	{
   1718 		UNIMPLEMENTED();
   1719 	}
   1720 
   1721 	vkGetBufferMemoryRequirements(device, pInfo->buffer, &(pMemoryRequirements->memoryRequirements));
   1722 }
   1723 
   1724 VKAPI_ATTR void VKAPI_CALL vkGetImageSparseMemoryRequirements2(VkDevice device, const VkImageSparseMemoryRequirementsInfo2* pInfo, uint32_t* pSparseMemoryRequirementCount, VkSparseImageMemoryRequirements2* pSparseMemoryRequirements)
   1725 {
   1726 	TRACE("(VkDevice device = 0x%X, const VkImageSparseMemoryRequirementsInfo2* pInfo = 0x%X, uint32_t* pSparseMemoryRequirementCount = 0x%X, VkSparseImageMemoryRequirements2* pSparseMemoryRequirements = 0x%X)",
   1727 	      device, pInfo, pSparseMemoryRequirementCount, pSparseMemoryRequirements);
   1728 
   1729 	if(pInfo->pNext || pSparseMemoryRequirements->pNext)
   1730 	{
   1731 		UNIMPLEMENTED();
   1732 	}
   1733 
   1734 	vkGetImageSparseMemoryRequirements(device, pInfo->image, pSparseMemoryRequirementCount, &(pSparseMemoryRequirements->memoryRequirements));
   1735 }
   1736 
   1737 VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceFeatures2(VkPhysicalDevice physicalDevice, VkPhysicalDeviceFeatures2* pFeatures)
   1738 {
   1739 	TRACE("(VkPhysicalDevice physicalDevice = 0x%X, VkPhysicalDeviceFeatures2* pFeatures = 0x%X)", physicalDevice, pFeatures);
   1740 
   1741 	VkBaseOutStructure* extensionFeatures = reinterpret_cast<VkBaseOutStructure*>(pFeatures->pNext);
   1742 	while(extensionFeatures)
   1743 	{
   1744 		switch(extensionFeatures->sType)
   1745 		{
   1746 		case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLER_YCBCR_CONVERSION_FEATURES:
   1747 			{
   1748 				auto& features = *reinterpret_cast<VkPhysicalDeviceSamplerYcbcrConversionFeatures*>(extensionFeatures);
   1749 				vk::Cast(physicalDevice)->getFeatures(&features);
   1750 			}
   1751 			break;
   1752 		case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_16BIT_STORAGE_FEATURES:
   1753 			{
   1754 				auto& features = *reinterpret_cast<VkPhysicalDevice16BitStorageFeatures*>(extensionFeatures);
   1755 				vk::Cast(physicalDevice)->getFeatures(&features);
   1756 			}
   1757 			break;
   1758 		case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VARIABLE_POINTER_FEATURES:
   1759 			{
   1760 				auto& features = *reinterpret_cast<VkPhysicalDeviceVariablePointerFeatures*>(extensionFeatures);
   1761 				vk::Cast(physicalDevice)->getFeatures(&features);
   1762 			}
   1763 			break;
   1764 		case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_8BIT_STORAGE_FEATURES_KHR:
   1765 			{
   1766 				auto& features = *reinterpret_cast<VkPhysicalDevice8BitStorageFeaturesKHR*>(extensionFeatures);
   1767 				vk::Cast(physicalDevice)->getFeatures(&features);
   1768 			}
   1769 			break;
   1770 		case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_FEATURES:
   1771 			{
   1772 				auto& features = *reinterpret_cast<VkPhysicalDeviceMultiviewFeatures*>(extensionFeatures);
   1773 				vk::Cast(physicalDevice)->getFeatures(&features);
   1774 			}
   1775 			break;
   1776 		case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROTECTED_MEMORY_FEATURES:
   1777 			{
   1778 				auto& features = *reinterpret_cast<VkPhysicalDeviceProtectedMemoryFeatures*>(extensionFeatures);
   1779 				vk::Cast(physicalDevice)->getFeatures(&features);
   1780 			}
   1781 			break;
   1782 		default:
   1783 			// "the [driver] must skip over, without processing (other than reading the sType and pNext members) any structures in the chain with sType values not defined by [supported extenions]"
   1784 			UNIMPLEMENTED();   // TODO(b/119321052): UNIMPLEMENTED() should be used only for features that must still be implemented. Use a more informational macro here.
   1785 			break;
   1786 		}
   1787 
   1788 		extensionFeatures = extensionFeatures->pNext;
   1789 	}
   1790 
   1791 	vkGetPhysicalDeviceFeatures(physicalDevice, &(pFeatures->features));
   1792 }
   1793 
   1794 VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceProperties2(VkPhysicalDevice physicalDevice, VkPhysicalDeviceProperties2* pProperties)
   1795 {
   1796 	TRACE("(VkPhysicalDevice physicalDevice = 0x%X, VkPhysicalDeviceProperties2* pProperties = 0x%X)", physicalDevice, pProperties);
   1797 
   1798 	VkBaseOutStructure* extensionProperties = reinterpret_cast<VkBaseOutStructure*>(pProperties->pNext);
   1799 	while(extensionProperties)
   1800 	{
   1801 		switch(extensionProperties->sType)
   1802 		{
   1803 		case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ID_PROPERTIES:
   1804 			{
   1805 				auto& properties = *reinterpret_cast<VkPhysicalDeviceIDProperties*>(extensionProperties);
   1806 				vk::Cast(physicalDevice)->getProperties(&properties);
   1807 			}
   1808 			break;
   1809 		case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_3_PROPERTIES:
   1810 			{
   1811 				auto& properties = *reinterpret_cast<VkPhysicalDeviceMaintenance3Properties*>(extensionProperties);
   1812 				vk::Cast(physicalDevice)->getProperties(&properties);
   1813 			}
   1814 			break;
   1815 		case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_PROPERTIES:
   1816 			{
   1817 				auto& properties = *reinterpret_cast<VkPhysicalDeviceMultiviewProperties*>(extensionProperties);
   1818 				vk::Cast(physicalDevice)->getProperties(&properties);
   1819 			}
   1820 			break;
   1821 		case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_POINT_CLIPPING_PROPERTIES:
   1822 			{
   1823 				auto& properties = *reinterpret_cast<VkPhysicalDevicePointClippingProperties*>(extensionProperties);
   1824 				vk::Cast(physicalDevice)->getProperties(&properties);
   1825 			}
   1826 			break;
   1827 		case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROTECTED_MEMORY_PROPERTIES:
   1828 			{
   1829 				auto& properties = *reinterpret_cast<VkPhysicalDeviceProtectedMemoryProperties*>(extensionProperties);
   1830 				vk::Cast(physicalDevice)->getProperties(&properties);
   1831 			}
   1832 			break;
   1833 		case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SUBGROUP_PROPERTIES:
   1834 			{
   1835 				auto& properties = *reinterpret_cast<VkPhysicalDeviceSubgroupProperties*>(extensionProperties);
   1836 				vk::Cast(physicalDevice)->getProperties(&properties);
   1837 			}
   1838 			break;
   1839 		default:
   1840 			// "the [driver] must skip over, without processing (other than reading the sType and pNext members) any structures in the chain with sType values not defined by [supported extenions]"
   1841 			UNIMPLEMENTED();   // TODO(b/119321052): UNIMPLEMENTED() should be used only for features that must still be implemented. Use a more informational macro here.
   1842 			break;
   1843 		}
   1844 
   1845 		extensionProperties = extensionProperties->pNext;
   1846 	}
   1847 
   1848 	vkGetPhysicalDeviceProperties(physicalDevice, &(pProperties->properties));
   1849 }
   1850 
   1851 VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceFormatProperties2(VkPhysicalDevice physicalDevice, VkFormat format, VkFormatProperties2* pFormatProperties)
   1852 {
   1853 	TRACE("(VkPhysicalDevice physicalDevice = 0x%X, VkFormat format = %d, VkFormatProperties2* pFormatProperties = 0x%X)",
   1854 		    physicalDevice, format, pFormatProperties);
   1855 
   1856 	if(pFormatProperties->pNext)
   1857 	{
   1858 		UNIMPLEMENTED();
   1859 	}
   1860 
   1861 	vkGetPhysicalDeviceFormatProperties(physicalDevice, format, &(pFormatProperties->formatProperties));
   1862 }
   1863 
   1864 VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceImageFormatProperties2(VkPhysicalDevice physicalDevice, const VkPhysicalDeviceImageFormatInfo2* pImageFormatInfo, VkImageFormatProperties2* pImageFormatProperties)
   1865 {
   1866 	TRACE("(VkPhysicalDevice physicalDevice = 0x%X, const VkPhysicalDeviceImageFormatInfo2* pImageFormatInfo = 0x%X, VkImageFormatProperties2* pImageFormatProperties = 0x%X)",
   1867 		    physicalDevice, pImageFormatInfo, pImageFormatProperties);
   1868 
   1869 	if(pImageFormatInfo->pNext || pImageFormatProperties->pNext)
   1870 	{
   1871 		UNIMPLEMENTED();
   1872 	}
   1873 
   1874 	return vkGetPhysicalDeviceImageFormatProperties(physicalDevice,
   1875 		                                            pImageFormatInfo->format,
   1876 		                                            pImageFormatInfo->type,
   1877 		                                            pImageFormatInfo->tiling,
   1878 		                                            pImageFormatInfo->usage,
   1879 		                                            pImageFormatInfo->flags,
   1880 		                                            &(pImageFormatProperties->imageFormatProperties));
   1881 }
   1882 
   1883 VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceQueueFamilyProperties2(VkPhysicalDevice physicalDevice, uint32_t* pQueueFamilyPropertyCount, VkQueueFamilyProperties2* pQueueFamilyProperties)
   1884 {
   1885 	TRACE("(VkPhysicalDevice physicalDevice = 0x%X, uint32_t* pQueueFamilyPropertyCount = 0x%X, VkQueueFamilyProperties2* pQueueFamilyProperties = 0x%X)",
   1886 		physicalDevice, pQueueFamilyPropertyCount, pQueueFamilyProperties);
   1887 
   1888 	if(pQueueFamilyProperties && pQueueFamilyProperties->pNext)
   1889 	{
   1890 		UNIMPLEMENTED();
   1891 	}
   1892 
   1893 	vkGetPhysicalDeviceQueueFamilyProperties(physicalDevice, pQueueFamilyPropertyCount,
   1894 		pQueueFamilyProperties ? &(pQueueFamilyProperties->queueFamilyProperties) : nullptr);
   1895 }
   1896 
   1897 VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceMemoryProperties2(VkPhysicalDevice physicalDevice, VkPhysicalDeviceMemoryProperties2* pMemoryProperties)
   1898 {
   1899 	TRACE("(VkPhysicalDevice physicalDevice = 0x%X, VkPhysicalDeviceMemoryProperties2* pMemoryProperties = 0x%X)", physicalDevice, pMemoryProperties);
   1900 
   1901 	if(pMemoryProperties->pNext)
   1902 	{
   1903 		UNIMPLEMENTED();
   1904 	}
   1905 
   1906 	vkGetPhysicalDeviceMemoryProperties(physicalDevice, &(pMemoryProperties->memoryProperties));
   1907 }
   1908 
   1909 VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceSparseImageFormatProperties2(VkPhysicalDevice physicalDevice, const VkPhysicalDeviceSparseImageFormatInfo2* pFormatInfo, uint32_t* pPropertyCount, VkSparseImageFormatProperties2* pProperties)
   1910 {
   1911 	TRACE("(VkPhysicalDevice physicalDevice = 0x%X, const VkPhysicalDeviceSparseImageFormatInfo2* pFormatInfo = 0x%X, uint32_t* pPropertyCount = 0x%X, VkSparseImageFormatProperties2* pProperties = 0x%X)",
   1912 	     physicalDevice, pFormatInfo, pPropertyCount, pProperties);
   1913 
   1914 	if(pProperties && pProperties->pNext)
   1915 	{
   1916 		UNIMPLEMENTED();
   1917 	}
   1918 
   1919 	vkGetPhysicalDeviceSparseImageFormatProperties(physicalDevice, pFormatInfo->format, pFormatInfo->type,
   1920 	                                               pFormatInfo->samples, pFormatInfo->usage, pFormatInfo->tiling,
   1921 	                                               pPropertyCount, pProperties ? &(pProperties->properties) : nullptr);
   1922 }
   1923 
   1924 VKAPI_ATTR void VKAPI_CALL vkTrimCommandPool(VkDevice device, VkCommandPool commandPool, VkCommandPoolTrimFlags flags)
   1925 {
   1926 	TRACE("(VkDevice device = 0x%X, VkCommandPool commandPool = 0x%X, VkCommandPoolTrimFlags flags = %d)",
   1927 	      device, commandPool, flags);
   1928 
   1929 	vk::Cast(commandPool)->trim(flags);
   1930 }
   1931 
   1932 VKAPI_ATTR void VKAPI_CALL vkGetDeviceQueue2(VkDevice device, const VkDeviceQueueInfo2* pQueueInfo, VkQueue* pQueue)
   1933 {
   1934 	TRACE("(VkDevice device = 0x%X, const VkDeviceQueueInfo2* pQueueInfo = 0x%X, VkQueue* pQueue = 0x%X)",
   1935 	      device, pQueueInfo, pQueue);
   1936 
   1937 	if(pQueueInfo->pNext)
   1938 	{
   1939 		UNIMPLEMENTED();
   1940 	}
   1941 
   1942 	// The only flag that can be set here is VK_DEVICE_QUEUE_CREATE_PROTECTED_BIT
   1943 	// According to the Vulkan spec, 4.3.1. Queue Family Properties:
   1944 	// "VK_DEVICE_QUEUE_CREATE_PROTECTED_BIT specifies that the device queue is a
   1945 	//  protected-capable queue. If the protected memory feature is not enabled,
   1946 	//  the VK_DEVICE_QUEUE_CREATE_PROTECTED_BIT bit of flags must not be set."
   1947 	if(pQueueInfo->flags)
   1948 	{
   1949 		*pQueue = VK_NULL_HANDLE;
   1950 	}
   1951 	else
   1952 	{
   1953 		vkGetDeviceQueue(device, pQueueInfo->queueFamilyIndex, pQueueInfo->queueIndex, pQueue);
   1954 	}
   1955 }
   1956 
   1957 VKAPI_ATTR VkResult VKAPI_CALL vkCreateSamplerYcbcrConversion(VkDevice device, const VkSamplerYcbcrConversionCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSamplerYcbcrConversion* pYcbcrConversion)
   1958 {
   1959 	TRACE("()");
   1960 	UNIMPLEMENTED();
   1961 	return VK_SUCCESS;
   1962 }
   1963 
   1964 VKAPI_ATTR void VKAPI_CALL vkDestroySamplerYcbcrConversion(VkDevice device, VkSamplerYcbcrConversion ycbcrConversion, const VkAllocationCallbacks* pAllocator)
   1965 {
   1966 	TRACE("()");
   1967 	UNIMPLEMENTED();
   1968 }
   1969 
   1970 VKAPI_ATTR VkResult VKAPI_CALL vkCreateDescriptorUpdateTemplate(VkDevice device, const VkDescriptorUpdateTemplateCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkDescriptorUpdateTemplate* pDescriptorUpdateTemplate)
   1971 {
   1972 	TRACE("()");
   1973 	UNIMPLEMENTED();
   1974 	return VK_SUCCESS;
   1975 }
   1976 
   1977 VKAPI_ATTR void VKAPI_CALL vkDestroyDescriptorUpdateTemplate(VkDevice device, VkDescriptorUpdateTemplate descriptorUpdateTemplate, const VkAllocationCallbacks* pAllocator)
   1978 {
   1979 	TRACE("()");
   1980 	UNIMPLEMENTED();
   1981 }
   1982 
   1983 VKAPI_ATTR void VKAPI_CALL vkUpdateDescriptorSetWithTemplate(VkDevice device, VkDescriptorSet descriptorSet, VkDescriptorUpdateTemplate descriptorUpdateTemplate, const void* pData)
   1984 {
   1985 	TRACE("()");
   1986 	UNIMPLEMENTED();
   1987 }
   1988 
   1989 VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceExternalBufferProperties(VkPhysicalDevice physicalDevice, const VkPhysicalDeviceExternalBufferInfo* pExternalBufferInfo, VkExternalBufferProperties* pExternalBufferProperties)
   1990 {
   1991 	TRACE("(VkPhysicalDevice physicalDevice = 0x%X, const VkPhysicalDeviceExternalBufferInfo* pExternalBufferInfo = 0x%X, VkExternalBufferProperties* pExternalBufferProperties = 0x%X)",
   1992 	      physicalDevice, pExternalBufferInfo, pExternalBufferProperties);
   1993 
   1994 	UNIMPLEMENTED();
   1995 }
   1996 
   1997 VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceExternalFenceProperties(VkPhysicalDevice physicalDevice, const VkPhysicalDeviceExternalFenceInfo* pExternalFenceInfo, VkExternalFenceProperties* pExternalFenceProperties)
   1998 {
   1999 	TRACE("(VkPhysicalDevice physicalDevice = 0x%X, const VkPhysicalDeviceExternalFenceInfo* pExternalFenceInfo = 0x%X, VkExternalFenceProperties* pExternalFenceProperties = 0x%X)",
   2000 	      physicalDevice, pExternalFenceInfo, pExternalFenceProperties);
   2001 
   2002 	UNIMPLEMENTED();
   2003 }
   2004 
   2005 VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceExternalSemaphoreProperties(VkPhysicalDevice physicalDevice, const VkPhysicalDeviceExternalSemaphoreInfo* pExternalSemaphoreInfo, VkExternalSemaphoreProperties* pExternalSemaphoreProperties)
   2006 {
   2007 	TRACE("(VkPhysicalDevice physicalDevice = 0x%X, const VkPhysicalDeviceExternalSemaphoreInfo* pExternalSemaphoreInfo = 0x%X, VkExternalSemaphoreProperties* pExternalSemaphoreProperties = 0x%X)",
   2008 	      physicalDevice, pExternalSemaphoreInfo, pExternalSemaphoreProperties);
   2009 
   2010 	UNIMPLEMENTED();
   2011 }
   2012 
   2013 VKAPI_ATTR void VKAPI_CALL vkGetDescriptorSetLayoutSupport(VkDevice device, const VkDescriptorSetLayoutCreateInfo* pCreateInfo, VkDescriptorSetLayoutSupport* pSupport)
   2014 {
   2015 	TRACE("(VkDevice device, const VkDescriptorSetLayoutCreateInfo* pCreateInfo, VkDescriptorSetLayoutSupport* pSupport)",
   2016 	      device, pCreateInfo, pSupport);
   2017 
   2018 	vk::Cast(device)->getDescriptorSetLayoutSupport(pCreateInfo, pSupport);
   2019 }
   2020 
   2021 }
   2022