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