blob: 16ffd2fc87cf6b619ed794d6fa5b930ea17fa18f [file] [log] [blame]
jvanverthd2497f32016-03-18 12:39:05 -07001/*
2 * Copyright 2016 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
Mike Kleinc0bd9f92019-04-23 12:05:21 -05008#include "include/gpu/vk/GrVkExtensions.h"
Greg Daniel98bffae2018-08-01 13:25:41 -04009
10// Can remove this once we get rid of the extension flags.
Mike Kleinc0bd9f92019-04-23 12:05:21 -050011#include "include/gpu/vk/GrVkBackendContext.h"
jvanverthd2497f32016-03-18 12:39:05 -070012
Ben Wagner8bd6e8f2019-05-15 09:28:52 -040013#include "src/core/SkTSearch.h"
John Stiles6e9ead92020-07-14 00:13:51 +000014#include "src/core/SkTSort.h"
jvanverthd2497f32016-03-18 12:39:05 -070015
Greg Daniela31f4e52018-08-01 16:48:52 -040016// finds the index of ext in infos or a negative result if ext is not found.
17static int find_info(const SkTArray<GrVkExtensions::Info>& infos, const char ext[]) {
18 if (infos.empty()) {
jvanverthd2497f32016-03-18 12:39:05 -070019 return -1;
20 }
21 SkString extensionStr(ext);
Greg Daniela31f4e52018-08-01 16:48:52 -040022 GrVkExtensions::Info::Less less;
23 int idx = SkTSearch<GrVkExtensions::Info, SkString, GrVkExtensions::Info::Less>(
24 &infos.front(), infos.count(), extensionStr, sizeof(GrVkExtensions::Info),
25 less);
jvanverthd2497f32016-03-18 12:39:05 -070026 return idx;
27}
28
Greg Daniela31f4e52018-08-01 16:48:52 -040029namespace { // This cannot be static because it is used as a template parameter.
30inline bool extension_compare(const GrVkExtensions::Info& a, const GrVkExtensions::Info& b) {
31 return strcmp(a.fName.c_str(), b.fName.c_str()) < 0;
32}
John Stilesa6841be2020-08-06 14:11:56 -040033} // namespace
Greg Daniela31f4e52018-08-01 16:48:52 -040034
35void GrVkExtensions::init(GrVkGetProc getProc,
36 VkInstance instance,
37 VkPhysicalDevice physDev,
38 uint32_t instanceExtensionCount,
Greg Daniel98bffae2018-08-01 13:25:41 -040039 const char* const* instanceExtensions,
40 uint32_t deviceExtensionCount,
41 const char* const* deviceExtensions) {
Greg Daniel98bffae2018-08-01 13:25:41 -040042 for (uint32_t i = 0; i < instanceExtensionCount; ++i) {
43 const char* extension = instanceExtensions[i];
44 // if not already in the list, add it
Greg Daniela31f4e52018-08-01 16:48:52 -040045 if (find_info(fExtensions, extension) < 0) {
John Stiles6e9ead92020-07-14 00:13:51 +000046 fExtensions.push_back() = Info(extension);
John Stiles886a9042020-07-14 16:28:33 -040047 SkTQSort(fExtensions.begin(), fExtensions.end(), extension_compare);
jvanverth633b3562016-03-23 11:01:22 -070048 }
49 }
Greg Daniel98bffae2018-08-01 13:25:41 -040050 for (uint32_t i = 0; i < deviceExtensionCount; ++i) {
51 const char* extension = deviceExtensions[i];
52 // if not already in the list, add it
Greg Daniela31f4e52018-08-01 16:48:52 -040053 if (find_info(fExtensions, extension) < 0) {
John Stiles6e9ead92020-07-14 00:13:51 +000054 fExtensions.push_back() = Info(extension);
John Stiles886a9042020-07-14 16:28:33 -040055 SkTQSort(fExtensions.begin(), fExtensions.end(), extension_compare);
Greg Danieldc13c212018-06-28 23:29:35 +000056 }
Greg Danieldc13c212018-06-28 23:29:35 +000057 }
Greg Daniela31f4e52018-08-01 16:48:52 -040058 this->getSpecVersions(getProc, instance, physDev);
jvanverthfd7bd452016-03-25 06:29:52 -070059}
60
Greg Daniela31f4e52018-08-01 16:48:52 -040061#define GET_PROC(F, inst) \
62 PFN_vk##F grVk##F = (PFN_vk ## F) getProc("vk" #F, inst, VK_NULL_HANDLE)
63
64void GrVkExtensions::getSpecVersions(GrVkGetProc getProc, VkInstance instance,
65 VkPhysicalDevice physDevice) {
66 // We grab all the extensions for the VkInstance and VkDevice so we can look up what spec
67 // version each of the supported extensions are. We do not grab the extensions for layers
68 // because we don't know what layers the client has enabled and in general we don't do anything
69 // special for those extensions.
70
71 if (instance == VK_NULL_HANDLE) {
72 return;
73 }
74 GET_PROC(EnumerateInstanceExtensionProperties, VK_NULL_HANDLE);
75 SkASSERT(grVkEnumerateInstanceExtensionProperties);
76
77 VkResult res;
78 // instance extensions
79 uint32_t extensionCount = 0;
80 res = grVkEnumerateInstanceExtensionProperties(nullptr, &extensionCount, nullptr);
81 if (VK_SUCCESS != res) {
82 return;
83 }
84 VkExtensionProperties* extensions = new VkExtensionProperties[extensionCount];
85 res = grVkEnumerateInstanceExtensionProperties(nullptr, &extensionCount, extensions);
86 if (VK_SUCCESS != res) {
87 delete[] extensions;
88 return;
89 }
90 for (uint32_t i = 0; i < extensionCount; ++i) {
91 int idx = find_info(fExtensions, extensions[i].extensionName);
92 if (idx >= 0) {
93 fExtensions[idx].fSpecVersion = extensions[i].specVersion;
94 }
95 }
96 delete[] extensions;
97
98 if (physDevice == VK_NULL_HANDLE) {
99 return;
100 }
101 GET_PROC(EnumerateDeviceExtensionProperties, instance);
102 SkASSERT(grVkEnumerateDeviceExtensionProperties);
103
104 // device extensions
105 extensionCount = 0;
106 res = grVkEnumerateDeviceExtensionProperties(physDevice, nullptr, &extensionCount, nullptr);
107 if (VK_SUCCESS != res) {
108 return;
109 }
110 extensions = new VkExtensionProperties[extensionCount];
111 res = grVkEnumerateDeviceExtensionProperties(physDevice, nullptr, &extensionCount, extensions);
112 if (VK_SUCCESS != res) {
113 delete[] extensions;
114 return;
115 }
116 for (uint32_t i = 0; i < extensionCount; ++i) {
117 int idx = find_info(fExtensions, extensions[i].extensionName);
118 if (idx >= 0) {
119 fExtensions[idx].fSpecVersion = extensions[i].specVersion;
120 }
121 }
122 delete[] extensions;
123}
124
125bool GrVkExtensions::hasExtension(const char ext[], uint32_t minVersion) const {
126 int idx = find_info(fExtensions, ext);
127 return idx >= 0 && fExtensions[idx].fSpecVersion >= minVersion;
jvanverthd2497f32016-03-18 12:39:05 -0700128}
129