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 struct 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 } // namespace vk
86
87 // Supports one semaphore from current surface, and one semaphore passed to
88 // glSignalSemaphoreEXT.
89 using SignalSemaphoreVector = angle::FixedVector<VkSemaphore, 2>;
90
CollectGarbage(std::vector<vk::GarbageObject> * garbageOut)91 inline void CollectGarbage(std::vector<vk::GarbageObject> *garbageOut) {}
92
93 template <typename ArgT, typename... ArgsT>
CollectGarbage(std::vector<vk::GarbageObject> * garbageOut,ArgT object,ArgsT...objectsIn)94 void CollectGarbage(std::vector<vk::GarbageObject> *garbageOut, ArgT object, ArgsT... objectsIn)
95 {
96 if (object->valid())
97 {
98 garbageOut->emplace_back(vk::GarbageObject::Get(object));
99 }
100 CollectGarbage(garbageOut, objectsIn...);
101 }
102
103 class WaitableCompressEvent
104 {
105 public:
WaitableCompressEvent(std::shared_ptr<angle::WaitableEvent> waitableEvent)106 WaitableCompressEvent(std::shared_ptr<angle::WaitableEvent> waitableEvent)
107 : mWaitableEvent(waitableEvent)
108 {}
109
~WaitableCompressEvent()110 virtual ~WaitableCompressEvent() {}
111
wait()112 void wait() { return mWaitableEvent->wait(); }
113
isReady()114 bool isReady() { return mWaitableEvent->isReady(); }
115
116 virtual bool getResult() = 0;
117
118 private:
119 std::shared_ptr<angle::WaitableEvent> mWaitableEvent;
120 };
121
122 class RendererVk : angle::NonCopyable
123 {
124 public:
125 RendererVk();
126 ~RendererVk();
127
128 angle::Result initialize(DisplayVk *displayVk,
129 egl::Display *display,
130 const char *wsiExtension,
131 const char *wsiLayer);
132 // Reload volk vk* function ptrs if needed for an already initialized RendererVk
133 void reloadVolkIfNeeded() const;
134 void onDestroy(vk::Context *context);
135
136 void notifyDeviceLost();
137 bool isDeviceLost() const;
138 bool hasSharedGarbage();
139 void releaseSharedResources(vk::ResourceUseList *resourceList);
140
141 std::string getVendorString() const;
142 std::string getRendererDescription() const;
143 std::string getVersionString() const;
144
145 gl::Version getMaxSupportedESVersion() const;
146 gl::Version getMaxConformantESVersion() const;
147
getInstance()148 VkInstance getInstance() const { return mInstance; }
getPhysicalDevice()149 VkPhysicalDevice getPhysicalDevice() const { return mPhysicalDevice; }
getPhysicalDeviceProperties()150 const VkPhysicalDeviceProperties &getPhysicalDeviceProperties() const
151 {
152 return mPhysicalDeviceProperties;
153 }
getPhysicalDeviceSubgroupProperties()154 const VkPhysicalDeviceSubgroupProperties &getPhysicalDeviceSubgroupProperties() const
155 {
156 return mSubgroupProperties;
157 }
getPhysicalDeviceFeatures()158 const VkPhysicalDeviceFeatures &getPhysicalDeviceFeatures() const
159 {
160 return mPhysicalDeviceFeatures;
161 }
getDevice()162 VkDevice getDevice() const { return mDevice; }
163
getAllocator()164 const vk::Allocator &getAllocator() const { return mAllocator; }
165
166 angle::Result selectPresentQueueForSurface(DisplayVk *displayVk,
167 VkSurfaceKHR surface,
168 uint32_t *presentQueueOut);
169
170 const gl::Caps &getNativeCaps() const;
171 const gl::TextureCapsMap &getNativeTextureCaps() const;
172 const gl::Extensions &getNativeExtensions() const;
173 const gl::Limitations &getNativeLimitations() const;
174
getQueueFamilyIndex()175 uint32_t getQueueFamilyIndex() const { return mCurrentQueueFamilyIndex; }
getQueueFamilyProperties()176 const VkQueueFamilyProperties &getQueueFamilyProperties() const
177 {
178 return mQueueFamilyProperties[mCurrentQueueFamilyIndex];
179 }
180
getMemoryProperties()181 const vk::MemoryProperties &getMemoryProperties() const { return mMemoryProperties; }
182
getFormat(GLenum internalFormat)183 const vk::Format &getFormat(GLenum internalFormat) const
184 {
185 return mFormatTable[internalFormat];
186 }
187
getFormat(angle::FormatID formatID)188 const vk::Format &getFormat(angle::FormatID formatID) const { return mFormatTable[formatID]; }
189
190 angle::Result getPipelineCacheSize(DisplayVk *displayVk, size_t *pipelineCacheSizeOut);
191 angle::Result syncPipelineCacheVk(DisplayVk *displayVk, const gl::Context *context);
192
193 // Issues a new serial for linked shader modules. Used in the pipeline cache.
194 Serial issueShaderSerial();
195
getFeatures()196 const angle::FeaturesVk &getFeatures() const { return mFeatures; }
getMaxVertexAttribDivisor()197 uint32_t getMaxVertexAttribDivisor() const { return mMaxVertexAttribDivisor; }
getMaxVertexAttribStride()198 VkDeviceSize getMaxVertexAttribStride() const { return mMaxVertexAttribStride; }
199
getMinImportedHostPointerAlignment()200 VkDeviceSize getMinImportedHostPointerAlignment() const
201 {
202 return mMinImportedHostPointerAlignment;
203 }
getDefaultUniformBufferSize()204 uint32_t getDefaultUniformBufferSize() const { return mDefaultUniformBufferSize; }
205
isMockICDEnabled()206 bool isMockICDEnabled() const { return mEnabledICD == angle::vk::ICD::Mock; }
207
208 // Query the format properties for select bits (linearTilingFeatures, optimalTilingFeatures and
209 // bufferFeatures). Looks through mandatory features first, and falls back to querying the
210 // device (first time only).
211 bool hasLinearImageFormatFeatureBits(angle::FormatID format,
212 const VkFormatFeatureFlags featureBits) const;
213 VkFormatFeatureFlags getLinearImageFormatFeatureBits(
214 angle::FormatID format,
215 const VkFormatFeatureFlags featureBits) const;
216 VkFormatFeatureFlags getImageFormatFeatureBits(angle::FormatID format,
217 const VkFormatFeatureFlags featureBits) const;
218 bool hasImageFormatFeatureBits(angle::FormatID format,
219 const VkFormatFeatureFlags featureBits) const;
220 bool hasBufferFormatFeatureBits(angle::FormatID format,
221 const VkFormatFeatureFlags featureBits) const;
222
getDriverPriority(egl::ContextPriority priority)223 ANGLE_INLINE egl::ContextPriority getDriverPriority(egl::ContextPriority priority)
224 {
225 return mCommandQueue.getDriverPriority(priority);
226 }
227
228 // This command buffer should be submitted immediately via queueSubmitOneOff.
229 angle::Result getCommandBufferOneOff(vk::Context *context,
230 bool hasProtectedContent,
231 vk::PrimaryCommandBuffer *commandBufferOut);
232
233 // Fire off a single command buffer immediately with default priority.
234 // Command buffer must be allocated with getCommandBufferOneOff and is reclaimed.
235 angle::Result queueSubmitOneOff(vk::Context *context,
236 vk::PrimaryCommandBuffer &&primary,
237 bool hasProtectedContent,
238 egl::ContextPriority priority,
239 const vk::Fence *fence,
240 vk::SubmitPolicy submitPolicy,
241 Serial *serialOut);
242
243 template <typename... ArgsT>
collectGarbageAndReinit(vk::SharedResourceUse * use,ArgsT...garbageIn)244 void collectGarbageAndReinit(vk::SharedResourceUse *use, ArgsT... garbageIn)
245 {
246 std::vector<vk::GarbageObject> sharedGarbage;
247 CollectGarbage(&sharedGarbage, garbageIn...);
248 if (!sharedGarbage.empty())
249 {
250 collectGarbage(std::move(*use), std::move(sharedGarbage));
251 }
252 else
253 {
254 // Force releasing "use" even if no garbage was created.
255 use->release();
256 }
257 // Keep "use" valid.
258 use->init();
259 }
260
collectGarbage(vk::SharedResourceUse && use,std::vector<vk::GarbageObject> && sharedGarbage)261 void collectGarbage(vk::SharedResourceUse &&use, std::vector<vk::GarbageObject> &&sharedGarbage)
262 {
263 if (!sharedGarbage.empty())
264 {
265 std::lock_guard<std::mutex> lock(mGarbageMutex);
266 mSharedGarbage.emplace_back(std::move(use), std::move(sharedGarbage));
267 }
268 }
269
270 angle::Result getPipelineCache(vk::PipelineCache **pipelineCache);
onNewGraphicsPipeline()271 void onNewGraphicsPipeline()
272 {
273 std::lock_guard<std::mutex> lock(mPipelineCacheMutex);
274 mPipelineCacheDirty = true;
275 }
276
277 void onNewValidationMessage(const std::string &message);
278 std::string getAndClearLastValidationMessage(uint32_t *countSinceLastClear);
279
280 uint64_t getMaxFenceWaitTimeNs() const;
281
getCurrentQueueSerial()282 ANGLE_INLINE Serial getCurrentQueueSerial()
283 {
284 if (mFeatures.asyncCommandQueue.enabled)
285 {
286 return mCommandProcessor.getCurrentQueueSerial();
287 }
288 else
289 {
290 std::lock_guard<std::mutex> lock(mCommandQueueMutex);
291 return mCommandQueue.getCurrentQueueSerial();
292 }
293 }
294
getLastSubmittedQueueSerial()295 ANGLE_INLINE Serial getLastSubmittedQueueSerial()
296 {
297 if (mFeatures.asyncCommandQueue.enabled)
298 {
299 return mCommandProcessor.getLastSubmittedQueueSerial();
300 }
301 else
302 {
303 std::lock_guard<std::mutex> lock(mCommandQueueMutex);
304 return mCommandQueue.getLastSubmittedQueueSerial();
305 }
306 }
307
getLastCompletedQueueSerial()308 ANGLE_INLINE Serial getLastCompletedQueueSerial()
309 {
310 if (mFeatures.asyncCommandQueue.enabled)
311 {
312 return mCommandProcessor.getLastCompletedQueueSerial();
313 }
314 else
315 {
316 std::lock_guard<std::mutex> lock(mCommandQueueMutex);
317 return mCommandQueue.getLastCompletedQueueSerial();
318 }
319 }
320
getDisplay()321 egl::Display *getDisplay() const { return mDisplay; }
322
getLastPresentResult(VkSwapchainKHR swapchain)323 VkResult getLastPresentResult(VkSwapchainKHR swapchain)
324 {
325 return mCommandProcessor.getLastPresentResult(swapchain);
326 }
327
enableDebugUtils()328 bool enableDebugUtils() const { return mEnableDebugUtils; }
angleDebuggerMode()329 bool angleDebuggerMode() const { return mAngleDebuggerMode; }
330
getSamplerCache()331 SamplerCache &getSamplerCache() { return mSamplerCache; }
getYuvConversionCache()332 SamplerYcbcrConversionCache &getYuvConversionCache() { return mYuvConversionCache; }
getActiveHandleCounts()333 vk::ActiveHandleCounter &getActiveHandleCounts() { return mActiveHandleCounts; }
334
getEnableValidationLayers()335 bool getEnableValidationLayers() const { return mEnableValidationLayers; }
336
getResourceSerialFactory()337 vk::ResourceSerialFactory &getResourceSerialFactory() { return mResourceSerialFactory; }
338
339 void setGlobalDebugAnnotator();
340
341 void outputVmaStatString();
342
343 bool haveSameFormatFeatureBits(angle::FormatID formatID1, angle::FormatID formatID2) const;
344
345 angle::Result cleanupGarbage(Serial lastCompletedQueueSerial);
346 void cleanupCompletedCommandsGarbage();
347
348 angle::Result submitFrame(vk::Context *context,
349 bool hasProtectedContent,
350 egl::ContextPriority contextPriority,
351 std::vector<VkSemaphore> &&waitSemaphores,
352 std::vector<VkPipelineStageFlags> &&waitSemaphoreStageMasks,
353 const vk::Semaphore *signalSemaphore,
354 std::vector<vk::ResourceUseList> &&resourceUseLists,
355 vk::GarbageList &¤tGarbage,
356 vk::CommandPool *commandPool);
357
358 void handleDeviceLost();
359 angle::Result finishToSerial(vk::Context *context, Serial serial);
360 angle::Result waitForSerialWithUserTimeout(vk::Context *context,
361 Serial serial,
362 uint64_t timeout,
363 VkResult *result);
364 angle::Result finish(vk::Context *context, bool hasProtectedContent);
365 angle::Result checkCompletedCommands(vk::Context *context);
366
367 angle::Result flushRenderPassCommands(vk::Context *context,
368 bool hasProtectedContent,
369 const vk::RenderPass &renderPass,
370 vk::CommandBufferHelper **renderPassCommands);
371 angle::Result flushOutsideRPCommands(vk::Context *context,
372 bool hasProtectedContent,
373 vk::CommandBufferHelper **outsideRPCommands);
374
375 VkResult queuePresent(vk::Context *context,
376 egl::ContextPriority priority,
377 const VkPresentInfoKHR &presentInfo);
378
379 vk::CommandBufferHelper *getCommandBufferHelper(bool hasRenderPass);
380 void recycleCommandBufferHelper(vk::CommandBufferHelper *commandBuffer);
381
382 // Process GPU memory reports
processMemoryReportCallback(const VkDeviceMemoryReportCallbackDataEXT & callbackData)383 void processMemoryReportCallback(const VkDeviceMemoryReportCallbackDataEXT &callbackData)
384 {
385 bool logCallback = getFeatures().logMemoryReportCallbacks.enabled;
386 mMemoryReport.processCallback(callbackData, logCallback);
387 }
388
389 // Accumulate cache stats for a specific cache
accumulateCacheStats(VulkanCacheType cache,const CacheStats & stats)390 void accumulateCacheStats(VulkanCacheType cache, const CacheStats &stats)
391 {
392 mVulkanCacheStats[cache].accumulate(stats);
393 }
394 // Log cache stats for all caches
395 void logCacheStats() const;
396
getSupportedVulkanPipelineStageMask()397 VkPipelineStageFlags getSupportedVulkanPipelineStageMask() const
398 {
399 return mSupportedVulkanPipelineStageMask;
400 }
401
402 angle::Result getFormatDescriptorCountForVkFormat(ContextVk *contextVk,
403 VkFormat format,
404 uint32_t *descriptorCountOut);
405
406 angle::Result getFormatDescriptorCountForExternalFormat(ContextVk *contextVk,
407 uint64_t format,
408 uint32_t *descriptorCountOut);
409
410 private:
411 angle::Result initializeDevice(DisplayVk *displayVk, uint32_t queueFamilyIndex);
412 void ensureCapsInitialized() const;
413
414 void queryDeviceExtensionFeatures(const vk::ExtensionNameList &deviceExtensionNames);
415
416 void initFeatures(DisplayVk *display, const vk::ExtensionNameList &extensions);
417 angle::Result initPipelineCache(DisplayVk *display,
418 vk::PipelineCache *pipelineCache,
419 bool *success);
420
421 template <VkFormatFeatureFlags VkFormatProperties::*features>
422 VkFormatFeatureFlags getFormatFeatureBits(angle::FormatID formatID,
423 const VkFormatFeatureFlags featureBits) const;
424
425 template <VkFormatFeatureFlags VkFormatProperties::*features>
426 bool hasFormatFeatureBits(angle::FormatID formatID,
427 const VkFormatFeatureFlags featureBits) const;
428
429 egl::Display *mDisplay;
430
431 std::unique_ptr<angle::Library> mLibVulkanLibrary;
432
433 mutable bool mCapsInitialized;
434 mutable gl::Caps mNativeCaps;
435 mutable gl::TextureCapsMap mNativeTextureCaps;
436 mutable gl::Extensions mNativeExtensions;
437 mutable gl::Limitations mNativeLimitations;
438 mutable angle::FeaturesVk mFeatures;
439
440 VkInstance mInstance;
441 bool mEnableValidationLayers;
442 // True if ANGLE is enabling the VK_EXT_debug_utils extension.
443 bool mEnableDebugUtils;
444 // True if ANGLE should call the vkCmd*DebugUtilsLabelEXT functions in order to communicate to
445 // debuggers (e.g. AGI) the OpenGL ES commands that the application uses. This is independent
446 // of mEnableDebugUtils, as an external graphics debugger can enable the VK_EXT_debug_utils
447 // extension and cause this to be set true.
448 bool mAngleDebuggerMode;
449 angle::vk::ICD mEnabledICD;
450 VkDebugUtilsMessengerEXT mDebugUtilsMessenger;
451 VkDebugReportCallbackEXT mDebugReportCallback;
452 VkPhysicalDevice mPhysicalDevice;
453 VkPhysicalDeviceProperties mPhysicalDeviceProperties;
454 VkPhysicalDeviceFeatures mPhysicalDeviceFeatures;
455 VkPhysicalDeviceLineRasterizationFeaturesEXT mLineRasterizationFeatures;
456 VkPhysicalDeviceProvokingVertexFeaturesEXT mProvokingVertexFeatures;
457 VkPhysicalDeviceVertexAttributeDivisorFeaturesEXT mVertexAttributeDivisorFeatures;
458 VkPhysicalDeviceVertexAttributeDivisorPropertiesEXT mVertexAttributeDivisorProperties;
459 VkPhysicalDeviceTransformFeedbackFeaturesEXT mTransformFeedbackFeatures;
460 VkPhysicalDeviceIndexTypeUint8FeaturesEXT mIndexTypeUint8Features;
461 VkPhysicalDeviceSubgroupProperties mSubgroupProperties;
462 VkPhysicalDeviceDeviceMemoryReportFeaturesEXT mMemoryReportFeatures;
463 VkDeviceDeviceMemoryReportCreateInfoEXT mMemoryReportCallback;
464 VkPhysicalDeviceExternalMemoryHostPropertiesEXT mExternalMemoryHostProperties;
465 VkPhysicalDeviceShaderFloat16Int8FeaturesKHR mShaderFloat16Int8Features;
466 VkPhysicalDeviceDepthStencilResolvePropertiesKHR mDepthStencilResolveProperties;
467 VkPhysicalDeviceMultisampledRenderToSingleSampledFeaturesEXT
468 mMultisampledRenderToSingleSampledFeatures;
469 VkPhysicalDeviceMultiviewFeatures mMultiviewFeatures;
470 VkPhysicalDeviceMultiviewProperties mMultiviewProperties;
471 VkPhysicalDeviceDriverPropertiesKHR mDriverProperties;
472 VkPhysicalDeviceCustomBorderColorFeaturesEXT mCustomBorderColorFeatures;
473 VkPhysicalDeviceProtectedMemoryFeatures mProtectedMemoryFeatures;
474 VkPhysicalDeviceProtectedMemoryProperties mProtectedMemoryProperties;
475 VkExternalFenceProperties mExternalFenceProperties;
476 VkExternalSemaphoreProperties mExternalSemaphoreProperties;
477 VkPhysicalDeviceSamplerYcbcrConversionFeatures mSamplerYcbcrConversionFeatures;
478 std::vector<VkQueueFamilyProperties> mQueueFamilyProperties;
479 uint32_t mMaxVertexAttribDivisor;
480 uint32_t mCurrentQueueFamilyIndex;
481 VkDeviceSize mMaxVertexAttribStride;
482 VkDeviceSize mMinImportedHostPointerAlignment;
483 uint32_t mDefaultUniformBufferSize;
484 VkDevice mDevice;
485 AtomicSerialFactory mShaderSerialFactory;
486
487 bool mDeviceLost;
488
489 std::mutex mGarbageMutex;
490 vk::SharedGarbageList mSharedGarbage;
491
492 vk::MemoryProperties mMemoryProperties;
493 vk::FormatTable mFormatTable;
494
495 // All access to the pipeline cache is done through EGL objects so it is thread safe to not use
496 // a lock.
497 std::mutex mPipelineCacheMutex;
498 vk::PipelineCache mPipelineCache;
499 uint32_t mPipelineCacheVkUpdateTimeout;
500 bool mPipelineCacheDirty;
501 bool mPipelineCacheInitialized;
502
503 // A cache of VkFormatProperties as queried from the device over time.
504 mutable angle::FormatMap<VkFormatProperties> mFormatProperties;
505
506 // Latest validation data for debug overlay.
507 std::string mLastValidationMessage;
508 uint32_t mValidationMessageCount;
509
510 DebugAnnotatorVk mAnnotator;
511
512 // How close to VkPhysicalDeviceLimits::maxMemoryAllocationCount we allow ourselves to get
513 static constexpr double kPercentMaxMemoryAllocationCount = 0.3;
514 // How many objects to garbage collect before issuing a flush()
515 uint32_t mGarbageCollectionFlushThreshold;
516
517 // Only used for "one off" command buffers.
518 vk::CommandPool mOneOffCommandPool;
519
520 struct PendingOneOffCommands
521 {
522 Serial serial;
523 vk::PrimaryCommandBuffer commandBuffer;
524 };
525 std::deque<PendingOneOffCommands> mPendingOneOffCommands;
526
527 std::mutex mCommandQueueMutex;
528 vk::CommandQueue mCommandQueue;
529
530 // Command buffer pool management.
531 std::mutex mCommandBufferHelperFreeListMutex;
532 std::vector<vk::CommandBufferHelper *> mCommandBufferHelperFreeList;
533
534 // Async Command Queue
535 vk::CommandProcessor mCommandProcessor;
536
537 vk::Allocator mAllocator;
538 SamplerCache mSamplerCache;
539 SamplerYcbcrConversionCache mYuvConversionCache;
540 angle::HashMap<VkFormat, uint32_t> mVkFormatDescriptorCountMap;
541 vk::ActiveHandleCounter mActiveHandleCounts;
542
543 // Tracks resource serials.
544 vk::ResourceSerialFactory mResourceSerialFactory;
545
546 // Process GPU memory reports
547 vk::MemoryReport mMemoryReport;
548
549 // Stats about all Vulkan object caches
550 using VulkanCacheStats = angle::PackedEnumMap<VulkanCacheType, CacheStats>;
551 VulkanCacheStats mVulkanCacheStats;
552
553 // A mask to filter out Vulkan pipeline stages that are not supported, applied in situations
554 // where multiple stages are prespecified (for example with image layout transitions):
555 //
556 // - Excludes GEOMETRY if geometry shaders are not supported.
557 // - Excludes TESSELLATION_CONTROL and TESSELLATION_EVALUATION if tessellation shaders are not
558 // supported.
559 //
560 // Note that this mask can have bits set that don't correspond to valid stages, so it's strictly
561 // only useful for masking out unsupported stages in an otherwise valid set of stages.
562 VkPipelineStageFlags mSupportedVulkanPipelineStageMask;
563
564 // Use thread pool to compress cache data.
565 std::shared_ptr<rx::WaitableCompressEvent> mCompressEvent;
566 };
567
568 } // namespace rx
569
570 #endif // LIBANGLE_RENDERER_VULKAN_RENDERERVK_H_
571