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 // DisplayVk.h: 7 // Defines the class interface for DisplayVk, implementing DisplayImpl. 8 // 9 10 #ifndef LIBANGLE_RENDERER_VULKAN_DISPLAYVK_H_ 11 #define LIBANGLE_RENDERER_VULKAN_DISPLAYVK_H_ 12 13 #include "common/MemoryBuffer.h" 14 #include "libANGLE/renderer/DisplayImpl.h" 15 #include "libANGLE/renderer/vulkan/ResourceVk.h" 16 #include "libANGLE/renderer/vulkan/vk_cache_utils.h" 17 #include "libANGLE/renderer/vulkan/vk_helpers.h" 18 #include "libANGLE/renderer/vulkan/vk_utils.h" 19 20 namespace rx 21 { 22 class RendererVk; 23 24 using ContextVkSet = std::set<ContextVk *>; 25 26 class ShareGroupVk : public ShareGroupImpl 27 { 28 public: 29 ShareGroupVk(); 30 void onDestroy(const egl::Display *display) override; 31 32 // PipelineLayoutCache and DescriptorSetLayoutCache can be shared between multiple threads 33 // accessing them via shared contexts. The ShareGroup locks around gl entrypoints ensuring 34 // synchronous update to the caches. getPipelineLayoutCache()35 PipelineLayoutCache &getPipelineLayoutCache() { return mPipelineLayoutCache; } getDescriptorSetLayoutCache()36 DescriptorSetLayoutCache &getDescriptorSetLayoutCache() { return mDescriptorSetLayoutCache; } getContexts()37 const ContextVkSet &getContexts() const { return mContexts; } 38 39 void releaseResourceUseLists(const Serial &submitSerial); acquireResourceUseList(vk::ResourceUseList && resourceUseList)40 void acquireResourceUseList(vk::ResourceUseList &&resourceUseList) 41 { 42 mResourceUseLists.emplace_back(std::move(resourceUseList)); 43 } 44 45 vk::BufferPool *getDefaultBufferPool(RendererVk *renderer, 46 VkDeviceSize size, 47 uint32_t memoryTypeIndex); 48 void pruneDefaultBufferPools(RendererVk *renderer); 49 bool isDueForBufferPoolPrune(); 50 51 void addContext(ContextVk *contextVk); 52 void removeContext(ContextVk *contextVk); 53 54 private: 55 // ANGLE uses a PipelineLayout cache to store compatible pipeline layouts. 56 PipelineLayoutCache mPipelineLayoutCache; 57 58 // DescriptorSetLayouts are also managed in a cache. 59 DescriptorSetLayoutCache mDescriptorSetLayoutCache; 60 61 // The list of contexts within the share group 62 ContextVkSet mContexts; 63 64 // List of resources currently used that need to be freed when any ContextVk in this 65 // ShareGroupVk submits the next command. 66 std::vector<vk::ResourceUseList> mResourceUseLists; 67 68 // The per shared group buffer pools that all buffers should sub-allocate from. 69 vk::BufferPoolPointerArray mDefaultBufferPools; 70 71 // The pool dedicated for small allocations that uses faster buddy algorithm 72 std::unique_ptr<vk::BufferPool> mSmallBufferPool; 73 static constexpr VkDeviceSize kMaxSizeToUseSmallBufferPool = 256; 74 75 // The system time when last pruneEmptyBuffer gets called. 76 double mLastPruneTime; 77 78 // If true, it is expected that a BufferBlock may still in used by textures that outlived 79 // ShareGroup. The non-empty BufferBlock will be put into RendererVk's orphan list instead. 80 bool mOrphanNonEmptyBufferBlock; 81 }; 82 83 class DisplayVk : public DisplayImpl, public vk::Context 84 { 85 public: 86 DisplayVk(const egl::DisplayState &state); 87 ~DisplayVk() override; 88 89 egl::Error initialize(egl::Display *display) override; 90 void terminate() override; 91 92 egl::Error makeCurrent(egl::Display *display, 93 egl::Surface *drawSurface, 94 egl::Surface *readSurface, 95 gl::Context *context) override; 96 97 bool testDeviceLost() override; 98 egl::Error restoreLostDevice(const egl::Display *display) override; 99 100 std::string getRendererDescription() override; 101 std::string getVendorString() override; 102 std::string getVersionString(bool includeFullVersion) override; 103 104 DeviceImpl *createDevice() override; 105 106 egl::Error waitClient(const gl::Context *context) override; 107 egl::Error waitNative(const gl::Context *context, EGLint engine) override; 108 109 SurfaceImpl *createWindowSurface(const egl::SurfaceState &state, 110 EGLNativeWindowType window, 111 const egl::AttributeMap &attribs) override; 112 SurfaceImpl *createPbufferSurface(const egl::SurfaceState &state, 113 const egl::AttributeMap &attribs) override; 114 SurfaceImpl *createPbufferFromClientBuffer(const egl::SurfaceState &state, 115 EGLenum buftype, 116 EGLClientBuffer clientBuffer, 117 const egl::AttributeMap &attribs) override; 118 SurfaceImpl *createPixmapSurface(const egl::SurfaceState &state, 119 NativePixmapType nativePixmap, 120 const egl::AttributeMap &attribs) override; 121 122 ImageImpl *createImage(const egl::ImageState &state, 123 const gl::Context *context, 124 EGLenum target, 125 const egl::AttributeMap &attribs) override; 126 127 ContextImpl *createContext(const gl::State &state, 128 gl::ErrorSet *errorSet, 129 const egl::Config *configuration, 130 const gl::Context *shareContext, 131 const egl::AttributeMap &attribs) override; 132 133 StreamProducerImpl *createStreamProducerD3DTexture(egl::Stream::ConsumerType consumerType, 134 const egl::AttributeMap &attribs) override; 135 136 EGLSyncImpl *createSync(const egl::AttributeMap &attribs) override; 137 138 gl::Version getMaxSupportedESVersion() const override; 139 gl::Version getMaxConformantESVersion() const override; 140 141 egl::Error validateImageClientBuffer(const gl::Context *context, 142 EGLenum target, 143 EGLClientBuffer clientBuffer, 144 const egl::AttributeMap &attribs) const override; 145 ExternalImageSiblingImpl *createExternalImageSibling(const gl::Context *context, 146 EGLenum target, 147 EGLClientBuffer buffer, 148 const egl::AttributeMap &attribs) override; 149 virtual const char *getWSIExtension() const = 0; 150 virtual const char *getWSILayer() const; 151 virtual bool isUsingSwapchain() const; 152 153 // Determine if a config with given formats and sample counts is supported. This callback may 154 // modify the config to add or remove platform specific attributes such as nativeVisualID. If 155 // the config is not supported by the window system, it removes the EGL_WINDOW_BIT from 156 // surfaceType, which would still allow the config to be used for pbuffers. 157 virtual void checkConfigSupport(egl::Config *config) = 0; 158 159 ANGLE_NO_DISCARD bool getScratchBuffer(size_t requestedSizeBytes, 160 angle::MemoryBuffer **scratchBufferOut) const; getScratchBuffer()161 angle::ScratchBuffer *getScratchBuffer() const { return &mScratchBuffer; } 162 163 void handleError(VkResult result, 164 const char *file, 165 const char *function, 166 unsigned int line) override; 167 168 // TODO(jmadill): Remove this once refactor is done. http://anglebug.com/3041 169 egl::Error getEGLError(EGLint errorCode); 170 171 void initializeFrontendFeatures(angle::FrontendFeatures *features) const override; 172 173 void populateFeatureList(angle::FeatureList *features) override; 174 175 ShareGroupImpl *createShareGroup() override; 176 177 protected: 178 void generateExtensions(egl::DisplayExtensions *outExtensions) const override; 179 180 private: 181 virtual SurfaceImpl *createWindowSurfaceVk(const egl::SurfaceState &state, 182 EGLNativeWindowType window) = 0; 183 void generateCaps(egl::Caps *outCaps) const override; 184 185 virtual angle::Result waitNativeImpl(); 186 187 mutable angle::ScratchBuffer mScratchBuffer; 188 189 vk::Error mSavedError; 190 }; 191 192 } // namespace rx 193 194 #endif // LIBANGLE_RENDERER_VULKAN_DISPLAYVK_H_ 195