• 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 // RendererVk.h:
7 //    Defines the class interface for RendererVk.
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/PoolAlloc.h"
22 #include "common/angleutils.h"
23 #include "common/vulkan/vk_headers.h"
24 #include "common/vulkan/vulkan_icd.h"
25 #include "libANGLE/BlobCache.h"
26 #include "libANGLE/Caps.h"
27 #include "libANGLE/WorkerThread.h"
28 #include "libANGLE/renderer/vulkan/CommandProcessor.h"
29 #include "libANGLE/renderer/vulkan/DebugAnnotatorVk.h"
30 #include "libANGLE/renderer/vulkan/QueryVk.h"
31 #include "libANGLE/renderer/vulkan/ResourceVk.h"
32 #include "libANGLE/renderer/vulkan/UtilsVk.h"
33 #include "libANGLE/renderer/vulkan/vk_format_utils.h"
34 #include "libANGLE/renderer/vulkan/vk_helpers.h"
35 #include "libANGLE/renderer/vulkan/vk_internal_shaders_autogen.h"
36 #include "libANGLE/renderer/vulkan/vk_mem_alloc_wrapper.h"
37 
38 namespace angle
39 {
40 class Library;
41 }  // namespace angle
42 
43 namespace egl
44 {
45 class Display;
46 class BlobCache;
47 }  // namespace egl
48 
49 namespace rx
50 {
51 class DisplayVk;
52 class FramebufferVk;
53 
54 namespace vk
55 {
56 class Format;
57 
58 static constexpr size_t kMaxExtensionNames = 400;
59 using ExtensionNameList                    = angle::FixedVector<const char *, kMaxExtensionNames>;
60 
61 // Process GPU memory reports
62 class MemoryReport final : angle::NonCopyable
63 {
64   public:
65     MemoryReport();
66     void processCallback(const VkDeviceMemoryReportCallbackDataEXT &callbackData, bool logCallback);
67     void logMemoryReportStats() const;
68 
69   private:
70     struct MemorySizes
71     {
72         VkDeviceSize allocatedMemory;
73         VkDeviceSize allocatedMemoryMax;
74         VkDeviceSize importedMemory;
75         VkDeviceSize importedMemoryMax;
76     };
77     mutable std::mutex mMemoryReportMutex;
78     VkDeviceSize mCurrentTotalAllocatedMemory;
79     VkDeviceSize mMaxTotalAllocatedMemory;
80     angle::HashMap<VkObjectType, MemorySizes> mSizesPerType;
81     VkDeviceSize mCurrentTotalImportedMemory;
82     VkDeviceSize mMaxTotalImportedMemory;
83     angle::HashMap<uint64_t, int> mUniqueIDCounts;
84 };
85 
86 class BufferMemoryAllocator : angle::NonCopyable
87 {
88   public:
89     BufferMemoryAllocator();
90     ~BufferMemoryAllocator();
91 
92     VkResult initialize(RendererVk *renderer, VkDeviceSize preferredLargeHeapBlockSize);
93     void destroy(RendererVk *renderer);
94 
95     // Initializes the buffer handle and memory allocation.
96     VkResult createBuffer(RendererVk *renderer,
97                           const VkBufferCreateInfo &bufferCreateInfo,
98                           VkMemoryPropertyFlags requiredFlags,
99                           VkMemoryPropertyFlags preferredFlags,
100                           bool persistentlyMapped,
101                           uint32_t *memoryTypeIndexOut,
102                           Buffer *bufferOut,
103                           Allocation *allocationOut);
104 
105     void getMemoryTypeProperties(RendererVk *renderer,
106                                  uint32_t memoryTypeIndex,
107                                  VkMemoryPropertyFlags *flagsOut) const;
108     VkResult findMemoryTypeIndexForBufferInfo(RendererVk *renderer,
109                                               const VkBufferCreateInfo &bufferCreateInfo,
110                                               VkMemoryPropertyFlags requiredFlags,
111                                               VkMemoryPropertyFlags preferredFlags,
112                                               bool persistentlyMappedBuffers,
113                                               uint32_t *memoryTypeIndexOut) const;
114 
115   private:
116 };
117 }  // namespace vk
118 
119 // Supports one semaphore from current surface, and one semaphore passed to
120 // glSignalSemaphoreEXT.
121 using SignalSemaphoreVector = angle::FixedVector<VkSemaphore, 2>;
122 
CollectGarbage(std::vector<vk::GarbageObject> * garbageOut)123 inline void CollectGarbage(std::vector<vk::GarbageObject> *garbageOut) {}
124 
125 template <typename ArgT, typename... ArgsT>
CollectGarbage(std::vector<vk::GarbageObject> * garbageOut,ArgT object,ArgsT...objectsIn)126 void CollectGarbage(std::vector<vk::GarbageObject> *garbageOut, ArgT object, ArgsT... objectsIn)
127 {
128     if (object->valid())
129     {
130         garbageOut->emplace_back(vk::GarbageObject::Get(object));
131     }
132     CollectGarbage(garbageOut, objectsIn...);
133 }
134 
135 class WaitableCompressEvent
136 {
137   public:
WaitableCompressEvent(std::shared_ptr<angle::WaitableEvent> waitableEvent)138     WaitableCompressEvent(std::shared_ptr<angle::WaitableEvent> waitableEvent)
139         : mWaitableEvent(waitableEvent)
140     {}
141 
~WaitableCompressEvent()142     virtual ~WaitableCompressEvent() {}
143 
wait()144     void wait() { return mWaitableEvent->wait(); }
145 
isReady()146     bool isReady() { return mWaitableEvent->isReady(); }
147 
148     virtual bool getResult() = 0;
149 
150   private:
151     std::shared_ptr<angle::WaitableEvent> mWaitableEvent;
152 };
153 
154 class RendererVk : angle::NonCopyable
155 {
156   public:
157     RendererVk();
158     ~RendererVk();
159 
160     angle::Result initialize(DisplayVk *displayVk,
161                              egl::Display *display,
162                              const char *wsiExtension,
163                              const char *wsiLayer);
164     // Reload volk vk* function ptrs if needed for an already initialized RendererVk
165     void reloadVolkIfNeeded() const;
166     void onDestroy(vk::Context *context);
167 
168     void notifyDeviceLost();
169     bool isDeviceLost() const;
170     bool hasSharedGarbage();
171     void releaseSharedResources(vk::ResourceUseList *resourceList);
172 
173     std::string getVendorString() const;
174     std::string getRendererDescription() const;
175     std::string getVersionString() const;
176 
177     gl::Version getMaxSupportedESVersion() const;
178     gl::Version getMaxConformantESVersion() const;
179 
getApiVersion()180     uint32_t getApiVersion() const { return mApiVersion; }
getInstance()181     VkInstance getInstance() const { return mInstance; }
getPhysicalDevice()182     VkPhysicalDevice getPhysicalDevice() const { return mPhysicalDevice; }
getPhysicalDeviceProperties()183     const VkPhysicalDeviceProperties &getPhysicalDeviceProperties() const
184     {
185         return mPhysicalDeviceProperties;
186     }
getPhysicalDeviceSubgroupProperties()187     const VkPhysicalDeviceSubgroupProperties &getPhysicalDeviceSubgroupProperties() const
188     {
189         return mSubgroupProperties;
190     }
getPhysicalDeviceFeatures()191     const VkPhysicalDeviceFeatures &getPhysicalDeviceFeatures() const
192     {
193         return mPhysicalDeviceFeatures;
194     }
getEnabledFeatures()195     const VkPhysicalDeviceFeatures2KHR &getEnabledFeatures() const { return mEnabledFeatures; }
getDevice()196     VkDevice getDevice() const { return mDevice; }
197 
getBufferMemoryAllocator()198     vk::BufferMemoryAllocator &getBufferMemoryAllocator() { return mBufferMemoryAllocator; }
getAllocator()199     const vk::Allocator &getAllocator() const { return mAllocator; }
200 
201     angle::Result selectPresentQueueForSurface(DisplayVk *displayVk,
202                                                VkSurfaceKHR surface,
203                                                uint32_t *presentQueueOut);
204 
205     const gl::Caps &getNativeCaps() const;
206     const gl::TextureCapsMap &getNativeTextureCaps() const;
207     const gl::Extensions &getNativeExtensions() const;
208     const gl::Limitations &getNativeLimitations() const;
209 
getQueueFamilyIndex()210     uint32_t getQueueFamilyIndex() const { return mCurrentQueueFamilyIndex; }
getQueueFamilyProperties()211     const VkQueueFamilyProperties &getQueueFamilyProperties() const
212     {
213         return mQueueFamilyProperties[mCurrentQueueFamilyIndex];
214     }
215 
getMemoryProperties()216     const vk::MemoryProperties &getMemoryProperties() const { return mMemoryProperties; }
217 
getFormat(GLenum internalFormat)218     const vk::Format &getFormat(GLenum internalFormat) const
219     {
220         return mFormatTable[internalFormat];
221     }
222 
getFormat(angle::FormatID formatID)223     const vk::Format &getFormat(angle::FormatID formatID) const { return mFormatTable[formatID]; }
224 
225     angle::Result getPipelineCacheSize(DisplayVk *displayVk, size_t *pipelineCacheSizeOut);
226     angle::Result syncPipelineCacheVk(DisplayVk *displayVk, const gl::Context *context);
227 
228     // Issues a new serial for linked shader modules. Used in the pipeline cache.
229     Serial issueShaderSerial();
230 
getFeatures()231     const angle::FeaturesVk &getFeatures() const { return mFeatures; }
getMaxVertexAttribDivisor()232     uint32_t getMaxVertexAttribDivisor() const { return mMaxVertexAttribDivisor; }
getMaxVertexAttribStride()233     VkDeviceSize getMaxVertexAttribStride() const { return mMaxVertexAttribStride; }
234 
getMinImportedHostPointerAlignment()235     VkDeviceSize getMinImportedHostPointerAlignment() const
236     {
237         return mMinImportedHostPointerAlignment;
238     }
getDefaultUniformBufferSize()239     uint32_t getDefaultUniformBufferSize() const { return mDefaultUniformBufferSize; }
240 
isMockICDEnabled()241     bool isMockICDEnabled() const { return mEnabledICD == angle::vk::ICD::Mock; }
242 
243     // Query the format properties for select bits (linearTilingFeatures, optimalTilingFeatures and
244     // bufferFeatures).  Looks through mandatory features first, and falls back to querying the
245     // device (first time only).
246     bool hasLinearImageFormatFeatureBits(angle::FormatID format,
247                                          const VkFormatFeatureFlags featureBits) const;
248     VkFormatFeatureFlags getLinearImageFormatFeatureBits(
249         angle::FormatID format,
250         const VkFormatFeatureFlags featureBits) const;
251     VkFormatFeatureFlags getImageFormatFeatureBits(angle::FormatID format,
252                                                    const VkFormatFeatureFlags featureBits) const;
253     bool hasImageFormatFeatureBits(angle::FormatID format,
254                                    const VkFormatFeatureFlags featureBits) const;
255     bool hasBufferFormatFeatureBits(angle::FormatID format,
256                                     const VkFormatFeatureFlags featureBits) const;
257 
getDriverPriority(egl::ContextPriority priority)258     ANGLE_INLINE egl::ContextPriority getDriverPriority(egl::ContextPriority priority)
259     {
260         if (mFeatures.asyncCommandQueue.enabled)
261         {
262             return mCommandProcessor.getDriverPriority(priority);
263         }
264         else
265         {
266             return mCommandQueue.getDriverPriority(priority);
267         }
268     }
getDeviceQueueIndex()269     ANGLE_INLINE uint32_t getDeviceQueueIndex()
270     {
271         if (mFeatures.asyncCommandQueue.enabled)
272         {
273             return mCommandProcessor.getDeviceQueueIndex();
274         }
275         else
276         {
277             return mCommandQueue.getDeviceQueueIndex();
278         }
279     }
280 
getQueue(egl::ContextPriority priority)281     VkQueue getQueue(egl::ContextPriority priority)
282     {
283         if (mFeatures.asyncCommandQueue.enabled)
284         {
285             return mCommandProcessor.getQueue(priority);
286         }
287         else
288         {
289             return mCommandQueue.getQueue(priority);
290         }
291     }
292 
293     // This command buffer should be submitted immediately via queueSubmitOneOff.
294     angle::Result getCommandBufferOneOff(vk::Context *context,
295                                          bool hasProtectedContent,
296                                          vk::PrimaryCommandBuffer *commandBufferOut);
297 
resetSecondaryCommandBuffer(vk::CommandBuffer && commandBuffer)298     void resetSecondaryCommandBuffer(vk::CommandBuffer &&commandBuffer)
299     {
300         mCommandBufferRecycler.resetCommandBufferHelper(std::move(commandBuffer));
301     }
302 
303     // Fire off a single command buffer immediately with default priority.
304     // Command buffer must be allocated with getCommandBufferOneOff and is reclaimed.
305     angle::Result queueSubmitOneOff(vk::Context *context,
306                                     vk::PrimaryCommandBuffer &&primary,
307                                     bool hasProtectedContent,
308                                     egl::ContextPriority priority,
309                                     const vk::Semaphore *waitSemaphore,
310                                     VkPipelineStageFlags waitSemaphoreStageMasks,
311                                     const vk::Fence *fence,
312                                     vk::SubmitPolicy submitPolicy,
313                                     Serial *serialOut);
314 
315     template <typename... ArgsT>
collectGarbageAndReinit(vk::SharedResourceUse * use,ArgsT...garbageIn)316     void collectGarbageAndReinit(vk::SharedResourceUse *use, ArgsT... garbageIn)
317     {
318         std::vector<vk::GarbageObject> sharedGarbage;
319         CollectGarbage(&sharedGarbage, garbageIn...);
320         if (!sharedGarbage.empty())
321         {
322             collectGarbage(std::move(*use), std::move(sharedGarbage));
323         }
324         else
325         {
326             // Force releasing "use" even if no garbage was created.
327             use->release();
328         }
329         // Keep "use" valid.
330         use->init();
331     }
332 
collectGarbage(vk::SharedResourceUse && use,std::vector<vk::GarbageObject> && sharedGarbage)333     void collectGarbage(vk::SharedResourceUse &&use, std::vector<vk::GarbageObject> &&sharedGarbage)
334     {
335         if (!sharedGarbage.empty())
336         {
337             vk::SharedGarbage garbage(std::move(use), std::move(sharedGarbage));
338             if (!garbage.destroyIfComplete(this, getLastCompletedQueueSerial()))
339             {
340                 std::lock_guard<std::mutex> lock(mGarbageMutex);
341                 mSharedGarbage.push_back(std::move(garbage));
342             }
343         }
344     }
345 
346     angle::Result getPipelineCache(vk::PipelineCache **pipelineCache);
onNewGraphicsPipeline()347     void onNewGraphicsPipeline()
348     {
349         std::lock_guard<std::mutex> lock(mPipelineCacheMutex);
350         mPipelineCacheDirty = true;
351     }
352 
353     void onNewValidationMessage(const std::string &message);
354     std::string getAndClearLastValidationMessage(uint32_t *countSinceLastClear);
355 
356     uint64_t getMaxFenceWaitTimeNs() const;
357 
getLastCompletedQueueSerial()358     ANGLE_INLINE Serial getLastCompletedQueueSerial()
359     {
360         if (mFeatures.asyncCommandQueue.enabled)
361         {
362             return mCommandProcessor.getLastCompletedQueueSerial();
363         }
364         else
365         {
366             std::lock_guard<std::mutex> lock(mCommandQueueMutex);
367             return mCommandQueue.getLastCompletedQueueSerial();
368         }
369     }
370 
isCommandQueueBusy()371     ANGLE_INLINE bool isCommandQueueBusy()
372     {
373         std::lock_guard<std::mutex> lock(mCommandQueueMutex);
374         if (mFeatures.asyncCommandQueue.enabled)
375         {
376             return mCommandProcessor.isBusy();
377         }
378         else
379         {
380             return mCommandQueue.isBusy();
381         }
382     }
383 
ensureNoPendingWork(vk::Context * context)384     angle::Result ensureNoPendingWork(vk::Context *context)
385     {
386         if (mFeatures.asyncCommandQueue.enabled)
387         {
388             return mCommandProcessor.ensureNoPendingWork(context);
389         }
390         else
391         {
392             return mCommandQueue.ensureNoPendingWork(context);
393         }
394     }
395 
getDisplay()396     egl::Display *getDisplay() const { return mDisplay; }
397 
getLastPresentResult(VkSwapchainKHR swapchain)398     VkResult getLastPresentResult(VkSwapchainKHR swapchain)
399     {
400         return mCommandProcessor.getLastPresentResult(swapchain);
401     }
402 
enableDebugUtils()403     bool enableDebugUtils() const { return mEnableDebugUtils; }
angleDebuggerMode()404     bool angleDebuggerMode() const { return mAngleDebuggerMode; }
405 
getSamplerCache()406     SamplerCache &getSamplerCache() { return mSamplerCache; }
getYuvConversionCache()407     SamplerYcbcrConversionCache &getYuvConversionCache() { return mYuvConversionCache; }
408 
409     void onAllocateHandle(vk::HandleType handleType);
410     void onDeallocateHandle(vk::HandleType handleType);
411 
getEnableValidationLayers()412     bool getEnableValidationLayers() const { return mEnableValidationLayers; }
413 
getResourceSerialFactory()414     vk::ResourceSerialFactory &getResourceSerialFactory() { return mResourceSerialFactory; }
415 
416     void setGlobalDebugAnnotator();
417 
418     void outputVmaStatString();
419 
420     bool haveSameFormatFeatureBits(angle::FormatID formatID1, angle::FormatID formatID2) const;
421 
422     angle::Result cleanupGarbage(Serial lastCompletedQueueSerial);
423     void cleanupCompletedCommandsGarbage();
424 
425     angle::Result submitFrame(vk::Context *context,
426                               bool hasProtectedContent,
427                               egl::ContextPriority contextPriority,
428                               std::vector<VkSemaphore> &&waitSemaphores,
429                               std::vector<VkPipelineStageFlags> &&waitSemaphoreStageMasks,
430                               const vk::Semaphore *signalSemaphore,
431                               std::vector<vk::ResourceUseList> &&resourceUseLists,
432                               vk::GarbageList &&currentGarbage,
433                               vk::CommandPool *commandPool,
434                               Serial *submitSerialOut);
435 
436     void handleDeviceLost();
437     angle::Result finishToSerial(vk::Context *context, Serial serial);
438     angle::Result waitForSerialWithUserTimeout(vk::Context *context,
439                                                Serial serial,
440                                                uint64_t timeout,
441                                                VkResult *result);
442     angle::Result finish(vk::Context *context, bool hasProtectedContent);
443     angle::Result checkCompletedCommands(vk::Context *context);
444 
445     angle::Result flushRenderPassCommands(vk::Context *context,
446                                           bool hasProtectedContent,
447                                           const vk::RenderPass &renderPass,
448                                           vk::CommandBufferHelper **renderPassCommands);
449     angle::Result flushOutsideRPCommands(vk::Context *context,
450                                          bool hasProtectedContent,
451                                          vk::CommandBufferHelper **outsideRPCommands);
452 
453     VkResult queuePresent(vk::Context *context,
454                           egl::ContextPriority priority,
455                           const VkPresentInfoKHR &presentInfo);
456 
457     angle::Result getCommandBufferHelper(vk::Context *context,
458                                          bool hasRenderPass,
459                                          vk::CommandPool *commandPool,
460                                          vk::CommandBufferHelper **commandBufferHelperOut);
461     void recycleCommandBufferHelper(VkDevice device, vk::CommandBufferHelper **commandBuffer);
462 
463     // Process GPU memory reports
processMemoryReportCallback(const VkDeviceMemoryReportCallbackDataEXT & callbackData)464     void processMemoryReportCallback(const VkDeviceMemoryReportCallbackDataEXT &callbackData)
465     {
466         bool logCallback = getFeatures().logMemoryReportCallbacks.enabled;
467         mMemoryReport.processCallback(callbackData, logCallback);
468     }
469 
470     // Accumulate cache stats for a specific cache
accumulateCacheStats(VulkanCacheType cache,const CacheStats & stats)471     void accumulateCacheStats(VulkanCacheType cache, const CacheStats &stats)
472     {
473         std::lock_guard<std::mutex> localLock(mCacheStatsMutex);
474         mVulkanCacheStats[cache].accumulate(stats);
475     }
476     // Log cache stats for all caches
477     void logCacheStats() const;
478 
getSupportedVulkanPipelineStageMask()479     VkPipelineStageFlags getSupportedVulkanPipelineStageMask() const
480     {
481         return mSupportedVulkanPipelineStageMask;
482     }
483 
484     angle::Result getFormatDescriptorCountForVkFormat(ContextVk *contextVk,
485                                                       VkFormat format,
486                                                       uint32_t *descriptorCountOut);
487 
488     angle::Result getFormatDescriptorCountForExternalFormat(ContextVk *contextVk,
489                                                             uint64_t format,
490                                                             uint32_t *descriptorCountOut);
491 
getMaxCopyBytesUsingCPUWhenPreservingBufferData()492     VkDeviceSize getMaxCopyBytesUsingCPUWhenPreservingBufferData() const
493     {
494         return mMaxCopyBytesUsingCPUWhenPreservingBufferData;
495     }
496 
getEnabledInstanceExtensions()497     const vk::ExtensionNameList &getEnabledInstanceExtensions() const
498     {
499         return mEnabledInstanceExtensions;
500     }
501 
getEnabledDeviceExtensions()502     const vk::ExtensionNameList &getEnabledDeviceExtensions() const
503     {
504         return mEnabledDeviceExtensions;
505     }
506 
507   private:
508     angle::Result initializeDevice(DisplayVk *displayVk, uint32_t queueFamilyIndex);
509     void ensureCapsInitialized() const;
510 
511     void queryDeviceExtensionFeatures(const vk::ExtensionNameList &deviceExtensionNames);
512 
513     void initFeatures(DisplayVk *display, const vk::ExtensionNameList &extensions);
514     angle::Result initPipelineCache(DisplayVk *display,
515                                     vk::PipelineCache *pipelineCache,
516                                     bool *success);
517 
518     template <VkFormatFeatureFlags VkFormatProperties::*features>
519     VkFormatFeatureFlags getFormatFeatureBits(angle::FormatID formatID,
520                                               const VkFormatFeatureFlags featureBits) const;
521 
522     template <VkFormatFeatureFlags VkFormatProperties::*features>
523     bool hasFormatFeatureBits(angle::FormatID formatID,
524                               const VkFormatFeatureFlags featureBits) const;
525 
526     egl::Display *mDisplay;
527 
528     std::unique_ptr<angle::Library> mLibVulkanLibrary;
529 
530     mutable bool mCapsInitialized;
531     mutable gl::Caps mNativeCaps;
532     mutable gl::TextureCapsMap mNativeTextureCaps;
533     mutable gl::Extensions mNativeExtensions;
534     mutable gl::Limitations mNativeLimitations;
535     mutable angle::FeaturesVk mFeatures;
536 
537     uint32_t mApiVersion;
538     VkInstance mInstance;
539     bool mEnableValidationLayers;
540     // True if ANGLE is enabling the VK_EXT_debug_utils extension.
541     bool mEnableDebugUtils;
542     // True if ANGLE should call the vkCmd*DebugUtilsLabelEXT functions in order to communicate to
543     // debuggers (e.g. AGI) the OpenGL ES commands that the application uses.  This is independent
544     // of mEnableDebugUtils, as an external graphics debugger can enable the VK_EXT_debug_utils
545     // extension and cause this to be set true.
546     bool mAngleDebuggerMode;
547     angle::vk::ICD mEnabledICD;
548     VkDebugUtilsMessengerEXT mDebugUtilsMessenger;
549     VkDebugReportCallbackEXT mDebugReportCallback;
550     VkPhysicalDevice mPhysicalDevice;
551     VkPhysicalDeviceProperties mPhysicalDeviceProperties;
552     VkPhysicalDeviceFeatures mPhysicalDeviceFeatures;
553     VkPhysicalDeviceLineRasterizationFeaturesEXT mLineRasterizationFeatures;
554     VkPhysicalDeviceProvokingVertexFeaturesEXT mProvokingVertexFeatures;
555     VkPhysicalDeviceVertexAttributeDivisorFeaturesEXT mVertexAttributeDivisorFeatures;
556     VkPhysicalDeviceVertexAttributeDivisorPropertiesEXT mVertexAttributeDivisorProperties;
557     VkPhysicalDeviceTransformFeedbackFeaturesEXT mTransformFeedbackFeatures;
558     VkPhysicalDeviceIndexTypeUint8FeaturesEXT mIndexTypeUint8Features;
559     VkPhysicalDeviceSubgroupProperties mSubgroupProperties;
560     VkPhysicalDeviceDeviceMemoryReportFeaturesEXT mMemoryReportFeatures;
561     VkDeviceDeviceMemoryReportCreateInfoEXT mMemoryReportCallback;
562     VkPhysicalDeviceExternalMemoryHostPropertiesEXT mExternalMemoryHostProperties;
563     VkPhysicalDeviceShaderFloat16Int8FeaturesKHR mShaderFloat16Int8Features;
564     VkPhysicalDeviceDepthStencilResolvePropertiesKHR mDepthStencilResolveProperties;
565     VkPhysicalDeviceMultisampledRenderToSingleSampledFeaturesEXT
566         mMultisampledRenderToSingleSampledFeatures;
567     VkPhysicalDeviceMultiviewFeatures mMultiviewFeatures;
568     VkPhysicalDeviceFeatures2KHR mEnabledFeatures;
569     VkPhysicalDeviceMultiviewProperties mMultiviewProperties;
570     VkPhysicalDeviceDriverPropertiesKHR mDriverProperties;
571     VkPhysicalDeviceCustomBorderColorFeaturesEXT mCustomBorderColorFeatures;
572     VkPhysicalDeviceProtectedMemoryFeatures mProtectedMemoryFeatures;
573     VkPhysicalDeviceProtectedMemoryProperties mProtectedMemoryProperties;
574     VkPhysicalDeviceHostQueryResetFeaturesEXT mHostQueryResetFeatures;
575     VkExternalFenceProperties mExternalFenceProperties;
576     VkExternalSemaphoreProperties mExternalSemaphoreProperties;
577     VkPhysicalDeviceSamplerYcbcrConversionFeatures mSamplerYcbcrConversionFeatures;
578     std::vector<VkQueueFamilyProperties> mQueueFamilyProperties;
579     uint32_t mMaxVertexAttribDivisor;
580     uint32_t mCurrentQueueFamilyIndex;
581     VkDeviceSize mMaxVertexAttribStride;
582     VkDeviceSize mMinImportedHostPointerAlignment;
583     uint32_t mDefaultUniformBufferSize;
584     VkDevice mDevice;
585     AtomicSerialFactory mShaderSerialFactory;
586     VkDeviceSize mMaxCopyBytesUsingCPUWhenPreservingBufferData;
587 
588     bool mDeviceLost;
589 
590     std::mutex mGarbageMutex;
591     vk::SharedGarbageList mSharedGarbage;
592 
593     vk::MemoryProperties mMemoryProperties;
594     vk::FormatTable mFormatTable;
595 
596     // All access to the pipeline cache is done through EGL objects so it is thread safe to not use
597     // a lock.
598     std::mutex mPipelineCacheMutex;
599     vk::PipelineCache mPipelineCache;
600     uint32_t mPipelineCacheVkUpdateTimeout;
601     bool mPipelineCacheDirty;
602     bool mPipelineCacheInitialized;
603 
604     // A cache of VkFormatProperties as queried from the device over time.
605     mutable angle::FormatMap<VkFormatProperties> mFormatProperties;
606 
607     // Latest validation data for debug overlay.
608     std::string mLastValidationMessage;
609     uint32_t mValidationMessageCount;
610 
611     DebugAnnotatorVk mAnnotator;
612 
613     // How close to VkPhysicalDeviceLimits::maxMemoryAllocationCount we allow ourselves to get
614     static constexpr double kPercentMaxMemoryAllocationCount = 0.3;
615     // How many objects to garbage collect before issuing a flush()
616     uint32_t mGarbageCollectionFlushThreshold;
617 
618     // Only used for "one off" command buffers.
619     vk::CommandPool mOneOffCommandPool;
620 
621     struct PendingOneOffCommands
622     {
623         Serial serial;
624         vk::PrimaryCommandBuffer commandBuffer;
625     };
626     std::deque<PendingOneOffCommands> mPendingOneOffCommands;
627 
628     // Synchronous Command Queue
629     std::mutex mCommandQueueMutex;
630     vk::CommandQueue mCommandQueue;
631 
632     // Async Command Queue
633     vk::CommandProcessor mCommandProcessor;
634 
635     // Command buffer pool management.
636     std::mutex mCommandBufferRecyclerMutex;
637     vk::CommandBufferRecycler mCommandBufferRecycler;
638 
639     vk::BufferMemoryAllocator mBufferMemoryAllocator;
640     vk::Allocator mAllocator;
641     SamplerCache mSamplerCache;
642     SamplerYcbcrConversionCache mYuvConversionCache;
643     angle::HashMap<VkFormat, uint32_t> mVkFormatDescriptorCountMap;
644     vk::ActiveHandleCounter mActiveHandleCounts;
645     std::mutex mActiveHandleCountsMutex;
646 
647     // Tracks resource serials.
648     vk::ResourceSerialFactory mResourceSerialFactory;
649 
650     // Process GPU memory reports
651     vk::MemoryReport mMemoryReport;
652 
653     // Stats about all Vulkan object caches
654     using VulkanCacheStats = angle::PackedEnumMap<VulkanCacheType, CacheStats>;
655     VulkanCacheStats mVulkanCacheStats;
656     mutable std::mutex mCacheStatsMutex;
657 
658     // A mask to filter out Vulkan pipeline stages that are not supported, applied in situations
659     // where multiple stages are prespecified (for example with image layout transitions):
660     //
661     // - Excludes GEOMETRY if geometry shaders are not supported.
662     // - Excludes TESSELLATION_CONTROL and TESSELLATION_EVALUATION if tessellation shaders are not
663     //   supported.
664     //
665     // Note that this mask can have bits set that don't correspond to valid stages, so it's strictly
666     // only useful for masking out unsupported stages in an otherwise valid set of stages.
667     VkPipelineStageFlags mSupportedVulkanPipelineStageMask;
668 
669     // Use thread pool to compress cache data.
670     std::shared_ptr<rx::WaitableCompressEvent> mCompressEvent;
671 
672     vk::ExtensionNameList mEnabledInstanceExtensions;
673     vk::ExtensionNameList mEnabledDeviceExtensions;
674 };
675 
676 }  // namespace rx
677 
678 #endif  // LIBANGLE_RENDERER_VULKAN_RENDERERVK_H_
679