1cb93a386Sopenharmony_ci/* 2cb93a386Sopenharmony_ci * Copyright 2016 Google Inc. 3cb93a386Sopenharmony_ci * 4cb93a386Sopenharmony_ci * Use of this source code is governed by a BSD-style license that can be 5cb93a386Sopenharmony_ci * found in the LICENSE file. 6cb93a386Sopenharmony_ci */ 7cb93a386Sopenharmony_ci 8cb93a386Sopenharmony_ci#include "include/gpu/vk/GrVkExtensions.h" 9cb93a386Sopenharmony_ci 10cb93a386Sopenharmony_ci// Can remove this once we get rid of the extension flags. 11cb93a386Sopenharmony_ci#include "include/gpu/vk/GrVkBackendContext.h" 12cb93a386Sopenharmony_ci 13cb93a386Sopenharmony_ci#include "src/core/SkTSearch.h" 14cb93a386Sopenharmony_ci#include "src/core/SkTSort.h" 15cb93a386Sopenharmony_ci 16cb93a386Sopenharmony_ci// finds the index of ext in infos or a negative result if ext is not found. 17cb93a386Sopenharmony_cistatic int find_info(const SkTArray<GrVkExtensions::Info>& infos, const char ext[]) { 18cb93a386Sopenharmony_ci if (infos.empty()) { 19cb93a386Sopenharmony_ci return -1; 20cb93a386Sopenharmony_ci } 21cb93a386Sopenharmony_ci SkString extensionStr(ext); 22cb93a386Sopenharmony_ci GrVkExtensions::Info::Less less; 23cb93a386Sopenharmony_ci int idx = SkTSearch<GrVkExtensions::Info, SkString, GrVkExtensions::Info::Less>( 24cb93a386Sopenharmony_ci &infos.front(), infos.count(), extensionStr, sizeof(GrVkExtensions::Info), 25cb93a386Sopenharmony_ci less); 26cb93a386Sopenharmony_ci return idx; 27cb93a386Sopenharmony_ci} 28cb93a386Sopenharmony_ci 29cb93a386Sopenharmony_cinamespace { // This cannot be static because it is used as a template parameter. 30cb93a386Sopenharmony_ciinline bool extension_compare(const GrVkExtensions::Info& a, const GrVkExtensions::Info& b) { 31cb93a386Sopenharmony_ci return strcmp(a.fName.c_str(), b.fName.c_str()) < 0; 32cb93a386Sopenharmony_ci} 33cb93a386Sopenharmony_ci} // namespace 34cb93a386Sopenharmony_ci 35cb93a386Sopenharmony_civoid GrVkExtensions::init(GrVkGetProc getProc, 36cb93a386Sopenharmony_ci VkInstance instance, 37cb93a386Sopenharmony_ci VkPhysicalDevice physDev, 38cb93a386Sopenharmony_ci uint32_t instanceExtensionCount, 39cb93a386Sopenharmony_ci const char* const* instanceExtensions, 40cb93a386Sopenharmony_ci uint32_t deviceExtensionCount, 41cb93a386Sopenharmony_ci const char* const* deviceExtensions) { 42cb93a386Sopenharmony_ci for (uint32_t i = 0; i < instanceExtensionCount; ++i) { 43cb93a386Sopenharmony_ci const char* extension = instanceExtensions[i]; 44cb93a386Sopenharmony_ci // if not already in the list, add it 45cb93a386Sopenharmony_ci if (find_info(fExtensions, extension) < 0) { 46cb93a386Sopenharmony_ci fExtensions.push_back() = Info(extension); 47cb93a386Sopenharmony_ci SkTQSort(fExtensions.begin(), fExtensions.end(), extension_compare); 48cb93a386Sopenharmony_ci } 49cb93a386Sopenharmony_ci } 50cb93a386Sopenharmony_ci for (uint32_t i = 0; i < deviceExtensionCount; ++i) { 51cb93a386Sopenharmony_ci const char* extension = deviceExtensions[i]; 52cb93a386Sopenharmony_ci // if not already in the list, add it 53cb93a386Sopenharmony_ci if (find_info(fExtensions, extension) < 0) { 54cb93a386Sopenharmony_ci fExtensions.push_back() = Info(extension); 55cb93a386Sopenharmony_ci SkTQSort(fExtensions.begin(), fExtensions.end(), extension_compare); 56cb93a386Sopenharmony_ci } 57cb93a386Sopenharmony_ci } 58cb93a386Sopenharmony_ci this->getSpecVersions(getProc, instance, physDev); 59cb93a386Sopenharmony_ci} 60cb93a386Sopenharmony_ci 61cb93a386Sopenharmony_ci#define GET_PROC(F, inst) \ 62cb93a386Sopenharmony_ci PFN_vk##F grVk##F = (PFN_vk ## F) getProc("vk" #F, inst, VK_NULL_HANDLE) 63cb93a386Sopenharmony_ci 64cb93a386Sopenharmony_civoid GrVkExtensions::getSpecVersions(GrVkGetProc getProc, VkInstance instance, 65cb93a386Sopenharmony_ci VkPhysicalDevice physDevice) { 66cb93a386Sopenharmony_ci // We grab all the extensions for the VkInstance and VkDevice so we can look up what spec 67cb93a386Sopenharmony_ci // version each of the supported extensions are. We do not grab the extensions for layers 68cb93a386Sopenharmony_ci // because we don't know what layers the client has enabled and in general we don't do anything 69cb93a386Sopenharmony_ci // special for those extensions. 70cb93a386Sopenharmony_ci 71cb93a386Sopenharmony_ci if (instance == VK_NULL_HANDLE) { 72cb93a386Sopenharmony_ci return; 73cb93a386Sopenharmony_ci } 74cb93a386Sopenharmony_ci GET_PROC(EnumerateInstanceExtensionProperties, VK_NULL_HANDLE); 75cb93a386Sopenharmony_ci SkASSERT(grVkEnumerateInstanceExtensionProperties); 76cb93a386Sopenharmony_ci 77cb93a386Sopenharmony_ci VkResult res; 78cb93a386Sopenharmony_ci // instance extensions 79cb93a386Sopenharmony_ci uint32_t extensionCount = 0; 80cb93a386Sopenharmony_ci res = grVkEnumerateInstanceExtensionProperties(nullptr, &extensionCount, nullptr); 81cb93a386Sopenharmony_ci if (VK_SUCCESS != res) { 82cb93a386Sopenharmony_ci return; 83cb93a386Sopenharmony_ci } 84cb93a386Sopenharmony_ci VkExtensionProperties* extensions = new VkExtensionProperties[extensionCount]; 85cb93a386Sopenharmony_ci res = grVkEnumerateInstanceExtensionProperties(nullptr, &extensionCount, extensions); 86cb93a386Sopenharmony_ci if (VK_SUCCESS != res) { 87cb93a386Sopenharmony_ci delete[] extensions; 88cb93a386Sopenharmony_ci return; 89cb93a386Sopenharmony_ci } 90cb93a386Sopenharmony_ci for (uint32_t i = 0; i < extensionCount; ++i) { 91cb93a386Sopenharmony_ci int idx = find_info(fExtensions, extensions[i].extensionName); 92cb93a386Sopenharmony_ci if (idx >= 0) { 93cb93a386Sopenharmony_ci fExtensions[idx].fSpecVersion = extensions[i].specVersion; 94cb93a386Sopenharmony_ci } 95cb93a386Sopenharmony_ci } 96cb93a386Sopenharmony_ci delete[] extensions; 97cb93a386Sopenharmony_ci 98cb93a386Sopenharmony_ci if (physDevice == VK_NULL_HANDLE) { 99cb93a386Sopenharmony_ci return; 100cb93a386Sopenharmony_ci } 101cb93a386Sopenharmony_ci GET_PROC(EnumerateDeviceExtensionProperties, instance); 102cb93a386Sopenharmony_ci SkASSERT(grVkEnumerateDeviceExtensionProperties); 103cb93a386Sopenharmony_ci 104cb93a386Sopenharmony_ci // device extensions 105cb93a386Sopenharmony_ci extensionCount = 0; 106cb93a386Sopenharmony_ci res = grVkEnumerateDeviceExtensionProperties(physDevice, nullptr, &extensionCount, nullptr); 107cb93a386Sopenharmony_ci if (VK_SUCCESS != res) { 108cb93a386Sopenharmony_ci return; 109cb93a386Sopenharmony_ci } 110cb93a386Sopenharmony_ci extensions = new VkExtensionProperties[extensionCount]; 111cb93a386Sopenharmony_ci res = grVkEnumerateDeviceExtensionProperties(physDevice, nullptr, &extensionCount, extensions); 112cb93a386Sopenharmony_ci if (VK_SUCCESS != res) { 113cb93a386Sopenharmony_ci delete[] extensions; 114cb93a386Sopenharmony_ci return; 115cb93a386Sopenharmony_ci } 116cb93a386Sopenharmony_ci for (uint32_t i = 0; i < extensionCount; ++i) { 117cb93a386Sopenharmony_ci int idx = find_info(fExtensions, extensions[i].extensionName); 118cb93a386Sopenharmony_ci if (idx >= 0) { 119cb93a386Sopenharmony_ci fExtensions[idx].fSpecVersion = extensions[i].specVersion; 120cb93a386Sopenharmony_ci } 121cb93a386Sopenharmony_ci } 122cb93a386Sopenharmony_ci delete[] extensions; 123cb93a386Sopenharmony_ci} 124cb93a386Sopenharmony_ci 125cb93a386Sopenharmony_cibool GrVkExtensions::hasExtension(const char ext[], uint32_t minVersion) const { 126cb93a386Sopenharmony_ci int idx = find_info(fExtensions, ext); 127cb93a386Sopenharmony_ci return idx >= 0 && fExtensions[idx].fSpecVersion >= minVersion; 128cb93a386Sopenharmony_ci} 129cb93a386Sopenharmony_ci 130