• 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 // SurfaceVk.h:
7 //    Defines the class interface for SurfaceVk, implementing SurfaceImpl.
8 //
9 
10 #ifndef LIBANGLE_RENDERER_VULKAN_SURFACEVK_H_
11 #define LIBANGLE_RENDERER_VULKAN_SURFACEVK_H_
12 
13 #include <vulkan/vulkan.h>
14 
15 #include "libANGLE/renderer/SurfaceImpl.h"
16 #include "libANGLE/renderer/vulkan/RenderTargetVk.h"
17 #include "libANGLE/renderer/vulkan/vk_helpers.h"
18 
19 namespace rx
20 {
21 class RendererVk;
22 
23 class SurfaceVk : public SurfaceImpl
24 {
25   public:
26     angle::Result getAttachmentRenderTarget(const gl::Context *context,
27                                             GLenum binding,
28                                             const gl::ImageIndex &imageIndex,
29                                             FramebufferAttachmentRenderTarget **rtOut) override;
30 
31   protected:
32     SurfaceVk(const egl::SurfaceState &surfaceState);
33     ~SurfaceVk() override;
34 
35     RenderTargetVk mColorRenderTarget;
36     RenderTargetVk mDepthStencilRenderTarget;
37 };
38 
39 class OffscreenSurfaceVk : public SurfaceVk
40 {
41   public:
42     OffscreenSurfaceVk(const egl::SurfaceState &surfaceState, EGLint width, EGLint height);
43     ~OffscreenSurfaceVk() override;
44 
45     egl::Error initialize(const egl::Display *display) override;
46     void destroy(const egl::Display *display) override;
47 
48     FramebufferImpl *createDefaultFramebuffer(const gl::Context *context,
49                                               const gl::FramebufferState &state) override;
50     egl::Error swap(const gl::Context *context) override;
51     egl::Error postSubBuffer(const gl::Context *context,
52                              EGLint x,
53                              EGLint y,
54                              EGLint width,
55                              EGLint height) override;
56     egl::Error querySurfacePointerANGLE(EGLint attribute, void **value) override;
57     egl::Error bindTexImage(const gl::Context *context,
58                             gl::Texture *texture,
59                             EGLint buffer) override;
60     egl::Error releaseTexImage(const gl::Context *context, EGLint buffer) override;
61     egl::Error getSyncValues(EGLuint64KHR *ust, EGLuint64KHR *msc, EGLuint64KHR *sbc) override;
62     void setSwapInterval(EGLint interval) override;
63 
64     // width and height can change with client window resizing
65     EGLint getWidth() const override;
66     EGLint getHeight() const override;
67 
68     EGLint isPostSubBufferSupported() const override;
69     EGLint getSwapBehavior() const override;
70 
71     angle::Result initializeContents(const gl::Context *context,
72                                      const gl::ImageIndex &imageIndex) override;
73 
74     vk::ImageHelper *getColorAttachmentImage();
75 
76   private:
77     struct AttachmentImage final : angle::NonCopyable
78     {
79         AttachmentImage();
80         ~AttachmentImage();
81 
82         angle::Result initialize(DisplayVk *displayVk,
83                                  EGLint width,
84                                  EGLint height,
85                                  const vk::Format &vkFormat,
86                                  GLint samples);
87         void destroy(const egl::Display *display);
88 
89         vk::ImageHelper image;
90         vk::ImageView imageView;
91     };
92 
93     angle::Result initializeImpl(DisplayVk *displayVk);
94 
95     EGLint mWidth;
96     EGLint mHeight;
97 
98     AttachmentImage mColorAttachment;
99     AttachmentImage mDepthStencilAttachment;
100 };
101 
102 class WindowSurfaceVk : public SurfaceVk
103 {
104   public:
105     WindowSurfaceVk(const egl::SurfaceState &surfaceState,
106                     EGLNativeWindowType window,
107                     EGLint width,
108                     EGLint height);
109     ~WindowSurfaceVk() override;
110 
111     void destroy(const egl::Display *display) override;
112 
113     egl::Error initialize(const egl::Display *display) override;
114     FramebufferImpl *createDefaultFramebuffer(const gl::Context *context,
115                                               const gl::FramebufferState &state) override;
116     egl::Error swap(const gl::Context *context) override;
117     egl::Error swapWithDamage(const gl::Context *context, EGLint *rects, EGLint n_rects) override;
118     egl::Error postSubBuffer(const gl::Context *context,
119                              EGLint x,
120                              EGLint y,
121                              EGLint width,
122                              EGLint height) override;
123     egl::Error querySurfacePointerANGLE(EGLint attribute, void **value) override;
124     egl::Error bindTexImage(const gl::Context *context,
125                             gl::Texture *texture,
126                             EGLint buffer) override;
127     egl::Error releaseTexImage(const gl::Context *context, EGLint buffer) override;
128     egl::Error getSyncValues(EGLuint64KHR *ust, EGLuint64KHR *msc, EGLuint64KHR *sbc) override;
129     void setSwapInterval(EGLint interval) override;
130 
131     // width and height can change with client window resizing
132     EGLint getWidth() const override;
133     EGLint getHeight() const override;
134 
135     EGLint isPostSubBufferSupported() const override;
136     EGLint getSwapBehavior() const override;
137 
138     angle::Result initializeContents(const gl::Context *context,
139                                      const gl::ImageIndex &imageIndex) override;
140 
141     angle::Result getCurrentFramebuffer(vk::Context *context,
142                                         const vk::RenderPass &compatibleRenderPass,
143                                         vk::Framebuffer **framebufferOut);
144 
145     vk::Semaphore getAcquireImageSemaphore();
146 
147   protected:
148     EGLNativeWindowType mNativeWindowType;
149     VkSurfaceKHR mSurface;
150     VkInstance mInstance;
151 
152   private:
153     virtual angle::Result createSurfaceVk(vk::Context *context, gl::Extents *extentsOut)      = 0;
154     virtual angle::Result getCurrentWindowSize(vk::Context *context, gl::Extents *extentsOut) = 0;
155 
156     angle::Result initializeImpl(DisplayVk *displayVk);
157     angle::Result recreateSwapchain(ContextVk *contextVk,
158                                     const gl::Extents &extents,
159                                     uint32_t swapHistoryIndex);
160     angle::Result createSwapChain(vk::Context *context,
161                                   const gl::Extents &extents,
162                                   VkSwapchainKHR oldSwapchain);
163     angle::Result checkForOutOfDateSwapchain(ContextVk *contextVk,
164                                              uint32_t swapHistoryIndex,
165                                              bool presentOutOfDate);
166     void releaseSwapchainImages(ContextVk *contextVk);
167     void destroySwapChainImages(DisplayVk *displayVk);
168     VkResult nextSwapchainImage(vk::Context *context);
169     angle::Result present(ContextVk *contextVk,
170                           EGLint *rects,
171                           EGLint n_rects,
172                           bool *presentOutOfDate);
173 
174     angle::Result swapImpl(const gl::Context *context, EGLint *rects, EGLint n_rects);
175 
176     bool isMultiSampled() const;
177 
178     VkSurfaceCapabilitiesKHR mSurfaceCaps;
179     std::vector<VkPresentModeKHR> mPresentModes;
180 
181     VkSwapchainKHR mSwapchain;
182     // Cached information used to recreate swapchains.
183     VkPresentModeKHR mSwapchainPresentMode;         // Current swapchain mode
184     VkPresentModeKHR mDesiredSwapchainPresentMode;  // Desired mode set through setSwapInterval()
185     uint32_t mMinImageCount;
186     VkSurfaceTransformFlagBitsKHR mPreTransform;
187     VkCompositeAlphaFlagBitsKHR mCompositeAlpha;
188 
189     uint32_t mCurrentSwapchainImageIndex;
190 
191     struct SwapchainImage : angle::NonCopyable
192     {
193         SwapchainImage();
194         SwapchainImage(SwapchainImage &&other);
195         ~SwapchainImage();
196 
197         vk::ImageHelper image;
198         vk::ImageView imageView;
199         vk::Framebuffer framebuffer;
200     };
201 
202     std::vector<SwapchainImage> mSwapchainImages;
203     vk::Semaphore mAcquireImageSemaphore;
204 
205     // A circular buffer that stores the serial of the renderer on every swap.  The CPU is
206     // throttled by waiting for the 2nd previous serial to finish.  Old swapchains are scheduled to
207     // be destroyed at the same time.
208     struct SwapHistory : angle::NonCopyable
209     {
210         SwapHistory();
211         SwapHistory(SwapHistory &&other) = delete;
212         SwapHistory &operator=(SwapHistory &&other) = delete;
213         ~SwapHistory();
214 
215         void destroy(RendererVk *renderer);
216 
217         angle::Result waitFence(ContextVk *contextVk);
218 
219         // Fence associated with the last submitted work to render to this swapchain image.
220         vk::Shared<vk::Fence> sharedFence;
221 
222         vk::Semaphore presentImageSemaphore;
223 
224         VkSwapchainKHR swapchain = VK_NULL_HANDLE;
225     };
226     static constexpr size_t kSwapHistorySize = 2;
227     std::array<SwapHistory, kSwapHistorySize> mSwapHistory;
228     size_t mCurrentSwapHistoryIndex;
229 
230     // Depth/stencil image.  Possibly multisampled.
231     vk::ImageHelper mDepthStencilImage;
232     vk::ImageView mDepthStencilImageView;
233 
234     // Multisample color image, view and framebuffer, if multisampling enabled.
235     vk::ImageHelper mColorImageMS;
236     vk::ImageView mColorImageViewMS;
237     vk::Framebuffer mFramebufferMS;
238 };
239 
240 }  // namespace rx
241 
242 #endif  // LIBANGLE_RENDERER_VULKAN_SURFACEVK_H_
243