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 // FramebufferVk.h: 7 // Defines the class interface for FramebufferVk, implementing FramebufferImpl. 8 // 9 10 #ifndef LIBANGLE_RENDERER_VULKAN_FRAMEBUFFERVK_H_ 11 #define LIBANGLE_RENDERER_VULKAN_FRAMEBUFFERVK_H_ 12 13 #include "libANGLE/angletypes.h" 14 #include "libANGLE/renderer/FramebufferImpl.h" 15 #include "libANGLE/renderer/RenderTargetCache.h" 16 #include "libANGLE/renderer/vulkan/BufferVk.h" 17 #include "libANGLE/renderer/vulkan/ResourceVk.h" 18 #include "libANGLE/renderer/vulkan/SurfaceVk.h" 19 #include "libANGLE/renderer/vulkan/UtilsVk.h" 20 #include "libANGLE/renderer/vulkan/vk_cache_utils.h" 21 #include "libANGLE/renderer/vulkan/vk_helpers.h" 22 23 namespace rx 24 { 25 class RendererVk; 26 class RenderTargetVk; 27 class WindowSurfaceVk; 28 29 // FramebufferVk Cache 30 class FramebufferCache final : angle::NonCopyable 31 { 32 public: 33 FramebufferCache() = default; ~FramebufferCache()34 ~FramebufferCache() { ASSERT(mPayload.empty()); } 35 36 void destroy(RendererVk *rendererVk); 37 38 bool get(ContextVk *contextVk, 39 const vk::FramebufferDesc &desc, 40 vk::FramebufferHelper **framebufferOut); 41 void insert(const vk::FramebufferDesc &desc, vk::FramebufferHelper &&framebufferHelper); 42 void clear(ContextVk *contextVk); 43 44 private: 45 angle::HashMap<vk::FramebufferDesc, vk::FramebufferHelper> mPayload; 46 CacheStats mCacheStats; 47 }; 48 49 class FramebufferVk : public FramebufferImpl 50 { 51 public: 52 // Factory methods so we don't have to use constructors with overloads. 53 static FramebufferVk *CreateUserFBO(RendererVk *renderer, const gl::FramebufferState &state); 54 55 // The passed-in SurfaceVk must be destroyed after this FBO is destroyed. Our Surface code is 56 // ref-counted on the number of 'current' contexts, so we shouldn't get any dangling surface 57 // references. See Surface::setIsCurrent(bool). 58 static FramebufferVk *CreateDefaultFBO(RendererVk *renderer, 59 const gl::FramebufferState &state, 60 WindowSurfaceVk *backbuffer); 61 62 ~FramebufferVk() override; 63 void destroy(const gl::Context *context) override; 64 65 angle::Result discard(const gl::Context *context, 66 size_t count, 67 const GLenum *attachments) override; 68 angle::Result invalidate(const gl::Context *context, 69 size_t count, 70 const GLenum *attachments) override; 71 angle::Result invalidateSub(const gl::Context *context, 72 size_t count, 73 const GLenum *attachments, 74 const gl::Rectangle &area) override; 75 76 angle::Result clear(const gl::Context *context, GLbitfield mask) override; 77 angle::Result clearBufferfv(const gl::Context *context, 78 GLenum buffer, 79 GLint drawbuffer, 80 const GLfloat *values) override; 81 angle::Result clearBufferuiv(const gl::Context *context, 82 GLenum buffer, 83 GLint drawbuffer, 84 const GLuint *values) override; 85 angle::Result clearBufferiv(const gl::Context *context, 86 GLenum buffer, 87 GLint drawbuffer, 88 const GLint *values) override; 89 angle::Result clearBufferfi(const gl::Context *context, 90 GLenum buffer, 91 GLint drawbuffer, 92 GLfloat depth, 93 GLint stencil) override; 94 95 const gl::InternalFormat &getImplementationColorReadFormat( 96 const gl::Context *context) const override; 97 angle::Result readPixels(const gl::Context *context, 98 const gl::Rectangle &area, 99 GLenum format, 100 GLenum type, 101 const gl::PixelPackState &pack, 102 gl::Buffer *packBuffer, 103 void *pixels) override; 104 105 angle::Result blit(const gl::Context *context, 106 const gl::Rectangle &sourceArea, 107 const gl::Rectangle &destArea, 108 GLbitfield mask, 109 GLenum filter) override; 110 111 gl::FramebufferStatus checkStatus(const gl::Context *context) const override; 112 113 angle::Result syncState(const gl::Context *context, 114 GLenum binding, 115 const gl::Framebuffer::DirtyBits &dirtyBits, 116 gl::Command command) override; 117 118 angle::Result getSamplePosition(const gl::Context *context, 119 size_t index, 120 GLfloat *xy) const override; 121 RenderTargetVk *getDepthStencilRenderTarget() const; 122 123 // Internal helper function for readPixels operations. 124 angle::Result readPixelsImpl(ContextVk *contextVk, 125 const gl::Rectangle &area, 126 const PackPixelsParams &packPixelsParams, 127 VkImageAspectFlagBits copyAspectFlags, 128 RenderTargetVk *renderTarget, 129 void *pixels); 130 131 gl::Extents getReadImageExtents() const; 132 gl::Rectangle getNonRotatedCompleteRenderArea() const; 133 gl::Rectangle getRotatedCompleteRenderArea(ContextVk *contextVk) const; 134 gl::Rectangle getRotatedScissoredRenderArea(ContextVk *contextVk) const; 135 136 const gl::DrawBufferMask &getEmulatedAlphaAttachmentMask() const; 137 RenderTargetVk *getColorDrawRenderTarget(size_t colorIndex) const; 138 RenderTargetVk *getColorReadRenderTarget() const; 139 140 angle::Result startNewRenderPass(ContextVk *contextVk, 141 const gl::Rectangle &scissoredRenderArea, 142 vk::RenderPassCommandBuffer **commandBufferOut, 143 bool *renderPassDescChangedOut); 144 145 GLint getSamples() const; 146 getRenderPassDesc()147 const vk::RenderPassDesc &getRenderPassDesc() const { return mRenderPassDesc; } 148 149 void updateColorResolveAttachment( 150 uint32_t colorIndexGL, 151 vk::ImageOrBufferViewSubresourceSerial resolveImageViewSerial); 152 153 angle::Result getFramebuffer(ContextVk *contextVk, 154 vk::Framebuffer **framebufferOut, 155 const vk::ImageView *resolveImageViewIn, 156 const SwapchainResolveMode swapchainResolveMode); 157 hasDeferredClears()158 bool hasDeferredClears() const { return !mDeferredClears.empty(); } 159 angle::Result flushDeferredClears(ContextVk *contextVk); setReadOnlyDepthFeedbackLoopMode(bool readOnlyDepthFeedbackModeEnabled)160 void setReadOnlyDepthFeedbackLoopMode(bool readOnlyDepthFeedbackModeEnabled) 161 { 162 mReadOnlyDepthFeedbackLoopMode = readOnlyDepthFeedbackModeEnabled; 163 } isReadOnlyDepthFeedbackLoopMode()164 bool isReadOnlyDepthFeedbackLoopMode() const { return mReadOnlyDepthFeedbackLoopMode; } 165 void updateRenderPassReadOnlyDepthMode(ContextVk *contextVk, 166 vk::RenderPassCommandBufferHelper *renderPass); 167 168 void onSwitchProgramFramebufferFetch(ContextVk *contextVk, bool programUsesFramebufferFetch); hasFramebufferFetch()169 bool hasFramebufferFetch() const { return mCurrentFramebufferDesc.hasFramebufferFetch(); } 170 171 void removeColorResolveAttachment(uint32_t colorIndexGL); 172 173 private: 174 FramebufferVk(RendererVk *renderer, 175 const gl::FramebufferState &state, 176 WindowSurfaceVk *backbuffer); 177 178 // The 'in' rectangles must be clipped to the scissor and FBO. The clipping is done in 'blit'. 179 angle::Result blitWithCommand(ContextVk *contextVk, 180 const gl::Rectangle &sourceArea, 181 const gl::Rectangle &destArea, 182 RenderTargetVk *readRenderTarget, 183 RenderTargetVk *drawRenderTarget, 184 GLenum filter, 185 bool colorBlit, 186 bool depthBlit, 187 bool stencilBlit, 188 bool flipX, 189 bool flipY); 190 191 // Resolve color with subpass attachment 192 angle::Result resolveColorWithSubpass(ContextVk *contextVk, 193 const UtilsVk::BlitResolveParameters ¶ms); 194 195 // Resolve color with vkCmdResolveImage 196 angle::Result resolveColorWithCommand(ContextVk *contextVk, 197 const UtilsVk::BlitResolveParameters ¶ms, 198 vk::ImageHelper *srcImage); 199 200 angle::Result clearImpl(const gl::Context *context, 201 gl::DrawBufferMask clearColorBuffers, 202 bool clearDepth, 203 bool clearStencil, 204 const VkClearColorValue &clearColorValue, 205 const VkClearDepthStencilValue &clearDepthStencilValue); 206 207 void mergeClearsWithDeferredClears(gl::DrawBufferMask clearColorBuffers, 208 bool clearDepth, 209 bool clearStencil, 210 const VkClearColorValue &clearColorValue, 211 const VkClearDepthStencilValue &clearDepthStencilValue); 212 angle::Result clearWithDraw(ContextVk *contextVk, 213 const gl::Rectangle &clearArea, 214 gl::DrawBufferMask clearColorBuffers, 215 bool clearDepth, 216 bool clearStencil, 217 gl::BlendStateExt::ColorMaskStorage::Type colorMasks, 218 uint8_t stencilMask, 219 const VkClearColorValue &clearColorValue, 220 const VkClearDepthStencilValue &clearDepthStencilValue); 221 void redeferClears(ContextVk *contextVk); 222 void clearWithCommand(ContextVk *contextVk, const gl::Rectangle &scissoredRenderArea); 223 void clearWithLoadOp(ContextVk *contextVk); 224 void updateActiveColorMasks(size_t colorIndex, bool r, bool g, bool b, bool a); 225 void updateRenderPassDesc(ContextVk *contextVk); 226 angle::Result updateColorAttachment(const gl::Context *context, uint32_t colorIndex); 227 angle::Result updateDepthStencilAttachment(const gl::Context *context); 228 void updateDepthStencilAttachmentSerial(ContextVk *contextVk); 229 angle::Result flushColorAttachmentUpdates(const gl::Context *context, 230 bool deferClears, 231 uint32_t colorIndex); 232 angle::Result flushDepthStencilAttachmentUpdates(const gl::Context *context, bool deferClears); 233 angle::Result invalidateImpl(ContextVk *contextVk, 234 size_t count, 235 const GLenum *attachments, 236 bool isSubInvalidate, 237 const gl::Rectangle &invalidateArea); 238 239 RenderTargetVk *getReadPixelsRenderTarget(GLenum format) const; 240 VkImageAspectFlagBits getReadPixelsAspectFlags(GLenum format) const; 241 242 VkClearValue getCorrectedColorClearValue(size_t colorIndexGL, 243 const VkClearColorValue &clearColor) const; 244 245 void updateLayerCount(); 246 247 WindowSurfaceVk *mBackbuffer; 248 249 vk::RenderPassDesc mRenderPassDesc; 250 vk::FramebufferHelper *mFramebuffer; 251 RenderTargetCache<RenderTargetVk> mRenderTargetCache; 252 253 // This variable is used to quickly compute if we need to do a masked clear. If a color 254 // channel is masked out, we check against the Framebuffer Attachments (RenderTargets) to see 255 // if the masked out channel is present in any of the attachments. 256 gl::BlendStateExt::ColorMaskStorage::Type mActiveColorComponentMasksForClear; 257 258 // When we draw to the framebuffer, and the real format has an alpha channel but the format of 259 // the framebuffer does not, we need to mask out the alpha channel. This DrawBufferMask will 260 // contain the mask to apply to the alpha channel when drawing. 261 gl::DrawBufferMask mEmulatedAlphaAttachmentMask; 262 263 vk::FramebufferDesc mCurrentFramebufferDesc; 264 FramebufferCache mFramebufferCache; 265 266 vk::ClearValuesArray mDeferredClears; 267 268 // Tracks if we are in depth feedback loop. Depth read only feedback loop is a special kind of 269 // depth stencil read only mode. When we are in feedback loop, we must flush renderpass to exit 270 // the loop instead of update the layout. 271 bool mReadOnlyDepthFeedbackLoopMode; 272 }; 273 } // namespace rx 274 275 #endif // LIBANGLE_RENDERER_VULKAN_FRAMEBUFFERVK_H_ 276