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