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 &¤tGarbage,
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