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_utils.h"
18 
19 namespace rx
20 {
21 class RendererVk;
22 
23 using ContextVkSet = std::set<ContextVk *>;
24 
25 class ShareGroupVk : public ShareGroupImpl
26 {
27   public:
28     ShareGroupVk();
29     void onDestroy(const egl::Display *display) override;
30 
31     // PipelineLayoutCache and DescriptorSetLayoutCache can be shared between multiple threads
32     // accessing them via shared contexts. The ShareGroup locks around gl entrypoints ensuring
33     // synchronous update to the caches.
getPipelineLayoutCache()34     PipelineLayoutCache &getPipelineLayoutCache() { return mPipelineLayoutCache; }
getDescriptorSetLayoutCache()35     DescriptorSetLayoutCache &getDescriptorSetLayoutCache() { return mDescriptorSetLayoutCache; }
getContexts()36     ContextVkSet *getContexts() { return &mContexts; }
37 
releaseResourceUseLists()38     std::vector<vk::ResourceUseList> &&releaseResourceUseLists()
39     {
40         return std::move(mResourceUseLists);
41     }
acquireResourceUseList(vk::ResourceUseList && resourceUseList)42     void acquireResourceUseList(vk::ResourceUseList &&resourceUseList)
43     {
44         mResourceUseLists.emplace_back(std::move(resourceUseList));
45     }
46 
isSyncObjectPendingFlush()47     bool isSyncObjectPendingFlush() { return mSyncObjectPendingFlush; }
setSyncObjectPendingFlush()48     void setSyncObjectPendingFlush() { mSyncObjectPendingFlush = true; }
clearSyncObjectPendingFlush()49     void clearSyncObjectPendingFlush() { mSyncObjectPendingFlush = false; }
50 
51   private:
52     // ANGLE uses a PipelineLayout cache to store compatible pipeline layouts.
53     PipelineLayoutCache mPipelineLayoutCache;
54 
55     // DescriptorSetLayouts are also managed in a cache.
56     DescriptorSetLayoutCache mDescriptorSetLayoutCache;
57 
58     // The list of contexts within the share group
59     ContextVkSet mContexts;
60 
61     // List of resources currently used that need to be freed when any ContextVk in this
62     // ShareGroupVk submits the next command.
63     std::vector<vk::ResourceUseList> mResourceUseLists;
64 
65     bool mSyncObjectPendingFlush;
66 };
67 
68 class DisplayVk : public DisplayImpl, public vk::Context
69 {
70   public:
71     DisplayVk(const egl::DisplayState &state);
72     ~DisplayVk() override;
73 
74     egl::Error initialize(egl::Display *display) override;
75     void terminate() override;
76 
77     egl::Error makeCurrent(egl::Display *display,
78                            egl::Surface *drawSurface,
79                            egl::Surface *readSurface,
80                            gl::Context *context) override;
81 
82     bool testDeviceLost() override;
83     egl::Error restoreLostDevice(const egl::Display *display) override;
84 
85     std::string getRendererDescription() override;
86     std::string getVendorString() override;
87     std::string getVersionString() override;
88 
89     egl::Error waitClient(const gl::Context *context) override;
90     egl::Error waitNative(const gl::Context *context, EGLint engine) override;
91 
92     SurfaceImpl *createWindowSurface(const egl::SurfaceState &state,
93                                      EGLNativeWindowType window,
94                                      const egl::AttributeMap &attribs) override;
95     SurfaceImpl *createPbufferSurface(const egl::SurfaceState &state,
96                                       const egl::AttributeMap &attribs) override;
97     SurfaceImpl *createPbufferFromClientBuffer(const egl::SurfaceState &state,
98                                                EGLenum buftype,
99                                                EGLClientBuffer clientBuffer,
100                                                const egl::AttributeMap &attribs) override;
101     SurfaceImpl *createPixmapSurface(const egl::SurfaceState &state,
102                                      NativePixmapType nativePixmap,
103                                      const egl::AttributeMap &attribs) override;
104 
105     ImageImpl *createImage(const egl::ImageState &state,
106                            const gl::Context *context,
107                            EGLenum target,
108                            const egl::AttributeMap &attribs) override;
109 
110     ContextImpl *createContext(const gl::State &state,
111                                gl::ErrorSet *errorSet,
112                                const egl::Config *configuration,
113                                const gl::Context *shareContext,
114                                const egl::AttributeMap &attribs) override;
115 
116     StreamProducerImpl *createStreamProducerD3DTexture(egl::Stream::ConsumerType consumerType,
117                                                        const egl::AttributeMap &attribs) override;
118 
119     EGLSyncImpl *createSync(const egl::AttributeMap &attribs) override;
120 
121     gl::Version getMaxSupportedESVersion() const override;
122     gl::Version getMaxConformantESVersion() const override;
123 
124     virtual const char *getWSIExtension() const = 0;
125     virtual const char *getWSILayer() const;
126     virtual bool isUsingSwapchain() const;
127 
128     // Determine if a config with given formats and sample counts is supported.  This callback may
129     // modify the config to add or remove platform specific attributes such as nativeVisualID.  If
130     // the config is not supported by the window system, it removes the EGL_WINDOW_BIT from
131     // surfaceType, which would still allow the config to be used for pbuffers.
132     virtual void checkConfigSupport(egl::Config *config) = 0;
133 
134     ANGLE_NO_DISCARD bool getScratchBuffer(size_t requestedSizeBytes,
135                                            angle::MemoryBuffer **scratchBufferOut) const;
getScratchBuffer()136     angle::ScratchBuffer *getScratchBuffer() const { return &mScratchBuffer; }
137 
138     void handleError(VkResult result,
139                      const char *file,
140                      const char *function,
141                      unsigned int line) override;
142 
143     // TODO(jmadill): Remove this once refactor is done. http://anglebug.com/3041
144     egl::Error getEGLError(EGLint errorCode);
145 
146     void populateFeatureList(angle::FeatureList *features) override;
147 
148     ShareGroupImpl *createShareGroup() override;
149 
150   protected:
151     void generateExtensions(egl::DisplayExtensions *outExtensions) const override;
152 
153   private:
154     virtual SurfaceImpl *createWindowSurfaceVk(const egl::SurfaceState &state,
155                                                EGLNativeWindowType window) = 0;
156     void generateCaps(egl::Caps *outCaps) const override;
157 
158     virtual angle::Result waitNativeImpl();
159 
160     mutable angle::ScratchBuffer mScratchBuffer;
161 
162     vk::Error mSavedError;
163 };
164 
165 }  // namespace rx
166 
167 #endif  // LIBANGLE_RENDERER_VULKAN_DISPLAYVK_H_
168