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