1 //
2 // Copyright 2016 The ANGLE Project Authors. All rights reserved.
3 // Use of this source code is governed by a BSD-style license that can be
4 // found in the LICENSE file.
5 //
6 // vk_renderer.h:
7 // Defines the class interface for Renderer.
8 //
9
10 #ifndef LIBANGLE_RENDERER_VULKAN_RENDERERVK_H_
11 #define LIBANGLE_RENDERER_VULKAN_RENDERERVK_H_
12
13 #include <condition_variable>
14 #include <deque>
15 #include <memory>
16 #include <mutex>
17 #include <queue>
18 #include <thread>
19
20 #include "common/PackedEnums.h"
21 #include "common/SimpleMutex.h"
22 #include "common/WorkerThread.h"
23 #include "common/angleutils.h"
24 #include "common/vulkan/vk_headers.h"
25 #include "common/vulkan/vulkan_icd.h"
26 #include "libANGLE/Caps.h"
27 #include "libANGLE/renderer/vulkan/CommandQueue.h"
28 #include "libANGLE/renderer/vulkan/DebugAnnotatorVk.h"
29 #include "libANGLE/renderer/vulkan/MemoryTracking.h"
30 #include "libANGLE/renderer/vulkan/QueryVk.h"
31 #include "libANGLE/renderer/vulkan/UtilsVk.h"
32 #include "libANGLE/renderer/vulkan/vk_format_utils.h"
33 #include "libANGLE/renderer/vulkan/vk_helpers.h"
34 #include "libANGLE/renderer/vulkan/vk_internal_shaders_autogen.h"
35 #include "libANGLE/renderer/vulkan/vk_mem_alloc_wrapper.h"
36 #include "libANGLE/renderer/vulkan/vk_resource.h"
37
38 namespace angle
39 {
40 class Library;
41 struct FrontendFeatures;
42 } // namespace angle
43
44 namespace rx
45 {
46 class FramebufferVk;
47
48 namespace vk
49 {
50 class Format;
51
52 static constexpr size_t kMaxExtensionNames = 400;
53 using ExtensionNameList = angle::FixedVector<const char *, kMaxExtensionNames>;
54
55 static constexpr size_t kMaxSyncValExtraProperties = 9;
56 // Information used to accurately skip known synchronization issues in ANGLE.
57 // TODO: remove messageContents1 and messageContents2 fields after all
58 // supressions have transitioned to using extraProperties.
59 struct SkippedSyncvalMessage
60 {
61 const char *messageId;
62 const char *messageContents1;
63 const char *messageContents2 = "";
64 bool isDueToNonConformantCoherentColorFramebufferFetch = false;
65 const char *extraProperties[kMaxSyncValExtraProperties] = {};
66 };
67
68 class ImageMemorySuballocator : angle::NonCopyable
69 {
70 public:
71 ImageMemorySuballocator();
72 ~ImageMemorySuballocator();
73
74 void destroy(vk::Renderer *renderer);
75
76 // Allocates memory for the image and binds it.
77 VkResult allocateAndBindMemory(ErrorContext *context,
78 Image *image,
79 const VkImageCreateInfo *imageCreateInfo,
80 VkMemoryPropertyFlags requiredFlags,
81 VkMemoryPropertyFlags preferredFlags,
82 const VkMemoryRequirements *memoryRequirements,
83 const bool allocateDedicatedMemory,
84 MemoryAllocationType memoryAllocationType,
85 Allocation *allocationOut,
86 VkMemoryPropertyFlags *memoryFlagsOut,
87 uint32_t *memoryTypeIndexOut,
88 VkDeviceSize *sizeOut);
89
90 // Maps the memory to initialize with non-zero value.
91 VkResult mapMemoryAndInitWithNonZeroValue(vk::Renderer *renderer,
92 Allocation *allocation,
93 VkDeviceSize size,
94 int value,
95 VkMemoryPropertyFlags flags);
96
97 // Determines if dedicated memory is required for the allocation.
98 bool needsDedicatedMemory(VkDeviceSize size) const;
99 };
100
101 // Supports one semaphore from current surface, and one semaphore passed to
102 // glSignalSemaphoreEXT.
103 using SignalSemaphoreVector = angle::FixedVector<VkSemaphore, 2>;
104
105 class OneOffCommandPool : angle::NonCopyable
106 {
107 public:
108 OneOffCommandPool();
109 void init(vk::ProtectionType protectionType);
110 angle::Result getCommandBuffer(vk::ErrorContext *context,
111 vk::ScopedPrimaryCommandBuffer *commandBufferOut);
112 void releaseCommandBuffer(const QueueSerial &submitQueueSerial,
113 vk::PrimaryCommandBuffer &&primary);
114 void destroy(VkDevice device);
115
116 private:
117 vk::ProtectionType mProtectionType;
118 angle::SimpleMutex mMutex;
119 vk::CommandPool mCommandPool;
120 struct PendingOneOffCommands
121 {
122 vk::ResourceUse use;
123 vk::PrimaryCommandBuffer commandBuffer;
124 };
125 std::deque<PendingOneOffCommands> mPendingCommands;
126 };
127
128 enum class UseDebugLayers
129 {
130 Yes,
131 YesIfAvailable,
132 No,
133 };
134
135 enum class UseVulkanSwapchain
136 {
137 Yes,
138 No,
139 };
140
141 class Renderer : angle::NonCopyable
142 {
143 public:
144 Renderer();
145 ~Renderer();
146
147 angle::Result initialize(vk::ErrorContext *context,
148 vk::GlobalOps *globalOps,
149 angle::vk::ICD desiredICD,
150 uint32_t preferredVendorId,
151 uint32_t preferredDeviceId,
152 const uint8_t *preferredDeviceUuid,
153 const uint8_t *preferredDriverUuid,
154 VkDriverId preferredDriverId,
155 UseDebugLayers useDebugLayers,
156 const char *wsiExtension,
157 const char *wsiLayer,
158 angle::NativeWindowSystem nativeWindowSystem,
159 const angle::FeatureOverrides &featureOverrides);
160
161 // Reload volk vk* function ptrs if needed for an already initialized Renderer
162 void reloadVolkIfNeeded() const;
163 void onDestroy(vk::ErrorContext *context);
164
165 void notifyDeviceLost();
166 bool isDeviceLost() const;
167 bool hasSharedGarbage();
168
169 std::string getVendorString() const;
170 std::string getRendererDescription() const;
171 std::string getVersionString(bool includeFullVersion) const;
172
173 gl::Version getMaxSupportedESVersion() const;
174 gl::Version getMaxConformantESVersion() const;
175
176 uint32_t getDeviceVersion() const;
getInstance()177 VkInstance getInstance() const { return mInstance; }
getPhysicalDevice()178 VkPhysicalDevice getPhysicalDevice() const { return mPhysicalDevice; }
getPhysicalDeviceProperties()179 const VkPhysicalDeviceProperties &getPhysicalDeviceProperties() const
180 {
181 return mPhysicalDeviceProperties;
182 }
getPhysicalDeviceDrmProperties()183 const VkPhysicalDeviceDrmPropertiesEXT &getPhysicalDeviceDrmProperties() const
184 {
185 return mDrmProperties;
186 }
187 const VkPhysicalDevicePrimitivesGeneratedQueryFeaturesEXT &
getPhysicalDevicePrimitivesGeneratedQueryFeatures()188 getPhysicalDevicePrimitivesGeneratedQueryFeatures() const
189 {
190 return mPrimitivesGeneratedQueryFeatures;
191 }
getPhysicalDeviceHostImageCopyProperties()192 const VkPhysicalDeviceHostImageCopyPropertiesEXT &getPhysicalDeviceHostImageCopyProperties()
193 const
194 {
195 return mHostImageCopyProperties;
196 }
getPhysicalDeviceFeatures()197 const VkPhysicalDeviceFeatures &getPhysicalDeviceFeatures() const
198 {
199 return mPhysicalDeviceFeatures;
200 }
getEnabledFeatures()201 const VkPhysicalDeviceFeatures2KHR &getEnabledFeatures() const { return mEnabledFeatures; }
getDevice()202 VkDevice getDevice() const { return mDevice; }
203
getAllocator()204 const vk::Allocator &getAllocator() const { return mAllocator; }
getImageMemorySuballocator()205 vk::ImageMemorySuballocator &getImageMemorySuballocator() { return mImageMemorySuballocator; }
206
207 angle::Result checkQueueForSurfacePresent(vk::ErrorContext *context,
208 VkSurfaceKHR surface,
209 bool *supportedOut);
210
211 const gl::Caps &getNativeCaps() const;
212 const gl::TextureCapsMap &getNativeTextureCaps() const;
213 const gl::Extensions &getNativeExtensions() const;
214 const gl::Limitations &getNativeLimitations() const;
215 const ShPixelLocalStorageOptions &getNativePixelLocalStorageOptions() const;
216 void initializeFrontendFeatures(angle::FrontendFeatures *features) const;
217
getQueueFamilyIndex()218 uint32_t getQueueFamilyIndex() const { return mCurrentQueueFamilyIndex; }
getQueueFamilyProperties()219 const VkQueueFamilyProperties &getQueueFamilyProperties() const
220 {
221 return mQueueFamilyProperties[mCurrentQueueFamilyIndex];
222 }
getDeviceQueueIndex(egl::ContextPriority priority)223 const DeviceQueueIndex getDeviceQueueIndex(egl::ContextPriority priority) const
224 {
225 return mCommandQueue.getDeviceQueueIndex(priority);
226 }
getDefaultDeviceQueueIndex()227 const DeviceQueueIndex getDefaultDeviceQueueIndex() const
228 {
229 // By default it will always use medium priority
230 return mCommandQueue.getDeviceQueueIndex(egl::ContextPriority::Medium);
231 }
232
getMemoryProperties()233 const vk::MemoryProperties &getMemoryProperties() const { return mMemoryProperties; }
234
getFormat(GLenum internalFormat)235 const vk::Format &getFormat(GLenum internalFormat) const
236 {
237 return mFormatTable[internalFormat];
238 }
239
getFormat(angle::FormatID formatID)240 const vk::Format &getFormat(angle::FormatID formatID) const { return mFormatTable[formatID]; }
241
242 // Get the pipeline cache data after retrieving the size, but only if the size is increased
243 // since last query. This function should be called with the |mPipelineCacheMutex| lock already
244 // held.
245 angle::Result getLockedPipelineCacheDataIfNew(vk::ErrorContext *context,
246 size_t *pipelineCacheSizeOut,
247 size_t lastSyncSize,
248 std::vector<uint8_t> *pipelineCacheDataOut);
249 angle::Result syncPipelineCacheVk(vk::ErrorContext *context,
250 vk::GlobalOps *globalOps,
251 const gl::Context *contextGL);
252
getFeatures()253 const angle::FeaturesVk &getFeatures() const { return mFeatures; }
getMaxVertexAttribDivisor()254 uint32_t getMaxVertexAttribDivisor() const { return mMaxVertexAttribDivisor; }
getMaxVertexAttribStride()255 VkDeviceSize getMaxVertexAttribStride() const { return mMaxVertexAttribStride; }
getMaxColorInputAttachmentCount()256 uint32_t getMaxColorInputAttachmentCount() const { return mMaxColorInputAttachmentCount; }
isInFlightCommandsEmpty()257 ANGLE_INLINE bool isInFlightCommandsEmpty() const
258 {
259 return mCommandQueue.isInFlightCommandsEmpty();
260 }
261
getDefaultUniformBufferSize()262 uint32_t getDefaultUniformBufferSize() const { return mDefaultUniformBufferSize; }
263
getEnabledICD()264 angle::vk::ICD getEnabledICD() const { return mEnabledICD; }
isMockICDEnabled()265 bool isMockICDEnabled() const { return mEnabledICD == angle::vk::ICD::Mock; }
266
267 // Query the format properties for select bits (linearTilingFeatures, optimalTilingFeatures
268 // and bufferFeatures). Looks through mandatory features first, and falls back to querying
269 // the device (first time only).
270 bool hasLinearImageFormatFeatureBits(angle::FormatID format,
271 const VkFormatFeatureFlags featureBits) const;
272 VkFormatFeatureFlags getLinearImageFormatFeatureBits(
273 angle::FormatID format,
274 const VkFormatFeatureFlags featureBits) const;
275 VkFormatFeatureFlags getImageFormatFeatureBits(angle::FormatID format,
276 const VkFormatFeatureFlags featureBits) const;
277 bool hasImageFormatFeatureBits(angle::FormatID format,
278 const VkFormatFeatureFlags featureBits) const;
279 bool hasBufferFormatFeatureBits(angle::FormatID format,
280 const VkFormatFeatureFlags featureBits) const;
281
isAsyncCommandBufferResetAndGarbageCleanupEnabled()282 bool isAsyncCommandBufferResetAndGarbageCleanupEnabled() const
283 {
284 return mFeatures.asyncCommandBufferResetAndGarbageCleanup.enabled;
285 }
286
getDriverPriority(egl::ContextPriority priority)287 ANGLE_INLINE egl::ContextPriority getDriverPriority(egl::ContextPriority priority)
288 {
289 return mCommandQueue.getDriverPriority(priority);
290 }
291
getQueue(egl::ContextPriority priority)292 VkQueue getQueue(egl::ContextPriority priority) { return mCommandQueue.getQueue(priority); }
293 // Helpers to implement the functionality of EGL_ANGLE_device_vulkan
lockVulkanQueueForExternalAccess()294 void lockVulkanQueueForExternalAccess() { mCommandQueue.lockVulkanQueueForExternalAccess(); }
unlockVulkanQueueForExternalAccess()295 void unlockVulkanQueueForExternalAccess()
296 {
297 mCommandQueue.unlockVulkanQueueForExternalAccess();
298 }
299
300 // This command buffer should be submitted immediately via queueSubmitOneOff.
getCommandBufferOneOff(vk::ErrorContext * context,vk::ProtectionType protectionType,vk::ScopedPrimaryCommandBuffer * commandBufferOut)301 angle::Result getCommandBufferOneOff(vk::ErrorContext *context,
302 vk::ProtectionType protectionType,
303 vk::ScopedPrimaryCommandBuffer *commandBufferOut)
304 {
305 return mOneOffCommandPoolMap[protectionType].getCommandBuffer(context, commandBufferOut);
306 }
307
308 // Fire off a single command buffer immediately with default priority.
309 // Command buffer must be allocated with getCommandBufferOneOff and is reclaimed.
310 angle::Result queueSubmitOneOff(vk::ErrorContext *context,
311 vk::ScopedPrimaryCommandBuffer &&scopedCommandBuffer,
312 vk::ProtectionType protectionType,
313 egl::ContextPriority priority,
314 VkSemaphore waitSemaphore,
315 VkPipelineStageFlags waitSemaphoreStageMasks,
316 QueueSerial *queueSerialOut);
317
318 angle::Result queueSubmitWaitSemaphore(vk::ErrorContext *context,
319 egl::ContextPriority priority,
320 const vk::Semaphore &waitSemaphore,
321 VkPipelineStageFlags waitSemaphoreStageMasks,
322 QueueSerial submitQueueSerial);
323
324 template <typename ArgT>
collectGarbage(const vk::ResourceUse & use,ArgT garbageIn)325 void collectGarbage(const vk::ResourceUse &use, ArgT garbageIn)
326 {
327 if (!garbageIn->valid())
328 {
329 return;
330 }
331
332 if (hasResourceUseFinished(use))
333 {
334 garbageIn->destroy(mDevice);
335 }
336 else
337 {
338 std::vector<vk::GarbageObject> sharedGarbage;
339 sharedGarbage.emplace_back(vk::GarbageObject::Get(garbageIn));
340 collectGarbage(use, std::move(sharedGarbage));
341 }
342 }
343
collectGarbage(const vk::ResourceUse & use,vk::GarbageObjects && sharedGarbage)344 void collectGarbage(const vk::ResourceUse &use, vk::GarbageObjects &&sharedGarbage)
345 {
346 ASSERT(!sharedGarbage.empty());
347 if (hasResourceUseFinished(use))
348 {
349 for (auto &garbage : sharedGarbage)
350 {
351 garbage.destroy(this);
352 }
353 sharedGarbage.clear();
354 }
355 else
356 {
357 vk::SharedGarbage garbage(use, std::move(sharedGarbage));
358 mSharedGarbageList.add(this, std::move(garbage));
359 }
360 }
361
collectSuballocationGarbage(const vk::ResourceUse & use,vk::BufferSuballocation && suballocation,vk::Buffer && buffer)362 void collectSuballocationGarbage(const vk::ResourceUse &use,
363 vk::BufferSuballocation &&suballocation,
364 vk::Buffer &&buffer)
365 {
366 vk::BufferSuballocationGarbage garbage(use, std::move(suballocation), std::move(buffer));
367 mSuballocationGarbageList.add(this, std::move(garbage));
368 }
369
370 size_t getNextPipelineCacheBlobCacheSlotIndex(size_t *previousSlotIndexOut);
371 size_t updatePipelineCacheChunkCount(size_t chunkCount);
372 angle::Result getPipelineCache(vk::ErrorContext *context,
373 vk::PipelineCacheAccess *pipelineCacheOut);
374 angle::Result mergeIntoPipelineCache(vk::ErrorContext *context,
375 const vk::PipelineCache &pipelineCache);
376
377 void onNewValidationMessage(const std::string &message);
378 std::string getAndClearLastValidationMessage(uint32_t *countSinceLastClear);
379
getSkippedValidationMessages()380 const std::vector<const char *> &getSkippedValidationMessages() const
381 {
382 return mSkippedValidationMessages;
383 }
getSkippedSyncvalMessages()384 const std::vector<vk::SkippedSyncvalMessage> &getSkippedSyncvalMessages() const
385 {
386 return mSkippedSyncvalMessages;
387 }
388
isCoherentColorFramebufferFetchEmulated()389 bool isCoherentColorFramebufferFetchEmulated() const
390 {
391 return mFeatures.supportsShaderFramebufferFetch.enabled &&
392 !mIsColorFramebufferFetchCoherent;
393 }
394
onColorFramebufferFetchUse()395 void onColorFramebufferFetchUse() { mIsColorFramebufferFetchUsed = true; }
isColorFramebufferFetchUsed()396 bool isColorFramebufferFetchUsed() const { return mIsColorFramebufferFetchUsed; }
397
398 uint64_t getMaxFenceWaitTimeNs() const;
399
isCommandQueueBusy()400 ANGLE_INLINE bool isCommandQueueBusy() { return mCommandQueue.isBusy(this); }
401
getCommandQueuePerfCounters()402 angle::VulkanPerfCounters getCommandQueuePerfCounters()
403 {
404 return mCommandQueue.getPerfCounters();
405 }
resetCommandQueuePerFrameCounters()406 void resetCommandQueuePerFrameCounters() { mCommandQueue.resetPerFramePerfCounters(); }
407
getGlobalOps()408 vk::GlobalOps *getGlobalOps() const { return mGlobalOps; }
409
enableDebugUtils()410 bool enableDebugUtils() const { return mEnableDebugUtils; }
angleDebuggerMode()411 bool angleDebuggerMode() const { return mAngleDebuggerMode; }
412
getSamplerCache()413 SamplerCache &getSamplerCache() { return mSamplerCache; }
getYuvConversionCache()414 SamplerYcbcrConversionCache &getYuvConversionCache() { return mYuvConversionCache; }
415
416 void onAllocateHandle(vk::HandleType handleType);
417 void onDeallocateHandle(vk::HandleType handleType, uint32_t count);
418
getEnableValidationLayers()419 bool getEnableValidationLayers() const { return mEnableValidationLayers; }
420
getResourceSerialFactory()421 vk::ResourceSerialFactory &getResourceSerialFactory() { return mResourceSerialFactory; }
422
423 void setGlobalDebugAnnotator(bool *installedAnnotatorOut);
424
425 void outputVmaStatString();
426
427 bool haveSameFormatFeatureBits(angle::FormatID formatID1, angle::FormatID formatID2) const;
428
429 void cleanupGarbage(bool *anyGarbageCleanedOut);
430 void cleanupPendingSubmissionGarbage();
431
432 angle::Result submitCommands(vk::ErrorContext *context,
433 vk::ProtectionType protectionType,
434 egl::ContextPriority contextPriority,
435 const vk::Semaphore *signalSemaphore,
436 const vk::SharedExternalFence *externalFence,
437 std::vector<VkImageMemoryBarrier> &&imagesToTransitionToForeign,
438 const QueueSerial &submitQueueSerial);
439
440 angle::Result submitPriorityDependency(vk::ErrorContext *context,
441 vk::ProtectionTypes protectionTypes,
442 egl::ContextPriority srcContextPriority,
443 egl::ContextPriority dstContextPriority,
444 SerialIndex index);
445
446 void handleDeviceLost();
447 angle::Result finishResourceUse(vk::ErrorContext *context, const vk::ResourceUse &use);
448 angle::Result finishQueueSerial(vk::ErrorContext *context, const QueueSerial &queueSerial);
449 angle::Result waitForResourceUseToFinishWithUserTimeout(vk::ErrorContext *context,
450 const vk::ResourceUse &use,
451 uint64_t timeout,
452 VkResult *result);
453 angle::Result checkCompletedCommands(vk::ErrorContext *context);
454
455 angle::Result checkCompletedCommandsAndCleanup(vk::ErrorContext *context);
456 angle::Result releaseFinishedCommands(vk::ErrorContext *context);
457
458 angle::Result flushWaitSemaphores(vk::ProtectionType protectionType,
459 egl::ContextPriority priority,
460 std::vector<VkSemaphore> &&waitSemaphores,
461 std::vector<VkPipelineStageFlags> &&waitSemaphoreStageMasks);
462 angle::Result flushRenderPassCommands(vk::Context *context,
463 vk::ProtectionType protectionType,
464 egl::ContextPriority priority,
465 const vk::RenderPass &renderPass,
466 VkFramebuffer framebufferOverride,
467 vk::RenderPassCommandBufferHelper **renderPassCommands);
468 angle::Result flushOutsideRPCommands(
469 vk::Context *context,
470 vk::ProtectionType protectionType,
471 egl::ContextPriority priority,
472 vk::OutsideRenderPassCommandBufferHelper **outsideRPCommands);
473
474 VkResult queuePresent(vk::ErrorContext *context,
475 egl::ContextPriority priority,
476 const VkPresentInfoKHR &presentInfo);
477
478 angle::Result getOutsideRenderPassCommandBufferHelper(
479 vk::ErrorContext *context,
480 vk::SecondaryCommandPool *commandPool,
481 vk::SecondaryCommandMemoryAllocator *commandsAllocator,
482 vk::OutsideRenderPassCommandBufferHelper **commandBufferHelperOut);
483 angle::Result getRenderPassCommandBufferHelper(
484 vk::ErrorContext *context,
485 vk::SecondaryCommandPool *commandPool,
486 vk::SecondaryCommandMemoryAllocator *commandsAllocator,
487 vk::RenderPassCommandBufferHelper **commandBufferHelperOut);
488
489 void recycleOutsideRenderPassCommandBufferHelper(
490 vk::OutsideRenderPassCommandBufferHelper **commandBuffer);
491 void recycleRenderPassCommandBufferHelper(vk::RenderPassCommandBufferHelper **commandBuffer);
492
493 // Process GPU memory reports
processMemoryReportCallback(const VkDeviceMemoryReportCallbackDataEXT & callbackData)494 void processMemoryReportCallback(const VkDeviceMemoryReportCallbackDataEXT &callbackData)
495 {
496 bool logCallback = getFeatures().logMemoryReportCallbacks.enabled;
497 mMemoryReport.processCallback(callbackData, logCallback);
498 }
499
500 // Accumulate cache stats for a specific cache
accumulateCacheStats(VulkanCacheType cache,const CacheStats & stats)501 void accumulateCacheStats(VulkanCacheType cache, const CacheStats &stats)
502 {
503 std::unique_lock<angle::SimpleMutex> localLock(mCacheStatsMutex);
504 mVulkanCacheStats[cache].accumulate(stats);
505 }
506 // Log cache stats for all caches
507 void logCacheStats() const;
508
getSupportedBufferWritePipelineStageMask()509 VkPipelineStageFlags getSupportedBufferWritePipelineStageMask() const
510 {
511 return mSupportedBufferWritePipelineStageMask;
512 }
513
getPipelineStageMask(EventStage eventStage)514 VkPipelineStageFlags getPipelineStageMask(EventStage eventStage) const
515 {
516 return mEventStageToPipelineStageFlagsMap[eventStage];
517 }
518
getImageMemoryBarrierData(ImageLayout layout)519 const ImageMemoryBarrierData &getImageMemoryBarrierData(ImageLayout layout) const
520 {
521 return mImageLayoutAndMemoryBarrierDataMap[layout];
522 }
523
getSupportedVulkanShaderStageMask()524 VkShaderStageFlags getSupportedVulkanShaderStageMask() const
525 {
526 return mSupportedVulkanShaderStageMask;
527 }
528
529 angle::Result getFormatDescriptorCountForVkFormat(vk::ErrorContext *context,
530 VkFormat format,
531 uint32_t *descriptorCountOut);
532
533 angle::Result getFormatDescriptorCountForExternalFormat(vk::ErrorContext *context,
534 uint64_t format,
535 uint32_t *descriptorCountOut);
536
getMaxCopyBytesUsingCPUWhenPreservingBufferData()537 VkDeviceSize getMaxCopyBytesUsingCPUWhenPreservingBufferData() const
538 {
539 return mMaxCopyBytesUsingCPUWhenPreservingBufferData;
540 }
541
getEnabledInstanceExtensions()542 const vk::ExtensionNameList &getEnabledInstanceExtensions() const
543 {
544 return mEnabledInstanceExtensions;
545 }
546
getEnabledDeviceExtensions()547 const vk::ExtensionNameList &getEnabledDeviceExtensions() const
548 {
549 return mEnabledDeviceExtensions;
550 }
551
552 VkDeviceSize getPreferedBufferBlockSize(uint32_t memoryTypeIndex) const;
553
getDefaultBufferAlignment()554 size_t getDefaultBufferAlignment() const { return mDefaultBufferAlignment; }
555
getStagingBufferMemoryTypeIndex(vk::MemoryCoherency coherency)556 uint32_t getStagingBufferMemoryTypeIndex(vk::MemoryCoherency coherency) const
557 {
558 return mStagingBufferMemoryTypeIndex[coherency];
559 }
getStagingBufferAlignment()560 size_t getStagingBufferAlignment() const { return mStagingBufferAlignment; }
561
getVertexConversionBufferMemoryTypeIndex(MemoryHostVisibility hostVisibility)562 uint32_t getVertexConversionBufferMemoryTypeIndex(MemoryHostVisibility hostVisibility) const
563 {
564 return hostVisibility == MemoryHostVisibility::Visible
565 ? mHostVisibleVertexConversionBufferMemoryTypeIndex
566 : mDeviceLocalVertexConversionBufferMemoryTypeIndex;
567 }
getVertexConversionBufferAlignment()568 size_t getVertexConversionBufferAlignment() const { return mVertexConversionBufferAlignment; }
569
getDeviceLocalMemoryTypeIndex()570 uint32_t getDeviceLocalMemoryTypeIndex() const
571 {
572 return mDeviceLocalVertexConversionBufferMemoryTypeIndex;
573 }
574
isShadingRateSupported(gl::ShadingRate shadingRate)575 bool isShadingRateSupported(gl::ShadingRate shadingRate) const
576 {
577 return mSupportedFragmentShadingRates.test(shadingRate);
578 }
579
getMaxFragmentShadingRateAttachmentTexelSize()580 VkExtent2D getMaxFragmentShadingRateAttachmentTexelSize() const
581 {
582 ASSERT(mFeatures.supportsFoveatedRendering.enabled);
583 return mFragmentShadingRateProperties.maxFragmentShadingRateAttachmentTexelSize;
584 }
585
addBufferBlockToOrphanList(vk::BufferBlock * block)586 void addBufferBlockToOrphanList(vk::BufferBlock *block) { mOrphanedBufferBlockList.add(block); }
587
getSuballocationDestroyedSize()588 VkDeviceSize getSuballocationDestroyedSize() const
589 {
590 return mSuballocationGarbageList.getDestroyedGarbageSize();
591 }
onBufferPoolPrune()592 void onBufferPoolPrune() { mSuballocationGarbageList.resetDestroyedGarbageSize(); }
getSuballocationGarbageSize()593 VkDeviceSize getSuballocationGarbageSize() const
594 {
595 return mSuballocationGarbageList.getSubmittedGarbageSize();
596 }
getPendingSuballocationGarbageSize()597 VkDeviceSize getPendingSuballocationGarbageSize()
598 {
599 return mSuballocationGarbageList.getUnsubmittedGarbageSize();
600 }
601
getPendingSubmissionGarbageSize()602 VkDeviceSize getPendingSubmissionGarbageSize() const
603 {
604 return mSharedGarbageList.getUnsubmittedGarbageSize();
605 }
606
getPreferredFilterForYUV(VkFilter defaultFilter)607 ANGLE_INLINE VkFilter getPreferredFilterForYUV(VkFilter defaultFilter)
608 {
609 return getFeatures().preferLinearFilterForYUV.enabled ? VK_FILTER_LINEAR : defaultFilter;
610 }
611
612 angle::Result allocateScopedQueueSerialIndex(vk::ScopedQueueSerialIndex *indexOut);
613 angle::Result allocateQueueSerialIndex(SerialIndex *serialIndexOut);
getLargestQueueSerialIndexEverAllocated()614 size_t getLargestQueueSerialIndexEverAllocated() const
615 {
616 return mQueueSerialIndexAllocator.getLargestIndexEverAllocated();
617 }
618 void releaseQueueSerialIndex(SerialIndex index);
619 Serial generateQueueSerial(SerialIndex index);
620 void reserveQueueSerials(SerialIndex index,
621 size_t count,
622 RangedSerialFactory *rangedSerialFactory);
623
624 // Return true if all serials in ResourceUse have been submitted.
625 bool hasResourceUseSubmitted(const vk::ResourceUse &use) const;
626 bool hasQueueSerialSubmitted(const QueueSerial &queueSerial) const;
627 Serial getLastSubmittedSerial(SerialIndex index) const;
628 // Return true if all serials in ResourceUse have been finished.
629 bool hasResourceUseFinished(const vk::ResourceUse &use) const;
630 bool hasQueueSerialFinished(const QueueSerial &queueSerial) const;
631
632 // Memory statistics can be updated on allocation and deallocation.
633 template <typename HandleT>
onMemoryAlloc(vk::MemoryAllocationType allocType,VkDeviceSize size,uint32_t memoryTypeIndex,HandleT handle)634 void onMemoryAlloc(vk::MemoryAllocationType allocType,
635 VkDeviceSize size,
636 uint32_t memoryTypeIndex,
637 HandleT handle)
638 {
639 mMemoryAllocationTracker.onMemoryAllocImpl(allocType, size, memoryTypeIndex,
640 reinterpret_cast<void *>(handle));
641 }
642
643 template <typename HandleT>
onMemoryDealloc(vk::MemoryAllocationType allocType,VkDeviceSize size,uint32_t memoryTypeIndex,HandleT handle)644 void onMemoryDealloc(vk::MemoryAllocationType allocType,
645 VkDeviceSize size,
646 uint32_t memoryTypeIndex,
647 HandleT handle)
648 {
649 mMemoryAllocationTracker.onMemoryDeallocImpl(allocType, size, memoryTypeIndex,
650 reinterpret_cast<void *>(handle));
651 }
652
getMemoryAllocationTracker()653 MemoryAllocationTracker *getMemoryAllocationTracker() { return &mMemoryAllocationTracker; }
654
getPendingGarbageSizeLimit()655 VkDeviceSize getPendingGarbageSizeLimit() const { return mPendingGarbageSizeLimit; }
656
657 void requestAsyncCommandsAndGarbageCleanup(vk::ErrorContext *context);
658
getMaxMemoryAllocationSize()659 VkDeviceSize getMaxMemoryAllocationSize() const
660 {
661 return mMaintenance3Properties.maxMemoryAllocationSize;
662 }
663
664 // Cleanup garbage and finish command batches from the queue if necessary in the event of an OOM
665 // error.
666 angle::Result cleanupSomeGarbage(ErrorContext *context, bool *anyGarbageCleanedOut);
667
668 // Static function to get Vulkan object type name.
669 static const char *GetVulkanObjectTypeName(VkObjectType type);
670
nullColorAttachmentWithExternalFormatResolve()671 bool nullColorAttachmentWithExternalFormatResolve() const
672 {
673 #if defined(ANGLE_PLATFORM_ANDROID)
674 ASSERT(mFeatures.supportsExternalFormatResolve.enabled);
675 return mExternalFormatResolveProperties.nullColorAttachmentWithExternalFormatResolve;
676 #else
677 return false;
678 #endif
679 }
680
getExternalFormatTable()681 vk::ExternalFormatTable *getExternalFormatTable() { return &mExternalFormatTable; }
682
getPipelineCacheGraphStream()683 std::ostringstream &getPipelineCacheGraphStream() { return mPipelineCacheGraph; }
isPipelineCacheGraphDumpEnabled()684 bool isPipelineCacheGraphDumpEnabled() const { return mDumpPipelineCacheGraph; }
getPipelineCacheGraphDumpPath()685 const char *getPipelineCacheGraphDumpPath() const
686 {
687 return mPipelineCacheGraphDumpPath.c_str();
688 }
689
getRefCountedEventRecycler()690 vk::RefCountedEventRecycler *getRefCountedEventRecycler() { return &mRefCountedEventRecycler; }
691
getCleanUpThreadId()692 std::thread::id getCleanUpThreadId() const { return mCleanUpThread.getThreadId(); }
693
getEmptyDescriptorLayout()694 const vk::DescriptorSetLayoutPtr &getEmptyDescriptorLayout() const
695 {
696 ASSERT(mPlaceHolderDescriptorSetLayout);
697 ASSERT(mPlaceHolderDescriptorSetLayout->valid());
698 return mPlaceHolderDescriptorSetLayout;
699 }
700
701 // VK_EXT_device_fault allows gathering more info if the device is lost.
702 VkResult retrieveDeviceLostDetails() const;
703
704 private:
705 angle::Result setupDevice(vk::ErrorContext *context,
706 const angle::FeatureOverrides &featureOverrides,
707 const char *wsiLayer,
708 UseVulkanSwapchain useVulkanSwapchain,
709 angle::NativeWindowSystem nativeWindowSystem);
710 angle::Result createDeviceAndQueue(vk::ErrorContext *context, uint32_t queueFamilyIndex);
711 void ensureCapsInitialized() const;
712 void initializeValidationMessageSuppressions();
713
714 void queryDeviceExtensionFeatures(const vk::ExtensionNameList &deviceExtensionNames);
715 void appendDeviceExtensionFeaturesNotPromoted(const vk::ExtensionNameList &deviceExtensionNames,
716 VkPhysicalDeviceFeatures2KHR *deviceFeatures,
717 VkPhysicalDeviceProperties2 *deviceProperties);
718 void appendDeviceExtensionFeaturesPromotedTo11(
719 const vk::ExtensionNameList &deviceExtensionNames,
720 VkPhysicalDeviceFeatures2KHR *deviceFeatures,
721 VkPhysicalDeviceProperties2 *deviceProperties);
722 void appendDeviceExtensionFeaturesPromotedTo12(
723 const vk::ExtensionNameList &deviceExtensionNames,
724 VkPhysicalDeviceFeatures2KHR *deviceFeatures,
725 VkPhysicalDeviceProperties2 *deviceProperties);
726 void appendDeviceExtensionFeaturesPromotedTo13(
727 const vk::ExtensionNameList &deviceExtensionNames,
728 VkPhysicalDeviceFeatures2KHR *deviceFeatures,
729 VkPhysicalDeviceProperties2 *deviceProperties);
730
731 angle::Result enableInstanceExtensions(vk::ErrorContext *context,
732 const VulkanLayerVector &enabledInstanceLayerNames,
733 const char *wsiExtension,
734 UseVulkanSwapchain useVulkanSwapchain,
735 bool canLoadDebugUtils);
736 angle::Result enableDeviceExtensions(vk::ErrorContext *context,
737 const angle::FeatureOverrides &featureOverrides,
738 UseVulkanSwapchain useVulkanSwapchain,
739 angle::NativeWindowSystem nativeWindowSystem);
740
741 void enableDeviceExtensionsNotPromoted(const vk::ExtensionNameList &deviceExtensionNames);
742 void enableDeviceExtensionsPromotedTo11(const vk::ExtensionNameList &deviceExtensionNames);
743 void enableDeviceExtensionsPromotedTo12(const vk::ExtensionNameList &deviceExtensionNames);
744 void enableDeviceExtensionsPromotedTo13(const vk::ExtensionNameList &deviceExtensionNames);
745
746 void initDeviceExtensionEntryPoints();
747 // Initialize extension entry points from core ones if needed
748 void initializeInstanceExtensionEntryPointsFromCore() const;
749 void initializeDeviceExtensionEntryPointsFromCore() const;
750
751 void initFeatures(const vk::ExtensionNameList &extensions,
752 const angle::FeatureOverrides &featureOverrides,
753 UseVulkanSwapchain useVulkanSwapchain,
754 angle::NativeWindowSystem nativeWindowSystem);
755 void appBasedFeatureOverrides(const vk::ExtensionNameList &extensions);
756 // TODO (b/372694741): Remove once run-time control is supported.
757 void appBasedFeatureOverridesAndroidDesktop(const vk::ExtensionNameList &extensions);
758 angle::Result initPipelineCache(vk::ErrorContext *context,
759 vk::PipelineCache *pipelineCache,
760 bool *success);
761 angle::Result ensurePipelineCacheInitialized(vk::ErrorContext *context);
762
763 template <VkFormatFeatureFlags VkFormatProperties::*features>
764 VkFormatFeatureFlags getFormatFeatureBits(angle::FormatID formatID,
765 const VkFormatFeatureFlags featureBits) const;
766
767 template <VkFormatFeatureFlags VkFormatProperties::*features>
768 bool hasFormatFeatureBits(angle::FormatID formatID,
769 const VkFormatFeatureFlags featureBits) const;
770
771 // Initialize VMA allocator and buffer suballocator related data.
772 angle::Result initializeMemoryAllocator(vk::ErrorContext *context);
773
774 // Query and cache supported fragment shading rates
775 void queryAndCacheFragmentShadingRates();
776 // Determine support for shading rate based rendering
777 bool canSupportFragmentShadingRate() const;
778 // Determine support for foveated rendering
779 bool canSupportFoveatedRendering() const;
780 // Prefer host visible device local via device local based on device type and heap size.
781 bool canPreferDeviceLocalMemoryHostVisible(VkPhysicalDeviceType deviceType);
782
783 // Find the threshold for pending suballocation and image garbage sizes before the context
784 // should be flushed.
785 void calculatePendingGarbageSizeLimit();
786
787 template <typename CommandBufferHelperT, typename RecyclerT>
788 angle::Result getCommandBufferImpl(vk::ErrorContext *context,
789 vk::SecondaryCommandPool *commandPool,
790 vk::SecondaryCommandMemoryAllocator *commandsAllocator,
791 RecyclerT *recycler,
792 CommandBufferHelperT **commandBufferHelperOut);
793
794 vk::GlobalOps *mGlobalOps;
795
796 void *mLibVulkanLibrary;
797
798 mutable bool mCapsInitialized;
799 mutable gl::Caps mNativeCaps;
800 mutable gl::TextureCapsMap mNativeTextureCaps;
801 mutable gl::Extensions mNativeExtensions;
802 mutable gl::Limitations mNativeLimitations;
803 mutable ShPixelLocalStorageOptions mNativePLSOptions;
804 mutable angle::FeaturesVk mFeatures;
805
806 // The instance and device versions. The instance version is the one from the Vulkan loader,
807 // while the device version comes from VkPhysicalDeviceProperties::apiVersion. With instance
808 // version 1.0, only device version 1.0 can be used. If instance version is at least 1.1, any
809 // device version (even higher than that) can be used. Some extensions have been promoted to
810 // Vulkan 1.1 or higher, but the version check must be done against the instance or device
811 // version, depending on whether it's an instance or device extension.
812 //
813 // Note that mDeviceVersion is technically redundant with mPhysicalDeviceProperties.apiVersion,
814 // but ANGLE may use a smaller version with problematic ICDs.
815 uint32_t mInstanceVersion;
816 uint32_t mDeviceVersion;
817
818 VkInstance mInstance;
819 bool mEnableValidationLayers;
820 // True if ANGLE is enabling the VK_EXT_debug_utils extension.
821 bool mEnableDebugUtils;
822 // True if ANGLE should call the vkCmd*DebugUtilsLabelEXT functions in order to communicate
823 // to debuggers (e.g. AGI) the OpenGL ES commands that the application uses. This is
824 // independent of mEnableDebugUtils, as an external graphics debugger can enable the
825 // VK_EXT_debug_utils extension and cause this to be set true.
826 bool mAngleDebuggerMode;
827 angle::vk::ICD mEnabledICD;
828 VkDebugUtilsMessengerEXT mDebugUtilsMessenger;
829 VkPhysicalDevice mPhysicalDevice;
830
831 VkPhysicalDeviceProperties2 mPhysicalDeviceProperties2;
832 VkPhysicalDeviceProperties &mPhysicalDeviceProperties;
833
834 VkPhysicalDeviceIDProperties mPhysicalDeviceIDProperties;
835 VkPhysicalDeviceFeatures mPhysicalDeviceFeatures;
836 VkPhysicalDeviceLineRasterizationFeaturesEXT mLineRasterizationFeatures;
837 VkPhysicalDeviceProvokingVertexFeaturesEXT mProvokingVertexFeatures;
838 VkPhysicalDeviceVertexAttributeDivisorFeaturesEXT mVertexAttributeDivisorFeatures;
839 VkPhysicalDeviceVertexAttributeDivisorPropertiesEXT mVertexAttributeDivisorProperties;
840 VkPhysicalDeviceTransformFeedbackFeaturesEXT mTransformFeedbackFeatures;
841 VkPhysicalDeviceIndexTypeUint8FeaturesEXT mIndexTypeUint8Features;
842 VkPhysicalDeviceSubgroupProperties mSubgroupProperties;
843 VkPhysicalDeviceShaderSubgroupExtendedTypesFeaturesKHR mSubgroupExtendedTypesFeatures;
844 VkPhysicalDeviceDeviceMemoryReportFeaturesEXT mMemoryReportFeatures;
845 VkDeviceDeviceMemoryReportCreateInfoEXT mMemoryReportCallback;
846 VkPhysicalDeviceShaderFloat16Int8FeaturesKHR mShaderFloat16Int8Features;
847 VkPhysicalDeviceDepthStencilResolvePropertiesKHR mDepthStencilResolveProperties;
848 VkPhysicalDeviceMultisampledRenderToSingleSampledFeaturesEXT
849 mMultisampledRenderToSingleSampledFeatures;
850 VkPhysicalDeviceImage2DViewOf3DFeaturesEXT mImage2dViewOf3dFeatures;
851 VkPhysicalDeviceMultiviewFeatures mMultiviewFeatures;
852 VkPhysicalDeviceFeatures2KHR mEnabledFeatures;
853 VkPhysicalDeviceMultiviewProperties mMultiviewProperties;
854 VkPhysicalDeviceDriverPropertiesKHR mDriverProperties;
855 VkPhysicalDeviceCustomBorderColorFeaturesEXT mCustomBorderColorFeatures;
856 VkPhysicalDeviceProtectedMemoryFeatures mProtectedMemoryFeatures;
857 VkPhysicalDeviceHostQueryResetFeaturesEXT mHostQueryResetFeatures;
858 VkPhysicalDeviceDepthClampZeroOneFeaturesEXT mDepthClampZeroOneFeatures;
859 VkPhysicalDeviceDepthClipControlFeaturesEXT mDepthClipControlFeatures;
860 VkPhysicalDeviceBlendOperationAdvancedFeaturesEXT mBlendOperationAdvancedFeatures;
861 VkPhysicalDevicePrimitivesGeneratedQueryFeaturesEXT mPrimitivesGeneratedQueryFeatures;
862 VkPhysicalDevicePrimitiveTopologyListRestartFeaturesEXT mPrimitiveTopologyListRestartFeatures;
863 VkPhysicalDeviceSamplerYcbcrConversionFeatures mSamplerYcbcrConversionFeatures;
864 VkPhysicalDeviceExtendedDynamicStateFeaturesEXT mExtendedDynamicStateFeatures;
865 VkPhysicalDeviceExtendedDynamicState2FeaturesEXT mExtendedDynamicState2Features;
866 VkPhysicalDeviceGraphicsPipelineLibraryFeaturesEXT mGraphicsPipelineLibraryFeatures;
867 VkPhysicalDeviceGraphicsPipelineLibraryPropertiesEXT mGraphicsPipelineLibraryProperties;
868 VkPhysicalDeviceVertexInputDynamicStateFeaturesEXT mVertexInputDynamicStateFeatures;
869 VkPhysicalDeviceDynamicRenderingFeaturesKHR mDynamicRenderingFeatures;
870 VkPhysicalDeviceDynamicRenderingLocalReadFeaturesKHR mDynamicRenderingLocalReadFeatures;
871 VkPhysicalDeviceFragmentShadingRateFeaturesKHR mFragmentShadingRateFeatures;
872 VkPhysicalDeviceFragmentShadingRatePropertiesKHR mFragmentShadingRateProperties;
873 VkPhysicalDeviceFragmentShaderInterlockFeaturesEXT mFragmentShaderInterlockFeatures;
874 VkPhysicalDeviceImagelessFramebufferFeaturesKHR mImagelessFramebufferFeatures;
875 VkPhysicalDevicePipelineRobustnessFeaturesEXT mPipelineRobustnessFeatures;
876 VkPhysicalDevicePipelineProtectedAccessFeaturesEXT mPipelineProtectedAccessFeatures;
877 VkPhysicalDeviceRasterizationOrderAttachmentAccessFeaturesEXT
878 mRasterizationOrderAttachmentAccessFeatures;
879 VkPhysicalDeviceShaderAtomicFloatFeaturesEXT mShaderAtomicFloatFeatures;
880 VkPhysicalDeviceMaintenance5FeaturesKHR mMaintenance5Features;
881 VkPhysicalDeviceSwapchainMaintenance1FeaturesEXT mSwapchainMaintenance1Features;
882 VkPhysicalDeviceLegacyDitheringFeaturesEXT mDitheringFeatures;
883 VkPhysicalDeviceDrmPropertiesEXT mDrmProperties;
884 VkPhysicalDeviceTimelineSemaphoreFeaturesKHR mTimelineSemaphoreFeatures;
885 VkPhysicalDeviceHostImageCopyFeaturesEXT mHostImageCopyFeatures;
886 VkPhysicalDeviceHostImageCopyPropertiesEXT mHostImageCopyProperties;
887 VkPhysicalDeviceTextureCompressionASTCHDRFeaturesEXT mTextureCompressionASTCHDRFeatures;
888 std::vector<VkImageLayout> mHostImageCopySrcLayoutsStorage;
889 std::vector<VkImageLayout> mHostImageCopyDstLayoutsStorage;
890 VkPhysicalDeviceImageCompressionControlFeaturesEXT mImageCompressionControlFeatures;
891 VkPhysicalDeviceImageCompressionControlSwapchainFeaturesEXT
892 mImageCompressionControlSwapchainFeatures;
893 #if defined(ANGLE_PLATFORM_ANDROID)
894 VkPhysicalDeviceExternalFormatResolveFeaturesANDROID mExternalFormatResolveFeatures;
895 VkPhysicalDeviceExternalFormatResolvePropertiesANDROID mExternalFormatResolveProperties;
896 #endif
897 VkPhysicalDevice8BitStorageFeatures m8BitStorageFeatures;
898 VkPhysicalDevice16BitStorageFeatures m16BitStorageFeatures;
899 VkPhysicalDeviceSynchronization2Features mSynchronization2Features;
900 VkPhysicalDeviceVariablePointersFeatures mVariablePointersFeatures;
901 VkPhysicalDeviceFloatControlsProperties mFloatControlProperties;
902 VkPhysicalDeviceUniformBufferStandardLayoutFeaturesKHR mUniformBufferStandardLayoutFeatures;
903 VkPhysicalDeviceMaintenance3Properties mMaintenance3Properties;
904 VkPhysicalDeviceFaultFeaturesEXT mFaultFeatures;
905
906 uint32_t mLegacyDitheringVersion = 0;
907
908 angle::PackedEnumBitSet<gl::ShadingRate, uint8_t> mSupportedFragmentShadingRates;
909 angle::PackedEnumMap<gl::ShadingRate, VkSampleCountFlags>
910 mSupportedFragmentShadingRateSampleCounts;
911 std::vector<VkQueueFamilyProperties> mQueueFamilyProperties;
912 uint32_t mCurrentQueueFamilyIndex;
913 uint32_t mMaxVertexAttribDivisor;
914 VkDeviceSize mMaxVertexAttribStride;
915 mutable uint32_t mMaxColorInputAttachmentCount;
916 uint32_t mDefaultUniformBufferSize;
917 VkDevice mDevice;
918 VkDeviceSize mMaxCopyBytesUsingCPUWhenPreservingBufferData;
919
920 bool mDeviceLost;
921
922 vk::SharedGarbageList<vk::SharedGarbage> mSharedGarbageList;
923 // Suballocations have its own dedicated garbage list for performance optimization since they
924 // tend to be the most common garbage objects.
925 vk::SharedGarbageList<vk::BufferSuballocationGarbage> mSuballocationGarbageList;
926 // Holds orphaned BufferBlocks when ShareGroup gets destroyed
927 vk::BufferBlockGarbageList mOrphanedBufferBlockList;
928 // Holds RefCountedEvent that are free and ready to reuse
929 vk::RefCountedEventRecycler mRefCountedEventRecycler;
930
931 VkDeviceSize mPendingGarbageSizeLimit;
932
933 vk::FormatTable mFormatTable;
934 // A cache of VkFormatProperties as queried from the device over time.
935 mutable angle::FormatMap<VkFormatProperties> mFormatProperties;
936
937 vk::Allocator mAllocator;
938
939 // Used to allocate memory for images using VMA, utilizing suballocation.
940 vk::ImageMemorySuballocator mImageMemorySuballocator;
941
942 vk::MemoryProperties mMemoryProperties;
943 VkDeviceSize mPreferredLargeHeapBlockSize;
944
945 // The default alignment for BufferVk object
946 size_t mDefaultBufferAlignment;
947 // The memory type index for staging buffer that is host visible.
948 angle::PackedEnumMap<vk::MemoryCoherency, uint32_t> mStagingBufferMemoryTypeIndex;
949 size_t mStagingBufferAlignment;
950 // For vertex conversion buffers
951 uint32_t mHostVisibleVertexConversionBufferMemoryTypeIndex;
952 uint32_t mDeviceLocalVertexConversionBufferMemoryTypeIndex;
953 size_t mVertexConversionBufferAlignment;
954
955 // The mutex protects -
956 // 1. initialization of the cache
957 // 2. Vulkan driver guarantess synchronization for read and write operations but the spec
958 // requires external synchronization when mPipelineCache is the dstCache of
959 // vkMergePipelineCaches. Lock the mutex if mergeProgramPipelineCachesToGlobalCache is
960 // enabled
961 angle::SimpleMutex mPipelineCacheMutex;
962 vk::PipelineCache mPipelineCache;
963 size_t mCurrentPipelineCacheBlobCacheSlotIndex;
964 size_t mPipelineCacheChunkCount;
965 uint32_t mPipelineCacheVkUpdateTimeout;
966 size_t mPipelineCacheSizeAtLastSync;
967 std::atomic<bool> mPipelineCacheInitialized;
968
969 // Latest validation data for debug overlay.
970 std::string mLastValidationMessage;
971 uint32_t mValidationMessageCount;
972
973 // Skipped validation messages. The exact contents of the list depends on the availability
974 // of certain extensions.
975 std::vector<const char *> mSkippedValidationMessages;
976 // Syncval skipped messages. The exact contents of the list depends on the availability of
977 // certain extensions.
978 std::vector<vk::SkippedSyncvalMessage> mSkippedSyncvalMessages;
979
980 // Whether framebuffer fetch is internally coherent. If framebuffer fetch is not coherent,
981 // technically ANGLE could simply not expose EXT_shader_framebuffer_fetch and instead only
982 // expose EXT_shader_framebuffer_fetch_non_coherent. In practice, too many Android apps assume
983 // EXT_shader_framebuffer_fetch is available and break without it. Others use string matching
984 // to detect when EXT_shader_framebuffer_fetch is available, and accidentally match
985 // EXT_shader_framebuffer_fetch_non_coherent and believe coherent framebuffer fetch is
986 // available.
987 //
988 // For these reasons, ANGLE always exposes EXT_shader_framebuffer_fetch. To ensure coherence
989 // between draw calls, it automatically inserts barriers between draw calls when the program
990 // uses framebuffer fetch. ANGLE does not attempt to guarantee coherence for self-overlapping
991 // geometry, which makes this emulation incorrect per spec, but practically harmless.
992 //
993 // This emulation can also be used to implement coherent advanced blend similarly if needed.
994 bool mIsColorFramebufferFetchCoherent;
995 // Whether framebuffer fetch has been used, for the purposes of more accurate syncval error
996 // filtering.
997 bool mIsColorFramebufferFetchUsed;
998
999 // How close to VkPhysicalDeviceLimits::maxMemoryAllocationCount we allow ourselves to get
1000 static constexpr double kPercentMaxMemoryAllocationCount = 0.3;
1001 // How many objects to garbage collect before issuing a flush()
1002 uint32_t mGarbageCollectionFlushThreshold;
1003
1004 // Only used for "one off" command buffers.
1005 angle::PackedEnumMap<vk::ProtectionType, OneOffCommandPool> mOneOffCommandPoolMap;
1006
1007 // Command queue
1008 vk::CommandQueue mCommandQueue;
1009
1010 // Async cleanup thread
1011 vk::CleanUpThread mCleanUpThread;
1012
1013 // Command buffer pool management.
1014 vk::CommandBufferRecycler<vk::OutsideRenderPassCommandBufferHelper>
1015 mOutsideRenderPassCommandBufferRecycler;
1016 vk::CommandBufferRecycler<vk::RenderPassCommandBufferHelper> mRenderPassCommandBufferRecycler;
1017
1018 SamplerCache mSamplerCache;
1019 SamplerYcbcrConversionCache mYuvConversionCache;
1020 angle::HashMap<VkFormat, uint32_t> mVkFormatDescriptorCountMap;
1021 vk::ActiveHandleCounter mActiveHandleCounts;
1022 angle::SimpleMutex mActiveHandleCountsMutex;
1023
1024 // Tracks resource serials.
1025 vk::ResourceSerialFactory mResourceSerialFactory;
1026
1027 // QueueSerial generator
1028 vk::QueueSerialIndexAllocator mQueueSerialIndexAllocator;
1029 std::array<AtomicSerialFactory, kMaxQueueSerialIndexCount> mQueueSerialFactory;
1030
1031 // Application executable information
1032 VkApplicationInfo mApplicationInfo;
1033 // Process GPU memory reports
1034 vk::MemoryReport mMemoryReport;
1035 // Helpers for adding trace annotations
1036 DebugAnnotatorVk mAnnotator;
1037
1038 // Stats about all Vulkan object caches
1039 VulkanCacheStats mVulkanCacheStats;
1040 mutable angle::SimpleMutex mCacheStatsMutex;
1041
1042 // A mask to filter out Vulkan pipeline stages that are not supported, applied in situations
1043 // where multiple stages are prespecified (for example with image layout transitions):
1044 //
1045 // - Excludes GEOMETRY if geometry shaders are not supported.
1046 // - Excludes TESSELLATION_CONTROL and TESSELLATION_EVALUATION if tessellation shaders are
1047 // not
1048 // supported.
1049 //
1050 // Note that this mask can have bits set that don't correspond to valid stages, so it's
1051 // strictly only useful for masking out unsupported stages in an otherwise valid set of
1052 // stages.
1053 VkPipelineStageFlags mSupportedBufferWritePipelineStageMask;
1054 VkShaderStageFlags mSupportedVulkanShaderStageMask;
1055 // The 1:1 mapping between EventStage and VkPipelineStageFlags
1056 EventStageToVkPipelineStageFlagsMap mEventStageToPipelineStageFlagsMap;
1057 ImageLayoutToMemoryBarrierDataMap mImageLayoutAndMemoryBarrierDataMap;
1058
1059 // Use thread pool to compress cache data.
1060 std::shared_ptr<angle::WaitableEvent> mCompressEvent;
1061
1062 VulkanLayerVector mEnabledDeviceLayerNames;
1063 vk::ExtensionNameList mEnabledInstanceExtensions;
1064 vk::ExtensionNameList mEnabledDeviceExtensions;
1065
1066 // Memory tracker for allocations and deallocations.
1067 MemoryAllocationTracker mMemoryAllocationTracker;
1068
1069 vk::ExternalFormatTable mExternalFormatTable;
1070
1071 // A graph built from pipeline descs and their transitions. This is not thread-safe, but it's
1072 // only a debug feature that's disabled by default.
1073 std::ostringstream mPipelineCacheGraph;
1074 bool mDumpPipelineCacheGraph;
1075 std::string mPipelineCacheGraphDumpPath;
1076
1077 // A placeholder descriptor set layout handle for layouts with no bindings.
1078 vk::DescriptorSetLayoutPtr mPlaceHolderDescriptorSetLayout;
1079
1080 // Cached value for the buffer memory size limit.
1081 VkDeviceSize mMaxBufferMemorySizeLimit;
1082 };
1083
generateQueueSerial(SerialIndex index)1084 ANGLE_INLINE Serial Renderer::generateQueueSerial(SerialIndex index)
1085 {
1086 return mQueueSerialFactory[index].generate();
1087 }
1088
reserveQueueSerials(SerialIndex index,size_t count,RangedSerialFactory * rangedSerialFactory)1089 ANGLE_INLINE void Renderer::reserveQueueSerials(SerialIndex index,
1090 size_t count,
1091 RangedSerialFactory *rangedSerialFactory)
1092 {
1093 mQueueSerialFactory[index].reserve(rangedSerialFactory, count);
1094 }
1095
hasResourceUseSubmitted(const vk::ResourceUse & use)1096 ANGLE_INLINE bool Renderer::hasResourceUseSubmitted(const vk::ResourceUse &use) const
1097 {
1098 return mCommandQueue.hasResourceUseSubmitted(use);
1099 }
1100
hasQueueSerialSubmitted(const QueueSerial & queueSerial)1101 ANGLE_INLINE bool Renderer::hasQueueSerialSubmitted(const QueueSerial &queueSerial) const
1102 {
1103 return mCommandQueue.hasQueueSerialSubmitted(queueSerial);
1104 }
1105
getLastSubmittedSerial(SerialIndex index)1106 ANGLE_INLINE Serial Renderer::getLastSubmittedSerial(SerialIndex index) const
1107 {
1108 return mCommandQueue.getLastSubmittedSerial(index);
1109 }
1110
hasResourceUseFinished(const vk::ResourceUse & use)1111 ANGLE_INLINE bool Renderer::hasResourceUseFinished(const vk::ResourceUse &use) const
1112 {
1113 return mCommandQueue.hasResourceUseFinished(use);
1114 }
1115
hasQueueSerialFinished(const QueueSerial & queueSerial)1116 ANGLE_INLINE bool Renderer::hasQueueSerialFinished(const QueueSerial &queueSerial) const
1117 {
1118 return mCommandQueue.hasQueueSerialFinished(queueSerial);
1119 }
1120
requestAsyncCommandsAndGarbageCleanup(vk::ErrorContext * context)1121 ANGLE_INLINE void Renderer::requestAsyncCommandsAndGarbageCleanup(vk::ErrorContext *context)
1122 {
1123 mCleanUpThread.requestCleanUp();
1124 }
1125
checkCompletedCommands(vk::ErrorContext * context)1126 ANGLE_INLINE angle::Result Renderer::checkCompletedCommands(vk::ErrorContext *context)
1127 {
1128 return mCommandQueue.checkCompletedCommands(context);
1129 }
1130
checkCompletedCommandsAndCleanup(vk::ErrorContext * context)1131 ANGLE_INLINE angle::Result Renderer::checkCompletedCommandsAndCleanup(vk::ErrorContext *context)
1132 {
1133 return mCommandQueue.checkAndCleanupCompletedCommands(context);
1134 }
1135
releaseFinishedCommands(vk::ErrorContext * context)1136 ANGLE_INLINE angle::Result Renderer::releaseFinishedCommands(vk::ErrorContext *context)
1137 {
1138 return mCommandQueue.releaseFinishedCommands(context);
1139 }
1140 } // namespace vk
1141 } // namespace rx
1142
1143 #endif // LIBANGLE_RENDERER_VULKAN_RENDERERVK_H_
1144