• 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 <vulkan/vulkan.h>
14 #include <memory>
15 #include <mutex>
16 
17 #include "common/PoolAlloc.h"
18 #include "common/angleutils.h"
19 #include "libANGLE/BlobCache.h"
20 #include "libANGLE/Caps.h"
21 #include "libANGLE/renderer/vulkan/CommandGraph.h"
22 #include "libANGLE/renderer/vulkan/QueryVk.h"
23 #include "libANGLE/renderer/vulkan/UtilsVk.h"
24 #include "libANGLE/renderer/vulkan/vk_format_utils.h"
25 #include "libANGLE/renderer/vulkan/vk_helpers.h"
26 #include "libANGLE/renderer/vulkan/vk_internal_shaders_autogen.h"
27 
28 namespace egl
29 {
30 class Display;
31 class BlobCache;
32 }  // namespace egl
33 
34 namespace rx
35 {
36 class DisplayVk;
37 class FramebufferVk;
38 
39 namespace vk
40 {
41 struct Format;
42 }
43 
44 // Supports one semaphore from current surface, and one semaphore passed to
45 // glSignalSemaphoreEXT.
46 using SignalSemaphoreVector = angle::FixedVector<VkSemaphore, 2>;
47 
48 class RendererVk : angle::NonCopyable
49 {
50   public:
51     RendererVk();
52     ~RendererVk();
53 
54     angle::Result initialize(DisplayVk *displayVk,
55                              egl::Display *display,
56                              const char *wsiExtension,
57                              const char *wsiLayer);
58     void onDestroy(vk::Context *context);
59 
60     void notifyDeviceLost();
61     bool isDeviceLost() const;
62 
63     std::string getVendorString() const;
64     std::string getRendererDescription() const;
65 
66     gl::Version getMaxSupportedESVersion() const;
67     gl::Version getMaxConformantESVersion() const;
68 
getInstance()69     VkInstance getInstance() const { return mInstance; }
getPhysicalDevice()70     VkPhysicalDevice getPhysicalDevice() const { return mPhysicalDevice; }
getPhysicalDeviceProperties()71     const VkPhysicalDeviceProperties &getPhysicalDeviceProperties() const
72     {
73         return mPhysicalDeviceProperties;
74     }
getPhysicalDeviceSubgroupProperties()75     const VkPhysicalDeviceSubgroupProperties &getPhysicalDeviceSubgroupProperties() const
76     {
77         return mPhysicalDeviceSubgroupProperties;
78     }
getPhysicalDeviceFeatures()79     const VkPhysicalDeviceFeatures &getPhysicalDeviceFeatures() const
80     {
81         return mPhysicalDeviceFeatures;
82     }
getDevice()83     VkDevice getDevice() const { return mDevice; }
84 
85     angle::Result selectPresentQueueForSurface(DisplayVk *displayVk,
86                                                VkSurfaceKHR surface,
87                                                uint32_t *presentQueueOut);
88 
89     const gl::Caps &getNativeCaps() const;
90     const gl::TextureCapsMap &getNativeTextureCaps() const;
91     const gl::Extensions &getNativeExtensions() const;
92     const gl::Limitations &getNativeLimitations() const;
93 
getQueueFamilyIndex()94     uint32_t getQueueFamilyIndex() const { return mCurrentQueueFamilyIndex; }
95 
getMemoryProperties()96     const vk::MemoryProperties &getMemoryProperties() const { return mMemoryProperties; }
97 
98     // TODO(jmadill): We could pass angle::FormatID here.
getFormat(GLenum internalFormat)99     const vk::Format &getFormat(GLenum internalFormat) const
100     {
101         return mFormatTable[internalFormat];
102     }
103 
getFormat(angle::FormatID formatID)104     const vk::Format &getFormat(angle::FormatID formatID) const { return mFormatTable[formatID]; }
105 
106     // Queries the descriptor set layout cache. Creates the layout if not present.
107     angle::Result getDescriptorSetLayout(
108         vk::Context *context,
109         const vk::DescriptorSetLayoutDesc &desc,
110         vk::BindingPointer<vk::DescriptorSetLayout> *descriptorSetLayoutOut);
111 
112     // Queries the pipeline layout cache. Creates the layout if not present.
113     angle::Result getPipelineLayout(vk::Context *context,
114                                     const vk::PipelineLayoutDesc &desc,
115                                     const vk::DescriptorSetLayoutPointerArray &descriptorSetLayouts,
116                                     vk::BindingPointer<vk::PipelineLayout> *pipelineLayoutOut);
117 
118     angle::Result syncPipelineCacheVk(DisplayVk *displayVk);
119 
120     // Issues a new serial for linked shader modules. Used in the pipeline cache.
121     Serial issueShaderSerial();
122 
getFeatures()123     const angle::FeaturesVk &getFeatures() const
124     {
125         ASSERT(mFeaturesInitialized);
126         return mFeatures;
127     }
128 
isMockICDEnabled()129     bool isMockICDEnabled() const { return mEnableMockICD; }
130 
131     // Query the format properties for select bits (linearTilingFeatures, optimalTilingFeatures and
132     // bufferFeatures).  Looks through mandatory features first, and falls back to querying the
133     // device (first time only).
134     bool hasLinearImageFormatFeatureBits(VkFormat format, const VkFormatFeatureFlags featureBits);
135     VkFormatFeatureFlags getImageFormatFeatureBits(VkFormat format,
136                                                    const VkFormatFeatureFlags featureBits);
137     bool hasImageFormatFeatureBits(VkFormat format, const VkFormatFeatureFlags featureBits);
138     bool hasBufferFormatFeatureBits(VkFormat format, const VkFormatFeatureFlags featureBits);
139 
140     angle::Result queueSubmit(vk::Context *context,
141                               const VkSubmitInfo &submitInfo,
142                               const vk::Fence &fence);
143     angle::Result queueWaitIdle(vk::Context *context);
144     VkResult queuePresent(const VkPresentInfoKHR &presentInfo);
145 
146     Serial nextSerial();
147 
148     angle::Result newSharedFence(vk::Context *context, vk::Shared<vk::Fence> *sharedFenceOut);
resetSharedFence(vk::Shared<vk::Fence> * sharedFenceIn)149     inline void resetSharedFence(vk::Shared<vk::Fence> *sharedFenceIn)
150     {
151         sharedFenceIn->resetAndRecycle(&mFenceRecycler);
152     }
153 
154     void addGarbage(vk::Shared<vk::Fence> &&fence, std::vector<vk::GarbageObjectBase> &&garbage);
155     void addGarbage(std::vector<vk::Shared<vk::Fence>> &&fences,
156                     std::vector<vk::GarbageObjectBase> &&garbage);
157 
158     static constexpr size_t kMaxExtensionNames = 200;
159     using ExtensionNameList = angle::FixedVector<const char *, kMaxExtensionNames>;
160 
161     angle::Result getPipelineCache(vk::PipelineCache **pipelineCache);
onNewGraphicsPipeline()162     void onNewGraphicsPipeline() { mPipelineCacheDirty = true; }
163 
164   private:
165     angle::Result initializeDevice(DisplayVk *displayVk, uint32_t queueFamilyIndex);
166     void ensureCapsInitialized() const;
167 
168     void initFeatures(const ExtensionNameList &extensions);
169     void initPipelineCacheVkKey();
170     angle::Result initPipelineCache(DisplayVk *display,
171                                     vk::PipelineCache *pipelineCache,
172                                     bool *success);
173 
174     template <VkFormatFeatureFlags VkFormatProperties::*features>
175     VkFormatFeatureFlags getFormatFeatureBits(VkFormat format,
176                                               const VkFormatFeatureFlags featureBits);
177 
178     template <VkFormatFeatureFlags VkFormatProperties::*features>
179     bool hasFormatFeatureBits(VkFormat format, const VkFormatFeatureFlags featureBits);
180 
181     angle::Result cleanupGarbage(vk::Context *context, bool block);
182 
183     egl::Display *mDisplay;
184 
185     mutable bool mCapsInitialized;
186     mutable gl::Caps mNativeCaps;
187     mutable gl::TextureCapsMap mNativeTextureCaps;
188     mutable gl::Extensions mNativeExtensions;
189     mutable gl::Limitations mNativeLimitations;
190     mutable bool mFeaturesInitialized;
191     mutable angle::FeaturesVk mFeatures;
192 
193     VkInstance mInstance;
194     bool mEnableValidationLayers;
195     bool mEnableMockICD;
196     VkDebugUtilsMessengerEXT mDebugUtilsMessenger;
197     VkDebugReportCallbackEXT mDebugReportCallback;
198     VkPhysicalDevice mPhysicalDevice;
199     VkPhysicalDeviceProperties mPhysicalDeviceProperties;
200     VkPhysicalDeviceSubgroupProperties mPhysicalDeviceSubgroupProperties;
201     VkPhysicalDeviceFeatures mPhysicalDeviceFeatures;
202     std::vector<VkQueueFamilyProperties> mQueueFamilyProperties;
203     std::mutex mQueueMutex;
204     VkQueue mQueue;
205     uint32_t mCurrentQueueFamilyIndex;
206     uint32_t mMaxVertexAttribDivisor;
207     VkDevice mDevice;
208     AtomicSerialFactory mQueueSerialFactory;
209     AtomicSerialFactory mShaderSerialFactory;
210     Serial mCurrentQueueSerial;
211 
212     bool mDeviceLost;
213 
214     vk::Recycler<vk::Fence> mFenceRecycler;
215 
216     std::mutex mGarbageMutex;
217     using FencedGarbage =
218         std::pair<std::vector<vk::Shared<vk::Fence>>, std::vector<vk::GarbageObjectBase>>;
219     std::vector<FencedGarbage> mFencedGarbage;
220 
221     vk::MemoryProperties mMemoryProperties;
222     vk::FormatTable mFormatTable;
223 
224     // All access to the pipeline cache is done through EGL objects so it is thread safe to not use
225     // a lock.
226     vk::PipelineCache mPipelineCache;
227     egl::BlobCache::Key mPipelineCacheVkBlobKey;
228     uint32_t mPipelineCacheVkUpdateTimeout;
229     bool mPipelineCacheDirty;
230     bool mPipelineCacheInitialized;
231 
232     // A cache of VkFormatProperties as queried from the device over time.
233     std::array<VkFormatProperties, vk::kNumVkFormats> mFormatProperties;
234 
235     // ANGLE uses a PipelineLayout cache to store compatible pipeline layouts.
236     std::mutex mPipelineLayoutCacheMutex;
237     PipelineLayoutCache mPipelineLayoutCache;
238 
239     // DescriptorSetLayouts are also managed in a cache.
240     std::mutex mDescriptorSetLayoutCacheMutex;
241     DescriptorSetLayoutCache mDescriptorSetLayoutCache;
242 };
243 
244 }  // namespace rx
245 
246 #endif  // LIBANGLE_RENDERER_VULKAN_RENDERERVK_H_
247