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/renderer/FramebufferImpl.h" 14 #include "libANGLE/renderer/RenderTargetCache.h" 15 #include "libANGLE/renderer/vulkan/BufferVk.h" 16 #include "libANGLE/renderer/vulkan/ResourceVk.h" 17 #include "libANGLE/renderer/vulkan/UtilsVk.h" 18 #include "libANGLE/renderer/vulkan/vk_cache_utils.h" 19 20 namespace rx 21 { 22 class RendererVk; 23 class RenderTargetVk; 24 class WindowSurfaceVk; 25 26 class FramebufferVk : public FramebufferImpl 27 { 28 public: 29 // Factory methods so we don't have to use constructors with overloads. 30 static FramebufferVk *CreateUserFBO(RendererVk *renderer, const gl::FramebufferState &state); 31 32 // The passed-in SurfaceVK must be destroyed after this FBO is destroyed. Our Surface code is 33 // ref-counted on the number of 'current' contexts, so we shouldn't get any dangling surface 34 // references. See Surface::setIsCurrent(bool). 35 static FramebufferVk *CreateDefaultFBO(RendererVk *renderer, 36 const gl::FramebufferState &state, 37 WindowSurfaceVk *backbuffer); 38 39 ~FramebufferVk() override; 40 void destroy(const gl::Context *context) override; 41 42 angle::Result discard(const gl::Context *context, 43 size_t count, 44 const GLenum *attachments) override; 45 angle::Result invalidate(const gl::Context *context, 46 size_t count, 47 const GLenum *attachments) override; 48 angle::Result invalidateSub(const gl::Context *context, 49 size_t count, 50 const GLenum *attachments, 51 const gl::Rectangle &area) override; 52 53 angle::Result clear(const gl::Context *context, GLbitfield mask) override; 54 angle::Result clearBufferfv(const gl::Context *context, 55 GLenum buffer, 56 GLint drawbuffer, 57 const GLfloat *values) override; 58 angle::Result clearBufferuiv(const gl::Context *context, 59 GLenum buffer, 60 GLint drawbuffer, 61 const GLuint *values) override; 62 angle::Result clearBufferiv(const gl::Context *context, 63 GLenum buffer, 64 GLint drawbuffer, 65 const GLint *values) override; 66 angle::Result clearBufferfi(const gl::Context *context, 67 GLenum buffer, 68 GLint drawbuffer, 69 GLfloat depth, 70 GLint stencil) override; 71 72 const gl::InternalFormat &getImplementationColorReadFormat( 73 const gl::Context *context) const override; 74 angle::Result readPixels(const gl::Context *context, 75 const gl::Rectangle &area, 76 GLenum format, 77 GLenum type, 78 void *pixels) override; 79 80 angle::Result blit(const gl::Context *context, 81 const gl::Rectangle &sourceArea, 82 const gl::Rectangle &destArea, 83 GLbitfield mask, 84 GLenum filter) override; 85 86 bool checkStatus(const gl::Context *context) const override; 87 88 angle::Result syncState(const gl::Context *context, 89 GLenum binding, 90 const gl::Framebuffer::DirtyBits &dirtyBits) override; 91 92 angle::Result getSamplePosition(const gl::Context *context, 93 size_t index, 94 GLfloat *xy) const override; 95 RenderTargetVk *getDepthStencilRenderTarget() const; 96 97 // Internal helper function for readPixels operations. 98 angle::Result readPixelsImpl(ContextVk *contextVk, 99 const gl::Rectangle &area, 100 const PackPixelsParams &packPixelsParams, 101 VkImageAspectFlagBits copyAspectFlags, 102 RenderTargetVk *renderTarget, 103 void *pixels); 104 105 gl::Extents getReadImageExtents() const; 106 gl::Rectangle getCompleteRenderArea() const; 107 gl::Rectangle getScissoredRenderArea(ContextVk *contextVk) const; 108 109 const gl::DrawBufferMask &getEmulatedAlphaAttachmentMask() const; 110 RenderTargetVk *getColorDrawRenderTarget(size_t colorIndex) const; 111 RenderTargetVk *getColorReadRenderTarget() const; 112 113 angle::Result startNewRenderPass(ContextVk *contextVk, 114 const gl::Rectangle &renderArea, 115 vk::CommandBuffer **commandBufferOut); 116 117 RenderTargetVk *getFirstRenderTarget() const; 118 GLint getSamples() const; 119 getRenderPassDesc()120 const vk::RenderPassDesc &getRenderPassDesc() const { return mRenderPassDesc; } getFramebufferDesc()121 const vk::FramebufferDesc &getFramebufferDesc() const { return mCurrentFramebufferDesc; } 122 // We only support depth/stencil packed format and depthstencil attachment always follow all 123 // color attachments getDepthStencilAttachmentIndexVk()124 size_t getDepthStencilAttachmentIndexVk() const 125 { 126 return getState().getEnabledDrawBuffers().count(); 127 } 128 129 private: 130 FramebufferVk(RendererVk *renderer, 131 const gl::FramebufferState &state, 132 WindowSurfaceVk *backbuffer); 133 134 // The 'in' rectangles must be clipped to the scissor and FBO. The clipping is done in 'blit'. 135 angle::Result blitWithCommand(ContextVk *contextVk, 136 const gl::Rectangle &sourceArea, 137 const gl::Rectangle &destArea, 138 RenderTargetVk *readRenderTarget, 139 RenderTargetVk *drawRenderTarget, 140 GLenum filter, 141 bool colorBlit, 142 bool depthBlit, 143 bool stencilBlit, 144 bool flipX, 145 bool flipY); 146 147 // Resolve color with vkCmdResolveImage 148 angle::Result resolveColorWithCommand(ContextVk *contextVk, 149 const UtilsVk::BlitResolveParameters ¶ms, 150 vk::ImageHelper *srcImage); 151 152 angle::Result getFramebuffer(ContextVk *contextVk, vk::Framebuffer **framebufferOut); 153 154 angle::Result clearImpl(const gl::Context *context, 155 gl::DrawBufferMask clearColorBuffers, 156 bool clearDepth, 157 bool clearStencil, 158 const VkClearColorValue &clearColorValue, 159 const VkClearDepthStencilValue &clearDepthStencilValue); 160 161 angle::Result clearImmediatelyWithRenderPassOp( 162 ContextVk *contextVk, 163 const gl::Rectangle &clearArea, 164 gl::DrawBufferMask clearColorBuffers, 165 bool clearDepth, 166 bool clearStencil, 167 const VkClearColorValue &clearColorValue, 168 const VkClearDepthStencilValue &clearDepthStencilValue); 169 170 angle::Result clearWithDraw(ContextVk *contextVk, 171 const gl::Rectangle &clearArea, 172 gl::DrawBufferMask clearColorBuffers, 173 bool clearDepth, 174 bool clearStencil, 175 VkColorComponentFlags colorMaskFlags, 176 uint8_t stencilMask, 177 const VkClearColorValue &clearColorValue, 178 const VkClearDepthStencilValue &clearDepthStencilValue); 179 void clearWithRenderPassOp(gl::DrawBufferMask clearColorBuffers, 180 bool clearDepth, 181 bool clearStencil, 182 const VkClearColorValue &clearColorValue, 183 const VkClearDepthStencilValue &clearDepthStencilValue); 184 void updateActiveColorMasks(size_t colorIndex, bool r, bool g, bool b, bool a); 185 void updateRenderPassDesc(); 186 angle::Result updateColorAttachment(const gl::Context *context, 187 bool deferClears, 188 uint32_t colorIndex); 189 angle::Result invalidateImpl(ContextVk *contextVk, size_t count, const GLenum *attachments); 190 // Release all FramebufferVk objects in the cache and clear cache 191 void clearCache(ContextVk *contextVk); 192 angle::Result updateDepthStencilAttachment(const gl::Context *context, bool deferClears); 193 void updateDepthStencilAttachmentSerial(ContextVk *contextVk); 194 195 RenderTargetVk *getReadPixelsRenderTarget(GLenum format) const; 196 VkImageAspectFlagBits getReadPixelsAspectFlags(GLenum format) const; 197 198 angle::Result flushDeferredClears(ContextVk *contextVk, const gl::Rectangle &renderArea); 199 VkClearValue getCorrectedColorClearValue(size_t colorIndexGL, 200 const VkClearColorValue &clearColor) const; 201 202 WindowSurfaceVk *mBackbuffer; 203 204 vk::RenderPassDesc mRenderPassDesc; 205 vk::FramebufferHelper *mFramebuffer; 206 RenderTargetCache<RenderTargetVk> mRenderTargetCache; 207 208 // These two variables are used to quickly compute if we need to do a masked clear. If a color 209 // channel is masked out, we check against the Framebuffer Attachments (RenderTargets) to see 210 // if the masked out channel is present in any of the attachments. 211 VkColorComponentFlags mActiveColorComponents; 212 gl::DrawBufferMask mActiveColorComponentMasksForClear[4]; 213 vk::DynamicBuffer mReadPixelBuffer; 214 215 // When we draw to the framebuffer, and the real format has an alpha channel but the format of 216 // the framebuffer does not, we need to mask out the alpha channel. This DrawBufferMask will 217 // contain the mask to apply to the alpha channel when drawing. 218 gl::DrawBufferMask mEmulatedAlphaAttachmentMask; 219 220 vk::FramebufferDesc mCurrentFramebufferDesc; 221 std::unordered_map<vk::FramebufferDesc, vk::FramebufferHelper> mFramebufferCache; 222 bool mSupportDepthStencilFeedbackLoops; 223 224 vk::ClearValuesArray mDeferredClears; 225 }; 226 } // namespace rx 227 228 #endif // LIBANGLE_RENDERER_VULKAN_FRAMEBUFFERVK_H_ 229