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