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