Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
VulkanExtensions.cpp
Go to the documentation of this file.
1/*
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
9
10#include "src/base/SkTSearch.h"
11#include "src/base/SkTSort.h"
12
13using namespace skia_private;
14
15namespace skgpu {
16
17// finds the index of ext in infos or a negative result if ext is not found.
18static int find_info(const TArray<VulkanExtensions::Info>& infos, const char ext[]) {
19 if (infos.empty()) {
20 return -1;
21 }
22 SkString extensionStr(ext);
24 int idx = SkTSearch<VulkanExtensions::Info, SkString, VulkanExtensions::Info::Less>(
25 &infos.front(), infos.size(), extensionStr, sizeof(VulkanExtensions::Info),
26 less);
27 return idx;
28}
29
30namespace { // This cannot be static because it is used as a template parameter.
31inline bool extension_compare(const VulkanExtensions::Info& a, const VulkanExtensions::Info& b) {
32 return strcmp(a.fName.c_str(), b.fName.c_str()) < 0;
33}
34} // namespace
35
37 VkInstance instance,
38 VkPhysicalDevice physDev,
39 uint32_t instanceExtensionCount,
40 const char* const* instanceExtensions,
41 uint32_t deviceExtensionCount,
42 const char* const* deviceExtensions) {
43 for (uint32_t i = 0; i < instanceExtensionCount; ++i) {
44 const char* extension = instanceExtensions[i];
45 // if not already in the list, add it
46 if (find_info(fExtensions, extension) < 0) {
47 fExtensions.push_back() = Info(extension);
48 SkTQSort(fExtensions.begin(), fExtensions.end(), extension_compare);
49 }
50 }
51 for (uint32_t i = 0; i < deviceExtensionCount; ++i) {
52 const char* extension = deviceExtensions[i];
53 // if not already in the list, add it
54 if (find_info(fExtensions, extension) < 0) {
55 fExtensions.push_back() = Info(extension);
56 SkTQSort(fExtensions.begin(), fExtensions.end(), extension_compare);
57 }
58 }
59 this->getSpecVersions(std::move(getProc), instance, physDev);
60}
61
62#define GET_PROC(F, inst) \
63 PFN_vk##F grVk##F = (PFN_vk ## F) getProc("vk" #F, inst, VK_NULL_HANDLE)
64
65void VulkanExtensions::getSpecVersions(const VulkanGetProc& getProc,
66 VkInstance instance,
67 VkPhysicalDevice physDevice) {
68 // We grab all the extensions for the VkInstance and VkDevice so we can look up what spec
69 // version each of the supported extensions are. We do not grab the extensions for layers
70 // because we don't know what layers the client has enabled and in general we don't do anything
71 // special for those extensions.
72
73 if (instance == VK_NULL_HANDLE) {
74 return;
75 }
76 GET_PROC(EnumerateInstanceExtensionProperties, VK_NULL_HANDLE);
77 SkASSERT(grVkEnumerateInstanceExtensionProperties);
78
79 VkResult res;
80 // instance extensions
81 uint32_t extensionCount = 0;
82 res = grVkEnumerateInstanceExtensionProperties(nullptr, &extensionCount, nullptr);
83 if (VK_SUCCESS != res) {
84 return;
85 }
86 VkExtensionProperties* extensions = new VkExtensionProperties[extensionCount];
87 res = grVkEnumerateInstanceExtensionProperties(nullptr, &extensionCount, extensions);
88 if (VK_SUCCESS != res) {
89 delete[] extensions;
90 return;
91 }
92 for (uint32_t i = 0; i < extensionCount; ++i) {
93 int idx = find_info(fExtensions, extensions[i].extensionName);
94 if (idx >= 0) {
95 fExtensions[idx].fSpecVersion = extensions[i].specVersion;
96 }
97 }
98 delete[] extensions;
99
100 if (physDevice == VK_NULL_HANDLE) {
101 return;
102 }
103 GET_PROC(EnumerateDeviceExtensionProperties, instance);
104 SkASSERT(grVkEnumerateDeviceExtensionProperties);
105
106 // device extensions
107 extensionCount = 0;
108 res = grVkEnumerateDeviceExtensionProperties(physDevice, nullptr, &extensionCount, nullptr);
109 if (VK_SUCCESS != res) {
110 return;
111 }
112 extensions = new VkExtensionProperties[extensionCount];
113 res = grVkEnumerateDeviceExtensionProperties(physDevice, nullptr, &extensionCount, extensions);
114 if (VK_SUCCESS != res) {
115 delete[] extensions;
116 return;
117 }
118 for (uint32_t i = 0; i < extensionCount; ++i) {
119 int idx = find_info(fExtensions, extensions[i].extensionName);
120 if (idx >= 0) {
121 fExtensions[idx].fSpecVersion = extensions[i].specVersion;
122 }
123 }
124 delete[] extensions;
125}
126
127bool VulkanExtensions::hasExtension(const char ext[], uint32_t minVersion) const {
128 int idx = find_info(fExtensions, ext);
129 return idx >= 0 && fExtensions[idx].fSpecVersion >= minVersion;
130}
131
132} // namespace skgpu
#define SkASSERT(cond)
Definition SkAssert.h:116
void SkTQSort(T *begin, T *end, const C &lessThan)
Definition SkTSort.h:194
void init(VulkanGetProc, VkInstance, VkPhysicalDevice, uint32_t instanceExtensionCount, const char *const *instanceExtensions, uint32_t deviceExtensionCount, const char *const *deviceExtensions)
bool hasExtension(const char[], uint32_t minVersion) const
bool empty() const
Definition SkTArray.h:194
int size() const
Definition SkTArray.h:416
VkInstance instance
Definition main.cc:48
static bool b
struct MyStruct a[10]
static int find_info(const TArray< VulkanExtensions::Info > &infos, const char ext[])
std::function< PFN_vkVoidFunction(const char *, VkInstance, VkDevice)> VulkanGetProc
Definition VulkanTypes.h:29
VkResult
@ VK_SUCCESS
#define VK_NULL_HANDLE
Definition vulkan_core.h:46