• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //
2 // Copyright 2016 The ANGLE Project Authors. All rights reserved.
3 // Use of this source code is governed by a BSD-style license that can be
4 // found in the LICENSE file.
5 //
6 // RendererVk.h:
7 //    Defines the class interface for RendererVk.
8 //
9 
10 #ifndef LIBANGLE_RENDERER_VULKAN_RENDERERVK_H_
11 #define LIBANGLE_RENDERER_VULKAN_RENDERERVK_H_
12 
13 #include <deque>
14 #include <memory>
15 #include <mutex>
16 
17 #include "vk_ext_provoking_vertex.h"
18 #include "volk.h"
19 
20 #include "common/PackedEnums.h"
21 #include "common/PoolAlloc.h"
22 #include "common/angleutils.h"
23 #include "libANGLE/BlobCache.h"
24 #include "libANGLE/Caps.h"
25 #include "libANGLE/renderer/vulkan/QueryVk.h"
26 #include "libANGLE/renderer/vulkan/ResourceVk.h"
27 #include "libANGLE/renderer/vulkan/UtilsVk.h"
28 #include "libANGLE/renderer/vulkan/vk_format_utils.h"
29 #include "libANGLE/renderer/vulkan/vk_helpers.h"
30 #include "libANGLE/renderer/vulkan/vk_internal_shaders_autogen.h"
31 #include "libANGLE/renderer/vulkan/vk_mem_alloc_wrapper.h"
32 
33 namespace egl
34 {
35 class Display;
36 class BlobCache;
37 }  // namespace egl
38 
39 namespace rx
40 {
41 class DisplayVk;
42 class FramebufferVk;
43 
44 namespace vk
45 {
46 struct Format;
47 }  // namespace vk
48 
49 // Supports one semaphore from current surface, and one semaphore passed to
50 // glSignalSemaphoreEXT.
51 using SignalSemaphoreVector = angle::FixedVector<VkSemaphore, 2>;
52 
CollectGarbage(std::vector<vk::GarbageObject> * garbageOut)53 inline void CollectGarbage(std::vector<vk::GarbageObject> *garbageOut) {}
54 
55 template <typename ArgT, typename... ArgsT>
CollectGarbage(std::vector<vk::GarbageObject> * garbageOut,ArgT object,ArgsT...objectsIn)56 void CollectGarbage(std::vector<vk::GarbageObject> *garbageOut, ArgT object, ArgsT... objectsIn)
57 {
58     if (object->valid())
59     {
60         garbageOut->emplace_back(vk::GarbageObject::Get(object));
61     }
62     CollectGarbage(garbageOut, objectsIn...);
63 }
64 
65 class RendererVk : angle::NonCopyable
66 {
67   public:
68     RendererVk();
69     ~RendererVk();
70 
71     angle::Result initialize(DisplayVk *displayVk,
72                              egl::Display *display,
73                              const char *wsiExtension,
74                              const char *wsiLayer);
75     // Reload volk vk* function ptrs if needed for an already initialized RendererVk
76     void reloadVolkIfNeeded() const;
77     void onDestroy();
78 
79     void notifyDeviceLost();
80     bool isDeviceLost() const;
81 
82     std::string getVendorString() const;
83     std::string getRendererDescription() const;
84 
85     gl::Version getMaxSupportedESVersion() const;
86     gl::Version getMaxConformantESVersion() const;
87 
getInstance()88     VkInstance getInstance() const { return mInstance; }
getPhysicalDevice()89     VkPhysicalDevice getPhysicalDevice() const { return mPhysicalDevice; }
getPhysicalDeviceProperties()90     const VkPhysicalDeviceProperties &getPhysicalDeviceProperties() const
91     {
92         return mPhysicalDeviceProperties;
93     }
getPhysicalDeviceSubgroupProperties()94     const VkPhysicalDeviceSubgroupProperties &getPhysicalDeviceSubgroupProperties() const
95     {
96         return mPhysicalDeviceSubgroupProperties;
97     }
getPhysicalDeviceFeatures()98     const VkPhysicalDeviceFeatures &getPhysicalDeviceFeatures() const
99     {
100         return mPhysicalDeviceFeatures;
101     }
getDevice()102     VkDevice getDevice() const { return mDevice; }
103 
getAllocator()104     const VmaAllocator &getAllocator() const { return mAllocator; }
105 
106     angle::Result selectPresentQueueForSurface(DisplayVk *displayVk,
107                                                VkSurfaceKHR surface,
108                                                uint32_t *presentQueueOut);
109 
110     const gl::Caps &getNativeCaps() const;
111     const gl::TextureCapsMap &getNativeTextureCaps() const;
112     const gl::Extensions &getNativeExtensions() const;
113     const gl::Limitations &getNativeLimitations() const;
114 
getQueueFamilyIndex()115     uint32_t getQueueFamilyIndex() const { return mCurrentQueueFamilyIndex; }
getQueueFamilyProperties()116     const VkQueueFamilyProperties &getQueueFamilyProperties() const
117     {
118         return mQueueFamilyProperties[mCurrentQueueFamilyIndex];
119     }
120 
getMemoryProperties()121     const vk::MemoryProperties &getMemoryProperties() const { return mMemoryProperties; }
122 
getFormat(GLenum internalFormat)123     const vk::Format &getFormat(GLenum internalFormat) const
124     {
125         return mFormatTable[internalFormat];
126     }
127 
getFormat(angle::FormatID formatID)128     const vk::Format &getFormat(angle::FormatID formatID) const { return mFormatTable[formatID]; }
129 
130     // Queries the descriptor set layout cache. Creates the layout if not present.
131     angle::Result getDescriptorSetLayout(
132         vk::Context *context,
133         const vk::DescriptorSetLayoutDesc &desc,
134         vk::BindingPointer<vk::DescriptorSetLayout> *descriptorSetLayoutOut);
135 
136     // Queries the pipeline layout cache. Creates the layout if not present.
137     angle::Result getPipelineLayout(vk::Context *context,
138                                     const vk::PipelineLayoutDesc &desc,
139                                     const vk::DescriptorSetLayoutPointerArray &descriptorSetLayouts,
140                                     vk::BindingPointer<vk::PipelineLayout> *pipelineLayoutOut);
141 
142     angle::Result getPipelineCacheSize(DisplayVk *displayVk, size_t *pipelineCacheSizeOut);
143     angle::Result syncPipelineCacheVk(DisplayVk *displayVk);
144 
145     // Issues a new serial for linked shader modules. Used in the pipeline cache.
146     Serial issueShaderSerial();
147 
getFeatures()148     const angle::FeaturesVk &getFeatures() const { return mFeatures; }
getMaxVertexAttribDivisor()149     uint32_t getMaxVertexAttribDivisor() const { return mMaxVertexAttribDivisor; }
getMaxVertexAttribStride()150     VkDeviceSize getMaxVertexAttribStride() const { return mMaxVertexAttribStride; }
151 
getMinImportedHostPointerAlignment()152     VkDeviceSize getMinImportedHostPointerAlignment() const
153     {
154         return mMinImportedHostPointerAlignment;
155     }
156 
isMockICDEnabled()157     bool isMockICDEnabled() const { return mEnabledICD == vk::ICD::Mock; }
158 
159     // Query the format properties for select bits (linearTilingFeatures, optimalTilingFeatures and
160     // bufferFeatures).  Looks through mandatory features first, and falls back to querying the
161     // device (first time only).
162     bool hasLinearImageFormatFeatureBits(VkFormat format, const VkFormatFeatureFlags featureBits);
163     VkFormatFeatureFlags getImageFormatFeatureBits(VkFormat format,
164                                                    const VkFormatFeatureFlags featureBits);
165     bool hasImageFormatFeatureBits(VkFormat format, const VkFormatFeatureFlags featureBits);
166     bool hasBufferFormatFeatureBits(VkFormat format, const VkFormatFeatureFlags featureBits);
167 
getDriverPriority(egl::ContextPriority priority)168     ANGLE_INLINE egl::ContextPriority getDriverPriority(egl::ContextPriority priority)
169     {
170         return mPriorities[priority];
171     }
172 
173     angle::Result queueSubmit(vk::Context *context,
174                               egl::ContextPriority priority,
175                               const VkSubmitInfo &submitInfo,
176                               const vk::Fence *fence,
177                               Serial *serialOut);
178     angle::Result queueWaitIdle(vk::Context *context, egl::ContextPriority priority);
179     angle::Result deviceWaitIdle(vk::Context *context);
180     VkResult queuePresent(egl::ContextPriority priority, const VkPresentInfoKHR &presentInfo);
181 
182     // This command buffer should be submitted immediately via queueSubmitOneOff.
183     angle::Result getCommandBufferOneOff(vk::Context *context,
184                                          vk::PrimaryCommandBuffer *commandBufferOut);
185 
186     // Fire off a single command buffer immediately with default priority.
187     // Command buffer must be allocated with getCommandBufferOneOff and is reclaimed.
188     angle::Result queueSubmitOneOff(vk::Context *context,
189                                     vk::PrimaryCommandBuffer &&primary,
190                                     egl::ContextPriority priority,
191                                     Serial *serialOut);
192 
193     angle::Result newSharedFence(vk::Context *context, vk::Shared<vk::Fence> *sharedFenceOut);
resetSharedFence(vk::Shared<vk::Fence> * sharedFenceIn)194     inline void resetSharedFence(vk::Shared<vk::Fence> *sharedFenceIn)
195     {
196         sharedFenceIn->resetAndRecycle(&mFenceRecycler);
197     }
198 
199     template <typename... ArgsT>
collectGarbageAndReinit(vk::SharedResourceUse * use,ArgsT...garbageIn)200     void collectGarbageAndReinit(vk::SharedResourceUse *use, ArgsT... garbageIn)
201     {
202         std::vector<vk::GarbageObject> sharedGarbage;
203         CollectGarbage(&sharedGarbage, garbageIn...);
204         if (!sharedGarbage.empty())
205         {
206             collectGarbage(std::move(*use), std::move(sharedGarbage));
207         }
208         else
209         {
210             // Force releasing "use" even if no garbage was created.
211             use->release();
212         }
213         // Keep "use" valid.
214         use->init();
215     }
216 
collectGarbage(vk::SharedResourceUse && use,std::vector<vk::GarbageObject> && sharedGarbage)217     void collectGarbage(vk::SharedResourceUse &&use, std::vector<vk::GarbageObject> &&sharedGarbage)
218     {
219         if (!sharedGarbage.empty())
220         {
221             mSharedGarbage.emplace_back(std::move(use), std::move(sharedGarbage));
222         }
223     }
224 
225     static constexpr size_t kMaxExtensionNames = 200;
226     using ExtensionNameList = angle::FixedVector<const char *, kMaxExtensionNames>;
227 
228     angle::Result getPipelineCache(vk::PipelineCache **pipelineCache);
onNewGraphicsPipeline()229     void onNewGraphicsPipeline() { mPipelineCacheDirty = true; }
230 
231     void onNewValidationMessage(const std::string &message);
232     std::string getAndClearLastValidationMessage(uint32_t *countSinceLastClear);
233 
234     uint64_t getMaxFenceWaitTimeNs() const;
getCurrentQueueSerial()235     Serial getCurrentQueueSerial() const { return mCurrentQueueSerial; }
getLastSubmittedQueueSerial()236     Serial getLastSubmittedQueueSerial() const { return mLastSubmittedQueueSerial; }
getLastCompletedQueueSerial()237     Serial getLastCompletedQueueSerial() const { return mLastCompletedQueueSerial; }
238 
239     void onCompletedSerial(Serial serial);
240 
shouldCleanupGarbage()241     bool shouldCleanupGarbage()
242     {
243         return (mSharedGarbage.size() > mGarbageCollectionFlushThreshold);
244     }
245 
enableDebugUtils()246     bool enableDebugUtils() const { return mEnableDebugUtils; }
247 
248   private:
249     angle::Result initializeDevice(DisplayVk *displayVk, uint32_t queueFamilyIndex);
250     void ensureCapsInitialized() const;
251 
252     void queryDeviceExtensionFeatures(const ExtensionNameList &deviceExtensionNames);
253 
254     void initFeatures(DisplayVk *display, const ExtensionNameList &extensions);
255     void initPipelineCacheVkKey();
256     angle::Result initPipelineCache(DisplayVk *display,
257                                     vk::PipelineCache *pipelineCache,
258                                     bool *success);
259 
260     template <VkFormatFeatureFlags VkFormatProperties::*features>
261     VkFormatFeatureFlags getFormatFeatureBits(VkFormat format,
262                                               const VkFormatFeatureFlags featureBits);
263 
264     template <VkFormatFeatureFlags VkFormatProperties::*features>
265     bool hasFormatFeatureBits(VkFormat format, const VkFormatFeatureFlags featureBits);
266 
267     angle::Result cleanupGarbage(bool block);
268 
269     egl::Display *mDisplay;
270 
271     mutable bool mCapsInitialized;
272     mutable gl::Caps mNativeCaps;
273     mutable gl::TextureCapsMap mNativeTextureCaps;
274     mutable gl::Extensions mNativeExtensions;
275     mutable gl::Limitations mNativeLimitations;
276     mutable angle::FeaturesVk mFeatures;
277 
278     VkInstance mInstance;
279     bool mEnableValidationLayers;
280     bool mEnableDebugUtils;
281     vk::ICD mEnabledICD;
282     VkDebugUtilsMessengerEXT mDebugUtilsMessenger;
283     VkDebugReportCallbackEXT mDebugReportCallback;
284     VkPhysicalDevice mPhysicalDevice;
285     VkPhysicalDeviceProperties mPhysicalDeviceProperties;
286     VkPhysicalDeviceFeatures mPhysicalDeviceFeatures;
287     VkPhysicalDeviceLineRasterizationFeaturesEXT mLineRasterizationFeatures;
288     VkPhysicalDeviceProvokingVertexFeaturesEXT mProvokingVertexFeatures;
289     VkPhysicalDeviceVertexAttributeDivisorFeaturesEXT mVertexAttributeDivisorFeatures;
290     VkPhysicalDeviceVertexAttributeDivisorPropertiesEXT mVertexAttributeDivisorProperties;
291     VkPhysicalDeviceTransformFeedbackFeaturesEXT mTransformFeedbackFeatures;
292     VkPhysicalDeviceIndexTypeUint8FeaturesEXT mIndexTypeUint8Features;
293     VkPhysicalDeviceSubgroupProperties mPhysicalDeviceSubgroupProperties;
294     VkPhysicalDeviceExternalMemoryHostPropertiesEXT mPhysicalDeviceExternalMemoryHostProperties;
295     std::vector<VkQueueFamilyProperties> mQueueFamilyProperties;
296     std::mutex mQueueMutex;
297     angle::PackedEnumMap<egl::ContextPriority, VkQueue> mQueues;
298     angle::PackedEnumMap<egl::ContextPriority, egl::ContextPriority> mPriorities;
299     uint32_t mCurrentQueueFamilyIndex;
300     uint32_t mMaxVertexAttribDivisor;
301     VkDeviceSize mMaxVertexAttribStride;
302     VkDeviceSize mMinImportedHostPointerAlignment;
303     VkDevice mDevice;
304     AtomicSerialFactory mQueueSerialFactory;
305     AtomicSerialFactory mShaderSerialFactory;
306 
307     Serial mLastCompletedQueueSerial;
308     Serial mLastSubmittedQueueSerial;
309     Serial mCurrentQueueSerial;
310 
311     bool mDeviceLost;
312 
313     vk::Recycler<vk::Fence> mFenceRecycler;
314 
315     std::mutex mGarbageMutex;
316     vk::SharedGarbageList mSharedGarbage;
317 
318     vk::MemoryProperties mMemoryProperties;
319     vk::FormatTable mFormatTable;
320 
321     // All access to the pipeline cache is done through EGL objects so it is thread safe to not use
322     // a lock.
323     vk::PipelineCache mPipelineCache;
324     egl::BlobCache::Key mPipelineCacheVkBlobKey;
325     uint32_t mPipelineCacheVkUpdateTimeout;
326     bool mPipelineCacheDirty;
327     bool mPipelineCacheInitialized;
328 
329     // A cache of VkFormatProperties as queried from the device over time.
330     std::array<VkFormatProperties, vk::kNumVkFormats> mFormatProperties;
331 
332     // ANGLE uses a PipelineLayout cache to store compatible pipeline layouts.
333     std::mutex mPipelineLayoutCacheMutex;
334     PipelineLayoutCache mPipelineLayoutCache;
335 
336     // DescriptorSetLayouts are also managed in a cache.
337     std::mutex mDescriptorSetLayoutCacheMutex;
338     DescriptorSetLayoutCache mDescriptorSetLayoutCache;
339 
340     // Latest validation data for debug overlay.
341     std::string mLastValidationMessage;
342     uint32_t mValidationMessageCount;
343 
344     // How close to VkPhysicalDeviceLimits::maxMemoryAllocationCount we allow ourselves to get
345     static constexpr double kPercentMaxMemoryAllocationCount = 0.3;
346     // How many objects to garbage collect before issuing a flush()
347     uint32_t mGarbageCollectionFlushThreshold;
348 
349     // Only used for "one off" command buffers.
350     vk::CommandPool mOneOffCommandPool;
351 
352     struct PendingOneOffCommands
353     {
354         Serial serial;
355         vk::PrimaryCommandBuffer commandBuffer;
356     };
357     std::deque<PendingOneOffCommands> mPendingOneOffCommands;
358 
359     // track whether we initialized (or released) glslang
360     bool mGlslangInitialized;
361 
362     VmaAllocator mAllocator;
363 };
364 
365 }  // namespace rx
366 
367 #endif  // LIBANGLE_RENDERER_VULKAN_RENDERERVK_H_
368