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