17ec681f3Smrg/*
27ec681f3Smrg * Copyright © 2020 Intel Corporation
37ec681f3Smrg *
47ec681f3Smrg * Permission is hereby granted, free of charge, to any person obtaining a
57ec681f3Smrg * copy of this software and associated documentation files (the "Software"),
67ec681f3Smrg * to deal in the Software without restriction, including without limitation
77ec681f3Smrg * the rights to use, copy, modify, merge, publish, distribute, sublicense,
87ec681f3Smrg * and/or sell copies of the Software, and to permit persons to whom the
97ec681f3Smrg * Software is furnished to do so, subject to the following conditions:
107ec681f3Smrg *
117ec681f3Smrg * The above copyright notice and this permission notice (including the next
127ec681f3Smrg * paragraph) shall be included in all copies or substantial portions of the
137ec681f3Smrg * Software.
147ec681f3Smrg *
157ec681f3Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
167ec681f3Smrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
177ec681f3Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
187ec681f3Smrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
197ec681f3Smrg * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
207ec681f3Smrg * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
217ec681f3Smrg * IN THE SOFTWARE.
227ec681f3Smrg */
237ec681f3Smrg
247ec681f3Smrg#include "vk_device.h"
257ec681f3Smrg
267ec681f3Smrg#include "vk_common_entrypoints.h"
277ec681f3Smrg#include "vk_instance.h"
287ec681f3Smrg#include "vk_log.h"
297ec681f3Smrg#include "vk_physical_device.h"
307ec681f3Smrg#include "vk_queue.h"
317ec681f3Smrg#include "vk_util.h"
327ec681f3Smrg#include "util/hash_table.h"
337ec681f3Smrg#include "util/ralloc.h"
347ec681f3Smrg
357ec681f3SmrgVkResult
367ec681f3Smrgvk_device_init(struct vk_device *device,
377ec681f3Smrg               struct vk_physical_device *physical_device,
387ec681f3Smrg               const struct vk_device_dispatch_table *dispatch_table,
397ec681f3Smrg               const VkDeviceCreateInfo *pCreateInfo,
407ec681f3Smrg               const VkAllocationCallbacks *alloc)
417ec681f3Smrg{
427ec681f3Smrg   memset(device, 0, sizeof(*device));
437ec681f3Smrg   vk_object_base_init(device, &device->base, VK_OBJECT_TYPE_DEVICE);
447ec681f3Smrg   if (alloc != NULL)
457ec681f3Smrg      device->alloc = *alloc;
467ec681f3Smrg   else
477ec681f3Smrg      device->alloc = physical_device->instance->alloc;
487ec681f3Smrg
497ec681f3Smrg   device->physical = physical_device;
507ec681f3Smrg
517ec681f3Smrg   device->dispatch_table = *dispatch_table;
527ec681f3Smrg
537ec681f3Smrg   /* Add common entrypoints without overwriting driver-provided ones. */
547ec681f3Smrg   vk_device_dispatch_table_from_entrypoints(
557ec681f3Smrg      &device->dispatch_table, &vk_common_device_entrypoints, false);
567ec681f3Smrg
577ec681f3Smrg   for (uint32_t i = 0; i < pCreateInfo->enabledExtensionCount; i++) {
587ec681f3Smrg      int idx;
597ec681f3Smrg      for (idx = 0; idx < VK_DEVICE_EXTENSION_COUNT; idx++) {
607ec681f3Smrg         if (strcmp(pCreateInfo->ppEnabledExtensionNames[i],
617ec681f3Smrg                    vk_device_extensions[idx].extensionName) == 0)
627ec681f3Smrg            break;
637ec681f3Smrg      }
647ec681f3Smrg
657ec681f3Smrg      if (idx >= VK_DEVICE_EXTENSION_COUNT)
667ec681f3Smrg         return vk_errorf(physical_device, VK_ERROR_EXTENSION_NOT_PRESENT,
677ec681f3Smrg                          "%s not supported",
687ec681f3Smrg                          pCreateInfo->ppEnabledExtensionNames[i]);
697ec681f3Smrg
707ec681f3Smrg      if (!physical_device->supported_extensions.extensions[idx])
717ec681f3Smrg         return vk_errorf(physical_device, VK_ERROR_EXTENSION_NOT_PRESENT,
727ec681f3Smrg                          "%s not supported",
737ec681f3Smrg                          pCreateInfo->ppEnabledExtensionNames[i]);
747ec681f3Smrg
757ec681f3Smrg#ifdef ANDROID
767ec681f3Smrg      if (!vk_android_allowed_device_extensions.extensions[idx])
777ec681f3Smrg         return vk_errorf(physical_device, VK_ERROR_EXTENSION_NOT_PRESENT,
787ec681f3Smrg                          "%s not supported",
797ec681f3Smrg                          pCreateInfo->ppEnabledExtensionNames[i]);
807ec681f3Smrg#endif
817ec681f3Smrg
827ec681f3Smrg      device->enabled_extensions.extensions[idx] = true;
837ec681f3Smrg   }
847ec681f3Smrg
857ec681f3Smrg   VkResult result =
867ec681f3Smrg      vk_physical_device_check_device_features(physical_device,
877ec681f3Smrg                                               pCreateInfo);
887ec681f3Smrg   if (result != VK_SUCCESS)
897ec681f3Smrg      return result;
907ec681f3Smrg
917ec681f3Smrg   p_atomic_set(&device->private_data_next_index, 0);
927ec681f3Smrg
937ec681f3Smrg   list_inithead(&device->queues);
947ec681f3Smrg
957ec681f3Smrg#ifdef ANDROID
967ec681f3Smrg   mtx_init(&device->swapchain_private_mtx, mtx_plain);
977ec681f3Smrg   device->swapchain_private = NULL;
987ec681f3Smrg#endif /* ANDROID */
997ec681f3Smrg
1007ec681f3Smrg   return VK_SUCCESS;
1017ec681f3Smrg}
1027ec681f3Smrg
1037ec681f3Smrgvoid
1047ec681f3Smrgvk_device_finish(UNUSED struct vk_device *device)
1057ec681f3Smrg{
1067ec681f3Smrg   /* Drivers should tear down their own queues */
1077ec681f3Smrg   assert(list_is_empty(&device->queues));
1087ec681f3Smrg
1097ec681f3Smrg#ifdef ANDROID
1107ec681f3Smrg   if (device->swapchain_private) {
1117ec681f3Smrg      hash_table_foreach(device->swapchain_private, entry)
1127ec681f3Smrg         util_sparse_array_finish(entry->data);
1137ec681f3Smrg      ralloc_free(device->swapchain_private);
1147ec681f3Smrg   }
1157ec681f3Smrg#endif /* ANDROID */
1167ec681f3Smrg
1177ec681f3Smrg   vk_object_base_finish(&device->base);
1187ec681f3Smrg}
1197ec681f3Smrg
1207ec681f3SmrgPFN_vkVoidFunction
1217ec681f3Smrgvk_device_get_proc_addr(const struct vk_device *device,
1227ec681f3Smrg                        const char *name)
1237ec681f3Smrg{
1247ec681f3Smrg   if (device == NULL || name == NULL)
1257ec681f3Smrg      return NULL;
1267ec681f3Smrg
1277ec681f3Smrg   struct vk_instance *instance = device->physical->instance;
1287ec681f3Smrg   return vk_device_dispatch_table_get_if_supported(&device->dispatch_table,
1297ec681f3Smrg                                                    name,
1307ec681f3Smrg                                                    instance->app_info.api_version,
1317ec681f3Smrg                                                    &instance->enabled_extensions,
1327ec681f3Smrg                                                    &device->enabled_extensions);
1337ec681f3Smrg}
1347ec681f3Smrg
1357ec681f3SmrgVKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL
1367ec681f3Smrgvk_common_GetDeviceProcAddr(VkDevice _device,
1377ec681f3Smrg                            const char *pName)
1387ec681f3Smrg{
1397ec681f3Smrg   VK_FROM_HANDLE(vk_device, device, _device);
1407ec681f3Smrg   return vk_device_get_proc_addr(device, pName);
1417ec681f3Smrg}
1427ec681f3Smrg
1437ec681f3SmrgVKAPI_ATTR void VKAPI_CALL
1447ec681f3Smrgvk_common_GetDeviceQueue(VkDevice _device,
1457ec681f3Smrg                         uint32_t queueFamilyIndex,
1467ec681f3Smrg                         uint32_t queueIndex,
1477ec681f3Smrg                         VkQueue *pQueue)
1487ec681f3Smrg{
1497ec681f3Smrg   VK_FROM_HANDLE(vk_device, device, _device);
1507ec681f3Smrg
1517ec681f3Smrg   const VkDeviceQueueInfo2 info = {
1527ec681f3Smrg      .sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_INFO_2,
1537ec681f3Smrg      .pNext = NULL,
1547ec681f3Smrg      /* flags = 0 because (Vulkan spec 1.2.170 - vkGetDeviceQueue):
1557ec681f3Smrg       *
1567ec681f3Smrg       *    "vkGetDeviceQueue must only be used to get queues that were
1577ec681f3Smrg       *     created with the flags parameter of VkDeviceQueueCreateInfo set
1587ec681f3Smrg       *     to zero. To get queues that were created with a non-zero flags
1597ec681f3Smrg       *     parameter use vkGetDeviceQueue2."
1607ec681f3Smrg       */
1617ec681f3Smrg      .flags = 0,
1627ec681f3Smrg      .queueFamilyIndex = queueFamilyIndex,
1637ec681f3Smrg      .queueIndex = queueIndex,
1647ec681f3Smrg   };
1657ec681f3Smrg
1667ec681f3Smrg   device->dispatch_table.GetDeviceQueue2(_device, &info, pQueue);
1677ec681f3Smrg}
1687ec681f3Smrg
1697ec681f3SmrgVKAPI_ATTR void VKAPI_CALL
1707ec681f3Smrgvk_common_GetDeviceQueue2(VkDevice _device,
1717ec681f3Smrg                          const VkDeviceQueueInfo2 *pQueueInfo,
1727ec681f3Smrg                          VkQueue *pQueue)
1737ec681f3Smrg{
1747ec681f3Smrg   VK_FROM_HANDLE(vk_device, device, _device);
1757ec681f3Smrg
1767ec681f3Smrg   struct vk_queue *queue = NULL;
1777ec681f3Smrg   vk_foreach_queue(iter, device) {
1787ec681f3Smrg      if (iter->queue_family_index == pQueueInfo->queueFamilyIndex &&
1797ec681f3Smrg          iter->index_in_family == pQueueInfo->queueIndex) {
1807ec681f3Smrg         queue = iter;
1817ec681f3Smrg         break;
1827ec681f3Smrg      }
1837ec681f3Smrg   }
1847ec681f3Smrg
1857ec681f3Smrg   /* From the Vulkan 1.1.70 spec:
1867ec681f3Smrg    *
1877ec681f3Smrg    *    "The queue returned by vkGetDeviceQueue2 must have the same flags
1887ec681f3Smrg    *    value from this structure as that used at device creation time in a
1897ec681f3Smrg    *    VkDeviceQueueCreateInfo instance. If no matching flags were specified
1907ec681f3Smrg    *    at device creation time then pQueue will return VK_NULL_HANDLE."
1917ec681f3Smrg    */
1927ec681f3Smrg   if (queue && queue->flags == pQueueInfo->flags)
1937ec681f3Smrg      *pQueue = vk_queue_to_handle(queue);
1947ec681f3Smrg   else
1957ec681f3Smrg      *pQueue = VK_NULL_HANDLE;
1967ec681f3Smrg}
1977ec681f3Smrg
1987ec681f3SmrgVKAPI_ATTR void VKAPI_CALL
1997ec681f3Smrgvk_common_GetBufferMemoryRequirements(VkDevice _device,
2007ec681f3Smrg                                      VkBuffer buffer,
2017ec681f3Smrg                                      VkMemoryRequirements *pMemoryRequirements)
2027ec681f3Smrg{
2037ec681f3Smrg   VK_FROM_HANDLE(vk_device, device, _device);
2047ec681f3Smrg
2057ec681f3Smrg   VkBufferMemoryRequirementsInfo2 info = {
2067ec681f3Smrg      .sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_REQUIREMENTS_INFO_2,
2077ec681f3Smrg      .buffer = buffer,
2087ec681f3Smrg   };
2097ec681f3Smrg   VkMemoryRequirements2 reqs = {
2107ec681f3Smrg      .sType = VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2,
2117ec681f3Smrg   };
2127ec681f3Smrg   device->dispatch_table.GetBufferMemoryRequirements2(_device, &info, &reqs);
2137ec681f3Smrg
2147ec681f3Smrg   *pMemoryRequirements = reqs.memoryRequirements;
2157ec681f3Smrg}
2167ec681f3Smrg
2177ec681f3SmrgVKAPI_ATTR VkResult VKAPI_CALL
2187ec681f3Smrgvk_common_BindBufferMemory(VkDevice _device,
2197ec681f3Smrg                           VkBuffer buffer,
2207ec681f3Smrg                           VkDeviceMemory memory,
2217ec681f3Smrg                           VkDeviceSize memoryOffset)
2227ec681f3Smrg{
2237ec681f3Smrg   VK_FROM_HANDLE(vk_device, device, _device);
2247ec681f3Smrg
2257ec681f3Smrg   VkBindBufferMemoryInfo bind = {
2267ec681f3Smrg      .sType         = VK_STRUCTURE_TYPE_BIND_BUFFER_MEMORY_INFO,
2277ec681f3Smrg      .buffer        = buffer,
2287ec681f3Smrg      .memory        = memory,
2297ec681f3Smrg      .memoryOffset  = memoryOffset,
2307ec681f3Smrg   };
2317ec681f3Smrg
2327ec681f3Smrg   return device->dispatch_table.BindBufferMemory2(_device, 1, &bind);
2337ec681f3Smrg}
2347ec681f3Smrg
2357ec681f3SmrgVKAPI_ATTR void VKAPI_CALL
2367ec681f3Smrgvk_common_GetImageMemoryRequirements(VkDevice _device,
2377ec681f3Smrg                                     VkImage image,
2387ec681f3Smrg                                     VkMemoryRequirements *pMemoryRequirements)
2397ec681f3Smrg{
2407ec681f3Smrg   VK_FROM_HANDLE(vk_device, device, _device);
2417ec681f3Smrg
2427ec681f3Smrg   VkImageMemoryRequirementsInfo2 info = {
2437ec681f3Smrg      .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_REQUIREMENTS_INFO_2,
2447ec681f3Smrg      .image = image,
2457ec681f3Smrg   };
2467ec681f3Smrg   VkMemoryRequirements2 reqs = {
2477ec681f3Smrg      .sType = VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2,
2487ec681f3Smrg   };
2497ec681f3Smrg   device->dispatch_table.GetImageMemoryRequirements2(_device, &info, &reqs);
2507ec681f3Smrg
2517ec681f3Smrg   *pMemoryRequirements = reqs.memoryRequirements;
2527ec681f3Smrg}
2537ec681f3Smrg
2547ec681f3SmrgVKAPI_ATTR VkResult VKAPI_CALL
2557ec681f3Smrgvk_common_BindImageMemory(VkDevice _device,
2567ec681f3Smrg                          VkImage image,
2577ec681f3Smrg                          VkDeviceMemory memory,
2587ec681f3Smrg                          VkDeviceSize memoryOffset)
2597ec681f3Smrg{
2607ec681f3Smrg   VK_FROM_HANDLE(vk_device, device, _device);
2617ec681f3Smrg
2627ec681f3Smrg   VkBindImageMemoryInfo bind = {
2637ec681f3Smrg      .sType         = VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_INFO,
2647ec681f3Smrg      .image         = image,
2657ec681f3Smrg      .memory        = memory,
2667ec681f3Smrg      .memoryOffset  = memoryOffset,
2677ec681f3Smrg   };
2687ec681f3Smrg
2697ec681f3Smrg   return device->dispatch_table.BindImageMemory2(_device, 1, &bind);
2707ec681f3Smrg}
2717ec681f3Smrg
2727ec681f3SmrgVKAPI_ATTR void VKAPI_CALL
2737ec681f3Smrgvk_common_GetImageSparseMemoryRequirements(VkDevice _device,
2747ec681f3Smrg                                           VkImage image,
2757ec681f3Smrg                                           uint32_t *pSparseMemoryRequirementCount,
2767ec681f3Smrg                                           VkSparseImageMemoryRequirements *pSparseMemoryRequirements)
2777ec681f3Smrg{
2787ec681f3Smrg   VK_FROM_HANDLE(vk_device, device, _device);
2797ec681f3Smrg
2807ec681f3Smrg   VkImageSparseMemoryRequirementsInfo2 info = {
2817ec681f3Smrg      .sType = VK_STRUCTURE_TYPE_IMAGE_SPARSE_MEMORY_REQUIREMENTS_INFO_2,
2827ec681f3Smrg      .image = image,
2837ec681f3Smrg   };
2847ec681f3Smrg
2857ec681f3Smrg   if (!pSparseMemoryRequirements) {
2867ec681f3Smrg      device->dispatch_table.GetImageSparseMemoryRequirements2(_device,
2877ec681f3Smrg                                                               &info,
2887ec681f3Smrg                                                               pSparseMemoryRequirementCount,
2897ec681f3Smrg                                                               NULL);
2907ec681f3Smrg      return;
2917ec681f3Smrg   }
2927ec681f3Smrg
2937ec681f3Smrg   STACK_ARRAY(VkSparseImageMemoryRequirements2, mem_reqs2, *pSparseMemoryRequirementCount);
2947ec681f3Smrg
2957ec681f3Smrg   for (unsigned i = 0; i < *pSparseMemoryRequirementCount; ++i) {
2967ec681f3Smrg      mem_reqs2[i].sType = VK_STRUCTURE_TYPE_SPARSE_IMAGE_MEMORY_REQUIREMENTS_2;
2977ec681f3Smrg      mem_reqs2[i].pNext = NULL;
2987ec681f3Smrg   }
2997ec681f3Smrg
3007ec681f3Smrg   device->dispatch_table.GetImageSparseMemoryRequirements2(_device,
3017ec681f3Smrg                                                            &info,
3027ec681f3Smrg                                                            pSparseMemoryRequirementCount,
3037ec681f3Smrg                                                            mem_reqs2);
3047ec681f3Smrg
3057ec681f3Smrg   for (unsigned i = 0; i < *pSparseMemoryRequirementCount; ++i)
3067ec681f3Smrg      pSparseMemoryRequirements[i] = mem_reqs2[i].memoryRequirements;
3077ec681f3Smrg
3087ec681f3Smrg   STACK_ARRAY_FINISH(mem_reqs2);
3097ec681f3Smrg}
3107ec681f3Smrg
3117ec681f3SmrgVKAPI_ATTR VkResult VKAPI_CALL
3127ec681f3Smrgvk_common_DeviceWaitIdle(VkDevice _device)
3137ec681f3Smrg{
3147ec681f3Smrg   VK_FROM_HANDLE(vk_device, device, _device);
3157ec681f3Smrg   const struct vk_device_dispatch_table *disp = &device->dispatch_table;
3167ec681f3Smrg
3177ec681f3Smrg   vk_foreach_queue(queue, device) {
3187ec681f3Smrg      VkResult result = disp->QueueWaitIdle(vk_queue_to_handle(queue));
3197ec681f3Smrg      if (result != VK_SUCCESS)
3207ec681f3Smrg         return result;
3217ec681f3Smrg   }
3227ec681f3Smrg
3237ec681f3Smrg   return VK_SUCCESS;
3247ec681f3Smrg}
3257ec681f3Smrg
3267ec681f3Smrgstatic void
3277ec681f3Smrgcopy_vk_struct_guts(VkBaseOutStructure *dst, VkBaseInStructure *src, size_t struct_size)
3287ec681f3Smrg{
3297ec681f3Smrg   STATIC_ASSERT(sizeof(*dst) == sizeof(*src));
3307ec681f3Smrg   memcpy(dst + 1, src + 1, struct_size - sizeof(VkBaseOutStructure));
3317ec681f3Smrg}
3327ec681f3Smrg
3337ec681f3Smrg#define CORE_FEATURE(feature) features->feature = core->feature
3347ec681f3Smrg
3357ec681f3Smrgbool
3367ec681f3Smrgvk_get_physical_device_core_1_1_feature_ext(struct VkBaseOutStructure *ext,
3377ec681f3Smrg                                            const VkPhysicalDeviceVulkan11Features *core)
3387ec681f3Smrg{
3397ec681f3Smrg
3407ec681f3Smrg   switch (ext->sType) {
3417ec681f3Smrg   case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_16BIT_STORAGE_FEATURES: {
3427ec681f3Smrg      VkPhysicalDevice16BitStorageFeatures *features = (void *)ext;
3437ec681f3Smrg      CORE_FEATURE(storageBuffer16BitAccess);
3447ec681f3Smrg      CORE_FEATURE(uniformAndStorageBuffer16BitAccess);
3457ec681f3Smrg      CORE_FEATURE(storagePushConstant16);
3467ec681f3Smrg      CORE_FEATURE(storageInputOutput16);
3477ec681f3Smrg      return true;
3487ec681f3Smrg   }
3497ec681f3Smrg
3507ec681f3Smrg   case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_FEATURES: {
3517ec681f3Smrg      VkPhysicalDeviceMultiviewFeatures *features = (void *)ext;
3527ec681f3Smrg      CORE_FEATURE(multiview);
3537ec681f3Smrg      CORE_FEATURE(multiviewGeometryShader);
3547ec681f3Smrg      CORE_FEATURE(multiviewTessellationShader);
3557ec681f3Smrg      return true;
3567ec681f3Smrg   }
3577ec681f3Smrg
3587ec681f3Smrg   case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROTECTED_MEMORY_FEATURES: {
3597ec681f3Smrg      VkPhysicalDeviceProtectedMemoryFeatures *features = (void *)ext;
3607ec681f3Smrg      CORE_FEATURE(protectedMemory);
3617ec681f3Smrg      return true;
3627ec681f3Smrg   }
3637ec681f3Smrg
3647ec681f3Smrg   case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLER_YCBCR_CONVERSION_FEATURES: {
3657ec681f3Smrg      VkPhysicalDeviceSamplerYcbcrConversionFeatures *features = (void *) ext;
3667ec681f3Smrg      CORE_FEATURE(samplerYcbcrConversion);
3677ec681f3Smrg      return true;
3687ec681f3Smrg   }
3697ec681f3Smrg
3707ec681f3Smrg   case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_DRAW_PARAMETERS_FEATURES: {
3717ec681f3Smrg      VkPhysicalDeviceShaderDrawParametersFeatures *features = (void *)ext;
3727ec681f3Smrg      CORE_FEATURE(shaderDrawParameters);
3737ec681f3Smrg      return true;
3747ec681f3Smrg   }
3757ec681f3Smrg
3767ec681f3Smrg   case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VARIABLE_POINTERS_FEATURES: {
3777ec681f3Smrg      VkPhysicalDeviceVariablePointersFeatures *features = (void *)ext;
3787ec681f3Smrg      CORE_FEATURE(variablePointersStorageBuffer);
3797ec681f3Smrg      CORE_FEATURE(variablePointers);
3807ec681f3Smrg      return true;
3817ec681f3Smrg   }
3827ec681f3Smrg
3837ec681f3Smrg   case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_FEATURES:
3847ec681f3Smrg      copy_vk_struct_guts(ext, (void *)core, sizeof(*core));
3857ec681f3Smrg      return true;
3867ec681f3Smrg
3877ec681f3Smrg   default:
3887ec681f3Smrg      return false;
3897ec681f3Smrg   }
3907ec681f3Smrg}
3917ec681f3Smrg
3927ec681f3Smrgbool
3937ec681f3Smrgvk_get_physical_device_core_1_2_feature_ext(struct VkBaseOutStructure *ext,
3947ec681f3Smrg                                            const VkPhysicalDeviceVulkan12Features *core)
3957ec681f3Smrg{
3967ec681f3Smrg
3977ec681f3Smrg   switch (ext->sType) {
3987ec681f3Smrg   case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_8BIT_STORAGE_FEATURES_KHR: {
3997ec681f3Smrg      VkPhysicalDevice8BitStorageFeaturesKHR *features = (void *)ext;
4007ec681f3Smrg      CORE_FEATURE(storageBuffer8BitAccess);
4017ec681f3Smrg      CORE_FEATURE(uniformAndStorageBuffer8BitAccess);
4027ec681f3Smrg      CORE_FEATURE(storagePushConstant8);
4037ec681f3Smrg      return true;
4047ec681f3Smrg   }
4057ec681f3Smrg
4067ec681f3Smrg   case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BUFFER_DEVICE_ADDRESS_FEATURES_KHR: {
4077ec681f3Smrg      VkPhysicalDeviceBufferDeviceAddressFeaturesKHR *features = (void *)ext;
4087ec681f3Smrg      CORE_FEATURE(bufferDeviceAddress);
4097ec681f3Smrg      CORE_FEATURE(bufferDeviceAddressCaptureReplay);
4107ec681f3Smrg      CORE_FEATURE(bufferDeviceAddressMultiDevice);
4117ec681f3Smrg      return true;
4127ec681f3Smrg   }
4137ec681f3Smrg
4147ec681f3Smrg   case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_FEATURES_EXT: {
4157ec681f3Smrg      VkPhysicalDeviceDescriptorIndexingFeaturesEXT *features = (void *)ext;
4167ec681f3Smrg      CORE_FEATURE(shaderInputAttachmentArrayDynamicIndexing);
4177ec681f3Smrg      CORE_FEATURE(shaderUniformTexelBufferArrayDynamicIndexing);
4187ec681f3Smrg      CORE_FEATURE(shaderStorageTexelBufferArrayDynamicIndexing);
4197ec681f3Smrg      CORE_FEATURE(shaderUniformBufferArrayNonUniformIndexing);
4207ec681f3Smrg      CORE_FEATURE(shaderSampledImageArrayNonUniformIndexing);
4217ec681f3Smrg      CORE_FEATURE(shaderStorageBufferArrayNonUniformIndexing);
4227ec681f3Smrg      CORE_FEATURE(shaderStorageImageArrayNonUniformIndexing);
4237ec681f3Smrg      CORE_FEATURE(shaderInputAttachmentArrayNonUniformIndexing);
4247ec681f3Smrg      CORE_FEATURE(shaderUniformTexelBufferArrayNonUniformIndexing);
4257ec681f3Smrg      CORE_FEATURE(shaderStorageTexelBufferArrayNonUniformIndexing);
4267ec681f3Smrg      CORE_FEATURE(descriptorBindingUniformBufferUpdateAfterBind);
4277ec681f3Smrg      CORE_FEATURE(descriptorBindingSampledImageUpdateAfterBind);
4287ec681f3Smrg      CORE_FEATURE(descriptorBindingStorageImageUpdateAfterBind);
4297ec681f3Smrg      CORE_FEATURE(descriptorBindingStorageBufferUpdateAfterBind);
4307ec681f3Smrg      CORE_FEATURE(descriptorBindingUniformTexelBufferUpdateAfterBind);
4317ec681f3Smrg      CORE_FEATURE(descriptorBindingStorageTexelBufferUpdateAfterBind);
4327ec681f3Smrg      CORE_FEATURE(descriptorBindingUpdateUnusedWhilePending);
4337ec681f3Smrg      CORE_FEATURE(descriptorBindingPartiallyBound);
4347ec681f3Smrg      CORE_FEATURE(descriptorBindingVariableDescriptorCount);
4357ec681f3Smrg      CORE_FEATURE(runtimeDescriptorArray);
4367ec681f3Smrg      return true;
4377ec681f3Smrg   }
4387ec681f3Smrg
4397ec681f3Smrg   case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FLOAT16_INT8_FEATURES_KHR: {
4407ec681f3Smrg      VkPhysicalDeviceFloat16Int8FeaturesKHR *features = (void *)ext;
4417ec681f3Smrg      CORE_FEATURE(shaderFloat16);
4427ec681f3Smrg      CORE_FEATURE(shaderInt8);
4437ec681f3Smrg      return true;
4447ec681f3Smrg   }
4457ec681f3Smrg
4467ec681f3Smrg   case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_HOST_QUERY_RESET_FEATURES_EXT: {
4477ec681f3Smrg      VkPhysicalDeviceHostQueryResetFeaturesEXT *features = (void *)ext;
4487ec681f3Smrg      CORE_FEATURE(hostQueryReset);
4497ec681f3Smrg      return true;
4507ec681f3Smrg   }
4517ec681f3Smrg
4527ec681f3Smrg   case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGELESS_FRAMEBUFFER_FEATURES_KHR: {
4537ec681f3Smrg      VkPhysicalDeviceImagelessFramebufferFeaturesKHR *features = (void *)ext;
4547ec681f3Smrg      CORE_FEATURE(imagelessFramebuffer);
4557ec681f3Smrg      return true;
4567ec681f3Smrg   }
4577ec681f3Smrg
4587ec681f3Smrg   case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SCALAR_BLOCK_LAYOUT_FEATURES_EXT: {
4597ec681f3Smrg      VkPhysicalDeviceScalarBlockLayoutFeaturesEXT *features =(void *)ext;
4607ec681f3Smrg      CORE_FEATURE(scalarBlockLayout);
4617ec681f3Smrg      return true;
4627ec681f3Smrg   }
4637ec681f3Smrg
4647ec681f3Smrg   case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SEPARATE_DEPTH_STENCIL_LAYOUTS_FEATURES_KHR: {
4657ec681f3Smrg      VkPhysicalDeviceSeparateDepthStencilLayoutsFeaturesKHR *features = (void *)ext;
4667ec681f3Smrg      CORE_FEATURE(separateDepthStencilLayouts);
4677ec681f3Smrg      return true;
4687ec681f3Smrg   }
4697ec681f3Smrg
4707ec681f3Smrg   case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_ATOMIC_INT64_FEATURES_KHR: {
4717ec681f3Smrg      VkPhysicalDeviceShaderAtomicInt64FeaturesKHR *features = (void *)ext;
4727ec681f3Smrg      CORE_FEATURE(shaderBufferInt64Atomics);
4737ec681f3Smrg      CORE_FEATURE(shaderSharedInt64Atomics);
4747ec681f3Smrg      return true;
4757ec681f3Smrg   }
4767ec681f3Smrg
4777ec681f3Smrg   case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_SUBGROUP_EXTENDED_TYPES_FEATURES_KHR: {
4787ec681f3Smrg      VkPhysicalDeviceShaderSubgroupExtendedTypesFeaturesKHR *features = (void *)ext;
4797ec681f3Smrg      CORE_FEATURE(shaderSubgroupExtendedTypes);
4807ec681f3Smrg      return true;
4817ec681f3Smrg   }
4827ec681f3Smrg
4837ec681f3Smrg   case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TIMELINE_SEMAPHORE_FEATURES_KHR: {
4847ec681f3Smrg      VkPhysicalDeviceTimelineSemaphoreFeaturesKHR *features = (void *) ext;
4857ec681f3Smrg      CORE_FEATURE(timelineSemaphore);
4867ec681f3Smrg      return true;
4877ec681f3Smrg   }
4887ec681f3Smrg
4897ec681f3Smrg   case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_UNIFORM_BUFFER_STANDARD_LAYOUT_FEATURES_KHR: {
4907ec681f3Smrg      VkPhysicalDeviceUniformBufferStandardLayoutFeaturesKHR *features = (void *)ext;
4917ec681f3Smrg      CORE_FEATURE(uniformBufferStandardLayout);
4927ec681f3Smrg      return true;
4937ec681f3Smrg   }
4947ec681f3Smrg
4957ec681f3Smrg   case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_MEMORY_MODEL_FEATURES_KHR: {
4967ec681f3Smrg      VkPhysicalDeviceVulkanMemoryModelFeaturesKHR *features = (void *)ext;
4977ec681f3Smrg      CORE_FEATURE(vulkanMemoryModel);
4987ec681f3Smrg      CORE_FEATURE(vulkanMemoryModelDeviceScope);
4997ec681f3Smrg      CORE_FEATURE(vulkanMemoryModelAvailabilityVisibilityChains);
5007ec681f3Smrg      return true;
5017ec681f3Smrg   }
5027ec681f3Smrg
5037ec681f3Smrg   case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_FEATURES:
5047ec681f3Smrg      copy_vk_struct_guts(ext, (void *)core, sizeof(*core));
5057ec681f3Smrg      return true;
5067ec681f3Smrg
5077ec681f3Smrg   default:
5087ec681f3Smrg      return false;
5097ec681f3Smrg   }
5107ec681f3Smrg}
5117ec681f3Smrg
5127ec681f3Smrg#undef CORE_FEATURE
5137ec681f3Smrg
5147ec681f3Smrg#define CORE_RENAMED_PROPERTY(ext_property, core_property) \
5157ec681f3Smrg   memcpy(&properties->ext_property, &core->core_property, sizeof(core->core_property))
5167ec681f3Smrg
5177ec681f3Smrg#define CORE_PROPERTY(property) CORE_RENAMED_PROPERTY(property, property)
5187ec681f3Smrg
5197ec681f3Smrgbool
5207ec681f3Smrgvk_get_physical_device_core_1_1_property_ext(struct VkBaseOutStructure *ext,
5217ec681f3Smrg                                             const VkPhysicalDeviceVulkan11Properties *core)
5227ec681f3Smrg{
5237ec681f3Smrg   switch (ext->sType) {
5247ec681f3Smrg   case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ID_PROPERTIES: {
5257ec681f3Smrg      VkPhysicalDeviceIDProperties *properties = (void *)ext;
5267ec681f3Smrg      CORE_PROPERTY(deviceUUID);
5277ec681f3Smrg      CORE_PROPERTY(driverUUID);
5287ec681f3Smrg      CORE_PROPERTY(deviceLUID);
5297ec681f3Smrg      CORE_PROPERTY(deviceLUIDValid);
5307ec681f3Smrg      return true;
5317ec681f3Smrg   }
5327ec681f3Smrg
5337ec681f3Smrg   case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_3_PROPERTIES: {
5347ec681f3Smrg      VkPhysicalDeviceMaintenance3Properties *properties = (void *)ext;
5357ec681f3Smrg      CORE_PROPERTY(maxPerSetDescriptors);
5367ec681f3Smrg      CORE_PROPERTY(maxMemoryAllocationSize);
5377ec681f3Smrg      return true;
5387ec681f3Smrg   }
5397ec681f3Smrg
5407ec681f3Smrg   case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_PROPERTIES: {
5417ec681f3Smrg      VkPhysicalDeviceMultiviewProperties *properties = (void *)ext;
5427ec681f3Smrg      CORE_PROPERTY(maxMultiviewViewCount);
5437ec681f3Smrg      CORE_PROPERTY(maxMultiviewInstanceIndex);
5447ec681f3Smrg      return true;
5457ec681f3Smrg   }
5467ec681f3Smrg
5477ec681f3Smrg   case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_POINT_CLIPPING_PROPERTIES: {
5487ec681f3Smrg      VkPhysicalDevicePointClippingProperties *properties = (void *) ext;
5497ec681f3Smrg      CORE_PROPERTY(pointClippingBehavior);
5507ec681f3Smrg      return true;
5517ec681f3Smrg   }
5527ec681f3Smrg
5537ec681f3Smrg   case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROTECTED_MEMORY_PROPERTIES: {
5547ec681f3Smrg      VkPhysicalDeviceProtectedMemoryProperties *properties = (void *)ext;
5557ec681f3Smrg      CORE_PROPERTY(protectedNoFault);
5567ec681f3Smrg      return true;
5577ec681f3Smrg   }
5587ec681f3Smrg
5597ec681f3Smrg   case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SUBGROUP_PROPERTIES: {
5607ec681f3Smrg      VkPhysicalDeviceSubgroupProperties *properties = (void *)ext;
5617ec681f3Smrg      CORE_PROPERTY(subgroupSize);
5627ec681f3Smrg      CORE_RENAMED_PROPERTY(supportedStages,
5637ec681f3Smrg                                    subgroupSupportedStages);
5647ec681f3Smrg      CORE_RENAMED_PROPERTY(supportedOperations,
5657ec681f3Smrg                                    subgroupSupportedOperations);
5667ec681f3Smrg      CORE_RENAMED_PROPERTY(quadOperationsInAllStages,
5677ec681f3Smrg                                    subgroupQuadOperationsInAllStages);
5687ec681f3Smrg      return true;
5697ec681f3Smrg   }
5707ec681f3Smrg
5717ec681f3Smrg   case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_PROPERTIES:
5727ec681f3Smrg      copy_vk_struct_guts(ext, (void *)core, sizeof(*core));
5737ec681f3Smrg      return true;
5747ec681f3Smrg
5757ec681f3Smrg   default:
5767ec681f3Smrg      return false;
5777ec681f3Smrg   }
5787ec681f3Smrg}
5797ec681f3Smrg
5807ec681f3Smrgbool
5817ec681f3Smrgvk_get_physical_device_core_1_2_property_ext(struct VkBaseOutStructure *ext,
5827ec681f3Smrg                                             const VkPhysicalDeviceVulkan12Properties *core)
5837ec681f3Smrg{
5847ec681f3Smrg   switch (ext->sType) {
5857ec681f3Smrg   case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEPTH_STENCIL_RESOLVE_PROPERTIES_KHR: {
5867ec681f3Smrg      VkPhysicalDeviceDepthStencilResolvePropertiesKHR *properties = (void *)ext;
5877ec681f3Smrg      CORE_PROPERTY(supportedDepthResolveModes);
5887ec681f3Smrg      CORE_PROPERTY(supportedStencilResolveModes);
5897ec681f3Smrg      CORE_PROPERTY(independentResolveNone);
5907ec681f3Smrg      CORE_PROPERTY(independentResolve);
5917ec681f3Smrg      return true;
5927ec681f3Smrg   }
5937ec681f3Smrg
5947ec681f3Smrg   case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_PROPERTIES_EXT: {
5957ec681f3Smrg      VkPhysicalDeviceDescriptorIndexingPropertiesEXT *properties = (void *)ext;
5967ec681f3Smrg      CORE_PROPERTY(maxUpdateAfterBindDescriptorsInAllPools);
5977ec681f3Smrg      CORE_PROPERTY(shaderUniformBufferArrayNonUniformIndexingNative);
5987ec681f3Smrg      CORE_PROPERTY(shaderSampledImageArrayNonUniformIndexingNative);
5997ec681f3Smrg      CORE_PROPERTY(shaderStorageBufferArrayNonUniformIndexingNative);
6007ec681f3Smrg      CORE_PROPERTY(shaderStorageImageArrayNonUniformIndexingNative);
6017ec681f3Smrg      CORE_PROPERTY(shaderInputAttachmentArrayNonUniformIndexingNative);
6027ec681f3Smrg      CORE_PROPERTY(robustBufferAccessUpdateAfterBind);
6037ec681f3Smrg      CORE_PROPERTY(quadDivergentImplicitLod);
6047ec681f3Smrg      CORE_PROPERTY(maxPerStageDescriptorUpdateAfterBindSamplers);
6057ec681f3Smrg      CORE_PROPERTY(maxPerStageDescriptorUpdateAfterBindUniformBuffers);
6067ec681f3Smrg      CORE_PROPERTY(maxPerStageDescriptorUpdateAfterBindStorageBuffers);
6077ec681f3Smrg      CORE_PROPERTY(maxPerStageDescriptorUpdateAfterBindSampledImages);
6087ec681f3Smrg      CORE_PROPERTY(maxPerStageDescriptorUpdateAfterBindStorageImages);
6097ec681f3Smrg      CORE_PROPERTY(maxPerStageDescriptorUpdateAfterBindInputAttachments);
6107ec681f3Smrg      CORE_PROPERTY(maxPerStageUpdateAfterBindResources);
6117ec681f3Smrg      CORE_PROPERTY(maxDescriptorSetUpdateAfterBindSamplers);
6127ec681f3Smrg      CORE_PROPERTY(maxDescriptorSetUpdateAfterBindUniformBuffers);
6137ec681f3Smrg      CORE_PROPERTY(maxDescriptorSetUpdateAfterBindUniformBuffersDynamic);
6147ec681f3Smrg      CORE_PROPERTY(maxDescriptorSetUpdateAfterBindStorageBuffers);
6157ec681f3Smrg      CORE_PROPERTY(maxDescriptorSetUpdateAfterBindStorageBuffersDynamic);
6167ec681f3Smrg      CORE_PROPERTY(maxDescriptorSetUpdateAfterBindSampledImages);
6177ec681f3Smrg      CORE_PROPERTY(maxDescriptorSetUpdateAfterBindStorageImages);
6187ec681f3Smrg      CORE_PROPERTY(maxDescriptorSetUpdateAfterBindInputAttachments);
6197ec681f3Smrg      return true;
6207ec681f3Smrg   }
6217ec681f3Smrg
6227ec681f3Smrg   case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DRIVER_PROPERTIES_KHR: {
6237ec681f3Smrg      VkPhysicalDeviceDriverPropertiesKHR *properties = (void *) ext;
6247ec681f3Smrg      CORE_PROPERTY(driverID);
6257ec681f3Smrg      CORE_PROPERTY(driverName);
6267ec681f3Smrg      CORE_PROPERTY(driverInfo);
6277ec681f3Smrg      CORE_PROPERTY(conformanceVersion);
6287ec681f3Smrg      return true;
6297ec681f3Smrg   }
6307ec681f3Smrg
6317ec681f3Smrg   case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLER_FILTER_MINMAX_PROPERTIES_EXT: {
6327ec681f3Smrg      VkPhysicalDeviceSamplerFilterMinmaxPropertiesEXT *properties = (void *)ext;
6337ec681f3Smrg      CORE_PROPERTY(filterMinmaxImageComponentMapping);
6347ec681f3Smrg      CORE_PROPERTY(filterMinmaxSingleComponentFormats);
6357ec681f3Smrg      return true;
6367ec681f3Smrg   }
6377ec681f3Smrg
6387ec681f3Smrg   case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FLOAT_CONTROLS_PROPERTIES_KHR : {
6397ec681f3Smrg      VkPhysicalDeviceFloatControlsPropertiesKHR *properties = (void *)ext;
6407ec681f3Smrg      CORE_PROPERTY(denormBehaviorIndependence);
6417ec681f3Smrg      CORE_PROPERTY(roundingModeIndependence);
6427ec681f3Smrg      CORE_PROPERTY(shaderDenormFlushToZeroFloat16);
6437ec681f3Smrg      CORE_PROPERTY(shaderDenormPreserveFloat16);
6447ec681f3Smrg      CORE_PROPERTY(shaderRoundingModeRTEFloat16);
6457ec681f3Smrg      CORE_PROPERTY(shaderRoundingModeRTZFloat16);
6467ec681f3Smrg      CORE_PROPERTY(shaderSignedZeroInfNanPreserveFloat16);
6477ec681f3Smrg      CORE_PROPERTY(shaderDenormFlushToZeroFloat32);
6487ec681f3Smrg      CORE_PROPERTY(shaderDenormPreserveFloat32);
6497ec681f3Smrg      CORE_PROPERTY(shaderRoundingModeRTEFloat32);
6507ec681f3Smrg      CORE_PROPERTY(shaderRoundingModeRTZFloat32);
6517ec681f3Smrg      CORE_PROPERTY(shaderSignedZeroInfNanPreserveFloat32);
6527ec681f3Smrg      CORE_PROPERTY(shaderDenormFlushToZeroFloat64);
6537ec681f3Smrg      CORE_PROPERTY(shaderDenormPreserveFloat64);
6547ec681f3Smrg      CORE_PROPERTY(shaderRoundingModeRTEFloat64);
6557ec681f3Smrg      CORE_PROPERTY(shaderRoundingModeRTZFloat64);
6567ec681f3Smrg      CORE_PROPERTY(shaderSignedZeroInfNanPreserveFloat64);
6577ec681f3Smrg      return true;
6587ec681f3Smrg   }
6597ec681f3Smrg
6607ec681f3Smrg   case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TIMELINE_SEMAPHORE_PROPERTIES_KHR: {
6617ec681f3Smrg      VkPhysicalDeviceTimelineSemaphorePropertiesKHR *properties = (void *) ext;
6627ec681f3Smrg      CORE_PROPERTY(maxTimelineSemaphoreValueDifference);
6637ec681f3Smrg      return true;
6647ec681f3Smrg   }
6657ec681f3Smrg
6667ec681f3Smrg   case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_PROPERTIES:
6677ec681f3Smrg      copy_vk_struct_guts(ext, (void *)core, sizeof(*core));
6687ec681f3Smrg      return true;
6697ec681f3Smrg
6707ec681f3Smrg   default:
6717ec681f3Smrg      return false;
6727ec681f3Smrg   }
6737ec681f3Smrg}
6747ec681f3Smrg
6757ec681f3Smrg#undef CORE_RENAMED_PROPERTY
6767ec681f3Smrg#undef CORE_PROPERTY
6777ec681f3Smrg
678