Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
VulkanSharedContext.cpp
Go to the documentation of this file.
1/*
2 * Copyright 2022 Google LLC
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
21
22namespace skgpu::graphite {
23
25 const ContextOptions& options) {
26 if (context.fInstance == VK_NULL_HANDLE ||
28 context.fDevice == VK_NULL_HANDLE ||
29 context.fQueue == VK_NULL_HANDLE) {
30 SKGPU_LOG_E("Failed to create VulkanSharedContext because either fInstance,"
31 "fPhysicalDevice, fDevice, or fQueue in the VulkanBackendContext is"
32 "VK_NULL_HANDLE.");
33 return nullptr;
34 }
35 if (!context.fGetProc) {
36 SKGPU_LOG_E("Failed to create VulkanSharedContext because there is no valid VulkanGetProc"
37 "on the VulkanBackendContext");
38 return nullptr;
39 }
40
41 PFN_vkEnumerateInstanceVersion localEnumerateInstanceVersion =
42 reinterpret_cast<PFN_vkEnumerateInstanceVersion>(
43 context.fGetProc("vkEnumerateInstanceVersion", VK_NULL_HANDLE, VK_NULL_HANDLE));
44 uint32_t instanceVersion = 0;
45 if (!localEnumerateInstanceVersion) {
46 instanceVersion = VK_MAKE_VERSION(1, 0, 0);
47 } else {
48 VkResult err = localEnumerateInstanceVersion(&instanceVersion);
49 if (err) {
50 SKGPU_LOG_E("Failed to enumerate instance version. Err: %d\n", err);
51 return nullptr;
52 }
53 }
54
55 PFN_vkGetPhysicalDeviceProperties localGetPhysicalDeviceProperties =
56 reinterpret_cast<PFN_vkGetPhysicalDeviceProperties>(
57 context.fGetProc("vkGetPhysicalDeviceProperties",
58 context.fInstance,
60
61 if (!localGetPhysicalDeviceProperties) {
62 SKGPU_LOG_E("Failed to get function pointer to vkGetPhysicalDeviceProperties.");
63 return nullptr;
64 }
65 VkPhysicalDeviceProperties physDeviceProperties;
66 localGetPhysicalDeviceProperties(context.fPhysicalDevice, &physDeviceProperties);
67 uint32_t physDevVersion = physDeviceProperties.apiVersion;
68
69 uint32_t apiVersion = context.fMaxAPIVersion ? context.fMaxAPIVersion : instanceVersion;
70
71 instanceVersion = std::min(instanceVersion, apiVersion);
72 physDevVersion = std::min(physDevVersion, apiVersion);
73
76 context.fInstance,
77 context.fDevice,
78 instanceVersion,
79 physDevVersion,
80 context.fVkExtensions));
81 if (!interface->validate(instanceVersion, physDevVersion, context.fVkExtensions)) {
82 SKGPU_LOG_E("Failed to validate VulkanInterface.");
83 return nullptr;
84 }
85
87 const VkPhysicalDeviceFeatures2* featuresPtr;
88 // If fDeviceFeatures2 is not null, then we ignore fDeviceFeatures. If both are null, we assume
89 // no features are enabled.
90 if (!context.fDeviceFeatures2 && context.fDeviceFeatures) {
91 features.pNext = nullptr;
92 features.features = *context.fDeviceFeatures;
93 featuresPtr = &features;
94 } else {
95 featuresPtr = context.fDeviceFeatures2;
96 }
97
98 std::unique_ptr<const VulkanCaps> caps(new VulkanCaps(options,
99 interface.get(),
100 context.fPhysicalDevice,
101 physDevVersion,
102 featuresPtr,
103 context.fVkExtensions,
104 context.fProtectedContext));
105
107 if (!memoryAllocator) {
108 // We were not given a memory allocator at creation
109 bool threadSafe = !options.fClientWillExternallySynchronizeAllThreads;
111 context.fPhysicalDevice,
112 context.fDevice,
113 physDevVersion,
114 context.fVkExtensions,
115 interface.get(),
116 threadSafe);
117 }
118 if (!memoryAllocator) {
119 SKGPU_LOG_E("No supplied vulkan memory allocator and unable to create one internally.");
120 return nullptr;
121 }
122
123 return sk_sp<SharedContext>(new VulkanSharedContext(context,
124 std::move(interface),
125 std::move(memoryAllocator),
126 std::move(caps)));
127}
128
129VulkanSharedContext::VulkanSharedContext(const VulkanBackendContext& backendContext,
132 std::unique_ptr<const VulkanCaps> caps)
133 : skgpu::graphite::SharedContext(std::move(caps), BackendApi::kVulkan)
134 , fInterface(std::move(interface))
135 , fMemoryAllocator(std::move(memoryAllocator))
136 , fDevice(std::move(backendContext.fDevice))
137 , fQueueIndex(backendContext.fGraphicsQueueIndex)
138 , fDeviceLostContext(backendContext.fDeviceLostContext)
139 , fDeviceLostProc(backendContext.fDeviceLostProc) {}
140
142 // need to clear out resources before the allocator is removed
143 this->globalCache()->deleteResources();
144}
145
146std::unique_ptr<ResourceProvider> VulkanSharedContext::makeResourceProvider(
147 SingleOwner* singleOwner,
148 uint32_t recorderID,
149 size_t resourceBudget) {
150 // Establish a uniform buffer that can be updated across multiple render passes and cmd buffers
151 size_t alignedIntrinsicConstantSize =
153 this->vulkanCaps().requiredUniformBufferAlignment());
154 sk_sp<Buffer> intrinsicConstantBuffer = VulkanBuffer::Make(this,
155 alignedIntrinsicConstantSize,
158 "IntrinsicConstantBuffer");
159 if (!intrinsicConstantBuffer) {
160 SKGPU_LOG_E("Failed to create intrinsic constant uniform buffer");
161 return nullptr;
162 }
163 SkASSERT(static_cast<VulkanBuffer*>(intrinsicConstantBuffer.get())->bufferUsageFlags()
165
166 // Establish a vertex buffer that can be updated across multiple render passes and cmd buffers
167 // for loading MSAA from resolve
168 sk_sp<Buffer> loadMSAAVertexBuffer =
173 "LoadMSAAVertexBuffer");
174 if (!loadMSAAVertexBuffer) {
175 SKGPU_LOG_E("Failed to create vertex buffer for loading MSAA from resolve");
176 return nullptr;
177 }
178 SkASSERT(static_cast<VulkanBuffer*>(loadMSAAVertexBuffer.get())->bufferUsageFlags()
180
181 return std::unique_ptr<ResourceProvider>(
182 new VulkanResourceProvider(this,
183 singleOwner,
184 recorderID,
185 resourceBudget,
186 std::move(intrinsicConstantBuffer),
187 std::move(loadMSAAVertexBuffer)));
188}
189
191 switch (result) {
192 case VK_SUCCESS:
193 return true;
195 {
196 SkAutoMutexExclusive lock(fDeviceIsLostMutex);
197 if (fDeviceIsLost) {
198 return false;
199 }
200 fDeviceIsLost = true;
201 // Fall through to InvokeDeviceLostCallback (on first VK_ERROR_DEVICE_LOST) only afer
202 // releasing fDeviceIsLostMutex, otherwise clients might cause deadlock by checking
203 // isDeviceLost() from the callback.
204 }
206 device(),
207 fDeviceLostContext,
208 fDeviceLostProc,
209 vulkanCaps().supportsDeviceFaultInfo());
210 return false;
213 // TODO: determine how we'll track this in a thread-safe manner
214 //this->setOOMed();
215 return false;
216 default:
217 return false;
218 }
219}
220} // namespace skgpu::graphite
const char * options
#define SKGPU_LOG_E(fmt,...)
Definition Log.h:38
#define SkASSERT(cond)
Definition SkAssert.h:116
T * get() const
Definition SkRefCnt.h:303
static sk_sp< VulkanMemoryAllocator > Make(VkInstance instance, VkPhysicalDevice physicalDevice, VkDevice device, uint32_t physicalDeviceVersion, const VulkanExtensions *extensions, const VulkanInterface *interface, bool threadSafe)
const Caps * caps() const
VkBufferUsageFlags bufferUsageFlags() const
static sk_sp< Buffer > Make(const VulkanSharedContext *, size_t, BufferType, AccessPattern, std::string_view label)
skgpu::VulkanMemoryAllocator * memoryAllocator() const
bool checkVkResult(VkResult result) const
const skgpu::VulkanInterface * interface() const
const VulkanCaps & vulkanCaps() const
std::unique_ptr< ResourceProvider > makeResourceProvider(SingleOwner *, uint32_t recorderID, size_t resourceBudget) override
static sk_sp< SharedContext > Make(const VulkanBackendContext &, const ContextOptions &)
GAsyncResult * result
BackendApi
Definition GpuTypes.h:22
void InvokeDeviceLostCallback(const skgpu::VulkanInterface *vulkanInterface, VkDevice vkDevice, skgpu::VulkanDeviceLostContext deviceLostContext, skgpu::VulkanDeviceLostProc deviceLostProc, bool supportsDeviceFaultInfoExtension)
Definition ref_ptr.h:256
VkPhysicalDeviceFeatures features
const VkPhysicalDeviceFeatures2 * fDeviceFeatures2
sk_sp< VulkanMemoryAllocator > fMemoryAllocator
const VkPhysicalDeviceFeatures * fDeviceFeatures
const skgpu::VulkanExtensions * fVkExtensions
bool validate(uint32_t instanceVersion, uint32_t physicalDeviceVersion, const VulkanExtensions *) const
void(VKAPI_PTR * PFN_vkGetPhysicalDeviceProperties)(VkPhysicalDevice physicalDevice, VkPhysicalDeviceProperties *pProperties)
#define VK_MAKE_VERSION(major, minor, patch)
Definition vulkan_core.h:78
@ VK_BUFFER_USAGE_TRANSFER_DST_BIT
@ VK_BUFFER_USAGE_VERTEX_BUFFER_BIT
VkResult
@ VK_ERROR_DEVICE_LOST
@ VK_SUCCESS
@ VK_ERROR_OUT_OF_HOST_MEMORY
@ VK_ERROR_OUT_OF_DEVICE_MEMORY
#define VK_NULL_HANDLE
Definition vulkan_core.h:46
VkResult(VKAPI_PTR * PFN_vkEnumerateInstanceVersion)(uint32_t *pApiVersion)